* [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28
@ 2010-11-26 6:48 Shawn Guo
2010-11-26 6:49 ` [PATCH 01/15] ARM: mxs: Add core definitions Shawn Guo
` (46 more replies)
0 siblings, 47 replies; 146+ messages in thread
From: Shawn Guo @ 2010-11-26 6:48 UTC (permalink / raw)
To: linux-arm-kernel
This patch series is the successor of the following one.
[PATCH 00/11] ARM: imx: Add initial i.MX28 support
http://lists.infradead.org/pipermail/linux-arm-kernel/2010-November/031464.html
It puts everything about MX23 and MX28 into mach-mxs to address
the concern from Uwe and Sascha.
It's being developed against Sascha's imx-for-2.6.38 tree,
and supports single image for MX23 and MX28, since they share
the same PHYS_OFFSET.
Shawn Guo (15):
arch/arm/Kconfig | 10 +
arch/arm/Makefile | 1 +
arch/arm/mach-mxs/Kconfig | 34 +
arch/arm/mach-mxs/Makefile | 14 +
arch/arm/mach-mxs/Makefile.boot | 3 +
arch/arm/mach-mxs/clock-mx23.c | 521 ++++++++++++++++
arch/arm/mach-mxs/clock-mx28.c | 732 +++++++++++++++++++++++
arch/arm/mach-mxs/clock.c | 201 +++++++
arch/arm/mach-mxs/cpu.c | 11 +
arch/arm/mach-mxs/devices-mx23.h | 16 +
arch/arm/mach-mxs/devices-mx28.h | 22 +
arch/arm/mach-mxs/devices.c | 75 +++
arch/arm/mach-mxs/devices/Kconfig | 5 +
arch/arm/mach-mxs/devices/Makefile | 2 +
arch/arm/mach-mxs/devices/platform-duart.c | 47 ++
arch/arm/mach-mxs/devices/platform-fec.c | 51 ++
arch/arm/mach-mxs/gpio.c | 364 +++++++++++
arch/arm/mach-mxs/icoll.c | 77 +++
arch/arm/mach-mxs/include/mach/clkdev.h | 7 +
arch/arm/mach-mxs/include/mach/clock.h | 64 ++
arch/arm/mach-mxs/include/mach/common.h | 33 +
arch/arm/mach-mxs/include/mach/debug-macro.S | 51 ++
arch/arm/mach-mxs/include/mach/devices-common.h | 46 ++
arch/arm/mach-mxs/include/mach/entry-macro.S | 36 ++
arch/arm/mach-mxs/include/mach/gpio.h | 49 ++
arch/arm/mach-mxs/include/mach/hardware.h | 66 ++
arch/arm/mach-mxs/include/mach/io.h | 22 +
arch/arm/mach-mxs/include/mach/iomux-mx23.h | 29 +
arch/arm/mach-mxs/include/mach/iomux-mx28.h | 44 ++
arch/arm/mach-mxs/include/mach/iomux.h | 77 +++
arch/arm/mach-mxs/include/mach/irqs.h | 32 +
arch/arm/mach-mxs/include/mach/memory.h | 24 +
arch/arm/mach-mxs/include/mach/mx23.h | 147 +++++
arch/arm/mach-mxs/include/mach/mx28.h | 227 +++++++
arch/arm/mach-mxs/include/mach/mxs.h | 60 ++
arch/arm/mach-mxs/include/mach/system.h | 27 +
arch/arm/mach-mxs/include/mach/timex.h | 21 +
arch/arm/mach-mxs/include/mach/uncompress.h | 82 +++
arch/arm/mach-mxs/include/mach/vmalloc.h | 22 +
arch/arm/mach-mxs/iomux.c | 110 ++++
arch/arm/mach-mxs/mach-mx23evk.c | 59 ++
arch/arm/mach-mxs/mach-mx28evk.c | 108 ++++
arch/arm/mach-mxs/mm-mx23.c | 48 ++
arch/arm/mach-mxs/mm-mx28.c | 48 ++
arch/arm/mach-mxs/regs-clkctrl-mx23.h | 455 ++++++++++++++
arch/arm/mach-mxs/regs-clkctrl-mx28.h | 663 ++++++++++++++++++++
arch/arm/mach-mxs/system.c | 152 +++++
arch/arm/mach-mxs/timer.c | 285 +++++++++
48 files changed, 5280 insertions(+), 0 deletions(-)
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH 01/15] ARM: mxs: Add core definitions
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
@ 2010-11-26 6:49 ` Shawn Guo
2010-11-26 11:30 ` Uwe Kleine-König
2010-11-26 6:49 ` [PATCH 02/15] ARM: mxs: Add helper definition and function Shawn Guo
` (45 subsequent siblings)
46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-11-26 6:49 UTC (permalink / raw)
To: linux-arm-kernel
Add core definitions for MXS-based SoC MX23 and MX28.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
arch/arm/mach-mxs/include/mach/hardware.h | 66 +++++++++
arch/arm/mach-mxs/include/mach/irqs.h | 32 ++++
arch/arm/mach-mxs/include/mach/memory.h | 24 +++
arch/arm/mach-mxs/include/mach/mx23.h | 147 +++++++++++++++++++
arch/arm/mach-mxs/include/mach/mx28.h | 227 +++++++++++++++++++++++++++++
arch/arm/mach-mxs/include/mach/mxs.h | 60 ++++++++
6 files changed, 556 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/include/mach/hardware.h
create mode 100644 arch/arm/mach-mxs/include/mach/irqs.h
create mode 100644 arch/arm/mach-mxs/include/mach/memory.h
create mode 100644 arch/arm/mach-mxs/include/mach/mx23.h
create mode 100644 arch/arm/mach-mxs/include/mach/mx28.h
create mode 100644 arch/arm/mach-mxs/include/mach/mxs.h
diff --git a/arch/arm/mach-mxs/include/mach/hardware.h b/arch/arm/mach-mxs/include/mach/hardware.h
new file mode 100644
index 0000000..5edccd5
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/hardware.h
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2004-2007 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
+ * 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_MXS_HARDWARE_H__
+#define __MACH_MXS_HARDWARE_H__
+
+#include <asm/sizes.h>
+
+#ifdef __ASSEMBLER__
+#define IOMEM(addr) (addr)
+#else
+#define IOMEM(addr) ((void __force __iomem *)(addr))
+#endif
+
+#define MXS_IO_P2V_MODULE(addr, module) \
+ (((addr) - module ## _BASE_ADDR) < module ## _SIZE ? \
+ (addr) - (module ## _BASE_ADDR) + (module ## _BASE_ADDR_VIRT) : 0)
+
+/*
+ * It maps the whole address space to [0xf4000000, 0xf5ffffff].
+ *
+ * OCRAM 0x00000000+0x020000 -> 0xf4000000+0x020000
+ * IO 0x80000000+0x100000 -> 0xf4400000+0x100000
+ */
+#define MXS_IO_P2V(x) ( \
+ 0xf4000000 + \
+ (((x) & 0x50000000) >> 6) + \
+ (((x) & 0x0b000000) >> 4) + \
+ (((x) & 0x000fffff)))
+
+#define MXS_IO_ADDRESS(x) IOMEM(MXS_IO_P2V(x))
+
+#ifdef CONFIG_SOC_IMX23
+# include <mach/mx23.h>
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+# include <mach/mx28.h>
+#endif
+
+#include <mach/mxs.h>
+
+#define mxs_map_entry(soc, name, _type) { \
+ .virtual = soc ## _IO_P2V(soc ## _ ## name ## _BASE_ADDR), \
+ .pfn = __phys_to_pfn(soc ## _ ## name ## _BASE_ADDR), \
+ .length = soc ## _ ## name ## _SIZE, \
+ .type = _type, \
+}
+
+#endif /* __MACH_MXS_HARDWARE_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/irqs.h b/arch/arm/mach-mxs/include/mach/irqs.h
new file mode 100644
index 0000000..f771039
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/irqs.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2004-2007 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.
+ */
+
+#ifndef __MACH_MXS_IRQS_H__
+#define __MACH_MXS_IRQS_H__
+
+#define MXS_INTERNAL_IRQS 128
+
+#define MXS_GPIO_IRQ_START MXS_INTERNAL_IRQS
+
+/* the maximum for MXS-based */
+#define MXS_GPIO_IRQS (32 * 5)
+
+/*
+ * The next 16 interrupts are for board specific purposes. Since
+ * the kernel can only run on one machine at a time, we can re-use
+ * these. If you need more, increase MXS_BOARD_IRQS, but keep it
+ * within sensible limits.
+ */
+#define MXS_BOARD_IRQ_START (MXS_GPIO_IRQ_START + MXS_GPIO_IRQS)
+#define MXS_BOARD_IRQS 16
+
+#define NR_IRQS (MXS_BOARD_IRQ_START + MXS_BOARD_IRQS)
+
+#endif /* __MACH_MXS_IRQS_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/memory.h b/arch/arm/mach-mxs/include/mach/memory.h
new file mode 100644
index 0000000..b5420a5
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/memory.h
@@ -0,0 +1,24 @@
+/*
+ * 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_MXS_MEMORY_H__
+#define __MACH_MXS_MEMORY_H__
+
+#define PHYS_OFFSET UL(0x40000000)
+
+#endif /* __MACH_MXS_MEMORY_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mx23.h b/arch/arm/mach-mxs/include/mach/mx23.h
new file mode 100644
index 0000000..27a11ee
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mx23.h
@@ -0,0 +1,147 @@
+/*
+ * 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_MX23_H__
+#define __MACH_MX23_H__
+
+#ifndef __ASSEMBLER__
+#include <linux/io.h>
+#endif
+
+/*
+ * OCRAM
+ */
+#define MX23_OCRAM_BASE_ADDR 0x00000000
+#define MX23_OCRAM_SIZE SZ_32K
+
+/*
+ * IO
+ */
+#define MX23_IO_BASE_ADDR 0x80000000
+#define MX23_IO_SIZE SZ_1M
+
+#define MX23_ICOLL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x000000)
+#define MX23_APBH_DMA_BASE_ADDR (MX23_IO_BASE_ADDR + 0x004000)
+#define MX23_BCH_BASE_ADDR (MX23_IO_BASE_ADDR + 0x00a000)
+#define MX23_GPMI_BASE_ADDR (MX23_IO_BASE_ADDR + 0x00c000)
+#define MX23_SSP1_BASE_ADDR (MX23_IO_BASE_ADDR + 0x010000)
+#define MX23_SSP2_BASE_ADDR (MX23_IO_BASE_ADDR + 0x034000)
+#define MX23_PINCTRL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x018000)
+#define MX23_DIGCTL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x01c000)
+#define MX23_ETM_BASE_ADDR (MX23_IO_BASE_ADDR + 0x020000)
+#define MX23_APBX_DMA_BASE_ADDR (MX23_IO_BASE_ADDR + 0x024000)
+#define MX23_DCP_BASE_ADDR (MX23_IO_BASE_ADDR + 0x028000)
+#define MX23_PXP_BASE_ADDR (MX23_IO_BASE_ADDR + 0x02a000)
+#define MX23_OCOTP_BASE_ADDR (MX23_IO_BASE_ADDR + 0x02c000)
+#define MX23_AXI_AHB0_BASE_ADDR (MX23_IO_BASE_ADDR + 0x02e000)
+#define MX23_LCDIF_BASE_ADDR (MX23_IO_BASE_ADDR + 0x030000)
+#define MX23_TVENC_BASE_ADDR (MX23_IO_BASE_ADDR + 0x038000)
+#define MX23_CLKCTRL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x040000)
+#define MX23_SAIF0_BASE_ADDR (MX23_IO_BASE_ADDR + 0x042000)
+#define MX23_POWER_BASE_ADDR (MX23_IO_BASE_ADDR + 0x044000)
+#define MX23_SAIF1_BASE_ADDR (MX23_IO_BASE_ADDR + 0x046000)
+#define MX23_AUDIOOUT_BASE_ADDR (MX23_IO_BASE_ADDR + 0x048000)
+#define MX23_AUDIOIN_BASE_ADDR (MX23_IO_BASE_ADDR + 0x04c000)
+#define MX23_LRADC_BASE_ADDR (MX23_IO_BASE_ADDR + 0x050000)
+#define MX23_SPDIF_BASE_ADDR (MX23_IO_BASE_ADDR + 0x054000)
+#define MX23_RTC_BASE_ADDR (MX23_IO_BASE_ADDR + 0x05c000)
+#define MX23_I2C0_BASE_ADDR (MX23_IO_BASE_ADDR + 0x058000)
+#define MX23_PWM_BASE_ADDR (MX23_IO_BASE_ADDR + 0x064000)
+#define MX23_TIMROT_BASE_ADDR (MX23_IO_BASE_ADDR + 0x068000)
+#define MX23_AUART1_BASE_ADDR (MX23_IO_BASE_ADDR + 0x06c000)
+#define MX23_AUART2_BASE_ADDR (MX23_IO_BASE_ADDR + 0x06e000)
+#define MX23_DUART_BASE_ADDR (MX23_IO_BASE_ADDR + 0x070000)
+#define MX23_USBPHY_BASE_ADDR (MX23_IO_BASE_ADDR + 0x07c000)
+#define MX23_USBCTRL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x080000)
+#define MX23_DRAM_BASE_ADDR (MX23_IO_BASE_ADDR + 0x0e0000)
+
+#define MX23_IO_P2V(x) MXS_IO_P2V(x)
+#define MX23_IO_ADDRESS(x) IOMEM(MX23_IO_P2V(x))
+
+/*
+ * IRQ
+ */
+#define MX23_INT_DUART 0
+#define MX23_INT_COMMS_RX 1
+#define MX23_INT_COMMS_TX 1
+#define MX23_INT_SSP2_ERROR 2
+#define MX23_INT_VDD5V 3
+#define MX23_INT_HEADPHONE_SHORT 4
+#define MX23_INT_DAC_DMA 5
+#define MX23_INT_DAC_ERROR 6
+#define MX23_INT_ADC_DMA 7
+#define MX23_INT_ADC_ERROR 8
+#define MX23_INT_SPDIF_DMA 9
+#define MX23_INT_SAIF2_DMA 9
+#define MX23_INT_SPDIF_ERROR 10
+#define MX23_INT_SAIF1_IRQ 10
+#define MX23_INT_SAIF2_IRQ 10
+#define MX23_INT_USB_CTRL 11
+#define MX23_INT_USB_WAKEUP 12
+#define MX23_INT_GPMI_DMA 13
+#define MX23_INT_SSP1_DMA 14
+#define MX23_INT_SSP_ERROR 15
+#define MX23_INT_GPIO0 16
+#define MX23_INT_GPIO1 17
+#define MX23_INT_GPIO2 18
+#define MX23_INT_SAIF1_DMA 19
+#define MX23_INT_SSP2_DMA 20
+#define MX23_INT_ECC8_IRQ 21
+#define MX23_INT_RTC_ALARM 22
+#define MX23_INT_UARTAPP_TX_DMA 23
+#define MX23_INT_UARTAPP_INTERNAL 24
+#define MX23_INT_UARTAPP_RX_DMA 25
+#define MX23_INT_I2C_DMA 26
+#define MX23_INT_I2C_ERROR 27
+#define MX23_INT_TIMER0 28
+#define MX23_INT_TIMER1 29
+#define MX23_INT_TIMER2 30
+#define MX23_INT_TIMER3 31
+#define MX23_INT_BATT_BRNOUT 32
+#define MX23_INT_VDDD_BRNOUT 33
+#define MX23_INT_VDDIO_BRNOUT 34
+#define MX23_INT_VDD18_BRNOUT 35
+#define MX23_INT_TOUCH_DETECT 36
+#define MX23_INT_LRADC_CH0 37
+#define MX23_INT_LRADC_CH1 38
+#define MX23_INT_LRADC_CH2 39
+#define MX23_INT_LRADC_CH3 40
+#define MX23_INT_LRADC_CH4 41
+#define MX23_INT_LRADC_CH5 42
+#define MX23_INT_LRADC_CH6 43
+#define MX23_INT_LRADC_CH7 44
+#define MX23_INT_LCDIF_DMA 45
+#define MX23_INT_LCDIF_ERROR 46
+#define MX23_INT_DIGCTL_DEBUG_TRAP 47
+#define MX23_INT_RTC_1MSEC 48
+#define MX23_INT_DRI_DMA 49
+#define MX23_INT_DRI_ATTENTION 50
+#define MX23_INT_GPMI_ATTENTION 51
+#define MX23_INT_IR 52
+#define MX23_INT_DCP_VMI 53
+#define MX23_INT_DCP 54
+#define MX23_INT_BCH 56
+#define MX23_INT_PXP 57
+#define MX23_INT_UARTAPP2_TX_DMA 58
+#define MX23_INT_UARTAPP2_INTERNAL 59
+#define MX23_INT_UARTAPP2_RX_DMA 60
+#define MX23_INT_VDAC_DETECT 61
+#define MX23_INT_VDD5V_DROOP 64
+#define MX23_INT_DCDC4P2_BO 65
+
+#endif /* __MACH_MX23_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mx28.h b/arch/arm/mach-mxs/include/mach/mx28.h
new file mode 100644
index 0000000..836d807
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mx28.h
@@ -0,0 +1,227 @@
+/*
+ * 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
+
+/*
+ * 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_MAC0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0f0000)
+#define MX28_ENET_MAC1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0f4000)
+
+#define MX28_IO_P2V(x) MXS_IO_P2V(x)
+#define MX28_IO_ADDRESS(x) IOMEM(MX28_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
+
+#endif /* __MACH_MX28_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mxs.h b/arch/arm/mach-mxs/include/mach/mxs.h
new file mode 100644
index 0000000..128c114
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mxs.h
@@ -0,0 +1,60 @@
+/*
+ * 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_MXS_H__
+#define __MACH_MXS_H__
+
+#define MXS_SET_ADDR 0x4
+#define MXS_CLR_ADDR 0x8
+#define MXS_TOG_ADDR 0xc
+
+/*
+ * MXS CPU types
+ */
+#define MXS_CPU_MX23 23
+#define MXS_CPU_MX28 28
+
+#ifndef __ASSEMBLY__
+extern unsigned int __mxs_cpu_type;
+#endif
+
+#ifdef CONFIG_SOC_IMX23
+# ifdef mxs_cpu_type
+# undef mxs_cpu_type
+# define mxs_cpu_type __mxs_cpu_type
+# else
+# define mxs_cpu_type MXS_CPU_MX23
+# endif
+# define cpu_is_mx23() (mxs_cpu_type == MXS_CPU_MX23)
+#else
+# define cpu_is_mx23() (0)
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+# ifdef mxs_cpu_type
+# undef mxs_cpu_type
+# define mxs_cpu_type __mxs_cpu_type
+# else
+# define mxs_cpu_type MXS_CPU_MX28
+# endif
+# define cpu_is_mx28() (mxs_cpu_type == MXS_CPU_MX28)
+#else
+# define cpu_is_mx28() (0)
+#endif
+
+#endif /* __MACH_MXS_H__ */
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH 02/15] ARM: mxs: Add helper definition and function
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
2010-11-26 6:49 ` [PATCH 01/15] ARM: mxs: Add core definitions Shawn Guo
@ 2010-11-26 6:49 ` Shawn Guo
2010-11-26 6:49 ` [PATCH 03/15] ARM: mxs: Add reset routines Shawn Guo
` (44 subsequent siblings)
46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-11-26 6:49 UTC (permalink / raw)
To: linux-arm-kernel
Add helper definition and function for MXS-based.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
arch/arm/mach-mxs/cpu.c | 11 ++++++++++
arch/arm/mach-mxs/include/mach/common.h | 33 ++++++++++++++++++++++++++++++
arch/arm/mach-mxs/include/mach/io.h | 22 ++++++++++++++++++++
arch/arm/mach-mxs/include/mach/timex.h | 21 +++++++++++++++++++
arch/arm/mach-mxs/include/mach/vmalloc.h | 22 ++++++++++++++++++++
5 files changed, 109 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/cpu.c
create mode 100644 arch/arm/mach-mxs/include/mach/common.h
create mode 100644 arch/arm/mach-mxs/include/mach/io.h
create mode 100644 arch/arm/mach-mxs/include/mach/timex.h
create mode 100644 arch/arm/mach-mxs/include/mach/vmalloc.h
diff --git a/arch/arm/mach-mxs/cpu.c b/arch/arm/mach-mxs/cpu.c
new file mode 100644
index 0000000..764b0d5
--- /dev/null
+++ b/arch/arm/mach-mxs/cpu.c
@@ -0,0 +1,11 @@
+
+#include <linux/module.h>
+
+unsigned int __mxs_cpu_type;
+EXPORT_SYMBOL(__mxs_cpu_type);
+
+void mxs_set_cpu_type(unsigned int type)
+{
+ __mxs_cpu_type = type;
+}
+
diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
new file mode 100644
index 0000000..2911057
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/common.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2004-2007 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.
+ */
+
+#ifndef __MACH_MXS_COMMON_H__
+#define __MACH_MXS_COMMON_H__
+
+struct clk;
+
+extern int mxs_reset_block(void __iomem *);
+extern void mxs_arch_reset_init(void __iomem *);
+extern void mxs_set_cpu_type(unsigned int);
+extern void mxs_timer_init(struct clk *, void __iomem *, int);
+
+extern int mx23_register_gpios(void);
+extern int mx23_clocks_init(void);
+extern void mx23_map_io(void);
+extern void mx23_init_irq(void);
+
+extern int mx28_register_gpios(void);
+extern int mx28_clocks_init(void);
+extern void mx28_map_io(void);
+extern void mx28_init_irq(void);
+
+extern void icoll_init_irq(void __iomem *);
+
+#endif /* __MACH_MXS_COMMON_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/io.h b/arch/arm/mach-mxs/include/mach/io.h
new file mode 100644
index 0000000..289b722
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/io.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2004-2007 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.
+ */
+
+#ifndef __MACH_MXS_IO_H__
+#define __MACH_MXS_IO_H__
+
+/* Allow IO space to be anywhere in the memory */
+#define IO_SPACE_LIMIT 0xffffffff
+
+/* io address mapping macro */
+#define __io(a) __typesafe_io(a)
+
+#define __mem_pci(a) (a)
+
+#endif /* __MACH_MXS_IO_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/timex.h b/arch/arm/mach-mxs/include/mach/timex.h
new file mode 100644
index 0000000..734ce89
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/timex.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 1999 ARM Limited
+ * Copyright 2004-2007 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.
+ */
+
+#ifndef __MACH_MXS_TIMEX_H__
+#define __MACH_MXS_TIMEX_H__
+
+#define CLOCK_TICK_RATE 32000 /* 32K */
+
+#endif /* __MACH_MXS_TIMEX_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/vmalloc.h b/arch/arm/mach-mxs/include/mach/vmalloc.h
new file mode 100644
index 0000000..103b016
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/vmalloc.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2000 Russell King.
+ * Copyright 2004-2007 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.
+ */
+
+#ifndef __MACH_MXS_VMALLOC_H__
+#define __MACH_MXS_VMALLOC_H__
+
+/* vmalloc ending address */
+#define VMALLOC_END 0xf4000000UL
+
+#endif /* __MACH_MXS_VMALLOC_H__ */
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH 03/15] ARM: mxs: Add reset routines
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
2010-11-26 6:49 ` [PATCH 01/15] ARM: mxs: Add core definitions Shawn Guo
2010-11-26 6:49 ` [PATCH 02/15] ARM: mxs: Add helper definition and function Shawn Guo
@ 2010-11-26 6:49 ` Shawn Guo
2010-11-26 9:31 ` Lothar Waßmann
2010-11-26 6:49 ` [PATCH 04/15] ARM: mxs: Add interrupt support Shawn Guo
` (43 subsequent siblings)
46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-11-26 6:49 UTC (permalink / raw)
To: linux-arm-kernel
* The mxs wdog is implemented in RTC block.
* There is a generic software reset routine for most modules on mxs.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
arch/arm/mach-mxs/include/mach/system.h | 27 ++++++
arch/arm/mach-mxs/system.c | 152 +++++++++++++++++++++++++++++++
2 files changed, 179 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/include/mach/system.h
create mode 100644 arch/arm/mach-mxs/system.c
diff --git a/arch/arm/mach-mxs/include/mach/system.h b/arch/arm/mach-mxs/include/mach/system.h
new file mode 100644
index 0000000..0e42823
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/system.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright 2004-2008 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.
+ */
+
+#ifndef __MACH_MXS_SYSTEM_H__
+#define __MACH_MXS_SYSTEM_H__
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+void arch_reset(char mode, const char *cmd);
+
+#endif /* __MACH_MXS_SYSTEM_H__ */
diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c
new file mode 100644
index 0000000..de33c66
--- /dev/null
+++ b/arch/arm/mach-mxs/system.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright 2006-2007,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
+ *
+ * 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/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+
+#include <asm/proc-fns.h>
+#include <asm/system.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+
+#define MXS_RTC_WATCHDOG 0x50
+#define MXS_WATCHDOG_EN (1 << 4)
+
+#define MXS_MODULE_CLKGATE (1 << 30)
+#define MXS_MODULE_SFTRST (1 << 31)
+
+static void __iomem *wdog_base;
+
+/*
+ * Reset the system. It is called by machine_restart().
+ */
+void arch_reset(char mode, const char *cmd)
+{
+ struct clk *clk;
+
+ clk = clk_get_sys("rtc", NULL);
+ if (!IS_ERR(clk))
+ clk_enable(clk);
+
+ /* Set wdog count */
+ __raw_writel(1, wdog_base + MXS_RTC_WATCHDOG);
+
+ /* Assert SRS signal */
+ __raw_writel(MXS_WATCHDOG_EN, wdog_base + MXS_SET_ADDR);
+
+ /* Wait for reset to assert... */
+ mdelay(500);
+
+ pr_err("Watchdog reset failed to assert reset\n");
+
+ /* Delay to allow the serial port to show the message */
+ mdelay(50);
+
+ /* We'll take a jump through zero as a poor second */
+ cpu_reset(0);
+}
+
+void mxs_arch_reset_init(void __iomem *base)
+{
+ wdog_base = base;
+}
+
+int mxs_reset_block(void __iomem *reset_addr)
+{
+ u32 val;
+ 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 */
+ val = __raw_readl(reset_addr);
+ val &= ~MXS_MODULE_SFTRST;
+ __raw_writel(val, reset_addr);
+ /*
+ * SFTRST needs 3 GPMI clocks to settle, the reference manual
+ * recommends to wait 1us.
+ */
+ udelay(1);
+ /* Poll SFTRST cleared */
+ timeout = 0x400;
+ while ((__raw_readl(reset_addr) & MXS_MODULE_SFTRST) && --timeout)
+ /* nothing */;
+ if (!timeout)
+ goto error;
+
+ /* Clear CLKGATE */
+ val = __raw_readl(reset_addr);
+ val &= ~MXS_MODULE_CLKGATE;
+ __raw_writel(val, reset_addr);
+ /* Set SFTRST to reset the block */
+ val = __raw_readl(reset_addr);
+ val |= MXS_MODULE_SFTRST;
+ __raw_writel(val, reset_addr);
+ /* Wait 1us */
+ udelay(1);
+ /* Poll CLKGATE set */
+ timeout = 0x400;
+ while ((!(__raw_readl(reset_addr) & MXS_MODULE_CLKGATE)) && --timeout)
+ /* nothing */;
+ if (!timeout)
+ goto error;
+
+ /* Clear SFTRST */
+ val = __raw_readl(reset_addr);
+ val &= ~MXS_MODULE_SFTRST;
+ __raw_writel(val, reset_addr);
+ /* Wait 1us */
+ udelay(1);
+ /* Poll SFTRST cleared */
+ timeout = 0x400;
+ while ((__raw_readl(reset_addr) & MXS_MODULE_SFTRST) && --timeout)
+ /* nothing */;
+ if (!timeout)
+ goto error;
+
+ /* Clear CLKGATE */
+ val = __raw_readl(reset_addr);
+ val &= ~MXS_MODULE_CLKGATE;
+ __raw_writel(val, reset_addr);
+ /* Wait 1us */
+ udelay(1);
+ /* Poll CLKGATE cleared */
+ timeout = 0x400;
+ while ((__raw_readl(reset_addr) & MXS_MODULE_CLKGATE) && --timeout)
+ /* nothing */;
+ if (!timeout)
+ goto error;
+
+ return 0;
+
+error:
+ pr_err("%s(%p): module reset timeout\n", __func__, reset_addr);
+ return -ETIMEDOUT;
+}
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH 04/15] ARM: mxs: Add interrupt support
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (2 preceding siblings ...)
2010-11-26 6:49 ` [PATCH 03/15] ARM: mxs: Add reset routines Shawn Guo
@ 2010-11-26 6:49 ` Shawn Guo
2010-11-30 13:56 ` Uwe Kleine-König
2010-11-26 6:49 ` [PATCH 05/15] ARM: mxs: Add low-level debug UART support Shawn Guo
` (42 subsequent siblings)
46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-11-26 6:49 UTC (permalink / raw)
To: linux-arm-kernel
Add Interrupt Collector (ICOLL) support for MXS-based.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
arch/arm/mach-mxs/icoll.c | 77 ++++++++++++++++++++++++++
arch/arm/mach-mxs/include/mach/entry-macro.S | 36 ++++++++++++
2 files changed, 113 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/icoll.c
create mode 100644 arch/arm/mach-mxs/include/mach/entry-macro.S
diff --git a/arch/arm/mach-mxs/icoll.c b/arch/arm/mach-mxs/icoll.c
new file mode 100644
index 0000000..a7a7d4f
--- /dev/null
+++ b/arch/arm/mach-mxs/icoll.c
@@ -0,0 +1,77 @@
+/*
+ * 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 mxs_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;
+
+ /* Reset icoll */
+ mxs_reset_block(irqbase + HW_ICOLL_CTRL);
+
+ for (i = 0; i < MXS_INTERNAL_IRQS; i++) {
+ set_irq_chip(i, &mxs_icoll_chip);
+ set_irq_handler(i, handle_level_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+}
diff --git a/arch/arm/mach-mxs/include/mach/entry-macro.S b/arch/arm/mach-mxs/include/mach/entry-macro.S
new file mode 100644
index 0000000..597948d
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/entry-macro.S
@@ -0,0 +1,36 @@
+/*
+ * Low-level IRQ helper macros for Freescale MXS-based
+ *
+ * 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.
+ */
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \base, =icoll_base
+ ldr \base, [\base]
+ ldr \irqnr, [\base, #0x70]
+ cmp \irqnr, #0x7F
+ moveqs \irqnr, #0
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH 05/15] ARM: mxs: Add low-level debug UART support
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (3 preceding siblings ...)
2010-11-26 6:49 ` [PATCH 04/15] ARM: mxs: Add interrupt support Shawn Guo
@ 2010-11-26 6:49 ` Shawn Guo
2010-11-30 15:48 ` Uwe Kleine-König
2010-11-26 6:49 ` [PATCH 06/15] ARM: mxs: Add timer support Shawn Guo
` (41 subsequent siblings)
46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-11-26 6:49 UTC (permalink / raw)
To: linux-arm-kernel
* DEBUG_LL support, which is incompatible with single MXS image
because of different DUART base address on MX23 and MX28
* uncompress message support
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
arch/arm/mach-mxs/include/mach/debug-macro.S | 51 ++++++++++++++++
arch/arm/mach-mxs/include/mach/uncompress.h | 82 ++++++++++++++++++++++++++
2 files changed, 133 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/include/mach/debug-macro.S
create mode 100644 arch/arm/mach-mxs/include/mach/uncompress.h
diff --git a/arch/arm/mach-mxs/include/mach/debug-macro.S b/arch/arm/mach-mxs/include/mach/debug-macro.S
new file mode 100644
index 0000000..efb3173
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/debug-macro.S
@@ -0,0 +1,51 @@
+/* arch/arm/mach-mxs/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * 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>
+
+#ifdef CONFIG_SOC_IMX23
+#ifdef UART_PADDR
+#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
+#endif
+#define UART_PADDR MX23_DUART_BASE_ADDR
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+#ifdef UART_PADDR
+#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
+#endif
+#define UART_PADDR MX28_DUART_BASE_ADDR
+#endif
+
+#define UART_VADDR MXS_IO_ADDRESS(UART_PADDR)
+
+ .macro addruart, rp, rv
+ ldr \rp, =UART_PADDR @ physical
+ ldr \rv, =UART_VADDR @ virtual
+ .endm
+
+ .macro senduart, rd, rx
+ str \rd, [\rx, #0x0] @ DR
+ .endm
+
+ .macro waituart, rd, rx
+1001: ldr \rd, [\rx, #0x18] @ FR
+ tst \rd, #1 << 5 @ FR_TXFF
+ bne 1001b
+ .endm
+
+ .macro busyuart, rd, rx
+1002: ldr \rd, [\rx, #0x18] @ FR
+ tst \rd, #1 << 3 @ FR_BUSY
+ beq 1002b
+ .endm
diff --git a/arch/arm/mach-mxs/include/mach/uncompress.h b/arch/arm/mach-mxs/include/mach/uncompress.h
new file mode 100644
index 0000000..47e5479
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/uncompress.h
@@ -0,0 +1,82 @@
+/*
+ * arch/arm/mach-mxs/include/mach/uncompress.h
+ *
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) Shane Nay (shane@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
+ * 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.
+ */
+#ifndef __MACH_MXS_UNCOMPRESS_H__
+#define __MACH_MXS_UNCOMPRESS_H__
+
+#define __MXS_BOOT_UNCOMPRESS
+
+#include <asm/mach-types.h>
+
+static unsigned long uart_base;
+
+#define UART(x) (*(volatile unsigned long *)(uart_base + (x)))
+
+#define DR 0x00
+#define FR 0x18
+#define FR_BUSY (1 << 3)
+#define FR_TXFE (1 << 7)
+#define CR 0x30
+#define CR_UARTEN 1
+
+/*
+ * The following code assumes the serial port has already been
+ * initialized by the bootloader. We search for the first enabled
+ * port in the most probable order. If you didn't setup a port in
+ * your bootloader then nothing will appear (which might be desired).
+ *
+ * This does not append a newline
+ */
+
+static void putc(int ch)
+{
+ if (!uart_base)
+ return;
+ if (!(UART(CR) & CR_UARTEN))
+ return;
+
+ while (!(UART(FR) & FR_TXFE))
+ barrier();
+
+ UART(DR) = ch;
+}
+
+static inline void flush(void)
+{
+}
+
+#define MX23_DUART_BASE_ADDR 0x80070000
+#define MX28_DUART_BASE_ADDR 0x80074000
+
+static __inline__ void __arch_decomp_setup(unsigned long arch_id)
+{
+ switch (arch_id) {
+ case MACH_TYPE_MX23EVK:
+ uart_base = MX23_DUART_BASE_ADDR;
+ break;
+ case MACH_TYPE_MX28EVK:
+ uart_base = MX28_DUART_BASE_ADDR;
+ break;
+ default:
+ break;
+ }
+}
+
+#define arch_decomp_setup() __arch_decomp_setup(arch_id)
+#define arch_decomp_wdog()
+
+#endif /* __MACH_MXS_UNCOMPRESS_H__ */
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH 06/15] ARM: mxs: Add timer support
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (4 preceding siblings ...)
2010-11-26 6:49 ` [PATCH 05/15] ARM: mxs: Add low-level debug UART support Shawn Guo
@ 2010-11-26 6:49 ` Shawn Guo
2010-11-30 16:13 ` Uwe Kleine-König
2010-11-26 6:49 ` [PATCH 07/15] ARM: mxs: Add gpio support Shawn Guo
` (40 subsequent siblings)
46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-11-26 6:49 UTC (permalink / raw)
To: linux-arm-kernel
Freescale MXS-based SoCs implement timer support in block TIMROT.
There are two versions of TIMROT. The v1 on MX23 only gets 16 bits
counter and has no match function. The v2 on MX28 extends the
counter to 32 bits and add the match function.
As the result, we need two instances of timers with v1 for better
implementation, one for next_event and another for get_cycles.
Otherwise, get_cycles may get imprecise result after long time
cumulating. With v2, one instance can serve two purposes well.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
arch/arm/mach-mxs/timer.c | 285 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 285 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/timer.c
diff --git a/arch/arm/mach-mxs/timer.c b/arch/arm/mach-mxs/timer.c
new file mode 100644
index 0000000..c52b465
--- /dev/null
+++ b/arch/arm/mach-mxs/timer.c
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2000-2001 Deep Blue Solutions
+ * 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
+ * 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/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clockchips.h>
+#include <linux/clk.h>
+
+#include <mach/hardware.h>
+#include <asm/mach/time.h>
+#include <mach/common.h>
+
+/*
+ * There are 2 versions of the timrot on Freescale MXS-based SoCs.
+ * The v1 on MX23 only gets 16 bits counter and has no match function.
+ * The v2 on MX28 extends the counter to 32 bits and add the match function.
+ *
+ * As the result, we need two instances of timers with v1 for better
+ * implementation, one for next_event and another for get_cycles. Otherwise,
+ * get_cycles may get imprecise result after long time cumulating.
+ * With v2, one instance can serve two purposes well.
+ */
+#define timrot_is_v1() (cpu_is_mx23())
+
+#define HW_TIMROT_ROTCTRL 0x00
+#define HW_TIMROT_TIMCTRLn(n) (0x20 + (n) * 0x40)
+#define HW_TIMROT_RUNNING_COUNTn(n) (0x30 + (n) * 0x40)
+#define HW_TIMROT_MATCH_COUNTn(n) (0x50 + (n) * 0x40)
+#define BM_TIMROT_TIMCTRLn_RELOAD (1 << 6)
+#define BM_TIMROT_TIMCTRLn_UPDATE (1 << 7)
+#define BM_TIMROT_TIMCTRLn_MATCH_MODE (1 << 11)
+#define BM_TIMROT_TIMCTRLn_IRQ_EN (1 << 14)
+#define BM_TIMROT_TIMCTRLn_IRQ (1 << 15)
+#define BP_TIMROT_TIMCTRLn_SELECT 0
+#define BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL (timrot_is_v1() ? 0x8 : 0xb)
+
+static struct clock_event_device clockevent_mxs;
+static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
+
+static void __iomem *timer_base;
+
+static inline void timrot_irq_disable(void)
+{
+ __raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN,
+ timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_CLR_ADDR);
+}
+
+static inline void timrot_irq_enable(void)
+{
+ __raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN,
+ timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_SET_ADDR);
+}
+
+static void timrot_irq_acknowledge(void)
+{
+ __raw_writel(BM_TIMROT_TIMCTRLn_IRQ,
+ timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_CLR_ADDR);
+}
+
+static cycle_t timrot_get_cycles(struct clocksource *cs)
+{
+ if (timrot_is_v1())
+ return ~((__raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(1))
+ & 0xffff0000) >> 16);
+ else
+ return ~__raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(0));
+}
+
+static int timrot_set_next_event(unsigned long evt,
+ struct clock_event_device *dev)
+{
+ unsigned long match;
+ int ret;
+
+ /* timrot decrements the count */
+ if (timrot_is_v1()) {
+ __raw_writel(evt, timer_base + HW_TIMROT_RUNNING_COUNTn(0));
+ ret = 0;
+ } else {
+ match = __raw_readl(timer_base + HW_TIMROT_MATCH_COUNTn(0))
+ - evt;
+ __raw_writel(match, timer_base + HW_TIMROT_MATCH_COUNTn(0));
+ ret = (int)(match - __raw_readl(timer_base +
+ HW_TIMROT_RUNNING_COUNTn(0))) > 0 ? -ETIME : 0;
+ }
+
+ return ret;
+}
+
+static irqreturn_t mxs_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = &clockevent_mxs;
+
+ timrot_irq_acknowledge();
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction mxs_timer_irq = {
+ .name = "MXS Timer Tick",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = mxs_timer_interrupt,
+};
+
+#ifdef DEBUG
+static const char *clock_event_mode_label[] = {
+ [CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
+ [CLOCK_EVT_MODE_ONESHOT] = "CLOCK_EVT_MODE_ONESHOT",
+ [CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN",
+ [CLOCK_EVT_MODE_UNUSED] = "CLOCK_EVT_MODE_UNUSED"
+};
+#endif /* DEBUG */
+
+static void mxs_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ unsigned long flags;
+
+ /*
+ * The timer interrupt generation is disabled at least
+ * for enough time to call mxs_set_next_event()
+ */
+ local_irq_save(flags);
+
+ /* Disable interrupt in timer module */
+ timrot_irq_disable();
+
+ if (mode != clockevent_mode) {
+ /* Set event time into far-far future */
+ __raw_writel(__raw_readl(timer_base +
+ HW_TIMROT_RUNNING_COUNTn(0)) + 3,
+ timer_base + HW_TIMROT_MATCH_COUNTn(0));
+
+ /* Clear pending interrupt */
+ timrot_irq_acknowledge();
+ }
+
+#ifdef DEBUG
+ printk(KERN_INFO "mxs_set_mode: changing mode from %s to %s\n",
+ clock_event_mode_label[clockevent_mode],
+ clock_event_mode_label[mode]);
+#endif /* DEBUG */
+
+ /* Remember timer mode */
+ clockevent_mode = mode;
+ local_irq_restore(flags);
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ printk(KERN_ERR "mxs_set_mode: Periodic mode is not "
+ "supported for MXS-based\n");
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ /*
+ * Do not put overhead of interrupt enable/disable into
+ * mxs_set_next_event(), the core has about 4 minutes
+ * to call mxs_set_next_event() or shutdown clock after
+ * mode switching
+ */
+ local_irq_save(flags);
+ timrot_irq_enable();
+ local_irq_restore(flags);
+ break;
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_RESUME:
+ /* Left event sources disabled, no more interrupts appear */
+ break;
+ }
+}
+
+static struct clock_event_device clockevent_mxs = {
+ .name = "mxs_timrot",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .shift = 32,
+ .set_mode = mxs_set_mode,
+ .set_next_event = timrot_set_next_event,
+ .rating = 200,
+};
+
+static int __init mxs_clockevent_init(struct clk *timer_clk)
+{
+ unsigned int c = clk_get_rate(timer_clk);
+
+ clockevent_mxs.mult = div_sc(c, NSEC_PER_SEC, clockevent_mxs.shift);
+ clockevent_mxs.cpumask = cpumask_of(0);
+ if (timrot_is_v1()) {
+ clockevent_mxs.max_delta_ns =
+ clockevent_delta2ns(0xfffe, &clockevent_mxs);
+ clockevent_mxs.min_delta_ns =
+ clockevent_delta2ns(0xf, &clockevent_mxs);
+ } else {
+ clockevent_mxs.max_delta_ns =
+ clockevent_delta2ns(0xfffffffe, &clockevent_mxs);
+ clockevent_mxs.min_delta_ns =
+ clockevent_delta2ns(0xff, &clockevent_mxs);
+ }
+
+ clockevents_register_device(&clockevent_mxs);
+
+ return 0;
+}
+
+static struct clocksource clocksource_mxs = {
+ .name = "mxs_timer",
+ .rating = 200,
+ .read = timrot_get_cycles,
+ .mask = CLOCKSOURCE_MASK(32),
+ .shift = 10,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int __init mxs_clocksource_init(struct clk *timer_clk)
+{
+ unsigned int c = clk_get_rate(timer_clk);
+
+ if (timrot_is_v1())
+ clocksource_mxs.mask = CLOCKSOURCE_MASK(16);
+ clocksource_mxs.mult = clocksource_hz2mult(c, clocksource_mxs.shift);
+ clocksource_register(&clocksource_mxs);
+
+ return 0;
+}
+
+void __init mxs_timer_init(struct clk *timer_clk,
+ void __iomem *base, int irq)
+{
+ clk_enable(timer_clk);
+
+ timer_base = base;
+
+ /*
+ * Initialize timers to a known state
+ */
+ mxs_reset_block(base + HW_TIMROT_ROTCTRL);
+
+ if (timrot_is_v1()) {
+ /* timer0 is for next_event */
+ __raw_writel(
+ BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL |
+ BM_TIMROT_TIMCTRLn_UPDATE |
+ BM_TIMROT_TIMCTRLn_IRQ_EN,
+ base + HW_TIMROT_TIMCTRLn(0));
+ /* timer1 is for get_cycles */
+ __raw_writel(
+ BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL |
+ BM_TIMROT_TIMCTRLn_RELOAD,
+ base + HW_TIMROT_TIMCTRLn(1));
+ __raw_writel(0xffff, timer_base + HW_TIMROT_RUNNING_COUNTn(1));
+
+ } else {
+ __raw_writel(
+ BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL |
+ BM_TIMROT_TIMCTRLn_IRQ_EN |
+ BM_TIMROT_TIMCTRLn_MATCH_MODE,
+ timer_base + HW_TIMROT_TIMCTRLn(0));
+ }
+
+ /* init and register the timer to the framework */
+ mxs_clocksource_init(timer_clk);
+ mxs_clockevent_init(timer_clk);
+
+ /* Make irqs happen */
+ setup_irq(irq, &mxs_timer_irq);
+}
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH 07/15] ARM: mxs: Add gpio support
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (5 preceding siblings ...)
2010-11-26 6:49 ` [PATCH 06/15] ARM: mxs: Add timer support Shawn Guo
@ 2010-11-26 6:49 ` Shawn Guo
2010-11-30 16:21 ` Uwe Kleine-König
2010-11-26 6:49 ` [PATCH 08/15] ARM: mxs: Add iomux support Shawn Guo
` (39 subsequent siblings)
46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-11-26 6:49 UTC (permalink / raw)
To: linux-arm-kernel
MXS-based SoCs implement gpio support in block PINCTRL.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
arch/arm/mach-mxs/gpio.c | 364 +++++++++++++++++++++++++++++++++
arch/arm/mach-mxs/include/mach/gpio.h | 49 +++++
2 files changed, 413 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/gpio.c
create mode 100644 arch/arm/mach-mxs/include/mach/gpio.h
diff --git a/arch/arm/mach-mxs/gpio.c b/arch/arm/mach-mxs/gpio.c
new file mode 100644
index 0000000..7e3674b
--- /dev/null
+++ b/arch/arm/mach-mxs/gpio.c
@@ -0,0 +1,364 @@
+/*
+ * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
+ * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
+ *
+ * Based on code from Freescale,
+ * Copyright (C) 2004-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/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <mach/hardware.h>
+#include <asm-generic/bug.h>
+
+static struct mxs_gpio_port *mxs_gpio_ports;
+static int gpio_table_size;
+
+#define PINCTRL_DOUT(n) ((cpu_is_mx23() ? 0x0500 : 0x0700) + (n) * 0x10)
+#define PINCTRL_DIN(n) ((cpu_is_mx23() ? 0x0600 : 0x0900) + (n) * 0x10)
+#define PINCTRL_DOE(n) ((cpu_is_mx23() ? 0x0700 : 0x0b00) + (n) * 0x10)
+#define PINCTRL_PIN2IRQ(n) ((cpu_is_mx23() ? 0x0800 : 0x1000) + (n) * 0x10)
+#define PINCTRL_IRQEN(n) ((cpu_is_mx23() ? 0x0900 : 0x1100) + (n) * 0x10)
+#define PINCTRL_IRQLEV(n) ((cpu_is_mx23() ? 0x0a00 : 0x1200) + (n) * 0x10)
+#define PINCTRL_IRQPOL(n) ((cpu_is_mx23() ? 0x0b00 : 0x1300) + (n) * 0x10)
+#define PINCTRL_IRQSTAT(n) ((cpu_is_mx23() ? 0x0c00 : 0x1400) + (n) * 0x10)
+
+#define GPIO_INT_FALL_EDGE 0x0
+#define GPIO_INT_LOW_LEV 0x1
+#define GPIO_INT_RISE_EDGE 0x2
+#define GPIO_INT_HIGH_LEV 0x3
+
+/* Note: This driver assumes 32 GPIOs are handled in one register */
+
+static void _clear_gpio_irqstatus(struct mxs_gpio_port *port, u32 index)
+{
+ __raw_writel(1 << index,
+ port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR_ADDR);
+}
+
+static void _set_gpio_irqenable(struct mxs_gpio_port *port, u32 index,
+ int enable)
+{
+ if (enable == 0) {
+ __raw_writel(1 << index,
+ port->base + PINCTRL_PIN2IRQ(port->id) + MXS_CLR_ADDR);
+ __raw_writel(1 << index,
+ port->base + PINCTRL_IRQEN(port->id) + MXS_CLR_ADDR);
+ } else {
+ __raw_writel(1 << index,
+ port->base + PINCTRL_PIN2IRQ(port->id) + MXS_SET_ADDR);
+ __raw_writel(1 << index,
+ port->base + PINCTRL_IRQEN(port->id) + MXS_SET_ADDR);
+ }
+}
+
+static void gpio_ack_irq(u32 irq)
+{
+ u32 gpio = irq_to_gpio(irq);
+ _clear_gpio_irqstatus(&mxs_gpio_ports[gpio / 32], gpio & 0x1f);
+}
+
+static void gpio_mask_irq(u32 irq)
+{
+ u32 gpio = irq_to_gpio(irq);
+ _set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 0);
+}
+
+static void gpio_unmask_irq(u32 irq)
+{
+ u32 gpio = irq_to_gpio(irq);
+ _set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 1);
+}
+
+static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset);
+
+static int gpio_set_irq_type(u32 irq, u32 type)
+{
+ u32 gpio = irq_to_gpio(irq);
+ struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32];
+ u32 val;
+ int edge;
+
+ port->both_edges &= ~(1 << (gpio & 31));
+ switch (type) {
+ case IRQ_TYPE_EDGE_RISING:
+ edge = GPIO_INT_RISE_EDGE;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ edge = GPIO_INT_FALL_EDGE;
+ break;
+ case IRQ_TYPE_EDGE_BOTH:
+ val = mxs_gpio_get(&port->chip, gpio & 31);
+ if (val) {
+ edge = GPIO_INT_LOW_LEV;
+ pr_debug("mxs: set GPIO %d to low trigger\n", gpio);
+ } else {
+ edge = GPIO_INT_HIGH_LEV;
+ pr_debug("mxs: set GPIO %d to high trigger\n", gpio);
+ }
+ port->both_edges |= 1 << (gpio & 31);
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ edge = GPIO_INT_LOW_LEV;
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ edge = GPIO_INT_HIGH_LEV;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* set level or edge */
+ if (edge & 0x1)
+ __raw_writel(1 << (gpio & 31),
+ port->base + PINCTRL_IRQLEV(port->id) + MXS_SET_ADDR);
+ else
+ __raw_writel(1 << (gpio & 31),
+ port->base + PINCTRL_IRQLEV(port->id) + MXS_CLR_ADDR);
+
+ /* set polarity */
+ if ((edge >> 1) & 0x1)
+ __raw_writel(1 << (gpio & 31),
+ port->base + PINCTRL_IRQPOL(port->id) + MXS_SET_ADDR);
+ else
+ __raw_writel(1 << (gpio & 31),
+ port->base + PINCTRL_IRQPOL(port->id) + MXS_CLR_ADDR);
+
+ _clear_gpio_irqstatus(port, gpio & 0x1f);
+
+ return 0;
+}
+
+static void mxs_flip_edge(struct mxs_gpio_port *port, u32 gpio)
+{
+ u32 val;
+ int edge;
+
+ edge = 1 << (gpio & 31);
+ val = __raw_readl(port->base + PINCTRL_IRQLEV(port->id));
+ if (val & edge) {
+ /* level is invalid for this function */
+ pr_err("mxs: invalid configuration for GPIO %d: %x\n",
+ gpio, edge);
+ return;
+ }
+ __raw_writel(1 << (gpio & 31),
+ port->base + PINCTRL_IRQPOL(port->id) + MXS_TOG_ADDR);
+}
+
+/* MXS has one interrupt *per* gpio port */
+static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc)
+{
+ u32 irq_stat;
+ struct mxs_gpio_port *port = (struct mxs_gpio_port *)get_irq_data(irq);
+ u32 gpio_irq_no_base = port->virtual_irq_start;
+
+ irq_stat = __raw_readl(port->base + PINCTRL_IRQSTAT(port->id)) &
+ __raw_readl(port->base + PINCTRL_IRQEN(port->id)) &
+ __raw_readl(port->base + PINCTRL_PIN2IRQ(port->id));
+
+ while (irq_stat != 0) {
+ int irqoffset = fls(irq_stat) - 1;
+
+ if (port->both_edges & (1 << irqoffset))
+ mxs_flip_edge(port, irqoffset);
+
+ generic_handle_irq(gpio_irq_no_base + irqoffset);
+
+ irq_stat &= ~(1 << irqoffset);
+ }
+}
+
+/*
+ * Set interrupt number "irq" in the GPIO as a wake-up source.
+ * While system is running, all registered GPIO interrupts need to have
+ * wake-up enabled. When system is suspended, only selected GPIO interrupts
+ * need to have wake-up enabled.
+ * @param irq interrupt source number
+ * @param enable enable as wake-up if equal to non-zero
+ * @return This function returns 0 on success.
+ */
+static int gpio_set_wake_irq(u32 irq, u32 enable)
+{
+ u32 gpio = irq_to_gpio(irq);
+ u32 gpio_idx = gpio & 0x1f;
+ struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32];
+
+ if (enable) {
+ if (port->irq_high && (gpio_idx >= 16))
+ enable_irq_wake(port->irq_high);
+ else
+ enable_irq_wake(port->irq);
+ } else {
+ if (port->irq_high && (gpio_idx >= 16))
+ disable_irq_wake(port->irq_high);
+ else
+ disable_irq_wake(port->irq);
+ }
+
+ return 0;
+}
+
+static struct irq_chip gpio_irq_chip = {
+ .ack = gpio_ack_irq,
+ .mask = gpio_mask_irq,
+ .unmask = gpio_unmask_irq,
+ .set_type = gpio_set_irq_type,
+ .set_wake = gpio_set_wake_irq,
+};
+
+static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset,
+ int dir)
+{
+ struct mxs_gpio_port *port =
+ container_of(chip, struct mxs_gpio_port, chip);
+ u32 l;
+ unsigned long flags;
+ void __iomem *reg = port->base + PINCTRL_DOE(port->id);
+
+ spin_lock_irqsave(&port->lock, flags);
+ l = __raw_readl(reg);
+ if (dir)
+ l |= 1 << offset;
+ else
+ l &= ~(1 << offset);
+ __raw_writel(l, reg);
+ spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void mxs_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct mxs_gpio_port *port =
+ container_of(chip, struct mxs_gpio_port, chip);
+ u32 l;
+ unsigned long flags;
+ void __iomem *reg = port->base + PINCTRL_DOUT(port->id);
+
+ spin_lock_irqsave(&port->lock, flags);
+ l = (__raw_readl(reg) & (~(1 << offset))) | (!!value << offset);
+ __raw_writel(l, reg);
+ spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct mxs_gpio_port *port =
+ container_of(chip, struct mxs_gpio_port, chip);
+ void __iomem *reg = port->base + PINCTRL_DIN(port->id);
+
+ return (__raw_readl(reg) >> offset) & 1;
+}
+
+static int mxs_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ _set_gpio_direction(chip, offset, 0);
+ return 0;
+}
+
+static int mxs_gpio_direction_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ mxs_gpio_set(chip, offset, value);
+ _set_gpio_direction(chip, offset, 1);
+ return 0;
+}
+
+int __init mxs_gpio_init(struct mxs_gpio_port *port, int cnt)
+{
+ int i, j;
+
+ /* save for local usage */
+ mxs_gpio_ports = port;
+ gpio_table_size = cnt;
+
+ printk(KERN_INFO "MXS GPIO hardware\n");
+
+ for (i = 0; i < cnt; i++) {
+ /* disable the interrupt and clear the status */
+ __raw_writel(0, port[i].base +
+ PINCTRL_PIN2IRQ(i));
+ __raw_writel(0, port[i].base +
+ PINCTRL_IRQEN(i));
+ __raw_writel(~0, port[i].base +
+ PINCTRL_IRQSTAT(i) + MXS_CLR_ADDR);
+
+ for (j = port[i].virtual_irq_start;
+ j < port[i].virtual_irq_start + 32; j++) {
+ set_irq_chip(j, &gpio_irq_chip);
+ set_irq_handler(j, handle_level_irq);
+ set_irq_flags(j, IRQF_VALID);
+ }
+
+ /* register gpio chip */
+ port[i].chip.direction_input = mxs_gpio_direction_input;
+ port[i].chip.direction_output = mxs_gpio_direction_output;
+ port[i].chip.get = mxs_gpio_get;
+ port[i].chip.set = mxs_gpio_set;
+ port[i].chip.base = i * 32;
+ port[i].chip.ngpio = 32;
+
+ spin_lock_init(&port[i].lock);
+
+ /* its a serious configuration bug when it fails */
+ BUG_ON( gpiochip_add(&port[i].chip) < 0 );
+
+ /* setup one handler for each entry */
+ set_irq_chained_handler(port[i].irq, mxs_gpio_irq_handler);
+ set_irq_data(port[i].irq, &port[i]);
+ }
+
+ return 0;
+}
+
+#define DEFINE_MXS_GPIO_PORT(soc, _id) \
+ { \
+ .chip.label = "gpio-" #_id, \
+ .id = _id, \
+ .irq = soc ## _INT_GPIO ## _id, \
+ .base = soc ## _IO_ADDRESS( \
+ soc ## _PINCTRL ## _BASE_ADDR), \
+ .virtual_irq_start = MXS_GPIO_IRQ_START + (_id) * 32, \
+ }
+
+#define DEFINE_REGISTER_FUNCTION(prefix) \
+int __init prefix ## _register_gpios(void) \
+{ \
+ return mxs_gpio_init(prefix ## _gpio_ports, \
+ ARRAY_SIZE(prefix ## _gpio_ports)); \
+}
+
+#ifdef CONFIG_SOC_IMX23
+static struct mxs_gpio_port mx23_gpio_ports[] = {
+ DEFINE_MXS_GPIO_PORT(MX23, 0),
+ DEFINE_MXS_GPIO_PORT(MX23, 1),
+ DEFINE_MXS_GPIO_PORT(MX23, 2),
+};
+DEFINE_REGISTER_FUNCTION(mx23)
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+static struct mxs_gpio_port mx28_gpio_ports[] = {
+ DEFINE_MXS_GPIO_PORT(MX28, 0),
+ DEFINE_MXS_GPIO_PORT(MX28, 1),
+ DEFINE_MXS_GPIO_PORT(MX28, 2),
+ DEFINE_MXS_GPIO_PORT(MX28, 3),
+ DEFINE_MXS_GPIO_PORT(MX28, 4),
+};
+DEFINE_REGISTER_FUNCTION(mx28)
+#endif
diff --git a/arch/arm/mach-mxs/include/mach/gpio.h b/arch/arm/mach-mxs/include/mach/gpio.h
new file mode 100644
index 0000000..7692de6
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/gpio.h
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.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.
+ */
+
+#ifndef __MACH_MXS_GPIO_H__
+#define __MACH_MXS_GPIO_H__
+
+#include <linux/spinlock.h>
+#include <mach/hardware.h>
+#include <asm-generic/gpio.h>
+
+#define MXS_GPIO_NR(bank, nr) ((bank) * 32 + (nr))
+
+/* use gpiolib dispatchers */
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep __gpio_cansleep
+
+#define gpio_to_irq(gpio) (MXS_GPIO_IRQ_START + (gpio))
+#define irq_to_gpio(irq) ((irq) - MXS_GPIO_IRQ_START)
+
+struct mxs_gpio_port {
+ void __iomem *base;
+ int id;
+ int irq;
+ int irq_high;
+ int virtual_irq_start;
+ struct gpio_chip chip;
+ u32 both_edges;
+ spinlock_t lock;
+};
+
+int mxs_gpio_init(struct mxs_gpio_port*, int);
+
+#endif /* __MACH_MXS_GPIO_H__ */
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH 08/15] ARM: mxs: Add iomux support
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (6 preceding siblings ...)
2010-11-26 6:49 ` [PATCH 07/15] ARM: mxs: Add gpio support Shawn Guo
@ 2010-11-26 6:49 ` Shawn Guo
2010-11-30 16:32 ` Uwe Kleine-König
2010-11-26 6:49 ` [PATCH 09/15] ARM: mxs: Add clock support Shawn Guo
` (38 subsequent siblings)
46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-11-26 6:49 UTC (permalink / raw)
To: linux-arm-kernel
MXS-based SoCs implements iomux functions in block PINCTRL.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
arch/arm/mach-mxs/include/mach/iomux-mx23.h | 29 +++++++
arch/arm/mach-mxs/include/mach/iomux-mx28.h | 44 +++++++++++
arch/arm/mach-mxs/include/mach/iomux.h | 77 +++++++++++++++++++
arch/arm/mach-mxs/iomux.c | 110 +++++++++++++++++++++++++++
4 files changed, 260 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/include/mach/iomux-mx23.h
create mode 100644 arch/arm/mach-mxs/include/mach/iomux-mx28.h
create mode 100644 arch/arm/mach-mxs/include/mach/iomux.h
create mode 100644 arch/arm/mach-mxs/iomux.c
diff --git a/arch/arm/mach-mxs/include/mach/iomux-mx23.h b/arch/arm/mach-mxs/include/mach/iomux-mx23.h
new file mode 100644
index 0000000..3fc0439
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/iomux-mx23.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * 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
+ */
+
+#ifndef __MACH_IOMUX_MX23_H__
+#define __MACH_IOMUX_MX23_H__
+
+#include <mach/iomux.h>
+
+/*
+ * The naming convention for the pad modes is MX23_PAD_<padname>__<padmode>
+ * If <padname> or <padmode> refers to a GPIO, it is named GPIO_<unit>_<num>
+ * See also iomux.h
+ *
+ * BANK PIN MUX VOL MA PULL
+ */
+/* DUART */
+#define MX23_PAD_PWM0__DUART_RX IOMUX_PAD(1, 26, PAD_MUXSEL_2, PAD_VOL_NONE, PAD_4MA, PAD_NOPULL)
+#define MX23_PAD_PWM1__DUART_TX IOMUX_PAD(1, 27, PAD_MUXSEL_2, PAD_VOL_NONE, PAD_4MA, PAD_NOPULL)
+
+#endif /* __MACH_IOMUX_MX23_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/iomux-mx28.h b/arch/arm/mach-mxs/include/mach/iomux-mx28.h
new file mode 100644
index 0000000..ca37a15
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/iomux-mx28.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * 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
+ */
+
+#ifndef __MACH_IOMUX_MX28_H__
+#define __MACH_IOMUX_MX28_H__
+
+#include <mach/iomux.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.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/mach-mxs/include/mach/iomux.h b/arch/arm/mach-mxs/include/mach/iomux.h
new file mode 100644
index 0000000..27bcada
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/iomux.h
@@ -0,0 +1,77 @@
+/*
+ * 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_MXS_IOMUX_H__
+#define __MACH_MXS_IOMUX_H__
+
+typedef struct pad_desc {
+ unsigned bank:3;
+ unsigned pin:5;
+ unsigned muxsel:2;
+ unsigned ma:3;
+ unsigned vol:2;
+ unsigned pull:1;
+} iomux_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
+
+/*
+ * setups a single pad in the iomuxer
+ */
+int mxs_iomux_setup_pad(iomux_cfg_t *pad);
+
+/*
+ * setups multiple pads
+ * convenient way to call the above function with tables
+ */
+int mxs_iomux_setup_multiple_pads(iomux_cfg_t *pad_list, unsigned count);
+
+/*
+ * Initialise the iomux controller
+ */
+void mxs_iomux_init(void __iomem *iomux_base);
+
+#endif /* __MACH_MXS_IOMUX_H__*/
diff --git a/arch/arm/mach-mxs/iomux.c b/arch/arm/mach-mxs/iomux.c
new file mode 100644
index 0000000..803cadf
--- /dev/null
+++ b/arch/arm/mach-mxs/iomux.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2004-2006,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.h>
+
+static void __iomem *base;
+
+/*
+ * configures a single pad in the iomuxer
+ */
+int mxs_iomux_setup_pad(iomux_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 */
+ ofs = cpu_is_mx23() ? 0x200 : 0x300;
+ ofs += pad->bank * 0x40 + pad->pin / 8 * 0x10;
+ /* ma */
+ if (pad->ma != PAD_MA_NONE)
+ {
+ bp = pad->pin % 8 * 4;
+ bm = 0x3 << bp;
+ reg = __raw_readl(base + ofs);
+ reg &= ~bm;
+ reg |= pad->ma << bp;
+ __raw_writel(reg, base + ofs);
+ }
+ /* vol */
+ if (pad->vol != PAD_VOL_NONE)
+ {
+ bp = pad->pin % 8 * 4 + 2;
+ bm = 0x1 << bp;
+ reg = __raw_readl(base + ofs);
+ reg &= ~bm;
+ reg |= pad->vol << bp;
+ __raw_writel(reg, base + ofs);
+ }
+
+ /* pull */
+ ofs = cpu_is_mx23() ? 0x400 : 0x600;
+ ofs += 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(mxs_iomux_setup_pad);
+
+int mxs_iomux_setup_multiple_pads(iomux_cfg_t *pad_list, unsigned count)
+{
+ iomux_cfg_t *p = pad_list;
+ int i;
+ int ret;
+
+ for (i = 0; i < count; i++) {
+ ret = mxs_iomux_setup_pad(p);
+ if (ret)
+ return ret;
+ p++;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(mxs_iomux_setup_multiple_pads);
+
+void mxs_iomux_init(void __iomem *iomux_base)
+{
+ base = iomux_base;
+}
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH 09/15] ARM: mxs: Add clock support
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (7 preceding siblings ...)
2010-11-26 6:49 ` [PATCH 08/15] ARM: mxs: Add iomux support Shawn Guo
@ 2010-11-26 6:49 ` Shawn Guo
2010-11-30 16:39 ` Uwe Kleine-König
2010-12-02 15:07 ` Uwe Kleine-König
2010-11-26 6:49 ` [PATCH 10/15] ARM: mxs: Add static memory mapping Shawn Guo
` (37 subsequent siblings)
46 siblings, 2 replies; 146+ messages in thread
From: Shawn Guo @ 2010-11-26 6:49 UTC (permalink / raw)
To: linux-arm-kernel
Add clock for MXS-based SoCs, MX23 and MX28.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
arch/arm/mach-mxs/clock-mx23.c | 521 ++++++++++++++++++++++
arch/arm/mach-mxs/clock-mx28.c | 732 +++++++++++++++++++++++++++++++
arch/arm/mach-mxs/clock.c | 201 +++++++++
arch/arm/mach-mxs/include/mach/clkdev.h | 7 +
arch/arm/mach-mxs/include/mach/clock.h | 64 +++
arch/arm/mach-mxs/regs-clkctrl-mx23.h | 455 +++++++++++++++++++
arch/arm/mach-mxs/regs-clkctrl-mx28.h | 663 ++++++++++++++++++++++++++++
7 files changed, 2643 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/clock-mx23.c
create mode 100644 arch/arm/mach-mxs/clock-mx28.c
create mode 100644 arch/arm/mach-mxs/clock.c
create mode 100644 arch/arm/mach-mxs/include/mach/clkdev.h
create mode 100644 arch/arm/mach-mxs/include/mach/clock.h
create mode 100644 arch/arm/mach-mxs/regs-clkctrl-mx23.h
create mode 100644 arch/arm/mach-mxs/regs-clkctrl-mx28.h
diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c
new file mode 100644
index 0000000..832db0b
--- /dev/null
+++ b/arch/arm/mach-mxs/clock-mx23.c
@@ -0,0 +1,521 @@
+/*
+ * 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-mx23.h"
+
+#define CLKCTRL_BASE_ADDR MX23_IO_ADDRESS(MX23_CLKCTRL_BASE_ADDR)
+#define DIGCTRL_BASE_ADDR MX23_IO_ADDRESS(MX23_DIGCTL_BASE_ADDR)
+
+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 pll_clk_get_rate(struct clk *clk)
+{
+ return 480000000;
+}
+
+static int pll_clk_enable(struct clk *clk)
+{
+ __raw_writel(BM_CLKCTRL_PLLCTRL0_POWER |
+ BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS,
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLLCTRL0_SET);
+
+ /* Only a 10us delay is need. PLLCTRL1 LOCK bitfied is only a timer
+ * and is incorrect (excessive). Per definition of the PLLCTRL0
+ * POWER field, waiting at least 10us.
+ */
+ udelay(10);
+
+ return 0;
+}
+
+static void pll_clk_disable(struct clk *clk)
+{
+ __raw_writel(BM_CLKCTRL_PLLCTRL0_POWER |
+ BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS,
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLLCTRL0_CLR);
+}
+
+static struct clk pll_clk = {
+ .get_rate = pll_clk_get_rate,
+ .enable = pll_clk_enable,
+ .disable = pll_clk_disable,
+ .parent = &ref_xtal_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, FRAC, CPU)
+_CLK_GET_RATE_REF(ref_emi_clk, FRAC, EMI)
+_CLK_GET_RATE_REF(ref_pix_clk, FRAC, PIX)
+_CLK_GET_RATE_REF(ref_io_clk, FRAC, IO)
+
+#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 = &pll_clk, \
+ }
+
+_DEFINE_CLOCK_REF(ref_cpu_clk, FRAC, CPU);
+_DEFINE_CLOCK_REF(ref_emi_clk, FRAC, EMI);
+_DEFINE_CLOCK_REF(ref_pix_clk, FRAC, PIX);
+_DEFINE_CLOCK_REF(ref_io_clk, FRAC, IO);
+
+/*
+ * General clocks
+ *
+ * clk_get_rate
+ */
+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;
+}
+
+#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; \
+ \
+ return clk_get_rate(clk->parent) / div; \
+}
+
+_CLK_GET_RATE1(hbus_clk, HBUS)
+_CLK_GET_RATE1(xbus_clk, XBUS)
+_CLK_GET_RATE1(ssp_clk, SSP)
+_CLK_GET_RATE1(gpmi_clk, GPMI)
+_CLK_GET_RATE1(lcdif_clk, PIX)
+
+#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(audio_clk)
+_CLK_GET_RATE_STUB(pwm_clk)
+
+/*
+ * clk_set_rate
+ */
+static int cpu_clk_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);
+
+ if (clk->parent == &ref_xtal_clk) {
+ div_max = BM_CLKCTRL_CPU_DIV_XTAL >> BP_CLKCTRL_CPU_DIV_XTAL;
+ bm_busy = BM_CLKCTRL_CPU_BUSY_REF_XTAL;
+ div = DIV_ROUND_UP(parent_rate, rate);
+ if (div == 0 || div > div_max)
+ return -EINVAL;
+ } else {
+ div_max = BM_CLKCTRL_CPU_DIV_CPU >> BP_CLKCTRL_CPU_DIV_CPU;
+ bm_busy = BM_CLKCTRL_CPU_BUSY_REF_CPU;
+ div = frac = 1;
+ diff = parent_rate;
+ 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_FRAC);
+ reg &= ~BM_CLKCTRL_FRAC_CPUFRAC;
+ reg |= frac;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
+ }
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);
+ reg &= ~BM_CLKCTRL_CPU_DIV_CPU;
+ reg |= div << BP_CLKCTRL_CPU_DIV_CPU;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);
+
+ for (i = 10000; i; i--)
+ if (!(__raw_readl(CLKCTRL_BASE_ADDR +
+ HW_CLKCTRL_CPU) & bm_busy))
+ break;
+ if (!i) {
+ pr_err("%s: divider writing timeout\n", __func__);
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+#define _CLK_SET_RATE(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_RATE(xbus_clk, XBUS)
+_CLK_SET_RATE(ssp_clk, SSP)
+_CLK_SET_RATE(gpmi_clk, GPMI)
+_CLK_SET_RATE(lcdif_clk, PIX)
+
+#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(audio_clk)
+_CLK_SET_RATE_STUB(pwm_clk)
+_CLK_SET_RATE_STUB(clk32k_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(ssp_clk, SSP)
+_CLK_SET_PARENT(gpmi_clk, GPMI)
+_CLK_SET_PARENT(lcdif_clk, PIX)
+
+#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(uart_clk)
+_CLK_SET_PARENT_STUB(audio_clk)
+_CLK_SET_PARENT_STUB(pwm_clk)
+_CLK_SET_PARENT_STUB(clk32k_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 rtc_clk = {
+ .get_rate = rtc_clk_get_rate,
+ .parent = &ref_xtal_clk,
+};
+
+/* usb_clk gate is controlled in DIGCTRL other than CLKCTRL */
+static struct clk usb_clk = {
+ .enable_reg = DIGCTRL_BASE_ADDR,
+ .enable_shift = 2,
+ .enable = _raw_clk_enable,
+ .disable = _raw_clk_disable,
+ .parent = &pll_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(ssp_clk, SSP, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(gpmi_clk, GPMI, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(lcdif_clk, PIX, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(uart_clk, XTAL, UART_CLK_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(audio_clk, XTAL, FILT_CLK24M_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(pwm_clk, XTAL, PWM_CLK24M_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(clk32k_clk, XTAL, TIMROT_CLK32K_GATE, &ref_xtal_clk);
+
+#define _REGISTER_CLOCK(d, n, c) \
+ { \
+ .dev_id = d, \
+ .con_id = n, \
+ .clk = &c, \
+ },
+
+static struct clk_lookup lookups[] = {
+ _REGISTER_CLOCK("mxs-duart.0", NULL, uart_clk)
+ _REGISTER_CLOCK("rtc", NULL, rtc_clk)
+ _REGISTER_CLOCK(NULL, "hclk", hbus_clk)
+ _REGISTER_CLOCK(NULL, "xclk", xbus_clk)
+ _REGISTER_CLOCK(NULL, "usb", usb_clk)
+ _REGISTER_CLOCK(NULL, "audio", audio_clk)
+ _REGISTER_CLOCK(NULL, "pwm", pwm_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;
+ ssp_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP) ?
+ &ref_xtal_clk : &ref_io_clk;
+ gpmi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_GPMI) ?
+ &ref_xtal_clk : &ref_io_clk;
+ lcdif_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_PIX) ?
+ &ref_xtal_clk : &ref_pix_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_SSP);
+ reg &= ~BM_CLKCTRL_SSP_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP);
+
+ 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_PIX);
+ reg &= ~BM_CLKCTRL_PIX_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_PIX);
+
+ /*
+ * 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_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);
+
+ return 0;
+}
+
+int __init mx23_clocks_init(void)
+{
+ clk_misc_init();
+
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+ mxs_timer_init(&clk32k_clk, MX23_IO_ADDRESS(MX23_TIMROT_BASE_ADDR),
+ MX23_INT_TIMER0);
+
+ return 0;
+}
diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
new file mode 100644
index 0000000..2cb24c5
--- /dev/null
+++ b/arch/arm/mach-mxs/clock-mx28.c
@@ -0,0 +1,732 @@
+/*
+ * 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 gate 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("mxs-duart.0", NULL, uart_clk)
+ _REGISTER_CLOCK("fec.0", NULL, fec_clk)
+ _REGISTER_CLOCK("rtc", NULL, rtc_clk)
+ _REGISTER_CLOCK(NULL, "hclk", hbus_clk)
+ _REGISTER_CLOCK(NULL, "xclk", xbus_clk)
+ _REGISTER_CLOCK(NULL, "can0", can0_clk)
+ _REGISTER_CLOCK(NULL, "can1", can1_clk)
+ _REGISTER_CLOCK(NULL, "usb0", usb0_clk)
+ _REGISTER_CLOCK(NULL, "usb1", usb1_clk)
+ _REGISTER_CLOCK(NULL, "pwm", pwm_clk)
+ _REGISTER_CLOCK(NULL, "lradc", lradc_clk)
+ _REGISTER_CLOCK(NULL, "spdif", 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));
+
+ mxs_timer_init(&clk32k_clk, MX28_IO_ADDRESS(MX28_TIMROT_BASE_ADDR),
+ MX28_INT_TIMER0);
+
+ return 0;
+}
diff --git a/arch/arm/mach-mxs/clock.c b/arch/arm/mach-mxs/clock.c
new file mode 100644
index 0000000..e262759
--- /dev/null
+++ b/arch/arm/mach-mxs/clock.c
@@ -0,0 +1,201 @@
+/*
+ * Based on arch/arm/plat-omap/clock.c
+ *
+ * Copyright (C) 2004 - 2005 Nokia corporation
+ * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ * Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com>
+ * Copyright 2007 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
+ * 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.
+ */
+
+/* #define DEBUG */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/proc_fs.h>
+#include <linux/semaphore.h>
+#include <linux/string.h>
+
+#include <mach/clock.h>
+#include <mach/hardware.h>
+
+static LIST_HEAD(clocks);
+static DEFINE_MUTEX(clocks_mutex);
+
+/*-------------------------------------------------------------------------
+ * Standard clock functions defined in include/linux/clk.h
+ *-------------------------------------------------------------------------*/
+
+static void __clk_disable(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return;
+ WARN_ON(!clk->usecount);
+
+ if (!(--clk->usecount)) {
+ if (clk->disable)
+ clk->disable(clk);
+ __clk_disable(clk->parent);
+ __clk_disable(clk->secondary);
+ }
+}
+
+static int __clk_enable(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ if (clk->usecount++ == 0) {
+ __clk_enable(clk->parent);
+ __clk_enable(clk->secondary);
+
+ if (clk->enable)
+ clk->enable(clk);
+ }
+ return 0;
+}
+
+/* This function increments the reference count on the clock and enables the
+ * clock if not already enabled. The parent clock tree is recursively enabled
+ */
+int clk_enable(struct clk *clk)
+{
+ int ret = 0;
+
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ mutex_lock(&clocks_mutex);
+ ret = __clk_enable(clk);
+ mutex_unlock(&clocks_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_enable);
+
+/* This function decrements the reference count on the clock and disables
+ * the clock when reference count is 0. The parent clock tree is
+ * recursively disabled
+ */
+void clk_disable(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return;
+
+ mutex_lock(&clocks_mutex);
+ __clk_disable(clk);
+ mutex_unlock(&clocks_mutex);
+}
+EXPORT_SYMBOL(clk_disable);
+
+/* Retrieve the *current* clock rate. If the clock itself
+ * does not provide a special calculation routine, ask
+ * its parent and so on, until one is able to return
+ * a valid clock rate
+ */
+unsigned long clk_get_rate(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return 0UL;
+
+ if (clk->get_rate)
+ return clk->get_rate(clk);
+
+ return clk_get_rate(clk->parent);
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+/* Round the requested clock rate to the nearest supported
+ * rate that is less than or equal to the requested rate.
+ * This is dependent on the clock's current parent.
+ */
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ if (clk == NULL || IS_ERR(clk) || !clk->round_rate)
+ return 0;
+
+ return clk->round_rate(clk, rate);
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+/* Set the clock to the requested clock rate. The rate must
+ * match a supported rate exactly based on what clk_round_rate returns
+ */
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ int ret = -EINVAL;
+
+ if (clk == NULL || IS_ERR(clk) || clk->set_rate == NULL || rate == 0)
+ return ret;
+
+ mutex_lock(&clocks_mutex);
+ ret = clk->set_rate(clk, rate);
+ mutex_unlock(&clocks_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+/* Set the clock's parent to another clock source */
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ int ret = -EINVAL;
+ struct clk *old;
+
+ if (clk == NULL || IS_ERR(clk) || parent == NULL ||
+ IS_ERR(parent) || clk->set_parent == NULL)
+ return ret;
+
+ if (clk->usecount)
+ clk_enable(parent);
+
+ mutex_lock(&clocks_mutex);
+ ret = clk->set_parent(clk, parent);
+ if (ret == 0) {
+ old = clk->parent;
+ clk->parent = parent;
+ } else {
+ old = parent;
+ }
+ mutex_unlock(&clocks_mutex);
+
+ if (clk->usecount)
+ clk_disable(old);
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
+/* Retrieve the clock's parent clock source */
+struct clk *clk_get_parent(struct clk *clk)
+{
+ struct clk *ret = NULL;
+
+ if (clk == NULL || IS_ERR(clk))
+ return ret;
+
+ return clk->parent;
+}
+EXPORT_SYMBOL(clk_get_parent);
diff --git a/arch/arm/mach-mxs/include/mach/clkdev.h b/arch/arm/mach-mxs/include/mach/clkdev.h
new file mode 100644
index 0000000..3a8f2e3
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __MACH_MXS_CLKDEV_H__
+#define __MACH_MXS_CLKDEV_H__
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-mxs/include/mach/clock.h b/arch/arm/mach-mxs/include/mach/clock.h
new file mode 100644
index 0000000..041e276
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/clock.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2005-2007 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
+ * 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_MXS_CLOCK_H__
+#define __MACH_MXS_CLOCK_H__
+
+#ifndef __ASSEMBLY__
+#include <linux/list.h>
+
+struct module;
+
+struct clk {
+ int id;
+ /* Source clock this clk depends on */
+ struct clk *parent;
+ /* Secondary clock to enable/disable with this clock */
+ struct clk *secondary;
+ /* Reference count of clock enable/disable */
+ __s8 usecount;
+ /* Register bit position for clock's enable/disable control. */
+ u8 enable_shift;
+ /* Register address for clock's enable/disable control. */
+ void __iomem *enable_reg;
+ u32 flags;
+ /* get the current clock rate (always a fresh value) */
+ unsigned long (*get_rate) (struct clk *);
+ /* Function ptr to set the clock to a new rate. The rate must match a
+ supported rate returned from round_rate. Leave blank if clock is not
+ programmable */
+ int (*set_rate) (struct clk *, unsigned long);
+ /* Function ptr to round the requested clock rate to the nearest
+ supported rate that is less than or equal to the requested rate. */
+ unsigned long (*round_rate) (struct clk *, unsigned long);
+ /* Function ptr to enable the clock. Leave blank if clock can not
+ be gated. */
+ int (*enable) (struct clk *);
+ /* Function ptr to disable the clock. Leave blank if clock can not
+ be gated. */
+ void (*disable) (struct clk *);
+ /* Function ptr to set the parent clock of the clock. */
+ int (*set_parent) (struct clk *, struct clk *);
+};
+
+int clk_register(struct clk *clk);
+void clk_unregister(struct clk *clk);
+
+#endif /* __ASSEMBLY__ */
+#endif /* __MACH_MXS_CLOCK_H__ */
diff --git a/arch/arm/mach-mxs/regs-clkctrl-mx23.h b/arch/arm/mach-mxs/regs-clkctrl-mx23.h
new file mode 100644
index 0000000..dbc0474
--- /dev/null
+++ b/arch/arm/mach-mxs/regs-clkctrl-mx23.h
@@ -0,0 +1,455 @@
+/*
+ * Freescale CLKCTRL Register Definitions
+ *
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ * Copyright 2008-2010 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 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 __REGS_CLKCTRL_MX23_H__
+#define __REGS_CLKCTRL_MX23_H__
+
+
+#define HW_CLKCTRL_PLLCTRL0 (0x00000000)
+#define HW_CLKCTRL_PLLCTRL0_SET (0x00000004)
+#define HW_CLKCTRL_PLLCTRL0_CLR (0x00000008)
+#define HW_CLKCTRL_PLLCTRL0_TOG (0x0000000c)
+
+#define BP_CLKCTRL_PLLCTRL0_RSRVD6 30
+#define BM_CLKCTRL_PLLCTRL0_RSRVD6 0xC0000000
+#define BF_CLKCTRL_PLLCTRL0_RSRVD6(v) \
+ (((v) << 30) & BM_CLKCTRL_PLLCTRL0_RSRVD6)
+#define BP_CLKCTRL_PLLCTRL0_LFR_SEL 28
+#define BM_CLKCTRL_PLLCTRL0_LFR_SEL 0x30000000
+#define BF_CLKCTRL_PLLCTRL0_LFR_SEL(v) \
+ (((v) << 28) & BM_CLKCTRL_PLLCTRL0_LFR_SEL)
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__TIMES_2 0x1
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__TIMES_05 0x2
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLLCTRL0_RSRVD5 26
+#define BM_CLKCTRL_PLLCTRL0_RSRVD5 0x0C000000
+#define BF_CLKCTRL_PLLCTRL0_RSRVD5(v) \
+ (((v) << 26) & BM_CLKCTRL_PLLCTRL0_RSRVD5)
+#define BP_CLKCTRL_PLLCTRL0_CP_SEL 24
+#define BM_CLKCTRL_PLLCTRL0_CP_SEL 0x03000000
+#define BF_CLKCTRL_PLLCTRL0_CP_SEL(v) \
+ (((v) << 24) & BM_CLKCTRL_PLLCTRL0_CP_SEL)
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__TIMES_2 0x1
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__TIMES_05 0x2
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLLCTRL0_RSRVD4 22
+#define BM_CLKCTRL_PLLCTRL0_RSRVD4 0x00C00000
+#define BF_CLKCTRL_PLLCTRL0_RSRVD4(v) \
+ (((v) << 22) & BM_CLKCTRL_PLLCTRL0_RSRVD4)
+#define BP_CLKCTRL_PLLCTRL0_DIV_SEL 20
+#define BM_CLKCTRL_PLLCTRL0_DIV_SEL 0x00300000
+#define BF_CLKCTRL_PLLCTRL0_DIV_SEL(v) \
+ (((v) << 20) & BM_CLKCTRL_PLLCTRL0_DIV_SEL)
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__LOWER 0x1
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__LOWEST 0x2
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__UNDEFINED 0x3
+#define BM_CLKCTRL_PLLCTRL0_RSRVD3 0x00080000
+#define BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS 0x00040000
+#define BM_CLKCTRL_PLLCTRL0_RSRVD2 0x00020000
+#define BM_CLKCTRL_PLLCTRL0_POWER 0x00010000
+#define BP_CLKCTRL_PLLCTRL0_RSRVD1 0
+#define BM_CLKCTRL_PLLCTRL0_RSRVD1 0x0000FFFF
+#define BF_CLKCTRL_PLLCTRL0_RSRVD1(v) \
+ (((v) << 0) & BM_CLKCTRL_PLLCTRL0_RSRVD1)
+
+#define HW_CLKCTRL_PLLCTRL1 (0x00000010)
+
+#define BM_CLKCTRL_PLLCTRL1_LOCK 0x80000000
+#define BM_CLKCTRL_PLLCTRL1_FORCE_LOCK 0x40000000
+#define BP_CLKCTRL_PLLCTRL1_RSRVD1 16
+#define BM_CLKCTRL_PLLCTRL1_RSRVD1 0x3FFF0000
+#define BF_CLKCTRL_PLLCTRL1_RSRVD1(v) \
+ (((v) << 16) & BM_CLKCTRL_PLLCTRL1_RSRVD1)
+#define BP_CLKCTRL_PLLCTRL1_LOCK_COUNT 0
+#define BM_CLKCTRL_PLLCTRL1_LOCK_COUNT 0x0000FFFF
+#define BF_CLKCTRL_PLLCTRL1_LOCK_COUNT(v) \
+ (((v) << 0) & BM_CLKCTRL_PLLCTRL1_LOCK_COUNT)
+
+#define HW_CLKCTRL_CPU (0x00000020)
+#define HW_CLKCTRL_CPU_SET (0x00000024)
+#define HW_CLKCTRL_CPU_CLR (0x00000028)
+#define HW_CLKCTRL_CPU_TOG (0x0000002c)
+
+#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 (0x00000030)
+#define HW_CLKCTRL_HBUS_SET (0x00000034)
+#define HW_CLKCTRL_HBUS_CLR (0x00000038)
+#define HW_CLKCTRL_HBUS_TOG (0x0000003c)
+
+#define BP_CLKCTRL_HBUS_RSRVD4 30
+#define BM_CLKCTRL_HBUS_RSRVD4 0xC0000000
+#define BF_CLKCTRL_HBUS_RSRVD4(v) \
+ (((v) << 30) & BM_CLKCTRL_HBUS_RSRVD4)
+#define BM_CLKCTRL_HBUS_BUSY 0x20000000
+#define BM_CLKCTRL_HBUS_DCP_AS_ENABLE 0x10000000
+#define BM_CLKCTRL_HBUS_PXP_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_AUTO_SLOW_MODE 0x00100000
+#define BM_CLKCTRL_HBUS_RSRVD2 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 (0x00000040)
+
+#define BM_CLKCTRL_XBUS_BUSY 0x80000000
+#define BP_CLKCTRL_XBUS_RSRVD1 11
+#define BM_CLKCTRL_XBUS_RSRVD1 0x7FFFF800
+#define BF_CLKCTRL_XBUS_RSRVD1(v) \
+ (((v) << 11) & BM_CLKCTRL_XBUS_RSRVD1)
+#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 (0x00000050)
+#define HW_CLKCTRL_XTAL_SET (0x00000054)
+#define HW_CLKCTRL_XTAL_CLR (0x00000058)
+#define HW_CLKCTRL_XTAL_TOG (0x0000005c)
+
+#define BP_CLKCTRL_XTAL_UART_CLK_GATE 31
+#define BM_CLKCTRL_XTAL_UART_CLK_GATE 0x80000000
+#define BP_CLKCTRL_XTAL_FILT_CLK24M_GATE 30
+#define BM_CLKCTRL_XTAL_FILT_CLK24M_GATE 0x40000000
+#define BP_CLKCTRL_XTAL_PWM_CLK24M_GATE 29
+#define BM_CLKCTRL_XTAL_PWM_CLK24M_GATE 0x20000000
+#define BM_CLKCTRL_XTAL_DRI_CLK24M_GATE 0x10000000
+#define BM_CLKCTRL_XTAL_DIGCTRL_CLK1M_GATE 0x08000000
+#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_PIX (0x00000060)
+
+#define BP_CLKCTRL_PIX_CLKGATE 31
+#define BM_CLKCTRL_PIX_CLKGATE 0x80000000
+#define BM_CLKCTRL_PIX_RSRVD2 0x40000000
+#define BM_CLKCTRL_PIX_BUSY 0x20000000
+#define BP_CLKCTRL_PIX_RSRVD1 13
+#define BM_CLKCTRL_PIX_RSRVD1 0x1FFFE000
+#define BF_CLKCTRL_PIX_RSRVD1(v) \
+ (((v) << 13) & BM_CLKCTRL_PIX_RSRVD1)
+#define BM_CLKCTRL_PIX_DIV_FRAC_EN 0x00001000
+#define BP_CLKCTRL_PIX_DIV 0
+#define BM_CLKCTRL_PIX_DIV 0x00000FFF
+#define BF_CLKCTRL_PIX_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_PIX_DIV)
+
+#define HW_CLKCTRL_SSP (0x00000070)
+
+#define BP_CLKCTRL_SSP_CLKGATE 31
+#define BM_CLKCTRL_SSP_CLKGATE 0x80000000
+#define BM_CLKCTRL_SSP_RSRVD2 0x40000000
+#define BM_CLKCTRL_SSP_BUSY 0x20000000
+#define BP_CLKCTRL_SSP_RSRVD1 10
+#define BM_CLKCTRL_SSP_RSRVD1 0x1FFFFC00
+#define BF_CLKCTRL_SSP_RSRVD1(v) \
+ (((v) << 10) & BM_CLKCTRL_SSP_RSRVD1)
+#define BM_CLKCTRL_SSP_DIV_FRAC_EN 0x00000200
+#define BP_CLKCTRL_SSP_DIV 0
+#define BM_CLKCTRL_SSP_DIV 0x000001FF
+#define BF_CLKCTRL_SSP_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_SSP_DIV)
+
+#define HW_CLKCTRL_GPMI (0x00000080)
+
+#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 (0x00000090)
+
+#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 (0x000000a0)
+
+#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_IR (0x000000b0)
+
+#define BM_CLKCTRL_IR_CLKGATE 0x80000000
+#define BM_CLKCTRL_IR_RSRVD3 0x40000000
+#define BM_CLKCTRL_IR_AUTO_DIV 0x20000000
+#define BM_CLKCTRL_IR_IR_BUSY 0x10000000
+#define BM_CLKCTRL_IR_IROV_BUSY 0x08000000
+#define BP_CLKCTRL_IR_RSRVD2 25
+#define BM_CLKCTRL_IR_RSRVD2 0x06000000
+#define BF_CLKCTRL_IR_RSRVD2(v) \
+ (((v) << 25) & BM_CLKCTRL_IR_RSRVD2)
+#define BP_CLKCTRL_IR_IROV_DIV 16
+#define BM_CLKCTRL_IR_IROV_DIV 0x01FF0000
+#define BF_CLKCTRL_IR_IROV_DIV(v) \
+ (((v) << 16) & BM_CLKCTRL_IR_IROV_DIV)
+#define BP_CLKCTRL_IR_RSRVD1 10
+#define BM_CLKCTRL_IR_RSRVD1 0x0000FC00
+#define BF_CLKCTRL_IR_RSRVD1(v) \
+ (((v) << 10) & BM_CLKCTRL_IR_RSRVD1)
+#define BP_CLKCTRL_IR_IR_DIV 0
+#define BM_CLKCTRL_IR_IR_DIV 0x000003FF
+#define BF_CLKCTRL_IR_IR_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_IR_IR_DIV)
+
+#define HW_CLKCTRL_SAIF (0x000000c0)
+
+#define BM_CLKCTRL_SAIF_CLKGATE 0x80000000
+#define BM_CLKCTRL_SAIF_RSRVD2 0x40000000
+#define BM_CLKCTRL_SAIF_BUSY 0x20000000
+#define BP_CLKCTRL_SAIF_RSRVD1 17
+#define BM_CLKCTRL_SAIF_RSRVD1 0x1FFE0000
+#define BF_CLKCTRL_SAIF_RSRVD1(v) \
+ (((v) << 17) & BM_CLKCTRL_SAIF_RSRVD1)
+#define BM_CLKCTRL_SAIF_DIV_FRAC_EN 0x00010000
+#define BP_CLKCTRL_SAIF_DIV 0
+#define BM_CLKCTRL_SAIF_DIV 0x0000FFFF
+#define BF_CLKCTRL_SAIF_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_SAIF_DIV)
+
+#define HW_CLKCTRL_TV (0x000000d0)
+
+#define BM_CLKCTRL_TV_CLK_TV108M_GATE 0x80000000
+#define BM_CLKCTRL_TV_CLK_TV_GATE 0x40000000
+#define BP_CLKCTRL_TV_RSRVD 0
+#define BM_CLKCTRL_TV_RSRVD 0x3FFFFFFF
+#define BF_CLKCTRL_TV_RSRVD(v) \
+ (((v) << 0) & BM_CLKCTRL_TV_RSRVD)
+
+#define HW_CLKCTRL_ETM (0x000000e0)
+
+#define BM_CLKCTRL_ETM_CLKGATE 0x80000000
+#define BM_CLKCTRL_ETM_RSRVD2 0x40000000
+#define BM_CLKCTRL_ETM_BUSY 0x20000000
+#define BP_CLKCTRL_ETM_RSRVD1 7
+#define BM_CLKCTRL_ETM_RSRVD1 0x1FFFFF80
+#define BF_CLKCTRL_ETM_RSRVD1(v) \
+ (((v) << 7) & BM_CLKCTRL_ETM_RSRVD1)
+#define BM_CLKCTRL_ETM_DIV_FRAC_EN 0x00000040
+#define BP_CLKCTRL_ETM_DIV 0
+#define BM_CLKCTRL_ETM_DIV 0x0000003F
+#define BF_CLKCTRL_ETM_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_ETM_DIV)
+
+#define HW_CLKCTRL_FRAC (0x000000f0)
+#define HW_CLKCTRL_FRAC_SET (0x000000f4)
+#define HW_CLKCTRL_FRAC_CLR (0x000000f8)
+#define HW_CLKCTRL_FRAC_TOG (0x000000fc)
+
+#define BP_CLKCTRL_FRAC_CLKGATEIO 31
+#define BM_CLKCTRL_FRAC_CLKGATEIO 0x80000000
+#define BM_CLKCTRL_FRAC_IO_STABLE 0x40000000
+#define BP_CLKCTRL_FRAC_IOFRAC 24
+#define BM_CLKCTRL_FRAC_IOFRAC 0x3F000000
+#define BF_CLKCTRL_FRAC_IOFRAC(v) \
+ (((v) << 24) & BM_CLKCTRL_FRAC_IOFRAC)
+#define BP_CLKCTRL_FRAC_CLKGATEPIX 23
+#define BM_CLKCTRL_FRAC_CLKGATEPIX 0x00800000
+#define BM_CLKCTRL_FRAC_PIX_STABLE 0x00400000
+#define BP_CLKCTRL_FRAC_PIXFRAC 16
+#define BM_CLKCTRL_FRAC_PIXFRAC 0x003F0000
+#define BF_CLKCTRL_FRAC_PIXFRAC(v) \
+ (((v) << 16) & BM_CLKCTRL_FRAC_PIXFRAC)
+#define BP_CLKCTRL_FRAC_CLKGATEEMI 15
+#define BM_CLKCTRL_FRAC_CLKGATEEMI 0x00008000
+#define BM_CLKCTRL_FRAC_EMI_STABLE 0x00004000
+#define BP_CLKCTRL_FRAC_EMIFRAC 8
+#define BM_CLKCTRL_FRAC_EMIFRAC 0x00003F00
+#define BF_CLKCTRL_FRAC_EMIFRAC(v) \
+ (((v) << 8) & BM_CLKCTRL_FRAC_EMIFRAC)
+#define BP_CLKCTRL_FRAC_CLKGATECPU 7
+#define BM_CLKCTRL_FRAC_CLKGATECPU 0x00000080
+#define BM_CLKCTRL_FRAC_CPU_STABLE 0x00000040
+#define BP_CLKCTRL_FRAC_CPUFRAC 0
+#define BM_CLKCTRL_FRAC_CPUFRAC 0x0000003F
+#define BF_CLKCTRL_FRAC_CPUFRAC(v) \
+ (((v) << 0) & BM_CLKCTRL_FRAC_CPUFRAC)
+
+#define HW_CLKCTRL_FRAC1 (0x00000100)
+#define HW_CLKCTRL_FRAC1_SET (0x00000104)
+#define HW_CLKCTRL_FRAC1_CLR (0x00000108)
+#define HW_CLKCTRL_FRAC1_TOG (0x0000010c)
+
+#define BM_CLKCTRL_FRAC1_CLKGATEVID 0x80000000
+#define BM_CLKCTRL_FRAC1_VID_STABLE 0x40000000
+#define BP_CLKCTRL_FRAC1_RSRVD1 0
+#define BM_CLKCTRL_FRAC1_RSRVD1 0x3FFFFFFF
+#define BF_CLKCTRL_FRAC1_RSRVD1(v) \
+ (((v) << 0) & BM_CLKCTRL_FRAC1_RSRVD1)
+
+#define HW_CLKCTRL_CLKSEQ (0x00000110)
+#define HW_CLKCTRL_CLKSEQ_SET (0x00000114)
+#define HW_CLKCTRL_CLKSEQ_CLR (0x00000118)
+#define HW_CLKCTRL_CLKSEQ_TOG (0x0000011c)
+
+#define BP_CLKCTRL_CLKSEQ_RSRVD1 9
+#define BM_CLKCTRL_CLKSEQ_RSRVD1 0xFFFFFE00
+#define BF_CLKCTRL_CLKSEQ_RSRVD1(v) \
+ (((v) << 9) & BM_CLKCTRL_CLKSEQ_RSRVD1)
+#define BM_CLKCTRL_CLKSEQ_BYPASS_ETM 0x00000100
+#define BM_CLKCTRL_CLKSEQ_BYPASS_CPU 0x00000080
+#define BM_CLKCTRL_CLKSEQ_BYPASS_EMI 0x00000040
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP 0x00000020
+#define BM_CLKCTRL_CLKSEQ_BYPASS_GPMI 0x00000010
+#define BM_CLKCTRL_CLKSEQ_BYPASS_IR 0x00000008
+#define BM_CLKCTRL_CLKSEQ_RSRVD0 0x00000004
+#define BM_CLKCTRL_CLKSEQ_BYPASS_PIX 0x00000002
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF 0x00000001
+
+#define HW_CLKCTRL_RESET (0x00000120)
+
+#define BP_CLKCTRL_RESET_RSRVD 2
+#define BM_CLKCTRL_RESET_RSRVD 0xFFFFFFFC
+#define BF_CLKCTRL_RESET_RSRVD(v) \
+ (((v) << 2) & BM_CLKCTRL_RESET_RSRVD)
+#define BM_CLKCTRL_RESET_CHIP 0x00000002
+#define BM_CLKCTRL_RESET_DIG 0x00000001
+
+#define HW_CLKCTRL_STATUS (0x00000130)
+
+#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 (0x00000140)
+
+#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 /* __REGS_CLKCTRL_MX23_H__ */
diff --git a/arch/arm/mach-mxs/regs-clkctrl-mx28.h b/arch/arm/mach-mxs/regs-clkctrl-mx28.h
new file mode 100644
index 0000000..661df18
--- /dev/null
+++ b/arch/arm/mach-mxs/regs-clkctrl-mx28.h
@@ -0,0 +1,663 @@
+/*
+ * Freescale CLKCTRL Register Definitions
+ *
+ * Copyright 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., 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 __REGS_CLKCTRL_MX28_H__
+#define __REGS_CLKCTRL_MX28_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 /* __REGS_CLKCTRL_MX28_H__ */
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH 10/15] ARM: mxs: Add static memory mapping
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (8 preceding siblings ...)
2010-11-26 6:49 ` [PATCH 09/15] ARM: mxs: Add clock support Shawn Guo
@ 2010-11-26 6:49 ` Shawn Guo
2010-11-26 6:49 ` [PATCH 11/15] ARM: mxs: Dynamically allocate duart devices Shawn Guo
` (36 subsequent siblings)
46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-11-26 6:49 UTC (permalink / raw)
To: linux-arm-kernel
Create static memory mapping for MX23 and MX28.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
arch/arm/mach-mxs/mm-mx23.c | 48 +++++++++++++++++++++++++++++++++++++++++++
arch/arm/mach-mxs/mm-mx28.c | 48 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 96 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/mm-mx23.c
create mode 100644 arch/arm/mach-mxs/mm-mx28.c
diff --git a/arch/arm/mach-mxs/mm-mx23.c b/arch/arm/mach-mxs/mm-mx23.c
new file mode 100644
index 0000000..da6776c
--- /dev/null
+++ b/arch/arm/mach-mxs/mm-mx23.c
@@ -0,0 +1,48 @@
+/*
+ * 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.h>
+
+/*
+ * Define the MX23 memory map.
+ */
+static struct map_desc mx23_io_desc[] __initdata = {
+ mxs_map_entry(MX23, OCRAM, MT_DEVICE),
+ mxs_map_entry(MX23, 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 mx23_map_io(void)
+{
+ mxs_set_cpu_type(MXS_CPU_MX23);
+ mxs_iomux_init(MX23_IO_ADDRESS(MX23_PINCTRL_BASE_ADDR));
+ mxs_arch_reset_init(MX23_IO_ADDRESS(MX23_RTC_BASE_ADDR));
+ iotable_init(mx23_io_desc, ARRAY_SIZE(mx23_io_desc));
+}
+
+void __init mx23_init_irq(void)
+{
+ icoll_init_irq(MX23_IO_ADDRESS(MX23_ICOLL_BASE_ADDR));
+ mx23_register_gpios();
+}
diff --git a/arch/arm/mach-mxs/mm-mx28.c b/arch/arm/mach-mxs/mm-mx28.c
new file mode 100644
index 0000000..c0531e7
--- /dev/null
+++ b/arch/arm/mach-mxs/mm-mx28.c
@@ -0,0 +1,48 @@
+/*
+ * 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.h>
+
+/*
+ * Define the MX28 memory map.
+ */
+static struct map_desc mx28_io_desc[] __initdata = {
+ mxs_map_entry(MX28, OCRAM, MT_DEVICE),
+ mxs_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)
+{
+ mxs_set_cpu_type(MXS_CPU_MX28);
+ mxs_iomux_init(MX28_IO_ADDRESS(MX28_PINCTRL_BASE_ADDR));
+ mxs_arch_reset_init(MX28_IO_ADDRESS(MX28_RTC_BASE_ADDR));
+ iotable_init(mx28_io_desc, ARRAY_SIZE(mx28_io_desc));
+}
+
+void __init mx28_init_irq(void)
+{
+ icoll_init_irq(MX28_IO_ADDRESS(MX28_ICOLL_BASE_ADDR));
+ mx28_register_gpios();
+}
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH 11/15] ARM: mxs: Dynamically allocate duart devices
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (9 preceding siblings ...)
2010-11-26 6:49 ` [PATCH 10/15] ARM: mxs: Add static memory mapping Shawn Guo
@ 2010-11-26 6:49 ` Shawn Guo
2010-11-26 6:49 ` [PATCH 12/15] ARM: mxs: Dynamically allocate fec devices Shawn Guo
` (35 subsequent siblings)
46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-11-26 6:49 UTC (permalink / raw)
To: linux-arm-kernel
Dynamically allocate duart devices for MX23 and MX28.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
arch/arm/mach-mxs/devices-mx23.h | 16 +++++
arch/arm/mach-mxs/devices-mx28.h | 16 +++++
arch/arm/mach-mxs/devices.c | 75 +++++++++++++++++++++++
arch/arm/mach-mxs/devices/platform-duart.c | 47 ++++++++++++++
arch/arm/mach-mxs/include/mach/devices-common.h | 34 ++++++++++
5 files changed, 188 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/devices-mx23.h
create mode 100644 arch/arm/mach-mxs/devices-mx28.h
create mode 100644 arch/arm/mach-mxs/devices.c
create mode 100644 arch/arm/mach-mxs/devices/platform-duart.c
create mode 100644 arch/arm/mach-mxs/include/mach/devices-common.h
diff --git a/arch/arm/mach-mxs/devices-mx23.h b/arch/arm/mach-mxs/devices-mx23.h
new file mode 100644
index 0000000..d0f49fc
--- /dev/null
+++ b/arch/arm/mach-mxs/devices-mx23.h
@@ -0,0 +1,16 @@
+/*
+ * 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/mx23.h>
+#include <mach/devices-common.h>
+
+extern const struct mxs_duart_data mx23_duart_data __initconst;
+#define mx23_add_duart() \
+ mxs_add_duart(&mx23_duart_data)
diff --git a/arch/arm/mach-mxs/devices-mx28.h b/arch/arm/mach-mxs/devices-mx28.h
new file mode 100644
index 0000000..47c2f04
--- /dev/null
+++ b/arch/arm/mach-mxs/devices-mx28.h
@@ -0,0 +1,16 @@
+/*
+ * 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 mxs_duart_data mx28_duart_data __initconst;
+#define mx28_add_duart() \
+ mxs_add_duart(&mx28_duart_data)
diff --git a/arch/arm/mach-mxs/devices.c b/arch/arm/mach-mxs/devices.c
new file mode 100644
index 0000000..6b60f02
--- /dev/null
+++ b/arch/arm/mach-mxs/devices.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2008 Sascha Hauer, kernel at pengutronix.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/kernel.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <mach/common.h>
+
+struct platform_device *__init mxs_add_platform_device_dmamask(
+ const char *name, int id,
+ const struct resource *res, unsigned int num_resources,
+ const void *data, size_t size_data, u64 dmamask)
+{
+ int ret = -ENOMEM;
+ struct platform_device *pdev;
+
+ pdev = platform_device_alloc(name, id);
+ if (!pdev)
+ goto err;
+
+ if (dmamask) {
+ /*
+ * This memory isn't freed when the device is put,
+ * I don't have a nice idea for that though. Conceptually
+ * dma_mask in struct device should not be a pointer.
+ * See http://thread.gmane.org/gmane.linux.kernel.pci/9081
+ */
+ pdev->dev.dma_mask =
+ kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
+ if (!pdev->dev.dma_mask)
+ /* ret is still -ENOMEM; */
+ goto err;
+
+ *pdev->dev.dma_mask = dmamask;
+ pdev->dev.coherent_dma_mask = dmamask;
+ }
+
+ if (res) {
+ ret = platform_device_add_resources(pdev, res, num_resources);
+ if (ret)
+ goto err;
+ }
+
+ if (data) {
+ ret = platform_device_add_data(pdev, data, size_data);
+ if (ret)
+ goto err;
+ }
+
+ ret = platform_device_add(pdev);
+ if (ret) {
+err:
+ platform_device_put(pdev);
+ return ERR_PTR(ret);
+ }
+
+ return pdev;
+}
diff --git a/arch/arm/mach-mxs/devices/platform-duart.c b/arch/arm/mach-mxs/devices/platform-duart.c
new file mode 100644
index 0000000..7760caf
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/platform-duart.c
@@ -0,0 +1,47 @@
+/*
+ * 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 mxs_duart_data_entry(soc) \
+ { \
+ .iobase = soc ## _DUART_BASE_ADDR, \
+ .irq = soc ## _INT_DUART, \
+ }
+
+#ifdef CONFIG_SOC_IMX23
+const struct mxs_duart_data mx23_duart_data __initconst =
+ mxs_duart_data_entry(MX23);
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+const struct mxs_duart_data mx28_duart_data __initconst =
+ mxs_duart_data_entry(MX28);
+#endif
+
+struct platform_device *__init mxs_add_duart(
+ const struct mxs_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 mxs_add_platform_device("mxs-duart", 0, res, ARRAY_SIZE(res),
+ NULL, 0);
+}
diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h
new file mode 100644
index 0000000..07b4439
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/devices-common.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2009-2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * 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 <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+
+struct platform_device *mxs_add_platform_device_dmamask(
+ const char *name, int id,
+ const struct resource *res, unsigned int num_resources,
+ const void *data, size_t size_data, u64 dmamask);
+
+static inline struct platform_device *mxs_add_platform_device(
+ const char *name, int id,
+ const struct resource *res, unsigned int num_resources,
+ const void *data, size_t size_data)
+{
+ return mxs_add_platform_device_dmamask(
+ name, id, res, num_resources, data, size_data, 0);
+}
+
+/* duart */
+struct mxs_duart_data {
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init mxs_add_duart(
+ const struct mxs_duart_data *data);
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH 12/15] ARM: mxs: Dynamically allocate fec devices
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (10 preceding siblings ...)
2010-11-26 6:49 ` [PATCH 11/15] ARM: mxs: Dynamically allocate duart devices Shawn Guo
@ 2010-11-26 6:49 ` Shawn Guo
2010-11-30 20:01 ` Uwe Kleine-König
2010-11-26 6:49 ` [PATCH 13/15] ARM: mxs: Add initial mx23evk support Shawn Guo
` (34 subsequent siblings)
46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-11-26 6:49 UTC (permalink / raw)
To: linux-arm-kernel
Dynamically allocate fec devices for MX28, which gets dual
fec interface.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
arch/arm/mach-mxs/devices-mx28.h | 6 +++
arch/arm/mach-mxs/devices/platform-fec.c | 51 +++++++++++++++++++++++
arch/arm/mach-mxs/include/mach/devices-common.h | 12 +++++
3 files changed, 69 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/devices/platform-fec.c
diff --git a/arch/arm/mach-mxs/devices-mx28.h b/arch/arm/mach-mxs/devices-mx28.h
index 47c2f04..c509e5d 100644
--- a/arch/arm/mach-mxs/devices-mx28.h
+++ b/arch/arm/mach-mxs/devices-mx28.h
@@ -14,3 +14,9 @@
extern const struct mxs_duart_data mx28_duart_data __initconst;
#define mx28_add_duart() \
mxs_add_duart(&mx28_duart_data)
+
+extern const struct mxs_fec_data mx28_fec_data[] __initconst;
+#define mx28_add_fec(id, pdata) \
+ mxs_add_fec(&mx28_fec_data[id], pdata)
+#define mx28_add_fec0(pdata) mx28_add_fec(0, pdata)
+#define mx28_add_fec1(pdata) mx28_add_fec(1, pdata)
diff --git a/arch/arm/mach-mxs/devices/platform-fec.c b/arch/arm/mach-mxs/devices/platform-fec.c
new file mode 100644
index 0000000..a2389b2
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/platform-fec.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * 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 <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define mxs_fec_data_entry_single(soc, _id, _size) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _ENET_MAC ## _id ## _BASE_ADDR, \
+ .iosize = _size, \
+ .irq = soc ## _INT_ENET_MAC ## _id, \
+ }
+
+#define mxs_fec_data_entry(soc, _id, _size) \
+ [_id] = mxs_fec_data_entry_single(soc, _id, _size)
+
+#ifdef CONFIG_SOC_IMX28
+const struct mxs_fec_data mx28_fec_data[] __initconst = {
+#define mx28_fec_data_entry(_id) \
+ mxs_fec_data_entry(MX28, _id, SZ_16K)
+ mx28_fec_data_entry(0),
+ mx28_fec_data_entry(1),
+};
+#endif
+
+struct platform_device *__init mxs_add_fec(
+ const struct mxs_fec_data *data,
+ const struct fec_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + data->iosize - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return mxs_add_platform_device("fec", data->id,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h
index 07b4439..3da48d4 100644
--- a/arch/arm/mach-mxs/include/mach/devices-common.h
+++ b/arch/arm/mach-mxs/include/mach/devices-common.h
@@ -32,3 +32,15 @@ struct mxs_duart_data {
};
struct platform_device *__init mxs_add_duart(
const struct mxs_duart_data *data);
+
+/* fec */
+#include <linux/fec.h>
+struct mxs_fec_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init mxs_add_fec(
+ const struct mxs_fec_data *data,
+ const struct fec_platform_data *pdata);
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH 13/15] ARM: mxs: Add initial mx23evk support
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (11 preceding siblings ...)
2010-11-26 6:49 ` [PATCH 12/15] ARM: mxs: Dynamically allocate fec devices Shawn Guo
@ 2010-11-26 6:49 ` Shawn Guo
2010-11-30 20:02 ` Uwe Kleine-König
2010-11-26 6:49 ` [PATCH 14/15] ARM: mxs: Add initial mx28evk support Shawn Guo
` (33 subsequent siblings)
46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-11-26 6:49 UTC (permalink / raw)
To: linux-arm-kernel
Add initial mx23evk support with duart.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
arch/arm/mach-mxs/mach-mx23evk.c | 59 ++++++++++++++++++++++++++++++++++++++
1 files changed, 59 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/mach-mx23evk.c
diff --git a/arch/arm/mach-mxs/mach-mx23evk.c b/arch/arm/mach-mxs/mach-mx23evk.c
new file mode 100644
index 0000000..9048035
--- /dev/null
+++ b/arch/arm/mach-mxs/mach-mx23evk.c
@@ -0,0 +1,59 @@
+/*
+ * 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-mx23.h>
+
+#include "devices-mx23.h"
+
+static iomux_cfg_t mx23evk_pads[] = {
+ /* duart */
+ MX23_PAD_PWM0__DUART_RX,
+ MX23_PAD_PWM1__DUART_TX,
+};
+
+static void __init mx23evk_init(void)
+{
+ mxs_iomux_setup_multiple_pads(mx23evk_pads, ARRAY_SIZE(mx23evk_pads));
+
+ mx23_add_duart();
+}
+
+static void __init mx23evk_timer_init(void)
+{
+ mx23_clocks_init();
+}
+
+static struct sys_timer mx23evk_timer = {
+ .init = mx23evk_timer_init,
+};
+
+MACHINE_START(MX23EVK, "Freescale MX23 EVK")
+ /* Maintainer: Freescale Semiconductor, Inc. */
+ .boot_params = PHYS_OFFSET + 0x100,
+ .map_io = mx23_map_io,
+ .init_irq = mx23_init_irq,
+ .init_machine = mx23evk_init,
+ .timer = &mx23evk_timer,
+MACHINE_END
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH 14/15] ARM: mxs: Add initial mx28evk support
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (12 preceding siblings ...)
2010-11-26 6:49 ` [PATCH 13/15] ARM: mxs: Add initial mx23evk support Shawn Guo
@ 2010-11-26 6:49 ` Shawn Guo
2010-11-30 20:06 ` Uwe Kleine-König
2010-11-26 6:49 ` [PATCH 15/15] ARM: mxs: Add build configuration for mxs Shawn Guo
` (32 subsequent siblings)
46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-11-26 6:49 UTC (permalink / raw)
To: linux-arm-kernel
Add initial mx28evk support with duart and fec0.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
arch/arm/mach-mxs/mach-mx28evk.c | 108 ++++++++++++++++++++++++++++++++++++++
1 files changed, 108 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/mach-mx28evk.c
diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
new file mode 100644
index 0000000..901e6b1
--- /dev/null
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
@@ -0,0 +1,108 @@
+/*
+ * 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-mx28.h"
+
+#define MX28EVK_FEC_PHY_POWER MXS_GPIO_NR(2, 15)
+#define MX28EVK_FEC_PHY_RESET MXS_GPIO_NR(4, 13)
+
+static iomux_cfg_t mx28evk_pads[] = {
+ /* duart */
+ MX28_PAD_PWM0__DUART_RX,
+ MX28_PAD_PWM1__DUART_TX,
+
+ /* fec0 */
+ 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 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 const struct fec_platform_data mx28_fec_pdata __initconst = {
+ .phy = PHY_INTERFACE_MODE_RMII,
+};
+
+static void __init mx28evk_init(void)
+{
+ mxs_iomux_setup_multiple_pads(mx28evk_pads, ARRAY_SIZE(mx28evk_pads));
+
+ mx28_add_duart();
+
+ mx28evk_fec_reset();
+ mx28_add_fec0(&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 = PHYS_OFFSET + 0x100,
+ .map_io = mx28_map_io,
+ .init_irq = mx28_init_irq,
+ .init_machine = mx28evk_init,
+ .timer = &mx28evk_timer,
+MACHINE_END
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH 15/15] ARM: mxs: Add build configuration for mxs
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (13 preceding siblings ...)
2010-11-26 6:49 ` [PATCH 14/15] ARM: mxs: Add initial mx28evk support Shawn Guo
@ 2010-11-26 6:49 ` Shawn Guo
2010-11-30 20:08 ` Uwe Kleine-König
2010-11-29 11:59 ` [PATCH v2 01/15] ARM: mxs: Add core definitions Shawn Guo
` (31 subsequent siblings)
46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-11-26 6:49 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
arch/arm/Kconfig | 10 ++++++++++
arch/arm/Makefile | 1 +
arch/arm/mach-mxs/Kconfig | 34 ++++++++++++++++++++++++++++++++++
arch/arm/mach-mxs/Makefile | 14 ++++++++++++++
arch/arm/mach-mxs/Makefile.boot | 3 +++
arch/arm/mach-mxs/devices/Kconfig | 5 +++++
arch/arm/mach-mxs/devices/Makefile | 2 ++
7 files changed, 69 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/Kconfig
create mode 100644 arch/arm/mach-mxs/Makefile
create mode 100644 arch/arm/mach-mxs/Makefile.boot
create mode 100644 arch/arm/mach-mxs/devices/Kconfig
create mode 100644 arch/arm/mach-mxs/devices/Makefile
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index db524e7..b0a5130 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -351,6 +351,14 @@ config ARCH_MXC
help
Support for Freescale MXC/iMX-based family of processors
+config ARCH_MXS
+ bool "Freescale MXS-based"
+ select GENERIC_CLOCKEVENTS
+ select ARCH_REQUIRE_GPIOLIB
+ select COMMON_CLKDEV
+ help
+ Support for Freescale MXS-based family of processors
+
config ARCH_STMP3XXX
bool "Freescale STMP3xxx"
select CPU_ARM926T
@@ -924,6 +932,8 @@ source "arch/arm/plat-pxa/Kconfig"
source "arch/arm/mach-mmp/Kconfig"
+source "arch/arm/mach-mxs/Kconfig"
+
source "arch/arm/mach-realview/Kconfig"
source "arch/arm/mach-sa1100/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 057beb8..c22c1ad 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -158,6 +158,7 @@ machine-$(CONFIG_ARCH_MX25) := imx
machine-$(CONFIG_ARCH_MX3) := mx3
machine-$(CONFIG_ARCH_MX5) := mx5
machine-$(CONFIG_ARCH_MXC91231) := mxc91231
+machine-$(CONFIG_ARCH_MXS) := mxs
machine-$(CONFIG_ARCH_NETX) := netx
machine-$(CONFIG_ARCH_NOMADIK) := nomadik
machine-$(CONFIG_ARCH_NS9XXX) := ns9xxx
diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
new file mode 100644
index 0000000..c4ac7b4
--- /dev/null
+++ b/arch/arm/mach-mxs/Kconfig
@@ -0,0 +1,34 @@
+if ARCH_MXS
+
+source "arch/arm/mach-mxs/devices/Kconfig"
+
+config SOC_IMX23
+ bool
+ select CPU_ARM926T
+
+config SOC_IMX28
+ bool
+ select CPU_ARM926T
+
+comment "MXS platforms:"
+
+config MACH_MX23EVK
+ bool "Support MX23EVK Platform"
+ select SOC_IMX23
+ select MXS_HAVE_PLATFORM_DUART
+ default y
+ help
+ Include support for MX23EVK platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_MX28EVK
+ bool "Support MX28EVK Platform"
+ select SOC_IMX28
+ select MXS_HAVE_PLATFORM_DUART
+ select MXS_HAVE_PLATFORM_FEC
+ default y
+ help
+ Include support for MX28EVK platform. This includes specific
+ configurations for the board and its peripherals.
+
+endif
diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
new file mode 100644
index 0000000..0b24b0d
--- /dev/null
+++ b/arch/arm/mach-mxs/Makefile
@@ -0,0 +1,14 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Common support
+obj-y := clock.o cpu.o devices.o gpio.o icoll.o iomux.o system.o timer.o
+
+obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
+obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
+
+obj-$(CONFIG_MACH_MX23EVK) += mach-mx23evk.o
+obj-$(CONFIG_MACH_MX28EVK) += mach-mx28evk.o
+
+obj-y += devices/
diff --git a/arch/arm/mach-mxs/Makefile.boot b/arch/arm/mach-mxs/Makefile.boot
new file mode 100644
index 0000000..1568ad4
--- /dev/null
+++ b/arch/arm/mach-mxs/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y := 0x40008000
+params_phys-y := 0x40000100
+initrd_phys-y := 0x40800000
diff --git a/arch/arm/mach-mxs/devices/Kconfig b/arch/arm/mach-mxs/devices/Kconfig
new file mode 100644
index 0000000..a35a2dc
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/Kconfig
@@ -0,0 +1,5 @@
+config MXS_HAVE_PLATFORM_DUART
+ bool
+
+config MXS_HAVE_PLATFORM_FEC
+ bool
diff --git a/arch/arm/mach-mxs/devices/Makefile b/arch/arm/mach-mxs/devices/Makefile
new file mode 100644
index 0000000..4b5266a
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_MXS_HAVE_PLATFORM_DUART) += platform-duart.o
+obj-$(CONFIG_MXS_HAVE_PLATFORM_FEC) += platform-fec.o
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH 03/15] ARM: mxs: Add reset routines
2010-11-26 6:49 ` [PATCH 03/15] ARM: mxs: Add reset routines Shawn Guo
@ 2010-11-26 9:31 ` Lothar Waßmann
2010-11-26 9:57 ` Uwe Kleine-König
0 siblings, 1 reply; 146+ messages in thread
From: Lothar Waßmann @ 2010-11-26 9:31 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
Shawn Guo writes:
[...]
> diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c
> new file mode 100644
> index 0000000..de33c66
> --- /dev/null
> +++ b/arch/arm/mach-mxs/system.c
> @@ -0,0 +1,152 @@
> +/*
> + * Copyright (C) 1999 ARM Limited
> + * Copyright (C) 2000 Deep Blue Solutions Ltd
> + * Copyright 2006-2007,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
> + *
> + * 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/kernel.h>
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/err.h>
> +#include <linux/delay.h>
> +
> +#include <asm/proc-fns.h>
> +#include <asm/system.h>
> +
> +#include <mach/hardware.h>
> +#include <mach/common.h>
> +
> +#define MXS_RTC_WATCHDOG 0x50
> +#define MXS_WATCHDOG_EN (1 << 4)
> +
> +#define MXS_MODULE_CLKGATE (1 << 30)
> +#define MXS_MODULE_SFTRST (1 << 31)
> +
> +static void __iomem *wdog_base;
> +
> +/*
> + * Reset the system. It is called by machine_restart().
> + */
> +void arch_reset(char mode, const char *cmd)
> +{
> + struct clk *clk;
> +
> + clk = clk_get_sys("rtc", NULL);
> + if (!IS_ERR(clk))
> + clk_enable(clk);
> +
>
Since arch_reset() may be called from interrupt context (e.g. due to
SYSRQ-B) it must not call any functions that may sleep like clk_get*()
or clk_enable(). The clock should be acquired and enabled in the init
routine.
> +void mxs_arch_reset_init(void __iomem *base)
> +{
> + wdog_base = base;
> +}
> +
Lothar Wa?mann
--
___________________________________________________________
Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996
www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH 03/15] ARM: mxs: Add reset routines
2010-11-26 9:31 ` Lothar Waßmann
@ 2010-11-26 9:57 ` Uwe Kleine-König
2010-11-26 10:38 ` Lothar Waßmann
0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-11-26 9:57 UTC (permalink / raw)
To: linux-arm-kernel
Hello Lothar,
On Fri, Nov 26, 2010 at 10:31:46AM +0100, Lothar Wa?mann wrote:
> Shawn Guo writes:
> [...]
> > diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c
> > new file mode 100644
> > index 0000000..de33c66
> > --- /dev/null
> > +++ b/arch/arm/mach-mxs/system.c
> > @@ -0,0 +1,152 @@
> > +/*
> > + * Copyright (C) 1999 ARM Limited
> > + * Copyright (C) 2000 Deep Blue Solutions Ltd
> > + * Copyright 2006-2007,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
> > + *
> > + * 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/kernel.h>
> > +#include <linux/clk.h>
> > +#include <linux/io.h>
> > +#include <linux/err.h>
> > +#include <linux/delay.h>
> > +
> > +#include <asm/proc-fns.h>
> > +#include <asm/system.h>
> > +
> > +#include <mach/hardware.h>
> > +#include <mach/common.h>
> > +
> > +#define MXS_RTC_WATCHDOG 0x50
> > +#define MXS_WATCHDOG_EN (1 << 4)
> > +
> > +#define MXS_MODULE_CLKGATE (1 << 30)
> > +#define MXS_MODULE_SFTRST (1 << 31)
> > +
> > +static void __iomem *wdog_base;
> > +
> > +/*
> > + * Reset the system. It is called by machine_restart().
> > + */
> > +void arch_reset(char mode, const char *cmd)
> > +{
> > + struct clk *clk;
> > +
> > + clk = clk_get_sys("rtc", NULL);
> > + if (!IS_ERR(clk))
> > + clk_enable(clk);
> > +
> >
> Since arch_reset() may be called from interrupt context (e.g. due to
> SYSRQ-B) it must not call any functions that may sleep like clk_get*()
> or clk_enable(). The clock should be acquired and enabled in the init
> routine.
This is a problem that also exist in arch/arm/plat-mxc/system.c's
arch_reset.
Did you already verify that this is indeed a problem? I guess there are
more architectures that use clk_get in arch_reset, aren't there?
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH 03/15] ARM: mxs: Add reset routines
2010-11-26 9:57 ` Uwe Kleine-König
@ 2010-11-26 10:38 ` Lothar Waßmann
2010-11-26 11:32 ` Uwe Kleine-König
2010-11-26 14:16 ` [PATCH 03/15] ARM: mxs: Add reset routines Xinyu Chen
0 siblings, 2 replies; 146+ messages in thread
From: Lothar Waßmann @ 2010-11-26 10:38 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
Uwe Kleine-K?nig writes:
> On Fri, Nov 26, 2010 at 10:31:46AM +0100, Lothar Wa?mann wrote:
> > Shawn Guo writes:
> > [...]
> > > diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c
> > > new file mode 100644
> > > index 0000000..de33c66
> > > --- /dev/null
> > > +++ b/arch/arm/mach-mxs/system.c
> > > @@ -0,0 +1,152 @@
> > > +/*
> > > + * Copyright (C) 1999 ARM Limited
> > > + * Copyright (C) 2000 Deep Blue Solutions Ltd
> > > + * Copyright 2006-2007,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
> > > + *
> > > + * 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/kernel.h>
> > > +#include <linux/clk.h>
> > > +#include <linux/io.h>
> > > +#include <linux/err.h>
> > > +#include <linux/delay.h>
> > > +
> > > +#include <asm/proc-fns.h>
> > > +#include <asm/system.h>
> > > +
> > > +#include <mach/hardware.h>
> > > +#include <mach/common.h>
> > > +
> > > +#define MXS_RTC_WATCHDOG 0x50
> > > +#define MXS_WATCHDOG_EN (1 << 4)
> > > +
> > > +#define MXS_MODULE_CLKGATE (1 << 30)
> > > +#define MXS_MODULE_SFTRST (1 << 31)
> > > +
> > > +static void __iomem *wdog_base;
> > > +
> > > +/*
> > > + * Reset the system. It is called by machine_restart().
> > > + */
> > > +void arch_reset(char mode, const char *cmd)
> > > +{
> > > + struct clk *clk;
> > > +
> > > + clk = clk_get_sys("rtc", NULL);
> > > + if (!IS_ERR(clk))
> > > + clk_enable(clk);
> > > +
> > >
> > Since arch_reset() may be called from interrupt context (e.g. due to
> > SYSRQ-B) it must not call any functions that may sleep like clk_get*()
> > or clk_enable(). The clock should be acquired and enabled in the init
> > routine.
> This is a problem that also exist in arch/arm/plat-mxc/system.c's
> arch_reset.
>
> Did you already verify that this is indeed a problem? I guess there are
> more architectures that use clk_get in arch_reset, aren't there?
>
If you consider this a problem:
BUG: sleeping function called from invalid context at /usr/local/src/arm-linux/kernel/mutex.c:
280
in_atomic(): 1, irqs_disabled(): 128, pid: 0, name: swapper
2 locks held by swapper/0:
#0: (&port_lock_key){-.-...}, at: [<c01aed10>] imx_rxint+0x24/0x20c
#1: (sysrq_key_table_lock){-.....}, at: [<c01a8e14>] __handle_sysrq+0x20/0x170
irq event stamp: 130658
hardirqs last enabled at (130657): [<c0027f80>] default_idle+0x2c/0x3c
hardirqs last disabled at (130658): [<c0026a74>] __irq_svc+0x34/0xa8
softirqs last enabled at (130648): [<c004bc1c>] __do_softirq+0x144/0x164
softirqs last disabled at (130637): [<c004bc9c>] irq_exit+0x60/0xb4
Backtrace:
[<c002aee0>] (dump_backtrace+0x0/0x114) from [<c0260240>] (dump_stack+0x18/0x1c)
r7:00000000 r6:c0326000 r5:00000000 r4:c0326000
[<c0260228>] (dump_stack+0x0/0x1c) from [<c0041930>] (__might_sleep+0x11c/0x13c)
[<c0041814>] (__might_sleep+0x0/0x13c) from [<c026181c>] (mutex_lock_nested+0x34/0x31c)
r4:c032afd4
[<c02617e8>] (mutex_lock_nested+0x0/0x31c) from [<c003097c>] (clk_get_sys+0x30/0xe8)
[<c003094c>] (clk_get_sys+0x0/0xe8) from [<c00338c8>] (arch_reset+0x18/0x8c)
[<c00338b0>] (arch_reset+0x0/0x8c) from [<c0028564>] (arm_machine_restart+0x2c/0x5c)
r5:00000000 r4:00000068
[<c0028538>] (arm_machine_restart+0x0/0x5c) from [<c0027f3c>] (machine_restart+0x20/0x28)
r5:d186b9c0 r4:00000062
[<c0027f1c>] (machine_restart+0x0/0x28) from [<c0056db8>] (emergency_restart+0x14/0x18)
[<c0056da4>] (emergency_restart+0x0/0x18) from [<c01a9220>] (sysrq_handle_reboot+0x24/0x28)
[<c01a91fc>] (sysrq_handle_reboot+0x0/0x28) from [<c01a8eb4>] (__handle_sysrq+0xc0/0x170)
[<c01a8df4>] (__handle_sysrq+0x0/0x170) from [<c01a8fd4>] (handle_sysrq+0x34/0x40)
[<c01a8fa0>] (handle_sysrq+0x0/0x40) from [<c01aedd8>] (imx_rxint+0xec/0x20c)
[<c01aecec>] (imx_rxint+0x0/0x20c) from [<c01aef20>] (imx_int+0x28/0x68)
[<c01aeef8>] (imx_int+0x0/0x68) from [<c007a794>] (handle_IRQ_event+0x2c/0x100)
r7:0000002d r6:00000000 r5:00000000 r4:d1eab800
[<c007a768>] (handle_IRQ_event+0x0/0x100) from [<c007c4fc>] (handle_level_irq+0xbc/0x120)
r7:d1eab800 r6:c03340b8 r5:0000002d r4:c033407c
[<c007c440>] (handle_level_irq+0x0/0x120) from [<c0026070>] (_text+0x70/0x8c)
r7:00000002 r6:002d0000 r5:00000000 r4:0000002d
[<c0026000>] (_text+0x0/0x8c) from [<c0026a94>] (__irq_svc+0x54/0xa8)
Exception stack(0xc0327f48 to 0xc0327f90)
7f40: 00000001 0016e240 20000093 20000013 c0326000 c032aaa8
7f60: c03541e4 c032aaa0 8001ecc4 41069264 8001ec90 c0327f9c c0327f68 c0327f90
7f80: c006c620 c0027f8c 20000013 ffffffff
r5:fc400000 r4:0000001f
[<c0027f54>] (default_idle+0x0/0x3c) from [<c00284dc>] (cpu_idle+0x70/0xcc)
[<c002846c>] (cpu_idle+0x0/0xcc) from [<c025d338>] (rest_init+0x70/0x84)
r7:c032aaa0 r6:c0020e14 r5:c0020e18 r4:c0853ad8
[<c025d2c8>] (rest_init+0x0/0x84) from [<c00089a4>] (start_kernel+0x280/0x2d8)
[<c0008724>] (start_kernel+0x0/0x2d8) from [<80008034>] (0x80008034)
r5:c0354284 r4:00053175
------------[ cut here ]------------
WARNING: at /usr/local/src/arm-linux/kernel/mutex.c:207 mutex_lock_nested+0xb4/0x31c()
Modules linked in:
Backtrace:
[<c002aee0>] (dump_backtrace+0x0/0x114) from [<c0260240>] (dump_stack+0x18/0x1c)
r7:c02e09d3 r6:000000cf r5:c026189c r4:00000000
[<c0260228>] (dump_stack+0x0/0x1c) from [<c004682c>] (warn_slowpath_common+0x50/0x68)
[<c00467dc>] (warn_slowpath_common+0x0/0x68) from [<c004685c>] (warn_slowpath_null+0x18/0x1c)
r7:00000000 r6:c0326000 r5:c0329868 r4:c032afd4
[<c0046844>] (warn_slowpath_null+0x0/0x1c) from [<c026189c>] (mutex_lock_nested+0xb4/0x31c)
[<c02617e8>] (mutex_lock_nested+0x0/0x31c) from [<c003097c>] (clk_get_sys+0x30/0xe8)
[<c003094c>] (clk_get_sys+0x0/0xe8) from [<c00338c8>] (arch_reset+0x18/0x8c)
[<c00338b0>] (arch_reset+0x0/0x8c) from [<c0028564>] (arm_machine_restart+0x2c/0x5c)
r5:00000000 r4:00000068
[<c0028538>] (arm_machine_restart+0x0/0x5c) from [<c0027f3c>] (machine_restart+0x20/0x28)
r5:d186b9c0 r4:00000062
[<c0027f1c>] (machine_restart+0x0/0x28) from [<c0056db8>] (emergency_restart+0x14/0x18)
[<c0056da4>] (emergency_restart+0x0/0x18) from [<c01a9220>] (sysrq_handle_reboot+0x24/0x28)
[<c01a91fc>] (sysrq_handle_reboot+0x0/0x28) from [<c01a8eb4>] (__handle_sysrq+0xc0/0x170)
[<c01a8df4>] (__handle_sysrq+0x0/0x170) from [<c01a8fd4>] (handle_sysrq+0x34/0x40)
[<c01a8fa0>] (handle_sysrq+0x0/0x40) from [<c01aedd8>] (imx_rxint+0xec/0x20c)
[<c01aecec>] (imx_rxint+0x0/0x20c) from [<c01aef20>] (imx_int+0x28/0x68)
[<c01aeef8>] (imx_int+0x0/0x68) from [<c007a794>] (handle_IRQ_event+0x2c/0x100)
r7:0000002d r6:00000000 r5:00000000 r4:d1eab800
[<c007a768>] (handle_IRQ_event+0x0/0x100) from [<c007c4fc>] (handle_level_irq+0xbc/0x120)
r7:d1eab800 r6:c03340b8 r5:0000002d r4:c033407c
[<c007c440>] (handle_level_irq+0x0/0x120) from [<c0026070>] (_text+0x70/0x8c)
r7:00000002 r6:002d0000 r5:00000000 r4:0000002d
[<c0026000>] (_text+0x0/0x8c) from [<c0026a94>] (__irq_svc+0x54/0xa8)
Exception stack(0xc0327f48 to 0xc0327f90)
7f40: 00000001 0016e240 20000093 20000013 c0326000 c032aaa8
7f60: c03541e4 c032aaa0 8001ecc4 41069264 8001ec90 c0327f9c c0327f68 c0327f90
7f80: c006c620 c0027f8c 20000013 ffffffff
r5:fc400000 r4:0000001f
[<c0027f54>] (default_idle+0x0/0x3c) from [<c00284dc>] (cpu_idle+0x70/0xcc)
[<c002846c>] (cpu_idle+0x0/0xcc) from [<c025d338>] (rest_init+0x70/0x84)
r7:c032aaa0 r6:c0020e14 r5:c0020e18 r4:c0853ad8
[<c025d2c8>] (rest_init+0x0/0x84) from [<c00089a4>] (start_kernel+0x280/0x2d8)
[<c0008724>] (start_kernel+0x0/0x2d8) from [<80008034>] (0x80008034)
r5:c0354284 r4:00053175
---[ end trace b484fc13651ee6f1 ]---
Lothar Wa?mann
--
___________________________________________________________
Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996
www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH 01/15] ARM: mxs: Add core definitions
2010-11-26 6:49 ` [PATCH 01/15] ARM: mxs: Add core definitions Shawn Guo
@ 2010-11-26 11:30 ` Uwe Kleine-König
2010-11-29 7:21 ` Shawn Guo
0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-11-26 11:30 UTC (permalink / raw)
To: linux-arm-kernel
Hello Shawn,
On Fri, Nov 26, 2010 at 02:49:00PM +0800, Shawn Guo wrote:
> Add core definitions for MXS-based SoC MX23 and MX28.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> arch/arm/mach-mxs/include/mach/hardware.h | 66 +++++++++
> arch/arm/mach-mxs/include/mach/irqs.h | 32 ++++
> arch/arm/mach-mxs/include/mach/memory.h | 24 +++
> arch/arm/mach-mxs/include/mach/mx23.h | 147 +++++++++++++++++++
> arch/arm/mach-mxs/include/mach/mx28.h | 227 +++++++++++++++++++++++++++++
> arch/arm/mach-mxs/include/mach/mxs.h | 60 ++++++++
> 6 files changed, 556 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-mxs/include/mach/hardware.h
> create mode 100644 arch/arm/mach-mxs/include/mach/irqs.h
> create mode 100644 arch/arm/mach-mxs/include/mach/memory.h
> create mode 100644 arch/arm/mach-mxs/include/mach/mx23.h
> create mode 100644 arch/arm/mach-mxs/include/mach/mx28.h
> create mode 100644 arch/arm/mach-mxs/include/mach/mxs.h
>
> diff --git a/arch/arm/mach-mxs/include/mach/hardware.h b/arch/arm/mach-mxs/include/mach/hardware.h
> new file mode 100644
> index 0000000..5edccd5
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/hardware.h
> @@ -0,0 +1,66 @@
> +/*
> + * Copyright 2004-2007 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
> + * 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_MXS_HARDWARE_H__
> +#define __MACH_MXS_HARDWARE_H__
> +
> +#include <asm/sizes.h>
> +
> +#ifdef __ASSEMBLER__
> +#define IOMEM(addr) (addr)
> +#else
> +#define IOMEM(addr) ((void __force __iomem *)(addr))
> +#endif
> +
> +#define MXS_IO_P2V_MODULE(addr, module) \
> + (((addr) - module ## _BASE_ADDR) < module ## _SIZE ? \
> + (addr) - (module ## _BASE_ADDR) + (module ## _BASE_ADDR_VIRT) : 0)
Do you need this? On imx this is only used in
arch/arm/mach-mx3/mach-kzm_arm11_01.c that uses it to map chip selects.
IMHO it should better use a dynamic mapping for that which would allow
to let IMX_IO_P2V_MODULE die.
> +/*
> + * It maps the whole address space to [0xf4000000, 0xf5ffffff].
> + *
> + * OCRAM 0x00000000+0x020000 -> 0xf4000000+0x020000
> + * IO 0x80000000+0x100000 -> 0xf4400000+0x100000
> + */
> +#define MXS_IO_P2V(x) ( \
> + 0xf4000000 + \
> + (((x) & 0x50000000) >> 6) + \
> + (((x) & 0x0b000000) >> 4) + \
> + (((x) & 0x000fffff)))
Did you test this? For me MXS_IO_P2V(0x80000000) ==
MXS_IO_P2V(0x00000000). You should be able to choose a much simpler
function, e.g.
(0xf4000000 + (((x) & 0x80000000) >> 6) + (((x) & 0x000fffff))))
should work for the two areas above
> +
> +#define MXS_IO_ADDRESS(x) IOMEM(MXS_IO_P2V(x))
> +
> +#ifdef CONFIG_SOC_IMX23
You don't need to protect inclusion of mach/mx23 if all symbols defined
in it are properly namespaced.
> +# include <mach/mx23.h>
> +#endif
> +
> +#ifdef CONFIG_SOC_IMX28
> +# include <mach/mx28.h>
> +#endif
> +
> +#include <mach/mxs.h>
> +
> +#define mxs_map_entry(soc, name, _type) { \
> + .virtual = soc ## _IO_P2V(soc ## _ ## name ## _BASE_ADDR), \
> + .pfn = __phys_to_pfn(soc ## _ ## name ## _BASE_ADDR), \
> + .length = soc ## _ ## name ## _SIZE, \
> + .type = _type, \
> +}
> +
> +#endif /* __MACH_MXS_HARDWARE_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/irqs.h b/arch/arm/mach-mxs/include/mach/irqs.h
> new file mode 100644
> index 0000000..f771039
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/irqs.h
> @@ -0,0 +1,32 @@
> +/*
> + * Copyright 2004-2007 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.
> + */
> +
> +#ifndef __MACH_MXS_IRQS_H__
> +#define __MACH_MXS_IRQS_H__
> +
> +#define MXS_INTERNAL_IRQS 128
> +
> +#define MXS_GPIO_IRQ_START MXS_INTERNAL_IRQS
> +
> +/* the maximum for MXS-based */
> +#define MXS_GPIO_IRQS (32 * 5)
> +
> +/*
> + * The next 16 interrupts are for board specific purposes. Since
> + * the kernel can only run on one machine at a time, we can re-use
> + * these. If you need more, increase MXS_BOARD_IRQS, but keep it
> + * within sensible limits.
> + */
> +#define MXS_BOARD_IRQ_START (MXS_GPIO_IRQ_START + MXS_GPIO_IRQS)
> +#define MXS_BOARD_IRQS 16
> +
> +#define NR_IRQS (MXS_BOARD_IRQ_START + MXS_BOARD_IRQS)
> +
> +#endif /* __MACH_MXS_IRQS_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/memory.h b/arch/arm/mach-mxs/include/mach/memory.h
> new file mode 100644
> index 0000000..b5420a5
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/memory.h
> @@ -0,0 +1,24 @@
> +/*
> + * 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_MXS_MEMORY_H__
> +#define __MACH_MXS_MEMORY_H__
> +
> +#define PHYS_OFFSET UL(0x40000000)
> +
> +#endif /* __MACH_MXS_MEMORY_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/mx23.h b/arch/arm/mach-mxs/include/mach/mx23.h
> new file mode 100644
> index 0000000..27a11ee
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/mx23.h
> @@ -0,0 +1,147 @@
> +/*
> + * 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_MX23_H__
> +#define __MACH_MX23_H__
> +
> +#ifndef __ASSEMBLER__
> +#include <linux/io.h>
> +#endif
> +
> +/*
> + * OCRAM
> + */
> +#define MX23_OCRAM_BASE_ADDR 0x00000000
> +#define MX23_OCRAM_SIZE SZ_32K
> +
> +/*
> + * IO
> + */
> +#define MX23_IO_BASE_ADDR 0x80000000
> +#define MX23_IO_SIZE SZ_1M
> +
> +#define MX23_ICOLL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x000000)
> +#define MX23_APBH_DMA_BASE_ADDR (MX23_IO_BASE_ADDR + 0x004000)
> +#define MX23_BCH_BASE_ADDR (MX23_IO_BASE_ADDR + 0x00a000)
> +#define MX23_GPMI_BASE_ADDR (MX23_IO_BASE_ADDR + 0x00c000)
> +#define MX23_SSP1_BASE_ADDR (MX23_IO_BASE_ADDR + 0x010000)
> +#define MX23_SSP2_BASE_ADDR (MX23_IO_BASE_ADDR + 0x034000)
> +#define MX23_PINCTRL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x018000)
> +#define MX23_DIGCTL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x01c000)
> +#define MX23_ETM_BASE_ADDR (MX23_IO_BASE_ADDR + 0x020000)
> +#define MX23_APBX_DMA_BASE_ADDR (MX23_IO_BASE_ADDR + 0x024000)
> +#define MX23_DCP_BASE_ADDR (MX23_IO_BASE_ADDR + 0x028000)
> +#define MX23_PXP_BASE_ADDR (MX23_IO_BASE_ADDR + 0x02a000)
> +#define MX23_OCOTP_BASE_ADDR (MX23_IO_BASE_ADDR + 0x02c000)
> +#define MX23_AXI_AHB0_BASE_ADDR (MX23_IO_BASE_ADDR + 0x02e000)
> +#define MX23_LCDIF_BASE_ADDR (MX23_IO_BASE_ADDR + 0x030000)
> +#define MX23_TVENC_BASE_ADDR (MX23_IO_BASE_ADDR + 0x038000)
> +#define MX23_CLKCTRL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x040000)
> +#define MX23_SAIF0_BASE_ADDR (MX23_IO_BASE_ADDR + 0x042000)
> +#define MX23_POWER_BASE_ADDR (MX23_IO_BASE_ADDR + 0x044000)
> +#define MX23_SAIF1_BASE_ADDR (MX23_IO_BASE_ADDR + 0x046000)
> +#define MX23_AUDIOOUT_BASE_ADDR (MX23_IO_BASE_ADDR + 0x048000)
> +#define MX23_AUDIOIN_BASE_ADDR (MX23_IO_BASE_ADDR + 0x04c000)
> +#define MX23_LRADC_BASE_ADDR (MX23_IO_BASE_ADDR + 0x050000)
> +#define MX23_SPDIF_BASE_ADDR (MX23_IO_BASE_ADDR + 0x054000)
> +#define MX23_RTC_BASE_ADDR (MX23_IO_BASE_ADDR + 0x05c000)
> +#define MX23_I2C0_BASE_ADDR (MX23_IO_BASE_ADDR + 0x058000)
> +#define MX23_PWM_BASE_ADDR (MX23_IO_BASE_ADDR + 0x064000)
> +#define MX23_TIMROT_BASE_ADDR (MX23_IO_BASE_ADDR + 0x068000)
> +#define MX23_AUART1_BASE_ADDR (MX23_IO_BASE_ADDR + 0x06c000)
> +#define MX23_AUART2_BASE_ADDR (MX23_IO_BASE_ADDR + 0x06e000)
> +#define MX23_DUART_BASE_ADDR (MX23_IO_BASE_ADDR + 0x070000)
> +#define MX23_USBPHY_BASE_ADDR (MX23_IO_BASE_ADDR + 0x07c000)
> +#define MX23_USBCTRL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x080000)
> +#define MX23_DRAM_BASE_ADDR (MX23_IO_BASE_ADDR + 0x0e0000)
> +
> +#define MX23_IO_P2V(x) MXS_IO_P2V(x)
> +#define MX23_IO_ADDRESS(x) IOMEM(MX23_IO_P2V(x))
> +
> +/*
> + * IRQ
> + */
> +#define MX23_INT_DUART 0
> +#define MX23_INT_COMMS_RX 1
> +#define MX23_INT_COMMS_TX 1
really two names for irq 1?
> +#define MX23_INT_SSP2_ERROR 2
> +#define MX23_INT_VDD5V 3
> +#define MX23_INT_HEADPHONE_SHORT 4
> +#define MX23_INT_DAC_DMA 5
> +#define MX23_INT_DAC_ERROR 6
> +#define MX23_INT_ADC_DMA 7
> +#define MX23_INT_ADC_ERROR 8
> +#define MX23_INT_SPDIF_DMA 9
> +#define MX23_INT_SAIF2_DMA 9
ditto
> +#define MX23_INT_SPDIF_ERROR 10
> +#define MX23_INT_SAIF1_IRQ 10
> +#define MX23_INT_SAIF2_IRQ 10
ditto (3 that is)
> +#define MX23_INT_USB_CTRL 11
> +#define MX23_INT_USB_WAKEUP 12
> +#define MX23_INT_GPMI_DMA 13
> +#define MX23_INT_SSP1_DMA 14
> +#define MX23_INT_SSP_ERROR 15
> +#define MX23_INT_GPIO0 16
> +#define MX23_INT_GPIO1 17
> +#define MX23_INT_GPIO2 18
> +#define MX23_INT_SAIF1_DMA 19
> +#define MX23_INT_SSP2_DMA 20
> +#define MX23_INT_ECC8_IRQ 21
> +#define MX23_INT_RTC_ALARM 22
> +#define MX23_INT_UARTAPP_TX_DMA 23
> +#define MX23_INT_UARTAPP_INTERNAL 24
> +#define MX23_INT_UARTAPP_RX_DMA 25
> +#define MX23_INT_I2C_DMA 26
> +#define MX23_INT_I2C_ERROR 27
> +#define MX23_INT_TIMER0 28
> +#define MX23_INT_TIMER1 29
> +#define MX23_INT_TIMER2 30
> +#define MX23_INT_TIMER3 31
> +#define MX23_INT_BATT_BRNOUT 32
> +#define MX23_INT_VDDD_BRNOUT 33
> +#define MX23_INT_VDDIO_BRNOUT 34
> +#define MX23_INT_VDD18_BRNOUT 35
> +#define MX23_INT_TOUCH_DETECT 36
> +#define MX23_INT_LRADC_CH0 37
> +#define MX23_INT_LRADC_CH1 38
> +#define MX23_INT_LRADC_CH2 39
> +#define MX23_INT_LRADC_CH3 40
> +#define MX23_INT_LRADC_CH4 41
> +#define MX23_INT_LRADC_CH5 42
> +#define MX23_INT_LRADC_CH6 43
> +#define MX23_INT_LRADC_CH7 44
> +#define MX23_INT_LCDIF_DMA 45
> +#define MX23_INT_LCDIF_ERROR 46
> +#define MX23_INT_DIGCTL_DEBUG_TRAP 47
> +#define MX23_INT_RTC_1MSEC 48
> +#define MX23_INT_DRI_DMA 49
> +#define MX23_INT_DRI_ATTENTION 50
> +#define MX23_INT_GPMI_ATTENTION 51
> +#define MX23_INT_IR 52
> +#define MX23_INT_DCP_VMI 53
> +#define MX23_INT_DCP 54
> +#define MX23_INT_BCH 56
> +#define MX23_INT_PXP 57
> +#define MX23_INT_UARTAPP2_TX_DMA 58
> +#define MX23_INT_UARTAPP2_INTERNAL 59
> +#define MX23_INT_UARTAPP2_RX_DMA 60
> +#define MX23_INT_VDAC_DETECT 61
> +#define MX23_INT_VDD5V_DROOP 64
> +#define MX23_INT_DCDC4P2_BO 65
> +
> +#endif /* __MACH_MX23_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/mx28.h b/arch/arm/mach-mxs/include/mach/mx28.h
> new file mode 100644
> index 0000000..836d807
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/mx28.h
> @@ -0,0 +1,227 @@
> +/*
> + * 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
> +
> +/*
> + * 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_MAC0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0f0000)
> +#define MX28_ENET_MAC1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0f4000)
> +
> +#define MX28_IO_P2V(x) MXS_IO_P2V(x)
> +#define MX28_IO_ADDRESS(x) IOMEM(MX28_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
> +
> +#endif /* __MACH_MX28_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/mxs.h b/arch/arm/mach-mxs/include/mach/mxs.h
> new file mode 100644
> index 0000000..128c114
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/mxs.h
> @@ -0,0 +1,60 @@
> +/*
> + * 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_MXS_H__
> +#define __MACH_MXS_H__
> +
> +#define MXS_SET_ADDR 0x4
> +#define MXS_CLR_ADDR 0x8
> +#define MXS_TOG_ADDR 0xc
> +
> +/*
> + * MXS CPU types
> + */
> +#define MXS_CPU_MX23 23
> +#define MXS_CPU_MX28 28
> +
> +#ifndef __ASSEMBLY__
> +extern unsigned int __mxs_cpu_type;
> +#endif
> +
> +#ifdef CONFIG_SOC_IMX23
> +# ifdef mxs_cpu_type
> +# undef mxs_cpu_type
> +# define mxs_cpu_type __mxs_cpu_type
> +# else
> +# define mxs_cpu_type MXS_CPU_MX23
> +# endif
> +# define cpu_is_mx23() (mxs_cpu_type == MXS_CPU_MX23)
> +#else
> +# define cpu_is_mx23() (0)
> +#endif
> +
> +#ifdef CONFIG_SOC_IMX28
> +# ifdef mxs_cpu_type
> +# undef mxs_cpu_type
> +# define mxs_cpu_type __mxs_cpu_type
> +# else
> +# define mxs_cpu_type MXS_CPU_MX28
> +# endif
> +# define cpu_is_mx28() (mxs_cpu_type == MXS_CPU_MX28)
> +#else
> +# define cpu_is_mx28() (0)
> +#endif
For imx I wondered if this is overkill. When I started mainlining
ns9xxx I just did:
#define cpu_is_xyz() (machine_is_abc() || ...)
It's much easier and the generated code probably is not much worse.
(Better try to reduce the number of usages of these macros.)
(Note, if you're convinced this is good, go ahead, just my personal
opinion.)
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH 03/15] ARM: mxs: Add reset routines
2010-11-26 10:38 ` Lothar Waßmann
@ 2010-11-26 11:32 ` Uwe Kleine-König
2010-11-26 12:53 ` Lothar Waßmann
2010-11-29 9:25 ` [PATCH] prevent 'BUG: sleeping function called from invalid context' in arch_reset() Lothar Waßmann
2010-11-26 14:16 ` [PATCH 03/15] ARM: mxs: Add reset routines Xinyu Chen
1 sibling, 2 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-11-26 11:32 UTC (permalink / raw)
To: linux-arm-kernel
Hello Lothar,
On Fri, Nov 26, 2010 at 11:38:47AM +0100, Lothar Wa?mann wrote:
> Uwe Kleine-K?nig writes:
> > On Fri, Nov 26, 2010 at 10:31:46AM +0100, Lothar Wa?mann wrote:
> > > Since arch_reset() may be called from interrupt context (e.g. due to
> > > SYSRQ-B) it must not call any functions that may sleep like clk_get*()
> > > or clk_enable(). The clock should be acquired and enabled in the init
> > > routine.
> > This is a problem that also exist in arch/arm/plat-mxc/system.c's
> > arch_reset.
> >
> > Did you already verify that this is indeed a problem? I guess there are
> > more architectures that use clk_get in arch_reset, aren't there?
> >
> If you consider this a problem:
> BUG: sleeping function called from invalid context at /usr/local/src/arm-linux/kernel/mutex.c:
> 280
> in_atomic(): 1, irqs_disabled(): 128, pid: 0, name: swapper
> 2 locks held by swapper/0:
> #0: (&port_lock_key){-.-...}, at: [<c01aed10>] imx_rxint+0x24/0x20c
> #1: (sysrq_key_table_lock){-.....}, at: [<c01a8e14>] __handle_sysrq+0x20/0x170
> irq event stamp: 130658
> hardirqs last enabled at (130657): [<c0027f80>] default_idle+0x2c/0x3c
> hardirqs last disabled at (130658): [<c0026a74>] __irq_svc+0x34/0xa8
> softirqs last enabled at (130648): [<c004bc1c>] __do_softirq+0x144/0x164
> softirqs last disabled at (130637): [<c004bc9c>] irq_exit+0x60/0xb4
> Backtrace:
> [<c002aee0>] (dump_backtrace+0x0/0x114) from [<c0260240>] (dump_stack+0x18/0x1c)
> r7:00000000 r6:c0326000 r5:00000000 r4:c0326000
> [<c0260228>] (dump_stack+0x0/0x1c) from [<c0041930>] (__might_sleep+0x11c/0x13c)
> [<c0041814>] (__might_sleep+0x0/0x13c) from [<c026181c>] (mutex_lock_nested+0x34/0x31c)
> r4:c032afd4
> [<c02617e8>] (mutex_lock_nested+0x0/0x31c) from [<c003097c>] (clk_get_sys+0x30/0xe8)
> [<c003094c>] (clk_get_sys+0x0/0xe8) from [<c00338c8>] (arch_reset+0x18/0x8c)
> [<c00338b0>] (arch_reset+0x0/0x8c) from [<c0028564>] (arm_machine_restart+0x2c/0x5c)
> r5:00000000 r4:00000068
> [<c0028538>] (arm_machine_restart+0x0/0x5c) from [<c0027f3c>] (machine_restart+0x20/0x28)
> r5:d186b9c0 r4:00000062
> [<c0027f1c>] (machine_restart+0x0/0x28) from [<c0056db8>] (emergency_restart+0x14/0x18)
> [<c0056da4>] (emergency_restart+0x0/0x18) from [<c01a9220>] (sysrq_handle_reboot+0x24/0x28)
> [<c01a91fc>] (sysrq_handle_reboot+0x0/0x28) from [<c01a8eb4>] (__handle_sysrq+0xc0/0x170)
> [<c01a8df4>] (__handle_sysrq+0x0/0x170) from [<c01a8fd4>] (handle_sysrq+0x34/0x40)
> [<c01a8fa0>] (handle_sysrq+0x0/0x40) from [<c01aedd8>] (imx_rxint+0xec/0x20c)
> [<c01aecec>] (imx_rxint+0x0/0x20c) from [<c01aef20>] (imx_int+0x28/0x68)
> [<c01aeef8>] (imx_int+0x0/0x68) from [<c007a794>] (handle_IRQ_event+0x2c/0x100)
> r7:0000002d r6:00000000 r5:00000000 r4:d1eab800
> [<c007a768>] (handle_IRQ_event+0x0/0x100) from [<c007c4fc>] (handle_level_irq+0xbc/0x120)
> r7:d1eab800 r6:c03340b8 r5:0000002d r4:c033407c
> [<c007c440>] (handle_level_irq+0x0/0x120) from [<c0026070>] (_text+0x70/0x8c)
> r7:00000002 r6:002d0000 r5:00000000 r4:0000002d
> [<c0026000>] (_text+0x0/0x8c) from [<c0026a94>] (__irq_svc+0x54/0xa8)
> Exception stack(0xc0327f48 to 0xc0327f90)
> 7f40: 00000001 0016e240 20000093 20000013 c0326000 c032aaa8
> 7f60: c03541e4 c032aaa0 8001ecc4 41069264 8001ec90 c0327f9c c0327f68 c0327f90
> 7f80: c006c620 c0027f8c 20000013 ffffffff
> r5:fc400000 r4:0000001f
> [<c0027f54>] (default_idle+0x0/0x3c) from [<c00284dc>] (cpu_idle+0x70/0xcc)
> [<c002846c>] (cpu_idle+0x0/0xcc) from [<c025d338>] (rest_init+0x70/0x84)
> r7:c032aaa0 r6:c0020e14 r5:c0020e18 r4:c0853ad8
> [<c025d2c8>] (rest_init+0x0/0x84) from [<c00089a4>] (start_kernel+0x280/0x2d8)
> [<c0008724>] (start_kernel+0x0/0x2d8) from [<80008034>] (0x80008034)
> r5:c0354284 r4:00053175
> ------------[ cut here ]------------
> WARNING: at /usr/local/src/arm-linux/kernel/mutex.c:207 mutex_lock_nested+0xb4/0x31c()
> Modules linked in:
> Backtrace:
> [<c002aee0>] (dump_backtrace+0x0/0x114) from [<c0260240>] (dump_stack+0x18/0x1c)
> r7:c02e09d3 r6:000000cf r5:c026189c r4:00000000
> [<c0260228>] (dump_stack+0x0/0x1c) from [<c004682c>] (warn_slowpath_common+0x50/0x68)
> [<c00467dc>] (warn_slowpath_common+0x0/0x68) from [<c004685c>] (warn_slowpath_null+0x18/0x1c)
> r7:00000000 r6:c0326000 r5:c0329868 r4:c032afd4
> [<c0046844>] (warn_slowpath_null+0x0/0x1c) from [<c026189c>] (mutex_lock_nested+0xb4/0x31c)
> [<c02617e8>] (mutex_lock_nested+0x0/0x31c) from [<c003097c>] (clk_get_sys+0x30/0xe8)
> [<c003094c>] (clk_get_sys+0x0/0xe8) from [<c00338c8>] (arch_reset+0x18/0x8c)
> [<c00338b0>] (arch_reset+0x0/0x8c) from [<c0028564>] (arm_machine_restart+0x2c/0x5c)
> r5:00000000 r4:00000068
> [<c0028538>] (arm_machine_restart+0x0/0x5c) from [<c0027f3c>] (machine_restart+0x20/0x28)
> r5:d186b9c0 r4:00000062
> [<c0027f1c>] (machine_restart+0x0/0x28) from [<c0056db8>] (emergency_restart+0x14/0x18)
> [<c0056da4>] (emergency_restart+0x0/0x18) from [<c01a9220>] (sysrq_handle_reboot+0x24/0x28)
> [<c01a91fc>] (sysrq_handle_reboot+0x0/0x28) from [<c01a8eb4>] (__handle_sysrq+0xc0/0x170)
> [<c01a8df4>] (__handle_sysrq+0x0/0x170) from [<c01a8fd4>] (handle_sysrq+0x34/0x40)
> [<c01a8fa0>] (handle_sysrq+0x0/0x40) from [<c01aedd8>] (imx_rxint+0xec/0x20c)
> [<c01aecec>] (imx_rxint+0x0/0x20c) from [<c01aef20>] (imx_int+0x28/0x68)
> [<c01aeef8>] (imx_int+0x0/0x68) from [<c007a794>] (handle_IRQ_event+0x2c/0x100)
> r7:0000002d r6:00000000 r5:00000000 r4:d1eab800
> [<c007a768>] (handle_IRQ_event+0x0/0x100) from [<c007c4fc>] (handle_level_irq+0xbc/0x120)
> r7:d1eab800 r6:c03340b8 r5:0000002d r4:c033407c
> [<c007c440>] (handle_level_irq+0x0/0x120) from [<c0026070>] (_text+0x70/0x8c)
> r7:00000002 r6:002d0000 r5:00000000 r4:0000002d
> [<c0026000>] (_text+0x0/0x8c) from [<c0026a94>] (__irq_svc+0x54/0xa8)
> Exception stack(0xc0327f48 to 0xc0327f90)
> 7f40: 00000001 0016e240 20000093 20000013 c0326000 c032aaa8
> 7f60: c03541e4 c032aaa0 8001ecc4 41069264 8001ec90 c0327f9c c0327f68 c0327f90
> 7f80: c006c620 c0027f8c 20000013 ffffffff
> r5:fc400000 r4:0000001f
> [<c0027f54>] (default_idle+0x0/0x3c) from [<c00284dc>] (cpu_idle+0x70/0xcc)
> [<c002846c>] (cpu_idle+0x0/0xcc) from [<c025d338>] (rest_init+0x70/0x84)
> r7:c032aaa0 r6:c0020e14 r5:c0020e18 r4:c0853ad8
> [<c025d2c8>] (rest_init+0x0/0x84) from [<c00089a4>] (start_kernel+0x280/0x2d8)
> [<c0008724>] (start_kernel+0x0/0x2d8) from [<80008034>] (0x80008034)
> r5:c0354284 r4:00053175
> ---[ end trace b484fc13651ee6f1 ]---
do you care enough to send a patch? If not I can set it on my agenda.
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH 03/15] ARM: mxs: Add reset routines
2010-11-26 11:32 ` Uwe Kleine-König
@ 2010-11-26 12:53 ` Lothar Waßmann
2010-11-29 9:25 ` [PATCH] prevent 'BUG: sleeping function called from invalid context' in arch_reset() Lothar Waßmann
1 sibling, 0 replies; 146+ messages in thread
From: Lothar Waßmann @ 2010-11-26 12:53 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
Uwe Kleine-K?nig writes:
> Hello Lothar,
>
> On Fri, Nov 26, 2010 at 11:38:47AM +0100, Lothar Wa?mann wrote:
> > Uwe Kleine-K?nig writes:
> > > On Fri, Nov 26, 2010 at 10:31:46AM +0100, Lothar Wa?mann wrote:
> > > > Since arch_reset() may be called from interrupt context (e.g. due to
> > > > SYSRQ-B) it must not call any functions that may sleep like clk_get*()
> > > > or clk_enable(). The clock should be acquired and enabled in the init
> > > > routine.
> > > This is a problem that also exist in arch/arm/plat-mxc/system.c's
> > > arch_reset.
> > >
> > > Did you already verify that this is indeed a problem? I guess there are
> > > more architectures that use clk_get in arch_reset, aren't there?
> > >
> > If you consider this a problem:
> > BUG: sleeping function called from invalid context at /usr/local/src/arm-linux/kernel/mutex.c:
> > 280
> > in_atomic(): 1, irqs_disabled(): 128, pid: 0, name: swapper
> > 2 locks held by swapper/0:
> > #0: (&port_lock_key){-.-...}, at: [<c01aed10>] imx_rxint+0x24/0x20c
> > #1: (sysrq_key_table_lock){-.....}, at: [<c01a8e14>] __handle_sysrq+0x20/0x170
> > irq event stamp: 130658
> > hardirqs last enabled at (130657): [<c0027f80>] default_idle+0x2c/0x3c
> > hardirqs last disabled at (130658): [<c0026a74>] __irq_svc+0x34/0xa8
> > softirqs last enabled at (130648): [<c004bc1c>] __do_softirq+0x144/0x164
> > softirqs last disabled at (130637): [<c004bc9c>] irq_exit+0x60/0xb4
> > Backtrace:
> > [<c002aee0>] (dump_backtrace+0x0/0x114) from [<c0260240>] (dump_stack+0x18/0x1c)
> > r7:00000000 r6:c0326000 r5:00000000 r4:c0326000
> > [<c0260228>] (dump_stack+0x0/0x1c) from [<c0041930>] (__might_sleep+0x11c/0x13c)
> > [<c0041814>] (__might_sleep+0x0/0x13c) from [<c026181c>] (mutex_lock_nested+0x34/0x31c)
> > r4:c032afd4
> > [<c02617e8>] (mutex_lock_nested+0x0/0x31c) from [<c003097c>] (clk_get_sys+0x30/0xe8)
> > [<c003094c>] (clk_get_sys+0x0/0xe8) from [<c00338c8>] (arch_reset+0x18/0x8c)
> > [<c00338b0>] (arch_reset+0x0/0x8c) from [<c0028564>] (arm_machine_restart+0x2c/0x5c)
> > r5:00000000 r4:00000068
> > [<c0028538>] (arm_machine_restart+0x0/0x5c) from [<c0027f3c>] (machine_restart+0x20/0x28)
> > r5:d186b9c0 r4:00000062
> > [<c0027f1c>] (machine_restart+0x0/0x28) from [<c0056db8>] (emergency_restart+0x14/0x18)
> > [<c0056da4>] (emergency_restart+0x0/0x18) from [<c01a9220>] (sysrq_handle_reboot+0x24/0x28)
> > [<c01a91fc>] (sysrq_handle_reboot+0x0/0x28) from [<c01a8eb4>] (__handle_sysrq+0xc0/0x170)
> > [<c01a8df4>] (__handle_sysrq+0x0/0x170) from [<c01a8fd4>] (handle_sysrq+0x34/0x40)
> > [<c01a8fa0>] (handle_sysrq+0x0/0x40) from [<c01aedd8>] (imx_rxint+0xec/0x20c)
> > [<c01aecec>] (imx_rxint+0x0/0x20c) from [<c01aef20>] (imx_int+0x28/0x68)
> > [<c01aeef8>] (imx_int+0x0/0x68) from [<c007a794>] (handle_IRQ_event+0x2c/0x100)
> > r7:0000002d r6:00000000 r5:00000000 r4:d1eab800
> > [<c007a768>] (handle_IRQ_event+0x0/0x100) from [<c007c4fc>] (handle_level_irq+0xbc/0x120)
> > r7:d1eab800 r6:c03340b8 r5:0000002d r4:c033407c
> > [<c007c440>] (handle_level_irq+0x0/0x120) from [<c0026070>] (_text+0x70/0x8c)
> > r7:00000002 r6:002d0000 r5:00000000 r4:0000002d
> > [<c0026000>] (_text+0x0/0x8c) from [<c0026a94>] (__irq_svc+0x54/0xa8)
> > Exception stack(0xc0327f48 to 0xc0327f90)
> > 7f40: 00000001 0016e240 20000093 20000013 c0326000 c032aaa8
> > 7f60: c03541e4 c032aaa0 8001ecc4 41069264 8001ec90 c0327f9c c0327f68 c0327f90
> > 7f80: c006c620 c0027f8c 20000013 ffffffff
> > r5:fc400000 r4:0000001f
> > [<c0027f54>] (default_idle+0x0/0x3c) from [<c00284dc>] (cpu_idle+0x70/0xcc)
> > [<c002846c>] (cpu_idle+0x0/0xcc) from [<c025d338>] (rest_init+0x70/0x84)
> > r7:c032aaa0 r6:c0020e14 r5:c0020e18 r4:c0853ad8
> > [<c025d2c8>] (rest_init+0x0/0x84) from [<c00089a4>] (start_kernel+0x280/0x2d8)
> > [<c0008724>] (start_kernel+0x0/0x2d8) from [<80008034>] (0x80008034)
> > r5:c0354284 r4:00053175
> > ------------[ cut here ]------------
> > WARNING: at /usr/local/src/arm-linux/kernel/mutex.c:207 mutex_lock_nested+0xb4/0x31c()
> > Modules linked in:
> > Backtrace:
> > [<c002aee0>] (dump_backtrace+0x0/0x114) from [<c0260240>] (dump_stack+0x18/0x1c)
> > r7:c02e09d3 r6:000000cf r5:c026189c r4:00000000
> > [<c0260228>] (dump_stack+0x0/0x1c) from [<c004682c>] (warn_slowpath_common+0x50/0x68)
> > [<c00467dc>] (warn_slowpath_common+0x0/0x68) from [<c004685c>] (warn_slowpath_null+0x18/0x1c)
> > r7:00000000 r6:c0326000 r5:c0329868 r4:c032afd4
> > [<c0046844>] (warn_slowpath_null+0x0/0x1c) from [<c026189c>] (mutex_lock_nested+0xb4/0x31c)
> > [<c02617e8>] (mutex_lock_nested+0x0/0x31c) from [<c003097c>] (clk_get_sys+0x30/0xe8)
> > [<c003094c>] (clk_get_sys+0x0/0xe8) from [<c00338c8>] (arch_reset+0x18/0x8c)
> > [<c00338b0>] (arch_reset+0x0/0x8c) from [<c0028564>] (arm_machine_restart+0x2c/0x5c)
> > r5:00000000 r4:00000068
> > [<c0028538>] (arm_machine_restart+0x0/0x5c) from [<c0027f3c>] (machine_restart+0x20/0x28)
> > r5:d186b9c0 r4:00000062
> > [<c0027f1c>] (machine_restart+0x0/0x28) from [<c0056db8>] (emergency_restart+0x14/0x18)
> > [<c0056da4>] (emergency_restart+0x0/0x18) from [<c01a9220>] (sysrq_handle_reboot+0x24/0x28)
> > [<c01a91fc>] (sysrq_handle_reboot+0x0/0x28) from [<c01a8eb4>] (__handle_sysrq+0xc0/0x170)
> > [<c01a8df4>] (__handle_sysrq+0x0/0x170) from [<c01a8fd4>] (handle_sysrq+0x34/0x40)
> > [<c01a8fa0>] (handle_sysrq+0x0/0x40) from [<c01aedd8>] (imx_rxint+0xec/0x20c)
> > [<c01aecec>] (imx_rxint+0x0/0x20c) from [<c01aef20>] (imx_int+0x28/0x68)
> > [<c01aeef8>] (imx_int+0x0/0x68) from [<c007a794>] (handle_IRQ_event+0x2c/0x100)
> > r7:0000002d r6:00000000 r5:00000000 r4:d1eab800
> > [<c007a768>] (handle_IRQ_event+0x0/0x100) from [<c007c4fc>] (handle_level_irq+0xbc/0x120)
> > r7:d1eab800 r6:c03340b8 r5:0000002d r4:c033407c
> > [<c007c440>] (handle_level_irq+0x0/0x120) from [<c0026070>] (_text+0x70/0x8c)
> > r7:00000002 r6:002d0000 r5:00000000 r4:0000002d
> > [<c0026000>] (_text+0x0/0x8c) from [<c0026a94>] (__irq_svc+0x54/0xa8)
> > Exception stack(0xc0327f48 to 0xc0327f90)
> > 7f40: 00000001 0016e240 20000093 20000013 c0326000 c032aaa8
> > 7f60: c03541e4 c032aaa0 8001ecc4 41069264 8001ec90 c0327f9c c0327f68 c0327f90
> > 7f80: c006c620 c0027f8c 20000013 ffffffff
> > r5:fc400000 r4:0000001f
> > [<c0027f54>] (default_idle+0x0/0x3c) from [<c00284dc>] (cpu_idle+0x70/0xcc)
> > [<c002846c>] (cpu_idle+0x0/0xcc) from [<c025d338>] (rest_init+0x70/0x84)
> > r7:c032aaa0 r6:c0020e14 r5:c0020e18 r4:c0853ad8
> > [<c025d2c8>] (rest_init+0x0/0x84) from [<c00089a4>] (start_kernel+0x280/0x2d8)
> > [<c0008724>] (start_kernel+0x0/0x2d8) from [<80008034>] (0x80008034)
> > r5:c0354284 r4:00053175
> > ---[ end trace b484fc13651ee6f1 ]---
> do you care enough to send a patch? If not I can set it on my agenda.
>
I have it on my to-do list for quite some time. I'll finally try to
get it out soon.
Lothar Wa?mann
--
___________________________________________________________
Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996
www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH 03/15] ARM: mxs: Add reset routines
2010-11-26 10:38 ` Lothar Waßmann
2010-11-26 11:32 ` Uwe Kleine-König
@ 2010-11-26 14:16 ` Xinyu Chen
2010-11-26 14:38 ` Lothar Waßmann
1 sibling, 1 reply; 146+ messages in thread
From: Xinyu Chen @ 2010-11-26 14:16 UTC (permalink / raw)
To: linux-arm-kernel
Hi Lothar
2010/11/26 Lothar Wa?mann <LW@karo-electronics.de>:
> Hi,
>
> Uwe Kleine-K?nig writes:
>> On Fri, Nov 26, 2010 at 10:31:46AM +0100, Lothar Wa?mann wrote:
>> > Shawn Guo writes:
>> > [...]
>> > > diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c
>> > > new file mode 100644
>> > > index 0000000..de33c66
>> > > --- /dev/null
>> > > +++ b/arch/arm/mach-mxs/system.c
>> > > @@ -0,0 +1,152 @@
>> > > +/*
>> > > + * Copyright (C) 1999 ARM Limited
>> > > + * Copyright (C) 2000 Deep Blue Solutions Ltd
>> > > + * Copyright 2006-2007,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
>> > > + *
>> > > + * 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/kernel.h>
>> > > +#include <linux/clk.h>
>> > > +#include <linux/io.h>
>> > > +#include <linux/err.h>
>> > > +#include <linux/delay.h>
>> > > +
>> > > +#include <asm/proc-fns.h>
>> > > +#include <asm/system.h>
>> > > +
>> > > +#include <mach/hardware.h>
>> > > +#include <mach/common.h>
>> > > +
>> > > +#define MXS_RTC_WATCHDOG 0x50
>> > > +#define MXS_WATCHDOG_EN ? ? ? ? ?(1 << 4)
>> > > +
>> > > +#define MXS_MODULE_CLKGATE ? ? ? (1 << 30)
>> > > +#define MXS_MODULE_SFTRST ? ? ? ?(1 << 31)
>> > > +
>> > > +static void __iomem *wdog_base;
>> > > +
>> > > +/*
>> > > + * Reset the system. It is called by machine_restart().
>> > > + */
>> > > +void arch_reset(char mode, const char *cmd)
>> > > +{
>> > > + struct clk *clk;
>> > > +
>> > > + clk = clk_get_sys("rtc", NULL);
>> > > + if (!IS_ERR(clk))
>> > > + ? ? ? ? clk_enable(clk);
>> > > +
>> > >
>> > Since arch_reset() may be called from interrupt context (e.g. due to
>> > SYSRQ-B) it must not call any functions that may sleep like clk_get*()
>> > or clk_enable(). The clock should be acquired and enabled in the init
>> > routine.
>> This is a problem that also exist in arch/arm/plat-mxc/system.c's
>> arch_reset.
>>
>> Did you already verify that this is indeed a problem? ?I guess there are
>> more architectures that use clk_get in arch_reset, aren't there?
>>
> If you consider this a problem:
> BUG: sleeping function called from invalid context at /usr/local/src/arm-linux/kernel/mutex.c:
> 280
> in_atomic(): 1, irqs_disabled(): 128, pid: 0, name: swapper
> 2 locks held by swapper/0:
> ?#0: ?(&port_lock_key){-.-...}, at: [<c01aed10>] imx_rxint+0x24/0x20c
> ?#1: ?(sysrq_key_table_lock){-.....}, at: [<c01a8e14>] __handle_sysrq+0x20/0x170
> irq event stamp: 130658
> hardirqs last ?enabled at (130657): [<c0027f80>] default_idle+0x2c/0x3c
> hardirqs last disabled at (130658): [<c0026a74>] __irq_svc+0x34/0xa8
> softirqs last ?enabled at (130648): [<c004bc1c>] __do_softirq+0x144/0x164
> softirqs last disabled at (130637): [<c004bc9c>] irq_exit+0x60/0xb4
> Backtrace:
> [<c002aee0>] (dump_backtrace+0x0/0x114) from [<c0260240>] (dump_stack+0x18/0x1c)
> ?r7:00000000 r6:c0326000 r5:00000000 r4:c0326000
> [<c0260228>] (dump_stack+0x0/0x1c) from [<c0041930>] (__might_sleep+0x11c/0x13c)
> [<c0041814>] (__might_sleep+0x0/0x13c) from [<c026181c>] (mutex_lock_nested+0x34/0x31c)
> ?r4:c032afd4
> [<c02617e8>] (mutex_lock_nested+0x0/0x31c) from [<c003097c>] (clk_get_sys+0x30/0xe8)
> [<c003094c>] (clk_get_sys+0x0/0xe8) from [<c00338c8>] (arch_reset+0x18/0x8c)
> [<c00338b0>] (arch_reset+0x0/0x8c) from [<c0028564>] (arm_machine_restart+0x2c/0x5c)
> ?r5:00000000 r4:00000068
> [<c0028538>] (arm_machine_restart+0x0/0x5c) from [<c0027f3c>] (machine_restart+0x20/0x28)
> ?r5:d186b9c0 r4:00000062
> [<c0027f1c>] (machine_restart+0x0/0x28) from [<c0056db8>] (emergency_restart+0x14/0x18)
> [<c0056da4>] (emergency_restart+0x0/0x18) from [<c01a9220>] (sysrq_handle_reboot+0x24/0x28)
> [<c01a91fc>] (sysrq_handle_reboot+0x0/0x28) from [<c01a8eb4>] (__handle_sysrq+0xc0/0x170)
> [<c01a8df4>] (__handle_sysrq+0x0/0x170) from [<c01a8fd4>] (handle_sysrq+0x34/0x40)
> [<c01a8fa0>] (handle_sysrq+0x0/0x40) from [<c01aedd8>] (imx_rxint+0xec/0x20c)
> [<c01aecec>] (imx_rxint+0x0/0x20c) from [<c01aef20>] (imx_int+0x28/0x68)
> [<c01aeef8>] (imx_int+0x0/0x68) from [<c007a794>] (handle_IRQ_event+0x2c/0x100)
> ?r7:0000002d r6:00000000 r5:00000000 r4:d1eab800
> [<c007a768>] (handle_IRQ_event+0x0/0x100) from [<c007c4fc>] (handle_level_irq+0xbc/0x120)
> ?r7:d1eab800 r6:c03340b8 r5:0000002d r4:c033407c
> [<c007c440>] (handle_level_irq+0x0/0x120) from [<c0026070>] (_text+0x70/0x8c)
> ?r7:00000002 r6:002d0000 r5:00000000 r4:0000002d
> [<c0026000>] (_text+0x0/0x8c) from [<c0026a94>] (__irq_svc+0x54/0xa8)
> Exception stack(0xc0327f48 to 0xc0327f90)
> 7f40: ? ? ? ? ? ? ? ? ? 00000001 0016e240 20000093 20000013 c0326000 c032aaa8
> 7f60: c03541e4 c032aaa0 8001ecc4 41069264 8001ec90 c0327f9c c0327f68 c0327f90
> 7f80: c006c620 c0027f8c 20000013 ffffffff
> ?r5:fc400000 r4:0000001f
> [<c0027f54>] (default_idle+0x0/0x3c) from [<c00284dc>] (cpu_idle+0x70/0xcc)
> [<c002846c>] (cpu_idle+0x0/0xcc) from [<c025d338>] (rest_init+0x70/0x84)
> ?r7:c032aaa0 r6:c0020e14 r5:c0020e18 r4:c0853ad8
> [<c025d2c8>] (rest_init+0x0/0x84) from [<c00089a4>] (start_kernel+0x280/0x2d8)
> [<c0008724>] (start_kernel+0x0/0x2d8) from [<80008034>] (0x80008034)
> ?r5:c0354284 r4:00053175
> ------------[ cut here ]------------
> WARNING: at /usr/local/src/arm-linux/kernel/mutex.c:207 mutex_lock_nested+0xb4/0x31c()
> Modules linked in:
> Backtrace:
> [<c002aee0>] (dump_backtrace+0x0/0x114) from [<c0260240>] (dump_stack+0x18/0x1c)
> ?r7:c02e09d3 r6:000000cf r5:c026189c r4:00000000
> [<c0260228>] (dump_stack+0x0/0x1c) from [<c004682c>] (warn_slowpath_common+0x50/0x68)
> [<c00467dc>] (warn_slowpath_common+0x0/0x68) from [<c004685c>] (warn_slowpath_null+0x18/0x1c)
> ?r7:00000000 r6:c0326000 r5:c0329868 r4:c032afd4
> [<c0046844>] (warn_slowpath_null+0x0/0x1c) from [<c026189c>] (mutex_lock_nested+0xb4/0x31c)
> [<c02617e8>] (mutex_lock_nested+0x0/0x31c) from [<c003097c>] (clk_get_sys+0x30/0xe8)
> [<c003094c>] (clk_get_sys+0x0/0xe8) from [<c00338c8>] (arch_reset+0x18/0x8c)
> [<c00338b0>] (arch_reset+0x0/0x8c) from [<c0028564>] (arm_machine_restart+0x2c/0x5c)
> ?r5:00000000 r4:00000068
> [<c0028538>] (arm_machine_restart+0x0/0x5c) from [<c0027f3c>] (machine_restart+0x20/0x28)
> ?r5:d186b9c0 r4:00000062
> [<c0027f1c>] (machine_restart+0x0/0x28) from [<c0056db8>] (emergency_restart+0x14/0x18)
> [<c0056da4>] (emergency_restart+0x0/0x18) from [<c01a9220>] (sysrq_handle_reboot+0x24/0x28)
> [<c01a91fc>] (sysrq_handle_reboot+0x0/0x28) from [<c01a8eb4>] (__handle_sysrq+0xc0/0x170)
> [<c01a8df4>] (__handle_sysrq+0x0/0x170) from [<c01a8fd4>] (handle_sysrq+0x34/0x40)
> [<c01a8fa0>] (handle_sysrq+0x0/0x40) from [<c01aedd8>] (imx_rxint+0xec/0x20c)
> [<c01aecec>] (imx_rxint+0x0/0x20c) from [<c01aef20>] (imx_int+0x28/0x68)
> [<c01aeef8>] (imx_int+0x0/0x68) from [<c007a794>] (handle_IRQ_event+0x2c/0x100)
> ?r7:0000002d r6:00000000 r5:00000000 r4:d1eab800
> [<c007a768>] (handle_IRQ_event+0x0/0x100) from [<c007c4fc>] (handle_level_irq+0xbc/0x120)
> ?r7:d1eab800 r6:c03340b8 r5:0000002d r4:c033407c
> [<c007c440>] (handle_level_irq+0x0/0x120) from [<c0026070>] (_text+0x70/0x8c)
> ?r7:00000002 r6:002d0000 r5:00000000 r4:0000002d
> [<c0026000>] (_text+0x0/0x8c) from [<c0026a94>] (__irq_svc+0x54/0xa8)
> Exception stack(0xc0327f48 to 0xc0327f90)
> 7f40: ? ? ? ? ? ? ? ? ? 00000001 0016e240 20000093 20000013 c0326000 c032aaa8
> 7f60: c03541e4 c032aaa0 8001ecc4 41069264 8001ec90 c0327f9c c0327f68 c0327f90
> 7f80: c006c620 c0027f8c 20000013 ffffffff
> ?r5:fc400000 r4:0000001f
> [<c0027f54>] (default_idle+0x0/0x3c) from [<c00284dc>] (cpu_idle+0x70/0xcc)
> [<c002846c>] (cpu_idle+0x0/0xcc) from [<c025d338>] (rest_init+0x70/0x84)
> ?r7:c032aaa0 r6:c0020e14 r5:c0020e18 r4:c0853ad8
> [<c025d2c8>] (rest_init+0x0/0x84) from [<c00089a4>] (start_kernel+0x280/0x2d8)
> [<c0008724>] (start_kernel+0x0/0x2d8) from [<80008034>] (0x80008034)
> ?r5:c0354284 r4:00053175
> ---[ end trace b484fc13651ee6f1 ]---
could we use spin_lock but not mutex_lock in the clk_enable/disable?
I'm considering there may have drivers call clk enable/disable in the
irq context to done feature or save power.
--
Best Regards
Xinyu Chen
Freescale Semiconductor, MAD Linux
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH 03/15] ARM: mxs: Add reset routines
2010-11-26 14:16 ` [PATCH 03/15] ARM: mxs: Add reset routines Xinyu Chen
@ 2010-11-26 14:38 ` Lothar Waßmann
0 siblings, 0 replies; 146+ messages in thread
From: Lothar Waßmann @ 2010-11-26 14:38 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
Xinyu Chen writes:
> Hi Lothar
>
> 2010/11/26 Lothar Wa?mann <LW@karo-electronics.de>:
> > If you consider this a problem:
> > BUG: sleeping function called from invalid context at /usr/local/src/arm-linux/kernel/mutex.c:
> > 280
> > in_atomic(): 1, irqs_disabled(): 128, pid: 0, name: swapper
> > 2 locks held by swapper/0:
> > ?#0: ?(&port_lock_key){-.-...}, at: [<c01aed10>] imx_rxint+0x24/0x20c
> > ?#1: ?(sysrq_key_table_lock){-.....}, at: [<c01a8e14>] __handle_sysrq+0x20/0x170
> > irq event stamp: 130658
> > hardirqs last ?enabled at (130657): [<c0027f80>] default_idle+0x2c/0x3c
> > hardirqs last disabled at (130658): [<c0026a74>] __irq_svc+0x34/0xa8
> > softirqs last ?enabled at (130648): [<c004bc1c>] __do_softirq+0x144/0x164
> > softirqs last disabled at (130637): [<c004bc9c>] irq_exit+0x60/0xb4
> > Backtrace:
> > [<c002aee0>] (dump_backtrace+0x0/0x114) from [<c0260240>] (dump_stack+0x18/0x1c)
> > ?r7:00000000 r6:c0326000 r5:00000000 r4:c0326000
> > [<c0260228>] (dump_stack+0x0/0x1c) from [<c0041930>] (__might_sleep+0x11c/0x13c)
> > [<c0041814>] (__might_sleep+0x0/0x13c) from [<c026181c>] (mutex_lock_nested+0x34/0x31c)
> > ?r4:c032afd4
> > [<c02617e8>] (mutex_lock_nested+0x0/0x31c) from [<c003097c>] (clk_get_sys+0x30/0xe8)
> > [<c003094c>] (clk_get_sys+0x0/0xe8) from [<c00338c8>] (arch_reset+0x18/0x8c)
> > [<c00338b0>] (arch_reset+0x0/0x8c) from [<c0028564>] (arm_machine_restart+0x2c/0x5c)
> > ?r5:00000000 r4:00000068
> > [<c0028538>] (arm_machine_restart+0x0/0x5c) from [<c0027f3c>] (machine_restart+0x20/0x28)
> > ?r5:d186b9c0 r4:00000062
> > [<c0027f1c>] (machine_restart+0x0/0x28) from [<c0056db8>] (emergency_restart+0x14/0x18)
> > [<c0056da4>] (emergency_restart+0x0/0x18) from [<c01a9220>] (sysrq_handle_reboot+0x24/0x28)
> > [<c01a91fc>] (sysrq_handle_reboot+0x0/0x28) from [<c01a8eb4>] (__handle_sysrq+0xc0/0x170)
> > [<c01a8df4>] (__handle_sysrq+0x0/0x170) from [<c01a8fd4>] (handle_sysrq+0x34/0x40)
> > [<c01a8fa0>] (handle_sysrq+0x0/0x40) from [<c01aedd8>] (imx_rxint+0xec/0x20c)
> > [<c01aecec>] (imx_rxint+0x0/0x20c) from [<c01aef20>] (imx_int+0x28/0x68)
> > [<c01aeef8>] (imx_int+0x0/0x68) from [<c007a794>] (handle_IRQ_event+0x2c/0x100)
> > ?r7:0000002d r6:00000000 r5:00000000 r4:d1eab800
> > [<c007a768>] (handle_IRQ_event+0x0/0x100) from [<c007c4fc>] (handle_level_irq+0xbc/0x120)
> > ?r7:d1eab800 r6:c03340b8 r5:0000002d r4:c033407c
> > [<c007c440>] (handle_level_irq+0x0/0x120) from [<c0026070>] (_text+0x70/0x8c)
> > ?r7:00000002 r6:002d0000 r5:00000000 r4:0000002d
> > [<c0026000>] (_text+0x0/0x8c) from [<c0026a94>] (__irq_svc+0x54/0xa8)
> > Exception stack(0xc0327f48 to 0xc0327f90)
> > 7f40: ? ? ? ? ? ? ? ? ? 00000001 0016e240 20000093 20000013 c0326000 c032aaa8
> > 7f60: c03541e4 c032aaa0 8001ecc4 41069264 8001ec90 c0327f9c c0327f68 c0327f90
> > 7f80: c006c620 c0027f8c 20000013 ffffffff
> > ?r5:fc400000 r4:0000001f
> > [<c0027f54>] (default_idle+0x0/0x3c) from [<c00284dc>] (cpu_idle+0x70/0xcc)
> > [<c002846c>] (cpu_idle+0x0/0xcc) from [<c025d338>] (rest_init+0x70/0x84)
> > ?r7:c032aaa0 r6:c0020e14 r5:c0020e18 r4:c0853ad8
> > [<c025d2c8>] (rest_init+0x0/0x84) from [<c00089a4>] (start_kernel+0x280/0x2d8)
> > [<c0008724>] (start_kernel+0x0/0x2d8) from [<80008034>] (0x80008034)
> > ?r5:c0354284 r4:00053175
> > ------------[ cut here ]------------
> > WARNING: at /usr/local/src/arm-linux/kernel/mutex.c:207 mutex_lock_nested+0xb4/0x31c()
> > Modules linked in:
> > Backtrace:
> > [<c002aee0>] (dump_backtrace+0x0/0x114) from [<c0260240>] (dump_stack+0x18/0x1c)
> > ?r7:c02e09d3 r6:000000cf r5:c026189c r4:00000000
> > [<c0260228>] (dump_stack+0x0/0x1c) from [<c004682c>] (warn_slowpath_common+0x50/0x68)
> > [<c00467dc>] (warn_slowpath_common+0x0/0x68) from [<c004685c>] (warn_slowpath_null+0x18/0x1c)
> > ?r7:00000000 r6:c0326000 r5:c0329868 r4:c032afd4
> > [<c0046844>] (warn_slowpath_null+0x0/0x1c) from [<c026189c>] (mutex_lock_nested+0xb4/0x31c)
> > [<c02617e8>] (mutex_lock_nested+0x0/0x31c) from [<c003097c>] (clk_get_sys+0x30/0xe8)
> > [<c003094c>] (clk_get_sys+0x0/0xe8) from [<c00338c8>] (arch_reset+0x18/0x8c)
> > [<c00338b0>] (arch_reset+0x0/0x8c) from [<c0028564>] (arm_machine_restart+0x2c/0x5c)
> > ?r5:00000000 r4:00000068
> > [<c0028538>] (arm_machine_restart+0x0/0x5c) from [<c0027f3c>] (machine_restart+0x20/0x28)
> > ?r5:d186b9c0 r4:00000062
> > [<c0027f1c>] (machine_restart+0x0/0x28) from [<c0056db8>] (emergency_restart+0x14/0x18)
> > [<c0056da4>] (emergency_restart+0x0/0x18) from [<c01a9220>] (sysrq_handle_reboot+0x24/0x28)
> > [<c01a91fc>] (sysrq_handle_reboot+0x0/0x28) from [<c01a8eb4>] (__handle_sysrq+0xc0/0x170)
> > [<c01a8df4>] (__handle_sysrq+0x0/0x170) from [<c01a8fd4>] (handle_sysrq+0x34/0x40)
> > [<c01a8fa0>] (handle_sysrq+0x0/0x40) from [<c01aedd8>] (imx_rxint+0xec/0x20c)
> > [<c01aecec>] (imx_rxint+0x0/0x20c) from [<c01aef20>] (imx_int+0x28/0x68)
> > [<c01aeef8>] (imx_int+0x0/0x68) from [<c007a794>] (handle_IRQ_event+0x2c/0x100)
> > ?r7:0000002d r6:00000000 r5:00000000 r4:d1eab800
> > [<c007a768>] (handle_IRQ_event+0x0/0x100) from [<c007c4fc>] (handle_level_irq+0xbc/0x120)
> > ?r7:d1eab800 r6:c03340b8 r5:0000002d r4:c033407c
> > [<c007c440>] (handle_level_irq+0x0/0x120) from [<c0026070>] (_text+0x70/0x8c)
> > ?r7:00000002 r6:002d0000 r5:00000000 r4:0000002d
> > [<c0026000>] (_text+0x0/0x8c) from [<c0026a94>] (__irq_svc+0x54/0xa8)
> > Exception stack(0xc0327f48 to 0xc0327f90)
> > 7f40: ? ? ? ? ? ? ? ? ? 00000001 0016e240 20000093 20000013 c0326000 c032aaa8
> > 7f60: c03541e4 c032aaa0 8001ecc4 41069264 8001ec90 c0327f9c c0327f68 c0327f90
> > 7f80: c006c620 c0027f8c 20000013 ffffffff
> > ?r5:fc400000 r4:0000001f
> > [<c0027f54>] (default_idle+0x0/0x3c) from [<c00284dc>] (cpu_idle+0x70/0xcc)
> > [<c002846c>] (cpu_idle+0x0/0xcc) from [<c025d338>] (rest_init+0x70/0x84)
> > ?r7:c032aaa0 r6:c0020e14 r5:c0020e18 r4:c0853ad8
> > [<c025d2c8>] (rest_init+0x0/0x84) from [<c00089a4>] (start_kernel+0x280/0x2d8)
> > [<c0008724>] (start_kernel+0x0/0x2d8) from [<80008034>] (0x80008034)
> > ?r5:c0354284 r4:00053175
> > ---[ end trace b484fc13651ee6f1 ]---
>
> could we use spin_lock but not mutex_lock in the clk_enable/disable?
> I'm considering there may have drivers call clk enable/disable in the
> irq context to done feature or save power.
>
This has already been discussed in June this year and rejected:
http://lists.infradead.org/pipermail/linux-arm-kernel/2010-June/017758.html
Anyway the offending code in this case is the clk_get_sys() function.
Lothar Wa?mann
--
___________________________________________________________
Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996
www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH 01/15] ARM: mxs: Add core definitions
2010-11-26 11:30 ` Uwe Kleine-König
@ 2010-11-29 7:21 ` Shawn Guo
0 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-11-29 7:21 UTC (permalink / raw)
To: linux-arm-kernel
Hi Uwe,
Thanks for the review.
2010/11/26 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Shawn,
>
> On Fri, Nov 26, 2010 at 02:49:00PM +0800, Shawn Guo wrote:
>> Add core definitions for MXS-based SoC MX23 and MX28.
>>
>> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
>> ---
>> ?arch/arm/mach-mxs/include/mach/hardware.h | ? 66 +++++++++
>> ?arch/arm/mach-mxs/include/mach/irqs.h ? ? | ? 32 ++++
>> ?arch/arm/mach-mxs/include/mach/memory.h ? | ? 24 +++
>> ?arch/arm/mach-mxs/include/mach/mx23.h ? ? | ?147 +++++++++++++++++++
>> ?arch/arm/mach-mxs/include/mach/mx28.h ? ? | ?227 +++++++++++++++++++++++++++++
>> ?arch/arm/mach-mxs/include/mach/mxs.h ? ? ?| ? 60 ++++++++
>> ?6 files changed, 556 insertions(+), 0 deletions(-)
>> ?create mode 100644 arch/arm/mach-mxs/include/mach/hardware.h
>> ?create mode 100644 arch/arm/mach-mxs/include/mach/irqs.h
>> ?create mode 100644 arch/arm/mach-mxs/include/mach/memory.h
>> ?create mode 100644 arch/arm/mach-mxs/include/mach/mx23.h
>> ?create mode 100644 arch/arm/mach-mxs/include/mach/mx28.h
>> ?create mode 100644 arch/arm/mach-mxs/include/mach/mxs.h
>>
>> diff --git a/arch/arm/mach-mxs/include/mach/hardware.h b/arch/arm/mach-mxs/include/mach/hardware.h
>> new file mode 100644
>> index 0000000..5edccd5
>> --- /dev/null
>> +++ b/arch/arm/mach-mxs/include/mach/hardware.h
>> @@ -0,0 +1,66 @@
>> +/*
>> + * Copyright 2004-2007 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
>> + * 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_MXS_HARDWARE_H__
>> +#define __MACH_MXS_HARDWARE_H__
>> +
>> +#include <asm/sizes.h>
>> +
>> +#ifdef __ASSEMBLER__
>> +#define IOMEM(addr) ?(addr)
>> +#else
>> +#define IOMEM(addr) ?((void __force __iomem *)(addr))
>> +#endif
>> +
>> +#define MXS_IO_P2V_MODULE(addr, module) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? (((addr) - module ## _BASE_ADDR) < module ## _SIZE ? ? ? ? ? ? ?\
>> + ? ? ?(addr) - (module ## _BASE_ADDR) + (module ## _BASE_ADDR_VIRT) : 0)
> Do you need this? ?On imx this is only used in
> arch/arm/mach-mx3/mach-kzm_arm11_01.c that uses it to map chip selects.
> IMHO it should better use a dynamic mapping for that which would allow
> to let IMX_IO_P2V_MODULE die.
>
Will remove it.
>> +/*
>> + * It maps the whole address space to [0xf4000000, 0xf5ffffff].
>> + *
>> + * ? OCRAM ? 0x00000000+0x020000 ? ? -> ? ? ?0xf4000000+0x020000
>> + * ? IO ? ? ?0x80000000+0x100000 ? ? -> ? ? ?0xf4400000+0x100000
>> + */
>> +#define MXS_IO_P2V(x) ? ? ? ?( ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
>> + ? ? ? ? ? ? ? ? ? ? 0xf4000000 + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? ? ? ? ? ? ? ? ? (((x) & 0x50000000) >> 6) + ? ? ? ? ? ? ? ? ? ? \
>> + ? ? ? ? ? ? ? ? ? ? (((x) & 0x0b000000) >> 4) + ? ? ? ? ? ? ? ? ? ? \
>> + ? ? ? ? ? ? ? ? ? ? (((x) & 0x000fffff)))
> Did you test this? ?For me MXS_IO_P2V(0x80000000) ==
> MXS_IO_P2V(0x00000000). ?You should be able to choose a much simpler
> function, e.g.
>
> ? ? ? ? ? ? ? ?(0xf4000000 + (((x) & 0x80000000) >> 6) + (((x) & 0x000fffff))))
>
> should work for the two areas above
>
I tested it with limited modules. But I would take your suggestion to
simplify the definition.
>> +
>> +#define MXS_IO_ADDRESS(x) ? ?IOMEM(MXS_IO_P2V(x))
>> +
>> +#ifdef CONFIG_SOC_IMX23
> You don't need to protect inclusion of mach/mx23 if all symbols defined
> in it are properly namespaced.
>
Will remove them.
>> +# include <mach/mx23.h>
>> +#endif
>> +
>> +#ifdef CONFIG_SOC_IMX28
>> +# include <mach/mx28.h>
>> +#endif
>> +
>> +#include <mach/mxs.h>
>> +
>> +#define mxs_map_entry(soc, name, _type) ? ? ?{ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
>> + ? ? .virtual = soc ## _IO_P2V(soc ## _ ## name ## _BASE_ADDR), ? ? ?\
>> + ? ? .pfn = __phys_to_pfn(soc ## _ ## name ## _BASE_ADDR), ? ? ? ? ? \
>> + ? ? .length = soc ## _ ## name ## _SIZE, ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> + ? ? .type = _type, ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?\
>> +}
>> +
>> +#endif /* __MACH_MXS_HARDWARE_H__ */
>> diff --git a/arch/arm/mach-mxs/include/mach/irqs.h b/arch/arm/mach-mxs/include/mach/irqs.h
>> new file mode 100644
>> index 0000000..f771039
>> --- /dev/null
>> +++ b/arch/arm/mach-mxs/include/mach/irqs.h
>> @@ -0,0 +1,32 @@
>> +/*
>> + * ?Copyright 2004-2007 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.
>> + */
>> +
>> +#ifndef __MACH_MXS_IRQS_H__
>> +#define __MACH_MXS_IRQS_H__
>> +
>> +#define MXS_INTERNAL_IRQS ? ?128
>> +
>> +#define MXS_GPIO_IRQ_START ? MXS_INTERNAL_IRQS
>> +
>> +/* the maximum for MXS-based */
>> +#define MXS_GPIO_IRQS ? ? ? ? ? ? ? ?(32 * 5)
>> +
>> +/*
>> + * The next 16 interrupts are for board specific purposes. ?Since
>> + * the kernel can only run on one machine at a time, we can re-use
>> + * these. ?If you need more, increase MXS_BOARD_IRQS, but keep it
>> + * within sensible limits.
>> + */
>> +#define MXS_BOARD_IRQ_START ?(MXS_GPIO_IRQ_START + MXS_GPIO_IRQS)
>> +#define MXS_BOARD_IRQS ? ? ? ? ? ? ? 16
>> +
>> +#define NR_IRQS ? ? ? ? ? ? ? ? ? ? ?(MXS_BOARD_IRQ_START + MXS_BOARD_IRQS)
>> +
>> +#endif /* __MACH_MXS_IRQS_H__ */
>> diff --git a/arch/arm/mach-mxs/include/mach/memory.h b/arch/arm/mach-mxs/include/mach/memory.h
>> new file mode 100644
>> index 0000000..b5420a5
>> --- /dev/null
>> +++ b/arch/arm/mach-mxs/include/mach/memory.h
>> @@ -0,0 +1,24 @@
>> +/*
>> + * 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_MXS_MEMORY_H__
>> +#define __MACH_MXS_MEMORY_H__
>> +
>> +#define PHYS_OFFSET ? ? ? ? ?UL(0x40000000)
>> +
>> +#endif /* __MACH_MXS_MEMORY_H__ */
>> diff --git a/arch/arm/mach-mxs/include/mach/mx23.h b/arch/arm/mach-mxs/include/mach/mx23.h
>> new file mode 100644
>> index 0000000..27a11ee
>> --- /dev/null
>> +++ b/arch/arm/mach-mxs/include/mach/mx23.h
>> @@ -0,0 +1,147 @@
>> +/*
>> + * 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_MX23_H__
>> +#define __MACH_MX23_H__
>> +
>> +#ifndef __ASSEMBLER__
>> +#include <linux/io.h>
>> +#endif
>> +
>> +/*
>> + * OCRAM
>> + */
>> +#define MX23_OCRAM_BASE_ADDR ? ? ? ? 0x00000000
>> +#define MX23_OCRAM_SIZE ? ? ? ? ? ? ? ? ? ? ?SZ_32K
>> +
>> +/*
>> + * IO
>> + */
>> +#define MX23_IO_BASE_ADDR ? ? ? ? ? ?0x80000000
>> +#define MX23_IO_SIZE ? ? ? ? ? ? ? ? SZ_1M
>> +
>> +#define MX23_ICOLL_BASE_ADDR ? ? ? ? (MX23_IO_BASE_ADDR + 0x000000)
>> +#define MX23_APBH_DMA_BASE_ADDR ? ? ? ? ? ? ?(MX23_IO_BASE_ADDR + 0x004000)
>> +#define MX23_BCH_BASE_ADDR ? ? ? ? ? (MX23_IO_BASE_ADDR + 0x00a000)
>> +#define MX23_GPMI_BASE_ADDR ? ? ? ? ?(MX23_IO_BASE_ADDR + 0x00c000)
>> +#define MX23_SSP1_BASE_ADDR ? ? ? ? ?(MX23_IO_BASE_ADDR + 0x010000)
>> +#define MX23_SSP2_BASE_ADDR ? ? ? ? ?(MX23_IO_BASE_ADDR + 0x034000)
>> +#define MX23_PINCTRL_BASE_ADDR ? ? ? ? ? ? ? (MX23_IO_BASE_ADDR + 0x018000)
>> +#define MX23_DIGCTL_BASE_ADDR ? ? ? ? ? ? ? ?(MX23_IO_BASE_ADDR + 0x01c000)
>> +#define MX23_ETM_BASE_ADDR ? ? ? ? ? (MX23_IO_BASE_ADDR + 0x020000)
>> +#define MX23_APBX_DMA_BASE_ADDR ? ? ? ? ? ? ?(MX23_IO_BASE_ADDR + 0x024000)
>> +#define MX23_DCP_BASE_ADDR ? ? ? ? ? (MX23_IO_BASE_ADDR + 0x028000)
>> +#define MX23_PXP_BASE_ADDR ? ? ? ? ? (MX23_IO_BASE_ADDR + 0x02a000)
>> +#define MX23_OCOTP_BASE_ADDR ? ? ? ? (MX23_IO_BASE_ADDR + 0x02c000)
>> +#define MX23_AXI_AHB0_BASE_ADDR ? ? ? ? ? ? ?(MX23_IO_BASE_ADDR + 0x02e000)
>> +#define MX23_LCDIF_BASE_ADDR ? ? ? ? (MX23_IO_BASE_ADDR + 0x030000)
>> +#define MX23_TVENC_BASE_ADDR ? ? ? ? (MX23_IO_BASE_ADDR + 0x038000)
>> +#define MX23_CLKCTRL_BASE_ADDR ? ? ? ? ? ? ? (MX23_IO_BASE_ADDR + 0x040000)
>> +#define MX23_SAIF0_BASE_ADDR ? ? ? ? (MX23_IO_BASE_ADDR + 0x042000)
>> +#define MX23_POWER_BASE_ADDR ? ? ? ? (MX23_IO_BASE_ADDR + 0x044000)
>> +#define MX23_SAIF1_BASE_ADDR ? ? ? ? (MX23_IO_BASE_ADDR + 0x046000)
>> +#define MX23_AUDIOOUT_BASE_ADDR ? ? ? ? ? ? ?(MX23_IO_BASE_ADDR + 0x048000)
>> +#define MX23_AUDIOIN_BASE_ADDR ? ? ? ? ? ? ? (MX23_IO_BASE_ADDR + 0x04c000)
>> +#define MX23_LRADC_BASE_ADDR ? ? ? ? (MX23_IO_BASE_ADDR + 0x050000)
>> +#define MX23_SPDIF_BASE_ADDR ? ? ? ? (MX23_IO_BASE_ADDR + 0x054000)
>> +#define MX23_RTC_BASE_ADDR ? ? ? ? ? (MX23_IO_BASE_ADDR + 0x05c000)
>> +#define MX23_I2C0_BASE_ADDR ? ? ? ? ?(MX23_IO_BASE_ADDR + 0x058000)
>> +#define MX23_PWM_BASE_ADDR ? ? ? ? ? (MX23_IO_BASE_ADDR + 0x064000)
>> +#define MX23_TIMROT_BASE_ADDR ? ? ? ? ? ? ? ?(MX23_IO_BASE_ADDR + 0x068000)
>> +#define MX23_AUART1_BASE_ADDR ? ? ? ? ? ? ? ?(MX23_IO_BASE_ADDR + 0x06c000)
>> +#define MX23_AUART2_BASE_ADDR ? ? ? ? ? ? ? ?(MX23_IO_BASE_ADDR + 0x06e000)
>> +#define MX23_DUART_BASE_ADDR ? ? ? ? (MX23_IO_BASE_ADDR + 0x070000)
>> +#define MX23_USBPHY_BASE_ADDR ? ? ? ? ? ? ? ?(MX23_IO_BASE_ADDR + 0x07c000)
>> +#define MX23_USBCTRL_BASE_ADDR ? ? ? ? ? ? ? (MX23_IO_BASE_ADDR + 0x080000)
>> +#define MX23_DRAM_BASE_ADDR ? ? ? ? ?(MX23_IO_BASE_ADDR + 0x0e0000)
>> +
>> +#define MX23_IO_P2V(x) ? ? ? ? ? ? ? ? ? ? ? MXS_IO_P2V(x)
>> +#define MX23_IO_ADDRESS(x) ? ? ? ? ? IOMEM(MX23_IO_P2V(x))
>> +
>> +/*
>> + * IRQ
>> + */
>> +#define MX23_INT_DUART ? ? ? ? ? ? ? ? ? ? ? 0
>> +#define MX23_INT_COMMS_RX ? ? ? ? ? ?1
>> +#define MX23_INT_COMMS_TX ? ? ? ? ? ?1
> really two names for irq 1?
>
i.MX23 Application Processor Reference Manual, section 5.2.3 Interrupt Sources.
>> +#define MX23_INT_SSP2_ERROR ? ? ? ? ?2
>> +#define MX23_INT_VDD5V ? ? ? ? ? ? ? ? ? ? ? 3
>> +#define MX23_INT_HEADPHONE_SHORT ? ? 4
>> +#define MX23_INT_DAC_DMA ? ? ? ? ? ? 5
>> +#define MX23_INT_DAC_ERROR ? ? ? ? ? 6
>> +#define MX23_INT_ADC_DMA ? ? ? ? ? ? 7
>> +#define MX23_INT_ADC_ERROR ? ? ? ? ? 8
>> +#define MX23_INT_SPDIF_DMA ? ? ? ? ? 9
>> +#define MX23_INT_SAIF2_DMA ? ? ? ? ? 9
> ditto
>
>> +#define MX23_INT_SPDIF_ERROR ? ? ? ? 10
>> +#define MX23_INT_SAIF1_IRQ ? ? ? ? ? 10
>> +#define MX23_INT_SAIF2_IRQ ? ? ? ? ? 10
> ditto (3 that is)
>> +#define MX23_INT_USB_CTRL ? ? ? ? ? ?11
>> +#define MX23_INT_USB_WAKEUP ? ? ? ? ?12
>> +#define MX23_INT_GPMI_DMA ? ? ? ? ? ?13
>> +#define MX23_INT_SSP1_DMA ? ? ? ? ? ?14
>> +#define MX23_INT_SSP_ERROR ? ? ? ? ? 15
>> +#define MX23_INT_GPIO0 ? ? ? ? ? ? ? ? ? ? ? 16
>> +#define MX23_INT_GPIO1 ? ? ? ? ? ? ? ? ? ? ? 17
>> +#define MX23_INT_GPIO2 ? ? ? ? ? ? ? ? ? ? ? 18
>> +#define MX23_INT_SAIF1_DMA ? ? ? ? ? 19
>> +#define MX23_INT_SSP2_DMA ? ? ? ? ? ?20
>> +#define MX23_INT_ECC8_IRQ ? ? ? ? ? ?21
>> +#define MX23_INT_RTC_ALARM ? ? ? ? ? 22
>> +#define MX23_INT_UARTAPP_TX_DMA ? ? ? ? ? ? ?23
>> +#define MX23_INT_UARTAPP_INTERNAL ? ?24
>> +#define MX23_INT_UARTAPP_RX_DMA ? ? ? ? ? ? ?25
>> +#define MX23_INT_I2C_DMA ? ? ? ? ? ? 26
>> +#define MX23_INT_I2C_ERROR ? ? ? ? ? 27
>> +#define MX23_INT_TIMER0 ? ? ? ? ? ? ? ? ? ? ?28
>> +#define MX23_INT_TIMER1 ? ? ? ? ? ? ? ? ? ? ?29
>> +#define MX23_INT_TIMER2 ? ? ? ? ? ? ? ? ? ? ?30
>> +#define MX23_INT_TIMER3 ? ? ? ? ? ? ? ? ? ? ?31
>> +#define MX23_INT_BATT_BRNOUT ? ? ? ? 32
>> +#define MX23_INT_VDDD_BRNOUT ? ? ? ? 33
>> +#define MX23_INT_VDDIO_BRNOUT ? ? ? ? ? ? ? ?34
>> +#define MX23_INT_VDD18_BRNOUT ? ? ? ? ? ? ? ?35
>> +#define MX23_INT_TOUCH_DETECT ? ? ? ? ? ? ? ?36
>> +#define MX23_INT_LRADC_CH0 ? ? ? ? ? 37
>> +#define MX23_INT_LRADC_CH1 ? ? ? ? ? 38
>> +#define MX23_INT_LRADC_CH2 ? ? ? ? ? 39
>> +#define MX23_INT_LRADC_CH3 ? ? ? ? ? 40
>> +#define MX23_INT_LRADC_CH4 ? ? ? ? ? 41
>> +#define MX23_INT_LRADC_CH5 ? ? ? ? ? 42
>> +#define MX23_INT_LRADC_CH6 ? ? ? ? ? 43
>> +#define MX23_INT_LRADC_CH7 ? ? ? ? ? 44
>> +#define MX23_INT_LCDIF_DMA ? ? ? ? ? 45
>> +#define MX23_INT_LCDIF_ERROR ? ? ? ? 46
>> +#define MX23_INT_DIGCTL_DEBUG_TRAP ? 47
>> +#define MX23_INT_RTC_1MSEC ? ? ? ? ? 48
>> +#define MX23_INT_DRI_DMA ? ? ? ? ? ? 49
>> +#define MX23_INT_DRI_ATTENTION ? ? ? ? ? ? ? 50
>> +#define MX23_INT_GPMI_ATTENTION ? ? ? ? ? ? ?51
>> +#define MX23_INT_IR ? ? ? ? ? ? ? ? ?52
>> +#define MX23_INT_DCP_VMI ? ? ? ? ? ? 53
>> +#define MX23_INT_DCP ? ? ? ? ? ? ? ? 54
>> +#define MX23_INT_BCH ? ? ? ? ? ? ? ? 56
>> +#define MX23_INT_PXP ? ? ? ? ? ? ? ? 57
>> +#define MX23_INT_UARTAPP2_TX_DMA ? ? 58
>> +#define MX23_INT_UARTAPP2_INTERNAL ? 59
>> +#define MX23_INT_UARTAPP2_RX_DMA ? ? 60
>> +#define MX23_INT_VDAC_DETECT ? ? ? ? 61
>> +#define MX23_INT_VDD5V_DROOP ? ? ? ? 64
>> +#define MX23_INT_DCDC4P2_BO ? ? ? ? ?65
>> +
>> +#endif /* __MACH_MX23_H__ */
>> diff --git a/arch/arm/mach-mxs/include/mach/mx28.h b/arch/arm/mach-mxs/include/mach/mx28.h
>> new file mode 100644
>> index 0000000..836d807
>> --- /dev/null
>> +++ b/arch/arm/mach-mxs/include/mach/mx28.h
>> @@ -0,0 +1,227 @@
>> +/*
>> + * 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
>> +
>> +/*
>> + * 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_MAC0_BASE_ADDR ? ? (MX28_IO_BASE_ADDR + 0x0f0000)
>> +#define MX28_ENET_MAC1_BASE_ADDR ? ? (MX28_IO_BASE_ADDR + 0x0f4000)
>> +
>> +#define MX28_IO_P2V(x) ? ? ? ? ? ? ? ? ? ? ? MXS_IO_P2V(x)
>> +#define MX28_IO_ADDRESS(x) ? ? ? ? ? IOMEM(MX28_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
>> +
>> +#endif /* __MACH_MX28_H__ */
>> diff --git a/arch/arm/mach-mxs/include/mach/mxs.h b/arch/arm/mach-mxs/include/mach/mxs.h
>> new file mode 100644
>> index 0000000..128c114
>> --- /dev/null
>> +++ b/arch/arm/mach-mxs/include/mach/mxs.h
>> @@ -0,0 +1,60 @@
>> +/*
>> + * 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_MXS_H__
>> +#define __MACH_MXS_H__
>> +
>> +#define MXS_SET_ADDR ? ? ? ? 0x4
>> +#define MXS_CLR_ADDR ? ? ? ? 0x8
>> +#define MXS_TOG_ADDR ? ? ? ? 0xc
>> +
>> +/*
>> + * MXS CPU types
>> + */
>> +#define MXS_CPU_MX23 ? ? ? ? 23
>> +#define MXS_CPU_MX28 ? ? ? ? 28
>> +
>> +#ifndef __ASSEMBLY__
>> +extern unsigned int __mxs_cpu_type;
>> +#endif
>> +
>> +#ifdef CONFIG_SOC_IMX23
>> +# ifdef mxs_cpu_type
>> +# ?undef mxs_cpu_type
>> +# ?define mxs_cpu_type __mxs_cpu_type
>> +# else
>> +# ?define mxs_cpu_type MXS_CPU_MX23
>> +# endif
>> +# define cpu_is_mx23() ? ? ? ? ? ? ? (mxs_cpu_type == MXS_CPU_MX23)
>> +#else
>> +# define cpu_is_mx23() ? ? ? ? ? ? ? (0)
>> +#endif
>> +
>> +#ifdef CONFIG_SOC_IMX28
>> +# ifdef mxs_cpu_type
>> +# ?undef mxs_cpu_type
>> +# ?define mxs_cpu_type __mxs_cpu_type
>> +# else
>> +# ?define mxs_cpu_type MXS_CPU_MX28
>> +# endif
>> +# define cpu_is_mx28() ? ? ? ? ? ? ? (mxs_cpu_type == MXS_CPU_MX28)
>> +#else
>> +# define cpu_is_mx28() ? ? ? ? ? ? ? (0)
>> +#endif
> For imx I wondered if this is overkill. ?When I started mainlining
> ns9xxx I just did:
>
> ? ? ? ?#define cpu_is_xyz() (machine_is_abc() || ...)
>
> It's much easier and the generated code probably is not much worse.
> (Better try to reduce the number of usages of these macros.)
>
> (Note, if you're convinced this is good, go ahead, just my personal
> opinion.)
>
Your suggestion make sense to me. I will take it.
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH] prevent 'BUG: sleeping function called from invalid context' in arch_reset()
2010-11-26 11:32 ` Uwe Kleine-König
2010-11-26 12:53 ` Lothar Waßmann
@ 2010-11-29 9:25 ` Lothar Waßmann
2010-11-29 9:58 ` Uwe Kleine-König
1 sibling, 1 reply; 146+ messages in thread
From: Lothar Waßmann @ 2010-11-29 9:25 UTC (permalink / raw)
To: linux-arm-kernel
arch_reset() may be called from interrupt context (e.g. induced by
SYSRQ-B), thus clk_get() and clk_enable() must not be called from
within arch_reset(). Move these calls to mxc_arch_reset_init().
Signed-off-by: Lothar Wa?mann <LW@KARO-electronics.de>
---
diff --git a/arch/arm/plat-mxc/system.c b/arch/arm/plat-mxc/system.c
index c3972c5..9b02251 100644
--- a/arch/arm/plat-mxc/system.c
+++ b/arch/arm/plat-mxc/system.c
@@ -53,11 +53,6 @@ void arch_reset(char mode, const char *cmd)
if (cpu_is_mx1()) {
wcr_enable = (1 << 0);
} else {
- struct clk *clk;
-
- clk = clk_get_sys("imx-wdt.0", NULL);
- if (!IS_ERR(clk))
- clk_enable(clk);
wcr_enable = (1 << 2);
}
@@ -78,5 +73,14 @@ void arch_reset(char mode, const char *cmd)
void mxc_arch_reset_init(void __iomem *base)
{
+ struct clk *clk;
+
wdog_base = base;
+
+ if (cpu_is_mx1())
+ return;
+
+ clk = clk_get_sys("imx-wdt.0", NULL);
+ if (!IS_ERR(clk))
+ clk_enable(clk);
}
Lothar Wa?mann
--
___________________________________________________________
Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996
www.karo-electronics.de | info@karo-electronics.de
___________________________________________________________
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH] prevent 'BUG: sleeping function called from invalid context' in arch_reset()
2010-11-29 9:25 ` [PATCH] prevent 'BUG: sleeping function called from invalid context' in arch_reset() Lothar Waßmann
@ 2010-11-29 9:58 ` Uwe Kleine-König
2010-12-06 16:13 ` Uwe Kleine-König
0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-11-29 9:58 UTC (permalink / raw)
To: linux-arm-kernel
Hello Lothar,
On Mon, Nov 29, 2010 at 10:25:34AM +0100, Lothar Wa?mann wrote:
> arch_reset() may be called from interrupt context (e.g. induced by
> SYSRQ-B), thus clk_get() and clk_enable() must not be called from
> within arch_reset(). Move these calls to mxc_arch_reset_init().
I wonder if SYSRQ-B is the only way to trigger that. And if yes if that
could be "fixed" to allow sleeping?!
> Signed-off-by: Lothar Wa?mann <LW@KARO-electronics.de>
> ---
> diff --git a/arch/arm/plat-mxc/system.c b/arch/arm/plat-mxc/system.c
> index c3972c5..9b02251 100644
> --- a/arch/arm/plat-mxc/system.c
> +++ b/arch/arm/plat-mxc/system.c
> @@ -53,11 +53,6 @@ void arch_reset(char mode, const char *cmd)
> if (cpu_is_mx1()) {
> wcr_enable = (1 << 0);
> } else {
> - struct clk *clk;
> -
> - clk = clk_get_sys("imx-wdt.0", NULL);
> - if (!IS_ERR(clk))
> - clk_enable(clk);
> wcr_enable = (1 << 2);
> }
>
> @@ -78,5 +73,14 @@ void arch_reset(char mode, const char *cmd)
>
> void mxc_arch_reset_init(void __iomem *base)
> {
> + struct clk *clk;
> +
> wdog_base = base;
> +
> + if (cpu_is_mx1())
> + return;
> +
> + clk = clk_get_sys("imx-wdt.0", NULL);
> + if (!IS_ERR(clk))
> + clk_enable(clk);
> }
Unrelated to this patch, I wonder why this isn't named "imx2-wdt.0". I
just checked, the driver (drivers/watchdog/imx2_wdt.c) uses clk_get_sys,
too. IMHO we should rename that.
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 01/15] ARM: mxs: Add core definitions
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (14 preceding siblings ...)
2010-11-26 6:49 ` [PATCH 15/15] ARM: mxs: Add build configuration for mxs Shawn Guo
@ 2010-11-29 11:59 ` Shawn Guo
2010-11-30 9:21 ` Uwe Kleine-König
2010-11-29 11:59 ` [PATCH v2 02/15] ARM: mxs: Add helper definition and function Shawn Guo
` (30 subsequent siblings)
46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-11-29 11:59 UTC (permalink / raw)
To: linux-arm-kernel
Add core definitions for MXS-based SoC MX23 and MX28.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
- Remove MXS_IO_P2V_MODULE from hardware.h which is not needed
- Simplify MXS_IO_P2V_MODULE definition in hardware.h
- Remove unnecessary inclusion protection from hardware.h
- Change cpu_is_mx23/mx28() implementation in mxs.h to use machine_is_xxx
arch/arm/mach-mxs/include/mach/hardware.h | 55 +++++++
arch/arm/mach-mxs/include/mach/irqs.h | 32 ++++
arch/arm/mach-mxs/include/mach/memory.h | 24 +++
arch/arm/mach-mxs/include/mach/mx23.h | 147 +++++++++++++++++++
arch/arm/mach-mxs/include/mach/mx28.h | 227 +++++++++++++++++++++++++++++
arch/arm/mach-mxs/include/mach/mxs.h | 43 ++++++
6 files changed, 528 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/include/mach/hardware.h
create mode 100644 arch/arm/mach-mxs/include/mach/irqs.h
create mode 100644 arch/arm/mach-mxs/include/mach/memory.h
create mode 100644 arch/arm/mach-mxs/include/mach/mx23.h
create mode 100644 arch/arm/mach-mxs/include/mach/mx28.h
create mode 100644 arch/arm/mach-mxs/include/mach/mxs.h
diff --git a/arch/arm/mach-mxs/include/mach/hardware.h b/arch/arm/mach-mxs/include/mach/hardware.h
new file mode 100644
index 0000000..9e757e0
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/hardware.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2004-2007 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
+ * 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_MXS_HARDWARE_H__
+#define __MACH_MXS_HARDWARE_H__
+
+#include <asm/sizes.h>
+
+#ifdef __ASSEMBLER__
+#define IOMEM(addr) (addr)
+#else
+#define IOMEM(addr) ((void __force __iomem *)(addr))
+#endif
+
+/*
+ * It maps the whole address space to [0xf4000000, 0xf5ffffff].
+ *
+ * OCRAM 0x00000000+0x020000 -> 0xf4000000+0x020000
+ * IO 0x80000000+0x100000 -> 0xf4400000+0x100000
+ */
+#define MXS_IO_P2V(x) (0xf4000000 + \
+ (((x) & 0x80000000) >> 6) + \
+ (((x) & 0x000fffff)))
+
+
+#define MXS_IO_ADDRESS(x) IOMEM(MXS_IO_P2V(x))
+
+#include <mach/mx23.h>
+#include <mach/mx28.h>
+#include <mach/mxs.h>
+
+#define mxs_map_entry(soc, name, _type) { \
+ .virtual = soc ## _IO_P2V(soc ## _ ## name ## _BASE_ADDR), \
+ .pfn = __phys_to_pfn(soc ## _ ## name ## _BASE_ADDR), \
+ .length = soc ## _ ## name ## _SIZE, \
+ .type = _type, \
+}
+
+#endif /* __MACH_MXS_HARDWARE_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/irqs.h b/arch/arm/mach-mxs/include/mach/irqs.h
new file mode 100644
index 0000000..f771039
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/irqs.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2004-2007 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.
+ */
+
+#ifndef __MACH_MXS_IRQS_H__
+#define __MACH_MXS_IRQS_H__
+
+#define MXS_INTERNAL_IRQS 128
+
+#define MXS_GPIO_IRQ_START MXS_INTERNAL_IRQS
+
+/* the maximum for MXS-based */
+#define MXS_GPIO_IRQS (32 * 5)
+
+/*
+ * The next 16 interrupts are for board specific purposes. Since
+ * the kernel can only run on one machine at a time, we can re-use
+ * these. If you need more, increase MXS_BOARD_IRQS, but keep it
+ * within sensible limits.
+ */
+#define MXS_BOARD_IRQ_START (MXS_GPIO_IRQ_START + MXS_GPIO_IRQS)
+#define MXS_BOARD_IRQS 16
+
+#define NR_IRQS (MXS_BOARD_IRQ_START + MXS_BOARD_IRQS)
+
+#endif /* __MACH_MXS_IRQS_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/memory.h b/arch/arm/mach-mxs/include/mach/memory.h
new file mode 100644
index 0000000..b5420a5
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/memory.h
@@ -0,0 +1,24 @@
+/*
+ * 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_MXS_MEMORY_H__
+#define __MACH_MXS_MEMORY_H__
+
+#define PHYS_OFFSET UL(0x40000000)
+
+#endif /* __MACH_MXS_MEMORY_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mx23.h b/arch/arm/mach-mxs/include/mach/mx23.h
new file mode 100644
index 0000000..27a11ee
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mx23.h
@@ -0,0 +1,147 @@
+/*
+ * 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_MX23_H__
+#define __MACH_MX23_H__
+
+#ifndef __ASSEMBLER__
+#include <linux/io.h>
+#endif
+
+/*
+ * OCRAM
+ */
+#define MX23_OCRAM_BASE_ADDR 0x00000000
+#define MX23_OCRAM_SIZE SZ_32K
+
+/*
+ * IO
+ */
+#define MX23_IO_BASE_ADDR 0x80000000
+#define MX23_IO_SIZE SZ_1M
+
+#define MX23_ICOLL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x000000)
+#define MX23_APBH_DMA_BASE_ADDR (MX23_IO_BASE_ADDR + 0x004000)
+#define MX23_BCH_BASE_ADDR (MX23_IO_BASE_ADDR + 0x00a000)
+#define MX23_GPMI_BASE_ADDR (MX23_IO_BASE_ADDR + 0x00c000)
+#define MX23_SSP1_BASE_ADDR (MX23_IO_BASE_ADDR + 0x010000)
+#define MX23_SSP2_BASE_ADDR (MX23_IO_BASE_ADDR + 0x034000)
+#define MX23_PINCTRL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x018000)
+#define MX23_DIGCTL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x01c000)
+#define MX23_ETM_BASE_ADDR (MX23_IO_BASE_ADDR + 0x020000)
+#define MX23_APBX_DMA_BASE_ADDR (MX23_IO_BASE_ADDR + 0x024000)
+#define MX23_DCP_BASE_ADDR (MX23_IO_BASE_ADDR + 0x028000)
+#define MX23_PXP_BASE_ADDR (MX23_IO_BASE_ADDR + 0x02a000)
+#define MX23_OCOTP_BASE_ADDR (MX23_IO_BASE_ADDR + 0x02c000)
+#define MX23_AXI_AHB0_BASE_ADDR (MX23_IO_BASE_ADDR + 0x02e000)
+#define MX23_LCDIF_BASE_ADDR (MX23_IO_BASE_ADDR + 0x030000)
+#define MX23_TVENC_BASE_ADDR (MX23_IO_BASE_ADDR + 0x038000)
+#define MX23_CLKCTRL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x040000)
+#define MX23_SAIF0_BASE_ADDR (MX23_IO_BASE_ADDR + 0x042000)
+#define MX23_POWER_BASE_ADDR (MX23_IO_BASE_ADDR + 0x044000)
+#define MX23_SAIF1_BASE_ADDR (MX23_IO_BASE_ADDR + 0x046000)
+#define MX23_AUDIOOUT_BASE_ADDR (MX23_IO_BASE_ADDR + 0x048000)
+#define MX23_AUDIOIN_BASE_ADDR (MX23_IO_BASE_ADDR + 0x04c000)
+#define MX23_LRADC_BASE_ADDR (MX23_IO_BASE_ADDR + 0x050000)
+#define MX23_SPDIF_BASE_ADDR (MX23_IO_BASE_ADDR + 0x054000)
+#define MX23_RTC_BASE_ADDR (MX23_IO_BASE_ADDR + 0x05c000)
+#define MX23_I2C0_BASE_ADDR (MX23_IO_BASE_ADDR + 0x058000)
+#define MX23_PWM_BASE_ADDR (MX23_IO_BASE_ADDR + 0x064000)
+#define MX23_TIMROT_BASE_ADDR (MX23_IO_BASE_ADDR + 0x068000)
+#define MX23_AUART1_BASE_ADDR (MX23_IO_BASE_ADDR + 0x06c000)
+#define MX23_AUART2_BASE_ADDR (MX23_IO_BASE_ADDR + 0x06e000)
+#define MX23_DUART_BASE_ADDR (MX23_IO_BASE_ADDR + 0x070000)
+#define MX23_USBPHY_BASE_ADDR (MX23_IO_BASE_ADDR + 0x07c000)
+#define MX23_USBCTRL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x080000)
+#define MX23_DRAM_BASE_ADDR (MX23_IO_BASE_ADDR + 0x0e0000)
+
+#define MX23_IO_P2V(x) MXS_IO_P2V(x)
+#define MX23_IO_ADDRESS(x) IOMEM(MX23_IO_P2V(x))
+
+/*
+ * IRQ
+ */
+#define MX23_INT_DUART 0
+#define MX23_INT_COMMS_RX 1
+#define MX23_INT_COMMS_TX 1
+#define MX23_INT_SSP2_ERROR 2
+#define MX23_INT_VDD5V 3
+#define MX23_INT_HEADPHONE_SHORT 4
+#define MX23_INT_DAC_DMA 5
+#define MX23_INT_DAC_ERROR 6
+#define MX23_INT_ADC_DMA 7
+#define MX23_INT_ADC_ERROR 8
+#define MX23_INT_SPDIF_DMA 9
+#define MX23_INT_SAIF2_DMA 9
+#define MX23_INT_SPDIF_ERROR 10
+#define MX23_INT_SAIF1_IRQ 10
+#define MX23_INT_SAIF2_IRQ 10
+#define MX23_INT_USB_CTRL 11
+#define MX23_INT_USB_WAKEUP 12
+#define MX23_INT_GPMI_DMA 13
+#define MX23_INT_SSP1_DMA 14
+#define MX23_INT_SSP_ERROR 15
+#define MX23_INT_GPIO0 16
+#define MX23_INT_GPIO1 17
+#define MX23_INT_GPIO2 18
+#define MX23_INT_SAIF1_DMA 19
+#define MX23_INT_SSP2_DMA 20
+#define MX23_INT_ECC8_IRQ 21
+#define MX23_INT_RTC_ALARM 22
+#define MX23_INT_UARTAPP_TX_DMA 23
+#define MX23_INT_UARTAPP_INTERNAL 24
+#define MX23_INT_UARTAPP_RX_DMA 25
+#define MX23_INT_I2C_DMA 26
+#define MX23_INT_I2C_ERROR 27
+#define MX23_INT_TIMER0 28
+#define MX23_INT_TIMER1 29
+#define MX23_INT_TIMER2 30
+#define MX23_INT_TIMER3 31
+#define MX23_INT_BATT_BRNOUT 32
+#define MX23_INT_VDDD_BRNOUT 33
+#define MX23_INT_VDDIO_BRNOUT 34
+#define MX23_INT_VDD18_BRNOUT 35
+#define MX23_INT_TOUCH_DETECT 36
+#define MX23_INT_LRADC_CH0 37
+#define MX23_INT_LRADC_CH1 38
+#define MX23_INT_LRADC_CH2 39
+#define MX23_INT_LRADC_CH3 40
+#define MX23_INT_LRADC_CH4 41
+#define MX23_INT_LRADC_CH5 42
+#define MX23_INT_LRADC_CH6 43
+#define MX23_INT_LRADC_CH7 44
+#define MX23_INT_LCDIF_DMA 45
+#define MX23_INT_LCDIF_ERROR 46
+#define MX23_INT_DIGCTL_DEBUG_TRAP 47
+#define MX23_INT_RTC_1MSEC 48
+#define MX23_INT_DRI_DMA 49
+#define MX23_INT_DRI_ATTENTION 50
+#define MX23_INT_GPMI_ATTENTION 51
+#define MX23_INT_IR 52
+#define MX23_INT_DCP_VMI 53
+#define MX23_INT_DCP 54
+#define MX23_INT_BCH 56
+#define MX23_INT_PXP 57
+#define MX23_INT_UARTAPP2_TX_DMA 58
+#define MX23_INT_UARTAPP2_INTERNAL 59
+#define MX23_INT_UARTAPP2_RX_DMA 60
+#define MX23_INT_VDAC_DETECT 61
+#define MX23_INT_VDD5V_DROOP 64
+#define MX23_INT_DCDC4P2_BO 65
+
+#endif /* __MACH_MX23_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mx28.h b/arch/arm/mach-mxs/include/mach/mx28.h
new file mode 100644
index 0000000..836d807
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mx28.h
@@ -0,0 +1,227 @@
+/*
+ * 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
+
+/*
+ * 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_MAC0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0f0000)
+#define MX28_ENET_MAC1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0f4000)
+
+#define MX28_IO_P2V(x) MXS_IO_P2V(x)
+#define MX28_IO_ADDRESS(x) IOMEM(MX28_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
+
+#endif /* __MACH_MX28_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mxs.h b/arch/arm/mach-mxs/include/mach/mxs.h
new file mode 100644
index 0000000..b691c34
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mxs.h
@@ -0,0 +1,43 @@
+/*
+ * 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_MXS_H__
+#define __MACH_MXS_H__
+
+#include <asm/mach-types.h>
+
+#define MXS_SET_ADDR 0x4
+#define MXS_CLR_ADDR 0x8
+#define MXS_TOG_ADDR 0xc
+
+/*
+ * MXS CPU types
+ */
+#ifdef CONFIG_SOC_IMX23
+# define cpu_is_mx23() (machine_is_mx23evk())
+#else
+# define cpu_is_mx23() (0)
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+# define cpu_is_mx28() (machine_is_mx28evk())
+#else
+# define cpu_is_mx28() (0)
+#endif
+
+#endif /* __MACH_MXS_H__ */
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH v2 02/15] ARM: mxs: Add helper definition and function
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (15 preceding siblings ...)
2010-11-29 11:59 ` [PATCH v2 01/15] ARM: mxs: Add core definitions Shawn Guo
@ 2010-11-29 11:59 ` Shawn Guo
2010-11-29 11:59 ` [PATCH v2 03/15] ARM: mxs: Add reset routines Shawn Guo
` (29 subsequent siblings)
46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-11-29 11:59 UTC (permalink / raw)
To: linux-arm-kernel
Add helper definition and function for MXS-based.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
- Remove cpu.c and reference to mxs_set_cpu_type() from common.h
arch/arm/mach-mxs/include/mach/common.h | 32 ++++++++++++++++++++++++++++++
arch/arm/mach-mxs/include/mach/io.h | 22 ++++++++++++++++++++
arch/arm/mach-mxs/include/mach/timex.h | 21 +++++++++++++++++++
arch/arm/mach-mxs/include/mach/vmalloc.h | 22 ++++++++++++++++++++
4 files changed, 97 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/include/mach/common.h
create mode 100644 arch/arm/mach-mxs/include/mach/io.h
create mode 100644 arch/arm/mach-mxs/include/mach/timex.h
create mode 100644 arch/arm/mach-mxs/include/mach/vmalloc.h
diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
new file mode 100644
index 0000000..dca0460
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/common.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2004-2007 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.
+ */
+
+#ifndef __MACH_MXS_COMMON_H__
+#define __MACH_MXS_COMMON_H__
+
+struct clk;
+
+extern int mxs_reset_block(void __iomem *);
+extern void mxs_arch_reset_init(void __iomem *);
+extern void mxs_timer_init(struct clk *, void __iomem *, int);
+
+extern int mx23_register_gpios(void);
+extern int mx23_clocks_init(void);
+extern void mx23_map_io(void);
+extern void mx23_init_irq(void);
+
+extern int mx28_register_gpios(void);
+extern int mx28_clocks_init(void);
+extern void mx28_map_io(void);
+extern void mx28_init_irq(void);
+
+extern void icoll_init_irq(void __iomem *);
+
+#endif /* __MACH_MXS_COMMON_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/io.h b/arch/arm/mach-mxs/include/mach/io.h
new file mode 100644
index 0000000..289b722
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/io.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2004-2007 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.
+ */
+
+#ifndef __MACH_MXS_IO_H__
+#define __MACH_MXS_IO_H__
+
+/* Allow IO space to be anywhere in the memory */
+#define IO_SPACE_LIMIT 0xffffffff
+
+/* io address mapping macro */
+#define __io(a) __typesafe_io(a)
+
+#define __mem_pci(a) (a)
+
+#endif /* __MACH_MXS_IO_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/timex.h b/arch/arm/mach-mxs/include/mach/timex.h
new file mode 100644
index 0000000..734ce89
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/timex.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 1999 ARM Limited
+ * Copyright 2004-2007 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.
+ */
+
+#ifndef __MACH_MXS_TIMEX_H__
+#define __MACH_MXS_TIMEX_H__
+
+#define CLOCK_TICK_RATE 32000 /* 32K */
+
+#endif /* __MACH_MXS_TIMEX_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/vmalloc.h b/arch/arm/mach-mxs/include/mach/vmalloc.h
new file mode 100644
index 0000000..103b016
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/vmalloc.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2000 Russell King.
+ * Copyright 2004-2007 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.
+ */
+
+#ifndef __MACH_MXS_VMALLOC_H__
+#define __MACH_MXS_VMALLOC_H__
+
+/* vmalloc ending address */
+#define VMALLOC_END 0xf4000000UL
+
+#endif /* __MACH_MXS_VMALLOC_H__ */
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH v2 03/15] ARM: mxs: Add reset routines
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (16 preceding siblings ...)
2010-11-29 11:59 ` [PATCH v2 02/15] ARM: mxs: Add helper definition and function Shawn Guo
@ 2010-11-29 11:59 ` Shawn Guo
2010-11-30 10:25 ` Uwe Kleine-König
2010-12-02 9:40 ` Uwe Kleine-König
2010-11-29 11:59 ` [PATCH v2 06/15] ARM: mxs: Add timer support Shawn Guo
` (28 subsequent siblings)
46 siblings, 2 replies; 146+ messages in thread
From: Shawn Guo @ 2010-11-29 11:59 UTC (permalink / raw)
To: linux-arm-kernel
- The mxs wdog is implemented in RTC block.
- There is a generic software reset routine for most modules on mxs.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
- Move rtc clock enabling from arch_reset() into mxs_arch_reset_init()
arch/arm/mach-mxs/include/mach/system.h | 27 ++++++
arch/arm/mach-mxs/system.c | 152 +++++++++++++++++++++++++++++++
2 files changed, 179 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/include/mach/system.h
create mode 100644 arch/arm/mach-mxs/system.c
diff --git a/arch/arm/mach-mxs/include/mach/system.h b/arch/arm/mach-mxs/include/mach/system.h
new file mode 100644
index 0000000..0e42823
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/system.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright 2004-2008 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.
+ */
+
+#ifndef __MACH_MXS_SYSTEM_H__
+#define __MACH_MXS_SYSTEM_H__
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+void arch_reset(char mode, const char *cmd);
+
+#endif /* __MACH_MXS_SYSTEM_H__ */
diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c
new file mode 100644
index 0000000..7ad73bf
--- /dev/null
+++ b/arch/arm/mach-mxs/system.c
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright 2006-2007,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
+ *
+ * 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/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+
+#include <asm/proc-fns.h>
+#include <asm/system.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+
+#define MXS_RTC_WATCHDOG 0x50
+#define MXS_WATCHDOG_EN (1 << 4)
+
+#define MXS_MODULE_CLKGATE (1 << 30)
+#define MXS_MODULE_SFTRST (1 << 31)
+
+static void __iomem *wdog_base;
+
+/*
+ * Reset the system. It is called by machine_restart().
+ */
+void arch_reset(char mode, const char *cmd)
+{
+ /* Set wdog count */
+ __raw_writel(1, wdog_base + MXS_RTC_WATCHDOG);
+
+ /* Assert SRS signal */
+ __raw_writel(MXS_WATCHDOG_EN, wdog_base + MXS_SET_ADDR);
+
+ /* Wait for reset to assert... */
+ mdelay(500);
+
+ pr_err("Watchdog reset failed to assert reset\n");
+
+ /* Delay to allow the serial port to show the message */
+ mdelay(50);
+
+ /* We'll take a jump through zero as a poor second */
+ cpu_reset(0);
+}
+
+void mxs_arch_reset_init(void __iomem *base)
+{
+ struct clk *clk;
+
+ wdog_base = base;
+
+ clk = clk_get_sys("rtc", NULL);
+ if (!IS_ERR(clk))
+ clk_enable(clk);
+}
+
+int mxs_reset_block(void __iomem *reset_addr)
+{
+ u32 val;
+ 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 */
+ val = __raw_readl(reset_addr);
+ val &= ~MXS_MODULE_SFTRST;
+ __raw_writel(val, reset_addr);
+ /*
+ * SFTRST needs 3 GPMI clocks to settle, the reference manual
+ * recommends to wait 1us.
+ */
+ udelay(1);
+ /* Poll SFTRST cleared */
+ timeout = 0x400;
+ while ((__raw_readl(reset_addr) & MXS_MODULE_SFTRST) && --timeout)
+ /* nothing */;
+ if (!timeout)
+ goto error;
+
+ /* Clear CLKGATE */
+ val = __raw_readl(reset_addr);
+ val &= ~MXS_MODULE_CLKGATE;
+ __raw_writel(val, reset_addr);
+ /* Set SFTRST to reset the block */
+ val = __raw_readl(reset_addr);
+ val |= MXS_MODULE_SFTRST;
+ __raw_writel(val, reset_addr);
+ /* Wait 1us */
+ udelay(1);
+ /* Poll CLKGATE set */
+ timeout = 0x400;
+ while ((!(__raw_readl(reset_addr) & MXS_MODULE_CLKGATE)) && --timeout)
+ /* nothing */;
+ if (!timeout)
+ goto error;
+
+ /* Clear SFTRST */
+ val = __raw_readl(reset_addr);
+ val &= ~MXS_MODULE_SFTRST;
+ __raw_writel(val, reset_addr);
+ /* Wait 1us */
+ udelay(1);
+ /* Poll SFTRST cleared */
+ timeout = 0x400;
+ while ((__raw_readl(reset_addr) & MXS_MODULE_SFTRST) && --timeout)
+ /* nothing */;
+ if (!timeout)
+ goto error;
+
+ /* Clear CLKGATE */
+ val = __raw_readl(reset_addr);
+ val &= ~MXS_MODULE_CLKGATE;
+ __raw_writel(val, reset_addr);
+ /* Wait 1us */
+ udelay(1);
+ /* Poll CLKGATE cleared */
+ timeout = 0x400;
+ while ((__raw_readl(reset_addr) & MXS_MODULE_CLKGATE) && --timeout)
+ /* nothing */;
+ if (!timeout)
+ goto error;
+
+ return 0;
+
+error:
+ pr_err("%s(%p): module reset timeout\n", __func__, reset_addr);
+ return -ETIMEDOUT;
+}
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH v2 06/15] ARM: mxs: Add timer support
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (17 preceding siblings ...)
2010-11-29 11:59 ` [PATCH v2 03/15] ARM: mxs: Add reset routines Shawn Guo
@ 2010-11-29 11:59 ` Shawn Guo
2010-11-29 11:59 ` [PATCH v2 10/15] ARM: mxs: Add static memory mapping Shawn Guo
` (27 subsequent siblings)
46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-11-29 11:59 UTC (permalink / raw)
To: linux-arm-kernel
Freescale MXS-based SoCs implement timer support in block TIMROT.
There are two versions of TIMROT. The v1 on MX23 only gets 16 bits
counter and has no match function. The v2 on MX28 extends the
counter to 32 bits and add the match function.
As the result, we need two instances of timers with v1 for better
implementation, one for next_event and another for get_cycles.
Otherwise, get_cycles may get imprecise result after long time
cumulating. With v2, one instance can serve two purposes well.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
- Fix a bug in timrot_set_next_event(). It should read
HW_TIMROT_RUNNING_COUNTn to get the current counts.
arch/arm/mach-mxs/timer.c | 285 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 285 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/timer.c
diff --git a/arch/arm/mach-mxs/timer.c b/arch/arm/mach-mxs/timer.c
new file mode 100644
index 0000000..b07e2e9
--- /dev/null
+++ b/arch/arm/mach-mxs/timer.c
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2000-2001 Deep Blue Solutions
+ * 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
+ * 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/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clockchips.h>
+#include <linux/clk.h>
+
+#include <mach/hardware.h>
+#include <asm/mach/time.h>
+#include <mach/common.h>
+
+/*
+ * There are 2 versions of the timrot on Freescale MXS-based SoCs.
+ * The v1 on MX23 only gets 16 bits counter and has no match function.
+ * The v2 on MX28 extends the counter to 32 bits and add the match function.
+ *
+ * As the result, we need two instances of timers with v1 for better
+ * implementation, one for next_event and another for get_cycles. Otherwise,
+ * get_cycles may get imprecise result after long time cumulating.
+ * With v2, one instance can serve two purposes well.
+ */
+#define timrot_is_v1() (cpu_is_mx23())
+
+#define HW_TIMROT_ROTCTRL 0x00
+#define HW_TIMROT_TIMCTRLn(n) (0x20 + (n) * 0x40)
+#define HW_TIMROT_RUNNING_COUNTn(n) (0x30 + (n) * 0x40)
+#define HW_TIMROT_MATCH_COUNTn(n) (0x50 + (n) * 0x40)
+#define BM_TIMROT_TIMCTRLn_RELOAD (1 << 6)
+#define BM_TIMROT_TIMCTRLn_UPDATE (1 << 7)
+#define BM_TIMROT_TIMCTRLn_MATCH_MODE (1 << 11)
+#define BM_TIMROT_TIMCTRLn_IRQ_EN (1 << 14)
+#define BM_TIMROT_TIMCTRLn_IRQ (1 << 15)
+#define BP_TIMROT_TIMCTRLn_SELECT 0
+#define BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL (timrot_is_v1() ? 0x8 : 0xb)
+
+static struct clock_event_device clockevent_mxs;
+static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
+
+static void __iomem *timer_base;
+
+static inline void timrot_irq_disable(void)
+{
+ __raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN,
+ timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_CLR_ADDR);
+}
+
+static inline void timrot_irq_enable(void)
+{
+ __raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN,
+ timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_SET_ADDR);
+}
+
+static void timrot_irq_acknowledge(void)
+{
+ __raw_writel(BM_TIMROT_TIMCTRLn_IRQ,
+ timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_CLR_ADDR);
+}
+
+static cycle_t timrot_get_cycles(struct clocksource *cs)
+{
+ if (timrot_is_v1())
+ return ~((__raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(1))
+ & 0xffff0000) >> 16);
+ else
+ return ~__raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(0));
+}
+
+static int timrot_set_next_event(unsigned long evt,
+ struct clock_event_device *dev)
+{
+ unsigned long match;
+ int ret;
+
+ /* timrot decrements the count */
+ if (timrot_is_v1()) {
+ __raw_writel(evt, timer_base + HW_TIMROT_RUNNING_COUNTn(0));
+ ret = 0;
+ } else {
+ match = __raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(0))
+ - evt;
+ __raw_writel(match, timer_base + HW_TIMROT_MATCH_COUNTn(0));
+ ret = (int)(match - __raw_readl(timer_base +
+ HW_TIMROT_RUNNING_COUNTn(0))) > 0 ? -ETIME : 0;
+ }
+
+ return ret;
+}
+
+static irqreturn_t mxs_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = &clockevent_mxs;
+
+ timrot_irq_acknowledge();
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction mxs_timer_irq = {
+ .name = "MXS Timer Tick",
+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = mxs_timer_interrupt,
+};
+
+#ifdef DEBUG
+static const char *clock_event_mode_label[] = {
+ [CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
+ [CLOCK_EVT_MODE_ONESHOT] = "CLOCK_EVT_MODE_ONESHOT",
+ [CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN",
+ [CLOCK_EVT_MODE_UNUSED] = "CLOCK_EVT_MODE_UNUSED"
+};
+#endif /* DEBUG */
+
+static void mxs_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ unsigned long flags;
+
+ /*
+ * The timer interrupt generation is disabled at least
+ * for enough time to call mxs_set_next_event()
+ */
+ local_irq_save(flags);
+
+ /* Disable interrupt in timer module */
+ timrot_irq_disable();
+
+ if (mode != clockevent_mode) {
+ /* Set event time into far-far future */
+ __raw_writel(__raw_readl(timer_base +
+ HW_TIMROT_RUNNING_COUNTn(0)) + 3,
+ timer_base + HW_TIMROT_MATCH_COUNTn(0));
+
+ /* Clear pending interrupt */
+ timrot_irq_acknowledge();
+ }
+
+#ifdef DEBUG
+ printk(KERN_INFO "mxs_set_mode: changing mode from %s to %s\n",
+ clock_event_mode_label[clockevent_mode],
+ clock_event_mode_label[mode]);
+#endif /* DEBUG */
+
+ /* Remember timer mode */
+ clockevent_mode = mode;
+ local_irq_restore(flags);
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ printk(KERN_ERR "mxs_set_mode: Periodic mode is not "
+ "supported for MXS-based\n");
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ /*
+ * Do not put overhead of interrupt enable/disable into
+ * mxs_set_next_event(), the core has about 4 minutes
+ * to call mxs_set_next_event() or shutdown clock after
+ * mode switching
+ */
+ local_irq_save(flags);
+ timrot_irq_enable();
+ local_irq_restore(flags);
+ break;
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_RESUME:
+ /* Left event sources disabled, no more interrupts appear */
+ break;
+ }
+}
+
+static struct clock_event_device clockevent_mxs = {
+ .name = "mxs_timrot",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .shift = 32,
+ .set_mode = mxs_set_mode,
+ .set_next_event = timrot_set_next_event,
+ .rating = 200,
+};
+
+static int __init mxs_clockevent_init(struct clk *timer_clk)
+{
+ unsigned int c = clk_get_rate(timer_clk);
+
+ clockevent_mxs.mult = div_sc(c, NSEC_PER_SEC, clockevent_mxs.shift);
+ clockevent_mxs.cpumask = cpumask_of(0);
+ if (timrot_is_v1()) {
+ clockevent_mxs.max_delta_ns =
+ clockevent_delta2ns(0xfffe, &clockevent_mxs);
+ clockevent_mxs.min_delta_ns =
+ clockevent_delta2ns(0xf, &clockevent_mxs);
+ } else {
+ clockevent_mxs.max_delta_ns =
+ clockevent_delta2ns(0xfffffffe, &clockevent_mxs);
+ clockevent_mxs.min_delta_ns =
+ clockevent_delta2ns(0xff, &clockevent_mxs);
+ }
+
+ clockevents_register_device(&clockevent_mxs);
+
+ return 0;
+}
+
+static struct clocksource clocksource_mxs = {
+ .name = "mxs_timer",
+ .rating = 200,
+ .read = timrot_get_cycles,
+ .mask = CLOCKSOURCE_MASK(32),
+ .shift = 10,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int __init mxs_clocksource_init(struct clk *timer_clk)
+{
+ unsigned int c = clk_get_rate(timer_clk);
+
+ if (timrot_is_v1())
+ clocksource_mxs.mask = CLOCKSOURCE_MASK(16);
+ clocksource_mxs.mult = clocksource_hz2mult(c, clocksource_mxs.shift);
+ clocksource_register(&clocksource_mxs);
+
+ return 0;
+}
+
+void __init mxs_timer_init(struct clk *timer_clk,
+ void __iomem *base, int irq)
+{
+ clk_enable(timer_clk);
+
+ timer_base = base;
+
+ /*
+ * Initialize timers to a known state
+ */
+ mxs_reset_block(base + HW_TIMROT_ROTCTRL);
+
+ if (timrot_is_v1()) {
+ /* timer0 is for next_event */
+ __raw_writel(
+ BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL |
+ BM_TIMROT_TIMCTRLn_UPDATE |
+ BM_TIMROT_TIMCTRLn_IRQ_EN,
+ base + HW_TIMROT_TIMCTRLn(0));
+ /* timer1 is for get_cycles */
+ __raw_writel(
+ BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL |
+ BM_TIMROT_TIMCTRLn_RELOAD,
+ base + HW_TIMROT_TIMCTRLn(1));
+ __raw_writel(0xffff, timer_base + HW_TIMROT_RUNNING_COUNTn(1));
+
+ } else {
+ __raw_writel(
+ BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL |
+ BM_TIMROT_TIMCTRLn_IRQ_EN |
+ BM_TIMROT_TIMCTRLn_MATCH_MODE,
+ timer_base + HW_TIMROT_TIMCTRLn(0));
+ }
+
+ /* init and register the timer to the framework */
+ mxs_clocksource_init(timer_clk);
+ mxs_clockevent_init(timer_clk);
+
+ /* Make irqs happen */
+ setup_irq(irq, &mxs_timer_irq);
+}
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH v2 10/15] ARM: mxs: Add static memory mapping
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (18 preceding siblings ...)
2010-11-29 11:59 ` [PATCH v2 06/15] ARM: mxs: Add timer support Shawn Guo
@ 2010-11-29 11:59 ` Shawn Guo
2010-11-29 11:59 ` [PATCH v2 15/15] ARM: mxs: Add build configuration for mxs Shawn Guo
` (26 subsequent siblings)
46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-11-29 11:59 UTC (permalink / raw)
To: linux-arm-kernel
Create static memory mapping for MX23 and MX28.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
- Remove the calls to mxs_set_cpu_type()
arch/arm/mach-mxs/mm-mx23.c | 47 +++++++++++++++++++++++++++++++++++++++++++
arch/arm/mach-mxs/mm-mx28.c | 47 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 94 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/mm-mx23.c
create mode 100644 arch/arm/mach-mxs/mm-mx28.c
diff --git a/arch/arm/mach-mxs/mm-mx23.c b/arch/arm/mach-mxs/mm-mx23.c
new file mode 100644
index 0000000..d254064
--- /dev/null
+++ b/arch/arm/mach-mxs/mm-mx23.c
@@ -0,0 +1,47 @@
+/*
+ * 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.h>
+
+/*
+ * Define the MX23 memory map.
+ */
+static struct map_desc mx23_io_desc[] __initdata = {
+ mxs_map_entry(MX23, OCRAM, MT_DEVICE),
+ mxs_map_entry(MX23, 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 mx23_map_io(void)
+{
+ mxs_iomux_init(MX23_IO_ADDRESS(MX23_PINCTRL_BASE_ADDR));
+ mxs_arch_reset_init(MX23_IO_ADDRESS(MX23_RTC_BASE_ADDR));
+ iotable_init(mx23_io_desc, ARRAY_SIZE(mx23_io_desc));
+}
+
+void __init mx23_init_irq(void)
+{
+ icoll_init_irq(MX23_IO_ADDRESS(MX23_ICOLL_BASE_ADDR));
+ mx23_register_gpios();
+}
diff --git a/arch/arm/mach-mxs/mm-mx28.c b/arch/arm/mach-mxs/mm-mx28.c
new file mode 100644
index 0000000..38c27bc
--- /dev/null
+++ b/arch/arm/mach-mxs/mm-mx28.c
@@ -0,0 +1,47 @@
+/*
+ * 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.h>
+
+/*
+ * Define the MX28 memory map.
+ */
+static struct map_desc mx28_io_desc[] __initdata = {
+ mxs_map_entry(MX28, OCRAM, MT_DEVICE),
+ mxs_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)
+{
+ mxs_iomux_init(MX28_IO_ADDRESS(MX28_PINCTRL_BASE_ADDR));
+ mxs_arch_reset_init(MX28_IO_ADDRESS(MX28_RTC_BASE_ADDR));
+ iotable_init(mx28_io_desc, ARRAY_SIZE(mx28_io_desc));
+}
+
+void __init mx28_init_irq(void)
+{
+ icoll_init_irq(MX28_IO_ADDRESS(MX28_ICOLL_BASE_ADDR));
+ mx28_register_gpios();
+}
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH v2 15/15] ARM: mxs: Add build configuration for mxs
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (19 preceding siblings ...)
2010-11-29 11:59 ` [PATCH v2 10/15] ARM: mxs: Add static memory mapping Shawn Guo
@ 2010-11-29 11:59 ` Shawn Guo
2010-12-07 16:31 ` [PATCH v3 01/15] ARM: mxs: Add core definitions Shawn Guo
` (25 subsequent siblings)
46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-11-29 11:59 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
- Remove cpu.o from arch/arm/mach-mxs/Makefile
arch/arm/Kconfig | 10 ++++++++++
arch/arm/Makefile | 1 +
arch/arm/mach-mxs/Kconfig | 34 ++++++++++++++++++++++++++++++++++
arch/arm/mach-mxs/Makefile | 14 ++++++++++++++
arch/arm/mach-mxs/Makefile.boot | 3 +++
arch/arm/mach-mxs/devices/Kconfig | 5 +++++
arch/arm/mach-mxs/devices/Makefile | 2 ++
7 files changed, 69 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/Kconfig
create mode 100644 arch/arm/mach-mxs/Makefile
create mode 100644 arch/arm/mach-mxs/Makefile.boot
create mode 100644 arch/arm/mach-mxs/devices/Kconfig
create mode 100644 arch/arm/mach-mxs/devices/Makefile
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index db524e7..b0a5130 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -351,6 +351,14 @@ config ARCH_MXC
help
Support for Freescale MXC/iMX-based family of processors
+config ARCH_MXS
+ bool "Freescale MXS-based"
+ select GENERIC_CLOCKEVENTS
+ select ARCH_REQUIRE_GPIOLIB
+ select COMMON_CLKDEV
+ help
+ Support for Freescale MXS-based family of processors
+
config ARCH_STMP3XXX
bool "Freescale STMP3xxx"
select CPU_ARM926T
@@ -924,6 +932,8 @@ source "arch/arm/plat-pxa/Kconfig"
source "arch/arm/mach-mmp/Kconfig"
+source "arch/arm/mach-mxs/Kconfig"
+
source "arch/arm/mach-realview/Kconfig"
source "arch/arm/mach-sa1100/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 057beb8..c22c1ad 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -158,6 +158,7 @@ machine-$(CONFIG_ARCH_MX25) := imx
machine-$(CONFIG_ARCH_MX3) := mx3
machine-$(CONFIG_ARCH_MX5) := mx5
machine-$(CONFIG_ARCH_MXC91231) := mxc91231
+machine-$(CONFIG_ARCH_MXS) := mxs
machine-$(CONFIG_ARCH_NETX) := netx
machine-$(CONFIG_ARCH_NOMADIK) := nomadik
machine-$(CONFIG_ARCH_NS9XXX) := ns9xxx
diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
new file mode 100644
index 0000000..c4ac7b4
--- /dev/null
+++ b/arch/arm/mach-mxs/Kconfig
@@ -0,0 +1,34 @@
+if ARCH_MXS
+
+source "arch/arm/mach-mxs/devices/Kconfig"
+
+config SOC_IMX23
+ bool
+ select CPU_ARM926T
+
+config SOC_IMX28
+ bool
+ select CPU_ARM926T
+
+comment "MXS platforms:"
+
+config MACH_MX23EVK
+ bool "Support MX23EVK Platform"
+ select SOC_IMX23
+ select MXS_HAVE_PLATFORM_DUART
+ default y
+ help
+ Include support for MX23EVK platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_MX28EVK
+ bool "Support MX28EVK Platform"
+ select SOC_IMX28
+ select MXS_HAVE_PLATFORM_DUART
+ select MXS_HAVE_PLATFORM_FEC
+ default y
+ help
+ Include support for MX28EVK platform. This includes specific
+ configurations for the board and its peripherals.
+
+endif
diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
new file mode 100644
index 0000000..8fcb683
--- /dev/null
+++ b/arch/arm/mach-mxs/Makefile
@@ -0,0 +1,14 @@
+#
+# Makefile for the linux kernel.
+#
+
+# Common support
+obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
+
+obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
+obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
+
+obj-$(CONFIG_MACH_MX23EVK) += mach-mx23evk.o
+obj-$(CONFIG_MACH_MX28EVK) += mach-mx28evk.o
+
+obj-y += devices/
diff --git a/arch/arm/mach-mxs/Makefile.boot b/arch/arm/mach-mxs/Makefile.boot
new file mode 100644
index 0000000..1568ad4
--- /dev/null
+++ b/arch/arm/mach-mxs/Makefile.boot
@@ -0,0 +1,3 @@
+ zreladdr-y := 0x40008000
+params_phys-y := 0x40000100
+initrd_phys-y := 0x40800000
diff --git a/arch/arm/mach-mxs/devices/Kconfig b/arch/arm/mach-mxs/devices/Kconfig
new file mode 100644
index 0000000..a35a2dc
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/Kconfig
@@ -0,0 +1,5 @@
+config MXS_HAVE_PLATFORM_DUART
+ bool
+
+config MXS_HAVE_PLATFORM_FEC
+ bool
diff --git a/arch/arm/mach-mxs/devices/Makefile b/arch/arm/mach-mxs/devices/Makefile
new file mode 100644
index 0000000..4b5266a
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_MXS_HAVE_PLATFORM_DUART) += platform-duart.o
+obj-$(CONFIG_MXS_HAVE_PLATFORM_FEC) += platform-fec.o
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH v2 01/15] ARM: mxs: Add core definitions
2010-11-29 11:59 ` [PATCH v2 01/15] ARM: mxs: Add core definitions Shawn Guo
@ 2010-11-30 9:21 ` Uwe Kleine-König
0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-11-30 9:21 UTC (permalink / raw)
To: linux-arm-kernel
Hello Shawn,
On Mon, Nov 29, 2010 at 07:59:11PM +0800, Shawn Guo wrote:
> Add core definitions for MXS-based SoC MX23 and MX28.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v2:
> - Remove MXS_IO_P2V_MODULE from hardware.h which is not needed
> - Simplify MXS_IO_P2V_MODULE definition in hardware.h
> - Remove unnecessary inclusion protection from hardware.h
> - Change cpu_is_mx23/mx28() implementation in mxs.h to use machine_is_xxx
>
> arch/arm/mach-mxs/include/mach/hardware.h | 55 +++++++
> arch/arm/mach-mxs/include/mach/irqs.h | 32 ++++
> arch/arm/mach-mxs/include/mach/memory.h | 24 +++
> arch/arm/mach-mxs/include/mach/mx23.h | 147 +++++++++++++++++++
> arch/arm/mach-mxs/include/mach/mx28.h | 227 +++++++++++++++++++++++++++++
> arch/arm/mach-mxs/include/mach/mxs.h | 43 ++++++
> 6 files changed, 528 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-mxs/include/mach/hardware.h
> create mode 100644 arch/arm/mach-mxs/include/mach/irqs.h
> create mode 100644 arch/arm/mach-mxs/include/mach/memory.h
> create mode 100644 arch/arm/mach-mxs/include/mach/mx23.h
> create mode 100644 arch/arm/mach-mxs/include/mach/mx28.h
> create mode 100644 arch/arm/mach-mxs/include/mach/mxs.h
>
> diff --git a/arch/arm/mach-mxs/include/mach/hardware.h b/arch/arm/mach-mxs/include/mach/hardware.h
> new file mode 100644
> index 0000000..9e757e0
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/hardware.h
> @@ -0,0 +1,55 @@
> +/*
> + * Copyright 2004-2007 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
> + * 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_MXS_HARDWARE_H__
> +#define __MACH_MXS_HARDWARE_H__
> +
> +#include <asm/sizes.h>
> +
> +#ifdef __ASSEMBLER__
> +#define IOMEM(addr) (addr)
> +#else
> +#define IOMEM(addr) ((void __force __iomem *)(addr))
> +#endif
> +
> +/*
> + * It maps the whole address space to [0xf4000000, 0xf5ffffff].
> + *
> + * OCRAM 0x00000000+0x020000 -> 0xf4000000+0x020000
> + * IO 0x80000000+0x100000 -> 0xf4400000+0x100000
> + */
> +#define MXS_IO_P2V(x) (0xf4000000 + \
> + (((x) & 0x80000000) >> 6) + \
> + (((x) & 0x000fffff)))
The comment doesn't match the function.
> +
> +
> +#define MXS_IO_ADDRESS(x) IOMEM(MXS_IO_P2V(x))
> +
> +#include <mach/mx23.h>
> +#include <mach/mx28.h>
> +#include <mach/mxs.h>
> +
> +#define mxs_map_entry(soc, name, _type) { \
> + .virtual = soc ## _IO_P2V(soc ## _ ## name ## _BASE_ADDR), \
> + .pfn = __phys_to_pfn(soc ## _ ## name ## _BASE_ADDR), \
> + .length = soc ## _ ## name ## _SIZE, \
> + .type = _type, \
> +}
> +
> +#endif /* __MACH_MXS_HARDWARE_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/irqs.h b/arch/arm/mach-mxs/include/mach/irqs.h
> new file mode 100644
> index 0000000..f771039
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/irqs.h
> @@ -0,0 +1,32 @@
> +/*
> + * Copyright 2004-2007 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.
> + */
> +
> +#ifndef __MACH_MXS_IRQS_H__
> +#define __MACH_MXS_IRQS_H__
> +
> +#define MXS_INTERNAL_IRQS 128
> +
> +#define MXS_GPIO_IRQ_START MXS_INTERNAL_IRQS
> +
> +/* the maximum for MXS-based */
> +#define MXS_GPIO_IRQS (32 * 5)
> +
> +/*
> + * The next 16 interrupts are for board specific purposes. Since
> + * the kernel can only run on one machine at a time, we can re-use
> + * these. If you need more, increase MXS_BOARD_IRQS, but keep it
> + * within sensible limits.
> + */
> +#define MXS_BOARD_IRQ_START (MXS_GPIO_IRQ_START + MXS_GPIO_IRQS)
> +#define MXS_BOARD_IRQS 16
> +
> +#define NR_IRQS (MXS_BOARD_IRQ_START + MXS_BOARD_IRQS)
> +
> +#endif /* __MACH_MXS_IRQS_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/memory.h b/arch/arm/mach-mxs/include/mach/memory.h
> new file mode 100644
> index 0000000..b5420a5
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/memory.h
> @@ -0,0 +1,24 @@
> +/*
> + * 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_MXS_MEMORY_H__
> +#define __MACH_MXS_MEMORY_H__
> +
> +#define PHYS_OFFSET UL(0x40000000)
> +
> +#endif /* __MACH_MXS_MEMORY_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/mx23.h b/arch/arm/mach-mxs/include/mach/mx23.h
> new file mode 100644
> index 0000000..27a11ee
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/mx23.h
> @@ -0,0 +1,147 @@
> +/*
> + * 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_MX23_H__
> +#define __MACH_MX23_H__
> +
> +#ifndef __ASSEMBLER__
> +#include <linux/io.h>
> +#endif
> +
> +/*
> + * OCRAM
> + */
> +#define MX23_OCRAM_BASE_ADDR 0x00000000
> +#define MX23_OCRAM_SIZE SZ_32K
> +
> +/*
> + * IO
> + */
> +#define MX23_IO_BASE_ADDR 0x80000000
> +#define MX23_IO_SIZE SZ_1M
> +
> +#define MX23_ICOLL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x000000)
> +#define MX23_APBH_DMA_BASE_ADDR (MX23_IO_BASE_ADDR + 0x004000)
> +#define MX23_BCH_BASE_ADDR (MX23_IO_BASE_ADDR + 0x00a000)
> +#define MX23_GPMI_BASE_ADDR (MX23_IO_BASE_ADDR + 0x00c000)
> +#define MX23_SSP1_BASE_ADDR (MX23_IO_BASE_ADDR + 0x010000)
> +#define MX23_SSP2_BASE_ADDR (MX23_IO_BASE_ADDR + 0x034000)
I'd prefer to have these sorted consistently. Either sort by name or
address, but not a mixure of both.
> +#define MX23_PINCTRL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x018000)
> +#define MX23_DIGCTL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x01c000)
> +#define MX23_ETM_BASE_ADDR (MX23_IO_BASE_ADDR + 0x020000)
> +#define MX23_APBX_DMA_BASE_ADDR (MX23_IO_BASE_ADDR + 0x024000)
> +#define MX23_DCP_BASE_ADDR (MX23_IO_BASE_ADDR + 0x028000)
> +#define MX23_PXP_BASE_ADDR (MX23_IO_BASE_ADDR + 0x02a000)
> +#define MX23_OCOTP_BASE_ADDR (MX23_IO_BASE_ADDR + 0x02c000)
> +#define MX23_AXI_AHB0_BASE_ADDR (MX23_IO_BASE_ADDR + 0x02e000)
> +#define MX23_LCDIF_BASE_ADDR (MX23_IO_BASE_ADDR + 0x030000)
> +#define MX23_TVENC_BASE_ADDR (MX23_IO_BASE_ADDR + 0x038000)
> +#define MX23_CLKCTRL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x040000)
> +#define MX23_SAIF0_BASE_ADDR (MX23_IO_BASE_ADDR + 0x042000)
> +#define MX23_POWER_BASE_ADDR (MX23_IO_BASE_ADDR + 0x044000)
> +#define MX23_SAIF1_BASE_ADDR (MX23_IO_BASE_ADDR + 0x046000)
> +#define MX23_AUDIOOUT_BASE_ADDR (MX23_IO_BASE_ADDR + 0x048000)
> +#define MX23_AUDIOIN_BASE_ADDR (MX23_IO_BASE_ADDR + 0x04c000)
> +#define MX23_LRADC_BASE_ADDR (MX23_IO_BASE_ADDR + 0x050000)
> +#define MX23_SPDIF_BASE_ADDR (MX23_IO_BASE_ADDR + 0x054000)
> +#define MX23_RTC_BASE_ADDR (MX23_IO_BASE_ADDR + 0x05c000)
> +#define MX23_I2C0_BASE_ADDR (MX23_IO_BASE_ADDR + 0x058000)
> +#define MX23_PWM_BASE_ADDR (MX23_IO_BASE_ADDR + 0x064000)
> +#define MX23_TIMROT_BASE_ADDR (MX23_IO_BASE_ADDR + 0x068000)
> +#define MX23_AUART1_BASE_ADDR (MX23_IO_BASE_ADDR + 0x06c000)
> +#define MX23_AUART2_BASE_ADDR (MX23_IO_BASE_ADDR + 0x06e000)
> +#define MX23_DUART_BASE_ADDR (MX23_IO_BASE_ADDR + 0x070000)
> +#define MX23_USBPHY_BASE_ADDR (MX23_IO_BASE_ADDR + 0x07c000)
> +#define MX23_USBCTRL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x080000)
> +#define MX23_DRAM_BASE_ADDR (MX23_IO_BASE_ADDR + 0x0e0000)
> +
> +#define MX23_IO_P2V(x) MXS_IO_P2V(x)
> +#define MX23_IO_ADDRESS(x) IOMEM(MX23_IO_P2V(x))
> +
> +/*
> + * IRQ
> + */
> +#define MX23_INT_DUART 0
> +#define MX23_INT_COMMS_RX 1
> +#define MX23_INT_COMMS_TX 1
> +#define MX23_INT_SSP2_ERROR 2
> +#define MX23_INT_VDD5V 3
> +#define MX23_INT_HEADPHONE_SHORT 4
> +#define MX23_INT_DAC_DMA 5
> +#define MX23_INT_DAC_ERROR 6
> +#define MX23_INT_ADC_DMA 7
> +#define MX23_INT_ADC_ERROR 8
> +#define MX23_INT_SPDIF_DMA 9
> +#define MX23_INT_SAIF2_DMA 9
> +#define MX23_INT_SPDIF_ERROR 10
> +#define MX23_INT_SAIF1_IRQ 10
> +#define MX23_INT_SAIF2_IRQ 10
> +#define MX23_INT_USB_CTRL 11
> +#define MX23_INT_USB_WAKEUP 12
> +#define MX23_INT_GPMI_DMA 13
> +#define MX23_INT_SSP1_DMA 14
> +#define MX23_INT_SSP_ERROR 15
> +#define MX23_INT_GPIO0 16
> +#define MX23_INT_GPIO1 17
> +#define MX23_INT_GPIO2 18
> +#define MX23_INT_SAIF1_DMA 19
> +#define MX23_INT_SSP2_DMA 20
> +#define MX23_INT_ECC8_IRQ 21
> +#define MX23_INT_RTC_ALARM 22
> +#define MX23_INT_UARTAPP_TX_DMA 23
> +#define MX23_INT_UARTAPP_INTERNAL 24
> +#define MX23_INT_UARTAPP_RX_DMA 25
> +#define MX23_INT_I2C_DMA 26
> +#define MX23_INT_I2C_ERROR 27
> +#define MX23_INT_TIMER0 28
> +#define MX23_INT_TIMER1 29
> +#define MX23_INT_TIMER2 30
> +#define MX23_INT_TIMER3 31
> +#define MX23_INT_BATT_BRNOUT 32
> +#define MX23_INT_VDDD_BRNOUT 33
> +#define MX23_INT_VDDIO_BRNOUT 34
> +#define MX23_INT_VDD18_BRNOUT 35
> +#define MX23_INT_TOUCH_DETECT 36
> +#define MX23_INT_LRADC_CH0 37
> +#define MX23_INT_LRADC_CH1 38
> +#define MX23_INT_LRADC_CH2 39
> +#define MX23_INT_LRADC_CH3 40
> +#define MX23_INT_LRADC_CH4 41
> +#define MX23_INT_LRADC_CH5 42
> +#define MX23_INT_LRADC_CH6 43
> +#define MX23_INT_LRADC_CH7 44
> +#define MX23_INT_LCDIF_DMA 45
> +#define MX23_INT_LCDIF_ERROR 46
> +#define MX23_INT_DIGCTL_DEBUG_TRAP 47
> +#define MX23_INT_RTC_1MSEC 48
> +#define MX23_INT_DRI_DMA 49
> +#define MX23_INT_DRI_ATTENTION 50
> +#define MX23_INT_GPMI_ATTENTION 51
> +#define MX23_INT_IR 52
> +#define MX23_INT_DCP_VMI 53
> +#define MX23_INT_DCP 54
> +#define MX23_INT_BCH 56
> +#define MX23_INT_PXP 57
> +#define MX23_INT_UARTAPP2_TX_DMA 58
> +#define MX23_INT_UARTAPP2_INTERNAL 59
> +#define MX23_INT_UARTAPP2_RX_DMA 60
> +#define MX23_INT_VDAC_DETECT 61
> +#define MX23_INT_VDD5V_DROOP 64
> +#define MX23_INT_DCDC4P2_BO 65
> +
> +#endif /* __MACH_MX23_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/mx28.h b/arch/arm/mach-mxs/include/mach/mx28.h
> new file mode 100644
> index 0000000..836d807
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/mx28.h
> @@ -0,0 +1,227 @@
> +/*
> + * 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
> +
> +/*
> + * 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_MAC0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0f0000)
> +#define MX28_ENET_MAC1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0f4000)
> +
> +#define MX28_IO_P2V(x) MXS_IO_P2V(x)
> +#define MX28_IO_ADDRESS(x) IOMEM(MX28_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
I'd skip these RESV defines. They are unused anyhow. And as soon as
you need them they need a more sensible name anyhow.
> +#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
> +
> +#endif /* __MACH_MX28_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/mxs.h b/arch/arm/mach-mxs/include/mach/mxs.h
> new file mode 100644
> index 0000000..b691c34
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/mxs.h
> @@ -0,0 +1,43 @@
> +/*
> + * 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_MXS_H__
> +#define __MACH_MXS_H__
> +
> +#include <asm/mach-types.h>
> +
> +#define MXS_SET_ADDR 0x4
> +#define MXS_CLR_ADDR 0x8
> +#define MXS_TOG_ADDR 0xc
> +
> +/*
> + * MXS CPU types
> + */
> +#ifdef CONFIG_SOC_IMX23
> +# define cpu_is_mx23() (machine_is_mx23evk())
> +#else
> +# define cpu_is_mx23() (0)
> +#endif
> +
> +#ifdef CONFIG_SOC_IMX28
> +# define cpu_is_mx28() (machine_is_mx28evk())
> +#else
> +# define cpu_is_mx28() (0)
> +#endif
Why not just:
#define cpu_is_mx28() (machine_is_mx28evk())
? If MACH_MX28EVK isn't defined the macro expands so 0 anyhow.
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 03/15] ARM: mxs: Add reset routines
2010-11-29 11:59 ` [PATCH v2 03/15] ARM: mxs: Add reset routines Shawn Guo
@ 2010-11-30 10:25 ` Uwe Kleine-König
2010-12-01 10:45 ` Shawn Guo
2010-12-02 6:02 ` Shawn Guo
2010-12-02 9:40 ` Uwe Kleine-König
1 sibling, 2 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-11-30 10:25 UTC (permalink / raw)
To: linux-arm-kernel
Hello,
On Mon, Nov 29, 2010 at 07:59:13PM +0800, Shawn Guo wrote:
> - The mxs wdog is implemented in RTC block.
> - There is a generic software reset routine for most modules on mxs.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v2:
> - Move rtc clock enabling from arch_reset() into mxs_arch_reset_init()
>
> arch/arm/mach-mxs/include/mach/system.h | 27 ++++++
> arch/arm/mach-mxs/system.c | 152 +++++++++++++++++++++++++++++++
> 2 files changed, 179 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-mxs/include/mach/system.h
> create mode 100644 arch/arm/mach-mxs/system.c
>
> diff --git a/arch/arm/mach-mxs/include/mach/system.h b/arch/arm/mach-mxs/include/mach/system.h
> new file mode 100644
> index 0000000..0e42823
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/system.h
> @@ -0,0 +1,27 @@
> +/*
> + * Copyright (C) 1999 ARM Limited
> + * Copyright (C) 2000 Deep Blue Solutions Ltd
> + * Copyright 2004-2008 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.
> + */
> +
> +#ifndef __MACH_MXS_SYSTEM_H__
> +#define __MACH_MXS_SYSTEM_H__
> +
> +static inline void arch_idle(void)
> +{
> + cpu_do_idle();
> +}
> +
> +void arch_reset(char mode, const char *cmd);
> +
> +#endif /* __MACH_MXS_SYSTEM_H__ */
> diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c
> new file mode 100644
> index 0000000..7ad73bf
> --- /dev/null
> +++ b/arch/arm/mach-mxs/system.c
> @@ -0,0 +1,152 @@
> +/*
> + * Copyright (C) 1999 ARM Limited
> + * Copyright (C) 2000 Deep Blue Solutions Ltd
> + * Copyright 2006-2007,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
> + *
> + * 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/kernel.h>
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/err.h>
> +#include <linux/delay.h>
> +
> +#include <asm/proc-fns.h>
> +#include <asm/system.h>
> +
> +#include <mach/hardware.h>
> +#include <mach/common.h>
> +
> +#define MXS_RTC_WATCHDOG 0x50
> +#define MXS_WATCHDOG_EN (1 << 4)
> +
> +#define MXS_MODULE_CLKGATE (1 << 30)
> +#define MXS_MODULE_SFTRST (1 << 31)
> +
> +static void __iomem *wdog_base;
> +
> +/*
> + * Reset the system. It is called by machine_restart().
> + */
> +void arch_reset(char mode, const char *cmd)
> +{
> + /* Set wdog count */
> + __raw_writel(1, wdog_base + MXS_RTC_WATCHDOG);
Which unit is used here? Does the timer only start running when it's
enabled below? Does this apply when the watchdog is already in use,
too?
> +
> + /* Assert SRS signal */
> + __raw_writel(MXS_WATCHDOG_EN, wdog_base + MXS_SET_ADDR);
> +
> + /* Wait for reset to assert... */
> + mdelay(500);
> +
> + pr_err("Watchdog reset failed to assert reset\n");
> +
> + /* Delay to allow the serial port to show the message */
> + mdelay(50);
> +
> + /* We'll take a jump through zero as a poor second */
> + cpu_reset(0);
> +}
> +
> +void mxs_arch_reset_init(void __iomem *base)
> +{
> + struct clk *clk;
> +
> + wdog_base = base;
> +
> + clk = clk_get_sys("rtc", NULL);
> + if (!IS_ERR(clk))
> + clk_enable(clk);
Actually I'm not sure if it's worth to do this. It might hurt if you
want to save power.
I'll try to find a time slot to look into that.
> +}
> +
> +int mxs_reset_block(void __iomem *reset_addr)
> +{
> + u32 val;
> + 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 */
> + val = __raw_readl(reset_addr);
> + val &= ~MXS_MODULE_SFTRST;
> + __raw_writel(val, reset_addr);
__raw_writel(MXS_MODULE_SFTRST, reset_addr + MXS_CLEAR_ADDR);
instead of read-modify-write here doesn't work here?
> + /*
> + * SFTRST needs 3 GPMI clocks to settle, the reference manual
> + * recommends to wait 1us.
> + */
> + udelay(1);
> + /* Poll SFTRST cleared */
> + timeout = 0x400;
> + while ((__raw_readl(reset_addr) & MXS_MODULE_SFTRST) && --timeout)
> + /* nothing */;
> + if (!timeout)
Maybe add an unlikely here? (i.e.
if (unlikely(!timeout))
...
)
> + goto error;
> +
> + /* Clear CLKGATE */
> + val = __raw_readl(reset_addr);
Not sure it's worth to optimize here, but you read reset_addr above.
> + val &= ~MXS_MODULE_CLKGATE;
> + __raw_writel(val, reset_addr);
> + /* Set SFTRST to reset the block */
> + val = __raw_readl(reset_addr);
> + val |= MXS_MODULE_SFTRST;
> + __raw_writel(val, reset_addr);
> + /* Wait 1us */
> + udelay(1);
The comment doesn't help much.
> + /* Poll CLKGATE set */
> + timeout = 0x400;
> + while ((!(__raw_readl(reset_addr) & MXS_MODULE_CLKGATE)) && --timeout)
> + /* nothing */;
> + if (!timeout)
> + goto error;
> +
> + /* Clear SFTRST */
> + val = __raw_readl(reset_addr);
> + val &= ~MXS_MODULE_SFTRST;
> + __raw_writel(val, reset_addr);
> + /* Wait 1us */
> + udelay(1);
> + /* Poll SFTRST cleared */
> + timeout = 0x400;
> + while ((__raw_readl(reset_addr) & MXS_MODULE_SFTRST) && --timeout)
> + /* nothing */;
> + if (!timeout)
> + goto error;
> +
> + /* Clear CLKGATE */
> + val = __raw_readl(reset_addr);
> + val &= ~MXS_MODULE_CLKGATE;
> + __raw_writel(val, reset_addr);
> + /* Wait 1us */
> + udelay(1);
> + /* Poll CLKGATE cleared */
> + timeout = 0x400;
> + while ((__raw_readl(reset_addr) & MXS_MODULE_CLKGATE) && --timeout)
> + /* nothing */;
> + if (!timeout)
> + goto error;
There are quite some repetitions in this function. If you could get it
down to something that looks like
clear SFTRST
udelay
poll SFTRST cleared
clear CLKGATE
set SFTRST
udelay
poll CLKGATE set
clear SFTRST
udelay
poll SFTRST cleared
clear CLKGATE
udelay
poll CLKGATE cleared
it's IMHO better than the comment above. If "clear CLKGATE" and "set
SFTRST" can be done in a single step this might be done like that:
/* comment describing setmask_poll */
static int setmask_poll(void __iomem *addr, u32 set, u32 mask,
u32 pollval, u32 pollmask, u32 *curval)
{
int timeout = 0x400;
*curval &= ~mask;
*curval |= set;
__raw_writel(*curval, addr)
/*
* some nice comment about 1us being a good idea
*/
udelay(1);
do {
*curval = __raw_readl(addr);
if ((*curval & pollmask) == pollval)
return 0;
} while(--timeout);
return 1;
}
int mxs_reset_block(void __iomem *reset_addr)
{
u32 val = __raw_readl(reset_addr);
int ret;
/* clear SFTRST and poll SFTRST becoming clear */
ret = setmask_poll(reset_addr,
0, MXS_MODULE_SFTRST,
0, MXS_MODULE_SFTRST, &val);
if (ret)
goto error;
/* clear CLKGATE, set SFTRST and poll CLKGATE becoming set */
ret = setmask_poll(reset_addr,
MXS_MODULE_SFTRST, MXS_MODULE_SFTRST | MXS_MODULE_CLKGATE,
0, MXS_MODULE_CLKGATE, &val);
if (ret)
goto error;
...
}
Well, not very nice, but IMHO better that your code. Maybe
mxs_reset_block fits in a Terminal that way without decreasing the font
size :-)
> +
> + return 0;
> +
> +error:
> + pr_err("%s(%p): module reset timeout\n", __func__, reset_addr);
> + return -ETIMEDOUT;
> +}
> --
> 1.7.1
>
>
>
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH 04/15] ARM: mxs: Add interrupt support
2010-11-26 6:49 ` [PATCH 04/15] ARM: mxs: Add interrupt support Shawn Guo
@ 2010-11-30 13:56 ` Uwe Kleine-König
2010-11-30 17:02 ` Russell King - ARM Linux
2010-12-01 11:23 ` Shawn Guo
0 siblings, 2 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-11-30 13:56 UTC (permalink / raw)
To: linux-arm-kernel
Hello Shawn,
On Fri, Nov 26, 2010 at 02:49:03PM +0800, Shawn Guo wrote:
> Add Interrupt Collector (ICOLL) support for MXS-based.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> arch/arm/mach-mxs/icoll.c | 77 ++++++++++++++++++++++++++
> arch/arm/mach-mxs/include/mach/entry-macro.S | 36 ++++++++++++
> 2 files changed, 113 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-mxs/icoll.c
> create mode 100644 arch/arm/mach-mxs/include/mach/entry-macro.S
>
> diff --git a/arch/arm/mach-mxs/icoll.c b/arch/arm/mach-mxs/icoll.c
> new file mode 100644
> index 0000000..a7a7d4f
> --- /dev/null
> +++ b/arch/arm/mach-mxs/icoll.c
> @@ -0,0 +1,77 @@
> +/*
> + * 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);
You need to write this before handling the irq, no?
> +
> + /* 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 mxs_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;
> +
> + /* Reset icoll */
> + mxs_reset_block(irqbase + HW_ICOLL_CTRL);
> +
> + for (i = 0; i < MXS_INTERNAL_IRQS; i++) {
> + set_irq_chip(i, &mxs_icoll_chip);
> + set_irq_handler(i, handle_level_irq);
> + set_irq_flags(i, IRQF_VALID);
> + }
> +}
> diff --git a/arch/arm/mach-mxs/include/mach/entry-macro.S b/arch/arm/mach-mxs/include/mach/entry-macro.S
> new file mode 100644
> index 0000000..597948d
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/entry-macro.S
> @@ -0,0 +1,36 @@
> +/*
> + * Low-level IRQ helper macros for Freescale MXS-based
> + *
> + * 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.
> + */
> +
> + .macro disable_fiq
> + .endm
> +
> + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
> + ldr \base, =icoll_base
Maybe it's worth to hardcode the base address if only a single cpu is
compiled in? And what about setting the base register in
get_irqnr_preamble?
> + ldr \base, [\base]
> + ldr \irqnr, [\base, #0x70]
> + cmp \irqnr, #0x7F
> + moveqs \irqnr, #0
Hmm, you only need that cmp+moveqs because you cannot be sure that an
irq is pending, right. Maybe it would make sense not to check for irqs
in a loop? (This is a arm-global thing, Russell?) (BTW, you're lucky,
for your irq controller it's only ugly to check if there is an irq
pending. IIRC ns9xxx has a race here.)
> + .endm
> +
> + .macro get_irqnr_preamble, base, tmp
> + .endm
> +
> + .macro arch_ret_to_user, tmp1, tmp2
> + .endm
> --
> 1.7.1
>
>
>
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH 05/15] ARM: mxs: Add low-level debug UART support
2010-11-26 6:49 ` [PATCH 05/15] ARM: mxs: Add low-level debug UART support Shawn Guo
@ 2010-11-30 15:48 ` Uwe Kleine-König
0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-11-30 15:48 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Nov 26, 2010 at 02:49:04PM +0800, Shawn Guo wrote:
> * DEBUG_LL support, which is incompatible with single MXS image
> because of different DUART base address on MX23 and MX28
> * uncompress message support
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> arch/arm/mach-mxs/include/mach/debug-macro.S | 51 ++++++++++++++++
> arch/arm/mach-mxs/include/mach/uncompress.h | 82 ++++++++++++++++++++++++++
> 2 files changed, 133 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-mxs/include/mach/debug-macro.S
> create mode 100644 arch/arm/mach-mxs/include/mach/uncompress.h
>
> diff --git a/arch/arm/mach-mxs/include/mach/debug-macro.S b/arch/arm/mach-mxs/include/mach/debug-macro.S
> new file mode 100644
> index 0000000..efb3173
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/debug-macro.S
> @@ -0,0 +1,51 @@
> +/* arch/arm/mach-mxs/include/mach/debug-macro.S
> + *
> + * Debugging macro include header
> + *
> + * Copyright (C) 1994-1999 Russell King
> + * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
> + *
> + * 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>
> +
> +#ifdef CONFIG_SOC_IMX23
> +#ifdef UART_PADDR
> +#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
> +#endif
> +#define UART_PADDR MX23_DUART_BASE_ADDR
> +#endif
> +
> +#ifdef CONFIG_SOC_IMX28
> +#ifdef UART_PADDR
> +#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
> +#endif
> +#define UART_PADDR MX28_DUART_BASE_ADDR
> +#endif
> +
> +#define UART_VADDR MXS_IO_ADDRESS(UART_PADDR)
> +
> + .macro addruart, rp, rv
> + ldr \rp, =UART_PADDR @ physical
> + ldr \rv, =UART_VADDR @ virtual
> + .endm
> +
> + .macro senduart, rd, rx
> + str \rd, [\rx, #0x0] @ DR
> + .endm
> +
> + .macro waituart, rd, rx
> +1001: ldr \rd, [\rx, #0x18] @ FR
> + tst \rd, #1 << 5 @ FR_TXFF
> + bne 1001b
> + .endm
> +
> + .macro busyuart, rd, rx
> +1002: ldr \rd, [\rx, #0x18] @ FR
> + tst \rd, #1 << 3 @ FR_BUSY
> + beq 1002b
> + .endm
> diff --git a/arch/arm/mach-mxs/include/mach/uncompress.h b/arch/arm/mach-mxs/include/mach/uncompress.h
> new file mode 100644
> index 0000000..47e5479
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/uncompress.h
> @@ -0,0 +1,82 @@
> +/*
> + * arch/arm/mach-mxs/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
> + * 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.
> + */
> +#ifndef __MACH_MXS_UNCOMPRESS_H__
> +#define __MACH_MXS_UNCOMPRESS_H__
> +
> +#define __MXS_BOOT_UNCOMPRESS
> +
> +#include <asm/mach-types.h>
> +
> +static unsigned long uart_base;
> +
> +#define UART(x) (*(volatile unsigned long *)(uart_base + (x)))
> +
> +#define DR 0x00
> +#define FR 0x18
> +#define FR_BUSY (1 << 3)
> +#define FR_TXFE (1 << 7)
> +#define CR 0x30
> +#define CR_UARTEN 1
> +
> +/*
> + * The following code assumes the serial port has already been
> + * initialized by the bootloader. We search for the first enabled
> + * port in the most probable order. If you didn't setup a port in
> + * your bootloader then nothing will appear (which might be desired).
> + *
> + * This does not append a newline
> + */
This comment seems wrong.
> +static void putc(int ch)
> +{
> + if (!uart_base)
> + return;
> + if (!(UART(CR) & CR_UARTEN))
> + return;
> +
> + while (!(UART(FR) & FR_TXFE))
> + barrier();
> +
> + UART(DR) = ch;
> +}
> +
> +static inline void flush(void)
> +{
> +}
> +
> +#define MX23_DUART_BASE_ADDR 0x80070000
> +#define MX28_DUART_BASE_ADDR 0x80074000
> +
> +static __inline__ void __arch_decomp_setup(unsigned long arch_id)
> +{
> + switch (arch_id) {
> + case MACH_TYPE_MX23EVK:
> + uart_base = MX23_DUART_BASE_ADDR;
> + break;
> + case MACH_TYPE_MX28EVK:
> + uart_base = MX28_DUART_BASE_ADDR;
> + break;
> + default:
> + break;
> + }
> +}
> +
> +#define arch_decomp_setup() __arch_decomp_setup(arch_id)
> +#define arch_decomp_wdog()
> +
> +#endif /* __MACH_MXS_UNCOMPRESS_H__ */
> --
> 1.7.1
>
>
>
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH 06/15] ARM: mxs: Add timer support
2010-11-26 6:49 ` [PATCH 06/15] ARM: mxs: Add timer support Shawn Guo
@ 2010-11-30 16:13 ` Uwe Kleine-König
2010-12-02 14:44 ` Shawn Guo
0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-11-30 16:13 UTC (permalink / raw)
To: linux-arm-kernel
Hello Shawn,
[added Thomas to Cc, he can probably say more here. Don't know if he
want though :-)]
On Fri, Nov 26, 2010 at 02:49:05PM +0800, Shawn Guo wrote:
> Freescale MXS-based SoCs implement timer support in block TIMROT.
> There are two versions of TIMROT. The v1 on MX23 only gets 16 bits
> counter and has no match function. The v2 on MX28 extends the
> counter to 32 bits and add the match function.
>
> As the result, we need two instances of timers with v1 for better
> implementation, one for next_event and another for get_cycles.
> Otherwise, get_cycles may get imprecise result after long time
> cumulating. With v2, one instance can serve two purposes well.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> arch/arm/mach-mxs/timer.c | 285 +++++++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 285 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-mxs/timer.c
>
> diff --git a/arch/arm/mach-mxs/timer.c b/arch/arm/mach-mxs/timer.c
> new file mode 100644
> index 0000000..c52b465
> --- /dev/null
> +++ b/arch/arm/mach-mxs/timer.c
> @@ -0,0 +1,285 @@
> +/*
> + * Copyright (C) 2000-2001 Deep Blue Solutions
> + * 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
> + * 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/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/clockchips.h>
> +#include <linux/clk.h>
> +
> +#include <mach/hardware.h>
> +#include <asm/mach/time.h>
> +#include <mach/common.h>
> +
> +/*
> + * There are 2 versions of the timrot on Freescale MXS-based SoCs.
> + * The v1 on MX23 only gets 16 bits counter and has no match function.
> + * The v2 on MX28 extends the counter to 32 bits and add the match function.
> + *
> + * As the result, we need two instances of timers with v1 for better
> + * implementation, one for next_event and another for get_cycles. Otherwise,
> + * get_cycles may get imprecise result after long time cumulating.
> + * With v2, one instance can serve two purposes well.
> + */
> +#define timrot_is_v1() (cpu_is_mx23())
> +
> +#define HW_TIMROT_ROTCTRL 0x00
> +#define HW_TIMROT_TIMCTRLn(n) (0x20 + (n) * 0x40)
> +#define HW_TIMROT_RUNNING_COUNTn(n) (0x30 + (n) * 0x40)
> +#define HW_TIMROT_MATCH_COUNTn(n) (0x50 + (n) * 0x40)
> +#define BM_TIMROT_TIMCTRLn_RELOAD (1 << 6)
> +#define BM_TIMROT_TIMCTRLn_UPDATE (1 << 7)
> +#define BM_TIMROT_TIMCTRLn_MATCH_MODE (1 << 11)
> +#define BM_TIMROT_TIMCTRLn_IRQ_EN (1 << 14)
> +#define BM_TIMROT_TIMCTRLn_IRQ (1 << 15)
> +#define BP_TIMROT_TIMCTRLn_SELECT 0
> +#define BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL (timrot_is_v1() ? 0x8 : 0xb)
I don't like hiding different register offsets behind a constant. This
might make usage of the constant more expensive than the C-code let
expect.
> +
> +static struct clock_event_device clockevent_mxs;
> +static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
> +
> +static void __iomem *timer_base;
> +
> +static inline void timrot_irq_disable(void)
> +{
> + __raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN,
> + timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_CLR_ADDR);
> +}
> +
> +static inline void timrot_irq_enable(void)
> +{
> + __raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN,
> + timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_SET_ADDR);
> +}
> +
> +static void timrot_irq_acknowledge(void)
> +{
> + __raw_writel(BM_TIMROT_TIMCTRLn_IRQ,
> + timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_CLR_ADDR);
> +}
> +
> +static cycle_t timrot_get_cycles(struct clocksource *cs)
> +{
> + if (timrot_is_v1())
> + return ~((__raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(1))
> + & 0xffff0000) >> 16);
> + else
> + return ~__raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(0));
> +}
Maybe better implement timrotv1_get_cycles and timrotv2_get_cycles and
only do the distinction once at init time when setting the callback
instead of each time it is called.
> +static int timrot_set_next_event(unsigned long evt,
> + struct clock_event_device *dev)
> +{
> + unsigned long match;
> + int ret;
> +
> + /* timrot decrements the count */
> + if (timrot_is_v1()) {
> + __raw_writel(evt, timer_base + HW_TIMROT_RUNNING_COUNTn(0));
> + ret = 0;
> + } else {
> + match = __raw_readl(timer_base + HW_TIMROT_MATCH_COUNTn(0))
> + - evt;
> + __raw_writel(match, timer_base + HW_TIMROT_MATCH_COUNTn(0));
> + ret = (int)(match - __raw_readl(timer_base +
> + HW_TIMROT_RUNNING_COUNTn(0))) > 0 ? -ETIME : 0;
> + }
> +
> + return ret;
> +}
ditto
> +
> +static irqreturn_t mxs_timer_interrupt(int irq, void *dev_id)
> +{
> + struct clock_event_device *evt = &clockevent_mxs;
> +
> + timrot_irq_acknowledge();
> + evt->event_handler(evt);
> +
> + return IRQ_HANDLED;
> +}
> +
> +static struct irqaction mxs_timer_irq = {
> + .name = "MXS Timer Tick",
> + .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL,
IRQF_DISABLED is a noop, skip it.
> + .handler = mxs_timer_interrupt,
> +};
> +
> +#ifdef DEBUG
> +static const char *clock_event_mode_label[] = {
> + [CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
> + [CLOCK_EVT_MODE_ONESHOT] = "CLOCK_EVT_MODE_ONESHOT",
> + [CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN",
> + [CLOCK_EVT_MODE_UNUSED] = "CLOCK_EVT_MODE_UNUSED"
> +};
> +#endif /* DEBUG */
> +
> +static void mxs_set_mode(enum clock_event_mode mode,
> + struct clock_event_device *evt)
> +{
> + unsigned long flags;
> +
> + /*
> + * The timer interrupt generation is disabled at least
> + * for enough time to call mxs_set_next_event()
> + */
> + local_irq_save(flags);
I think set_mode is called with irqs already off.
> +
> + /* Disable interrupt in timer module */
> + timrot_irq_disable();
> +
> + if (mode != clockevent_mode) {
> + /* Set event time into far-far future */
> + __raw_writel(__raw_readl(timer_base +
> + HW_TIMROT_RUNNING_COUNTn(0)) + 3,
> + timer_base + HW_TIMROT_MATCH_COUNTn(0));
I don't know if this is needed, maybe there cannot be a pending event
when set_mode is called? Thomas?
> + /* Clear pending interrupt */
> + timrot_irq_acknowledge();
> + }
> +
> +#ifdef DEBUG
> + printk(KERN_INFO "mxs_set_mode: changing mode from %s to %s\n",
> + clock_event_mode_label[clockevent_mode],
> + clock_event_mode_label[mode]);
> +#endif /* DEBUG */
> +
> + /* Remember timer mode */
> + clockevent_mode = mode;
> + local_irq_restore(flags);
> +
> + switch (mode) {
> + case CLOCK_EVT_MODE_PERIODIC:
> + printk(KERN_ERR "mxs_set_mode: Periodic mode is not "
> + "supported for MXS-based\n");
> + break;
> + case CLOCK_EVT_MODE_ONESHOT:
> + /*
> + * Do not put overhead of interrupt enable/disable into
> + * mxs_set_next_event(), the core has about 4 minutes
> + * to call mxs_set_next_event() or shutdown clock after
> + * mode switching
> + */
> + local_irq_save(flags);
> + timrot_irq_enable();
> + local_irq_restore(flags);
> + break;
> + case CLOCK_EVT_MODE_SHUTDOWN:
> + case CLOCK_EVT_MODE_UNUSED:
> + case CLOCK_EVT_MODE_RESUME:
> + /* Left event sources disabled, no more interrupts appear */
> + break;
> + }
> +}
> +
> +static struct clock_event_device clockevent_mxs = {
> + .name = "mxs_timrot",
> + .features = CLOCK_EVT_FEAT_ONESHOT,
> + .shift = 32,
> + .set_mode = mxs_set_mode,
> + .set_next_event = timrot_set_next_event,
> + .rating = 200,
> +};
> +
> +static int __init mxs_clockevent_init(struct clk *timer_clk)
> +{
> + unsigned int c = clk_get_rate(timer_clk);
> +
> + clockevent_mxs.mult = div_sc(c, NSEC_PER_SEC, clockevent_mxs.shift);
> + clockevent_mxs.cpumask = cpumask_of(0);
> + if (timrot_is_v1()) {
> + clockevent_mxs.max_delta_ns =
> + clockevent_delta2ns(0xfffe, &clockevent_mxs);
> + clockevent_mxs.min_delta_ns =
> + clockevent_delta2ns(0xf, &clockevent_mxs);
> + } else {
> + clockevent_mxs.max_delta_ns =
> + clockevent_delta2ns(0xfffffffe, &clockevent_mxs);
> + clockevent_mxs.min_delta_ns =
> + clockevent_delta2ns(0xff, &clockevent_mxs);
> + }
> +
> + clockevents_register_device(&clockevent_mxs);
> +
> + return 0;
> +}
> +
> +static struct clocksource clocksource_mxs = {
> + .name = "mxs_timer",
> + .rating = 200,
> + .read = timrot_get_cycles,
> + .mask = CLOCKSOURCE_MASK(32),
> + .shift = 10,
> + .flags = CLOCK_SOURCE_IS_CONTINUOUS,
> +};
> +
> +static int __init mxs_clocksource_init(struct clk *timer_clk)
> +{
> + unsigned int c = clk_get_rate(timer_clk);
> +
> + if (timrot_is_v1())
> + clocksource_mxs.mask = CLOCKSOURCE_MASK(16);
I wonder if a shift of 10 is a bit heavy for a 16 bit timer.
> + clocksource_mxs.mult = clocksource_hz2mult(c, clocksource_mxs.shift);
> + clocksource_register(&clocksource_mxs);
> +
> + return 0;
> +}
> +
> +void __init mxs_timer_init(struct clk *timer_clk,
> + void __iomem *base, int irq)
> +{
> + clk_enable(timer_clk);
> +
> + timer_base = base;
> +
> + /*
> + * Initialize timers to a known state
> + */
> + mxs_reset_block(base + HW_TIMROT_ROTCTRL);
> +
> + if (timrot_is_v1()) {
> + /* timer0 is for next_event */
The more usual names are clock_event ...
> + __raw_writel(
> + BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL |
> + BM_TIMROT_TIMCTRLn_UPDATE |
> + BM_TIMROT_TIMCTRLn_IRQ_EN,
> + base + HW_TIMROT_TIMCTRLn(0));
> + /* timer1 is for get_cycles */
and clocksource.
> + __raw_writel(
> + BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL |
> + BM_TIMROT_TIMCTRLn_RELOAD,
> + base + HW_TIMROT_TIMCTRLn(1));
> + __raw_writel(0xffff, timer_base + HW_TIMROT_RUNNING_COUNTn(1));
> +
> + } else {
> + __raw_writel(
> + BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL |
> + BM_TIMROT_TIMCTRLn_IRQ_EN |
> + BM_TIMROT_TIMCTRLn_MATCH_MODE,
> + timer_base + HW_TIMROT_TIMCTRLn(0));
> + }
> +
> + /* init and register the timer to the framework */
> + mxs_clocksource_init(timer_clk);
> + mxs_clockevent_init(timer_clk);
> +
> + /* Make irqs happen */
> + setup_irq(irq, &mxs_timer_irq);
> +}
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH 07/15] ARM: mxs: Add gpio support
2010-11-26 6:49 ` [PATCH 07/15] ARM: mxs: Add gpio support Shawn Guo
@ 2010-11-30 16:21 ` Uwe Kleine-König
0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-11-30 16:21 UTC (permalink / raw)
To: linux-arm-kernel
Hello,
On Fri, Nov 26, 2010 at 02:49:06PM +0800, Shawn Guo wrote:
> MXS-based SoCs implement gpio support in block PINCTRL.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> arch/arm/mach-mxs/gpio.c | 364 +++++++++++++++++++++++++++++++++
> arch/arm/mach-mxs/include/mach/gpio.h | 49 +++++
> 2 files changed, 413 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-mxs/gpio.c
> create mode 100644 arch/arm/mach-mxs/include/mach/gpio.h
>
> diff --git a/arch/arm/mach-mxs/gpio.c b/arch/arm/mach-mxs/gpio.c
> new file mode 100644
> index 0000000..7e3674b
> --- /dev/null
> +++ b/arch/arm/mach-mxs/gpio.c
> @@ -0,0 +1,364 @@
> +/*
> + * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
> + * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
> + *
> + * Based on code from Freescale,
> + * Copyright (C) 2004-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/init.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/irq.h>
> +#include <linux/gpio.h>
> +#include <mach/hardware.h>
> +#include <asm-generic/bug.h>
> +
> +static struct mxs_gpio_port *mxs_gpio_ports;
> +static int gpio_table_size;
> +
> +#define PINCTRL_DOUT(n) ((cpu_is_mx23() ? 0x0500 : 0x0700) + (n) * 0x10)
> +#define PINCTRL_DIN(n) ((cpu_is_mx23() ? 0x0600 : 0x0900) + (n) * 0x10)
> +#define PINCTRL_DOE(n) ((cpu_is_mx23() ? 0x0700 : 0x0b00) + (n) * 0x10)
> +#define PINCTRL_PIN2IRQ(n) ((cpu_is_mx23() ? 0x0800 : 0x1000) + (n) * 0x10)
> +#define PINCTRL_IRQEN(n) ((cpu_is_mx23() ? 0x0900 : 0x1100) + (n) * 0x10)
> +#define PINCTRL_IRQLEV(n) ((cpu_is_mx23() ? 0x0a00 : 0x1200) + (n) * 0x10)
> +#define PINCTRL_IRQPOL(n) ((cpu_is_mx23() ? 0x0b00 : 0x1300) + (n) * 0x10)
> +#define PINCTRL_IRQSTAT(n) ((cpu_is_mx23() ? 0x0c00 : 0x1400) + (n) * 0x10)
> +
> +#define GPIO_INT_FALL_EDGE 0x0
> +#define GPIO_INT_LOW_LEV 0x1
> +#define GPIO_INT_RISE_EDGE 0x2
> +#define GPIO_INT_HIGH_LEV 0x3
> +
> +/* Note: This driver assumes 32 GPIOs are handled in one register */
> +
> +static void _clear_gpio_irqstatus(struct mxs_gpio_port *port, u32 index)
> +{
> + __raw_writel(1 << index,
> + port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR_ADDR);
> +}
> +
> +static void _set_gpio_irqenable(struct mxs_gpio_port *port, u32 index,
> + int enable)
> +{
> + if (enable == 0) {
> + __raw_writel(1 << index,
> + port->base + PINCTRL_PIN2IRQ(port->id) + MXS_CLR_ADDR);
> + __raw_writel(1 << index,
> + port->base + PINCTRL_IRQEN(port->id) + MXS_CLR_ADDR);
> + } else {
> + __raw_writel(1 << index,
> + port->base + PINCTRL_PIN2IRQ(port->id) + MXS_SET_ADDR);
> + __raw_writel(1 << index,
> + port->base + PINCTRL_IRQEN(port->id) + MXS_SET_ADDR);
> + }
> +}
> +
> +static void gpio_ack_irq(u32 irq)
> +{
> + u32 gpio = irq_to_gpio(irq);
> + _clear_gpio_irqstatus(&mxs_gpio_ports[gpio / 32], gpio & 0x1f);
> +}
> +
> +static void gpio_mask_irq(u32 irq)
> +{
> + u32 gpio = irq_to_gpio(irq);
> + _set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 0);
> +}
> +
> +static void gpio_unmask_irq(u32 irq)
> +{
> + u32 gpio = irq_to_gpio(irq);
> + _set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 1);
> +}
> +
> +static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset);
> +
> +static int gpio_set_irq_type(u32 irq, u32 type)
> +{
> + u32 gpio = irq_to_gpio(irq);
> + struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32];
> + u32 val;
> + int edge;
> +
> + port->both_edges &= ~(1 << (gpio & 31));
> + switch (type) {
> + case IRQ_TYPE_EDGE_RISING:
> + edge = GPIO_INT_RISE_EDGE;
> + break;
> + case IRQ_TYPE_EDGE_FALLING:
> + edge = GPIO_INT_FALL_EDGE;
> + break;
> + case IRQ_TYPE_EDGE_BOTH:
> + val = mxs_gpio_get(&port->chip, gpio & 31);
> + if (val) {
> + edge = GPIO_INT_LOW_LEV;
> + pr_debug("mxs: set GPIO %d to low trigger\n", gpio);
> + } else {
> + edge = GPIO_INT_HIGH_LEV;
> + pr_debug("mxs: set GPIO %d to high trigger\n", gpio);
> + }
> + port->both_edges |= 1 << (gpio & 31);
This is ugly and might be racy. Do you really need to support
IRQ_TYPE_EDGE_BOTH?
> + break;
> + case IRQ_TYPE_LEVEL_LOW:
> + edge = GPIO_INT_LOW_LEV;
> + break;
> + case IRQ_TYPE_LEVEL_HIGH:
> + edge = GPIO_INT_HIGH_LEV;
> + break;
> + default:
> + return -EINVAL;
> + }
> +
> + /* set level or edge */
> + if (edge & 0x1)
Why use 0x1 here instead of a constant?
> + __raw_writel(1 << (gpio & 31),
> + port->base + PINCTRL_IRQLEV(port->id) + MXS_SET_ADDR);
> + else
> + __raw_writel(1 << (gpio & 31),
> + port->base + PINCTRL_IRQLEV(port->id) + MXS_CLR_ADDR);
> +
> + /* set polarity */
> + if ((edge >> 1) & 0x1)
ditto
> + __raw_writel(1 << (gpio & 31),
> + port->base + PINCTRL_IRQPOL(port->id) + MXS_SET_ADDR);
> + else
> + __raw_writel(1 << (gpio & 31),
> + port->base + PINCTRL_IRQPOL(port->id) + MXS_CLR_ADDR);
> +
> + _clear_gpio_irqstatus(port, gpio & 0x1f);
> +
> + return 0;
> +}
> +
> +static void mxs_flip_edge(struct mxs_gpio_port *port, u32 gpio)
> +{
> + u32 val;
> + int edge;
> +
> + edge = 1 << (gpio & 31);
> + val = __raw_readl(port->base + PINCTRL_IRQLEV(port->id));
> + if (val & edge) {
> + /* level is invalid for this function */
> + pr_err("mxs: invalid configuration for GPIO %d: %x\n",
> + gpio, edge);
> + return;
> + }
> + __raw_writel(1 << (gpio & 31),
> + port->base + PINCTRL_IRQPOL(port->id) + MXS_TOG_ADDR);
> +}
> +
> +/* MXS has one interrupt *per* gpio port */
> +static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc)
> +{
> + u32 irq_stat;
> + struct mxs_gpio_port *port = (struct mxs_gpio_port *)get_irq_data(irq);
> + u32 gpio_irq_no_base = port->virtual_irq_start;
> +
> + irq_stat = __raw_readl(port->base + PINCTRL_IRQSTAT(port->id)) &
> + __raw_readl(port->base + PINCTRL_IRQEN(port->id)) &
> + __raw_readl(port->base + PINCTRL_PIN2IRQ(port->id));
> +
> + while (irq_stat != 0) {
> + int irqoffset = fls(irq_stat) - 1;
> +
> + if (port->both_edges & (1 << irqoffset))
> + mxs_flip_edge(port, irqoffset);
> +
> + generic_handle_irq(gpio_irq_no_base + irqoffset);
> +
> + irq_stat &= ~(1 << irqoffset);
> + }
> +}
> +
> +/*
> + * Set interrupt number "irq" in the GPIO as a wake-up source.
> + * While system is running, all registered GPIO interrupts need to have
> + * wake-up enabled. When system is suspended, only selected GPIO interrupts
> + * need to have wake-up enabled.
> + * @param irq interrupt source number
> + * @param enable enable as wake-up if equal to non-zero
> + * @return This function returns 0 on success.
> + */
> +static int gpio_set_wake_irq(u32 irq, u32 enable)
> +{
> + u32 gpio = irq_to_gpio(irq);
> + u32 gpio_idx = gpio & 0x1f;
> + struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32];
> +
> + if (enable) {
> + if (port->irq_high && (gpio_idx >= 16))
> + enable_irq_wake(port->irq_high);
> + else
> + enable_irq_wake(port->irq);
> + } else {
> + if (port->irq_high && (gpio_idx >= 16))
> + disable_irq_wake(port->irq_high);
> + else
> + disable_irq_wake(port->irq);
> + }
> +
> + return 0;
> +}
> +
> +static struct irq_chip gpio_irq_chip = {
> + .ack = gpio_ack_irq,
> + .mask = gpio_mask_irq,
> + .unmask = gpio_unmask_irq,
> + .set_type = gpio_set_irq_type,
> + .set_wake = gpio_set_wake_irq,
> +};
> +
> +static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset,
> + int dir)
> +{
> + struct mxs_gpio_port *port =
> + container_of(chip, struct mxs_gpio_port, chip);
> + u32 l;
> + unsigned long flags;
> + void __iomem *reg = port->base + PINCTRL_DOE(port->id);
> +
> + spin_lock_irqsave(&port->lock, flags);
> + l = __raw_readl(reg);
> + if (dir)
> + l |= 1 << offset;
> + else
> + l &= ~(1 << offset);
> + __raw_writel(l, reg);
> + spin_unlock_irqrestore(&port->lock, flags);
No SET/CLR register set?
> +}
> +
> +static void mxs_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
> +{
> + struct mxs_gpio_port *port =
> + container_of(chip, struct mxs_gpio_port, chip);
> + u32 l;
> + unsigned long flags;
> + void __iomem *reg = port->base + PINCTRL_DOUT(port->id);
> +
> + spin_lock_irqsave(&port->lock, flags);
> + l = (__raw_readl(reg) & (~(1 << offset))) | (!!value << offset);
> + __raw_writel(l, reg);
> + spin_unlock_irqrestore(&port->lock, flags);
> +}
> +
> +static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset)
> +{
> + struct mxs_gpio_port *port =
> + container_of(chip, struct mxs_gpio_port, chip);
> + void __iomem *reg = port->base + PINCTRL_DIN(port->id);
> +
> + return (__raw_readl(reg) >> offset) & 1;
> +}
> +
> +static int mxs_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
> +{
> + _set_gpio_direction(chip, offset, 0);
> + return 0;
> +}
> +
> +static int mxs_gpio_direction_output(struct gpio_chip *chip,
> + unsigned offset, int value)
> +{
> + mxs_gpio_set(chip, offset, value);
> + _set_gpio_direction(chip, offset, 1);
> + return 0;
> +}
> +
> +int __init mxs_gpio_init(struct mxs_gpio_port *port, int cnt)
> +{
> + int i, j;
> +
> + /* save for local usage */
> + mxs_gpio_ports = port;
> + gpio_table_size = cnt;
> +
> + printk(KERN_INFO "MXS GPIO hardware\n");
pr_info?
> +
> + for (i = 0; i < cnt; i++) {
> + /* disable the interrupt and clear the status */
> + __raw_writel(0, port[i].base +
> + PINCTRL_PIN2IRQ(i));
> + __raw_writel(0, port[i].base +
> + PINCTRL_IRQEN(i));
> + __raw_writel(~0, port[i].base +
> + PINCTRL_IRQSTAT(i) + MXS_CLR_ADDR);
> +
> + for (j = port[i].virtual_irq_start;
> + j < port[i].virtual_irq_start + 32; j++) {
> + set_irq_chip(j, &gpio_irq_chip);
> + set_irq_handler(j, handle_level_irq);
> + set_irq_flags(j, IRQF_VALID);
> + }
> +
> + /* register gpio chip */
> + port[i].chip.direction_input = mxs_gpio_direction_input;
> + port[i].chip.direction_output = mxs_gpio_direction_output;
> + port[i].chip.get = mxs_gpio_get;
> + port[i].chip.set = mxs_gpio_set;
> + port[i].chip.base = i * 32;
> + port[i].chip.ngpio = 32;
> +
> + spin_lock_init(&port[i].lock);
> +
> + /* its a serious configuration bug when it fails */
> + BUG_ON( gpiochip_add(&port[i].chip) < 0 );
> +
> + /* setup one handler for each entry */
> + set_irq_chained_handler(port[i].irq, mxs_gpio_irq_handler);
> + set_irq_data(port[i].irq, &port[i]);
> + }
> +
> + return 0;
> +}
> +
> +#define DEFINE_MXS_GPIO_PORT(soc, _id) \
> + { \
> + .chip.label = "gpio-" #_id, \
> + .id = _id, \
> + .irq = soc ## _INT_GPIO ## _id, \
> + .base = soc ## _IO_ADDRESS( \
> + soc ## _PINCTRL ## _BASE_ADDR), \
> + .virtual_irq_start = MXS_GPIO_IRQ_START + (_id) * 32, \
> + }
> +
> +#define DEFINE_REGISTER_FUNCTION(prefix) \
> +int __init prefix ## _register_gpios(void) \
> +{ \
> + return mxs_gpio_init(prefix ## _gpio_ports, \
> + ARRAY_SIZE(prefix ## _gpio_ports)); \
> +}
> +
> +#ifdef CONFIG_SOC_IMX23
> +static struct mxs_gpio_port mx23_gpio_ports[] = {
> + DEFINE_MXS_GPIO_PORT(MX23, 0),
> + DEFINE_MXS_GPIO_PORT(MX23, 1),
> + DEFINE_MXS_GPIO_PORT(MX23, 2),
> +};
> +DEFINE_REGISTER_FUNCTION(mx23)
> +#endif
> +
> +#ifdef CONFIG_SOC_IMX28
> +static struct mxs_gpio_port mx28_gpio_ports[] = {
> + DEFINE_MXS_GPIO_PORT(MX28, 0),
> + DEFINE_MXS_GPIO_PORT(MX28, 1),
> + DEFINE_MXS_GPIO_PORT(MX28, 2),
> + DEFINE_MXS_GPIO_PORT(MX28, 3),
> + DEFINE_MXS_GPIO_PORT(MX28, 4),
> +};
> +DEFINE_REGISTER_FUNCTION(mx28)
> +#endif
> diff --git a/arch/arm/mach-mxs/include/mach/gpio.h b/arch/arm/mach-mxs/include/mach/gpio.h
> new file mode 100644
> index 0000000..7692de6
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/gpio.h
> @@ -0,0 +1,49 @@
> +/*
> + * Copyright 2007 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
> + * 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_MXS_GPIO_H__
> +#define __MACH_MXS_GPIO_H__
> +
> +#include <linux/spinlock.h>
> +#include <mach/hardware.h>
> +#include <asm-generic/gpio.h>
> +
> +#define MXS_GPIO_NR(bank, nr) ((bank) * 32 + (nr))
> +
> +/* use gpiolib dispatchers */
> +#define gpio_get_value __gpio_get_value
> +#define gpio_set_value __gpio_set_value
> +#define gpio_cansleep __gpio_cansleep
> +
> +#define gpio_to_irq(gpio) (MXS_GPIO_IRQ_START + (gpio))
> +#define irq_to_gpio(irq) ((irq) - MXS_GPIO_IRQ_START)
> +
> +struct mxs_gpio_port {
> + void __iomem *base;
> + int id;
> + int irq;
> + int irq_high;
> + int virtual_irq_start;
> + struct gpio_chip chip;
> + u32 both_edges;
> + spinlock_t lock;
> +};
This doesn't need to be that public, arch/arm/mach-mxs/gpio.h would be
enough.
> +
> +int mxs_gpio_init(struct mxs_gpio_port*, int);
ditto.
> +
> +#endif /* __MACH_MXS_GPIO_H__ */
> --
> 1.7.1
>
>
>
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH 08/15] ARM: mxs: Add iomux support
2010-11-26 6:49 ` [PATCH 08/15] ARM: mxs: Add iomux support Shawn Guo
@ 2010-11-30 16:32 ` Uwe Kleine-König
0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-11-30 16:32 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Nov 26, 2010 at 02:49:07PM +0800, Shawn Guo wrote:
> MXS-based SoCs implements iomux functions in block PINCTRL.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> arch/arm/mach-mxs/include/mach/iomux-mx23.h | 29 +++++++
> arch/arm/mach-mxs/include/mach/iomux-mx28.h | 44 +++++++++++
> arch/arm/mach-mxs/include/mach/iomux.h | 77 +++++++++++++++++++
> arch/arm/mach-mxs/iomux.c | 110 +++++++++++++++++++++++++++
> 4 files changed, 260 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-mxs/include/mach/iomux-mx23.h
> create mode 100644 arch/arm/mach-mxs/include/mach/iomux-mx28.h
> create mode 100644 arch/arm/mach-mxs/include/mach/iomux.h
> create mode 100644 arch/arm/mach-mxs/iomux.c
>
> diff --git a/arch/arm/mach-mxs/include/mach/iomux-mx23.h b/arch/arm/mach-mxs/include/mach/iomux-mx23.h
> new file mode 100644
> index 0000000..3fc0439
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/iomux-mx23.h
> @@ -0,0 +1,29 @@
> +/*
> + * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
> + * Copyright (C) 2010 Freescale Semiconductor, Inc.
> + *
> + * 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
> + */
> +
> +#ifndef __MACH_IOMUX_MX23_H__
> +#define __MACH_IOMUX_MX23_H__
> +
> +#include <mach/iomux.h>
> +
> +/*
> + * The naming convention for the pad modes is MX23_PAD_<padname>__<padmode>
> + * If <padname> or <padmode> refers to a GPIO, it is named GPIO_<unit>_<num>
> + * See also iomux.h
> + *
> + * BANK PIN MUX VOL MA PULL
> + */
> +/* DUART */
> +#define MX23_PAD_PWM0__DUART_RX IOMUX_PAD(1, 26, PAD_MUXSEL_2, PAD_VOL_NONE, PAD_4MA, PAD_NOPULL)
> +#define MX23_PAD_PWM1__DUART_TX IOMUX_PAD(1, 27, PAD_MUXSEL_2, PAD_VOL_NONE, PAD_4MA, PAD_NOPULL)
> +
> +#endif /* __MACH_IOMUX_MX23_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/iomux-mx28.h b/arch/arm/mach-mxs/include/mach/iomux-mx28.h
> new file mode 100644
> index 0000000..ca37a15
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/iomux-mx28.h
> @@ -0,0 +1,44 @@
> +/*
> + * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
> + * Copyright (C) 2010 Freescale Semiconductor, Inc.
> + *
> + * 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
> + */
> +
> +#ifndef __MACH_IOMUX_MX28_H__
> +#define __MACH_IOMUX_MX28_H__
> +
> +#include <mach/iomux.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.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/mach-mxs/include/mach/iomux.h b/arch/arm/mach-mxs/include/mach/iomux.h
> new file mode 100644
> index 0000000..27bcada
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/iomux.h
> @@ -0,0 +1,77 @@
> +/*
> + * 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_MXS_IOMUX_H__
> +#define __MACH_MXS_IOMUX_H__
> +
> +typedef struct pad_desc {
> + unsigned bank:3;
> + unsigned pin:5;
> + unsigned muxsel:2;
> + unsigned ma:3;
> + unsigned vol:2;
> + unsigned pull:1;
> +} iomux_cfg_t;
mxc just switches to u64 (IIRC) for pad descriptions because the values
are easier to manipulate. This would be better for mxs, too.
> +
> +#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
> +
> +/*
> + * setups a single pad in the iomuxer
> + */
> +int mxs_iomux_setup_pad(iomux_cfg_t *pad);
> +
> +/*
> + * setups multiple pads
> + * convenient way to call the above function with tables
> + */
> +int mxs_iomux_setup_multiple_pads(iomux_cfg_t *pad_list, unsigned count);
> +
> +/*
> + * Initialise the iomux controller
> + */
> +void mxs_iomux_init(void __iomem *iomux_base);
> +
> +#endif /* __MACH_MXS_IOMUX_H__*/
> diff --git a/arch/arm/mach-mxs/iomux.c b/arch/arm/mach-mxs/iomux.c
> new file mode 100644
> index 0000000..803cadf
> --- /dev/null
> +++ b/arch/arm/mach-mxs/iomux.c
> @@ -0,0 +1,110 @@
> +/*
> + * Copyright 2004-2006,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.h>
> +
> +static void __iomem *base;
> +
> +/*
> + * configures a single pad in the iomuxer
> + */
> +int mxs_iomux_setup_pad(iomux_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 */
> + ofs = cpu_is_mx23() ? 0x200 : 0x300;
> + ofs += pad->bank * 0x40 + pad->pin / 8 * 0x10;
> + /* ma */
> + if (pad->ma != PAD_MA_NONE)
> + {
> + bp = pad->pin % 8 * 4;
> + bm = 0x3 << bp;
> + reg = __raw_readl(base + ofs);
> + reg &= ~bm;
> + reg |= pad->ma << bp;
> + __raw_writel(reg, base + ofs);
> + }
> + /* vol */
> + if (pad->vol != PAD_VOL_NONE)
> + {
> + bp = pad->pin % 8 * 4 + 2;
> + bm = 0x1 << bp;
> + reg = __raw_readl(base + ofs);
> + reg &= ~bm;
> + reg |= pad->vol << bp;
> + __raw_writel(reg, base + ofs);
> + }
> +
> + /* pull */
> + ofs = cpu_is_mx23() ? 0x400 : 0x600;
> + ofs += 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(mxs_iomux_setup_pad);
Really needed?
> +
> +int mxs_iomux_setup_multiple_pads(iomux_cfg_t *pad_list, unsigned count)
> +{
> + iomux_cfg_t *p = pad_list;
> + int i;
> + int ret;
> +
> + for (i = 0; i < count; i++) {
> + ret = mxs_iomux_setup_pad(p);
> + if (ret)
> + return ret;
> + p++;
> + }
> +
> + return 0;
> +}
> +EXPORT_SYMBOL(mxs_iomux_setup_multiple_pads);
> +
> +void mxs_iomux_init(void __iomem *iomux_base)
> +{
> + base = iomux_base;
> +}
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH 09/15] ARM: mxs: Add clock support
2010-11-26 6:49 ` [PATCH 09/15] ARM: mxs: Add clock support Shawn Guo
@ 2010-11-30 16:39 ` Uwe Kleine-König
2010-12-07 13:09 ` Shawn Guo
2010-12-02 15:07 ` Uwe Kleine-König
1 sibling, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-11-30 16:39 UTC (permalink / raw)
To: linux-arm-kernel
Hello Shawn,
On Fri, Nov 26, 2010 at 02:49:08PM +0800, Shawn Guo wrote:
> Add clock for MXS-based SoCs, MX23 and MX28.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> arch/arm/mach-mxs/clock-mx23.c | 521 ++++++++++++++++++++++
> arch/arm/mach-mxs/clock-mx28.c | 732 +++++++++++++++++++++++++++++++
> arch/arm/mach-mxs/clock.c | 201 +++++++++
> arch/arm/mach-mxs/include/mach/clkdev.h | 7 +
> arch/arm/mach-mxs/include/mach/clock.h | 64 +++
> arch/arm/mach-mxs/regs-clkctrl-mx23.h | 455 +++++++++++++++++++
> arch/arm/mach-mxs/regs-clkctrl-mx28.h | 663 ++++++++++++++++++++++++++++
> 7 files changed, 2643 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-mxs/clock-mx23.c
> create mode 100644 arch/arm/mach-mxs/clock-mx28.c
> create mode 100644 arch/arm/mach-mxs/clock.c
> create mode 100644 arch/arm/mach-mxs/include/mach/clkdev.h
> create mode 100644 arch/arm/mach-mxs/include/mach/clock.h
> create mode 100644 arch/arm/mach-mxs/regs-clkctrl-mx23.h
> create mode 100644 arch/arm/mach-mxs/regs-clkctrl-mx28.h
>
> diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c
> new file mode 100644
> index 0000000..832db0b
> --- /dev/null
> +++ b/arch/arm/mach-mxs/clock-mx23.c
> @@ -0,0 +1,521 @@
> +/*
> + * 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-mx23.h"
> +
> +#define CLKCTRL_BASE_ADDR MX23_IO_ADDRESS(MX23_CLKCTRL_BASE_ADDR)
> +#define DIGCTRL_BASE_ADDR MX23_IO_ADDRESS(MX23_DIGCTL_BASE_ADDR)
> +
> +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;
> +}
Hmm, I would have used an approach that is quickly switchable to the
generic clock stuff posted a few times here. But probably already too
late. So it's up to you to decide when to switch (or if at all).
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH 04/15] ARM: mxs: Add interrupt support
2010-11-30 13:56 ` Uwe Kleine-König
@ 2010-11-30 17:02 ` Russell King - ARM Linux
2010-12-01 11:23 ` Shawn Guo
1 sibling, 0 replies; 146+ messages in thread
From: Russell King - ARM Linux @ 2010-11-30 17:02 UTC (permalink / raw)
To: linux-arm-kernel
On Tue, Nov 30, 2010 at 02:56:23PM +0100, Uwe Kleine-K?nig wrote:
> > + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
> > + ldr \base, =icoll_base
> Maybe it's worth to hardcode the base address if only a single cpu is
> compiled in? And what about setting the base register in
> get_irqnr_preamble?
>
> > + ldr \base, [\base]
> > + ldr \irqnr, [\base, #0x70]
> > + cmp \irqnr, #0x7F
> > + moveqs \irqnr, #0
> Hmm, you only need that cmp+moveqs because you cannot be sure that an
> irq is pending, right. Maybe it would make sense not to check for irqs
> in a loop? (This is a arm-global thing, Russell?) (BTW, you're lucky,
> for your irq controller it's only ugly to check if there is an irq
> pending. IIRC ns9xxx has a race here.)
It always makes sense to check for more IRQs after you've processed
the first one before returning. Entering and exiting from the calling
context is very expensive compared to looping back to check for further
interrupts.
It's also possible for interrupts to be received on a core, but there
to be no IRQ pending in the controller. So you can't guarantee that
you have work to do just because the CPU entered the IRQ vector. This
is especially true with level-activated IRQ sources.
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH 12/15] ARM: mxs: Dynamically allocate fec devices
2010-11-26 6:49 ` [PATCH 12/15] ARM: mxs: Dynamically allocate fec devices Shawn Guo
@ 2010-11-30 20:01 ` Uwe Kleine-König
0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-11-30 20:01 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Nov 26, 2010 at 02:49:11PM +0800, Shawn Guo wrote:
> Dynamically allocate fec devices for MX28, which gets dual
> fec interface.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> arch/arm/mach-mxs/devices-mx28.h | 6 +++
> arch/arm/mach-mxs/devices/platform-fec.c | 51 +++++++++++++++++++++++
> arch/arm/mach-mxs/include/mach/devices-common.h | 12 +++++
> 3 files changed, 69 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-mxs/devices/platform-fec.c
>
> diff --git a/arch/arm/mach-mxs/devices-mx28.h b/arch/arm/mach-mxs/devices-mx28.h
> index 47c2f04..c509e5d 100644
> --- a/arch/arm/mach-mxs/devices-mx28.h
> +++ b/arch/arm/mach-mxs/devices-mx28.h
> @@ -14,3 +14,9 @@
> extern const struct mxs_duart_data mx28_duart_data __initconst;
> #define mx28_add_duart() \
> mxs_add_duart(&mx28_duart_data)
> +
> +extern const struct mxs_fec_data mx28_fec_data[] __initconst;
> +#define mx28_add_fec(id, pdata) \
> + mxs_add_fec(&mx28_fec_data[id], pdata)
> +#define mx28_add_fec0(pdata) mx28_add_fec(0, pdata)
> +#define mx28_add_fec1(pdata) mx28_add_fec(1, pdata)
On MXC I only kept the defines that have the id in the macro name for
compatibility. Just to let you know.
> diff --git a/arch/arm/mach-mxs/devices/platform-fec.c b/arch/arm/mach-mxs/devices/platform-fec.c
> new file mode 100644
> index 0000000..a2389b2
> --- /dev/null
> +++ b/arch/arm/mach-mxs/devices/platform-fec.c
> @@ -0,0 +1,51 @@
> +/*
> + * Copyright (C) 2010 Pengutronix
> + * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
> + *
> + * 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 <asm/sizes.h>
> +#include <mach/hardware.h>
> +#include <mach/devices-common.h>
> +
> +#define mxs_fec_data_entry_single(soc, _id, _size) \
> + { \
> + .id = _id, \
> + .iobase = soc ## _ENET_MAC ## _id ## _BASE_ADDR, \
> + .iosize = _size, \
You don't necessarily need to add the size here as it's equal for all
devices.
> + .irq = soc ## _INT_ENET_MAC ## _id, \
> + }
> +
> +#define mxs_fec_data_entry(soc, _id, _size) \
> + [_id] = mxs_fec_data_entry_single(soc, _id, _size)
> +
> +#ifdef CONFIG_SOC_IMX28
> +const struct mxs_fec_data mx28_fec_data[] __initconst = {
> +#define mx28_fec_data_entry(_id) \
> + mxs_fec_data_entry(MX28, _id, SZ_16K)
> + mx28_fec_data_entry(0),
> + mx28_fec_data_entry(1),
> +};
> +#endif
> +
> +struct platform_device *__init mxs_add_fec(
> + const struct mxs_fec_data *data,
> + const struct fec_platform_data *pdata)
> +{
> + struct resource res[] = {
> + {
> + .start = data->iobase,
> + .end = data->iobase + data->iosize - 1,
> + .flags = IORESOURCE_MEM,
> + }, {
> + .start = data->irq,
> + .end = data->irq,
> + .flags = IORESOURCE_IRQ,
> + },
> + };
> +
> + return mxs_add_platform_device("fec", data->id,
> + res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
> +}
> diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h
> index 07b4439..3da48d4 100644
> --- a/arch/arm/mach-mxs/include/mach/devices-common.h
> +++ b/arch/arm/mach-mxs/include/mach/devices-common.h
> @@ -32,3 +32,15 @@ struct mxs_duart_data {
> };
> struct platform_device *__init mxs_add_duart(
> const struct mxs_duart_data *data);
> +
> +/* fec */
> +#include <linux/fec.h>
> +struct mxs_fec_data {
> + int id;
> + resource_size_t iobase;
> + resource_size_t iosize;
> + resource_size_t irq;
> +};
> +struct platform_device *__init mxs_add_fec(
> + const struct mxs_fec_data *data,
> + const struct fec_platform_data *pdata);
> --
> 1.7.1
>
>
>
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH 13/15] ARM: mxs: Add initial mx23evk support
2010-11-26 6:49 ` [PATCH 13/15] ARM: mxs: Add initial mx23evk support Shawn Guo
@ 2010-11-30 20:02 ` Uwe Kleine-König
0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-11-30 20:02 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Nov 26, 2010 at 02:49:12PM +0800, Shawn Guo wrote:
> Add initial mx23evk support with duart.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> arch/arm/mach-mxs/mach-mx23evk.c | 59 ++++++++++++++++++++++++++++++++++++++
> 1 files changed, 59 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-mxs/mach-mx23evk.c
>
> diff --git a/arch/arm/mach-mxs/mach-mx23evk.c b/arch/arm/mach-mxs/mach-mx23evk.c
> new file mode 100644
> index 0000000..9048035
> --- /dev/null
> +++ b/arch/arm/mach-mxs/mach-mx23evk.c
> @@ -0,0 +1,59 @@
> +/*
> + * 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-mx23.h>
> +
> +#include "devices-mx23.h"
> +
> +static iomux_cfg_t mx23evk_pads[] = {
> + /* duart */
> + MX23_PAD_PWM0__DUART_RX,
> + MX23_PAD_PWM1__DUART_TX,
> +};
> +
> +static void __init mx23evk_init(void)
> +{
> + mxs_iomux_setup_multiple_pads(mx23evk_pads, ARRAY_SIZE(mx23evk_pads));
> +
> + mx23_add_duart();
> +}
> +
> +static void __init mx23evk_timer_init(void)
> +{
> + mx23_clocks_init();
> +}
> +
> +static struct sys_timer mx23evk_timer = {
> + .init = mx23evk_timer_init,
> +};
> +
> +MACHINE_START(MX23EVK, "Freescale MX23 EVK")
> + /* Maintainer: Freescale Semiconductor, Inc. */
> + .boot_params = PHYS_OFFSET + 0x100,
MX23_PHYS_OFFSET. Or better just don't define .boot_params at all.
> + .map_io = mx23_map_io,
> + .init_irq = mx23_init_irq,
> + .init_machine = mx23evk_init,
> + .timer = &mx23evk_timer,
> +MACHINE_END
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH 14/15] ARM: mxs: Add initial mx28evk support
2010-11-26 6:49 ` [PATCH 14/15] ARM: mxs: Add initial mx28evk support Shawn Guo
@ 2010-11-30 20:06 ` Uwe Kleine-König
0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-11-30 20:06 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Nov 26, 2010 at 02:49:13PM +0800, Shawn Guo wrote:
> Add initial mx28evk support with duart and fec0.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> arch/arm/mach-mxs/mach-mx28evk.c | 108 ++++++++++++++++++++++++++++++++++++++
> 1 files changed, 108 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-mxs/mach-mx28evk.c
>
> diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
> new file mode 100644
> index 0000000..901e6b1
> --- /dev/null
> +++ b/arch/arm/mach-mxs/mach-mx28evk.c
> @@ -0,0 +1,108 @@
> +/*
> + * 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-mx28.h"
> +
> +#define MX28EVK_FEC_PHY_POWER MXS_GPIO_NR(2, 15)
> +#define MX28EVK_FEC_PHY_RESET MXS_GPIO_NR(4, 13)
> +
> +static iomux_cfg_t mx28evk_pads[] = {
> + /* duart */
> + MX28_PAD_PWM0__DUART_RX,
> + MX28_PAD_PWM1__DUART_TX,
> +
> + /* fec0 */
> + 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 inline void mx28evk_fec_reset(void)
If the function is inlined everything is OK. If not it should live in
.init.text. I suggest to remove the inline to give the compiler the
freedom to inline it or not and mark it with __init.
> +{
> + 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);
technically gpio_direction_output can fail. Not sure this matters much
here though.
> +
> + /* 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);
You can save a few bytes here by using the same format string as above.
Obviously you need to pass "POWER" and "RESET" as parameter for that.
Is it worth the effort? Up to you to decide.
> + return;
> + }
> + gpio_direction_output(MX28EVK_FEC_PHY_RESET, 0);
> + mdelay(1);
> + gpio_set_value(MX28EVK_FEC_PHY_RESET, 1);
> +}
> +
> +static const struct fec_platform_data mx28_fec_pdata __initconst = {
> + .phy = PHY_INTERFACE_MODE_RMII,
> +};
> +
> +static void __init mx28evk_init(void)
> +{
> + mxs_iomux_setup_multiple_pads(mx28evk_pads, ARRAY_SIZE(mx28evk_pads));
> +
> + mx28_add_duart();
> +
> + mx28evk_fec_reset();
> + mx28_add_fec0(&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 = PHYS_OFFSET + 0x100,
> + .map_io = mx28_map_io,
> + .init_irq = mx28_init_irq,
> + .init_machine = mx28evk_init,
> + .timer = &mx28evk_timer,
> +MACHINE_END
> --
> 1.7.1
>
>
>
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH 15/15] ARM: mxs: Add build configuration for mxs
2010-11-26 6:49 ` [PATCH 15/15] ARM: mxs: Add build configuration for mxs Shawn Guo
@ 2010-11-30 20:08 ` Uwe Kleine-König
0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-11-30 20:08 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Nov 26, 2010 at 02:49:14PM +0800, Shawn Guo wrote:
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> arch/arm/Kconfig | 10 ++++++++++
> arch/arm/Makefile | 1 +
> arch/arm/mach-mxs/Kconfig | 34 ++++++++++++++++++++++++++++++++++
> arch/arm/mach-mxs/Makefile | 14 ++++++++++++++
> arch/arm/mach-mxs/Makefile.boot | 3 +++
> arch/arm/mach-mxs/devices/Kconfig | 5 +++++
> arch/arm/mach-mxs/devices/Makefile | 2 ++
> 7 files changed, 69 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-mxs/Kconfig
> create mode 100644 arch/arm/mach-mxs/Makefile
> create mode 100644 arch/arm/mach-mxs/Makefile.boot
> create mode 100644 arch/arm/mach-mxs/devices/Kconfig
> create mode 100644 arch/arm/mach-mxs/devices/Makefile
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index db524e7..b0a5130 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -351,6 +351,14 @@ config ARCH_MXC
> help
> Support for Freescale MXC/iMX-based family of processors
>
> +config ARCH_MXS
> + bool "Freescale MXS-based"
> + select GENERIC_CLOCKEVENTS
> + select ARCH_REQUIRE_GPIOLIB
> + select COMMON_CLKDEV
> + help
> + Support for Freescale MXS-based family of processors
> +
> config ARCH_STMP3XXX
> bool "Freescale STMP3xxx"
> select CPU_ARM926T
> @@ -924,6 +932,8 @@ source "arch/arm/plat-pxa/Kconfig"
>
> source "arch/arm/mach-mmp/Kconfig"
>
> +source "arch/arm/mach-mxs/Kconfig"
> +
> source "arch/arm/mach-realview/Kconfig"
>
> source "arch/arm/mach-sa1100/Kconfig"
optimally you should put the source line between mxc and stmp3xxx to
have the same order as in the symbol definition above.
> diff --git a/arch/arm/Makefile b/arch/arm/Makefile
> index 057beb8..c22c1ad 100644
> --- a/arch/arm/Makefile
> +++ b/arch/arm/Makefile
> @@ -158,6 +158,7 @@ machine-$(CONFIG_ARCH_MX25) := imx
> machine-$(CONFIG_ARCH_MX3) := mx3
> machine-$(CONFIG_ARCH_MX5) := mx5
> machine-$(CONFIG_ARCH_MXC91231) := mxc91231
> +machine-$(CONFIG_ARCH_MXS) := mxs
> machine-$(CONFIG_ARCH_NETX) := netx
> machine-$(CONFIG_ARCH_NOMADIK) := nomadik
> machine-$(CONFIG_ARCH_NS9XXX) := ns9xxx
> diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
> new file mode 100644
> index 0000000..c4ac7b4
> --- /dev/null
> +++ b/arch/arm/mach-mxs/Kconfig
> @@ -0,0 +1,34 @@
> +if ARCH_MXS
> +
> +source "arch/arm/mach-mxs/devices/Kconfig"
> +
> +config SOC_IMX23
> + bool
> + select CPU_ARM926T
> +
> +config SOC_IMX28
> + bool
> + select CPU_ARM926T
> +
> +comment "MXS platforms:"
> +
> +config MACH_MX23EVK
> + bool "Support MX23EVK Platform"
> + select SOC_IMX23
> + select MXS_HAVE_PLATFORM_DUART
> + default y
> + help
> + Include support for MX23EVK platform. This includes specific
> + configurations for the board and its peripherals.
> +
> +config MACH_MX28EVK
> + bool "Support MX28EVK Platform"
> + select SOC_IMX28
> + select MXS_HAVE_PLATFORM_DUART
> + select MXS_HAVE_PLATFORM_FEC
> + default y
> + help
> + Include support for MX28EVK platform. This includes specific
> + configurations for the board and its peripherals.
> +
> +endif
> diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
> new file mode 100644
> index 0000000..0b24b0d
> --- /dev/null
> +++ b/arch/arm/mach-mxs/Makefile
> @@ -0,0 +1,14 @@
> +#
> +# Makefile for the linux kernel.
not very helpful
> +#
> +
> +# Common support
> +obj-y := clock.o cpu.o devices.o gpio.o icoll.o iomux.o system.o timer.o
> +
> +obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
> +obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
> +
> +obj-$(CONFIG_MACH_MX23EVK) += mach-mx23evk.o
> +obj-$(CONFIG_MACH_MX28EVK) += mach-mx28evk.o
> +
> +obj-y += devices/
> diff --git a/arch/arm/mach-mxs/Makefile.boot b/arch/arm/mach-mxs/Makefile.boot
> new file mode 100644
> index 0000000..1568ad4
> --- /dev/null
> +++ b/arch/arm/mach-mxs/Makefile.boot
> @@ -0,0 +1,3 @@
> + zreladdr-y := 0x40008000
> +params_phys-y := 0x40000100
> +initrd_phys-y := 0x40800000
do you need params_phys and initrd_phys?
> diff --git a/arch/arm/mach-mxs/devices/Kconfig b/arch/arm/mach-mxs/devices/Kconfig
> new file mode 100644
> index 0000000..a35a2dc
> --- /dev/null
> +++ b/arch/arm/mach-mxs/devices/Kconfig
> @@ -0,0 +1,5 @@
> +config MXS_HAVE_PLATFORM_DUART
> + bool
> +
> +config MXS_HAVE_PLATFORM_FEC
> + bool
> diff --git a/arch/arm/mach-mxs/devices/Makefile b/arch/arm/mach-mxs/devices/Makefile
> new file mode 100644
> index 0000000..4b5266a
> --- /dev/null
> +++ b/arch/arm/mach-mxs/devices/Makefile
> @@ -0,0 +1,2 @@
> +obj-$(CONFIG_MXS_HAVE_PLATFORM_DUART) += platform-duart.o
> +obj-$(CONFIG_MXS_HAVE_PLATFORM_FEC) += platform-fec.o
> --
> 1.7.1
>
>
>
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 03/15] ARM: mxs: Add reset routines
2010-11-30 10:25 ` Uwe Kleine-König
@ 2010-12-01 10:45 ` Shawn Guo
2010-12-01 10:59 ` Uwe Kleine-König
2010-12-02 6:02 ` Shawn Guo
1 sibling, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-01 10:45 UTC (permalink / raw)
To: linux-arm-kernel
Hi Uwe,
2010/11/30 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello,
>
> On Mon, Nov 29, 2010 at 07:59:13PM +0800, Shawn Guo wrote:
>> +/*
>> + * Reset the system. It is called by machine_restart().
>> + */
>> +void arch_reset(char mode, const char *cmd)
>> +{
>> + ? ? /* Set wdog count */
>> + ? ? __raw_writel(1, wdog_base + MXS_RTC_WATCHDOG);
> Which unit is used here? ?Does the timer only start running when it's
> enabled below? ?Does this apply when the watchdog is already in use,
> too?
>
The unit RTC (i.MX28 RM chapter 22) which has watchdog function inside
is used here.
Good catch here. I thought the watchdog counter only starts counting
after WATCHDOG_EN is set. But I just confirmed it with designer that
the watchdog counter starts counting once CLKGATE is cleared, and
WATCHDOG_EN bit only controls the watchdog reset generation. Even in
this case, 1ms should be long enough for the WATCHDOG_EN setting below
to get executed before counter goes to 0. What is your concern here?
I should change mdelay(500) to mdelay(1).
>> +
>> + ? ? /* Assert SRS signal */
>> + ? ? __raw_writel(MXS_WATCHDOG_EN, wdog_base + MXS_SET_ADDR);
>> +
>> + ? ? /* Wait for reset to assert... */
>> + ? ? mdelay(500);
>> +
>> + ? ? pr_err("Watchdog reset failed to assert reset\n");
>> +
>> + ? ? /* Delay to allow the serial port to show the message */
>> + ? ? mdelay(50);
>> +
>> + ? ? /* We'll take a jump through zero as a poor second */
>> + ? ? cpu_reset(0);
>> +}
>> +
>> +void mxs_arch_reset_init(void __iomem *base)
>> +{
>> + ? ? struct clk *clk;
>> +
>> + ? ? wdog_base = base;
>> +
>> + ? ? clk = clk_get_sys("rtc", NULL);
>> + ? ? if (!IS_ERR(clk))
>> + ? ? ? ? ? ? clk_enable(clk);
> Actually I'm not sure if it's worth to do this. ?It might hurt if you
> want to save power.
>
> I'll try to find a time slot to look into that.
>
As this is the very initial support, I would not consider the power
saving very much. I will be very happy to applied your solution after
it becomes available.
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 03/15] ARM: mxs: Add reset routines
2010-12-01 10:45 ` Shawn Guo
@ 2010-12-01 10:59 ` Uwe Kleine-König
2010-12-01 11:34 ` Shawn Guo
0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-01 10:59 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Dec 01, 2010 at 06:45:20PM +0800, Shawn Guo wrote:
> Hi Uwe,
>
> 2010/11/30 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> > Hello,
> >
> > On Mon, Nov 29, 2010 at 07:59:13PM +0800, Shawn Guo wrote:
> >> +/*
> >> + * Reset the system. It is called by machine_restart().
> >> + */
> >> +void arch_reset(char mode, const char *cmd)
> >> +{
> >> + ? ? /* Set wdog count */
> >> + ? ? __raw_writel(1, wdog_base + MXS_RTC_WATCHDOG);
> > Which unit is used here? ?Does the timer only start running when it's
> > enabled below? ?Does this apply when the watchdog is already in use,
> > too?
> >
> The unit RTC (i.MX28 RM chapter 22) which has watchdog function inside
> is used here.
"unit" was meant as in "seconds". I assume it means seconds below, but
it doesn't matter much.
> Good catch here. I thought the watchdog counter only starts counting
> after WATCHDOG_EN is set. But I just confirmed it with designer that
> the watchdog counter starts counting once CLKGATE is cleared, and
> WATCHDOG_EN bit only controls the watchdog reset generation. Even in
> this case, 1ms should be long enough for the WATCHDOG_EN setting below
> to get executed before counter goes to 0. What is your concern here?
My concern is that it might happen that even though the timer is set to
1s, the first change happens nearly immediatly resulting in a zero.
Depending on the hardware a reset occurs when the enable bit is only set
after the counter reached zero.
> I should change mdelay(500) to mdelay(1).
>
> >> +
> >> + ? ? /* Assert SRS signal */
> >> + ? ? __raw_writel(MXS_WATCHDOG_EN, wdog_base + MXS_SET_ADDR);
> >> +
> >> + ? ? /* Wait for reset to assert... */
> >> + ? ? mdelay(500);
> >> +
> >> + ? ? pr_err("Watchdog reset failed to assert reset\n");
> >> +
> >> + ? ? /* Delay to allow the serial port to show the message */
> >> + ? ? mdelay(50);
> >> +
> >> + ? ? /* We'll take a jump through zero as a poor second */
> >> + ? ? cpu_reset(0);
> >> +}
> >> +
> >> +void mxs_arch_reset_init(void __iomem *base)
> >> +{
> >> + ? ? struct clk *clk;
> >> +
> >> + ? ? wdog_base = base;
> >> +
> >> + ? ? clk = clk_get_sys("rtc", NULL);
> >> + ? ? if (!IS_ERR(clk))
> >> + ? ? ? ? ? ? clk_enable(clk);
> > Actually I'm not sure if it's worth to do this. ?It might hurt if you
> > want to save power.
> >
> > I'll try to find a time slot to look into that.
> >
> As this is the very initial support, I would not consider the power
> saving very much. I will be very happy to applied your solution after
> it becomes available.
That's OK
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH 04/15] ARM: mxs: Add interrupt support
2010-11-30 13:56 ` Uwe Kleine-König
2010-11-30 17:02 ` Russell King - ARM Linux
@ 2010-12-01 11:23 ` Shawn Guo
1 sibling, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-01 11:23 UTC (permalink / raw)
To: linux-arm-kernel
Hi Uwe,
2010/11/30 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Shawn,
>
> On Fri, Nov 26, 2010 at 02:49:03PM +0800, Shawn Guo wrote:
[...]
>> +static void icoll_ack_irq(unsigned int irq)
>> +{
>> + ? ? __raw_writel(0, icoll_base + HW_ICOLL_VECTOR);
> You need to write this before handling the irq, no?
>
No need, indeed. Will remove it.
>> +
>> + ? ? /* ACK current interrupt (level 0) */
>> + ? ? __raw_writel(BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0,
>> + ? ? ? ? ? ? ? ? ? ? icoll_base + HW_ICOLL_LEVELACK);
>> +}
>> +
[...]
>> +
>> + ? ? .macro ?get_irqnr_and_base, irqnr, irqstat, base, tmp
>> + ? ? ldr ? ? \base, =icoll_base
> Maybe it's worth to hardcode the base address if only a single cpu is
> compiled in? ?And what about setting the base register in
> get_irqnr_preamble?
>
I suppose you have known that MX23 and MX28 could be built into single
zImage. So you are asking something as below, right?
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
ldr \irqnr, [\base, #0x70]
cmp \irqnr, #0x7F
moveqs \irqnr, #0
.endm
.macro get_irqnr_preamble, base, tmp
#if defined (CONFIG_SOC_IMX23) && defined (CONFIG_SOC_IMX28)
ldr \base, =icoll_base
ldr \base, [\base]
#elif defined (CONFIG_SOC_IMX23)
ldr \base, =MX23_ICOLL_BASE_ADDR
#else
ldr \base, =MX28_ICOLL_BASE_ADDR
#endif
.endm
>> + ? ? ldr ? ? \base, [\base]
>> + ? ? ldr ? ? \irqnr, [\base, #0x70]
>> + ? ? cmp ? ? \irqnr, #0x7F
>> + ? ? moveqs ?\irqnr, #0
> Hmm, you only need that cmp+moveqs because you cannot be sure that an
> irq is pending, right. ?Maybe it would make sense not to check for irqs
> in a loop? ?(This is a arm-global thing, Russell?) ?(BTW, you're lucky,
> for your irq controller it's only ugly to check if there is an irq
> pending. ?IIRC ns9xxx has a race here.)
>
Right. But we actually have a problem with that on i.MX28, because
i.MX28 uses IRQ 127 as below.
#define MX28_INT_GPIO0 127
So GPIO0 interrupt will not work. Any suggestion to work around it?
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 03/15] ARM: mxs: Add reset routines
2010-12-01 10:59 ` Uwe Kleine-König
@ 2010-12-01 11:34 ` Shawn Guo
0 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-01 11:34 UTC (permalink / raw)
To: linux-arm-kernel
Hi Uwe,
2010/12/1 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> On Wed, Dec 01, 2010 at 06:45:20PM +0800, Shawn Guo wrote:
>> Hi Uwe,
>>
>> 2010/11/30 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>> > Hello,
>> >
>> > On Mon, Nov 29, 2010 at 07:59:13PM +0800, Shawn Guo wrote:
>> >> +/*
>> >> + * Reset the system. It is called by machine_restart().
>> >> + */
>> >> +void arch_reset(char mode, const char *cmd)
>> >> +{
>> >> + ? ? /* Set wdog count */
>> >> + ? ? __raw_writel(1, wdog_base + MXS_RTC_WATCHDOG);
>> > Which unit is used here? ?Does the timer only start running when it's
>> > enabled below? ?Does this apply when the watchdog is already in use,
>> > too?
>> >
>> The unit RTC (i.MX28 RM chapter 22) which has watchdog function inside
>> is used here.
> "unit" was meant as in "seconds". ?I assume it means seconds below, but
> it doesn't matter much.
>
Sorry. The unit is 1ms.
>> Good catch here. ?I thought the watchdog counter only starts counting
>> after WATCHDOG_EN is set. ?But I just confirmed it with designer that
>> the watchdog counter starts counting once CLKGATE is cleared, and
>> WATCHDOG_EN bit only controls the watchdog reset generation. ?Even in
>> this case, 1ms should be long enough for the WATCHDOG_EN setting below
>> to get executed before counter goes to 0. ?What is your concern here?
> My concern is that it might happen that even though the timer is set to
> 1s, the first change happens nearly immediatly resulting in a zero.
> Depending on the hardware a reset occurs when the enable bit is only set
> after the counter reached zero.
>
Should the following changes be safe enough to address your concern?
/* Set wdog timer 10 ms */
__raw_writel(10, wdog_base + MXS_RTC_WATCHDOG);
/* Enable wdog reset */
__raw_writel(MXS_WATCHDOG_EN, wdog_base + MXS_SET_ADDR);
/* Wait for reset to assert... */
mdelay(10);
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 03/15] ARM: mxs: Add reset routines
2010-11-30 10:25 ` Uwe Kleine-König
2010-12-01 10:45 ` Shawn Guo
@ 2010-12-02 6:02 ` Shawn Guo
2010-12-02 7:27 ` Uwe Kleine-König
1 sibling, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-02 6:02 UTC (permalink / raw)
To: linux-arm-kernel
Hi Uwe,
2010/11/30 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello,
>
[...]
>
>> + ? ? /* Poll CLKGATE set */
>> + ? ? timeout = 0x400;
>> + ? ? while ((!(__raw_readl(reset_addr) & MXS_MODULE_CLKGATE)) && --timeout)
>> + ? ? ? ? ? ? /* nothing */;
>> + ? ? if (!timeout)
>> + ? ? ? ? ? ? goto error;
>> +
>> + ? ? /* Clear SFTRST */
>> + ? ? val = __raw_readl(reset_addr);
>> + ? ? val &= ~MXS_MODULE_SFTRST;
>> + ? ? __raw_writel(val, reset_addr);
>> + ? ? /* Wait 1us */
>> + ? ? udelay(1);
>> + ? ? /* Poll SFTRST cleared */
>> + ? ? timeout = 0x400;
>> + ? ? while ((__raw_readl(reset_addr) & MXS_MODULE_SFTRST) && --timeout)
>> + ? ? ? ? ? ? /* nothing */;
>> + ? ? if (!timeout)
>> + ? ? ? ? ? ? goto error;
>> +
>> + ? ? /* Clear CLKGATE */
>> + ? ? val = __raw_readl(reset_addr);
>> + ? ? val &= ~MXS_MODULE_CLKGATE;
>> + ? ? __raw_writel(val, reset_addr);
>> + ? ? /* Wait 1us */
>> + ? ? udelay(1);
>> + ? ? /* Poll CLKGATE cleared */
>> + ? ? timeout = 0x400;
>> + ? ? while ((__raw_readl(reset_addr) & MXS_MODULE_CLKGATE) && --timeout)
>> + ? ? ? ? ? ? /* nothing */;
>> + ? ? if (!timeout)
>> + ? ? ? ? ? ? goto error;
>
> There are quite some repetitions in this function. ?If you could get it
> down to something that looks like
>
> ? ? ? ?clear SFTRST
> ? ? ? ?udelay
> ? ? ? ?poll SFTRST cleared
>
> ? ? ? ?clear CLKGATE
> ? ? ? ?set SFTRST
> ? ? ? ?udelay
> ? ? ? ?poll CLKGATE set
>
> ? ? ? ?clear SFTRST
> ? ? ? ?udelay
> ? ? ? ?poll SFTRST cleared
>
> ? ? ? ?clear CLKGATE
> ? ? ? ?udelay
> ? ? ? ?poll CLKGATE cleared
>
> it's IMHO better than the comment above. ?If "clear CLKGATE" and "set
> SFTRST" can be done in a single step this might be done like that:
>
> ? ? ? ?/* comment describing setmask_poll */
> ? ? ? ?static int setmask_poll(void __iomem *addr, u32 set, u32 mask,
> ? ? ? ? ? ? ? ?u32 pollval, u32 pollmask, u32 *curval)
> ? ? ? ?{
> ? ? ? ? ? ? ? ?int timeout = 0x400;
>
> ? ? ? ? ? ? ? ?*curval &= ~mask;
> ? ? ? ? ? ? ? ?*curval |= set;
> ? ? ? ? ? ? ? ?__raw_writel(*curval, addr)
>
> ? ? ? ? ? ? ? ?/*
> ? ? ? ? ? ? ? ? * some nice comment about 1us being a good idea
> ? ? ? ? ? ? ? ? */
> ? ? ? ? ? ? ? ?udelay(1);
>
> ? ? ? ? ? ? ? ?do {
> ? ? ? ? ? ? ? ? ? ? ? ?*curval = __raw_readl(addr);
> ? ? ? ? ? ? ? ? ? ? ? ?if ((*curval & pollmask) == pollval)
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?return 0;
>
> ? ? ? ? ? ? ? ?} while(--timeout);
>
> ? ? ? ? ? ? ? ?return 1;
> ? ? ? ?}
>
> ? ? ? ?int mxs_reset_block(void __iomem *reset_addr)
> ? ? ? ?{
> ? ? ? ? ? ? ? ?u32 val = __raw_readl(reset_addr);
> ? ? ? ? ? ? ? ?int ret;
>
> ? ? ? ? ? ? ? ?/* clear SFTRST and poll SFTRST becoming clear */
> ? ? ? ? ? ? ? ?ret = setmask_poll(reset_addr,
> ? ? ? ? ? ? ? ? ? ? ? ?0, MXS_MODULE_SFTRST,
> ? ? ? ? ? ? ? ? ? ? ? ?0, MXS_MODULE_SFTRST, &val);
> ? ? ? ? ? ? ? ?if (ret)
> ? ? ? ? ? ? ? ? ? ? ? ?goto error;
>
> ? ? ? ? ? ? ? ?/* clear CLKGATE, set SFTRST and poll CLKGATE becoming set */
> ? ? ? ? ? ? ? ?ret = setmask_poll(reset_addr,
> ? ? ? ? ? ? ? ? ? ? ? ?MXS_MODULE_SFTRST, MXS_MODULE_SFTRST | MXS_MODULE_CLKGATE,
> ? ? ? ? ? ? ? ? ? ? ? ?0, MXS_MODULE_CLKGATE, &val);
> ? ? ? ? ? ? ? ?if (ret)
> ? ? ? ? ? ? ? ? ? ? ? ?goto error;
>
> ? ? ? ? ? ? ? ?...
> ? ? ? ?}
>
> Well, not very nice, but IMHO better that your code. ?Maybe
> mxs_reset_block fits in a Terminal that way without decreasing the font
> size :-)
>
I checked designer about doing "clear CLKGATE" and "set SFTRST" in a
single step, and got the following feedback.
"Per HW design, it is not safe to get those two done by write once
time. By two step write, one instruction period interval can be
ensured at least for clock enabling before sync. Soft reset. Your
code is only once time write in fact, so it shall not be equal to two
write operation."
In this case, how do the following changes look to you?
/*
* Clear the bit and poll it cleared, the bit has to be
* SFTRST(bit 31) or CLKGATE (bit 30) of block control register.
*/
static int clear_poll_bit(void __iomem *addr, u32 mask)
{
int timeout = 0x400;
/* clear the bit */
__raw_writel(mask, addr + MXS_CLR_ADDR);
/*
* SFTRST needs 3 GPMI clocks to settle, the reference manual
* recommends to wait 1us.
*/
udelay(1);
/* poll the bit becoming clear */
while ((__raw_readl(addr) & mask) && --timeout)
/* nothing */;
if (unlikely(!timeout))
return 1;
return 0;
}
int mxs_reset_block(void __iomem *reset_addr)
{
int ret;
int timeout = 0x400;
/* clear and poll SFTRST */
ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
if (ret)
goto error;
/* clear CLKGATE */
__raw_writel(MXS_MODULE_CLKGATE, reset_addr + MXS_CLR_ADDR);
/* set SFTRST to reset the block */
__raw_writel(MXS_MODULE_SFTRST, reset_addr + MXS_SET_ADDR);
udelay(1);
/* poll CLKGATE becoming set */
while ((!(__raw_readl(reset_addr) & MXS_MODULE_CLKGATE)) && --timeout)
/* nothing */;
if (unlikely(!timeout))
goto error;
/* clear and poll SFTRST */
ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
if (ret)
goto error;
/* clear and poll CLKGATE */
ret = clear_poll_bit(reset_addr, MXS_MODULE_CLKGATE);
if (ret)
goto error;
error:
pr_err("%s(%p): module reset timeout\n", __func__, reset_addr);
return -ETIMEDOUT;
}
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 03/15] ARM: mxs: Add reset routines
2010-12-02 6:02 ` Shawn Guo
@ 2010-12-02 7:27 ` Uwe Kleine-König
0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-02 7:27 UTC (permalink / raw)
To: linux-arm-kernel
Hi Shawn,
On Thu, Dec 02, 2010 at 02:02:39PM +0800, Shawn Guo wrote:
> Hi Uwe,
>
> 2010/11/30 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> > Hello,
> >
> [...]
> >
> >> + ? ? /* Poll CLKGATE set */
> >> + ? ? timeout = 0x400;
> >> + ? ? while ((!(__raw_readl(reset_addr) & MXS_MODULE_CLKGATE)) && --timeout)
> >> + ? ? ? ? ? ? /* nothing */;
> >> + ? ? if (!timeout)
> >> + ? ? ? ? ? ? goto error;
> >> +
> >> + ? ? /* Clear SFTRST */
> >> + ? ? val = __raw_readl(reset_addr);
> >> + ? ? val &= ~MXS_MODULE_SFTRST;
> >> + ? ? __raw_writel(val, reset_addr);
> >> + ? ? /* Wait 1us */
> >> + ? ? udelay(1);
> >> + ? ? /* Poll SFTRST cleared */
> >> + ? ? timeout = 0x400;
> >> + ? ? while ((__raw_readl(reset_addr) & MXS_MODULE_SFTRST) && --timeout)
> >> + ? ? ? ? ? ? /* nothing */;
> >> + ? ? if (!timeout)
> >> + ? ? ? ? ? ? goto error;
> >> +
> >> + ? ? /* Clear CLKGATE */
> >> + ? ? val = __raw_readl(reset_addr);
> >> + ? ? val &= ~MXS_MODULE_CLKGATE;
> >> + ? ? __raw_writel(val, reset_addr);
> >> + ? ? /* Wait 1us */
> >> + ? ? udelay(1);
> >> + ? ? /* Poll CLKGATE cleared */
> >> + ? ? timeout = 0x400;
> >> + ? ? while ((__raw_readl(reset_addr) & MXS_MODULE_CLKGATE) && --timeout)
> >> + ? ? ? ? ? ? /* nothing */;
> >> + ? ? if (!timeout)
> >> + ? ? ? ? ? ? goto error;
> >
> > There are quite some repetitions in this function. ?If you could get it
> > down to something that looks like
> >
> > ? ? ? ?clear SFTRST
> > ? ? ? ?udelay
> > ? ? ? ?poll SFTRST cleared
> >
> > ? ? ? ?clear CLKGATE
> > ? ? ? ?set SFTRST
> > ? ? ? ?udelay
> > ? ? ? ?poll CLKGATE set
> >
> > ? ? ? ?clear SFTRST
> > ? ? ? ?udelay
> > ? ? ? ?poll SFTRST cleared
> >
> > ? ? ? ?clear CLKGATE
> > ? ? ? ?udelay
> > ? ? ? ?poll CLKGATE cleared
> >
> > it's IMHO better than the comment above. ?If "clear CLKGATE" and "set
> > SFTRST" can be done in a single step this might be done like that:
> >
> > ? ? ? ?/* comment describing setmask_poll */
> > ? ? ? ?static int setmask_poll(void __iomem *addr, u32 set, u32 mask,
> > ? ? ? ? ? ? ? ?u32 pollval, u32 pollmask, u32 *curval)
> > ? ? ? ?{
> > ? ? ? ? ? ? ? ?int timeout = 0x400;
> >
> > ? ? ? ? ? ? ? ?*curval &= ~mask;
> > ? ? ? ? ? ? ? ?*curval |= set;
> > ? ? ? ? ? ? ? ?__raw_writel(*curval, addr)
> >
> > ? ? ? ? ? ? ? ?/*
> > ? ? ? ? ? ? ? ? * some nice comment about 1us being a good idea
> > ? ? ? ? ? ? ? ? */
> > ? ? ? ? ? ? ? ?udelay(1);
> >
> > ? ? ? ? ? ? ? ?do {
> > ? ? ? ? ? ? ? ? ? ? ? ?*curval = __raw_readl(addr);
> > ? ? ? ? ? ? ? ? ? ? ? ?if ((*curval & pollmask) == pollval)
> > ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?return 0;
> >
> > ? ? ? ? ? ? ? ?} while(--timeout);
> >
> > ? ? ? ? ? ? ? ?return 1;
> > ? ? ? ?}
> >
> > ? ? ? ?int mxs_reset_block(void __iomem *reset_addr)
> > ? ? ? ?{
> > ? ? ? ? ? ? ? ?u32 val = __raw_readl(reset_addr);
> > ? ? ? ? ? ? ? ?int ret;
> >
> > ? ? ? ? ? ? ? ?/* clear SFTRST and poll SFTRST becoming clear */
> > ? ? ? ? ? ? ? ?ret = setmask_poll(reset_addr,
> > ? ? ? ? ? ? ? ? ? ? ? ?0, MXS_MODULE_SFTRST,
> > ? ? ? ? ? ? ? ? ? ? ? ?0, MXS_MODULE_SFTRST, &val);
> > ? ? ? ? ? ? ? ?if (ret)
> > ? ? ? ? ? ? ? ? ? ? ? ?goto error;
> >
> > ? ? ? ? ? ? ? ?/* clear CLKGATE, set SFTRST and poll CLKGATE becoming set */
> > ? ? ? ? ? ? ? ?ret = setmask_poll(reset_addr,
> > ? ? ? ? ? ? ? ? ? ? ? ?MXS_MODULE_SFTRST, MXS_MODULE_SFTRST | MXS_MODULE_CLKGATE,
> > ? ? ? ? ? ? ? ? ? ? ? ?0, MXS_MODULE_CLKGATE, &val);
> > ? ? ? ? ? ? ? ?if (ret)
> > ? ? ? ? ? ? ? ? ? ? ? ?goto error;
> >
> > ? ? ? ? ? ? ? ?...
> > ? ? ? ?}
> >
> > Well, not very nice, but IMHO better that your code. ?Maybe
> > mxs_reset_block fits in a Terminal that way without decreasing the font
> > size :-)
> >
> I checked designer about doing "clear CLKGATE" and "set SFTRST" in a
> single step, and got the following feedback.
>
> "Per HW design, it is not safe to get those two done by write once
> time. By two step write, one instruction period interval can be
> ensured at least for clock enabling before sync. Soft reset. Your
> code is only once time write in fact, so it shall not be equal to two
> write operation."
>
> In this case, how do the following changes look to you?
>
> /*
> * Clear the bit and poll it cleared, the bit has to be
> * SFTRST(bit 31) or CLKGATE (bit 30) of block control register.
for the function it doesn't have to be one of these bits. Maybe:
Clear the bit and poll it cleared. This is usually called with
a reset address and mask being either SFTRST(bit 31) or CLKGATE
(bit 30).
> */
> static int clear_poll_bit(void __iomem *addr, u32 mask)
> {
> int timeout = 0x400;
>
> /* clear the bit */
> __raw_writel(mask, addr + MXS_CLR_ADDR);
ah, so there is a clr register, that's nice.
>
> /*
> * SFTRST needs 3 GPMI clocks to settle, the reference manual
> * recommends to wait 1us.
> */
> udelay(1);
>
> /* poll the bit becoming clear */
> while ((__raw_readl(addr) & mask) && --timeout)
> /* nothing */;
>
> if (unlikely(!timeout))
> return 1;
>
> return 0;
return !timeout; ?
> }
>
> int mxs_reset_block(void __iomem *reset_addr)
> {
> int ret;
> int timeout = 0x400;
>
> /* clear and poll SFTRST */
> ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
> if (ret)
> goto error;
>
> /* clear CLKGATE */
> __raw_writel(MXS_MODULE_CLKGATE, reset_addr + MXS_CLR_ADDR);
> /* set SFTRST to reset the block */
> __raw_writel(MXS_MODULE_SFTRST, reset_addr + MXS_SET_ADDR);
> udelay(1);
> /* poll CLKGATE becoming set */
> while ((!(__raw_readl(reset_addr) & MXS_MODULE_CLKGATE)) && --timeout)
> /* nothing */;
> if (unlikely(!timeout))
> goto error;
>
> /* clear and poll SFTRST */
> ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
> if (ret)
> goto error;
>
> /* clear and poll CLKGATE */
> ret = clear_poll_bit(reset_addr, MXS_MODULE_CLKGATE);
> if (ret)
> goto error;
>
return 0;
> error:
> pr_err("%s(%p): module reset timeout\n", __func__, reset_addr);
> return -ETIMEDOUT;
> }
Other than that it looks much better IMHO.
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 03/15] ARM: mxs: Add reset routines
2010-11-29 11:59 ` [PATCH v2 03/15] ARM: mxs: Add reset routines Shawn Guo
2010-11-30 10:25 ` Uwe Kleine-König
@ 2010-12-02 9:40 ` Uwe Kleine-König
2010-12-02 10:16 ` Shawn Guo
1 sibling, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-02 9:40 UTC (permalink / raw)
To: linux-arm-kernel
Hello Shawn
On Mon, Nov 29, 2010 at 07:59:13PM +0800, Shawn Guo wrote:
> +/*
> + * Reset the system. It is called by machine_restart().
> + */
> +void arch_reset(char mode, const char *cmd)
> +{
> + /* Set wdog count */
> + __raw_writel(1, wdog_base + MXS_RTC_WATCHDOG);
> +
> + /* Assert SRS signal */
> + __raw_writel(MXS_WATCHDOG_EN, wdog_base + MXS_SET_ADDR);
> +
> + /* Wait for reset to assert... */
> + mdelay(500);
> +
> + pr_err("Watchdog reset failed to assert reset\n");
> +
> + /* Delay to allow the serial port to show the message */
> + mdelay(50);
> +
> + /* We'll take a jump through zero as a poor second */
> + cpu_reset(0);
After reading a bit in IMX28RM, I wonder why do you bother with the
watchdog at all? Doesn't
__raw_writel(MXS_CLKCTRL_RESET_CHIP, MXS_CLKCTRL_RESET + MXS_SET_ADDR);
work easier and without the need to worry about timeouts, sleeping while
clk_{get,enable} and races?
(Note I didn't check if i.MX23 has the same register at the same
address.)
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 03/15] ARM: mxs: Add reset routines
2010-12-02 9:40 ` Uwe Kleine-König
@ 2010-12-02 10:16 ` Shawn Guo
0 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-02 10:16 UTC (permalink / raw)
To: linux-arm-kernel
Hi Uwe,
2010/12/2 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Shawn
>
> On Mon, Nov 29, 2010 at 07:59:13PM +0800, Shawn Guo wrote:
>> +/*
>> + * Reset the system. It is called by machine_restart().
>> + */
>> +void arch_reset(char mode, const char *cmd)
>> +{
>> + ? ? /* Set wdog count */
>> + ? ? __raw_writel(1, wdog_base + MXS_RTC_WATCHDOG);
>> +
>> + ? ? /* Assert SRS signal */
>> + ? ? __raw_writel(MXS_WATCHDOG_EN, wdog_base + MXS_SET_ADDR);
>> +
>> + ? ? /* Wait for reset to assert... */
>> + ? ? mdelay(500);
>> +
>> + ? ? pr_err("Watchdog reset failed to assert reset\n");
>> +
>> + ? ? /* Delay to allow the serial port to show the message */
>> + ? ? mdelay(50);
>> +
>> + ? ? /* We'll take a jump through zero as a poor second */
>> + ? ? cpu_reset(0);
> After reading a bit in IMX28RM, I wonder why do you bother with the
> watchdog at all? ?Doesn't
>
> ? ? ? ?__raw_writel(MXS_CLKCTRL_RESET_CHIP, MXS_CLKCTRL_RESET + MXS_SET_ADDR);
>
> work easier and without the need to worry about timeouts, sleeping while
> clk_{get,enable} and races?
> (Note I didn't check if i.MX23 has the same register at the same
> address.)
>
Yes, it's a good way to reset mxs SoC. But the bad thing is the
offset of the register is different between MX23 and MX28. Also there
is no SET_ADDR for this register.
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH 06/15] ARM: mxs: Add timer support
2010-11-30 16:13 ` Uwe Kleine-König
@ 2010-12-02 14:44 ` Shawn Guo
2010-12-02 15:20 ` Thomas Gleixner
2010-12-02 16:48 ` Uwe Kleine-König
0 siblings, 2 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-02 14:44 UTC (permalink / raw)
To: linux-arm-kernel
Hi Uwe,
2010/12/1 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Shawn,
>
[...]
>> +
>> + ? ? /* Disable interrupt in timer module */
>> + ? ? timrot_irq_disable();
>> +
>> + ? ? if (mode != clockevent_mode) {
>> + ? ? ? ? ? ? /* Set event time into far-far future */
>> + ? ? ? ? ? ? __raw_writel(__raw_readl(timer_base +
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? HW_TIMROT_RUNNING_COUNTn(0)) + 3,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? timer_base + HW_TIMROT_MATCH_COUNTn(0));
> I don't know if this is needed, maybe there cannot be a pending event
> when set_mode is called? ?Thomas?
>
Freescale BSP works well without this. It's probably not needed.
>> +
>> +static struct clocksource clocksource_mxs = {
>> + ? ? .name ? ? ? ? ? = "mxs_timer",
>> + ? ? .rating ? ? ? ? = 200,
>> + ? ? .read ? ? ? ? ? = timrot_get_cycles,
>> + ? ? .mask ? ? ? ? ? = CLOCKSOURCE_MASK(32),
>> + ? ? .shift ? ? ? ? ?= 10,
>> + ? ? .flags ? ? ? ? ?= CLOCK_SOURCE_IS_CONTINUOUS,
>> +};
>> +
>> +static int __init mxs_clocksource_init(struct clk *timer_clk)
>> +{
>> + ? ? unsigned int c = clk_get_rate(timer_clk);
>> +
>> + ? ? if (timrot_is_v1())
>> + ? ? ? ? ? ? clocksource_mxs.mask = CLOCKSOURCE_MASK(16);
> I wonder if a shift of 10 is a bit heavy for a 16 bit timer.
>
I do not understand that. The shift is used in clocksource_hz2mult() as below.
static inline u32 clocksource_hz2mult(u32 hz, u32 shift_constant)
{
/* hz = cyc/(Billion ns)
* mult/2^shift = ns/cyc
* mult = ns/cyc * 2^shift
* mult = 1Billion/hz * 2^shift
* mult = 1000000000 * 2^shift / hz
* mult = (1000000000<<shift) / hz
*/
u64 tmp = ((u64)1000000000) << shift_constant;
tmp += hz/2; /* round for do_div */
do_div(tmp, hz);
return (u32)tmp;
}
The shift is working against the timers frequency (hz). Should hz be
the thing concerned here instead of timer bit width? Since both MX23
and MX28 timer are running@32K, so shift value 10 is picked here.
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH 09/15] ARM: mxs: Add clock support
2010-11-26 6:49 ` [PATCH 09/15] ARM: mxs: Add clock support Shawn Guo
2010-11-30 16:39 ` Uwe Kleine-König
@ 2010-12-02 15:07 ` Uwe Kleine-König
2010-12-03 5:07 ` Shawn Guo
1 sibling, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-02 15:07 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Nov 26, 2010 at 02:49:08PM +0800, Shawn Guo wrote:
> Add clock for MXS-based SoCs, MX23 and MX28.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> arch/arm/mach-mxs/clock-mx23.c | 521 ++++++++++++++++++++++
> arch/arm/mach-mxs/clock-mx28.c | 732 +++++++++++++++++++++++++++++++
> arch/arm/mach-mxs/clock.c | 201 +++++++++
> arch/arm/mach-mxs/include/mach/clkdev.h | 7 +
> arch/arm/mach-mxs/include/mach/clock.h | 64 +++
> arch/arm/mach-mxs/regs-clkctrl-mx23.h | 455 +++++++++++++++++++
> arch/arm/mach-mxs/regs-clkctrl-mx28.h | 663 ++++++++++++++++++++++++++++
> 7 files changed, 2643 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-mxs/clock-mx23.c
> create mode 100644 arch/arm/mach-mxs/clock-mx28.c
> create mode 100644 arch/arm/mach-mxs/clock.c
> create mode 100644 arch/arm/mach-mxs/include/mach/clkdev.h
> create mode 100644 arch/arm/mach-mxs/include/mach/clock.h
> create mode 100644 arch/arm/mach-mxs/regs-clkctrl-mx23.h
> create mode 100644 arch/arm/mach-mxs/regs-clkctrl-mx28.h
>
> diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c
> new file mode 100644
> index 0000000..832db0b
> --- /dev/null
> +++ b/arch/arm/mach-mxs/clock-mx23.c
> @@ -0,0 +1,521 @@
> +/*
> + * 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-mx23.h"
> +
> +#define CLKCTRL_BASE_ADDR MX23_IO_ADDRESS(MX23_CLKCTRL_BASE_ADDR)
> +#define DIGCTRL_BASE_ADDR MX23_IO_ADDRESS(MX23_DIGCTL_BASE_ADDR)
> +
> +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 pll_clk_get_rate(struct clk *clk)
> +{
> + return 480000000;
> +}
> +
> +static int pll_clk_enable(struct clk *clk)
> +{
> + __raw_writel(BM_CLKCTRL_PLLCTRL0_POWER |
> + BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS,
> + CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLLCTRL0_SET);
> +
> + /* Only a 10us delay is need. PLLCTRL1 LOCK bitfied is only a timer
> + * and is incorrect (excessive). Per definition of the PLLCTRL0
> + * POWER field, waiting at least 10us.
> + */
> + udelay(10);
> +
> + return 0;
> +}
> +
> +static void pll_clk_disable(struct clk *clk)
> +{
> + __raw_writel(BM_CLKCTRL_PLLCTRL0_POWER |
> + BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS,
> + CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLLCTRL0_CLR);
> +}
> +
> +static struct clk pll_clk = {
> + .get_rate = pll_clk_get_rate,
> + .enable = pll_clk_enable,
> + .disable = pll_clk_disable,
> + .parent = &ref_xtal_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, FRAC, CPU)
> +_CLK_GET_RATE_REF(ref_emi_clk, FRAC, EMI)
> +_CLK_GET_RATE_REF(ref_pix_clk, FRAC, PIX)
> +_CLK_GET_RATE_REF(ref_io_clk, FRAC, IO)
> +
> +#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 = &pll_clk, \
> + }
> +
> +_DEFINE_CLOCK_REF(ref_cpu_clk, FRAC, CPU);
What happens if get_clock_rate(ref_cpu_clk) is called?:
ref_cpu_clk_get_rate
reg = something
div = something else
parent_rate = clk_get_rate(clk->parent)
= pll_clk_get_rate()
= 480000000;
return parent_rate * 18 / div
= (480000000 * 18) / div
= 0x202fbf000 / div
= ...
Note that 0x202fbf000 is too big for an unsigned long so (AFAIK) this is
truncated to 0x02fbf000 / div which is wrong.
The same overflow happens in at least one set_rate function, too.
Either you have to switch to long long or (IMHO preferable) use shifted
values.
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH 06/15] ARM: mxs: Add timer support
2010-12-02 14:44 ` Shawn Guo
@ 2010-12-02 15:20 ` Thomas Gleixner
2010-12-02 16:48 ` Uwe Kleine-König
1 sibling, 0 replies; 146+ messages in thread
From: Thomas Gleixner @ 2010-12-02 15:20 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, 2 Dec 2010, Shawn Guo wrote:
> Hi Uwe,
>
> 2010/12/1 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> > Hello Shawn,
> >
> [...]
> >> +
> >> + ? ? /* Disable interrupt in timer module */
> >> + ? ? timrot_irq_disable();
> >> +
> >> + ? ? if (mode != clockevent_mode) {
> >> + ? ? ? ? ? ? /* Set event time into far-far future */
> >> + ? ? ? ? ? ? __raw_writel(__raw_readl(timer_base +
> >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? HW_TIMROT_RUNNING_COUNTn(0)) + 3,
> >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? timer_base + HW_TIMROT_MATCH_COUNTn(0));
> > I don't know if this is needed, maybe there cannot be a pending event
> > when set_mode is called? ?Thomas?
> >
> Freescale BSP works well without this. It's probably not needed.
There is no guarantee, that there is no event pending. Especially not
when we shutdown the timer. And the observation that the Fleescale
stuff did not explode yet does not prove anything.
> > I wonder if a shift of 10 is a bit heavy for a 16 bit timer.
> >
> I do not understand that. The shift is used in clocksource_hz2mult() as below.
>
> static inline u32 clocksource_hz2mult(u32 hz, u32 shift_constant)
Use clocksource_register_hz() or clocksource_register_khz() and let
the clocksource code decide the shift and mult value.
Thanks,
tglx
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH 06/15] ARM: mxs: Add timer support
2010-12-02 14:44 ` Shawn Guo
2010-12-02 15:20 ` Thomas Gleixner
@ 2010-12-02 16:48 ` Uwe Kleine-König
1 sibling, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-02 16:48 UTC (permalink / raw)
To: linux-arm-kernel
Hello Shawn (and Thomas),
On Thu, Dec 02, 2010 at 10:44:06PM +0800, Shawn Guo wrote:
> >> +
> >> +static struct clocksource clocksource_mxs = {
> >> + ? ? .name ? ? ? ? ? = "mxs_timer",
> >> + ? ? .rating ? ? ? ? = 200,
> >> + ? ? .read ? ? ? ? ? = timrot_get_cycles,
> >> + ? ? .mask ? ? ? ? ? = CLOCKSOURCE_MASK(32),
> >> + ? ? .shift ? ? ? ? ?= 10,
> >> + ? ? .flags ? ? ? ? ?= CLOCK_SOURCE_IS_CONTINUOUS,
> >> +};
> >> +
> >> +static int __init mxs_clocksource_init(struct clk *timer_clk)
> >> +{
> >> + ? ? unsigned int c = clk_get_rate(timer_clk);
> >> +
> >> + ? ? if (timrot_is_v1())
> >> + ? ? ? ? ? ? clocksource_mxs.mask = CLOCKSOURCE_MASK(16);
> > I wonder if a shift of 10 is a bit heavy for a 16 bit timer.
> >
> I do not understand that. The shift is used in clocksource_hz2mult() as below.
>
> static inline u32 clocksource_hz2mult(u32 hz, u32 shift_constant)
> {
> /* hz = cyc/(Billion ns)
> * mult/2^shift = ns/cyc
> * mult = ns/cyc * 2^shift
> * mult = 1Billion/hz * 2^shift
> * mult = 1000000000 * 2^shift / hz
> * mult = (1000000000<<shift) / hz
> */
> u64 tmp = ((u64)1000000000) << shift_constant;
>
> tmp += hz/2; /* round for do_div */
> do_div(tmp, hz);
>
> return (u32)tmp;
> }
>
> The shift is working against the timers frequency (hz). Should hz be
> the thing concerned here instead of timer bit width? Since both MX23
> and MX28 timer are running at 32K, so shift value 10 is picked here.
Might be, it's some time ago that I dealt with the clock code. After
rechecking I think you're right, but now I think 10 is too low :-)
In general a bigger shift increases accuracy at the cost of the range of
values that can be converted (from ticks to ns). As a 16 bit counter
has a very limited range anyhow you can at least use a high accuracy
without loosing anything.
With shift=10 and tickrate=32k you get mult=0x1e84800, so the maximal
value that (theoretically) occurs is 0xffff * 0x1e84800 = 0x1e84617b800
which is far away from using the available 64 bits. So (unless I'm
mistaken) the shift value using most of the 64 would be 33 but that
would overflow mult (which is only 32bit wide). So I'd recommend 17
(resulting in mult=0xf4240000) for both the 16 and the 32 bit case.
Thomas, does this make sense?
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH 09/15] ARM: mxs: Add clock support
2010-12-02 15:07 ` Uwe Kleine-König
@ 2010-12-03 5:07 ` Shawn Guo
0 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-03 5:07 UTC (permalink / raw)
To: linux-arm-kernel
2010/12/2 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> On Fri, Nov 26, 2010 at 02:49:08PM +0800, Shawn Guo wrote:
>> +
>> +/*
>> + * 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, FRAC, CPU)
>> +_CLK_GET_RATE_REF(ref_emi_clk, FRAC, EMI)
>> +_CLK_GET_RATE_REF(ref_pix_clk, FRAC, PIX)
>> +_CLK_GET_RATE_REF(ref_io_clk, FRAC, IO)
>> +
>> +#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 ? ? ? ? = &pll_clk, ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
>> + ? ? }
>> +
>> +_DEFINE_CLOCK_REF(ref_cpu_clk, FRAC, CPU);
> What happens if get_clock_rate(ref_cpu_clk) is called?:
>
> ? ? ? ?ref_cpu_clk_get_rate
> ? ? ? ? ? ? ? ?reg = something
> ? ? ? ? ? ? ? ?div = something else
> ? ? ? ? ? ? ? ?parent_rate = clk_get_rate(clk->parent)
> ? ? ? ? ? ? ? ? ? ? ? ?= pll_clk_get_rate()
> ? ? ? ? ? ? ? ? ? ? ? ?= 480000000;
> ? ? ? ? ? ? ? ?return parent_rate * 18 / div
> ? ? ? ? ? ? ? ? ? ? ? ?= (480000000 * 18) / div
> ? ? ? ? ? ? ? ? ? ? ? ?= 0x202fbf000 / div
> ? ? ? ? ? ? ? ? ? ? ? ?= ...
>
> Note that 0x202fbf000 is too big for an unsigned long so (AFAIK) this is
> truncated to 0x02fbf000 / div which is wrong.
>
> The same overflow happens in at least one set_rate function, too.
>
> Either you have to switch to long long or (IMHO preferable) use shifted
> values.
>
Excellent catch. It solved another issue that I ran into, which
caused by imprecise mdelay.
Thanks a million, Uwe.
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH] prevent 'BUG: sleeping function called from invalid context' in arch_reset()
2010-11-29 9:58 ` Uwe Kleine-König
@ 2010-12-06 16:13 ` Uwe Kleine-König
0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-06 16:13 UTC (permalink / raw)
To: linux-arm-kernel
[extended the audience, some context: arch/arm/plat-mxc currently uses
a clk_enable in arch_reset which might sleep]
On Mon, Nov 29, 2010 at 10:58:33AM +0100, Uwe Kleine-K?nig wrote:
> Hello Lothar,
>
> On Mon, Nov 29, 2010 at 10:25:34AM +0100, Lothar Wa?mann wrote:
> > arch_reset() may be called from interrupt context (e.g. induced by
> > SYSRQ-B), thus clk_get() and clk_enable() must not be called from
> > within arch_reset(). Move these calls to mxc_arch_reset_init().
> I wonder if SYSRQ-B is the only way to trigger that. And if yes if that
> could be "fixed" to allow sleeping?!
Hmmm, the comment for emergency_restart() says:
/**
* emergency_restart - reboot the system
*
* Without shutting down any hardware or taking any locks
* reboot the system. This is called when we know we are in
* trouble so this is our best effort to reboot. This is
* safe to call in interrupt context.
*/
emergency_restart has several callers apart from sysrq (watchdog, ocfs2,
kdb, panic), so I think allowing to sleep isn't that easy.
Moreover the sysrq function is called with the uart port's lock hold,
that would need fixing in the serial driver. I found the same problem
in amba-pl011 (the only driver I checked), so this seems to be a big
task. Sysrq holds a lock, too, while calling the handler.
I still think it's wrong to enable the watchdog clock unconditionally
during boot and wonder if that sleep in atomic can just be ignored?!
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH 09/15] ARM: mxs: Add clock support
2010-11-30 16:39 ` Uwe Kleine-König
@ 2010-12-07 13:09 ` Shawn Guo
2010-12-07 13:33 ` Uwe Kleine-König
0 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-07 13:09 UTC (permalink / raw)
To: linux-arm-kernel
Hi Uwe,
2010/12/1 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Shawn,
>
> On Fri, Nov 26, 2010 at 02:49:08PM +0800, Shawn Guo wrote:
>> Add clock for MXS-based SoCs, MX23 and MX28.
>>
>> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
>> ---
>> ?arch/arm/mach-mxs/clock-mx23.c ? ? ? ? ?| ?521 ++++++++++++++++++++++
>> ?arch/arm/mach-mxs/clock-mx28.c ? ? ? ? ?| ?732 +++++++++++++++++++++++++++++++
>> ?arch/arm/mach-mxs/clock.c ? ? ? ? ? ? ? | ?201 +++++++++
>> ?arch/arm/mach-mxs/include/mach/clkdev.h | ? ?7 +
>> ?arch/arm/mach-mxs/include/mach/clock.h ?| ? 64 +++
>> ?arch/arm/mach-mxs/regs-clkctrl-mx23.h ? | ?455 +++++++++++++++++++
>> ?arch/arm/mach-mxs/regs-clkctrl-mx28.h ? | ?663 ++++++++++++++++++++++++++++
>> ?7 files changed, 2643 insertions(+), 0 deletions(-)
>> ?create mode 100644 arch/arm/mach-mxs/clock-mx23.c
>> ?create mode 100644 arch/arm/mach-mxs/clock-mx28.c
>> ?create mode 100644 arch/arm/mach-mxs/clock.c
>> ?create mode 100644 arch/arm/mach-mxs/include/mach/clkdev.h
>> ?create mode 100644 arch/arm/mach-mxs/include/mach/clock.h
>> ?create mode 100644 arch/arm/mach-mxs/regs-clkctrl-mx23.h
>> ?create mode 100644 arch/arm/mach-mxs/regs-clkctrl-mx28.h
>>
>> diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c
>> new file mode 100644
>> index 0000000..832db0b
>> --- /dev/null
>> +++ b/arch/arm/mach-mxs/clock-mx23.c
>> @@ -0,0 +1,521 @@
>> +/*
>> + * 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-mx23.h"
>> +
>> +#define CLKCTRL_BASE_ADDR ? ?MX23_IO_ADDRESS(MX23_CLKCTRL_BASE_ADDR)
>> +#define DIGCTRL_BASE_ADDR ? ?MX23_IO_ADDRESS(MX23_DIGCTL_BASE_ADDR)
>> +
>> +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;
>> +}
> Hmm, I would have used an approach that is quickly switchable to the
> generic clock stuff posted a few times here. ?But probably already too
> late. ?So it's up to you to decide when to switch (or if at all).
>
I suppose you are talking about the common struct clk patch from
Jeremy Kerr. Since mxs is closely tracking mxc, I would switch mxs
only mxc is switched.
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH 09/15] ARM: mxs: Add clock support
2010-12-07 13:09 ` Shawn Guo
@ 2010-12-07 13:33 ` Uwe Kleine-König
2010-12-07 13:53 ` Shawn Guo
0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-07 13:33 UTC (permalink / raw)
To: linux-arm-kernel
Hello Shawn,
> > Hmm, I would have used an approach that is quickly switchable to the
> > generic clock stuff posted a few times here. ?But probably already too
> > late. ?So it's up to you to decide when to switch (or if at all).
> >
> I suppose you are talking about the common struct clk patch from
> Jeremy Kerr. Since mxs is closely tracking mxc, I would switch mxs
> only mxc is switched.
I want mxc switched sooner rather than later.
If you ask me, don't stop to be inovative because of tracking mxc which
supports many machines and so isn't that flexible as a new machine
support.
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH 09/15] ARM: mxs: Add clock support
2010-12-07 13:33 ` Uwe Kleine-König
@ 2010-12-07 13:53 ` Shawn Guo
0 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-07 13:53 UTC (permalink / raw)
To: linux-arm-kernel
Hi Uwe,
2010/12/7 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Shawn,
>
>> > Hmm, I would have used an approach that is quickly switchable to the
>> > generic clock stuff posted a few times here. ?But probably already too
>> > late. ?So it's up to you to decide when to switch (or if at all).
>> >
>> I suppose you are talking about the common struct clk patch from
>> Jeremy Kerr. ?Since mxs is closely tracking mxc, I would switch mxs
>> only mxc is switched.
> I want mxc switched sooner rather than later.
>
> If you ask me, don't stop to be inovative because of tracking mxc which
> supports many machines and so isn't that flexible as a new machine
> support.
>
OK. I will try to switch once Jeremy's bits get merged. But can we
pick the current implementation on imx tree for now, and then switch
based off imx tree later?
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v3 01/15] ARM: mxs: Add core definitions
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (20 preceding siblings ...)
2010-11-29 11:59 ` [PATCH v2 15/15] ARM: mxs: Add build configuration for mxs Shawn Guo
@ 2010-12-07 16:31 ` Shawn Guo
2010-12-07 20:18 ` Uwe Kleine-König
2010-12-07 16:31 ` [PATCH v3 03/15] ARM: mxs: Add reset routines Shawn Guo
` (24 subsequent siblings)
46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-07 16:31 UTC (permalink / raw)
To: linux-arm-kernel
Add core definitions for MXS-based SoC MX23 and MX28.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
- Update MXS_IO_P2V definition and comment to get them matched
- Sort mx23 base address definitions by offset
- Remove mx28 reserved IRQ definitions
- Remove unnecessary dummy definitions for cpu_is_mx23() and cpu_is_mx28()
Changes for v2:
- Remove MXS_IO_P2V_MODULE from hardware.h which is not needed
- Simplify MXS_IO_P2V_MODULE definition in hardware.h
- Remove unnecessary inclusion protection from hardware.h
- Change cpu_is_mx23/mx28() implementation in mxs.h to use machine_is_xxx
arch/arm/mach-mxs/include/mach/hardware.h | 55 +++++++++
arch/arm/mach-mxs/include/mach/irqs.h | 32 +++++
arch/arm/mach-mxs/include/mach/memory.h | 24 ++++
arch/arm/mach-mxs/include/mach/mx23.h | 147 ++++++++++++++++++++++
arch/arm/mach-mxs/include/mach/mx28.h | 190 +++++++++++++++++++++++++++++
arch/arm/mach-mxs/include/mach/mxs.h | 34 +++++
6 files changed, 482 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/include/mach/hardware.h
create mode 100644 arch/arm/mach-mxs/include/mach/irqs.h
create mode 100644 arch/arm/mach-mxs/include/mach/memory.h
create mode 100644 arch/arm/mach-mxs/include/mach/mx23.h
create mode 100644 arch/arm/mach-mxs/include/mach/mx28.h
create mode 100644 arch/arm/mach-mxs/include/mach/mxs.h
diff --git a/arch/arm/mach-mxs/include/mach/hardware.h b/arch/arm/mach-mxs/include/mach/hardware.h
new file mode 100644
index 0000000..d73f149
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/hardware.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2004-2007 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
+ * 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_MXS_HARDWARE_H__
+#define __MACH_MXS_HARDWARE_H__
+
+#include <asm/sizes.h>
+
+#ifdef __ASSEMBLER__
+#define IOMEM(addr) (addr)
+#else
+#define IOMEM(addr) ((void __force __iomem *)(addr))
+#endif
+
+/*
+ * It maps the whole address space to [0xf4000000, 0xf5ffffff].
+ *
+ * OCRAM 0x00000000+0x020000 -> 0xf4000000+0x020000
+ * IO 0x80000000+0x100000 -> 0xf5000000+0x100000
+ */
+#define MXS_IO_P2V(x) (0xf4000000 + \
+ (((x) & 0x80000000) >> 7) + \
+ (((x) & 0x000fffff)))
+
+
+#define MXS_IO_ADDRESS(x) IOMEM(MXS_IO_P2V(x))
+
+#include <mach/mx23.h>
+#include <mach/mx28.h>
+#include <mach/mxs.h>
+
+#define mxs_map_entry(soc, name, _type) { \
+ .virtual = soc ## _IO_P2V(soc ## _ ## name ## _BASE_ADDR), \
+ .pfn = __phys_to_pfn(soc ## _ ## name ## _BASE_ADDR), \
+ .length = soc ## _ ## name ## _SIZE, \
+ .type = _type, \
+}
+
+#endif /* __MACH_MXS_HARDWARE_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/irqs.h b/arch/arm/mach-mxs/include/mach/irqs.h
new file mode 100644
index 0000000..f771039
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/irqs.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2004-2007 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.
+ */
+
+#ifndef __MACH_MXS_IRQS_H__
+#define __MACH_MXS_IRQS_H__
+
+#define MXS_INTERNAL_IRQS 128
+
+#define MXS_GPIO_IRQ_START MXS_INTERNAL_IRQS
+
+/* the maximum for MXS-based */
+#define MXS_GPIO_IRQS (32 * 5)
+
+/*
+ * The next 16 interrupts are for board specific purposes. Since
+ * the kernel can only run on one machine at a time, we can re-use
+ * these. If you need more, increase MXS_BOARD_IRQS, but keep it
+ * within sensible limits.
+ */
+#define MXS_BOARD_IRQ_START (MXS_GPIO_IRQ_START + MXS_GPIO_IRQS)
+#define MXS_BOARD_IRQS 16
+
+#define NR_IRQS (MXS_BOARD_IRQ_START + MXS_BOARD_IRQS)
+
+#endif /* __MACH_MXS_IRQS_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/memory.h b/arch/arm/mach-mxs/include/mach/memory.h
new file mode 100644
index 0000000..b5420a5
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/memory.h
@@ -0,0 +1,24 @@
+/*
+ * 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_MXS_MEMORY_H__
+#define __MACH_MXS_MEMORY_H__
+
+#define PHYS_OFFSET UL(0x40000000)
+
+#endif /* __MACH_MXS_MEMORY_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mx23.h b/arch/arm/mach-mxs/include/mach/mx23.h
new file mode 100644
index 0000000..2033ed4
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mx23.h
@@ -0,0 +1,147 @@
+/*
+ * 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_MX23_H__
+#define __MACH_MX23_H__
+
+#ifndef __ASSEMBLER__
+#include <linux/io.h>
+#endif
+
+/*
+ * OCRAM
+ */
+#define MX23_OCRAM_BASE_ADDR 0x00000000
+#define MX23_OCRAM_SIZE SZ_32K
+
+/*
+ * IO
+ */
+#define MX23_IO_BASE_ADDR 0x80000000
+#define MX23_IO_SIZE SZ_1M
+
+#define MX23_ICOLL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x000000)
+#define MX23_APBH_DMA_BASE_ADDR (MX23_IO_BASE_ADDR + 0x004000)
+#define MX23_BCH_BASE_ADDR (MX23_IO_BASE_ADDR + 0x00a000)
+#define MX23_GPMI_BASE_ADDR (MX23_IO_BASE_ADDR + 0x00c000)
+#define MX23_SSP1_BASE_ADDR (MX23_IO_BASE_ADDR + 0x010000)
+#define MX23_PINCTRL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x018000)
+#define MX23_DIGCTL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x01c000)
+#define MX23_ETM_BASE_ADDR (MX23_IO_BASE_ADDR + 0x020000)
+#define MX23_APBX_DMA_BASE_ADDR (MX23_IO_BASE_ADDR + 0x024000)
+#define MX23_DCP_BASE_ADDR (MX23_IO_BASE_ADDR + 0x028000)
+#define MX23_PXP_BASE_ADDR (MX23_IO_BASE_ADDR + 0x02a000)
+#define MX23_OCOTP_BASE_ADDR (MX23_IO_BASE_ADDR + 0x02c000)
+#define MX23_AXI_AHB0_BASE_ADDR (MX23_IO_BASE_ADDR + 0x02e000)
+#define MX23_LCDIF_BASE_ADDR (MX23_IO_BASE_ADDR + 0x030000)
+#define MX23_SSP2_BASE_ADDR (MX23_IO_BASE_ADDR + 0x034000)
+#define MX23_TVENC_BASE_ADDR (MX23_IO_BASE_ADDR + 0x038000)
+#define MX23_CLKCTRL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x040000)
+#define MX23_SAIF0_BASE_ADDR (MX23_IO_BASE_ADDR + 0x042000)
+#define MX23_POWER_BASE_ADDR (MX23_IO_BASE_ADDR + 0x044000)
+#define MX23_SAIF1_BASE_ADDR (MX23_IO_BASE_ADDR + 0x046000)
+#define MX23_AUDIOOUT_BASE_ADDR (MX23_IO_BASE_ADDR + 0x048000)
+#define MX23_AUDIOIN_BASE_ADDR (MX23_IO_BASE_ADDR + 0x04c000)
+#define MX23_LRADC_BASE_ADDR (MX23_IO_BASE_ADDR + 0x050000)
+#define MX23_SPDIF_BASE_ADDR (MX23_IO_BASE_ADDR + 0x054000)
+#define MX23_I2C0_BASE_ADDR (MX23_IO_BASE_ADDR + 0x058000)
+#define MX23_RTC_BASE_ADDR (MX23_IO_BASE_ADDR + 0x05c000)
+#define MX23_PWM_BASE_ADDR (MX23_IO_BASE_ADDR + 0x064000)
+#define MX23_TIMROT_BASE_ADDR (MX23_IO_BASE_ADDR + 0x068000)
+#define MX23_AUART1_BASE_ADDR (MX23_IO_BASE_ADDR + 0x06c000)
+#define MX23_AUART2_BASE_ADDR (MX23_IO_BASE_ADDR + 0x06e000)
+#define MX23_DUART_BASE_ADDR (MX23_IO_BASE_ADDR + 0x070000)
+#define MX23_USBPHY_BASE_ADDR (MX23_IO_BASE_ADDR + 0x07c000)
+#define MX23_USBCTRL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x080000)
+#define MX23_DRAM_BASE_ADDR (MX23_IO_BASE_ADDR + 0x0e0000)
+
+#define MX23_IO_P2V(x) MXS_IO_P2V(x)
+#define MX23_IO_ADDRESS(x) IOMEM(MX23_IO_P2V(x))
+
+/*
+ * IRQ
+ */
+#define MX23_INT_DUART 0
+#define MX23_INT_COMMS_RX 1
+#define MX23_INT_COMMS_TX 1
+#define MX23_INT_SSP2_ERROR 2
+#define MX23_INT_VDD5V 3
+#define MX23_INT_HEADPHONE_SHORT 4
+#define MX23_INT_DAC_DMA 5
+#define MX23_INT_DAC_ERROR 6
+#define MX23_INT_ADC_DMA 7
+#define MX23_INT_ADC_ERROR 8
+#define MX23_INT_SPDIF_DMA 9
+#define MX23_INT_SAIF2_DMA 9
+#define MX23_INT_SPDIF_ERROR 10
+#define MX23_INT_SAIF1_IRQ 10
+#define MX23_INT_SAIF2_IRQ 10
+#define MX23_INT_USB_CTRL 11
+#define MX23_INT_USB_WAKEUP 12
+#define MX23_INT_GPMI_DMA 13
+#define MX23_INT_SSP1_DMA 14
+#define MX23_INT_SSP_ERROR 15
+#define MX23_INT_GPIO0 16
+#define MX23_INT_GPIO1 17
+#define MX23_INT_GPIO2 18
+#define MX23_INT_SAIF1_DMA 19
+#define MX23_INT_SSP2_DMA 20
+#define MX23_INT_ECC8_IRQ 21
+#define MX23_INT_RTC_ALARM 22
+#define MX23_INT_UARTAPP_TX_DMA 23
+#define MX23_INT_UARTAPP_INTERNAL 24
+#define MX23_INT_UARTAPP_RX_DMA 25
+#define MX23_INT_I2C_DMA 26
+#define MX23_INT_I2C_ERROR 27
+#define MX23_INT_TIMER0 28
+#define MX23_INT_TIMER1 29
+#define MX23_INT_TIMER2 30
+#define MX23_INT_TIMER3 31
+#define MX23_INT_BATT_BRNOUT 32
+#define MX23_INT_VDDD_BRNOUT 33
+#define MX23_INT_VDDIO_BRNOUT 34
+#define MX23_INT_VDD18_BRNOUT 35
+#define MX23_INT_TOUCH_DETECT 36
+#define MX23_INT_LRADC_CH0 37
+#define MX23_INT_LRADC_CH1 38
+#define MX23_INT_LRADC_CH2 39
+#define MX23_INT_LRADC_CH3 40
+#define MX23_INT_LRADC_CH4 41
+#define MX23_INT_LRADC_CH5 42
+#define MX23_INT_LRADC_CH6 43
+#define MX23_INT_LRADC_CH7 44
+#define MX23_INT_LCDIF_DMA 45
+#define MX23_INT_LCDIF_ERROR 46
+#define MX23_INT_DIGCTL_DEBUG_TRAP 47
+#define MX23_INT_RTC_1MSEC 48
+#define MX23_INT_DRI_DMA 49
+#define MX23_INT_DRI_ATTENTION 50
+#define MX23_INT_GPMI_ATTENTION 51
+#define MX23_INT_IR 52
+#define MX23_INT_DCP_VMI 53
+#define MX23_INT_DCP 54
+#define MX23_INT_BCH 56
+#define MX23_INT_PXP 57
+#define MX23_INT_UARTAPP2_TX_DMA 58
+#define MX23_INT_UARTAPP2_INTERNAL 59
+#define MX23_INT_UARTAPP2_RX_DMA 60
+#define MX23_INT_VDAC_DETECT 61
+#define MX23_INT_VDD5V_DROOP 64
+#define MX23_INT_DCDC4P2_BO 65
+
+#endif /* __MACH_MX23_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mx28.h b/arch/arm/mach-mxs/include/mach/mx28.h
new file mode 100644
index 0000000..be1c2a4
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mx28.h
@@ -0,0 +1,190 @@
+/*
+ * 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
+
+/*
+ * 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_MAC0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0f0000)
+#define MX28_ENET_MAC1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0f4000)
+
+#define MX28_IO_P2V(x) MXS_IO_P2V(x)
+#define MX28_IO_ADDRESS(x) IOMEM(MX28_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_CAN0 8
+#define MX28_INT_CAN1 9
+#define MX28_INT_LRADC_TOUCH 10
+#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_PERFMON 27
+#define MX28_INT_RTC_1MSEC 28
+#define MX28_INT_RTC_ALARM 29
+#define MX28_INT_COMMS 31
+#define MX28_INT_EMI_ERR 32
+#define MX28_INT_LCDIF 38
+#define MX28_INT_PXP 39
+#define MX28_INT_BCH 41
+#define MX28_INT_GPMI 42
+#define MX28_INT_SPDIF_ERROR 45
+#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_SAIF1 58
+#define MX28_INT_SAIF0 59
+#define MX28_INT_SPDIF_DMA 66
+#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_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_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_GPIO4 123
+#define MX28_INT_GPIO3 124
+#define MX28_INT_GPIO2 125
+#define MX28_INT_GPIO1 126
+#define MX28_INT_GPIO0 127
+
+#endif /* __MACH_MX28_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mxs.h b/arch/arm/mach-mxs/include/mach/mxs.h
new file mode 100644
index 0000000..13e06ae
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mxs.h
@@ -0,0 +1,34 @@
+/*
+ * 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_MXS_H__
+#define __MACH_MXS_H__
+
+#include <asm/mach-types.h>
+
+#define MXS_SET_ADDR 0x4
+#define MXS_CLR_ADDR 0x8
+#define MXS_TOG_ADDR 0xc
+
+/*
+ * MXS CPU types
+ */
+# define cpu_is_mx23() (machine_is_mx23evk())
+# define cpu_is_mx28() (machine_is_mx28evk())
+
+#endif /* __MACH_MXS_H__ */
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH v3 03/15] ARM: mxs: Add reset routines
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (21 preceding siblings ...)
2010-12-07 16:31 ` [PATCH v3 01/15] ARM: mxs: Add core definitions Shawn Guo
@ 2010-12-07 16:31 ` Shawn Guo
2010-12-07 20:27 ` Uwe Kleine-König
2010-12-08 7:33 ` Lothar Waßmann
2010-12-07 16:31 ` [PATCH v2 04/15] ARM: mxs: Add interrupt support Shawn Guo
` (23 subsequent siblings)
46 siblings, 2 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-07 16:31 UTC (permalink / raw)
To: linux-arm-kernel
- The mxs wdog is implemented in RTC block.
- There is a generic software reset routine for most modules on mxs.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
- Change wdog timeout to 10ms for safety
- Simplify function mxs_reset_block() to get it look better
Changes for v2:
- Move rtc clock enabling from arch_reset() into mxs_arch_reset_init()
arch/arm/mach-mxs/include/mach/system.h | 27 ++++++
arch/arm/mach-mxs/system.c | 134 +++++++++++++++++++++++++++++++
2 files changed, 161 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/include/mach/system.h
create mode 100644 arch/arm/mach-mxs/system.c
diff --git a/arch/arm/mach-mxs/include/mach/system.h b/arch/arm/mach-mxs/include/mach/system.h
new file mode 100644
index 0000000..0e42823
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/system.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright 2004-2008 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.
+ */
+
+#ifndef __MACH_MXS_SYSTEM_H__
+#define __MACH_MXS_SYSTEM_H__
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+void arch_reset(char mode, const char *cmd);
+
+#endif /* __MACH_MXS_SYSTEM_H__ */
diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c
new file mode 100644
index 0000000..58cb044
--- /dev/null
+++ b/arch/arm/mach-mxs/system.c
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright 2006-2007,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
+ *
+ * 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/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+
+#include <asm/proc-fns.h>
+#include <asm/system.h>
+
+#include <mach/hardware.h>
+#include <mach/common.h>
+
+#define MXS_RTC_WATCHDOG 0x50
+#define MXS_WATCHDOG_EN (1 << 4)
+
+#define MXS_MODULE_CLKGATE (1 << 30)
+#define MXS_MODULE_SFTRST (1 << 31)
+
+static void __iomem *wdog_base;
+
+/*
+ * Reset the system. It is called by machine_restart().
+ */
+void arch_reset(char mode, const char *cmd)
+{
+ /* Set wdog timer 10 ms */
+ __raw_writel(10, wdog_base + MXS_RTC_WATCHDOG);
+
+ /* Enable wdog reset */
+ __raw_writel(MXS_WATCHDOG_EN, wdog_base + MXS_SET_ADDR);
+
+ /* Wait for reset to assert... */
+ mdelay(10);
+
+ pr_err("Watchdog reset failed to assert reset\n");
+
+ /* Delay to allow the serial port to show the message */
+ mdelay(50);
+
+ /* We'll take a jump through zero as a poor second */
+ cpu_reset(0);
+}
+
+void mxs_arch_reset_init(void __iomem *base)
+{
+ struct clk *clk;
+
+ wdog_base = base;
+
+ clk = clk_get_sys("rtc", NULL);
+ if (!IS_ERR(clk))
+ clk_enable(clk);
+}
+
+/*
+ * Clear the bit and poll it cleared. This is usually called with
+ * a reset address and mask being either SFTRST(bit 31) or CLKGATE
+ * (bit 30).
+ */
+static int clear_poll_bit(void __iomem *addr, u32 mask)
+{
+ int timeout = 0x400;
+
+ /* clear the bit */
+ __raw_writel(mask, addr + MXS_CLR_ADDR);
+
+ /*
+ * SFTRST needs 3 GPMI clocks to settle, the reference manual
+ * recommends to wait 1us.
+ */
+ udelay(1);
+
+ /* poll the bit becoming clear */
+ while ((__raw_readl(addr) & mask) && --timeout)
+ /* nothing */;
+
+ return !timeout;
+}
+
+int mxs_reset_block(void __iomem *reset_addr)
+{
+ int ret;
+ int timeout = 0x400;
+
+ /* clear and poll SFTRST */
+ ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
+ if (ret)
+ goto error;
+
+ /* clear CLKGATE */
+ __raw_writel(MXS_MODULE_CLKGATE, reset_addr + MXS_CLR_ADDR);
+ /* set SFTRST to reset the block */
+ __raw_writel(MXS_MODULE_SFTRST, reset_addr + MXS_SET_ADDR);
+ udelay(1);
+ /* poll CLKGATE becoming set */
+ while ((!(__raw_readl(reset_addr) & MXS_MODULE_CLKGATE)) && --timeout)
+ /* nothing */;
+ if (unlikely(!timeout))
+ goto error;
+
+ /* clear and poll SFTRST */
+ ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
+ if (ret)
+ goto error;
+
+ /* clear and poll CLKGATE */
+ ret = clear_poll_bit(reset_addr, MXS_MODULE_CLKGATE);
+ if (ret)
+ goto error;
+
+ return 0;
+
+error:
+ pr_err("%s(%p): module reset timeout\n", __func__, reset_addr);
+ return -ETIMEDOUT;
+}
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH v2 04/15] ARM: mxs: Add interrupt support
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (22 preceding siblings ...)
2010-12-07 16:31 ` [PATCH v3 03/15] ARM: mxs: Add reset routines Shawn Guo
@ 2010-12-07 16:31 ` Shawn Guo
2010-12-07 21:03 ` Uwe Kleine-König
2010-12-08 8:24 ` Lothar Waßmann
2010-12-07 16:31 ` [PATCH v2 05/15] ARM: mxs: Add low-level debug UART support Shawn Guo
` (22 subsequent siblings)
46 siblings, 2 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-07 16:31 UTC (permalink / raw)
To: linux-arm-kernel
Add Interrupt Collector (ICOLL) support for MXS-based.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
- Get icoll base in get_irqnr_preamble
- Check the case of single SoC build and use hard-coding address if possible
arch/arm/mach-mxs/icoll.c | 77 ++++++++++++++++++++++++++
arch/arm/mach-mxs/include/mach/entry-macro.S | 44 +++++++++++++++
2 files changed, 121 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/icoll.c
create mode 100644 arch/arm/mach-mxs/include/mach/entry-macro.S
diff --git a/arch/arm/mach-mxs/icoll.c b/arch/arm/mach-mxs/icoll.c
new file mode 100644
index 0000000..a7a7d4f
--- /dev/null
+++ b/arch/arm/mach-mxs/icoll.c
@@ -0,0 +1,77 @@
+/*
+ * 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 mxs_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;
+
+ /* Reset icoll */
+ mxs_reset_block(irqbase + HW_ICOLL_CTRL);
+
+ for (i = 0; i < MXS_INTERNAL_IRQS; i++) {
+ set_irq_chip(i, &mxs_icoll_chip);
+ set_irq_handler(i, handle_level_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+}
diff --git a/arch/arm/mach-mxs/include/mach/entry-macro.S b/arch/arm/mach-mxs/include/mach/entry-macro.S
new file mode 100644
index 0000000..2c7755b
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/entry-macro.S
@@ -0,0 +1,44 @@
+/*
+ * Low-level IRQ helper macros for Freescale MXS-based
+ *
+ * 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 <mach/hardware.h>
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \irqnr, [\base, #0x70]
+ cmp \irqnr, #0x7F
+ moveqs \irqnr, #0
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+#if defined (CONFIG_SOC_IMX23) && defined (CONFIG_SOC_IMX28)
+ ldr \base, =icoll_base
+ ldr \base, [\base]
+#elif defined (CONFIG_SOC_IMX23)
+ ldr \base, =MX23_ICOLL_BASE_ADDR
+#else
+ ldr \base, =MX28_ICOLL_BASE_ADDR
+#endif
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH v2 05/15] ARM: mxs: Add low-level debug UART support
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (23 preceding siblings ...)
2010-12-07 16:31 ` [PATCH v2 04/15] ARM: mxs: Add interrupt support Shawn Guo
@ 2010-12-07 16:31 ` Shawn Guo
2010-12-08 20:27 ` Uwe Kleine-König
2010-12-07 16:31 ` [PATCH v3 06/15] ARM: mxs: Add timer support Shawn Guo
` (21 subsequent siblings)
46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-07 16:31 UTC (permalink / raw)
To: linux-arm-kernel
- DEBUG_LL support, which is incompatible with single MXS image
because of different DUART base address on MX23 and MX28
- uncompress message support
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
- Remove incorrect comments
arch/arm/mach-mxs/include/mach/debug-macro.S | 51 +++++++++++++++++
arch/arm/mach-mxs/include/mach/uncompress.h | 78 ++++++++++++++++++++++++++
2 files changed, 129 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/include/mach/debug-macro.S
create mode 100644 arch/arm/mach-mxs/include/mach/uncompress.h
diff --git a/arch/arm/mach-mxs/include/mach/debug-macro.S b/arch/arm/mach-mxs/include/mach/debug-macro.S
new file mode 100644
index 0000000..efb3173
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/debug-macro.S
@@ -0,0 +1,51 @@
+/* arch/arm/mach-mxs/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * 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>
+
+#ifdef CONFIG_SOC_IMX23
+#ifdef UART_PADDR
+#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
+#endif
+#define UART_PADDR MX23_DUART_BASE_ADDR
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+#ifdef UART_PADDR
+#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
+#endif
+#define UART_PADDR MX28_DUART_BASE_ADDR
+#endif
+
+#define UART_VADDR MXS_IO_ADDRESS(UART_PADDR)
+
+ .macro addruart, rp, rv
+ ldr \rp, =UART_PADDR @ physical
+ ldr \rv, =UART_VADDR @ virtual
+ .endm
+
+ .macro senduart, rd, rx
+ str \rd, [\rx, #0x0] @ DR
+ .endm
+
+ .macro waituart, rd, rx
+1001: ldr \rd, [\rx, #0x18] @ FR
+ tst \rd, #1 << 5 @ FR_TXFF
+ bne 1001b
+ .endm
+
+ .macro busyuart, rd, rx
+1002: ldr \rd, [\rx, #0x18] @ FR
+ tst \rd, #1 << 3 @ FR_BUSY
+ beq 1002b
+ .endm
diff --git a/arch/arm/mach-mxs/include/mach/uncompress.h b/arch/arm/mach-mxs/include/mach/uncompress.h
new file mode 100644
index 0000000..efdacc7
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/uncompress.h
@@ -0,0 +1,78 @@
+/*
+ * arch/arm/mach-mxs/include/mach/uncompress.h
+ *
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) Shane Nay (shane@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
+ * 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.
+ */
+#ifndef __MACH_MXS_UNCOMPRESS_H__
+#define __MACH_MXS_UNCOMPRESS_H__
+
+#define __MXS_BOOT_UNCOMPRESS
+
+#include <asm/mach-types.h>
+
+static unsigned long uart_base;
+
+#define UART(x) (*(volatile unsigned long *)(uart_base + (x)))
+
+#define DR 0x00
+#define FR 0x18
+#define FR_BUSY (1 << 3)
+#define FR_TXFE (1 << 7)
+#define CR 0x30
+#define CR_UARTEN 1
+
+/*
+ * The following code assumes the serial port has already been
+ * initialized by the bootloader.
+ */
+
+static void putc(int ch)
+{
+ if (!uart_base)
+ return;
+ if (!(UART(CR) & CR_UARTEN))
+ return;
+
+ while (!(UART(FR) & FR_TXFE))
+ barrier();
+
+ UART(DR) = ch;
+}
+
+static inline void flush(void)
+{
+}
+
+#define MX23_DUART_BASE_ADDR 0x80070000
+#define MX28_DUART_BASE_ADDR 0x80074000
+
+static __inline__ void __arch_decomp_setup(unsigned long arch_id)
+{
+ switch (arch_id) {
+ case MACH_TYPE_MX23EVK:
+ uart_base = MX23_DUART_BASE_ADDR;
+ break;
+ case MACH_TYPE_MX28EVK:
+ uart_base = MX28_DUART_BASE_ADDR;
+ break;
+ default:
+ break;
+ }
+}
+
+#define arch_decomp_setup() __arch_decomp_setup(arch_id)
+#define arch_decomp_wdog()
+
+#endif /* __MACH_MXS_UNCOMPRESS_H__ */
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH v3 06/15] ARM: mxs: Add timer support
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (24 preceding siblings ...)
2010-12-07 16:31 ` [PATCH v2 05/15] ARM: mxs: Add low-level debug UART support Shawn Guo
@ 2010-12-07 16:31 ` Shawn Guo
2010-12-07 21:18 ` Uwe Kleine-König
2010-12-08 8:30 ` Lothar Waßmann
2010-12-07 16:31 ` [PATCH v2 07/15] ARM: mxs: Add gpio support Shawn Guo
` (20 subsequent siblings)
46 siblings, 2 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-07 16:31 UTC (permalink / raw)
To: linux-arm-kernel
Freescale MXS-based SoCs implement timer support in block TIMROT.
There are two versions of TIMROT. The v1 on MX23 only gets 16 bits
counter and has no match function. The v2 on MX28 extends the
counter to 32 bits and add the match function.
As the result, we need two instances of timers with v1 for better
implementation, one for clock_event and another for clocksource.
Otherwise, get_cycles may get imprecise result after long time
cumulating. With v2, one instance can serve two purposes well.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
- Use term clock_event over next_event and clocksource over get_cycles
- Split BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL into two definitions for v1 and v2 respectively
- Turn timrot_get_cycles() into timrotv1_get_cycles() and timrotv2_get_cycles()
- Turn timrot_set_next_event() into timrotv1_set_next_event() and timrotv2_set_next_event()
- Skip flag IRQF_DISABLED
- Remove unncessary IRQ disabling in mxs_set_mode()
- Change shift of clocksource_mxs to 17
Changes for v2:
- Fix a bug in timrot_set_next_event(). It should read
HW_TIMROT_RUNNING_COUNTn to get the current counts.
arch/arm/mach-mxs/timer.c | 276 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 276 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/timer.c
diff --git a/arch/arm/mach-mxs/timer.c b/arch/arm/mach-mxs/timer.c
new file mode 100644
index 0000000..b0e7ffe
--- /dev/null
+++ b/arch/arm/mach-mxs/timer.c
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2000-2001 Deep Blue Solutions
+ * 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
+ * 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/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clockchips.h>
+#include <linux/clk.h>
+
+#include <mach/hardware.h>
+#include <asm/mach/time.h>
+#include <mach/common.h>
+
+/*
+ * There are 2 versions of the timrot on Freescale MXS-based SoCs.
+ * The v1 on MX23 only gets 16 bits counter and has no match function.
+ * The v2 on MX28 extends the counter to 32 bits and add the match function.
+ *
+ * As the result, we need two instances of timers with v1 for better
+ * implementation, one for clock_event and another for clocksource. Otherwise,
+ * get_cycles may get imprecise result after long time cumulating.
+ * With v2, one instance can serve two purposes well.
+ */
+#define timrot_is_v1() (cpu_is_mx23())
+
+#define HW_TIMROT_ROTCTRL 0x00
+#define HW_TIMROT_TIMCTRLn(n) (0x20 + (n) * 0x40)
+#define HW_TIMROT_RUNNING_COUNTn(n) (0x30 + (n) * 0x40)
+#define HW_TIMROT_MATCH_COUNTn(n) (0x50 + (n) * 0x40)
+#define BM_TIMROT_TIMCTRLn_RELOAD (1 << 6)
+#define BM_TIMROT_TIMCTRLn_UPDATE (1 << 7)
+#define BM_TIMROT_TIMCTRLn_MATCH_MODE (1 << 11)
+#define BM_TIMROT_TIMCTRLn_IRQ_EN (1 << 14)
+#define BM_TIMROT_TIMCTRLn_IRQ (1 << 15)
+#define BP_TIMROT_TIMCTRLn_SELECT 0
+#define BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL 0x8
+#define BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL 0xb
+
+static struct clock_event_device clockevent_mxs;
+static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
+
+static void __iomem *timer_base;
+
+static inline void timrot_irq_disable(void)
+{
+ __raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN,
+ timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_CLR_ADDR);
+}
+
+static inline void timrot_irq_enable(void)
+{
+ __raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN,
+ timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_SET_ADDR);
+}
+
+static void timrot_irq_acknowledge(void)
+{
+ __raw_writel(BM_TIMROT_TIMCTRLn_IRQ,
+ timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_CLR_ADDR);
+}
+
+static cycle_t timrotv1_get_cycles(struct clocksource *cs)
+{
+ return ~((__raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(1))
+ & 0xffff0000) >> 16);
+}
+
+static cycle_t timrotv2_get_cycles(struct clocksource *cs)
+{
+ return ~__raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(0));
+}
+
+static int timrotv1_set_next_event(unsigned long evt,
+ struct clock_event_device *dev)
+{
+ /* timrot decrements the count */
+ __raw_writel(evt, timer_base + HW_TIMROT_RUNNING_COUNTn(0));
+
+ return 0;
+}
+
+static int timrotv2_set_next_event(unsigned long evt,
+ struct clock_event_device *dev)
+{
+ unsigned long match;
+
+ /* timrot decrements the count */
+ match = __raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(0))
+ - evt;
+ __raw_writel(match, timer_base + HW_TIMROT_MATCH_COUNTn(0));
+
+ return (int)(match - __raw_readl(timer_base +
+ HW_TIMROT_RUNNING_COUNTn(0))) > 0 ? -ETIME : 0;
+}
+
+static irqreturn_t mxs_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = &clockevent_mxs;
+
+ timrot_irq_acknowledge();
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction mxs_timer_irq = {
+ .name = "MXS Timer Tick",
+ .flags = IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = mxs_timer_interrupt,
+};
+
+#ifdef DEBUG
+static const char *clock_event_mode_label[] = {
+ [CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
+ [CLOCK_EVT_MODE_ONESHOT] = "CLOCK_EVT_MODE_ONESHOT",
+ [CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN",
+ [CLOCK_EVT_MODE_UNUSED] = "CLOCK_EVT_MODE_UNUSED"
+};
+#endif /* DEBUG */
+
+static void mxs_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ /* Disable interrupt in timer module */
+ timrot_irq_disable();
+
+ if (mode != clockevent_mode) {
+ /* Set event time into far-far future */
+ __raw_writel(__raw_readl(timer_base +
+ HW_TIMROT_RUNNING_COUNTn(0)) + 3,
+ timer_base + HW_TIMROT_MATCH_COUNTn(0));
+
+ /* Clear pending interrupt */
+ timrot_irq_acknowledge();
+ }
+
+#ifdef DEBUG
+ printk(KERN_INFO "mxs_set_mode: changing mode from %s to %s\n",
+ clock_event_mode_label[clockevent_mode],
+ clock_event_mode_label[mode]);
+#endif /* DEBUG */
+
+ /* Remember timer mode */
+ clockevent_mode = mode;
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ printk(KERN_ERR "mxs_set_mode: Periodic mode is not "
+ "supported for MXS-based\n");
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ timrot_irq_enable();
+ break;
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_RESUME:
+ /* Left event sources disabled, no more interrupts appear */
+ break;
+ }
+}
+
+static struct clock_event_device clockevent_mxs = {
+ .name = "mxs_timrot",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .shift = 32,
+ .set_mode = mxs_set_mode,
+ .set_next_event = timrotv2_set_next_event,
+ .rating = 200,
+};
+
+static int __init mxs_clockevent_init(struct clk *timer_clk)
+{
+ unsigned int c = clk_get_rate(timer_clk);
+
+ clockevent_mxs.mult = div_sc(c, NSEC_PER_SEC, clockevent_mxs.shift);
+ clockevent_mxs.cpumask = cpumask_of(0);
+ if (timrot_is_v1()) {
+ clockevent_mxs.set_next_event = timrotv1_set_next_event;
+ clockevent_mxs.max_delta_ns =
+ clockevent_delta2ns(0xfffe, &clockevent_mxs);
+ clockevent_mxs.min_delta_ns =
+ clockevent_delta2ns(0xf, &clockevent_mxs);
+ } else {
+ clockevent_mxs.max_delta_ns =
+ clockevent_delta2ns(0xfffffffe, &clockevent_mxs);
+ clockevent_mxs.min_delta_ns =
+ clockevent_delta2ns(0xff, &clockevent_mxs);
+ }
+
+ clockevents_register_device(&clockevent_mxs);
+
+ return 0;
+}
+
+static struct clocksource clocksource_mxs = {
+ .name = "mxs_timer",
+ .rating = 200,
+ .read = timrotv2_get_cycles,
+ .mask = CLOCKSOURCE_MASK(32),
+ .shift = 17,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int __init mxs_clocksource_init(struct clk *timer_clk)
+{
+ unsigned int c = clk_get_rate(timer_clk);
+
+ if (timrot_is_v1()) {
+ clocksource_mxs.read = timrotv1_get_cycles;
+ clocksource_mxs.mask = CLOCKSOURCE_MASK(16);
+ }
+ clocksource_mxs.mult = clocksource_hz2mult(c, clocksource_mxs.shift);
+ clocksource_register(&clocksource_mxs);
+
+ return 0;
+}
+
+void __init mxs_timer_init(struct clk *timer_clk,
+ void __iomem *base, int irq)
+{
+ clk_enable(timer_clk);
+
+ timer_base = base;
+
+ /*
+ * Initialize timers to a known state
+ */
+ mxs_reset_block(base + HW_TIMROT_ROTCTRL);
+
+ if (timrot_is_v1()) {
+ /* timer0 is for clock_event */
+ __raw_writel(
+ BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL |
+ BM_TIMROT_TIMCTRLn_UPDATE |
+ BM_TIMROT_TIMCTRLn_IRQ_EN,
+ base + HW_TIMROT_TIMCTRLn(0));
+ /* timer1 is for clocksource */
+ __raw_writel(
+ BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL |
+ BM_TIMROT_TIMCTRLn_RELOAD,
+ base + HW_TIMROT_TIMCTRLn(1));
+ __raw_writel(0xffff, timer_base + HW_TIMROT_RUNNING_COUNTn(1));
+
+ } else {
+ __raw_writel(
+ BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL |
+ BM_TIMROT_TIMCTRLn_IRQ_EN |
+ BM_TIMROT_TIMCTRLn_MATCH_MODE,
+ timer_base + HW_TIMROT_TIMCTRLn(0));
+ }
+
+ /* init and register the timer to the framework */
+ mxs_clocksource_init(timer_clk);
+ mxs_clockevent_init(timer_clk);
+
+ /* Make irqs happen */
+ setup_irq(irq, &mxs_timer_irq);
+}
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH v2 07/15] ARM: mxs: Add gpio support
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (25 preceding siblings ...)
2010-12-07 16:31 ` [PATCH v3 06/15] ARM: mxs: Add timer support Shawn Guo
@ 2010-12-07 16:31 ` Shawn Guo
2010-12-08 7:21 ` Lothar Waßmann
2010-12-07 16:31 ` [PATCH v2 08/15] ARM: mxs: Add iomux support Shawn Guo
` (19 subsequent siblings)
46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-07 16:31 UTC (permalink / raw)
To: linux-arm-kernel
MXS-based SoCs implement gpio support in block PINCTRL.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
- Create arch/arm/mach-mxs/gpio.h to accommodate stuff private for mach-mxs
- Use GPIO_INT_LEV_MASK and GPIO_INT_POL_MASK instead of constant
- Remove both edges IRQ support which is not needed
- Use SET and CLR register of PINCTRL_DOE in _set_gpio_direction()
- Use pr_info over printk(KERN_INFO)
arch/arm/mach-mxs/gpio.c | 331 +++++++++++++++++++++++++++++++++
arch/arm/mach-mxs/gpio.h | 36 ++++
arch/arm/mach-mxs/include/mach/gpio.h | 35 ++++
3 files changed, 402 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/gpio.c
create mode 100644 arch/arm/mach-mxs/gpio.h
create mode 100644 arch/arm/mach-mxs/include/mach/gpio.h
diff --git a/arch/arm/mach-mxs/gpio.c b/arch/arm/mach-mxs/gpio.c
new file mode 100644
index 0000000..6db7541
--- /dev/null
+++ b/arch/arm/mach-mxs/gpio.c
@@ -0,0 +1,331 @@
+/*
+ * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
+ * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
+ *
+ * Based on code from Freescale,
+ * Copyright (C) 2004-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/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <mach/hardware.h>
+#include <asm-generic/bug.h>
+
+#include "gpio.h"
+
+static struct mxs_gpio_port *mxs_gpio_ports;
+static int gpio_table_size;
+
+#define PINCTRL_DOUT(n) ((cpu_is_mx23() ? 0x0500 : 0x0700) + (n) * 0x10)
+#define PINCTRL_DIN(n) ((cpu_is_mx23() ? 0x0600 : 0x0900) + (n) * 0x10)
+#define PINCTRL_DOE(n) ((cpu_is_mx23() ? 0x0700 : 0x0b00) + (n) * 0x10)
+#define PINCTRL_PIN2IRQ(n) ((cpu_is_mx23() ? 0x0800 : 0x1000) + (n) * 0x10)
+#define PINCTRL_IRQEN(n) ((cpu_is_mx23() ? 0x0900 : 0x1100) + (n) * 0x10)
+#define PINCTRL_IRQLEV(n) ((cpu_is_mx23() ? 0x0a00 : 0x1200) + (n) * 0x10)
+#define PINCTRL_IRQPOL(n) ((cpu_is_mx23() ? 0x0b00 : 0x1300) + (n) * 0x10)
+#define PINCTRL_IRQSTAT(n) ((cpu_is_mx23() ? 0x0c00 : 0x1400) + (n) * 0x10)
+
+#define GPIO_INT_FALL_EDGE 0x0
+#define GPIO_INT_LOW_LEV 0x1
+#define GPIO_INT_RISE_EDGE 0x2
+#define GPIO_INT_HIGH_LEV 0x3
+#define GPIO_INT_LEV_MASK (1 << 0)
+#define GPIO_INT_POL_MASK (1 << 1)
+
+/* Note: This driver assumes 32 GPIOs are handled in one register */
+
+static void _clear_gpio_irqstatus(struct mxs_gpio_port *port, u32 index)
+{
+ __raw_writel(1 << index,
+ port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR_ADDR);
+}
+
+static void _set_gpio_irqenable(struct mxs_gpio_port *port, u32 index,
+ int enable)
+{
+ if (enable == 0) {
+ __raw_writel(1 << index,
+ port->base + PINCTRL_PIN2IRQ(port->id) + MXS_CLR_ADDR);
+ __raw_writel(1 << index,
+ port->base + PINCTRL_IRQEN(port->id) + MXS_CLR_ADDR);
+ } else {
+ __raw_writel(1 << index,
+ port->base + PINCTRL_PIN2IRQ(port->id) + MXS_SET_ADDR);
+ __raw_writel(1 << index,
+ port->base + PINCTRL_IRQEN(port->id) + MXS_SET_ADDR);
+ }
+}
+
+static void gpio_ack_irq(u32 irq)
+{
+ u32 gpio = irq_to_gpio(irq);
+ _clear_gpio_irqstatus(&mxs_gpio_ports[gpio / 32], gpio & 0x1f);
+}
+
+static void gpio_mask_irq(u32 irq)
+{
+ u32 gpio = irq_to_gpio(irq);
+ _set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 0);
+}
+
+static void gpio_unmask_irq(u32 irq)
+{
+ u32 gpio = irq_to_gpio(irq);
+ _set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 1);
+}
+
+static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset);
+
+static int gpio_set_irq_type(u32 irq, u32 type)
+{
+ u32 gpio = irq_to_gpio(irq);
+ struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32];
+ int edge;
+
+ switch (type) {
+ case IRQ_TYPE_EDGE_RISING:
+ edge = GPIO_INT_RISE_EDGE;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ edge = GPIO_INT_FALL_EDGE;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ edge = GPIO_INT_LOW_LEV;
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ edge = GPIO_INT_HIGH_LEV;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* set level or edge */
+ if (edge & GPIO_INT_LEV_MASK)
+ __raw_writel(1 << (gpio & 31),
+ port->base + PINCTRL_IRQLEV(port->id) + MXS_SET_ADDR);
+ else
+ __raw_writel(1 << (gpio & 31),
+ port->base + PINCTRL_IRQLEV(port->id) + MXS_CLR_ADDR);
+
+ /* set polarity */
+ if (edge & GPIO_INT_POL_MASK)
+ __raw_writel(1 << (gpio & 31),
+ port->base + PINCTRL_IRQPOL(port->id) + MXS_SET_ADDR);
+ else
+ __raw_writel(1 << (gpio & 31),
+ port->base + PINCTRL_IRQPOL(port->id) + MXS_CLR_ADDR);
+
+ _clear_gpio_irqstatus(port, gpio & 0x1f);
+
+ return 0;
+}
+
+/* MXS has one interrupt *per* gpio port */
+static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc)
+{
+ u32 irq_stat;
+ struct mxs_gpio_port *port = (struct mxs_gpio_port *)get_irq_data(irq);
+ u32 gpio_irq_no_base = port->virtual_irq_start;
+
+ irq_stat = __raw_readl(port->base + PINCTRL_IRQSTAT(port->id)) &
+ __raw_readl(port->base + PINCTRL_IRQEN(port->id)) &
+ __raw_readl(port->base + PINCTRL_PIN2IRQ(port->id));
+
+ while (irq_stat != 0) {
+ int irqoffset = fls(irq_stat) - 1;
+ generic_handle_irq(gpio_irq_no_base + irqoffset);
+ irq_stat &= ~(1 << irqoffset);
+ }
+}
+
+/*
+ * Set interrupt number "irq" in the GPIO as a wake-up source.
+ * While system is running, all registered GPIO interrupts need to have
+ * wake-up enabled. When system is suspended, only selected GPIO interrupts
+ * need to have wake-up enabled.
+ * @param irq interrupt source number
+ * @param enable enable as wake-up if equal to non-zero
+ * @return This function returns 0 on success.
+ */
+static int gpio_set_wake_irq(u32 irq, u32 enable)
+{
+ u32 gpio = irq_to_gpio(irq);
+ u32 gpio_idx = gpio & 0x1f;
+ struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32];
+
+ if (enable) {
+ if (port->irq_high && (gpio_idx >= 16))
+ enable_irq_wake(port->irq_high);
+ else
+ enable_irq_wake(port->irq);
+ } else {
+ if (port->irq_high && (gpio_idx >= 16))
+ disable_irq_wake(port->irq_high);
+ else
+ disable_irq_wake(port->irq);
+ }
+
+ return 0;
+}
+
+static struct irq_chip gpio_irq_chip = {
+ .ack = gpio_ack_irq,
+ .mask = gpio_mask_irq,
+ .unmask = gpio_unmask_irq,
+ .set_type = gpio_set_irq_type,
+ .set_wake = gpio_set_wake_irq,
+};
+
+static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset,
+ int dir)
+{
+ struct mxs_gpio_port *port =
+ container_of(chip, struct mxs_gpio_port, chip);
+ unsigned long flags;
+
+ spin_lock_irqsave(&port->lock, flags);
+ if (dir)
+ __raw_writel(1 << offset,
+ port->base + PINCTRL_DOE(port->id) + MXS_SET_ADDR);
+ else
+ __raw_writel(1 << offset,
+ port->base + PINCTRL_DOE(port->id) + MXS_CLR_ADDR);
+ spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static void mxs_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct mxs_gpio_port *port =
+ container_of(chip, struct mxs_gpio_port, chip);
+ u32 l;
+ unsigned long flags;
+ void __iomem *reg = port->base + PINCTRL_DOUT(port->id);
+
+ spin_lock_irqsave(&port->lock, flags);
+ l = (__raw_readl(reg) & (~(1 << offset))) | (!!value << offset);
+ __raw_writel(l, reg);
+ spin_unlock_irqrestore(&port->lock, flags);
+}
+
+static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct mxs_gpio_port *port =
+ container_of(chip, struct mxs_gpio_port, chip);
+ void __iomem *reg = port->base + PINCTRL_DIN(port->id);
+
+ return (__raw_readl(reg) >> offset) & 1;
+}
+
+static int mxs_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ _set_gpio_direction(chip, offset, 0);
+ return 0;
+}
+
+static int mxs_gpio_direction_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ mxs_gpio_set(chip, offset, value);
+ _set_gpio_direction(chip, offset, 1);
+ return 0;
+}
+
+int __init mxs_gpio_init(struct mxs_gpio_port *port, int cnt)
+{
+ int i, j;
+
+ /* save for local usage */
+ mxs_gpio_ports = port;
+ gpio_table_size = cnt;
+
+ pr_info("MXS GPIO hardware\n");
+
+ for (i = 0; i < cnt; i++) {
+ /* disable the interrupt and clear the status */
+ __raw_writel(0, port[i].base +
+ PINCTRL_PIN2IRQ(i));
+ __raw_writel(0, port[i].base +
+ PINCTRL_IRQEN(i));
+ __raw_writel(~0, port[i].base +
+ PINCTRL_IRQSTAT(i) + MXS_CLR_ADDR);
+
+ for (j = port[i].virtual_irq_start;
+ j < port[i].virtual_irq_start + 32; j++) {
+ set_irq_chip(j, &gpio_irq_chip);
+ set_irq_handler(j, handle_level_irq);
+ set_irq_flags(j, IRQF_VALID);
+ }
+
+ /* register gpio chip */
+ port[i].chip.direction_input = mxs_gpio_direction_input;
+ port[i].chip.direction_output = mxs_gpio_direction_output;
+ port[i].chip.get = mxs_gpio_get;
+ port[i].chip.set = mxs_gpio_set;
+ port[i].chip.base = i * 32;
+ port[i].chip.ngpio = 32;
+
+ spin_lock_init(&port[i].lock);
+
+ /* its a serious configuration bug when it fails */
+ BUG_ON( gpiochip_add(&port[i].chip) < 0 );
+
+ /* setup one handler for each entry */
+ set_irq_chained_handler(port[i].irq, mxs_gpio_irq_handler);
+ set_irq_data(port[i].irq, &port[i]);
+ }
+
+ return 0;
+}
+
+#define DEFINE_MXS_GPIO_PORT(soc, _id) \
+ { \
+ .chip.label = "gpio-" #_id, \
+ .id = _id, \
+ .irq = soc ## _INT_GPIO ## _id, \
+ .base = soc ## _IO_ADDRESS( \
+ soc ## _PINCTRL ## _BASE_ADDR), \
+ .virtual_irq_start = MXS_GPIO_IRQ_START + (_id) * 32, \
+ }
+
+#define DEFINE_REGISTER_FUNCTION(prefix) \
+int __init prefix ## _register_gpios(void) \
+{ \
+ return mxs_gpio_init(prefix ## _gpio_ports, \
+ ARRAY_SIZE(prefix ## _gpio_ports)); \
+}
+
+#ifdef CONFIG_SOC_IMX23
+static struct mxs_gpio_port mx23_gpio_ports[] = {
+ DEFINE_MXS_GPIO_PORT(MX23, 0),
+ DEFINE_MXS_GPIO_PORT(MX23, 1),
+ DEFINE_MXS_GPIO_PORT(MX23, 2),
+};
+DEFINE_REGISTER_FUNCTION(mx23)
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+static struct mxs_gpio_port mx28_gpio_ports[] = {
+ DEFINE_MXS_GPIO_PORT(MX28, 0),
+ DEFINE_MXS_GPIO_PORT(MX28, 1),
+ DEFINE_MXS_GPIO_PORT(MX28, 2),
+ DEFINE_MXS_GPIO_PORT(MX28, 3),
+ DEFINE_MXS_GPIO_PORT(MX28, 4),
+};
+DEFINE_REGISTER_FUNCTION(mx28)
+#endif
diff --git a/arch/arm/mach-mxs/gpio.h b/arch/arm/mach-mxs/gpio.h
new file mode 100644
index 0000000..e469281
--- /dev/null
+++ b/arch/arm/mach-mxs/gpio.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.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.
+ */
+
+#ifndef __MXS_GPIO_H__
+#define __MXS_GPIO_H__
+
+#include <linux/spinlock.h>
+
+struct mxs_gpio_port {
+ void __iomem *base;
+ int id;
+ int irq;
+ int irq_high;
+ int virtual_irq_start;
+ struct gpio_chip chip;
+ spinlock_t lock;
+};
+
+int mxs_gpio_init(struct mxs_gpio_port*, int);
+
+#endif /* __MXS_GPIO_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/gpio.h b/arch/arm/mach-mxs/include/mach/gpio.h
new file mode 100644
index 0000000..a743e3a
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/gpio.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2007 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
+ * 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_MXS_GPIO_H__
+#define __MACH_MXS_GPIO_H__
+
+#include <mach/hardware.h>
+#include <asm-generic/gpio.h>
+
+#define MXS_GPIO_NR(bank, nr) ((bank) * 32 + (nr))
+
+/* use gpiolib dispatchers */
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep __gpio_cansleep
+
+#define gpio_to_irq(gpio) (MXS_GPIO_IRQ_START + (gpio))
+#define irq_to_gpio(irq) ((irq) - MXS_GPIO_IRQ_START)
+
+#endif /* __MACH_MXS_GPIO_H__ */
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH v2 08/15] ARM: mxs: Add iomux support
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (26 preceding siblings ...)
2010-12-07 16:31 ` [PATCH v2 07/15] ARM: mxs: Add gpio support Shawn Guo
@ 2010-12-07 16:31 ` Shawn Guo
2010-12-08 7:25 ` Lothar Waßmann
2010-12-07 16:31 ` [PATCH v2 09/15] ARM: mxs: Add clock support Shawn Guo
` (18 subsequent siblings)
46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-07 16:31 UTC (permalink / raw)
To: linux-arm-kernel
MXS-based SoCs implements iomux functions in block PINCTRL.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
- Define iomux_cfg_t as u64
- Turn mxs_iomux_setup_pad() into a static function
- Fix a bug in mxs_iomux_setup_pad(), muxsel starts at offset 0x100 than 0 of pinctrl block.
arch/arm/mach-mxs/include/mach/iomux-mx23.h | 29 +++++++
arch/arm/mach-mxs/include/mach/iomux-mx28.h | 44 +++++++++++
arch/arm/mach-mxs/include/mach/iomux.h | 72 +++++++++++++++++
arch/arm/mach-mxs/iomux.c | 110 +++++++++++++++++++++++++++
4 files changed, 255 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/include/mach/iomux-mx23.h
create mode 100644 arch/arm/mach-mxs/include/mach/iomux-mx28.h
create mode 100644 arch/arm/mach-mxs/include/mach/iomux.h
create mode 100644 arch/arm/mach-mxs/iomux.c
diff --git a/arch/arm/mach-mxs/include/mach/iomux-mx23.h b/arch/arm/mach-mxs/include/mach/iomux-mx23.h
new file mode 100644
index 0000000..3fc0439
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/iomux-mx23.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * 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
+ */
+
+#ifndef __MACH_IOMUX_MX23_H__
+#define __MACH_IOMUX_MX23_H__
+
+#include <mach/iomux.h>
+
+/*
+ * The naming convention for the pad modes is MX23_PAD_<padname>__<padmode>
+ * If <padname> or <padmode> refers to a GPIO, it is named GPIO_<unit>_<num>
+ * See also iomux.h
+ *
+ * BANK PIN MUX VOL MA PULL
+ */
+/* DUART */
+#define MX23_PAD_PWM0__DUART_RX IOMUX_PAD(1, 26, PAD_MUXSEL_2, PAD_VOL_NONE, PAD_4MA, PAD_NOPULL)
+#define MX23_PAD_PWM1__DUART_TX IOMUX_PAD(1, 27, PAD_MUXSEL_2, PAD_VOL_NONE, PAD_4MA, PAD_NOPULL)
+
+#endif /* __MACH_IOMUX_MX23_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/iomux-mx28.h b/arch/arm/mach-mxs/include/mach/iomux-mx28.h
new file mode 100644
index 0000000..ca37a15
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/iomux-mx28.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * 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
+ */
+
+#ifndef __MACH_IOMUX_MX28_H__
+#define __MACH_IOMUX_MX28_H__
+
+#include <mach/iomux.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.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/mach-mxs/include/mach/iomux.h b/arch/arm/mach-mxs/include/mach/iomux.h
new file mode 100644
index 0000000..91de8e7
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/iomux.h
@@ -0,0 +1,72 @@
+/*
+ * 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_MXS_IOMUX_H__
+#define __MACH_MXS_IOMUX_H__
+
+typedef struct pad_desc {
+ unsigned bank:12;
+ unsigned pin:20;
+ unsigned muxsel:8;
+ unsigned ma:12;
+ unsigned vol:8;
+ unsigned pull:4;
+} iomux_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
+
+/*
+ * setups multiple pads
+ * convenient way to call the above function with tables
+ */
+int mxs_iomux_setup_multiple_pads(iomux_cfg_t *pad_list, unsigned count);
+
+/*
+ * Initialise the iomux controller
+ */
+void mxs_iomux_init(void __iomem *iomux_base);
+
+#endif /* __MACH_MXS_IOMUX_H__*/
diff --git a/arch/arm/mach-mxs/iomux.c b/arch/arm/mach-mxs/iomux.c
new file mode 100644
index 0000000..e6ebb0d
--- /dev/null
+++ b/arch/arm/mach-mxs/iomux.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2004-2006,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.h>
+
+static void __iomem *base;
+
+/*
+ * configures a single pad in the iomuxer
+ */
+static int mxs_iomux_setup_pad(iomux_cfg_t *pad)
+{
+ u32 reg, ofs, bp, bm;
+
+ /* muxsel */
+ ofs = 0x100;
+ 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 */
+ ofs = cpu_is_mx23() ? 0x200 : 0x300;
+ ofs += pad->bank * 0x40 + pad->pin / 8 * 0x10;
+ /* ma */
+ if (pad->ma != PAD_MA_NONE)
+ {
+ bp = pad->pin % 8 * 4;
+ bm = 0x3 << bp;
+ reg = __raw_readl(base + ofs);
+ reg &= ~bm;
+ reg |= pad->ma << bp;
+ __raw_writel(reg, base + ofs);
+ }
+ /* vol */
+ if (pad->vol != PAD_VOL_NONE)
+ {
+ bp = pad->pin % 8 * 4 + 2;
+ bm = 0x1 << bp;
+ reg = __raw_readl(base + ofs);
+ reg &= ~bm;
+ reg |= pad->vol << bp;
+ __raw_writel(reg, base + ofs);
+ }
+
+ /* pull */
+ ofs = cpu_is_mx23() ? 0x400 : 0x600;
+ ofs += 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;
+}
+
+int mxs_iomux_setup_multiple_pads(iomux_cfg_t *pad_list, unsigned count)
+{
+ iomux_cfg_t *p = pad_list;
+ int i;
+ int ret;
+
+ for (i = 0; i < count; i++) {
+ ret = mxs_iomux_setup_pad(p);
+ if (ret)
+ return ret;
+ p++;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(mxs_iomux_setup_multiple_pads);
+
+void mxs_iomux_init(void __iomem *iomux_base)
+{
+ base = iomux_base;
+}
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH v2 09/15] ARM: mxs: Add clock support
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (27 preceding siblings ...)
2010-12-07 16:31 ` [PATCH v2 08/15] ARM: mxs: Add iomux support Shawn Guo
@ 2010-12-07 16:31 ` Shawn Guo
2010-12-08 20:57 ` Uwe Kleine-König
2010-12-09 8:41 ` Uwe Kleine-König
2010-12-07 16:32 ` [PATCH v2 12/15] ARM: mxs: Dynamically allocate fec devices Shawn Guo
` (17 subsequent siblings)
46 siblings, 2 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-07 16:31 UTC (permalink / raw)
To: linux-arm-kernel
Add clock for MXS-based SoCs, MX23 and MX28.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
- Shift pll0_clock freq 480MHz in children freq computation to avoid overflow
- Fix fec_clk to stand for fec clock than IEEE1588 time clock
- Add pll2_clk into clock lookups, as it's fec phy clock and needs to be on before reset phy
arch/arm/mach-mxs/clock-mx23.c | 521 ++++++++++++++++++++++
arch/arm/mach-mxs/clock-mx28.c | 731 +++++++++++++++++++++++++++++++
arch/arm/mach-mxs/clock.c | 201 +++++++++
arch/arm/mach-mxs/include/mach/clkdev.h | 7 +
arch/arm/mach-mxs/include/mach/clock.h | 64 +++
arch/arm/mach-mxs/regs-clkctrl-mx23.h | 455 +++++++++++++++++++
arch/arm/mach-mxs/regs-clkctrl-mx28.h | 663 ++++++++++++++++++++++++++++
7 files changed, 2642 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/clock-mx23.c
create mode 100644 arch/arm/mach-mxs/clock-mx28.c
create mode 100644 arch/arm/mach-mxs/clock.c
create mode 100644 arch/arm/mach-mxs/include/mach/clkdev.h
create mode 100644 arch/arm/mach-mxs/include/mach/clock.h
create mode 100644 arch/arm/mach-mxs/regs-clkctrl-mx23.h
create mode 100644 arch/arm/mach-mxs/regs-clkctrl-mx28.h
diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c
new file mode 100644
index 0000000..832db0b
--- /dev/null
+++ b/arch/arm/mach-mxs/clock-mx23.c
@@ -0,0 +1,521 @@
+/*
+ * 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-mx23.h"
+
+#define CLKCTRL_BASE_ADDR MX23_IO_ADDRESS(MX23_CLKCTRL_BASE_ADDR)
+#define DIGCTRL_BASE_ADDR MX23_IO_ADDRESS(MX23_DIGCTL_BASE_ADDR)
+
+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 pll_clk_get_rate(struct clk *clk)
+{
+ return 480000000;
+}
+
+static int pll_clk_enable(struct clk *clk)
+{
+ __raw_writel(BM_CLKCTRL_PLLCTRL0_POWER |
+ BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS,
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLLCTRL0_SET);
+
+ /* Only a 10us delay is need. PLLCTRL1 LOCK bitfied is only a timer
+ * and is incorrect (excessive). Per definition of the PLLCTRL0
+ * POWER field, waiting at least 10us.
+ */
+ udelay(10);
+
+ return 0;
+}
+
+static void pll_clk_disable(struct clk *clk)
+{
+ __raw_writel(BM_CLKCTRL_PLLCTRL0_POWER |
+ BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS,
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLLCTRL0_CLR);
+}
+
+static struct clk pll_clk = {
+ .get_rate = pll_clk_get_rate,
+ .enable = pll_clk_enable,
+ .disable = pll_clk_disable,
+ .parent = &ref_xtal_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, FRAC, CPU)
+_CLK_GET_RATE_REF(ref_emi_clk, FRAC, EMI)
+_CLK_GET_RATE_REF(ref_pix_clk, FRAC, PIX)
+_CLK_GET_RATE_REF(ref_io_clk, FRAC, IO)
+
+#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 = &pll_clk, \
+ }
+
+_DEFINE_CLOCK_REF(ref_cpu_clk, FRAC, CPU);
+_DEFINE_CLOCK_REF(ref_emi_clk, FRAC, EMI);
+_DEFINE_CLOCK_REF(ref_pix_clk, FRAC, PIX);
+_DEFINE_CLOCK_REF(ref_io_clk, FRAC, IO);
+
+/*
+ * General clocks
+ *
+ * clk_get_rate
+ */
+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;
+}
+
+#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; \
+ \
+ return clk_get_rate(clk->parent) / div; \
+}
+
+_CLK_GET_RATE1(hbus_clk, HBUS)
+_CLK_GET_RATE1(xbus_clk, XBUS)
+_CLK_GET_RATE1(ssp_clk, SSP)
+_CLK_GET_RATE1(gpmi_clk, GPMI)
+_CLK_GET_RATE1(lcdif_clk, PIX)
+
+#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(audio_clk)
+_CLK_GET_RATE_STUB(pwm_clk)
+
+/*
+ * clk_set_rate
+ */
+static int cpu_clk_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);
+
+ if (clk->parent == &ref_xtal_clk) {
+ div_max = BM_CLKCTRL_CPU_DIV_XTAL >> BP_CLKCTRL_CPU_DIV_XTAL;
+ bm_busy = BM_CLKCTRL_CPU_BUSY_REF_XTAL;
+ div = DIV_ROUND_UP(parent_rate, rate);
+ if (div == 0 || div > div_max)
+ return -EINVAL;
+ } else {
+ div_max = BM_CLKCTRL_CPU_DIV_CPU >> BP_CLKCTRL_CPU_DIV_CPU;
+ bm_busy = BM_CLKCTRL_CPU_BUSY_REF_CPU;
+ div = frac = 1;
+ diff = parent_rate;
+ 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_FRAC);
+ reg &= ~BM_CLKCTRL_FRAC_CPUFRAC;
+ reg |= frac;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
+ }
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);
+ reg &= ~BM_CLKCTRL_CPU_DIV_CPU;
+ reg |= div << BP_CLKCTRL_CPU_DIV_CPU;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);
+
+ for (i = 10000; i; i--)
+ if (!(__raw_readl(CLKCTRL_BASE_ADDR +
+ HW_CLKCTRL_CPU) & bm_busy))
+ break;
+ if (!i) {
+ pr_err("%s: divider writing timeout\n", __func__);
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+#define _CLK_SET_RATE(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_RATE(xbus_clk, XBUS)
+_CLK_SET_RATE(ssp_clk, SSP)
+_CLK_SET_RATE(gpmi_clk, GPMI)
+_CLK_SET_RATE(lcdif_clk, PIX)
+
+#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(audio_clk)
+_CLK_SET_RATE_STUB(pwm_clk)
+_CLK_SET_RATE_STUB(clk32k_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(ssp_clk, SSP)
+_CLK_SET_PARENT(gpmi_clk, GPMI)
+_CLK_SET_PARENT(lcdif_clk, PIX)
+
+#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(uart_clk)
+_CLK_SET_PARENT_STUB(audio_clk)
+_CLK_SET_PARENT_STUB(pwm_clk)
+_CLK_SET_PARENT_STUB(clk32k_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 rtc_clk = {
+ .get_rate = rtc_clk_get_rate,
+ .parent = &ref_xtal_clk,
+};
+
+/* usb_clk gate is controlled in DIGCTRL other than CLKCTRL */
+static struct clk usb_clk = {
+ .enable_reg = DIGCTRL_BASE_ADDR,
+ .enable_shift = 2,
+ .enable = _raw_clk_enable,
+ .disable = _raw_clk_disable,
+ .parent = &pll_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(ssp_clk, SSP, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(gpmi_clk, GPMI, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(lcdif_clk, PIX, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(uart_clk, XTAL, UART_CLK_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(audio_clk, XTAL, FILT_CLK24M_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(pwm_clk, XTAL, PWM_CLK24M_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(clk32k_clk, XTAL, TIMROT_CLK32K_GATE, &ref_xtal_clk);
+
+#define _REGISTER_CLOCK(d, n, c) \
+ { \
+ .dev_id = d, \
+ .con_id = n, \
+ .clk = &c, \
+ },
+
+static struct clk_lookup lookups[] = {
+ _REGISTER_CLOCK("mxs-duart.0", NULL, uart_clk)
+ _REGISTER_CLOCK("rtc", NULL, rtc_clk)
+ _REGISTER_CLOCK(NULL, "hclk", hbus_clk)
+ _REGISTER_CLOCK(NULL, "xclk", xbus_clk)
+ _REGISTER_CLOCK(NULL, "usb", usb_clk)
+ _REGISTER_CLOCK(NULL, "audio", audio_clk)
+ _REGISTER_CLOCK(NULL, "pwm", pwm_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;
+ ssp_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP) ?
+ &ref_xtal_clk : &ref_io_clk;
+ gpmi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_GPMI) ?
+ &ref_xtal_clk : &ref_io_clk;
+ lcdif_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_PIX) ?
+ &ref_xtal_clk : &ref_pix_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_SSP);
+ reg &= ~BM_CLKCTRL_SSP_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP);
+
+ 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_PIX);
+ reg &= ~BM_CLKCTRL_PIX_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_PIX);
+
+ /*
+ * 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_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);
+
+ return 0;
+}
+
+int __init mx23_clocks_init(void)
+{
+ clk_misc_init();
+
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+ mxs_timer_init(&clk32k_clk, MX23_IO_ADDRESS(MX23_TIMROT_BASE_ADDR),
+ MX23_INT_TIMER0);
+
+ return 0;
+}
diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
new file mode 100644
index 0000000..9c0abe1
--- /dev/null
+++ b/arch/arm/mach-mxs/clock-mx28.c
@@ -0,0 +1,731 @@
+/*
+ * 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 / 1000 * 18 / div * 1000; \
+}
+
+_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)
+
+#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_GET_RATE_STUB(fec_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 { \
+ rate /= 1000; \
+ parent_rate /= 1000; \
+ diff = parent_rate; \
+ div = frac = 1; \
+ 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)
+
+/* 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_RATE_STUB(fec_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 gate 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);
+_DEFINE_CLOCK(fec_clk, ENET, DISABLE, &hbus_clk);
+
+#define _REGISTER_CLOCK(d, n, c) \
+ { \
+ .dev_id = d, \
+ .con_id = n, \
+ .clk = &c, \
+ },
+
+static struct clk_lookup lookups[] = {
+ _REGISTER_CLOCK("mxs-duart.0", NULL, uart_clk)
+ _REGISTER_CLOCK("fec.0", NULL, fec_clk)
+ _REGISTER_CLOCK("rtc", NULL, rtc_clk)
+ _REGISTER_CLOCK("pll2", NULL, pll2_clk)
+ _REGISTER_CLOCK(NULL, "hclk", hbus_clk)
+ _REGISTER_CLOCK(NULL, "xclk", xbus_clk)
+ _REGISTER_CLOCK(NULL, "can0", can0_clk)
+ _REGISTER_CLOCK(NULL, "can1", can1_clk)
+ _REGISTER_CLOCK(NULL, "usb0", usb0_clk)
+ _REGISTER_CLOCK(NULL, "usb1", usb1_clk)
+ _REGISTER_CLOCK(NULL, "pwm", pwm_clk)
+ _REGISTER_CLOCK(NULL, "lradc", lradc_clk)
+ _REGISTER_CLOCK(NULL, "spdif", 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;
+ 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));
+
+ mxs_timer_init(&clk32k_clk, MX28_IO_ADDRESS(MX28_TIMROT_BASE_ADDR),
+ MX28_INT_TIMER0);
+
+ return 0;
+}
diff --git a/arch/arm/mach-mxs/clock.c b/arch/arm/mach-mxs/clock.c
new file mode 100644
index 0000000..e262759
--- /dev/null
+++ b/arch/arm/mach-mxs/clock.c
@@ -0,0 +1,201 @@
+/*
+ * Based on arch/arm/plat-omap/clock.c
+ *
+ * Copyright (C) 2004 - 2005 Nokia corporation
+ * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ * Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com>
+ * Copyright 2007 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
+ * 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.
+ */
+
+/* #define DEBUG */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/proc_fs.h>
+#include <linux/semaphore.h>
+#include <linux/string.h>
+
+#include <mach/clock.h>
+#include <mach/hardware.h>
+
+static LIST_HEAD(clocks);
+static DEFINE_MUTEX(clocks_mutex);
+
+/*-------------------------------------------------------------------------
+ * Standard clock functions defined in include/linux/clk.h
+ *-------------------------------------------------------------------------*/
+
+static void __clk_disable(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return;
+ WARN_ON(!clk->usecount);
+
+ if (!(--clk->usecount)) {
+ if (clk->disable)
+ clk->disable(clk);
+ __clk_disable(clk->parent);
+ __clk_disable(clk->secondary);
+ }
+}
+
+static int __clk_enable(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ if (clk->usecount++ == 0) {
+ __clk_enable(clk->parent);
+ __clk_enable(clk->secondary);
+
+ if (clk->enable)
+ clk->enable(clk);
+ }
+ return 0;
+}
+
+/* This function increments the reference count on the clock and enables the
+ * clock if not already enabled. The parent clock tree is recursively enabled
+ */
+int clk_enable(struct clk *clk)
+{
+ int ret = 0;
+
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ mutex_lock(&clocks_mutex);
+ ret = __clk_enable(clk);
+ mutex_unlock(&clocks_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_enable);
+
+/* This function decrements the reference count on the clock and disables
+ * the clock when reference count is 0. The parent clock tree is
+ * recursively disabled
+ */
+void clk_disable(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return;
+
+ mutex_lock(&clocks_mutex);
+ __clk_disable(clk);
+ mutex_unlock(&clocks_mutex);
+}
+EXPORT_SYMBOL(clk_disable);
+
+/* Retrieve the *current* clock rate. If the clock itself
+ * does not provide a special calculation routine, ask
+ * its parent and so on, until one is able to return
+ * a valid clock rate
+ */
+unsigned long clk_get_rate(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return 0UL;
+
+ if (clk->get_rate)
+ return clk->get_rate(clk);
+
+ return clk_get_rate(clk->parent);
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+/* Round the requested clock rate to the nearest supported
+ * rate that is less than or equal to the requested rate.
+ * This is dependent on the clock's current parent.
+ */
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ if (clk == NULL || IS_ERR(clk) || !clk->round_rate)
+ return 0;
+
+ return clk->round_rate(clk, rate);
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+/* Set the clock to the requested clock rate. The rate must
+ * match a supported rate exactly based on what clk_round_rate returns
+ */
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ int ret = -EINVAL;
+
+ if (clk == NULL || IS_ERR(clk) || clk->set_rate == NULL || rate == 0)
+ return ret;
+
+ mutex_lock(&clocks_mutex);
+ ret = clk->set_rate(clk, rate);
+ mutex_unlock(&clocks_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+/* Set the clock's parent to another clock source */
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ int ret = -EINVAL;
+ struct clk *old;
+
+ if (clk == NULL || IS_ERR(clk) || parent == NULL ||
+ IS_ERR(parent) || clk->set_parent == NULL)
+ return ret;
+
+ if (clk->usecount)
+ clk_enable(parent);
+
+ mutex_lock(&clocks_mutex);
+ ret = clk->set_parent(clk, parent);
+ if (ret == 0) {
+ old = clk->parent;
+ clk->parent = parent;
+ } else {
+ old = parent;
+ }
+ mutex_unlock(&clocks_mutex);
+
+ if (clk->usecount)
+ clk_disable(old);
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
+/* Retrieve the clock's parent clock source */
+struct clk *clk_get_parent(struct clk *clk)
+{
+ struct clk *ret = NULL;
+
+ if (clk == NULL || IS_ERR(clk))
+ return ret;
+
+ return clk->parent;
+}
+EXPORT_SYMBOL(clk_get_parent);
diff --git a/arch/arm/mach-mxs/include/mach/clkdev.h b/arch/arm/mach-mxs/include/mach/clkdev.h
new file mode 100644
index 0000000..3a8f2e3
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __MACH_MXS_CLKDEV_H__
+#define __MACH_MXS_CLKDEV_H__
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-mxs/include/mach/clock.h b/arch/arm/mach-mxs/include/mach/clock.h
new file mode 100644
index 0000000..041e276
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/clock.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2005-2007 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
+ * 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_MXS_CLOCK_H__
+#define __MACH_MXS_CLOCK_H__
+
+#ifndef __ASSEMBLY__
+#include <linux/list.h>
+
+struct module;
+
+struct clk {
+ int id;
+ /* Source clock this clk depends on */
+ struct clk *parent;
+ /* Secondary clock to enable/disable with this clock */
+ struct clk *secondary;
+ /* Reference count of clock enable/disable */
+ __s8 usecount;
+ /* Register bit position for clock's enable/disable control. */
+ u8 enable_shift;
+ /* Register address for clock's enable/disable control. */
+ void __iomem *enable_reg;
+ u32 flags;
+ /* get the current clock rate (always a fresh value) */
+ unsigned long (*get_rate) (struct clk *);
+ /* Function ptr to set the clock to a new rate. The rate must match a
+ supported rate returned from round_rate. Leave blank if clock is not
+ programmable */
+ int (*set_rate) (struct clk *, unsigned long);
+ /* Function ptr to round the requested clock rate to the nearest
+ supported rate that is less than or equal to the requested rate. */
+ unsigned long (*round_rate) (struct clk *, unsigned long);
+ /* Function ptr to enable the clock. Leave blank if clock can not
+ be gated. */
+ int (*enable) (struct clk *);
+ /* Function ptr to disable the clock. Leave blank if clock can not
+ be gated. */
+ void (*disable) (struct clk *);
+ /* Function ptr to set the parent clock of the clock. */
+ int (*set_parent) (struct clk *, struct clk *);
+};
+
+int clk_register(struct clk *clk);
+void clk_unregister(struct clk *clk);
+
+#endif /* __ASSEMBLY__ */
+#endif /* __MACH_MXS_CLOCK_H__ */
diff --git a/arch/arm/mach-mxs/regs-clkctrl-mx23.h b/arch/arm/mach-mxs/regs-clkctrl-mx23.h
new file mode 100644
index 0000000..dbc0474
--- /dev/null
+++ b/arch/arm/mach-mxs/regs-clkctrl-mx23.h
@@ -0,0 +1,455 @@
+/*
+ * Freescale CLKCTRL Register Definitions
+ *
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ * Copyright 2008-2010 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 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 __REGS_CLKCTRL_MX23_H__
+#define __REGS_CLKCTRL_MX23_H__
+
+
+#define HW_CLKCTRL_PLLCTRL0 (0x00000000)
+#define HW_CLKCTRL_PLLCTRL0_SET (0x00000004)
+#define HW_CLKCTRL_PLLCTRL0_CLR (0x00000008)
+#define HW_CLKCTRL_PLLCTRL0_TOG (0x0000000c)
+
+#define BP_CLKCTRL_PLLCTRL0_RSRVD6 30
+#define BM_CLKCTRL_PLLCTRL0_RSRVD6 0xC0000000
+#define BF_CLKCTRL_PLLCTRL0_RSRVD6(v) \
+ (((v) << 30) & BM_CLKCTRL_PLLCTRL0_RSRVD6)
+#define BP_CLKCTRL_PLLCTRL0_LFR_SEL 28
+#define BM_CLKCTRL_PLLCTRL0_LFR_SEL 0x30000000
+#define BF_CLKCTRL_PLLCTRL0_LFR_SEL(v) \
+ (((v) << 28) & BM_CLKCTRL_PLLCTRL0_LFR_SEL)
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__TIMES_2 0x1
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__TIMES_05 0x2
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLLCTRL0_RSRVD5 26
+#define BM_CLKCTRL_PLLCTRL0_RSRVD5 0x0C000000
+#define BF_CLKCTRL_PLLCTRL0_RSRVD5(v) \
+ (((v) << 26) & BM_CLKCTRL_PLLCTRL0_RSRVD5)
+#define BP_CLKCTRL_PLLCTRL0_CP_SEL 24
+#define BM_CLKCTRL_PLLCTRL0_CP_SEL 0x03000000
+#define BF_CLKCTRL_PLLCTRL0_CP_SEL(v) \
+ (((v) << 24) & BM_CLKCTRL_PLLCTRL0_CP_SEL)
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__TIMES_2 0x1
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__TIMES_05 0x2
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLLCTRL0_RSRVD4 22
+#define BM_CLKCTRL_PLLCTRL0_RSRVD4 0x00C00000
+#define BF_CLKCTRL_PLLCTRL0_RSRVD4(v) \
+ (((v) << 22) & BM_CLKCTRL_PLLCTRL0_RSRVD4)
+#define BP_CLKCTRL_PLLCTRL0_DIV_SEL 20
+#define BM_CLKCTRL_PLLCTRL0_DIV_SEL 0x00300000
+#define BF_CLKCTRL_PLLCTRL0_DIV_SEL(v) \
+ (((v) << 20) & BM_CLKCTRL_PLLCTRL0_DIV_SEL)
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__LOWER 0x1
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__LOWEST 0x2
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__UNDEFINED 0x3
+#define BM_CLKCTRL_PLLCTRL0_RSRVD3 0x00080000
+#define BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS 0x00040000
+#define BM_CLKCTRL_PLLCTRL0_RSRVD2 0x00020000
+#define BM_CLKCTRL_PLLCTRL0_POWER 0x00010000
+#define BP_CLKCTRL_PLLCTRL0_RSRVD1 0
+#define BM_CLKCTRL_PLLCTRL0_RSRVD1 0x0000FFFF
+#define BF_CLKCTRL_PLLCTRL0_RSRVD1(v) \
+ (((v) << 0) & BM_CLKCTRL_PLLCTRL0_RSRVD1)
+
+#define HW_CLKCTRL_PLLCTRL1 (0x00000010)
+
+#define BM_CLKCTRL_PLLCTRL1_LOCK 0x80000000
+#define BM_CLKCTRL_PLLCTRL1_FORCE_LOCK 0x40000000
+#define BP_CLKCTRL_PLLCTRL1_RSRVD1 16
+#define BM_CLKCTRL_PLLCTRL1_RSRVD1 0x3FFF0000
+#define BF_CLKCTRL_PLLCTRL1_RSRVD1(v) \
+ (((v) << 16) & BM_CLKCTRL_PLLCTRL1_RSRVD1)
+#define BP_CLKCTRL_PLLCTRL1_LOCK_COUNT 0
+#define BM_CLKCTRL_PLLCTRL1_LOCK_COUNT 0x0000FFFF
+#define BF_CLKCTRL_PLLCTRL1_LOCK_COUNT(v) \
+ (((v) << 0) & BM_CLKCTRL_PLLCTRL1_LOCK_COUNT)
+
+#define HW_CLKCTRL_CPU (0x00000020)
+#define HW_CLKCTRL_CPU_SET (0x00000024)
+#define HW_CLKCTRL_CPU_CLR (0x00000028)
+#define HW_CLKCTRL_CPU_TOG (0x0000002c)
+
+#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 (0x00000030)
+#define HW_CLKCTRL_HBUS_SET (0x00000034)
+#define HW_CLKCTRL_HBUS_CLR (0x00000038)
+#define HW_CLKCTRL_HBUS_TOG (0x0000003c)
+
+#define BP_CLKCTRL_HBUS_RSRVD4 30
+#define BM_CLKCTRL_HBUS_RSRVD4 0xC0000000
+#define BF_CLKCTRL_HBUS_RSRVD4(v) \
+ (((v) << 30) & BM_CLKCTRL_HBUS_RSRVD4)
+#define BM_CLKCTRL_HBUS_BUSY 0x20000000
+#define BM_CLKCTRL_HBUS_DCP_AS_ENABLE 0x10000000
+#define BM_CLKCTRL_HBUS_PXP_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_AUTO_SLOW_MODE 0x00100000
+#define BM_CLKCTRL_HBUS_RSRVD2 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 (0x00000040)
+
+#define BM_CLKCTRL_XBUS_BUSY 0x80000000
+#define BP_CLKCTRL_XBUS_RSRVD1 11
+#define BM_CLKCTRL_XBUS_RSRVD1 0x7FFFF800
+#define BF_CLKCTRL_XBUS_RSRVD1(v) \
+ (((v) << 11) & BM_CLKCTRL_XBUS_RSRVD1)
+#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 (0x00000050)
+#define HW_CLKCTRL_XTAL_SET (0x00000054)
+#define HW_CLKCTRL_XTAL_CLR (0x00000058)
+#define HW_CLKCTRL_XTAL_TOG (0x0000005c)
+
+#define BP_CLKCTRL_XTAL_UART_CLK_GATE 31
+#define BM_CLKCTRL_XTAL_UART_CLK_GATE 0x80000000
+#define BP_CLKCTRL_XTAL_FILT_CLK24M_GATE 30
+#define BM_CLKCTRL_XTAL_FILT_CLK24M_GATE 0x40000000
+#define BP_CLKCTRL_XTAL_PWM_CLK24M_GATE 29
+#define BM_CLKCTRL_XTAL_PWM_CLK24M_GATE 0x20000000
+#define BM_CLKCTRL_XTAL_DRI_CLK24M_GATE 0x10000000
+#define BM_CLKCTRL_XTAL_DIGCTRL_CLK1M_GATE 0x08000000
+#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_PIX (0x00000060)
+
+#define BP_CLKCTRL_PIX_CLKGATE 31
+#define BM_CLKCTRL_PIX_CLKGATE 0x80000000
+#define BM_CLKCTRL_PIX_RSRVD2 0x40000000
+#define BM_CLKCTRL_PIX_BUSY 0x20000000
+#define BP_CLKCTRL_PIX_RSRVD1 13
+#define BM_CLKCTRL_PIX_RSRVD1 0x1FFFE000
+#define BF_CLKCTRL_PIX_RSRVD1(v) \
+ (((v) << 13) & BM_CLKCTRL_PIX_RSRVD1)
+#define BM_CLKCTRL_PIX_DIV_FRAC_EN 0x00001000
+#define BP_CLKCTRL_PIX_DIV 0
+#define BM_CLKCTRL_PIX_DIV 0x00000FFF
+#define BF_CLKCTRL_PIX_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_PIX_DIV)
+
+#define HW_CLKCTRL_SSP (0x00000070)
+
+#define BP_CLKCTRL_SSP_CLKGATE 31
+#define BM_CLKCTRL_SSP_CLKGATE 0x80000000
+#define BM_CLKCTRL_SSP_RSRVD2 0x40000000
+#define BM_CLKCTRL_SSP_BUSY 0x20000000
+#define BP_CLKCTRL_SSP_RSRVD1 10
+#define BM_CLKCTRL_SSP_RSRVD1 0x1FFFFC00
+#define BF_CLKCTRL_SSP_RSRVD1(v) \
+ (((v) << 10) & BM_CLKCTRL_SSP_RSRVD1)
+#define BM_CLKCTRL_SSP_DIV_FRAC_EN 0x00000200
+#define BP_CLKCTRL_SSP_DIV 0
+#define BM_CLKCTRL_SSP_DIV 0x000001FF
+#define BF_CLKCTRL_SSP_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_SSP_DIV)
+
+#define HW_CLKCTRL_GPMI (0x00000080)
+
+#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 (0x00000090)
+
+#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 (0x000000a0)
+
+#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_IR (0x000000b0)
+
+#define BM_CLKCTRL_IR_CLKGATE 0x80000000
+#define BM_CLKCTRL_IR_RSRVD3 0x40000000
+#define BM_CLKCTRL_IR_AUTO_DIV 0x20000000
+#define BM_CLKCTRL_IR_IR_BUSY 0x10000000
+#define BM_CLKCTRL_IR_IROV_BUSY 0x08000000
+#define BP_CLKCTRL_IR_RSRVD2 25
+#define BM_CLKCTRL_IR_RSRVD2 0x06000000
+#define BF_CLKCTRL_IR_RSRVD2(v) \
+ (((v) << 25) & BM_CLKCTRL_IR_RSRVD2)
+#define BP_CLKCTRL_IR_IROV_DIV 16
+#define BM_CLKCTRL_IR_IROV_DIV 0x01FF0000
+#define BF_CLKCTRL_IR_IROV_DIV(v) \
+ (((v) << 16) & BM_CLKCTRL_IR_IROV_DIV)
+#define BP_CLKCTRL_IR_RSRVD1 10
+#define BM_CLKCTRL_IR_RSRVD1 0x0000FC00
+#define BF_CLKCTRL_IR_RSRVD1(v) \
+ (((v) << 10) & BM_CLKCTRL_IR_RSRVD1)
+#define BP_CLKCTRL_IR_IR_DIV 0
+#define BM_CLKCTRL_IR_IR_DIV 0x000003FF
+#define BF_CLKCTRL_IR_IR_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_IR_IR_DIV)
+
+#define HW_CLKCTRL_SAIF (0x000000c0)
+
+#define BM_CLKCTRL_SAIF_CLKGATE 0x80000000
+#define BM_CLKCTRL_SAIF_RSRVD2 0x40000000
+#define BM_CLKCTRL_SAIF_BUSY 0x20000000
+#define BP_CLKCTRL_SAIF_RSRVD1 17
+#define BM_CLKCTRL_SAIF_RSRVD1 0x1FFE0000
+#define BF_CLKCTRL_SAIF_RSRVD1(v) \
+ (((v) << 17) & BM_CLKCTRL_SAIF_RSRVD1)
+#define BM_CLKCTRL_SAIF_DIV_FRAC_EN 0x00010000
+#define BP_CLKCTRL_SAIF_DIV 0
+#define BM_CLKCTRL_SAIF_DIV 0x0000FFFF
+#define BF_CLKCTRL_SAIF_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_SAIF_DIV)
+
+#define HW_CLKCTRL_TV (0x000000d0)
+
+#define BM_CLKCTRL_TV_CLK_TV108M_GATE 0x80000000
+#define BM_CLKCTRL_TV_CLK_TV_GATE 0x40000000
+#define BP_CLKCTRL_TV_RSRVD 0
+#define BM_CLKCTRL_TV_RSRVD 0x3FFFFFFF
+#define BF_CLKCTRL_TV_RSRVD(v) \
+ (((v) << 0) & BM_CLKCTRL_TV_RSRVD)
+
+#define HW_CLKCTRL_ETM (0x000000e0)
+
+#define BM_CLKCTRL_ETM_CLKGATE 0x80000000
+#define BM_CLKCTRL_ETM_RSRVD2 0x40000000
+#define BM_CLKCTRL_ETM_BUSY 0x20000000
+#define BP_CLKCTRL_ETM_RSRVD1 7
+#define BM_CLKCTRL_ETM_RSRVD1 0x1FFFFF80
+#define BF_CLKCTRL_ETM_RSRVD1(v) \
+ (((v) << 7) & BM_CLKCTRL_ETM_RSRVD1)
+#define BM_CLKCTRL_ETM_DIV_FRAC_EN 0x00000040
+#define BP_CLKCTRL_ETM_DIV 0
+#define BM_CLKCTRL_ETM_DIV 0x0000003F
+#define BF_CLKCTRL_ETM_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_ETM_DIV)
+
+#define HW_CLKCTRL_FRAC (0x000000f0)
+#define HW_CLKCTRL_FRAC_SET (0x000000f4)
+#define HW_CLKCTRL_FRAC_CLR (0x000000f8)
+#define HW_CLKCTRL_FRAC_TOG (0x000000fc)
+
+#define BP_CLKCTRL_FRAC_CLKGATEIO 31
+#define BM_CLKCTRL_FRAC_CLKGATEIO 0x80000000
+#define BM_CLKCTRL_FRAC_IO_STABLE 0x40000000
+#define BP_CLKCTRL_FRAC_IOFRAC 24
+#define BM_CLKCTRL_FRAC_IOFRAC 0x3F000000
+#define BF_CLKCTRL_FRAC_IOFRAC(v) \
+ (((v) << 24) & BM_CLKCTRL_FRAC_IOFRAC)
+#define BP_CLKCTRL_FRAC_CLKGATEPIX 23
+#define BM_CLKCTRL_FRAC_CLKGATEPIX 0x00800000
+#define BM_CLKCTRL_FRAC_PIX_STABLE 0x00400000
+#define BP_CLKCTRL_FRAC_PIXFRAC 16
+#define BM_CLKCTRL_FRAC_PIXFRAC 0x003F0000
+#define BF_CLKCTRL_FRAC_PIXFRAC(v) \
+ (((v) << 16) & BM_CLKCTRL_FRAC_PIXFRAC)
+#define BP_CLKCTRL_FRAC_CLKGATEEMI 15
+#define BM_CLKCTRL_FRAC_CLKGATEEMI 0x00008000
+#define BM_CLKCTRL_FRAC_EMI_STABLE 0x00004000
+#define BP_CLKCTRL_FRAC_EMIFRAC 8
+#define BM_CLKCTRL_FRAC_EMIFRAC 0x00003F00
+#define BF_CLKCTRL_FRAC_EMIFRAC(v) \
+ (((v) << 8) & BM_CLKCTRL_FRAC_EMIFRAC)
+#define BP_CLKCTRL_FRAC_CLKGATECPU 7
+#define BM_CLKCTRL_FRAC_CLKGATECPU 0x00000080
+#define BM_CLKCTRL_FRAC_CPU_STABLE 0x00000040
+#define BP_CLKCTRL_FRAC_CPUFRAC 0
+#define BM_CLKCTRL_FRAC_CPUFRAC 0x0000003F
+#define BF_CLKCTRL_FRAC_CPUFRAC(v) \
+ (((v) << 0) & BM_CLKCTRL_FRAC_CPUFRAC)
+
+#define HW_CLKCTRL_FRAC1 (0x00000100)
+#define HW_CLKCTRL_FRAC1_SET (0x00000104)
+#define HW_CLKCTRL_FRAC1_CLR (0x00000108)
+#define HW_CLKCTRL_FRAC1_TOG (0x0000010c)
+
+#define BM_CLKCTRL_FRAC1_CLKGATEVID 0x80000000
+#define BM_CLKCTRL_FRAC1_VID_STABLE 0x40000000
+#define BP_CLKCTRL_FRAC1_RSRVD1 0
+#define BM_CLKCTRL_FRAC1_RSRVD1 0x3FFFFFFF
+#define BF_CLKCTRL_FRAC1_RSRVD1(v) \
+ (((v) << 0) & BM_CLKCTRL_FRAC1_RSRVD1)
+
+#define HW_CLKCTRL_CLKSEQ (0x00000110)
+#define HW_CLKCTRL_CLKSEQ_SET (0x00000114)
+#define HW_CLKCTRL_CLKSEQ_CLR (0x00000118)
+#define HW_CLKCTRL_CLKSEQ_TOG (0x0000011c)
+
+#define BP_CLKCTRL_CLKSEQ_RSRVD1 9
+#define BM_CLKCTRL_CLKSEQ_RSRVD1 0xFFFFFE00
+#define BF_CLKCTRL_CLKSEQ_RSRVD1(v) \
+ (((v) << 9) & BM_CLKCTRL_CLKSEQ_RSRVD1)
+#define BM_CLKCTRL_CLKSEQ_BYPASS_ETM 0x00000100
+#define BM_CLKCTRL_CLKSEQ_BYPASS_CPU 0x00000080
+#define BM_CLKCTRL_CLKSEQ_BYPASS_EMI 0x00000040
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP 0x00000020
+#define BM_CLKCTRL_CLKSEQ_BYPASS_GPMI 0x00000010
+#define BM_CLKCTRL_CLKSEQ_BYPASS_IR 0x00000008
+#define BM_CLKCTRL_CLKSEQ_RSRVD0 0x00000004
+#define BM_CLKCTRL_CLKSEQ_BYPASS_PIX 0x00000002
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF 0x00000001
+
+#define HW_CLKCTRL_RESET (0x00000120)
+
+#define BP_CLKCTRL_RESET_RSRVD 2
+#define BM_CLKCTRL_RESET_RSRVD 0xFFFFFFFC
+#define BF_CLKCTRL_RESET_RSRVD(v) \
+ (((v) << 2) & BM_CLKCTRL_RESET_RSRVD)
+#define BM_CLKCTRL_RESET_CHIP 0x00000002
+#define BM_CLKCTRL_RESET_DIG 0x00000001
+
+#define HW_CLKCTRL_STATUS (0x00000130)
+
+#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 (0x00000140)
+
+#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 /* __REGS_CLKCTRL_MX23_H__ */
diff --git a/arch/arm/mach-mxs/regs-clkctrl-mx28.h b/arch/arm/mach-mxs/regs-clkctrl-mx28.h
new file mode 100644
index 0000000..661df18
--- /dev/null
+++ b/arch/arm/mach-mxs/regs-clkctrl-mx28.h
@@ -0,0 +1,663 @@
+/*
+ * Freescale CLKCTRL Register Definitions
+ *
+ * Copyright 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., 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 __REGS_CLKCTRL_MX28_H__
+#define __REGS_CLKCTRL_MX28_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 /* __REGS_CLKCTRL_MX28_H__ */
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH v2 12/15] ARM: mxs: Dynamically allocate fec devices
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (28 preceding siblings ...)
2010-12-07 16:31 ` [PATCH v2 09/15] ARM: mxs: Add clock support Shawn Guo
@ 2010-12-07 16:32 ` Shawn Guo
2010-12-07 16:32 ` [PATCH v2 13/15] ARM: mxs: Add initial mx23evk support Shawn Guo
` (16 subsequent siblings)
46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-07 16:32 UTC (permalink / raw)
To: linux-arm-kernel
Dynamically allocate fec devices for MX28, which gets dual
fec interface.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
- Remove the use of mx28_add_fec0 and mx28_add_fec1
- Remove unnessary passing of data->iosize
arch/arm/mach-mxs/devices-mx28.h | 4 ++
arch/arm/mach-mxs/devices/platform-fec.c | 50 +++++++++++++++++++++++
arch/arm/mach-mxs/include/mach/devices-common.h | 12 +++++
3 files changed, 66 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/devices/platform-fec.c
diff --git a/arch/arm/mach-mxs/devices-mx28.h b/arch/arm/mach-mxs/devices-mx28.h
index 47c2f04..00b736c 100644
--- a/arch/arm/mach-mxs/devices-mx28.h
+++ b/arch/arm/mach-mxs/devices-mx28.h
@@ -14,3 +14,7 @@
extern const struct mxs_duart_data mx28_duart_data __initconst;
#define mx28_add_duart() \
mxs_add_duart(&mx28_duart_data)
+
+extern const struct mxs_fec_data mx28_fec_data[] __initconst;
+#define mx28_add_fec(id, pdata) \
+ mxs_add_fec(&mx28_fec_data[id], pdata)
diff --git a/arch/arm/mach-mxs/devices/platform-fec.c b/arch/arm/mach-mxs/devices/platform-fec.c
new file mode 100644
index 0000000..fb62f0c
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/platform-fec.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * 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 <asm/sizes.h>
+#include <mach/hardware.h>
+#include <mach/devices-common.h>
+
+#define mxs_fec_data_entry_single(soc, _id) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _ENET_MAC ## _id ## _BASE_ADDR, \
+ .irq = soc ## _INT_ENET_MAC ## _id, \
+ }
+
+#define mxs_fec_data_entry(soc, _id) \
+ [_id] = mxs_fec_data_entry_single(soc, _id)
+
+#ifdef CONFIG_SOC_IMX28
+const struct mxs_fec_data mx28_fec_data[] __initconst = {
+#define mx28_fec_data_entry(_id) \
+ mxs_fec_data_entry(MX28, _id)
+ mx28_fec_data_entry(0),
+ mx28_fec_data_entry(1),
+};
+#endif
+
+struct platform_device *__init mxs_add_fec(
+ const struct mxs_fec_data *data,
+ const struct fec_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return mxs_add_platform_device("fec", data->id,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h
index 07b4439..3da48d4 100644
--- a/arch/arm/mach-mxs/include/mach/devices-common.h
+++ b/arch/arm/mach-mxs/include/mach/devices-common.h
@@ -32,3 +32,15 @@ struct mxs_duart_data {
};
struct platform_device *__init mxs_add_duart(
const struct mxs_duart_data *data);
+
+/* fec */
+#include <linux/fec.h>
+struct mxs_fec_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init mxs_add_fec(
+ const struct mxs_fec_data *data,
+ const struct fec_platform_data *pdata);
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH v2 13/15] ARM: mxs: Add initial mx23evk support
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (29 preceding siblings ...)
2010-12-07 16:32 ` [PATCH v2 12/15] ARM: mxs: Dynamically allocate fec devices Shawn Guo
@ 2010-12-07 16:32 ` Shawn Guo
2010-12-07 16:32 ` [PATCH v2 14/15] ARM: mxs: Add initial mx28evk support Shawn Guo
` (15 subsequent siblings)
46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-07 16:32 UTC (permalink / raw)
To: linux-arm-kernel
Add initial mx23evk support with duart.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
- Remove boot_params
arch/arm/mach-mxs/mach-mx23evk.c | 58 ++++++++++++++++++++++++++++++++++++++
1 files changed, 58 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/mach-mx23evk.c
diff --git a/arch/arm/mach-mxs/mach-mx23evk.c b/arch/arm/mach-mxs/mach-mx23evk.c
new file mode 100644
index 0000000..2169937
--- /dev/null
+++ b/arch/arm/mach-mxs/mach-mx23evk.c
@@ -0,0 +1,58 @@
+/*
+ * 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-mx23.h>
+
+#include "devices-mx23.h"
+
+static iomux_cfg_t mx23evk_pads[] = {
+ /* duart */
+ MX23_PAD_PWM0__DUART_RX,
+ MX23_PAD_PWM1__DUART_TX,
+};
+
+static void __init mx23evk_init(void)
+{
+ mxs_iomux_setup_multiple_pads(mx23evk_pads, ARRAY_SIZE(mx23evk_pads));
+
+ mx23_add_duart();
+}
+
+static void __init mx23evk_timer_init(void)
+{
+ mx23_clocks_init();
+}
+
+static struct sys_timer mx23evk_timer = {
+ .init = mx23evk_timer_init,
+};
+
+MACHINE_START(MX23EVK, "Freescale MX23 EVK")
+ /* Maintainer: Freescale Semiconductor, Inc. */
+ .map_io = mx23_map_io,
+ .init_irq = mx23_init_irq,
+ .init_machine = mx23evk_init,
+ .timer = &mx23evk_timer,
+MACHINE_END
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH v2 14/15] ARM: mxs: Add initial mx28evk support
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (30 preceding siblings ...)
2010-12-07 16:32 ` [PATCH v2 13/15] ARM: mxs: Add initial mx23evk support Shawn Guo
@ 2010-12-07 16:32 ` Shawn Guo
2010-12-08 20:28 ` Uwe Kleine-König
2010-12-07 16:32 ` [PATCH v3 15/15] ARM: mxs: Add build configuration for mxs Shawn Guo
` (14 subsequent siblings)
46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-07 16:32 UTC (permalink / raw)
To: linux-arm-kernel
Add initial mx28evk support with duart and fec0.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
- Change function mx28evk_fec_reset() from inline to __init
- Enable pll2 clock before phy operation
- Add error checking for gpio_direction_output()
- Save bytes by passing parameter into pr_err format string
- Change mx28_add_fec0() to mx28_add_fec(0)
- Remove boot_params
arch/arm/mach-mxs/mach-mx28evk.c | 126 ++++++++++++++++++++++++++++++++++++++
1 files changed, 126 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/mach-mx28evk.c
diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
new file mode 100644
index 0000000..3e8e37a
--- /dev/null
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
@@ -0,0 +1,126 @@
+/*
+ * 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 <linux/clk.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-mx28.h"
+#include "gpio.h"
+
+#define MX28EVK_FEC_PHY_POWER MXS_GPIO_NR(2, 15)
+#define MX28EVK_FEC_PHY_RESET MXS_GPIO_NR(4, 13)
+
+static iomux_cfg_t mx28evk_pads[] = {
+ /* duart */
+ MX28_PAD_PWM0__DUART_RX,
+ MX28_PAD_PWM1__DUART_TX,
+
+ /* fec0 */
+ 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 void __init mx28evk_fec_reset(void)
+{
+ int ret;
+ struct clk *clk;
+
+ /* Enable fec phy clock */
+ clk = clk_get_sys("pll2", NULL);
+ if (!IS_ERR(clk))
+ clk_enable(clk);
+
+ /* Power up fec phy */
+ ret = gpio_request(MX28EVK_FEC_PHY_POWER, "fec-phy-power");
+ if (ret) {
+ pr_err("Failed to request gpio fec-phy-%s: %d\n", "power", ret);
+ return;
+ }
+
+ ret = gpio_direction_output(MX28EVK_FEC_PHY_POWER, 0);
+ if (ret) {
+ pr_err("Failed to drive gpio fec-phy-%s: %d\n", "power", ret);
+ return;
+ }
+
+ /* Reset fec phy */
+ ret = gpio_request(MX28EVK_FEC_PHY_RESET, "fec-phy-reset");
+ if (ret) {
+ pr_err("Failed to request gpio fec-phy-%s: %d\n", "reset", ret);
+ return;
+ }
+
+ gpio_direction_output(MX28EVK_FEC_PHY_RESET, 0);
+ if (ret) {
+ pr_err("Failed to drive gpio fec-phy-%s: %d\n", "reset", ret);
+ return;
+ }
+
+ mdelay(1);
+ gpio_set_value(MX28EVK_FEC_PHY_RESET, 1);
+}
+
+static const struct fec_platform_data mx28_fec_pdata __initconst = {
+ .phy = PHY_INTERFACE_MODE_RMII,
+};
+
+static void __init mx28evk_init(void)
+{
+ mxs_iomux_setup_multiple_pads(mx28evk_pads, ARRAY_SIZE(mx28evk_pads));
+
+ mx28_add_duart();
+
+ mx28evk_fec_reset();
+ mx28_add_fec(0, &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. */
+ .map_io = mx28_map_io,
+ .init_irq = mx28_init_irq,
+ .init_machine = mx28evk_init,
+ .timer = &mx28evk_timer,
+MACHINE_END
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH v3 15/15] ARM: mxs: Add build configuration for mxs
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (31 preceding siblings ...)
2010-12-07 16:32 ` [PATCH v2 14/15] ARM: mxs: Add initial mx28evk support Shawn Guo
@ 2010-12-07 16:32 ` Shawn Guo
2010-12-10 14:51 ` Uwe Kleine-König
2010-12-09 15:12 ` [PATCH v4 01/15] ARM: mxs: Add core definitions Shawn Guo
` (13 subsequent siblings)
46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-07 16:32 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
- Sort mach-mxs behind plat-mxc in arch/arm/Kconfig
- Remove meaningless comment from arch/arm/mach-mxs/Makefile
- Remove unused params_phys and initrd_phys from arch/arm/mach-mxs/Makefile.boot
Changes for v2:
- Remove cpu.o from arch/arm/mach-mxs/Makefile
arch/arm/Kconfig | 10 ++++++++++
arch/arm/Makefile | 1 +
arch/arm/mach-mxs/Kconfig | 34 ++++++++++++++++++++++++++++++++++
arch/arm/mach-mxs/Makefile | 10 ++++++++++
arch/arm/mach-mxs/Makefile.boot | 1 +
arch/arm/mach-mxs/devices/Kconfig | 5 +++++
arch/arm/mach-mxs/devices/Makefile | 2 ++
7 files changed, 63 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/Kconfig
create mode 100644 arch/arm/mach-mxs/Makefile
create mode 100644 arch/arm/mach-mxs/Makefile.boot
create mode 100644 arch/arm/mach-mxs/devices/Kconfig
create mode 100644 arch/arm/mach-mxs/devices/Makefile
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index db524e7..0403aa8 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -351,6 +351,14 @@ config ARCH_MXC
help
Support for Freescale MXC/iMX-based family of processors
+config ARCH_MXS
+ bool "Freescale MXS-based"
+ select GENERIC_CLOCKEVENTS
+ select ARCH_REQUIRE_GPIOLIB
+ select COMMON_CLKDEV
+ help
+ Support for Freescale MXS-based family of processors
+
config ARCH_STMP3XXX
bool "Freescale STMP3xxx"
select CPU_ARM926T
@@ -902,6 +910,8 @@ source "arch/arm/mach-mv78xx0/Kconfig"
source "arch/arm/plat-mxc/Kconfig"
+source "arch/arm/mach-mxs/Kconfig"
+
source "arch/arm/mach-netx/Kconfig"
source "arch/arm/mach-nomadik/Kconfig"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 057beb8..c22c1ad 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -158,6 +158,7 @@ machine-$(CONFIG_ARCH_MX25) := imx
machine-$(CONFIG_ARCH_MX3) := mx3
machine-$(CONFIG_ARCH_MX5) := mx5
machine-$(CONFIG_ARCH_MXC91231) := mxc91231
+machine-$(CONFIG_ARCH_MXS) := mxs
machine-$(CONFIG_ARCH_NETX) := netx
machine-$(CONFIG_ARCH_NOMADIK) := nomadik
machine-$(CONFIG_ARCH_NS9XXX) := ns9xxx
diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig
new file mode 100644
index 0000000..c4ac7b4
--- /dev/null
+++ b/arch/arm/mach-mxs/Kconfig
@@ -0,0 +1,34 @@
+if ARCH_MXS
+
+source "arch/arm/mach-mxs/devices/Kconfig"
+
+config SOC_IMX23
+ bool
+ select CPU_ARM926T
+
+config SOC_IMX28
+ bool
+ select CPU_ARM926T
+
+comment "MXS platforms:"
+
+config MACH_MX23EVK
+ bool "Support MX23EVK Platform"
+ select SOC_IMX23
+ select MXS_HAVE_PLATFORM_DUART
+ default y
+ help
+ Include support for MX23EVK platform. This includes specific
+ configurations for the board and its peripherals.
+
+config MACH_MX28EVK
+ bool "Support MX28EVK Platform"
+ select SOC_IMX28
+ select MXS_HAVE_PLATFORM_DUART
+ select MXS_HAVE_PLATFORM_FEC
+ default y
+ help
+ Include support for MX28EVK platform. This includes specific
+ configurations for the board and its peripherals.
+
+endif
diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
new file mode 100644
index 0000000..40b808c
--- /dev/null
+++ b/arch/arm/mach-mxs/Makefile
@@ -0,0 +1,10 @@
+# Common support
+obj-y := clock.o cpu.o devices.o gpio.o icoll.o iomux.o system.o timer.o
+
+obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
+obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
+
+obj-$(CONFIG_MACH_MX23EVK) += mach-mx23evk.o
+obj-$(CONFIG_MACH_MX28EVK) += mach-mx28evk.o
+
+obj-y += devices/
diff --git a/arch/arm/mach-mxs/Makefile.boot b/arch/arm/mach-mxs/Makefile.boot
new file mode 100644
index 0000000..eb541e0
--- /dev/null
+++ b/arch/arm/mach-mxs/Makefile.boot
@@ -0,0 +1 @@
+zreladdr-y := 0x40008000
diff --git a/arch/arm/mach-mxs/devices/Kconfig b/arch/arm/mach-mxs/devices/Kconfig
new file mode 100644
index 0000000..a35a2dc
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/Kconfig
@@ -0,0 +1,5 @@
+config MXS_HAVE_PLATFORM_DUART
+ bool
+
+config MXS_HAVE_PLATFORM_FEC
+ bool
diff --git a/arch/arm/mach-mxs/devices/Makefile b/arch/arm/mach-mxs/devices/Makefile
new file mode 100644
index 0000000..4b5266a
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/Makefile
@@ -0,0 +1,2 @@
+obj-$(CONFIG_MXS_HAVE_PLATFORM_DUART) += platform-duart.o
+obj-$(CONFIG_MXS_HAVE_PLATFORM_FEC) += platform-fec.o
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH v3 01/15] ARM: mxs: Add core definitions
2010-12-07 16:31 ` [PATCH v3 01/15] ARM: mxs: Add core definitions Shawn Guo
@ 2010-12-07 20:18 ` Uwe Kleine-König
2010-12-08 4:50 ` Shawn Guo
0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-07 20:18 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Dec 08, 2010 at 12:31:52AM +0800, Shawn Guo wrote:
> Add core definitions for MXS-based SoC MX23 and MX28.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v3:
> - Update MXS_IO_P2V definition and comment to get them matched
> - Sort mx23 base address definitions by offset
> - Remove mx28 reserved IRQ definitions
> - Remove unnecessary dummy definitions for cpu_is_mx23() and cpu_is_mx28()
>
> Changes for v2:
> - Remove MXS_IO_P2V_MODULE from hardware.h which is not needed
> - Simplify MXS_IO_P2V_MODULE definition in hardware.h
> - Remove unnecessary inclusion protection from hardware.h
> - Change cpu_is_mx23/mx28() implementation in mxs.h to use machine_is_xxx
>
> arch/arm/mach-mxs/include/mach/hardware.h | 55 +++++++++
> arch/arm/mach-mxs/include/mach/irqs.h | 32 +++++
> arch/arm/mach-mxs/include/mach/memory.h | 24 ++++
> arch/arm/mach-mxs/include/mach/mx23.h | 147 ++++++++++++++++++++++
> arch/arm/mach-mxs/include/mach/mx28.h | 190 +++++++++++++++++++++++++++++
> arch/arm/mach-mxs/include/mach/mxs.h | 34 +++++
> 6 files changed, 482 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-mxs/include/mach/hardware.h
> create mode 100644 arch/arm/mach-mxs/include/mach/irqs.h
> create mode 100644 arch/arm/mach-mxs/include/mach/memory.h
> create mode 100644 arch/arm/mach-mxs/include/mach/mx23.h
> create mode 100644 arch/arm/mach-mxs/include/mach/mx28.h
> create mode 100644 arch/arm/mach-mxs/include/mach/mxs.h
>
> diff --git a/arch/arm/mach-mxs/include/mach/hardware.h b/arch/arm/mach-mxs/include/mach/hardware.h
> new file mode 100644
> index 0000000..d73f149
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/hardware.h
> @@ -0,0 +1,55 @@
> +/*
> + * Copyright 2004-2007 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
> + * 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_MXS_HARDWARE_H__
> +#define __MACH_MXS_HARDWARE_H__
> +
> +#include <asm/sizes.h>
> +
> +#ifdef __ASSEMBLER__
> +#define IOMEM(addr) (addr)
> +#else
> +#define IOMEM(addr) ((void __force __iomem *)(addr))
> +#endif
> +
> +/*
> + * It maps the whole address space to [0xf4000000, 0xf5ffffff].
The maximal address that can occur is 0xf50fffff
> + *
> + * OCRAM 0x00000000+0x020000 -> 0xf4000000+0x020000
> + * IO 0x80000000+0x100000 -> 0xf5000000+0x100000
> + */
> +#define MXS_IO_P2V(x) (0xf4000000 + \
> + (((x) & 0x80000000) >> 7) + \
> + (((x) & 0x000fffff)))
> +
> +
> +#define MXS_IO_ADDRESS(x) IOMEM(MXS_IO_P2V(x))
> +
> +#include <mach/mx23.h>
> +#include <mach/mx28.h>
> +#include <mach/mxs.h>
> +
> +#define mxs_map_entry(soc, name, _type) { \
> + .virtual = soc ## _IO_P2V(soc ## _ ## name ## _BASE_ADDR), \
> + .pfn = __phys_to_pfn(soc ## _ ## name ## _BASE_ADDR), \
> + .length = soc ## _ ## name ## _SIZE, \
> + .type = _type, \
> +}
> +
> +#endif /* __MACH_MXS_HARDWARE_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/irqs.h b/arch/arm/mach-mxs/include/mach/irqs.h
> new file mode 100644
> index 0000000..f771039
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/irqs.h
> @@ -0,0 +1,32 @@
> +/*
> + * Copyright 2004-2007 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.
> + */
> +
> +#ifndef __MACH_MXS_IRQS_H__
> +#define __MACH_MXS_IRQS_H__
> +
> +#define MXS_INTERNAL_IRQS 128
> +
> +#define MXS_GPIO_IRQ_START MXS_INTERNAL_IRQS
> +
> +/* the maximum for MXS-based */
> +#define MXS_GPIO_IRQS (32 * 5)
> +
> +/*
> + * The next 16 interrupts are for board specific purposes. Since
> + * the kernel can only run on one machine at a time, we can re-use
> + * these. If you need more, increase MXS_BOARD_IRQS, but keep it
> + * within sensible limits.
> + */
> +#define MXS_BOARD_IRQ_START (MXS_GPIO_IRQ_START + MXS_GPIO_IRQS)
> +#define MXS_BOARD_IRQS 16
> +
> +#define NR_IRQS (MXS_BOARD_IRQ_START + MXS_BOARD_IRQS)
> +
> +#endif /* __MACH_MXS_IRQS_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/memory.h b/arch/arm/mach-mxs/include/mach/memory.h
> new file mode 100644
> index 0000000..b5420a5
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/memory.h
> @@ -0,0 +1,24 @@
> +/*
> + * 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_MXS_MEMORY_H__
> +#define __MACH_MXS_MEMORY_H__
> +
> +#define PHYS_OFFSET UL(0x40000000)
> +
> +#endif /* __MACH_MXS_MEMORY_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/mx23.h b/arch/arm/mach-mxs/include/mach/mx23.h
> new file mode 100644
> index 0000000..2033ed4
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/mx23.h
> @@ -0,0 +1,147 @@
> +/*
> + * 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_MX23_H__
> +#define __MACH_MX23_H__
> +
> +#ifndef __ASSEMBLER__
> +#include <linux/io.h>
> +#endif
You don't need this, do you?
#inclusion of hardware.h would be OK, then you could remove the
#includes of mx23.h and mx28.h in there.
(Believe me, this is better, mxc already made me headaches because of
that.)
> +/*
> + * OCRAM
> + */
> +#define MX23_OCRAM_BASE_ADDR 0x00000000
> +#define MX23_OCRAM_SIZE SZ_32K
> +
> +/*
> + * IO
> + */
> +#define MX23_IO_BASE_ADDR 0x80000000
> +#define MX23_IO_SIZE SZ_1M
> +
> +#define MX23_ICOLL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x000000)
> +#define MX23_APBH_DMA_BASE_ADDR (MX23_IO_BASE_ADDR + 0x004000)
> +#define MX23_BCH_BASE_ADDR (MX23_IO_BASE_ADDR + 0x00a000)
> +#define MX23_GPMI_BASE_ADDR (MX23_IO_BASE_ADDR + 0x00c000)
> +#define MX23_SSP1_BASE_ADDR (MX23_IO_BASE_ADDR + 0x010000)
> +#define MX23_PINCTRL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x018000)
> +#define MX23_DIGCTL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x01c000)
> +#define MX23_ETM_BASE_ADDR (MX23_IO_BASE_ADDR + 0x020000)
> +#define MX23_APBX_DMA_BASE_ADDR (MX23_IO_BASE_ADDR + 0x024000)
> +#define MX23_DCP_BASE_ADDR (MX23_IO_BASE_ADDR + 0x028000)
> +#define MX23_PXP_BASE_ADDR (MX23_IO_BASE_ADDR + 0x02a000)
> +#define MX23_OCOTP_BASE_ADDR (MX23_IO_BASE_ADDR + 0x02c000)
> +#define MX23_AXI_AHB0_BASE_ADDR (MX23_IO_BASE_ADDR + 0x02e000)
> +#define MX23_LCDIF_BASE_ADDR (MX23_IO_BASE_ADDR + 0x030000)
> +#define MX23_SSP2_BASE_ADDR (MX23_IO_BASE_ADDR + 0x034000)
> +#define MX23_TVENC_BASE_ADDR (MX23_IO_BASE_ADDR + 0x038000)
> +#define MX23_CLKCTRL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x040000)
> +#define MX23_SAIF0_BASE_ADDR (MX23_IO_BASE_ADDR + 0x042000)
> +#define MX23_POWER_BASE_ADDR (MX23_IO_BASE_ADDR + 0x044000)
> +#define MX23_SAIF1_BASE_ADDR (MX23_IO_BASE_ADDR + 0x046000)
> +#define MX23_AUDIOOUT_BASE_ADDR (MX23_IO_BASE_ADDR + 0x048000)
> +#define MX23_AUDIOIN_BASE_ADDR (MX23_IO_BASE_ADDR + 0x04c000)
> +#define MX23_LRADC_BASE_ADDR (MX23_IO_BASE_ADDR + 0x050000)
> +#define MX23_SPDIF_BASE_ADDR (MX23_IO_BASE_ADDR + 0x054000)
> +#define MX23_I2C0_BASE_ADDR (MX23_IO_BASE_ADDR + 0x058000)
> +#define MX23_RTC_BASE_ADDR (MX23_IO_BASE_ADDR + 0x05c000)
> +#define MX23_PWM_BASE_ADDR (MX23_IO_BASE_ADDR + 0x064000)
> +#define MX23_TIMROT_BASE_ADDR (MX23_IO_BASE_ADDR + 0x068000)
> +#define MX23_AUART1_BASE_ADDR (MX23_IO_BASE_ADDR + 0x06c000)
> +#define MX23_AUART2_BASE_ADDR (MX23_IO_BASE_ADDR + 0x06e000)
> +#define MX23_DUART_BASE_ADDR (MX23_IO_BASE_ADDR + 0x070000)
> +#define MX23_USBPHY_BASE_ADDR (MX23_IO_BASE_ADDR + 0x07c000)
> +#define MX23_USBCTRL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x080000)
> +#define MX23_DRAM_BASE_ADDR (MX23_IO_BASE_ADDR + 0x0e0000)
> +
> +#define MX23_IO_P2V(x) MXS_IO_P2V(x)
> +#define MX23_IO_ADDRESS(x) IOMEM(MX23_IO_P2V(x))
> +
> +/*
> + * IRQ
> + */
> +#define MX23_INT_DUART 0
> +#define MX23_INT_COMMS_RX 1
> +#define MX23_INT_COMMS_TX 1
> +#define MX23_INT_SSP2_ERROR 2
> +#define MX23_INT_VDD5V 3
> +#define MX23_INT_HEADPHONE_SHORT 4
> +#define MX23_INT_DAC_DMA 5
> +#define MX23_INT_DAC_ERROR 6
> +#define MX23_INT_ADC_DMA 7
> +#define MX23_INT_ADC_ERROR 8
> +#define MX23_INT_SPDIF_DMA 9
> +#define MX23_INT_SAIF2_DMA 9
> +#define MX23_INT_SPDIF_ERROR 10
> +#define MX23_INT_SAIF1_IRQ 10
> +#define MX23_INT_SAIF2_IRQ 10
> +#define MX23_INT_USB_CTRL 11
> +#define MX23_INT_USB_WAKEUP 12
> +#define MX23_INT_GPMI_DMA 13
> +#define MX23_INT_SSP1_DMA 14
> +#define MX23_INT_SSP_ERROR 15
> +#define MX23_INT_GPIO0 16
> +#define MX23_INT_GPIO1 17
> +#define MX23_INT_GPIO2 18
> +#define MX23_INT_SAIF1_DMA 19
> +#define MX23_INT_SSP2_DMA 20
> +#define MX23_INT_ECC8_IRQ 21
> +#define MX23_INT_RTC_ALARM 22
> +#define MX23_INT_UARTAPP_TX_DMA 23
> +#define MX23_INT_UARTAPP_INTERNAL 24
> +#define MX23_INT_UARTAPP_RX_DMA 25
> +#define MX23_INT_I2C_DMA 26
> +#define MX23_INT_I2C_ERROR 27
> +#define MX23_INT_TIMER0 28
> +#define MX23_INT_TIMER1 29
> +#define MX23_INT_TIMER2 30
> +#define MX23_INT_TIMER3 31
> +#define MX23_INT_BATT_BRNOUT 32
> +#define MX23_INT_VDDD_BRNOUT 33
> +#define MX23_INT_VDDIO_BRNOUT 34
> +#define MX23_INT_VDD18_BRNOUT 35
> +#define MX23_INT_TOUCH_DETECT 36
> +#define MX23_INT_LRADC_CH0 37
> +#define MX23_INT_LRADC_CH1 38
> +#define MX23_INT_LRADC_CH2 39
> +#define MX23_INT_LRADC_CH3 40
> +#define MX23_INT_LRADC_CH4 41
> +#define MX23_INT_LRADC_CH5 42
> +#define MX23_INT_LRADC_CH6 43
> +#define MX23_INT_LRADC_CH7 44
> +#define MX23_INT_LCDIF_DMA 45
> +#define MX23_INT_LCDIF_ERROR 46
> +#define MX23_INT_DIGCTL_DEBUG_TRAP 47
> +#define MX23_INT_RTC_1MSEC 48
> +#define MX23_INT_DRI_DMA 49
> +#define MX23_INT_DRI_ATTENTION 50
> +#define MX23_INT_GPMI_ATTENTION 51
> +#define MX23_INT_IR 52
> +#define MX23_INT_DCP_VMI 53
> +#define MX23_INT_DCP 54
> +#define MX23_INT_BCH 56
> +#define MX23_INT_PXP 57
> +#define MX23_INT_UARTAPP2_TX_DMA 58
> +#define MX23_INT_UARTAPP2_INTERNAL 59
> +#define MX23_INT_UARTAPP2_RX_DMA 60
> +#define MX23_INT_VDAC_DETECT 61
> +#define MX23_INT_VDD5V_DROOP 64
> +#define MX23_INT_DCDC4P2_BO 65
> +
> +#endif /* __MACH_MX23_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/mx28.h b/arch/arm/mach-mxs/include/mach/mx28.h
> new file mode 100644
> index 0000000..be1c2a4
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/mx28.h
> @@ -0,0 +1,190 @@
> +/*
> + * 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
ditto
> +
> +/*
> + * 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_MAC0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0f0000)
> +#define MX28_ENET_MAC1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0f4000)
> +
> +#define MX28_IO_P2V(x) MXS_IO_P2V(x)
> +#define MX28_IO_ADDRESS(x) IOMEM(MX28_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_CAN0 8
> +#define MX28_INT_CAN1 9
> +#define MX28_INT_LRADC_TOUCH 10
> +#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_PERFMON 27
> +#define MX28_INT_RTC_1MSEC 28
> +#define MX28_INT_RTC_ALARM 29
> +#define MX28_INT_COMMS 31
> +#define MX28_INT_EMI_ERR 32
> +#define MX28_INT_LCDIF 38
> +#define MX28_INT_PXP 39
> +#define MX28_INT_BCH 41
> +#define MX28_INT_GPMI 42
> +#define MX28_INT_SPDIF_ERROR 45
> +#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_SAIF1 58
> +#define MX28_INT_SAIF0 59
> +#define MX28_INT_SPDIF_DMA 66
> +#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_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_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_GPIO4 123
> +#define MX28_INT_GPIO3 124
> +#define MX28_INT_GPIO2 125
> +#define MX28_INT_GPIO1 126
> +#define MX28_INT_GPIO0 127
> +
> +#endif /* __MACH_MX28_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/mxs.h b/arch/arm/mach-mxs/include/mach/mxs.h
> new file mode 100644
> index 0000000..13e06ae
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/mxs.h
> @@ -0,0 +1,34 @@
> +/*
> + * 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_MXS_H__
> +#define __MACH_MXS_H__
> +
> +#include <asm/mach-types.h>
> +
> +#define MXS_SET_ADDR 0x4
> +#define MXS_CLR_ADDR 0x8
> +#define MXS_TOG_ADDR 0xc
> +
> +/*
> + * MXS CPU types
> + */
> +# define cpu_is_mx23() (machine_is_mx23evk())
> +# define cpu_is_mx28() (machine_is_mx28evk())
> +
> +#endif /* __MACH_MXS_H__ */
> --
> 1.7.1
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v3 03/15] ARM: mxs: Add reset routines
2010-12-07 16:31 ` [PATCH v3 03/15] ARM: mxs: Add reset routines Shawn Guo
@ 2010-12-07 20:27 ` Uwe Kleine-König
2010-12-08 7:33 ` Lothar Waßmann
1 sibling, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-07 20:27 UTC (permalink / raw)
To: linux-arm-kernel
Hello Shawn,
On Wed, Dec 08, 2010 at 12:31:53AM +0800, Shawn Guo wrote:
> - The mxs wdog is implemented in RTC block.
> - There is a generic software reset routine for most modules on mxs.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v3:
> - Change wdog timeout to 10ms for safety
> - Simplify function mxs_reset_block() to get it look better
>
> Changes for v2:
> - Move rtc clock enabling from arch_reset() into mxs_arch_reset_init()
>
> arch/arm/mach-mxs/include/mach/system.h | 27 ++++++
> arch/arm/mach-mxs/system.c | 134 +++++++++++++++++++++++++++++++
> 2 files changed, 161 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-mxs/include/mach/system.h
> create mode 100644 arch/arm/mach-mxs/system.c
>
> diff --git a/arch/arm/mach-mxs/include/mach/system.h b/arch/arm/mach-mxs/include/mach/system.h
> new file mode 100644
> index 0000000..0e42823
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/system.h
> @@ -0,0 +1,27 @@
> +/*
> + * Copyright (C) 1999 ARM Limited
> + * Copyright (C) 2000 Deep Blue Solutions Ltd
> + * Copyright 2004-2008 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.
> + */
> +
> +#ifndef __MACH_MXS_SYSTEM_H__
> +#define __MACH_MXS_SYSTEM_H__
> +
> +static inline void arch_idle(void)
> +{
> + cpu_do_idle();
> +}
> +
> +void arch_reset(char mode, const char *cmd);
> +
> +#endif /* __MACH_MXS_SYSTEM_H__ */
> diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c
> new file mode 100644
> index 0000000..58cb044
> --- /dev/null
> +++ b/arch/arm/mach-mxs/system.c
> @@ -0,0 +1,134 @@
> +/*
> + * Copyright (C) 1999 ARM Limited
> + * Copyright (C) 2000 Deep Blue Solutions Ltd
> + * Copyright 2006-2007,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
> + *
> + * 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/kernel.h>
> +#include <linux/clk.h>
> +#include <linux/io.h>
> +#include <linux/err.h>
> +#include <linux/delay.h>
> +
> +#include <asm/proc-fns.h>
> +#include <asm/system.h>
> +
> +#include <mach/hardware.h>
> +#include <mach/common.h>
> +
> +#define MXS_RTC_WATCHDOG 0x50
> +#define MXS_WATCHDOG_EN (1 << 4)
> +
> +#define MXS_MODULE_CLKGATE (1 << 30)
> +#define MXS_MODULE_SFTRST (1 << 31)
> +
> +static void __iomem *wdog_base;
> +
> +/*
> + * Reset the system. It is called by machine_restart().
> + */
> +void arch_reset(char mode, const char *cmd)
> +{
> + /* Set wdog timer 10 ms */
> + __raw_writel(10, wdog_base + MXS_RTC_WATCHDOG);
> +
> + /* Enable wdog reset */
> + __raw_writel(MXS_WATCHDOG_EN, wdog_base + MXS_SET_ADDR);
> +
> + /* Wait for reset to assert... */
> + mdelay(10);
> +
> + pr_err("Watchdog reset failed to assert reset\n");
> +
> + /* Delay to allow the serial port to show the message */
> + mdelay(50);
> +
> + /* We'll take a jump through zero as a poor second */
> + cpu_reset(0);
> +}
> +
> +void mxs_arch_reset_init(void __iomem *base)
> +{
> + struct clk *clk;
> +
> + wdog_base = base;
> +
> + clk = clk_get_sys("rtc", NULL);
> + if (!IS_ERR(clk))
> + clk_enable(clk);
> +}
> +
> +/*
> + * Clear the bit and poll it cleared. This is usually called with
> + * a reset address and mask being either SFTRST(bit 31) or CLKGATE
> + * (bit 30).
> + */
> +static int clear_poll_bit(void __iomem *addr, u32 mask)
> +{
> + int timeout = 0x400;
> +
> + /* clear the bit */
> + __raw_writel(mask, addr + MXS_CLR_ADDR);
> +
> + /*
> + * SFTRST needs 3 GPMI clocks to settle, the reference manual
> + * recommends to wait 1us.
> + */
> + udelay(1);
> +
> + /* poll the bit becoming clear */
> + while ((__raw_readl(addr) & mask) && --timeout)
> + /* nothing */;
> +
> + return !timeout;
> +}
> +
> +int mxs_reset_block(void __iomem *reset_addr)
> +{
> + int ret;
> + int timeout = 0x400;
> +
> + /* clear and poll SFTRST */
> + ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
> + if (ret)
unlikely(ret)?
> + goto error;
> +
> + /* clear CLKGATE */
> + __raw_writel(MXS_MODULE_CLKGATE, reset_addr + MXS_CLR_ADDR);
> + /* set SFTRST to reset the block */
> + __raw_writel(MXS_MODULE_SFTRST, reset_addr + MXS_SET_ADDR);
> + udelay(1);
> + /* poll CLKGATE becoming set */
Can you add empty lines above the comments, please. This makes it much
easier to read.
> + while ((!(__raw_readl(reset_addr) & MXS_MODULE_CLKGATE)) && --timeout)
> + /* nothing */;
> + if (unlikely(!timeout))
> + goto error;
> +
> + /* clear and poll SFTRST */
> + ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
> + if (ret)
> + goto error;
> +
> + /* clear and poll CLKGATE */
> + ret = clear_poll_bit(reset_addr, MXS_MODULE_CLKGATE);
> + if (ret)
> + goto error;
> +
> + return 0;
> +
> +error:
> + pr_err("%s(%p): module reset timeout\n", __func__, reset_addr);
> + return -ETIMEDOUT;
> +}
> --
> 1.7.1
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 04/15] ARM: mxs: Add interrupt support
2010-12-07 16:31 ` [PATCH v2 04/15] ARM: mxs: Add interrupt support Shawn Guo
@ 2010-12-07 21:03 ` Uwe Kleine-König
2010-12-08 8:27 ` Shawn Guo
2010-12-08 8:56 ` Shawn Guo
2010-12-08 8:24 ` Lothar Waßmann
1 sibling, 2 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-07 21:03 UTC (permalink / raw)
To: linux-arm-kernel
Hello Shawn,
On Wed, Dec 08, 2010 at 12:31:54AM +0800, Shawn Guo wrote:
> Add Interrupt Collector (ICOLL) support for MXS-based.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v2:
> - Get icoll base in get_irqnr_preamble
> - Check the case of single SoC build and use hard-coding address if possible
>
> arch/arm/mach-mxs/icoll.c | 77 ++++++++++++++++++++++++++
> arch/arm/mach-mxs/include/mach/entry-macro.S | 44 +++++++++++++++
> 2 files changed, 121 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-mxs/icoll.c
> create mode 100644 arch/arm/mach-mxs/include/mach/entry-macro.S
>
> diff --git a/arch/arm/mach-mxs/icoll.c b/arch/arm/mach-mxs/icoll.c
> new file mode 100644
> index 0000000..a7a7d4f
> --- /dev/null
> +++ b/arch/arm/mach-mxs/icoll.c
> @@ -0,0 +1,77 @@
> +/*
> + * 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);
You need to write this before handling the irq, no? Note this question
is a repetition. You answered "No need, indeed. Will remove it."
According to MCIMX28RM a write to HW_ICOLL_VECTOR "indicates the
in-service state". Are you sure this is not needed? If no (i.e. it's
needed) the write should go into entry-macro.S. As I don't have
hardware yet I cannot test that. Maybe it's only needed when the
priority levels are used?!
> +
> + /* ACK current interrupt (level 0) */
I suggest to extend this a bit, like:
The Interrupt Collector is able to prioritize irqs. Currently
only level 0 is used. So acking can use
BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 unconditionally.
> + __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 mxs_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;
> +
> + /* Reset icoll */
> + mxs_reset_block(irqbase + HW_ICOLL_CTRL);
I assume this initializes the priority for each irq to level 0. Maybe
this should be documented here.
> +
> + for (i = 0; i < MXS_INTERNAL_IRQS; i++) {
> + set_irq_chip(i, &mxs_icoll_chip);
> + set_irq_handler(i, handle_level_irq);
> + set_irq_flags(i, IRQF_VALID);
> + }
> +}
> diff --git a/arch/arm/mach-mxs/include/mach/entry-macro.S b/arch/arm/mach-mxs/include/mach/entry-macro.S
> new file mode 100644
> index 0000000..2c7755b
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/entry-macro.S
> @@ -0,0 +1,44 @@
> +/*
> + * Low-level IRQ helper macros for Freescale MXS-based
> + *
> + * 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 <mach/hardware.h>
> +
> + .macro disable_fiq
> + .endm
I think is isn't needed. Only when you start to actually use the fiq.
> + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
> + ldr \irqnr, [\base, #0x70]
> + cmp \irqnr, #0x7F
> + moveqs \irqnr, #0
> + .endm
> +
> + .macro get_irqnr_preamble, base, tmp
> +#if defined (CONFIG_SOC_IMX23) && defined (CONFIG_SOC_IMX28)
no space between defined and ( please.
> + ldr \base, =icoll_base
> + ldr \base, [\base]
> +#elif defined (CONFIG_SOC_IMX23)
> + ldr \base, =MX23_ICOLL_BASE_ADDR
> +#else
> + ldr \base, =MX28_ICOLL_BASE_ADDR
> +#endif
Mhh, you said the base addresses are different. Unless I'm mistaken
they are not. So you can just remove icoll_base.
> + .endm
> +
> + .macro arch_ret_to_user, tmp1, tmp2
> + .endm
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v3 06/15] ARM: mxs: Add timer support
2010-12-07 16:31 ` [PATCH v3 06/15] ARM: mxs: Add timer support Shawn Guo
@ 2010-12-07 21:18 ` Uwe Kleine-König
2010-12-08 5:58 ` Shawn Guo
2010-12-08 8:30 ` Lothar Waßmann
1 sibling, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-07 21:18 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Dec 08, 2010 at 12:31:56AM +0800, Shawn Guo wrote:
> Freescale MXS-based SoCs implement timer support in block TIMROT.
> There are two versions of TIMROT. The v1 on MX23 only gets 16 bits
> counter and has no match function. The v2 on MX28 extends the
> counter to 32 bits and add the match function.
>
> As the result, we need two instances of timers with v1 for better
> implementation, one for clock_event and another for clocksource.
> Otherwise, get_cycles may get imprecise result after long time
> cumulating. With v2, one instance can serve two purposes well.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v3:
> - Use term clock_event over next_event and clocksource over get_cycles
> - Split BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL into two definitions for v1 and v2 respectively
> - Turn timrot_get_cycles() into timrotv1_get_cycles() and timrotv2_get_cycles()
> - Turn timrot_set_next_event() into timrotv1_set_next_event() and timrotv2_set_next_event()
> - Skip flag IRQF_DISABLED
> - Remove unncessary IRQ disabling in mxs_set_mode()
> - Change shift of clocksource_mxs to 17
>
> Changes for v2:
> - Fix a bug in timrot_set_next_event(). It should read
> HW_TIMROT_RUNNING_COUNTn to get the current counts.
>
> arch/arm/mach-mxs/timer.c | 276 +++++++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 276 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-mxs/timer.c
>
> diff --git a/arch/arm/mach-mxs/timer.c b/arch/arm/mach-mxs/timer.c
> new file mode 100644
> index 0000000..b0e7ffe
> --- /dev/null
> +++ b/arch/arm/mach-mxs/timer.c
> @@ -0,0 +1,276 @@
> +/*
> + * Copyright (C) 2000-2001 Deep Blue Solutions
> + * 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
> + * 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/interrupt.h>
> +#include <linux/irq.h>
> +#include <linux/clockchips.h>
> +#include <linux/clk.h>
> +
> +#include <mach/hardware.h>
> +#include <asm/mach/time.h>
> +#include <mach/common.h>
> +
> +/*
> + * There are 2 versions of the timrot on Freescale MXS-based SoCs.
> + * The v1 on MX23 only gets 16 bits counter and has no match function.
> + * The v2 on MX28 extends the counter to 32 bits and add the match function.
> + *
> + * As the result, we need two instances of timers with v1 for better
> + * implementation, one for clock_event and another for clocksource. Otherwise,
> + * get_cycles may get imprecise result after long time cumulating.
> + * With v2, one instance can serve two purposes well.
> + */
> +#define timrot_is_v1() (cpu_is_mx23())
> +
> +#define HW_TIMROT_ROTCTRL 0x00
> +#define HW_TIMROT_TIMCTRLn(n) (0x20 + (n) * 0x40)
> +#define HW_TIMROT_RUNNING_COUNTn(n) (0x30 + (n) * 0x40)
> +#define HW_TIMROT_MATCH_COUNTn(n) (0x50 + (n) * 0x40)
> +#define BM_TIMROT_TIMCTRLn_RELOAD (1 << 6)
> +#define BM_TIMROT_TIMCTRLn_UPDATE (1 << 7)
> +#define BM_TIMROT_TIMCTRLn_MATCH_MODE (1 << 11)
> +#define BM_TIMROT_TIMCTRLn_IRQ_EN (1 << 14)
> +#define BM_TIMROT_TIMCTRLn_IRQ (1 << 15)
> +#define BP_TIMROT_TIMCTRLn_SELECT 0
> +#define BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL 0x8
> +#define BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL 0xb
> +
> +static struct clock_event_device clockevent_mxs;
> +static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
> +
> +static void __iomem *timer_base;
> +
> +static inline void timrot_irq_disable(void)
> +{
> + __raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN,
> + timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_CLR_ADDR);
> +}
> +
> +static inline void timrot_irq_enable(void)
> +{
> + __raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN,
> + timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_SET_ADDR);
> +}
> +
> +static void timrot_irq_acknowledge(void)
> +{
> + __raw_writel(BM_TIMROT_TIMCTRLn_IRQ,
> + timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_CLR_ADDR);
> +}
> +
> +static cycle_t timrotv1_get_cycles(struct clocksource *cs)
> +{
> + return ~((__raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(1))
> + & 0xffff0000) >> 16);
> +}
> +
> +static cycle_t timrotv2_get_cycles(struct clocksource *cs)
> +{
> + return ~__raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(0));
> +}
> +
> +static int timrotv1_set_next_event(unsigned long evt,
> + struct clock_event_device *dev)
> +{
> + /* timrot decrements the count */
> + __raw_writel(evt, timer_base + HW_TIMROT_RUNNING_COUNTn(0));
> +
> + return 0;
> +}
> +
> +static int timrotv2_set_next_event(unsigned long evt,
> + struct clock_event_device *dev)
> +{
> + unsigned long match;
> +
> + /* timrot decrements the count */
> + match = __raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(0))
> + - evt;
> + __raw_writel(match, timer_base + HW_TIMROT_MATCH_COUNTn(0));
> +
> + return (int)(match - __raw_readl(timer_base +
> + HW_TIMROT_RUNNING_COUNTn(0))) > 0 ? -ETIME : 0;
Wouldn't it be easier to use the same approach as in timrotv1? (i.e.
use two timers and then having a simpler set_next_event.)
> +}
> +
> +static irqreturn_t mxs_timer_interrupt(int irq, void *dev_id)
> +{
> + struct clock_event_device *evt = &clockevent_mxs;
I assume dev_id is &clockevent_mxs
> +
> + timrot_irq_acknowledge();
> + evt->event_handler(evt);
> +
> + return IRQ_HANDLED;
> +}
> +
> +static struct irqaction mxs_timer_irq = {
> + .name = "MXS Timer Tick",
> + .flags = IRQF_TIMER | IRQF_IRQPOLL,
> + .handler = mxs_timer_interrupt,
> +};
> +
> +#ifdef DEBUG
> +static const char *clock_event_mode_label[] = {
> + [CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
> + [CLOCK_EVT_MODE_ONESHOT] = "CLOCK_EVT_MODE_ONESHOT",
> + [CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN",
> + [CLOCK_EVT_MODE_UNUSED] = "CLOCK_EVT_MODE_UNUSED"
> +};
> +#endif /* DEBUG */
> +
> +static void mxs_set_mode(enum clock_event_mode mode,
> + struct clock_event_device *evt)
> +{
> + /* Disable interrupt in timer module */
> + timrot_irq_disable();
> +
> + if (mode != clockevent_mode) {
> + /* Set event time into far-far future */
> + __raw_writel(__raw_readl(timer_base +
> + HW_TIMROT_RUNNING_COUNTn(0)) + 3,
> + timer_base + HW_TIMROT_MATCH_COUNTn(0));
> +
> + /* Clear pending interrupt */
> + timrot_irq_acknowledge();
> + }
> +
> +#ifdef DEBUG
> + printk(KERN_INFO "mxs_set_mode: changing mode from %s to %s\n",
> + clock_event_mode_label[clockevent_mode],
> + clock_event_mode_label[mode]);
> +#endif /* DEBUG */
> +
> + /* Remember timer mode */
> + clockevent_mode = mode;
> +
> + switch (mode) {
> + case CLOCK_EVT_MODE_PERIODIC:
> + printk(KERN_ERR "mxs_set_mode: Periodic mode is not "
> + "supported for MXS-based\n");
It's more that it's not implemented. (At least it could be provided
when a dedicated timer is used for clock_event.)
> + break;
> + case CLOCK_EVT_MODE_ONESHOT:
> + timrot_irq_enable();
> + break;
> + case CLOCK_EVT_MODE_SHUTDOWN:
> + case CLOCK_EVT_MODE_UNUSED:
> + case CLOCK_EVT_MODE_RESUME:
> + /* Left event sources disabled, no more interrupts appear */
> + break;
> + }
> +}
> +
> +static struct clock_event_device clockevent_mxs = {
> + .name = "mxs_timrot",
> + .features = CLOCK_EVT_FEAT_ONESHOT,
> + .shift = 32,
> + .set_mode = mxs_set_mode,
> + .set_next_event = timrotv2_set_next_event,
> + .rating = 200,
> +};
> +
> +static int __init mxs_clockevent_init(struct clk *timer_clk)
> +{
> + unsigned int c = clk_get_rate(timer_clk);
> +
> + clockevent_mxs.mult = div_sc(c, NSEC_PER_SEC, clockevent_mxs.shift);
> + clockevent_mxs.cpumask = cpumask_of(0);
> + if (timrot_is_v1()) {
> + clockevent_mxs.set_next_event = timrotv1_set_next_event;
> + clockevent_mxs.max_delta_ns =
> + clockevent_delta2ns(0xfffe, &clockevent_mxs);
> + clockevent_mxs.min_delta_ns =
> + clockevent_delta2ns(0xf, &clockevent_mxs);
> + } else {
> + clockevent_mxs.max_delta_ns =
> + clockevent_delta2ns(0xfffffffe, &clockevent_mxs);
> + clockevent_mxs.min_delta_ns =
> + clockevent_delta2ns(0xff, &clockevent_mxs);
Why is timrotv1's min_delta smaller than v2's?
> + }
> +
> + clockevents_register_device(&clockevent_mxs);
> +
> + return 0;
> +}
> +
> +static struct clocksource clocksource_mxs = {
> + .name = "mxs_timer",
> + .rating = 200,
> + .read = timrotv2_get_cycles,
> + .mask = CLOCKSOURCE_MASK(32),
> + .shift = 17,
> + .flags = CLOCK_SOURCE_IS_CONTINUOUS,
> +};
> +
> +static int __init mxs_clocksource_init(struct clk *timer_clk)
> +{
> + unsigned int c = clk_get_rate(timer_clk);
> +
> + if (timrot_is_v1()) {
> + clocksource_mxs.read = timrotv1_get_cycles;
> + clocksource_mxs.mask = CLOCKSOURCE_MASK(16);
> + }
> + clocksource_mxs.mult = clocksource_hz2mult(c, clocksource_mxs.shift);
> + clocksource_register(&clocksource_mxs);
> +
> + return 0;
> +}
> +
> +void __init mxs_timer_init(struct clk *timer_clk,
> + void __iomem *base, int irq)
> +{
> + clk_enable(timer_clk);
> +
> + timer_base = base;
> +
> + /*
> + * Initialize timers to a known state
> + */
> + mxs_reset_block(base + HW_TIMROT_ROTCTRL);
> +
> + if (timrot_is_v1()) {
> + /* timer0 is for clock_event */
> + __raw_writel(
> + BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL |
> + BM_TIMROT_TIMCTRLn_UPDATE |
> + BM_TIMROT_TIMCTRLn_IRQ_EN,
> + base + HW_TIMROT_TIMCTRLn(0));
> + /* timer1 is for clocksource */
> + __raw_writel(
> + BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL |
> + BM_TIMROT_TIMCTRLn_RELOAD,
> + base + HW_TIMROT_TIMCTRLn(1));
> + __raw_writel(0xffff, timer_base + HW_TIMROT_RUNNING_COUNTn(1));
> +
> + } else {
> + __raw_writel(
> + BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL |
> + BM_TIMROT_TIMCTRLn_IRQ_EN |
> + BM_TIMROT_TIMCTRLn_MATCH_MODE,
> + timer_base + HW_TIMROT_TIMCTRLn(0));
> + }
> +
> + /* init and register the timer to the framework */
> + mxs_clocksource_init(timer_clk);
> + mxs_clockevent_init(timer_clk);
> +
> + /* Make irqs happen */
> + setup_irq(irq, &mxs_timer_irq);
> +}
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v3 01/15] ARM: mxs: Add core definitions
2010-12-07 20:18 ` Uwe Kleine-König
@ 2010-12-08 4:50 ` Shawn Guo
2010-12-08 9:17 ` Uwe Kleine-König
0 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-08 4:50 UTC (permalink / raw)
To: linux-arm-kernel
Hi Uwe,
2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> On Wed, Dec 08, 2010 at 12:31:52AM +0800, Shawn Guo wrote:
[...]
>> +#ifndef __MACH_MX23_H__
>> +#define __MACH_MX23_H__
>> +
>> +#ifndef __ASSEMBLER__
>> +#include <linux/io.h>
>> +#endif
> You don't need this, do you?
>
It can be removed after adding "#include <linux/io.h>" into icoll.c.
> #inclusion of hardware.h would be OK, then you could remove the
> #includes of mx23.h and mx28.h in there.
> (Believe me, this is better, mxc already made me headaches because of
> that.)
>
I do not get it. Can you please help me understand what you want
exactly? Remove includes of mx23.h and mx28.h from hardware.h, and
then include mx23.h, mx28.h, hardware.h individually when necessary?
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v3 06/15] ARM: mxs: Add timer support
2010-12-07 21:18 ` Uwe Kleine-König
@ 2010-12-08 5:58 ` Shawn Guo
2010-12-08 9:25 ` Uwe Kleine-König
0 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-08 5:58 UTC (permalink / raw)
To: linux-arm-kernel
Hi Uwe,
2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> On Wed, Dec 08, 2010 at 12:31:56AM +0800, Shawn Guo wrote:
[...]
>> +static int timrotv2_set_next_event(unsigned long evt,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct clock_event_device *dev)
>> +{
>> + ? ? unsigned long match;
>> +
>> + ? ? /* timrot decrements the count */
>> + ? ? match = __raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(0))
>> + ? ? ? ? ? ? ? ? ? ? - evt;
>> + ? ? __raw_writel(match, timer_base + HW_TIMROT_MATCH_COUNTn(0));
>> +
>> + ? ? return (int)(match - __raw_readl(timer_base +
>> + ? ? ? ? ? ? ? ? ? ? HW_TIMROT_RUNNING_COUNTn(0))) > 0 ? -ETIME : 0;
> Wouldn't it be easier to use the same approach as in timrotv1? ?(i.e.
> use two timers and then having a simpler set_next_event.)
>
Using two timrotv1 timers is not to make code look simpler. Instead,
we have to use two, because timrotv1 has no match function. One most
significant improvement of v2 over v1 is adding match function, so
that one v2 timer can serve clock_event and clocksource without
problem. I would keep the implementation to utilize v2 capability,
save timer resource and show the difference between v1 and v2.
>> +}
>> +
>> +static irqreturn_t mxs_timer_interrupt(int irq, void *dev_id)
>> +{
>> + ? ? struct clock_event_device *evt = &clockevent_mxs;
> I assume dev_id is &clockevent_mxs
>
The assumption is only true if we assign &clockevent_mxs to dev_id.
So you want to see the following change?
static irqreturn_t mxs_timer_interrupt(int irq, void *dev_id)
{
- struct clock_event_device *evt = &clockevent_mxs;
+ struct clock_event_device *evt = dev_id;
timrot_irq_acknowledge();
evt->event_handler(evt);
static struct irqaction mxs_timer_irq = {
.name = "MXS Timer Tick",
+ .dev_id = &clockevent_mxs,
.flags = IRQF_TIMER | IRQF_IRQPOLL,
.handler = mxs_timer_interrupt,
};
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 07/15] ARM: mxs: Add gpio support
2010-12-07 16:31 ` [PATCH v2 07/15] ARM: mxs: Add gpio support Shawn Guo
@ 2010-12-08 7:21 ` Lothar Waßmann
0 siblings, 0 replies; 146+ messages in thread
From: Lothar Waßmann @ 2010-12-08 7:21 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
Shawn Guo writes:
> MXS-based SoCs implement gpio support in block PINCTRL.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v2:
> - Create arch/arm/mach-mxs/gpio.h to accommodate stuff private for mach-mxs
> - Use GPIO_INT_LEV_MASK and GPIO_INT_POL_MASK instead of constant
> - Remove both edges IRQ support which is not needed
> - Use SET and CLR register of PINCTRL_DOE in _set_gpio_direction()
> - Use pr_info over printk(KERN_INFO)
>
> arch/arm/mach-mxs/gpio.c | 331 +++++++++++++++++++++++++++++++++
> arch/arm/mach-mxs/gpio.h | 36 ++++
> arch/arm/mach-mxs/include/mach/gpio.h | 35 ++++
> 3 files changed, 402 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-mxs/gpio.c
> create mode 100644 arch/arm/mach-mxs/gpio.h
> create mode 100644 arch/arm/mach-mxs/include/mach/gpio.h
>
> diff --git a/arch/arm/mach-mxs/gpio.c b/arch/arm/mach-mxs/gpio.c
> new file mode 100644
> index 0000000..6db7541
> --- /dev/null
> +++ b/arch/arm/mach-mxs/gpio.c
[...]
> +static void mxs_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
> +{
> + struct mxs_gpio_port *port =
> + container_of(chip, struct mxs_gpio_port, chip);
> + u32 l;
> + unsigned long flags;
> + void __iomem *reg = port->base + PINCTRL_DOUT(port->id);
> +
> + spin_lock_irqsave(&port->lock, flags);
> + l = (__raw_readl(reg) & (~(1 << offset))) | (!!value << offset);
> + __raw_writel(l, reg);
> + spin_unlock_irqrestore(&port->lock, flags);
Why not:
__raw_writel(1 << offset, reg + (value ? MXS_SET_ADDR : MXS_CLR_ADDR));
which would not even need any locking.
Lothar Wa?mann
--
___________________________________________________________
Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996
www.karo-electronics.de | info@karo-electronics.de
___________________________________________________________
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 08/15] ARM: mxs: Add iomux support
2010-12-07 16:31 ` [PATCH v2 08/15] ARM: mxs: Add iomux support Shawn Guo
@ 2010-12-08 7:25 ` Lothar Waßmann
2010-12-08 10:52 ` Shawn Guo
0 siblings, 1 reply; 146+ messages in thread
From: Lothar Waßmann @ 2010-12-08 7:25 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
Shawn Guo writes:
> MXS-based SoCs implements iomux functions in block PINCTRL.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v2:
> - Define iomux_cfg_t as u64
^^^^^^^^^^^^^^^^^^^^^^^^^
Really?
> +typedef struct pad_desc {
> + unsigned bank:12;
> + unsigned pin:20;
> + unsigned muxsel:8;
> + unsigned ma:12;
> + unsigned vol:8;
> + unsigned pull:4;
> +} iomux_cfg_t;
^^^^^^^^^^^^^^^^^
Lothar Wa?mann
--
___________________________________________________________
Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996
www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v3 03/15] ARM: mxs: Add reset routines
2010-12-07 16:31 ` [PATCH v3 03/15] ARM: mxs: Add reset routines Shawn Guo
2010-12-07 20:27 ` Uwe Kleine-König
@ 2010-12-08 7:33 ` Lothar Waßmann
2010-12-08 20:31 ` Uwe Kleine-König
1 sibling, 1 reply; 146+ messages in thread
From: Lothar Waßmann @ 2010-12-08 7:33 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
Shawn Guo writes:
> - The mxs wdog is implemented in RTC block.
> - There is a generic software reset routine for most modules on mxs.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v3:
> - Change wdog timeout to 10ms for safety
> - Simplify function mxs_reset_block() to get it look better
>
> Changes for v2:
> - Move rtc clock enabling from arch_reset() into mxs_arch_reset_init()
>
mxs_arch_reset_init() is currently being called from the .map_io hook
in mach-mxs/mm-mx23.c and mm-mx28.c which is called before clocks are
registered.
But IMO this should be removed from the .map_io hook anyway (as well
as mxs_iomux_init()).
Lothar Wa?mann
--
___________________________________________________________
Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996
www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 04/15] ARM: mxs: Add interrupt support
2010-12-07 16:31 ` [PATCH v2 04/15] ARM: mxs: Add interrupt support Shawn Guo
2010-12-07 21:03 ` Uwe Kleine-König
@ 2010-12-08 8:24 ` Lothar Waßmann
1 sibling, 0 replies; 146+ messages in thread
From: Lothar Waßmann @ 2010-12-08 8:24 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
Shawn Guo writes:
> Add Interrupt Collector (ICOLL) support for MXS-based.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v2:
> - Get icoll base in get_irqnr_preamble
> - Check the case of single SoC build and use hard-coding address if possible
>
> arch/arm/mach-mxs/icoll.c | 77 ++++++++++++++++++++++++++
> arch/arm/mach-mxs/include/mach/entry-macro.S | 44 +++++++++++++++
> 2 files changed, 121 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-mxs/icoll.c
> create mode 100644 arch/arm/mach-mxs/include/mach/entry-macro.S
>
[...]
> diff --git a/arch/arm/mach-mxs/include/mach/entry-macro.S b/arch/arm/mach-mxs/include/mach/entry-macro.S
> new file mode 100644
> index 0000000..2c7755b
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/entry-macro.S
> @@ -0,0 +1,44 @@
> +/*
> + * Low-level IRQ helper macros for Freescale MXS-based
> + *
> + * 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 <mach/hardware.h>
> +
> + .macro disable_fiq
> + .endm
> +
> + .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
> + ldr \irqnr, [\base, #0x70]
> + cmp \irqnr, #0x7F
> + moveqs \irqnr, #0
> + .endm
> +
> + .macro get_irqnr_preamble, base, tmp
> +#if defined (CONFIG_SOC_IMX23) && defined (CONFIG_SOC_IMX28)
> + ldr \base, =icoll_base
> + ldr \base, [\base]
> +#elif defined (CONFIG_SOC_IMX23)
> + ldr \base, =MX23_ICOLL_BASE_ADDR
>
MX23_IO_ADDRESS(MX23_ICOLL_BASE_ADDR)
> +#else
> + ldr \base, =MX28_ICOLL_BASE_ADDR
>
MX28_IO_ADDRESS(MX28_ICOLL_BASE_ADDR)
Lothar Wa?mann
--
___________________________________________________________
Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996
www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 04/15] ARM: mxs: Add interrupt support
2010-12-07 21:03 ` Uwe Kleine-König
@ 2010-12-08 8:27 ` Shawn Guo
2010-12-08 9:39 ` Uwe Kleine-König
2010-12-08 8:56 ` Shawn Guo
1 sibling, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-08 8:27 UTC (permalink / raw)
To: linux-arm-kernel
Hi Uwe,
2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Shawn,
>
> On Wed, Dec 08, 2010 at 12:31:54AM +0800, Shawn Guo wrote:
[...]
>> +
>> +static void icoll_ack_irq(unsigned int irq)
>> +{
>> + ? ? __raw_writel(0, icoll_base + HW_ICOLL_VECTOR);
> You need to write this before handling the irq, no? ?Note this question
> is a repetition. ?You answered "No need, indeed. ?Will remove it."
> According to MCIMX28RM a write to HW_ICOLL_VECTOR "indicates the
> in-service state". ?Are you sure this is not needed? ?If no (i.e. it's
> needed) the write should go into entry-macro.S. ?As I don't have
> hardware yet I cannot test that. ?Maybe it's only needed when the
> priority levels are used?!
>
Sorry. I made a mistake. I thought I had tested the removal of line
and gave the comment, but actually not. The line is needed, and image
will stop working without the line.
Regarding to moving the writing to register VECTOR into entry-macro.S,
can you please help me understand the reason behind the suggestion?
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v3 06/15] ARM: mxs: Add timer support
2010-12-07 16:31 ` [PATCH v3 06/15] ARM: mxs: Add timer support Shawn Guo
2010-12-07 21:18 ` Uwe Kleine-König
@ 2010-12-08 8:30 ` Lothar Waßmann
2010-12-08 9:31 ` Uwe Kleine-König
1 sibling, 1 reply; 146+ messages in thread
From: Lothar Waßmann @ 2010-12-08 8:30 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
Shawn Guo writes:
> Freescale MXS-based SoCs implement timer support in block TIMROT.
> There are two versions of TIMROT. The v1 on MX23 only gets 16 bits
> counter and has no match function. The v2 on MX28 extends the
> counter to 32 bits and add the match function.
>
> As the result, we need two instances of timers with v1 for better
> implementation, one for clock_event and another for clocksource.
> Otherwise, get_cycles may get imprecise result after long time
> cumulating. With v2, one instance can serve two purposes well.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v3:
> - Use term clock_event over next_event and clocksource over get_cycles
> - Split BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL into two definitions for v1 and v2 respectively
> - Turn timrot_get_cycles() into timrotv1_get_cycles() and timrotv2_get_cycles()
> - Turn timrot_set_next_event() into timrotv1_set_next_event() and timrotv2_set_next_event()
> - Skip flag IRQF_DISABLED
> - Remove unncessary IRQ disabling in mxs_set_mode()
> - Change shift of clocksource_mxs to 17
>
> Changes for v2:
> - Fix a bug in timrot_set_next_event(). It should read
> HW_TIMROT_RUNNING_COUNTn to get the current counts.
>
> arch/arm/mach-mxs/timer.c | 276 +++++++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 276 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-mxs/timer.c
>
> diff --git a/arch/arm/mach-mxs/timer.c b/arch/arm/mach-mxs/timer.c
> new file mode 100644
> index 0000000..b0e7ffe
> --- /dev/null
> +++ b/arch/arm/mach-mxs/timer.c
[...]
> + switch (mode) {
> + case CLOCK_EVT_MODE_PERIODIC:
> + printk(KERN_ERR "mxs_set_mode: Periodic mode is not "
> + "supported for MXS-based\n");
>
Please do not line wrap message strings. Also, if you want the
function name to appear in the message, use __func__ or __FUNCTION__.
That way the name is always correct even if the function is renamed or
the printk() statement is copied to a different function.
Lothar Wa?mann
--
___________________________________________________________
Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996
www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 04/15] ARM: mxs: Add interrupt support
2010-12-07 21:03 ` Uwe Kleine-König
2010-12-08 8:27 ` Shawn Guo
@ 2010-12-08 8:56 ` Shawn Guo
2010-12-08 9:14 ` Uwe Kleine-König
1 sibling, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-08 8:56 UTC (permalink / raw)
To: linux-arm-kernel
Hi Uwe,
2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Shawn,
>
[...]
>> +
>> + ? ? .macro ?disable_fiq
>> + ? ? .endm
> I think is isn't needed. ?Only when you start to actually use the fiq.
>
Without it, the compiler will complain when compiling
arch/arm/kernel/entry-armv.S.
[...]
>> + ? ? ldr ? ? \base, =icoll_base
>> + ? ? ldr ? ? \base, [\base]
>> +#elif defined (CONFIG_SOC_IMX23)
>> + ? ? ldr ? ? \base, =MX23_ICOLL_BASE_ADDR
>> +#else
>> + ? ? ldr ? ? \base, =MX28_ICOLL_BASE_ADDR
>> +#endif
> Mhh, you said the base addresses are different. ?Unless I'm mistaken
> they are not. ?So you can just remove icoll_base.
>
Something went wrong in my head. The addresses are same.
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 04/15] ARM: mxs: Add interrupt support
2010-12-08 8:56 ` Shawn Guo
@ 2010-12-08 9:14 ` Uwe Kleine-König
0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-08 9:14 UTC (permalink / raw)
To: linux-arm-kernel
Hello Shawn,
On Wed, Dec 08, 2010 at 04:56:40PM +0800, Shawn Guo wrote:
> 2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> [...]
> >> +
> >> + ? ? .macro ?disable_fiq
> >> + ? ? .endm
> > I think is isn't needed. ?Only when you start to actually use the fiq.
> >
> Without it, the compiler will complain when compiling
> arch/arm/kernel/entry-armv.S.
OK
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v3 01/15] ARM: mxs: Add core definitions
2010-12-08 4:50 ` Shawn Guo
@ 2010-12-08 9:17 ` Uwe Kleine-König
0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-08 9:17 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Dec 08, 2010 at 12:50:56PM +0800, Shawn Guo wrote:
> Hi Uwe,
>
> 2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> > On Wed, Dec 08, 2010 at 12:31:52AM +0800, Shawn Guo wrote:
> [...]
> >> +#ifndef __MACH_MX23_H__
> >> +#define __MACH_MX23_H__
> >> +
> >> +#ifndef __ASSEMBLER__
> >> +#include <linux/io.h>
> >> +#endif
> > You don't need this, do you?
> >
> It can be removed after adding "#include <linux/io.h>" into icoll.c.
fine
> > #inclusion of hardware.h would be OK, then you could remove the
> > #includes of mx23.h and mx28.h in there.
> > (Believe me, this is better, mxc already made me headaches because of
> > that.)
> >
> I do not get it. Can you please help me understand what you want
> exactly? Remove includes of mx23.h and mx28.h from hardware.h, and
> then include mx23.h, mx28.h, hardware.h individually when necessary?
Yeap. You will need hardware.h for mx2[38].h to get the macros
MXS_IO_P2V and IOMEM.
Best regards
UWe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v3 06/15] ARM: mxs: Add timer support
2010-12-08 5:58 ` Shawn Guo
@ 2010-12-08 9:25 ` Uwe Kleine-König
0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-08 9:25 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Dec 08, 2010 at 01:58:17PM +0800, Shawn Guo wrote:
> Hi Uwe,
>
> 2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> > On Wed, Dec 08, 2010 at 12:31:56AM +0800, Shawn Guo wrote:
> [...]
> >> +static int timrotv2_set_next_event(unsigned long evt,
> >> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? struct clock_event_device *dev)
> >> +{
> >> + ? ? unsigned long match;
> >> +
> >> + ? ? /* timrot decrements the count */
> >> + ? ? match = __raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(0))
> >> + ? ? ? ? ? ? ? ? ? ? - evt;
> >> + ? ? __raw_writel(match, timer_base + HW_TIMROT_MATCH_COUNTn(0));
> >> +
> >> + ? ? return (int)(match - __raw_readl(timer_base +
> >> + ? ? ? ? ? ? ? ? ? ? HW_TIMROT_RUNNING_COUNTn(0))) > 0 ? -ETIME : 0;
> > Wouldn't it be easier to use the same approach as in timrotv1? ?(i.e.
> > use two timers and then having a simpler set_next_event.)
> >
> Using two timrotv1 timers is not to make code look simpler. Instead,
> we have to use two, because timrotv1 has no match function. One most
> significant improvement of v2 over v1 is adding match function, so
> that one v2 timer can serve clock_event and clocksource without
> problem. I would keep the implementation to utilize v2 capability,
> save timer resource and show the difference between v1 and v2.
Is there an advantage of keeping one additional timer unused? IMHO it
doesn't make much sense to use the match support just because it exists
if it doesn't make things easier. Here the main impact is that it
complicates the set_next_event callback.
> >> +}
> >> +
> >> +static irqreturn_t mxs_timer_interrupt(int irq, void *dev_id)
> >> +{
> >> + ? ? struct clock_event_device *evt = &clockevent_mxs;
> > I assume dev_id is &clockevent_mxs
> >
> The assumption is only true if we assign &clockevent_mxs to dev_id.
> So you want to see the following change?
>
> static irqreturn_t mxs_timer_interrupt(int irq, void *dev_id)
> {
> - struct clock_event_device *evt = &clockevent_mxs;
> + struct clock_event_device *evt = dev_id;
This might save an instruction or two.
> timrot_irq_acknowledge();
> evt->event_handler(evt);
>
> static struct irqaction mxs_timer_irq = {
> .name = "MXS Timer Tick",
> + .dev_id = &clockevent_mxs,
> .flags = IRQF_TIMER | IRQF_IRQPOLL,
> .handler = mxs_timer_interrupt,
> };
This looks more correct at least (IMHO).
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v3 06/15] ARM: mxs: Add timer support
2010-12-08 8:30 ` Lothar Waßmann
@ 2010-12-08 9:31 ` Uwe Kleine-König
0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-08 9:31 UTC (permalink / raw)
To: linux-arm-kernel
Hello Lothar,
On Wed, Dec 08, 2010 at 09:30:39AM +0100, Lothar Wa?mann wrote:
> > + switch (mode) {
> > + case CLOCK_EVT_MODE_PERIODIC:
> > + printk(KERN_ERR "mxs_set_mode: Periodic mode is not "
> > + "supported for MXS-based\n");
> >
> Please do not line wrap message strings. Also, if you want the
> function name to appear in the message, use __func__ or __FUNCTION__.
> That way the name is always correct even if the function is renamed or
> the printk() statement is copied to a different function.
__FUNCTION__ isn't considered good, so please use __func__.
(__FUNCTION__ is a gcc extension, __func__ is c99 (I think)).
checkpatch warns about __FUNCTION__, too.
Shawn, you can also consider using pr_err.
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 04/15] ARM: mxs: Add interrupt support
2010-12-08 8:27 ` Shawn Guo
@ 2010-12-08 9:39 ` Uwe Kleine-König
2010-12-08 10:46 ` Shawn Guo
0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-08 9:39 UTC (permalink / raw)
To: linux-arm-kernel
Hello Shawn,
On Wed, Dec 08, 2010 at 04:27:56PM +0800, Shawn Guo wrote:
> 2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> > On Wed, Dec 08, 2010 at 12:31:54AM +0800, Shawn Guo wrote:
> [...]
> >> +
> >> +static void icoll_ack_irq(unsigned int irq)
> >> +{
> >> + ? ? __raw_writel(0, icoll_base + HW_ICOLL_VECTOR);
> > You need to write this before handling the irq, no? ?Note this question
> > is a repetition. ?You answered "No need, indeed. ?Will remove it."
> > According to MCIMX28RM a write to HW_ICOLL_VECTOR "indicates the
> > in-service state". ?Are you sure this is not needed? ?If no (i.e. it's
> > needed) the write should go into entry-macro.S. ?As I don't have
> > hardware yet I cannot test that. ?Maybe it's only needed when the
> > priority levels are used?!
> >
> Sorry. I made a mistake. I thought I had tested the removal of line
> and gave the comment, but actually not. The line is needed, and image
> will stop working without the line.
>
> Regarding to moving the writing to register VECTOR into entry-macro.S,
> can you please help me understand the reason behind the suggestion?
Section 5.2.1 of MCIMX28RM writes:
After the CPU enters the interrupt service routine, it must
notify the interrupt collector as soon as possible. Software
indicates the in-service state by writing to the HW_ICOLL_VECTOR
register.
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 04/15] ARM: mxs: Add interrupt support
2010-12-08 9:39 ` Uwe Kleine-König
@ 2010-12-08 10:46 ` Shawn Guo
2010-12-08 12:09 ` Uwe Kleine-König
0 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-08 10:46 UTC (permalink / raw)
To: linux-arm-kernel
Hi Uwe,
2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Shawn,
>
> On Wed, Dec 08, 2010 at 04:27:56PM +0800, Shawn Guo wrote:
>> 2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>> > On Wed, Dec 08, 2010 at 12:31:54AM +0800, Shawn Guo wrote:
>> [...]
>> >> +
>> >> +static void icoll_ack_irq(unsigned int irq)
>> >> +{
>> >> + ? ? __raw_writel(0, icoll_base + HW_ICOLL_VECTOR);
>> > You need to write this before handling the irq, no? ?Note this question
>> > is a repetition. ?You answered "No need, indeed. ?Will remove it."
>> > According to MCIMX28RM a write to HW_ICOLL_VECTOR "indicates the
>> > in-service state". ?Are you sure this is not needed? ?If no (i.e. it's
>> > needed) the write should go into entry-macro.S. ?As I don't have
>> > hardware yet I cannot test that. ?Maybe it's only needed when the
>> > priority levels are used?!
>> >
>> Sorry. I made a mistake. ?I thought I had tested the removal of line
>> and gave the comment, but actually not. The line is needed, and image
>> will stop working without the line.
>>
>> Regarding to moving the writing to register VECTOR into entry-macro.S,
>> can you please help me understand the reason behind the suggestion?
> Section 5.2.1 of MCIMX28RM writes:
>
> ? ? ? ?After the CPU enters the interrupt service routine, it must
> ? ? ? ?notify the interrupt collector as soon as possible. Software
> ? ? ? ?indicates the in-service state by writing to the HW_ICOLL_VECTOR
> ? ? ? ?register.
>
In case you will ask why, I would give the fact here. I'm not sure
what is your first thought. Mine is to add it into get_irqnr_preamble
as below.
.macro get_irqnr_preamble, base, tmp
ldr \base, =ICOLL_ADDR
mov \tmp, #0
str \tmp, [\base]
.endm
But I got the following error.
[...]
VFS: Mounted root (nfs filesystem) on device 0:11.
Freeing init memory: 92K
irq 101: nobody cared (try booting with the "irqpoll" option)
[<c0025084>] (unwind_backtrace+0x0/0xe4) from [<c0063d54>] (__report_bad_irq+0x3
4/0x8c)
[<c0063d54>] (__report_bad_irq+0x34/0x8c) from [<c0063ef8>] (note_interrupt+0x14
c/0x1d8)
[<c0063ef8>] (note_interrupt+0x14c/0x1d8) from [<c0064d5c>] (handle_level_irq+0x
108/0x198)
[<c0064d5c>] (handle_level_irq+0x108/0x198) from [<c001f070>] (asm_do_IRQ+0x70/0
x94)
[<c001f070>] (asm_do_IRQ+0x70/0x94) from [<c0237050>] (__irq_svc+0x50/0x8c)
Exception stack(0xc02e7d38 to 0xc02e7d80)
7d20: c02e7db0 00000000
7d40: ffffffd0 00000000 c7990800 00000000 c79a3820 000005a8 c02e7df8 c0217380
7d60: c7997a28 000005a8 00000000 c02e7d80 c02173a8 c02173c0 40000013 ffffffff
[<c0237050>] (__irq_svc+0x50/0x8c) from [<c02173c0>] (xs_tcp_data_recv+0x40/0x62
c)
[<c02173c0>] (xs_tcp_data_recv+0x40/0x62c) from [<c01d6160>] (tcp_read_sock+0x70
/0x1e8)
[<c01d6160>] (tcp_read_sock+0x70/0x1e8) from [<c021734c>] (xs_tcp_data_ready+0x7
c/0xb0)
[<c021734c>] (xs_tcp_data_ready+0x7c/0xb0) from [<c01dee3c>] (tcp_rcv_establishe
d+0x484/0x610)
[<c01dee3c>] (tcp_rcv_established+0x484/0x610) from [<c01e5fd4>] (tcp_v4_do_rcv+
0x28/0x1c8)
[<c01e5fd4>] (tcp_v4_do_rcv+0x28/0x1c8) from [<c01e65fc>] (tcp_v4_rcv+0x488/0x83
c)
[<c01e65fc>] (tcp_v4_rcv+0x488/0x83c) from [<c01ca038>] (ip_local_deliver+0x100/
0x1fc)
[<c01ca038>] (ip_local_deliver+0x100/0x1fc) from [<c01c9efc>] (ip_rcv+0x540/0x57
c)
[<c01c9efc>] (ip_rcv+0x540/0x57c) from [<c01ad490>] (__netif_receive_skb+0x32c/0
x388)
[<c01ad490>] (__netif_receive_skb+0x32c/0x388) from [<c01ad56c>] (process_backlo
g+0x80/0x140)
[<c01ad56c>] (process_backlog+0x80/0x140) from [<c01ad8a4>] (net_rx_action+0x58/
0x180)
[<c01ad8a4>] (net_rx_action+0x58/0x180) from [<c0037c50>] (__do_softirq+0x78/0x1
10)
[<c0037c50>] (__do_softirq+0x78/0x110) from [<c0037d2c>] (irq_exit+0x44/0xa8)
[<c0037d2c>] (irq_exit+0x44/0xa8) from [<c001f074>] (asm_do_IRQ+0x74/0x94)
[<c001f074>] (asm_do_IRQ+0x74/0x94) from [<c0237050>] (__irq_svc+0x50/0x8c)
Exception stack(0xc02e7f80 to 0xc02e7fc8)
7f80: 00000000 0005317f 0005217f 60000013 c02e6000 c001baf4 c001baf0 c02e9b60
7fa0: 4001a848 41069265 4001a7e0 00000000 600000d3 c02e7fc8 c0020bc4 c0020bd0
7fc0: 60000013 ffffffff
[<c0237050>] (__irq_svc+0x50/0x8c) from [<c0020bd0>] (default_idle+0x2c/0x30)
[<c0020bd0>] (default_idle+0x2c/0x30) from [<c002110c>] (cpu_idle+0x60/0xc0)
[<c002110c>] (cpu_idle+0x60/0xc0) from [<c00088f0>] (start_kernel+0x238/0x27c)
[<c00088f0>] (start_kernel+0x238/0x27c) from [<40008034>] (0x40008034)
handlers:
[<c01872e4>] (fec_enet_interrupt+0x0/0x3ec)
Disabling IRQ #101
However, when I add it into get_irqnr_and_base as below.
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
mov \tmp, #0
str \tmp, [\base]
ldr \irqnr, [\base, #0x70]
cmp \irqnr, #0x7F
moveqs \irqnr, #0
.endm
Everything seems fine.
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 08/15] ARM: mxs: Add iomux support
2010-12-08 7:25 ` Lothar Waßmann
@ 2010-12-08 10:52 ` Shawn Guo
2010-12-08 10:56 ` Uwe Kleine-König
0 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-08 10:52 UTC (permalink / raw)
To: linux-arm-kernel
Hi Lothar,
Thanks for the review.
On Wed, Dec 8, 2010 at 3:25 PM, Lothar Wa?mann <LW@karo-electronics.de> wrote:
> Hi,
>
> Shawn Guo writes:
>> MXS-based SoCs implements iomux functions in block PINCTRL.
>>
>> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
>> ---
>> Changes for v2:
>> ?- Define iomux_cfg_t as u64
> ? ? ^^^^^^^^^^^^^^^^^^^^^^^^^
> Really?
>
>> +typedef struct pad_desc {
>> + ? ? unsigned bank:12;
>> + ? ? unsigned pin:20;
>> + ? ? unsigned muxsel:8;
>> + ? ? unsigned ma:12;
>> + ? ? unsigned vol:8;
>> + ? ? unsigned pull:4;
>> +} iomux_cfg_t;
> ^^^^^^^^^^^^^^^^^
>
I did not pick the correct word. What I meant is 64 bits. Since this
error is in change log, I would fix it if there is v3 of the patch.
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 08/15] ARM: mxs: Add iomux support
2010-12-08 10:52 ` Shawn Guo
@ 2010-12-08 10:56 ` Uwe Kleine-König
2010-12-08 11:29 ` Shawn Guo
0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-08 10:56 UTC (permalink / raw)
To: linux-arm-kernel
Hello,
On Wed, Dec 08, 2010 at 06:52:36PM +0800, Shawn Guo wrote:
> Hi Lothar,
>
> Thanks for the review.
>
> On Wed, Dec 8, 2010 at 3:25 PM, Lothar Wa?mann <LW@karo-electronics.de> wrote:
> > Hi,
> >
> > Shawn Guo writes:
> >> MXS-based SoCs implements iomux functions in block PINCTRL.
> >>
> >> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> >> ---
> >> Changes for v2:
> >> ?- Define iomux_cfg_t as u64
> > ? ? ^^^^^^^^^^^^^^^^^^^^^^^^^
> > Really?
> >
> >> +typedef struct pad_desc {
> >> + ? ? unsigned bank:12;
> >> + ? ? unsigned pin:20;
> >> + ? ? unsigned muxsel:8;
> >> + ? ? unsigned ma:12;
> >> + ? ? unsigned vol:8;
> >> + ? ? unsigned pull:4;
> >> +} iomux_cfg_t;
> > ^^^^^^^^^^^^^^^^^
> >
> I did not pick the correct word. What I meant is 64 bits. Since this
> error is in change log, I would fix it if there is v3 of the patch.
the idea was to really use an u64 to have the pin definitions modifyable.
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 08/15] ARM: mxs: Add iomux support
2010-12-08 10:56 ` Uwe Kleine-König
@ 2010-12-08 11:29 ` Shawn Guo
2010-12-08 11:32 ` Lothar Waßmann
0 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-08 11:29 UTC (permalink / raw)
To: linux-arm-kernel
2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello,
>
> On Wed, Dec 08, 2010 at 06:52:36PM +0800, Shawn Guo wrote:
>> Hi Lothar,
>>
>> Thanks for the review.
>>
>> On Wed, Dec 8, 2010 at 3:25 PM, Lothar Wa?mann <LW@karo-electronics.de> wrote:
>> > Hi,
>> >
>> > Shawn Guo writes:
>> >> MXS-based SoCs implements iomux functions in block PINCTRL.
>> >>
>> >> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
>> >> ---
>> >> Changes for v2:
>> >> ?- Define iomux_cfg_t as u64
>> > ? ? ^^^^^^^^^^^^^^^^^^^^^^^^^
>> > Really?
>> >
>> >> +typedef struct pad_desc {
>> >> + ? ? unsigned bank:12;
>> >> + ? ? unsigned pin:20;
>> >> + ? ? unsigned muxsel:8;
>> >> + ? ? unsigned ma:12;
>> >> + ? ? unsigned vol:8;
>> >> + ? ? unsigned pull:4;
>> >> +} iomux_cfg_t;
>> > ^^^^^^^^^^^^^^^^^
>> >
>> I did not pick the correct word. ?What I meant is 64 bits. ?Since this
>> error is in change log, I would fix it if there is v3 of the patch.
> the idea was to really use an u64 to have the pin definitions modifyable.
>
Ah, I misunderstood the comments. But I did not see mxc switches to
u64. Do you have example to show what you want exactly?
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 08/15] ARM: mxs: Add iomux support
2010-12-08 11:29 ` Shawn Guo
@ 2010-12-08 11:32 ` Lothar Waßmann
2010-12-09 6:15 ` Shawn Guo
0 siblings, 1 reply; 146+ messages in thread
From: Lothar Waßmann @ 2010-12-08 11:32 UTC (permalink / raw)
To: linux-arm-kernel
Shawn Guo writes:
> 2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> > Hello,
> >
> > On Wed, Dec 08, 2010 at 06:52:36PM +0800, Shawn Guo wrote:
> >> Hi Lothar,
> >>
> >> Thanks for the review.
> >>
> >> On Wed, Dec 8, 2010 at 3:25 PM, Lothar Wa?mann <LW@karo-electronics.de> wrote:
> >> > Hi,
> >> >
> >> > Shawn Guo writes:
> >> >> MXS-based SoCs implements iomux functions in block PINCTRL.
> >> >>
> >> >> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> >> >> ---
> >> >> Changes for v2:
> >> >> ?- Define iomux_cfg_t as u64
> >> > ? ? ^^^^^^^^^^^^^^^^^^^^^^^^^
> >> > Really?
> >> >
> >> >> +typedef struct pad_desc {
> >> >> + ? ? unsigned bank:12;
> >> >> + ? ? unsigned pin:20;
> >> >> + ? ? unsigned muxsel:8;
> >> >> + ? ? unsigned ma:12;
> >> >> + ? ? unsigned vol:8;
> >> >> + ? ? unsigned pull:4;
> >> >> +} iomux_cfg_t;
> >> > ^^^^^^^^^^^^^^^^^
> >> >
> >> I did not pick the correct word. ?What I meant is 64 bits. ?Since this
> >> error is in change log, I would fix it if there is v3 of the patch.
> > the idea was to really use an u64 to have the pin definitions modifyable.
> >
> Ah, I misunderstood the comments. But I did not see mxc switches to
> u64. Do you have example to show what you want exactly?
>
See:
http://lists.infradead.org/pipermail/linux-arm-kernel/2010-November/032202.html
Lothar Wa?mann
--
___________________________________________________________
Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996
www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 04/15] ARM: mxs: Add interrupt support
2010-12-08 10:46 ` Shawn Guo
@ 2010-12-08 12:09 ` Uwe Kleine-König
2010-12-08 12:31 ` Shawn Guo
0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-08 12:09 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Dec 08, 2010 at 06:46:49PM +0800, Shawn Guo wrote:
> Hi Uwe,
>
> 2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> > Hello Shawn,
> >
> > On Wed, Dec 08, 2010 at 04:27:56PM +0800, Shawn Guo wrote:
> >> 2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> >> > On Wed, Dec 08, 2010 at 12:31:54AM +0800, Shawn Guo wrote:
> >> [...]
> >> >> +
> >> >> +static void icoll_ack_irq(unsigned int irq)
> >> >> +{
> >> >> + ? ? __raw_writel(0, icoll_base + HW_ICOLL_VECTOR);
> >> > You need to write this before handling the irq, no? ?Note this question
> >> > is a repetition. ?You answered "No need, indeed. ?Will remove it."
> >> > According to MCIMX28RM a write to HW_ICOLL_VECTOR "indicates the
> >> > in-service state". ?Are you sure this is not needed? ?If no (i.e. it's
> >> > needed) the write should go into entry-macro.S. ?As I don't have
> >> > hardware yet I cannot test that. ?Maybe it's only needed when the
> >> > priority levels are used?!
> >> >
> >> Sorry. I made a mistake. ?I thought I had tested the removal of line
> >> and gave the comment, but actually not. The line is needed, and image
> >> will stop working without the line.
> >>
> >> Regarding to moving the writing to register VECTOR into entry-macro.S,
> >> can you please help me understand the reason behind the suggestion?
> > Section 5.2.1 of MCIMX28RM writes:
> >
> > ? ? ? ?After the CPU enters the interrupt service routine, it must
> > ? ? ? ?notify the interrupt collector as soon as possible. Software
> > ? ? ? ?indicates the in-service state by writing to the HW_ICOLL_VECTOR
> > ? ? ? ?register.
> >
> In case you will ask why, I would give the fact here. I'm not sure
> what is your first thought. Mine is to add it into get_irqnr_preamble
> as below.
>
> .macro get_irqnr_preamble, base, tmp
> ldr \base, =ICOLL_ADDR
> mov \tmp, #0
> str \tmp, [\base]
> .endm
It's wrong to do that in get_irqnr_preamble.
> But I got the following error.
>
> [...]
> VFS: Mounted root (nfs filesystem) on device 0:11.
> Freeing init memory: 92K
> irq 101: nobody cared (try booting with the "irqpoll" option)
> [<c0025084>] (unwind_backtrace+0x0/0xe4) from [<c0063d54>] (__report_bad_irq+0x3
> 4/0x8c)
> [<c0063d54>] (__report_bad_irq+0x34/0x8c) from [<c0063ef8>] (note_interrupt+0x14
> c/0x1d8)
> [<c0063ef8>] (note_interrupt+0x14c/0x1d8) from [<c0064d5c>] (handle_level_irq+0x
> 108/0x198)
> [<c0064d5c>] (handle_level_irq+0x108/0x198) from [<c001f070>] (asm_do_IRQ+0x70/0
> x94)
> [<c001f070>] (asm_do_IRQ+0x70/0x94) from [<c0237050>] (__irq_svc+0x50/0x8c)
> Exception stack(0xc02e7d38 to 0xc02e7d80)
> 7d20: c02e7db0 00000000
> 7d40: ffffffd0 00000000 c7990800 00000000 c79a3820 000005a8 c02e7df8 c0217380
> 7d60: c7997a28 000005a8 00000000 c02e7d80 c02173a8 c02173c0 40000013 ffffffff
> [<c0237050>] (__irq_svc+0x50/0x8c) from [<c02173c0>] (xs_tcp_data_recv+0x40/0x62
> c)
> [<c02173c0>] (xs_tcp_data_recv+0x40/0x62c) from [<c01d6160>] (tcp_read_sock+0x70
> /0x1e8)
> [<c01d6160>] (tcp_read_sock+0x70/0x1e8) from [<c021734c>] (xs_tcp_data_ready+0x7
> c/0xb0)
> [<c021734c>] (xs_tcp_data_ready+0x7c/0xb0) from [<c01dee3c>] (tcp_rcv_establishe
> d+0x484/0x610)
> [<c01dee3c>] (tcp_rcv_established+0x484/0x610) from [<c01e5fd4>] (tcp_v4_do_rcv+
> 0x28/0x1c8)
> [<c01e5fd4>] (tcp_v4_do_rcv+0x28/0x1c8) from [<c01e65fc>] (tcp_v4_rcv+0x488/0x83
> c)
> [<c01e65fc>] (tcp_v4_rcv+0x488/0x83c) from [<c01ca038>] (ip_local_deliver+0x100/
> 0x1fc)
> [<c01ca038>] (ip_local_deliver+0x100/0x1fc) from [<c01c9efc>] (ip_rcv+0x540/0x57
> c)
> [<c01c9efc>] (ip_rcv+0x540/0x57c) from [<c01ad490>] (__netif_receive_skb+0x32c/0
> x388)
> [<c01ad490>] (__netif_receive_skb+0x32c/0x388) from [<c01ad56c>] (process_backlo
> g+0x80/0x140)
> [<c01ad56c>] (process_backlog+0x80/0x140) from [<c01ad8a4>] (net_rx_action+0x58/
> 0x180)
> [<c01ad8a4>] (net_rx_action+0x58/0x180) from [<c0037c50>] (__do_softirq+0x78/0x1
> 10)
> [<c0037c50>] (__do_softirq+0x78/0x110) from [<c0037d2c>] (irq_exit+0x44/0xa8)
> [<c0037d2c>] (irq_exit+0x44/0xa8) from [<c001f074>] (asm_do_IRQ+0x74/0x94)
> [<c001f074>] (asm_do_IRQ+0x74/0x94) from [<c0237050>] (__irq_svc+0x50/0x8c)
> Exception stack(0xc02e7f80 to 0xc02e7fc8)
> 7f80: 00000000 0005317f 0005217f 60000013 c02e6000 c001baf4 c001baf0 c02e9b60
> 7fa0: 4001a848 41069265 4001a7e0 00000000 600000d3 c02e7fc8 c0020bc4 c0020bd0
> 7fc0: 60000013 ffffffff
> [<c0237050>] (__irq_svc+0x50/0x8c) from [<c0020bd0>] (default_idle+0x2c/0x30)
> [<c0020bd0>] (default_idle+0x2c/0x30) from [<c002110c>] (cpu_idle+0x60/0xc0)
> [<c002110c>] (cpu_idle+0x60/0xc0) from [<c00088f0>] (start_kernel+0x238/0x27c)
> [<c00088f0>] (start_kernel+0x238/0x27c) from [<40008034>] (0x40008034)
> handlers:
> [<c01872e4>] (fec_enet_interrupt+0x0/0x3ec)
> Disabling IRQ #101
>
> However, when I add it into get_irqnr_and_base as below.
>
> .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
> mov \tmp, #0
> str \tmp, [\base]
> ldr \irqnr, [\base, #0x70]
> cmp \irqnr, #0x7F
> moveqs \irqnr, #0
> .endm
>
> Everything seems fine.
I think you need to do the following:
.macro get_irqnr_and_base, irqnr, irqstat, base, tmp
ldr \irqnr, [\base, #0x70]
cmp \irqnr, #0x7F
strne \irqnr, [\base]
moveq \irqnr, #0
.endm
(i.e. only write to VECTOR if there is an irq pending).
As before this is completely untested.
Another thing I just noticed is that you don't really want to hardcode
the 0x70, take a look into
arch/arm/mach-ns9xxx/include/mach/entry-macro.S for an example to avoid
it.
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 04/15] ARM: mxs: Add interrupt support
2010-12-08 12:09 ` Uwe Kleine-König
@ 2010-12-08 12:31 ` Shawn Guo
0 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-08 12:31 UTC (permalink / raw)
To: linux-arm-kernel
2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> On Wed, Dec 08, 2010 at 06:46:49PM +0800, Shawn Guo wrote:
>> Hi Uwe,
>>
>> 2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>> > Hello Shawn,
>> >
>> > On Wed, Dec 08, 2010 at 04:27:56PM +0800, Shawn Guo wrote:
>> >> 2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>> >> > On Wed, Dec 08, 2010 at 12:31:54AM +0800, Shawn Guo wrote:
>> >> [...]
>> >> >> +
>> >> >> +static void icoll_ack_irq(unsigned int irq)
>> >> >> +{
>> >> >> + ? ? __raw_writel(0, icoll_base + HW_ICOLL_VECTOR);
>> >> > You need to write this before handling the irq, no? ?Note this question
>> >> > is a repetition. ?You answered "No need, indeed. ?Will remove it."
>> >> > According to MCIMX28RM a write to HW_ICOLL_VECTOR "indicates the
>> >> > in-service state". ?Are you sure this is not needed? ?If no (i.e. it's
>> >> > needed) the write should go into entry-macro.S. ?As I don't have
>> >> > hardware yet I cannot test that. ?Maybe it's only needed when the
>> >> > priority levels are used?!
>> >> >
>> >> Sorry. I made a mistake. ?I thought I had tested the removal of line
>> >> and gave the comment, but actually not. The line is needed, and image
>> >> will stop working without the line.
>> >>
>> >> Regarding to moving the writing to register VECTOR into entry-macro.S,
>> >> can you please help me understand the reason behind the suggestion?
>> > Section 5.2.1 of MCIMX28RM writes:
>> >
>> > ? ? ? ?After the CPU enters the interrupt service routine, it must
>> > ? ? ? ?notify the interrupt collector as soon as possible. Software
>> > ? ? ? ?indicates the in-service state by writing to the HW_ICOLL_VECTOR
>> > ? ? ? ?register.
>> >
>> In case you will ask why, I would give the fact here. ?I'm not sure
>> what is your first thought. ?Mine is to add it into get_irqnr_preamble
>> as below.
>>
>> ? ? ? ? .macro ?get_irqnr_preamble, base, tmp
>> ? ? ? ? ldr ? ? \base, =ICOLL_ADDR
>> ? ? ? ? mov ? ? \tmp, #0
>> ? ? ? ? str ? ? \tmp, [\base]
>> ? ? ? ? .endm
> It's wrong to do that in get_irqnr_preamble.
>
>> But I got the following error.
>>
>> [...]
>> VFS: Mounted root (nfs filesystem) on device 0:11.
>> Freeing init memory: 92K
>> irq 101: nobody cared (try booting with the "irqpoll" option)
>> [<c0025084>] (unwind_backtrace+0x0/0xe4) from [<c0063d54>] (__report_bad_irq+0x3
>> 4/0x8c)
>> [<c0063d54>] (__report_bad_irq+0x34/0x8c) from [<c0063ef8>] (note_interrupt+0x14
>> c/0x1d8)
>> [<c0063ef8>] (note_interrupt+0x14c/0x1d8) from [<c0064d5c>] (handle_level_irq+0x
>> 108/0x198)
>> [<c0064d5c>] (handle_level_irq+0x108/0x198) from [<c001f070>] (asm_do_IRQ+0x70/0
>> x94)
>> [<c001f070>] (asm_do_IRQ+0x70/0x94) from [<c0237050>] (__irq_svc+0x50/0x8c)
>> Exception stack(0xc02e7d38 to 0xc02e7d80)
>> 7d20: ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? c02e7db0 00000000
>> 7d40: ffffffd0 00000000 c7990800 00000000 c79a3820 000005a8 c02e7df8 c0217380
>> 7d60: c7997a28 000005a8 00000000 c02e7d80 c02173a8 c02173c0 40000013 ffffffff
>> [<c0237050>] (__irq_svc+0x50/0x8c) from [<c02173c0>] (xs_tcp_data_recv+0x40/0x62
>> c)
>> [<c02173c0>] (xs_tcp_data_recv+0x40/0x62c) from [<c01d6160>] (tcp_read_sock+0x70
>> /0x1e8)
>> [<c01d6160>] (tcp_read_sock+0x70/0x1e8) from [<c021734c>] (xs_tcp_data_ready+0x7
>> c/0xb0)
>> [<c021734c>] (xs_tcp_data_ready+0x7c/0xb0) from [<c01dee3c>] (tcp_rcv_establishe
>> d+0x484/0x610)
>> [<c01dee3c>] (tcp_rcv_established+0x484/0x610) from [<c01e5fd4>] (tcp_v4_do_rcv+
>> 0x28/0x1c8)
>> [<c01e5fd4>] (tcp_v4_do_rcv+0x28/0x1c8) from [<c01e65fc>] (tcp_v4_rcv+0x488/0x83
>> c)
>> [<c01e65fc>] (tcp_v4_rcv+0x488/0x83c) from [<c01ca038>] (ip_local_deliver+0x100/
>> 0x1fc)
>> [<c01ca038>] (ip_local_deliver+0x100/0x1fc) from [<c01c9efc>] (ip_rcv+0x540/0x57
>> c)
>> [<c01c9efc>] (ip_rcv+0x540/0x57c) from [<c01ad490>] (__netif_receive_skb+0x32c/0
>> x388)
>> [<c01ad490>] (__netif_receive_skb+0x32c/0x388) from [<c01ad56c>] (process_backlo
>> g+0x80/0x140)
>> [<c01ad56c>] (process_backlog+0x80/0x140) from [<c01ad8a4>] (net_rx_action+0x58/
>> 0x180)
>> [<c01ad8a4>] (net_rx_action+0x58/0x180) from [<c0037c50>] (__do_softirq+0x78/0x1
>> 10)
>> [<c0037c50>] (__do_softirq+0x78/0x110) from [<c0037d2c>] (irq_exit+0x44/0xa8)
>> [<c0037d2c>] (irq_exit+0x44/0xa8) from [<c001f074>] (asm_do_IRQ+0x74/0x94)
>> [<c001f074>] (asm_do_IRQ+0x74/0x94) from [<c0237050>] (__irq_svc+0x50/0x8c)
>> Exception stack(0xc02e7f80 to 0xc02e7fc8)
>> 7f80: 00000000 0005317f 0005217f 60000013 c02e6000 c001baf4 c001baf0 c02e9b60
>> 7fa0: 4001a848 41069265 4001a7e0 00000000 600000d3 c02e7fc8 c0020bc4 c0020bd0
>> 7fc0: 60000013 ffffffff
>> [<c0237050>] (__irq_svc+0x50/0x8c) from [<c0020bd0>] (default_idle+0x2c/0x30)
>> [<c0020bd0>] (default_idle+0x2c/0x30) from [<c002110c>] (cpu_idle+0x60/0xc0)
>> [<c002110c>] (cpu_idle+0x60/0xc0) from [<c00088f0>] (start_kernel+0x238/0x27c)
>> [<c00088f0>] (start_kernel+0x238/0x27c) from [<40008034>] (0x40008034)
>> handlers:
>> [<c01872e4>] (fec_enet_interrupt+0x0/0x3ec)
>> Disabling IRQ #101
>>
>> However, when I add it into get_irqnr_and_base as below.
>>
>> ? ? ? ? .macro ?get_irqnr_and_base, irqnr, irqstat, base, tmp
>> ? ? ? ? mov ? ? \tmp, #0
>> ? ? ? ? str ? ? \tmp, [\base]
>> ? ? ? ? ldr ? ? \irqnr, [\base, #0x70]
>> ? ? ? ? cmp ? ? \irqnr, #0x7F
>> ? ? ? ? moveqs ?\irqnr, #0
>> ? ? ? ? .endm
>>
>> Everything seems fine.
>
> I think you need to do the following:
>
> ? ? ? ?.macro ?get_irqnr_and_base, irqnr, irqstat, base, tmp
> ? ? ? ?ldr ? ? \irqnr, [\base, #0x70]
> ? ? ? ?cmp ? ? \irqnr, #0x7F
> ? ? ? ?strne ? \irqnr, [\base]
> ? ? ? ?moveq ? \irqnr, #0
> ? ? ? ?.endm
>
> (i.e. only write to VECTOR if there is an irq pending).
>
> As before this is completely untested.
>
Tested. It's OK. Thanks Uwe.
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 05/15] ARM: mxs: Add low-level debug UART support
2010-12-07 16:31 ` [PATCH v2 05/15] ARM: mxs: Add low-level debug UART support Shawn Guo
@ 2010-12-08 20:27 ` Uwe Kleine-König
2010-12-09 2:02 ` Shawn Guo
0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-08 20:27 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Dec 08, 2010 at 12:31:55AM +0800, Shawn Guo wrote:
> - DEBUG_LL support, which is incompatible with single MXS image
maybe better: s/single/multi-soc/
> because of different DUART base address on MX23 and MX28
> - uncompress message support
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v2:
> - Remove incorrect comments
>
> arch/arm/mach-mxs/include/mach/debug-macro.S | 51 +++++++++++++++++
> arch/arm/mach-mxs/include/mach/uncompress.h | 78 ++++++++++++++++++++++++++
> 2 files changed, 129 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-mxs/include/mach/debug-macro.S
> create mode 100644 arch/arm/mach-mxs/include/mach/uncompress.h
>
> diff --git a/arch/arm/mach-mxs/include/mach/debug-macro.S b/arch/arm/mach-mxs/include/mach/debug-macro.S
> new file mode 100644
> index 0000000..efb3173
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/debug-macro.S
> @@ -0,0 +1,51 @@
> +/* arch/arm/mach-mxs/include/mach/debug-macro.S
> + *
> + * Debugging macro include header
> + *
> + * Copyright (C) 1994-1999 Russell King
> + * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
> + *
> + * 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>
> +
> +#ifdef CONFIG_SOC_IMX23
> +#ifdef UART_PADDR
> +#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
> +#endif
> +#define UART_PADDR MX23_DUART_BASE_ADDR
> +#endif
> +
> +#ifdef CONFIG_SOC_IMX28
> +#ifdef UART_PADDR
> +#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
> +#endif
> +#define UART_PADDR MX28_DUART_BASE_ADDR
> +#endif
> +
> +#define UART_VADDR MXS_IO_ADDRESS(UART_PADDR)
> +
> + .macro addruart, rp, rv
> + ldr \rp, =UART_PADDR @ physical
> + ldr \rv, =UART_VADDR @ virtual
> + .endm
> +
> + .macro senduart, rd, rx
> + str \rd, [\rx, #0x0] @ DR
> + .endm
> +
> + .macro waituart, rd, rx
> +1001: ldr \rd, [\rx, #0x18] @ FR
> + tst \rd, #1 << 5 @ FR_TXFF
> + bne 1001b
> + .endm
> +
> + .macro busyuart, rd, rx
> +1002: ldr \rd, [\rx, #0x18] @ FR
> + tst \rd, #1 << 3 @ FR_BUSY
> + beq 1002b
> + .endm
> diff --git a/arch/arm/mach-mxs/include/mach/uncompress.h b/arch/arm/mach-mxs/include/mach/uncompress.h
> new file mode 100644
> index 0000000..efdacc7
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/uncompress.h
> @@ -0,0 +1,78 @@
> +/*
> + * arch/arm/mach-mxs/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
> + * 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.
> + */
> +#ifndef __MACH_MXS_UNCOMPRESS_H__
> +#define __MACH_MXS_UNCOMPRESS_H__
> +
> +#define __MXS_BOOT_UNCOMPRESS
> +
> +#include <asm/mach-types.h>
> +
> +static unsigned long uart_base;
> +
> +#define UART(x) (*(volatile unsigned long *)(uart_base + (x)))
> +
> +#define DR 0x00
> +#define FR 0x18
> +#define FR_BUSY (1 << 3)
> +#define FR_TXFE (1 << 7)
> +#define CR 0x30
> +#define CR_UARTEN 1
Maybe namespace these? Maybe better define CR_UARTEN as (1 << 0) for
consistency?
> +
> +/*
> + * The following code assumes the serial port has already been
> + * initialized by the bootloader.
Maybe add:
* If it's not, the output is simply discarded.
> + */
> +
> +static void putc(int ch)
> +{
> + if (!uart_base)
> + return;
> + if (!(UART(CR) & CR_UARTEN))
> + return;
> +
> + while (!(UART(FR) & FR_TXFE))
> + barrier();
> +
> + UART(DR) = ch;
> +}
> +
> +static inline void flush(void)
> +{
> +}
> +
> +#define MX23_DUART_BASE_ADDR 0x80070000
> +#define MX28_DUART_BASE_ADDR 0x80074000
> +
> +static __inline__ void __arch_decomp_setup(unsigned long arch_id)
> +{
> + switch (arch_id) {
> + case MACH_TYPE_MX23EVK:
> + uart_base = MX23_DUART_BASE_ADDR;
> + break;
> + case MACH_TYPE_MX28EVK:
> + uart_base = MX28_DUART_BASE_ADDR;
> + break;
> + default:
> + break;
> + }
> +}
> +
> +#define arch_decomp_setup() __arch_decomp_setup(arch_id)
> +#define arch_decomp_wdog()
> +
> +#endif /* __MACH_MXS_UNCOMPRESS_H__ */
> --
> 1.7.1
>
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 14/15] ARM: mxs: Add initial mx28evk support
2010-12-07 16:32 ` [PATCH v2 14/15] ARM: mxs: Add initial mx28evk support Shawn Guo
@ 2010-12-08 20:28 ` Uwe Kleine-König
2010-12-09 7:04 ` Shawn Guo
0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-08 20:28 UTC (permalink / raw)
To: linux-arm-kernel
Hello Shawn,
On Wed, Dec 08, 2010 at 12:32:02AM +0800, Shawn Guo wrote:
> Add initial mx28evk support with duart and fec0.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v2:
> - Change function mx28evk_fec_reset() from inline to __init
> - Enable pll2 clock before phy operation
> - Add error checking for gpio_direction_output()
> - Save bytes by passing parameter into pr_err format string
> - Change mx28_add_fec0() to mx28_add_fec(0)
> - Remove boot_params
>
> arch/arm/mach-mxs/mach-mx28evk.c | 126 ++++++++++++++++++++++++++++++++++++++
> 1 files changed, 126 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-mxs/mach-mx28evk.c
>
> diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
> new file mode 100644
> index 0000000..3e8e37a
> --- /dev/null
> +++ b/arch/arm/mach-mxs/mach-mx28evk.c
> @@ -0,0 +1,126 @@
> +/*
> + * 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 <linux/clk.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-mx28.h"
> +#include "gpio.h"
> +
> +#define MX28EVK_FEC_PHY_POWER MXS_GPIO_NR(2, 15)
> +#define MX28EVK_FEC_PHY_RESET MXS_GPIO_NR(4, 13)
> +
> +static iomux_cfg_t mx28evk_pads[] = {
This can be const and __initconst, ditto for mx23evk
> + /* duart */
> + MX28_PAD_PWM0__DUART_RX,
> + MX28_PAD_PWM1__DUART_TX,
> +
> + /* fec0 */
> + 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 void __init mx28evk_fec_reset(void)
> +{
> + int ret;
> + struct clk *clk;
> +
> + /* Enable fec phy clock */
> + clk = clk_get_sys("pll2", NULL);
> + if (!IS_ERR(clk))
> + clk_enable(clk);
> +
> + /* Power up fec phy */
> + ret = gpio_request(MX28EVK_FEC_PHY_POWER, "fec-phy-power");
> + if (ret) {
> + pr_err("Failed to request gpio fec-phy-%s: %d\n", "power", ret);
> + return;
> + }
> +
> + ret = gpio_direction_output(MX28EVK_FEC_PHY_POWER, 0);
> + if (ret) {
> + pr_err("Failed to drive gpio fec-phy-%s: %d\n", "power", ret);
> + return;
> + }
> +
> + /* Reset fec phy */
> + ret = gpio_request(MX28EVK_FEC_PHY_RESET, "fec-phy-reset");
> + if (ret) {
> + pr_err("Failed to request gpio fec-phy-%s: %d\n", "reset", ret);
> + return;
> + }
> +
> + gpio_direction_output(MX28EVK_FEC_PHY_RESET, 0);
> + if (ret) {
> + pr_err("Failed to drive gpio fec-phy-%s: %d\n", "reset", ret);
> + return;
> + }
> +
> + mdelay(1);
> + gpio_set_value(MX28EVK_FEC_PHY_RESET, 1);
> +}
> +
> +static const struct fec_platform_data mx28_fec_pdata __initconst = {
> + .phy = PHY_INTERFACE_MODE_RMII,
> +};
> +
> +static void __init mx28evk_init(void)
> +{
> + mxs_iomux_setup_multiple_pads(mx28evk_pads, ARRAY_SIZE(mx28evk_pads));
> +
> + mx28_add_duart();
> +
> + mx28evk_fec_reset();
> + mx28_add_fec(0, &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. */
> + .map_io = mx28_map_io,
> + .init_irq = mx28_init_irq,
> + .init_machine = mx28evk_init,
> + .timer = &mx28evk_timer,
> +MACHINE_END
> --
> 1.7.1
>
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v3 03/15] ARM: mxs: Add reset routines
2010-12-08 7:33 ` Lothar Waßmann
@ 2010-12-08 20:31 ` Uwe Kleine-König
2010-12-09 8:51 ` Shawn Guo
0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-08 20:31 UTC (permalink / raw)
To: linux-arm-kernel
Hi Lothar,
On Wed, Dec 08, 2010 at 08:33:32AM +0100, Lothar Wa?mann wrote:
> Hi,
>
> Shawn Guo writes:
> > - The mxs wdog is implemented in RTC block.
> > - There is a generic software reset routine for most modules on mxs.
> >
> > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> > ---
> > Changes for v3:
> > - Change wdog timeout to 10ms for safety
> > - Simplify function mxs_reset_block() to get it look better
> >
> > Changes for v2:
> > - Move rtc clock enabling from arch_reset() into mxs_arch_reset_init()
> >
> mxs_arch_reset_init() is currently being called from the .map_io hook
> in mach-mxs/mm-mx23.c and mm-mx28.c which is called before clocks are
> registered.
> But IMO this should be removed from the .map_io hook anyway (as well
> as mxs_iomux_init()).
I assume you want to make this an initcall?
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 09/15] ARM: mxs: Add clock support
2010-12-07 16:31 ` [PATCH v2 09/15] ARM: mxs: Add clock support Shawn Guo
@ 2010-12-08 20:57 ` Uwe Kleine-König
2010-12-09 1:44 ` Shawn Guo
2010-12-09 8:41 ` Uwe Kleine-König
1 sibling, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-08 20:57 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Dec 08, 2010 at 12:31:59AM +0800, Shawn Guo wrote:
> Add clock for MXS-based SoCs, MX23 and MX28.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v2:
> - Shift pll0_clock freq 480MHz in children freq computation to avoid overflow
really?
> [...]
> +/*
> + * pll_clk
> + */
> +static unsigned long pll_clk_get_rate(struct clk *clk)
> +{
> + return 480000000;
pll's get_rate still returns 0x1c9c3800
> [...]
> +/*
> + * 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, FRAC, CPU)
ref_cpu_clk's get_rate still uses parent_rate * 18
> +_CLK_GET_RATE_REF(ref_emi_clk, FRAC, EMI)
> +_CLK_GET_RATE_REF(ref_pix_clk, FRAC, PIX)
> +_CLK_GET_RATE_REF(ref_io_clk, FRAC, IO)
> +
> +#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 = &pll_clk, \
> + }
> +
> +_DEFINE_CLOCK_REF(ref_cpu_clk, FRAC, CPU);
ref_cpu_clk's parent still is pll_clk
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 09/15] ARM: mxs: Add clock support
2010-12-08 20:57 ` Uwe Kleine-König
@ 2010-12-09 1:44 ` Shawn Guo
0 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 1:44 UTC (permalink / raw)
To: linux-arm-kernel
2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> On Wed, Dec 08, 2010 at 12:31:59AM +0800, Shawn Guo wrote:
>> Add clock for MXS-based SoCs, MX23 and MX28.
>>
>> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
>> ---
>> Changes for v2:
>> ?- Shift pll0_clock freq 480MHz in children freq computation to avoid overflow
> really?
>
>> [...]
>> +/*
>> + * pll_clk
>> + */
>> +static unsigned long pll_clk_get_rate(struct clk *clk)
>> +{
>> + ? ? return 480000000;
> pll's get_rate still returns 0x1c9c3800
>
>> [...]
>> +/*
>> + * 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, FRAC, CPU)
> ref_cpu_clk's get_rate still uses parent_rate * 18
>
>> +_CLK_GET_RATE_REF(ref_emi_clk, FRAC, EMI)
>> +_CLK_GET_RATE_REF(ref_pix_clk, FRAC, PIX)
>> +_CLK_GET_RATE_REF(ref_io_clk, FRAC, IO)
>> +
>> +#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 ? ? ? ? = &pll_clk, ? ? ? ? ? ? ? ? ? ? ? ? ? ? \
>> + ? ? }
>> +
>> +_DEFINE_CLOCK_REF(ref_cpu_clk, FRAC, CPU);
> ref_cpu_clk's parent still is pll_clk
>
My mistake. I only fixed clock-mx28.c and forgot clock-mx23.c.
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 05/15] ARM: mxs: Add low-level debug UART support
2010-12-08 20:27 ` Uwe Kleine-König
@ 2010-12-09 2:02 ` Shawn Guo
2010-12-09 8:42 ` Uwe Kleine-König
0 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 2:02 UTC (permalink / raw)
To: linux-arm-kernel
Hi Uwe,
2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> On Wed, Dec 08, 2010 at 12:31:55AM +0800, Shawn Guo wrote:
[...]
>> diff --git a/arch/arm/mach-mxs/include/mach/uncompress.h b/arch/arm/mach-mxs/include/mach/uncompress.h
>> new file mode 100644
>> index 0000000..efdacc7
>> --- /dev/null
>> +++ b/arch/arm/mach-mxs/include/mach/uncompress.h
>> @@ -0,0 +1,78 @@
>> +/*
>> + * ?arch/arm/mach-mxs/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
>> + * 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.
>> + */
>> +#ifndef __MACH_MXS_UNCOMPRESS_H__
>> +#define __MACH_MXS_UNCOMPRESS_H__
>> +
>> +#define __MXS_BOOT_UNCOMPRESS
>> +
>> +#include <asm/mach-types.h>
>> +
>> +static unsigned long uart_base;
>> +
>> +#define UART(x) (*(volatile unsigned long *)(uart_base + (x)))
>> +
>> +#define DR ? ? ? ? ? 0x00
>> +#define FR ? ? ? ? ? 0x18
>> +#define FR_BUSY ? ? ? ? ? ? ?(1 << 3)
>> +#define FR_TXFE ? ? ? ? ? ? ?(1 << 7)
>> +#define CR ? ? ? ? ? 0x30
>> +#define CR_UARTEN ? ?1
> Maybe namespace these? ?Maybe better define CR_UARTEN as (1 << 0) for
> consistency?
>
Are you expecting namespace "MXS_" or "DUART_" for better?
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 08/15] ARM: mxs: Add iomux support
2010-12-08 11:32 ` Lothar Waßmann
@ 2010-12-09 6:15 ` Shawn Guo
2010-12-09 8:43 ` Uwe Kleine-König
0 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 6:15 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Dec 8, 2010 at 7:32 PM, Lothar Wa?mann <LW@karo-electronics.de> wrote:
> Shawn Guo writes:
>> 2010/12/8 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>> > Hello,
>> >
>> > On Wed, Dec 08, 2010 at 06:52:36PM +0800, Shawn Guo wrote:
>> >> Hi Lothar,
>> >>
>> >> Thanks for the review.
>> >>
>> >> On Wed, Dec 8, 2010 at 3:25 PM, Lothar Wa?mann <LW@karo-electronics.de> wrote:
>> >> > Hi,
>> >> >
>> >> > Shawn Guo writes:
>> >> >> MXS-based SoCs implements iomux functions in block PINCTRL.
>> >> >>
>> >> >> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
>> >> >> ---
>> >> >> Changes for v2:
>> >> >> ?- Define iomux_cfg_t as u64
>> >> > ? ? ^^^^^^^^^^^^^^^^^^^^^^^^^
>> >> > Really?
>> >> >
>> >> >> +typedef struct pad_desc {
>> >> >> + ? ? unsigned bank:12;
>> >> >> + ? ? unsigned pin:20;
>> >> >> + ? ? unsigned muxsel:8;
>> >> >> + ? ? unsigned ma:12;
>> >> >> + ? ? unsigned vol:8;
>> >> >> + ? ? unsigned pull:4;
>> >> >> +} iomux_cfg_t;
>> >> > ^^^^^^^^^^^^^^^^^
>> >> >
>> >> I did not pick the correct word. ?What I meant is 64 bits. ?Since this
>> >> error is in change log, I would fix it if there is v3 of the patch.
>> > the idea was to really use an u64 to have the pin definitions modifyable.
>> >
>> Ah, I misunderstood the comments. ?But I did not see mxc switches to
>> u64. ?Do you have example to show what you want exactly?
>>
> See:
> http://lists.infradead.org/pipermail/linux-arm-kernel/2010-November/032202.html
>
Thanks, Lothar.
Hi Uwe,
Looking at the page Lothar gave, the patch is to facilitate adding
platform specific pad_ctrl settings to an
existing pad definition. In this case, it might be reasonable to keep
EXPORT_SYMBOL(mxs_iomux_setup_pad), which you asked me to remove.
What do you think?
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 14/15] ARM: mxs: Add initial mx28evk support
2010-12-08 20:28 ` Uwe Kleine-König
@ 2010-12-09 7:04 ` Shawn Guo
2010-12-09 8:32 ` Uwe Kleine-König
0 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 7:04 UTC (permalink / raw)
To: linux-arm-kernel
Hi Uwe,
2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Shawn,
>
> On Wed, Dec 08, 2010 at 12:32:02AM +0800, Shawn Guo wrote:
>> Add initial mx28evk support with duart and fec0.
>>
>> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
>> ---
>> Changes for v2:
>> ?- Change function mx28evk_fec_reset() from inline to __init
>> ?- Enable pll2 clock before phy operation
>> ?- Add error checking for gpio_direction_output()
>> ?- Save bytes by passing parameter into pr_err format string
>> ?- Change mx28_add_fec0() to mx28_add_fec(0)
>> ?- Remove boot_params
>>
>> ?arch/arm/mach-mxs/mach-mx28evk.c | ?126 ++++++++++++++++++++++++++++++++++++++
>> ?1 files changed, 126 insertions(+), 0 deletions(-)
>> ?create mode 100644 arch/arm/mach-mxs/mach-mx28evk.c
>>
>> diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
>> new file mode 100644
>> index 0000000..3e8e37a
>> --- /dev/null
>> +++ b/arch/arm/mach-mxs/mach-mx28evk.c
>> @@ -0,0 +1,126 @@
>> +/*
>> + * 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 <linux/clk.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-mx28.h"
>> +#include "gpio.h"
>> +
>> +#define MX28EVK_FEC_PHY_POWER ? ? ? ?MXS_GPIO_NR(2, 15)
>> +#define MX28EVK_FEC_PHY_RESET ? ? ? ?MXS_GPIO_NR(4, 13)
>> +
>> +static iomux_cfg_t mx28evk_pads[] = {
> This can be const and __initconst, ditto for mx23evk
>
With u64 iomux_cfg_t changes, I'm afraid the suggestion becomes invalid.
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 14/15] ARM: mxs: Add initial mx28evk support
2010-12-09 7:04 ` Shawn Guo
@ 2010-12-09 8:32 ` Uwe Kleine-König
2010-12-09 9:03 ` Shawn Guo
0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-09 8:32 UTC (permalink / raw)
To: linux-arm-kernel
Hello Shwan,
On Thu, Dec 09, 2010 at 03:04:37PM +0800, Shawn Guo wrote:
> 2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> > On Wed, Dec 08, 2010 at 12:32:02AM +0800, Shawn Guo wrote:
> >> +static iomux_cfg_t mx28evk_pads[] = {
> > This can be const and __initconst, ditto for mx23evk
> >
> With u64 iomux_cfg_t changes, I'm afraid the suggestion becomes invalid.
Really? Why?
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 09/15] ARM: mxs: Add clock support
2010-12-07 16:31 ` [PATCH v2 09/15] ARM: mxs: Add clock support Shawn Guo
2010-12-08 20:57 ` Uwe Kleine-König
@ 2010-12-09 8:41 ` Uwe Kleine-König
2010-12-09 10:04 ` Shawn Guo
2010-12-09 10:30 ` Shawn Guo
1 sibling, 2 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-09 8:41 UTC (permalink / raw)
To: linux-arm-kernel
Hello Shawn,
> +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 / 1000 * 18 / div * 1000; \
> +}
1000 isn't the most clever choice. It might be for a human, but not for
a machine.
I'd suggest (untested):
return SH_DIV((parent_rate >> 8) * 18, div, 8);
(don't know if 8 is a good value). What is the range of div here?
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 05/15] ARM: mxs: Add low-level debug UART support
2010-12-09 2:02 ` Shawn Guo
@ 2010-12-09 8:42 ` Uwe Kleine-König
0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-09 8:42 UTC (permalink / raw)
To: linux-arm-kernel
Hello Shawn,
On Thu, Dec 09, 2010 at 10:02:48AM +0800, Shawn Guo wrote:
> 2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> >> +#ifndef __MACH_MXS_UNCOMPRESS_H__
> >> +#define __MACH_MXS_UNCOMPRESS_H__
> >> +
> >> +#define __MXS_BOOT_UNCOMPRESS
is this used, BTW?
> >> +
> >> +#include <asm/mach-types.h>
> >> +
> >> +static unsigned long uart_base;
> >> +
> >> +#define UART(x) (*(volatile unsigned long *)(uart_base + (x)))
> >> +
> >> +#define DR ? ? ? ? ? 0x00
> >> +#define FR ? ? ? ? ? 0x18
> >> +#define FR_BUSY ? ? ? ? ? ? ?(1 << 3)
> >> +#define FR_TXFE ? ? ? ? ? ? ?(1 << 7)
> >> +#define CR ? ? ? ? ? 0x30
> >> +#define CR_UARTEN ? ?1
> > Maybe namespace these? ?Maybe better define CR_UARTEN as (1 << 0) for
> > consistency?
> >
> Are you expecting namespace "MXS_" or "DUART_" for better?
both?
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 08/15] ARM: mxs: Add iomux support
2010-12-09 6:15 ` Shawn Guo
@ 2010-12-09 8:43 ` Uwe Kleine-König
0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-09 8:43 UTC (permalink / raw)
To: linux-arm-kernel
Hello,
On Thu, Dec 09, 2010 at 02:15:27PM +0800, Shawn Guo wrote:
> >> Ah, I misunderstood the comments. ?But I did not see mxc switches to
> >> u64. ?Do you have example to show what you want exactly?
> >>
> > See:
> > http://lists.infradead.org/pipermail/linux-arm-kernel/2010-November/032202.html
> >
> Thanks, Lothar.
>
> Hi Uwe,
>
> Looking at the page Lothar gave, the patch is to facilitate adding
> platform specific pad_ctrl settings to an
> existing pad definition. In this case, it might be reasonable to keep
> EXPORT_SYMBOL(mxs_iomux_setup_pad), which you asked me to remove.
> What do you think?
Just don't make it static. There is no need for EXPORT_SYMBOL. Ditto
for the multiple variant.
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v3 03/15] ARM: mxs: Add reset routines
2010-12-08 20:31 ` Uwe Kleine-König
@ 2010-12-09 8:51 ` Shawn Guo
2010-12-09 8:55 ` Uwe Kleine-König
0 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 8:51 UTC (permalink / raw)
To: linux-arm-kernel
2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hi Lothar,
>
> On Wed, Dec 08, 2010 at 08:33:32AM +0100, Lothar Wa?mann wrote:
>> Hi,
>>
>> Shawn Guo writes:
>> > ?- The mxs wdog is implemented in RTC block.
>> > ?- There is a generic software reset routine for most modules on mxs.
>> >
>> > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
>> > ---
>> > Changes for v3:
>> > ?- Change wdog timeout to 10ms for safety
>> > ?- Simplify function mxs_reset_block() to get it look better
>> >
>> > Changes for v2:
>> > ?- Move rtc clock enabling from arch_reset() into mxs_arch_reset_init()
>> >
>> mxs_arch_reset_init() is currently being called from the .map_io hook
>> in mach-mxs/mm-mx23.c and mm-mx28.c which is called before clocks are
>> registered.
>> But IMO this should be removed from the .map_io hook anyway (as well
>> as mxs_iomux_init()).
> I assume you want to make this an initcall?
>
Here is how they look.
static int __init mxs_arch_reset_init(void)
{
struct clk *clk;
wdog_base = cpu_is_mx23() ? MX23_IO_ADDRESS(MX23_RTC_BASE_ADDR) :
MX28_IO_ADDRESS(MX28_RTC_BASE_ADDR);
clk = clk_get_sys("rtc", NULL);
if (!IS_ERR(clk))
clk_enable(clk);
else
return 0;
}
core_initcall(mxs_arch_reset_init);
static int __init mxs_iomux_init(void)
{
iomux_base = MXS_IO_ADDRESS(MXS_PINCTRL_BASE_ADDR);
return 0;
}
core_initcall(mxs_iomux_init);
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v3 03/15] ARM: mxs: Add reset routines
2010-12-09 8:51 ` Shawn Guo
@ 2010-12-09 8:55 ` Uwe Kleine-König
0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-09 8:55 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, Dec 09, 2010 at 04:51:08PM +0800, Shawn Guo wrote:
> static int __init mxs_iomux_init(void)
> {
> iomux_base = MXS_IO_ADDRESS(MXS_PINCTRL_BASE_ADDR);
>
> return 0;
> }
> core_initcall(mxs_iomux_init);
why not simply initialize iomux_base statically?
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 14/15] ARM: mxs: Add initial mx28evk support
2010-12-09 8:32 ` Uwe Kleine-König
@ 2010-12-09 9:03 ` Shawn Guo
2010-12-09 9:37 ` Uwe Kleine-König
0 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 9:03 UTC (permalink / raw)
To: linux-arm-kernel
Hi Uwe,
2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Shwan,
>
> On Thu, Dec 09, 2010 at 03:04:37PM +0800, Shawn Guo wrote:
>> 2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>> > On Wed, Dec 08, 2010 at 12:32:02AM +0800, Shawn Guo wrote:
>> >> +static iomux_cfg_t mx28evk_pads[] = {
>> > This can be const and __initconst, ditto for mx23evk
>> >
>> With u64 iomux_cfg_t changes, I'm afraid the suggestion becomes invalid.
> Really? Why?
>
I'm confused by the compiling error below when adding __initconst for
mx28evk_pads[], and mistakenly blaming u64 iomux_cfg_t changes.
arch/arm/mach-mxs/mach-mx28evk.c: In function ?mx28evk_init?:
arch/arm/mach-mxs/mach-mx28evk.c:34: error: mx28_fec_pdata causes a
section type conflict
make[1]: *** [arch/arm/mach-mxs/mach-mx28evk.o] Error 1
make: *** [arch/arm/mach-mxs] Error 2
Actually it can be fixed by the following change.
-static const struct fec_platform_data mx28_fec_pdata __initconst = {
+static struct fec_platform_data mx28_fec_pdata __initconst = {
.phy = PHY_INTERFACE_MODE_RMII,
};
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 14/15] ARM: mxs: Add initial mx28evk support
2010-12-09 9:03 ` Shawn Guo
@ 2010-12-09 9:37 ` Uwe Kleine-König
2010-12-09 10:17 ` Shawn Guo
0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-09 9:37 UTC (permalink / raw)
To: linux-arm-kernel
Hello Shawn
On Thu, Dec 09, 2010 at 05:03:54PM +0800, Shawn Guo wrote:
> 2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> > Hello Shwan,
ups, sorry for mistyping your name.
> > On Thu, Dec 09, 2010 at 03:04:37PM +0800, Shawn Guo wrote:
> >> 2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> >> > On Wed, Dec 08, 2010 at 12:32:02AM +0800, Shawn Guo wrote:
> >> >> +static iomux_cfg_t mx28evk_pads[] = {
> >> > This can be const and __initconst, ditto for mx23evk
> >> >
> >> With u64 iomux_cfg_t changes, I'm afraid the suggestion becomes invalid.
> > Really? Why?
> >
> I'm confused by the compiling error below when adding __initconst for
> mx28evk_pads[], and mistakenly blaming u64 iomux_cfg_t changes.
>
> arch/arm/mach-mxs/mach-mx28evk.c: In function ?mx28evk_init?:
> arch/arm/mach-mxs/mach-mx28evk.c:34: error: mx28_fec_pdata causes a
> section type conflict
> make[1]: *** [arch/arm/mach-mxs/mach-mx28evk.o] Error 1
> make: *** [arch/arm/mach-mxs] Error 2
>
> Actually it can be fixed by the following change.
>
> -static const struct fec_platform_data mx28_fec_pdata __initconst = {
> +static struct fec_platform_data mx28_fec_pdata __initconst = {
> .phy = PHY_INTERFACE_MODE_RMII,
> };
this change is wrong. You need to assert that all data being marked
with __initconst is const, too.
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 09/15] ARM: mxs: Add clock support
2010-12-09 8:41 ` Uwe Kleine-König
@ 2010-12-09 10:04 ` Shawn Guo
2010-12-09 10:30 ` Shawn Guo
1 sibling, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 10:04 UTC (permalink / raw)
To: linux-arm-kernel
Hi Uwe,
2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Shawn,
>
>> +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 / 1000 * 18 / div * 1000; ? ? ? ? ? ? ? ? ? ?\
>> +}
> 1000 isn't the most clever choice. ?It might be for a human, but not for
> a machine.
>
> I'd suggest (untested):
>
> ? ? ? ?return SH_DIV((parent_rate >> 8) * 18, div, 8);
>
> (don't know if 8 is a good value). ?What is the range of div here?
>
The div range is 18 ~ 35.
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 14/15] ARM: mxs: Add initial mx28evk support
2010-12-09 9:37 ` Uwe Kleine-König
@ 2010-12-09 10:17 ` Shawn Guo
2010-12-09 12:27 ` Lothar Waßmann
0 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 10:17 UTC (permalink / raw)
To: linux-arm-kernel
2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Shawn
> On Thu, Dec 09, 2010 at 05:03:54PM +0800, Shawn Guo wrote:
>> 2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>> > Hello Shwan,
> ups, sorry for mistyping your name.
>
>> > On Thu, Dec 09, 2010 at 03:04:37PM +0800, Shawn Guo wrote:
>> >> 2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>> >> > On Wed, Dec 08, 2010 at 12:32:02AM +0800, Shawn Guo wrote:
>> >> >> +static iomux_cfg_t mx28evk_pads[] = {
>> >> > This can be const and __initconst, ditto for mx23evk
>> >> >
>> >> With u64 iomux_cfg_t changes, I'm afraid the suggestion becomes invalid.
>> > Really? Why?
>> >
>> I'm confused by the compiling error below when adding __initconst for
>> mx28evk_pads[], and mistakenly blaming u64 iomux_cfg_t changes.
>>
>> arch/arm/mach-mxs/mach-mx28evk.c: In function ?mx28evk_init?:
>> arch/arm/mach-mxs/mach-mx28evk.c:34: error: mx28_fec_pdata causes a
>> section type conflict
>> make[1]: *** [arch/arm/mach-mxs/mach-mx28evk.o] Error 1
>> make: *** [arch/arm/mach-mxs] Error 2
>>
>> Actually it can be fixed by the following change.
>>
>> -static const struct fec_platform_data mx28_fec_pdata __initconst = {
>> +static struct fec_platform_data mx28_fec_pdata __initconst = {
>> ? ? ? ? ?.phy = PHY_INTERFACE_MODE_RMII,
>> ?};
> this change is wrong. ?You need to assert that all data being marked
> with __initconst is const, too.
>
After adding const for mx28evk_pads[], I got the following error.
CC arch/arm/mach-mxs/mach-mx28evk.o
arch/arm/mach-mxs/mach-mx28evk.c: In function ?mx28evk_init?:
arch/arm/mach-mxs/mach-mx28evk.c:102: warning: passing argument 1 of
?mxs_iomux_setup_multiple_pads? discards qualifiers from pointer
target type
arch/arm/mach-mxs/include/mach/iomux.h:115: note: expected
?iomux_cfg_t *? but argument is of type ?const iomux_cfg_t *?
This takes me back to my first judgment. Is it proper to add
__initconst for mx28evk_pads[]? We are changing iomux_cfg_t to u64 for
making pad definition modifiable.
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 09/15] ARM: mxs: Add clock support
2010-12-09 8:41 ` Uwe Kleine-König
2010-12-09 10:04 ` Shawn Guo
@ 2010-12-09 10:30 ` Shawn Guo
1 sibling, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 10:30 UTC (permalink / raw)
To: linux-arm-kernel
2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Shawn,
>
>> +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 / 1000 * 18 / div * 1000; ? ? ? ? ? ? ? ? ? ?\
>> +}
> 1000 isn't the most clever choice. ?It might be for a human, but not for
> a machine.
>
> I'd suggest (untested):
>
> ? ? ? ?return SH_DIV((parent_rate >> 8) * 18, div, 8);
>
> (don't know if 8 is a good value). ?What is the range of div here?
>
Tested.
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 14/15] ARM: mxs: Add initial mx28evk support
2010-12-09 10:17 ` Shawn Guo
@ 2010-12-09 12:27 ` Lothar Waßmann
2010-12-09 13:38 ` Shawn Guo
0 siblings, 1 reply; 146+ messages in thread
From: Lothar Waßmann @ 2010-12-09 12:27 UTC (permalink / raw)
To: linux-arm-kernel
Shawn Guo writes:
> 2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> > Hello Shawn
> > On Thu, Dec 09, 2010 at 05:03:54PM +0800, Shawn Guo wrote:
> >> 2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> >> > Hello Shwan,
> > ups, sorry for mistyping your name.
> >
> >> > On Thu, Dec 09, 2010 at 03:04:37PM +0800, Shawn Guo wrote:
> >> >> 2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> >> >> > On Wed, Dec 08, 2010 at 12:32:02AM +0800, Shawn Guo wrote:
> >> >> >> +static iomux_cfg_t mx28evk_pads[] = {
> >> >> > This can be const and __initconst, ditto for mx23evk
> >> >> >
> >> >> With u64 iomux_cfg_t changes, I'm afraid the suggestion becomes invalid.
> >> > Really? Why?
> >> >
> >> I'm confused by the compiling error below when adding __initconst for
> >> mx28evk_pads[], and mistakenly blaming u64 iomux_cfg_t changes.
> >>
> >> arch/arm/mach-mxs/mach-mx28evk.c: In function ?mx28evk_init?:
> >> arch/arm/mach-mxs/mach-mx28evk.c:34: error: mx28_fec_pdata causes a
> >> section type conflict
> >> make[1]: *** [arch/arm/mach-mxs/mach-mx28evk.o] Error 1
> >> make: *** [arch/arm/mach-mxs] Error 2
> >>
> >> Actually it can be fixed by the following change.
> >>
> >> -static const struct fec_platform_data mx28_fec_pdata __initconst = {
> >> +static struct fec_platform_data mx28_fec_pdata __initconst = {
> >> ? ? ? ? ?.phy = PHY_INTERFACE_MODE_RMII,
> >> ?};
> > this change is wrong. ?You need to assert that all data being marked
> > with __initconst is const, too.
> >
> After adding const for mx28evk_pads[], I got the following error.
>
> CC arch/arm/mach-mxs/mach-mx28evk.o
> arch/arm/mach-mxs/mach-mx28evk.c: In function ?mx28evk_init?:
> arch/arm/mach-mxs/mach-mx28evk.c:102: warning: passing argument 1 of
> ?mxs_iomux_setup_multiple_pads? discards qualifiers from pointer
> target type
> arch/arm/mach-mxs/include/mach/iomux.h:115: note: expected
> ?iomux_cfg_t *? but argument is of type ?const iomux_cfg_t *?
>
The argument of mxs_iomux_setup_multiple_pads() should get the const
attribute:
-int mxs_iomux_setup_multiple_pads(iomux_cfg_t *pad_list, unsigned count)
+int mxs_iomux_setup_multiple_pads(const iomux_cfg_t *pad_list, unsigned count)
> This takes me back to my first judgment. Is it proper to add
> __initconst for mx28evk_pads[]? We are changing iomux_cfg_t to u64 for
> making pad definition modifiable.
>
Modifiable in the sense that you can add platform specific PAD
settings by simply ORing them to the original pad definition so that
there is no need for runtime modifications like:
| iomux_v3_cfg_t power_key = MX51_PAD_EIM_A27__GPIO_2_21;
...
| power_key.pad_ctrl = MX51_GPIO_PAD_CTRL_2;
| mxc_iomux_v3_setup_pad(&power_key);
but you can do:
| iomux_v3_cfg_t power_key = (MX51_PAD_EIM_A27__GPIO_2_21 &
| ~MUX_PAD_CTRL_MASK) | MX51_GPIO_PAD_CTRL_2;
...
| mxc_iomux_v3_setup_pad(power_key);
instead. You can also augment the pad desc in a static table:
|static iomux_cfg_t pad_desc[] = {
| (MX51_PAD_EIM_A27__GPIO_2_21 & ~MUX_PAD_CTRL_MASK) | MX51_GPIO_PAD_CTRL_2,
Lothar Wa?mann
--
___________________________________________________________
Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996
www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 14/15] ARM: mxs: Add initial mx28evk support
2010-12-09 12:27 ` Lothar Waßmann
@ 2010-12-09 13:38 ` Shawn Guo
2010-12-09 13:54 ` Shawn Guo
0 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 13:38 UTC (permalink / raw)
To: linux-arm-kernel
Hi Lothar,
On Thu, Dec 9, 2010 at 8:27 PM, Lothar Wa?mann <LW@karo-electronics.de> wrote:
> Shawn Guo writes:
>> 2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>> > Hello Shawn
>> > On Thu, Dec 09, 2010 at 05:03:54PM +0800, Shawn Guo wrote:
>> >> 2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>> >> > Hello Shwan,
>> > ups, sorry for mistyping your name.
>> >
>> >> > On Thu, Dec 09, 2010 at 03:04:37PM +0800, Shawn Guo wrote:
>> >> >> 2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>> >> >> > On Wed, Dec 08, 2010 at 12:32:02AM +0800, Shawn Guo wrote:
>> >> >> >> +static iomux_cfg_t mx28evk_pads[] = {
>> >> >> > This can be const and __initconst, ditto for mx23evk
>> >> >> >
>> >> >> With u64 iomux_cfg_t changes, I'm afraid the suggestion becomes invalid.
>> >> > Really? Why?
>> >> >
>> >> I'm confused by the compiling error below when adding __initconst for
>> >> mx28evk_pads[], and mistakenly blaming u64 iomux_cfg_t changes.
>> >>
>> >> arch/arm/mach-mxs/mach-mx28evk.c: In function ?mx28evk_init?:
>> >> arch/arm/mach-mxs/mach-mx28evk.c:34: error: mx28_fec_pdata causes a
>> >> section type conflict
>> >> make[1]: *** [arch/arm/mach-mxs/mach-mx28evk.o] Error 1
>> >> make: *** [arch/arm/mach-mxs] Error 2
>> >>
>> >> Actually it can be fixed by the following change.
>> >>
>> >> -static const struct fec_platform_data mx28_fec_pdata __initconst = {
>> >> +static struct fec_platform_data mx28_fec_pdata __initconst = {
>> >> ? ? ? ? ?.phy = PHY_INTERFACE_MODE_RMII,
>> >> ?};
>> > this change is wrong. ?You need to assert that all data being marked
>> > with __initconst is const, too.
>> >
>> After adding const for mx28evk_pads[], I got the following error.
>>
>> ? CC ? ? ?arch/arm/mach-mxs/mach-mx28evk.o
>> arch/arm/mach-mxs/mach-mx28evk.c: In function ?mx28evk_init?:
>> arch/arm/mach-mxs/mach-mx28evk.c:102: warning: passing argument 1 of
>> ?mxs_iomux_setup_multiple_pads? discards qualifiers from pointer
>> target type
>> arch/arm/mach-mxs/include/mach/iomux.h:115: note: expected
>> ?iomux_cfg_t *? but argument is of type ?const iomux_cfg_t *?
>>
> The argument of mxs_iomux_setup_multiple_pads() should get the const
> attribute:
> -int mxs_iomux_setup_multiple_pads(iomux_cfg_t *pad_list, unsigned count)
> +int mxs_iomux_setup_multiple_pads(const iomux_cfg_t *pad_list, unsigned count)
>
>> This takes me back to my first judgment. ?Is it proper to add
>> __initconst for mx28evk_pads[]? We are changing iomux_cfg_t to u64 for
>> making pad definition modifiable.
>>
> Modifiable in the sense that you can add platform specific PAD
> settings by simply ORing them to the original pad definition so that
> there is no need for runtime modifications like:
> | ? ? ? iomux_v3_cfg_t power_key = MX51_PAD_EIM_A27__GPIO_2_21;
> ...
> | ? ? ? power_key.pad_ctrl = MX51_GPIO_PAD_CTRL_2;
> | ? ? ? mxc_iomux_v3_setup_pad(&power_key);
> but you can do:
> | ? ? ? iomux_v3_cfg_t power_key = (MX51_PAD_EIM_A27__GPIO_2_21 &
> | ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ~MUX_PAD_CTRL_MASK) | MX51_GPIO_PAD_CTRL_2;
> ...
> | ? ? ? mxc_iomux_v3_setup_pad(power_key);
> instead. You can also augment the pad desc in a static table:
> |static iomux_cfg_t pad_desc[] = {
> | ? ? ? (MX51_PAD_EIM_A27__GPIO_2_21 & ~MUX_PAD_CTRL_MASK) | MX51_GPIO_PAD_CTRL_2,
>
>
Thanks for the explanation. But I'm a little puzzled by the use of
"const" here. Per your suggestion, I have the following.
mach-28evk.c
static const iomux_cfg_t mx28evk_pads[] __initconst = {
iomux.h
int mxs_iomux_setup_multiple_pads(const iomux_cfg_t *pad_list, unsigned count);
iomux.c
int mxs_iomux_setup_multiple_pads(const iomux_cfg_t *pad_list, unsigned count)
Compiler complains as below.
CC arch/arm/mach-mxs/iomux.o
arch/arm/mach-mxs/iomux.c:89: error: conflicting types for
?mxs_iomux_setup_multiple_pads?
arch/arm/mach-mxs/include/mach/iomux.h:115: note: previous declaration
of ?mxs_iomux_setup_multiple_pads? was here
make[1]: *** [arch/arm/mach-mxs/iomux.o] Error 1
make: *** [arch/arm/mach-mxs] Error 2
If I remove the "const" in iomux.h as below.
iomux.h
int mxs_iomux_setup_multiple_pads(iomux_cfg_t *pad_list, unsigned count);
Compiler gives the following warning.
CC arch/arm/mach-mxs/mach-mx28evk.o
arch/arm/mach-mxs/mach-mx28evk.c: In function ?mx28evk_init?:
arch/arm/mach-mxs/mach-mx28evk.c:102: warning: passing argument 1 of
?mxs_iomux_setup_multiple_pads? discards qualifiers from pointer
target type
arch/arm/mach-mxs/include/mach/iomux.h:115: note: expected
?iomux_cfg_t *? but argument is of type ?const iomux_cfg_t *?
What's wrong here?
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v2 14/15] ARM: mxs: Add initial mx28evk support
2010-12-09 13:38 ` Shawn Guo
@ 2010-12-09 13:54 ` Shawn Guo
0 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 13:54 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, Dec 9, 2010 at 9:38 PM, Shawn Guo <shawn.gsc@gmail.com> wrote:
> Hi Lothar,
>
> On Thu, Dec 9, 2010 at 8:27 PM, Lothar Wa?mann <LW@karo-electronics.de> wrote:
>> Shawn Guo writes:
>>> 2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>>> > Hello Shawn
>>> > On Thu, Dec 09, 2010 at 05:03:54PM +0800, Shawn Guo wrote:
>>> >> 2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>>> >> > Hello Shwan,
>>> > ups, sorry for mistyping your name.
>>> >
>>> >> > On Thu, Dec 09, 2010 at 03:04:37PM +0800, Shawn Guo wrote:
>>> >> >> 2010/12/9 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
>>> >> >> > On Wed, Dec 08, 2010 at 12:32:02AM +0800, Shawn Guo wrote:
>>> >> >> >> +static iomux_cfg_t mx28evk_pads[] = {
>>> >> >> > This can be const and __initconst, ditto for mx23evk
>>> >> >> >
>>> >> >> With u64 iomux_cfg_t changes, I'm afraid the suggestion becomes invalid.
>>> >> > Really? Why?
>>> >> >
>>> >> I'm confused by the compiling error below when adding __initconst for
>>> >> mx28evk_pads[], and mistakenly blaming u64 iomux_cfg_t changes.
>>> >>
>>> >> arch/arm/mach-mxs/mach-mx28evk.c: In function ?mx28evk_init?:
>>> >> arch/arm/mach-mxs/mach-mx28evk.c:34: error: mx28_fec_pdata causes a
>>> >> section type conflict
>>> >> make[1]: *** [arch/arm/mach-mxs/mach-mx28evk.o] Error 1
>>> >> make: *** [arch/arm/mach-mxs] Error 2
>>> >>
>>> >> Actually it can be fixed by the following change.
>>> >>
>>> >> -static const struct fec_platform_data mx28_fec_pdata __initconst = {
>>> >> +static struct fec_platform_data mx28_fec_pdata __initconst = {
>>> >> ? ? ? ? ?.phy = PHY_INTERFACE_MODE_RMII,
>>> >> ?};
>>> > this change is wrong. ?You need to assert that all data being marked
>>> > with __initconst is const, too.
>>> >
>>> After adding const for mx28evk_pads[], I got the following error.
>>>
>>> ? CC ? ? ?arch/arm/mach-mxs/mach-mx28evk.o
>>> arch/arm/mach-mxs/mach-mx28evk.c: In function ?mx28evk_init?:
>>> arch/arm/mach-mxs/mach-mx28evk.c:102: warning: passing argument 1 of
>>> ?mxs_iomux_setup_multiple_pads? discards qualifiers from pointer
>>> target type
>>> arch/arm/mach-mxs/include/mach/iomux.h:115: note: expected
>>> ?iomux_cfg_t *? but argument is of type ?const iomux_cfg_t *?
>>>
>> The argument of mxs_iomux_setup_multiple_pads() should get the const
>> attribute:
>> -int mxs_iomux_setup_multiple_pads(iomux_cfg_t *pad_list, unsigned count)
>> +int mxs_iomux_setup_multiple_pads(const iomux_cfg_t *pad_list, unsigned count)
>>
>>> This takes me back to my first judgment. ?Is it proper to add
>>> __initconst for mx28evk_pads[]? We are changing iomux_cfg_t to u64 for
>>> making pad definition modifiable.
>>>
>> Modifiable in the sense that you can add platform specific PAD
>> settings by simply ORing them to the original pad definition so that
>> there is no need for runtime modifications like:
>> | ? ? ? iomux_v3_cfg_t power_key = MX51_PAD_EIM_A27__GPIO_2_21;
>> ...
>> | ? ? ? power_key.pad_ctrl = MX51_GPIO_PAD_CTRL_2;
>> | ? ? ? mxc_iomux_v3_setup_pad(&power_key);
>> but you can do:
>> | ? ? ? iomux_v3_cfg_t power_key = (MX51_PAD_EIM_A27__GPIO_2_21 &
>> | ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ~MUX_PAD_CTRL_MASK) | MX51_GPIO_PAD_CTRL_2;
>> ...
>> | ? ? ? mxc_iomux_v3_setup_pad(power_key);
>> instead. You can also augment the pad desc in a static table:
>> |static iomux_cfg_t pad_desc[] = {
>> | ? ? ? (MX51_PAD_EIM_A27__GPIO_2_21 & ~MUX_PAD_CTRL_MASK) | MX51_GPIO_PAD_CTRL_2,
>>
>>
> Thanks for the explanation. ?But I'm a little puzzled by the use of
> "const" here. Per your suggestion, I have the following.
>
> mach-28evk.c
> static const iomux_cfg_t mx28evk_pads[] __initconst = {
>
> iomux.h
> int mxs_iomux_setup_multiple_pads(const iomux_cfg_t *pad_list, unsigned count);
>
> iomux.c
> int mxs_iomux_setup_multiple_pads(const iomux_cfg_t *pad_list, unsigned count)
>
> Compiler complains as below.
>
> ?CC ? ? ?arch/arm/mach-mxs/iomux.o
> arch/arm/mach-mxs/iomux.c:89: error: conflicting types for
> ?mxs_iomux_setup_multiple_pads?
> arch/arm/mach-mxs/include/mach/iomux.h:115: note: previous declaration
> of ?mxs_iomux_setup_multiple_pads? was here
> make[1]: *** [arch/arm/mach-mxs/iomux.o] Error 1
> make: *** [arch/arm/mach-mxs] Error 2
>
> If I remove the "const" in iomux.h as below.
>
> iomux.h
> int mxs_iomux_setup_multiple_pads(iomux_cfg_t *pad_list, unsigned count);
>
> Compiler gives the following warning.
>
> ?CC ? ? ?arch/arm/mach-mxs/mach-mx28evk.o
> arch/arm/mach-mxs/mach-mx28evk.c: In function ?mx28evk_init?:
> arch/arm/mach-mxs/mach-mx28evk.c:102: warning: passing argument 1 of
> ?mxs_iomux_setup_multiple_pads? discards qualifiers from pointer
> target type
> arch/arm/mach-mxs/include/mach/iomux.h:115: note: expected
> ?iomux_cfg_t *? but argument is of type ?const iomux_cfg_t *?
>
> What's wrong here?
>
Sorry. Please ignore this message.
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v4 01/15] ARM: mxs: Add core definitions
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (32 preceding siblings ...)
2010-12-07 16:32 ` [PATCH v3 15/15] ARM: mxs: Add build configuration for mxs Shawn Guo
@ 2010-12-09 15:12 ` Shawn Guo
2010-12-09 17:37 ` Russell King - ARM Linux
2010-12-09 15:12 ` [PATCH v3 02/15] ARM: mxs: Add helper definition and function Shawn Guo
` (12 subsequent siblings)
46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 15:12 UTC (permalink / raw)
To: linux-arm-kernel
Add core definitions for MXS-based SoC MX23 and MX28.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v4:
- Move all MXS related definitions from hardware.h into mxs.h,
but have to keep hardware.h which is required by external file.
- Define IO addresses common to MXS-based in mxs.h
- Include hardware.h in mxs.h, include mxs.h in mx23.h and mx28.h,
so that files can include mxs.h, mx23.h, mx28.h individually
when necessary.
- Remove #include <linux/io.h> from mx23.h and mx28.h, since it's
not necessary.
Changes for v3:
- Update MXS_IO_P2V definition and comment to get them matched
- Sort mx23 base address definitions by offset
- Remove mx28 reserved IRQ definitions
- Remove unnecessary dummy definitions for cpu_is_mx23() and cpu_is_mx28()
Changes for v2:
- Remove MXS_IO_P2V_MODULE from hardware.h which is not needed
- Simplify MXS_IO_P2V_MODULE definition in hardware.h
- Remove unnecessary inclusion protection from hardware.h
- Change cpu_is_mx23/mx28() implementation in mxs.h to use machine_is_xxx
arch/arm/mach-mxs/include/mach/hardware.h | 29 +++++
arch/arm/mach-mxs/include/mach/irqs.h | 32 +++++
arch/arm/mach-mxs/include/mach/memory.h | 24 ++++
arch/arm/mach-mxs/include/mach/mx23.h | 145 ++++++++++++++++++++++
arch/arm/mach-mxs/include/mach/mx28.h | 188 +++++++++++++++++++++++++++++
arch/arm/mach-mxs/include/mach/mxs.h | 85 +++++++++++++
6 files changed, 503 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/include/mach/hardware.h
create mode 100644 arch/arm/mach-mxs/include/mach/irqs.h
create mode 100644 arch/arm/mach-mxs/include/mach/memory.h
create mode 100644 arch/arm/mach-mxs/include/mach/mx23.h
create mode 100644 arch/arm/mach-mxs/include/mach/mx28.h
create mode 100644 arch/arm/mach-mxs/include/mach/mxs.h
diff --git a/arch/arm/mach-mxs/include/mach/hardware.h b/arch/arm/mach-mxs/include/mach/hardware.h
new file mode 100644
index 0000000..53e89a0
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/hardware.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2004-2007 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
+ * 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_MXS_HARDWARE_H__
+#define __MACH_MXS_HARDWARE_H__
+
+#ifdef __ASSEMBLER__
+#define IOMEM(addr) (addr)
+#else
+#define IOMEM(addr) ((void __force __iomem *)(addr))
+#endif
+
+#endif /* __MACH_MXS_HARDWARE_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/irqs.h b/arch/arm/mach-mxs/include/mach/irqs.h
new file mode 100644
index 0000000..f771039
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/irqs.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2004-2007 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.
+ */
+
+#ifndef __MACH_MXS_IRQS_H__
+#define __MACH_MXS_IRQS_H__
+
+#define MXS_INTERNAL_IRQS 128
+
+#define MXS_GPIO_IRQ_START MXS_INTERNAL_IRQS
+
+/* the maximum for MXS-based */
+#define MXS_GPIO_IRQS (32 * 5)
+
+/*
+ * The next 16 interrupts are for board specific purposes. Since
+ * the kernel can only run on one machine at a time, we can re-use
+ * these. If you need more, increase MXS_BOARD_IRQS, but keep it
+ * within sensible limits.
+ */
+#define MXS_BOARD_IRQ_START (MXS_GPIO_IRQ_START + MXS_GPIO_IRQS)
+#define MXS_BOARD_IRQS 16
+
+#define NR_IRQS (MXS_BOARD_IRQ_START + MXS_BOARD_IRQS)
+
+#endif /* __MACH_MXS_IRQS_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/memory.h b/arch/arm/mach-mxs/include/mach/memory.h
new file mode 100644
index 0000000..b5420a5
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/memory.h
@@ -0,0 +1,24 @@
+/*
+ * 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_MXS_MEMORY_H__
+#define __MACH_MXS_MEMORY_H__
+
+#define PHYS_OFFSET UL(0x40000000)
+
+#endif /* __MACH_MXS_MEMORY_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mx23.h b/arch/arm/mach-mxs/include/mach/mx23.h
new file mode 100644
index 0000000..9edd02e
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mx23.h
@@ -0,0 +1,145 @@
+/*
+ * 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_MX23_H__
+#define __MACH_MX23_H__
+
+#include <mach/mxs.h>
+
+/*
+ * OCRAM
+ */
+#define MX23_OCRAM_BASE_ADDR 0x00000000
+#define MX23_OCRAM_SIZE SZ_32K
+
+/*
+ * IO
+ */
+#define MX23_IO_BASE_ADDR 0x80000000
+#define MX23_IO_SIZE SZ_1M
+
+#define MX23_ICOLL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x000000)
+#define MX23_APBH_DMA_BASE_ADDR (MX23_IO_BASE_ADDR + 0x004000)
+#define MX23_BCH_BASE_ADDR (MX23_IO_BASE_ADDR + 0x00a000)
+#define MX23_GPMI_BASE_ADDR (MX23_IO_BASE_ADDR + 0x00c000)
+#define MX23_SSP1_BASE_ADDR (MX23_IO_BASE_ADDR + 0x010000)
+#define MX23_PINCTRL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x018000)
+#define MX23_DIGCTL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x01c000)
+#define MX23_ETM_BASE_ADDR (MX23_IO_BASE_ADDR + 0x020000)
+#define MX23_APBX_DMA_BASE_ADDR (MX23_IO_BASE_ADDR + 0x024000)
+#define MX23_DCP_BASE_ADDR (MX23_IO_BASE_ADDR + 0x028000)
+#define MX23_PXP_BASE_ADDR (MX23_IO_BASE_ADDR + 0x02a000)
+#define MX23_OCOTP_BASE_ADDR (MX23_IO_BASE_ADDR + 0x02c000)
+#define MX23_AXI_AHB0_BASE_ADDR (MX23_IO_BASE_ADDR + 0x02e000)
+#define MX23_LCDIF_BASE_ADDR (MX23_IO_BASE_ADDR + 0x030000)
+#define MX23_SSP2_BASE_ADDR (MX23_IO_BASE_ADDR + 0x034000)
+#define MX23_TVENC_BASE_ADDR (MX23_IO_BASE_ADDR + 0x038000)
+#define MX23_CLKCTRL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x040000)
+#define MX23_SAIF0_BASE_ADDR (MX23_IO_BASE_ADDR + 0x042000)
+#define MX23_POWER_BASE_ADDR (MX23_IO_BASE_ADDR + 0x044000)
+#define MX23_SAIF1_BASE_ADDR (MX23_IO_BASE_ADDR + 0x046000)
+#define MX23_AUDIOOUT_BASE_ADDR (MX23_IO_BASE_ADDR + 0x048000)
+#define MX23_AUDIOIN_BASE_ADDR (MX23_IO_BASE_ADDR + 0x04c000)
+#define MX23_LRADC_BASE_ADDR (MX23_IO_BASE_ADDR + 0x050000)
+#define MX23_SPDIF_BASE_ADDR (MX23_IO_BASE_ADDR + 0x054000)
+#define MX23_I2C0_BASE_ADDR (MX23_IO_BASE_ADDR + 0x058000)
+#define MX23_RTC_BASE_ADDR (MX23_IO_BASE_ADDR + 0x05c000)
+#define MX23_PWM_BASE_ADDR (MX23_IO_BASE_ADDR + 0x064000)
+#define MX23_TIMROT_BASE_ADDR (MX23_IO_BASE_ADDR + 0x068000)
+#define MX23_AUART1_BASE_ADDR (MX23_IO_BASE_ADDR + 0x06c000)
+#define MX23_AUART2_BASE_ADDR (MX23_IO_BASE_ADDR + 0x06e000)
+#define MX23_DUART_BASE_ADDR (MX23_IO_BASE_ADDR + 0x070000)
+#define MX23_USBPHY_BASE_ADDR (MX23_IO_BASE_ADDR + 0x07c000)
+#define MX23_USBCTRL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x080000)
+#define MX23_DRAM_BASE_ADDR (MX23_IO_BASE_ADDR + 0x0e0000)
+
+#define MX23_IO_P2V(x) MXS_IO_P2V(x)
+#define MX23_IO_ADDRESS(x) IOMEM(MX23_IO_P2V(x))
+
+/*
+ * IRQ
+ */
+#define MX23_INT_DUART 0
+#define MX23_INT_COMMS_RX 1
+#define MX23_INT_COMMS_TX 1
+#define MX23_INT_SSP2_ERROR 2
+#define MX23_INT_VDD5V 3
+#define MX23_INT_HEADPHONE_SHORT 4
+#define MX23_INT_DAC_DMA 5
+#define MX23_INT_DAC_ERROR 6
+#define MX23_INT_ADC_DMA 7
+#define MX23_INT_ADC_ERROR 8
+#define MX23_INT_SPDIF_DMA 9
+#define MX23_INT_SAIF2_DMA 9
+#define MX23_INT_SPDIF_ERROR 10
+#define MX23_INT_SAIF1_IRQ 10
+#define MX23_INT_SAIF2_IRQ 10
+#define MX23_INT_USB_CTRL 11
+#define MX23_INT_USB_WAKEUP 12
+#define MX23_INT_GPMI_DMA 13
+#define MX23_INT_SSP1_DMA 14
+#define MX23_INT_SSP_ERROR 15
+#define MX23_INT_GPIO0 16
+#define MX23_INT_GPIO1 17
+#define MX23_INT_GPIO2 18
+#define MX23_INT_SAIF1_DMA 19
+#define MX23_INT_SSP2_DMA 20
+#define MX23_INT_ECC8_IRQ 21
+#define MX23_INT_RTC_ALARM 22
+#define MX23_INT_UARTAPP_TX_DMA 23
+#define MX23_INT_UARTAPP_INTERNAL 24
+#define MX23_INT_UARTAPP_RX_DMA 25
+#define MX23_INT_I2C_DMA 26
+#define MX23_INT_I2C_ERROR 27
+#define MX23_INT_TIMER0 28
+#define MX23_INT_TIMER1 29
+#define MX23_INT_TIMER2 30
+#define MX23_INT_TIMER3 31
+#define MX23_INT_BATT_BRNOUT 32
+#define MX23_INT_VDDD_BRNOUT 33
+#define MX23_INT_VDDIO_BRNOUT 34
+#define MX23_INT_VDD18_BRNOUT 35
+#define MX23_INT_TOUCH_DETECT 36
+#define MX23_INT_LRADC_CH0 37
+#define MX23_INT_LRADC_CH1 38
+#define MX23_INT_LRADC_CH2 39
+#define MX23_INT_LRADC_CH3 40
+#define MX23_INT_LRADC_CH4 41
+#define MX23_INT_LRADC_CH5 42
+#define MX23_INT_LRADC_CH6 43
+#define MX23_INT_LRADC_CH7 44
+#define MX23_INT_LCDIF_DMA 45
+#define MX23_INT_LCDIF_ERROR 46
+#define MX23_INT_DIGCTL_DEBUG_TRAP 47
+#define MX23_INT_RTC_1MSEC 48
+#define MX23_INT_DRI_DMA 49
+#define MX23_INT_DRI_ATTENTION 50
+#define MX23_INT_GPMI_ATTENTION 51
+#define MX23_INT_IR 52
+#define MX23_INT_DCP_VMI 53
+#define MX23_INT_DCP 54
+#define MX23_INT_BCH 56
+#define MX23_INT_PXP 57
+#define MX23_INT_UARTAPP2_TX_DMA 58
+#define MX23_INT_UARTAPP2_INTERNAL 59
+#define MX23_INT_UARTAPP2_RX_DMA 60
+#define MX23_INT_VDAC_DETECT 61
+#define MX23_INT_VDD5V_DROOP 64
+#define MX23_INT_DCDC4P2_BO 65
+
+#endif /* __MACH_MX23_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mx28.h b/arch/arm/mach-mxs/include/mach/mx28.h
new file mode 100644
index 0000000..0716745
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mx28.h
@@ -0,0 +1,188 @@
+/*
+ * 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__
+
+#include <mach/mxs.h>
+
+/*
+ * 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_MAC0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0f0000)
+#define MX28_ENET_MAC1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0f4000)
+
+#define MX28_IO_P2V(x) MXS_IO_P2V(x)
+#define MX28_IO_ADDRESS(x) IOMEM(MX28_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_CAN0 8
+#define MX28_INT_CAN1 9
+#define MX28_INT_LRADC_TOUCH 10
+#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_PERFMON 27
+#define MX28_INT_RTC_1MSEC 28
+#define MX28_INT_RTC_ALARM 29
+#define MX28_INT_COMMS 31
+#define MX28_INT_EMI_ERR 32
+#define MX28_INT_LCDIF 38
+#define MX28_INT_PXP 39
+#define MX28_INT_BCH 41
+#define MX28_INT_GPMI 42
+#define MX28_INT_SPDIF_ERROR 45
+#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_SAIF1 58
+#define MX28_INT_SAIF0 59
+#define MX28_INT_SPDIF_DMA 66
+#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_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_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_GPIO4 123
+#define MX28_INT_GPIO3 124
+#define MX28_INT_GPIO2 125
+#define MX28_INT_GPIO1 126
+#define MX28_INT_GPIO0 127
+
+#endif /* __MACH_MX28_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/mxs.h b/arch/arm/mach-mxs/include/mach/mxs.h
new file mode 100644
index 0000000..4212ab0
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mxs.h
@@ -0,0 +1,85 @@
+/*
+ * 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_MXS_H__
+#define __MACH_MXS_H__
+
+#include <asm/mach-types.h>
+#include <mach/hardware.h>
+
+/*
+ * MXS CPU types
+ */
+#define cpu_is_mx23() (machine_is_mx23evk())
+#define cpu_is_mx28() (machine_is_mx28evk())
+
+#define MXS_SET_ADDR 0x4
+#define MXS_CLR_ADDR 0x8
+#define MXS_TOG_ADDR 0xc
+
+/*
+ * IO addresses common to MXS-based
+ */
+#define MXS_IO_BASE_ADDR 0x80000000
+#define MXS_IO_SIZE SZ_1M
+
+#define MXS_ICOLL_BASE_ADDR (MXS_IO_BASE_ADDR + 0x000000)
+#define MXS_APBH_DMA_BASE_ADDR (MXS_IO_BASE_ADDR + 0x004000)
+#define MXS_BCH_BASE_ADDR (MXS_IO_BASE_ADDR + 0x00a000)
+#define MXS_GPMI_BASE_ADDR (MXS_IO_BASE_ADDR + 0x00c000)
+#define MXS_PINCTRL_BASE_ADDR (MXS_IO_BASE_ADDR + 0x018000)
+#define MXS_DIGCTL_BASE_ADDR (MXS_IO_BASE_ADDR + 0x01c000)
+#define MXS_APBX_DMA_BASE_ADDR (MXS_IO_BASE_ADDR + 0x024000)
+#define MXS_DCP_BASE_ADDR (MXS_IO_BASE_ADDR + 0x028000)
+#define MXS_PXP_BASE_ADDR (MXS_IO_BASE_ADDR + 0x02a000)
+#define MXS_OCOTP_BASE_ADDR (MXS_IO_BASE_ADDR + 0x02c000)
+#define MXS_AXI_AHB0_BASE_ADDR (MXS_IO_BASE_ADDR + 0x02e000)
+#define MXS_LCDIF_BASE_ADDR (MXS_IO_BASE_ADDR + 0x030000)
+#define MXS_CLKCTRL_BASE_ADDR (MXS_IO_BASE_ADDR + 0x040000)
+#define MXS_SAIF0_BASE_ADDR (MXS_IO_BASE_ADDR + 0x042000)
+#define MXS_POWER_BASE_ADDR (MXS_IO_BASE_ADDR + 0x044000)
+#define MXS_SAIF1_BASE_ADDR (MXS_IO_BASE_ADDR + 0x046000)
+#define MXS_LRADC_BASE_ADDR (MXS_IO_BASE_ADDR + 0x050000)
+#define MXS_SPDIF_BASE_ADDR (MXS_IO_BASE_ADDR + 0x054000)
+#define MXS_I2C0_BASE_ADDR (MXS_IO_BASE_ADDR + 0x058000)
+#define MXS_PWM_BASE_ADDR (MXS_IO_BASE_ADDR + 0x064000)
+#define MXS_TIMROT_BASE_ADDR (MXS_IO_BASE_ADDR + 0x068000)
+#define MXS_AUART1_BASE_ADDR (MXS_IO_BASE_ADDR + 0x06c000)
+#define MXS_AUART2_BASE_ADDR (MXS_IO_BASE_ADDR + 0x06e000)
+#define MXS_DRAM_BASE_ADDR (MXS_IO_BASE_ADDR + 0x0e0000)
+
+/*
+ * It maps the whole address space to [0xf4000000, 0xf50fffff].
+ *
+ * OCRAM 0x00000000+0x020000 -> 0xf4000000+0x020000
+ * IO 0x80000000+0x100000 -> 0xf5000000+0x100000
+ */
+#define MXS_IO_P2V(x) (0xf4000000 + \
+ (((x) & 0x80000000) >> 7) + \
+ (((x) & 0x000fffff)))
+
+#define MXS_IO_ADDRESS(x) IOMEM(MXS_IO_P2V(x))
+
+#define mxs_map_entry(soc, name, _type) { \
+ .virtual = soc ## _IO_P2V(soc ## _ ## name ## _BASE_ADDR), \
+ .pfn = __phys_to_pfn(soc ## _ ## name ## _BASE_ADDR), \
+ .length = soc ## _ ## name ## _SIZE, \
+ .type = _type, \
+}
+
+#endif /* __MACH_MXS_H__ */
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH v3 02/15] ARM: mxs: Add helper definition and function
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (33 preceding siblings ...)
2010-12-09 15:12 ` [PATCH v4 01/15] ARM: mxs: Add core definitions Shawn Guo
@ 2010-12-09 15:12 ` Shawn Guo
2010-12-09 15:12 ` [PATCH v4 03/15] ARM: mxs: Add reset routines Shawn Guo
` (11 subsequent siblings)
46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 15:12 UTC (permalink / raw)
To: linux-arm-kernel
Add helper definition and function for MXS-based.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
- Remove reference to mxs_arch_reset_init() from common.h,
since it becomes __initcall.
- icoll_init_irq() does not need to carry on icoll base address,
since MX23 and MX28 share the same one.
- mxs_timer_init() does not need to carry on timrot base address,
since MX23 and MX28 share the same one.
Changes for v2:
- Remove cpu.c and reference to mxs_set_cpu_type() from common.h
arch/arm/mach-mxs/include/mach/common.h | 31 ++++++++++++++++++++++++++++++
arch/arm/mach-mxs/include/mach/io.h | 22 +++++++++++++++++++++
arch/arm/mach-mxs/include/mach/timex.h | 21 ++++++++++++++++++++
arch/arm/mach-mxs/include/mach/vmalloc.h | 22 +++++++++++++++++++++
4 files changed, 96 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/include/mach/common.h
create mode 100644 arch/arm/mach-mxs/include/mach/io.h
create mode 100644 arch/arm/mach-mxs/include/mach/timex.h
create mode 100644 arch/arm/mach-mxs/include/mach/vmalloc.h
diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
new file mode 100644
index 0000000..59133eb
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/common.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2004-2007 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.
+ */
+
+#ifndef __MACH_MXS_COMMON_H__
+#define __MACH_MXS_COMMON_H__
+
+struct clk;
+
+extern int mxs_reset_block(void __iomem *);
+extern void mxs_timer_init(struct clk *, int);
+
+extern int mx23_register_gpios(void);
+extern int mx23_clocks_init(void);
+extern void mx23_map_io(void);
+extern void mx23_init_irq(void);
+
+extern int mx28_register_gpios(void);
+extern int mx28_clocks_init(void);
+extern void mx28_map_io(void);
+extern void mx28_init_irq(void);
+
+extern void icoll_init_irq(void);
+
+#endif /* __MACH_MXS_COMMON_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/io.h b/arch/arm/mach-mxs/include/mach/io.h
new file mode 100644
index 0000000..289b722
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/io.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2004-2007 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.
+ */
+
+#ifndef __MACH_MXS_IO_H__
+#define __MACH_MXS_IO_H__
+
+/* Allow IO space to be anywhere in the memory */
+#define IO_SPACE_LIMIT 0xffffffff
+
+/* io address mapping macro */
+#define __io(a) __typesafe_io(a)
+
+#define __mem_pci(a) (a)
+
+#endif /* __MACH_MXS_IO_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/timex.h b/arch/arm/mach-mxs/include/mach/timex.h
new file mode 100644
index 0000000..734ce89
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/timex.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 1999 ARM Limited
+ * Copyright 2004-2007 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.
+ */
+
+#ifndef __MACH_MXS_TIMEX_H__
+#define __MACH_MXS_TIMEX_H__
+
+#define CLOCK_TICK_RATE 32000 /* 32K */
+
+#endif /* __MACH_MXS_TIMEX_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/vmalloc.h b/arch/arm/mach-mxs/include/mach/vmalloc.h
new file mode 100644
index 0000000..103b016
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/vmalloc.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2000 Russell King.
+ * Copyright 2004-2007 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.
+ */
+
+#ifndef __MACH_MXS_VMALLOC_H__
+#define __MACH_MXS_VMALLOC_H__
+
+/* vmalloc ending address */
+#define VMALLOC_END 0xf4000000UL
+
+#endif /* __MACH_MXS_VMALLOC_H__ */
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH v4 03/15] ARM: mxs: Add reset routines
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (34 preceding siblings ...)
2010-12-09 15:12 ` [PATCH v3 02/15] ARM: mxs: Add helper definition and function Shawn Guo
@ 2010-12-09 15:12 ` Shawn Guo
2010-12-09 15:12 ` [PATCH v3 04/15] ARM: mxs: Add interrupt support Shawn Guo
` (10 subsequent siblings)
46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 15:12 UTC (permalink / raw)
To: linux-arm-kernel
- The mxs wdog is implemented in RTC block.
- There is a generic software reset routine for most modules on mxs.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v4:
- Add blank line above comment to make the code easy to read
- Tell compiler unlikely(ret)
- Make mxs_arch_reset_init __initcall
Changes for v3:
- Change wdog timeout to 10ms for safety
- Simplify function mxs_reset_block() to get it look better
Changes for v2:
- Move rtc clock enabling from arch_reset() into mxs_arch_reset_init()
arch/arm/mach-mxs/include/mach/system.h | 27 ++++++
arch/arm/mach-mxs/system.c | 142 +++++++++++++++++++++++++++++++
2 files changed, 169 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/include/mach/system.h
create mode 100644 arch/arm/mach-mxs/system.c
diff --git a/arch/arm/mach-mxs/include/mach/system.h b/arch/arm/mach-mxs/include/mach/system.h
new file mode 100644
index 0000000..0e42823
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/system.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright 2004-2008 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.
+ */
+
+#ifndef __MACH_MXS_SYSTEM_H__
+#define __MACH_MXS_SYSTEM_H__
+
+static inline void arch_idle(void)
+{
+ cpu_do_idle();
+}
+
+void arch_reset(char mode, const char *cmd);
+
+#endif /* __MACH_MXS_SYSTEM_H__ */
diff --git a/arch/arm/mach-mxs/system.c b/arch/arm/mach-mxs/system.c
new file mode 100644
index 0000000..bc73f9f
--- /dev/null
+++ b/arch/arm/mach-mxs/system.c
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ * Copyright 2006-2007,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
+ *
+ * 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/kernel.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+
+#include <asm/proc-fns.h>
+#include <asm/system.h>
+
+#include <mach/mx23.h>
+#include <mach/mx28.h>
+#include <mach/common.h>
+
+#define MXS_RTC_WATCHDOG 0x50
+#define MXS_WATCHDOG_EN (1 << 4)
+
+#define MXS_MODULE_CLKGATE (1 << 30)
+#define MXS_MODULE_SFTRST (1 << 31)
+
+static void __iomem *wdog_base;
+
+/*
+ * Reset the system. It is called by machine_restart().
+ */
+void arch_reset(char mode, const char *cmd)
+{
+ /* Set wdog timer 10 ms */
+ __raw_writel(10, wdog_base + MXS_RTC_WATCHDOG);
+
+ /* Enable wdog reset */
+ __raw_writel(MXS_WATCHDOG_EN, wdog_base + MXS_SET_ADDR);
+
+ /* Wait for reset to assert... */
+ mdelay(10);
+
+ pr_err("Watchdog reset failed to assert reset\n");
+
+ /* Delay to allow the serial port to show the message */
+ mdelay(50);
+
+ /* We'll take a jump through zero as a poor second */
+ cpu_reset(0);
+}
+
+static int __init mxs_arch_reset_init(void)
+{
+ struct clk *clk;
+
+ wdog_base = cpu_is_mx23() ? MX23_IO_ADDRESS(MX23_RTC_BASE_ADDR) :
+ MX28_IO_ADDRESS(MX28_RTC_BASE_ADDR);
+
+ clk = clk_get_sys("rtc", NULL);
+ if (!IS_ERR(clk))
+ clk_enable(clk);
+
+ return 0;
+}
+core_initcall(mxs_arch_reset_init);
+
+/*
+ * Clear the bit and poll it cleared. This is usually called with
+ * a reset address and mask being either SFTRST(bit 31) or CLKGATE
+ * (bit 30).
+ */
+static int clear_poll_bit(void __iomem *addr, u32 mask)
+{
+ int timeout = 0x400;
+
+ /* clear the bit */
+ __raw_writel(mask, addr + MXS_CLR_ADDR);
+
+ /*
+ * SFTRST needs 3 GPMI clocks to settle, the reference manual
+ * recommends to wait 1us.
+ */
+ udelay(1);
+
+ /* poll the bit becoming clear */
+ while ((__raw_readl(addr) & mask) && --timeout)
+ /* nothing */;
+
+ return !timeout;
+}
+
+int mxs_reset_block(void __iomem *reset_addr)
+{
+ int ret;
+ int timeout = 0x400;
+
+ /* clear and poll SFTRST */
+ ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
+ if (unlikely(ret))
+ goto error;
+
+ /* clear CLKGATE */
+ __raw_writel(MXS_MODULE_CLKGATE, reset_addr + MXS_CLR_ADDR);
+
+ /* set SFTRST to reset the block */
+ __raw_writel(MXS_MODULE_SFTRST, reset_addr + MXS_SET_ADDR);
+ udelay(1);
+
+ /* poll CLKGATE becoming set */
+ while ((!(__raw_readl(reset_addr) & MXS_MODULE_CLKGATE)) && --timeout)
+ /* nothing */;
+ if (unlikely(!timeout))
+ goto error;
+
+ /* clear and poll SFTRST */
+ ret = clear_poll_bit(reset_addr, MXS_MODULE_SFTRST);
+ if (unlikely(ret))
+ goto error;
+
+ /* clear and poll CLKGATE */
+ ret = clear_poll_bit(reset_addr, MXS_MODULE_CLKGATE);
+ if (unlikely(ret))
+ goto error;
+
+ return 0;
+
+error:
+ pr_err("%s(%p): module reset timeout\n", __func__, reset_addr);
+ return -ETIMEDOUT;
+}
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH v3 04/15] ARM: mxs: Add interrupt support
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (35 preceding siblings ...)
2010-12-09 15:12 ` [PATCH v4 03/15] ARM: mxs: Add reset routines Shawn Guo
@ 2010-12-09 15:12 ` Shawn Guo
2010-12-09 15:12 ` [PATCH v3 05/15] ARM: mxs: Add low-level debug UART support Shawn Guo
` (9 subsequent siblings)
46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 15:12 UTC (permalink / raw)
To: linux-arm-kernel
Add Interrupt Collector (ICOLL) support for MXS-based.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
- icoll.c: add #include <linux/io.h> as it's removed from mx23.h
and mx28.h
- Change inclusion of hardware.h to mxs.h
- Move writing to HW_ICOLL_VECTOR from icoll.c icoll_ack_irq()
into entry-macro.S get_irqnr_and_base
- icoll.c: add more words into comments for level 0 irq ack
- mx23 and mx28 share the same icoll base address, so hard-coding
of the address is ok
- entry-macro.S: define and use HW_ICOLL_STAT_OFFSET over 0x70
Changes for v2:
- Get icoll base in get_irqnr_preamble
- Check the case of single SoC build and use hard-coding address if possible
arch/arm/mach-mxs/icoll.c | 81 ++++++++++++++++++++++++++
arch/arm/mach-mxs/include/mach/entry-macro.S | 41 +++++++++++++
2 files changed, 122 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/icoll.c
create mode 100644 arch/arm/mach-mxs/include/mach/entry-macro.S
diff --git a/arch/arm/mach-mxs/icoll.c b/arch/arm/mach-mxs/icoll.c
new file mode 100644
index 0000000..5dd43ba
--- /dev/null
+++ b/arch/arm/mach-mxs/icoll.c
@@ -0,0 +1,81 @@
+/*
+ * 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 <linux/io.h>
+
+#include <mach/mxs.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
+
+static void __iomem *icoll_base = MXS_IO_ADDRESS(MXS_ICOLL_BASE_ADDR);
+
+static void icoll_ack_irq(unsigned int irq)
+{
+ /*
+ * The Interrupt Collector is able to prioritize irqs.
+ * Currently only level 0 is used. So acking can use
+ * BV_ICOLL_LEVELACK_IRQLEVELACK__LEVEL0 unconditionally.
+ */
+ __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 mxs_icoll_chip = {
+ .ack = icoll_ack_irq,
+ .mask = icoll_mask_irq,
+ .unmask = icoll_unmask_irq,
+};
+
+void __init icoll_init_irq(void)
+{
+ int i;
+
+ /*
+ * Interrupt Collector reset, which initializes the priority
+ * for each irq to level 0.
+ */
+ mxs_reset_block(icoll_base + HW_ICOLL_CTRL);
+
+ for (i = 0; i < MXS_INTERNAL_IRQS; i++) {
+ set_irq_chip(i, &mxs_icoll_chip);
+ set_irq_handler(i, handle_level_irq);
+ set_irq_flags(i, IRQF_VALID);
+ }
+}
diff --git a/arch/arm/mach-mxs/include/mach/entry-macro.S b/arch/arm/mach-mxs/include/mach/entry-macro.S
new file mode 100644
index 0000000..2f2a7cf
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/entry-macro.S
@@ -0,0 +1,41 @@
+/*
+ * Low-level IRQ helper macros for Freescale MXS-based
+ *
+ * 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 <mach/mxs.h>
+
+#define ICOLL_VBASE MXS_IO_ADDRESS(MXS_ICOLL_BASE_ADDR)
+#define HW_ICOLL_STAT_OFFSET 0x70
+
+ .macro disable_fiq
+ .endm
+
+ .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
+ ldr \irqnr, [\base, #HW_ICOLL_STAT_OFFSET]
+ cmp \irqnr, #0x7F
+ strne \irqnr, [\base]
+ moveqs \irqnr, #0
+ .endm
+
+ .macro get_irqnr_preamble, base, tmp
+ ldr \base, =ICOLL_VBASE
+ .endm
+
+ .macro arch_ret_to_user, tmp1, tmp2
+ .endm
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH v3 05/15] ARM: mxs: Add low-level debug UART support
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (36 preceding siblings ...)
2010-12-09 15:12 ` [PATCH v3 04/15] ARM: mxs: Add interrupt support Shawn Guo
@ 2010-12-09 15:12 ` Shawn Guo
2010-12-09 15:12 ` [PATCH v4 06/15] ARM: mxs: Add timer support Shawn Guo
` (8 subsequent siblings)
46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 15:12 UTC (permalink / raw)
To: linux-arm-kernel
- DEBUG_LL support, which is incompatible with multi-soc MXS image
because of different DUART base address on MX23 and MX28
- uncompress message support
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
- debug-macro.S: change inclusion of hardware.h to mx23.h plus mx28.h
- Remove #define __MXS_BOOT_UNCOMPRESS
- Add namespace MXS_DUART_ for macros
- Add comment "If it's not, the output is simply discarded."
Changes for v2:
- Remove incorrect comments
arch/arm/mach-mxs/include/mach/debug-macro.S | 52 ++++++++++++++++++
arch/arm/mach-mxs/include/mach/uncompress.h | 76 ++++++++++++++++++++++++++
2 files changed, 128 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/include/mach/debug-macro.S
create mode 100644 arch/arm/mach-mxs/include/mach/uncompress.h
diff --git a/arch/arm/mach-mxs/include/mach/debug-macro.S b/arch/arm/mach-mxs/include/mach/debug-macro.S
new file mode 100644
index 0000000..a1522fd
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/debug-macro.S
@@ -0,0 +1,52 @@
+/* arch/arm/mach-mxs/include/mach/debug-macro.S
+ *
+ * Debugging macro include header
+ *
+ * Copyright (C) 1994-1999 Russell King
+ * Moved from linux/arch/arm/kernel/debug.S by Ben Dooks
+ *
+ * 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/mx23.h>
+#include <mach/mx28.h>
+
+#ifdef CONFIG_SOC_IMX23
+#ifdef UART_PADDR
+#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
+#endif
+#define UART_PADDR MX23_DUART_BASE_ADDR
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+#ifdef UART_PADDR
+#error "CONFIG_DEBUG_LL is incompatible with multiple archs"
+#endif
+#define UART_PADDR MX28_DUART_BASE_ADDR
+#endif
+
+#define UART_VADDR MXS_IO_ADDRESS(UART_PADDR)
+
+ .macro addruart, rp, rv
+ ldr \rp, =UART_PADDR @ physical
+ ldr \rv, =UART_VADDR @ virtual
+ .endm
+
+ .macro senduart, rd, rx
+ str \rd, [\rx, #0x0] @ DR
+ .endm
+
+ .macro waituart, rd, rx
+1001: ldr \rd, [\rx, #0x18] @ FR
+ tst \rd, #1 << 5 @ FR_TXFF
+ bne 1001b
+ .endm
+
+ .macro busyuart, rd, rx
+1002: ldr \rd, [\rx, #0x18] @ FR
+ tst \rd, #1 << 3 @ FR_BUSY
+ beq 1002b
+ .endm
diff --git a/arch/arm/mach-mxs/include/mach/uncompress.h b/arch/arm/mach-mxs/include/mach/uncompress.h
new file mode 100644
index 0000000..793d92e
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/uncompress.h
@@ -0,0 +1,76 @@
+/*
+ * arch/arm/mach-mxs/include/mach/uncompress.h
+ *
+ * Copyright (C) 1999 ARM Limited
+ * Copyright (C) Shane Nay (shane@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
+ * 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.
+ */
+#ifndef __MACH_MXS_UNCOMPRESS_H__
+#define __MACH_MXS_UNCOMPRESS_H__
+
+#include <asm/mach-types.h>
+
+static unsigned long uart_base;
+
+#define UART(x) (*(volatile unsigned long *)(uart_base + (x)))
+
+#define MXS_DUART_DR 0x00
+#define MXS_DUART_FR 0x18
+#define MXS_DUART_FR_TXFE (1 << 7)
+#define MXS_DUART_CR 0x30
+#define MXS_DUART_CR_UARTEN (1 << 0)
+
+/*
+ * The following code assumes the serial port has already been
+ * initialized by the bootloader. If it's not, the output is
+ * simply discarded.
+ */
+
+static void putc(int ch)
+{
+ if (!uart_base)
+ return;
+ if (!(UART(MXS_DUART_CR) & MXS_DUART_CR_UARTEN))
+ return;
+
+ while (!(UART(MXS_DUART_FR) & MXS_DUART_FR_TXFE))
+ barrier();
+
+ UART(MXS_DUART_DR) = ch;
+}
+
+static inline void flush(void)
+{
+}
+
+#define MX23_DUART_BASE_ADDR 0x80070000
+#define MX28_DUART_BASE_ADDR 0x80074000
+
+static __inline__ void __arch_decomp_setup(unsigned long arch_id)
+{
+ switch (arch_id) {
+ case MACH_TYPE_MX23EVK:
+ uart_base = MX23_DUART_BASE_ADDR;
+ break;
+ case MACH_TYPE_MX28EVK:
+ uart_base = MX28_DUART_BASE_ADDR;
+ break;
+ default:
+ break;
+ }
+}
+
+#define arch_decomp_setup() __arch_decomp_setup(arch_id)
+#define arch_decomp_wdog()
+
+#endif /* __MACH_MXS_UNCOMPRESS_H__ */
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH v4 06/15] ARM: mxs: Add timer support
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (37 preceding siblings ...)
2010-12-09 15:12 ` [PATCH v3 05/15] ARM: mxs: Add low-level debug UART support Shawn Guo
@ 2010-12-09 15:12 ` Shawn Guo
2010-12-09 15:12 ` [PATCH v3 07/15] ARM: mxs: Add gpio support Shawn Guo
` (7 subsequent siblings)
46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 15:12 UTC (permalink / raw)
To: linux-arm-kernel
There are 2 versions of the timrot on Freescale MXS-based SoCs.
The v1 on MX23 only gets 16 bits counter, while v2 on MX28
extends the counter to 32 bits.
The implementation uses two timers, one for clock_event and
another for clocksource. MX28 uses timer0 and timer1, while
MX23 uses timer0 and timer3.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v4:
- Change inclusion of hardware.h to mxs.h
- Use two timers on MX28 also to simpify timrotv2_set_next_event()
- MX23 and MX28 share the common timrot base address, so it can be
a hard-assignment.
- Pass &clockevent_mxs to mxs_timer_interrupt via mxs_timer_irq.dev_id
- Fix code of setting far-far future
- Change printk to pr_info and pr_err
- Change timrotv2 min_delta_ns to 0xf
Changes for v3:
- Use term clock_event over next_event and clocksource over get_cycles
- Split BV_TIMROT_TIMCTRLn_SELECT__32KHZ_XTAL into two definitions for v1 and v2 respectively
- Turn timrot_get_cycles() into timrotv1_get_cycles() and timrotv2_get_cycles()
- Turn timrot_set_next_event() into timrotv1_set_next_event() and timrotv2_set_next_event()
- Skip flag IRQF_DISABLED
- Remove unncessary IRQ disabling in mxs_set_mode()
- Change shift of clocksource_mxs to 17
Changes for v2:
- Fix a bug in timrot_set_next_event(). It should read
HW_TIMROT_RUNNING_COUNTn to get the current counts.
arch/arm/mach-mxs/timer.c | 270 +++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 270 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/timer.c
diff --git a/arch/arm/mach-mxs/timer.c b/arch/arm/mach-mxs/timer.c
new file mode 100644
index 0000000..75f2805
--- /dev/null
+++ b/arch/arm/mach-mxs/timer.c
@@ -0,0 +1,270 @@
+/*
+ * Copyright (C) 2000-2001 Deep Blue Solutions
+ * 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
+ * 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/interrupt.h>
+#include <linux/irq.h>
+#include <linux/clockchips.h>
+#include <linux/clk.h>
+
+#include <asm/mach/time.h>
+#include <mach/mxs.h>
+#include <mach/common.h>
+
+/*
+ * There are 2 versions of the timrot on Freescale MXS-based SoCs.
+ * The v1 on MX23 only gets 16 bits counter, while v2 on MX28
+ * extends the counter to 32 bits.
+ *
+ * The implementation uses two timers, one for clock_event and
+ * another for clocksource. MX28 uses timer0 and timer1, while
+ * MX23 uses timer0 and timer3.
+ */
+#define timrot_is_v1() (cpu_is_mx23())
+
+#define HW_TIMROT_ROTCTRL 0x00
+#define HW_TIMROT_TIMCTRLn(n) (0x20 + (n) * 0x40)
+#define HW_TIMROT_RUNNING_COUNTn(n) (0x30 + (n) * 0x40)
+#define HW_TIMROT_FIXED_COUNTn(n) (0x40 + (n) * 0x40)
+#define BM_TIMROT_TIMCTRLn_RELOAD (1 << 6)
+#define BM_TIMROT_TIMCTRLn_UPDATE (1 << 7)
+#define BM_TIMROT_TIMCTRLn_IRQ_EN (1 << 14)
+#define BM_TIMROT_TIMCTRLn_IRQ (1 << 15)
+#define BP_TIMROT_TIMCTRLn_SELECT 0
+#define BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL 0x8
+#define BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL 0xb
+
+static struct clock_event_device clockevent_mxs;
+static enum clock_event_mode clockevent_mode = CLOCK_EVT_MODE_UNUSED;
+
+static void __iomem *timer_base = MXS_IO_ADDRESS(MXS_TIMROT_BASE_ADDR);
+
+static inline void timrot_irq_disable(void)
+{
+ __raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN,
+ timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_CLR_ADDR);
+}
+
+static inline void timrot_irq_enable(void)
+{
+ __raw_writel(BM_TIMROT_TIMCTRLn_IRQ_EN,
+ timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_SET_ADDR);
+}
+
+static void timrot_irq_acknowledge(void)
+{
+ __raw_writel(BM_TIMROT_TIMCTRLn_IRQ,
+ timer_base + HW_TIMROT_TIMCTRLn(0) + MXS_CLR_ADDR);
+}
+
+static cycle_t timrotv1_get_cycles(struct clocksource *cs)
+{
+ return ~((__raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(1))
+ & 0xffff0000) >> 16);
+}
+
+static cycle_t timrotv2_get_cycles(struct clocksource *cs)
+{
+ return ~__raw_readl(timer_base + HW_TIMROT_RUNNING_COUNTn(1));
+}
+
+static int timrotv1_set_next_event(unsigned long evt,
+ struct clock_event_device *dev)
+{
+ /* timrot decrements the count */
+ __raw_writel(evt, timer_base + HW_TIMROT_RUNNING_COUNTn(0));
+
+ return 0;
+}
+
+static int timrotv2_set_next_event(unsigned long evt,
+ struct clock_event_device *dev)
+{
+ /* timrot decrements the count */
+ __raw_writel(evt, timer_base + HW_TIMROT_FIXED_COUNTn(0));
+
+ return 0;
+}
+
+static irqreturn_t mxs_timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *evt = dev_id;
+
+ timrot_irq_acknowledge();
+ evt->event_handler(evt);
+
+ return IRQ_HANDLED;
+}
+
+static struct irqaction mxs_timer_irq = {
+ .name = "MXS Timer Tick",
+ .dev_id = &clockevent_mxs,
+ .flags = IRQF_TIMER | IRQF_IRQPOLL,
+ .handler = mxs_timer_interrupt,
+};
+
+#ifdef DEBUG
+static const char *clock_event_mode_label[] = {
+ [CLOCK_EVT_MODE_PERIODIC] = "CLOCK_EVT_MODE_PERIODIC",
+ [CLOCK_EVT_MODE_ONESHOT] = "CLOCK_EVT_MODE_ONESHOT",
+ [CLOCK_EVT_MODE_SHUTDOWN] = "CLOCK_EVT_MODE_SHUTDOWN",
+ [CLOCK_EVT_MODE_UNUSED] = "CLOCK_EVT_MODE_UNUSED"
+};
+#endif /* DEBUG */
+
+static void mxs_set_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+ /* Disable interrupt in timer module */
+ timrot_irq_disable();
+
+ if (mode != clockevent_mode) {
+ /* Set event time into the furthest future */
+ if (timrot_is_v1())
+ __raw_writel(0xffff,
+ timer_base + HW_TIMROT_RUNNING_COUNTn(1));
+ else
+ __raw_writel(0xffffffff,
+ timer_base + HW_TIMROT_FIXED_COUNTn(1));
+
+ /* Clear pending interrupt */
+ timrot_irq_acknowledge();
+ }
+
+#ifdef DEBUG
+ pr_info("%s: changing mode from %s to %s\n", __func__,
+ clock_event_mode_label[clockevent_mode],
+ clock_event_mode_label[mode]);
+#endif /* DEBUG */
+
+ /* Remember timer mode */
+ clockevent_mode = mode;
+
+ switch (mode) {
+ case CLOCK_EVT_MODE_PERIODIC:
+ pr_err("%s: Periodic mode is not implemented\n", __func__);
+ break;
+ case CLOCK_EVT_MODE_ONESHOT:
+ timrot_irq_enable();
+ break;
+ case CLOCK_EVT_MODE_SHUTDOWN:
+ case CLOCK_EVT_MODE_UNUSED:
+ case CLOCK_EVT_MODE_RESUME:
+ /* Left event sources disabled, no more interrupts appear */
+ break;
+ }
+}
+
+static struct clock_event_device clockevent_mxs = {
+ .name = "mxs_timrot",
+ .features = CLOCK_EVT_FEAT_ONESHOT,
+ .shift = 32,
+ .set_mode = mxs_set_mode,
+ .set_next_event = timrotv2_set_next_event,
+ .rating = 200,
+};
+
+static int __init mxs_clockevent_init(struct clk *timer_clk)
+{
+ unsigned int c = clk_get_rate(timer_clk);
+
+ clockevent_mxs.mult = div_sc(c, NSEC_PER_SEC, clockevent_mxs.shift);
+ clockevent_mxs.cpumask = cpumask_of(0);
+ if (timrot_is_v1()) {
+ clockevent_mxs.set_next_event = timrotv1_set_next_event;
+ clockevent_mxs.max_delta_ns =
+ clockevent_delta2ns(0xfffe, &clockevent_mxs);
+ clockevent_mxs.min_delta_ns =
+ clockevent_delta2ns(0xf, &clockevent_mxs);
+ } else {
+ clockevent_mxs.max_delta_ns =
+ clockevent_delta2ns(0xfffffffe, &clockevent_mxs);
+ clockevent_mxs.min_delta_ns =
+ clockevent_delta2ns(0xf, &clockevent_mxs);
+ }
+
+ clockevents_register_device(&clockevent_mxs);
+
+ return 0;
+}
+
+static struct clocksource clocksource_mxs = {
+ .name = "mxs_timer",
+ .rating = 200,
+ .read = timrotv2_get_cycles,
+ .mask = CLOCKSOURCE_MASK(32),
+ .shift = 17,
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+static int __init mxs_clocksource_init(struct clk *timer_clk)
+{
+ unsigned int c = clk_get_rate(timer_clk);
+
+ if (timrot_is_v1()) {
+ clocksource_mxs.read = timrotv1_get_cycles;
+ clocksource_mxs.mask = CLOCKSOURCE_MASK(16);
+ }
+ clocksource_mxs.mult = clocksource_hz2mult(c, clocksource_mxs.shift);
+ clocksource_register(&clocksource_mxs);
+
+ return 0;
+}
+
+void __init mxs_timer_init(struct clk *timer_clk, int irq)
+{
+ clk_enable(timer_clk);
+
+ /*
+ * Initialize timers to a known state
+ */
+ mxs_reset_block(timer_base + HW_TIMROT_ROTCTRL);
+
+ /* timer0 is for clock_event */
+ __raw_writel((timrot_is_v1() ?
+ BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL :
+ BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL) |
+ BM_TIMROT_TIMCTRLn_UPDATE |
+ BM_TIMROT_TIMCTRLn_IRQ_EN,
+ timer_base + HW_TIMROT_TIMCTRLn(0));
+
+ /* timer1 is for clocksource */
+ __raw_writel((timrot_is_v1() ?
+ BV_TIMROTv1_TIMCTRLn_SELECT__32KHZ_XTAL :
+ BV_TIMROTv2_TIMCTRLn_SELECT__32KHZ_XTAL) |
+ BM_TIMROT_TIMCTRLn_RELOAD,
+ timer_base + HW_TIMROT_TIMCTRLn(1));
+
+ /* set timer1 fixed count to the maximum */
+ if (timrot_is_v1())
+ __raw_writel(0xffff,
+ timer_base + HW_TIMROT_RUNNING_COUNTn(1));
+ else
+ __raw_writel(0xffffffff,
+ timer_base + HW_TIMROT_FIXED_COUNTn(1));
+
+ /* init and register the timer to the framework */
+ mxs_clocksource_init(timer_clk);
+ mxs_clockevent_init(timer_clk);
+
+ /* Make irqs happen */
+ setup_irq(irq, &mxs_timer_irq);
+}
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH v3 07/15] ARM: mxs: Add gpio support
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (38 preceding siblings ...)
2010-12-09 15:12 ` [PATCH v4 06/15] ARM: mxs: Add timer support Shawn Guo
@ 2010-12-09 15:12 ` Shawn Guo
2010-12-09 16:47 ` Lothar Waßmann
2010-12-09 15:12 ` [PATCH v3 08/15] ARM: mxs: Add iomux support Shawn Guo
` (6 subsequent siblings)
46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 15:12 UTC (permalink / raw)
To: linux-arm-kernel
MXS-based SoCs implement gpio support in block PINCTRL.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
- include/mach/gpio.h: remove the inclusion of hardware.h
- gpio.c: change inclusion of hardware.h to mx23.h plus mx28.h
- Remove spinlock totally since SET/CLE can be used in all the
gpio register access
Changes for v2:
- Create arch/arm/mach-mxs/gpio.h to accommodate stuff private for mach-mxs
- Use GPIO_INT_LEV_MASK and GPIO_INT_POL_MASK instead of constant
- Remove both edges IRQ support which is not needed
- Use SET and CLR register of PINCTRL_DOE in _set_gpio_direction()
- Use pr_info over printk(KERN_INFO)
arch/arm/mach-mxs/gpio.c | 321 +++++++++++++++++++++++++++++++++
arch/arm/mach-mxs/gpio.h | 33 ++++
arch/arm/mach-mxs/include/mach/gpio.h | 34 ++++
3 files changed, 388 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/gpio.c
create mode 100644 arch/arm/mach-mxs/gpio.h
create mode 100644 arch/arm/mach-mxs/include/mach/gpio.h
diff --git a/arch/arm/mach-mxs/gpio.c b/arch/arm/mach-mxs/gpio.c
new file mode 100644
index 0000000..d88acf3
--- /dev/null
+++ b/arch/arm/mach-mxs/gpio.c
@@ -0,0 +1,321 @@
+/*
+ * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
+ * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
+ *
+ * Based on code from Freescale,
+ * Copyright (C) 2004-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/init.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <mach/mx23.h>
+#include <mach/mx28.h>
+#include <asm-generic/bug.h>
+
+#include "gpio.h"
+
+static struct mxs_gpio_port *mxs_gpio_ports;
+static int gpio_table_size;
+
+#define PINCTRL_DOUT(n) ((cpu_is_mx23() ? 0x0500 : 0x0700) + (n) * 0x10)
+#define PINCTRL_DIN(n) ((cpu_is_mx23() ? 0x0600 : 0x0900) + (n) * 0x10)
+#define PINCTRL_DOE(n) ((cpu_is_mx23() ? 0x0700 : 0x0b00) + (n) * 0x10)
+#define PINCTRL_PIN2IRQ(n) ((cpu_is_mx23() ? 0x0800 : 0x1000) + (n) * 0x10)
+#define PINCTRL_IRQEN(n) ((cpu_is_mx23() ? 0x0900 : 0x1100) + (n) * 0x10)
+#define PINCTRL_IRQLEV(n) ((cpu_is_mx23() ? 0x0a00 : 0x1200) + (n) * 0x10)
+#define PINCTRL_IRQPOL(n) ((cpu_is_mx23() ? 0x0b00 : 0x1300) + (n) * 0x10)
+#define PINCTRL_IRQSTAT(n) ((cpu_is_mx23() ? 0x0c00 : 0x1400) + (n) * 0x10)
+
+#define GPIO_INT_FALL_EDGE 0x0
+#define GPIO_INT_LOW_LEV 0x1
+#define GPIO_INT_RISE_EDGE 0x2
+#define GPIO_INT_HIGH_LEV 0x3
+#define GPIO_INT_LEV_MASK (1 << 0)
+#define GPIO_INT_POL_MASK (1 << 1)
+
+/* Note: This driver assumes 32 GPIOs are handled in one register */
+
+static void _clear_gpio_irqstatus(struct mxs_gpio_port *port, u32 index)
+{
+ __raw_writel(1 << index,
+ port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR_ADDR);
+}
+
+static void _set_gpio_irqenable(struct mxs_gpio_port *port, u32 index,
+ int enable)
+{
+ if (enable == 0) {
+ __raw_writel(1 << index,
+ port->base + PINCTRL_PIN2IRQ(port->id) + MXS_CLR_ADDR);
+ __raw_writel(1 << index,
+ port->base + PINCTRL_IRQEN(port->id) + MXS_CLR_ADDR);
+ } else {
+ __raw_writel(1 << index,
+ port->base + PINCTRL_PIN2IRQ(port->id) + MXS_SET_ADDR);
+ __raw_writel(1 << index,
+ port->base + PINCTRL_IRQEN(port->id) + MXS_SET_ADDR);
+ }
+}
+
+static void gpio_ack_irq(u32 irq)
+{
+ u32 gpio = irq_to_gpio(irq);
+ _clear_gpio_irqstatus(&mxs_gpio_ports[gpio / 32], gpio & 0x1f);
+}
+
+static void gpio_mask_irq(u32 irq)
+{
+ u32 gpio = irq_to_gpio(irq);
+ _set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 0);
+}
+
+static void gpio_unmask_irq(u32 irq)
+{
+ u32 gpio = irq_to_gpio(irq);
+ _set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 1);
+}
+
+static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset);
+
+static int gpio_set_irq_type(u32 irq, u32 type)
+{
+ u32 gpio = irq_to_gpio(irq);
+ struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32];
+ int edge;
+
+ switch (type) {
+ case IRQ_TYPE_EDGE_RISING:
+ edge = GPIO_INT_RISE_EDGE;
+ break;
+ case IRQ_TYPE_EDGE_FALLING:
+ edge = GPIO_INT_FALL_EDGE;
+ break;
+ case IRQ_TYPE_LEVEL_LOW:
+ edge = GPIO_INT_LOW_LEV;
+ break;
+ case IRQ_TYPE_LEVEL_HIGH:
+ edge = GPIO_INT_HIGH_LEV;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* set level or edge */
+ if (edge & GPIO_INT_LEV_MASK)
+ __raw_writel(1 << (gpio & 31),
+ port->base + PINCTRL_IRQLEV(port->id) + MXS_SET_ADDR);
+ else
+ __raw_writel(1 << (gpio & 31),
+ port->base + PINCTRL_IRQLEV(port->id) + MXS_CLR_ADDR);
+
+ /* set polarity */
+ if (edge & GPIO_INT_POL_MASK)
+ __raw_writel(1 << (gpio & 31),
+ port->base + PINCTRL_IRQPOL(port->id) + MXS_SET_ADDR);
+ else
+ __raw_writel(1 << (gpio & 31),
+ port->base + PINCTRL_IRQPOL(port->id) + MXS_CLR_ADDR);
+
+ _clear_gpio_irqstatus(port, gpio & 0x1f);
+
+ return 0;
+}
+
+/* MXS has one interrupt *per* gpio port */
+static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc)
+{
+ u32 irq_stat;
+ struct mxs_gpio_port *port = (struct mxs_gpio_port *)get_irq_data(irq);
+ u32 gpio_irq_no_base = port->virtual_irq_start;
+
+ irq_stat = __raw_readl(port->base + PINCTRL_IRQSTAT(port->id)) &
+ __raw_readl(port->base + PINCTRL_IRQEN(port->id)) &
+ __raw_readl(port->base + PINCTRL_PIN2IRQ(port->id));
+
+ while (irq_stat != 0) {
+ int irqoffset = fls(irq_stat) - 1;
+ generic_handle_irq(gpio_irq_no_base + irqoffset);
+ irq_stat &= ~(1 << irqoffset);
+ }
+}
+
+/*
+ * Set interrupt number "irq" in the GPIO as a wake-up source.
+ * While system is running, all registered GPIO interrupts need to have
+ * wake-up enabled. When system is suspended, only selected GPIO interrupts
+ * need to have wake-up enabled.
+ * @param irq interrupt source number
+ * @param enable enable as wake-up if equal to non-zero
+ * @return This function returns 0 on success.
+ */
+static int gpio_set_wake_irq(u32 irq, u32 enable)
+{
+ u32 gpio = irq_to_gpio(irq);
+ u32 gpio_idx = gpio & 0x1f;
+ struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32];
+
+ if (enable) {
+ if (port->irq_high && (gpio_idx >= 16))
+ enable_irq_wake(port->irq_high);
+ else
+ enable_irq_wake(port->irq);
+ } else {
+ if (port->irq_high && (gpio_idx >= 16))
+ disable_irq_wake(port->irq_high);
+ else
+ disable_irq_wake(port->irq);
+ }
+
+ return 0;
+}
+
+static struct irq_chip gpio_irq_chip = {
+ .ack = gpio_ack_irq,
+ .mask = gpio_mask_irq,
+ .unmask = gpio_unmask_irq,
+ .set_type = gpio_set_irq_type,
+ .set_wake = gpio_set_wake_irq,
+};
+
+static void _set_gpio_direction(struct gpio_chip *chip, unsigned offset,
+ int dir)
+{
+ struct mxs_gpio_port *port =
+ container_of(chip, struct mxs_gpio_port, chip);
+
+ if (dir)
+ __raw_writel(1 << offset,
+ port->base + PINCTRL_DOE(port->id) + MXS_SET_ADDR);
+ else
+ __raw_writel(1 << offset,
+ port->base + PINCTRL_DOE(port->id) + MXS_CLR_ADDR);
+}
+
+static void mxs_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+ struct mxs_gpio_port *port =
+ container_of(chip, struct mxs_gpio_port, chip);
+
+ __raw_writel(1 << offset, port->base + PINCTRL_DOUT(port->id) +
+ (value ? MXS_SET_ADDR : MXS_CLR_ADDR));
+}
+
+static int mxs_gpio_get(struct gpio_chip *chip, unsigned offset)
+{
+ struct mxs_gpio_port *port =
+ container_of(chip, struct mxs_gpio_port, chip);
+
+ return (__raw_readl(port->base + PINCTRL_DIN(port->id)) >> offset) & 1;
+}
+
+static int mxs_gpio_direction_input(struct gpio_chip *chip, unsigned offset)
+{
+ _set_gpio_direction(chip, offset, 0);
+ return 0;
+}
+
+static int mxs_gpio_direction_output(struct gpio_chip *chip,
+ unsigned offset, int value)
+{
+ mxs_gpio_set(chip, offset, value);
+ _set_gpio_direction(chip, offset, 1);
+ return 0;
+}
+
+int __init mxs_gpio_init(struct mxs_gpio_port *port, int cnt)
+{
+ int i, j;
+
+ /* save for local usage */
+ mxs_gpio_ports = port;
+ gpio_table_size = cnt;
+
+ pr_info("MXS GPIO hardware\n");
+
+ for (i = 0; i < cnt; i++) {
+ /* disable the interrupt and clear the status */
+ __raw_writel(0, port[i].base +
+ PINCTRL_PIN2IRQ(i));
+ __raw_writel(0, port[i].base +
+ PINCTRL_IRQEN(i));
+ __raw_writel(~0, port[i].base +
+ PINCTRL_IRQSTAT(i) + MXS_CLR_ADDR);
+
+ for (j = port[i].virtual_irq_start;
+ j < port[i].virtual_irq_start + 32; j++) {
+ set_irq_chip(j, &gpio_irq_chip);
+ set_irq_handler(j, handle_level_irq);
+ set_irq_flags(j, IRQF_VALID);
+ }
+
+ /* register gpio chip */
+ port[i].chip.direction_input = mxs_gpio_direction_input;
+ port[i].chip.direction_output = mxs_gpio_direction_output;
+ port[i].chip.get = mxs_gpio_get;
+ port[i].chip.set = mxs_gpio_set;
+ port[i].chip.base = i * 32;
+ port[i].chip.ngpio = 32;
+
+ /* its a serious configuration bug when it fails */
+ BUG_ON( gpiochip_add(&port[i].chip) < 0 );
+
+ /* setup one handler for each entry */
+ set_irq_chained_handler(port[i].irq, mxs_gpio_irq_handler);
+ set_irq_data(port[i].irq, &port[i]);
+ }
+
+ return 0;
+}
+
+#define DEFINE_MXS_GPIO_PORT(soc, _id) \
+ { \
+ .chip.label = "gpio-" #_id, \
+ .id = _id, \
+ .irq = soc ## _INT_GPIO ## _id, \
+ .base = soc ## _IO_ADDRESS( \
+ soc ## _PINCTRL ## _BASE_ADDR), \
+ .virtual_irq_start = MXS_GPIO_IRQ_START + (_id) * 32, \
+ }
+
+#define DEFINE_REGISTER_FUNCTION(prefix) \
+int __init prefix ## _register_gpios(void) \
+{ \
+ return mxs_gpio_init(prefix ## _gpio_ports, \
+ ARRAY_SIZE(prefix ## _gpio_ports)); \
+}
+
+#ifdef CONFIG_SOC_IMX23
+static struct mxs_gpio_port mx23_gpio_ports[] = {
+ DEFINE_MXS_GPIO_PORT(MX23, 0),
+ DEFINE_MXS_GPIO_PORT(MX23, 1),
+ DEFINE_MXS_GPIO_PORT(MX23, 2),
+};
+DEFINE_REGISTER_FUNCTION(mx23)
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+static struct mxs_gpio_port mx28_gpio_ports[] = {
+ DEFINE_MXS_GPIO_PORT(MX28, 0),
+ DEFINE_MXS_GPIO_PORT(MX28, 1),
+ DEFINE_MXS_GPIO_PORT(MX28, 2),
+ DEFINE_MXS_GPIO_PORT(MX28, 3),
+ DEFINE_MXS_GPIO_PORT(MX28, 4),
+};
+DEFINE_REGISTER_FUNCTION(mx28)
+#endif
diff --git a/arch/arm/mach-mxs/gpio.h b/arch/arm/mach-mxs/gpio.h
new file mode 100644
index 0000000..49ed668
--- /dev/null
+++ b/arch/arm/mach-mxs/gpio.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2007 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
+ * 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 __MXS_GPIO_H__
+#define __MXS_GPIO_H__
+
+struct mxs_gpio_port {
+ void __iomem *base;
+ int id;
+ int irq;
+ int irq_high;
+ int virtual_irq_start;
+ struct gpio_chip chip;
+};
+
+int mxs_gpio_init(struct mxs_gpio_port*, int);
+
+#endif /* __MXS_GPIO_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/gpio.h b/arch/arm/mach-mxs/include/mach/gpio.h
new file mode 100644
index 0000000..0a80c32
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/gpio.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2007 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Juergen Beisert, kernel@pengutronix.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.
+ */
+
+#ifndef __MACH_MXS_GPIO_H__
+#define __MACH_MXS_GPIO_H__
+
+#include <asm-generic/gpio.h>
+
+#define MXS_GPIO_NR(bank, nr) ((bank) * 32 + (nr))
+
+/* use gpiolib dispatchers */
+#define gpio_get_value __gpio_get_value
+#define gpio_set_value __gpio_set_value
+#define gpio_cansleep __gpio_cansleep
+
+#define gpio_to_irq(gpio) (MXS_GPIO_IRQ_START + (gpio))
+#define irq_to_gpio(irq) ((irq) - MXS_GPIO_IRQ_START)
+
+#endif /* __MACH_MXS_GPIO_H__ */
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH v3 08/15] ARM: mxs: Add iomux support
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (39 preceding siblings ...)
2010-12-09 15:12 ` [PATCH v3 07/15] ARM: mxs: Add gpio support Shawn Guo
@ 2010-12-09 15:12 ` Shawn Guo
2010-12-09 16:12 ` Lothar Waßmann
2010-12-09 15:12 ` [PATCH v3 09/15] ARM: mxs: Add clock support Shawn Guo
` (5 subsequent siblings)
46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 15:12 UTC (permalink / raw)
To: linux-arm-kernel
MXS-based SoCs implements iomux functions in block PINCTRL.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
- Change iomux_cfg_t to u64 to facilitate adding platform specific
pad_ctrl settings to an existing pad definition
- Change inclusion of hardware.h to mxs.h
- Get iomux_base a hard-assignment in mxs_iomux_setup_pad(), since
mx23 and mx28 share the common pinctrl base adress and it's only
used in mxs_iomux_setup_pad().
- Remove EXPORT_SYMBOL and the static of mxs_iomux_setup_pad()
Changes for v2:
- Define iomux_cfg_t as u64
- Turn mxs_iomux_setup_pad() into a static function
- Fix a bug in mxs_iomux_setup_pad(), muxsel starts at offset 0x100 than 0 of pinctrl block.
arch/arm/mach-mxs/include/mach/iomux-mx23.h | 29 +++++++
arch/arm/mach-mxs/include/mach/iomux-mx28.h | 44 ++++++++++
arch/arm/mach-mxs/include/mach/iomux.h | 117 +++++++++++++++++++++++++++
arch/arm/mach-mxs/iomux.c | 103 +++++++++++++++++++++++
4 files changed, 293 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/include/mach/iomux-mx23.h
create mode 100644 arch/arm/mach-mxs/include/mach/iomux-mx28.h
create mode 100644 arch/arm/mach-mxs/include/mach/iomux.h
create mode 100644 arch/arm/mach-mxs/iomux.c
diff --git a/arch/arm/mach-mxs/include/mach/iomux-mx23.h b/arch/arm/mach-mxs/include/mach/iomux-mx23.h
new file mode 100644
index 0000000..3fc0439
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/iomux-mx23.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * 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
+ */
+
+#ifndef __MACH_IOMUX_MX23_H__
+#define __MACH_IOMUX_MX23_H__
+
+#include <mach/iomux.h>
+
+/*
+ * The naming convention for the pad modes is MX23_PAD_<padname>__<padmode>
+ * If <padname> or <padmode> refers to a GPIO, it is named GPIO_<unit>_<num>
+ * See also iomux.h
+ *
+ * BANK PIN MUX VOL MA PULL
+ */
+/* DUART */
+#define MX23_PAD_PWM0__DUART_RX IOMUX_PAD(1, 26, PAD_MUXSEL_2, PAD_VOL_NONE, PAD_4MA, PAD_NOPULL)
+#define MX23_PAD_PWM1__DUART_TX IOMUX_PAD(1, 27, PAD_MUXSEL_2, PAD_VOL_NONE, PAD_4MA, PAD_NOPULL)
+
+#endif /* __MACH_IOMUX_MX23_H__ */
diff --git a/arch/arm/mach-mxs/include/mach/iomux-mx28.h b/arch/arm/mach-mxs/include/mach/iomux-mx28.h
new file mode 100644
index 0000000..226bf41
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/iomux-mx28.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * 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
+ */
+
+#ifndef __MACH_IOMUX_MX28_H__
+#define __MACH_IOMUX_MX28_H__
+
+#include <mach/iomux.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.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_PULLUP)
+#define MX28_PAD_ENET0_MDIO__ENET0_MDIO IOMUX_PAD(4, 1, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
+#define MX28_PAD_ENET0_RX_EN__ENET0_RX_EN IOMUX_PAD(4, 2, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
+#define MX28_PAD_ENET0_RXD0__ENET0_RXD0 IOMUX_PAD(4, 3, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
+#define MX28_PAD_ENET0_RXD1__ENET0_RXD1 IOMUX_PAD(4, 4, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
+#define MX28_PAD_ENET0_TX_EN__ENET0_TX_EN IOMUX_PAD(4, 6, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
+#define MX28_PAD_ENET0_TXD0__ENET0_TXD0 IOMUX_PAD(4, 7, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
+#define MX28_PAD_ENET0_TXD1__ENET0_TXD1 IOMUX_PAD(4, 8, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
+#define MX28_PAD_ENET_CLK__ENET_CLK IOMUX_PAD(4, 16, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
+
+/* 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/mach-mxs/include/mach/iomux.h b/arch/arm/mach-mxs/include/mach/iomux.h
new file mode 100644
index 0000000..0939446
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/iomux.h
@@ -0,0 +1,117 @@
+/*
+ * 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_MXS_IOMUX_H__
+#define __MACH_MXS_IOMUX_H__
+
+/*
+ * IOMUX/PAD Bit field definitions
+ *
+ * PAD_BANK: 0..2 (3)
+ * PAD_PIN: 3..7 (5)
+ * PAD_MUXSEL: 8..9 (2)
+ * PAD_MA: 10..12 (3)
+ * PAD_VOL: 13..14 (2)
+ * PAD_PULL: 15 (1)
+ * RESERVED: 16..63 (48)
+ */
+typedef u64 iomux_cfg_t;
+
+#define PAD_BANK_SHIFT 0
+#define PAD_BANK_MASK ((iomux_cfg_t)0x7 << PAD_BANK_SHIFT)
+#define PAD_PIN_SHIFT 3
+#define PAD_PIN_MASK ((iomux_cfg_t)0x1f << PAD_PIN_SHIFT)
+#define PAD_MUXSEL_SHIFT 8
+#define PAD_MUXSEL_MASK ((iomux_cfg_t)0x3 << PAD_MUXSEL_SHIFT)
+#define PAD_MA_SHIFT 10
+#define PAD_MA_MASK ((iomux_cfg_t)0x7 << PAD_MA_SHIFT)
+#define PAD_VOL_SHIFT 13
+#define PAD_VOL_MASK ((iomux_cfg_t)0x3 << PAD_VOL_SHIFT)
+#define PAD_PULL_SHIFT 15
+#define PAD_PULL_MASK ((iomux_cfg_t)0x1 << PAD_PULL_SHIFT)
+
+#define IOMUX_PAD(_bank, _pin, _muxsel, _vol, _ma, _pull) \
+ (((iomux_cfg_t)(_bank) << PAD_BANK_SHIFT) | \
+ ((iomux_cfg_t)(_pin) << PAD_PIN_SHIFT) | \
+ ((iomux_cfg_t)(_muxsel) << PAD_MUXSEL_SHIFT) | \
+ ((iomux_cfg_t)(_vol) << PAD_VOL_SHIFT) | \
+ ((iomux_cfg_t)(_ma) << PAD_MA_SHIFT) | \
+ ((iomux_cfg_t)(_pull) << PAD_PULL_SHIFT))
+
+#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_PULLUP 1
+
+static inline unsigned int PAD_BANK(iomux_cfg_t pad)
+{
+ return (pad & PAD_BANK_MASK) >> PAD_BANK_SHIFT;
+}
+
+static inline unsigned int PAD_PIN(iomux_cfg_t pad)
+{
+ return (pad & PAD_PIN_MASK) >> PAD_PIN_SHIFT;
+}
+
+static inline unsigned int PAD_MUXSEL(iomux_cfg_t pad)
+{
+ return (pad & PAD_MUXSEL_MASK) >> PAD_MUXSEL_SHIFT;
+}
+
+static inline unsigned int PAD_MA(iomux_cfg_t pad)
+{
+ return (pad & PAD_MA_MASK) >> PAD_MA_SHIFT;
+}
+
+static inline unsigned int PAD_VOL(iomux_cfg_t pad)
+{
+ return (pad & PAD_VOL_MASK) >> PAD_VOL_SHIFT;
+}
+
+static inline unsigned int PAD_PULL(iomux_cfg_t pad)
+{
+ return (pad & PAD_PULL_MASK) >> PAD_PULL_SHIFT;
+}
+
+/*
+ * setups a single pad in the iomuxer
+ */
+int mxs_iomux_setup_pad(iomux_cfg_t pad);
+
+/*
+ * setups multiple pads
+ * convenient way to call the above function with tables
+ */
+int mxs_iomux_setup_multiple_pads(const iomux_cfg_t *pad_list, unsigned count);
+
+#endif /* __MACH_MXS_IOMUX_H__*/
diff --git a/arch/arm/mach-mxs/iomux.c b/arch/arm/mach-mxs/iomux.c
new file mode 100644
index 0000000..b6e63a4
--- /dev/null
+++ b/arch/arm/mach-mxs/iomux.c
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2004-2006,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/mxs.h>
+#include <mach/iomux.h>
+
+/*
+ * configures a single pad in the iomuxer
+ */
+int mxs_iomux_setup_pad(iomux_cfg_t pad)
+{
+ u32 reg, ofs, bp, bm;
+ void __iomem *iomux_base = MXS_IO_ADDRESS(MXS_PINCTRL_BASE_ADDR);
+
+ /* muxsel */
+ ofs = 0x100;
+ ofs += PAD_BANK(pad) * 0x20 + PAD_PIN(pad) / 16 * 0x10;
+ bp = PAD_PIN(pad) % 16 * 2;
+ bm = 0x3 << bp;
+ reg = __raw_readl(iomux_base + ofs);
+ reg &= ~bm;
+ reg |= PAD_MUXSEL(pad) << bp;
+ __raw_writel(reg, iomux_base + ofs);
+
+ /* drive */
+ ofs = cpu_is_mx23() ? 0x200 : 0x300;
+ ofs += PAD_BANK(pad) * 0x40 + PAD_PIN(pad) / 8 * 0x10;
+ /* ma */
+ if (PAD_MA(pad) != PAD_MA_NONE)
+ {
+ bp = PAD_PIN(pad) % 8 * 4;
+ bm = 0x3 << bp;
+ reg = __raw_readl(iomux_base + ofs);
+ reg &= ~bm;
+ reg |= PAD_MA(pad) << bp;
+ __raw_writel(reg, iomux_base + ofs);
+ }
+ /* vol */
+ if (PAD_VOL(pad) != PAD_VOL_NONE)
+ {
+ bp = PAD_PIN(pad) % 8 * 4 + 2;
+ bm = 0x1 << bp;
+ reg = __raw_readl(iomux_base + ofs);
+ reg &= ~bm;
+ reg |= PAD_VOL(pad) << bp;
+ __raw_writel(reg, iomux_base + ofs);
+ }
+
+ /* pull */
+ ofs = cpu_is_mx23() ? 0x400 : 0x600;
+ ofs += PAD_BANK(pad) * 0x10;
+ bp = PAD_PIN(pad);
+ bm = 0x1 << bp;
+ reg = __raw_readl(iomux_base + ofs);
+ reg &= ~bm;
+ reg |= PAD_PULL(pad) << bp;
+ __raw_writel(reg, iomux_base + ofs);
+
+ return 0;
+}
+
+int mxs_iomux_setup_multiple_pads(const iomux_cfg_t *pad_list, unsigned count)
+{
+ const iomux_cfg_t *p = pad_list;
+ int i;
+ int ret;
+
+ for (i = 0; i < count; i++) {
+ ret = mxs_iomux_setup_pad(*p);
+ if (ret)
+ return ret;
+ p++;
+ }
+
+ return 0;
+}
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH v3 09/15] ARM: mxs: Add clock support
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (40 preceding siblings ...)
2010-12-09 15:12 ` [PATCH v3 08/15] ARM: mxs: Add iomux support Shawn Guo
@ 2010-12-09 15:12 ` Shawn Guo
2010-12-09 21:11 ` Uwe Kleine-König
2010-12-09 15:12 ` [PATCH v2 10/15] ARM: mxs: Add static memory mapping Shawn Guo
` (4 subsequent siblings)
46 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 15:12 UTC (permalink / raw)
To: linux-arm-kernel
Add clock for MXS-based SoCs, MX23 and MX28.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
- Fix freq overflow in clock-mx23.c as well
- Fix the overflow using SH_DIV and shifting 8 bits
- Remove the inclusion of hardware.h and include mx23.h/mx28.h
Changes for v2:
- Shift pll0_clock freq 480MHz in children freq computation to avoid overflow
- Fix fec_clk to stand for fec clock than IEEE1588 time clock
- Add pll2_clk into clock lookups, as it's fec phy clock and needs to be on before reset phy
arch/arm/mach-mxs/clock-mx23.c | 526 ++++++++++++++++++++++
arch/arm/mach-mxs/clock-mx28.c | 734 +++++++++++++++++++++++++++++++
arch/arm/mach-mxs/clock.c | 200 +++++++++
arch/arm/mach-mxs/include/mach/clkdev.h | 7 +
arch/arm/mach-mxs/include/mach/clock.h | 64 +++
arch/arm/mach-mxs/regs-clkctrl-mx23.h | 455 +++++++++++++++++++
arch/arm/mach-mxs/regs-clkctrl-mx28.h | 663 ++++++++++++++++++++++++++++
7 files changed, 2649 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/clock-mx23.c
create mode 100644 arch/arm/mach-mxs/clock-mx28.c
create mode 100644 arch/arm/mach-mxs/clock.c
create mode 100644 arch/arm/mach-mxs/include/mach/clkdev.h
create mode 100644 arch/arm/mach-mxs/include/mach/clock.h
create mode 100644 arch/arm/mach-mxs/regs-clkctrl-mx23.h
create mode 100644 arch/arm/mach-mxs/regs-clkctrl-mx28.h
diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c
new file mode 100644
index 0000000..b2923da
--- /dev/null
+++ b/arch/arm/mach-mxs/clock-mx23.c
@@ -0,0 +1,526 @@
+/*
+ * 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 <linux/jiffies.h>
+
+#include <asm/clkdev.h>
+#include <asm/div64.h>
+
+#include <mach/mx23.h>
+#include <mach/common.h>
+#include <mach/clock.h>
+
+#include "regs-clkctrl-mx23.h"
+
+#define CLKCTRL_BASE_ADDR MX23_IO_ADDRESS(MX23_CLKCTRL_BASE_ADDR)
+#define DIGCTRL_BASE_ADDR MX23_IO_ADDRESS(MX23_DIGCTL_BASE_ADDR)
+
+#define PARENT_RATE_SHIFT 8
+
+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 pll_clk_get_rate(struct clk *clk)
+{
+ return 480000000;
+}
+
+static int pll_clk_enable(struct clk *clk)
+{
+ __raw_writel(BM_CLKCTRL_PLLCTRL0_POWER |
+ BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS,
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLLCTRL0_SET);
+
+ /* Only a 10us delay is need. PLLCTRL1 LOCK bitfied is only a timer
+ * and is incorrect (excessive). Per definition of the PLLCTRL0
+ * POWER field, waiting at least 10us.
+ */
+ udelay(10);
+
+ return 0;
+}
+
+static void pll_clk_disable(struct clk *clk)
+{
+ __raw_writel(BM_CLKCTRL_PLLCTRL0_POWER |
+ BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS,
+ CLKCTRL_BASE_ADDR + HW_CLKCTRL_PLLCTRL0_CLR);
+}
+
+static struct clk pll_clk = {
+ .get_rate = pll_clk_get_rate,
+ .enable = pll_clk_enable,
+ .disable = pll_clk_disable,
+ .parent = &ref_xtal_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 SH_DIV((parent_rate >> PARENT_RATE_SHIFT) * 18, \
+ div, PARENT_RATE_SHIFT); \
+}
+
+_CLK_GET_RATE_REF(ref_cpu_clk, FRAC, CPU)
+_CLK_GET_RATE_REF(ref_emi_clk, FRAC, EMI)
+_CLK_GET_RATE_REF(ref_pix_clk, FRAC, PIX)
+_CLK_GET_RATE_REF(ref_io_clk, FRAC, IO)
+
+#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 = &pll_clk, \
+ }
+
+_DEFINE_CLOCK_REF(ref_cpu_clk, FRAC, CPU);
+_DEFINE_CLOCK_REF(ref_emi_clk, FRAC, EMI);
+_DEFINE_CLOCK_REF(ref_pix_clk, FRAC, PIX);
+_DEFINE_CLOCK_REF(ref_io_clk, FRAC, IO);
+
+/*
+ * General clocks
+ *
+ * clk_get_rate
+ */
+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;
+}
+
+#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; \
+ \
+ return clk_get_rate(clk->parent) / div; \
+}
+
+_CLK_GET_RATE1(hbus_clk, HBUS)
+_CLK_GET_RATE1(xbus_clk, XBUS)
+_CLK_GET_RATE1(ssp_clk, SSP)
+_CLK_GET_RATE1(gpmi_clk, GPMI)
+_CLK_GET_RATE1(lcdif_clk, PIX)
+
+#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(audio_clk)
+_CLK_GET_RATE_STUB(pwm_clk)
+
+/*
+ * clk_set_rate
+ */
+static int cpu_clk_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);
+
+ if (clk->parent == &ref_xtal_clk) {
+ div_max = BM_CLKCTRL_CPU_DIV_XTAL >> BP_CLKCTRL_CPU_DIV_XTAL;
+ bm_busy = BM_CLKCTRL_CPU_BUSY_REF_XTAL;
+ div = DIV_ROUND_UP(parent_rate, rate);
+ if (div == 0 || div > div_max)
+ return -EINVAL;
+ } else {
+ div_max = BM_CLKCTRL_CPU_DIV_CPU >> BP_CLKCTRL_CPU_DIV_CPU;
+ bm_busy = BM_CLKCTRL_CPU_BUSY_REF_CPU;
+ rate <<= PARENT_RATE_SHIFT;
+ parent_rate <<= PARENT_RATE_SHIFT;
+ diff = parent_rate;
+ div = frac = 1;
+ 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_FRAC);
+ reg &= ~BM_CLKCTRL_FRAC_CPUFRAC;
+ reg |= frac;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_FRAC);
+ }
+
+ reg = __raw_readl(CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);
+ reg &= ~BM_CLKCTRL_CPU_DIV_CPU;
+ reg |= div << BP_CLKCTRL_CPU_DIV_CPU;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_CPU);
+
+ for (i = 10000; i; i--)
+ if (!(__raw_readl(CLKCTRL_BASE_ADDR +
+ HW_CLKCTRL_CPU) & bm_busy))
+ break;
+ if (!i) {
+ pr_err("%s: divider writing timeout\n", __func__);
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+#define _CLK_SET_RATE(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_RATE(xbus_clk, XBUS)
+_CLK_SET_RATE(ssp_clk, SSP)
+_CLK_SET_RATE(gpmi_clk, GPMI)
+_CLK_SET_RATE(lcdif_clk, PIX)
+
+#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(audio_clk)
+_CLK_SET_RATE_STUB(pwm_clk)
+_CLK_SET_RATE_STUB(clk32k_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(ssp_clk, SSP)
+_CLK_SET_PARENT(gpmi_clk, GPMI)
+_CLK_SET_PARENT(lcdif_clk, PIX)
+
+#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(uart_clk)
+_CLK_SET_PARENT_STUB(audio_clk)
+_CLK_SET_PARENT_STUB(pwm_clk)
+_CLK_SET_PARENT_STUB(clk32k_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 rtc_clk = {
+ .get_rate = rtc_clk_get_rate,
+ .parent = &ref_xtal_clk,
+};
+
+/* usb_clk gate is controlled in DIGCTRL other than CLKCTRL */
+static struct clk usb_clk = {
+ .enable_reg = DIGCTRL_BASE_ADDR,
+ .enable_shift = 2,
+ .enable = _raw_clk_enable,
+ .disable = _raw_clk_disable,
+ .parent = &pll_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(ssp_clk, SSP, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(gpmi_clk, GPMI, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(lcdif_clk, PIX, CLKGATE, &ref_xtal_clk);
+_DEFINE_CLOCK(uart_clk, XTAL, UART_CLK_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(audio_clk, XTAL, FILT_CLK24M_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(pwm_clk, XTAL, PWM_CLK24M_GATE, &ref_xtal_clk);
+_DEFINE_CLOCK(clk32k_clk, XTAL, TIMROT_CLK32K_GATE, &ref_xtal_clk);
+
+#define _REGISTER_CLOCK(d, n, c) \
+ { \
+ .dev_id = d, \
+ .con_id = n, \
+ .clk = &c, \
+ },
+
+static struct clk_lookup lookups[] = {
+ _REGISTER_CLOCK("mxs-duart.0", NULL, uart_clk)
+ _REGISTER_CLOCK("rtc", NULL, rtc_clk)
+ _REGISTER_CLOCK(NULL, "hclk", hbus_clk)
+ _REGISTER_CLOCK(NULL, "xclk", xbus_clk)
+ _REGISTER_CLOCK(NULL, "usb", usb_clk)
+ _REGISTER_CLOCK(NULL, "audio", audio_clk)
+ _REGISTER_CLOCK(NULL, "pwm", pwm_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;
+ ssp_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_SSP) ?
+ &ref_xtal_clk : &ref_io_clk;
+ gpmi_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_GPMI) ?
+ &ref_xtal_clk : &ref_io_clk;
+ lcdif_clk.parent = (reg & BM_CLKCTRL_CLKSEQ_BYPASS_PIX) ?
+ &ref_xtal_clk : &ref_pix_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_SSP);
+ reg &= ~BM_CLKCTRL_SSP_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_SSP);
+
+ 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_PIX);
+ reg &= ~BM_CLKCTRL_PIX_DIV_FRAC_EN;
+ __raw_writel(reg, CLKCTRL_BASE_ADDR + HW_CLKCTRL_PIX);
+
+ /*
+ * 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_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);
+
+ return 0;
+}
+
+int __init mx23_clocks_init(void)
+{
+ clk_misc_init();
+
+ clkdev_add_table(lookups, ARRAY_SIZE(lookups));
+
+ mxs_timer_init(&clk32k_clk, MX23_INT_TIMER0);
+
+ return 0;
+}
diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
new file mode 100644
index 0000000..4a5c518
--- /dev/null
+++ b/arch/arm/mach-mxs/clock-mx28.c
@@ -0,0 +1,734 @@
+/*
+ * 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 <linux/jiffies.h>
+
+#include <asm/clkdev.h>
+#include <asm/div64.h>
+
+#include <mach/mx28.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)
+
+#define PARENT_RATE_SHIFT 8
+
+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 SH_DIV((parent_rate >> PARENT_RATE_SHIFT) * 18, \
+ div, PARENT_RATE_SHIFT); \
+}
+
+_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)
+
+#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_GET_RATE_STUB(fec_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 { \
+ rate <<= PARENT_RATE_SHIFT; \
+ parent_rate <<= PARENT_RATE_SHIFT; \
+ diff = parent_rate; \
+ div = frac = 1; \
+ 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)
+
+/* 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_RATE_STUB(fec_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 gate 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);
+_DEFINE_CLOCK(fec_clk, ENET, DISABLE, &hbus_clk);
+
+#define _REGISTER_CLOCK(d, n, c) \
+ { \
+ .dev_id = d, \
+ .con_id = n, \
+ .clk = &c, \
+ },
+
+static struct clk_lookup lookups[] = {
+ _REGISTER_CLOCK("mxs-duart.0", NULL, uart_clk)
+ _REGISTER_CLOCK("fec.0", NULL, fec_clk)
+ _REGISTER_CLOCK("rtc", NULL, rtc_clk)
+ _REGISTER_CLOCK("pll2", NULL, pll2_clk)
+ _REGISTER_CLOCK(NULL, "hclk", hbus_clk)
+ _REGISTER_CLOCK(NULL, "xclk", xbus_clk)
+ _REGISTER_CLOCK(NULL, "can0", can0_clk)
+ _REGISTER_CLOCK(NULL, "can1", can1_clk)
+ _REGISTER_CLOCK(NULL, "usb0", usb0_clk)
+ _REGISTER_CLOCK(NULL, "usb1", usb1_clk)
+ _REGISTER_CLOCK(NULL, "pwm", pwm_clk)
+ _REGISTER_CLOCK(NULL, "lradc", lradc_clk)
+ _REGISTER_CLOCK(NULL, "spdif", 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;
+ 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));
+
+ mxs_timer_init(&clk32k_clk, MX28_INT_TIMER0);
+
+ return 0;
+}
diff --git a/arch/arm/mach-mxs/clock.c b/arch/arm/mach-mxs/clock.c
new file mode 100644
index 0000000..e7d2269
--- /dev/null
+++ b/arch/arm/mach-mxs/clock.c
@@ -0,0 +1,200 @@
+/*
+ * Based on arch/arm/plat-omap/clock.c
+ *
+ * Copyright (C) 2004 - 2005 Nokia corporation
+ * Written by Tuukka Tikkanen <tuukka.tikkanen@elektrobit.com>
+ * Modified for omap shared clock framework by Tony Lindgren <tony@atomide.com>
+ * Copyright 2007 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
+ * 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.
+ */
+
+/* #define DEBUG */
+
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/platform_device.h>
+#include <linux/proc_fs.h>
+#include <linux/semaphore.h>
+#include <linux/string.h>
+
+#include <mach/clock.h>
+
+static LIST_HEAD(clocks);
+static DEFINE_MUTEX(clocks_mutex);
+
+/*-------------------------------------------------------------------------
+ * Standard clock functions defined in include/linux/clk.h
+ *-------------------------------------------------------------------------*/
+
+static void __clk_disable(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return;
+ WARN_ON(!clk->usecount);
+
+ if (!(--clk->usecount)) {
+ if (clk->disable)
+ clk->disable(clk);
+ __clk_disable(clk->parent);
+ __clk_disable(clk->secondary);
+ }
+}
+
+static int __clk_enable(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ if (clk->usecount++ == 0) {
+ __clk_enable(clk->parent);
+ __clk_enable(clk->secondary);
+
+ if (clk->enable)
+ clk->enable(clk);
+ }
+ return 0;
+}
+
+/* This function increments the reference count on the clock and enables the
+ * clock if not already enabled. The parent clock tree is recursively enabled
+ */
+int clk_enable(struct clk *clk)
+{
+ int ret = 0;
+
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ mutex_lock(&clocks_mutex);
+ ret = __clk_enable(clk);
+ mutex_unlock(&clocks_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_enable);
+
+/* This function decrements the reference count on the clock and disables
+ * the clock when reference count is 0. The parent clock tree is
+ * recursively disabled
+ */
+void clk_disable(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return;
+
+ mutex_lock(&clocks_mutex);
+ __clk_disable(clk);
+ mutex_unlock(&clocks_mutex);
+}
+EXPORT_SYMBOL(clk_disable);
+
+/* Retrieve the *current* clock rate. If the clock itself
+ * does not provide a special calculation routine, ask
+ * its parent and so on, until one is able to return
+ * a valid clock rate
+ */
+unsigned long clk_get_rate(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return 0UL;
+
+ if (clk->get_rate)
+ return clk->get_rate(clk);
+
+ return clk_get_rate(clk->parent);
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+/* Round the requested clock rate to the nearest supported
+ * rate that is less than or equal to the requested rate.
+ * This is dependent on the clock's current parent.
+ */
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ if (clk == NULL || IS_ERR(clk) || !clk->round_rate)
+ return 0;
+
+ return clk->round_rate(clk, rate);
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+/* Set the clock to the requested clock rate. The rate must
+ * match a supported rate exactly based on what clk_round_rate returns
+ */
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ int ret = -EINVAL;
+
+ if (clk == NULL || IS_ERR(clk) || clk->set_rate == NULL || rate == 0)
+ return ret;
+
+ mutex_lock(&clocks_mutex);
+ ret = clk->set_rate(clk, rate);
+ mutex_unlock(&clocks_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+/* Set the clock's parent to another clock source */
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ int ret = -EINVAL;
+ struct clk *old;
+
+ if (clk == NULL || IS_ERR(clk) || parent == NULL ||
+ IS_ERR(parent) || clk->set_parent == NULL)
+ return ret;
+
+ if (clk->usecount)
+ clk_enable(parent);
+
+ mutex_lock(&clocks_mutex);
+ ret = clk->set_parent(clk, parent);
+ if (ret == 0) {
+ old = clk->parent;
+ clk->parent = parent;
+ } else {
+ old = parent;
+ }
+ mutex_unlock(&clocks_mutex);
+
+ if (clk->usecount)
+ clk_disable(old);
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
+/* Retrieve the clock's parent clock source */
+struct clk *clk_get_parent(struct clk *clk)
+{
+ struct clk *ret = NULL;
+
+ if (clk == NULL || IS_ERR(clk))
+ return ret;
+
+ return clk->parent;
+}
+EXPORT_SYMBOL(clk_get_parent);
diff --git a/arch/arm/mach-mxs/include/mach/clkdev.h b/arch/arm/mach-mxs/include/mach/clkdev.h
new file mode 100644
index 0000000..3a8f2e3
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __MACH_MXS_CLKDEV_H__
+#define __MACH_MXS_CLKDEV_H__
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-mxs/include/mach/clock.h b/arch/arm/mach-mxs/include/mach/clock.h
new file mode 100644
index 0000000..041e276
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/clock.h
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2005-2007 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
+ * 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_MXS_CLOCK_H__
+#define __MACH_MXS_CLOCK_H__
+
+#ifndef __ASSEMBLY__
+#include <linux/list.h>
+
+struct module;
+
+struct clk {
+ int id;
+ /* Source clock this clk depends on */
+ struct clk *parent;
+ /* Secondary clock to enable/disable with this clock */
+ struct clk *secondary;
+ /* Reference count of clock enable/disable */
+ __s8 usecount;
+ /* Register bit position for clock's enable/disable control. */
+ u8 enable_shift;
+ /* Register address for clock's enable/disable control. */
+ void __iomem *enable_reg;
+ u32 flags;
+ /* get the current clock rate (always a fresh value) */
+ unsigned long (*get_rate) (struct clk *);
+ /* Function ptr to set the clock to a new rate. The rate must match a
+ supported rate returned from round_rate. Leave blank if clock is not
+ programmable */
+ int (*set_rate) (struct clk *, unsigned long);
+ /* Function ptr to round the requested clock rate to the nearest
+ supported rate that is less than or equal to the requested rate. */
+ unsigned long (*round_rate) (struct clk *, unsigned long);
+ /* Function ptr to enable the clock. Leave blank if clock can not
+ be gated. */
+ int (*enable) (struct clk *);
+ /* Function ptr to disable the clock. Leave blank if clock can not
+ be gated. */
+ void (*disable) (struct clk *);
+ /* Function ptr to set the parent clock of the clock. */
+ int (*set_parent) (struct clk *, struct clk *);
+};
+
+int clk_register(struct clk *clk);
+void clk_unregister(struct clk *clk);
+
+#endif /* __ASSEMBLY__ */
+#endif /* __MACH_MXS_CLOCK_H__ */
diff --git a/arch/arm/mach-mxs/regs-clkctrl-mx23.h b/arch/arm/mach-mxs/regs-clkctrl-mx23.h
new file mode 100644
index 0000000..dbc0474
--- /dev/null
+++ b/arch/arm/mach-mxs/regs-clkctrl-mx23.h
@@ -0,0 +1,455 @@
+/*
+ * Freescale CLKCTRL Register Definitions
+ *
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ * Copyright 2008-2010 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 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 __REGS_CLKCTRL_MX23_H__
+#define __REGS_CLKCTRL_MX23_H__
+
+
+#define HW_CLKCTRL_PLLCTRL0 (0x00000000)
+#define HW_CLKCTRL_PLLCTRL0_SET (0x00000004)
+#define HW_CLKCTRL_PLLCTRL0_CLR (0x00000008)
+#define HW_CLKCTRL_PLLCTRL0_TOG (0x0000000c)
+
+#define BP_CLKCTRL_PLLCTRL0_RSRVD6 30
+#define BM_CLKCTRL_PLLCTRL0_RSRVD6 0xC0000000
+#define BF_CLKCTRL_PLLCTRL0_RSRVD6(v) \
+ (((v) << 30) & BM_CLKCTRL_PLLCTRL0_RSRVD6)
+#define BP_CLKCTRL_PLLCTRL0_LFR_SEL 28
+#define BM_CLKCTRL_PLLCTRL0_LFR_SEL 0x30000000
+#define BF_CLKCTRL_PLLCTRL0_LFR_SEL(v) \
+ (((v) << 28) & BM_CLKCTRL_PLLCTRL0_LFR_SEL)
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__TIMES_2 0x1
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__TIMES_05 0x2
+#define BV_CLKCTRL_PLLCTRL0_LFR_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLLCTRL0_RSRVD5 26
+#define BM_CLKCTRL_PLLCTRL0_RSRVD5 0x0C000000
+#define BF_CLKCTRL_PLLCTRL0_RSRVD5(v) \
+ (((v) << 26) & BM_CLKCTRL_PLLCTRL0_RSRVD5)
+#define BP_CLKCTRL_PLLCTRL0_CP_SEL 24
+#define BM_CLKCTRL_PLLCTRL0_CP_SEL 0x03000000
+#define BF_CLKCTRL_PLLCTRL0_CP_SEL(v) \
+ (((v) << 24) & BM_CLKCTRL_PLLCTRL0_CP_SEL)
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__TIMES_2 0x1
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__TIMES_05 0x2
+#define BV_CLKCTRL_PLLCTRL0_CP_SEL__UNDEFINED 0x3
+#define BP_CLKCTRL_PLLCTRL0_RSRVD4 22
+#define BM_CLKCTRL_PLLCTRL0_RSRVD4 0x00C00000
+#define BF_CLKCTRL_PLLCTRL0_RSRVD4(v) \
+ (((v) << 22) & BM_CLKCTRL_PLLCTRL0_RSRVD4)
+#define BP_CLKCTRL_PLLCTRL0_DIV_SEL 20
+#define BM_CLKCTRL_PLLCTRL0_DIV_SEL 0x00300000
+#define BF_CLKCTRL_PLLCTRL0_DIV_SEL(v) \
+ (((v) << 20) & BM_CLKCTRL_PLLCTRL0_DIV_SEL)
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__DEFAULT 0x0
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__LOWER 0x1
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__LOWEST 0x2
+#define BV_CLKCTRL_PLLCTRL0_DIV_SEL__UNDEFINED 0x3
+#define BM_CLKCTRL_PLLCTRL0_RSRVD3 0x00080000
+#define BM_CLKCTRL_PLLCTRL0_EN_USB_CLKS 0x00040000
+#define BM_CLKCTRL_PLLCTRL0_RSRVD2 0x00020000
+#define BM_CLKCTRL_PLLCTRL0_POWER 0x00010000
+#define BP_CLKCTRL_PLLCTRL0_RSRVD1 0
+#define BM_CLKCTRL_PLLCTRL0_RSRVD1 0x0000FFFF
+#define BF_CLKCTRL_PLLCTRL0_RSRVD1(v) \
+ (((v) << 0) & BM_CLKCTRL_PLLCTRL0_RSRVD1)
+
+#define HW_CLKCTRL_PLLCTRL1 (0x00000010)
+
+#define BM_CLKCTRL_PLLCTRL1_LOCK 0x80000000
+#define BM_CLKCTRL_PLLCTRL1_FORCE_LOCK 0x40000000
+#define BP_CLKCTRL_PLLCTRL1_RSRVD1 16
+#define BM_CLKCTRL_PLLCTRL1_RSRVD1 0x3FFF0000
+#define BF_CLKCTRL_PLLCTRL1_RSRVD1(v) \
+ (((v) << 16) & BM_CLKCTRL_PLLCTRL1_RSRVD1)
+#define BP_CLKCTRL_PLLCTRL1_LOCK_COUNT 0
+#define BM_CLKCTRL_PLLCTRL1_LOCK_COUNT 0x0000FFFF
+#define BF_CLKCTRL_PLLCTRL1_LOCK_COUNT(v) \
+ (((v) << 0) & BM_CLKCTRL_PLLCTRL1_LOCK_COUNT)
+
+#define HW_CLKCTRL_CPU (0x00000020)
+#define HW_CLKCTRL_CPU_SET (0x00000024)
+#define HW_CLKCTRL_CPU_CLR (0x00000028)
+#define HW_CLKCTRL_CPU_TOG (0x0000002c)
+
+#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 (0x00000030)
+#define HW_CLKCTRL_HBUS_SET (0x00000034)
+#define HW_CLKCTRL_HBUS_CLR (0x00000038)
+#define HW_CLKCTRL_HBUS_TOG (0x0000003c)
+
+#define BP_CLKCTRL_HBUS_RSRVD4 30
+#define BM_CLKCTRL_HBUS_RSRVD4 0xC0000000
+#define BF_CLKCTRL_HBUS_RSRVD4(v) \
+ (((v) << 30) & BM_CLKCTRL_HBUS_RSRVD4)
+#define BM_CLKCTRL_HBUS_BUSY 0x20000000
+#define BM_CLKCTRL_HBUS_DCP_AS_ENABLE 0x10000000
+#define BM_CLKCTRL_HBUS_PXP_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_AUTO_SLOW_MODE 0x00100000
+#define BM_CLKCTRL_HBUS_RSRVD2 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 (0x00000040)
+
+#define BM_CLKCTRL_XBUS_BUSY 0x80000000
+#define BP_CLKCTRL_XBUS_RSRVD1 11
+#define BM_CLKCTRL_XBUS_RSRVD1 0x7FFFF800
+#define BF_CLKCTRL_XBUS_RSRVD1(v) \
+ (((v) << 11) & BM_CLKCTRL_XBUS_RSRVD1)
+#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 (0x00000050)
+#define HW_CLKCTRL_XTAL_SET (0x00000054)
+#define HW_CLKCTRL_XTAL_CLR (0x00000058)
+#define HW_CLKCTRL_XTAL_TOG (0x0000005c)
+
+#define BP_CLKCTRL_XTAL_UART_CLK_GATE 31
+#define BM_CLKCTRL_XTAL_UART_CLK_GATE 0x80000000
+#define BP_CLKCTRL_XTAL_FILT_CLK24M_GATE 30
+#define BM_CLKCTRL_XTAL_FILT_CLK24M_GATE 0x40000000
+#define BP_CLKCTRL_XTAL_PWM_CLK24M_GATE 29
+#define BM_CLKCTRL_XTAL_PWM_CLK24M_GATE 0x20000000
+#define BM_CLKCTRL_XTAL_DRI_CLK24M_GATE 0x10000000
+#define BM_CLKCTRL_XTAL_DIGCTRL_CLK1M_GATE 0x08000000
+#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_PIX (0x00000060)
+
+#define BP_CLKCTRL_PIX_CLKGATE 31
+#define BM_CLKCTRL_PIX_CLKGATE 0x80000000
+#define BM_CLKCTRL_PIX_RSRVD2 0x40000000
+#define BM_CLKCTRL_PIX_BUSY 0x20000000
+#define BP_CLKCTRL_PIX_RSRVD1 13
+#define BM_CLKCTRL_PIX_RSRVD1 0x1FFFE000
+#define BF_CLKCTRL_PIX_RSRVD1(v) \
+ (((v) << 13) & BM_CLKCTRL_PIX_RSRVD1)
+#define BM_CLKCTRL_PIX_DIV_FRAC_EN 0x00001000
+#define BP_CLKCTRL_PIX_DIV 0
+#define BM_CLKCTRL_PIX_DIV 0x00000FFF
+#define BF_CLKCTRL_PIX_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_PIX_DIV)
+
+#define HW_CLKCTRL_SSP (0x00000070)
+
+#define BP_CLKCTRL_SSP_CLKGATE 31
+#define BM_CLKCTRL_SSP_CLKGATE 0x80000000
+#define BM_CLKCTRL_SSP_RSRVD2 0x40000000
+#define BM_CLKCTRL_SSP_BUSY 0x20000000
+#define BP_CLKCTRL_SSP_RSRVD1 10
+#define BM_CLKCTRL_SSP_RSRVD1 0x1FFFFC00
+#define BF_CLKCTRL_SSP_RSRVD1(v) \
+ (((v) << 10) & BM_CLKCTRL_SSP_RSRVD1)
+#define BM_CLKCTRL_SSP_DIV_FRAC_EN 0x00000200
+#define BP_CLKCTRL_SSP_DIV 0
+#define BM_CLKCTRL_SSP_DIV 0x000001FF
+#define BF_CLKCTRL_SSP_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_SSP_DIV)
+
+#define HW_CLKCTRL_GPMI (0x00000080)
+
+#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 (0x00000090)
+
+#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 (0x000000a0)
+
+#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_IR (0x000000b0)
+
+#define BM_CLKCTRL_IR_CLKGATE 0x80000000
+#define BM_CLKCTRL_IR_RSRVD3 0x40000000
+#define BM_CLKCTRL_IR_AUTO_DIV 0x20000000
+#define BM_CLKCTRL_IR_IR_BUSY 0x10000000
+#define BM_CLKCTRL_IR_IROV_BUSY 0x08000000
+#define BP_CLKCTRL_IR_RSRVD2 25
+#define BM_CLKCTRL_IR_RSRVD2 0x06000000
+#define BF_CLKCTRL_IR_RSRVD2(v) \
+ (((v) << 25) & BM_CLKCTRL_IR_RSRVD2)
+#define BP_CLKCTRL_IR_IROV_DIV 16
+#define BM_CLKCTRL_IR_IROV_DIV 0x01FF0000
+#define BF_CLKCTRL_IR_IROV_DIV(v) \
+ (((v) << 16) & BM_CLKCTRL_IR_IROV_DIV)
+#define BP_CLKCTRL_IR_RSRVD1 10
+#define BM_CLKCTRL_IR_RSRVD1 0x0000FC00
+#define BF_CLKCTRL_IR_RSRVD1(v) \
+ (((v) << 10) & BM_CLKCTRL_IR_RSRVD1)
+#define BP_CLKCTRL_IR_IR_DIV 0
+#define BM_CLKCTRL_IR_IR_DIV 0x000003FF
+#define BF_CLKCTRL_IR_IR_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_IR_IR_DIV)
+
+#define HW_CLKCTRL_SAIF (0x000000c0)
+
+#define BM_CLKCTRL_SAIF_CLKGATE 0x80000000
+#define BM_CLKCTRL_SAIF_RSRVD2 0x40000000
+#define BM_CLKCTRL_SAIF_BUSY 0x20000000
+#define BP_CLKCTRL_SAIF_RSRVD1 17
+#define BM_CLKCTRL_SAIF_RSRVD1 0x1FFE0000
+#define BF_CLKCTRL_SAIF_RSRVD1(v) \
+ (((v) << 17) & BM_CLKCTRL_SAIF_RSRVD1)
+#define BM_CLKCTRL_SAIF_DIV_FRAC_EN 0x00010000
+#define BP_CLKCTRL_SAIF_DIV 0
+#define BM_CLKCTRL_SAIF_DIV 0x0000FFFF
+#define BF_CLKCTRL_SAIF_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_SAIF_DIV)
+
+#define HW_CLKCTRL_TV (0x000000d0)
+
+#define BM_CLKCTRL_TV_CLK_TV108M_GATE 0x80000000
+#define BM_CLKCTRL_TV_CLK_TV_GATE 0x40000000
+#define BP_CLKCTRL_TV_RSRVD 0
+#define BM_CLKCTRL_TV_RSRVD 0x3FFFFFFF
+#define BF_CLKCTRL_TV_RSRVD(v) \
+ (((v) << 0) & BM_CLKCTRL_TV_RSRVD)
+
+#define HW_CLKCTRL_ETM (0x000000e0)
+
+#define BM_CLKCTRL_ETM_CLKGATE 0x80000000
+#define BM_CLKCTRL_ETM_RSRVD2 0x40000000
+#define BM_CLKCTRL_ETM_BUSY 0x20000000
+#define BP_CLKCTRL_ETM_RSRVD1 7
+#define BM_CLKCTRL_ETM_RSRVD1 0x1FFFFF80
+#define BF_CLKCTRL_ETM_RSRVD1(v) \
+ (((v) << 7) & BM_CLKCTRL_ETM_RSRVD1)
+#define BM_CLKCTRL_ETM_DIV_FRAC_EN 0x00000040
+#define BP_CLKCTRL_ETM_DIV 0
+#define BM_CLKCTRL_ETM_DIV 0x0000003F
+#define BF_CLKCTRL_ETM_DIV(v) \
+ (((v) << 0) & BM_CLKCTRL_ETM_DIV)
+
+#define HW_CLKCTRL_FRAC (0x000000f0)
+#define HW_CLKCTRL_FRAC_SET (0x000000f4)
+#define HW_CLKCTRL_FRAC_CLR (0x000000f8)
+#define HW_CLKCTRL_FRAC_TOG (0x000000fc)
+
+#define BP_CLKCTRL_FRAC_CLKGATEIO 31
+#define BM_CLKCTRL_FRAC_CLKGATEIO 0x80000000
+#define BM_CLKCTRL_FRAC_IO_STABLE 0x40000000
+#define BP_CLKCTRL_FRAC_IOFRAC 24
+#define BM_CLKCTRL_FRAC_IOFRAC 0x3F000000
+#define BF_CLKCTRL_FRAC_IOFRAC(v) \
+ (((v) << 24) & BM_CLKCTRL_FRAC_IOFRAC)
+#define BP_CLKCTRL_FRAC_CLKGATEPIX 23
+#define BM_CLKCTRL_FRAC_CLKGATEPIX 0x00800000
+#define BM_CLKCTRL_FRAC_PIX_STABLE 0x00400000
+#define BP_CLKCTRL_FRAC_PIXFRAC 16
+#define BM_CLKCTRL_FRAC_PIXFRAC 0x003F0000
+#define BF_CLKCTRL_FRAC_PIXFRAC(v) \
+ (((v) << 16) & BM_CLKCTRL_FRAC_PIXFRAC)
+#define BP_CLKCTRL_FRAC_CLKGATEEMI 15
+#define BM_CLKCTRL_FRAC_CLKGATEEMI 0x00008000
+#define BM_CLKCTRL_FRAC_EMI_STABLE 0x00004000
+#define BP_CLKCTRL_FRAC_EMIFRAC 8
+#define BM_CLKCTRL_FRAC_EMIFRAC 0x00003F00
+#define BF_CLKCTRL_FRAC_EMIFRAC(v) \
+ (((v) << 8) & BM_CLKCTRL_FRAC_EMIFRAC)
+#define BP_CLKCTRL_FRAC_CLKGATECPU 7
+#define BM_CLKCTRL_FRAC_CLKGATECPU 0x00000080
+#define BM_CLKCTRL_FRAC_CPU_STABLE 0x00000040
+#define BP_CLKCTRL_FRAC_CPUFRAC 0
+#define BM_CLKCTRL_FRAC_CPUFRAC 0x0000003F
+#define BF_CLKCTRL_FRAC_CPUFRAC(v) \
+ (((v) << 0) & BM_CLKCTRL_FRAC_CPUFRAC)
+
+#define HW_CLKCTRL_FRAC1 (0x00000100)
+#define HW_CLKCTRL_FRAC1_SET (0x00000104)
+#define HW_CLKCTRL_FRAC1_CLR (0x00000108)
+#define HW_CLKCTRL_FRAC1_TOG (0x0000010c)
+
+#define BM_CLKCTRL_FRAC1_CLKGATEVID 0x80000000
+#define BM_CLKCTRL_FRAC1_VID_STABLE 0x40000000
+#define BP_CLKCTRL_FRAC1_RSRVD1 0
+#define BM_CLKCTRL_FRAC1_RSRVD1 0x3FFFFFFF
+#define BF_CLKCTRL_FRAC1_RSRVD1(v) \
+ (((v) << 0) & BM_CLKCTRL_FRAC1_RSRVD1)
+
+#define HW_CLKCTRL_CLKSEQ (0x00000110)
+#define HW_CLKCTRL_CLKSEQ_SET (0x00000114)
+#define HW_CLKCTRL_CLKSEQ_CLR (0x00000118)
+#define HW_CLKCTRL_CLKSEQ_TOG (0x0000011c)
+
+#define BP_CLKCTRL_CLKSEQ_RSRVD1 9
+#define BM_CLKCTRL_CLKSEQ_RSRVD1 0xFFFFFE00
+#define BF_CLKCTRL_CLKSEQ_RSRVD1(v) \
+ (((v) << 9) & BM_CLKCTRL_CLKSEQ_RSRVD1)
+#define BM_CLKCTRL_CLKSEQ_BYPASS_ETM 0x00000100
+#define BM_CLKCTRL_CLKSEQ_BYPASS_CPU 0x00000080
+#define BM_CLKCTRL_CLKSEQ_BYPASS_EMI 0x00000040
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SSP 0x00000020
+#define BM_CLKCTRL_CLKSEQ_BYPASS_GPMI 0x00000010
+#define BM_CLKCTRL_CLKSEQ_BYPASS_IR 0x00000008
+#define BM_CLKCTRL_CLKSEQ_RSRVD0 0x00000004
+#define BM_CLKCTRL_CLKSEQ_BYPASS_PIX 0x00000002
+#define BM_CLKCTRL_CLKSEQ_BYPASS_SAIF 0x00000001
+
+#define HW_CLKCTRL_RESET (0x00000120)
+
+#define BP_CLKCTRL_RESET_RSRVD 2
+#define BM_CLKCTRL_RESET_RSRVD 0xFFFFFFFC
+#define BF_CLKCTRL_RESET_RSRVD(v) \
+ (((v) << 2) & BM_CLKCTRL_RESET_RSRVD)
+#define BM_CLKCTRL_RESET_CHIP 0x00000002
+#define BM_CLKCTRL_RESET_DIG 0x00000001
+
+#define HW_CLKCTRL_STATUS (0x00000130)
+
+#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 (0x00000140)
+
+#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 /* __REGS_CLKCTRL_MX23_H__ */
diff --git a/arch/arm/mach-mxs/regs-clkctrl-mx28.h b/arch/arm/mach-mxs/regs-clkctrl-mx28.h
new file mode 100644
index 0000000..661df18
--- /dev/null
+++ b/arch/arm/mach-mxs/regs-clkctrl-mx28.h
@@ -0,0 +1,663 @@
+/*
+ * Freescale CLKCTRL Register Definitions
+ *
+ * Copyright 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., 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 __REGS_CLKCTRL_MX28_H__
+#define __REGS_CLKCTRL_MX28_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 /* __REGS_CLKCTRL_MX28_H__ */
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH v2 10/15] ARM: mxs: Add static memory mapping
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (41 preceding siblings ...)
2010-12-09 15:12 ` [PATCH v3 09/15] ARM: mxs: Add clock support Shawn Guo
@ 2010-12-09 15:12 ` Shawn Guo
2010-12-09 15:12 ` [PATCH v2 11/15] ARM: mxs: Dynamically allocate duart devices Shawn Guo
` (3 subsequent siblings)
46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 15:12 UTC (permalink / raw)
To: linux-arm-kernel
Create static memory mapping for MX23 and MX28.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
- Change the inclusion of hardware.h to mx23.h and mx28.h respectively
- Remove the call to mxs_iomux_init() and mxs_arch_reset_init() from
map_io callback, and turn them into __initcall, as the call here is
a little late.
arch/arm/mach-mxs/mm-mx23.c | 45 +++++++++++++++++++++++++++++++++++++++++++
arch/arm/mach-mxs/mm-mx28.c | 45 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 90 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/mm-mx23.c
create mode 100644 arch/arm/mach-mxs/mm-mx28.c
diff --git a/arch/arm/mach-mxs/mm-mx23.c b/arch/arm/mach-mxs/mm-mx23.c
new file mode 100644
index 0000000..5148cd6
--- /dev/null
+++ b/arch/arm/mach-mxs/mm-mx23.c
@@ -0,0 +1,45 @@
+/*
+ * 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/mx23.h>
+#include <mach/common.h>
+#include <mach/iomux.h>
+
+/*
+ * Define the MX23 memory map.
+ */
+static struct map_desc mx23_io_desc[] __initdata = {
+ mxs_map_entry(MX23, OCRAM, MT_DEVICE),
+ mxs_map_entry(MX23, 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 mx23_map_io(void)
+{
+ iotable_init(mx23_io_desc, ARRAY_SIZE(mx23_io_desc));
+}
+
+void __init mx23_init_irq(void)
+{
+ icoll_init_irq();
+ mx23_register_gpios();
+}
diff --git a/arch/arm/mach-mxs/mm-mx28.c b/arch/arm/mach-mxs/mm-mx28.c
new file mode 100644
index 0000000..7e4cea3
--- /dev/null
+++ b/arch/arm/mach-mxs/mm-mx28.c
@@ -0,0 +1,45 @@
+/*
+ * 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/mx28.h>
+#include <mach/common.h>
+#include <mach/iomux.h>
+
+/*
+ * Define the MX28 memory map.
+ */
+static struct map_desc mx28_io_desc[] __initdata = {
+ mxs_map_entry(MX28, OCRAM, MT_DEVICE),
+ mxs_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)
+{
+ iotable_init(mx28_io_desc, ARRAY_SIZE(mx28_io_desc));
+}
+
+void __init mx28_init_irq(void)
+{
+ icoll_init_irq();
+ mx28_register_gpios();
+}
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH v2 11/15] ARM: mxs: Dynamically allocate duart devices
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (42 preceding siblings ...)
2010-12-09 15:12 ` [PATCH v2 10/15] ARM: mxs: Add static memory mapping Shawn Guo
@ 2010-12-09 15:12 ` Shawn Guo
2010-12-09 15:12 ` [PATCH v3 12/15] ARM: mxs: Dynamically allocate fec devices Shawn Guo
` (2 subsequent siblings)
46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 15:12 UTC (permalink / raw)
To: linux-arm-kernel
Dynamically allocate duart devices for MX23 and MX28.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
- Change inclusion of hardware.h to mx23.h plus mx28.h
arch/arm/mach-mxs/devices-mx23.h | 16 +++++
arch/arm/mach-mxs/devices-mx28.h | 16 +++++
arch/arm/mach-mxs/devices.c | 75 +++++++++++++++++++++++
arch/arm/mach-mxs/devices/platform-duart.c | 48 ++++++++++++++
arch/arm/mach-mxs/include/mach/devices-common.h | 34 ++++++++++
5 files changed, 189 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/devices-mx23.h
create mode 100644 arch/arm/mach-mxs/devices-mx28.h
create mode 100644 arch/arm/mach-mxs/devices.c
create mode 100644 arch/arm/mach-mxs/devices/platform-duart.c
create mode 100644 arch/arm/mach-mxs/include/mach/devices-common.h
diff --git a/arch/arm/mach-mxs/devices-mx23.h b/arch/arm/mach-mxs/devices-mx23.h
new file mode 100644
index 0000000..d0f49fc
--- /dev/null
+++ b/arch/arm/mach-mxs/devices-mx23.h
@@ -0,0 +1,16 @@
+/*
+ * 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/mx23.h>
+#include <mach/devices-common.h>
+
+extern const struct mxs_duart_data mx23_duart_data __initconst;
+#define mx23_add_duart() \
+ mxs_add_duart(&mx23_duart_data)
diff --git a/arch/arm/mach-mxs/devices-mx28.h b/arch/arm/mach-mxs/devices-mx28.h
new file mode 100644
index 0000000..47c2f04
--- /dev/null
+++ b/arch/arm/mach-mxs/devices-mx28.h
@@ -0,0 +1,16 @@
+/*
+ * 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 mxs_duart_data mx28_duart_data __initconst;
+#define mx28_add_duart() \
+ mxs_add_duart(&mx28_duart_data)
diff --git a/arch/arm/mach-mxs/devices.c b/arch/arm/mach-mxs/devices.c
new file mode 100644
index 0000000..6b60f02
--- /dev/null
+++ b/arch/arm/mach-mxs/devices.c
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2008 Sascha Hauer, kernel at pengutronix.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/kernel.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <mach/common.h>
+
+struct platform_device *__init mxs_add_platform_device_dmamask(
+ const char *name, int id,
+ const struct resource *res, unsigned int num_resources,
+ const void *data, size_t size_data, u64 dmamask)
+{
+ int ret = -ENOMEM;
+ struct platform_device *pdev;
+
+ pdev = platform_device_alloc(name, id);
+ if (!pdev)
+ goto err;
+
+ if (dmamask) {
+ /*
+ * This memory isn't freed when the device is put,
+ * I don't have a nice idea for that though. Conceptually
+ * dma_mask in struct device should not be a pointer.
+ * See http://thread.gmane.org/gmane.linux.kernel.pci/9081
+ */
+ pdev->dev.dma_mask =
+ kmalloc(sizeof(*pdev->dev.dma_mask), GFP_KERNEL);
+ if (!pdev->dev.dma_mask)
+ /* ret is still -ENOMEM; */
+ goto err;
+
+ *pdev->dev.dma_mask = dmamask;
+ pdev->dev.coherent_dma_mask = dmamask;
+ }
+
+ if (res) {
+ ret = platform_device_add_resources(pdev, res, num_resources);
+ if (ret)
+ goto err;
+ }
+
+ if (data) {
+ ret = platform_device_add_data(pdev, data, size_data);
+ if (ret)
+ goto err;
+ }
+
+ ret = platform_device_add(pdev);
+ if (ret) {
+err:
+ platform_device_put(pdev);
+ return ERR_PTR(ret);
+ }
+
+ return pdev;
+}
diff --git a/arch/arm/mach-mxs/devices/platform-duart.c b/arch/arm/mach-mxs/devices/platform-duart.c
new file mode 100644
index 0000000..2fe0df5
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/platform-duart.c
@@ -0,0 +1,48 @@
+/*
+ * 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/mx23.h>
+#include <mach/mx28.h>
+#include <mach/devices-common.h>
+
+#define mxs_duart_data_entry(soc) \
+ { \
+ .iobase = soc ## _DUART_BASE_ADDR, \
+ .irq = soc ## _INT_DUART, \
+ }
+
+#ifdef CONFIG_SOC_IMX23
+const struct mxs_duart_data mx23_duart_data __initconst =
+ mxs_duart_data_entry(MX23);
+#endif
+
+#ifdef CONFIG_SOC_IMX28
+const struct mxs_duart_data mx28_duart_data __initconst =
+ mxs_duart_data_entry(MX28);
+#endif
+
+struct platform_device *__init mxs_add_duart(
+ const struct mxs_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 mxs_add_platform_device("mxs-duart", 0, res, ARRAY_SIZE(res),
+ NULL, 0);
+}
diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h
new file mode 100644
index 0000000..07b4439
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/devices-common.h
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2009-2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * 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 <linux/kernel.h>
+#include <linux/platform_device.h>
+#include <linux/init.h>
+
+struct platform_device *mxs_add_platform_device_dmamask(
+ const char *name, int id,
+ const struct resource *res, unsigned int num_resources,
+ const void *data, size_t size_data, u64 dmamask);
+
+static inline struct platform_device *mxs_add_platform_device(
+ const char *name, int id,
+ const struct resource *res, unsigned int num_resources,
+ const void *data, size_t size_data)
+{
+ return mxs_add_platform_device_dmamask(
+ name, id, res, num_resources, data, size_data, 0);
+}
+
+/* duart */
+struct mxs_duart_data {
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init mxs_add_duart(
+ const struct mxs_duart_data *data);
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH v3 12/15] ARM: mxs: Dynamically allocate fec devices
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (43 preceding siblings ...)
2010-12-09 15:12 ` [PATCH v2 11/15] ARM: mxs: Dynamically allocate duart devices Shawn Guo
@ 2010-12-09 15:12 ` Shawn Guo
2010-12-09 15:12 ` [PATCH v3 13/15] ARM: mxs: Add initial mx23evk support Shawn Guo
2010-12-09 15:12 ` [PATCH v3 14/15] ARM: mxs: Add initial mx28evk support Shawn Guo
46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 15:12 UTC (permalink / raw)
To: linux-arm-kernel
Dynamically allocate fec devices for MX28, which gets dual
fec interface.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
- Change inclusion of hardware.h to mx28.h
Changes for v2:
- Remove the use of mx28_add_fec0 and mx28_add_fec1
- Remove unnessary passing of data->iosize
arch/arm/mach-mxs/devices-mx28.h | 4 ++
arch/arm/mach-mxs/devices/platform-fec.c | 50 +++++++++++++++++++++++
arch/arm/mach-mxs/include/mach/devices-common.h | 12 +++++
3 files changed, 66 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/devices/platform-fec.c
diff --git a/arch/arm/mach-mxs/devices-mx28.h b/arch/arm/mach-mxs/devices-mx28.h
index 47c2f04..00b736c 100644
--- a/arch/arm/mach-mxs/devices-mx28.h
+++ b/arch/arm/mach-mxs/devices-mx28.h
@@ -14,3 +14,7 @@
extern const struct mxs_duart_data mx28_duart_data __initconst;
#define mx28_add_duart() \
mxs_add_duart(&mx28_duart_data)
+
+extern const struct mxs_fec_data mx28_fec_data[] __initconst;
+#define mx28_add_fec(id, pdata) \
+ mxs_add_fec(&mx28_fec_data[id], pdata)
diff --git a/arch/arm/mach-mxs/devices/platform-fec.c b/arch/arm/mach-mxs/devices/platform-fec.c
new file mode 100644
index 0000000..c08168c
--- /dev/null
+++ b/arch/arm/mach-mxs/devices/platform-fec.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2010 Pengutronix
+ * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
+ *
+ * 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 <asm/sizes.h>
+#include <mach/mx28.h>
+#include <mach/devices-common.h>
+
+#define mxs_fec_data_entry_single(soc, _id) \
+ { \
+ .id = _id, \
+ .iobase = soc ## _ENET_MAC ## _id ## _BASE_ADDR, \
+ .irq = soc ## _INT_ENET_MAC ## _id, \
+ }
+
+#define mxs_fec_data_entry(soc, _id) \
+ [_id] = mxs_fec_data_entry_single(soc, _id)
+
+#ifdef CONFIG_SOC_IMX28
+const struct mxs_fec_data mx28_fec_data[] __initconst = {
+#define mx28_fec_data_entry(_id) \
+ mxs_fec_data_entry(MX28, _id)
+ mx28_fec_data_entry(0),
+ mx28_fec_data_entry(1),
+};
+#endif
+
+struct platform_device *__init mxs_add_fec(
+ const struct mxs_fec_data *data,
+ const struct fec_platform_data *pdata)
+{
+ struct resource res[] = {
+ {
+ .start = data->iobase,
+ .end = data->iobase + SZ_16K - 1,
+ .flags = IORESOURCE_MEM,
+ }, {
+ .start = data->irq,
+ .end = data->irq,
+ .flags = IORESOURCE_IRQ,
+ },
+ };
+
+ return mxs_add_platform_device("fec", data->id,
+ res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
+}
diff --git a/arch/arm/mach-mxs/include/mach/devices-common.h b/arch/arm/mach-mxs/include/mach/devices-common.h
index 07b4439..3da48d4 100644
--- a/arch/arm/mach-mxs/include/mach/devices-common.h
+++ b/arch/arm/mach-mxs/include/mach/devices-common.h
@@ -32,3 +32,15 @@ struct mxs_duart_data {
};
struct platform_device *__init mxs_add_duart(
const struct mxs_duart_data *data);
+
+/* fec */
+#include <linux/fec.h>
+struct mxs_fec_data {
+ int id;
+ resource_size_t iobase;
+ resource_size_t iosize;
+ resource_size_t irq;
+};
+struct platform_device *__init mxs_add_fec(
+ const struct mxs_fec_data *data,
+ const struct fec_platform_data *pdata);
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH v3 13/15] ARM: mxs: Add initial mx23evk support
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (44 preceding siblings ...)
2010-12-09 15:12 ` [PATCH v3 12/15] ARM: mxs: Dynamically allocate fec devices Shawn Guo
@ 2010-12-09 15:12 ` Shawn Guo
2010-12-09 15:12 ` [PATCH v3 14/15] ARM: mxs: Add initial mx28evk support Shawn Guo
46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 15:12 UTC (permalink / raw)
To: linux-arm-kernel
Add initial mx23evk support with duart.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
- Remove inclusion of hardware.h
- Add __initconst for mx23evk_pads[]
Changes for v2:
- Remove boot_params
arch/arm/mach-mxs/mach-mx23evk.c | 57 ++++++++++++++++++++++++++++++++++++++
1 files changed, 57 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/mach-mx23evk.c
diff --git a/arch/arm/mach-mxs/mach-mx23evk.c b/arch/arm/mach-mxs/mach-mx23evk.c
new file mode 100644
index 0000000..c34b840
--- /dev/null
+++ b/arch/arm/mach-mxs/mach-mx23evk.c
@@ -0,0 +1,57 @@
+/*
+ * 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/common.h>
+#include <mach/iomux-mx23.h>
+
+#include "devices-mx23.h"
+
+static const iomux_cfg_t mx23evk_pads[] __initconst = {
+ /* duart */
+ MX23_PAD_PWM0__DUART_RX,
+ MX23_PAD_PWM1__DUART_TX,
+};
+
+static void __init mx23evk_init(void)
+{
+ mxs_iomux_setup_multiple_pads(mx23evk_pads, ARRAY_SIZE(mx23evk_pads));
+
+ mx23_add_duart();
+}
+
+static void __init mx23evk_timer_init(void)
+{
+ mx23_clocks_init();
+}
+
+static struct sys_timer mx23evk_timer = {
+ .init = mx23evk_timer_init,
+};
+
+MACHINE_START(MX23EVK, "Freescale MX23 EVK")
+ /* Maintainer: Freescale Semiconductor, Inc. */
+ .map_io = mx23_map_io,
+ .init_irq = mx23_init_irq,
+ .init_machine = mx23evk_init,
+ .timer = &mx23evk_timer,
+MACHINE_END
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH v3 14/15] ARM: mxs: Add initial mx28evk support
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (45 preceding siblings ...)
2010-12-09 15:12 ` [PATCH v3 13/15] ARM: mxs: Add initial mx23evk support Shawn Guo
@ 2010-12-09 15:12 ` Shawn Guo
46 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-09 15:12 UTC (permalink / raw)
To: linux-arm-kernel
Add initial mx28evk support with duart and fec0.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
- Remove inclusion of hardware.h
- Add __initconst for mx28evk_pads[]
Changes for v2:
- Change function mx28evk_fec_reset() from inline to __init
- Enable pll2 clock before phy operation
- Add error checking for gpio_direction_output()
- Save bytes by passing parameter into pr_err format string
- Change mx28_add_fec0() to mx28_add_fec(0)
- Remove boot_params
arch/arm/mach-mxs/mach-mx28evk.c | 125 ++++++++++++++++++++++++++++++++++++++
1 files changed, 125 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/mach-mx28evk.c
diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
new file mode 100644
index 0000000..226d374
--- /dev/null
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
@@ -0,0 +1,125 @@
+/*
+ * 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 <linux/clk.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/time.h>
+
+#include <mach/common.h>
+#include <mach/iomux-mx28.h>
+
+#include "devices-mx28.h"
+#include "gpio.h"
+
+#define MX28EVK_FEC_PHY_POWER MXS_GPIO_NR(2, 15)
+#define MX28EVK_FEC_PHY_RESET MXS_GPIO_NR(4, 13)
+
+static const iomux_cfg_t mx28evk_pads[] __initconst = {
+ /* duart */
+ MX28_PAD_PWM0__DUART_RX,
+ MX28_PAD_PWM1__DUART_TX,
+
+ /* fec0 */
+ 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 void __init mx28evk_fec_reset(void)
+{
+ int ret;
+ struct clk *clk;
+
+ /* Enable fec phy clock */
+ clk = clk_get_sys("pll2", NULL);
+ if (!IS_ERR(clk))
+ clk_enable(clk);
+
+ /* Power up fec phy */
+ ret = gpio_request(MX28EVK_FEC_PHY_POWER, "fec-phy-power");
+ if (ret) {
+ pr_err("Failed to request gpio fec-phy-%s: %d\n", "power", ret);
+ return;
+ }
+
+ ret = gpio_direction_output(MX28EVK_FEC_PHY_POWER, 0);
+ if (ret) {
+ pr_err("Failed to drive gpio fec-phy-%s: %d\n", "power", ret);
+ return;
+ }
+
+ /* Reset fec phy */
+ ret = gpio_request(MX28EVK_FEC_PHY_RESET, "fec-phy-reset");
+ if (ret) {
+ pr_err("Failed to request gpio fec-phy-%s: %d\n", "reset", ret);
+ return;
+ }
+
+ gpio_direction_output(MX28EVK_FEC_PHY_RESET, 0);
+ if (ret) {
+ pr_err("Failed to drive gpio fec-phy-%s: %d\n", "reset", ret);
+ return;
+ }
+
+ mdelay(1);
+ gpio_set_value(MX28EVK_FEC_PHY_RESET, 1);
+}
+
+static const struct fec_platform_data mx28_fec_pdata __initconst = {
+ .phy = PHY_INTERFACE_MODE_RMII,
+};
+
+static void __init mx28evk_init(void)
+{
+ mxs_iomux_setup_multiple_pads(mx28evk_pads, ARRAY_SIZE(mx28evk_pads));
+
+ mx28_add_duart();
+
+ mx28evk_fec_reset();
+ mx28_add_fec(0, &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. */
+ .map_io = mx28_map_io,
+ .init_irq = mx28_init_irq,
+ .init_machine = mx28evk_init,
+ .timer = &mx28evk_timer,
+MACHINE_END
--
1.7.1
^ permalink raw reply related [flat|nested] 146+ messages in thread
* [PATCH v3 08/15] ARM: mxs: Add iomux support
2010-12-09 15:12 ` [PATCH v3 08/15] ARM: mxs: Add iomux support Shawn Guo
@ 2010-12-09 16:12 ` Lothar Waßmann
0 siblings, 0 replies; 146+ messages in thread
From: Lothar Waßmann @ 2010-12-09 16:12 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
Shawn Guo writes:
> MXS-based SoCs implements iomux functions in block PINCTRL.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v3:
> - Change iomux_cfg_t to u64 to facilitate adding platform specific
> pad_ctrl settings to an existing pad definition
> - Change inclusion of hardware.h to mxs.h
> - Get iomux_base a hard-assignment in mxs_iomux_setup_pad(), since
> mx23 and mx28 share the common pinctrl base adress and it's only
> used in mxs_iomux_setup_pad().
> - Remove EXPORT_SYMBOL and the static of mxs_iomux_setup_pad()
>
> Changes for v2:
> - Define iomux_cfg_t as u64
> - Turn mxs_iomux_setup_pad() into a static function
> - Fix a bug in mxs_iomux_setup_pad(), muxsel starts at offset 0x100 than 0 of pinctrl block.
>
> arch/arm/mach-mxs/include/mach/iomux-mx23.h | 29 +++++++
> arch/arm/mach-mxs/include/mach/iomux-mx28.h | 44 ++++++++++
> arch/arm/mach-mxs/include/mach/iomux.h | 117 +++++++++++++++++++++++++++
> arch/arm/mach-mxs/iomux.c | 103 +++++++++++++++++++++++
> 4 files changed, 293 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-mxs/include/mach/iomux-mx23.h
> create mode 100644 arch/arm/mach-mxs/include/mach/iomux-mx28.h
> create mode 100644 arch/arm/mach-mxs/include/mach/iomux.h
> create mode 100644 arch/arm/mach-mxs/iomux.c
>
> diff --git a/arch/arm/mach-mxs/include/mach/iomux-mx23.h b/arch/arm/mach-mxs/include/mach/iomux-mx23.h
> new file mode 100644
> index 0000000..3fc0439
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/iomux-mx23.h
> @@ -0,0 +1,29 @@
> +/*
> + * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
> + * Copyright (C) 2010 Freescale Semiconductor, Inc.
> + *
> + * 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
> + */
> +
> +#ifndef __MACH_IOMUX_MX23_H__
> +#define __MACH_IOMUX_MX23_H__
> +
> +#include <mach/iomux.h>
> +
> +/*
> + * The naming convention for the pad modes is MX23_PAD_<padname>__<padmode>
> + * If <padname> or <padmode> refers to a GPIO, it is named GPIO_<unit>_<num>
> + * See also iomux.h
> + *
> + * BANK PIN MUX VOL MA PULL
^
TAB/SPACE mixup (emacs can highlight those ;)
> + */
> +/* DUART */
> +#define MX23_PAD_PWM0__DUART_RX IOMUX_PAD(1, 26, PAD_MUXSEL_2, PAD_VOL_NONE, PAD_4MA, PAD_NOPULL)
> +#define MX23_PAD_PWM1__DUART_TX IOMUX_PAD(1, 27, PAD_MUXSEL_2, PAD_VOL_NONE, PAD_4MA, PAD_NOPULL)
> +
> +#endif /* __MACH_IOMUX_MX23_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/iomux-mx28.h b/arch/arm/mach-mxs/include/mach/iomux-mx28.h
> new file mode 100644
> index 0000000..226bf41
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/iomux-mx28.h
> @@ -0,0 +1,44 @@
> +/*
> + * Copyright (C) 2009-2010 Amit Kucheria <amit.kucheria@canonical.com>
> + * Copyright (C) 2010 Freescale Semiconductor, Inc.
> + *
> + * 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
> + */
> +
> +#ifndef __MACH_IOMUX_MX28_H__
> +#define __MACH_IOMUX_MX28_H__
> +
> +#include <mach/iomux.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.h
> + *
> + * BANK PIN MUX VOL MA PULL
^
TAB/SPACE mixup
> + */
> +/* 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_PULLUP)
> +#define MX28_PAD_ENET0_MDIO__ENET0_MDIO IOMUX_PAD(4, 1, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
> +#define MX28_PAD_ENET0_RX_EN__ENET0_RX_EN IOMUX_PAD(4, 2, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
> +#define MX28_PAD_ENET0_RXD0__ENET0_RXD0 IOMUX_PAD(4, 3, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
> +#define MX28_PAD_ENET0_RXD1__ENET0_RXD1 IOMUX_PAD(4, 4, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
> +#define MX28_PAD_ENET0_TX_EN__ENET0_TX_EN IOMUX_PAD(4, 6, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
> +#define MX28_PAD_ENET0_TXD0__ENET0_TXD0 IOMUX_PAD(4, 7, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
> +#define MX28_PAD_ENET0_TXD1__ENET0_TXD1 IOMUX_PAD(4, 8, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
> +#define MX28_PAD_ENET_CLK__ENET_CLK IOMUX_PAD(4, 16, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
> +
> +/* 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/mach-mxs/include/mach/iomux.h b/arch/arm/mach-mxs/include/mach/iomux.h
> new file mode 100644
> index 0000000..0939446
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/iomux.h
> @@ -0,0 +1,117 @@
> +/*
> + * 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_MXS_IOMUX_H__
> +#define __MACH_MXS_IOMUX_H__
> +
> +/*
> + * IOMUX/PAD Bit field definitions
> + *
> + * PAD_BANK: 0..2 (3)
> + * PAD_PIN: 3..7 (5)
> + * PAD_MUXSEL: 8..9 (2)
> + * PAD_MA: 10..12 (3)
> + * PAD_VOL: 13..14 (2)
> + * PAD_PULL: 15 (1)
> + * RESERVED: 16..63 (48)
> + */
> +typedef u64 iomux_cfg_t;
> +
Only because i.MX5 has so many bits to remember does not mean we have
to waste space on this arch too. No need for u64 here (could obviously
even be u16).
> +#define PAD_BANK_SHIFT 0
> +#define PAD_BANK_MASK ((iomux_cfg_t)0x7 << PAD_BANK_SHIFT)
> +#define PAD_PIN_SHIFT 3
> +#define PAD_PIN_MASK ((iomux_cfg_t)0x1f << PAD_PIN_SHIFT)
> +#define PAD_MUXSEL_SHIFT 8
> +#define PAD_MUXSEL_MASK ((iomux_cfg_t)0x3 << PAD_MUXSEL_SHIFT)
> +#define PAD_MA_SHIFT 10
> +#define PAD_MA_MASK ((iomux_cfg_t)0x7 << PAD_MA_SHIFT)
> +#define PAD_VOL_SHIFT 13
> +#define PAD_VOL_MASK ((iomux_cfg_t)0x3 << PAD_VOL_SHIFT)
> +#define PAD_PULL_SHIFT 15
> +#define PAD_PULL_MASK ((iomux_cfg_t)0x1 << PAD_PULL_SHIFT)
> +
> +#define IOMUX_PAD(_bank, _pin, _muxsel, _vol, _ma, _pull) \
> + (((iomux_cfg_t)(_bank) << PAD_BANK_SHIFT) | \
> + ((iomux_cfg_t)(_pin) << PAD_PIN_SHIFT) | \
> + ((iomux_cfg_t)(_muxsel) << PAD_MUXSEL_SHIFT) | \
> + ((iomux_cfg_t)(_vol) << PAD_VOL_SHIFT) | \
> + ((iomux_cfg_t)(_ma) << PAD_MA_SHIFT) | \
> + ((iomux_cfg_t)(_pull) << PAD_PULL_SHIFT))
> +
These also should have a namespace prefix like:
MXS_PAD_*, MXS_IOMUX_PAD()
> +#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_PULLUP 1
> +
> +static inline unsigned int PAD_BANK(iomux_cfg_t pad)
> +{
> + return (pad & PAD_BANK_MASK) >> PAD_BANK_SHIFT;
> +}
> +
> +static inline unsigned int PAD_PIN(iomux_cfg_t pad)
> +{
> + return (pad & PAD_PIN_MASK) >> PAD_PIN_SHIFT;
> +}
> +
> +static inline unsigned int PAD_MUXSEL(iomux_cfg_t pad)
> +{
> + return (pad & PAD_MUXSEL_MASK) >> PAD_MUXSEL_SHIFT;
> +}
> +
> +static inline unsigned int PAD_MA(iomux_cfg_t pad)
> +{
> + return (pad & PAD_MA_MASK) >> PAD_MA_SHIFT;
> +}
> +
> +static inline unsigned int PAD_VOL(iomux_cfg_t pad)
> +{
> + return (pad & PAD_VOL_MASK) >> PAD_VOL_SHIFT;
> +}
> +
> +static inline unsigned int PAD_PULL(iomux_cfg_t pad)
> +{
> + return (pad & PAD_PULL_MASK) >> PAD_PULL_SHIFT;
> +}
> +
> +/*
> + * setups a single pad in the iomuxer
s/setups/configures/
> + */
> +int mxs_iomux_setup_pad(iomux_cfg_t pad);
> +
> +/*
> + * setups multiple pads
dto.
> + * convenient way to call the above function with tables
> + */
> +int mxs_iomux_setup_multiple_pads(const iomux_cfg_t *pad_list, unsigned count);
> +
> +#endif /* __MACH_MXS_IOMUX_H__*/
> diff --git a/arch/arm/mach-mxs/iomux.c b/arch/arm/mach-mxs/iomux.c
> new file mode 100644
> index 0000000..b6e63a4
> --- /dev/null
> +++ b/arch/arm/mach-mxs/iomux.c
> @@ -0,0 +1,103 @@
> +/*
> + * Copyright 2004-2006,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/mxs.h>
> +#include <mach/iomux.h>
> +
> +/*
> + * configures a single pad in the iomuxer
> + */
> +int mxs_iomux_setup_pad(iomux_cfg_t pad)
> +{
> + u32 reg, ofs, bp, bm;
> + void __iomem *iomux_base = MXS_IO_ADDRESS(MXS_PINCTRL_BASE_ADDR);
> +
> + /* muxsel */
> + ofs = 0x100;
> + ofs += PAD_BANK(pad) * 0x20 + PAD_PIN(pad) / 16 * 0x10;
> + bp = PAD_PIN(pad) % 16 * 2;
> + bm = 0x3 << bp;
> + reg = __raw_readl(iomux_base + ofs);
> + reg &= ~bm;
> + reg |= PAD_MUXSEL(pad) << bp;
> + __raw_writel(reg, iomux_base + ofs);
> +
> + /* drive */
> + ofs = cpu_is_mx23() ? 0x200 : 0x300;
> + ofs += PAD_BANK(pad) * 0x40 + PAD_PIN(pad) / 8 * 0x10;
> + /* ma */
'mA' would make it much clearer that milliamps are meant.
> + if (PAD_MA(pad) != PAD_MA_NONE)
> + {
'{' should be at the end of the 'if' line.
> + bp = PAD_PIN(pad) % 8 * 4;
> + bm = 0x3 << bp;
> + reg = __raw_readl(iomux_base + ofs);
> + reg &= ~bm;
> + reg |= PAD_MA(pad) << bp;
> + __raw_writel(reg, iomux_base + ofs);
> + }
> + /* vol */
> + if (PAD_VOL(pad) != PAD_VOL_NONE)
> + {
dto.
> + bp = PAD_PIN(pad) % 8 * 4 + 2;
> + bm = 0x1 << bp;
> + reg = __raw_readl(iomux_base + ofs);
> + reg &= ~bm;
> + reg |= PAD_VOL(pad) << bp;
> + __raw_writel(reg, iomux_base + ofs);
You could use a write to the SET/CLR address here instead of read/modify/write.
> + }
> +
> + /* pull */
> + ofs = cpu_is_mx23() ? 0x400 : 0x600;
> + ofs += PAD_BANK(pad) * 0x10;
> + bp = PAD_PIN(pad);
> + bm = 0x1 << bp;
> + reg = __raw_readl(iomux_base + ofs);
> + reg &= ~bm;
> + reg |= PAD_PULL(pad) << bp;
> + __raw_writel(reg, iomux_base + ofs);
dto.
> +
> + return 0;
> +}
> +
> +int mxs_iomux_setup_multiple_pads(const iomux_cfg_t *pad_list, unsigned count)
> +{
> + const iomux_cfg_t *p = pad_list;
> + int i;
> + int ret;
> +
> + for (i = 0; i < count; i++) {
> + ret = mxs_iomux_setup_pad(*p);
> + if (ret)
> + return ret;
> + p++;
> + }
> +
> + return 0;
> +}
> --
> 1.7.1
>
>
Lothar Wa?mann
--
___________________________________________________________
Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996
www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v3 07/15] ARM: mxs: Add gpio support
2010-12-09 15:12 ` [PATCH v3 07/15] ARM: mxs: Add gpio support Shawn Guo
@ 2010-12-09 16:47 ` Lothar Waßmann
2010-12-10 7:06 ` Shawn Guo
0 siblings, 1 reply; 146+ messages in thread
From: Lothar Waßmann @ 2010-12-09 16:47 UTC (permalink / raw)
To: linux-arm-kernel
Hi,
Shawn Guo writes:
> MXS-based SoCs implement gpio support in block PINCTRL.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v3:
> - include/mach/gpio.h: remove the inclusion of hardware.h
> - gpio.c: change inclusion of hardware.h to mx23.h plus mx28.h
> - Remove spinlock totally since SET/CLE can be used in all the
> gpio register access
>
> Changes for v2:
> - Create arch/arm/mach-mxs/gpio.h to accommodate stuff private for mach-mxs
> - Use GPIO_INT_LEV_MASK and GPIO_INT_POL_MASK instead of constant
> - Remove both edges IRQ support which is not needed
> - Use SET and CLR register of PINCTRL_DOE in _set_gpio_direction()
> - Use pr_info over printk(KERN_INFO)
>
> arch/arm/mach-mxs/gpio.c | 321 +++++++++++++++++++++++++++++++++
> arch/arm/mach-mxs/gpio.h | 33 ++++
> arch/arm/mach-mxs/include/mach/gpio.h | 34 ++++
> 3 files changed, 388 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-mxs/gpio.c
> create mode 100644 arch/arm/mach-mxs/gpio.h
> create mode 100644 arch/arm/mach-mxs/include/mach/gpio.h
>
> diff --git a/arch/arm/mach-mxs/gpio.c b/arch/arm/mach-mxs/gpio.c
> new file mode 100644
> index 0000000..d88acf3
> --- /dev/null
> +++ b/arch/arm/mach-mxs/gpio.c
> @@ -0,0 +1,321 @@
> +/*
> + * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
> + * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
> + *
> + * Based on code from Freescale,
> + * Copyright (C) 2004-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/init.h>
> +#include <linux/interrupt.h>
> +#include <linux/io.h>
> +#include <linux/irq.h>
> +#include <linux/gpio.h>
> +#include <mach/mx23.h>
> +#include <mach/mx28.h>
> +#include <asm-generic/bug.h>
> +
> +#include "gpio.h"
> +
> +static struct mxs_gpio_port *mxs_gpio_ports;
> +static int gpio_table_size;
> +
> +#define PINCTRL_DOUT(n) ((cpu_is_mx23() ? 0x0500 : 0x0700) + (n) * 0x10)
> +#define PINCTRL_DIN(n) ((cpu_is_mx23() ? 0x0600 : 0x0900) + (n) * 0x10)
> +#define PINCTRL_DOE(n) ((cpu_is_mx23() ? 0x0700 : 0x0b00) + (n) * 0x10)
> +#define PINCTRL_PIN2IRQ(n) ((cpu_is_mx23() ? 0x0800 : 0x1000) + (n) * 0x10)
> +#define PINCTRL_IRQEN(n) ((cpu_is_mx23() ? 0x0900 : 0x1100) + (n) * 0x10)
> +#define PINCTRL_IRQLEV(n) ((cpu_is_mx23() ? 0x0a00 : 0x1200) + (n) * 0x10)
> +#define PINCTRL_IRQPOL(n) ((cpu_is_mx23() ? 0x0b00 : 0x1300) + (n) * 0x10)
> +#define PINCTRL_IRQSTAT(n) ((cpu_is_mx23() ? 0x0c00 : 0x1400) + (n) * 0x10)
> +
> +#define GPIO_INT_FALL_EDGE 0x0
> +#define GPIO_INT_LOW_LEV 0x1
> +#define GPIO_INT_RISE_EDGE 0x2
> +#define GPIO_INT_HIGH_LEV 0x3
> +#define GPIO_INT_LEV_MASK (1 << 0)
> +#define GPIO_INT_POL_MASK (1 << 1)
> +
> +/* Note: This driver assumes 32 GPIOs are handled in one register */
> +
> +static void _clear_gpio_irqstatus(struct mxs_gpio_port *port, u32 index)
> +{
> + __raw_writel(1 << index,
> + port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR_ADDR);
> +}
> +
> +static void _set_gpio_irqenable(struct mxs_gpio_port *port, u32 index,
> + int enable)
> +{
> + if (enable == 0) {
> + __raw_writel(1 << index,
> + port->base + PINCTRL_PIN2IRQ(port->id) + MXS_CLR_ADDR);
> + __raw_writel(1 << index,
> + port->base + PINCTRL_IRQEN(port->id) + MXS_CLR_ADDR);
This will loose interrupt pulses that happen while IRQs are disabled.
IMO PIN2IRQ should only be cleared when an IRQ is freed, not when it
is disabled.
Lothar Wa?mann
--
___________________________________________________________
Ka-Ro electronics GmbH | Pascalstra?e 22 | D - 52076 Aachen
Phone: +49 2408 1402-0 | Fax: +49 2408 1402-10
Gesch?ftsf?hrer: Matthias Kaussen
Handelsregistereintrag: Amtsgericht Aachen, HRB 4996
www.karo-electronics.de | info at karo-electronics.de
___________________________________________________________
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v4 01/15] ARM: mxs: Add core definitions
2010-12-09 15:12 ` [PATCH v4 01/15] ARM: mxs: Add core definitions Shawn Guo
@ 2010-12-09 17:37 ` Russell King - ARM Linux
0 siblings, 0 replies; 146+ messages in thread
From: Russell King - ARM Linux @ 2010-12-09 17:37 UTC (permalink / raw)
To: linux-arm-kernel
A word of advice, merely as an on-looker. Don't thread your new
versions of patches into the old thread. I now have a total mixture
of v4, v3, v2, etc of these patches and it's not obvious what's the
latest, even if I switch to unsorted or received date.
It might be better to version the series, so that anyone can see which
patches related to the last series - and if you want per patch version
information, include that in the body of the message.
2190 Dec 08 Shawn Guo ( 112) ??>[PATCH v2 12/15] ARM: mxs: Dynamically
2191 Dec 08 Shawn Guo ( 84) ??>[PATCH v2 13/15] ARM: mxs: Add initial
2192 Dec 08 Shawn Guo ( 157) ??>[PATCH v2 14/15] ARM: mxs: Add initial
2193 Dec 08 Uwe Kleine-K?ni ( 183) ? ??>
2194 Dec 09 Shawn Guo ( 78) ? ??>
2195 Dec 09 Uwe Kleine-K?ni ( 22) ? ??>
2196 Dec 09 Shawn Guo ( 39) ? ??>
2197 Dec 09 Uwe Kleine-K?ni ( 30) ? ??>
2198 Dec 09 Shawn Guo ( 58) ? ??>
2199 Dec 09 Lothar Wa?mann ( 93) ? ??>
2200 Dec 09 Shawn Guo ( 130) ? ??>
2201 Dec 09 Shawn Guo ( 133) ? ??>
2202 Dec 08 Shawn Guo ( 155) ??>[PATCH v3 15/15] ARM: mxs: Add build c
2203 N Dec 09 Shawn Guo ( 588) ??>[PATCH v4 01/15] ARM: mxs: Add core de
2204 N Dec 09 Shawn Guo ( 154) ??>[PATCH v3 02/15] ARM: mxs: Add helper
2205 N Dec 09 Shawn Guo ( 213) ??>[PATCH v4 03/15] ARM: mxs: Add reset r
2206 N Dec 09 Shawn Guo ( 168) ??>[PATCH v3 04/15] ARM: mxs: Add interru
2207 N Dec 09 Shawn Guo ( 170) ??>[PATCH v3 05/15] ARM: mxs: Add low-lev
2208 N Dec 09 Shawn Guo ( 322) ??>[PATCH v4 06/15] ARM: mxs: Add timer s
2209 N Dec 09 Shawn Guo ( 440) ??>[PATCH v3 07/15] ARM: mxs: Add gpio su
2210 N Dec 09 Lothar Wa?mann ( 135) ? ??>
2211 N Dec 09 Shawn Guo (2730) ??>[PATCH v3 09/15] ARM: mxs: Add clock s
2212 N Dec 09 Shawn Guo ( 127) ??>[PATCH v2 10/15] ARM: mxs: Add static
2213 N Dec 09 Shawn Guo ( 247) ??>[PATCH v2 11/15] ARM: mxs: Dynamically
2214 N Dec 09 Shawn Guo ( 115) ??>[PATCH v3 12/15] ARM: mxs: Dynamically
2215 N Dec 09 Shawn Guo ( 87) ??>[PATCH v3 13/15] ARM: mxs: Add initial
2216 N Dec 09 Shawn Guo ( 160) ??>[PATCH v3 14/15] ARM: mxs: Add initial
2217 Dec 09 Lothar Wa?mann ( 432) ??>Re: [PATCH v3 08/15] ARM: mxs: Add iom
And we're currently on message number 3200 in this mailbox... so these
messages are buried about 1000 mails back. Not good.
On Thu, Dec 09, 2010 at 11:12:36PM +0800, Shawn Guo wrote:
> Add core definitions for MXS-based SoC MX23 and MX28.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v4:
> - Move all MXS related definitions from hardware.h into mxs.h,
> but have to keep hardware.h which is required by external file.
> - Define IO addresses common to MXS-based in mxs.h
> - Include hardware.h in mxs.h, include mxs.h in mx23.h and mx28.h,
> so that files can include mxs.h, mx23.h, mx28.h individually
> when necessary.
> - Remove #include <linux/io.h> from mx23.h and mx28.h, since it's
> not necessary.
>
> Changes for v3:
> - Update MXS_IO_P2V definition and comment to get them matched
> - Sort mx23 base address definitions by offset
> - Remove mx28 reserved IRQ definitions
> - Remove unnecessary dummy definitions for cpu_is_mx23() and cpu_is_mx28()
>
> Changes for v2:
> - Remove MXS_IO_P2V_MODULE from hardware.h which is not needed
> - Simplify MXS_IO_P2V_MODULE definition in hardware.h
> - Remove unnecessary inclusion protection from hardware.h
> - Change cpu_is_mx23/mx28() implementation in mxs.h to use machine_is_xxx
>
> arch/arm/mach-mxs/include/mach/hardware.h | 29 +++++
> arch/arm/mach-mxs/include/mach/irqs.h | 32 +++++
> arch/arm/mach-mxs/include/mach/memory.h | 24 ++++
> arch/arm/mach-mxs/include/mach/mx23.h | 145 ++++++++++++++++++++++
> arch/arm/mach-mxs/include/mach/mx28.h | 188 +++++++++++++++++++++++++++++
> arch/arm/mach-mxs/include/mach/mxs.h | 85 +++++++++++++
> 6 files changed, 503 insertions(+), 0 deletions(-)
> create mode 100644 arch/arm/mach-mxs/include/mach/hardware.h
> create mode 100644 arch/arm/mach-mxs/include/mach/irqs.h
> create mode 100644 arch/arm/mach-mxs/include/mach/memory.h
> create mode 100644 arch/arm/mach-mxs/include/mach/mx23.h
> create mode 100644 arch/arm/mach-mxs/include/mach/mx28.h
> create mode 100644 arch/arm/mach-mxs/include/mach/mxs.h
>
> diff --git a/arch/arm/mach-mxs/include/mach/hardware.h b/arch/arm/mach-mxs/include/mach/hardware.h
> new file mode 100644
> index 0000000..53e89a0
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/hardware.h
> @@ -0,0 +1,29 @@
> +/*
> + * Copyright 2004-2007 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
> + * 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_MXS_HARDWARE_H__
> +#define __MACH_MXS_HARDWARE_H__
> +
> +#ifdef __ASSEMBLER__
> +#define IOMEM(addr) (addr)
> +#else
> +#define IOMEM(addr) ((void __force __iomem *)(addr))
> +#endif
> +
> +#endif /* __MACH_MXS_HARDWARE_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/irqs.h b/arch/arm/mach-mxs/include/mach/irqs.h
> new file mode 100644
> index 0000000..f771039
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/irqs.h
> @@ -0,0 +1,32 @@
> +/*
> + * Copyright 2004-2007 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.
> + */
> +
> +#ifndef __MACH_MXS_IRQS_H__
> +#define __MACH_MXS_IRQS_H__
> +
> +#define MXS_INTERNAL_IRQS 128
> +
> +#define MXS_GPIO_IRQ_START MXS_INTERNAL_IRQS
> +
> +/* the maximum for MXS-based */
> +#define MXS_GPIO_IRQS (32 * 5)
> +
> +/*
> + * The next 16 interrupts are for board specific purposes. Since
> + * the kernel can only run on one machine at a time, we can re-use
> + * these. If you need more, increase MXS_BOARD_IRQS, but keep it
> + * within sensible limits.
> + */
> +#define MXS_BOARD_IRQ_START (MXS_GPIO_IRQ_START + MXS_GPIO_IRQS)
> +#define MXS_BOARD_IRQS 16
> +
> +#define NR_IRQS (MXS_BOARD_IRQ_START + MXS_BOARD_IRQS)
> +
> +#endif /* __MACH_MXS_IRQS_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/memory.h b/arch/arm/mach-mxs/include/mach/memory.h
> new file mode 100644
> index 0000000..b5420a5
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/memory.h
> @@ -0,0 +1,24 @@
> +/*
> + * 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_MXS_MEMORY_H__
> +#define __MACH_MXS_MEMORY_H__
> +
> +#define PHYS_OFFSET UL(0x40000000)
> +
> +#endif /* __MACH_MXS_MEMORY_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/mx23.h b/arch/arm/mach-mxs/include/mach/mx23.h
> new file mode 100644
> index 0000000..9edd02e
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/mx23.h
> @@ -0,0 +1,145 @@
> +/*
> + * 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_MX23_H__
> +#define __MACH_MX23_H__
> +
> +#include <mach/mxs.h>
> +
> +/*
> + * OCRAM
> + */
> +#define MX23_OCRAM_BASE_ADDR 0x00000000
> +#define MX23_OCRAM_SIZE SZ_32K
> +
> +/*
> + * IO
> + */
> +#define MX23_IO_BASE_ADDR 0x80000000
> +#define MX23_IO_SIZE SZ_1M
> +
> +#define MX23_ICOLL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x000000)
> +#define MX23_APBH_DMA_BASE_ADDR (MX23_IO_BASE_ADDR + 0x004000)
> +#define MX23_BCH_BASE_ADDR (MX23_IO_BASE_ADDR + 0x00a000)
> +#define MX23_GPMI_BASE_ADDR (MX23_IO_BASE_ADDR + 0x00c000)
> +#define MX23_SSP1_BASE_ADDR (MX23_IO_BASE_ADDR + 0x010000)
> +#define MX23_PINCTRL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x018000)
> +#define MX23_DIGCTL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x01c000)
> +#define MX23_ETM_BASE_ADDR (MX23_IO_BASE_ADDR + 0x020000)
> +#define MX23_APBX_DMA_BASE_ADDR (MX23_IO_BASE_ADDR + 0x024000)
> +#define MX23_DCP_BASE_ADDR (MX23_IO_BASE_ADDR + 0x028000)
> +#define MX23_PXP_BASE_ADDR (MX23_IO_BASE_ADDR + 0x02a000)
> +#define MX23_OCOTP_BASE_ADDR (MX23_IO_BASE_ADDR + 0x02c000)
> +#define MX23_AXI_AHB0_BASE_ADDR (MX23_IO_BASE_ADDR + 0x02e000)
> +#define MX23_LCDIF_BASE_ADDR (MX23_IO_BASE_ADDR + 0x030000)
> +#define MX23_SSP2_BASE_ADDR (MX23_IO_BASE_ADDR + 0x034000)
> +#define MX23_TVENC_BASE_ADDR (MX23_IO_BASE_ADDR + 0x038000)
> +#define MX23_CLKCTRL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x040000)
> +#define MX23_SAIF0_BASE_ADDR (MX23_IO_BASE_ADDR + 0x042000)
> +#define MX23_POWER_BASE_ADDR (MX23_IO_BASE_ADDR + 0x044000)
> +#define MX23_SAIF1_BASE_ADDR (MX23_IO_BASE_ADDR + 0x046000)
> +#define MX23_AUDIOOUT_BASE_ADDR (MX23_IO_BASE_ADDR + 0x048000)
> +#define MX23_AUDIOIN_BASE_ADDR (MX23_IO_BASE_ADDR + 0x04c000)
> +#define MX23_LRADC_BASE_ADDR (MX23_IO_BASE_ADDR + 0x050000)
> +#define MX23_SPDIF_BASE_ADDR (MX23_IO_BASE_ADDR + 0x054000)
> +#define MX23_I2C0_BASE_ADDR (MX23_IO_BASE_ADDR + 0x058000)
> +#define MX23_RTC_BASE_ADDR (MX23_IO_BASE_ADDR + 0x05c000)
> +#define MX23_PWM_BASE_ADDR (MX23_IO_BASE_ADDR + 0x064000)
> +#define MX23_TIMROT_BASE_ADDR (MX23_IO_BASE_ADDR + 0x068000)
> +#define MX23_AUART1_BASE_ADDR (MX23_IO_BASE_ADDR + 0x06c000)
> +#define MX23_AUART2_BASE_ADDR (MX23_IO_BASE_ADDR + 0x06e000)
> +#define MX23_DUART_BASE_ADDR (MX23_IO_BASE_ADDR + 0x070000)
> +#define MX23_USBPHY_BASE_ADDR (MX23_IO_BASE_ADDR + 0x07c000)
> +#define MX23_USBCTRL_BASE_ADDR (MX23_IO_BASE_ADDR + 0x080000)
> +#define MX23_DRAM_BASE_ADDR (MX23_IO_BASE_ADDR + 0x0e0000)
> +
> +#define MX23_IO_P2V(x) MXS_IO_P2V(x)
> +#define MX23_IO_ADDRESS(x) IOMEM(MX23_IO_P2V(x))
> +
> +/*
> + * IRQ
> + */
> +#define MX23_INT_DUART 0
> +#define MX23_INT_COMMS_RX 1
> +#define MX23_INT_COMMS_TX 1
> +#define MX23_INT_SSP2_ERROR 2
> +#define MX23_INT_VDD5V 3
> +#define MX23_INT_HEADPHONE_SHORT 4
> +#define MX23_INT_DAC_DMA 5
> +#define MX23_INT_DAC_ERROR 6
> +#define MX23_INT_ADC_DMA 7
> +#define MX23_INT_ADC_ERROR 8
> +#define MX23_INT_SPDIF_DMA 9
> +#define MX23_INT_SAIF2_DMA 9
> +#define MX23_INT_SPDIF_ERROR 10
> +#define MX23_INT_SAIF1_IRQ 10
> +#define MX23_INT_SAIF2_IRQ 10
> +#define MX23_INT_USB_CTRL 11
> +#define MX23_INT_USB_WAKEUP 12
> +#define MX23_INT_GPMI_DMA 13
> +#define MX23_INT_SSP1_DMA 14
> +#define MX23_INT_SSP_ERROR 15
> +#define MX23_INT_GPIO0 16
> +#define MX23_INT_GPIO1 17
> +#define MX23_INT_GPIO2 18
> +#define MX23_INT_SAIF1_DMA 19
> +#define MX23_INT_SSP2_DMA 20
> +#define MX23_INT_ECC8_IRQ 21
> +#define MX23_INT_RTC_ALARM 22
> +#define MX23_INT_UARTAPP_TX_DMA 23
> +#define MX23_INT_UARTAPP_INTERNAL 24
> +#define MX23_INT_UARTAPP_RX_DMA 25
> +#define MX23_INT_I2C_DMA 26
> +#define MX23_INT_I2C_ERROR 27
> +#define MX23_INT_TIMER0 28
> +#define MX23_INT_TIMER1 29
> +#define MX23_INT_TIMER2 30
> +#define MX23_INT_TIMER3 31
> +#define MX23_INT_BATT_BRNOUT 32
> +#define MX23_INT_VDDD_BRNOUT 33
> +#define MX23_INT_VDDIO_BRNOUT 34
> +#define MX23_INT_VDD18_BRNOUT 35
> +#define MX23_INT_TOUCH_DETECT 36
> +#define MX23_INT_LRADC_CH0 37
> +#define MX23_INT_LRADC_CH1 38
> +#define MX23_INT_LRADC_CH2 39
> +#define MX23_INT_LRADC_CH3 40
> +#define MX23_INT_LRADC_CH4 41
> +#define MX23_INT_LRADC_CH5 42
> +#define MX23_INT_LRADC_CH6 43
> +#define MX23_INT_LRADC_CH7 44
> +#define MX23_INT_LCDIF_DMA 45
> +#define MX23_INT_LCDIF_ERROR 46
> +#define MX23_INT_DIGCTL_DEBUG_TRAP 47
> +#define MX23_INT_RTC_1MSEC 48
> +#define MX23_INT_DRI_DMA 49
> +#define MX23_INT_DRI_ATTENTION 50
> +#define MX23_INT_GPMI_ATTENTION 51
> +#define MX23_INT_IR 52
> +#define MX23_INT_DCP_VMI 53
> +#define MX23_INT_DCP 54
> +#define MX23_INT_BCH 56
> +#define MX23_INT_PXP 57
> +#define MX23_INT_UARTAPP2_TX_DMA 58
> +#define MX23_INT_UARTAPP2_INTERNAL 59
> +#define MX23_INT_UARTAPP2_RX_DMA 60
> +#define MX23_INT_VDAC_DETECT 61
> +#define MX23_INT_VDD5V_DROOP 64
> +#define MX23_INT_DCDC4P2_BO 65
> +
> +#endif /* __MACH_MX23_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/mx28.h b/arch/arm/mach-mxs/include/mach/mx28.h
> new file mode 100644
> index 0000000..0716745
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/mx28.h
> @@ -0,0 +1,188 @@
> +/*
> + * 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__
> +
> +#include <mach/mxs.h>
> +
> +/*
> + * 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_MAC0_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0f0000)
> +#define MX28_ENET_MAC1_BASE_ADDR (MX28_IO_BASE_ADDR + 0x0f4000)
> +
> +#define MX28_IO_P2V(x) MXS_IO_P2V(x)
> +#define MX28_IO_ADDRESS(x) IOMEM(MX28_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_CAN0 8
> +#define MX28_INT_CAN1 9
> +#define MX28_INT_LRADC_TOUCH 10
> +#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_PERFMON 27
> +#define MX28_INT_RTC_1MSEC 28
> +#define MX28_INT_RTC_ALARM 29
> +#define MX28_INT_COMMS 31
> +#define MX28_INT_EMI_ERR 32
> +#define MX28_INT_LCDIF 38
> +#define MX28_INT_PXP 39
> +#define MX28_INT_BCH 41
> +#define MX28_INT_GPMI 42
> +#define MX28_INT_SPDIF_ERROR 45
> +#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_SAIF1 58
> +#define MX28_INT_SAIF0 59
> +#define MX28_INT_SPDIF_DMA 66
> +#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_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_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_GPIO4 123
> +#define MX28_INT_GPIO3 124
> +#define MX28_INT_GPIO2 125
> +#define MX28_INT_GPIO1 126
> +#define MX28_INT_GPIO0 127
> +
> +#endif /* __MACH_MX28_H__ */
> diff --git a/arch/arm/mach-mxs/include/mach/mxs.h b/arch/arm/mach-mxs/include/mach/mxs.h
> new file mode 100644
> index 0000000..4212ab0
> --- /dev/null
> +++ b/arch/arm/mach-mxs/include/mach/mxs.h
> @@ -0,0 +1,85 @@
> +/*
> + * 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_MXS_H__
> +#define __MACH_MXS_H__
> +
> +#include <asm/mach-types.h>
> +#include <mach/hardware.h>
> +
> +/*
> + * MXS CPU types
> + */
> +#define cpu_is_mx23() (machine_is_mx23evk())
> +#define cpu_is_mx28() (machine_is_mx28evk())
> +
> +#define MXS_SET_ADDR 0x4
> +#define MXS_CLR_ADDR 0x8
> +#define MXS_TOG_ADDR 0xc
> +
> +/*
> + * IO addresses common to MXS-based
> + */
> +#define MXS_IO_BASE_ADDR 0x80000000
> +#define MXS_IO_SIZE SZ_1M
> +
> +#define MXS_ICOLL_BASE_ADDR (MXS_IO_BASE_ADDR + 0x000000)
> +#define MXS_APBH_DMA_BASE_ADDR (MXS_IO_BASE_ADDR + 0x004000)
> +#define MXS_BCH_BASE_ADDR (MXS_IO_BASE_ADDR + 0x00a000)
> +#define MXS_GPMI_BASE_ADDR (MXS_IO_BASE_ADDR + 0x00c000)
> +#define MXS_PINCTRL_BASE_ADDR (MXS_IO_BASE_ADDR + 0x018000)
> +#define MXS_DIGCTL_BASE_ADDR (MXS_IO_BASE_ADDR + 0x01c000)
> +#define MXS_APBX_DMA_BASE_ADDR (MXS_IO_BASE_ADDR + 0x024000)
> +#define MXS_DCP_BASE_ADDR (MXS_IO_BASE_ADDR + 0x028000)
> +#define MXS_PXP_BASE_ADDR (MXS_IO_BASE_ADDR + 0x02a000)
> +#define MXS_OCOTP_BASE_ADDR (MXS_IO_BASE_ADDR + 0x02c000)
> +#define MXS_AXI_AHB0_BASE_ADDR (MXS_IO_BASE_ADDR + 0x02e000)
> +#define MXS_LCDIF_BASE_ADDR (MXS_IO_BASE_ADDR + 0x030000)
> +#define MXS_CLKCTRL_BASE_ADDR (MXS_IO_BASE_ADDR + 0x040000)
> +#define MXS_SAIF0_BASE_ADDR (MXS_IO_BASE_ADDR + 0x042000)
> +#define MXS_POWER_BASE_ADDR (MXS_IO_BASE_ADDR + 0x044000)
> +#define MXS_SAIF1_BASE_ADDR (MXS_IO_BASE_ADDR + 0x046000)
> +#define MXS_LRADC_BASE_ADDR (MXS_IO_BASE_ADDR + 0x050000)
> +#define MXS_SPDIF_BASE_ADDR (MXS_IO_BASE_ADDR + 0x054000)
> +#define MXS_I2C0_BASE_ADDR (MXS_IO_BASE_ADDR + 0x058000)
> +#define MXS_PWM_BASE_ADDR (MXS_IO_BASE_ADDR + 0x064000)
> +#define MXS_TIMROT_BASE_ADDR (MXS_IO_BASE_ADDR + 0x068000)
> +#define MXS_AUART1_BASE_ADDR (MXS_IO_BASE_ADDR + 0x06c000)
> +#define MXS_AUART2_BASE_ADDR (MXS_IO_BASE_ADDR + 0x06e000)
> +#define MXS_DRAM_BASE_ADDR (MXS_IO_BASE_ADDR + 0x0e0000)
> +
> +/*
> + * It maps the whole address space to [0xf4000000, 0xf50fffff].
> + *
> + * OCRAM 0x00000000+0x020000 -> 0xf4000000+0x020000
> + * IO 0x80000000+0x100000 -> 0xf5000000+0x100000
> + */
> +#define MXS_IO_P2V(x) (0xf4000000 + \
> + (((x) & 0x80000000) >> 7) + \
> + (((x) & 0x000fffff)))
> +
> +#define MXS_IO_ADDRESS(x) IOMEM(MXS_IO_P2V(x))
> +
> +#define mxs_map_entry(soc, name, _type) { \
> + .virtual = soc ## _IO_P2V(soc ## _ ## name ## _BASE_ADDR), \
> + .pfn = __phys_to_pfn(soc ## _ ## name ## _BASE_ADDR), \
> + .length = soc ## _ ## name ## _SIZE, \
> + .type = _type, \
> +}
> +
> +#endif /* __MACH_MXS_H__ */
> --
> 1.7.1
>
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v3 09/15] ARM: mxs: Add clock support
2010-12-09 15:12 ` [PATCH v3 09/15] ARM: mxs: Add clock support Shawn Guo
@ 2010-12-09 21:11 ` Uwe Kleine-König
0 siblings, 0 replies; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-09 21:11 UTC (permalink / raw)
To: linux-arm-kernel
Hello Shawn,
On Thu, Dec 09, 2010 at 11:12:44PM +0800, Shawn Guo wrote:
> diff --git a/arch/arm/mach-mxs/clock-mx23.c b/arch/arm/mach-mxs/clock-mx23.c
> new file mode 100644
> index 0000000..b2923da
> --- /dev/null
> +++ b/arch/arm/mach-mxs/clock-mx23.c
> @@ -0,0 +1,526 @@
> +[...]
> +static int cpu_clk_set_rate(struct clk *clk, unsigned long rate)
> +{
> +[...]
> + rate <<= PARENT_RATE_SHIFT;
> + parent_rate <<= PARENT_RATE_SHIFT;
You're making the problem worse here. You need to shift right!
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v3 07/15] ARM: mxs: Add gpio support
2010-12-09 16:47 ` Lothar Waßmann
@ 2010-12-10 7:06 ` Shawn Guo
2010-12-10 7:23 ` Shawn Guo
0 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-10 7:06 UTC (permalink / raw)
To: linux-arm-kernel
Hi Lothar,
On Fri, Dec 10, 2010 at 12:47 AM, Lothar Wa?mann <LW@karo-electronics.de> wrote:
> Hi,
>
> Shawn Guo writes:
>> MXS-based SoCs implement gpio support in block PINCTRL.
>>
>> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
>> ---
>> Changes for v3:
>> ?- include/mach/gpio.h: remove the inclusion of hardware.h
>> ?- gpio.c: change inclusion of hardware.h to mx23.h plus mx28.h
>> ?- Remove spinlock totally since SET/CLE can be used in all the
>> ? ?gpio register access
>>
>> Changes for v2:
>> ?- Create arch/arm/mach-mxs/gpio.h to accommodate stuff private for mach-mxs
>> ?- Use GPIO_INT_LEV_MASK and GPIO_INT_POL_MASK instead of constant
>> ?- Remove both edges IRQ support which is not needed
>> ?- Use SET and CLR register of PINCTRL_DOE in _set_gpio_direction()
>> ?- Use pr_info over printk(KERN_INFO)
>>
>> ?arch/arm/mach-mxs/gpio.c ? ? ? ? ? ? ?| ?321 +++++++++++++++++++++++++++++++++
>> ?arch/arm/mach-mxs/gpio.h ? ? ? ? ? ? ?| ? 33 ++++
>> ?arch/arm/mach-mxs/include/mach/gpio.h | ? 34 ++++
>> ?3 files changed, 388 insertions(+), 0 deletions(-)
>> ?create mode 100644 arch/arm/mach-mxs/gpio.c
>> ?create mode 100644 arch/arm/mach-mxs/gpio.h
>> ?create mode 100644 arch/arm/mach-mxs/include/mach/gpio.h
>>
>> diff --git a/arch/arm/mach-mxs/gpio.c b/arch/arm/mach-mxs/gpio.c
>> new file mode 100644
>> index 0000000..d88acf3
>> --- /dev/null
>> +++ b/arch/arm/mach-mxs/gpio.c
>> @@ -0,0 +1,321 @@
>> +/*
>> + * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
>> + * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
>> + *
>> + * Based on code from Freescale,
>> + * Copyright (C) 2004-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/init.h>
>> +#include <linux/interrupt.h>
>> +#include <linux/io.h>
>> +#include <linux/irq.h>
>> +#include <linux/gpio.h>
>> +#include <mach/mx23.h>
>> +#include <mach/mx28.h>
>> +#include <asm-generic/bug.h>
>> +
>> +#include "gpio.h"
>> +
>> +static struct mxs_gpio_port *mxs_gpio_ports;
>> +static int gpio_table_size;
>> +
>> +#define PINCTRL_DOUT(n) ? ? ? ? ? ? ?((cpu_is_mx23() ? 0x0500 : 0x0700) + (n) * 0x10)
>> +#define PINCTRL_DIN(n) ? ? ? ? ? ? ? ((cpu_is_mx23() ? 0x0600 : 0x0900) + (n) * 0x10)
>> +#define PINCTRL_DOE(n) ? ? ? ? ? ? ? ((cpu_is_mx23() ? 0x0700 : 0x0b00) + (n) * 0x10)
>> +#define PINCTRL_PIN2IRQ(n) ? ((cpu_is_mx23() ? 0x0800 : 0x1000) + (n) * 0x10)
>> +#define PINCTRL_IRQEN(n) ? ? ((cpu_is_mx23() ? 0x0900 : 0x1100) + (n) * 0x10)
>> +#define PINCTRL_IRQLEV(n) ? ?((cpu_is_mx23() ? 0x0a00 : 0x1200) + (n) * 0x10)
>> +#define PINCTRL_IRQPOL(n) ? ?((cpu_is_mx23() ? 0x0b00 : 0x1300) + (n) * 0x10)
>> +#define PINCTRL_IRQSTAT(n) ? ((cpu_is_mx23() ? 0x0c00 : 0x1400) + (n) * 0x10)
>> +
>> +#define GPIO_INT_FALL_EDGE ? 0x0
>> +#define GPIO_INT_LOW_LEV ? ? 0x1
>> +#define GPIO_INT_RISE_EDGE ? 0x2
>> +#define GPIO_INT_HIGH_LEV ? ?0x3
>> +#define GPIO_INT_LEV_MASK ? ?(1 << 0)
>> +#define GPIO_INT_POL_MASK ? ?(1 << 1)
>> +
>> +/* Note: This driver assumes 32 GPIOs are handled in one register */
>> +
>> +static void _clear_gpio_irqstatus(struct mxs_gpio_port *port, u32 index)
>> +{
>> + ? ? __raw_writel(1 << index,
>> + ? ? ? ? ? ? ? ? ? ? port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR_ADDR);
>> +}
>> +
>> +static void _set_gpio_irqenable(struct mxs_gpio_port *port, u32 index,
>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? int enable)
>> +{
>> + ? ? if (enable == 0) {
>> + ? ? ? ? ? ? __raw_writel(1 << index,
>> + ? ? ? ? ? ? ? ? ? ? port->base + PINCTRL_PIN2IRQ(port->id) + MXS_CLR_ADDR);
>> + ? ? ? ? ? ? __raw_writel(1 << index,
>> + ? ? ? ? ? ? ? ? ? ? port->base + PINCTRL_IRQEN(port->id) + MXS_CLR_ADDR);
> This will loose interrupt pulses that happen while IRQs are disabled.
> IMO PIN2IRQ should only be cleared when an IRQ is freed, not when it
> is disabled.
>
What about leaving PIN2IRQ always be 1 and only using IRQEN to
enable/disable IRQ? I consulted the designer it's no problem no
matter what the pin function is.
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v3 07/15] ARM: mxs: Add gpio support
2010-12-10 7:06 ` Shawn Guo
@ 2010-12-10 7:23 ` Shawn Guo
2010-12-10 8:11 ` Uwe Kleine-König
0 siblings, 1 reply; 146+ messages in thread
From: Shawn Guo @ 2010-12-10 7:23 UTC (permalink / raw)
To: linux-arm-kernel
On Fri, Dec 10, 2010 at 3:06 PM, Shawn Guo <shawn.gsc@gmail.com> wrote:
> Hi Lothar,
>
> On Fri, Dec 10, 2010 at 12:47 AM, Lothar Wa?mann <LW@karo-electronics.de> wrote:
>> Hi,
>>
>> Shawn Guo writes:
>>> MXS-based SoCs implement gpio support in block PINCTRL.
>>>
>>> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
>>> ---
>>> Changes for v3:
>>> ?- include/mach/gpio.h: remove the inclusion of hardware.h
>>> ?- gpio.c: change inclusion of hardware.h to mx23.h plus mx28.h
>>> ?- Remove spinlock totally since SET/CLE can be used in all the
>>> ? ?gpio register access
>>>
>>> Changes for v2:
>>> ?- Create arch/arm/mach-mxs/gpio.h to accommodate stuff private for mach-mxs
>>> ?- Use GPIO_INT_LEV_MASK and GPIO_INT_POL_MASK instead of constant
>>> ?- Remove both edges IRQ support which is not needed
>>> ?- Use SET and CLR register of PINCTRL_DOE in _set_gpio_direction()
>>> ?- Use pr_info over printk(KERN_INFO)
>>>
>>> ?arch/arm/mach-mxs/gpio.c ? ? ? ? ? ? ?| ?321 +++++++++++++++++++++++++++++++++
>>> ?arch/arm/mach-mxs/gpio.h ? ? ? ? ? ? ?| ? 33 ++++
>>> ?arch/arm/mach-mxs/include/mach/gpio.h | ? 34 ++++
>>> ?3 files changed, 388 insertions(+), 0 deletions(-)
>>> ?create mode 100644 arch/arm/mach-mxs/gpio.c
>>> ?create mode 100644 arch/arm/mach-mxs/gpio.h
>>> ?create mode 100644 arch/arm/mach-mxs/include/mach/gpio.h
>>>
>>> diff --git a/arch/arm/mach-mxs/gpio.c b/arch/arm/mach-mxs/gpio.c
>>> new file mode 100644
>>> index 0000000..d88acf3
>>> --- /dev/null
>>> +++ b/arch/arm/mach-mxs/gpio.c
>>> @@ -0,0 +1,321 @@
>>> +/*
>>> + * MXC GPIO support. (c) 2008 Daniel Mack <daniel@caiaq.de>
>>> + * Copyright 2008 Juergen Beisert, kernel at pengutronix.de
>>> + *
>>> + * Based on code from Freescale,
>>> + * Copyright (C) 2004-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/init.h>
>>> +#include <linux/interrupt.h>
>>> +#include <linux/io.h>
>>> +#include <linux/irq.h>
>>> +#include <linux/gpio.h>
>>> +#include <mach/mx23.h>
>>> +#include <mach/mx28.h>
>>> +#include <asm-generic/bug.h>
>>> +
>>> +#include "gpio.h"
>>> +
>>> +static struct mxs_gpio_port *mxs_gpio_ports;
>>> +static int gpio_table_size;
>>> +
>>> +#define PINCTRL_DOUT(n) ? ? ? ? ? ? ?((cpu_is_mx23() ? 0x0500 : 0x0700) + (n) * 0x10)
>>> +#define PINCTRL_DIN(n) ? ? ? ? ? ? ? ((cpu_is_mx23() ? 0x0600 : 0x0900) + (n) * 0x10)
>>> +#define PINCTRL_DOE(n) ? ? ? ? ? ? ? ((cpu_is_mx23() ? 0x0700 : 0x0b00) + (n) * 0x10)
>>> +#define PINCTRL_PIN2IRQ(n) ? ((cpu_is_mx23() ? 0x0800 : 0x1000) + (n) * 0x10)
>>> +#define PINCTRL_IRQEN(n) ? ? ((cpu_is_mx23() ? 0x0900 : 0x1100) + (n) * 0x10)
>>> +#define PINCTRL_IRQLEV(n) ? ?((cpu_is_mx23() ? 0x0a00 : 0x1200) + (n) * 0x10)
>>> +#define PINCTRL_IRQPOL(n) ? ?((cpu_is_mx23() ? 0x0b00 : 0x1300) + (n) * 0x10)
>>> +#define PINCTRL_IRQSTAT(n) ? ((cpu_is_mx23() ? 0x0c00 : 0x1400) + (n) * 0x10)
>>> +
>>> +#define GPIO_INT_FALL_EDGE ? 0x0
>>> +#define GPIO_INT_LOW_LEV ? ? 0x1
>>> +#define GPIO_INT_RISE_EDGE ? 0x2
>>> +#define GPIO_INT_HIGH_LEV ? ?0x3
>>> +#define GPIO_INT_LEV_MASK ? ?(1 << 0)
>>> +#define GPIO_INT_POL_MASK ? ?(1 << 1)
>>> +
>>> +/* Note: This driver assumes 32 GPIOs are handled in one register */
>>> +
>>> +static void _clear_gpio_irqstatus(struct mxs_gpio_port *port, u32 index)
>>> +{
>>> + ? ? __raw_writel(1 << index,
>>> + ? ? ? ? ? ? ? ? ? ? port->base + PINCTRL_IRQSTAT(port->id) + MXS_CLR_ADDR);
>>> +}
>>> +
>>> +static void _set_gpio_irqenable(struct mxs_gpio_port *port, u32 index,
>>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? int enable)
>>> +{
>>> + ? ? if (enable == 0) {
>>> + ? ? ? ? ? ? __raw_writel(1 << index,
>>> + ? ? ? ? ? ? ? ? ? ? port->base + PINCTRL_PIN2IRQ(port->id) + MXS_CLR_ADDR);
>>> + ? ? ? ? ? ? __raw_writel(1 << index,
>>> + ? ? ? ? ? ? ? ? ? ? port->base + PINCTRL_IRQEN(port->id) + MXS_CLR_ADDR);
>> This will loose interrupt pulses that happen while IRQs are disabled.
>> IMO PIN2IRQ should only be cleared when an IRQ is freed, not when it
>> is disabled.
>>
> What about leaving PIN2IRQ always be 1 and only using IRQEN to
> enable/disable IRQ? ?I consulted the designer it's no problem no
> matter what the pin function is.
>
The code will be like:
static void _set_gpio_irqenable(struct mxs_gpio_port *port, u32 index,
int enable)
{
if (enable) {
__raw_writel(1 << index,
port->base + PINCTRL_IRQEN(port->id) + MXS_SET_ADDR);
__raw_writel(1 << index,
port->base + PINCTRL_PIN2IRQ(port->id) + MXS_SET_ADDR);
} else {
__raw_writel(1 << index,
port->base + PINCTRL_IRQEN(port->id) + MXS_CLR_ADDR);
}
}
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v3 07/15] ARM: mxs: Add gpio support
2010-12-10 7:23 ` Shawn Guo
@ 2010-12-10 8:11 ` Uwe Kleine-König
2010-12-10 15:32 ` Shawn Guo
0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-10 8:11 UTC (permalink / raw)
To: linux-arm-kernel
Hello Shawn,
On Fri, Dec 10, 2010 at 03:23:13PM +0800, Shawn Guo wrote:
> On Fri, Dec 10, 2010 at 3:06 PM, Shawn Guo <shawn.gsc@gmail.com> wrote:
> > On Fri, Dec 10, 2010 at 12:47 AM, Lothar Wa?mann <LW@karo-electronics.de> wrote:
> >> Shawn Guo writes:
> >>> +static void _set_gpio_irqenable(struct mxs_gpio_port *port, u32 index,
> >>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? int enable)
> >>> +{
> >>> + ? ? if (enable == 0) {
> >>> + ? ? ? ? ? ? __raw_writel(1 << index,
> >>> + ? ? ? ? ? ? ? ? ? ? port->base + PINCTRL_PIN2IRQ(port->id) + MXS_CLR_ADDR);
> >>> + ? ? ? ? ? ? __raw_writel(1 << index,
> >>> + ? ? ? ? ? ? ? ? ? ? port->base + PINCTRL_IRQEN(port->id) + MXS_CLR_ADDR);
> >> This will loose interrupt pulses that happen while IRQs are disabled.
> >> IMO PIN2IRQ should only be cleared when an IRQ is freed, not when it
> >> is disabled.
> >>
> > What about leaving PIN2IRQ always be 1 and only using IRQEN to
> > enable/disable IRQ? ?I consulted the designer it's no problem no
> > matter what the pin function is.
> >
> The code will be like:
>
> static void _set_gpio_irqenable(struct mxs_gpio_port *port, u32 index,
> int enable)
> {
> if (enable) {
> __raw_writel(1 << index,
> port->base + PINCTRL_IRQEN(port->id) + MXS_SET_ADDR);
> __raw_writel(1 << index,
> port->base + PINCTRL_PIN2IRQ(port->id) + MXS_SET_ADDR);
> } else {
> __raw_writel(1 << index,
> port->base + PINCTRL_IRQEN(port->id) + MXS_CLR_ADDR);
> }
> }
If I understood Lothar correctly the best way is to set and clear
PINCTRL_PIN2IRQ in the irqchips irq_startup and irq_shutdown routine.
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v3 15/15] ARM: mxs: Add build configuration for mxs
2010-12-07 16:32 ` [PATCH v3 15/15] ARM: mxs: Add build configuration for mxs Shawn Guo
@ 2010-12-10 14:51 ` Uwe Kleine-König
2010-12-10 15:05 ` Shawn Guo
0 siblings, 1 reply; 146+ messages in thread
From: Uwe Kleine-König @ 2010-12-10 14:51 UTC (permalink / raw)
To: linux-arm-kernel
Hallo Shawn,
On Wed, Dec 08, 2010 at 12:32:03AM +0800, Shawn Guo wrote:
> - Remove cpu.o from arch/arm/mach-mxs/Makefile
> [...]
>
> diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
> new file mode 100644
> index 0000000..40b808c
> --- /dev/null
> +++ b/arch/arm/mach-mxs/Makefile
> @@ -0,0 +1,10 @@
> +# Common support
> +obj-y := clock.o cpu.o devices.o gpio.o icoll.o iomux.o system.o timer.o
^^^^^
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v3 15/15] ARM: mxs: Add build configuration for mxs
2010-12-10 14:51 ` Uwe Kleine-König
@ 2010-12-10 15:05 ` Shawn Guo
0 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-10 15:05 UTC (permalink / raw)
To: linux-arm-kernel
Hi Uwe,
2010/12/10 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hallo Shawn,
>
> On Wed, Dec 08, 2010 at 12:32:03AM +0800, Shawn Guo wrote:
>> ?- Remove cpu.o from arch/arm/mach-mxs/Makefile
>> [...]
>>
>> diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
>> new file mode 100644
>> index 0000000..40b808c
>> --- /dev/null
>> +++ b/arch/arm/mach-mxs/Makefile
>> @@ -0,0 +1,10 @@
>> +# Common support
>> +obj-y := clock.o cpu.o devices.o gpio.o icoll.o iomux.o system.o timer.o
> ? ? ? ? ? ? ? ? ? ?^^^^^
>
There was something wrong with my patch management. The commit of
removing cpu.o was squashed into another local patch. Thanks for
catching.
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 146+ messages in thread
* [PATCH v3 07/15] ARM: mxs: Add gpio support
2010-12-10 8:11 ` Uwe Kleine-König
@ 2010-12-10 15:32 ` Shawn Guo
0 siblings, 0 replies; 146+ messages in thread
From: Shawn Guo @ 2010-12-10 15:32 UTC (permalink / raw)
To: linux-arm-kernel
Hi Uwe,
2010/12/10 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Shawn,
>
> On Fri, Dec 10, 2010 at 03:23:13PM +0800, Shawn Guo wrote:
>> On Fri, Dec 10, 2010 at 3:06 PM, Shawn Guo <shawn.gsc@gmail.com> wrote:
>> > On Fri, Dec 10, 2010 at 12:47 AM, Lothar Wa?mann <LW@karo-electronics.de> wrote:
>> >> Shawn Guo writes:
>> >>> +static void _set_gpio_irqenable(struct mxs_gpio_port *port, u32 index,
>> >>> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? int enable)
>> >>> +{
>> >>> + ? ? if (enable == 0) {
>> >>> + ? ? ? ? ? ? __raw_writel(1 << index,
>> >>> + ? ? ? ? ? ? ? ? ? ? port->base + PINCTRL_PIN2IRQ(port->id) + MXS_CLR_ADDR);
>> >>> + ? ? ? ? ? ? __raw_writel(1 << index,
>> >>> + ? ? ? ? ? ? ? ? ? ? port->base + PINCTRL_IRQEN(port->id) + MXS_CLR_ADDR);
>> >> This will loose interrupt pulses that happen while IRQs are disabled.
>> >> IMO PIN2IRQ should only be cleared when an IRQ is freed, not when it
>> >> is disabled.
>> >>
>> > What about leaving PIN2IRQ always be 1 and only using IRQEN to
>> > enable/disable IRQ? ?I consulted the designer it's no problem no
>> > matter what the pin function is.
>> >
>> The code will be like:
>>
>> static void _set_gpio_irqenable(struct mxs_gpio_port *port, u32 index,
>> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? int enable)
>> {
>> ? ? ? ? if (enable) {
>> ? ? ? ? ? ? ? ? __raw_writel(1 << index,
>> ? ? ? ? ? ? ? ? ? ? ? ? port->base + PINCTRL_IRQEN(port->id) + MXS_SET_ADDR);
>> ? ? ? ? ? ? ? ? __raw_writel(1 << index,
>> ? ? ? ? ? ? ? ? ? ? ? ? port->base + PINCTRL_PIN2IRQ(port->id) + MXS_SET_ADDR);
>> ? ? ? ? } else {
>> ? ? ? ? ? ? ? ? __raw_writel(1 << index,
>> ? ? ? ? ? ? ? ? ? ? ? ? port->base + PINCTRL_IRQEN(port->id) + MXS_CLR_ADDR);
>> ? ? ? ? }
>> }
> If I understood Lothar correctly the best way is to set and clear
> PINCTRL_PIN2IRQ in the irqchips irq_startup and irq_shutdown routine.
>
Is there any problem with the current code to address Lothar's
concern? If no, I would not introduce two more irq_chip routines into
the file.
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 146+ messages in thread
end of thread, other threads:[~2010-12-10 15:32 UTC | newest]
Thread overview: 146+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-11-26 6:48 [PATCH 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
2010-11-26 6:49 ` [PATCH 01/15] ARM: mxs: Add core definitions Shawn Guo
2010-11-26 11:30 ` Uwe Kleine-König
2010-11-29 7:21 ` Shawn Guo
2010-11-26 6:49 ` [PATCH 02/15] ARM: mxs: Add helper definition and function Shawn Guo
2010-11-26 6:49 ` [PATCH 03/15] ARM: mxs: Add reset routines Shawn Guo
2010-11-26 9:31 ` Lothar Waßmann
2010-11-26 9:57 ` Uwe Kleine-König
2010-11-26 10:38 ` Lothar Waßmann
2010-11-26 11:32 ` Uwe Kleine-König
2010-11-26 12:53 ` Lothar Waßmann
2010-11-29 9:25 ` [PATCH] prevent 'BUG: sleeping function called from invalid context' in arch_reset() Lothar Waßmann
2010-11-29 9:58 ` Uwe Kleine-König
2010-12-06 16:13 ` Uwe Kleine-König
2010-11-26 14:16 ` [PATCH 03/15] ARM: mxs: Add reset routines Xinyu Chen
2010-11-26 14:38 ` Lothar Waßmann
2010-11-26 6:49 ` [PATCH 04/15] ARM: mxs: Add interrupt support Shawn Guo
2010-11-30 13:56 ` Uwe Kleine-König
2010-11-30 17:02 ` Russell King - ARM Linux
2010-12-01 11:23 ` Shawn Guo
2010-11-26 6:49 ` [PATCH 05/15] ARM: mxs: Add low-level debug UART support Shawn Guo
2010-11-30 15:48 ` Uwe Kleine-König
2010-11-26 6:49 ` [PATCH 06/15] ARM: mxs: Add timer support Shawn Guo
2010-11-30 16:13 ` Uwe Kleine-König
2010-12-02 14:44 ` Shawn Guo
2010-12-02 15:20 ` Thomas Gleixner
2010-12-02 16:48 ` Uwe Kleine-König
2010-11-26 6:49 ` [PATCH 07/15] ARM: mxs: Add gpio support Shawn Guo
2010-11-30 16:21 ` Uwe Kleine-König
2010-11-26 6:49 ` [PATCH 08/15] ARM: mxs: Add iomux support Shawn Guo
2010-11-30 16:32 ` Uwe Kleine-König
2010-11-26 6:49 ` [PATCH 09/15] ARM: mxs: Add clock support Shawn Guo
2010-11-30 16:39 ` Uwe Kleine-König
2010-12-07 13:09 ` Shawn Guo
2010-12-07 13:33 ` Uwe Kleine-König
2010-12-07 13:53 ` Shawn Guo
2010-12-02 15:07 ` Uwe Kleine-König
2010-12-03 5:07 ` Shawn Guo
2010-11-26 6:49 ` [PATCH 10/15] ARM: mxs: Add static memory mapping Shawn Guo
2010-11-26 6:49 ` [PATCH 11/15] ARM: mxs: Dynamically allocate duart devices Shawn Guo
2010-11-26 6:49 ` [PATCH 12/15] ARM: mxs: Dynamically allocate fec devices Shawn Guo
2010-11-30 20:01 ` Uwe Kleine-König
2010-11-26 6:49 ` [PATCH 13/15] ARM: mxs: Add initial mx23evk support Shawn Guo
2010-11-30 20:02 ` Uwe Kleine-König
2010-11-26 6:49 ` [PATCH 14/15] ARM: mxs: Add initial mx28evk support Shawn Guo
2010-11-30 20:06 ` Uwe Kleine-König
2010-11-26 6:49 ` [PATCH 15/15] ARM: mxs: Add build configuration for mxs Shawn Guo
2010-11-30 20:08 ` Uwe Kleine-König
2010-11-29 11:59 ` [PATCH v2 01/15] ARM: mxs: Add core definitions Shawn Guo
2010-11-30 9:21 ` Uwe Kleine-König
2010-11-29 11:59 ` [PATCH v2 02/15] ARM: mxs: Add helper definition and function Shawn Guo
2010-11-29 11:59 ` [PATCH v2 03/15] ARM: mxs: Add reset routines Shawn Guo
2010-11-30 10:25 ` Uwe Kleine-König
2010-12-01 10:45 ` Shawn Guo
2010-12-01 10:59 ` Uwe Kleine-König
2010-12-01 11:34 ` Shawn Guo
2010-12-02 6:02 ` Shawn Guo
2010-12-02 7:27 ` Uwe Kleine-König
2010-12-02 9:40 ` Uwe Kleine-König
2010-12-02 10:16 ` Shawn Guo
2010-11-29 11:59 ` [PATCH v2 06/15] ARM: mxs: Add timer support Shawn Guo
2010-11-29 11:59 ` [PATCH v2 10/15] ARM: mxs: Add static memory mapping Shawn Guo
2010-11-29 11:59 ` [PATCH v2 15/15] ARM: mxs: Add build configuration for mxs Shawn Guo
2010-12-07 16:31 ` [PATCH v3 01/15] ARM: mxs: Add core definitions Shawn Guo
2010-12-07 20:18 ` Uwe Kleine-König
2010-12-08 4:50 ` Shawn Guo
2010-12-08 9:17 ` Uwe Kleine-König
2010-12-07 16:31 ` [PATCH v3 03/15] ARM: mxs: Add reset routines Shawn Guo
2010-12-07 20:27 ` Uwe Kleine-König
2010-12-08 7:33 ` Lothar Waßmann
2010-12-08 20:31 ` Uwe Kleine-König
2010-12-09 8:51 ` Shawn Guo
2010-12-09 8:55 ` Uwe Kleine-König
2010-12-07 16:31 ` [PATCH v2 04/15] ARM: mxs: Add interrupt support Shawn Guo
2010-12-07 21:03 ` Uwe Kleine-König
2010-12-08 8:27 ` Shawn Guo
2010-12-08 9:39 ` Uwe Kleine-König
2010-12-08 10:46 ` Shawn Guo
2010-12-08 12:09 ` Uwe Kleine-König
2010-12-08 12:31 ` Shawn Guo
2010-12-08 8:56 ` Shawn Guo
2010-12-08 9:14 ` Uwe Kleine-König
2010-12-08 8:24 ` Lothar Waßmann
2010-12-07 16:31 ` [PATCH v2 05/15] ARM: mxs: Add low-level debug UART support Shawn Guo
2010-12-08 20:27 ` Uwe Kleine-König
2010-12-09 2:02 ` Shawn Guo
2010-12-09 8:42 ` Uwe Kleine-König
2010-12-07 16:31 ` [PATCH v3 06/15] ARM: mxs: Add timer support Shawn Guo
2010-12-07 21:18 ` Uwe Kleine-König
2010-12-08 5:58 ` Shawn Guo
2010-12-08 9:25 ` Uwe Kleine-König
2010-12-08 8:30 ` Lothar Waßmann
2010-12-08 9:31 ` Uwe Kleine-König
2010-12-07 16:31 ` [PATCH v2 07/15] ARM: mxs: Add gpio support Shawn Guo
2010-12-08 7:21 ` Lothar Waßmann
2010-12-07 16:31 ` [PATCH v2 08/15] ARM: mxs: Add iomux support Shawn Guo
2010-12-08 7:25 ` Lothar Waßmann
2010-12-08 10:52 ` Shawn Guo
2010-12-08 10:56 ` Uwe Kleine-König
2010-12-08 11:29 ` Shawn Guo
2010-12-08 11:32 ` Lothar Waßmann
2010-12-09 6:15 ` Shawn Guo
2010-12-09 8:43 ` Uwe Kleine-König
2010-12-07 16:31 ` [PATCH v2 09/15] ARM: mxs: Add clock support Shawn Guo
2010-12-08 20:57 ` Uwe Kleine-König
2010-12-09 1:44 ` Shawn Guo
2010-12-09 8:41 ` Uwe Kleine-König
2010-12-09 10:04 ` Shawn Guo
2010-12-09 10:30 ` Shawn Guo
2010-12-07 16:32 ` [PATCH v2 12/15] ARM: mxs: Dynamically allocate fec devices Shawn Guo
2010-12-07 16:32 ` [PATCH v2 13/15] ARM: mxs: Add initial mx23evk support Shawn Guo
2010-12-07 16:32 ` [PATCH v2 14/15] ARM: mxs: Add initial mx28evk support Shawn Guo
2010-12-08 20:28 ` Uwe Kleine-König
2010-12-09 7:04 ` Shawn Guo
2010-12-09 8:32 ` Uwe Kleine-König
2010-12-09 9:03 ` Shawn Guo
2010-12-09 9:37 ` Uwe Kleine-König
2010-12-09 10:17 ` Shawn Guo
2010-12-09 12:27 ` Lothar Waßmann
2010-12-09 13:38 ` Shawn Guo
2010-12-09 13:54 ` Shawn Guo
2010-12-07 16:32 ` [PATCH v3 15/15] ARM: mxs: Add build configuration for mxs Shawn Guo
2010-12-10 14:51 ` Uwe Kleine-König
2010-12-10 15:05 ` Shawn Guo
2010-12-09 15:12 ` [PATCH v4 01/15] ARM: mxs: Add core definitions Shawn Guo
2010-12-09 17:37 ` Russell King - ARM Linux
2010-12-09 15:12 ` [PATCH v3 02/15] ARM: mxs: Add helper definition and function Shawn Guo
2010-12-09 15:12 ` [PATCH v4 03/15] ARM: mxs: Add reset routines Shawn Guo
2010-12-09 15:12 ` [PATCH v3 04/15] ARM: mxs: Add interrupt support Shawn Guo
2010-12-09 15:12 ` [PATCH v3 05/15] ARM: mxs: Add low-level debug UART support Shawn Guo
2010-12-09 15:12 ` [PATCH v4 06/15] ARM: mxs: Add timer support Shawn Guo
2010-12-09 15:12 ` [PATCH v3 07/15] ARM: mxs: Add gpio support Shawn Guo
2010-12-09 16:47 ` Lothar Waßmann
2010-12-10 7:06 ` Shawn Guo
2010-12-10 7:23 ` Shawn Guo
2010-12-10 8:11 ` Uwe Kleine-König
2010-12-10 15:32 ` Shawn Guo
2010-12-09 15:12 ` [PATCH v3 08/15] ARM: mxs: Add iomux support Shawn Guo
2010-12-09 16:12 ` Lothar Waßmann
2010-12-09 15:12 ` [PATCH v3 09/15] ARM: mxs: Add clock support Shawn Guo
2010-12-09 21:11 ` Uwe Kleine-König
2010-12-09 15:12 ` [PATCH v2 10/15] ARM: mxs: Add static memory mapping Shawn Guo
2010-12-09 15:12 ` [PATCH v2 11/15] ARM: mxs: Dynamically allocate duart devices Shawn Guo
2010-12-09 15:12 ` [PATCH v3 12/15] ARM: mxs: Dynamically allocate fec devices Shawn Guo
2010-12-09 15:12 ` [PATCH v3 13/15] ARM: mxs: Add initial mx23evk support Shawn Guo
2010-12-09 15:12 ` [PATCH v3 14/15] ARM: mxs: Add initial mx28evk support Shawn Guo
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.