All of lore.kernel.org
 help / color / mirror / Atom feed
* [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.