summaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-sa1100
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:27:49 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:27:49 +0000
commitace9429bb58fd418f0c81d4c2835699bddf6bde6 (patch)
treeb2d64bc10158fdd5497876388cd68142ca374ed3 /arch/arm/mach-sa1100
parentInitial commit. (diff)
downloadlinux-ace9429bb58fd418f0c81d4c2835699bddf6bde6.tar.xz
linux-ace9429bb58fd418f0c81d4c2835699bddf6bde6.zip
Adding upstream version 6.6.15.upstream/6.6.15
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'arch/arm/mach-sa1100')
-rw-r--r--arch/arm/mach-sa1100/Kconfig88
-rw-r--r--arch/arm/mach-sa1100/Makefile20
-rw-r--r--arch/arm/mach-sa1100/assabet.c745
-rw-r--r--arch/arm/mach-sa1100/clock.c145
-rw-r--r--arch/arm/mach-sa1100/collie.c429
-rw-r--r--arch/arm/mach-sa1100/generic.c470
-rw-r--r--arch/arm/mach-sa1100/generic.h55
-rw-r--r--arch/arm/mach-sa1100/h3600.c109
-rw-r--r--arch/arm/mach-sa1100/h3xxx.c288
-rw-r--r--arch/arm/mach-sa1100/include/mach/SA-1100.h1798
-rw-r--r--arch/arm/mach-sa1100/include/mach/assabet.h99
-rw-r--r--arch/arm/mach-sa1100/include/mach/bitfield.h113
-rw-r--r--arch/arm/mach-sa1100/include/mach/collie.h94
-rw-r--r--arch/arm/mach-sa1100/include/mach/generic.h1
-rw-r--r--arch/arm/mach-sa1100/include/mach/h3xxx.h81
-rw-r--r--arch/arm/mach-sa1100/include/mach/hardware.h56
-rw-r--r--arch/arm/mach-sa1100/include/mach/irqs.h101
-rw-r--r--arch/arm/mach-sa1100/include/mach/jornada720.h28
-rw-r--r--arch/arm/mach-sa1100/include/mach/memory.h37
-rw-r--r--arch/arm/mach-sa1100/include/mach/mtd-xip.h23
-rw-r--r--arch/arm/mach-sa1100/include/mach/neponset.h31
-rw-r--r--arch/arm/mach-sa1100/include/mach/reset.h18
-rw-r--r--arch/arm/mach-sa1100/include/mach/uncompress.h52
-rw-r--r--arch/arm/mach-sa1100/jornada720.c380
-rw-r--r--arch/arm/mach-sa1100/jornada720_ssp.c202
-rw-r--r--arch/arm/mach-sa1100/neponset.c438
-rw-r--r--arch/arm/mach-sa1100/pm.c128
-rw-r--r--arch/arm/mach-sa1100/sleep.S143
-rw-r--r--arch/arm/mach-sa1100/ssp.c240
29 files changed, 6412 insertions, 0 deletions
diff --git a/arch/arm/mach-sa1100/Kconfig b/arch/arm/mach-sa1100/Kconfig
new file mode 100644
index 000000000..0fb4c24cf
--- /dev/null
+++ b/arch/arm/mach-sa1100/Kconfig
@@ -0,0 +1,88 @@
+# SPDX-License-Identifier: GPL-2.0-only
+menuconfig ARCH_SA1100
+ bool "SA11x0 Implementations"
+ depends on ARCH_MULTI_V4 && !(ARCH_MULTI_V4T || ARCH_MULTI_V5)
+ depends on !(ARCH_MOXART || ARCH_GEMINI)
+ depends on ATAGS
+ depends on CPU_LITTLE_ENDIAN
+ depends on MMU
+ select ARCH_NO_SG_CHAIN
+ select ARCH_MTD_XIP
+ select CLKSRC_MMIO
+ select CLKSRC_PXA
+ select CPU_FREQ
+ select CPU_SA1100
+ select GPIOLIB
+ select IRQ_DOMAIN
+ select ISA
+ select NEED_MACH_MEMORY_H
+ help
+ Support for StrongARM 11x0 based boards.
+
+if ARCH_SA1100
+
+config SA1100_ASSABET
+ bool "Assabet"
+ select ARM_SA1110_CPUFREQ
+ select GPIO_REG
+ select LEDS_GPIO_REGISTER
+ select REGULATOR
+ select REGULATOR_FIXED_VOLTAGE
+ help
+ Say Y here if you are using the Intel(R) StrongARM(R) SA-1110
+ Microprocessor Development Board (also known as the Assabet).
+
+config ASSABET_NEPONSET
+ bool "Include support for Neponset"
+ depends on SA1100_ASSABET
+ select SA1111
+ help
+ Say Y here if you are using the Intel(R) StrongARM(R) SA-1110
+ Microprocessor Development Board (Assabet) with the SA-1111
+ Development Board (Nepon).
+
+config SA1100_COLLIE
+ bool "Sharp Zaurus SL5500"
+ # FIXME: select ARM_SA11x0_CPUFREQ
+ select SHARP_LOCOMO
+ select SHARP_PARAM
+ select SHARP_SCOOP
+ help
+ Say Y here to support the Sharp Zaurus SL5500 PDAs.
+
+config SA1100_H3600
+ bool "Compaq iPAQ H3600/H3700"
+ select ARM_SA1110_CPUFREQ
+ select HTC_EGPIO
+ select MFD_IPAQ_MICRO
+ help
+ Say Y here if you intend to run this kernel on the Compaq iPAQ
+ H3600 and H3700 handheld computers.
+
+config SA1100_JORNADA720
+ bool "HP Jornada 720"
+ # FIXME: select ARM_SA11x0_CPUFREQ
+ select SA1111
+ help
+ Say Y here if you want to build a kernel for the HP Jornada 720
+ handheld computer. See
+ <http://h10025.www1.hp.com/ewfrf/wc/product?product=61677&cc=us&lc=en&dlc=en&product=61677#>
+
+config SA1100_JORNADA720_SSP
+ bool "HP Jornada 720 Extended SSP driver"
+ depends on SA1100_JORNADA720
+ select SA1100_SSP
+ help
+ Say Y here if you have a HP Jornada 7xx handheld computer and you
+ want to access devices connected to the MCU. Those include the
+ keyboard, touchscreen, backlight and battery. This driver also activates
+ the generic SSP which it extends.
+
+config SA1100_SSP
+ tristate "Generic PIO SSP"
+ help
+ Say Y here to enable support for the generic PIO SSP driver.
+ This isn't for audio support, but for attached sensors and
+ other devices, eg for BadgePAD 4 sensor support.
+
+endif
diff --git a/arch/arm/mach-sa1100/Makefile b/arch/arm/mach-sa1100/Makefile
new file mode 100644
index 000000000..b5816d675
--- /dev/null
+++ b/arch/arm/mach-sa1100/Makefile
@@ -0,0 +1,20 @@
+# SPDX-License-Identifier: GPL-2.0
+#
+# Makefile for the linux kernel.
+#
+
+# Common support
+obj-y := clock.o generic.o #nmi-oopser.o
+
+# Specific board support
+obj-$(CONFIG_SA1100_ASSABET) += assabet.o
+obj-$(CONFIG_ASSABET_NEPONSET) += neponset.o
+obj-$(CONFIG_SA1100_COLLIE) += collie.o
+obj-$(CONFIG_SA1100_H3600) += h3600.o h3xxx.o
+obj-$(CONFIG_SA1100_JORNADA720) += jornada720.o
+obj-$(CONFIG_SA1100_JORNADA720_SSP) += jornada720_ssp.o
+
+# Miscellaneous functions
+obj-$(CONFIG_PM) += pm.o sleep.o
+obj-$(CONFIG_SA1100_SSP) += ssp.o
+
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
new file mode 100644
index 000000000..2b833aa02
--- /dev/null
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -0,0 +1,745 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * linux/arch/arm/mach-sa1100/assabet.c
+ *
+ * Author: Nicolas Pitre
+ *
+ * This file contains all Assabet-specific tweaks.
+ */
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/errno.h>
+#include <linux/gpio/driver.h>
+#include <linux/gpio/gpio-reg.h>
+#include <linux/gpio/machine.h>
+#include <linux/gpio_keys.h>
+#include <linux/ioport.h>
+#include <linux/platform_data/sa11x0-serial.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/serial_core.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/ucb1x00.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <linux/leds.h>
+#include <linux/slab.h>
+
+#include <video/sa1100fb.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/setup.h>
+#include <asm/page.h>
+#include <asm/pgtable-hwdef.h>
+#include <asm/tlbflush.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+#include <mach/assabet.h>
+#include <linux/platform_data/mfd-mcp-sa11x0.h>
+#include <mach/irqs.h>
+
+#include "generic.h"
+
+#define ASSABET_BCR_DB1110 \
+ (ASSABET_BCR_SPK_OFF | \
+ ASSABET_BCR_LED_GREEN | ASSABET_BCR_LED_RED | \
+ ASSABET_BCR_RS232EN | ASSABET_BCR_LCD_12RGB | \
+ ASSABET_BCR_IRDA_MD0)
+
+#define ASSABET_BCR_DB1111 \
+ (ASSABET_BCR_SPK_OFF | \
+ ASSABET_BCR_LED_GREEN | ASSABET_BCR_LED_RED | \
+ ASSABET_BCR_RS232EN | ASSABET_BCR_LCD_12RGB | \
+ ASSABET_BCR_CF_BUS_OFF | ASSABET_BCR_STEREO_LB | \
+ ASSABET_BCR_IRDA_MD0 | ASSABET_BCR_CF_RST)
+
+unsigned long SCR_value = ASSABET_SCR_INIT;
+EXPORT_SYMBOL(SCR_value);
+
+static struct gpio_chip *assabet_bcr_gc;
+
+static const char *assabet_names[] = {
+ "cf_pwr", "cf_gfx_reset", "nsoft_reset", "irda_fsel",
+ "irda_md0", "irda_md1", "stereo_loopback", "ncf_bus_on",
+ "audio_pwr_on", "light_pwr_on", "lcd16data", "lcd_pwr_on",
+ "rs232_on", "nred_led", "ngreen_led", "vib_on",
+ "com_dtr", "com_rts", "radio_wake_mod", "i2c_enab",
+ "tvir_enab", "qmute", "radio_pwr_on", "spkr_off",
+ "rs232_valid", "com_dcd", "com_cts", "com_dsr",
+ "radio_cts", "radio_dsr", "radio_dcd", "radio_ri",
+};
+
+/* The old deprecated interface */
+void ASSABET_BCR_frob(unsigned int mask, unsigned int val)
+{
+ unsigned long m = mask, v = val;
+
+ assabet_bcr_gc->set_multiple(assabet_bcr_gc, &m, &v);
+}
+EXPORT_SYMBOL(ASSABET_BCR_frob);
+
+static void __init assabet_init_gpio(void __iomem *reg, u32 def_val)
+{
+ struct gpio_chip *gc;
+
+ writel_relaxed(def_val, reg);
+
+ gc = gpio_reg_init(NULL, reg, -1, 32, "assabet", 0xff000000, def_val,
+ assabet_names, NULL, NULL);
+
+ if (IS_ERR(gc))
+ return;
+
+ assabet_bcr_gc = gc;
+}
+
+/*
+ * The codec reset goes to three devices, so we need to release
+ * the rest when any one of these requests it. However, that
+ * causes the ADV7171 to consume around 100mA - more than half
+ * the LCD-blanked power.
+ *
+ * With the ADV7171, LCD and backlight enabled, we go over
+ * budget on the MAX846 Li-Ion charger, and if no Li-Ion battery
+ * is connected, the Assabet crashes.
+ */
+#define RST_UCB1X00 (1 << 0)
+#define RST_UDA1341 (1 << 1)
+#define RST_ADV7171 (1 << 2)
+
+#define SDA GPIO_GPIO(15)
+#define SCK GPIO_GPIO(18)
+#define MOD GPIO_GPIO(17)
+
+static void adv7171_start(void)
+{
+ GPSR = SCK;
+ udelay(1);
+ GPSR = SDA;
+ udelay(2);
+ GPCR = SDA;
+}
+
+static void adv7171_stop(void)
+{
+ GPSR = SCK;
+ udelay(2);
+ GPSR = SDA;
+ udelay(1);
+}
+
+static void adv7171_send(unsigned byte)
+{
+ unsigned i;
+
+ for (i = 0; i < 8; i++, byte <<= 1) {
+ GPCR = SCK;
+ udelay(1);
+ if (byte & 0x80)
+ GPSR = SDA;
+ else
+ GPCR = SDA;
+ udelay(1);
+ GPSR = SCK;
+ udelay(1);
+ }
+ GPCR = SCK;
+ udelay(1);
+ GPSR = SDA;
+ udelay(1);
+ GPDR &= ~SDA;
+ GPSR = SCK;
+ udelay(1);
+ if (GPLR & SDA)
+ printk(KERN_WARNING "No ACK from ADV7171\n");
+ udelay(1);
+ GPCR = SCK | SDA;
+ udelay(1);
+ GPDR |= SDA;
+ udelay(1);
+}
+
+static void adv7171_write(unsigned reg, unsigned val)
+{
+ unsigned gpdr = GPDR;
+ unsigned gplr = GPLR;
+
+ ASSABET_BCR_frob(ASSABET_BCR_AUDIO_ON, ASSABET_BCR_AUDIO_ON);
+ udelay(100);
+
+ GPCR = SDA | SCK | MOD; /* clear L3 mode to ensure UDA1341 doesn't respond */
+ GPDR = (GPDR | SCK | MOD) & ~SDA;
+ udelay(10);
+ if (!(GPLR & SDA))
+ printk(KERN_WARNING "Something dragging SDA down?\n");
+ GPDR |= SDA;
+
+ adv7171_start();
+ adv7171_send(0x54);
+ adv7171_send(reg);
+ adv7171_send(val);
+ adv7171_stop();
+
+ /* Restore GPIO state for L3 bus */
+ GPSR = gplr & (SDA | SCK | MOD);
+ GPCR = (~gplr) & (SDA | SCK | MOD);
+ GPDR = gpdr;
+}
+
+static void adv7171_sleep(void)
+{
+ /* Put the ADV7171 into sleep mode */
+ adv7171_write(0x04, 0x40);
+}
+
+static unsigned codec_nreset;
+
+static void assabet_codec_reset(unsigned mask, int set)
+{
+ unsigned long flags;
+ bool old;
+
+ local_irq_save(flags);
+ old = !codec_nreset;
+ if (set)
+ codec_nreset &= ~mask;
+ else
+ codec_nreset |= mask;
+
+ if (old != !codec_nreset) {
+ if (codec_nreset) {
+ ASSABET_BCR_set(ASSABET_BCR_NCODEC_RST);
+ adv7171_sleep();
+ } else {
+ ASSABET_BCR_clear(ASSABET_BCR_NCODEC_RST);
+ }
+ }
+ local_irq_restore(flags);
+}
+
+static void assabet_ucb1x00_reset(enum ucb1x00_reset state)
+{
+ int set = state == UCB_RST_REMOVE || state == UCB_RST_SUSPEND ||
+ state == UCB_RST_PROBE_FAIL;
+ assabet_codec_reset(RST_UCB1X00, set);
+}
+
+void assabet_uda1341_reset(int set)
+{
+ assabet_codec_reset(RST_UDA1341, set);
+}
+EXPORT_SYMBOL(assabet_uda1341_reset);
+
+
+/*
+ * Assabet flash support code.
+ */
+
+#ifdef ASSABET_REV_4
+/*
+ * Phase 4 Assabet has two 28F160B3 flash parts in bank 0:
+ */
+static struct mtd_partition assabet_partitions[] = {
+ {
+ .name = "bootloader",
+ .size = 0x00020000,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "bootloader params",
+ .size = 0x00020000,
+ .offset = MTDPART_OFS_APPEND,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "jffs",
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND,
+ }
+};
+#else
+/*
+ * Phase 5 Assabet has two 28F128J3A flash parts in bank 0:
+ */
+static struct mtd_partition assabet_partitions[] = {
+ {
+ .name = "bootloader",
+ .size = 0x00040000,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "bootloader params",
+ .size = 0x00040000,
+ .offset = MTDPART_OFS_APPEND,
+ .mask_flags = MTD_WRITEABLE,
+ }, {
+ .name = "jffs",
+ .size = MTDPART_SIZ_FULL,
+ .offset = MTDPART_OFS_APPEND,
+ }
+};
+#endif
+
+static struct flash_platform_data assabet_flash_data = {
+ .map_name = "cfi_probe",
+ .parts = assabet_partitions,
+ .nr_parts = ARRAY_SIZE(assabet_partitions),
+};
+
+static struct resource assabet_flash_resources[] = {
+ DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M),
+ DEFINE_RES_MEM(SA1100_CS1_PHYS, SZ_32M),
+};
+
+
+static struct ucb1x00_plat_data assabet_ucb1x00_data = {
+ .reset = assabet_ucb1x00_reset,
+ .gpio_base = -1,
+ .can_wakeup = 1,
+};
+
+static struct mcp_plat_data assabet_mcp_data = {
+ .mccr0 = MCCR0_ADM,
+ .sclk_rate = 11981000,
+ .codec_pdata = &assabet_ucb1x00_data,
+};
+
+static void assabet_lcd_set_visual(u32 visual)
+{
+ u_int is_true_color = visual == FB_VISUAL_TRUECOLOR;
+
+ if (machine_is_assabet()) {
+#if 1 // phase 4 or newer Assabet's
+ if (is_true_color)
+ ASSABET_BCR_set(ASSABET_BCR_LCD_12RGB);
+ else
+ ASSABET_BCR_clear(ASSABET_BCR_LCD_12RGB);
+#else
+ // older Assabet's
+ if (is_true_color)
+ ASSABET_BCR_clear(ASSABET_BCR_LCD_12RGB);
+ else
+ ASSABET_BCR_set(ASSABET_BCR_LCD_12RGB);
+#endif
+ }
+}
+
+#ifndef ASSABET_PAL_VIDEO
+static void assabet_lcd_backlight_power(int on)
+{
+ if (on)
+ ASSABET_BCR_set(ASSABET_BCR_LIGHT_ON);
+ else
+ ASSABET_BCR_clear(ASSABET_BCR_LIGHT_ON);
+}
+
+/*
+ * Turn on/off the backlight. When turning the backlight on, we wait
+ * 500us after turning it on so we don't cause the supplies to droop
+ * when we enable the LCD controller (and cause a hard reset.)
+ */
+static void assabet_lcd_power(int on)
+{
+ if (on) {
+ ASSABET_BCR_set(ASSABET_BCR_LCD_ON);
+ udelay(500);
+ } else
+ ASSABET_BCR_clear(ASSABET_BCR_LCD_ON);
+}
+
+/*
+ * The assabet uses a sharp LQ039Q2DS54 LCD module. It is actually
+ * takes an RGB666 signal, but we provide it with an RGB565 signal
+ * instead (def_rgb_16).
+ */
+static struct sa1100fb_mach_info lq039q2ds54_info = {
+ .pixclock = 171521, .bpp = 16,
+ .xres = 320, .yres = 240,
+
+ .hsync_len = 5, .vsync_len = 1,
+ .left_margin = 61, .upper_margin = 3,
+ .right_margin = 9, .lower_margin = 0,
+
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+
+ .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
+ .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
+
+ .backlight_power = assabet_lcd_backlight_power,
+ .lcd_power = assabet_lcd_power,
+ .set_visual = assabet_lcd_set_visual,
+};
+#else
+static void assabet_pal_backlight_power(int on)
+{
+ ASSABET_BCR_clear(ASSABET_BCR_LIGHT_ON);
+}
+
+static void assabet_pal_power(int on)
+{
+ ASSABET_BCR_clear(ASSABET_BCR_LCD_ON);
+}
+
+static struct sa1100fb_mach_info pal_info = {
+ .pixclock = 67797, .bpp = 16,
+ .xres = 640, .yres = 512,
+
+ .hsync_len = 64, .vsync_len = 6,
+ .left_margin = 125, .upper_margin = 70,
+ .right_margin = 115, .lower_margin = 36,
+
+ .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
+ .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(512),
+
+ .backlight_power = assabet_pal_backlight_power,
+ .lcd_power = assabet_pal_power,
+ .set_visual = assabet_lcd_set_visual,
+};
+#endif
+
+#ifdef CONFIG_ASSABET_NEPONSET
+static struct resource neponset_resources[] = {
+ DEFINE_RES_MEM(0x10000000, 0x08000000),
+ DEFINE_RES_MEM(0x18000000, 0x04000000),
+ DEFINE_RES_MEM(0x40000000, SZ_8K),
+ DEFINE_RES_IRQ(IRQ_GPIO25),
+};
+#endif
+
+static struct gpiod_lookup_table assabet_cf_gpio_table = {
+ .dev_id = "sa11x0-pcmcia.1",
+ .table = {
+ GPIO_LOOKUP("gpio", 21, "ready", GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP("gpio", 22, "detect", GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP("gpio", 24, "bvd2", GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP("gpio", 25, "bvd1", GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP("assabet", 1, "reset", GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP("assabet", 7, "bus-enable", GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
+static struct regulator_consumer_supply assabet_cf_vcc_consumers[] = {
+ REGULATOR_SUPPLY("vcc", "sa11x0-pcmcia.1"),
+};
+
+static struct fixed_voltage_config assabet_cf_vcc_pdata __initdata = {
+ .supply_name = "cf-power",
+ .microvolts = 3300000,
+};
+
+static struct gpiod_lookup_table assabet_cf_vcc_gpio_table = {
+ .dev_id = "reg-fixed-voltage.0",
+ .table = {
+ GPIO_LOOKUP("assabet", 0, NULL, GPIO_ACTIVE_HIGH),
+ { },
+ },
+};
+
+static struct gpiod_lookup_table assabet_leds_gpio_table = {
+ .dev_id = "leds-gpio",
+ .table = {
+ GPIO_LOOKUP("assabet", 13, NULL, GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP("assabet", 14, NULL, GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
+static struct gpio_led assabet_leds[] __initdata = {
+ {
+ .name = "assabet:red",
+ .default_trigger = "cpu0",
+ .default_state = LEDS_GPIO_DEFSTATE_KEEP,
+ }, {
+ .name = "assabet:green",
+ .default_trigger = "heartbeat",
+ .default_state = LEDS_GPIO_DEFSTATE_KEEP,
+ },
+};
+
+static const struct gpio_led_platform_data assabet_leds_pdata __initconst = {
+ .num_leds = ARRAY_SIZE(assabet_leds),
+ .leds = assabet_leds,
+};
+
+static struct gpio_keys_button assabet_keys_buttons[] = {
+ {
+ .gpio = 0,
+ .irq = IRQ_GPIO0,
+ .desc = "gpio0",
+ .wakeup = 1,
+ .can_disable = 1,
+ .debounce_interval = 5,
+ }, {
+ .gpio = 1,
+ .irq = IRQ_GPIO1,
+ .desc = "gpio1",
+ .wakeup = 1,
+ .can_disable = 1,
+ .debounce_interval = 5,
+ },
+};
+
+static const struct gpio_keys_platform_data assabet_keys_pdata = {
+ .buttons = assabet_keys_buttons,
+ .nbuttons = ARRAY_SIZE(assabet_keys_buttons),
+ .rep = 0,
+};
+
+static struct gpiod_lookup_table assabet_uart1_gpio_table = {
+ .dev_id = "sa11x0-uart.1",
+ .table = {
+ GPIO_LOOKUP("assabet", 16, "dtr", GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP("assabet", 17, "rts", GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP("assabet", 25, "dcd", GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP("assabet", 26, "cts", GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP("assabet", 27, "dsr", GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
+static struct gpiod_lookup_table assabet_uart3_gpio_table = {
+ .dev_id = "sa11x0-uart.3",
+ .table = {
+ GPIO_LOOKUP("assabet", 28, "cts", GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP("assabet", 29, "dsr", GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP("assabet", 30, "dcd", GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP("assabet", 31, "rng", GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
+static void __init assabet_init(void)
+{
+ /*
+ * Ensure that the power supply is in "high power" mode.
+ */
+ GPSR = GPIO_GPIO16;
+ GPDR |= GPIO_GPIO16;
+
+ /*
+ * Ensure that these pins are set as outputs and are driving
+ * logic 0. This ensures that we won't inadvertently toggle
+ * the WS latch in the CPLD, and we don't float causing
+ * excessive power drain. --rmk
+ */
+ GPCR = GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
+ GPDR |= GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM;
+
+ /*
+ * Also set GPIO27 as an output; this is used to clock UART3
+ * via the FPGA and as otherwise has no pullups or pulldowns,
+ * so stop it floating.
+ */
+ GPCR = GPIO_GPIO27;
+ GPDR |= GPIO_GPIO27;
+
+ /*
+ * Set up registers for sleep mode.
+ */
+ PWER = PWER_GPIO0;
+ PGSR = 0;
+ PCFR = 0;
+ PSDR = 0;
+ PPDR |= PPC_TXD3 | PPC_TXD1;
+ PPSR |= PPC_TXD3 | PPC_TXD1;
+
+ sa11x0_ppc_configure_mcp();
+
+ if (machine_has_neponset()) {
+#ifndef CONFIG_ASSABET_NEPONSET
+ printk( "Warning: Neponset detected but full support "
+ "hasn't been configured in the kernel\n" );
+#else
+ platform_device_register_simple("neponset", 0,
+ neponset_resources, ARRAY_SIZE(neponset_resources));
+#endif
+ } else {
+ gpiod_add_lookup_table(&assabet_uart1_gpio_table);
+ gpiod_add_lookup_table(&assabet_uart3_gpio_table);
+ gpiod_add_lookup_table(&assabet_cf_vcc_gpio_table);
+
+ sa11x0_register_fixed_regulator(0, &assabet_cf_vcc_pdata,
+ assabet_cf_vcc_consumers,
+ ARRAY_SIZE(assabet_cf_vcc_consumers),
+ true);
+
+ }
+
+ platform_device_register_resndata(NULL, "gpio-keys", 0,
+ NULL, 0,
+ &assabet_keys_pdata,
+ sizeof(assabet_keys_pdata));
+
+ gpiod_add_lookup_table(&assabet_leds_gpio_table);
+ gpio_led_register_device(-1, &assabet_leds_pdata);
+
+#ifndef ASSABET_PAL_VIDEO
+ sa11x0_register_lcd(&lq039q2ds54_info);
+#else
+ sa11x0_register_lcd(&pal_video);
+#endif
+ sa11x0_register_mtd(&assabet_flash_data, assabet_flash_resources,
+ ARRAY_SIZE(assabet_flash_resources));
+ sa11x0_register_mcp(&assabet_mcp_data);
+
+ if (!machine_has_neponset())
+ sa11x0_register_pcmcia(1, &assabet_cf_gpio_table);
+}
+
+/*
+ * On Assabet, we must probe for the Neponset board _before_
+ * paging_init() has occurred to actually determine the amount
+ * of RAM available. To do so, we map the appropriate IO section
+ * in the page table here in order to access GPIO registers.
+ */
+static void __init map_sa1100_gpio_regs( void )
+{
+ unsigned long phys = __PREG(GPLR) & PMD_MASK;
+ unsigned long virt = (unsigned long)io_p2v(phys);
+ int prot = PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_DOMAIN(DOMAIN_IO);
+ pmd_t *pmd;
+
+ pmd = pmd_off_k(virt);
+ *pmd = __pmd(phys | prot);
+ flush_pmd_entry(pmd);
+}
+
+/*
+ * Read System Configuration "Register"
+ * (taken from "Intel StrongARM SA-1110 Microprocessor Development Board
+ * User's Guide", section 4.4.1)
+ *
+ * This same scan is performed in arch/arm/boot/compressed/head-sa1100.S
+ * to set up the serial port for decompression status messages. We
+ * repeat it here because the kernel may not be loaded as a zImage, and
+ * also because it's a hassle to communicate the SCR value to the kernel
+ * from the decompressor.
+ *
+ * Note that IRQs are guaranteed to be disabled.
+ */
+static void __init get_assabet_scr(void)
+{
+ unsigned long scr, i;
+
+ GPDR |= 0x3fc; /* Configure GPIO 9:2 as outputs */
+ GPSR = 0x3fc; /* Write 0xFF to GPIO 9:2 */
+ GPDR &= ~(0x3fc); /* Configure GPIO 9:2 as inputs */
+ for(i = 100; i--; ) /* Read GPIO 9:2 */
+ scr = GPLR;
+ GPDR |= 0x3fc; /* restore correct pin direction */
+ scr &= 0x3fc; /* save as system configuration byte. */
+ SCR_value = scr;
+}
+
+static void __init
+fixup_assabet(struct tag *tags, char **cmdline)
+{
+ /* This must be done before any call to machine_has_neponset() */
+ map_sa1100_gpio_regs();
+ get_assabet_scr();
+
+ if (machine_has_neponset())
+ printk("Neponset expansion board detected\n");
+}
+
+
+static void assabet_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
+{
+ if (port->mapbase == _Ser1UTCR0) {
+ if (state)
+ ASSABET_BCR_clear(ASSABET_BCR_RS232EN);
+ else
+ ASSABET_BCR_set(ASSABET_BCR_RS232EN);
+ }
+}
+
+static struct sa1100_port_fns assabet_port_fns __initdata = {
+ .pm = assabet_uart_pm,
+};
+
+static struct map_desc assabet_io_desc[] __initdata = {
+ { /* Board Control Register */
+ .virtual = 0xf1000000,
+ .pfn = __phys_to_pfn(0x12000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* MQ200 */
+ .virtual = 0xf2800000,
+ .pfn = __phys_to_pfn(0x4b800000),
+ .length = 0x00800000,
+ .type = MT_DEVICE
+ }
+};
+
+static void __init assabet_map_io(void)
+{
+ sa1100_map_io();
+ iotable_init(assabet_io_desc, ARRAY_SIZE(assabet_io_desc));
+
+ /*
+ * Set SUS bit in SDCR0 so serial port 1 functions.
+ * Its called GPCLKR0 in my SA1110 manual.
+ */
+ Ser1SDCR0 |= SDCR0_SUS;
+ MSC1 = (MSC1 & ~0xffff) |
+ MSC_NonBrst | MSC_32BitStMem |
+ MSC_RdAcc(2) | MSC_WrAcc(2) | MSC_Rec(0);
+
+ if (!machine_has_neponset())
+ sa1100_register_uart_fns(&assabet_port_fns);
+
+ /*
+ * When Neponset is attached, the first UART should be
+ * UART3. That's what Angel is doing and many documents
+ * are stating this.
+ *
+ * We do the Neponset mapping even if Neponset support
+ * isn't compiled in so the user will still get something on
+ * the expected physical serial port.
+ *
+ * We no longer do this; not all boot loaders support it,
+ * and UART3 appears to be somewhat unreliable with blob.
+ */
+ sa1100_register_uart(0, 1);
+ sa1100_register_uart(2, 3);
+}
+
+static void __init assabet_init_irq(void)
+{
+ u32 def_val;
+
+ sa1100_init_irq();
+
+ if (machine_has_neponset())
+ def_val = ASSABET_BCR_DB1111;
+ else
+ def_val = ASSABET_BCR_DB1110;
+
+ /*
+ * Angel sets this, but other bootloaders may not.
+ *
+ * This must precede any driver calls to BCR_set() or BCR_clear().
+ */
+ assabet_init_gpio((void *)&ASSABET_BCR, def_val);
+}
+
+MACHINE_START(ASSABET, "Intel-Assabet")
+ .atag_offset = 0x100,
+ .fixup = fixup_assabet,
+ .map_io = assabet_map_io,
+ .nr_irqs = SA1100_NR_IRQS,
+ .init_irq = assabet_init_irq,
+ .init_time = sa1100_timer_init,
+ .init_machine = assabet_init,
+ .init_late = sa11x0_init_late,
+#ifdef CONFIG_SA1111
+ .dma_zone_size = SZ_1M,
+#endif
+ .restart = sa11x0_restart,
+MACHINE_END
diff --git a/arch/arm/mach-sa1100/clock.c b/arch/arm/mach-sa1100/clock.c
new file mode 100644
index 000000000..e8691921c
--- /dev/null
+++ b/arch/arm/mach-sa1100/clock.c
@@ -0,0 +1,145 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * linux/arch/arm/mach-sa1100/clock.c
+ */
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/clk.h>
+#include <linux/clkdev.h>
+#include <linux/clk-provider.h>
+#include <linux/io.h>
+#include <linux/spinlock.h>
+
+#include <mach/hardware.h>
+#include <mach/generic.h>
+
+static const char * const clk_tucr_parents[] = {
+ "clk32768", "clk3686400",
+};
+
+static DEFINE_SPINLOCK(tucr_lock);
+
+static int clk_gpio27_enable(struct clk_hw *hw)
+{
+ unsigned long flags;
+
+ /*
+ * First, set up the 3.6864MHz clock on GPIO 27 for the SA-1111:
+ * (SA-1110 Developer's Manual, section 9.1.2.1)
+ */
+ local_irq_save(flags);
+ GAFR |= GPIO_32_768kHz;
+ GPDR |= GPIO_32_768kHz;
+ local_irq_restore(flags);
+
+ return 0;
+}
+
+static void clk_gpio27_disable(struct clk_hw *hw)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+ GPDR &= ~GPIO_32_768kHz;
+ GAFR &= ~GPIO_32_768kHz;
+ local_irq_restore(flags);
+}
+
+static const struct clk_ops clk_gpio27_ops = {
+ .enable = clk_gpio27_enable,
+ .disable = clk_gpio27_disable,
+};
+
+static const char * const clk_gpio27_parents[] = {
+ "tucr-mux",
+};
+
+static const struct clk_init_data clk_gpio27_init_data __initconst = {
+ .name = "gpio27",
+ .ops = &clk_gpio27_ops,
+ .parent_names = clk_gpio27_parents,
+ .num_parents = ARRAY_SIZE(clk_gpio27_parents),
+};
+
+/*
+ * Derived from the table 8-1 in the SA1110 manual, the MPLL appears to
+ * multiply its input rate by 4 x (4 + PPCR). This calculation gives
+ * the exact rate. The figures given in the table are the rates rounded
+ * to 100kHz. Stick with sa11x0_getspeed() for the time being.
+ */
+static unsigned long clk_mpll_recalc_rate(struct clk_hw *hw,
+ unsigned long prate)
+{
+ return sa11x0_getspeed(0) * 1000;
+}
+
+static const struct clk_ops clk_mpll_ops = {
+ .recalc_rate = clk_mpll_recalc_rate,
+};
+
+static const char * const clk_mpll_parents[] = {
+ "clk3686400",
+};
+
+static const struct clk_init_data clk_mpll_init_data __initconst = {
+ .name = "mpll",
+ .ops = &clk_mpll_ops,
+ .parent_names = clk_mpll_parents,
+ .num_parents = ARRAY_SIZE(clk_mpll_parents),
+ .flags = CLK_GET_RATE_NOCACHE | CLK_IS_CRITICAL,
+};
+
+int __init sa11xx_clk_init(void)
+{
+ struct clk_hw *hw;
+ int ret;
+
+ hw = clk_hw_register_fixed_rate(NULL, "clk32768", NULL, 0, 32768);
+ if (IS_ERR(hw))
+ return PTR_ERR(hw);
+
+ clk_hw_register_clkdev(hw, NULL, "sa1100-rtc");
+
+ hw = clk_hw_register_fixed_rate(NULL, "clk3686400", NULL, 0, 3686400);
+ if (IS_ERR(hw))
+ return PTR_ERR(hw);
+
+ clk_hw_register_clkdev(hw, "OSTIMER0", NULL);
+
+ hw = kzalloc(sizeof(*hw), GFP_KERNEL);
+ if (!hw)
+ return -ENOMEM;
+ hw->init = &clk_mpll_init_data;
+ ret = clk_hw_register(NULL, hw);
+ if (ret) {
+ kfree(hw);
+ return ret;
+ }
+
+ clk_hw_register_clkdev(hw, NULL, "sa11x0-fb");
+ clk_hw_register_clkdev(hw, NULL, "sa11x0-pcmcia");
+ clk_hw_register_clkdev(hw, NULL, "sa11x0-pcmcia.0");
+ clk_hw_register_clkdev(hw, NULL, "sa11x0-pcmcia.1");
+ clk_hw_register_clkdev(hw, NULL, "1800");
+
+ hw = clk_hw_register_mux(NULL, "tucr-mux", clk_tucr_parents,
+ ARRAY_SIZE(clk_tucr_parents), 0,
+ (void __iomem *)&TUCR, FShft(TUCR_TSEL),
+ FAlnMsk(TUCR_TSEL), 0, &tucr_lock);
+ clk_set_rate(hw->clk, 3686400);
+
+ hw = kzalloc(sizeof(*hw), GFP_KERNEL);
+ if (!hw)
+ return -ENOMEM;
+ hw->init = &clk_gpio27_init_data;
+ ret = clk_hw_register(NULL, hw);
+ if (ret) {
+ kfree(hw);
+ return ret;
+ }
+
+ clk_hw_register_clkdev(hw, NULL, "sa1111.0");
+
+ return 0;
+}
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
new file mode 100644
index 000000000..466d755d5
--- /dev/null
+++ b/arch/arm/mach-sa1100/collie.c
@@ -0,0 +1,429 @@
+/*
+ * linux/arch/arm/mach-sa1100/collie.c
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ *
+ * This file contains all Collie-specific tweaks.
+ *
+ * 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.
+ *
+ * ChangeLog:
+ * 2006 Pavel Machek <pavel@ucw.cz>
+ * 03-06-2004 John Lenz <lenz@cs.wisc.edu>
+ * 06-04-2002 Chris Larson <kergoth@digitalnemesis.net>
+ * 04-16-2001 Lineo Japan,Inc. ...
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/tty.h>
+#include <linux/delay.h>
+#include <linux/platform_data/sa11x0-serial.h>
+#include <linux/platform_device.h>
+#include <linux/mfd/ucb1x00.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/timer.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+#include <linux/gpio/machine.h>
+#include <linux/power/gpio-charger.h>
+
+#include <video/sa1100fb.h>
+
+#include <mach/hardware.h>
+#include <asm/mach-types.h>
+#include <asm/page.h>
+#include <asm/setup.h>
+#include <mach/collie.h>
+
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+
+#include <asm/hardware/scoop.h>
+#include <asm/mach/sharpsl_param.h>
+#include <asm/hardware/locomo.h>
+#include <linux/platform_data/mfd-mcp-sa11x0.h>
+#include <mach/irqs.h>
+
+#include "generic.h"
+
+static struct resource collie_scoop_resources[] = {
+ [0] = DEFINE_RES_MEM(0x40800000, SZ_4K),
+};
+
+static struct scoop_config collie_scoop_setup = {
+ .io_dir = COLLIE_SCOOP_IO_DIR,
+ .io_out = COLLIE_SCOOP_IO_OUT,
+ .gpio_base = COLLIE_SCOOP_GPIO_BASE,
+};
+
+struct platform_device colliescoop_device = {
+ .name = "sharp-scoop",
+ .id = -1,
+ .dev = {
+ .platform_data = &collie_scoop_setup,
+ },
+ .num_resources = ARRAY_SIZE(collie_scoop_resources),
+ .resource = collie_scoop_resources,
+};
+
+static struct scoop_pcmcia_dev collie_pcmcia_scoop[] = {
+ {
+ .dev = &colliescoop_device.dev,
+ .irq = COLLIE_IRQ_GPIO_CF_IRQ,
+ .cd_irq = COLLIE_IRQ_GPIO_CF_CD,
+ .cd_irq_str = "PCMCIA0 CD",
+ },
+};
+
+static struct scoop_pcmcia_config collie_pcmcia_config = {
+ .devs = &collie_pcmcia_scoop[0],
+ .num_devs = 1,
+};
+
+static struct ucb1x00_plat_data collie_ucb1x00_data = {
+ .gpio_base = COLLIE_TC35143_GPIO_BASE,
+};
+
+static struct mcp_plat_data collie_mcp_data = {
+ .mccr0 = MCCR0_ADM | MCCR0_ExtClk,
+ .sclk_rate = 9216000,
+ .codec_pdata = &collie_ucb1x00_data,
+};
+
+/* Battery management GPIOs */
+static struct gpiod_lookup_table collie_battery_gpiod_table = {
+ /* the MCP codec mcp0 has the ucb1x00 as attached device */
+ .dev_id = "ucb1x00",
+ .table = {
+ /* This is found on the main GPIO on the SA1100 */
+ GPIO_LOOKUP("gpio", COLLIE_GPIO_CO,
+ "main battery full", GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP("gpio", COLLIE_GPIO_MAIN_BAT_LOW,
+ "main battery low", GPIO_ACTIVE_HIGH),
+ /*
+ * This is GPIO 0 on the Scoop expander, which is registered
+ * from common/scoop.c with this gpio chip label.
+ */
+ GPIO_LOOKUP("sharp-scoop", 0,
+ "main charge on", GPIO_ACTIVE_HIGH),
+ { },
+ },
+};
+
+/*
+ * Collie AC IN
+ */
+static struct gpiod_lookup_table collie_power_gpiod_table = {
+ .dev_id = "gpio-charger",
+ .table = {
+ GPIO_LOOKUP("gpio", COLLIE_GPIO_AC_IN,
+ NULL, GPIO_ACTIVE_HIGH),
+ { },
+ },
+};
+
+static char *collie_ac_supplied_to[] = {
+ "main-battery",
+ "backup-battery",
+};
+
+static struct gpio_charger_platform_data collie_power_data = {
+ .name = "charger",
+ .type = POWER_SUPPLY_TYPE_MAINS,
+ .supplied_to = collie_ac_supplied_to,
+ .num_supplicants = ARRAY_SIZE(collie_ac_supplied_to),
+};
+
+static struct platform_device collie_power_device = {
+ .name = "gpio-charger",
+ .id = -1,
+ .dev.platform_data = &collie_power_data,
+};
+
+#ifdef CONFIG_SHARP_LOCOMO
+/*
+ * low-level UART features.
+ */
+struct platform_device collie_locomo_device;
+
+static void collie_uart_set_mctrl(struct uart_port *port, u_int mctrl)
+{
+ if (mctrl & TIOCM_RTS)
+ locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_RTS, 0);
+ else
+ locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_RTS, 1);
+
+ if (mctrl & TIOCM_DTR)
+ locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_DTR, 0);
+ else
+ locomo_gpio_write(&collie_locomo_device.dev, LOCOMO_GPIO_DTR, 1);
+}
+
+static u_int collie_uart_get_mctrl(struct uart_port *port)
+{
+ int ret = TIOCM_CD;
+ unsigned int r;
+
+ r = locomo_gpio_read_output(&collie_locomo_device.dev, LOCOMO_GPIO_CTS & LOCOMO_GPIO_DSR);
+ if (r == -ENODEV)
+ return ret;
+ if (r & LOCOMO_GPIO_CTS)
+ ret |= TIOCM_CTS;
+ if (r & LOCOMO_GPIO_DSR)
+ ret |= TIOCM_DSR;
+
+ return ret;
+}
+
+static struct sa1100_port_fns collie_port_fns __initdata = {
+ .set_mctrl = collie_uart_set_mctrl,
+ .get_mctrl = collie_uart_get_mctrl,
+};
+
+static int collie_uart_probe(struct locomo_dev *dev)
+{
+ return 0;
+}
+
+static struct locomo_driver collie_uart_driver = {
+ .drv = {
+ .name = "collie_uart",
+ },
+ .devid = LOCOMO_DEVID_UART,
+ .probe = collie_uart_probe,
+};
+
+static int __init collie_uart_init(void)
+{
+ return locomo_driver_register(&collie_uart_driver);
+}
+device_initcall(collie_uart_init);
+
+#endif
+
+
+static struct resource locomo_resources[] = {
+ [0] = DEFINE_RES_MEM(0x40000000, SZ_8K),
+ [1] = DEFINE_RES_IRQ(IRQ_GPIO25),
+};
+
+static struct locomo_platform_data locomo_info = {
+ .irq_base = IRQ_BOARD_START,
+};
+
+struct platform_device collie_locomo_device = {
+ .name = "locomo",
+ .id = 0,
+ .dev = {
+ .platform_data = &locomo_info,
+ },
+ .num_resources = ARRAY_SIZE(locomo_resources),
+ .resource = locomo_resources,
+};
+
+static struct gpio_keys_button collie_gpio_keys[] = {
+ {
+ .type = EV_PWR,
+ .code = KEY_RESERVED,
+ .gpio = COLLIE_GPIO_ON_KEY,
+ .desc = "On key",
+ .wakeup = 1,
+ .active_low = 1,
+ },
+ {
+ .type = EV_PWR,
+ .code = KEY_WAKEUP,
+ .gpio = COLLIE_GPIO_WAKEUP,
+ .desc = "Sync",
+ .wakeup = 1,
+ .active_low = 1,
+ },
+};
+
+static struct gpio_keys_platform_data collie_gpio_keys_data = {
+ .buttons = collie_gpio_keys,
+ .nbuttons = ARRAY_SIZE(collie_gpio_keys),
+};
+
+static struct platform_device collie_gpio_keys_device = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &collie_gpio_keys_data,
+ },
+};
+
+static struct platform_device *devices[] __initdata = {
+ &collie_locomo_device,
+ &colliescoop_device,
+ &collie_power_device,
+ &collie_gpio_keys_device,
+};
+
+static struct mtd_partition collie_partitions[] = {
+ {
+ .name = "bootloader",
+ .offset = 0,
+ .size = 0x000C0000,
+ .mask_flags = MTD_WRITEABLE
+ }, {
+ .name = "kernel",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0x00100000,
+ }, {
+ .name = "rootfs",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0x00e20000,
+ }, {
+ .name = "bootblock",
+ .offset = MTDPART_OFS_APPEND,
+ .size = 0x00020000,
+ .mask_flags = MTD_WRITEABLE
+ }
+};
+
+static int collie_flash_init(void)
+{
+ int rc = gpio_request(COLLIE_GPIO_VPEN, "flash Vpp enable");
+ if (rc)
+ return rc;
+
+ rc = gpio_direction_output(COLLIE_GPIO_VPEN, 1);
+ if (rc)
+ gpio_free(COLLIE_GPIO_VPEN);
+
+ return rc;
+}
+
+static void collie_set_vpp(int vpp)
+{
+ gpio_set_value(COLLIE_GPIO_VPEN, vpp);
+}
+
+static void collie_flash_exit(void)
+{
+ gpio_free(COLLIE_GPIO_VPEN);
+}
+
+static struct flash_platform_data collie_flash_data = {
+ .map_name = "cfi_probe",
+ .init = collie_flash_init,
+ .set_vpp = collie_set_vpp,
+ .exit = collie_flash_exit,
+ .parts = collie_partitions,
+ .nr_parts = ARRAY_SIZE(collie_partitions),
+};
+
+static struct resource collie_flash_resources[] = {
+ DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M),
+};
+
+static struct sa1100fb_mach_info collie_lcd_info = {
+ .pixclock = 171521, .bpp = 16,
+ .xres = 320, .yres = 240,
+
+ .hsync_len = 5, .vsync_len = 1,
+ .left_margin = 11, .upper_margin = 2,
+ .right_margin = 30, .lower_margin = 0,
+
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+
+ .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
+ .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
+
+#ifdef CONFIG_BACKLIGHT_LOCOMO
+ .lcd_power = locomolcd_power
+#endif
+};
+
+static void __init collie_init(void)
+{
+ int ret = 0;
+
+ /* cpu initialize */
+ GAFR = GPIO_SSP_TXD | GPIO_SSP_SCLK | GPIO_SSP_SFRM | GPIO_SSP_CLK |
+ GPIO_MCP_CLK | GPIO_32_768kHz;
+
+ GPDR = GPIO_LDD8 | GPIO_LDD9 | GPIO_LDD10 | GPIO_LDD11 | GPIO_LDD12 |
+ GPIO_LDD13 | GPIO_LDD14 | GPIO_LDD15 | GPIO_SSP_TXD |
+ GPIO_SSP_SCLK | GPIO_SSP_SFRM | GPIO_SDLC_SCLK |
+ _COLLIE_GPIO_UCB1x00_RESET | _COLLIE_GPIO_nMIC_ON |
+ _COLLIE_GPIO_nREMOCON_ON | GPIO_32_768kHz;
+
+ PPDR = PPC_LDD0 | PPC_LDD1 | PPC_LDD2 | PPC_LDD3 | PPC_LDD4 | PPC_LDD5 |
+ PPC_LDD6 | PPC_LDD7 | PPC_L_PCLK | PPC_L_LCLK | PPC_L_FCLK | PPC_L_BIAS |
+ PPC_TXD1 | PPC_TXD2 | PPC_TXD3 | PPC_TXD4 | PPC_SCLK | PPC_SFRM;
+
+ PWER = 0;
+
+ PGSR = _COLLIE_GPIO_nREMOCON_ON;
+
+ PSDR = PPC_RXD1 | PPC_RXD2 | PPC_RXD3 | PPC_RXD4;
+
+ PCFR = PCFR_OPDE;
+
+ GPSR |= _COLLIE_GPIO_UCB1x00_RESET;
+
+ sa11x0_ppc_configure_mcp();
+
+
+ platform_scoop_config = &collie_pcmcia_config;
+
+ gpiod_add_lookup_table(&collie_power_gpiod_table);
+ gpiod_add_lookup_table(&collie_battery_gpiod_table);
+
+ ret = platform_add_devices(devices, ARRAY_SIZE(devices));
+ if (ret) {
+ printk(KERN_WARNING "collie: Unable to register LoCoMo device\n");
+ }
+
+ sa11x0_register_lcd(&collie_lcd_info);
+ sa11x0_register_mtd(&collie_flash_data, collie_flash_resources,
+ ARRAY_SIZE(collie_flash_resources));
+ sa11x0_register_mcp(&collie_mcp_data);
+
+ sharpsl_save_param();
+}
+
+static struct map_desc collie_io_desc[] __initdata = {
+ { /* 32M main flash (cs0) */
+ .virtual = 0xe8000000,
+ .pfn = __phys_to_pfn(0x00000000),
+ .length = 0x02000000,
+ .type = MT_DEVICE
+ }, { /* 32M boot flash (cs1) */
+ .virtual = 0xea000000,
+ .pfn = __phys_to_pfn(0x08000000),
+ .length = 0x02000000,
+ .type = MT_DEVICE
+ }
+};
+
+static void __init collie_map_io(void)
+{
+ sa1100_map_io();
+ iotable_init(collie_io_desc, ARRAY_SIZE(collie_io_desc));
+
+#ifdef CONFIG_SHARP_LOCOMO
+ sa1100_register_uart_fns(&collie_port_fns);
+#endif
+ sa1100_register_uart(0, 3);
+ sa1100_register_uart(1, 1);
+}
+
+MACHINE_START(COLLIE, "Sharp-Collie")
+ .map_io = collie_map_io,
+ .nr_irqs = SA1100_NR_IRQS,
+ .init_irq = sa1100_init_irq,
+ .init_time = sa1100_timer_init,
+ .init_machine = collie_init,
+ .init_late = sa11x0_init_late,
+ .restart = sa11x0_restart,
+MACHINE_END
diff --git a/arch/arm/mach-sa1100/generic.c b/arch/arm/mach-sa1100/generic.c
new file mode 100644
index 000000000..0c586047d
--- /dev/null
+++ b/arch/arm/mach-sa1100/generic.c
@@ -0,0 +1,470 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * linux/arch/arm/mach-sa1100/generic.c
+ *
+ * Author: Nicolas Pitre
+ *
+ * Code common to all SA11x0 machines.
+ */
+#include <linux/gpio.h>
+#include <linux/gpio/machine.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <linux/pm.h>
+#include <linux/cpufreq.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/reboot.h>
+#include <linux/regulator/fixed.h>
+#include <linux/regulator/machine.h>
+#include <linux/irqchip/irq-sa11x0.h>
+
+#include <video/sa1100fb.h>
+
+#include <soc/sa1100/pwer.h>
+
+#include <asm/div64.h>
+#include <asm/mach/map.h>
+#include <asm/mach/flash.h>
+#include <asm/irq.h>
+#include <asm/system_misc.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <mach/reset.h>
+
+#include "generic.h"
+#include <clocksource/pxa.h>
+
+#define NR_FREQS 16
+
+/*
+ * This table is setup for a 3.6864MHz Crystal.
+ */
+struct cpufreq_frequency_table sa11x0_freq_table[NR_FREQS+1] = {
+ { .frequency = 59000, /* 59.0 MHz */},
+ { .frequency = 73700, /* 73.7 MHz */},
+ { .frequency = 88500, /* 88.5 MHz */},
+ { .frequency = 103200, /* 103.2 MHz */},
+ { .frequency = 118000, /* 118.0 MHz */},
+ { .frequency = 132700, /* 132.7 MHz */},
+ { .frequency = 147500, /* 147.5 MHz */},
+ { .frequency = 162200, /* 162.2 MHz */},
+ { .frequency = 176900, /* 176.9 MHz */},
+ { .frequency = 191700, /* 191.7 MHz */},
+ { .frequency = 206400, /* 206.4 MHz */},
+ { .frequency = 221200, /* 221.2 MHz */},
+ { .frequency = 235900, /* 235.9 MHz */},
+ { .frequency = 250700, /* 250.7 MHz */},
+ { .frequency = 265400, /* 265.4 MHz */},
+ { .frequency = 280200, /* 280.2 MHz */},
+ { .frequency = CPUFREQ_TABLE_END, },
+};
+
+unsigned int sa11x0_getspeed(unsigned int cpu)
+{
+ if (cpu)
+ return 0;
+ return sa11x0_freq_table[PPCR & 0xf].frequency;
+}
+
+/*
+ * Default power-off for SA1100
+ */
+static void sa1100_power_off(void)
+{
+ mdelay(100);
+ local_irq_disable();
+ /* disable internal oscillator, float CS lines */
+ PCFR = (PCFR_OPDE | PCFR_FP | PCFR_FS);
+ /* enable wake-up on GPIO0 (Assabet...) */
+ PWER = GFER = GRER = 1;
+ /*
+ * set scratchpad to zero, just in case it is used as a
+ * restart address by the bootloader.
+ */
+ PSPR = 0;
+ /* enter sleep mode */
+ PMCR = PMCR_SF;
+}
+
+void sa11x0_restart(enum reboot_mode mode, const char *cmd)
+{
+ clear_reset_status(RESET_STATUS_ALL);
+
+ if (mode == REBOOT_SOFT) {
+ /* Jump into ROM at address 0 */
+ soft_restart(0);
+ } else {
+ /* Use on-chip reset capability */
+ RSRR = RSRR_SWR;
+ }
+}
+
+static void sa11x0_register_device(struct platform_device *dev, void *data)
+{
+ int err;
+ dev->dev.platform_data = data;
+ err = platform_device_register(dev);
+ if (err)
+ printk(KERN_ERR "Unable to register device %s: %d\n",
+ dev->name, err);
+}
+
+
+static struct resource sa11x0udc_resources[] = {
+ [0] = DEFINE_RES_MEM(__PREG(Ser0UDCCR), SZ_64K),
+ [1] = DEFINE_RES_IRQ(IRQ_Ser0UDC),
+};
+
+static u64 sa11x0udc_dma_mask = 0xffffffffUL;
+
+static struct platform_device sa11x0udc_device = {
+ .name = "sa11x0-udc",
+ .id = -1,
+ .dev = {
+ .dma_mask = &sa11x0udc_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(sa11x0udc_resources),
+ .resource = sa11x0udc_resources,
+};
+
+static struct resource sa11x0uart1_resources[] = {
+ [0] = DEFINE_RES_MEM(__PREG(Ser1UTCR0), SZ_64K),
+ [1] = DEFINE_RES_IRQ(IRQ_Ser1UART),
+};
+
+static struct platform_device sa11x0uart1_device = {
+ .name = "sa11x0-uart",
+ .id = 1,
+ .num_resources = ARRAY_SIZE(sa11x0uart1_resources),
+ .resource = sa11x0uart1_resources,
+};
+
+static struct resource sa11x0uart3_resources[] = {
+ [0] = DEFINE_RES_MEM(__PREG(Ser3UTCR0), SZ_64K),
+ [1] = DEFINE_RES_IRQ(IRQ_Ser3UART),
+};
+
+static struct platform_device sa11x0uart3_device = {
+ .name = "sa11x0-uart",
+ .id = 3,
+ .num_resources = ARRAY_SIZE(sa11x0uart3_resources),
+ .resource = sa11x0uart3_resources,
+};
+
+static struct resource sa11x0mcp_resources[] = {
+ [0] = DEFINE_RES_MEM(__PREG(Ser4MCCR0), SZ_64K),
+ [1] = DEFINE_RES_MEM(__PREG(Ser4MCCR1), 4),
+ [2] = DEFINE_RES_IRQ(IRQ_Ser4MCP),
+};
+
+static u64 sa11x0mcp_dma_mask = 0xffffffffUL;
+
+static struct platform_device sa11x0mcp_device = {
+ .name = "sa11x0-mcp",
+ .id = -1,
+ .dev = {
+ .dma_mask = &sa11x0mcp_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(sa11x0mcp_resources),
+ .resource = sa11x0mcp_resources,
+};
+
+void __init sa11x0_ppc_configure_mcp(void)
+{
+ /* Setup the PPC unit for the MCP */
+ PPDR &= ~PPC_RXD4;
+ PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
+ PSDR |= PPC_RXD4;
+ PSDR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
+ PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
+}
+
+void sa11x0_register_mcp(struct mcp_plat_data *data)
+{
+ sa11x0_register_device(&sa11x0mcp_device, data);
+}
+
+static struct resource sa11x0ssp_resources[] = {
+ [0] = DEFINE_RES_MEM(0x80070000, SZ_64K),
+ [1] = DEFINE_RES_IRQ(IRQ_Ser4SSP),
+};
+
+static u64 sa11x0ssp_dma_mask = 0xffffffffUL;
+
+static struct platform_device sa11x0ssp_device = {
+ .name = "sa11x0-ssp",
+ .id = -1,
+ .dev = {
+ .dma_mask = &sa11x0ssp_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(sa11x0ssp_resources),
+ .resource = sa11x0ssp_resources,
+};
+
+static struct resource sa11x0fb_resources[] = {
+ [0] = DEFINE_RES_MEM(0xb0100000, SZ_64K),
+ [1] = DEFINE_RES_IRQ(IRQ_LCD),
+};
+
+static struct platform_device sa11x0fb_device = {
+ .name = "sa11x0-fb",
+ .id = -1,
+ .dev = {
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(sa11x0fb_resources),
+ .resource = sa11x0fb_resources,
+};
+
+void sa11x0_register_lcd(struct sa1100fb_mach_info *inf)
+{
+ sa11x0_register_device(&sa11x0fb_device, inf);
+}
+
+void sa11x0_register_pcmcia(int socket, struct gpiod_lookup_table *table)
+{
+ if (table)
+ gpiod_add_lookup_table(table);
+ platform_device_register_simple("sa11x0-pcmcia", socket, NULL, 0);
+}
+
+static struct platform_device sa11x0mtd_device = {
+ .name = "sa1100-mtd",
+ .id = -1,
+};
+
+void sa11x0_register_mtd(struct flash_platform_data *flash,
+ struct resource *res, int nr)
+{
+ flash->name = "sa1100";
+ sa11x0mtd_device.resource = res;
+ sa11x0mtd_device.num_resources = nr;
+ sa11x0_register_device(&sa11x0mtd_device, flash);
+}
+
+static struct resource sa1100_rtc_resources[] = {
+ DEFINE_RES_MEM(0x90010000, 0x40),
+ DEFINE_RES_IRQ_NAMED(IRQ_RTC1Hz, "rtc 1Hz"),
+ DEFINE_RES_IRQ_NAMED(IRQ_RTCAlrm, "rtc alarm"),
+};
+
+static struct platform_device sa11x0rtc_device = {
+ .name = "sa1100-rtc",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(sa1100_rtc_resources),
+ .resource = sa1100_rtc_resources,
+};
+
+static struct resource sa11x0dma_resources[] = {
+ DEFINE_RES_MEM(DMA_PHYS, DMA_SIZE),
+ DEFINE_RES_IRQ(IRQ_DMA0),
+ DEFINE_RES_IRQ(IRQ_DMA1),
+ DEFINE_RES_IRQ(IRQ_DMA2),
+ DEFINE_RES_IRQ(IRQ_DMA3),
+ DEFINE_RES_IRQ(IRQ_DMA4),
+ DEFINE_RES_IRQ(IRQ_DMA5),
+};
+
+static u64 sa11x0dma_dma_mask = DMA_BIT_MASK(32);
+
+static struct platform_device sa11x0dma_device = {
+ .name = "sa11x0-dma",
+ .id = -1,
+ .dev = {
+ .dma_mask = &sa11x0dma_dma_mask,
+ .coherent_dma_mask = 0xffffffff,
+ },
+ .num_resources = ARRAY_SIZE(sa11x0dma_resources),
+ .resource = sa11x0dma_resources,
+};
+
+static struct platform_device *sa11x0_devices[] __initdata = {
+ &sa11x0udc_device,
+ &sa11x0uart1_device,
+ &sa11x0uart3_device,
+ &sa11x0ssp_device,
+ &sa11x0rtc_device,
+ &sa11x0dma_device,
+};
+
+static int __init sa1100_init(void)
+{
+ struct resource wdt_res = DEFINE_RES_MEM(0x90000000, 0x20);
+ pm_power_off = sa1100_power_off;
+
+ regulator_has_full_constraints();
+
+ platform_device_register_simple("sa1100_wdt", -1, &wdt_res, 1);
+
+ return platform_add_devices(sa11x0_devices, ARRAY_SIZE(sa11x0_devices));
+}
+
+arch_initcall(sa1100_init);
+
+void __init sa11x0_init_late(void)
+{
+ sa11x0_pm_init();
+}
+
+int __init sa11x0_register_fixed_regulator(int n,
+ struct fixed_voltage_config *cfg,
+ struct regulator_consumer_supply *supplies, unsigned num_supplies,
+ bool uses_gpio)
+{
+ struct regulator_init_data *id;
+
+ cfg->init_data = id = kzalloc(sizeof(*cfg->init_data), GFP_KERNEL);
+ if (!cfg->init_data)
+ return -ENOMEM;
+
+ if (!uses_gpio)
+ id->constraints.always_on = 1;
+ id->constraints.name = cfg->supply_name;
+ id->constraints.min_uV = cfg->microvolts;
+ id->constraints.max_uV = cfg->microvolts;
+ id->constraints.valid_modes_mask = REGULATOR_MODE_NORMAL;
+ id->constraints.valid_ops_mask = REGULATOR_CHANGE_STATUS;
+ id->consumer_supplies = supplies;
+ id->num_consumer_supplies = num_supplies;
+
+ platform_device_register_resndata(NULL, "reg-fixed-voltage", n,
+ NULL, 0, cfg, sizeof(*cfg));
+ return 0;
+}
+
+/*
+ * Common I/O mapping:
+ *
+ * Typically, static virtual address mappings are as follow:
+ *
+ * 0xf0000000-0xf3ffffff: miscellaneous stuff (CPLDs, etc.)
+ * 0xf4000000-0xf4ffffff: SA-1111
+ * 0xf5000000-0xf5ffffff: reserved (used by cache flushing area)
+ * 0xf6000000-0xfffeffff: reserved (internal SA1100 IO defined above)
+ * 0xffff0000-0xffff0fff: SA1100 exception vectors
+ * 0xffff2000-0xffff2fff: Minicache copy_user_page area
+ *
+ * Below 0xe8000000 is reserved for vm allocation.
+ *
+ * The machine specific code must provide the extra mapping beside the
+ * default mapping provided here.
+ */
+
+static struct map_desc standard_io_desc[] __initdata = {
+ { /* PCM */
+ .virtual = 0xf8000000,
+ .pfn = __phys_to_pfn(0x80000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* SCM */
+ .virtual = 0xfa000000,
+ .pfn = __phys_to_pfn(0x90000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* MER */
+ .virtual = 0xfc000000,
+ .pfn = __phys_to_pfn(0xa0000000),
+ .length = 0x00100000,
+ .type = MT_DEVICE
+ }, { /* LCD + DMA */
+ .virtual = 0xfe000000,
+ .pfn = __phys_to_pfn(0xb0000000),
+ .length = 0x00200000,
+ .type = MT_DEVICE
+ },
+};
+
+void __init sa1100_map_io(void)
+{
+ iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
+}
+
+void __init sa1100_timer_init(void)
+{
+ pxa_timer_nodt_init(IRQ_OST0, io_p2v(0x90000000));
+}
+
+static struct resource irq_resource =
+ DEFINE_RES_MEM_NAMED(0x90050000, SZ_64K, "irqs");
+
+void __init sa1100_init_irq(void)
+{
+ request_resource(&iomem_resource, &irq_resource);
+
+ sa11x0_init_irq_nodt(IRQ_GPIO0_SC, irq_resource.start);
+
+ sa1100_init_gpio();
+ sa11xx_clk_init();
+}
+
+/*
+ * Disable the memory bus request/grant signals on the SA1110 to
+ * ensure that we don't receive spurious memory requests. We set
+ * the MBGNT signal false to ensure the SA1111 doesn't own the
+ * SDRAM bus.
+ */
+void sa1110_mb_disable(void)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ PGSR &= ~GPIO_MBGNT;
+ GPCR = GPIO_MBGNT;
+ GPDR = (GPDR & ~GPIO_MBREQ) | GPIO_MBGNT;
+
+ GAFR &= ~(GPIO_MBGNT | GPIO_MBREQ);
+
+ local_irq_restore(flags);
+}
+
+/*
+ * If the system is going to use the SA-1111 DMA engines, set up
+ * the memory bus request/grant pins.
+ */
+void sa1110_mb_enable(void)
+{
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ PGSR &= ~GPIO_MBGNT;
+ GPCR = GPIO_MBGNT;
+ GPDR = (GPDR & ~GPIO_MBREQ) | GPIO_MBGNT;
+
+ GAFR |= (GPIO_MBGNT | GPIO_MBREQ);
+ TUCR |= TUCR_MR;
+
+ local_irq_restore(flags);
+}
+
+int sa11x0_gpio_set_wake(unsigned int gpio, unsigned int on)
+{
+ if (on)
+ PWER |= BIT(gpio);
+ else
+ PWER &= ~BIT(gpio);
+
+ return 0;
+}
+
+int sa11x0_sc_set_wake(unsigned int irq, unsigned int on)
+{
+ if (BIT(irq) != IC_RTCAlrm)
+ return -EINVAL;
+
+ if (on)
+ PWER |= PWER_RTC;
+ else
+ PWER &= ~PWER_RTC;
+
+ return 0;
+}
diff --git a/arch/arm/mach-sa1100/generic.h b/arch/arm/mach-sa1100/generic.h
new file mode 100644
index 000000000..5fe0d4fc0
--- /dev/null
+++ b/arch/arm/mach-sa1100/generic.h
@@ -0,0 +1,55 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * linux/arch/arm/mach-sa1100/generic.h
+ *
+ * Author: Nicolas Pitre
+ */
+#include <linux/cpufreq.h>
+#include <linux/reboot.h>
+
+extern void sa1100_timer_init(void);
+extern void __init sa1100_map_io(void);
+extern void __init sa1100_init_irq(void);
+extern void __init sa1100_init_gpio(void);
+extern void sa11x0_restart(enum reboot_mode, const char *);
+extern void sa11x0_init_late(void);
+
+#define SET_BANK(__nr,__start,__size) \
+ mi->bank[__nr].start = (__start), \
+ mi->bank[__nr].size = (__size)
+
+extern void sa1110_mb_enable(void);
+extern void sa1110_mb_disable(void);
+
+extern struct cpufreq_frequency_table sa11x0_freq_table[];
+extern unsigned int sa11x0_getspeed(unsigned int cpu);
+
+struct flash_platform_data;
+struct resource;
+
+void sa11x0_register_mtd(struct flash_platform_data *flash,
+ struct resource *res, int nr);
+
+struct mcp_plat_data;
+void sa11x0_ppc_configure_mcp(void);
+void sa11x0_register_mcp(struct mcp_plat_data *data);
+
+struct sa1100fb_mach_info;
+void sa11x0_register_lcd(struct sa1100fb_mach_info *inf);
+
+#ifdef CONFIG_PM
+int sa11x0_pm_init(void);
+#else
+static inline int sa11x0_pm_init(void) { return 0; }
+#endif
+
+int sa11xx_clk_init(void);
+
+struct gpiod_lookup_table;
+void sa11x0_register_pcmcia(int socket, struct gpiod_lookup_table *);
+
+struct fixed_voltage_config;
+struct regulator_consumer_supply;
+int sa11x0_register_fixed_regulator(int n, struct fixed_voltage_config *cfg,
+ struct regulator_consumer_supply *supplies, unsigned num_supplies,
+ bool uses_gpio);
diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c
new file mode 100644
index 000000000..5e25dfa75
--- /dev/null
+++ b/arch/arm/mach-sa1100/h3600.c
@@ -0,0 +1,109 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Support for Compaq iPAQ H3600 handheld computer
+ *
+ * Copyright (c) 2000,1 Compaq Computer Corporation. (Author: Jamey Hicks)
+ * Copyright (c) 2009 Dmitry Artamonow <mad_soft@inbox.ru>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/gpio.h>
+
+#include <video/sa1100fb.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/arch.h>
+
+#include <mach/h3xxx.h>
+#include <mach/irqs.h>
+
+#include "generic.h"
+
+/*
+ * helper for sa1100fb
+ */
+static struct gpio h3600_lcd_gpio[] = {
+ { H3XXX_EGPIO_LCD_ON, GPIOF_OUT_INIT_LOW, "LCD power" },
+ { H3600_EGPIO_LCD_PCI, GPIOF_OUT_INIT_LOW, "LCD control" },
+ { H3600_EGPIO_LCD_5V_ON, GPIOF_OUT_INIT_LOW, "LCD 5v" },
+ { H3600_EGPIO_LVDD_ON, GPIOF_OUT_INIT_LOW, "LCD 9v/-6.5v" },
+};
+
+static bool h3600_lcd_request(void)
+{
+ static bool h3600_lcd_ok;
+ int rc;
+
+ if (h3600_lcd_ok)
+ return true;
+
+ rc = gpio_request_array(h3600_lcd_gpio, ARRAY_SIZE(h3600_lcd_gpio));
+ if (rc)
+ pr_err("%s: can't request GPIOs\n", __func__);
+ else
+ h3600_lcd_ok = true;
+
+ return h3600_lcd_ok;
+}
+
+static void h3600_lcd_power(int enable)
+{
+ if (!h3600_lcd_request())
+ return;
+
+ gpio_direction_output(H3XXX_EGPIO_LCD_ON, enable);
+ gpio_direction_output(H3600_EGPIO_LCD_PCI, enable);
+ gpio_direction_output(H3600_EGPIO_LCD_5V_ON, enable);
+ gpio_direction_output(H3600_EGPIO_LVDD_ON, enable);
+}
+
+static const struct sa1100fb_rgb h3600_rgb_16 = {
+ .red = { .offset = 12, .length = 4, },
+ .green = { .offset = 7, .length = 4, },
+ .blue = { .offset = 1, .length = 4, },
+ .transp = { .offset = 0, .length = 0, },
+};
+
+static struct sa1100fb_mach_info h3600_lcd_info = {
+ .pixclock = 174757, .bpp = 16,
+ .xres = 320, .yres = 240,
+
+ .hsync_len = 3, .vsync_len = 3,
+ .left_margin = 12, .upper_margin = 10,
+ .right_margin = 17, .lower_margin = 1,
+
+ .cmap_static = 1,
+
+ .lccr0 = LCCR0_Color | LCCR0_Sngl | LCCR0_Act,
+ .lccr3 = LCCR3_OutEnH | LCCR3_PixRsEdg | LCCR3_ACBsDiv(2),
+
+ .rgb[RGB_16] = &h3600_rgb_16,
+
+ .lcd_power = h3600_lcd_power,
+};
+
+
+static void __init h3600_map_io(void)
+{
+ h3xxx_map_io();
+}
+
+static void __init h3600_mach_init(void)
+{
+ h3xxx_mach_init();
+
+ sa11x0_register_lcd(&h3600_lcd_info);
+}
+
+MACHINE_START(H3600, "Compaq iPAQ H3600")
+ .atag_offset = 0x100,
+ .map_io = h3600_map_io,
+ .nr_irqs = SA1100_NR_IRQS,
+ .init_irq = sa1100_init_irq,
+ .init_time = sa1100_timer_init,
+ .init_machine = h3600_mach_init,
+ .init_late = sa11x0_init_late,
+ .restart = sa11x0_restart,
+MACHINE_END
+
diff --git a/arch/arm/mach-sa1100/h3xxx.c b/arch/arm/mach-sa1100/h3xxx.c
new file mode 100644
index 000000000..d685f03f5
--- /dev/null
+++ b/arch/arm/mach-sa1100/h3xxx.c
@@ -0,0 +1,288 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Support for Compaq iPAQ H3100 and H3600 handheld computers (common code)
+ *
+ * Copyright (c) 2000,1 Compaq Computer Corporation. (Author: Jamey Hicks)
+ * Copyright (c) 2009 Dmitry Artamonow <mad_soft@inbox.ru>
+ */
+
+#include <linux/kernel.h>
+#include <linux/gpio/machine.h>
+#include <linux/gpio.h>
+#include <linux/gpio_keys.h>
+#include <linux/input.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/platform_data/gpio-htc-egpio.h>
+#include <linux/platform_data/sa11x0-serial.h>
+#include <linux/platform_device.h>
+#include <linux/serial_core.h>
+
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+
+#include <mach/h3xxx.h>
+#include <mach/irqs.h>
+
+#include "generic.h"
+
+/*
+ * H3xxx flash support
+ */
+static struct mtd_partition h3xxx_partitions[] = {
+ {
+ .name = "H3XXX boot firmware",
+ .size = 0x00040000,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ }, {
+ .name = "H3XXX rootfs",
+ .size = MTDPART_SIZ_FULL,
+ .offset = 0x00040000,
+ }
+};
+
+static void h3xxx_set_vpp(int vpp)
+{
+ gpio_set_value(H3XXX_EGPIO_VPP_ON, vpp);
+}
+
+static int h3xxx_flash_init(void)
+{
+ int err = gpio_request(H3XXX_EGPIO_VPP_ON, "Flash Vpp");
+ if (err) {
+ pr_err("%s: can't request H3XXX_EGPIO_VPP_ON\n", __func__);
+ return err;
+ }
+
+ err = gpio_direction_output(H3XXX_EGPIO_VPP_ON, 0);
+ if (err)
+ gpio_free(H3XXX_EGPIO_VPP_ON);
+
+ return err;
+}
+
+static void h3xxx_flash_exit(void)
+{
+ gpio_free(H3XXX_EGPIO_VPP_ON);
+}
+
+static struct flash_platform_data h3xxx_flash_data = {
+ .map_name = "cfi_probe",
+ .set_vpp = h3xxx_set_vpp,
+ .init = h3xxx_flash_init,
+ .exit = h3xxx_flash_exit,
+ .parts = h3xxx_partitions,
+ .nr_parts = ARRAY_SIZE(h3xxx_partitions),
+};
+
+static struct resource h3xxx_flash_resource =
+ DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M);
+
+
+/*
+ * H3xxx uart support
+ */
+static void h3xxx_uart_pm(struct uart_port *port, u_int state, u_int oldstate)
+{
+ if (port->mapbase == _Ser3UTCR0) {
+ if (!gpio_request(H3XXX_EGPIO_RS232_ON, "RS232 transceiver")) {
+ gpio_direction_output(H3XXX_EGPIO_RS232_ON, !state);
+ gpio_free(H3XXX_EGPIO_RS232_ON);
+ } else {
+ pr_err("%s: can't request H3XXX_EGPIO_RS232_ON\n",
+ __func__);
+ }
+ }
+}
+
+/*
+ * Enable/Disable wake up events for this serial port.
+ * Obviously, we only support this on the normal COM port.
+ */
+static int h3xxx_uart_set_wake(struct uart_port *port, u_int enable)
+{
+ int err = -EINVAL;
+
+ if (port->mapbase == _Ser3UTCR0) {
+ if (enable)
+ PWER |= PWER_GPIO23 | PWER_GPIO25; /* DCD and CTS */
+ else
+ PWER &= ~(PWER_GPIO23 | PWER_GPIO25); /* DCD and CTS */
+ err = 0;
+ }
+ return err;
+}
+
+static struct sa1100_port_fns h3xxx_port_fns __initdata = {
+ .pm = h3xxx_uart_pm,
+ .set_wake = h3xxx_uart_set_wake,
+};
+
+static struct gpiod_lookup_table h3xxx_uart3_gpio_table = {
+ .dev_id = "sa11x0-uart.3",
+ .table = {
+ GPIO_LOOKUP("gpio", H3XXX_GPIO_COM_DCD, "dcd", GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP("gpio", H3XXX_GPIO_COM_CTS, "cts", GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP("gpio", H3XXX_GPIO_COM_RTS, "rts", GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
+/*
+ * EGPIO
+ */
+
+static struct resource egpio_resources[] = {
+ [0] = DEFINE_RES_MEM(H3600_EGPIO_PHYS, 0x4),
+};
+
+static struct htc_egpio_chip egpio_chips[] = {
+ [0] = {
+ .reg_start = 0,
+ .gpio_base = H3XXX_EGPIO_BASE,
+ .num_gpios = 16,
+ .direction = HTC_EGPIO_OUTPUT,
+ .initial_values = 0x0080, /* H3XXX_EGPIO_RS232_ON */
+ },
+};
+
+static struct htc_egpio_platform_data egpio_info = {
+ .reg_width = 16,
+ .bus_width = 16,
+ .chip = egpio_chips,
+ .num_chips = ARRAY_SIZE(egpio_chips),
+};
+
+static struct platform_device h3xxx_egpio = {
+ .name = "htc-egpio",
+ .id = -1,
+ .resource = egpio_resources,
+ .num_resources = ARRAY_SIZE(egpio_resources),
+ .dev = {
+ .platform_data = &egpio_info,
+ },
+};
+
+/*
+ * GPIO keys
+ */
+
+static struct gpio_keys_button h3xxx_button_table[] = {
+ {
+ .code = KEY_POWER,
+ .gpio = H3XXX_GPIO_PWR_BUTTON,
+ .desc = "Power Button",
+ .active_low = 1,
+ .type = EV_KEY,
+ .wakeup = 1,
+ }, {
+ .code = KEY_ENTER,
+ .gpio = H3XXX_GPIO_ACTION_BUTTON,
+ .active_low = 1,
+ .desc = "Action button",
+ .type = EV_KEY,
+ .wakeup = 0,
+ },
+};
+
+static struct gpio_keys_platform_data h3xxx_keys_data = {
+ .buttons = h3xxx_button_table,
+ .nbuttons = ARRAY_SIZE(h3xxx_button_table),
+};
+
+static struct platform_device h3xxx_keys = {
+ .name = "gpio-keys",
+ .id = -1,
+ .dev = {
+ .platform_data = &h3xxx_keys_data,
+ },
+};
+
+static struct resource h3xxx_micro_resources[] = {
+ DEFINE_RES_MEM(0x80010000, SZ_4K),
+ DEFINE_RES_MEM(0x80020000, SZ_4K),
+ DEFINE_RES_IRQ(IRQ_Ser1UART),
+};
+
+struct platform_device h3xxx_micro_asic = {
+ .name = "ipaq-h3xxx-micro",
+ .id = -1,
+ .resource = h3xxx_micro_resources,
+ .num_resources = ARRAY_SIZE(h3xxx_micro_resources),
+};
+
+static struct platform_device *h3xxx_devices[] = {
+ &h3xxx_egpio,
+ &h3xxx_keys,
+ &h3xxx_micro_asic,
+};
+
+static struct gpiod_lookup_table h3xxx_pcmcia_gpio_table = {
+ .dev_id = "sa11x0-pcmcia",
+ .table = {
+ GPIO_LOOKUP("gpio", H3XXX_GPIO_PCMCIA_CD0,
+ "pcmcia0-detect", GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP("gpio", H3XXX_GPIO_PCMCIA_IRQ0,
+ "pcmcia0-ready", GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP("gpio", H3XXX_GPIO_PCMCIA_CD1,
+ "pcmcia1-detect", GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP("gpio", H3XXX_GPIO_PCMCIA_IRQ1,
+ "pcmcia1-ready", GPIO_ACTIVE_HIGH),
+ { },
+ },
+};
+
+void __init h3xxx_mach_init(void)
+{
+ gpiod_add_lookup_table(&h3xxx_pcmcia_gpio_table);
+ gpiod_add_lookup_table(&h3xxx_uart3_gpio_table);
+ sa1100_register_uart_fns(&h3xxx_port_fns);
+ sa11x0_register_mtd(&h3xxx_flash_data, &h3xxx_flash_resource, 1);
+ platform_add_devices(h3xxx_devices, ARRAY_SIZE(h3xxx_devices));
+}
+
+static struct map_desc h3600_io_desc[] __initdata = {
+ { /* static memory bank 2 CS#2 */
+ .virtual = H3600_BANK_2_VIRT,
+ .pfn = __phys_to_pfn(SA1100_CS2_PHYS),
+ .length = 0x02800000,
+ .type = MT_DEVICE
+ }, { /* static memory bank 4 CS#4 */
+ .virtual = H3600_BANK_4_VIRT,
+ .pfn = __phys_to_pfn(SA1100_CS4_PHYS),
+ .length = 0x00800000,
+ .type = MT_DEVICE
+ }, { /* EGPIO 0 CS#5 */
+ .virtual = H3600_EGPIO_VIRT,
+ .pfn = __phys_to_pfn(H3600_EGPIO_PHYS),
+ .length = 0x01000000,
+ .type = MT_DEVICE
+ }
+};
+
+/*
+ * Common map_io initialization
+ */
+
+void __init h3xxx_map_io(void)
+{
+ sa1100_map_io();
+ iotable_init(h3600_io_desc, ARRAY_SIZE(h3600_io_desc));
+
+ sa1100_register_uart(0, 3); /* Common serial port */
+// sa1100_register_uart(1, 1); /* Microcontroller on 3100/3600 */
+
+ /* Ensure those pins are outputs and driving low */
+ PPDR |= PPC_TXD4 | PPC_SCLK | PPC_SFRM;
+ PPSR &= ~(PPC_TXD4 | PPC_SCLK | PPC_SFRM);
+
+ /* Configure suspend conditions */
+ PGSR = 0;
+ PCFR = PCFR_OPDE;
+ PSDR = 0;
+
+ GPCR = 0x0fffffff; /* All outputs are set low by default */
+ GPDR = 0; /* Configure all GPIOs as input */
+}
+
diff --git a/arch/arm/mach-sa1100/include/mach/SA-1100.h b/arch/arm/mach-sa1100/include/mach/SA-1100.h
new file mode 100644
index 000000000..6e6ff3e18
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/SA-1100.h
@@ -0,0 +1,1798 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * FILE SA-1100.h
+ *
+ * Version 1.2
+ * Author Copyright (c) Marc A. Viredaz, 1998
+ * DEC Western Research Laboratory, Palo Alto, CA
+ * Date January 1998 (April 1997)
+ * System StrongARM SA-1100
+ * Language C or ARM Assembly
+ * Purpose Definition of constants related to the StrongARM
+ * SA-1100 microprocessor (Advanced RISC Machine (ARM)
+ * architecture version 4). This file is based on the
+ * StrongARM SA-1100 data sheet version 2.2.
+ *
+ */
+
+
+/* Be sure that virtual mapping is defined right */
+#ifndef __ASM_ARCH_HARDWARE_H
+#error You must include hardware.h not SA-1100.h
+#endif
+
+#include "bitfield.h"
+
+/*
+ * SA1100 CS line to physical address
+ */
+
+#define SA1100_CS0_PHYS 0x00000000
+#define SA1100_CS1_PHYS 0x08000000
+#define SA1100_CS2_PHYS 0x10000000
+#define SA1100_CS3_PHYS 0x18000000
+#define SA1100_CS4_PHYS 0x40000000
+#define SA1100_CS5_PHYS 0x48000000
+
+/*
+ * Personal Computer Memory Card International Association (PCMCIA) sockets
+ */
+
+#define PCMCIAPrtSp 0x04000000 /* PCMCIA Partition Space [byte] */
+#define PCMCIASp (4*PCMCIAPrtSp) /* PCMCIA Space [byte] */
+#define PCMCIAIOSp PCMCIAPrtSp /* PCMCIA I/O Space [byte] */
+#define PCMCIAAttrSp PCMCIAPrtSp /* PCMCIA Attribute Space [byte] */
+#define PCMCIAMemSp PCMCIAPrtSp /* PCMCIA Memory Space [byte] */
+
+#define PCMCIA0Sp PCMCIASp /* PCMCIA 0 Space [byte] */
+#define PCMCIA0IOSp PCMCIAIOSp /* PCMCIA 0 I/O Space [byte] */
+#define PCMCIA0AttrSp PCMCIAAttrSp /* PCMCIA 0 Attribute Space [byte] */
+#define PCMCIA0MemSp PCMCIAMemSp /* PCMCIA 0 Memory Space [byte] */
+
+#define PCMCIA1Sp PCMCIASp /* PCMCIA 1 Space [byte] */
+#define PCMCIA1IOSp PCMCIAIOSp /* PCMCIA 1 I/O Space [byte] */
+#define PCMCIA1AttrSp PCMCIAAttrSp /* PCMCIA 1 Attribute Space [byte] */
+#define PCMCIA1MemSp PCMCIAMemSp /* PCMCIA 1 Memory Space [byte] */
+
+#define _PCMCIA(Nb) /* PCMCIA [0..1] */ \
+ (0x20000000 + (Nb)*PCMCIASp)
+#define _PCMCIAIO(Nb) _PCMCIA (Nb) /* PCMCIA I/O [0..1] */
+#define _PCMCIAAttr(Nb) /* PCMCIA Attribute [0..1] */ \
+ (_PCMCIA (Nb) + 2*PCMCIAPrtSp)
+#define _PCMCIAMem(Nb) /* PCMCIA Memory [0..1] */ \
+ (_PCMCIA (Nb) + 3*PCMCIAPrtSp)
+
+#define _PCMCIA0 _PCMCIA (0) /* PCMCIA 0 */
+#define _PCMCIA0IO _PCMCIAIO (0) /* PCMCIA 0 I/O */
+#define _PCMCIA0Attr _PCMCIAAttr (0) /* PCMCIA 0 Attribute */
+#define _PCMCIA0Mem _PCMCIAMem (0) /* PCMCIA 0 Memory */
+
+#define _PCMCIA1 _PCMCIA (1) /* PCMCIA 1 */
+#define _PCMCIA1IO _PCMCIAIO (1) /* PCMCIA 1 I/O */
+#define _PCMCIA1Attr _PCMCIAAttr (1) /* PCMCIA 1 Attribute */
+#define _PCMCIA1Mem _PCMCIAMem (1) /* PCMCIA 1 Memory */
+
+
+/*
+ * Universal Serial Bus (USB) Device Controller (UDC) control registers
+ *
+ * Registers
+ * Ser0UDCCR Serial port 0 Universal Serial Bus (USB) Device
+ * Controller (UDC) Control Register (read/write).
+ * Ser0UDCAR Serial port 0 Universal Serial Bus (USB) Device
+ * Controller (UDC) Address Register (read/write).
+ * Ser0UDCOMP Serial port 0 Universal Serial Bus (USB) Device
+ * Controller (UDC) Output Maximum Packet size register
+ * (read/write).
+ * Ser0UDCIMP Serial port 0 Universal Serial Bus (USB) Device
+ * Controller (UDC) Input Maximum Packet size register
+ * (read/write).
+ * Ser0UDCCS0 Serial port 0 Universal Serial Bus (USB) Device
+ * Controller (UDC) Control/Status register end-point 0
+ * (read/write).
+ * Ser0UDCCS1 Serial port 0 Universal Serial Bus (USB) Device
+ * Controller (UDC) Control/Status register end-point 1
+ * (output, read/write).
+ * Ser0UDCCS2 Serial port 0 Universal Serial Bus (USB) Device
+ * Controller (UDC) Control/Status register end-point 2
+ * (input, read/write).
+ * Ser0UDCD0 Serial port 0 Universal Serial Bus (USB) Device
+ * Controller (UDC) Data register end-point 0
+ * (read/write).
+ * Ser0UDCWC Serial port 0 Universal Serial Bus (USB) Device
+ * Controller (UDC) Write Count register end-point 0
+ * (read).
+ * Ser0UDCDR Serial port 0 Universal Serial Bus (USB) Device
+ * Controller (UDC) Data Register (read/write).
+ * Ser0UDCSR Serial port 0 Universal Serial Bus (USB) Device
+ * Controller (UDC) Status Register (read/write).
+ */
+
+#define Ser0UDCCR __REG(0x80000000) /* Ser. port 0 UDC Control Reg. */
+#define Ser0UDCAR __REG(0x80000004) /* Ser. port 0 UDC Address Reg. */
+#define Ser0UDCOMP __REG(0x80000008) /* Ser. port 0 UDC Output Maximum Packet size reg. */
+#define Ser0UDCIMP __REG(0x8000000C) /* Ser. port 0 UDC Input Maximum Packet size reg. */
+#define Ser0UDCCS0 __REG(0x80000010) /* Ser. port 0 UDC Control/Status reg. end-point 0 */
+#define Ser0UDCCS1 __REG(0x80000014) /* Ser. port 0 UDC Control/Status reg. end-point 1 (output) */
+#define Ser0UDCCS2 __REG(0x80000018) /* Ser. port 0 UDC Control/Status reg. end-point 2 (input) */
+#define Ser0UDCD0 __REG(0x8000001C) /* Ser. port 0 UDC Data reg. end-point 0 */
+#define Ser0UDCWC __REG(0x80000020) /* Ser. port 0 UDC Write Count reg. end-point 0 */
+#define Ser0UDCDR __REG(0x80000028) /* Ser. port 0 UDC Data Reg. */
+#define Ser0UDCSR __REG(0x80000030) /* Ser. port 0 UDC Status Reg. */
+
+#define UDCCR_UDD 0x00000001 /* UDC Disable */
+#define UDCCR_UDA 0x00000002 /* UDC Active (read) */
+#define UDCCR_RESIM 0x00000004 /* Resume Interrupt Mask, per errata */
+#define UDCCR_EIM 0x00000008 /* End-point 0 Interrupt Mask */
+ /* (disable) */
+#define UDCCR_RIM 0x00000010 /* Receive Interrupt Mask */
+ /* (disable) */
+#define UDCCR_TIM 0x00000020 /* Transmit Interrupt Mask */
+ /* (disable) */
+#define UDCCR_SRM 0x00000040 /* Suspend/Resume interrupt Mask */
+ /* (disable) */
+#define UDCCR_SUSIM UDCCR_SRM /* Per errata, SRM just masks suspend */
+#define UDCCR_REM 0x00000080 /* REset interrupt Mask (disable) */
+
+#define UDCAR_ADD Fld (7, 0) /* function ADDress */
+
+#define UDCOMP_OUTMAXP Fld (8, 0) /* OUTput MAXimum Packet size - 1 */
+ /* [byte] */
+#define UDCOMP_OutMaxPkt(Size) /* Output Maximum Packet size */ \
+ /* [1..256 byte] */ \
+ (((Size) - 1) << FShft (UDCOMP_OUTMAXP))
+
+#define UDCIMP_INMAXP Fld (8, 0) /* INput MAXimum Packet size - 1 */
+ /* [byte] */
+#define UDCIMP_InMaxPkt(Size) /* Input Maximum Packet size */ \
+ /* [1..256 byte] */ \
+ (((Size) - 1) << FShft (UDCIMP_INMAXP))
+
+#define UDCCS0_OPR 0x00000001 /* Output Packet Ready (read) */
+#define UDCCS0_IPR 0x00000002 /* Input Packet Ready */
+#define UDCCS0_SST 0x00000004 /* Sent STall */
+#define UDCCS0_FST 0x00000008 /* Force STall */
+#define UDCCS0_DE 0x00000010 /* Data End */
+#define UDCCS0_SE 0x00000020 /* Setup End (read) */
+#define UDCCS0_SO 0x00000040 /* Serviced Output packet ready */
+ /* (write) */
+#define UDCCS0_SSE 0x00000080 /* Serviced Setup End (write) */
+
+#define UDCCS1_RFS 0x00000001 /* Receive FIFO 12-bytes or more */
+ /* Service request (read) */
+#define UDCCS1_RPC 0x00000002 /* Receive Packet Complete */
+#define UDCCS1_RPE 0x00000004 /* Receive Packet Error (read) */
+#define UDCCS1_SST 0x00000008 /* Sent STall */
+#define UDCCS1_FST 0x00000010 /* Force STall */
+#define UDCCS1_RNE 0x00000020 /* Receive FIFO Not Empty (read) */
+
+#define UDCCS2_TFS 0x00000001 /* Transmit FIFO 8-bytes or less */
+ /* Service request (read) */
+#define UDCCS2_TPC 0x00000002 /* Transmit Packet Complete */
+#define UDCCS2_TPE 0x00000004 /* Transmit Packet Error (read) */
+#define UDCCS2_TUR 0x00000008 /* Transmit FIFO Under-Run */
+#define UDCCS2_SST 0x00000010 /* Sent STall */
+#define UDCCS2_FST 0x00000020 /* Force STall */
+
+#define UDCD0_DATA Fld (8, 0) /* receive/transmit DATA FIFOs */
+
+#define UDCWC_WC Fld (4, 0) /* Write Count */
+
+#define UDCDR_DATA Fld (8, 0) /* receive/transmit DATA FIFOs */
+
+#define UDCSR_EIR 0x00000001 /* End-point 0 Interrupt Request */
+#define UDCSR_RIR 0x00000002 /* Receive Interrupt Request */
+#define UDCSR_TIR 0x00000004 /* Transmit Interrupt Request */
+#define UDCSR_SUSIR 0x00000008 /* SUSpend Interrupt Request */
+#define UDCSR_RESIR 0x00000010 /* RESume Interrupt Request */
+#define UDCSR_RSTIR 0x00000020 /* ReSeT Interrupt Request */
+
+
+/*
+ * Universal Asynchronous Receiver/Transmitter (UART) control registers
+ *
+ * Registers
+ * Ser1UTCR0 Serial port 1 Universal Asynchronous
+ * Receiver/Transmitter (UART) Control Register 0
+ * (read/write).
+ * Ser1UTCR1 Serial port 1 Universal Asynchronous
+ * Receiver/Transmitter (UART) Control Register 1
+ * (read/write).
+ * Ser1UTCR2 Serial port 1 Universal Asynchronous
+ * Receiver/Transmitter (UART) Control Register 2
+ * (read/write).
+ * Ser1UTCR3 Serial port 1 Universal Asynchronous
+ * Receiver/Transmitter (UART) Control Register 3
+ * (read/write).
+ * Ser1UTDR Serial port 1 Universal Asynchronous
+ * Receiver/Transmitter (UART) Data Register
+ * (read/write).
+ * Ser1UTSR0 Serial port 1 Universal Asynchronous
+ * Receiver/Transmitter (UART) Status Register 0
+ * (read/write).
+ * Ser1UTSR1 Serial port 1 Universal Asynchronous
+ * Receiver/Transmitter (UART) Status Register 1 (read).
+ *
+ * Ser2UTCR0 Serial port 2 Universal Asynchronous
+ * Receiver/Transmitter (UART) Control Register 0
+ * (read/write).
+ * Ser2UTCR1 Serial port 2 Universal Asynchronous
+ * Receiver/Transmitter (UART) Control Register 1
+ * (read/write).
+ * Ser2UTCR2 Serial port 2 Universal Asynchronous
+ * Receiver/Transmitter (UART) Control Register 2
+ * (read/write).
+ * Ser2UTCR3 Serial port 2 Universal Asynchronous
+ * Receiver/Transmitter (UART) Control Register 3
+ * (read/write).
+ * Ser2UTCR4 Serial port 2 Universal Asynchronous
+ * Receiver/Transmitter (UART) Control Register 4
+ * (read/write).
+ * Ser2UTDR Serial port 2 Universal Asynchronous
+ * Receiver/Transmitter (UART) Data Register
+ * (read/write).
+ * Ser2UTSR0 Serial port 2 Universal Asynchronous
+ * Receiver/Transmitter (UART) Status Register 0
+ * (read/write).
+ * Ser2UTSR1 Serial port 2 Universal Asynchronous
+ * Receiver/Transmitter (UART) Status Register 1 (read).
+ *
+ * Ser3UTCR0 Serial port 3 Universal Asynchronous
+ * Receiver/Transmitter (UART) Control Register 0
+ * (read/write).
+ * Ser3UTCR1 Serial port 3 Universal Asynchronous
+ * Receiver/Transmitter (UART) Control Register 1
+ * (read/write).
+ * Ser3UTCR2 Serial port 3 Universal Asynchronous
+ * Receiver/Transmitter (UART) Control Register 2
+ * (read/write).
+ * Ser3UTCR3 Serial port 3 Universal Asynchronous
+ * Receiver/Transmitter (UART) Control Register 3
+ * (read/write).
+ * Ser3UTDR Serial port 3 Universal Asynchronous
+ * Receiver/Transmitter (UART) Data Register
+ * (read/write).
+ * Ser3UTSR0 Serial port 3 Universal Asynchronous
+ * Receiver/Transmitter (UART) Status Register 0
+ * (read/write).
+ * Ser3UTSR1 Serial port 3 Universal Asynchronous
+ * Receiver/Transmitter (UART) Status Register 1 (read).
+ *
+ * Clocks
+ * fxtl, Txtl Frequency, period of the system crystal (3.6864 MHz
+ * or 3.5795 MHz).
+ * fua, Tua Frequency, period of the UART communication.
+ */
+
+#define _UTCR0(Nb) __REG(0x80010000 + ((Nb) - 1)*0x00020000) /* UART Control Reg. 0 [1..3] */
+#define _UTCR1(Nb) __REG(0x80010004 + ((Nb) - 1)*0x00020000) /* UART Control Reg. 1 [1..3] */
+#define _UTCR2(Nb) __REG(0x80010008 + ((Nb) - 1)*0x00020000) /* UART Control Reg. 2 [1..3] */
+#define _UTCR3(Nb) __REG(0x8001000C + ((Nb) - 1)*0x00020000) /* UART Control Reg. 3 [1..3] */
+#define _UTCR4(Nb) __REG(0x80010010 + ((Nb) - 1)*0x00020000) /* UART Control Reg. 4 [2] */
+#define _UTDR(Nb) __REG(0x80010014 + ((Nb) - 1)*0x00020000) /* UART Data Reg. [1..3] */
+#define _UTSR0(Nb) __REG(0x8001001C + ((Nb) - 1)*0x00020000) /* UART Status Reg. 0 [1..3] */
+#define _UTSR1(Nb) __REG(0x80010020 + ((Nb) - 1)*0x00020000) /* UART Status Reg. 1 [1..3] */
+
+#define Ser1UTCR0 _UTCR0 (1) /* Ser. port 1 UART Control Reg. 0 */
+#define Ser1UTCR1 _UTCR1 (1) /* Ser. port 1 UART Control Reg. 1 */
+#define Ser1UTCR2 _UTCR2 (1) /* Ser. port 1 UART Control Reg. 2 */
+#define Ser1UTCR3 _UTCR3 (1) /* Ser. port 1 UART Control Reg. 3 */
+#define Ser1UTDR _UTDR (1) /* Ser. port 1 UART Data Reg. */
+#define Ser1UTSR0 _UTSR0 (1) /* Ser. port 1 UART Status Reg. 0 */
+#define Ser1UTSR1 _UTSR1 (1) /* Ser. port 1 UART Status Reg. 1 */
+
+#define Ser2UTCR0 _UTCR0 (2) /* Ser. port 2 UART Control Reg. 0 */
+#define Ser2UTCR1 _UTCR1 (2) /* Ser. port 2 UART Control Reg. 1 */
+#define Ser2UTCR2 _UTCR2 (2) /* Ser. port 2 UART Control Reg. 2 */
+#define Ser2UTCR3 _UTCR3 (2) /* Ser. port 2 UART Control Reg. 3 */
+#define Ser2UTCR4 _UTCR4 (2) /* Ser. port 2 UART Control Reg. 4 */
+#define Ser2UTDR _UTDR (2) /* Ser. port 2 UART Data Reg. */
+#define Ser2UTSR0 _UTSR0 (2) /* Ser. port 2 UART Status Reg. 0 */
+#define Ser2UTSR1 _UTSR1 (2) /* Ser. port 2 UART Status Reg. 1 */
+
+#define Ser3UTCR0 _UTCR0 (3) /* Ser. port 3 UART Control Reg. 0 */
+#define Ser3UTCR1 _UTCR1 (3) /* Ser. port 3 UART Control Reg. 1 */
+#define Ser3UTCR2 _UTCR2 (3) /* Ser. port 3 UART Control Reg. 2 */
+#define Ser3UTCR3 _UTCR3 (3) /* Ser. port 3 UART Control Reg. 3 */
+#define Ser3UTDR _UTDR (3) /* Ser. port 3 UART Data Reg. */
+#define Ser3UTSR0 _UTSR0 (3) /* Ser. port 3 UART Status Reg. 0 */
+#define Ser3UTSR1 _UTSR1 (3) /* Ser. port 3 UART Status Reg. 1 */
+
+/* Those are still used in some places */
+#define _Ser1UTCR0 __PREG(Ser1UTCR0)
+#define _Ser2UTCR0 __PREG(Ser2UTCR0)
+#define _Ser3UTCR0 __PREG(Ser3UTCR0)
+
+/* Register offsets */
+#define UTCR0 0x00
+#define UTCR1 0x04
+#define UTCR2 0x08
+#define UTCR3 0x0c
+#define UTDR 0x14
+#define UTSR0 0x1c
+#define UTSR1 0x20
+
+#define UTCR0_PE 0x00000001 /* Parity Enable */
+#define UTCR0_OES 0x00000002 /* Odd/Even parity Select */
+#define UTCR0_OddPar (UTCR0_OES*0) /* Odd Parity */
+#define UTCR0_EvenPar (UTCR0_OES*1) /* Even Parity */
+#define UTCR0_SBS 0x00000004 /* Stop Bit Select */
+#define UTCR0_1StpBit (UTCR0_SBS*0) /* 1 Stop Bit per frame */
+#define UTCR0_2StpBit (UTCR0_SBS*1) /* 2 Stop Bits per frame */
+#define UTCR0_DSS 0x00000008 /* Data Size Select */
+#define UTCR0_7BitData (UTCR0_DSS*0) /* 7-Bit Data */
+#define UTCR0_8BitData (UTCR0_DSS*1) /* 8-Bit Data */
+#define UTCR0_SCE 0x00000010 /* Sample Clock Enable */
+ /* (ser. port 1: GPIO [18], */
+ /* ser. port 3: GPIO [20]) */
+#define UTCR0_RCE 0x00000020 /* Receive Clock Edge select */
+#define UTCR0_RcRsEdg (UTCR0_RCE*0) /* Receive clock Rising-Edge */
+#define UTCR0_RcFlEdg (UTCR0_RCE*1) /* Receive clock Falling-Edge */
+#define UTCR0_TCE 0x00000040 /* Transmit Clock Edge select */
+#define UTCR0_TrRsEdg (UTCR0_TCE*0) /* Transmit clock Rising-Edge */
+#define UTCR0_TrFlEdg (UTCR0_TCE*1) /* Transmit clock Falling-Edge */
+#define UTCR0_Ser2IrDA /* Ser. port 2 IrDA settings */ \
+ (UTCR0_1StpBit + UTCR0_8BitData)
+
+#define UTCR1_BRD Fld (4, 0) /* Baud Rate Divisor/16 - 1 [11:8] */
+#define UTCR2_BRD Fld (8, 0) /* Baud Rate Divisor/16 - 1 [7:0] */
+ /* fua = fxtl/(16*(BRD[11:0] + 1)) */
+ /* Tua = 16*(BRD [11:0] + 1)*Txtl */
+#define UTCR1_BdRtDiv(Div) /* Baud Rate Divisor [16..65536] */ \
+ (((Div) - 16)/16 >> FSize (UTCR2_BRD) << \
+ FShft (UTCR1_BRD))
+#define UTCR2_BdRtDiv(Div) /* Baud Rate Divisor [16..65536] */ \
+ (((Div) - 16)/16 & FAlnMsk (UTCR2_BRD) << \
+ FShft (UTCR2_BRD))
+ /* fua = fxtl/(16*Floor (Div/16)) */
+ /* Tua = 16*Floor (Div/16)*Txtl */
+#define UTCR1_CeilBdRtDiv(Div) /* Ceil. of BdRtDiv [16..65536] */ \
+ (((Div) - 1)/16 >> FSize (UTCR2_BRD) << \
+ FShft (UTCR1_BRD))
+#define UTCR2_CeilBdRtDiv(Div) /* Ceil. of BdRtDiv [16..65536] */ \
+ (((Div) - 1)/16 & FAlnMsk (UTCR2_BRD) << \
+ FShft (UTCR2_BRD))
+ /* fua = fxtl/(16*Ceil (Div/16)) */
+ /* Tua = 16*Ceil (Div/16)*Txtl */
+
+#define UTCR3_RXE 0x00000001 /* Receive Enable */
+#define UTCR3_TXE 0x00000002 /* Transmit Enable */
+#define UTCR3_BRK 0x00000004 /* BReaK mode */
+#define UTCR3_RIE 0x00000008 /* Receive FIFO 1/3-to-2/3-full or */
+ /* more Interrupt Enable */
+#define UTCR3_TIE 0x00000010 /* Transmit FIFO 1/2-full or less */
+ /* Interrupt Enable */
+#define UTCR3_LBM 0x00000020 /* Look-Back Mode */
+#define UTCR3_Ser2IrDA /* Ser. port 2 IrDA settings (RIE, */ \
+ /* TIE, LBM can be set or cleared) */ \
+ (UTCR3_RXE + UTCR3_TXE)
+
+#define UTCR4_HSE 0x00000001 /* Hewlett-Packard Serial InfraRed */
+ /* (HP-SIR) modulation Enable */
+#define UTCR4_NRZ (UTCR4_HSE*0) /* Non-Return to Zero modulation */
+#define UTCR4_HPSIR (UTCR4_HSE*1) /* HP-SIR modulation */
+#define UTCR4_LPM 0x00000002 /* Low-Power Mode */
+#define UTCR4_Z3_16Bit (UTCR4_LPM*0) /* Zero pulse = 3/16 Bit time */
+#define UTCR4_Z1_6us (UTCR4_LPM*1) /* Zero pulse = 1.6 us */
+
+#define UTDR_DATA Fld (8, 0) /* receive/transmit DATA FIFOs */
+#if 0 /* Hidden receive FIFO bits */
+#define UTDR_PRE 0x00000100 /* receive PaRity Error (read) */
+#define UTDR_FRE 0x00000200 /* receive FRaming Error (read) */
+#define UTDR_ROR 0x00000400 /* Receive FIFO Over-Run (read) */
+#endif /* 0 */
+
+#define UTSR0_TFS 0x00000001 /* Transmit FIFO 1/2-full or less */
+ /* Service request (read) */
+#define UTSR0_RFS 0x00000002 /* Receive FIFO 1/3-to-2/3-full or */
+ /* more Service request (read) */
+#define UTSR0_RID 0x00000004 /* Receiver IDle */
+#define UTSR0_RBB 0x00000008 /* Receive Beginning of Break */
+#define UTSR0_REB 0x00000010 /* Receive End of Break */
+#define UTSR0_EIF 0x00000020 /* Error In FIFO (read) */
+
+#define UTSR1_TBY 0x00000001 /* Transmitter BusY (read) */
+#define UTSR1_RNE 0x00000002 /* Receive FIFO Not Empty (read) */
+#define UTSR1_TNF 0x00000004 /* Transmit FIFO Not Full (read) */
+#define UTSR1_PRE 0x00000008 /* receive PaRity Error (read) */
+#define UTSR1_FRE 0x00000010 /* receive FRaming Error (read) */
+#define UTSR1_ROR 0x00000020 /* Receive FIFO Over-Run (read) */
+
+
+/*
+ * Synchronous Data Link Controller (SDLC) control registers
+ *
+ * Registers
+ * Ser1SDCR0 Serial port 1 Synchronous Data Link Controller (SDLC)
+ * Control Register 0 (read/write).
+ * Ser1SDCR1 Serial port 1 Synchronous Data Link Controller (SDLC)
+ * Control Register 1 (read/write).
+ * Ser1SDCR2 Serial port 1 Synchronous Data Link Controller (SDLC)
+ * Control Register 2 (read/write).
+ * Ser1SDCR3 Serial port 1 Synchronous Data Link Controller (SDLC)
+ * Control Register 3 (read/write).
+ * Ser1SDCR4 Serial port 1 Synchronous Data Link Controller (SDLC)
+ * Control Register 4 (read/write).
+ * Ser1SDDR Serial port 1 Synchronous Data Link Controller (SDLC)
+ * Data Register (read/write).
+ * Ser1SDSR0 Serial port 1 Synchronous Data Link Controller (SDLC)
+ * Status Register 0 (read/write).
+ * Ser1SDSR1 Serial port 1 Synchronous Data Link Controller (SDLC)
+ * Status Register 1 (read/write).
+ *
+ * Clocks
+ * fxtl, Txtl Frequency, period of the system crystal (3.6864 MHz
+ * or 3.5795 MHz).
+ * fsd, Tsd Frequency, period of the SDLC communication.
+ */
+
+#define Ser1SDCR0 __REG(0x80020060) /* Ser. port 1 SDLC Control Reg. 0 */
+#define Ser1SDCR1 __REG(0x80020064) /* Ser. port 1 SDLC Control Reg. 1 */
+#define Ser1SDCR2 __REG(0x80020068) /* Ser. port 1 SDLC Control Reg. 2 */
+#define Ser1SDCR3 __REG(0x8002006C) /* Ser. port 1 SDLC Control Reg. 3 */
+#define Ser1SDCR4 __REG(0x80020070) /* Ser. port 1 SDLC Control Reg. 4 */
+#define Ser1SDDR __REG(0x80020078) /* Ser. port 1 SDLC Data Reg. */
+#define Ser1SDSR0 __REG(0x80020080) /* Ser. port 1 SDLC Status Reg. 0 */
+#define Ser1SDSR1 __REG(0x80020084) /* Ser. port 1 SDLC Status Reg. 1 */
+
+#define SDCR0_SUS 0x00000001 /* SDLC/UART Select */
+#define SDCR0_SDLC (SDCR0_SUS*0) /* SDLC mode (TXD1 & RXD1) */
+#define SDCR0_UART (SDCR0_SUS*1) /* UART mode (TXD1 & RXD1) */
+#define SDCR0_SDF 0x00000002 /* Single/Double start Flag select */
+#define SDCR0_SglFlg (SDCR0_SDF*0) /* Single start Flag */
+#define SDCR0_DblFlg (SDCR0_SDF*1) /* Double start Flag */
+#define SDCR0_LBM 0x00000004 /* Look-Back Mode */
+#define SDCR0_BMS 0x00000008 /* Bit Modulation Select */
+#define SDCR0_FM0 (SDCR0_BMS*0) /* Freq. Modulation zero (0) */
+#define SDCR0_NRZ (SDCR0_BMS*1) /* Non-Return to Zero modulation */
+#define SDCR0_SCE 0x00000010 /* Sample Clock Enable (GPIO [16]) */
+#define SDCR0_SCD 0x00000020 /* Sample Clock Direction select */
+ /* (GPIO [16]) */
+#define SDCR0_SClkIn (SDCR0_SCD*0) /* Sample Clock Input */
+#define SDCR0_SClkOut (SDCR0_SCD*1) /* Sample Clock Output */
+#define SDCR0_RCE 0x00000040 /* Receive Clock Edge select */
+#define SDCR0_RcRsEdg (SDCR0_RCE*0) /* Receive clock Rising-Edge */
+#define SDCR0_RcFlEdg (SDCR0_RCE*1) /* Receive clock Falling-Edge */
+#define SDCR0_TCE 0x00000080 /* Transmit Clock Edge select */
+#define SDCR0_TrRsEdg (SDCR0_TCE*0) /* Transmit clock Rising-Edge */
+#define SDCR0_TrFlEdg (SDCR0_TCE*1) /* Transmit clock Falling-Edge */
+
+#define SDCR1_AAF 0x00000001 /* Abort After Frame enable */
+ /* (GPIO [17]) */
+#define SDCR1_TXE 0x00000002 /* Transmit Enable */
+#define SDCR1_RXE 0x00000004 /* Receive Enable */
+#define SDCR1_RIE 0x00000008 /* Receive FIFO 1/3-to-2/3-full or */
+ /* more Interrupt Enable */
+#define SDCR1_TIE 0x00000010 /* Transmit FIFO 1/2-full or less */
+ /* Interrupt Enable */
+#define SDCR1_AME 0x00000020 /* Address Match Enable */
+#define SDCR1_TUS 0x00000040 /* Transmit FIFO Under-run Select */
+#define SDCR1_EFrmURn (SDCR1_TUS*0) /* End Frame on Under-Run */
+#define SDCR1_AbortURn (SDCR1_TUS*1) /* Abort on Under-Run */
+#define SDCR1_RAE 0x00000080 /* Receive Abort interrupt Enable */
+
+#define SDCR2_AMV Fld (8, 0) /* Address Match Value */
+
+#define SDCR3_BRD Fld (4, 0) /* Baud Rate Divisor/16 - 1 [11:8] */
+#define SDCR4_BRD Fld (8, 0) /* Baud Rate Divisor/16 - 1 [7:0] */
+ /* fsd = fxtl/(16*(BRD[11:0] + 1)) */
+ /* Tsd = 16*(BRD[11:0] + 1)*Txtl */
+#define SDCR3_BdRtDiv(Div) /* Baud Rate Divisor [16..65536] */ \
+ (((Div) - 16)/16 >> FSize (SDCR4_BRD) << \
+ FShft (SDCR3_BRD))
+#define SDCR4_BdRtDiv(Div) /* Baud Rate Divisor [16..65536] */ \
+ (((Div) - 16)/16 & FAlnMsk (SDCR4_BRD) << \
+ FShft (SDCR4_BRD))
+ /* fsd = fxtl/(16*Floor (Div/16)) */
+ /* Tsd = 16*Floor (Div/16)*Txtl */
+#define SDCR3_CeilBdRtDiv(Div) /* Ceil. of BdRtDiv [16..65536] */ \
+ (((Div) - 1)/16 >> FSize (SDCR4_BRD) << \
+ FShft (SDCR3_BRD))
+#define SDCR4_CeilBdRtDiv(Div) /* Ceil. of BdRtDiv [16..65536] */ \
+ (((Div) - 1)/16 & FAlnMsk (SDCR4_BRD) << \
+ FShft (SDCR4_BRD))
+ /* fsd = fxtl/(16*Ceil (Div/16)) */
+ /* Tsd = 16*Ceil (Div/16)*Txtl */
+
+#define SDDR_DATA Fld (8, 0) /* receive/transmit DATA FIFOs */
+#if 0 /* Hidden receive FIFO bits */
+#define SDDR_EOF 0x00000100 /* receive End-Of-Frame (read) */
+#define SDDR_CRE 0x00000200 /* receive CRC Error (read) */
+#define SDDR_ROR 0x00000400 /* Receive FIFO Over-Run (read) */
+#endif /* 0 */
+
+#define SDSR0_EIF 0x00000001 /* Error In FIFO (read) */
+#define SDSR0_TUR 0x00000002 /* Transmit FIFO Under-Run */
+#define SDSR0_RAB 0x00000004 /* Receive ABort */
+#define SDSR0_TFS 0x00000008 /* Transmit FIFO 1/2-full or less */
+ /* Service request (read) */
+#define SDSR0_RFS 0x00000010 /* Receive FIFO 1/3-to-2/3-full or */
+ /* more Service request (read) */
+
+#define SDSR1_RSY 0x00000001 /* Receiver SYnchronized (read) */
+#define SDSR1_TBY 0x00000002 /* Transmitter BusY (read) */
+#define SDSR1_RNE 0x00000004 /* Receive FIFO Not Empty (read) */
+#define SDSR1_TNF 0x00000008 /* Transmit FIFO Not Full (read) */
+#define SDSR1_RTD 0x00000010 /* Receive Transition Detected */
+#define SDSR1_EOF 0x00000020 /* receive End-Of-Frame (read) */
+#define SDSR1_CRE 0x00000040 /* receive CRC Error (read) */
+#define SDSR1_ROR 0x00000080 /* Receive FIFO Over-Run (read) */
+
+
+/*
+ * High-Speed Serial to Parallel controller (HSSP) control registers
+ *
+ * Registers
+ * Ser2HSCR0 Serial port 2 High-Speed Serial to Parallel
+ * controller (HSSP) Control Register 0 (read/write).
+ * Ser2HSCR1 Serial port 2 High-Speed Serial to Parallel
+ * controller (HSSP) Control Register 1 (read/write).
+ * Ser2HSDR Serial port 2 High-Speed Serial to Parallel
+ * controller (HSSP) Data Register (read/write).
+ * Ser2HSSR0 Serial port 2 High-Speed Serial to Parallel
+ * controller (HSSP) Status Register 0 (read/write).
+ * Ser2HSSR1 Serial port 2 High-Speed Serial to Parallel
+ * controller (HSSP) Status Register 1 (read).
+ * Ser2HSCR2 Serial port 2 High-Speed Serial to Parallel
+ * controller (HSSP) Control Register 2 (read/write).
+ * [The HSCR2 register is only implemented in
+ * versions 2.0 (rev. = 8) and higher of the StrongARM
+ * SA-1100.]
+ */
+
+#define Ser2HSCR0 __REG(0x80040060) /* Ser. port 2 HSSP Control Reg. 0 */
+#define Ser2HSCR1 __REG(0x80040064) /* Ser. port 2 HSSP Control Reg. 1 */
+#define Ser2HSDR __REG(0x8004006C) /* Ser. port 2 HSSP Data Reg. */
+#define Ser2HSSR0 __REG(0x80040074) /* Ser. port 2 HSSP Status Reg. 0 */
+#define Ser2HSSR1 __REG(0x80040078) /* Ser. port 2 HSSP Status Reg. 1 */
+#define Ser2HSCR2 __REG(0x90060028) /* Ser. port 2 HSSP Control Reg. 2 */
+
+#define HSCR0_ITR 0x00000001 /* IrDA Transmission Rate */
+#define HSCR0_UART (HSCR0_ITR*0) /* UART mode (115.2 kb/s if IrDA) */
+#define HSCR0_HSSP (HSCR0_ITR*1) /* HSSP mode (4 Mb/s) */
+#define HSCR0_LBM 0x00000002 /* Look-Back Mode */
+#define HSCR0_TUS 0x00000004 /* Transmit FIFO Under-run Select */
+#define HSCR0_EFrmURn (HSCR0_TUS*0) /* End Frame on Under-Run */
+#define HSCR0_AbortURn (HSCR0_TUS*1) /* Abort on Under-Run */
+#define HSCR0_TXE 0x00000008 /* Transmit Enable */
+#define HSCR0_RXE 0x00000010 /* Receive Enable */
+#define HSCR0_RIE 0x00000020 /* Receive FIFO 2/5-to-3/5-full or */
+ /* more Interrupt Enable */
+#define HSCR0_TIE 0x00000040 /* Transmit FIFO 1/2-full or less */
+ /* Interrupt Enable */
+#define HSCR0_AME 0x00000080 /* Address Match Enable */
+
+#define HSCR1_AMV Fld (8, 0) /* Address Match Value */
+
+#define HSDR_DATA Fld (8, 0) /* receive/transmit DATA FIFOs */
+#if 0 /* Hidden receive FIFO bits */
+#define HSDR_EOF 0x00000100 /* receive End-Of-Frame (read) */
+#define HSDR_CRE 0x00000200 /* receive CRC Error (read) */
+#define HSDR_ROR 0x00000400 /* Receive FIFO Over-Run (read) */
+#endif /* 0 */
+
+#define HSSR0_EIF 0x00000001 /* Error In FIFO (read) */
+#define HSSR0_TUR 0x00000002 /* Transmit FIFO Under-Run */
+#define HSSR0_RAB 0x00000004 /* Receive ABort */
+#define HSSR0_TFS 0x00000008 /* Transmit FIFO 1/2-full or less */
+ /* Service request (read) */
+#define HSSR0_RFS 0x00000010 /* Receive FIFO 2/5-to-3/5-full or */
+ /* more Service request (read) */
+#define HSSR0_FRE 0x00000020 /* receive FRaming Error */
+
+#define HSSR1_RSY 0x00000001 /* Receiver SYnchronized (read) */
+#define HSSR1_TBY 0x00000002 /* Transmitter BusY (read) */
+#define HSSR1_RNE 0x00000004 /* Receive FIFO Not Empty (read) */
+#define HSSR1_TNF 0x00000008 /* Transmit FIFO Not Full (read) */
+#define HSSR1_EOF 0x00000010 /* receive End-Of-Frame (read) */
+#define HSSR1_CRE 0x00000020 /* receive CRC Error (read) */
+#define HSSR1_ROR 0x00000040 /* Receive FIFO Over-Run (read) */
+
+#define HSCR2_TXP 0x00040000 /* Transmit data Polarity (TXD_2) */
+#define HSCR2_TrDataL (HSCR2_TXP*0) /* Transmit Data active Low */
+ /* (inverted) */
+#define HSCR2_TrDataH (HSCR2_TXP*1) /* Transmit Data active High */
+ /* (non-inverted) */
+#define HSCR2_RXP 0x00080000 /* Receive data Polarity (RXD_2) */
+#define HSCR2_RcDataL (HSCR2_RXP*0) /* Receive Data active Low */
+ /* (inverted) */
+#define HSCR2_RcDataH (HSCR2_RXP*1) /* Receive Data active High */
+ /* (non-inverted) */
+
+
+/*
+ * Multi-media Communications Port (MCP) control registers
+ *
+ * Registers
+ * Ser4MCCR0 Serial port 4 Multi-media Communications Port (MCP)
+ * Control Register 0 (read/write).
+ * Ser4MCDR0 Serial port 4 Multi-media Communications Port (MCP)
+ * Data Register 0 (audio, read/write).
+ * Ser4MCDR1 Serial port 4 Multi-media Communications Port (MCP)
+ * Data Register 1 (telecom, read/write).
+ * Ser4MCDR2 Serial port 4 Multi-media Communications Port (MCP)
+ * Data Register 2 (CODEC registers, read/write).
+ * Ser4MCSR Serial port 4 Multi-media Communications Port (MCP)
+ * Status Register (read/write).
+ * Ser4MCCR1 Serial port 4 Multi-media Communications Port (MCP)
+ * Control Register 1 (read/write).
+ * [The MCCR1 register is only implemented in
+ * versions 2.0 (rev. = 8) and higher of the StrongARM
+ * SA-1100.]
+ *
+ * Clocks
+ * fmc, Tmc Frequency, period of the MCP communication (10 MHz,
+ * 12 MHz, or GPIO [21]).
+ * faud, Taud Frequency, period of the audio sampling.
+ * ftcm, Ttcm Frequency, period of the telecom sampling.
+ */
+
+#define Ser4MCCR0 __REG(0x80060000) /* Ser. port 4 MCP Control Reg. 0 */
+#define Ser4MCDR0 __REG(0x80060008) /* Ser. port 4 MCP Data Reg. 0 (audio) */
+#define Ser4MCDR1 __REG(0x8006000C) /* Ser. port 4 MCP Data Reg. 1 (telecom) */
+#define Ser4MCDR2 __REG(0x80060010) /* Ser. port 4 MCP Data Reg. 2 (CODEC reg.) */
+#define Ser4MCSR __REG(0x80060018) /* Ser. port 4 MCP Status Reg. */
+#define Ser4MCCR1 __REG(0x90060030) /* Ser. port 4 MCP Control Reg. 1 */
+
+#define MCCR0_ASD Fld (7, 0) /* Audio Sampling rate Divisor/32 */
+ /* [6..127] */
+ /* faud = fmc/(32*ASD) */
+ /* Taud = 32*ASD*Tmc */
+#define MCCR0_AudSmpDiv(Div) /* Audio Sampling rate Divisor */ \
+ /* [192..4064] */ \
+ ((Div)/32 << FShft (MCCR0_ASD))
+ /* faud = fmc/(32*Floor (Div/32)) */
+ /* Taud = 32*Floor (Div/32)*Tmc */
+#define MCCR0_CeilAudSmpDiv(Div) /* Ceil. of AudSmpDiv [192..4064] */ \
+ (((Div) + 31)/32 << FShft (MCCR0_ASD))
+ /* faud = fmc/(32*Ceil (Div/32)) */
+ /* Taud = 32*Ceil (Div/32)*Tmc */
+#define MCCR0_TSD Fld (7, 8) /* Telecom Sampling rate */
+ /* Divisor/32 [16..127] */
+ /* ftcm = fmc/(32*TSD) */
+ /* Ttcm = 32*TSD*Tmc */
+#define MCCR0_TcmSmpDiv(Div) /* Telecom Sampling rate Divisor */ \
+ /* [512..4064] */ \
+ ((Div)/32 << FShft (MCCR0_TSD))
+ /* ftcm = fmc/(32*Floor (Div/32)) */
+ /* Ttcm = 32*Floor (Div/32)*Tmc */
+#define MCCR0_CeilTcmSmpDiv(Div) /* Ceil. of TcmSmpDiv [512..4064] */ \
+ (((Div) + 31)/32 << FShft (MCCR0_TSD))
+ /* ftcm = fmc/(32*Ceil (Div/32)) */
+ /* Ttcm = 32*Ceil (Div/32)*Tmc */
+#define MCCR0_MCE 0x00010000 /* MCP Enable */
+#define MCCR0_ECS 0x00020000 /* External Clock Select */
+#define MCCR0_IntClk (MCCR0_ECS*0) /* Internal Clock (10 or 12 MHz) */
+#define MCCR0_ExtClk (MCCR0_ECS*1) /* External Clock (GPIO [21]) */
+#define MCCR0_ADM 0x00040000 /* A/D (audio/telecom) data */
+ /* sampling/storing Mode */
+#define MCCR0_VldBit (MCCR0_ADM*0) /* Valid Bit storing mode */
+#define MCCR0_SmpCnt (MCCR0_ADM*1) /* Sampling Counter storing mode */
+#define MCCR0_TTE 0x00080000 /* Telecom Transmit FIFO 1/2-full */
+ /* or less interrupt Enable */
+#define MCCR0_TRE 0x00100000 /* Telecom Receive FIFO 1/2-full */
+ /* or more interrupt Enable */
+#define MCCR0_ATE 0x00200000 /* Audio Transmit FIFO 1/2-full */
+ /* or less interrupt Enable */
+#define MCCR0_ARE 0x00400000 /* Audio Receive FIFO 1/2-full or */
+ /* more interrupt Enable */
+#define MCCR0_LBM 0x00800000 /* Look-Back Mode */
+#define MCCR0_ECP Fld (2, 24) /* External Clock Prescaler - 1 */
+#define MCCR0_ExtClkDiv(Div) /* External Clock Divisor [1..4] */ \
+ (((Div) - 1) << FShft (MCCR0_ECP))
+
+#define MCDR0_DATA Fld (12, 4) /* receive/transmit audio DATA */
+ /* FIFOs */
+
+#define MCDR1_DATA Fld (14, 2) /* receive/transmit telecom DATA */
+ /* FIFOs */
+
+ /* receive/transmit CODEC reg. */
+ /* FIFOs: */
+#define MCDR2_DATA Fld (16, 0) /* reg. DATA */
+#define MCDR2_RW 0x00010000 /* reg. Read/Write (transmit) */
+#define MCDR2_Rd (MCDR2_RW*0) /* reg. Read */
+#define MCDR2_Wr (MCDR2_RW*1) /* reg. Write */
+#define MCDR2_ADD Fld (4, 17) /* reg. ADDress */
+
+#define MCSR_ATS 0x00000001 /* Audio Transmit FIFO 1/2-full */
+ /* or less Service request (read) */
+#define MCSR_ARS 0x00000002 /* Audio Receive FIFO 1/2-full or */
+ /* more Service request (read) */
+#define MCSR_TTS 0x00000004 /* Telecom Transmit FIFO 1/2-full */
+ /* or less Service request (read) */
+#define MCSR_TRS 0x00000008 /* Telecom Receive FIFO 1/2-full */
+ /* or more Service request (read) */
+#define MCSR_ATU 0x00000010 /* Audio Transmit FIFO Under-run */
+#define MCSR_ARO 0x00000020 /* Audio Receive FIFO Over-run */
+#define MCSR_TTU 0x00000040 /* Telecom Transmit FIFO Under-run */
+#define MCSR_TRO 0x00000080 /* Telecom Receive FIFO Over-run */
+#define MCSR_ANF 0x00000100 /* Audio transmit FIFO Not Full */
+ /* (read) */
+#define MCSR_ANE 0x00000200 /* Audio receive FIFO Not Empty */
+ /* (read) */
+#define MCSR_TNF 0x00000400 /* Telecom transmit FIFO Not Full */
+ /* (read) */
+#define MCSR_TNE 0x00000800 /* Telecom receive FIFO Not Empty */
+ /* (read) */
+#define MCSR_CWC 0x00001000 /* CODEC register Write Completed */
+ /* (read) */
+#define MCSR_CRC 0x00002000 /* CODEC register Read Completed */
+ /* (read) */
+#define MCSR_ACE 0x00004000 /* Audio CODEC Enabled (read) */
+#define MCSR_TCE 0x00008000 /* Telecom CODEC Enabled (read) */
+
+#define MCCR1_CFS 0x00100000 /* Clock Freq. Select */
+#define MCCR1_F12MHz (MCCR1_CFS*0) /* Freq. (fmc) = ~ 12 MHz */
+ /* (11.981 MHz) */
+#define MCCR1_F10MHz (MCCR1_CFS*1) /* Freq. (fmc) = ~ 10 MHz */
+ /* (9.585 MHz) */
+
+
+/*
+ * Synchronous Serial Port (SSP) control registers
+ *
+ * Registers
+ * Ser4SSCR0 Serial port 4 Synchronous Serial Port (SSP) Control
+ * Register 0 (read/write).
+ * Ser4SSCR1 Serial port 4 Synchronous Serial Port (SSP) Control
+ * Register 1 (read/write).
+ * [Bits SPO and SP are only implemented in versions 2.0
+ * (rev. = 8) and higher of the StrongARM SA-1100.]
+ * Ser4SSDR Serial port 4 Synchronous Serial Port (SSP) Data
+ * Register (read/write).
+ * Ser4SSSR Serial port 4 Synchronous Serial Port (SSP) Status
+ * Register (read/write).
+ *
+ * Clocks
+ * fxtl, Txtl Frequency, period of the system crystal (3.6864 MHz
+ * or 3.5795 MHz).
+ * fss, Tss Frequency, period of the SSP communication.
+ */
+
+#define Ser4SSCR0 __REG(0x80070060) /* Ser. port 4 SSP Control Reg. 0 */
+#define Ser4SSCR1 __REG(0x80070064) /* Ser. port 4 SSP Control Reg. 1 */
+#define Ser4SSDR __REG(0x8007006C) /* Ser. port 4 SSP Data Reg. */
+#define Ser4SSSR __REG(0x80070074) /* Ser. port 4 SSP Status Reg. */
+
+#define SSCR0_DSS Fld (4, 0) /* Data Size - 1 Select [3..15] */
+#define SSCR0_DataSize(Size) /* Data Size Select [4..16] */ \
+ (((Size) - 1) << FShft (SSCR0_DSS))
+#define SSCR0_FRF Fld (2, 4) /* FRame Format */
+#define SSCR0_Motorola /* Motorola Serial Peripheral */ \
+ /* Interface (SPI) format */ \
+ (0 << FShft (SSCR0_FRF))
+#define SSCR0_TI /* Texas Instruments Synchronous */ \
+ /* Serial format */ \
+ (1 << FShft (SSCR0_FRF))
+#define SSCR0_National /* National Microwire format */ \
+ (2 << FShft (SSCR0_FRF))
+#define SSCR0_SSE 0x00000080 /* SSP Enable */
+#define SSCR0_SCR Fld (8, 8) /* Serial Clock Rate divisor/2 - 1 */
+ /* fss = fxtl/(2*(SCR + 1)) */
+ /* Tss = 2*(SCR + 1)*Txtl */
+#define SSCR0_SerClkDiv(Div) /* Serial Clock Divisor [2..512] */ \
+ (((Div) - 2)/2 << FShft (SSCR0_SCR))
+ /* fss = fxtl/(2*Floor (Div/2)) */
+ /* Tss = 2*Floor (Div/2)*Txtl */
+#define SSCR0_CeilSerClkDiv(Div) /* Ceil. of SerClkDiv [2..512] */ \
+ (((Div) - 1)/2 << FShft (SSCR0_SCR))
+ /* fss = fxtl/(2*Ceil (Div/2)) */
+ /* Tss = 2*Ceil (Div/2)*Txtl */
+
+#define SSCR1_RIE 0x00000001 /* Receive FIFO 1/2-full or more */
+ /* Interrupt Enable */
+#define SSCR1_TIE 0x00000002 /* Transmit FIFO 1/2-full or less */
+ /* Interrupt Enable */
+#define SSCR1_LBM 0x00000004 /* Look-Back Mode */
+#define SSCR1_SPO 0x00000008 /* Sample clock (SCLK) POlarity */
+#define SSCR1_SClkIactL (SSCR1_SPO*0) /* Sample Clock Inactive Low */
+#define SSCR1_SClkIactH (SSCR1_SPO*1) /* Sample Clock Inactive High */
+#define SSCR1_SP 0x00000010 /* Sample clock (SCLK) Phase */
+#define SSCR1_SClk1P (SSCR1_SP*0) /* Sample Clock active 1 Period */
+ /* after frame (SFRM, 1st edge) */
+#define SSCR1_SClk1_2P (SSCR1_SP*1) /* Sample Clock active 1/2 Period */
+ /* after frame (SFRM, 1st edge) */
+#define SSCR1_ECS 0x00000020 /* External Clock Select */
+#define SSCR1_IntClk (SSCR1_ECS*0) /* Internal Clock */
+#define SSCR1_ExtClk (SSCR1_ECS*1) /* External Clock (GPIO [19]) */
+
+#define SSDR_DATA Fld (16, 0) /* receive/transmit DATA FIFOs */
+
+#define SSSR_TNF 0x00000002 /* Transmit FIFO Not Full (read) */
+#define SSSR_RNE 0x00000004 /* Receive FIFO Not Empty (read) */
+#define SSSR_BSY 0x00000008 /* SSP BuSY (read) */
+#define SSSR_TFS 0x00000010 /* Transmit FIFO 1/2-full or less */
+ /* Service request (read) */
+#define SSSR_RFS 0x00000020 /* Receive FIFO 1/2-full or more */
+ /* Service request (read) */
+#define SSSR_ROR 0x00000040 /* Receive FIFO Over-Run */
+
+
+/*
+ * Operating System (OS) timer control registers
+ *
+ * Registers
+ * OSMR0 Operating System (OS) timer Match Register 0
+ * (read/write).
+ * OSMR1 Operating System (OS) timer Match Register 1
+ * (read/write).
+ * OSMR2 Operating System (OS) timer Match Register 2
+ * (read/write).
+ * OSMR3 Operating System (OS) timer Match Register 3
+ * (read/write).
+ * OSCR Operating System (OS) timer Counter Register
+ * (read/write).
+ * OSSR Operating System (OS) timer Status Register
+ * (read/write).
+ * OWER Operating System (OS) timer Watch-dog Enable Register
+ * (read/write).
+ * OIER Operating System (OS) timer Interrupt Enable Register
+ * (read/write).
+ */
+
+#define OSMR0 io_p2v(0x90000000) /* OS timer Match Reg. 0 */
+#define OSMR1 io_p2v(0x90000004) /* OS timer Match Reg. 1 */
+#define OSMR2 io_p2v(0x90000008) /* OS timer Match Reg. 2 */
+#define OSMR3 io_p2v(0x9000000c) /* OS timer Match Reg. 3 */
+#define OSCR io_p2v(0x90000010) /* OS timer Counter Reg. */
+#define OSSR io_p2v(0x90000014) /* OS timer Status Reg. */
+#define OWER io_p2v(0x90000018) /* OS timer Watch-dog Enable Reg. */
+#define OIER io_p2v(0x9000001C) /* OS timer Interrupt Enable Reg. */
+
+#define OSSR_M(Nb) /* Match detected [0..3] */ \
+ (0x00000001 << (Nb))
+#define OSSR_M0 OSSR_M (0) /* Match detected 0 */
+#define OSSR_M1 OSSR_M (1) /* Match detected 1 */
+#define OSSR_M2 OSSR_M (2) /* Match detected 2 */
+#define OSSR_M3 OSSR_M (3) /* Match detected 3 */
+
+#define OWER_WME 0x00000001 /* Watch-dog Match Enable */
+ /* (set only) */
+
+#define OIER_E(Nb) /* match interrupt Enable [0..3] */ \
+ (0x00000001 << (Nb))
+#define OIER_E0 OIER_E (0) /* match interrupt Enable 0 */
+#define OIER_E1 OIER_E (1) /* match interrupt Enable 1 */
+#define OIER_E2 OIER_E (2) /* match interrupt Enable 2 */
+#define OIER_E3 OIER_E (3) /* match interrupt Enable 3 */
+
+
+/*
+ * Power Manager (PM) control registers
+ *
+ * Registers
+ * PMCR Power Manager (PM) Control Register (read/write).
+ * PSSR Power Manager (PM) Sleep Status Register (read/write).
+ * PSPR Power Manager (PM) Scratch-Pad Register (read/write).
+ * PWER Power Manager (PM) Wake-up Enable Register
+ * (read/write).
+ * PCFR Power Manager (PM) general ConFiguration Register
+ * (read/write).
+ * PPCR Power Manager (PM) Phase-Locked Loop (PLL)
+ * Configuration Register (read/write).
+ * PGSR Power Manager (PM) General-Purpose Input/Output (GPIO)
+ * Sleep state Register (read/write, see GPIO pins).
+ * POSR Power Manager (PM) Oscillator Status Register (read).
+ *
+ * Clocks
+ * fxtl, Txtl Frequency, period of the system crystal (3.6864 MHz
+ * or 3.5795 MHz).
+ * fcpu, Tcpu Frequency, period of the CPU core clock (CCLK).
+ */
+
+#define PMCR __REG(0x90020000) /* PM Control Reg. */
+#define PSSR __REG(0x90020004) /* PM Sleep Status Reg. */
+#define PSPR __REG(0x90020008) /* PM Scratch-Pad Reg. */
+#define PWER __REG(0x9002000C) /* PM Wake-up Enable Reg. */
+#define PCFR __REG(0x90020010) /* PM general ConFiguration Reg. */
+#define PPCR __REG(0x90020014) /* PM PLL Configuration Reg. */
+#define PGSR __REG(0x90020018) /* PM GPIO Sleep state Reg. */
+#define POSR __REG(0x9002001C) /* PM Oscillator Status Reg. */
+
+#define PMCR_SF 0x00000001 /* Sleep Force (set only) */
+
+#define PSSR_SS 0x00000001 /* Software Sleep */
+#define PSSR_BFS 0x00000002 /* Battery Fault Status */
+ /* (BATT_FAULT) */
+#define PSSR_VFS 0x00000004 /* Vdd Fault Status (VDD_FAULT) */
+#define PSSR_DH 0x00000008 /* DRAM control Hold */
+#define PSSR_PH 0x00000010 /* Peripheral control Hold */
+
+#define PWER_GPIO(Nb) GPIO_GPIO (Nb) /* GPIO [0..27] wake-up enable */
+#define PWER_GPIO0 PWER_GPIO (0) /* GPIO [0] wake-up enable */
+#define PWER_GPIO1 PWER_GPIO (1) /* GPIO [1] wake-up enable */
+#define PWER_GPIO2 PWER_GPIO (2) /* GPIO [2] wake-up enable */
+#define PWER_GPIO3 PWER_GPIO (3) /* GPIO [3] wake-up enable */
+#define PWER_GPIO4 PWER_GPIO (4) /* GPIO [4] wake-up enable */
+#define PWER_GPIO5 PWER_GPIO (5) /* GPIO [5] wake-up enable */
+#define PWER_GPIO6 PWER_GPIO (6) /* GPIO [6] wake-up enable */
+#define PWER_GPIO7 PWER_GPIO (7) /* GPIO [7] wake-up enable */
+#define PWER_GPIO8 PWER_GPIO (8) /* GPIO [8] wake-up enable */
+#define PWER_GPIO9 PWER_GPIO (9) /* GPIO [9] wake-up enable */
+#define PWER_GPIO10 PWER_GPIO (10) /* GPIO [10] wake-up enable */
+#define PWER_GPIO11 PWER_GPIO (11) /* GPIO [11] wake-up enable */
+#define PWER_GPIO12 PWER_GPIO (12) /* GPIO [12] wake-up enable */
+#define PWER_GPIO13 PWER_GPIO (13) /* GPIO [13] wake-up enable */
+#define PWER_GPIO14 PWER_GPIO (14) /* GPIO [14] wake-up enable */
+#define PWER_GPIO15 PWER_GPIO (15) /* GPIO [15] wake-up enable */
+#define PWER_GPIO16 PWER_GPIO (16) /* GPIO [16] wake-up enable */
+#define PWER_GPIO17 PWER_GPIO (17) /* GPIO [17] wake-up enable */
+#define PWER_GPIO18 PWER_GPIO (18) /* GPIO [18] wake-up enable */
+#define PWER_GPIO19 PWER_GPIO (19) /* GPIO [19] wake-up enable */
+#define PWER_GPIO20 PWER_GPIO (20) /* GPIO [20] wake-up enable */
+#define PWER_GPIO21 PWER_GPIO (21) /* GPIO [21] wake-up enable */
+#define PWER_GPIO22 PWER_GPIO (22) /* GPIO [22] wake-up enable */
+#define PWER_GPIO23 PWER_GPIO (23) /* GPIO [23] wake-up enable */
+#define PWER_GPIO24 PWER_GPIO (24) /* GPIO [24] wake-up enable */
+#define PWER_GPIO25 PWER_GPIO (25) /* GPIO [25] wake-up enable */
+#define PWER_GPIO26 PWER_GPIO (26) /* GPIO [26] wake-up enable */
+#define PWER_GPIO27 PWER_GPIO (27) /* GPIO [27] wake-up enable */
+#define PWER_RTC 0x80000000 /* RTC alarm wake-up enable */
+
+#define PCFR_OPDE 0x00000001 /* Oscillator Power-Down Enable */
+#define PCFR_ClkRun (PCFR_OPDE*0) /* Clock Running in sleep mode */
+#define PCFR_ClkStp (PCFR_OPDE*1) /* Clock Stopped in sleep mode */
+#define PCFR_FP 0x00000002 /* Float PCMCIA pins */
+#define PCFR_PCMCIANeg (PCFR_FP*0) /* PCMCIA pins Negated (1) */
+#define PCFR_PCMCIAFlt (PCFR_FP*1) /* PCMCIA pins Floating */
+#define PCFR_FS 0x00000004 /* Float Static memory pins */
+#define PCFR_StMemNeg (PCFR_FS*0) /* Static Memory pins Negated (1) */
+#define PCFR_StMemFlt (PCFR_FS*1) /* Static Memory pins Floating */
+#define PCFR_FO 0x00000008 /* Force RTC oscillator */
+ /* (32.768 kHz) enable On */
+
+#define PPCR_CCF Fld (5, 0) /* CPU core Clock (CCLK) Freq. */
+#define PPCR_Fx16 /* Freq. x 16 (fcpu = 16*fxtl) */ \
+ (0x00 << FShft (PPCR_CCF))
+#define PPCR_Fx20 /* Freq. x 20 (fcpu = 20*fxtl) */ \
+ (0x01 << FShft (PPCR_CCF))
+#define PPCR_Fx24 /* Freq. x 24 (fcpu = 24*fxtl) */ \
+ (0x02 << FShft (PPCR_CCF))
+#define PPCR_Fx28 /* Freq. x 28 (fcpu = 28*fxtl) */ \
+ (0x03 << FShft (PPCR_CCF))
+#define PPCR_Fx32 /* Freq. x 32 (fcpu = 32*fxtl) */ \
+ (0x04 << FShft (PPCR_CCF))
+#define PPCR_Fx36 /* Freq. x 36 (fcpu = 36*fxtl) */ \
+ (0x05 << FShft (PPCR_CCF))
+#define PPCR_Fx40 /* Freq. x 40 (fcpu = 40*fxtl) */ \
+ (0x06 << FShft (PPCR_CCF))
+#define PPCR_Fx44 /* Freq. x 44 (fcpu = 44*fxtl) */ \
+ (0x07 << FShft (PPCR_CCF))
+#define PPCR_Fx48 /* Freq. x 48 (fcpu = 48*fxtl) */ \
+ (0x08 << FShft (PPCR_CCF))
+#define PPCR_Fx52 /* Freq. x 52 (fcpu = 52*fxtl) */ \
+ (0x09 << FShft (PPCR_CCF))
+#define PPCR_Fx56 /* Freq. x 56 (fcpu = 56*fxtl) */ \
+ (0x0A << FShft (PPCR_CCF))
+#define PPCR_Fx60 /* Freq. x 60 (fcpu = 60*fxtl) */ \
+ (0x0B << FShft (PPCR_CCF))
+#define PPCR_Fx64 /* Freq. x 64 (fcpu = 64*fxtl) */ \
+ (0x0C << FShft (PPCR_CCF))
+#define PPCR_Fx68 /* Freq. x 68 (fcpu = 68*fxtl) */ \
+ (0x0D << FShft (PPCR_CCF))
+#define PPCR_Fx72 /* Freq. x 72 (fcpu = 72*fxtl) */ \
+ (0x0E << FShft (PPCR_CCF))
+#define PPCR_Fx76 /* Freq. x 76 (fcpu = 76*fxtl) */ \
+ (0x0F << FShft (PPCR_CCF))
+ /* 3.6864 MHz crystal (fxtl): */
+#define PPCR_F59_0MHz PPCR_Fx16 /* Freq. (fcpu) = 59.0 MHz */
+#define PPCR_F73_7MHz PPCR_Fx20 /* Freq. (fcpu) = 73.7 MHz */
+#define PPCR_F88_5MHz PPCR_Fx24 /* Freq. (fcpu) = 88.5 MHz */
+#define PPCR_F103_2MHz PPCR_Fx28 /* Freq. (fcpu) = 103.2 MHz */
+#define PPCR_F118_0MHz PPCR_Fx32 /* Freq. (fcpu) = 118.0 MHz */
+#define PPCR_F132_7MHz PPCR_Fx36 /* Freq. (fcpu) = 132.7 MHz */
+#define PPCR_F147_5MHz PPCR_Fx40 /* Freq. (fcpu) = 147.5 MHz */
+#define PPCR_F162_2MHz PPCR_Fx44 /* Freq. (fcpu) = 162.2 MHz */
+#define PPCR_F176_9MHz PPCR_Fx48 /* Freq. (fcpu) = 176.9 MHz */
+#define PPCR_F191_7MHz PPCR_Fx52 /* Freq. (fcpu) = 191.7 MHz */
+#define PPCR_F206_4MHz PPCR_Fx56 /* Freq. (fcpu) = 206.4 MHz */
+#define PPCR_F221_2MHz PPCR_Fx60 /* Freq. (fcpu) = 221.2 MHz */
+#define PPCR_F239_6MHz PPCR_Fx64 /* Freq. (fcpu) = 239.6 MHz */
+#define PPCR_F250_7MHz PPCR_Fx68 /* Freq. (fcpu) = 250.7 MHz */
+#define PPCR_F265_4MHz PPCR_Fx72 /* Freq. (fcpu) = 265.4 MHz */
+#define PPCR_F280_2MHz PPCR_Fx76 /* Freq. (fcpu) = 280.2 MHz */
+ /* 3.5795 MHz crystal (fxtl): */
+#define PPCR_F57_3MHz PPCR_Fx16 /* Freq. (fcpu) = 57.3 MHz */
+#define PPCR_F71_6MHz PPCR_Fx20 /* Freq. (fcpu) = 71.6 MHz */
+#define PPCR_F85_9MHz PPCR_Fx24 /* Freq. (fcpu) = 85.9 MHz */
+#define PPCR_F100_2MHz PPCR_Fx28 /* Freq. (fcpu) = 100.2 MHz */
+#define PPCR_F114_5MHz PPCR_Fx32 /* Freq. (fcpu) = 114.5 MHz */
+#define PPCR_F128_9MHz PPCR_Fx36 /* Freq. (fcpu) = 128.9 MHz */
+#define PPCR_F143_2MHz PPCR_Fx40 /* Freq. (fcpu) = 143.2 MHz */
+#define PPCR_F157_5MHz PPCR_Fx44 /* Freq. (fcpu) = 157.5 MHz */
+#define PPCR_F171_8MHz PPCR_Fx48 /* Freq. (fcpu) = 171.8 MHz */
+#define PPCR_F186_1MHz PPCR_Fx52 /* Freq. (fcpu) = 186.1 MHz */
+#define PPCR_F200_5MHz PPCR_Fx56 /* Freq. (fcpu) = 200.5 MHz */
+#define PPCR_F214_8MHz PPCR_Fx60 /* Freq. (fcpu) = 214.8 MHz */
+#define PPCR_F229_1MHz PPCR_Fx64 /* Freq. (fcpu) = 229.1 MHz */
+#define PPCR_F243_4MHz PPCR_Fx68 /* Freq. (fcpu) = 243.4 MHz */
+#define PPCR_F257_7MHz PPCR_Fx72 /* Freq. (fcpu) = 257.7 MHz */
+#define PPCR_F272_0MHz PPCR_Fx76 /* Freq. (fcpu) = 272.0 MHz */
+
+#define POSR_OOK 0x00000001 /* RTC Oscillator (32.768 kHz) OK */
+
+
+/*
+ * Reset Controller (RC) control registers
+ *
+ * Registers
+ * RSRR Reset Controller (RC) Software Reset Register
+ * (read/write).
+ * RCSR Reset Controller (RC) Status Register (read/write).
+ */
+
+#define RSRR __REG(0x90030000) /* RC Software Reset Reg. */
+#define RCSR __REG(0x90030004) /* RC Status Reg. */
+
+#define RSRR_SWR 0x00000001 /* SoftWare Reset (set only) */
+
+#define RCSR_HWR 0x00000001 /* HardWare Reset */
+#define RCSR_SWR 0x00000002 /* SoftWare Reset */
+#define RCSR_WDR 0x00000004 /* Watch-Dog Reset */
+#define RCSR_SMR 0x00000008 /* Sleep-Mode Reset */
+
+
+/*
+ * Test unit control registers
+ *
+ * Registers
+ * TUCR Test Unit Control Register (read/write).
+ */
+
+#define TUCR __REG(0x90030008) /* Test Unit Control Reg. */
+
+#define TUCR_TIC 0x00000040 /* TIC mode */
+#define TUCR_TTST 0x00000080 /* Trim TeST mode */
+#define TUCR_RCRC 0x00000100 /* Richard's Cyclic Redundancy */
+ /* Check */
+#define TUCR_PMD 0x00000200 /* Power Management Disable */
+#define TUCR_MR 0x00000400 /* Memory Request mode */
+#define TUCR_NoMB (TUCR_MR*0) /* No Memory Bus request & grant */
+#define TUCR_MBGPIO (TUCR_MR*1) /* Memory Bus request (MBREQ) & */
+ /* grant (MBGNT) on GPIO [22:21] */
+#define TUCR_CTB Fld (3, 20) /* Clock Test Bits */
+#define TUCR_FDC 0x00800000 /* RTC Force Delete Count */
+#define TUCR_FMC 0x01000000 /* Force Michelle's Control mode */
+#define TUCR_TMC 0x02000000 /* RTC Trimmer Multiplexer Control */
+#define TUCR_DPS 0x04000000 /* Disallow Pad Sleep */
+#define TUCR_TSEL Fld (3, 29) /* clock Test SELect on GPIO [27] */
+#define TUCR_32_768kHz /* 32.768 kHz osc. on GPIO [27] */ \
+ (0 << FShft (TUCR_TSEL))
+#define TUCR_3_6864MHz /* 3.6864 MHz osc. on GPIO [27] */ \
+ (1 << FShft (TUCR_TSEL))
+#define TUCR_VDD /* VDD ring osc./16 on GPIO [27] */ \
+ (2 << FShft (TUCR_TSEL))
+#define TUCR_96MHzPLL /* 96 MHz PLL/4 on GPIO [27] */ \
+ (3 << FShft (TUCR_TSEL))
+#define TUCR_Clock /* internal (fcpu/2) & 32.768 kHz */ \
+ /* Clocks on GPIO [26:27] */ \
+ (4 << FShft (TUCR_TSEL))
+#define TUCR_3_6864MHzA /* 3.6864 MHz osc. on GPIO [27] */ \
+ /* (Alternative) */ \
+ (5 << FShft (TUCR_TSEL))
+#define TUCR_MainPLL /* Main PLL/16 on GPIO [27] */ \
+ (6 << FShft (TUCR_TSEL))
+#define TUCR_VDDL /* VDDL ring osc./4 on GPIO [27] */ \
+ (7 << FShft (TUCR_TSEL))
+
+
+/*
+ * General-Purpose Input/Output (GPIO) control registers
+ *
+ * Registers
+ * GPLR General-Purpose Input/Output (GPIO) Pin Level
+ * Register (read).
+ * GPDR General-Purpose Input/Output (GPIO) Pin Direction
+ * Register (read/write).
+ * GPSR General-Purpose Input/Output (GPIO) Pin output Set
+ * Register (write).
+ * GPCR General-Purpose Input/Output (GPIO) Pin output Clear
+ * Register (write).
+ * GRER General-Purpose Input/Output (GPIO) Rising-Edge
+ * detect Register (read/write).
+ * GFER General-Purpose Input/Output (GPIO) Falling-Edge
+ * detect Register (read/write).
+ * GEDR General-Purpose Input/Output (GPIO) Edge Detect
+ * status Register (read/write).
+ * GAFR General-Purpose Input/Output (GPIO) Alternate
+ * Function Register (read/write).
+ *
+ * Clock
+ * fcpu, Tcpu Frequency, period of the CPU core clock (CCLK).
+ */
+
+#define GPLR __REG(0x90040000) /* GPIO Pin Level Reg. */
+#define GPDR __REG(0x90040004) /* GPIO Pin Direction Reg. */
+#define GPSR __REG(0x90040008) /* GPIO Pin output Set Reg. */
+#define GPCR __REG(0x9004000C) /* GPIO Pin output Clear Reg. */
+#define GRER __REG(0x90040010) /* GPIO Rising-Edge detect Reg. */
+#define GFER __REG(0x90040014) /* GPIO Falling-Edge detect Reg. */
+#define GEDR __REG(0x90040018) /* GPIO Edge Detect status Reg. */
+#define GAFR __REG(0x9004001C) /* GPIO Alternate Function Reg. */
+
+#define GPIO_MIN (0)
+#define GPIO_MAX (27)
+
+#define GPIO_GPIO(Nb) /* GPIO [0..27] */ \
+ (0x00000001 << (Nb))
+#define GPIO_GPIO0 GPIO_GPIO (0) /* GPIO [0] */
+#define GPIO_GPIO1 GPIO_GPIO (1) /* GPIO [1] */
+#define GPIO_GPIO2 GPIO_GPIO (2) /* GPIO [2] */
+#define GPIO_GPIO3 GPIO_GPIO (3) /* GPIO [3] */
+#define GPIO_GPIO4 GPIO_GPIO (4) /* GPIO [4] */
+#define GPIO_GPIO5 GPIO_GPIO (5) /* GPIO [5] */
+#define GPIO_GPIO6 GPIO_GPIO (6) /* GPIO [6] */
+#define GPIO_GPIO7 GPIO_GPIO (7) /* GPIO [7] */
+#define GPIO_GPIO8 GPIO_GPIO (8) /* GPIO [8] */
+#define GPIO_GPIO9 GPIO_GPIO (9) /* GPIO [9] */
+#define GPIO_GPIO10 GPIO_GPIO (10) /* GPIO [10] */
+#define GPIO_GPIO11 GPIO_GPIO (11) /* GPIO [11] */
+#define GPIO_GPIO12 GPIO_GPIO (12) /* GPIO [12] */
+#define GPIO_GPIO13 GPIO_GPIO (13) /* GPIO [13] */
+#define GPIO_GPIO14 GPIO_GPIO (14) /* GPIO [14] */
+#define GPIO_GPIO15 GPIO_GPIO (15) /* GPIO [15] */
+#define GPIO_GPIO16 GPIO_GPIO (16) /* GPIO [16] */
+#define GPIO_GPIO17 GPIO_GPIO (17) /* GPIO [17] */
+#define GPIO_GPIO18 GPIO_GPIO (18) /* GPIO [18] */
+#define GPIO_GPIO19 GPIO_GPIO (19) /* GPIO [19] */
+#define GPIO_GPIO20 GPIO_GPIO (20) /* GPIO [20] */
+#define GPIO_GPIO21 GPIO_GPIO (21) /* GPIO [21] */
+#define GPIO_GPIO22 GPIO_GPIO (22) /* GPIO [22] */
+#define GPIO_GPIO23 GPIO_GPIO (23) /* GPIO [23] */
+#define GPIO_GPIO24 GPIO_GPIO (24) /* GPIO [24] */
+#define GPIO_GPIO25 GPIO_GPIO (25) /* GPIO [25] */
+#define GPIO_GPIO26 GPIO_GPIO (26) /* GPIO [26] */
+#define GPIO_GPIO27 GPIO_GPIO (27) /* GPIO [27] */
+
+#define GPIO_LDD(Nb) /* LCD Data [8..15] (O) */ \
+ GPIO_GPIO ((Nb) - 6)
+#define GPIO_LDD8 GPIO_LDD (8) /* LCD Data [8] (O) */
+#define GPIO_LDD9 GPIO_LDD (9) /* LCD Data [9] (O) */
+#define GPIO_LDD10 GPIO_LDD (10) /* LCD Data [10] (O) */
+#define GPIO_LDD11 GPIO_LDD (11) /* LCD Data [11] (O) */
+#define GPIO_LDD12 GPIO_LDD (12) /* LCD Data [12] (O) */
+#define GPIO_LDD13 GPIO_LDD (13) /* LCD Data [13] (O) */
+#define GPIO_LDD14 GPIO_LDD (14) /* LCD Data [14] (O) */
+#define GPIO_LDD15 GPIO_LDD (15) /* LCD Data [15] (O) */
+ /* ser. port 4: */
+#define GPIO_SSP_TXD GPIO_GPIO (10) /* SSP Transmit Data (O) */
+#define GPIO_SSP_RXD GPIO_GPIO (11) /* SSP Receive Data (I) */
+#define GPIO_SSP_SCLK GPIO_GPIO (12) /* SSP Sample CLocK (O) */
+#define GPIO_SSP_SFRM GPIO_GPIO (13) /* SSP Sample FRaMe (O) */
+ /* ser. port 1: */
+#define GPIO_UART_TXD GPIO_GPIO (14) /* UART Transmit Data (O) */
+#define GPIO_UART_RXD GPIO_GPIO (15) /* UART Receive Data (I) */
+#define GPIO_SDLC_SCLK GPIO_GPIO (16) /* SDLC Sample CLocK (I/O) */
+#define GPIO_SDLC_AAF GPIO_GPIO (17) /* SDLC Abort After Frame (O) */
+#define GPIO_UART_SCLK1 GPIO_GPIO (18) /* UART Sample CLocK 1 (I) */
+ /* ser. port 4: */
+#define GPIO_SSP_CLK GPIO_GPIO (19) /* SSP external CLocK (I) */
+ /* ser. port 3: */
+#define GPIO_UART_SCLK3 GPIO_GPIO (20) /* UART Sample CLocK 3 (I) */
+ /* ser. port 4: */
+#define GPIO_MCP_CLK GPIO_GPIO (21) /* MCP CLocK (I) */
+ /* test controller: */
+#define GPIO_TIC_ACK GPIO_GPIO (21) /* TIC ACKnowledge (O) */
+#define GPIO_MBGNT GPIO_GPIO (21) /* Memory Bus GraNT (O) */
+#define GPIO_TREQA GPIO_GPIO (22) /* TIC REQuest A (I) */
+#define GPIO_MBREQ GPIO_GPIO (22) /* Memory Bus REQuest (I) */
+#define GPIO_TREQB GPIO_GPIO (23) /* TIC REQuest B (I) */
+#define GPIO_1Hz GPIO_GPIO (25) /* 1 Hz clock (O) */
+#define GPIO_RCLK GPIO_GPIO (26) /* internal (R) CLocK (O, fcpu/2) */
+#define GPIO_32_768kHz GPIO_GPIO (27) /* 32.768 kHz clock (O, RTC) */
+
+#define GPDR_In 0 /* Input */
+#define GPDR_Out 1 /* Output */
+
+
+/*
+ * Interrupt Controller (IC) control registers
+ *
+ * Registers
+ * ICIP Interrupt Controller (IC) Interrupt ReQuest (IRQ)
+ * Pending register (read).
+ * ICMR Interrupt Controller (IC) Mask Register (read/write).
+ * ICLR Interrupt Controller (IC) Level Register (read/write).
+ * ICCR Interrupt Controller (IC) Control Register
+ * (read/write).
+ * [The ICCR register is only implemented in versions 2.0
+ * (rev. = 8) and higher of the StrongARM SA-1100.]
+ * ICFP Interrupt Controller (IC) Fast Interrupt reQuest
+ * (FIQ) Pending register (read).
+ * ICPR Interrupt Controller (IC) Pending Register (read).
+ * [The ICPR register is active low (inverted) in
+ * versions 1.0 (rev. = 1) and 1.1 (rev. = 2) of the
+ * StrongARM SA-1100, it is active high (non-inverted) in
+ * versions 2.0 (rev. = 8) and higher.]
+ */
+
+#define ICIP __REG(0x90050000) /* IC IRQ Pending reg. */
+#define ICMR __REG(0x90050004) /* IC Mask Reg. */
+#define ICLR __REG(0x90050008) /* IC Level Reg. */
+#define ICCR __REG(0x9005000C) /* IC Control Reg. */
+#define ICFP __REG(0x90050010) /* IC FIQ Pending reg. */
+#define ICPR __REG(0x90050020) /* IC Pending Reg. */
+
+#define IC_GPIO(Nb) /* GPIO [0..10] */ \
+ (0x00000001 << (Nb))
+#define IC_GPIO0 IC_GPIO (0) /* GPIO [0] */
+#define IC_GPIO1 IC_GPIO (1) /* GPIO [1] */
+#define IC_GPIO2 IC_GPIO (2) /* GPIO [2] */
+#define IC_GPIO3 IC_GPIO (3) /* GPIO [3] */
+#define IC_GPIO4 IC_GPIO (4) /* GPIO [4] */
+#define IC_GPIO5 IC_GPIO (5) /* GPIO [5] */
+#define IC_GPIO6 IC_GPIO (6) /* GPIO [6] */
+#define IC_GPIO7 IC_GPIO (7) /* GPIO [7] */
+#define IC_GPIO8 IC_GPIO (8) /* GPIO [8] */
+#define IC_GPIO9 IC_GPIO (9) /* GPIO [9] */
+#define IC_GPIO10 IC_GPIO (10) /* GPIO [10] */
+#define IC_GPIO11_27 0x00000800 /* GPIO [11:27] (ORed) */
+#define IC_LCD 0x00001000 /* LCD controller */
+#define IC_Ser0UDC 0x00002000 /* Ser. port 0 UDC */
+#define IC_Ser1SDLC 0x00004000 /* Ser. port 1 SDLC */
+#define IC_Ser1UART 0x00008000 /* Ser. port 1 UART */
+#define IC_Ser2ICP 0x00010000 /* Ser. port 2 ICP */
+#define IC_Ser3UART 0x00020000 /* Ser. port 3 UART */
+#define IC_Ser4MCP 0x00040000 /* Ser. port 4 MCP */
+#define IC_Ser4SSP 0x00080000 /* Ser. port 4 SSP */
+#define IC_DMA(Nb) /* DMA controller channel [0..5] */ \
+ (0x00100000 << (Nb))
+#define IC_DMA0 IC_DMA (0) /* DMA controller channel 0 */
+#define IC_DMA1 IC_DMA (1) /* DMA controller channel 1 */
+#define IC_DMA2 IC_DMA (2) /* DMA controller channel 2 */
+#define IC_DMA3 IC_DMA (3) /* DMA controller channel 3 */
+#define IC_DMA4 IC_DMA (4) /* DMA controller channel 4 */
+#define IC_DMA5 IC_DMA (5) /* DMA controller channel 5 */
+#define IC_OST(Nb) /* OS Timer match [0..3] */ \
+ (0x04000000 << (Nb))
+#define IC_OST0 IC_OST (0) /* OS Timer match 0 */
+#define IC_OST1 IC_OST (1) /* OS Timer match 1 */
+#define IC_OST2 IC_OST (2) /* OS Timer match 2 */
+#define IC_OST3 IC_OST (3) /* OS Timer match 3 */
+#define IC_RTC1Hz 0x40000000 /* RTC 1 Hz clock */
+#define IC_RTCAlrm 0x80000000 /* RTC Alarm */
+
+#define ICLR_IRQ 0 /* Interrupt ReQuest */
+#define ICLR_FIQ 1 /* Fast Interrupt reQuest */
+
+#define ICCR_DIM 0x00000001 /* Disable Idle-mode interrupt */
+ /* Mask */
+#define ICCR_IdleAllInt (ICCR_DIM*0) /* Idle-mode All Interrupt enable */
+ /* (ICMR ignored) */
+#define ICCR_IdleMskInt (ICCR_DIM*1) /* Idle-mode non-Masked Interrupt */
+ /* enable (ICMR used) */
+
+
+/*
+ * Peripheral Pin Controller (PPC) control registers
+ *
+ * Registers
+ * PPDR Peripheral Pin Controller (PPC) Pin Direction
+ * Register (read/write).
+ * PPSR Peripheral Pin Controller (PPC) Pin State Register
+ * (read/write).
+ * PPAR Peripheral Pin Controller (PPC) Pin Assignment
+ * Register (read/write).
+ * PSDR Peripheral Pin Controller (PPC) Sleep-mode pin
+ * Direction Register (read/write).
+ * PPFR Peripheral Pin Controller (PPC) Pin Flag Register
+ * (read).
+ */
+
+#define PPDR __REG(0x90060000) /* PPC Pin Direction Reg. */
+#define PPSR __REG(0x90060004) /* PPC Pin State Reg. */
+#define PPAR __REG(0x90060008) /* PPC Pin Assignment Reg. */
+#define PSDR __REG(0x9006000C) /* PPC Sleep-mode pin Direction Reg. */
+#define PPFR __REG(0x90060010) /* PPC Pin Flag Reg. */
+
+#define PPC_LDD(Nb) /* LCD Data [0..7] */ \
+ (0x00000001 << (Nb))
+#define PPC_LDD0 PPC_LDD (0) /* LCD Data [0] */
+#define PPC_LDD1 PPC_LDD (1) /* LCD Data [1] */
+#define PPC_LDD2 PPC_LDD (2) /* LCD Data [2] */
+#define PPC_LDD3 PPC_LDD (3) /* LCD Data [3] */
+#define PPC_LDD4 PPC_LDD (4) /* LCD Data [4] */
+#define PPC_LDD5 PPC_LDD (5) /* LCD Data [5] */
+#define PPC_LDD6 PPC_LDD (6) /* LCD Data [6] */
+#define PPC_LDD7 PPC_LDD (7) /* LCD Data [7] */
+#define PPC_L_PCLK 0x00000100 /* LCD Pixel CLocK */
+#define PPC_L_LCLK 0x00000200 /* LCD Line CLocK */
+#define PPC_L_FCLK 0x00000400 /* LCD Frame CLocK */
+#define PPC_L_BIAS 0x00000800 /* LCD AC BIAS */
+ /* ser. port 1: */
+#define PPC_TXD1 0x00001000 /* SDLC/UART Transmit Data 1 */
+#define PPC_RXD1 0x00002000 /* SDLC/UART Receive Data 1 */
+ /* ser. port 2: */
+#define PPC_TXD2 0x00004000 /* IPC Transmit Data 2 */
+#define PPC_RXD2 0x00008000 /* IPC Receive Data 2 */
+ /* ser. port 3: */
+#define PPC_TXD3 0x00010000 /* UART Transmit Data 3 */
+#define PPC_RXD3 0x00020000 /* UART Receive Data 3 */
+ /* ser. port 4: */
+#define PPC_TXD4 0x00040000 /* MCP/SSP Transmit Data 4 */
+#define PPC_RXD4 0x00080000 /* MCP/SSP Receive Data 4 */
+#define PPC_SCLK 0x00100000 /* MCP/SSP Sample CLocK */
+#define PPC_SFRM 0x00200000 /* MCP/SSP Sample FRaMe */
+
+#define PPDR_In 0 /* Input */
+#define PPDR_Out 1 /* Output */
+
+ /* ser. port 1: */
+#define PPAR_UPR 0x00001000 /* UART Pin Reassignment */
+#define PPAR_UARTTR (PPAR_UPR*0) /* UART on TXD_1 & RXD_1 */
+#define PPAR_UARTGPIO (PPAR_UPR*1) /* UART on GPIO [14:15] */
+ /* ser. port 4: */
+#define PPAR_SPR 0x00040000 /* SSP Pin Reassignment */
+#define PPAR_SSPTRSS (PPAR_SPR*0) /* SSP on TXD_C, RXD_C, SCLK_C, */
+ /* & SFRM_C */
+#define PPAR_SSPGPIO (PPAR_SPR*1) /* SSP on GPIO [10:13] */
+
+#define PSDR_OutL 0 /* Output Low in sleep mode */
+#define PSDR_Flt 1 /* Floating (input) in sleep mode */
+
+#define PPFR_LCD 0x00000001 /* LCD controller */
+#define PPFR_SP1TX 0x00001000 /* Ser. Port 1 SDLC/UART Transmit */
+#define PPFR_SP1RX 0x00002000 /* Ser. Port 1 SDLC/UART Receive */
+#define PPFR_SP2TX 0x00004000 /* Ser. Port 2 ICP Transmit */
+#define PPFR_SP2RX 0x00008000 /* Ser. Port 2 ICP Receive */
+#define PPFR_SP3TX 0x00010000 /* Ser. Port 3 UART Transmit */
+#define PPFR_SP3RX 0x00020000 /* Ser. Port 3 UART Receive */
+#define PPFR_SP4 0x00040000 /* Ser. Port 4 MCP/SSP */
+#define PPFR_PerEn 0 /* Peripheral Enabled */
+#define PPFR_PPCEn 1 /* PPC Enabled */
+
+
+/*
+ * Dynamic Random-Access Memory (DRAM) control registers
+ *
+ * Registers
+ * MDCNFG Memory system: Dynamic Random-Access Memory (DRAM)
+ * CoNFiGuration register (read/write).
+ * MDCAS0 Memory system: Dynamic Random-Access Memory (DRAM)
+ * Column Address Strobe (CAS) shift register 0
+ * (read/write).
+ * MDCAS1 Memory system: Dynamic Random-Access Memory (DRAM)
+ * Column Address Strobe (CAS) shift register 1
+ * (read/write).
+ * MDCAS2 Memory system: Dynamic Random-Access Memory (DRAM)
+ * Column Address Strobe (CAS) shift register 2
+ * (read/write).
+ *
+ * Clocks
+ * fcpu, Tcpu Frequency, period of the CPU core clock (CCLK).
+ * fmem, Tmem Frequency, period of the memory clock (fmem = fcpu/2).
+ * fcas, Tcas Frequency, period of the DRAM CAS shift registers.
+ */
+
+#define MDCNFG __REG(0xA0000000) /* DRAM CoNFiGuration reg. */
+#define MDCAS0 __REG(0xA0000004) /* DRAM CAS shift reg. 0 */
+#define MDCAS1 __REG(0xA0000008) /* DRAM CAS shift reg. 1 */
+#define MDCAS2 __REG(0xA000000c) /* DRAM CAS shift reg. 2 */
+
+/* SA1100 MDCNFG values */
+#define MDCNFG_DE(Nb) /* DRAM Enable bank [0..3] */ \
+ (0x00000001 << (Nb))
+#define MDCNFG_DE0 MDCNFG_DE (0) /* DRAM Enable bank 0 */
+#define MDCNFG_DE1 MDCNFG_DE (1) /* DRAM Enable bank 1 */
+#define MDCNFG_DE2 MDCNFG_DE (2) /* DRAM Enable bank 2 */
+#define MDCNFG_DE3 MDCNFG_DE (3) /* DRAM Enable bank 3 */
+#define MDCNFG_DRAC Fld (2, 4) /* DRAM Row Address Count - 9 */
+#define MDCNFG_RowAdd(Add) /* Row Address count [9..12] */ \
+ (((Add) - 9) << FShft (MDCNFG_DRAC))
+#define MDCNFG_CDB2 0x00000040 /* shift reg. Clock Divide By 2 */
+ /* (fcas = fcpu/2) */
+#define MDCNFG_TRP Fld (4, 7) /* Time RAS Pre-charge - 1 [Tmem] */
+#define MDCNFG_PrChrg(Tcpu) /* Pre-Charge time [2..32 Tcpu] */ \
+ (((Tcpu) - 2)/2 << FShft (MDCNFG_TRP))
+#define MDCNFG_CeilPrChrg(Tcpu) /* Ceil. of PrChrg [2..32 Tcpu] */ \
+ (((Tcpu) - 1)/2 << FShft (MDCNFG_TRP))
+#define MDCNFG_TRASR Fld (4, 11) /* Time RAS Refresh - 1 [Tmem] */
+#define MDCNFG_Ref(Tcpu) /* Refresh time [2..32 Tcpu] */ \
+ (((Tcpu) - 2)/2 << FShft (MDCNFG_TRASR))
+#define MDCNFG_CeilRef(Tcpu) /* Ceil. of Ref [2..32 Tcpu] */ \
+ (((Tcpu) - 1)/2 << FShft (MDCNFG_TRASR))
+#define MDCNFG_TDL Fld (2, 15) /* Time Data Latch [Tcpu] */
+#define MDCNFG_DataLtch(Tcpu) /* Data Latch delay [0..3 Tcpu] */ \
+ ((Tcpu) << FShft (MDCNFG_TDL))
+#define MDCNFG_DRI Fld (15, 17) /* min. DRAM Refresh Interval/4 */
+ /* [Tmem] */
+#define MDCNFG_RefInt(Tcpu) /* min. Refresh Interval */ \
+ /* [0..262136 Tcpu] */ \
+ ((Tcpu)/8 << FShft (MDCNFG_DRI))
+
+/* SA1110 MDCNFG values */
+#define MDCNFG_SA1110_DE0 0x00000001 /* DRAM Enable bank 0 */
+#define MDCNFG_SA1110_DE1 0x00000002 /* DRAM Enable bank 1 */
+#define MDCNFG_SA1110_DTIM0 0x00000004 /* DRAM timing type 0/1 */
+#define MDCNFG_SA1110_DWID0 0x00000008 /* DRAM bus width 0/1 */
+#define MDCNFG_SA1110_DRAC0 Fld(3, 4) /* DRAM row addr bit count */
+ /* bank 0/1 */
+#define MDCNFG_SA1110_CDB20 0x00000080 /* Mem Clock divide by 2 0/1 */
+#define MDCNFG_SA1110_TRP0 Fld(3, 8) /* RAS precharge 0/1 */
+#define MDCNFG_SA1110_TDL0 Fld(2, 12) /* Data input latch after CAS*/
+ /* deassertion 0/1 */
+#define MDCNFG_SA1110_TWR0 Fld(2, 14) /* SDRAM write recovery 0/1 */
+#define MDCNFG_SA1110_DE2 0x00010000 /* DRAM Enable bank 0 */
+#define MDCNFG_SA1110_DE3 0x00020000 /* DRAM Enable bank 1 */
+#define MDCNFG_SA1110_DTIM2 0x00040000 /* DRAM timing type 0/1 */
+#define MDCNFG_SA1110_DWID2 0x00080000 /* DRAM bus width 0/1 */
+#define MDCNFG_SA1110_DRAC2 Fld(3, 20) /* DRAM row addr bit count */
+ /* bank 0/1 */
+#define MDCNFG_SA1110_CDB22 0x00800000 /* Mem Clock divide by 2 0/1 */
+#define MDCNFG_SA1110_TRP2 Fld(3, 24) /* RAS precharge 0/1 */
+#define MDCNFG_SA1110_TDL2 Fld(2, 28) /* Data input latch after CAS*/
+ /* deassertion 0/1 */
+#define MDCNFG_SA1110_TWR2 Fld(2, 30) /* SDRAM write recovery 0/1 */
+
+
+/*
+ * Static memory control registers
+ *
+ * Registers
+ * MSC0 Memory system: Static memory Control register 0
+ * (read/write).
+ * MSC1 Memory system: Static memory Control register 1
+ * (read/write).
+ *
+ * Clocks
+ * fcpu, Tcpu Frequency, period of the CPU core clock (CCLK).
+ * fmem, Tmem Frequency, period of the memory clock (fmem = fcpu/2).
+ */
+
+#define MSC0 __REG(0xa0000010) /* Static memory Control reg. 0 */
+#define MSC1 __REG(0xa0000014) /* Static memory Control reg. 1 */
+#define MSC2 __REG(0xa000002c) /* Static memory Control reg. 2, not contiguous */
+
+#define MSC_Bnk(Nb) /* static memory Bank [0..3] */ \
+ Fld (16, ((Nb) Modulo 2)*16)
+#define MSC0_Bnk0 MSC_Bnk (0) /* static memory Bank 0 */
+#define MSC0_Bnk1 MSC_Bnk (1) /* static memory Bank 1 */
+#define MSC1_Bnk2 MSC_Bnk (2) /* static memory Bank 2 */
+#define MSC1_Bnk3 MSC_Bnk (3) /* static memory Bank 3 */
+
+#define MSC_RT Fld (2, 0) /* ROM/static memory Type */
+#define MSC_NonBrst /* Non-Burst static memory */ \
+ (0 << FShft (MSC_RT))
+#define MSC_SRAM /* 32-bit byte-writable SRAM */ \
+ (1 << FShft (MSC_RT))
+#define MSC_Brst4 /* Burst-of-4 static memory */ \
+ (2 << FShft (MSC_RT))
+#define MSC_Brst8 /* Burst-of-8 static memory */ \
+ (3 << FShft (MSC_RT))
+#define MSC_RBW 0x0004 /* ROM/static memory Bus Width */
+#define MSC_32BitStMem (MSC_RBW*0) /* 32-Bit Static Memory */
+#define MSC_16BitStMem (MSC_RBW*1) /* 16-Bit Static Memory */
+#define MSC_RDF Fld (5, 3) /* ROM/static memory read Delay */
+ /* First access - 1(.5) [Tmem] */
+#define MSC_1stRdAcc(Tcpu) /* 1st Read Access time (burst */ \
+ /* static memory) [3..65 Tcpu] */ \
+ ((((Tcpu) - 3)/2) << FShft (MSC_RDF))
+#define MSC_Ceil1stRdAcc(Tcpu) /* Ceil. of 1stRdAcc [3..65 Tcpu] */ \
+ ((((Tcpu) - 2)/2) << FShft (MSC_RDF))
+#define MSC_RdAcc(Tcpu) /* Read Access time (non-burst */ \
+ /* static memory) [2..64 Tcpu] */ \
+ ((((Tcpu) - 2)/2) << FShft (MSC_RDF))
+#define MSC_CeilRdAcc(Tcpu) /* Ceil. of RdAcc [2..64 Tcpu] */ \
+ ((((Tcpu) - 1)/2) << FShft (MSC_RDF))
+#define MSC_RDN Fld (5, 8) /* ROM/static memory read Delay */
+ /* Next access - 1 [Tmem] */
+#define MSC_NxtRdAcc(Tcpu) /* Next Read Access time (burst */ \
+ /* static memory) [2..64 Tcpu] */ \
+ ((((Tcpu) - 2)/2) << FShft (MSC_RDN))
+#define MSC_CeilNxtRdAcc(Tcpu) /* Ceil. of NxtRdAcc [2..64 Tcpu] */ \
+ ((((Tcpu) - 1)/2) << FShft (MSC_RDN))
+#define MSC_WrAcc(Tcpu) /* Write Access time (non-burst */ \
+ /* static memory) [2..64 Tcpu] */ \
+ ((((Tcpu) - 2)/2) << FShft (MSC_RDN))
+#define MSC_CeilWrAcc(Tcpu) /* Ceil. of WrAcc [2..64 Tcpu] */ \
+ ((((Tcpu) - 1)/2) << FShft (MSC_RDN))
+#define MSC_RRR Fld (3, 13) /* ROM/static memory RecoveRy */
+ /* time/2 [Tmem] */
+#define MSC_Rec(Tcpu) /* Recovery time [0..28 Tcpu] */ \
+ (((Tcpu)/4) << FShft (MSC_RRR))
+#define MSC_CeilRec(Tcpu) /* Ceil. of Rec [0..28 Tcpu] */ \
+ ((((Tcpu) + 3)/4) << FShft (MSC_RRR))
+
+
+/*
+ * Personal Computer Memory Card International Association (PCMCIA) control
+ * register
+ *
+ * Register
+ * MECR Memory system: Expansion memory bus (PCMCIA)
+ * Configuration Register (read/write).
+ *
+ * Clocks
+ * fcpu, Tcpu Frequency, period of the CPU core clock (CCLK).
+ * fmem, Tmem Frequency, period of the memory clock (fmem = fcpu/2).
+ * fbclk, Tbclk Frequency, period of the PCMCIA clock (BCLK).
+ */
+
+ /* Memory system: */
+#define MECR __REG(0xA0000018) /* Expansion memory bus (PCMCIA) Configuration Reg. */
+
+#define MECR_PCMCIA(Nb) /* PCMCIA [0..1] */ \
+ Fld (15, (Nb)*16)
+#define MECR_PCMCIA0 MECR_PCMCIA (0) /* PCMCIA 0 */
+#define MECR_PCMCIA1 MECR_PCMCIA (1) /* PCMCIA 1 */
+
+#define MECR_BSIO Fld (5, 0) /* BCLK Select I/O - 1 [Tmem] */
+#define MECR_IOClk(Tcpu) /* I/O Clock [2..64 Tcpu] */ \
+ ((((Tcpu) - 2)/2) << FShft (MECR_BSIO))
+#define MECR_CeilIOClk(Tcpu) /* Ceil. of IOClk [2..64 Tcpu] */ \
+ ((((Tcpu) - 1)/2) << FShft (MECR_BSIO))
+#define MECR_BSA Fld (5, 5) /* BCLK Select Attribute - 1 */
+ /* [Tmem] */
+#define MECR_AttrClk(Tcpu) /* Attribute Clock [2..64 Tcpu] */ \
+ ((((Tcpu) - 2)/2) << FShft (MECR_BSA))
+#define MECR_CeilAttrClk(Tcpu) /* Ceil. of AttrClk [2..64 Tcpu] */ \
+ ((((Tcpu) - 1)/2) << FShft (MECR_BSA))
+#define MECR_BSM Fld (5, 10) /* BCLK Select Memory - 1 [Tmem] */
+#define MECR_MemClk(Tcpu) /* Memory Clock [2..64 Tcpu] */ \
+ ((((Tcpu) - 2)/2) << FShft (MECR_BSM))
+#define MECR_CeilMemClk(Tcpu) /* Ceil. of MemClk [2..64 Tcpu] */ \
+ ((((Tcpu) - 1)/2) << FShft (MECR_BSM))
+
+/*
+ * On SA1110 only
+ */
+
+#define MDREFR __REG(0xA000001C)
+
+#define MDREFR_TRASR Fld (4, 0)
+#define MDREFR_DRI Fld (12, 4)
+#define MDREFR_E0PIN (1 << 16)
+#define MDREFR_K0RUN (1 << 17)
+#define MDREFR_K0DB2 (1 << 18)
+#define MDREFR_E1PIN (1 << 20)
+#define MDREFR_K1RUN (1 << 21)
+#define MDREFR_K1DB2 (1 << 22)
+#define MDREFR_K2RUN (1 << 25)
+#define MDREFR_K2DB2 (1 << 26)
+#define MDREFR_EAPD (1 << 28)
+#define MDREFR_KAPD (1 << 29)
+#define MDREFR_SLFRSH (1 << 31)
+
+
+/*
+ * Direct Memory Access (DMA) control registers
+ */
+#define DMA_SIZE (6 * 0x20)
+#define DMA_PHYS 0xb0000000
+
+
+/*
+ * Liquid Crystal Display (LCD) control registers
+ *
+ * Registers
+ * LCCR0 Liquid Crystal Display (LCD) Control Register 0
+ * (read/write).
+ * [Bits LDM, BAM, and ERM are only implemented in
+ * versions 2.0 (rev. = 8) and higher of the StrongARM
+ * SA-1100.]
+ * LCSR Liquid Crystal Display (LCD) Status Register
+ * (read/write).
+ * [Bit LDD can be only read in versions 1.0 (rev. = 1)
+ * and 1.1 (rev. = 2) of the StrongARM SA-1100, it can be
+ * read and written (cleared) in versions 2.0 (rev. = 8)
+ * and higher.]
+ * DBAR1 Liquid Crystal Display (LCD) Direct Memory Access
+ * (DMA) Base Address Register channel 1 (read/write).
+ * DCAR1 Liquid Crystal Display (LCD) Direct Memory Access
+ * (DMA) Current Address Register channel 1 (read).
+ * DBAR2 Liquid Crystal Display (LCD) Direct Memory Access
+ * (DMA) Base Address Register channel 2 (read/write).
+ * DCAR2 Liquid Crystal Display (LCD) Direct Memory Access
+ * (DMA) Current Address Register channel 2 (read).
+ * LCCR1 Liquid Crystal Display (LCD) Control Register 1
+ * (read/write).
+ * [The LCCR1 register can be only written in
+ * versions 1.0 (rev. = 1) and 1.1 (rev. = 2) of the
+ * StrongARM SA-1100, it can be written and read in
+ * versions 2.0 (rev. = 8) and higher.]
+ * LCCR2 Liquid Crystal Display (LCD) Control Register 2
+ * (read/write).
+ * [The LCCR1 register can be only written in
+ * versions 1.0 (rev. = 1) and 1.1 (rev. = 2) of the
+ * StrongARM SA-1100, it can be written and read in
+ * versions 2.0 (rev. = 8) and higher.]
+ * LCCR3 Liquid Crystal Display (LCD) Control Register 3
+ * (read/write).
+ * [The LCCR1 register can be only written in
+ * versions 1.0 (rev. = 1) and 1.1 (rev. = 2) of the
+ * StrongARM SA-1100, it can be written and read in
+ * versions 2.0 (rev. = 8) and higher. Bit PCP is only
+ * implemented in versions 2.0 (rev. = 8) and higher of
+ * the StrongARM SA-1100.]
+ *
+ * Clocks
+ * fcpu, Tcpu Frequency, period of the CPU core clock (CCLK).
+ * fmem, Tmem Frequency, period of the memory clock (fmem = fcpu/2).
+ * fpix, Tpix Frequency, period of the pixel clock.
+ * fln, Tln Frequency, period of the line clock.
+ * fac, Tac Frequency, period of the AC bias clock.
+ */
+
+#define LCD_PEntrySp 2 /* LCD Palette Entry Space [byte] */
+#define LCD_4BitPSp /* LCD 4-Bit pixel Palette Space */ \
+ /* [byte] */ \
+ (16*LCD_PEntrySp)
+#define LCD_8BitPSp /* LCD 8-Bit pixel Palette Space */ \
+ /* [byte] */ \
+ (256*LCD_PEntrySp)
+#define LCD_12_16BitPSp /* LCD 12/16-Bit pixel */ \
+ /* dummy-Palette Space [byte] */ \
+ (16*LCD_PEntrySp)
+
+#define LCD_PGrey Fld (4, 0) /* LCD Palette entry Grey value */
+#define LCD_PBlue Fld (4, 0) /* LCD Palette entry Blue value */
+#define LCD_PGreen Fld (4, 4) /* LCD Palette entry Green value */
+#define LCD_PRed Fld (4, 8) /* LCD Palette entry Red value */
+#define LCD_PBS Fld (2, 12) /* LCD Pixel Bit Size */
+#define LCD_4Bit /* LCD 4-Bit pixel mode */ \
+ (0 << FShft (LCD_PBS))
+#define LCD_8Bit /* LCD 8-Bit pixel mode */ \
+ (1 << FShft (LCD_PBS))
+#define LCD_12_16Bit /* LCD 12/16-Bit pixel mode */ \
+ (2 << FShft (LCD_PBS))
+
+#define LCD_Int0_0 0x0 /* LCD Intensity = 0.0% = 0 */
+#define LCD_Int11_1 0x1 /* LCD Intensity = 11.1% = 1/9 */
+#define LCD_Int20_0 0x2 /* LCD Intensity = 20.0% = 1/5 */
+#define LCD_Int26_7 0x3 /* LCD Intensity = 26.7% = 4/15 */
+#define LCD_Int33_3 0x4 /* LCD Intensity = 33.3% = 3/9 */
+#define LCD_Int40_0 0x5 /* LCD Intensity = 40.0% = 2/5 */
+#define LCD_Int44_4 0x6 /* LCD Intensity = 44.4% = 4/9 */
+#define LCD_Int50_0 0x7 /* LCD Intensity = 50.0% = 1/2 */
+#define LCD_Int55_6 0x8 /* LCD Intensity = 55.6% = 5/9 */
+#define LCD_Int60_0 0x9 /* LCD Intensity = 60.0% = 3/5 */
+#define LCD_Int66_7 0xA /* LCD Intensity = 66.7% = 6/9 */
+#define LCD_Int73_3 0xB /* LCD Intensity = 73.3% = 11/15 */
+#define LCD_Int80_0 0xC /* LCD Intensity = 80.0% = 4/5 */
+#define LCD_Int88_9 0xD /* LCD Intensity = 88.9% = 8/9 */
+#define LCD_Int100_0 0xE /* LCD Intensity = 100.0% = 1 */
+#define LCD_Int100_0A 0xF /* LCD Intensity = 100.0% = 1 */
+ /* (Alternative) */
+
+#define LCCR0_LEN 0x00000001 /* LCD ENable */
+#define LCCR0_CMS 0x00000002 /* Color/Monochrome display Select */
+#define LCCR0_Color (LCCR0_CMS*0) /* Color display */
+#define LCCR0_Mono (LCCR0_CMS*1) /* Monochrome display */
+#define LCCR0_SDS 0x00000004 /* Single/Dual panel display */
+ /* Select */
+#define LCCR0_Sngl (LCCR0_SDS*0) /* Single panel display */
+#define LCCR0_Dual (LCCR0_SDS*1) /* Dual panel display */
+#define LCCR0_LDM 0x00000008 /* LCD Disable done (LDD) */
+ /* interrupt Mask (disable) */
+#define LCCR0_BAM 0x00000010 /* Base Address update (BAU) */
+ /* interrupt Mask (disable) */
+#define LCCR0_ERM 0x00000020 /* LCD ERror (BER, IOL, IUL, IOU, */
+ /* IUU, OOL, OUL, OOU, and OUU) */
+ /* interrupt Mask (disable) */
+#define LCCR0_PAS 0x00000080 /* Passive/Active display Select */
+#define LCCR0_Pas (LCCR0_PAS*0) /* Passive display (STN) */
+#define LCCR0_Act (LCCR0_PAS*1) /* Active display (TFT) */
+#define LCCR0_BLE 0x00000100 /* Big/Little Endian select */
+#define LCCR0_LtlEnd (LCCR0_BLE*0) /* Little Endian frame buffer */
+#define LCCR0_BigEnd (LCCR0_BLE*1) /* Big Endian frame buffer */
+#define LCCR0_DPD 0x00000200 /* Double Pixel Data (monochrome */
+ /* display mode) */
+#define LCCR0_4PixMono (LCCR0_DPD*0) /* 4-Pixel/clock Monochrome */
+ /* display */
+#define LCCR0_8PixMono (LCCR0_DPD*1) /* 8-Pixel/clock Monochrome */
+ /* display */
+#define LCCR0_PDD Fld (8, 12) /* Palette DMA request Delay */
+ /* [Tmem] */
+#define LCCR0_DMADel(Tcpu) /* palette DMA request Delay */ \
+ /* [0..510 Tcpu] */ \
+ ((Tcpu)/2 << FShft (LCCR0_PDD))
+
+#define LCSR_LDD 0x00000001 /* LCD Disable Done */
+#define LCSR_BAU 0x00000002 /* Base Address Update (read) */
+#define LCSR_BER 0x00000004 /* Bus ERror */
+#define LCSR_ABC 0x00000008 /* AC Bias clock Count */
+#define LCSR_IOL 0x00000010 /* Input FIFO Over-run Lower */
+ /* panel */
+#define LCSR_IUL 0x00000020 /* Input FIFO Under-run Lower */
+ /* panel */
+#define LCSR_IOU 0x00000040 /* Input FIFO Over-run Upper */
+ /* panel */
+#define LCSR_IUU 0x00000080 /* Input FIFO Under-run Upper */
+ /* panel */
+#define LCSR_OOL 0x00000100 /* Output FIFO Over-run Lower */
+ /* panel */
+#define LCSR_OUL 0x00000200 /* Output FIFO Under-run Lower */
+ /* panel */
+#define LCSR_OOU 0x00000400 /* Output FIFO Over-run Upper */
+ /* panel */
+#define LCSR_OUU 0x00000800 /* Output FIFO Under-run Upper */
+ /* panel */
+
+#define LCCR1_PPL Fld (6, 4) /* Pixels Per Line/16 - 1 */
+#define LCCR1_DisWdth(Pixel) /* Display Width [16..1024 pix.] */ \
+ (((Pixel) - 16)/16 << FShft (LCCR1_PPL))
+#define LCCR1_HSW Fld (6, 10) /* Horizontal Synchronization */
+ /* pulse Width - 1 [Tpix] (L_LCLK) */
+#define LCCR1_HorSnchWdth(Tpix) /* Horizontal Synchronization */ \
+ /* pulse Width [1..64 Tpix] */ \
+ (((Tpix) - 1) << FShft (LCCR1_HSW))
+#define LCCR1_ELW Fld (8, 16) /* End-of-Line pixel clock Wait */
+ /* count - 1 [Tpix] */
+#define LCCR1_EndLnDel(Tpix) /* End-of-Line Delay */ \
+ /* [1..256 Tpix] */ \
+ (((Tpix) - 1) << FShft (LCCR1_ELW))
+#define LCCR1_BLW Fld (8, 24) /* Beginning-of-Line pixel clock */
+ /* Wait count - 1 [Tpix] */
+#define LCCR1_BegLnDel(Tpix) /* Beginning-of-Line Delay */ \
+ /* [1..256 Tpix] */ \
+ (((Tpix) - 1) << FShft (LCCR1_BLW))
+
+#define LCCR2_LPP Fld (10, 0) /* Line Per Panel - 1 */
+#define LCCR2_DisHght(Line) /* Display Height [1..1024 lines] */ \
+ (((Line) - 1) << FShft (LCCR2_LPP))
+#define LCCR2_VSW Fld (6, 10) /* Vertical Synchronization pulse */
+ /* Width - 1 [Tln] (L_FCLK) */
+#define LCCR2_VrtSnchWdth(Tln) /* Vertical Synchronization pulse */ \
+ /* Width [1..64 Tln] */ \
+ (((Tln) - 1) << FShft (LCCR2_VSW))
+#define LCCR2_EFW Fld (8, 16) /* End-of-Frame line clock Wait */
+ /* count [Tln] */
+#define LCCR2_EndFrmDel(Tln) /* End-of-Frame Delay */ \
+ /* [0..255 Tln] */ \
+ ((Tln) << FShft (LCCR2_EFW))
+#define LCCR2_BFW Fld (8, 24) /* Beginning-of-Frame line clock */
+ /* Wait count [Tln] */
+#define LCCR2_BegFrmDel(Tln) /* Beginning-of-Frame Delay */ \
+ /* [0..255 Tln] */ \
+ ((Tln) << FShft (LCCR2_BFW))
+
+#define LCCR3_PCD Fld (8, 0) /* Pixel Clock Divisor/2 - 2 */
+ /* [1..255] (L_PCLK) */
+ /* fpix = fcpu/(2*(PCD + 2)) */
+ /* Tpix = 2*(PCD + 2)*Tcpu */
+#define LCCR3_PixClkDiv(Div) /* Pixel Clock Divisor [6..514] */ \
+ (((Div) - 4)/2 << FShft (LCCR3_PCD))
+ /* fpix = fcpu/(2*Floor (Div/2)) */
+ /* Tpix = 2*Floor (Div/2)*Tcpu */
+#define LCCR3_CeilPixClkDiv(Div) /* Ceil. of PixClkDiv [6..514] */ \
+ (((Div) - 3)/2 << FShft (LCCR3_PCD))
+ /* fpix = fcpu/(2*Ceil (Div/2)) */
+ /* Tpix = 2*Ceil (Div/2)*Tcpu */
+#define LCCR3_ACB Fld (8, 8) /* AC Bias clock half period - 1 */
+ /* [Tln] (L_BIAS) */
+#define LCCR3_ACBsDiv(Div) /* AC Bias clock Divisor [2..512] */ \
+ (((Div) - 2)/2 << FShft (LCCR3_ACB))
+ /* fac = fln/(2*Floor (Div/2)) */
+ /* Tac = 2*Floor (Div/2)*Tln */
+#define LCCR3_CeilACBsDiv(Div) /* Ceil. of ACBsDiv [2..512] */ \
+ (((Div) - 1)/2 << FShft (LCCR3_ACB))
+ /* fac = fln/(2*Ceil (Div/2)) */
+ /* Tac = 2*Ceil (Div/2)*Tln */
+#define LCCR3_API Fld (4, 16) /* AC bias Pin transitions per */
+ /* Interrupt */
+#define LCCR3_ACBsCntOff /* AC Bias clock transition Count */ \
+ /* Off */ \
+ (0 << FShft (LCCR3_API))
+#define LCCR3_ACBsCnt(Trans) /* AC Bias clock transition Count */ \
+ /* [1..15] */ \
+ ((Trans) << FShft (LCCR3_API))
+#define LCCR3_VSP 0x00100000 /* Vertical Synchronization pulse */
+ /* Polarity (L_FCLK) */
+#define LCCR3_VrtSnchH (LCCR3_VSP*0) /* Vertical Synchronization pulse */
+ /* active High */
+#define LCCR3_VrtSnchL (LCCR3_VSP*1) /* Vertical Synchronization pulse */
+ /* active Low */
+#define LCCR3_HSP 0x00200000 /* Horizontal Synchronization */
+ /* pulse Polarity (L_LCLK) */
+#define LCCR3_HorSnchH (LCCR3_HSP*0) /* Horizontal Synchronization */
+ /* pulse active High */
+#define LCCR3_HorSnchL (LCCR3_HSP*1) /* Horizontal Synchronization */
+ /* pulse active Low */
+#define LCCR3_PCP 0x00400000 /* Pixel Clock Polarity (L_PCLK) */
+#define LCCR3_PixRsEdg (LCCR3_PCP*0) /* Pixel clock Rising-Edge */
+#define LCCR3_PixFlEdg (LCCR3_PCP*1) /* Pixel clock Falling-Edge */
+#define LCCR3_OEP 0x00800000 /* Output Enable Polarity (L_BIAS, */
+ /* active display mode) */
+#define LCCR3_OutEnH (LCCR3_OEP*0) /* Output Enable active High */
+#define LCCR3_OutEnL (LCCR3_OEP*1) /* Output Enable active Low */
diff --git a/arch/arm/mach-sa1100/include/mach/assabet.h b/arch/arm/mach-sa1100/include/mach/assabet.h
new file mode 100644
index 000000000..641a96165
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/assabet.h
@@ -0,0 +1,99 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * arch/arm/mach-sa1100/include/mach/assabet.h
+ *
+ * Created 2000/06/05 by Nicolas Pitre <nico@fluxnic.net>
+ *
+ * This file contains the hardware specific definitions for Assabet
+ * Only include this file from SA1100-specific files.
+ *
+ * 2000/05/23 John Dorsey <john+@cs.cmu.edu>
+ * Definitions for Neponset added.
+ */
+#ifndef __ASM_ARCH_ASSABET_H
+#define __ASM_ARCH_ASSABET_H
+
+
+/* System Configuration Register flags */
+
+#define ASSABET_SCR_SDRAM_LOW (1<<2) /* SDRAM size (low bit) */
+#define ASSABET_SCR_SDRAM_HIGH (1<<3) /* SDRAM size (high bit) */
+#define ASSABET_SCR_FLASH_LOW (1<<4) /* Flash size (low bit) */
+#define ASSABET_SCR_FLASH_HIGH (1<<5) /* Flash size (high bit) */
+#define ASSABET_SCR_GFX (1<<8) /* Graphics Accelerator (0 = present) */
+#define ASSABET_SCR_SA1111 (1<<9) /* Neponset (0 = present) */
+
+#define ASSABET_SCR_INIT -1
+
+extern unsigned long SCR_value;
+
+#ifdef CONFIG_ASSABET_NEPONSET
+#define machine_has_neponset() ((SCR_value & ASSABET_SCR_SA1111) == 0)
+#else
+#define machine_has_neponset() (0)
+#endif
+
+/* Board Control Register */
+
+#define ASSABET_BCR_BASE 0xf1000000
+#define ASSABET_BCR (*(volatile unsigned int *)(ASSABET_BCR_BASE))
+
+#define ASSABET_BCR_CF_PWR (1<<0) /* Compact Flash Power (1 = 3.3v, 0 = off) */
+#define ASSABET_BCR_CF_RST (1<<1) /* Compact Flash Reset (1 = power up reset) */
+#define ASSABET_BCR_NGFX_RST (1<<1) /* Graphics Accelerator Reset (0 = hold reset) */
+#define ASSABET_BCR_NCODEC_RST (1<<2) /* 0 = Holds UCB1300, ADI7171, and UDA1341 in reset */
+#define ASSABET_BCR_IRDA_FSEL (1<<3) /* IRDA Frequency select (0 = SIR, 1 = MIR/ FIR) */
+#define ASSABET_BCR_IRDA_MD0 (1<<4) /* Range/Power select */
+#define ASSABET_BCR_IRDA_MD1 (1<<5) /* Range/Power select */
+#define ASSABET_BCR_STEREO_LB (1<<6) /* Stereo Loopback */
+#define ASSABET_BCR_CF_BUS_OFF (1<<7) /* Compact Flash bus (0 = on, 1 = off (float)) */
+#define ASSABET_BCR_AUDIO_ON (1<<8) /* Audio power on */
+#define ASSABET_BCR_LIGHT_ON (1<<9) /* Backlight */
+#define ASSABET_BCR_LCD_12RGB (1<<10) /* 0 = 16RGB, 1 = 12RGB */
+#define ASSABET_BCR_LCD_ON (1<<11) /* LCD power on */
+#define ASSABET_BCR_RS232EN (1<<12) /* RS232 transceiver enable */
+#define ASSABET_BCR_LED_RED (1<<13) /* D9 (0 = on, 1 = off) */
+#define ASSABET_BCR_LED_GREEN (1<<14) /* D8 (0 = on, 1 = off) */
+#define ASSABET_BCR_VIB_ON (1<<15) /* Vibration motor (quiet alert) */
+#define ASSABET_BCR_COM_DTR (1<<16) /* COMport Data Terminal Ready */
+#define ASSABET_BCR_COM_RTS (1<<17) /* COMport Request To Send */
+#define ASSABET_BCR_RAD_WU (1<<18) /* Radio wake up interrupt */
+#define ASSABET_BCR_SMB_EN (1<<19) /* System management bus enable */
+#define ASSABET_BCR_TV_IR_DEC (1<<20) /* TV IR Decode Enable (not implemented) */
+#define ASSABET_BCR_QMUTE (1<<21) /* Quick Mute */
+#define ASSABET_BCR_RAD_ON (1<<22) /* Radio Power On */
+#define ASSABET_BCR_SPK_OFF (1<<23) /* 1 = Speaker amplifier power off */
+
+#ifdef CONFIG_SA1100_ASSABET
+extern void ASSABET_BCR_frob(unsigned int mask, unsigned int set);
+#else
+#define ASSABET_BCR_frob(x,y) do { } while (0)
+#endif
+
+extern void assabet_uda1341_reset(int set);
+
+#define ASSABET_BCR_set(x) ASSABET_BCR_frob((x), (x))
+#define ASSABET_BCR_clear(x) ASSABET_BCR_frob((x), 0)
+
+#define ASSABET_BSR_BASE 0xf1000000
+#define ASSABET_BSR (*(volatile unsigned int*)(ASSABET_BSR_BASE))
+
+#define ASSABET_BSR_RS232_VALID (1 << 24)
+#define ASSABET_BSR_COM_DCD (1 << 25)
+#define ASSABET_BSR_COM_CTS (1 << 26)
+#define ASSABET_BSR_COM_DSR (1 << 27)
+#define ASSABET_BSR_RAD_CTS (1 << 28)
+#define ASSABET_BSR_RAD_DSR (1 << 29)
+#define ASSABET_BSR_RAD_DCD (1 << 30)
+#define ASSABET_BSR_RAD_RI (1 << 31)
+
+
+/* GPIOs (bitmasks) for which the generic definition doesn't say much */
+#define ASSABET_GPIO_RADIO_IRQ GPIO_GPIO (14) /* Radio interrupt request */
+#define ASSABET_GPIO_PS_MODE_SYNC GPIO_GPIO (16) /* Power supply mode/sync */
+#define ASSABET_GPIO_STEREO_64FS_CLK GPIO_GPIO (19) /* SSP UDA1341 clock input */
+#define ASSABET_GPIO_GFX_IRQ GPIO_GPIO (24) /* Graphics IRQ */
+#define ASSABET_GPIO_BATT_LOW GPIO_GPIO (26) /* Low battery */
+#define ASSABET_GPIO_RCLK GPIO_GPIO (26) /* CCLK/2 */
+
+#endif
diff --git a/arch/arm/mach-sa1100/include/mach/bitfield.h b/arch/arm/mach-sa1100/include/mach/bitfield.h
new file mode 100644
index 000000000..f1f0e3387
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/bitfield.h
@@ -0,0 +1,113 @@
+/*
+ * FILE bitfield.h
+ *
+ * Version 1.1
+ * Author Copyright (c) Marc A. Viredaz, 1998
+ * DEC Western Research Laboratory, Palo Alto, CA
+ * Date April 1998 (April 1997)
+ * System Advanced RISC Machine (ARM)
+ * Language C or ARM Assembly
+ * Purpose Definition of macros to operate on bit fields.
+ */
+
+
+
+#ifndef __BITFIELD_H
+#define __BITFIELD_H
+
+#ifndef __ASSEMBLY__
+#define UData(Data) ((unsigned long) (Data))
+#else
+#define UData(Data) (Data)
+#endif
+
+
+/*
+ * MACRO: Fld
+ *
+ * Purpose
+ * The macro "Fld" encodes a bit field, given its size and its shift value
+ * with respect to bit 0.
+ *
+ * Note
+ * A more intuitive way to encode bit fields would have been to use their
+ * mask. However, extracting size and shift value information from a bit
+ * field's mask is cumbersome and might break the assembler (255-character
+ * line-size limit).
+ *
+ * Input
+ * Size Size of the bit field, in number of bits.
+ * Shft Shift value of the bit field with respect to bit 0.
+ *
+ * Output
+ * Fld Encoded bit field.
+ */
+
+#define Fld(Size, Shft) (((Size) << 16) + (Shft))
+
+
+/*
+ * MACROS: FSize, FShft, FMsk, FAlnMsk, F1stBit
+ *
+ * Purpose
+ * The macros "FSize", "FShft", "FMsk", "FAlnMsk", and "F1stBit" return
+ * the size, shift value, mask, aligned mask, and first bit of a
+ * bit field.
+ *
+ * Input
+ * Field Encoded bit field (using the macro "Fld").
+ *
+ * Output
+ * FSize Size of the bit field, in number of bits.
+ * FShft Shift value of the bit field with respect to bit 0.
+ * FMsk Mask for the bit field.
+ * FAlnMsk Mask for the bit field, aligned on bit 0.
+ * F1stBit First bit of the bit field.
+ */
+
+#define FSize(Field) ((Field) >> 16)
+#define FShft(Field) ((Field) & 0x0000FFFF)
+#define FMsk(Field) (((UData (1) << FSize (Field)) - 1) << FShft (Field))
+#define FAlnMsk(Field) ((UData (1) << FSize (Field)) - 1)
+#define F1stBit(Field) (UData (1) << FShft (Field))
+
+
+/*
+ * MACRO: FInsrt
+ *
+ * Purpose
+ * The macro "FInsrt" inserts a value into a bit field by shifting the
+ * former appropriately.
+ *
+ * Input
+ * Value Bit-field value.
+ * Field Encoded bit field (using the macro "Fld").
+ *
+ * Output
+ * FInsrt Bit-field value positioned appropriately.
+ */
+
+#define FInsrt(Value, Field) \
+ (UData (Value) << FShft (Field))
+
+
+/*
+ * MACRO: FExtr
+ *
+ * Purpose
+ * The macro "FExtr" extracts the value of a bit field by masking and
+ * shifting it appropriately.
+ *
+ * Input
+ * Data Data containing the bit-field to be extracted.
+ * Field Encoded bit field (using the macro "Fld").
+ *
+ * Output
+ * FExtr Bit-field value.
+ */
+
+#define FExtr(Data, Field) \
+ ((UData (Data) >> FShft (Field)) & FAlnMsk (Field))
+
+
+#endif /* __BITFIELD_H */
diff --git a/arch/arm/mach-sa1100/include/mach/collie.h b/arch/arm/mach-sa1100/include/mach/collie.h
new file mode 100644
index 000000000..c95273c95
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/collie.h
@@ -0,0 +1,94 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * arch/arm/mach-sa1100/include/mach/collie.h
+ *
+ * This file contains the hardware specific definitions for Collie
+ * Only include this file from SA1100-specific files.
+ *
+ * ChangeLog:
+ * 04-06-2001 Lineo Japan, Inc.
+ * 04-16-2001 SHARP Corporation
+ * 07-07-2002 Chris Larson <clarson@digi.com>
+ *
+ */
+#ifndef __ASM_ARCH_COLLIE_H
+#define __ASM_ARCH_COLLIE_H
+
+#include "hardware.h" /* Gives GPIO_MAX */
+
+#define COLLIE_SCOOP_GPIO_BASE (GPIO_MAX + 1)
+#define COLLIE_GPIO_CHARGE_ON (COLLIE_SCOOP_GPIO_BASE + 0)
+#define COLLIE_SCP_DIAG_BOOT1 SCOOP_GPCR_PA12
+#define COLLIE_SCP_DIAG_BOOT2 SCOOP_GPCR_PA13
+#define COLLIE_SCP_MUTE_L SCOOP_GPCR_PA14
+#define COLLIE_SCP_MUTE_R SCOOP_GPCR_PA15
+#define COLLIE_SCP_5VON SCOOP_GPCR_PA16
+#define COLLIE_SCP_AMP_ON SCOOP_GPCR_PA17
+#define COLLIE_GPIO_VPEN (COLLIE_SCOOP_GPIO_BASE + 7)
+#define COLLIE_SCP_LB_VOL_CHG SCOOP_GPCR_PA19
+
+#define COLLIE_SCOOP_IO_DIR (COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R | \
+ COLLIE_SCP_5VON | COLLIE_SCP_AMP_ON | \
+ COLLIE_SCP_LB_VOL_CHG)
+#define COLLIE_SCOOP_IO_OUT (COLLIE_SCP_MUTE_L | COLLIE_SCP_MUTE_R)
+
+/* GPIOs for gpiolib */
+
+#define COLLIE_GPIO_ON_KEY (0)
+#define COLLIE_GPIO_AC_IN (1)
+#define COLLIE_GPIO_SDIO_INT (11)
+#define COLLIE_GPIO_CF_IRQ (14)
+#define COLLIE_GPIO_nREMOCON_INT (15)
+#define COLLIE_GPIO_UCB1x00_RESET (16)
+#define COLLIE_GPIO_nMIC_ON (17)
+#define COLLIE_GPIO_nREMOCON_ON (18)
+#define COLLIE_GPIO_CO (20)
+#define COLLIE_GPIO_MCP_CLK (21)
+#define COLLIE_GPIO_CF_CD (22)
+#define COLLIE_GPIO_UCB1x00_IRQ (23)
+#define COLLIE_GPIO_WAKEUP (24)
+#define COLLIE_GPIO_GA_INT (25)
+#define COLLIE_GPIO_MAIN_BAT_LOW (26)
+
+/* GPIO definitions for direct register access */
+
+#define _COLLIE_GPIO_ON_KEY GPIO_GPIO(0)
+#define _COLLIE_GPIO_AC_IN GPIO_GPIO(1)
+#define _COLLIE_GPIO_nREMOCON_INT GPIO_GPIO(15)
+#define _COLLIE_GPIO_UCB1x00_RESET GPIO_GPIO(16)
+#define _COLLIE_GPIO_nMIC_ON GPIO_GPIO(17)
+#define _COLLIE_GPIO_nREMOCON_ON GPIO_GPIO(18)
+#define _COLLIE_GPIO_CO GPIO_GPIO(20)
+#define _COLLIE_GPIO_WAKEUP GPIO_GPIO(24)
+/* Interrupts */
+
+#define COLLIE_IRQ_GPIO_ON_KEY IRQ_GPIO0
+#define COLLIE_IRQ_GPIO_AC_IN IRQ_GPIO1
+#define COLLIE_IRQ_GPIO_SDIO_IRQ IRQ_GPIO11
+#define COLLIE_IRQ_GPIO_CF_IRQ IRQ_GPIO14
+#define COLLIE_IRQ_GPIO_nREMOCON_INT IRQ_GPIO15
+#define COLLIE_IRQ_GPIO_CO IRQ_GPIO20
+#define COLLIE_IRQ_GPIO_CF_CD IRQ_GPIO22
+#define COLLIE_IRQ_GPIO_UCB1x00_IRQ IRQ_GPIO23
+#define COLLIE_IRQ_GPIO_WAKEUP IRQ_GPIO24
+#define COLLIE_IRQ_GPIO_GA_INT IRQ_GPIO25
+#define COLLIE_IRQ_GPIO_MAIN_BAT_LOW IRQ_GPIO26
+
+/* GPIO's on the TC35143AF (Toshiba Analog Frontend) */
+#define COLLIE_TC35143_GPIO_BASE (GPIO_MAX + 13)
+#define COLLIE_TC35143_GPIO_VERSION0 UCB_IO_0
+#define COLLIE_TC35143_GPIO_TBL_CHK UCB_IO_1
+#define COLLIE_TC35143_GPIO_VPEN_ON UCB_IO_2
+#define COLLIE_GPIO_IR_ON (COLLIE_TC35143_GPIO_BASE + 3)
+#define COLLIE_TC35143_GPIO_AMP_ON UCB_IO_4
+#define COLLIE_TC35143_GPIO_VERSION1 UCB_IO_5
+#define COLLIE_TC35143_GPIO_FS8KLPF UCB_IO_5
+#define COLLIE_TC35143_GPIO_BUZZER_BIAS UCB_IO_6
+#define COLLIE_GPIO_MBAT_ON (COLLIE_TC35143_GPIO_BASE + 7)
+#define COLLIE_GPIO_BBAT_ON (COLLIE_TC35143_GPIO_BASE + 8)
+#define COLLIE_GPIO_TMP_ON (COLLIE_TC35143_GPIO_BASE + 9)
+#define COLLIE_TC35143_GPIO_IN (UCB_IO_0 | UCB_IO_2 | UCB_IO_5)
+#define COLLIE_TC35143_GPIO_OUT (UCB_IO_1 | UCB_IO_3 | UCB_IO_4 \
+ | UCB_IO_6)
+
+#endif
diff --git a/arch/arm/mach-sa1100/include/mach/generic.h b/arch/arm/mach-sa1100/include/mach/generic.h
new file mode 100644
index 000000000..665542e0c
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/generic.h
@@ -0,0 +1 @@
+#include "../../generic.h"
diff --git a/arch/arm/mach-sa1100/include/mach/h3xxx.h b/arch/arm/mach-sa1100/include/mach/h3xxx.h
new file mode 100644
index 000000000..0ee2578e0
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/h3xxx.h
@@ -0,0 +1,81 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Definitions for Compaq iPAQ H3100 and H3600 handheld computers
+ *
+ * (c) 2000 Compaq Computer Corporation. (Author: Jamey Hicks)
+ * (c) 2009 Dmitry Artamonow <mad_soft@inbox.ru>
+ */
+
+#ifndef _INCLUDE_H3XXX_H_
+#define _INCLUDE_H3XXX_H_
+
+#include "hardware.h" /* Gives GPIO_MAX */
+
+/* Physical memory regions corresponding to chip selects */
+#define H3600_EGPIO_PHYS (SA1100_CS5_PHYS + 0x01000000)
+#define H3600_BANK_2_PHYS SA1100_CS2_PHYS
+#define H3600_BANK_4_PHYS SA1100_CS4_PHYS
+
+/* Virtual memory regions corresponding to chip selects 2 & 4 (used on sleeves) */
+#define H3600_EGPIO_VIRT 0xf0000000
+#define H3600_BANK_2_VIRT 0xf1000000
+#define H3600_BANK_4_VIRT 0xf3800000
+
+/*
+ * gpiolib numbers for all iPAQs
+ */
+#define H3XXX_GPIO_PWR_BUTTON 0
+#define H3XXX_GPIO_PCMCIA_CD1 10
+#define H3XXX_GPIO_PCMCIA_IRQ1 11
+#define H3XXX_GPIO_PCMCIA_CD0 17
+#define H3XXX_GPIO_ACTION_BUTTON 18
+#define H3XXX_GPIO_SYS_CLK 19
+#define H3XXX_GPIO_PCMCIA_IRQ0 21
+#define H3XXX_GPIO_COM_DCD 23
+#define H3XXX_GPIO_OPTION 24
+#define H3XXX_GPIO_COM_CTS 25
+#define H3XXX_GPIO_COM_RTS 26
+
+/* machine-specific gpios */
+
+#define H3100_GPIO_BT_ON 2
+#define H3100_GPIO_QMUTE 4
+#define H3100_GPIO_LCD_3V_ON 5
+#define H3100_GPIO_AUD_ON 6
+#define H3100_GPIO_AUD_PWR_ON 7
+#define H3100_GPIO_IR_ON 8
+#define H3100_GPIO_IR_FSEL 9
+
+#define H3600_GPIO_CLK_SET0 12 /* audio sample rate clock generator */
+#define H3600_GPIO_CLK_SET1 13
+#define H3600_GPIO_SOFT_RESET 20 /* also known as BATT_FAULT */
+#define H3600_GPIO_OPT_LOCK 22
+#define H3600_GPIO_OPT_DET 27
+
+
+/* H3100 / 3600 EGPIO pins */
+#define H3XXX_EGPIO_BASE (GPIO_MAX + 1)
+
+#define H3XXX_EGPIO_VPP_ON (H3XXX_EGPIO_BASE + 0)
+#define H3XXX_EGPIO_CARD_RESET (H3XXX_EGPIO_BASE + 1) /* reset the attached pcmcia/compactflash card. active high. */
+#define H3XXX_EGPIO_OPT_RESET (H3XXX_EGPIO_BASE + 2) /* reset the attached option pack. active high. */
+#define H3XXX_EGPIO_CODEC_NRESET (H3XXX_EGPIO_BASE + 3) /* reset the onboard UDA1341. active low. */
+#define H3XXX_EGPIO_OPT_NVRAM_ON (H3XXX_EGPIO_BASE + 4) /* apply power to optionpack nvram, active high. */
+#define H3XXX_EGPIO_OPT_ON (H3XXX_EGPIO_BASE + 5) /* full power to option pack. active high. */
+#define H3XXX_EGPIO_LCD_ON (H3XXX_EGPIO_BASE + 6) /* enable 3.3V to LCD. active high. */
+#define H3XXX_EGPIO_RS232_ON (H3XXX_EGPIO_BASE + 7) /* UART3 transceiver force on. Active high. */
+
+/* H3600 only EGPIO pins */
+#define H3600_EGPIO_LCD_PCI (H3XXX_EGPIO_BASE + 8) /* LCD control IC enable. active high. */
+#define H3600_EGPIO_IR_ON (H3XXX_EGPIO_BASE + 9) /* apply power to IR module. active high. */
+#define H3600_EGPIO_AUD_AMP_ON (H3XXX_EGPIO_BASE + 10) /* apply power to audio power amp. active high. */
+#define H3600_EGPIO_AUD_PWR_ON (H3XXX_EGPIO_BASE + 11) /* apply power to reset of audio circuit. active high. */
+#define H3600_EGPIO_QMUTE (H3XXX_EGPIO_BASE + 12) /* mute control for onboard UDA1341. active high. */
+#define H3600_EGPIO_IR_FSEL (H3XXX_EGPIO_BASE + 13) /* IR speed select: 1->fast, 0->slow */
+#define H3600_EGPIO_LCD_5V_ON (H3XXX_EGPIO_BASE + 14) /* enable 5V to LCD. active high. */
+#define H3600_EGPIO_LVDD_ON (H3XXX_EGPIO_BASE + 15) /* enable 9V and -6.5V to LCD. */
+
+void __init h3xxx_map_io(void);
+void __init h3xxx_mach_init(void);
+
+#endif /* _INCLUDE_H3XXX_H_ */
diff --git a/arch/arm/mach-sa1100/include/mach/hardware.h b/arch/arm/mach-sa1100/include/mach/hardware.h
new file mode 100644
index 000000000..6f2dbdc28
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/hardware.h
@@ -0,0 +1,56 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * arch/arm/mach-sa1100/include/mach/hardware.h
+ *
+ * Copyright (C) 1998 Nicolas Pitre <nico@fluxnic.net>
+ *
+ * This file contains the hardware definitions for SA1100 architecture
+ *
+ * 2000/05/23 John Dorsey <john+@cs.cmu.edu>
+ * Definitions for SA1111 added.
+ */
+
+#ifndef __ASM_ARCH_HARDWARE_H
+#define __ASM_ARCH_HARDWARE_H
+
+
+#define UNCACHEABLE_ADDR 0xfa050000 /* ICIP */
+
+
+/*
+ * SA1100 internal I/O mappings
+ *
+ * We have the following mapping:
+ * phys virt
+ * 80000000 f8000000
+ * 90000000 fa000000
+ * a0000000 fc000000
+ * b0000000 fe000000
+ */
+
+#define VIO_BASE 0xf8000000 /* virtual start of IO space */
+#define VIO_SHIFT 3 /* x = IO space shrink power */
+#define PIO_START 0x80000000 /* physical start of IO space */
+
+#define io_p2v( x ) \
+ IOMEM( (((x)&0x00ffffff) | (((x)&0x30000000)>>VIO_SHIFT)) + VIO_BASE )
+#define io_v2p( x ) \
+ ( (((x)&0x00ffffff) | (((x)&(0x30000000>>VIO_SHIFT))<<VIO_SHIFT)) + PIO_START )
+
+#define __MREG(x) IOMEM(io_p2v(x))
+
+#ifndef __ASSEMBLY__
+
+# define __REG(x) (*((volatile unsigned long __iomem *)io_p2v(x)))
+# define __PREG(x) (io_v2p((unsigned long)&(x)))
+
+#else
+
+# define __REG(x) io_p2v(x)
+# define __PREG(x) io_v2p(x)
+
+#endif
+
+#include "SA-1100.h"
+
+#endif /* _ASM_ARCH_HARDWARE_H */
diff --git a/arch/arm/mach-sa1100/include/mach/irqs.h b/arch/arm/mach-sa1100/include/mach/irqs.h
new file mode 100644
index 000000000..f4a41e665
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/irqs.h
@@ -0,0 +1,101 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * arch/arm/mach-sa1100/include/mach/irqs.h
+ *
+ * Copyright (C) 1996 Russell King
+ * Copyright (C) 1998 Deborah Wallach (updates for SA1100/Brutus).
+ * Copyright (C) 1999 Nicolas Pitre (full GPIO irq isolation)
+ *
+ * 2001/11/14 RMK Cleaned up and standardised a lot of the IRQs.
+ */
+
+#define IRQ_GPIO0_SC 1
+#define IRQ_GPIO1_SC 2
+#define IRQ_GPIO2_SC 3
+#define IRQ_GPIO3_SC 4
+#define IRQ_GPIO4_SC 5
+#define IRQ_GPIO5_SC 6
+#define IRQ_GPIO6_SC 7
+#define IRQ_GPIO7_SC 8
+#define IRQ_GPIO8_SC 9
+#define IRQ_GPIO9_SC 10
+#define IRQ_GPIO10_SC 11
+#define IRQ_GPIO11_27 12
+#define IRQ_LCD 13 /* LCD controller */
+#define IRQ_Ser0UDC 14 /* Ser. port 0 UDC */
+#define IRQ_Ser1SDLC 15 /* Ser. port 1 SDLC */
+#define IRQ_Ser1UART 16 /* Ser. port 1 UART */
+#define IRQ_Ser2ICP 17 /* Ser. port 2 ICP */
+#define IRQ_Ser3UART 18 /* Ser. port 3 UART */
+#define IRQ_Ser4MCP 19 /* Ser. port 4 MCP */
+#define IRQ_Ser4SSP 20 /* Ser. port 4 SSP */
+#define IRQ_DMA0 21 /* DMA controller channel 0 */
+#define IRQ_DMA1 22 /* DMA controller channel 1 */
+#define IRQ_DMA2 23 /* DMA controller channel 2 */
+#define IRQ_DMA3 24 /* DMA controller channel 3 */
+#define IRQ_DMA4 25 /* DMA controller channel 4 */
+#define IRQ_DMA5 26 /* DMA controller channel 5 */
+#define IRQ_OST0 27 /* OS Timer match 0 */
+#define IRQ_OST1 28 /* OS Timer match 1 */
+#define IRQ_OST2 29 /* OS Timer match 2 */
+#define IRQ_OST3 30 /* OS Timer match 3 */
+#define IRQ_RTC1Hz 31 /* RTC 1 Hz clock */
+#define IRQ_RTCAlrm 32 /* RTC Alarm */
+
+#define IRQ_GPIO0 33
+#define IRQ_GPIO1 34
+#define IRQ_GPIO2 35
+#define IRQ_GPIO3 36
+#define IRQ_GPIO4 37
+#define IRQ_GPIO5 38
+#define IRQ_GPIO6 39
+#define IRQ_GPIO7 40
+#define IRQ_GPIO8 41
+#define IRQ_GPIO9 42
+#define IRQ_GPIO10 43
+#define IRQ_GPIO11 44
+#define IRQ_GPIO12 45
+#define IRQ_GPIO13 46
+#define IRQ_GPIO14 47
+#define IRQ_GPIO15 48
+#define IRQ_GPIO16 49
+#define IRQ_GPIO17 50
+#define IRQ_GPIO18 51
+#define IRQ_GPIO19 52
+#define IRQ_GPIO20 53
+#define IRQ_GPIO21 54
+#define IRQ_GPIO22 55
+#define IRQ_GPIO23 56
+#define IRQ_GPIO24 57
+#define IRQ_GPIO25 58
+#define IRQ_GPIO26 59
+#define IRQ_GPIO27 60
+
+/*
+ * 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 IRQ_BOARD_END, but keep it
+ * within sensible limits. IRQs 61 to 76 are available.
+ */
+#define IRQ_BOARD_START 61
+#define IRQ_BOARD_END 77
+
+/*
+ * Figure out the MAX IRQ number.
+ *
+ * Neponset, SA1111 and UCB1x00 are sparse IRQ aware, so can dynamically
+ * allocate their IRQs above NR_IRQS.
+ *
+ * LoCoMo has 4 additional IRQs, but is not sparse IRQ aware, and so has
+ * to be included in the NR_IRQS calculation.
+ */
+#ifdef CONFIG_SHARP_LOCOMO
+#define NR_IRQS_LOCOMO 4
+#else
+#define NR_IRQS_LOCOMO 0
+#endif
+
+#ifndef NR_IRQS
+#define NR_IRQS (IRQ_BOARD_START + NR_IRQS_LOCOMO)
+#endif
+#define SA1100_NR_IRQS (IRQ_BOARD_START + NR_IRQS_LOCOMO)
diff --git a/arch/arm/mach-sa1100/include/mach/jornada720.h b/arch/arm/mach-sa1100/include/mach/jornada720.h
new file mode 100644
index 000000000..bb22fcab8
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/jornada720.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * arch/arm/mach-sa1100/include/mach/jornada720.h
+ *
+ * SSP/MCU communication definitions for HP Jornada 710/720/728
+ *
+ * Copyright 2007,2008 Kristoffer Ericson <Kristoffer.Ericson@gmail.com>
+ * Copyright 2000 John Ankcorn <jca@lcs.mit.edu>
+ */
+
+ /* HP Jornada 7xx microprocessor commands */
+#define GETBATTERYDATA 0xc0
+#define GETSCANKEYCODE 0x90
+#define GETTOUCHSAMPLES 0xa0
+#define GETCONTRAST 0xD0
+#define SETCONTRAST 0xD1
+#define GETBRIGHTNESS 0xD2
+#define SETBRIGHTNESS 0xD3
+#define CONTRASTOFF 0xD8
+#define BRIGHTNESSOFF 0xD9
+#define PWMOFF 0xDF
+#define TXDUMMY 0x11
+#define ERRORCODE 0x00
+
+extern void jornada_ssp_start(void);
+extern void jornada_ssp_end(void);
+extern int jornada_ssp_inout(u8 byte);
+extern int jornada_ssp_byte(u8 byte);
diff --git a/arch/arm/mach-sa1100/include/mach/memory.h b/arch/arm/mach-sa1100/include/mach/memory.h
new file mode 100644
index 000000000..3b19296f5
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/memory.h
@@ -0,0 +1,37 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * arch/arm/mach-sa1100/include/mach/memory.h
+ *
+ * Copyright (C) 1999-2000 Nicolas Pitre <nico@fluxnic.net>
+ */
+
+#ifndef __ASM_ARCH_MEMORY_H
+#define __ASM_ARCH_MEMORY_H
+
+#include <linux/sizes.h>
+
+/*
+ * Because of the wide memory address space between physical RAM banks on the
+ * SA1100, it's much convenient to use Linux's SparseMEM support to implement
+ * our memory map representation. Assuming all memory nodes have equal access
+ * characteristics, we then have generic discontiguous memory support.
+ *
+ * The sparsemem banks are matched with the physical memory bank addresses
+ * which are incidentally the same as virtual addresses.
+ *
+ * node 0: 0xc0000000 - 0xc7ffffff
+ * node 1: 0xc8000000 - 0xcfffffff
+ * node 2: 0xd0000000 - 0xd7ffffff
+ * node 3: 0xd8000000 - 0xdfffffff
+ */
+#define MAX_PHYSMEM_BITS 32
+#define SECTION_SIZE_BITS 27
+
+/*
+ * Cache flushing area - SA1100 zero bank
+ */
+#define FLUSH_BASE_PHYS 0xe0000000
+#define FLUSH_BASE 0xf5000000
+#define FLUSH_BASE_MINICACHE 0xf5100000
+
+#endif
diff --git a/arch/arm/mach-sa1100/include/mach/mtd-xip.h b/arch/arm/mach-sa1100/include/mach/mtd-xip.h
new file mode 100644
index 000000000..85e6a7911
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/mtd-xip.h
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * MTD primitives for XIP support. Architecture specific functions
+ *
+ * Do not include this file directly. It's included from linux/mtd/xip.h
+ *
+ * Author: Nicolas Pitre
+ * Created: Nov 2, 2004
+ * Copyright: (C) 2004 MontaVista Software, Inc.
+ */
+
+#ifndef __ARCH_SA1100_MTD_XIP_H__
+#define __ARCH_SA1100_MTD_XIP_H__
+
+#include <mach/hardware.h>
+
+#define xip_irqpending() (ICIP & ICMR)
+
+/* we sample OSCR and convert desired delta to usec (1/4 ~= 1000000/3686400) */
+#define xip_currtime() readl_relaxed(OSCR)
+#define xip_elapsed_since(x) (signed)((readl_relaxed(OSCR) - (x)) / 4)
+
+#endif /* __ARCH_SA1100_MTD_XIP_H__ */
diff --git a/arch/arm/mach-sa1100/include/mach/neponset.h b/arch/arm/mach-sa1100/include/mach/neponset.h
new file mode 100644
index 000000000..18411cfdf
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/neponset.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * arch/arm/mach-sa1100/include/mach/neponset.h
+ *
+ * Created 2000/06/05 by Nicolas Pitre <nico@fluxnic.net>
+ *
+ * This file contains the hardware specific definitions for Assabet
+ * Only include this file from SA1100-specific files.
+ *
+ * 2000/05/23 John Dorsey <john+@cs.cmu.edu>
+ * Definitions for Neponset added.
+ */
+#ifndef __ASM_ARCH_NEPONSET_H
+#define __ASM_ARCH_NEPONSET_H
+
+/*
+ * Neponset definitions:
+ */
+#define NCR_GP01_OFF (1<<0)
+#define NCR_TP_PWR_EN (1<<1)
+#define NCR_MS_PWR_EN (1<<2)
+#define NCR_ENET_OSC_EN (1<<3)
+#define NCR_SPI_KB_WK_UP (1<<4)
+#define NCR_A0VPP (1<<5)
+#define NCR_A1VPP (1<<6)
+
+void neponset_ncr_frob(unsigned int, unsigned int);
+#define neponset_ncr_set(v) neponset_ncr_frob(0, v)
+#define neponset_ncr_clear(v) neponset_ncr_frob(v, 0)
+
+#endif
diff --git a/arch/arm/mach-sa1100/include/mach/reset.h b/arch/arm/mach-sa1100/include/mach/reset.h
new file mode 100644
index 000000000..a6723d45a
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/reset.h
@@ -0,0 +1,18 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_ARCH_RESET_H
+#define __ASM_ARCH_RESET_H
+
+#include "hardware.h"
+
+#define RESET_STATUS_HARDWARE (1 << 0) /* Hardware Reset */
+#define RESET_STATUS_WATCHDOG (1 << 1) /* Watchdog Reset */
+#define RESET_STATUS_LOWPOWER (1 << 2) /* Exit from Low Power/Sleep */
+#define RESET_STATUS_GPIO (1 << 3) /* GPIO Reset */
+#define RESET_STATUS_ALL (0xf)
+
+static inline void clear_reset_status(unsigned int mask)
+{
+ RCSR = mask;
+}
+
+#endif /* __ASM_ARCH_RESET_H */
diff --git a/arch/arm/mach-sa1100/include/mach/uncompress.h b/arch/arm/mach-sa1100/include/mach/uncompress.h
new file mode 100644
index 000000000..f5eaa90a4
--- /dev/null
+++ b/arch/arm/mach-sa1100/include/mach/uncompress.h
@@ -0,0 +1,52 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * arch/arm/mach-sa1100/include/mach/uncompress.h
+ *
+ * (C) 1999 Nicolas Pitre <nico@fluxnic.net>
+ *
+ * Reorganised to be machine independent.
+ */
+
+#include "hardware.h"
+
+#define IOMEM(x) (x)
+
+/*
+ * The following code assumes the serial port has already been
+ * initialized by the bootloader. We search for the first enabled
+ * port in the most probable order. If you didn't setup a port in
+ * your bootloader then nothing will appear (which might be desired).
+ */
+
+#define UART(x) (*(volatile unsigned long *)(serial_port + (x)))
+
+static inline void putc(int c)
+{
+ unsigned long serial_port;
+
+ do {
+ serial_port = _Ser3UTCR0;
+ if (UART(UTCR3) & UTCR3_TXE) break;
+ serial_port = _Ser1UTCR0;
+ if (UART(UTCR3) & UTCR3_TXE) break;
+ serial_port = _Ser2UTCR0;
+ if (UART(UTCR3) & UTCR3_TXE) break;
+ return;
+ } while (0);
+
+ /* wait for space in the UART's transmitter */
+ while (!(UART(UTSR1) & UTSR1_TNF))
+ barrier();
+
+ /* send the character out. */
+ UART(UTDR) = c;
+}
+
+static inline void flush(void)
+{
+}
+
+/*
+ * Nothing to do for these
+ */
+#define arch_decomp_setup()
diff --git a/arch/arm/mach-sa1100/jornada720.c b/arch/arm/mach-sa1100/jornada720.c
new file mode 100644
index 000000000..e259298d9
--- /dev/null
+++ b/arch/arm/mach-sa1100/jornada720.c
@@ -0,0 +1,380 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * linux/arch/arm/mach-sa1100/jornada720.c
+ *
+ * HP Jornada720 init code
+ *
+ * Copyright (C) 2007 Kristoffer Ericson <Kristoffer.Ericson@gmail.com>
+ * Copyright (C) 2006 Filip Zyzniewski <filip.zyzniewski@tefnet.pl>
+ * Copyright (C) 2005 Michael Gernoth <michael@gernoth.net>
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/tty.h>
+#include <linux/delay.h>
+#include <linux/gpio/machine.h>
+#include <linux/platform_data/sa11x0-serial.h>
+#include <linux/platform_device.h>
+#include <linux/ioport.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <video/s1d13xxxfb.h>
+
+#include <asm/hardware/sa1111.h>
+#include <asm/page.h>
+#include <asm/mach-types.h>
+#include <asm/setup.h>
+#include <asm/mach/arch.h>
+#include <asm/mach/flash.h>
+#include <asm/mach/map.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+
+#include "generic.h"
+
+/*
+ * HP Documentation referred in this file:
+ * http://www.jlime.com/downloads/development/docs/jornada7xx/jornada720.txt
+ */
+
+/* line 110 of HP's doc */
+#define TUCR_VAL 0x20000400
+
+/* memory space (line 52 of HP's doc) */
+#define SA1111REGSTART 0x40000000
+#define SA1111REGLEN 0x00002000
+#define EPSONREGSTART 0x48000000
+#define EPSONREGLEN 0x00100000
+#define EPSONFBSTART 0x48200000
+/* 512kB framebuffer */
+#define EPSONFBLEN 512*1024
+
+static struct s1d13xxxfb_regval s1d13xxxfb_initregs[] = {
+ /* line 344 of HP's doc */
+ {0x0001,0x00}, // Miscellaneous Register
+ {0x01FC,0x00}, // Display Mode Register
+ {0x0004,0x00}, // General IO Pins Configuration Register 0
+ {0x0005,0x00}, // General IO Pins Configuration Register 1
+ {0x0008,0x00}, // General IO Pins Control Register 0
+ {0x0009,0x00}, // General IO Pins Control Register 1
+ {0x0010,0x01}, // Memory Clock Configuration Register
+ {0x0014,0x11}, // LCD Pixel Clock Configuration Register
+ {0x0018,0x01}, // CRT/TV Pixel Clock Configuration Register
+ {0x001C,0x01}, // MediaPlug Clock Configuration Register
+ {0x001E,0x01}, // CPU To Memory Wait State Select Register
+ {0x0020,0x00}, // Memory Configuration Register
+ {0x0021,0x45}, // DRAM Refresh Rate Register
+ {0x002A,0x01}, // DRAM Timings Control Register 0
+ {0x002B,0x03}, // DRAM Timings Control Register 1
+ {0x0030,0x1c}, // Panel Type Register
+ {0x0031,0x00}, // MOD Rate Register
+ {0x0032,0x4F}, // LCD Horizontal Display Width Register
+ {0x0034,0x07}, // LCD Horizontal Non-Display Period Register
+ {0x0035,0x01}, // TFT FPLINE Start Position Register
+ {0x0036,0x0B}, // TFT FPLINE Pulse Width Register
+ {0x0038,0xEF}, // LCD Vertical Display Height Register 0
+ {0x0039,0x00}, // LCD Vertical Display Height Register 1
+ {0x003A,0x13}, // LCD Vertical Non-Display Period Register
+ {0x003B,0x0B}, // TFT FPFRAME Start Position Register
+ {0x003C,0x01}, // TFT FPFRAME Pulse Width Register
+ {0x0040,0x05}, // LCD Display Mode Register (2:4bpp,3:8bpp,5:16bpp)
+ {0x0041,0x00}, // LCD Miscellaneous Register
+ {0x0042,0x00}, // LCD Display Start Address Register 0
+ {0x0043,0x00}, // LCD Display Start Address Register 1
+ {0x0044,0x00}, // LCD Display Start Address Register 2
+ {0x0046,0x80}, // LCD Memory Address Offset Register 0
+ {0x0047,0x02}, // LCD Memory Address Offset Register 1
+ {0x0048,0x00}, // LCD Pixel Panning Register
+ {0x004A,0x00}, // LCD Display FIFO High Threshold Control Register
+ {0x004B,0x00}, // LCD Display FIFO Low Threshold Control Register
+ {0x0050,0x4F}, // CRT/TV Horizontal Display Width Register
+ {0x0052,0x13}, // CRT/TV Horizontal Non-Display Period Register
+ {0x0053,0x01}, // CRT/TV HRTC Start Position Register
+ {0x0054,0x0B}, // CRT/TV HRTC Pulse Width Register
+ {0x0056,0xDF}, // CRT/TV Vertical Display Height Register 0
+ {0x0057,0x01}, // CRT/TV Vertical Display Height Register 1
+ {0x0058,0x2B}, // CRT/TV Vertical Non-Display Period Register
+ {0x0059,0x09}, // CRT/TV VRTC Start Position Register
+ {0x005A,0x01}, // CRT/TV VRTC Pulse Width Register
+ {0x005B,0x10}, // TV Output Control Register
+ {0x0060,0x03}, // CRT/TV Display Mode Register (2:4bpp,3:8bpp,5:16bpp)
+ {0x0062,0x00}, // CRT/TV Display Start Address Register 0
+ {0x0063,0x00}, // CRT/TV Display Start Address Register 1
+ {0x0064,0x00}, // CRT/TV Display Start Address Register 2
+ {0x0066,0x40}, // CRT/TV Memory Address Offset Register 0
+ {0x0067,0x01}, // CRT/TV Memory Address Offset Register 1
+ {0x0068,0x00}, // CRT/TV Pixel Panning Register
+ {0x006A,0x00}, // CRT/TV Display FIFO High Threshold Control Register
+ {0x006B,0x00}, // CRT/TV Display FIFO Low Threshold Control Register
+ {0x0070,0x00}, // LCD Ink/Cursor Control Register
+ {0x0071,0x01}, // LCD Ink/Cursor Start Address Register
+ {0x0072,0x00}, // LCD Cursor X Position Register 0
+ {0x0073,0x00}, // LCD Cursor X Position Register 1
+ {0x0074,0x00}, // LCD Cursor Y Position Register 0
+ {0x0075,0x00}, // LCD Cursor Y Position Register 1
+ {0x0076,0x00}, // LCD Ink/Cursor Blue Color 0 Register
+ {0x0077,0x00}, // LCD Ink/Cursor Green Color 0 Register
+ {0x0078,0x00}, // LCD Ink/Cursor Red Color 0 Register
+ {0x007A,0x1F}, // LCD Ink/Cursor Blue Color 1 Register
+ {0x007B,0x3F}, // LCD Ink/Cursor Green Color 1 Register
+ {0x007C,0x1F}, // LCD Ink/Cursor Red Color 1 Register
+ {0x007E,0x00}, // LCD Ink/Cursor FIFO Threshold Register
+ {0x0080,0x00}, // CRT/TV Ink/Cursor Control Register
+ {0x0081,0x01}, // CRT/TV Ink/Cursor Start Address Register
+ {0x0082,0x00}, // CRT/TV Cursor X Position Register 0
+ {0x0083,0x00}, // CRT/TV Cursor X Position Register 1
+ {0x0084,0x00}, // CRT/TV Cursor Y Position Register 0
+ {0x0085,0x00}, // CRT/TV Cursor Y Position Register 1
+ {0x0086,0x00}, // CRT/TV Ink/Cursor Blue Color 0 Register
+ {0x0087,0x00}, // CRT/TV Ink/Cursor Green Color 0 Register
+ {0x0088,0x00}, // CRT/TV Ink/Cursor Red Color 0 Register
+ {0x008A,0x1F}, // CRT/TV Ink/Cursor Blue Color 1 Register
+ {0x008B,0x3F}, // CRT/TV Ink/Cursor Green Color 1 Register
+ {0x008C,0x1F}, // CRT/TV Ink/Cursor Red Color 1 Register
+ {0x008E,0x00}, // CRT/TV Ink/Cursor FIFO Threshold Register
+ {0x0100,0x00}, // BitBlt Control Register 0
+ {0x0101,0x00}, // BitBlt Control Register 1
+ {0x0102,0x00}, // BitBlt ROP Code/Color Expansion Register
+ {0x0103,0x00}, // BitBlt Operation Register
+ {0x0104,0x00}, // BitBlt Source Start Address Register 0
+ {0x0105,0x00}, // BitBlt Source Start Address Register 1
+ {0x0106,0x00}, // BitBlt Source Start Address Register 2
+ {0x0108,0x00}, // BitBlt Destination Start Address Register 0
+ {0x0109,0x00}, // BitBlt Destination Start Address Register 1
+ {0x010A,0x00}, // BitBlt Destination Start Address Register 2
+ {0x010C,0x00}, // BitBlt Memory Address Offset Register 0
+ {0x010D,0x00}, // BitBlt Memory Address Offset Register 1
+ {0x0110,0x00}, // BitBlt Width Register 0
+ {0x0111,0x00}, // BitBlt Width Register 1
+ {0x0112,0x00}, // BitBlt Height Register 0
+ {0x0113,0x00}, // BitBlt Height Register 1
+ {0x0114,0x00}, // BitBlt Background Color Register 0
+ {0x0115,0x00}, // BitBlt Background Color Register 1
+ {0x0118,0x00}, // BitBlt Foreground Color Register 0
+ {0x0119,0x00}, // BitBlt Foreground Color Register 1
+ {0x01E0,0x00}, // Look-Up Table Mode Register
+ {0x01E2,0x00}, // Look-Up Table Address Register
+ /* not sure, wouldn't like to mess with the driver */
+ {0x01E4,0x00}, // Look-Up Table Data Register
+ /* jornada doc says 0x00, but I trust the driver */
+ {0x01F0,0x10}, // Power Save Configuration Register
+ {0x01F1,0x00}, // Power Save Status Register
+ {0x01F4,0x00}, // CPU-to-Memory Access Watchdog Timer Register
+ {0x01FC,0x01}, // Display Mode Register(0x01:LCD, 0x02:CRT, 0x03:LCD&CRT)
+};
+
+static struct s1d13xxxfb_pdata s1d13xxxfb_data = {
+ .initregs = s1d13xxxfb_initregs,
+ .initregssize = ARRAY_SIZE(s1d13xxxfb_initregs),
+ .platform_init_video = NULL
+};
+
+static struct resource s1d13xxxfb_resources[] = {
+ [0] = DEFINE_RES_MEM(EPSONFBSTART, EPSONFBLEN),
+ [1] = DEFINE_RES_MEM(EPSONREGSTART, EPSONREGLEN),
+};
+
+static struct platform_device s1d13xxxfb_device = {
+ .name = S1D_DEVICENAME,
+ .id = 0,
+ .dev = {
+ .platform_data = &s1d13xxxfb_data,
+ },
+ .num_resources = ARRAY_SIZE(s1d13xxxfb_resources),
+ .resource = s1d13xxxfb_resources,
+};
+
+static struct gpiod_lookup_table jornada_pcmcia_gpiod_table = {
+ .dev_id = "1800",
+ .table = {
+ GPIO_LOOKUP("sa1111", 0, "s0-power", GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP("sa1111", 1, "s1-power", GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP("sa1111", 2, "s0-3v", GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP("sa1111", 3, "s1-3v", GPIO_ACTIVE_HIGH),
+ { },
+ },
+};
+
+static struct resource sa1111_resources[] = {
+ [0] = DEFINE_RES_MEM(SA1111REGSTART, SA1111REGLEN),
+ [1] = DEFINE_RES_IRQ(IRQ_GPIO1),
+};
+
+static struct sa1111_platform_data sa1111_info = {
+ .disable_devs = SA1111_DEVID_PS2_MSE,
+};
+
+static u64 sa1111_dmamask = 0xffffffffUL;
+
+static struct platform_device sa1111_device = {
+ .name = "sa1111",
+ .id = 0,
+ .dev = {
+ .dma_mask = &sa1111_dmamask,
+ .coherent_dma_mask = 0xffffffff,
+ .platform_data = &sa1111_info,
+ },
+ .num_resources = ARRAY_SIZE(sa1111_resources),
+ .resource = sa1111_resources,
+};
+
+static struct platform_device jornada_ssp_device = {
+ .name = "jornada_ssp",
+ .id = -1,
+};
+
+static struct resource jornada_kbd_resources[] = {
+ DEFINE_RES_IRQ(IRQ_GPIO0),
+};
+
+static struct platform_device jornada_kbd_device = {
+ .name = "jornada720_kbd",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(jornada_kbd_resources),
+ .resource = jornada_kbd_resources,
+};
+
+static struct gpiod_lookup_table jornada_ts_gpiod_table = {
+ .dev_id = "jornada_ts",
+ .table = {
+ GPIO_LOOKUP("gpio", 9, "penup", GPIO_ACTIVE_HIGH),
+ },
+};
+
+static struct platform_device jornada_ts_device = {
+ .name = "jornada_ts",
+ .id = -1,
+};
+
+static struct platform_device *devices[] __initdata = {
+ &sa1111_device,
+ &jornada_ssp_device,
+ &s1d13xxxfb_device,
+ &jornada_kbd_device,
+ &jornada_ts_device,
+};
+
+static int __init jornada720_init(void)
+{
+ int ret = -ENODEV;
+
+ if (machine_is_jornada720()) {
+ /* we want to use gpio20 as input to drive the clock of our uart 3 */
+ GPDR |= GPIO_GPIO20; /* Clear gpio20 pin as input */
+ TUCR = TUCR_VAL;
+ GPSR = GPIO_GPIO20; /* start gpio20 pin */
+ udelay(1);
+ GPCR = GPIO_GPIO20; /* stop gpio20 */
+ udelay(1);
+ GPSR = GPIO_GPIO20; /* restart gpio20 */
+ udelay(20); /* give it some time to restart */
+
+ gpiod_add_lookup_table(&jornada_ts_gpiod_table);
+ gpiod_add_lookup_table(&jornada_pcmcia_gpiod_table);
+
+ ret = platform_add_devices(devices, ARRAY_SIZE(devices));
+ }
+
+ return ret;
+}
+
+arch_initcall(jornada720_init);
+
+static struct map_desc jornada720_io_desc[] __initdata = {
+ { /* Epson registers */
+ .virtual = 0xf0000000,
+ .pfn = __phys_to_pfn(EPSONREGSTART),
+ .length = EPSONREGLEN,
+ .type = MT_DEVICE
+ }, { /* Epson frame buffer */
+ .virtual = 0xf1000000,
+ .pfn = __phys_to_pfn(EPSONFBSTART),
+ .length = EPSONFBLEN,
+ .type = MT_DEVICE
+ }
+};
+
+static void __init jornada720_map_io(void)
+{
+ sa1100_map_io();
+ iotable_init(jornada720_io_desc, ARRAY_SIZE(jornada720_io_desc));
+
+ sa1100_register_uart(0, 3);
+ sa1100_register_uart(1, 1);
+}
+
+static struct mtd_partition jornada720_partitions[] = {
+ {
+ .name = "JORNADA720 boot firmware",
+ .size = 0x00040000,
+ .offset = 0,
+ .mask_flags = MTD_WRITEABLE, /* force read-only */
+ }, {
+ .name = "JORNADA720 kernel",
+ .size = 0x000c0000,
+ .offset = 0x00040000,
+ }, {
+ .name = "JORNADA720 params",
+ .size = 0x00040000,
+ .offset = 0x00100000,
+ }, {
+ .name = "JORNADA720 initrd",
+ .size = 0x00100000,
+ .offset = 0x00140000,
+ }, {
+ .name = "JORNADA720 root cramfs",
+ .size = 0x00300000,
+ .offset = 0x00240000,
+ }, {
+ .name = "JORNADA720 usr cramfs",
+ .size = 0x00800000,
+ .offset = 0x00540000,
+ }, {
+ .name = "JORNADA720 usr local",
+ .size = 0, /* will expand to the end of the flash */
+ .offset = 0x00d00000,
+ }
+};
+
+static void jornada720_set_vpp(int vpp)
+{
+ if (vpp)
+ /* enabling flash write (line 470 of HP's doc) */
+ PPSR |= PPC_LDD7;
+ else
+ /* disabling flash write (line 470 of HP's doc) */
+ PPSR &= ~PPC_LDD7;
+ PPDR |= PPC_LDD7;
+}
+
+static struct flash_platform_data jornada720_flash_data = {
+ .map_name = "cfi_probe",
+ .set_vpp = jornada720_set_vpp,
+ .parts = jornada720_partitions,
+ .nr_parts = ARRAY_SIZE(jornada720_partitions),
+};
+
+static struct resource jornada720_flash_resource =
+ DEFINE_RES_MEM(SA1100_CS0_PHYS, SZ_32M);
+
+static void __init jornada720_mach_init(void)
+{
+ sa11x0_register_mtd(&jornada720_flash_data, &jornada720_flash_resource, 1);
+}
+
+MACHINE_START(JORNADA720, "HP Jornada 720")
+ /* Maintainer: Kristoffer Ericson <Kristoffer.Ericson@gmail.com> */
+ .atag_offset = 0x100,
+ .map_io = jornada720_map_io,
+ .nr_irqs = SA1100_NR_IRQS,
+ .init_irq = sa1100_init_irq,
+ .init_time = sa1100_timer_init,
+ .init_machine = jornada720_mach_init,
+ .init_late = sa11x0_init_late,
+#ifdef CONFIG_SA1111
+ .dma_zone_size = SZ_1M,
+#endif
+ .restart = sa11x0_restart,
+MACHINE_END
diff --git a/arch/arm/mach-sa1100/jornada720_ssp.c b/arch/arm/mach-sa1100/jornada720_ssp.c
new file mode 100644
index 000000000..1956b095e
--- /dev/null
+++ b/arch/arm/mach-sa1100/jornada720_ssp.c
@@ -0,0 +1,202 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * arch/arm/mac-sa1100/jornada720_ssp.c
+ *
+ * Copyright (C) 2006/2007 Kristoffer Ericson <Kristoffer.Ericson@gmail.com>
+ * Copyright (C) 2006 Filip Zyzniewski <filip.zyzniewski@tefnet.pl>
+ *
+ * SSP driver for the HP Jornada 710/720/728
+ */
+
+#include <linux/delay.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/sched.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/jornada720.h>
+#include <asm/hardware/ssp.h>
+
+static DEFINE_SPINLOCK(jornada_ssp_lock);
+static unsigned long jornada_ssp_flags;
+
+/**
+ * jornada_ssp_reverse - reverses input byte
+ * @byte: input byte to reverse
+ *
+ * we need to reverse all data we receive from the mcu due to its physical location
+ * returns : 01110111 -> 11101110
+ */
+inline u8 jornada_ssp_reverse(u8 byte)
+{
+ return
+ ((0x80 & byte) >> 7) |
+ ((0x40 & byte) >> 5) |
+ ((0x20 & byte) >> 3) |
+ ((0x10 & byte) >> 1) |
+ ((0x08 & byte) << 1) |
+ ((0x04 & byte) << 3) |
+ ((0x02 & byte) << 5) |
+ ((0x01 & byte) << 7);
+};
+EXPORT_SYMBOL(jornada_ssp_reverse);
+
+/**
+ * jornada_ssp_byte - waits for ready ssp bus and sends byte
+ * @byte: input byte to transmit
+ *
+ * waits for fifo buffer to clear and then transmits, if it doesn't then we will
+ * timeout after <timeout> rounds. Needs mcu running before its called.
+ *
+ * returns : %mcu output on success
+ * : %-ETIMEDOUT on timeout
+ */
+int jornada_ssp_byte(u8 byte)
+{
+ int timeout = 400000;
+ u16 ret;
+
+ while ((GPLR & GPIO_GPIO10)) {
+ if (!--timeout) {
+ printk(KERN_WARNING "SSP: timeout while waiting for transmit\n");
+ return -ETIMEDOUT;
+ }
+ cpu_relax();
+ }
+
+ ret = jornada_ssp_reverse(byte) << 8;
+
+ ssp_write_word(ret);
+ ssp_read_word(&ret);
+
+ return jornada_ssp_reverse(ret);
+};
+EXPORT_SYMBOL(jornada_ssp_byte);
+
+/**
+ * jornada_ssp_inout - decide if input is command or trading byte
+ * @byte: input byte to send (may be %TXDUMMY)
+ *
+ * returns : (jornada_ssp_byte(byte)) on success
+ * : %-ETIMEDOUT on timeout failure
+ */
+int jornada_ssp_inout(u8 byte)
+{
+ int ret, i;
+
+ /* true means command byte */
+ if (byte != TXDUMMY) {
+ ret = jornada_ssp_byte(byte);
+ /* Proper return to commands is TxDummy */
+ if (ret != TXDUMMY) {
+ for (i = 0; i < 256; i++)/* flushing bus */
+ if (jornada_ssp_byte(TXDUMMY) == -1)
+ break;
+ return -ETIMEDOUT;
+ }
+ } else /* Exchange TxDummy for data */
+ ret = jornada_ssp_byte(TXDUMMY);
+
+ return ret;
+};
+EXPORT_SYMBOL(jornada_ssp_inout);
+
+/**
+ * jornada_ssp_start - enable mcu
+ *
+ */
+void jornada_ssp_start(void)
+{
+ spin_lock_irqsave(&jornada_ssp_lock, jornada_ssp_flags);
+ GPCR = GPIO_GPIO25;
+ udelay(50);
+ return;
+};
+EXPORT_SYMBOL(jornada_ssp_start);
+
+/**
+ * jornada_ssp_end - disable mcu and turn off lock
+ *
+ */
+void jornada_ssp_end(void)
+{
+ GPSR = GPIO_GPIO25;
+ spin_unlock_irqrestore(&jornada_ssp_lock, jornada_ssp_flags);
+ return;
+};
+EXPORT_SYMBOL(jornada_ssp_end);
+
+static int jornada_ssp_probe(struct platform_device *dev)
+{
+ int ret;
+
+ GPSR = GPIO_GPIO25;
+
+ ret = ssp_init();
+
+ /* worked fine, lets not bother with anything else */
+ if (!ret) {
+ printk(KERN_INFO "SSP: device initialized with irq\n");
+ return ret;
+ }
+
+ printk(KERN_WARNING "SSP: initialization failed, trying non-irq solution \n");
+
+ /* init of Serial 4 port */
+ Ser4MCCR0 = 0;
+ Ser4SSCR0 = 0x0387;
+ Ser4SSCR1 = 0x18;
+
+ /* clear out any left over data */
+ ssp_flush();
+
+ /* enable MCU */
+ jornada_ssp_start();
+
+ /* see if return value makes sense */
+ ret = jornada_ssp_inout(GETBRIGHTNESS);
+
+ /* seems like it worked, just feed it with TxDummy to get rid of data */
+ if (ret == TXDUMMY)
+ jornada_ssp_inout(TXDUMMY);
+
+ jornada_ssp_end();
+
+ /* failed, lets just kill everything */
+ if (ret == -ETIMEDOUT) {
+ printk(KERN_WARNING "SSP: attempts failed, bailing\n");
+ ssp_exit();
+ return -ENODEV;
+ }
+
+ /* all fine */
+ printk(KERN_INFO "SSP: device initialized\n");
+ return 0;
+};
+
+static void jornada_ssp_remove(struct platform_device *dev)
+{
+ /* Note that this doesn't actually remove the driver, since theres nothing to remove
+ * It just makes sure everything is turned off */
+ GPSR = GPIO_GPIO25;
+ ssp_exit();
+};
+
+struct platform_driver jornadassp_driver = {
+ .probe = jornada_ssp_probe,
+ .remove_new = jornada_ssp_remove,
+ .driver = {
+ .name = "jornada_ssp",
+ },
+};
+
+static int __init jornada_ssp_init(void)
+{
+ return platform_driver_register(&jornadassp_driver);
+}
+
+module_init(jornada_ssp_init);
diff --git a/arch/arm/mach-sa1100/neponset.c b/arch/arm/mach-sa1100/neponset.c
new file mode 100644
index 000000000..0ef0ebbf3
--- /dev/null
+++ b/arch/arm/mach-sa1100/neponset.c
@@ -0,0 +1,438 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * linux/arch/arm/mach-sa1100/neponset.c
+ */
+#include <linux/err.h>
+#include <linux/gpio/driver.h>
+#include <linux/gpio/gpio-reg.h>
+#include <linux/gpio/machine.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pm.h>
+#include <linux/serial_core.h>
+#include <linux/slab.h>
+#include <linux/smc91x.h>
+
+#include <asm/mach-types.h>
+#include <asm/mach/map.h>
+#include <asm/hardware/sa1111.h>
+#include <linux/sizes.h>
+
+#include <mach/hardware.h>
+#include <mach/assabet.h>
+#include <mach/neponset.h>
+#include <mach/irqs.h>
+
+#define NEP_IRQ_SMC91X 0
+#define NEP_IRQ_USAR 1
+#define NEP_IRQ_SA1111 2
+#define NEP_IRQ_NR 3
+
+#define WHOAMI 0x00
+#define LEDS 0x10
+#define SWPK 0x20
+#define IRR 0x24
+#define KP_Y_IN 0x80
+#define KP_X_OUT 0x90
+#define NCR_0 0xa0
+#define MDM_CTL_0 0xb0
+#define MDM_CTL_1 0xb4
+#define AUD_CTL 0xc0
+
+#define IRR_ETHERNET (1 << 0)
+#define IRR_USAR (1 << 1)
+#define IRR_SA1111 (1 << 2)
+
+#define NCR_NGPIO 7
+#define MDM_CTL0_NGPIO 4
+#define MDM_CTL1_NGPIO 6
+#define AUD_NGPIO 2
+
+extern void sa1110_mb_disable(void);
+
+#define to_neponset_gpio_chip(x) container_of(x, struct neponset_gpio_chip, gc)
+
+static const char *neponset_ncr_names[] = {
+ "gp01_off", "tp_power", "ms_power", "enet_osc",
+ "spi_kb_wk_up", "a0vpp", "a1vpp"
+};
+
+static const char *neponset_mdmctl0_names[] = {
+ "rts3", "dtr3", "rts1", "dtr1",
+};
+
+static const char *neponset_mdmctl1_names[] = {
+ "cts3", "dsr3", "dcd3", "cts1", "dsr1", "dcd1"
+};
+
+static const char *neponset_aud_names[] = {
+ "sel_1341", "mute_1341",
+};
+
+struct neponset_drvdata {
+ void __iomem *base;
+ struct platform_device *sa1111;
+ struct platform_device *smc91x;
+ unsigned irq_base;
+ struct gpio_chip *gpio[4];
+};
+
+static struct gpiod_lookup_table neponset_uart1_gpio_table = {
+ .dev_id = "sa11x0-uart.1",
+ .table = {
+ GPIO_LOOKUP("neponset-mdm-ctl0", 2, "rts", GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP("neponset-mdm-ctl0", 3, "dtr", GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP("neponset-mdm-ctl1", 3, "cts", GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP("neponset-mdm-ctl1", 4, "dsr", GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP("neponset-mdm-ctl1", 5, "dcd", GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
+static struct gpiod_lookup_table neponset_uart3_gpio_table = {
+ .dev_id = "sa11x0-uart.3",
+ .table = {
+ GPIO_LOOKUP("neponset-mdm-ctl0", 0, "rts", GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP("neponset-mdm-ctl0", 1, "dtr", GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP("neponset-mdm-ctl1", 0, "cts", GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP("neponset-mdm-ctl1", 1, "dsr", GPIO_ACTIVE_LOW),
+ GPIO_LOOKUP("neponset-mdm-ctl1", 2, "dcd", GPIO_ACTIVE_LOW),
+ { },
+ },
+};
+
+static struct gpiod_lookup_table neponset_pcmcia_table = {
+ .dev_id = "1800",
+ .table = {
+ GPIO_LOOKUP("sa1111", 1, "a0vcc", GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP("sa1111", 0, "a1vcc", GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP("neponset-ncr", 5, "a0vpp", GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP("neponset-ncr", 6, "a1vpp", GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP("sa1111", 2, "b0vcc", GPIO_ACTIVE_HIGH),
+ GPIO_LOOKUP("sa1111", 3, "b1vcc", GPIO_ACTIVE_HIGH),
+ { },
+ },
+};
+
+static struct neponset_drvdata *nep;
+
+void neponset_ncr_frob(unsigned int mask, unsigned int val)
+{
+ struct neponset_drvdata *n = nep;
+ unsigned long m = mask, v = val;
+
+ if (nep)
+ n->gpio[0]->set_multiple(n->gpio[0], &m, &v);
+ else
+ WARN(1, "nep unset\n");
+}
+EXPORT_SYMBOL(neponset_ncr_frob);
+
+/*
+ * Install handler for Neponset IRQ. Note that we have to loop here
+ * since the ETHERNET and USAR IRQs are level based, and we need to
+ * ensure that the IRQ signal is deasserted before returning. This
+ * is rather unfortunate.
+ */
+static void neponset_irq_handler(struct irq_desc *desc)
+{
+ struct neponset_drvdata *d = irq_desc_get_handler_data(desc);
+ unsigned int irr;
+
+ while (1) {
+ /*
+ * Acknowledge the parent IRQ.
+ */
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
+
+ /*
+ * Read the interrupt reason register. Let's have all
+ * active IRQ bits high. Note: there is a typo in the
+ * Neponset user's guide for the SA1111 IRR level.
+ */
+ irr = readb_relaxed(d->base + IRR);
+ irr ^= IRR_ETHERNET | IRR_USAR;
+
+ if ((irr & (IRR_ETHERNET | IRR_USAR | IRR_SA1111)) == 0)
+ break;
+
+ /*
+ * Since there is no individual mask, we have to
+ * mask the parent IRQ. This is safe, since we'll
+ * recheck the register for any pending IRQs.
+ */
+ if (irr & (IRR_ETHERNET | IRR_USAR)) {
+ desc->irq_data.chip->irq_mask(&desc->irq_data);
+
+ /*
+ * Ack the interrupt now to prevent re-entering
+ * this neponset handler. Again, this is safe
+ * since we'll check the IRR register prior to
+ * leaving.
+ */
+ desc->irq_data.chip->irq_ack(&desc->irq_data);
+
+ if (irr & IRR_ETHERNET)
+ generic_handle_irq(d->irq_base + NEP_IRQ_SMC91X);
+
+ if (irr & IRR_USAR)
+ generic_handle_irq(d->irq_base + NEP_IRQ_USAR);
+
+ desc->irq_data.chip->irq_unmask(&desc->irq_data);
+ }
+
+ if (irr & IRR_SA1111)
+ generic_handle_irq(d->irq_base + NEP_IRQ_SA1111);
+ }
+}
+
+/* Yes, we really do not have any kind of masking or unmasking */
+static void nochip_noop(struct irq_data *irq)
+{
+}
+
+static struct irq_chip nochip = {
+ .name = "neponset",
+ .irq_ack = nochip_noop,
+ .irq_mask = nochip_noop,
+ .irq_unmask = nochip_noop,
+};
+
+static int neponset_init_gpio(struct gpio_chip **gcp,
+ struct device *dev, const char *label, void __iomem *reg,
+ unsigned num, bool in, const char *const * names)
+{
+ struct gpio_chip *gc;
+
+ gc = gpio_reg_init(dev, reg, -1, num, label, in ? 0xffffffff : 0,
+ readl_relaxed(reg), names, NULL, NULL);
+ if (IS_ERR(gc))
+ return PTR_ERR(gc);
+
+ *gcp = gc;
+
+ return 0;
+}
+
+static struct sa1111_platform_data sa1111_info = {
+ .disable_devs = SA1111_DEVID_PS2_MSE,
+};
+
+static int neponset_probe(struct platform_device *dev)
+{
+ struct neponset_drvdata *d;
+ struct resource *nep_res, *sa1111_res, *smc91x_res;
+ struct resource sa1111_resources[] = {
+ DEFINE_RES_MEM(0x40000000, SZ_8K),
+ { .flags = IORESOURCE_IRQ },
+ };
+ struct platform_device_info sa1111_devinfo = {
+ .parent = &dev->dev,
+ .name = "sa1111",
+ .id = 0,
+ .res = sa1111_resources,
+ .num_res = ARRAY_SIZE(sa1111_resources),
+ .data = &sa1111_info,
+ .size_data = sizeof(sa1111_info),
+ .dma_mask = 0xffffffffUL,
+ };
+ struct resource smc91x_resources[] = {
+ DEFINE_RES_MEM_NAMED(SA1100_CS3_PHYS,
+ 0x02000000, "smc91x-regs"),
+ DEFINE_RES_MEM_NAMED(SA1100_CS3_PHYS + 0x02000000,
+ 0x02000000, "smc91x-attrib"),
+ { .flags = IORESOURCE_IRQ },
+ };
+ struct smc91x_platdata smc91x_platdata = {
+ .flags = SMC91X_USE_8BIT | SMC91X_IO_SHIFT_2 | SMC91X_NOWAIT,
+ };
+ struct platform_device_info smc91x_devinfo = {
+ .parent = &dev->dev,
+ .name = "smc91x",
+ .id = 0,
+ .res = smc91x_resources,
+ .num_res = ARRAY_SIZE(smc91x_resources),
+ .data = &smc91x_platdata,
+ .size_data = sizeof(smc91x_platdata),
+ };
+ int ret, irq;
+
+ if (nep)
+ return -EBUSY;
+
+ irq = ret = platform_get_irq(dev, 0);
+ if (ret < 0)
+ goto err_alloc;
+
+ nep_res = platform_get_resource(dev, IORESOURCE_MEM, 0);
+ smc91x_res = platform_get_resource(dev, IORESOURCE_MEM, 1);
+ sa1111_res = platform_get_resource(dev, IORESOURCE_MEM, 2);
+ if (!nep_res || !smc91x_res || !sa1111_res) {
+ ret = -ENXIO;
+ goto err_alloc;
+ }
+
+ d = kzalloc(sizeof(*d), GFP_KERNEL);
+ if (!d) {
+ ret = -ENOMEM;
+ goto err_alloc;
+ }
+
+ d->base = ioremap(nep_res->start, SZ_4K);
+ if (!d->base) {
+ ret = -ENOMEM;
+ goto err_ioremap;
+ }
+
+ if (readb_relaxed(d->base + WHOAMI) != 0x11) {
+ dev_warn(&dev->dev, "Neponset board detected, but wrong ID: %02x\n",
+ readb_relaxed(d->base + WHOAMI));
+ ret = -ENODEV;
+ goto err_id;
+ }
+
+ ret = irq_alloc_descs(-1, IRQ_BOARD_START, NEP_IRQ_NR, -1);
+ if (ret <= 0) {
+ dev_err(&dev->dev, "unable to allocate %u irqs: %d\n",
+ NEP_IRQ_NR, ret);
+ if (ret == 0)
+ ret = -ENOMEM;
+ goto err_irq_alloc;
+ }
+
+ d->irq_base = ret;
+
+ irq_set_chip_and_handler(d->irq_base + NEP_IRQ_SMC91X, &nochip,
+ handle_simple_irq);
+ irq_clear_status_flags(d->irq_base + NEP_IRQ_SMC91X, IRQ_NOREQUEST | IRQ_NOPROBE);
+ irq_set_chip_and_handler(d->irq_base + NEP_IRQ_USAR, &nochip,
+ handle_simple_irq);
+ irq_clear_status_flags(d->irq_base + NEP_IRQ_USAR, IRQ_NOREQUEST | IRQ_NOPROBE);
+ irq_set_chip(d->irq_base + NEP_IRQ_SA1111, &nochip);
+
+ irq_set_irq_type(irq, IRQ_TYPE_EDGE_RISING);
+ irq_set_chained_handler_and_data(irq, neponset_irq_handler, d);
+
+ /* Disable GPIO 0/1 drivers so the buttons work on the Assabet */
+ writeb_relaxed(NCR_GP01_OFF, d->base + NCR_0);
+
+ neponset_init_gpio(&d->gpio[0], &dev->dev, "neponset-ncr",
+ d->base + NCR_0, NCR_NGPIO, false,
+ neponset_ncr_names);
+ neponset_init_gpio(&d->gpio[1], &dev->dev, "neponset-mdm-ctl0",
+ d->base + MDM_CTL_0, MDM_CTL0_NGPIO, false,
+ neponset_mdmctl0_names);
+ neponset_init_gpio(&d->gpio[2], &dev->dev, "neponset-mdm-ctl1",
+ d->base + MDM_CTL_1, MDM_CTL1_NGPIO, true,
+ neponset_mdmctl1_names);
+ neponset_init_gpio(&d->gpio[3], &dev->dev, "neponset-aud-ctl",
+ d->base + AUD_CTL, AUD_NGPIO, false,
+ neponset_aud_names);
+
+ gpiod_add_lookup_table(&neponset_uart1_gpio_table);
+ gpiod_add_lookup_table(&neponset_uart3_gpio_table);
+ gpiod_add_lookup_table(&neponset_pcmcia_table);
+
+ /*
+ * We would set IRQ_GPIO25 to be a wake-up IRQ, but unfortunately
+ * something on the Neponset activates this IRQ on sleep (eth?)
+ */
+#if 0
+ enable_irq_wake(irq);
+#endif
+
+ dev_info(&dev->dev, "Neponset daughter board, providing IRQ%u-%u\n",
+ d->irq_base, d->irq_base + NEP_IRQ_NR - 1);
+ nep = d;
+
+ /* Ensure that the memory bus request/grant signals are setup */
+ sa1110_mb_disable();
+
+ sa1111_resources[0].parent = sa1111_res;
+ sa1111_resources[1].start = d->irq_base + NEP_IRQ_SA1111;
+ sa1111_resources[1].end = d->irq_base + NEP_IRQ_SA1111;
+ d->sa1111 = platform_device_register_full(&sa1111_devinfo);
+
+ smc91x_resources[0].parent = smc91x_res;
+ smc91x_resources[1].parent = smc91x_res;
+ smc91x_resources[2].start = d->irq_base + NEP_IRQ_SMC91X;
+ smc91x_resources[2].end = d->irq_base + NEP_IRQ_SMC91X;
+ d->smc91x = platform_device_register_full(&smc91x_devinfo);
+
+ platform_set_drvdata(dev, d);
+
+ return 0;
+
+ err_irq_alloc:
+ err_id:
+ iounmap(d->base);
+ err_ioremap:
+ kfree(d);
+ err_alloc:
+ return ret;
+}
+
+static void neponset_remove(struct platform_device *dev)
+{
+ struct neponset_drvdata *d = platform_get_drvdata(dev);
+ int irq = platform_get_irq(dev, 0);
+
+ if (!IS_ERR(d->sa1111))
+ platform_device_unregister(d->sa1111);
+ if (!IS_ERR(d->smc91x))
+ platform_device_unregister(d->smc91x);
+
+ gpiod_remove_lookup_table(&neponset_pcmcia_table);
+ gpiod_remove_lookup_table(&neponset_uart3_gpio_table);
+ gpiod_remove_lookup_table(&neponset_uart1_gpio_table);
+
+ irq_set_chained_handler(irq, NULL);
+ irq_free_descs(d->irq_base, NEP_IRQ_NR);
+ nep = NULL;
+ iounmap(d->base);
+ kfree(d);
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int neponset_resume(struct device *dev)
+{
+ struct neponset_drvdata *d = dev_get_drvdata(dev);
+ int i, ret = 0;
+
+ for (i = 0; i < ARRAY_SIZE(d->gpio); i++) {
+ ret = gpio_reg_resume(d->gpio[i]);
+ if (ret)
+ break;
+ }
+
+ return ret;
+}
+
+static const struct dev_pm_ops neponset_pm_ops = {
+ .resume_noirq = neponset_resume,
+ .restore_noirq = neponset_resume,
+};
+#define PM_OPS &neponset_pm_ops
+#else
+#define PM_OPS NULL
+#endif
+
+static struct platform_driver neponset_device_driver = {
+ .probe = neponset_probe,
+ .remove_new = neponset_remove,
+ .driver = {
+ .name = "neponset",
+ .pm = PM_OPS,
+ },
+};
+
+static int __init neponset_init(void)
+{
+ return platform_driver_register(&neponset_device_driver);
+}
+
+subsys_initcall(neponset_init);
diff --git a/arch/arm/mach-sa1100/pm.c b/arch/arm/mach-sa1100/pm.c
new file mode 100644
index 000000000..9495fc109
--- /dev/null
+++ b/arch/arm/mach-sa1100/pm.c
@@ -0,0 +1,128 @@
+/*
+ * SA1100 Power Management Routines
+ *
+ * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License.
+ *
+ * History:
+ *
+ * 2001-02-06: Cliff Brake Initial code
+ *
+ * 2001-02-25: Sukjae Cho <sjcho@east.isi.edu> &
+ * Chester Kuo <chester@linux.org.tw>
+ * Save more value for the resume function! Support
+ * Bitsy/Assabet/Freebird board
+ *
+ * 2001-08-29: Nicolas Pitre <nico@fluxnic.net>
+ * Cleaned up, pushed platform dependent stuff
+ * in the platform specific files.
+ *
+ * 2002-05-27: Nicolas Pitre Killed sleep.h and the kmalloced save array.
+ * Storage is local on the stack now.
+ */
+#include <linux/init.h>
+#include <linux/io.h>
+#include <linux/suspend.h>
+#include <linux/errno.h>
+#include <linux/time.h>
+
+#include <mach/hardware.h>
+#include <asm/page.h>
+#include <asm/suspend.h>
+#include <asm/mach/time.h>
+
+#include "generic.h"
+
+extern int sa1100_finish_suspend(unsigned long);
+
+#define SAVE(x) sleep_save[SLEEP_SAVE_##x] = x
+#define RESTORE(x) x = sleep_save[SLEEP_SAVE_##x]
+
+/*
+ * List of global SA11x0 peripheral registers to preserve.
+ * More ones like CP and general purpose register values are preserved
+ * on the stack and then the stack pointer is stored last in sleep.S.
+ */
+enum { SLEEP_SAVE_GPDR, SLEEP_SAVE_GAFR,
+ SLEEP_SAVE_PPDR, SLEEP_SAVE_PPSR, SLEEP_SAVE_PPAR, SLEEP_SAVE_PSDR,
+
+ SLEEP_SAVE_Ser1SDCR0,
+
+ SLEEP_SAVE_COUNT
+};
+
+
+static int sa11x0_pm_enter(suspend_state_t state)
+{
+ unsigned long gpio, sleep_save[SLEEP_SAVE_COUNT];
+
+ gpio = GPLR;
+
+ /* save vital registers */
+ SAVE(GPDR);
+ SAVE(GAFR);
+
+ SAVE(PPDR);
+ SAVE(PPSR);
+ SAVE(PPAR);
+ SAVE(PSDR);
+
+ SAVE(Ser1SDCR0);
+
+ /* Clear previous reset status */
+ RCSR = RCSR_HWR | RCSR_SWR | RCSR_WDR | RCSR_SMR;
+
+ /* set resume return address */
+ PSPR = __pa_symbol(cpu_resume);
+
+ /* go zzz */
+ cpu_suspend(0, sa1100_finish_suspend);
+
+ /*
+ * Ensure not to come back here if it wasn't intended
+ */
+ RCSR = RCSR_SMR;
+ PSPR = 0;
+
+ /*
+ * Ensure interrupt sources are disabled; we will re-init
+ * the interrupt subsystem via the device manager.
+ */
+ ICLR = 0;
+ ICCR = 1;
+ ICMR = 0;
+
+ /* restore registers */
+ RESTORE(GPDR);
+ RESTORE(GAFR);
+
+ RESTORE(PPDR);
+ RESTORE(PPSR);
+ RESTORE(PPAR);
+ RESTORE(PSDR);
+
+ RESTORE(Ser1SDCR0);
+
+ GPSR = gpio;
+ GPCR = ~gpio;
+
+ /*
+ * Clear the peripheral sleep-hold bit.
+ */
+ PSSR = PSSR_PH;
+
+ return 0;
+}
+
+static const struct platform_suspend_ops sa11x0_pm_ops = {
+ .enter = sa11x0_pm_enter,
+ .valid = suspend_valid_only_mem,
+};
+
+int __init sa11x0_pm_init(void)
+{
+ suspend_set_ops(&sa11x0_pm_ops);
+ return 0;
+}
diff --git a/arch/arm/mach-sa1100/sleep.S b/arch/arm/mach-sa1100/sleep.S
new file mode 100644
index 000000000..85863741e
--- /dev/null
+++ b/arch/arm/mach-sa1100/sleep.S
@@ -0,0 +1,143 @@
+/*
+ * SA11x0 Assembler Sleep/WakeUp Management Routines
+ *
+ * Copyright (c) 2001 Cliff Brake <cbrake@accelent.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License.
+ *
+ * History:
+ *
+ * 2001-02-06: Cliff Brake Initial code
+ *
+ * 2001-08-29: Nicolas Pitre Simplified.
+ *
+ * 2002-05-27: Nicolas Pitre Revisited, more cleanup and simplification.
+ * Storage is on the stack now.
+ */
+
+#include <linux/linkage.h>
+#include <asm/assembler.h>
+#include <mach/hardware.h>
+
+ .text
+/*
+ * sa1100_finish_suspend()
+ *
+ * Causes sa11x0 to enter sleep state
+ *
+ * Must be aligned to a cacheline.
+ */
+ .balign 32
+ENTRY(sa1100_finish_suspend)
+ @ disable clock switching
+ mcr p15, 0, r1, c15, c2, 2
+
+ ldr r6, =MDREFR
+ ldr r4, [r6]
+ orr r4, r4, #MDREFR_K1DB2
+ ldr r5, =PPCR
+
+ @ Pre-load __loop_udelay into the I-cache
+ mov r0, #1
+ bl __loop_udelay
+ mov r0, r0
+
+ @ The following must all exist in a single cache line to
+ @ avoid accessing memory until this sequence is complete,
+ @ otherwise we occasionally hang.
+
+ @ Adjust memory timing before lowering CPU clock
+ str r4, [r6]
+
+ @ delay 90us and set CPU PLL to lowest speed
+ @ fixes resume problem on high speed SA1110
+ mov r0, #90
+ bl __loop_udelay
+ mov r1, #0
+ str r1, [r5]
+ mov r0, #90
+ bl __loop_udelay
+
+ /*
+ * SA1110 SDRAM controller workaround. register values:
+ *
+ * r0 = &MSC0
+ * r1 = &MSC1
+ * r2 = &MSC2
+ * r3 = MSC0 value
+ * r4 = MSC1 value
+ * r5 = MSC2 value
+ * r6 = &MDREFR
+ * r7 = first MDREFR value
+ * r8 = second MDREFR value
+ * r9 = &MDCNFG
+ * r10 = MDCNFG value
+ * r11 = third MDREFR value
+ * r12 = &PMCR
+ * r13 = PMCR value (1)
+ */
+
+ ldr r0, =MSC0
+ ldr r1, =MSC1
+ ldr r2, =MSC2
+
+ ldr r3, [r0]
+ bic r3, r3, #FMsk(MSC_RT)
+ bic r3, r3, #FMsk(MSC_RT)<<16
+
+ ldr r4, [r1]
+ bic r4, r4, #FMsk(MSC_RT)
+ bic r4, r4, #FMsk(MSC_RT)<<16
+
+ ldr r5, [r2]
+ bic r5, r5, #FMsk(MSC_RT)
+ bic r5, r5, #FMsk(MSC_RT)<<16
+
+ ldr r7, [r6]
+ bic r7, r7, #0x0000FF00
+ bic r7, r7, #0x000000F0
+ orr r8, r7, #MDREFR_SLFRSH
+
+ ldr r9, =MDCNFG
+ ldr r10, [r9]
+ bic r10, r10, #(MDCNFG_DE0+MDCNFG_DE1)
+ bic r10, r10, #(MDCNFG_DE2+MDCNFG_DE3)
+
+ bic r11, r8, #MDREFR_SLFRSH
+ bic r11, r11, #MDREFR_E1PIN
+
+ ldr r12, =PMCR
+
+ mov r13, #PMCR_SF
+
+ b sa1110_sdram_controller_fix
+
+ .align 5
+sa1110_sdram_controller_fix:
+
+ @ Step 1 clear RT field of all MSCx registers
+ str r3, [r0]
+ str r4, [r1]
+ str r5, [r2]
+
+ @ Step 2 clear DRI field in MDREFR
+ str r7, [r6]
+
+ @ Step 3 set SLFRSH bit in MDREFR
+ str r8, [r6]
+
+ @ Step 4 clear DE bis in MDCNFG
+ str r10, [r9]
+
+ @ Step 5 clear DRAM refresh control register
+ str r11, [r6]
+
+ @ Wow, now the hardware suspend request pins can be used, that makes them functional for
+ @ about 7 ns out of the entire time that the CPU is running!
+
+ @ Step 6 set force sleep bit in PMCR
+
+ str r13, [r12]
+
+20: b 20b @ loop waiting for sleep
diff --git a/arch/arm/mach-sa1100/ssp.c b/arch/arm/mach-sa1100/ssp.c
new file mode 100644
index 000000000..613fd767a
--- /dev/null
+++ b/arch/arm/mach-sa1100/ssp.c
@@ -0,0 +1,240 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * linux/arch/arm/mach-sa1100/ssp.c
+ *
+ * Copyright (C) 2003 Russell King.
+ *
+ * Generic SSP driver. This provides the generic core for simple
+ * IO-based SSP applications.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+#include <mach/irqs.h>
+#include <asm/hardware/ssp.h>
+
+#define TIMEOUT 100000
+
+static irqreturn_t ssp_interrupt(int irq, void *dev_id)
+{
+ unsigned int status = Ser4SSSR;
+
+ if (status & SSSR_ROR)
+ printk(KERN_WARNING "SSP: receiver overrun\n");
+
+ Ser4SSSR = SSSR_ROR;
+
+ return status ? IRQ_HANDLED : IRQ_NONE;
+}
+
+/**
+ * ssp_write_word - write a word to the SSP port
+ * @data: 16-bit, MSB justified data to write.
+ *
+ * Wait for a free entry in the SSP transmit FIFO, and write a data
+ * word to the SSP port. Wait for the SSP port to start sending
+ * the data.
+ *
+ * The caller is expected to perform the necessary locking.
+ *
+ * Returns:
+ * %-ETIMEDOUT timeout occurred
+ * 0 success
+ */
+int ssp_write_word(u16 data)
+{
+ int timeout = TIMEOUT;
+
+ while (!(Ser4SSSR & SSSR_TNF)) {
+ if (!--timeout)
+ return -ETIMEDOUT;
+ cpu_relax();
+ }
+
+ Ser4SSDR = data;
+
+ timeout = TIMEOUT;
+ while (!(Ser4SSSR & SSSR_BSY)) {
+ if (!--timeout)
+ return -ETIMEDOUT;
+ cpu_relax();
+ }
+
+ return 0;
+}
+
+/**
+ * ssp_read_word - read a word from the SSP port
+ *
+ * Wait for a data word in the SSP receive FIFO, and return the
+ * received data. Data is LSB justified.
+ *
+ * Note: Currently, if data is not expected to be received, this
+ * function will wait for ever.
+ *
+ * The caller is expected to perform the necessary locking.
+ *
+ * Returns:
+ * %-ETIMEDOUT timeout occurred
+ * 16-bit data success
+ */
+int ssp_read_word(u16 *data)
+{
+ int timeout = TIMEOUT;
+
+ while (!(Ser4SSSR & SSSR_RNE)) {
+ if (!--timeout)
+ return -ETIMEDOUT;
+ cpu_relax();
+ }
+
+ *data = (u16)Ser4SSDR;
+
+ return 0;
+}
+
+/**
+ * ssp_flush - flush the transmit and receive FIFOs
+ *
+ * Wait for the SSP to idle, and ensure that the receive FIFO
+ * is empty.
+ *
+ * The caller is expected to perform the necessary locking.
+ *
+ * Returns:
+ * %-ETIMEDOUT timeout occurred
+ * 0 success
+ */
+int ssp_flush(void)
+{
+ int timeout = TIMEOUT * 2;
+
+ do {
+ while (Ser4SSSR & SSSR_RNE) {
+ if (!--timeout)
+ return -ETIMEDOUT;
+ (void) Ser4SSDR;
+ }
+ if (!--timeout)
+ return -ETIMEDOUT;
+ } while (Ser4SSSR & SSSR_BSY);
+
+ return 0;
+}
+
+/**
+ * ssp_enable - enable the SSP port
+ *
+ * Turn on the SSP port.
+ */
+void ssp_enable(void)
+{
+ Ser4SSCR0 |= SSCR0_SSE;
+}
+
+/**
+ * ssp_disable - shut down the SSP port
+ *
+ * Turn off the SSP port, optionally powering it down.
+ */
+void ssp_disable(void)
+{
+ Ser4SSCR0 &= ~SSCR0_SSE;
+}
+
+/**
+ * ssp_save_state - save the SSP configuration
+ * @ssp: pointer to structure to save SSP configuration
+ *
+ * Save the configured SSP state for suspend.
+ */
+void ssp_save_state(struct ssp_state *ssp)
+{
+ ssp->cr0 = Ser4SSCR0;
+ ssp->cr1 = Ser4SSCR1;
+
+ Ser4SSCR0 &= ~SSCR0_SSE;
+}
+
+/**
+ * ssp_restore_state - restore a previously saved SSP configuration
+ * @ssp: pointer to configuration saved by ssp_save_state
+ *
+ * Restore the SSP configuration saved previously by ssp_save_state.
+ */
+void ssp_restore_state(struct ssp_state *ssp)
+{
+ Ser4SSSR = SSSR_ROR;
+
+ Ser4SSCR0 = ssp->cr0 & ~SSCR0_SSE;
+ Ser4SSCR1 = ssp->cr1;
+ Ser4SSCR0 = ssp->cr0;
+}
+
+/**
+ * ssp_init - setup the SSP port
+ *
+ * initialise and claim resources for the SSP port.
+ *
+ * Returns:
+ * %-ENODEV if the SSP port is unavailable
+ * %-EBUSY if the resources are already in use
+ * %0 on success
+ */
+int ssp_init(void)
+{
+ int ret;
+
+ if (!(PPAR & PPAR_SPR) && (Ser4MCCR0 & MCCR0_MCE))
+ return -ENODEV;
+
+ if (!request_mem_region(__PREG(Ser4SSCR0), 0x18, "SSP")) {
+ return -EBUSY;
+ }
+
+ Ser4SSSR = SSSR_ROR;
+
+ ret = request_irq(IRQ_Ser4SSP, ssp_interrupt, 0, "SSP", NULL);
+ if (ret)
+ goto out_region;
+
+ return 0;
+
+ out_region:
+ release_mem_region(__PREG(Ser4SSCR0), 0x18);
+ return ret;
+}
+
+/**
+ * ssp_exit - undo the effects of ssp_init
+ *
+ * release and free resources for the SSP port.
+ */
+void ssp_exit(void)
+{
+ Ser4SSCR0 &= ~SSCR0_SSE;
+
+ free_irq(IRQ_Ser4SSP, NULL);
+ release_mem_region(__PREG(Ser4SSCR0), 0x18);
+}
+
+MODULE_AUTHOR("Russell King");
+MODULE_DESCRIPTION("SA11x0 SSP PIO driver");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(ssp_write_word);
+EXPORT_SYMBOL(ssp_read_word);
+EXPORT_SYMBOL(ssp_flush);
+EXPORT_SYMBOL(ssp_enable);
+EXPORT_SYMBOL(ssp_disable);
+EXPORT_SYMBOL(ssp_save_state);
+EXPORT_SYMBOL(ssp_restore_state);
+EXPORT_SYMBOL(ssp_init);
+EXPORT_SYMBOL(ssp_exit);