* [PATCH v6 00/15] ARM: mxs: Add initial support for MX23 and MX28
@ 2010-12-13 12:54 Shawn Guo
2010-12-13 12:54 ` [PATCH v6 01/15] ARM: mxs: Add core definitions Shawn Guo
` (7 more replies)
0 siblings, 8 replies; 28+ messages in thread
From: Shawn Guo @ 2010-12-13 12:54 UTC (permalink / raw)
To: linux-arm-kernel
Changes for v6 of this patch series:
- Introduce inline functions __mxs_setl(), __mxs_clrl()
and __mxs_togl() for bit set/clear/toggle operations
- Address comments given by Uwe on gpio.c (detailed change log
can be found in the patch version log)
- Remove cpu.o from arch/arm/mach-mxs/Makefile
[PATCH v6 01/15] ARM: mxs: Add core definitions
[PATCH v6 03/15] ARM: mxs: Add reset routines
[PATCH v6 06/15] ARM: mxs: Add timer support
[PATCH v6 07/15] ARM: mxs: Add gpio support
[PATCH v6 08/15] ARM: mxs: Add iomux support
[PATCH v6 15/15] ARM: mxs: Add build configuration for mxs
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 01/15] ARM: mxs: Add core definitions
2010-12-13 12:54 [PATCH v6 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
@ 2010-12-13 12:54 ` Shawn Guo
2010-12-15 16:22 ` Arnd Bergmann
2010-12-13 12:54 ` [PATCH v6 03/15] ARM: mxs: Add reset routines Shawn Guo
` (6 subsequent siblings)
7 siblings, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2010-12-13 12:54 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 v6:
- Add inline functions __mxs_setl(), __mxs_clrl() and __mxs_togl()
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 | 105 ++++++++++++++++
6 files changed, 523 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..f186c08
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/mxs.h
@@ -0,0 +1,105 @@
+/*
+ * 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__
+
+#ifndef __ASSEMBLER__
+#include <linux/io.h>
+#endif
+#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())
+
+/*
+ * 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, \
+}
+
+#define MXS_SET_ADDR 0x4
+#define MXS_CLR_ADDR 0x8
+#define MXS_TOG_ADDR 0xc
+
+#ifndef __ASSEMBLER__
+static inline void __mxs_setl(u32 mask, void __iomem *reg)
+{
+ __raw_writel(mask, reg + MXS_SET_ADDR);
+}
+
+static inline void __mxs_clrl(u32 mask, void __iomem *reg)
+{
+ __raw_writel(mask, reg + MXS_CLR_ADDR);
+}
+
+static inline void __mxs_togl(u32 mask, void __iomem *reg)
+{
+ __raw_writel(mask, reg + MXS_TOG_ADDR);
+}
+#endif
+
+#endif /* __MACH_MXS_H__ */
--
1.7.1
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v6 03/15] ARM: mxs: Add reset routines
2010-12-13 12:54 [PATCH v6 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
2010-12-13 12:54 ` [PATCH v6 01/15] ARM: mxs: Add core definitions Shawn Guo
@ 2010-12-13 12:54 ` Shawn Guo
2010-12-13 12:55 ` [PATCH v6 06/15] ARM: mxs: Add timer support Shawn Guo
` (5 subsequent siblings)
7 siblings, 0 replies; 28+ messages in thread
From: Shawn Guo @ 2010-12-13 12:54 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 v6:
- Use __mxs_setl() and __mxs_clrl() for bit set/clear
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..c156e25
--- /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 */
+ __mxs_setl(MXS_WATCHDOG_EN, wdog_base);
+
+ /* 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 */
+ __mxs_clrl(mask, 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 */
+ __mxs_clrl(MXS_MODULE_CLKGATE, reset_addr);
+
+ /* set SFTRST to reset the block */
+ __mxs_setl(MXS_MODULE_SFTRST, reset_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] 28+ messages in thread
* [PATCH v6 06/15] ARM: mxs: Add timer support
2010-12-13 12:54 [PATCH v6 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
2010-12-13 12:54 ` [PATCH v6 01/15] ARM: mxs: Add core definitions Shawn Guo
2010-12-13 12:54 ` [PATCH v6 03/15] ARM: mxs: Add reset routines Shawn Guo
@ 2010-12-13 12:55 ` Shawn Guo
2010-12-13 13:53 ` Russell King - ARM Linux
2010-12-13 12:55 ` [PATCH v6 07/15] ARM: mxs: Add gpio support Shawn Guo
` (4 subsequent siblings)
7 siblings, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2010-12-13 12:55 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 v6:
- Use __mxs_setl() and __mxs_clrl() for bit set/clear
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..508bb9e
--- /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)
+{
+ __mxs_clrl(BM_TIMROT_TIMCTRLn_IRQ_EN,
+ timer_base + HW_TIMROT_TIMCTRLn(0));
+}
+
+static inline void timrot_irq_enable(void)
+{
+ __mxs_setl(BM_TIMROT_TIMCTRLn_IRQ_EN,
+ timer_base + HW_TIMROT_TIMCTRLn(0));
+}
+
+static void timrot_irq_acknowledge(void)
+{
+ __mxs_clrl(BM_TIMROT_TIMCTRLn_IRQ,
+ timer_base + HW_TIMROT_TIMCTRLn(0));
+}
+
+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] 28+ messages in thread
* [PATCH v6 07/15] ARM: mxs: Add gpio support
2010-12-13 12:54 [PATCH v6 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (2 preceding siblings ...)
2010-12-13 12:55 ` [PATCH v6 06/15] ARM: mxs: Add timer support Shawn Guo
@ 2010-12-13 12:55 ` Shawn Guo
2010-12-13 12:55 ` [PATCH v6 08/15] ARM: mxs: Add iomux support Shawn Guo
` (3 subsequent siblings)
7 siblings, 0 replies; 28+ messages in thread
From: Shawn Guo @ 2010-12-13 12:55 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 v6:
- Use __mxs_setl() and __mxs_clrl() for bit set/clear
- Rename functions for not using leading underscore
- Add mxs_ to some functions name to align naming scheme
- Introduce variables pin_mask and pin_addr to make code look better
- Remove PINCTRL_PIN2IRQ from irq_stat assignment
- Add comment for clearing status bit in IRQSTAT
- Set up irq handler before registering gpio chip
Changes for v5:
- Leave PIN2IRQ set when disabling gpio IRQ to avoid
losting interrupt
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 | 315 +++++++++++++++++++++++++++++++++
arch/arm/mach-mxs/gpio.h | 33 ++++
arch/arm/mach-mxs/include/mach/gpio.h | 34 ++++
3 files changed, 382 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..16d9fb0
--- /dev/null
+++ b/arch/arm/mach-mxs/gpio.c
@@ -0,0 +1,315 @@
+/*
+ * 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)
+{
+ __mxs_clrl(1 << index, port->base + PINCTRL_IRQSTAT(port->id));
+}
+
+static void set_gpio_irqenable(struct mxs_gpio_port *port, u32 index,
+ int enable)
+{
+ if (enable) {
+ __mxs_setl(1 << index, port->base + PINCTRL_IRQEN(port->id));
+ __mxs_setl(1 << index, port->base + PINCTRL_PIN2IRQ(port->id));
+ } else {
+ __mxs_clrl(1 << index, port->base + PINCTRL_IRQEN(port->id));
+ }
+}
+
+static void mxs_gpio_ack_irq(u32 irq)
+{
+ u32 gpio = irq_to_gpio(irq);
+ clear_gpio_irqstatus(&mxs_gpio_ports[gpio / 32], gpio & 0x1f);
+}
+
+static void mxs_gpio_mask_irq(u32 irq)
+{
+ u32 gpio = irq_to_gpio(irq);
+ set_gpio_irqenable(&mxs_gpio_ports[gpio / 32], gpio & 0x1f, 0);
+}
+
+static void mxs_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 mxs_gpio_set_irq_type(u32 irq, u32 type)
+{
+ u32 gpio = irq_to_gpio(irq);
+ u32 pin_mask = 1 << (gpio & 31);
+ struct mxs_gpio_port *port = &mxs_gpio_ports[gpio / 32];
+ void __iomem *pin_addr;
+ 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 */
+ pin_addr = port->base + PINCTRL_IRQLEV(port->id);
+ if (edge & GPIO_INT_LEV_MASK)
+ __mxs_setl(pin_mask, pin_addr);
+ else
+ __mxs_clrl(pin_mask, pin_addr);
+
+ /* set polarity */
+ pin_addr = port->base + PINCTRL_IRQPOL(port->id);
+ if (edge & GPIO_INT_POL_MASK)
+ __mxs_setl(pin_mask, pin_addr);
+ else
+ __mxs_clrl(pin_mask, pin_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));
+
+ 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 mxs_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 = mxs_gpio_ack_irq,
+ .mask = mxs_gpio_mask_irq,
+ .unmask = mxs_gpio_unmask_irq,
+ .set_type = mxs_gpio_set_irq_type,
+ .set_wake = mxs_gpio_set_wake_irq,
+};
+
+static void mxs_set_gpio_direction(struct gpio_chip *chip, unsigned offset,
+ int dir)
+{
+ struct mxs_gpio_port *port =
+ container_of(chip, struct mxs_gpio_port, chip);
+ void __iomem *pin_addr = port->base + PINCTRL_DOE(port->id);
+
+ if (dir)
+ __mxs_setl(1 << offset, pin_addr);
+ else
+ __mxs_clrl(1 << offset, pin_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);
+ void __iomem *pin_addr = port->base + PINCTRL_DOUT(port->id);
+
+ if (value)
+ __mxs_setl(1 << offset, pin_addr);
+ else
+ __mxs_clrl(1 << offset, pin_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)
+{
+ mxs_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);
+ mxs_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));
+
+ /* clear address has to be used to clear IRQSTAT bits */
+ __mxs_clrl(~0U, port[i].base + PINCTRL_IRQSTAT(i));
+
+ 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);
+ }
+
+ /* 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]);
+
+ /* 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 );
+ }
+
+ 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] 28+ messages in thread
* [PATCH v6 08/15] ARM: mxs: Add iomux support
2010-12-13 12:54 [PATCH v6 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (3 preceding siblings ...)
2010-12-13 12:55 ` [PATCH v6 07/15] ARM: mxs: Add gpio support Shawn Guo
@ 2010-12-13 12:55 ` Shawn Guo
2010-12-16 9:51 ` Uwe Kleine-König
2010-12-13 12:55 ` [PATCH v6 15/15] ARM: mxs: Add build configuration for mxs Shawn Guo
` (2 subsequent siblings)
7 siblings, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2010-12-13 12:55 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 v6:
- Use __mxs_setl() and __mxs_clrl() for bit set/clear
Changes for v5:
- Change iomux_cfg_t from u64 to u16
- Add namespace MXS_ to shift, mask, and pad definitions
- Use SET/CLR register for 1 bit setting
- Get "if" and "{" at the same line
- Remove space in middle of tabs
- Change "setups" to "configures" in comments
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 | 116 +++++++++++++++++++++++++++
arch/arm/mach-mxs/iomux.c | 99 +++++++++++++++++++++++
4 files changed, 288 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..5a316f4
--- /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 MXS_IOMUX_PAD(1, 26, PAD_MUXSEL_2, PAD_VOL_NONE, PAD_4MA, PAD_NOPULL)
+#define MX23_PAD_PWM1__DUART_TX MXS_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..be8ad2d
--- /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 MXS_IOMUX_PAD(3, 16, PAD_MUXSEL_2, PAD_3V3, PAD_4MA, PAD_NOPULL)
+#define MX28_PAD_PWM1__DUART_TX MXS_IOMUX_PAD(3, 17, PAD_MUXSEL_2, PAD_3V3, PAD_4MA, PAD_NOPULL)
+
+/* FEC */
+#define MX28_PAD_ENET0_MDC__ENET0_MDC MXS_IOMUX_PAD(4, 0, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
+#define MX28_PAD_ENET0_MDIO__ENET0_MDIO MXS_IOMUX_PAD(4, 1, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
+#define MX28_PAD_ENET0_RX_EN__ENET0_RX_EN MXS_IOMUX_PAD(4, 2, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
+#define MX28_PAD_ENET0_RXD0__ENET0_RXD0 MXS_IOMUX_PAD(4, 3, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
+#define MX28_PAD_ENET0_RXD1__ENET0_RXD1 MXS_IOMUX_PAD(4, 4, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
+#define MX28_PAD_ENET0_TX_EN__ENET0_TX_EN MXS_IOMUX_PAD(4, 6, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
+#define MX28_PAD_ENET0_TXD0__ENET0_TXD0 MXS_IOMUX_PAD(4, 7, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
+#define MX28_PAD_ENET0_TXD1__ENET0_TXD1 MXS_IOMUX_PAD(4, 8, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
+#define MX28_PAD_ENET_CLK__ENET_CLK MXS_IOMUX_PAD(4, 16, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
+
+/* GPIO */
+#define MX28_PAD_SSP1_DATA3__GPIO_2_15 MXS_IOMUX_PAD(2, 15, PAD_MUXSEL_GPIO, PAD_3V3, PAD_4MA, PAD_NOPULL)
+#define MX28_PAD_ENET0_RX_CLK__GPIO_4_13 MXS_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..765b361
--- /dev/null
+++ b/arch/arm/mach-mxs/include/mach/iomux.h
@@ -0,0 +1,116 @@
+/*
+ * 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)
+ */
+typedef u16 iomux_cfg_t;
+
+#define MXS_PAD_BANK_SHIFT 0
+#define MXS_PAD_BANK_MASK ((iomux_cfg_t)0x7 << MXS_PAD_BANK_SHIFT)
+#define MXS_PAD_PIN_SHIFT 3
+#define MXS_PAD_PIN_MASK ((iomux_cfg_t)0x1f << MXS_PAD_PIN_SHIFT)
+#define MXS_PAD_MUXSEL_SHIFT 8
+#define MXS_PAD_MUXSEL_MASK ((iomux_cfg_t)0x3 << MXS_PAD_MUXSEL_SHIFT)
+#define MXS_PAD_MA_SHIFT 10
+#define MXS_PAD_MA_MASK ((iomux_cfg_t)0x7 << MXS_PAD_MA_SHIFT)
+#define MXS_PAD_VOL_SHIFT 13
+#define MXS_PAD_VOL_MASK ((iomux_cfg_t)0x3 << MXS_PAD_VOL_SHIFT)
+#define MXS_PAD_PULL_SHIFT 15
+#define MXS_PAD_PULL_MASK ((iomux_cfg_t)0x1 << MXS_PAD_PULL_SHIFT)
+
+#define MXS_IOMUX_PAD(_bank, _pin, _muxsel, _vol, _ma, _pull) \
+ (((iomux_cfg_t)(_bank) << MXS_PAD_BANK_SHIFT) | \
+ ((iomux_cfg_t)(_pin) << MXS_PAD_PIN_SHIFT) | \
+ ((iomux_cfg_t)(_muxsel) << MXS_PAD_MUXSEL_SHIFT) | \
+ ((iomux_cfg_t)(_vol) << MXS_PAD_VOL_SHIFT) | \
+ ((iomux_cfg_t)(_ma) << MXS_PAD_MA_SHIFT) | \
+ ((iomux_cfg_t)(_pull) << MXS_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 & MXS_PAD_BANK_MASK) >> MXS_PAD_BANK_SHIFT;
+}
+
+static inline unsigned int PAD_PIN(iomux_cfg_t pad)
+{
+ return (pad & MXS_PAD_PIN_MASK) >> MXS_PAD_PIN_SHIFT;
+}
+
+static inline unsigned int PAD_MUXSEL(iomux_cfg_t pad)
+{
+ return (pad & MXS_PAD_MUXSEL_MASK) >> MXS_PAD_MUXSEL_SHIFT;
+}
+
+static inline unsigned int PAD_MA(iomux_cfg_t pad)
+{
+ return (pad & MXS_PAD_MA_MASK) >> MXS_PAD_MA_SHIFT;
+}
+
+static inline unsigned int PAD_VOL(iomux_cfg_t pad)
+{
+ return (pad & MXS_PAD_VOL_MASK) >> MXS_PAD_VOL_SHIFT;
+}
+
+static inline unsigned int PAD_PULL(iomux_cfg_t pad)
+{
+ return (pad & MXS_PAD_PULL_MASK) >> MXS_PAD_PULL_SHIFT;
+}
+
+/*
+ * configures a single pad in the iomuxer
+ */
+int mxs_iomux_setup_pad(iomux_cfg_t pad);
+
+/*
+ * configures 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..131908c
--- /dev/null
+++ b/arch/arm/mach-mxs/iomux.c
@@ -0,0 +1,99 @@
+/*
+ * 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;
+ if (PAD_VOL(pad))
+ __mxs_setl(1 << bp, iomux_base + ofs);
+ else
+ __mxs_clrl(1 << bp, iomux_base + ofs);
+ }
+
+ /* pull */
+ ofs = cpu_is_mx23() ? 0x400 : 0x600;
+ ofs += PAD_BANK(pad) * 0x10;
+ bp = PAD_PIN(pad);
+ if (PAD_PULL(pad))
+ __mxs_setl(1 << bp, iomux_base + ofs);
+ else
+ __mxs_clrl(1 << bp, 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] 28+ messages in thread
* [PATCH v6 15/15] ARM: mxs: Add build configuration for mxs
2010-12-13 12:54 [PATCH v6 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (4 preceding siblings ...)
2010-12-13 12:55 ` [PATCH v6 08/15] ARM: mxs: Add iomux support Shawn Guo
@ 2010-12-13 12:55 ` Shawn Guo
2010-12-13 14:20 ` [PATCH v6 00/15] ARM: mxs: Add initial support for MX23 and MX28 Uwe Kleine-König
2010-12-15 16:24 ` [PATCH v6 00/15] ARM: mxs: Add initial support for MX23 and MX28 Arnd Bergmann
7 siblings, 0 replies; 28+ messages in thread
From: Shawn Guo @ 2010-12-13 12:55 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
Changes for v6:
- Remove cpu.o which should be removed in previous version but
actually not
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..39d3f9c
--- /dev/null
+++ b/arch/arm/mach-mxs/Makefile
@@ -0,0 +1,10 @@
+# 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..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] 28+ messages in thread
* [PATCH v6 06/15] ARM: mxs: Add timer support
2010-12-13 12:55 ` [PATCH v6 06/15] ARM: mxs: Add timer support Shawn Guo
@ 2010-12-13 13:53 ` Russell King - ARM Linux
0 siblings, 0 replies; 28+ messages in thread
From: Russell King - ARM Linux @ 2010-12-13 13:53 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Dec 13, 2010 at 08:55:00PM +0800, Shawn Guo wrote:
> +static struct clocksource clocksource_mxs = {
> + .name = "mxs_timer",
> + .rating = 200,
> + .read = timrotv2_get_cycles,
> + .mask = CLOCKSOURCE_MASK(32),
> + .shift = 17,
Please remove the .shift initializer.
> + .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);
and use clocksource_register_hz(&clocksource_mxs, c); instead here -
it will calculate the shift and mult for you.
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 00/15] ARM: mxs: Add initial support for MX23 and MX28
2010-12-13 12:54 [PATCH v6 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (5 preceding siblings ...)
2010-12-13 12:55 ` [PATCH v6 15/15] ARM: mxs: Add build configuration for mxs Shawn Guo
@ 2010-12-13 14:20 ` Uwe Kleine-König
2010-12-14 8:31 ` [PATCH v6 00/15] ARM: mxs: Add initial support for MX23 andMX28 Shawn Guo
2010-12-15 16:24 ` [PATCH v6 00/15] ARM: mxs: Add initial support for MX23 and MX28 Arnd Bergmann
7 siblings, 1 reply; 28+ messages in thread
From: Uwe Kleine-König @ 2010-12-13 14:20 UTC (permalink / raw)
To: linux-arm-kernel
Hello Shawn,
On Mon, Dec 13, 2010 at 08:54:57PM +0800, Shawn Guo wrote:
> Changes for v6 of this patch series:
> - Introduce inline functions __mxs_setl(), __mxs_clrl()
> and __mxs_togl() for bit set/clear/toggle operations
> - Address comments given by Uwe on gpio.c (detailed change log
> can be found in the patch version log)
> - Remove cpu.o from arch/arm/mach-mxs/Makefile
>
> [PATCH v6 01/15] ARM: mxs: Add core definitions
> [PATCH v6 03/15] ARM: mxs: Add reset routines
> [PATCH v6 06/15] ARM: mxs: Add timer support
> [PATCH v6 07/15] ARM: mxs: Add gpio support
> [PATCH v6 08/15] ARM: mxs: Add iomux support
> [PATCH v6 15/15] ARM: mxs: Add build configuration for mxs
There are some things still on my list. Most of them are only nitpicks,
but there is at least one bigger issue left:
- use virtual address in get_irqnr_preamble (comment by Lothar Wa?mann)
(Does irq handling really works without that?)
- various namespace problems, at least:
- ICOLL_VBASE in arch/arm/mach-mxs/include/mach/entry-macro.S
- uart_base, UART in arch/arm/mach-mxs/include/mach/uncompress.h
- clockevent_mxs, clockevent_mode in arch/arm/mach-mxs/timer.c
- on TIMROTv1 there is no HW_TIMROT_RUNNING_COUNTn register. That's
called HW_TIMROT_TIMCOUNTn.
- Typo in comment above timrot_is_v1: MX23 uses timers 0 and 1, too.
- Would it make sense to detect the version of the TIMROT block by
reading the TIMROT_VERSION register instead of using cpu_is_mxXYZ?
- IMHO you could better use MXS_CLKCTRL_RESET instead of the watchdog
in arch_reset. You argued that this needs an cpu_is_mxXYZ, still I
think this would be preferable. Alternatively you can use an
initcall that sets the address similar to how wdog_base is
initialized now. (BTW, wdog_base is another item in the namespace
list above.)
- Use clocksource_register_hz (recent comment by Russell King)
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 00/15] ARM: mxs: Add initial support for MX23 andMX28
2010-12-13 14:20 ` [PATCH v6 00/15] ARM: mxs: Add initial support for MX23 and MX28 Uwe Kleine-König
@ 2010-12-14 8:31 ` Shawn Guo
2010-12-14 13:00 ` Shawn Guo
0 siblings, 1 reply; 28+ messages in thread
From: Shawn Guo @ 2010-12-14 8:31 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Dec 13, 2010 at 07:20:45AM -0700, Uwe Kleine-K?nig wrote:
[...]
>
> There are some things still on my list. Most of them are only nitpicks,
> but there is at least one bigger issue left:
>
> - use virtual address in get_irqnr_preamble (comment by Lothar Wa?mann)
> (Does irq handling really works without that?)
No, it does not work without that. I just did not ran into the case,
as only the path of icoll_base will be hit when both mx23 and mx28 are
built in.
It reminded me that I should test single SoC build carefully.
> - various namespace problems, at least:
> - ICOLL_VBASE in arch/arm/mach-mxs/include/mach/entry-macro.S
> - uart_base, UART in arch/arm/mach-mxs/include/mach/uncompress.h
OK
> - clockevent_mxs, clockevent_mode in arch/arm/mach-mxs/timer.c
Since clockevent_mxs already has namespace "_mxs" in there, I have to
assume that you are asking something like mxs_clockevent_device and
mxs_clockevent_mode. Correct me if I'm wrong.
> - on TIMROTv1 there is no HW_TIMROT_RUNNING_COUNTn register. That's
> called HW_TIMROT_TIMCOUNTn.
I'm reusing the offset definition here. But it seems you are asking
two definitions to avoid confusion.
> - Typo in comment above timrot_is_v1: MX23 uses timers 0 and 1, too.
It's a typo, but partially. mx28 uses timrot 0 and 1, while mx23 uses
0 and 2. There are 4 registers for each timrot instance on mx28,
but only 2 on mx23. So address step 0x40 in HW_TIMROT_TIMCTRLn strides
one instance on mx28 while two instances on mx23. Confusion again,
adding more definitions, right?
> - Would it make sense to detect the version of the TIMROT block by
> reading the TIMROT_VERSION register instead of using cpu_is_mxXYZ?
Yes, we can do that, but we can not avoid using cpu_is_mxXYZ anyway,
as the offset of TIMROT_VERSION is different between mx23 and mx28.
If you really want to go this way, I can work it out for you to
have a look.
> - IMHO you could better use MXS_CLKCTRL_RESET instead of the watchdog
> in arch_reset. You argued that this needs an cpu_is_mxXYZ, still I
> think this would be preferable. Alternatively you can use an
> initcall that sets the address similar to how wdog_base is
> initialized now. (BTW, wdog_base is another item in the namespace
> list above.)
OK
> - Use clocksource_register_hz (recent comment by Russell King)
OK
Regards,
Shawn
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 00/15] ARM: mxs: Add initial support for MX23 andMX28
2010-12-14 8:31 ` [PATCH v6 00/15] ARM: mxs: Add initial support for MX23 andMX28 Shawn Guo
@ 2010-12-14 13:00 ` Shawn Guo
0 siblings, 0 replies; 28+ messages in thread
From: Shawn Guo @ 2010-12-14 13:00 UTC (permalink / raw)
To: linux-arm-kernel
Hi Uwe,
2010/12/14 Shawn Guo <shawn.guo@freescale.com>:
[...]
>> ?- on TIMROTv1 there is no HW_TIMROT_RUNNING_COUNTn register. ?That's
>> ? ?called HW_TIMROT_TIMCOUNTn.
> I'm reusing the offset definition here. But it seems you are asking
> two definitions to avoid confusion.
>
>> ?- Typo in comment above timrot_is_v1: MX23 uses timers 0 and 1, too.
> It's a typo, but partially. mx28 uses timrot 0 and 1, while mx23 uses
> 0 and 2. There are 4 registers for each timrot instance on mx28,
> but only 2 on mx23. So address step 0x40 in HW_TIMROT_TIMCTRLn strides
> one instance on mx28 while two instances on mx23. Confusion again,
> adding more definitions, right?
>
I'm not going to argue the first one, since HW_TIMROT_RUNNING_COUNTn
is being used in functions that are already separated for v1 and v2.
But for HW_TIMROT_TIMCTRLn, it's being used in shared codes/functions.
Can we keep the trick and add more comments on that to save some codes
duplication?
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 01/15] ARM: mxs: Add core definitions
2010-12-13 12:54 ` [PATCH v6 01/15] ARM: mxs: Add core definitions Shawn Guo
@ 2010-12-15 16:22 ` Arnd Bergmann
2010-12-15 16:40 ` Uwe Kleine-König
2010-12-15 16:47 ` Russell King - ARM Linux
0 siblings, 2 replies; 28+ messages in thread
From: Arnd Bergmann @ 2010-12-15 16:22 UTC (permalink / raw)
To: linux-arm-kernel
On Monday 13 December 2010, Shawn Guo wrote:
> Add core definitions for MXS-based SoC MX23 and MX28.
How different are these from the MXC SoCs? Is it really
worth having a totally separate plat-* directory for them?
AFAICT, combining the two would make it much easier to build
a kernel that works on mx23/28 as well as mx25 or the later
MXS implementations.
> 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
> +
> +#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
This looks like a rather ugly hack to hide misuse of __iomem
pointers. If you pass virtual addresses of I/O registers,
just make them always be of type (void __iomem *), so you
can actually benefit from the sparse annotations, rather
working against them.
> +
> +#ifndef __ASSEMBLER__
> +static inline void __mxs_setl(u32 mask, void __iomem *reg)
> +{
> + __raw_writel(mask, reg + MXS_SET_ADDR);
> +}
> +
> +static inline void __mxs_clrl(u32 mask, void __iomem *reg)
> +{
> + __raw_writel(mask, reg + MXS_CLR_ADDR);
> +}
> +
> +static inline void __mxs_togl(u32 mask, void __iomem *reg)
> +{
> + __raw_writel(mask, reg + MXS_TOG_ADDR);
> +}
> +#endif
Why __raw_writel()? All regular I/O accesses should use
readl/writel etc, not the internal helpers.
Arnd
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 00/15] ARM: mxs: Add initial support for MX23 and MX28
2010-12-13 12:54 [PATCH v6 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
` (6 preceding siblings ...)
2010-12-13 14:20 ` [PATCH v6 00/15] ARM: mxs: Add initial support for MX23 and MX28 Uwe Kleine-König
@ 2010-12-15 16:24 ` Arnd Bergmann
2010-12-15 16:34 ` Uwe Kleine-König
7 siblings, 1 reply; 28+ messages in thread
From: Arnd Bergmann @ 2010-12-15 16:24 UTC (permalink / raw)
To: linux-arm-kernel
On Monday 13 December 2010, Shawn Guo wrote:
> [PATCH v6 01/15] ARM: mxs: Add core definitions
> [PATCH v6 03/15] ARM: mxs: Add reset routines
> [PATCH v6 06/15] ARM: mxs: Add timer support
> [PATCH v6 07/15] ARM: mxs: Add gpio support
> [PATCH v6 08/15] ARM: mxs: Add iomux support
> [PATCH v6 15/15] ARM: mxs: Add build configuration for mxs
Where are the other patches? You listed (and posted) only six,
but apparently there is a total of 15 patches.
Arnd
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 00/15] ARM: mxs: Add initial support for MX23 and MX28
2010-12-15 16:24 ` [PATCH v6 00/15] ARM: mxs: Add initial support for MX23 and MX28 Arnd Bergmann
@ 2010-12-15 16:34 ` Uwe Kleine-König
0 siblings, 0 replies; 28+ messages in thread
From: Uwe Kleine-König @ 2010-12-15 16:34 UTC (permalink / raw)
To: linux-arm-kernel
Hello Arnd,
On Wed, Dec 15, 2010 at 05:24:03PM +0100, Arnd Bergmann wrote:
> On Monday 13 December 2010, Shawn Guo wrote:
> > [PATCH v6 01/15] ARM: mxs: Add core definitions
> > [PATCH v6 03/15] ARM: mxs: Add reset routines
> > [PATCH v6 06/15] ARM: mxs: Add timer support
> > [PATCH v6 07/15] ARM: mxs: Add gpio support
> > [PATCH v6 08/15] ARM: mxs: Add iomux support
> > [PATCH v6 15/15] ARM: mxs: Add build configuration for mxs
>
> Where are the other patches? You listed (and posted) only six,
> but apparently there is a total of 15 patches.
They are not updated since v5, for your convenience there is
http://git.pengutronix.de/?p=ukl/linux-2.6.git;a=shortlog;h=refs/heads/sgu/mxs-core-v6
and
git://git.pengutronix.de/git/ukl/linux-2.6.git sgu/mxs-core-v6
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 01/15] ARM: mxs: Add core definitions
2010-12-15 16:22 ` Arnd Bergmann
@ 2010-12-15 16:40 ` Uwe Kleine-König
2010-12-15 16:58 ` Arnd Bergmann
2010-12-15 16:47 ` Russell King - ARM Linux
1 sibling, 1 reply; 28+ messages in thread
From: Uwe Kleine-König @ 2010-12-15 16:40 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Dec 15, 2010 at 05:22:21PM +0100, Arnd Bergmann wrote:
> On Monday 13 December 2010, Shawn Guo wrote:
> > Add core definitions for MXS-based SoC MX23 and MX28.
>
> How different are these from the MXC SoCs? Is it really
> worth having a totally separate plat-* directory for them?
They are different enough that Sascha and I suggested to seperate them.
The first version of this series integrated mxs into mach-imx +
plat-mxc.
> AFAICT, combining the two would make it much easier to build
> a kernel that works on mx23/28 as well as mx25 or the later
> MXS implementations.
Right, but seeing the differences to mxc I vote for an arm-global
approach to build a cross-platform kernel.
> > 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
> > +
> > +#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
>
> This looks like a rather ugly hack to hide misuse of __iomem
> pointers. If you pass virtual addresses of I/O registers,
> just make them always be of type (void __iomem *), so you
> can actually benefit from the sparse annotations, rather
> working against them.
Actually this is to define the symbols for virtual addresses. And
because gas doesn't understand void * it gets a plain number.
And note, this is something that rmk suggested.
> > +
> > +#ifndef __ASSEMBLER__
> > +static inline void __mxs_setl(u32 mask, void __iomem *reg)
> > +{
> > + __raw_writel(mask, reg + MXS_SET_ADDR);
> > +}
> > +
> > +static inline void __mxs_clrl(u32 mask, void __iomem *reg)
> > +{
> > + __raw_writel(mask, reg + MXS_CLR_ADDR);
> > +}
> > +
> > +static inline void __mxs_togl(u32 mask, void __iomem *reg)
> > +{
> > + __raw_writel(mask, reg + MXS_TOG_ADDR);
> > +}
> > +#endif
>
> Why __raw_writel()? All regular I/O accesses should use
> readl/writel etc, not the internal helpers.
nak, readl does little endian accesses, __raw_readl native endian. So
for platform use __raw_readl is most of the time the better one.
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 01/15] ARM: mxs: Add core definitions
2010-12-15 16:22 ` Arnd Bergmann
2010-12-15 16:40 ` Uwe Kleine-König
@ 2010-12-15 16:47 ` Russell King - ARM Linux
2010-12-15 17:08 ` Arnd Bergmann
1 sibling, 1 reply; 28+ messages in thread
From: Russell King - ARM Linux @ 2010-12-15 16:47 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Dec 15, 2010 at 05:22:21PM +0100, Arnd Bergmann wrote:
> On Monday 13 December 2010, Shawn Guo wrote:
> > +#ifdef __ASSEMBLER__
> > +#define IOMEM(addr) (addr)
> > +#else
> > +#define IOMEM(addr) ((void __force __iomem *)(addr))
> > +#endif
>
> This looks like a rather ugly hack to hide misuse of __iomem
> pointers. If you pass virtual addresses of I/O registers,
> just make them always be of type (void __iomem *), so you
> can actually benefit from the sparse annotations, rather
> working against them.
Err, no - you're not understanding its purpose. It's used like so:
#define FOO_BASE IOMEM(0xf0000000)
in headers, which means you can use FOO_BASE both in C code (and it'll
be correctly typed) and also use it in assembly code (where it will be
an assembly expression.)
The alternative is we end up with:
#define FOO_ASM_BASE 0xf0000000
#define FOO_C_BASE ((void __force __iomem *)0xf0000000)
Or worse still, we end up with stuff like:
#define FOO_BASE 0xf0000000
struct blah {
unsigned long base;
};
unsigned int blah(struct blah *b, unsigned int reg)
{
return readl(b->base + reg);
}
Having IOMEM(), which can be audited to only be used in header files
defining registers gets around such problems, and ensures that the C
code is written more correctly than it otherwise would be.
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 01/15] ARM: mxs: Add core definitions
2010-12-15 16:40 ` Uwe Kleine-König
@ 2010-12-15 16:58 ` Arnd Bergmann
2010-12-15 17:06 ` Uwe Kleine-König
0 siblings, 1 reply; 28+ messages in thread
From: Arnd Bergmann @ 2010-12-15 16:58 UTC (permalink / raw)
To: linux-arm-kernel
On Wednesday 15 December 2010, Uwe Kleine-K?nig wrote:
> On Wed, Dec 15, 2010 at 05:22:21PM +0100, Arnd Bergmann wrote:
> > AFAICT, combining the two would make it much easier to build
> > a kernel that works on mx23/28 as well as mx25 or the later
> > MXS implementations.
> Right, but seeing the differences to mxc I vote for an arm-global
> approach to build a cross-platform kernel.
Ok, makes sense.
> > > +
> > > +#ifndef __ASSEMBLER__
> > > +static inline void __mxs_setl(u32 mask, void __iomem *reg)
> > > +{
> > > + __raw_writel(mask, reg + MXS_SET_ADDR);
> > > +}
> > > +
> > > +static inline void __mxs_clrl(u32 mask, void __iomem *reg)
> > > +{
> > > + __raw_writel(mask, reg + MXS_CLR_ADDR);
> > > +}
> > > +
> > > +static inline void __mxs_togl(u32 mask, void __iomem *reg)
> > > +{
> > > + __raw_writel(mask, reg + MXS_TOG_ADDR);
> > > +}
> > > +#endif
> >
> > Why __raw_writel()? All regular I/O accesses should use
> > readl/writel etc, not the internal helpers.
> nak, readl does little endian accesses, __raw_readl native endian. So
> for platform use __raw_readl is most of the time the better one.
Then we should define a proper function for this with well-defined
behaviour. I would suggest defining a mxs_readl/mxs_writel here,
that is defined to have the same endianess as the mxs SOC, but
otherwise has the same properties as readl/writel.
Arnd
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 01/15] ARM: mxs: Add core definitions
2010-12-15 16:58 ` Arnd Bergmann
@ 2010-12-15 17:06 ` Uwe Kleine-König
2010-12-15 17:17 ` Arnd Bergmann
2010-12-16 1:37 ` Shawn Guo
0 siblings, 2 replies; 28+ messages in thread
From: Uwe Kleine-König @ 2010-12-15 17:06 UTC (permalink / raw)
To: linux-arm-kernel
Hello Arnd,
On Wed, Dec 15, 2010 at 05:58:42PM +0100, Arnd Bergmann wrote:
> On Wednesday 15 December 2010, Uwe Kleine-K?nig wrote:
> > On Wed, Dec 15, 2010 at 05:22:21PM +0100, Arnd Bergmann wrote:
> > > > +
> > > > +#ifndef __ASSEMBLER__
> > > > +static inline void __mxs_setl(u32 mask, void __iomem *reg)
> > > > +{
> > > > + __raw_writel(mask, reg + MXS_SET_ADDR);
> > > > +}
> > > > +
> > > > +static inline void __mxs_clrl(u32 mask, void __iomem *reg)
> > > > +{
> > > > + __raw_writel(mask, reg + MXS_CLR_ADDR);
> > > > +}
> > > > +
> > > > +static inline void __mxs_togl(u32 mask, void __iomem *reg)
> > > > +{
> > > > + __raw_writel(mask, reg + MXS_TOG_ADDR);
> > > > +}
> > > > +#endif
> > >
> > > Why __raw_writel()? All regular I/O accesses should use
> > > readl/writel etc, not the internal helpers.
> > nak, readl does little endian accesses, __raw_readl native endian. So
> > for platform use __raw_readl is most of the time the better one.
>
> Then we should define a proper function for this with well-defined
> behaviour. I would suggest defining a mxs_readl/mxs_writel here,
> that is defined to have the same endianess as the mxs SOC, but
> otherwise has the same properties as readl/writel.
I don't get your point here. What are the properties of readl/writel
you want here? The barrier? __mem_pci?
For me __mxs_setl is a proper function with well-defined behaviour, no?
(One thing I currently consider to argue is to make these .c file local
because different IPs might have different offsets for SET, CLR and TOG
or not support it at all, but other than that I'm happy with it.)
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 01/15] ARM: mxs: Add core definitions
2010-12-15 16:47 ` Russell King - ARM Linux
@ 2010-12-15 17:08 ` Arnd Bergmann
2010-12-15 17:23 ` Russell King - ARM Linux
0 siblings, 1 reply; 28+ messages in thread
From: Arnd Bergmann @ 2010-12-15 17:08 UTC (permalink / raw)
To: linux-arm-kernel
On Wednesday 15 December 2010, Russell King - ARM Linux wrote:
> Err, no - you're not understanding its purpose. It's used like so:
>
> #define FOO_BASE IOMEM(0xf0000000)
>
> in headers, which means you can use FOO_BASE both in C code (and it'll
> be correctly typed) and also use it in assembly code (where it will be
> an assembly expression.)
>
> The alternative is we end up with:
>
> #define FOO_ASM_BASE 0xf0000000
> #define FOO_C_BASE ((void __force __iomem *)0xf0000000)
But isn't a hardwire virtual I/O address something that should be
used only very rarely?
I would assume that we only need to have the base address of the
mapping window defined somewhere and then use offsets:
#ifdef __ASSEMBLY__
#define IOMEM_BASE 0xf0000000
#else
#define IOMEM_BASE ((void __iomem *)0xf0000000)
#endif
#define FOO_BASE IOMEM_BASE + 0x18000
#define BAR_BASE IOMEM_BASE + 0x20000
> Or worse still, we end up with stuff like:
>
> #define FOO_BASE 0xf0000000
>
> struct blah {
> unsigned long base;
> };
>
> unsigned int blah(struct blah *b, unsigned int reg)
> {
> return readl(b->base + reg);
> }
>
> Having IOMEM(), which can be audited to only be used in header files
> defining registers gets around such problems, and ensures that the C
> code is written more correctly than it otherwise would be.
With the autiting, it certainly isn't that bad. One problem
I still see is that it's defined in the platform directory,
rather than somewhere in arch/arm/include/asm/, where it could
be mandated for use across all (or all new) platforms.
Introducing generic infrastructure at a platform level seems
problematic because the good parts will need to get copied
everywhere while the bad parts get stuck in obsolete platforms
forever.
Arnd
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 01/15] ARM: mxs: Add core definitions
2010-12-15 17:06 ` Uwe Kleine-König
@ 2010-12-15 17:17 ` Arnd Bergmann
2010-12-15 17:27 ` Russell King - ARM Linux
2010-12-15 18:49 ` Uwe Kleine-König
2010-12-16 1:37 ` Shawn Guo
1 sibling, 2 replies; 28+ messages in thread
From: Arnd Bergmann @ 2010-12-15 17:17 UTC (permalink / raw)
To: linux-arm-kernel
On Wednesday 15 December 2010, Uwe Kleine-K?nig wrote:
> > Then we should define a proper function for this with well-defined
> > behaviour. I would suggest defining a mxs_readl/mxs_writel here,
> > that is defined to have the same endianess as the mxs SOC, but
> > otherwise has the same properties as readl/writel.
> I don't get your point here. What are the properties of readl/writel
> you want here? The barrier? __mem_pci?
Being a documented interface.
> For me __mxs_setl is a proper function with well-defined behaviour, no?
> (One thing I currently consider to argue is to make these .c file local
> because different IPs might have different offsets for SET, CLR and TOG
> or not support it at all, but other than that I'm happy with it.)
The problem is that __raw_* is defined as a pointer reference on
all architectures, nothing more. Depending on the architecture and
compiler, sometimes even on the I/O subsystem, it may or may not
do any of the following:
* work on mapped PCI addresses
* work on mapped non-PCI addresses
* work on addresses returned from ioport_map
* be synchronized with spinlocks
* cause an atomic access on the bus
* trap on I/O device exceptions
* cause writes to be posted/nonposted
It's just not something that can possibly be used correctly
in portable code. I do realize that on mxs, it does pretty
much what you need, but that doesn't make it an officially
supported interface. Just like you are supposed to use spinlock
instead of raw_spinlock unless you know exactly why you need it
and document it.
Arnd
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 01/15] ARM: mxs: Add core definitions
2010-12-15 17:08 ` Arnd Bergmann
@ 2010-12-15 17:23 ` Russell King - ARM Linux
2010-12-15 17:51 ` Arnd Bergmann
0 siblings, 1 reply; 28+ messages in thread
From: Russell King - ARM Linux @ 2010-12-15 17:23 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Dec 15, 2010 at 06:08:41PM +0100, Arnd Bergmann wrote:
> On Wednesday 15 December 2010, Russell King - ARM Linux wrote:
> > Err, no - you're not understanding its purpose. It's used like so:
> >
> > #define FOO_BASE IOMEM(0xf0000000)
> >
> > in headers, which means you can use FOO_BASE both in C code (and it'll
> > be correctly typed) and also use it in assembly code (where it will be
> > an assembly expression.)
> >
> > The alternative is we end up with:
> >
> > #define FOO_ASM_BASE 0xf0000000
> > #define FOO_C_BASE ((void __force __iomem *)0xf0000000)
>
> But isn't a hardwire virtual I/O address something that should be
> used only very rarely?
You'd be surprised. With x86, the answer is clearly yes, because you
have the special IO space.
On architectures with no special IO space, everything is MMIO, including
system peripherals. So when you come to the basics such as interrupt
controllers and timers, which don't lend themselves to being ioremap()'d,
you have to come up with a different scheme.
With statically mapped MMIO devices, we define the v:p mapping explicitly,
and define constants above. And its these kinds of basic system
peripherals that need to be accessed in one way or another from assembly
code (eg, for stuff like sleep support.)
> I would assume that we only need to have the base address of the
> mapping window defined somewhere and then use offsets:
>
> #ifdef __ASSEMBLY__
> #define IOMEM_BASE 0xf0000000
> #else
> #define IOMEM_BASE ((void __iomem *)0xf0000000)
> #endif
>
> #define FOO_BASE IOMEM_BASE + 0x18000
> #define BAR_BASE IOMEM_BASE + 0x20000
What if your interrupt controller and system controller are 1GB apart?
> > Having IOMEM(), which can be audited to only be used in header files
> > defining registers gets around such problems, and ensures that the C
> > code is written more correctly than it otherwise would be.
>
> With the autiting, it certainly isn't that bad. One problem
> I still see is that it's defined in the platform directory,
> rather than somewhere in arch/arm/include/asm/, where it could
> be mandated for use across all (or all new) platforms.
>
> Introducing generic infrastructure at a platform level seems
> problematic because the good parts will need to get copied
> everywhere while the bad parts get stuck in obsolete platforms
> forever.
The reason I haven't done so is because it doesn't fit into an existing
header file (we could create asm/iomem.h to contain it for people to
include, but for the sake of five lines that's OTT.)
Putting it in asm/io.h doesn't work because that's generally not safe
for assembly code (and also causes issues with checkpatch wanting people
rightfully to be using linux/io.h).
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 01/15] ARM: mxs: Add core definitions
2010-12-15 17:17 ` Arnd Bergmann
@ 2010-12-15 17:27 ` Russell King - ARM Linux
2010-12-15 22:26 ` Arnd Bergmann
2010-12-15 18:49 ` Uwe Kleine-König
1 sibling, 1 reply; 28+ messages in thread
From: Russell King - ARM Linux @ 2010-12-15 17:27 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Dec 15, 2010 at 06:17:33PM +0100, Arnd Bergmann wrote:
> The problem is that __raw_* is defined as a pointer reference on
> all architectures, nothing more. Depending on the architecture and
> compiler, sometimes even on the I/O subsystem, it may or may not
> do any of the following:
>
> * work on mapped PCI addresses
> * work on mapped non-PCI addresses
> * work on addresses returned from ioport_map
> * be synchronized with spinlocks
Err. Even readl/writel are not synchronized with spinlocks. See
Documentation/memory-barriers.txt:
| Under certain circumstances (especially involving NUMA), I/O accesses within
| two spinlocked sections on two different CPUs may be seen as interleaved by the
| PCI bridge, because the PCI bridge does not necessarily participate in the
| cache-coherence protocol, and is therefore incapable of issuing the required
| read memory barriers.
|
| For example:
|
| CPU 1 CPU 2
| =============================== ===============================
| spin_lock(Q)
| writel(0, ADDR)
| writel(1, DATA);
| spin_unlock(Q);
| spin_lock(Q);
| writel(4, ADDR);
| writel(5, DATA);
| spin_unlock(Q);
|
| may be seen by the PCI bridge as follows:
|
| STORE *ADDR = 0, STORE *ADDR = 4, STORE *DATA = 1, STORE *DATA = 5
|
| which would probably cause the hardware to malfunction.
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 01/15] ARM: mxs: Add core definitions
2010-12-15 17:23 ` Russell King - ARM Linux
@ 2010-12-15 17:51 ` Arnd Bergmann
0 siblings, 0 replies; 28+ messages in thread
From: Arnd Bergmann @ 2010-12-15 17:51 UTC (permalink / raw)
To: linux-arm-kernel
On Wednesday 15 December 2010, Russell King - ARM Linux wrote:
> On Wed, Dec 15, 2010 at 06:08:41PM +0100, Arnd Bergmann wrote:
> > On Wednesday 15 December 2010, Russell King - ARM Linux wrote:
> > > The alternative is we end up with:
> > >
> > > #define FOO_ASM_BASE 0xf0000000
> > > #define FOO_C_BASE ((void __force __iomem *)0xf0000000)
> >
> > But isn't a hardwire virtual I/O address something that should be
> > used only very rarely?
>
> You'd be surprised. With x86, the answer is clearly yes, because you
> have the special IO space.
>
> On architectures with no special IO space, everything is MMIO, including
> system peripherals. So when you come to the basics such as interrupt
> controllers and timers, which don't lend themselves to being ioremap()'d,
> you have to come up with a different scheme.
I don't know too much about x86, but on most architectures I've looked
at recently (powerpc, tile, microblaze, ...), the peripherals get
initialized way after the memory management, so actually everything
can get mapped using ioremap.
I understand that it's convenient for the system devices on ARM,
especially if they get used from assembly code, but I still thought
this would be an exception for stuff that is rather low-level.
> With statically mapped MMIO devices, we define the v:p mapping explicitly,
> and define constants above. And its these kinds of basic system
> peripherals that need to be accessed in one way or another from assembly
> code (eg, for stuff like sleep support.)
Right, I know.
> > I would assume that we only need to have the base address of the
> > mapping window defined somewhere and then use offsets:
> >
> > #ifdef __ASSEMBLY__
> > #define IOMEM_BASE 0xf0000000
> > #else
> > #define IOMEM_BASE ((void __iomem *)0xf0000000)
> > #endif
> >
> > #define FOO_BASE IOMEM_BASE + 0x18000
> > #define BAR_BASE IOMEM_BASE + 0x20000
>
> What if your interrupt controller and system controller are 1GB apart?
Well, we already map them them through a table, so we can always
define the table in a way that physically distinct ranges get mapped
to virtually contiguous locations.
> The reason I haven't done so is because it doesn't fit into an existing
> header file (we could create asm/iomem.h to contain it for people to
> include, but for the sake of five lines that's OTT.)
>
> Putting it in asm/io.h doesn't work because that's generally not safe
> for assembly code (and also causes issues with checkpatch wanting people
> rightfully to be using linux/io.h).
A lot of platforms have a mach/hardware.h file that defines the
actual addresses, so maybe an asm/hardware.h would work as a
place to keep definitions like this, and that includes the
underlying mach/hardware.h.
Arnd
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 01/15] ARM: mxs: Add core definitions
2010-12-15 17:17 ` Arnd Bergmann
2010-12-15 17:27 ` Russell King - ARM Linux
@ 2010-12-15 18:49 ` Uwe Kleine-König
1 sibling, 0 replies; 28+ messages in thread
From: Uwe Kleine-König @ 2010-12-15 18:49 UTC (permalink / raw)
To: linux-arm-kernel
Hello Arnd,
On Wed, Dec 15, 2010 at 06:17:33PM +0100, Arnd Bergmann wrote:
> On Wednesday 15 December 2010, Uwe Kleine-K?nig wrote:
> > > Then we should define a proper function for this with well-defined
> > > behaviour. I would suggest defining a mxs_readl/mxs_writel here,
> > > that is defined to have the same endianess as the mxs SOC, but
> > > otherwise has the same properties as readl/writel.
> > I don't get your point here. What are the properties of readl/writel
> > you want here? The barrier? __mem_pci?
>
> Being a documented interface.
>
> > For me __mxs_setl is a proper function with well-defined behaviour, no?
> > (One thing I currently consider to argue is to make these .c file local
> > because different IPs might have different offsets for SET, CLR and TOG
> > or not support it at all, but other than that I'm happy with it.)
>
> The problem is that __raw_* is defined as a pointer reference on
> all architectures, nothing more. Depending on the architecture and
> compiler, sometimes even on the I/O subsystem, it may or may not
> do any of the following:
>
> * work on mapped PCI addresses
> * work on mapped non-PCI addresses
> * work on addresses returned from ioport_map
> * be synchronized with spinlocks
> * cause an atomic access on the bus
> * trap on I/O device exceptions
> * cause writes to be posted/nonposted
>
> It's just not something that can possibly be used correctly
> in portable code.
Code that is defined in arch/arm/mach-mxs doesn't necessarily need to
run on (say) x86. And if I configure an gpio IP on an embedded machine
I know this is not PCI. And to throw in some statistics:
ukl at octopus:~/gsrc/linux-2.6$ git grep -E '\<(read|write)l\>' arch/arm/mach-* | wc -l
947
ukl at octopus:~/gsrc/linux-2.6$ git grep -E '\<__raw_(read|write)l\>' arch/arm/mach-* | wc -l
2276
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 01/15] ARM: mxs: Add core definitions
2010-12-15 17:27 ` Russell King - ARM Linux
@ 2010-12-15 22:26 ` Arnd Bergmann
0 siblings, 0 replies; 28+ messages in thread
From: Arnd Bergmann @ 2010-12-15 22:26 UTC (permalink / raw)
To: linux-arm-kernel
On Wednesday 15 December 2010, Russell King - ARM Linux wrote:
> > * be synchronized with spinlocks
>
> Err. Even readl/writel are not synchronized with spinlocks. See
> Documentation/memory-barriers.txt:
readl is synchronized, writel by itself is never synchronized with
spinlocks if it is posted.
> | Under certain circumstances (especially involving NUMA), I/O accesses within
> | two spinlocked sections on two different CPUs may be seen as interleaved by the
> | PCI bridge, because the PCI bridge does not necessarily participate in the
> | cache-coherence protocol, and is therefore incapable of issuing the required
> | read memory barriers.
> |
> | For example:
> |
> | CPU 1 CPU 2
> | =============================== ===============================
> | spin_lock(Q)
> | writel(0, ADDR)
> | writel(1, DATA);
> | spin_unlock(Q);
> | spin_lock(Q);
> | writel(4, ADDR);
> | writel(5, DATA);
> | spin_unlock(Q);
> |
> | may be seen by the PCI bridge as follows:
> |
> | STORE *ADDR = 0, STORE *ADDR = 4, STORE *DATA = 1, STORE *DATA = 5
> |
> | which would probably cause the hardware to malfunction.
I was simplifying. To be more specific, __raw_readl/__raw_writel
makes no explicit guarantees regarding ordering with spinlocks.
I could argue that it also makes no guarantees about ordering between
writes, although for all practical purposes they are ordered
as long as you have sane buses underneath.
The ordering of readl/writel is defined to be at least as strict
as what x86 gets you on PCI. This means fully ordered for readl
and writel. In theory, writel is only ordered wrt spinlocks in
combination with mmiowb() as you mentioned, but hardly anyone uses
that correctly, so all sane architectures define mmiowb as a NOP
anyway, except when it's an extremely expensive operation and there
are only a handful of drivers that are actually being used and
they can be audited. I'm not crazy enough to ask anyone to
understand and use mmiowb() correctly ;-)
Russell, from previous discussions I had the impression that you did
not actually want __raw_readl/writel to be used for random platform
drivers, although you might not bother to complain about it either.
When I first complained about readl() being used for non-PCI drivers,
I got the reply that it's actually the right thing to do on ARM, so
I started telling people about that in reviews. My current mental
matrix of the various I/O so far accessors is:
readl: anywhere, except PCI I/O space, little-endian
inl: PCI I/O space, little-endian
readl_relaxed: SoC components only, little-endian
ioread32: anywhere, little-endian
ioread32be: anywhere, big-endian
pointer dereference: definitely nowhere, native-endian
__raw_readl: almost nowhere, native-endian
You apparently disagree on the last one, which is fine. Just tell
me what you want and I can make sure I'll look out for any
misuse of the rules in future reviews but don't complain about
correct uses.
Arnd
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 01/15] ARM: mxs: Add core definitions
2010-12-15 17:06 ` Uwe Kleine-König
2010-12-15 17:17 ` Arnd Bergmann
@ 2010-12-16 1:37 ` Shawn Guo
1 sibling, 0 replies; 28+ messages in thread
From: Shawn Guo @ 2010-12-16 1:37 UTC (permalink / raw)
To: linux-arm-kernel
Hi Uwe,
I thought you had started your vacation, since I have not seen any
message from you in the past two days. That's why I'm holding the v7.
So glad to see your message, the v7 will be out later today. I'm
struggling to get the patch series accepted before your New Year
Holiday.
I have one comment embedded below.
2010/12/16 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
> Hello Arnd,
>
> On Wed, Dec 15, 2010 at 05:58:42PM +0100, Arnd Bergmann wrote:
>> On Wednesday 15 December 2010, Uwe Kleine-K?nig wrote:
>> > On Wed, Dec 15, 2010 at 05:22:21PM +0100, Arnd Bergmann wrote:
>> > > > +
>> > > > +#ifndef __ASSEMBLER__
>> > > > +static inline void __mxs_setl(u32 mask, void __iomem *reg)
>> > > > +{
>> > > > + ? ? ? __raw_writel(mask, reg + MXS_SET_ADDR);
>> > > > +}
>> > > > +
>> > > > +static inline void __mxs_clrl(u32 mask, void __iomem *reg)
>> > > > +{
>> > > > + ? ? ? __raw_writel(mask, reg + MXS_CLR_ADDR);
>> > > > +}
>> > > > +
>> > > > +static inline void __mxs_togl(u32 mask, void __iomem *reg)
>> > > > +{
>> > > > + ? ? ? __raw_writel(mask, reg + MXS_TOG_ADDR);
>> > > > +}
>> > > > +#endif
>> > >
>> > > Why __raw_writel()? All regular I/O accesses should use
>> > > readl/writel etc, not the internal helpers.
>> > nak, readl does little endian accesses, __raw_readl native endian. ?So
>> > for platform use __raw_readl is most of the time the better one.
>>
>> Then we should define a proper function for this with well-defined
>> behaviour. I would suggest defining a mxs_readl/mxs_writel here,
>> that is defined to have the same endianess as the mxs SOC, but
>> otherwise has the same properties as readl/writel.
> I don't get your point here. ?What are the properties of readl/writel
> you want here? ?The barrier? ?__mem_pci?
>
> For me __mxs_setl is a proper function with well-defined behaviour, no?
> (One thing I currently consider to argue is to make these .c file local
> because different IPs might have different offsets for SET, CLR and TOG
> or not support it at all, but other than that I'm happy with it.)
>
Though some IPs do not have SET/CLR/TOG registers, all IPs having them
share the same offset.
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 08/15] ARM: mxs: Add iomux support
2010-12-13 12:55 ` [PATCH v6 08/15] ARM: mxs: Add iomux support Shawn Guo
@ 2010-12-16 9:51 ` Uwe Kleine-König
2010-12-16 10:26 ` Shawn Guo
0 siblings, 1 reply; 28+ messages in thread
From: Uwe Kleine-König @ 2010-12-16 9:51 UTC (permalink / raw)
To: linux-arm-kernel
Hello Shawn,
On Mon, Dec 13, 2010 at 08:55:02PM +0800, Shawn Guo wrote:
> +/*
> + * 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 MXS_IOMUX_PAD(3, 16, PAD_MUXSEL_2, PAD_3V3, PAD_4MA, PAD_NOPULL)
> +#define MX28_PAD_PWM1__DUART_TX MXS_IOMUX_PAD(3, 17, PAD_MUXSEL_2, PAD_3V3, PAD_4MA, PAD_NOPULL)
> +
> +/* FEC */
> +#define MX28_PAD_ENET0_MDC__ENET0_MDC MXS_IOMUX_PAD(4, 0, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
> +#define MX28_PAD_ENET0_MDIO__ENET0_MDIO MXS_IOMUX_PAD(4, 1, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
> +#define MX28_PAD_ENET0_RX_EN__ENET0_RX_EN MXS_IOMUX_PAD(4, 2, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
> +#define MX28_PAD_ENET0_RXD0__ENET0_RXD0 MXS_IOMUX_PAD(4, 3, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
> +#define MX28_PAD_ENET0_RXD1__ENET0_RXD1 MXS_IOMUX_PAD(4, 4, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
> +#define MX28_PAD_ENET0_TX_EN__ENET0_TX_EN MXS_IOMUX_PAD(4, 6, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
> +#define MX28_PAD_ENET0_TXD0__ENET0_TXD0 MXS_IOMUX_PAD(4, 7, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
> +#define MX28_PAD_ENET0_TXD1__ENET0_TXD1 MXS_IOMUX_PAD(4, 8, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
> +#define MX28_PAD_ENET_CLK__ENET_CLK MXS_IOMUX_PAD(4, 16, PAD_MUXSEL_0, PAD_3V3, PAD_8MA, PAD_PULLUP)
> +
> +/* GPIO */
> +#define MX28_PAD_SSP1_DATA3__GPIO_2_15 MXS_IOMUX_PAD(2, 15, PAD_MUXSEL_GPIO, PAD_3V3, PAD_4MA, PAD_NOPULL)
> +#define MX28_PAD_ENET0_RX_CLK__GPIO_4_13 MXS_IOMUX_PAD(4, 13, PAD_MUXSEL_GPIO, PAD_3V3, PAD_4MA, PAD_NOPULL)
Can we please have a defined order for these definitions? I suggest to
sort by the arguments to MXS_IOMUX_PAD.
Moreover to be able to benefit from iomux_cfg_t being an integer type it
would be great to have the generic defines use PAD_VOL_NONE, PAD_MA_NONE
and PAD_NOPULL and let these constants have the value 0 to be able to
simply say:
static const mxs_iomux_cfg_t my_pads[] = {
MX28_PAD_SSP1_DATA3__GPIO_2_15 | PAD_PULLUP,
...
};
And it would be nice to get all pad definitions at once generated from
the Freescale Excel sheet. Lothar Wa?mann already did that based on one
of your first versions of this series. I can provide it to you via
private mail if you think this might be easier for you. For plat-mxc
starting with the complete definitions prooved to be the better approach
because otherwise you get many merge conflicts and typing errors.
BTW, when Lothar did the conversion he found one mismatch between your
patch and the Excel sheet. You had MX28_PAD_ENET_CLK__ENET_CLK while
the table had MX28_PAD_ENET_CLK__CLKCTRL_ENET. I didn't check which of
these is consistent with the reference manual.
(Most of these suggestions are from Lothar, I'm just the messenger here,
but I'm of the same mind.)
Best regards,
Uwe
--
Pengutronix e.K. | Uwe Kleine-K?nig |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v6 08/15] ARM: mxs: Add iomux support
2010-12-16 9:51 ` Uwe Kleine-König
@ 2010-12-16 10:26 ` Shawn Guo
0 siblings, 0 replies; 28+ messages in thread
From: Shawn Guo @ 2010-12-16 10:26 UTC (permalink / raw)
To: linux-arm-kernel
Hi Uwe,
2010/12/16 Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>:
[...]
>
> Can we please have a defined order for these definitions? ?I suggest to
> sort by the arguments to MXS_IOMUX_PAD.
>
> Moreover to be able to benefit from iomux_cfg_t being an integer type it
> would be great to have the generic defines use PAD_VOL_NONE, PAD_MA_NONE
> and PAD_NOPULL and let these constants have the value 0 to be able to
> simply say:
>
> ? ? ? ?static const mxs_iomux_cfg_t my_pads[] = {
> ? ? ? ? ? ? ? ?MX28_PAD_SSP1_DATA3__GPIO_2_15 | PAD_PULLUP,
> ? ? ? ? ? ? ? ?...
> ? ? ? ?};
>
> And it would be nice to get all pad definitions at once generated from
> the Freescale Excel sheet. ?Lothar Wa?mann already did that based on one
> of your first versions of this series. ?I can provide it to you via
> private mail if you think this might be easier for you. ?For plat-mxc
OK. Please send me.
> starting with the complete definitions prooved to be the better approach
> because otherwise you get many merge conflicts and typing errors.
>
> BTW, when Lothar did the conversion he found one mismatch between your
> patch and the Excel sheet. ?You had MX28_PAD_ENET_CLK__ENET_CLK while
> the table had MX28_PAD_ENET_CLK__CLKCTRL_ENET. ?I didn't check which of
> these is consistent with the reference manual.
>
Excel is correct.
> (Most of these suggestions are from Lothar, I'm just the messenger here,
> but I'm of the same mind.)
>
Thanks, both.
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 28+ messages in thread
end of thread, other threads:[~2010-12-16 10:26 UTC | newest]
Thread overview: 28+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-12-13 12:54 [PATCH v6 00/15] ARM: mxs: Add initial support for MX23 and MX28 Shawn Guo
2010-12-13 12:54 ` [PATCH v6 01/15] ARM: mxs: Add core definitions Shawn Guo
2010-12-15 16:22 ` Arnd Bergmann
2010-12-15 16:40 ` Uwe Kleine-König
2010-12-15 16:58 ` Arnd Bergmann
2010-12-15 17:06 ` Uwe Kleine-König
2010-12-15 17:17 ` Arnd Bergmann
2010-12-15 17:27 ` Russell King - ARM Linux
2010-12-15 22:26 ` Arnd Bergmann
2010-12-15 18:49 ` Uwe Kleine-König
2010-12-16 1:37 ` Shawn Guo
2010-12-15 16:47 ` Russell King - ARM Linux
2010-12-15 17:08 ` Arnd Bergmann
2010-12-15 17:23 ` Russell King - ARM Linux
2010-12-15 17:51 ` Arnd Bergmann
2010-12-13 12:54 ` [PATCH v6 03/15] ARM: mxs: Add reset routines Shawn Guo
2010-12-13 12:55 ` [PATCH v6 06/15] ARM: mxs: Add timer support Shawn Guo
2010-12-13 13:53 ` Russell King - ARM Linux
2010-12-13 12:55 ` [PATCH v6 07/15] ARM: mxs: Add gpio support Shawn Guo
2010-12-13 12:55 ` [PATCH v6 08/15] ARM: mxs: Add iomux support Shawn Guo
2010-12-16 9:51 ` Uwe Kleine-König
2010-12-16 10:26 ` Shawn Guo
2010-12-13 12:55 ` [PATCH v6 15/15] ARM: mxs: Add build configuration for mxs Shawn Guo
2010-12-13 14:20 ` [PATCH v6 00/15] ARM: mxs: Add initial support for MX23 and MX28 Uwe Kleine-König
2010-12-14 8:31 ` [PATCH v6 00/15] ARM: mxs: Add initial support for MX23 andMX28 Shawn Guo
2010-12-14 13:00 ` Shawn Guo
2010-12-15 16:24 ` [PATCH v6 00/15] ARM: mxs: Add initial support for MX23 and MX28 Arnd Bergmann
2010-12-15 16:34 ` Uwe Kleine-König
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.