summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2011-01-06 11:26:18 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2011-01-06 11:26:18 +0100
commitf39d4d225ebdfdf5c2435e9895355c6b5fc74973 (patch)
treeffbbe92109e7323d43a6c18503a5f0a904fc0c2f
parentd836124f8bbe05843a3f954727e6544a0fb96013 (diff)
parentd4d7a192587bb25051dbc845aab45301d22e6ed3 (diff)
downloadbarebox-f39d4d225ebdfdf5c2435e9895355c6b5fc74973.tar.gz
barebox-f39d4d225ebdfdf5c2435e9895355c6b5fc74973.tar.xz
Merge branch 'next'
-rw-r--r--.gitignore2
-rw-r--r--Documentation/boards.dox1
-rw-r--r--Makefile8
-rw-r--r--arch/arm/Kconfig5
-rw-r--r--arch/arm/Makefile3
-rw-r--r--arch/arm/boards/chumby_falconwing/falconwing.c184
-rw-r--r--arch/arm/boards/karo-tx28/Makefile2
-rw-r--r--arch/arm/boards/karo-tx28/config.h16
-rw-r--r--arch/arm/boards/karo-tx28/env/config47
-rw-r--r--arch/arm/boards/karo-tx28/tx28-stk5.c377
-rw-r--r--arch/arm/boards/karo-tx28/tx28.c156
-rw-r--r--arch/arm/boards/pcm043/pcm043.c10
-rw-r--r--arch/arm/boards/versatile/Kconfig10
-rw-r--r--arch/arm/boards/versatile/Makefile2
-rw-r--r--arch/arm/boards/versatile/config.h5
-rw-r--r--arch/arm/boards/versatile/versatilepb.c72
-rw-r--r--arch/arm/configs/chumbyone_defconfig4
-rw-r--r--arch/arm/configs/tx28stk5_defconfig46
-rw-r--r--arch/arm/configs/versatilepb_defconfig48
-rw-r--r--arch/arm/cpu/Kconfig3
-rw-r--r--arch/arm/cpu/start.c3
-rw-r--r--arch/arm/include/asm/hardware/arm_timer.h33
-rw-r--r--arch/arm/mach-imx/include/mach/generic.h2
-rw-r--r--arch/arm/mach-imx/include/mach/imx-flash-header.h12
-rw-r--r--arch/arm/mach-imx/include/mach/imx-regs.h4
-rw-r--r--arch/arm/mach-omap/include/mach/omap3-clock.h33
-rw-r--r--arch/arm/mach-omap/include/mach/omap3-silicon.h16
-rw-r--r--arch/arm/mach-omap/include/mach/sys_info.h40
-rw-r--r--arch/arm/mach-omap/omap3_clock.c547
-rw-r--r--arch/arm/mach-omap/omap3_clock_core.S290
-rw-r--r--arch/arm/mach-omap/omap3_generic.c89
-rw-r--r--arch/arm/mach-stm/Kconfig36
-rw-r--r--arch/arm/mach-stm/Makefile6
-rw-r--r--arch/arm/mach-stm/clocksource-imx28.c73
-rw-r--r--arch/arm/mach-stm/imx.c (renamed from arch/arm/mach-stm/imx23.c)0
-rw-r--r--arch/arm/mach-stm/imx_lcd_clk.c149
-rw-r--r--arch/arm/mach-stm/include/mach/clock-imx23.h28
-rw-r--r--arch/arm/mach-stm/include/mach/clock-imx28.h31
-rw-r--r--arch/arm/mach-stm/include/mach/clock.h22
-rw-r--r--arch/arm/mach-stm/include/mach/fb.h43
-rw-r--r--arch/arm/mach-stm/include/mach/generic.h6
-rw-r--r--arch/arm/mach-stm/include/mach/gpio.h11
-rw-r--r--arch/arm/mach-stm/include/mach/imx-regs.h9
-rw-r--r--arch/arm/mach-stm/include/mach/imx23-regs.h1
-rw-r--r--arch/arm/mach-stm/include/mach/imx28-regs.h47
-rw-r--r--arch/arm/mach-stm/include/mach/iomux-imx28.h552
-rw-r--r--arch/arm/mach-stm/iomux-imx.c (renamed from arch/arm/mach-stm/iomux-imx23.c)114
-rw-r--r--arch/arm/mach-stm/reset-imx.c (renamed from arch/arm/mach-stm/reset-imx23.c)0
-rw-r--r--arch/arm/mach-stm/speed-imx23.c52
-rw-r--r--arch/arm/mach-stm/speed-imx28.c392
-rw-r--r--arch/arm/mach-versatile/Kconfig16
-rw-r--r--arch/arm/mach-versatile/Makefile2
-rw-r--r--arch/arm/mach-versatile/core.c224
-rw-r--r--arch/arm/mach-versatile/include/mach/clkdev.h7
-rw-r--r--arch/arm/mach-versatile/include/mach/debug_ll.h37
-rw-r--r--arch/arm/mach-versatile/include/mach/init.h8
-rw-r--r--arch/arm/mach-versatile/include/mach/platform.h417
-rw-r--r--arch/arm/tools/mach-types385
-rw-r--r--commands/Kconfig15
-rw-r--r--commands/Makefile2
-rw-r--r--commands/crc.c2
-rw-r--r--commands/flash.c4
-rw-r--r--commands/go.c2
-rw-r--r--commands/gpio.c2
-rw-r--r--commands/led.c90
-rw-r--r--commands/loadb.c3
-rw-r--r--commands/ls.c4
-rw-r--r--commands/menu.c2
-rw-r--r--commands/trigger.c107
-rw-r--r--commands/xyzModem.c2
-rw-r--r--common/Kconfig3
-rw-r--r--common/Makefile1
-rw-r--r--common/console.c5
-rw-r--r--common/console_simple.c26
-rw-r--r--common/poller.c45
-rw-r--r--common/startup.c2
-rw-r--r--drivers/Kconfig1
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/led/Kconfig21
-rw-r--r--drivers/led/Makefile3
-rw-r--r--drivers/led/core.c157
-rw-r--r--drivers/led/led-gpio.c94
-rw-r--r--drivers/led/led-triggers.c153
-rw-r--r--drivers/mci/Kconfig4
-rw-r--r--drivers/mci/stm378x.c143
-rw-r--r--drivers/net/fec_imx.c95
-rw-r--r--drivers/net/fec_imx.h23
-rw-r--r--drivers/net/netx_eth.c1
-rw-r--r--drivers/nor/cfi_flash.c143
-rw-r--r--drivers/nor/cfi_flash.h25
-rw-r--r--drivers/serial/Kconfig2
-rw-r--r--drivers/serial/stm-serial.c9
-rw-r--r--drivers/spi/imx_spi.c3
-rw-r--r--drivers/video/Kconfig7
-rw-r--r--drivers/video/Makefile1
-rw-r--r--drivers/video/fb.c44
-rw-r--r--drivers/video/stm.c540
-rw-r--r--include/common.h19
-rw-r--r--include/cramfs/cramfs_fs.h4
-rw-r--r--include/fb.h3
-rw-r--r--include/led.h102
-rw-r--r--include/net.h4
-rw-r--r--include/poller.h31
-rw-r--r--include/stdio.h18
-rw-r--r--include/usb/usb.h2
-rw-r--r--lib/readline.c4
-rw-r--r--lib/vsprintf.c4
-rw-r--r--net/eth.c8
-rw-r--r--net/net.c20
-rw-r--r--net/tftp.c2
110 files changed, 6210 insertions, 536 deletions
diff --git a/.gitignore b/.gitignore
index 4a4511394c..84d9f73580 100644
--- a/.gitignore
+++ b/.gitignore
@@ -35,8 +35,6 @@ barebox.netx
barebox.map
System.map
Module.symvers
-ARCH
-CROSS_COMPILE
barebox_default_env
#
diff --git a/Documentation/boards.dox b/Documentation/boards.dox
index c04e06b433..8087f015cd 100644
--- a/Documentation/boards.dox
+++ b/Documentation/boards.dox
@@ -14,6 +14,7 @@ ARM type:
@li @subpage pcm043
@li @subpage imx21ads
@li @subpage imx27ads
+@li @subpage tx28
@li @subpage the3stack
@li @subpage mx23_evk
@li @subpage board_babage
diff --git a/Makefile b/Makefile
index 637960c2f8..2f6aa8100b 100644
--- a/Makefile
+++ b/Makefile
@@ -389,7 +389,11 @@ ifeq ($(config-targets),1)
include $(srctree)/arch/$(ARCH)/Makefile
export KBUILD_DEFCONFIG
-config %config: scripts_basic outputmakefile FORCE
+config: scripts_basic outputmakefile FORCE
+ $(Q)mkdir -p include/linux include/config
+ $(Q)$(MAKE) $(build)=scripts/kconfig $@
+
+%config: scripts_basic outputmakefile FORCE
$(Q)mkdir -p include/linux include/config
$(Q)$(MAKE) $(build)=scripts/kconfig $@
@@ -1251,7 +1255,7 @@ target-dir = $(dir $@)
$(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@)
# Modules
-/ %/: prepare scripts FORCE
+%/: prepare scripts FORCE
$(Q)$(MAKE) $(build)=$(build-dir)
%.ko: prepare scripts FORCE
$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 8cb86cb449..f1536a5b15 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -61,6 +61,10 @@ config ARCH_S3C24xx
select CPU_ARM920T
select GENERIC_GPIO
+config ARCH_VERSATILE
+ bool "ARM Versatile boards (ARM926EJ-S)"
+ select CPU_ARM926T
+
endchoice
source arch/arm/cpu/Kconfig
@@ -72,6 +76,7 @@ source arch/arm/mach-netx/Kconfig
source arch/arm/mach-nomadik/Kconfig
source arch/arm/mach-omap/Kconfig
source arch/arm/mach-s3c24xx/Kconfig
+source arch/arm/mach-versatile/Kconfig
config AEABI
bool "Use the ARM EABI to compile barebox"
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 9729c23572..c90960e565 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -46,6 +46,7 @@ machine-$(CONFIG_ARCH_NOMADIK) := nomadik
machine-$(CONFIG_ARCH_NETX) := netx
machine-$(CONFIG_ARCH_OMAP) := omap
machine-$(CONFIG_ARCH_S3C24xx) := s3c24xx
+machine-$(CONFIG_ARCH_VERSATILE) := versatile
# Board directory name. This list is sorted alphanumerically
# by CONFIG_* macro name.
@@ -88,9 +89,11 @@ board-$(CONFIG_MACH_SCB9328) := scb9328
board-$(CONFIG_MACH_NESO) := guf-neso
board-$(CONFIG_MACH_MX23EVK) := freescale-mx23-evk
board-$(CONFIG_MACH_CHUMBY) := chumby_falconwing
+board-$(CONFIG_MACH_TX28) := karo-tx28
board-$(CONFIG_MACH_FREESCALE_MX51_PDK) := freescale-mx51-pdk
board-$(CONFIG_MACH_GUF_CUPID) := guf-cupid
board-$(CONFIG_MACH_MINI2440) := mini2440
+board-$(CONFIG_MACH_VERSATILEPB) := versatile
machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
diff --git a/arch/arm/boards/chumby_falconwing/falconwing.c b/arch/arm/boards/chumby_falconwing/falconwing.c
index 952a384061..76ff9068ff 100644
--- a/arch/arm/boards/chumby_falconwing/falconwing.c
+++ b/arch/arm/boards/chumby_falconwing/falconwing.c
@@ -28,6 +28,7 @@
#include <mach/imx-regs.h>
#include <mach/clock.h>
#include <mach/mci.h>
+#include <mach/fb.h>
static struct memory_platform_data ram_pdata = {
.name = "ram0",
@@ -35,6 +36,7 @@ static struct memory_platform_data ram_pdata = {
};
static struct device_d sdram_dev = {
+ .id = -1,
.name = "mem",
.map_base = IMX_MEMORY_BASE,
.size = 64 * 1024 * 1024,
@@ -52,6 +54,45 @@ static struct device_d mci_dev = {
.platform_data = &mci_pdata,
};
+static struct fb_videomode falconwing_vmode = {
+ /*
+ * Nanovision NMA35QV65-B2-K01 (directly connected)
+ * Clock: 6.25 MHz
+ * Syncs: high active, DE low active
+ * Display area: 70.08 mm x 52.56 mm
+ */
+ .name = "NMA35",
+ .refresh = 60,
+ .xres = 320,
+ .yres = 240,
+ .pixclock = KHZ2PICOS(6250), /* max. 10 MHz */
+ /* line lenght should be 64 µs */
+ .left_margin = 28,
+ .hsync_len = 24,
+ .right_margin = 28,
+ /* frame rate should be 60 Hz */
+ .upper_margin = 8,
+ .vsync_len = 4,
+ .lower_margin = 8,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+};
+
+static struct imx_fb_videomode fb_mode = {
+ .mode_list = &falconwing_vmode,
+ .mode_cnt = 1,
+ /* the NMA35 is a 24 bit display, but only 18 bits are connected */
+ .ld_intf_width = STMLCDIF_18BIT,
+};
+
+static struct device_d ldcif_dev = {
+ .name = "stmfb",
+ .map_base = IMX_FB_BASE,
+ .size = 4096,
+ .platform_data = &fb_mode,
+};
+
static const uint32_t pad_setup[] = {
/* may be not required as already done by the bootlet code */
#if 0
@@ -112,33 +153,34 @@ static const uint32_t pad_setup[] = {
PWM0_DUART_RX | STRENGTH(S4MA), /* strength is TBD */
/* lcd */
- LCD_VSYNC, /* kernel tries with 12 mA for all LCD related pins */
- LCD_HSYNC,
- LCD_ENABE,
- LCD_DOTCLOCK,
- LCD_D17,
- LCD_D16,
- LCD_D15,
- LCD_D14,
- LCD_D13,
- LCD_D12,
- LCD_D11,
- LCD_D10,
- LCD_D9,
- LCD_D8,
- LCD_D7,
- LCD_D6,
- LCD_D5,
- LCD_D4,
- LCD_D3,
- LCD_D2,
- LCD_D1,
- LCD_D0,
+ LCD_VSYNC | STRENGTH(S12MA),
+ LCD_HSYNC | STRENGTH(S12MA),
+ LCD_ENABE | STRENGTH(S12MA),
+ LCD_DOTCLOCK | STRENGTH(S12MA),
+ LCD_D17 | STRENGTH(S12MA),
+ LCD_D16 | STRENGTH(S12MA),
+ LCD_D15 | STRENGTH(S12MA),
+ LCD_D14 | STRENGTH(S12MA),
+ LCD_D13 | STRENGTH(S12MA),
+ LCD_D12 | STRENGTH(S12MA),
+ LCD_D11 | STRENGTH(S12MA),
+ LCD_D10 | STRENGTH(S12MA),
+ LCD_D9 | STRENGTH(S12MA),
+ LCD_D8 | STRENGTH(S12MA),
+ LCD_D7 | STRENGTH(S12MA),
+ LCD_D6 | STRENGTH(S12MA),
+ LCD_D5 | STRENGTH(S12MA),
+ LCD_D4 | STRENGTH(S12MA),
+ LCD_D3 | STRENGTH(S12MA),
+ LCD_D2 | STRENGTH(S12MA),
+ LCD_D1 | STRENGTH(S12MA),
+ LCD_D0 | STRENGTH(S12MA),
/* LCD usage currently unknown */
LCD_CS, /* used as SPI SS */
LCD_RS, /* used as SPI CLK */
- LCD_RESET,
+ /* keep the display in reset state */
+ LCD_RESET_GPIO | STRENGTH(S4MA) | GPIO_OUT | GPIO_VALUE(0),
LCD_WR, /* used as SPI MOSI */
/* I2C to the MMA7455L, KXTE9, AT24C08 (DCID), AT24C128B (ID EEPROM) and QN8005B */
@@ -224,8 +266,8 @@ static const uint32_t pad_setup[] = {
* Try to register an environment storage on the attached MCI card
* @return 0 on success
*
- * We relay on the existance of a useable SD card, already attached to
- * our system, to get someting like a persistant memory for our environment.
+ * We rely on the existence of a usable SD card, already attached to
+ * our system, to get something like a persistent memory for our environment.
* If this SD card is also the boot media, we can use the second partition
* for our environment purpose (if present!).
*/
@@ -252,7 +294,7 @@ static int register_persistant_environment(void)
return -ENODEV;
}
- /* use the full partition as our persistant environment storage */
+ /* use the full partition as our persistent environment storage */
return devfs_add_partition("disk0.1", 0, cdev->size, DEVFS_PARTITION_FIXED, "env0");
}
@@ -265,10 +307,11 @@ static int falconwing_devices_init(void)
imx_gpio_mode(pad_setup[i]);
register_device(&sdram_dev);
- imx_set_ioclk(480U * 1000U); /* enable IOCLK to run at the PLL frequency */
+ imx_set_ioclk(480000000); /* enable IOCLK to run at the PLL frequency */
/* run the SSP unit clock at 100,000 kHz */
- imx_set_sspclk(0, 100U * 1000U, 1);
+ imx_set_sspclk(0, 100000000, 1);
register_device(&mci_dev);
+ register_device(&ldcif_dev);
armlinux_add_dram(&sdram_dev);
armlinux_set_bootparams((void*)(sdram_dev.map_base + 0x100));
@@ -347,4 +390,89 @@ make ARCH=arm CROSS_COMPILE=armv5compiler
partition or you can do it in the classic way: mkfs on it, mount it and copy
all required data and programs into it.
+@section gpio_falconwing Available GPIOs
+
+The Falconwing uses some GPIOs to control various features. With the regular
+GPIO commands these features can be controlled at @a barebox's runtime.
+
+<table width="100%" border="1" cellspacing="1" cellpadding="3">
+ <tr>
+ <td>No</td>
+ <td>Direction</td>
+ <td>Function</td>
+ <td>Reset</td>
+ <td>Set</td>
+ </tr>
+ <tr>
+ <td>8</td>
+ <td>Output</td>
+ <td>Switch Audio Amplifier</td>
+ <td>Off</td>
+ <td>On</td>
+ </tr>
+ <tr>
+ <td>11</td>
+ <td>Input</td>
+ <td>Head Phone Detection</td>
+ <td>TBD</td>
+ <td>TBD</td>
+ </tr>
+ <tr>
+ <td>14</td>
+ <td>Input</td>
+ <td>Unused (J113)</td>
+ <td>User</td>
+ <td>User</td>
+ </tr>
+ <tr>
+ <td>15</td>
+ <td>Input</td>
+ <td>Unused (J114)</td>
+ <td>User</td>
+ <td>User</td>
+ </tr>
+ <tr>
+ <td>26</td>
+ <td>Output</td>
+ <td>USB Power</td>
+ <td>TBD</td>
+ <td>TBD</td>
+ </tr>
+ <tr>
+ <td>27</td>
+ <td>Input</td>
+ <td>Display Connected</td>
+ <td>Display<br>Attached</td>
+ <td>Display<br>Disconnected</td>
+ </tr>
+ <tr>
+ <td>29</td>
+ <td>Output</td>
+ <td>USB HUB Reset</td>
+ <td>TBD</td>
+ <td>TBD</td>
+ </tr>
+ <tr>
+ <td>50</td>
+ <td>Output</td>
+ <td>Display Reset</td>
+ <td>Display<br>Reset</td>
+ <td>Display<br>Running</td>
+ </tr>
+ <tr>
+ <td>60</td>
+ <td>Output</td>
+ <td>Display Backlight</td>
+ <td>Backlight<br>Off</td>
+ <td>Backlight<br>On (100 %)</td>
+ </tr>
+ <tr>
+ <td>62</td>
+ <td>Input</td>
+ <td>Bend</td>
+ <td>Not pressed</td>
+ <td>Pressed</td>
+ </tr>
+</table>
+
*/
diff --git a/arch/arm/boards/karo-tx28/Makefile b/arch/arm/boards/karo-tx28/Makefile
new file mode 100644
index 0000000000..d80ba17930
--- /dev/null
+++ b/arch/arm/boards/karo-tx28/Makefile
@@ -0,0 +1,2 @@
+obj-y += tx28.o
+obj-$(CONFIG_MACH_TX28STK5) += tx28-stk5.o
diff --git a/arch/arm/boards/karo-tx28/config.h b/arch/arm/boards/karo-tx28/config.h
new file mode 100644
index 0000000000..8f18fda7cc
--- /dev/null
+++ b/arch/arm/boards/karo-tx28/config.h
@@ -0,0 +1,16 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef _CONFIG_H_
+# define _CONFIG_H_
+
+#endif /* _CONFIG_H_ */
diff --git a/arch/arm/boards/karo-tx28/env/config b/arch/arm/boards/karo-tx28/env/config
new file mode 100644
index 0000000000..9b302b8e5d
--- /dev/null
+++ b/arch/arm/boards/karo-tx28/env/config
@@ -0,0 +1,47 @@
+#
+#
+
+machine=tx28
+baseboard=tx28stk5
+
+# use 'dhcp' to do dhcp in barebox and in kernel
+# use 'none' if you want to skip kernel ip autoconfiguration
+ip=dhcp
+
+# or set your networking parameters here
+#eth0.ipaddr=a.b.c.d
+#eth0.ethaddr=de:ad:be:ef:00:00
+#eth0.netmask=a.b.c.d
+#eth0.serverip=a.b.c.d
+#eth0.gateway=a.b.c.d
+
+# can be either 'net'
+kernel_loc=net
+# can be either 'net' or 'initrd'
+rootfs_loc=net
+
+# can be either 'jffs2' or 'ubifs'
+rootfs_type=ubifs
+rootfsimage=root-$machine.$rootfs_type
+
+# The image type of the kernel. Can be uimage, zimage, raw, or raw_lzo
+kernelimage_type=zimage
+kernelimage=zImage-$machine
+#kernelimage_type=uimage
+#kernelimage=uImage-$machine
+#kernelimage_type=raw
+#kernelimage=Image-$machine
+#kernelimage_type=raw_lzo
+#kernelimage=Image-$machine.lzo
+
+if [ -n $user ]; then
+ kernelimage="$user"-"$kernelimage"
+ nfsroot="$eth0.serverip:/home/$user/nfsroot/$machine"
+ rootfsimage="$user"-"$rootfsimage"
+else
+ nfsroot="$eth0.serverip:/path/to/nfs/root"
+fi
+
+autoboot_timeout=3
+
+bootargs="console=ttyAM0,115200 tx28_base=$baseboard"
diff --git a/arch/arm/boards/karo-tx28/tx28-stk5.c b/arch/arm/boards/karo-tx28/tx28-stk5.c
new file mode 100644
index 0000000000..6de41f7649
--- /dev/null
+++ b/arch/arm/boards/karo-tx28/tx28-stk5.c
@@ -0,0 +1,377 @@
+/*
+ * Copyright (C) 2010 Juergen Beisert, Pengutronix <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <gpio.h>
+#include <environment.h>
+#include <errno.h>
+#include <mci.h>
+#include <fec.h>
+#include <asm/io.h>
+#include <mach/imx-regs.h>
+#include <mach/clock.h>
+#include <mach/mci.h>
+#include <mach/fb.h>
+
+static struct stm_mci_platform_data mci_pdata = {
+ .caps = MMC_MODE_4BIT | MMC_MODE_HS | MMC_MODE_HS_52MHz,
+ .voltages = MMC_VDD_32_33 | MMC_VDD_33_34, /* fixed to 3.3 V */
+ .f_min = 400 * 1000,
+};
+
+static struct device_d mci_socket = {
+ .name = "stm_mci",
+ .map_base = IMX_SSP0_BASE,
+ .platform_data = &mci_pdata,
+};
+
+/* PhyAD[0..2]=0, RMIISEL=1 */
+static struct fec_platform_data fec_info = {
+ .xcv_type = RMII,
+ .phy_addr = 0,
+};
+
+static struct device_d fec_dev = {
+ .name = "fec_imx",
+ .map_base = IMX_FEC0_BASE,
+ .platform_data = &fec_info,
+};
+
+/*
+ * The TX28 EVK comes with a VGA connector. We can support many video modes
+ *
+ * Note: The VGA connector is driven from the LCD lines via an ADV7125. This
+ * DA converter needs an high active DE signal to show a video signal.
+ */
+static struct fb_videomode tx28evk_vmodes[] = {
+ {
+ /*
+ * Modeline "640x480" x 59.9 (to be used with the VGA connector)
+ * Clock: 25.18 MHz
+ * Line: 640 656 752 800 (31.5 kHz)
+ * Frame: 480 490 492 525
+ * Syncs: -hsync -vsync
+ */
+ .name = "VGA",
+ .refresh = 60,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = KHZ2PICOS(25180),
+ .left_margin = 48,
+ .hsync_len = 96,
+ .right_margin = 16,
+ .upper_margin = 33,
+ .vsync_len = 2,
+ .lower_margin = 10,
+ .sync = FB_SYNC_DE_HIGH_ACT,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ }, {
+ /*
+ * Emerging ETV570 640 x 480 display (directly connected)
+ * Clock: 25.175 MHz
+ * Syncs: low active, DE high active
+ * Display area: 115.2 mm x 86.4 mm
+ */
+ .name = "ETV570",
+ .refresh = 60,
+ .xres = 640,
+ .yres = 480,
+ .pixclock = KHZ2PICOS(25175),
+ .left_margin = 114,
+ .hsync_len = 30,
+ .right_margin = 16,
+ .upper_margin = 32,
+ .vsync_len = 3,
+ .lower_margin = 10,
+ .sync = FB_SYNC_DE_HIGH_ACT,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ /*
+ * This display is connected:
+ * display side -> CPU side
+ * ----------------------------
+ * RESET# pin -> GPIO126 (3/30) LCD_RESET -> L = display reset
+ * PWRCTRL pin -> GPIO63 (1/31) LCD_ENABLE - > H=on, L=off
+ * LEDCTRL pin -> GPIO112 (2/16) PWM0 -> 2.5 V = LEDs off
+ * -> 0 V = LEDs on
+ *
+ * Note: Backlight is on, only if PWRCTRL=H _and_ LEDCTRL=0
+ */
+ }, {
+ /*
+ * Modeline "800x600" x 60.3
+ * Clock: 40.00 MHz
+ * Line: 800 840 968 1056 (37.9 kHz)
+ * Frame: 600 601 605 628
+ * Syncs: +hsync +vsync
+ */
+ .name = "SVGA",
+ .refresh = 60,
+ .xres = 800,
+ .yres = 600,
+ .pixclock = KHZ2PICOS(40000),
+ .left_margin = 88,
+ .hsync_len = 128,
+ .right_margin = 40,
+ .upper_margin = 23,
+ .vsync_len = 4,
+ .lower_margin = 1,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT |
+ FB_SYNC_DE_HIGH_ACT,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ }, {
+ /*
+ * Modeline "1024x768" x 60.0
+ * Clock: 65.00 MHz
+ * Line: 1024 1048 1184 1344 (48.4 kHz)
+ * Frame: 768 771 777 806
+ * Syncs: -hsync -vsync
+ */
+ .name = "XGA",
+ .refresh = 60,
+ .xres = 1024,
+ .yres = 768,
+ .pixclock = KHZ2PICOS(65000),
+ .left_margin = 160,
+ .hsync_len = 136,
+ .right_margin = 24,
+ .upper_margin = 29,
+ .vsync_len = 6,
+ .lower_margin = 3,
+ .sync = FB_SYNC_DE_HIGH_ACT,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ }, {
+ /*
+ * Modeline "1280x1024" x 60.0
+ * Clock: 108.00 MHz
+ * Line: 1280 1328 1440 1688 (64.0 kHz)
+ * Frame: 1024 1025 1028 1066
+ * Syncs: +hsync +vsync
+ */
+ .name = "SXGA",
+ .refresh = 60,
+ .xres = 1280,
+ .yres = 1024,
+ .pixclock = KHZ2PICOS(108000),
+ .left_margin = 248,
+ .hsync_len = 112,
+ .right_margin = 48,
+ .upper_margin = 38,
+ .vsync_len = 3,
+ .lower_margin = 1,
+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT |
+ FB_SYNC_DE_HIGH_ACT,
+ .vmode = FB_VMODE_NONINTERLACED,
+ .flag = 0,
+ },
+};
+
+static struct imx_fb_videomode imxfb_mode = {
+ .mode_list = tx28evk_vmodes,
+ .mode_cnt = ARRAY_SIZE(tx28evk_vmodes),
+ .dotclk_delay = 0, /* no adaption required */
+ .ld_intf_width = STMLCDIF_24BIT, /* full 24 bit */
+};
+
+static struct device_d ldcif_dev = {
+ .name = "stmfb",
+ .map_base = IMX_FB_BASE,
+ .size = 4096,
+ .platform_data = &imxfb_mode,
+};
+
+static const uint32_t tx28_starterkit_pad_setup[] = {
+ /*
+ * Part II of phy's initialization
+ * Setup phy's mode to '111'
+ */
+
+ /*
+ * force the mod pins to a specific level
+ * '111' means: "All capable. Auto-negotiation enabled".
+ * For other values refer LAN8710's datasheet,
+ * chapter "Mode Bus - MODE[2:0]"
+ */
+ ENET0_RXD0_GPIO | VE_3_3V | GPIO_OUT | GPIO_VALUE(1), /* MOD0 */
+ ENET0_RXD1_GPIO | VE_3_3V | GPIO_OUT | GPIO_VALUE(1), /* MOD1 */
+ ENET0_RX_EN_GPIO | VE_3_3V | GPIO_OUT | GPIO_VALUE(1), /* MOD2 */
+
+ /* release the reset ('mod' pins get latched) */
+ ENET0_RX_CLK_GPIO | VE_3_3V | BITKEEPER(0) | GPIO_OUT | GPIO_VALUE(1),
+
+ /* right now the 'mod' pins are in their native mode */
+ ENET0_RXD0 | VE_3_3V | PULLUP(0),
+ ENET0_RXD1 | VE_3_3V | PULLUP(0),
+ ENET0_RX_EN | VE_3_3V | PULLUP(0),
+
+ /* Debug UART, available at card connector UART1 */
+ AUART0_CTS_DUART_RX | VE_3_3V | STRENGTH(S8MA),
+ AUART0_RTS_DUART_TX | VE_3_3V | STRENGTH(S8MA),
+ AUART0_RX_DUART_CTS | VE_3_3V | STRENGTH(S8MA),
+ AUART0_TX_DUART_RTS | VE_3_3V | STRENGTH(S8MA),
+ /* Application UART, available at connector UART2 */
+ AUART1_RX | VE_3_3V | BITKEEPER(0),
+ AUART1_TX | VE_3_3V | BITKEEPER(0),
+ AUART1_CTS | VE_3_3V | PULLUP(1),
+ AUART1_RTS | VE_3_3V | PULLUP(1),
+ /* Application UART, available at connector FIXME */
+ AUART2_RX | VE_3_3V | PULLUP(1),
+ AUART2_TX | VE_3_3V | PULLUP(1),
+ AUART2_CTS | VE_3_3V | BITKEEPER(0),
+ AUART2_RTS | VE_3_3V | BITKEEPER(0),
+
+ /* MCI interface */
+ SSP0_D0 | VE_3_3V | PULLUP(1),
+ SSP0_D1 | VE_3_3V | PULLUP(1),
+ SSP0_D2 | VE_3_3V | PULLUP(1),
+ SSP0_D3 | VE_3_3V | PULLUP(1),
+ SSP0_CMD | VE_3_3V | PULLUP(1),
+ SSP0_CD | VE_3_3V | PULLUP(1),
+ SSP0_SCK | VE_3_3V | BITKEEPER(0),
+
+ /* MCI slot power control 1 = off */
+ PWM3_GPIO | VE_3_3V | GPIO_OUT | GPIO_VALUE(0),
+ /* MCI write protect 1 = not protected */
+ SSP1_SCK_GPIO | VE_3_3V | GPIO_IN, /* FIXME pull up ? */
+
+ /* LED */
+ ENET0_RXD3_GPIO | VE_3_3V | GPIO_OUT | GPIO_VALUE(1),
+
+ /*
+ * The backlight is on, if:
+ * - the PWM0 pin outputs a low level
+ * * AND *
+ * - the LCD_ENABLE is at high level.
+ * In all other combinations the backlight is off.
+ *
+ * Switch it off here to avoid flickering.
+ */
+ PWM0_GPIO | VE_3_3V | PULLUP(0) | GPIO_OUT | GPIO_VALUE(1),
+
+ /* LCD interface to the VGA connector */
+ /* sync signals */
+ LCD_WR_RWN_LCD_HSYNC | VE_3_3V | BITKEEPER(0),
+ LCD_RD_E_LCD_VSYNC | VE_3_3V | BITKEEPER(0),
+ LCD_CS_LCD_ENABLE | VE_3_3V | BITKEEPER(0),
+ LCD_RS_LCD_DOTCLK | VE_3_3V | BITKEEPER(0),
+ /* data signals */
+ LCD_D0 | VE_3_3V | BITKEEPER(0),
+ LCD_D1 | VE_3_3V | BITKEEPER(0),
+ LCD_D2 | VE_3_3V | BITKEEPER(0),
+ LCD_D3 | VE_3_3V | BITKEEPER(0),
+ LCD_D4 | VE_3_3V | BITKEEPER(0),
+ LCD_D5 | VE_3_3V | BITKEEPER(0),
+ LCD_D6 | VE_3_3V | BITKEEPER(0),
+ LCD_D7 | VE_3_3V | BITKEEPER(0),
+ LCD_D8 | VE_3_3V | BITKEEPER(0),
+ LCD_D9 | VE_3_3V | BITKEEPER(0),
+ LCD_D10 | VE_3_3V | BITKEEPER(0),
+ LCD_D11 | VE_3_3V | BITKEEPER(0),
+ LCD_D12 | VE_3_3V | BITKEEPER(0),
+ LCD_D13 | VE_3_3V | BITKEEPER(0),
+ LCD_D14 | VE_3_3V | BITKEEPER(0),
+ LCD_D15 | VE_3_3V | BITKEEPER(0),
+ LCD_D16 | VE_3_3V | BITKEEPER(0),
+ LCD_D17 | VE_3_3V | BITKEEPER(0),
+ LCD_D18 | VE_3_3V | BITKEEPER(0),
+ LCD_D19 | VE_3_3V | BITKEEPER(0),
+ LCD_D20 | VE_3_3V | BITKEEPER(0),
+ LCD_D21 | VE_3_3V | BITKEEPER(0),
+ LCD_D22 | VE_3_3V | BITKEEPER(0),
+ LCD_D23 | VE_3_3V | BITKEEPER(0),
+
+ /* keep display's reset at low */
+ LCD_RESET_GPIO | VE_3_3V | GPIO_OUT | GPIO_VALUE(0),
+ /* keep display's power off */
+ LCD_ENABLE_GPIO | VE_3_3V | GPIO_OUT | GPIO_VALUE(0),
+};
+
+/**
+ * Try to register an environment storage on the attached MCI card
+ * @return 0 on success
+ *
+ * We rely on the existance of a usable SD card, already attached to
+ * our system, to get a persistent memory for our environment.
+ * If this SD card is also the boot medium, we can use the second partition
+ * for our environment purpose (if present!).
+ */
+static int register_persistent_environment(void)
+{
+ struct cdev *cdev;
+
+ /*
+ * The TX28 STK5 has only one usable MCI card socket.
+ * So, we expect its name as "disk0".
+ */
+ cdev = cdev_by_name("disk0");
+ if (cdev == NULL) {
+ pr_err("No MCI card preset\n");
+ return -ENODEV;
+ }
+
+ /* MCI card is present, also a usable partition on it? */
+ cdev = cdev_by_name("disk0.1");
+ if (cdev == NULL) {
+ pr_err("No second partition available\n");
+ pr_info("Please create at least a second partition with"
+ " 256 kiB...512 kiB in size (your choice)\n");
+ return -ENODEV;
+ }
+
+ /* use the full partition as our persistent environment storage */
+ return devfs_add_partition("disk0.1", 0, cdev->size,
+ DEVFS_PARTITION_FIXED, "env0");
+}
+
+void base_board_init(void)
+{
+ int i, ret;
+
+ /* initialize gpios */
+ for (i = 0; i < ARRAY_SIZE(tx28_starterkit_pad_setup); i++)
+ imx_gpio_mode(tx28_starterkit_pad_setup[i]);
+
+ /* enable IOCLK0 to run at the PLL frequency */
+ imx_set_ioclk(0, 480000000);
+ /* run the SSP unit clock at 100 MHz */
+ imx_set_sspclk(0, 100000000, 1);
+
+ register_device(&mci_socket);
+ register_device(&ldcif_dev);
+
+ imx_enable_enetclk();
+ register_device(&fec_dev);
+
+ ret = register_persistent_environment();
+ if (ret != 0)
+ printf("Cannot create the 'env0' persistent environment "
+ "storage (%d)\n", ret);
+}
+
+static struct device_d tx28kit_serial_device = {
+ .name = "stm_serial",
+ .map_base = IMX_DBGUART_BASE,
+ .size = 8192,
+};
+
+static int tx28kit_console_init(void)
+{
+ return register_device(&tx28kit_serial_device);
+}
+
+console_initcall(tx28kit_console_init);
diff --git a/arch/arm/boards/karo-tx28/tx28.c b/arch/arm/boards/karo-tx28/tx28.c
new file mode 100644
index 0000000000..6f4ef4ec1e
--- /dev/null
+++ b/arch/arm/boards/karo-tx28/tx28.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (C) 2010 Juergen Beisert, Pengutronix <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <gpio.h>
+#include <environment.h>
+#include <errno.h>
+#include <asm/armlinux.h>
+#include <asm/io.h>
+#include <generated/mach-types.h>
+#include <mach/imx-regs.h>
+
+static struct memory_platform_data ram_pdata = {
+ .name = "ram0",
+ .flags = DEVFS_RDWR,
+};
+
+static struct device_d sdram_dev = {
+ .id = -1,
+ .name = "mem",
+ .map_base = IMX_MEMORY_BASE,
+ .size = 128 * 1024 * 1024,
+ .platform_data = &ram_pdata,
+};
+
+/* setup the CPU card internal signals */
+static const uint32_t tx28_pad_setup[] = {
+ /* NAND interface */
+ GPMI_D0 | VE_3_3V | PULLUP(1),
+ GPMI_D1 | VE_3_3V | PULLUP(1),
+ GPMI_D2 | VE_3_3V | PULLUP(1),
+ GPMI_D3 | VE_3_3V | PULLUP(1),
+ GPMI_D4 | VE_3_3V | PULLUP(1),
+ GPMI_D5 | VE_3_3V | PULLUP(1),
+ GPMI_D6 | VE_3_3V | PULLUP(1),
+ GPMI_D7 | VE_3_3V | PULLUP(1),
+ GPMI_READY0 | VE_3_3V | PULLUP(0), /* external PU */
+ GPMI_RDN | VE_3_3V | PULLUP(1),
+ GPMI_WRN | VE_3_3V | BITKEEPER(1),
+ GPMI_ALE | VE_3_3V | PULLUP(1),
+ GPMI_CLE | VE_3_3V | PULLUP(1),
+ GPMI_RESETN_GPIO | VE_3_3V | GPIO_IN, /* act as WP, external PU */
+
+ /* Network interface */
+
+ /*
+ * Note: To setup the external phy in a manner the baseboard
+ * supports, its configuration is divided into a small part here in
+ * the CPU card setup and the remaining configuration in the baseboard
+ * file.
+ * Here: Switch on the power supply to the external phy, but keep its
+ * reset line low.
+ */
+
+ /* send a "good morning" to the ext. phy 0 = reset */
+ ENET0_RX_CLK_GPIO | VE_3_3V | PULLUP(0) | GPIO_OUT | GPIO_VALUE(0),
+
+ /* phy power control 1 = on */
+ PWM4_GPIO | VE_3_3V | GPIO_OUT | PULLUP(0) | GPIO_VALUE(1),
+
+ ENET_CLK | VE_3_3V | BITKEEPER(0),
+ ENET0_MDC | VE_3_3V | PULLUP(0),
+ ENET0_MDIO | VE_3_3V | PULLUP(0),
+ ENET0_TXD0 | VE_3_3V | PULLUP(0),
+ ENET0_TXD1 | VE_3_3V | PULLUP(0),
+ ENET0_TX_EN | VE_3_3V | PULLUP(0),
+ ENET0_TX_CLK | VE_3_3V | BITKEEPER(0),
+
+};
+
+extern void base_board_init(void);
+
+static int tx28_devices_init(void)
+{
+ int i;
+
+ /* initizalize gpios */
+ for (i = 0; i < ARRAY_SIZE(tx28_pad_setup); i++)
+ imx_gpio_mode(tx28_pad_setup[i]);
+
+ register_device(&sdram_dev);
+
+ armlinux_add_dram(&sdram_dev);
+ armlinux_set_bootparams((void *)(sdram_dev.map_base + 0x100));
+ armlinux_set_architecture(MACH_TYPE_TX28);
+
+ base_board_init();
+
+ return 0;
+}
+
+device_initcall(tx28_devices_init);
+
+/**
+@page tx28 KARO's TX28 CPU module
+
+@section tx28_cpu_card The CPU module
+
+http://www.karo-electronics.de/
+
+This CPU card is based on a Freescale i.MX28 CPU. The card is shipped with:
+
+- 128 MiB synchronous dynamic RAM (DDR2 type), 200 MHz support
+- 128 MiB NAND K9F1G08U0A (3.3V type)
+- PCA9554 GPIO expander
+- DS1339 RTC
+- LAN8710 Phy
+
+@section tx28_basboards Supported baseboards
+
+Supported baseboards are:
+- KARO's Starterkit 5
+
+@section tx28_stk5_howto How to get barebox for 'KARO's Starterkit 5'
+
+Using the default configuration:
+
+@verbatim
+make ARCH=arm tx28stk5_defconfig
+@endverbatim
+
+Build the binary image:
+
+@verbatim
+make ARCH=arm CROSS_COMPILE=armv5compiler
+@endverbatim
+
+@note replace the armv5compiler with your ARM v5 cross compiler.
+
+@note To use the result, you also need the following resources from Freescale:
+- the 'bootlets' archive
+- the 'elftosb2' encryption tool
+- in the case you want to start @b barebox from an attached SD card the
+ 'sdimage' tool from Freescale's 'uuc' archive.
+
+@section tx28_mlayout Memory layout when barebox is running:
+
+- 0x40000000 start of SDRAM
+- 0x40000100 start of kernel's boot parameters
+ - below malloc area: stack area
+ - below barebox: malloc area
+- 0x47000000 start of @b barebox
+
+*/
diff --git a/arch/arm/boards/pcm043/pcm043.c b/arch/arm/boards/pcm043/pcm043.c
index 2191bc8f19..38f1b8f522 100644
--- a/arch/arm/boards/pcm043/pcm043.c
+++ b/arch/arm/boards/pcm043/pcm043.c
@@ -39,6 +39,7 @@
#include <mach/imx-nand.h>
#include <fec.h>
#include <fb.h>
+#include <led.h>
#include <asm/mmu.h>
#include <mach/imx-ipu-fb.h>
#include <mach/imx-pll.h>
@@ -148,6 +149,10 @@ static int pcm043_mmu_init(void)
postcore_initcall(pcm043_mmu_init);
#endif
+struct gpio_led led0 = {
+ .gpio = 1 * 32 + 6,
+};
+
static int imx35_devices_init(void)
{
uint32_t reg;
@@ -157,6 +162,8 @@ static int imx35_devices_init(void)
writel(0x10000d03, CSCR_L(0));
writel(0x00720900, CSCR_A(0));
+ led_gpio_register(&led0);
+
reg = readl(IMX_CCM_BASE + CCM_RCSR);
/* some fuses provide us vital information about connected hardware */
if (reg & 0x20000000)
@@ -226,7 +233,8 @@ static struct pad_desc pcm043_pads[] = {
MX35_PAD_RTS1__UART1_RTS,
MX35_PAD_CTS1__UART1_CTS,
MX35_PAD_I2C1_CLK__I2C1_SCL,
- MX35_PAD_I2C1_DAT__I2C1_SDA
+ MX35_PAD_I2C1_DAT__I2C1_SDA,
+ MX35_PAD_ATA_CS0__GPIO2_6, /* LED */
};
static int imx35_console_init(void)
diff --git a/arch/arm/boards/versatile/Kconfig b/arch/arm/boards/versatile/Kconfig
new file mode 100644
index 0000000000..24289014cb
--- /dev/null
+++ b/arch/arm/boards/versatile/Kconfig
@@ -0,0 +1,10 @@
+
+if MACH_VERSATILEPB
+
+config ARCH_TEXT_BASE
+ hex
+ default 0x01000000
+
+config BOARDINFO
+ default "ARM Versatile/PB (ARM926EJ-S)"
+endif
diff --git a/arch/arm/boards/versatile/Makefile b/arch/arm/boards/versatile/Makefile
new file mode 100644
index 0000000000..a17aed316d
--- /dev/null
+++ b/arch/arm/boards/versatile/Makefile
@@ -0,0 +1,2 @@
+
+obj-$(CONFIG_MACH_VERSATILEPB) += versatilepb.o
diff --git a/arch/arm/boards/versatile/config.h b/arch/arm/boards/versatile/config.h
new file mode 100644
index 0000000000..25bb18f787
--- /dev/null
+++ b/arch/arm/boards/versatile/config.h
@@ -0,0 +1,5 @@
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#endif /* __CONFIG_H */
diff --git a/arch/arm/boards/versatile/versatilepb.c b/arch/arm/boards/versatile/versatilepb.c
new file mode 100644
index 0000000000..5568f216e4
--- /dev/null
+++ b/arch/arm/boards/versatile/versatilepb.c
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2010 B Labs Ltd,
+ * http://l4dev.org
+ * Author: Alexey Zaytsev <alexey.zaytsev@gmail.com>
+ *
+ * Based on mach-nomadik
+ * Copyright (C) 2009-2010 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <init.h>
+#include <asm/armlinux.h>
+#include <generated/mach-types.h>
+#include <mach/init.h>
+#include <mach/platform.h>
+#include <environment.h>
+#include <partition.h>
+#include <sizes.h>
+
+static struct device_d cfi_dev = {
+ .id = -1,
+ .name = "cfi_flash",
+ .map_base = VERSATILE_FLASH_BASE,
+ .size = VERSATILE_FLASH_SIZE,
+};
+
+static int vpb_console_init(void)
+{
+ versatile_register_uart(0);
+ return 0;
+}
+console_initcall(vpb_console_init);
+
+static struct device_d smc911x_dev = {
+ .id = -1,
+ .name = "smc91c111",
+ .map_base = VERSATILE_ETH_BASE,
+ .size = 64 * 1024,
+};
+
+static int vpb_devices_init(void)
+{
+ versatile_add_sdram(64 * 1024 *1024);
+
+ register_device(&cfi_dev);
+ devfs_add_partition("nor0", 0x00000, 0x40000, PARTITION_FIXED, "self");
+ devfs_add_partition("nor0", 0x40000, 0x20000, PARTITION_FIXED, "env0");
+
+ register_device(&smc911x_dev);
+
+ armlinux_set_architecture(MACH_TYPE_VERSATILE_PB);
+ armlinux_set_bootparams((void *)(0x00000100));
+
+ return 0;
+}
+device_initcall(vpb_devices_init);
diff --git a/arch/arm/configs/chumbyone_defconfig b/arch/arm/configs/chumbyone_defconfig
index 595b6a9b4c..45804a8d21 100644
--- a/arch/arm/configs/chumbyone_defconfig
+++ b/arch/arm/configs/chumbyone_defconfig
@@ -23,7 +23,11 @@ CONFIG_CMD_MTEST_ALTERNATIVE=y
CONFIG_CMD_RESET=y
CONFIG_CMD_TIMEOUT=y
CONFIG_CMD_PARTITION=y
+CONFIG_CMD_BMP=y
+CONFIG_CMD_GPIO=y
# CONFIG_SPI is not set
+CONFIG_VIDEO=y
+CONFIG_DRIVER_VIDEO_STM=y
CONFIG_MCI=y
CONFIG_MCI_STARTUP=y
CONFIG_MCI_STM378X=y
diff --git a/arch/arm/configs/tx28stk5_defconfig b/arch/arm/configs/tx28stk5_defconfig
new file mode 100644
index 0000000000..0851d5e242
--- /dev/null
+++ b/arch/arm/configs/tx28stk5_defconfig
@@ -0,0 +1,46 @@
+CONFIG_ARCH_STM=y
+CONFIG_ARCH_IMX28=y
+CONFIG_AEABI=y
+CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_MALLOC_SIZE=0x800000
+CONFIG_BROKEN=y
+CONFIG_LONGHELP=y
+CONFIG_GLOB=y
+CONFIG_HUSH_FANCY_PROMPT=y
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+CONFIG_MENU=y
+CONFIG_PARTITION=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/karo-tx28/env"
+CONFIG_DEBUG_INFO=y
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_LOADENV=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_ECHO_E=y
+CONFIG_CMD_MTEST=y
+CONFIG_CMD_MTEST_ALTERNATIVE=y
+CONFIG_CMD_BOOTM_ZLIB=y
+CONFIG_CMD_BOOTM_BZLIB=y
+CONFIG_CMD_BOOTM_SHOW_TYPE=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_GO=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_PARTITION=y
+CONFIG_CMD_BMP=y
+CONFIG_CMD_GPIO=y
+CONFIG_NET=y
+CONFIG_NET_DHCP=y
+CONFIG_NET_TFTP=y
+CONFIG_NET_RESOLV=y
+CONFIG_DRIVER_NET_FEC_IMX=y
+# CONFIG_SPI is not set
+CONFIG_VIDEO=y
+CONFIG_DRIVER_VIDEO_STM=y
+CONFIG_MCI=y
+CONFIG_MCI_STARTUP=y
+CONFIG_MCI_STM378X=y
diff --git a/arch/arm/configs/versatilepb_defconfig b/arch/arm/configs/versatilepb_defconfig
new file mode 100644
index 0000000000..6ffdf2897d
--- /dev/null
+++ b/arch/arm/configs/versatilepb_defconfig
@@ -0,0 +1,48 @@
+CONFIG_ARCH_VERSATILE=y
+CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y
+CONFIG_PROMPT="versatilepb> "
+CONFIG_LONGHELP=y
+CONFIG_GLOB=y
+CONFIG_HUSH_FANCY_PROMPT=y
+CONFIG_CMDLINE_EDITING=y
+CONFIG_AUTO_COMPLETE=y
+CONFIG_MENU=y
+CONFIG_PARTITION=y
+CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y
+CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/versatile/env"
+CONFIG_CMD_EDIT=y
+CONFIG_CMD_SLEEP=y
+CONFIG_CMD_SAVEENV=y
+CONFIG_CMD_LOADENV=y
+CONFIG_CMD_EXPORT=y
+CONFIG_CMD_PRINTENV=y
+CONFIG_CMD_READLINE=y
+CONFIG_CMD_MENU=y
+CONFIG_CMD_MENU_MANAGEMENT=y
+CONFIG_CMD_PASSWD=y
+CONFIG_CMD_ECHO_E=y
+CONFIG_CMD_LOADB=y
+CONFIG_CMD_MEMINFO=y
+CONFIG_CMD_MTEST=y
+CONFIG_CMD_MTEST_ALTERNATIVE=y
+CONFIG_CMD_BOOTM_ZLIB=y
+CONFIG_CMD_BOOTM_BZLIB=y
+CONFIG_CMD_BOOTM_SHOW_TYPE=y
+CONFIG_CMD_RESET=y
+CONFIG_CMD_GO=y
+CONFIG_CMD_TIMEOUT=y
+CONFIG_CMD_PARTITION=y
+CONFIG_CMD_UNLZO=y
+CONFIG_NET=y
+CONFIG_NET_DHCP=y
+CONFIG_NET_NFS=y
+CONFIG_NET_PING=y
+CONFIG_NET_TFTP=y
+CONFIG_NET_TFTP_PUSH=y
+CONFIG_NET_NETCONSOLE=y
+CONFIG_NET_RESOLV=y
+CONFIG_SERIAL_AMBA_PL011=y
+CONFIG_DRIVER_NET_SMC91111=y
+CONFIG_FS_CRAMFS=y
+CONFIG_SHA1=y
+CONFIG_SHA256=y
diff --git a/arch/arm/cpu/Kconfig b/arch/arm/cpu/Kconfig
index 7e17f9d3e2..3572a1fe6a 100644
--- a/arch/arm/cpu/Kconfig
+++ b/arch/arm/cpu/Kconfig
@@ -61,6 +61,9 @@ config CPU_32v7
comment "processor features"
+config ARCH_SUPPORTS_BIG_ENDIAN
+ bool
+
config CPU_BIG_ENDIAN
bool "Build big-endian kernel"
depends on ARCH_SUPPORTS_BIG_ENDIAN
diff --git a/arch/arm/cpu/start.c b/arch/arm/cpu/start.c
index 53d7ac199f..b55df5dc87 100644
--- a/arch/arm/cpu/start.c
+++ b/arch/arm/cpu/start.c
@@ -70,6 +70,9 @@ void __naked __bare_init reset(void)
r = get_cr();
r &= ~(CR_M | CR_C | CR_B | CR_S | CR_R | CR_V);
r |= CR_A | CR_I;
+#ifdef __ARMEB__
+ r |= CR_B;
+#endif
set_cr(r);
#ifdef CONFIG_MACH_DO_LOWLEVEL_INIT
diff --git a/arch/arm/include/asm/hardware/arm_timer.h b/arch/arm/include/asm/hardware/arm_timer.h
new file mode 100644
index 0000000000..0433279b82
--- /dev/null
+++ b/arch/arm/include/asm/hardware/arm_timer.h
@@ -0,0 +1,33 @@
+#ifndef __ASM_ARM_HARDWARE_ARM_TIMER_H
+#define __ASM_ARM_HARDWARE_ARM_TIMER_H
+
+/*
+ * From Linux v2.6.35
+ * arch/arm/include/asm/hardware/arm_timer.h
+ *
+ * ARM timer implementation, found in Integrator, Versatile and Realview
+ * platforms. Not all platforms support all registers and bits in these
+ * registers, so we mark them with A for Integrator AP, C for Integrator
+ * CP, V for Versatile and R for Realview.
+ *
+ * Integrator AP has 16-bit timers, Integrator CP, Versatile and Realview
+ * can have 16-bit or 32-bit selectable via a bit in the control register.
+ */
+#define TIMER_LOAD 0x00 /* ACVR rw */
+#define TIMER_VALUE 0x04 /* ACVR ro */
+#define TIMER_CTRL 0x08 /* ACVR rw */
+#define TIMER_CTRL_ONESHOT (1 << 0) /* CVR */
+#define TIMER_CTRL_32BIT (1 << 1) /* CVR */
+#define TIMER_CTRL_DIV1 (0 << 2) /* ACVR */
+#define TIMER_CTRL_DIV16 (1 << 2) /* ACVR */
+#define TIMER_CTRL_DIV256 (2 << 2) /* ACVR */
+#define TIMER_CTRL_IE (1 << 5) /* VR */
+#define TIMER_CTRL_PERIODIC (1 << 6) /* ACVR */
+#define TIMER_CTRL_ENABLE (1 << 7) /* ACVR */
+
+#define TIMER_INTCLR 0x0c /* ACVR wo */
+#define TIMER_RIS 0x10 /* CVR ro */
+#define TIMER_MIS 0x14 /* CVR ro */
+#define TIMER_BGLOAD 0x18 /* CVR rw */
+
+#endif
diff --git a/arch/arm/mach-imx/include/mach/generic.h b/arch/arm/mach-imx/include/mach/generic.h
index 9ca838b71d..29260361a2 100644
--- a/arch/arm/mach-imx/include/mach/generic.h
+++ b/arch/arm/mach-imx/include/mach/generic.h
@@ -51,3 +51,5 @@ u64 imx_uid(void);
#define cpu_is_mx51() (0)
#endif
+#define cpu_is_mx23() (0)
+#define cpu_is_mx28() (0)
diff --git a/arch/arm/mach-imx/include/mach/imx-flash-header.h b/arch/arm/mach-imx/include/mach/imx-flash-header.h
index f1054da08f..b8f51767de 100644
--- a/arch/arm/mach-imx/include/mach/imx-flash-header.h
+++ b/arch/arm/mach-imx/include/mach/imx-flash-header.h
@@ -20,6 +20,18 @@
#define FLASH_HEADER_OFFSET 0x0400
#endif
+#define __flash_header_0x1000 __section(.flash_header_0x1000)
+#define __dcd_entry_0x1000 __section(.dcd_entry_0x1000)
+#define __image_len_0x1000 __section(.image_len_0x1000)
+
+#define __flash_header_0x0100 __section(.flash_header_0x0100)
+#define __dcd_entry_0x0100 __section(.dcd_entry_0x0100)
+#define __image_len_0x0100 __section(.image_len_0x0100)
+
+#define __flash_header_0x0400 __section(.flash_header_0x0400)
+#define __dcd_entry_0x0400 __section(.dcd_entry_0x0400)
+#define __image_len_0x0400 __section(.image_len_0x0400)
+
/*
* NOR is not automatically copied anywhere by the boot ROM
*/
diff --git a/arch/arm/mach-imx/include/mach/imx-regs.h b/arch/arm/mach-imx/include/mach/imx-regs.h
index 605d320d9a..a234621374 100644
--- a/arch/arm/mach-imx/include/mach/imx-regs.h
+++ b/arch/arm/mach-imx/include/mach/imx-regs.h
@@ -57,6 +57,10 @@
# error "unknown i.MX soc type"
#endif
+/* There's a off-by-one betweem the gpio bank number and the gpiochip */
+/* range e.g. GPIO_1_5 is gpio 5 under linux */
+#define IMX_GPIO_NR(bank, nr) (((bank) - 1) * 32 + (nr))
+
#define GPIO_PIN_MASK 0x1f
#define GPIO_PORT_SHIFT 5
diff --git a/arch/arm/mach-omap/include/mach/omap3-clock.h b/arch/arm/mach-omap/include/mach/omap3-clock.h
index b655fe3a4b..10566e11cc 100644
--- a/arch/arm/mach-omap/include/mach/omap3-clock.h
+++ b/arch/arm/mach-omap/include/mach/omap3-clock.h
@@ -92,6 +92,12 @@
#define PLL_FAST_RELOCK_BYPASS 6 /* CORE */
#define PLL_LOCK 7 /* MPU, IVA, CORE & PER */
+/*
+ * Bit positions indicating current SYSCLK divider
+ */
+#define SYSCLK_DIV_1 (1 << 6)
+#define SYSCLK_DIV_2 (1 << 7)
+
/* The following configurations are OPP and SysClk value independant
* and hence are defined here.
*/
@@ -102,7 +108,8 @@
#define CORE_FUSB_DIV 2 /* 41.5MHz: */
#define CORE_L4_DIV 2 /* 83MHz : L4 */
#define CORE_L3_DIV 2 /* 166MHz : L3 {DDR} */
-#define GFX_DIV 2 /* 83MHz : CM_CLKSEL_GFX */
+#define GFX_DIV_34X 3 /* 96MHz : CM_CLKSEL_GFX (OMAP34XX) */
+#define GFX_DIV_36X 5 /* 200MHz : CM_CLKSEL_GFX (OMAP36XX) */
#define WKUP_RSM 2 /* 41.5MHz: CM_CLKSEL_WKUP */
/* PER DPLL */
@@ -124,12 +131,28 @@ struct dpll_param {
unsigned int fsel;
unsigned int m2;
};
+
+struct dpll_param_per_36x {
+ unsigned int m;
+ unsigned int n;
+ unsigned int m2;
+ unsigned int m3;
+ unsigned int m4;
+ unsigned int m5;
+ unsigned int m6;
+ unsigned int m2div;
+};
+
/* External functions see omap3_clock_core.S */
-extern struct dpll_param *get_mpu_dpll_param(void);
-extern struct dpll_param *get_iva_dpll_param(void);
-extern struct dpll_param *get_core_dpll_param(void);
-extern struct dpll_param *get_per_dpll_param(void);
+extern struct dpll_param *get_mpu_dpll_param_34x(u32);
+extern struct dpll_param *get_iva_dpll_param_34x(u32);
+extern struct dpll_param *get_core_dpll_param_34x(u32);
+extern struct dpll_param *get_per_dpll_param_34x(u32);
+extern struct dpll_param *get_mpu_dpll_param_36x(u32);
+extern struct dpll_param *get_iva_dpll_param_36x(u32);
+extern struct dpll_param *get_core_dpll_param_36x(u32);
+extern struct dpll_param_per_36x *get_per_dpll_param_36x(u32);
#endif /* __ASSEMBLY__ */
#endif /* endif _OMAP343X_CLOCKS_H_ */
diff --git a/arch/arm/mach-omap/include/mach/omap3-silicon.h b/arch/arm/mach-omap/include/mach/omap3-silicon.h
index 62e612bb63..0e6a45f8fd 100644
--- a/arch/arm/mach-omap/include/mach/omap3-silicon.h
+++ b/arch/arm/mach-omap/include/mach/omap3-silicon.h
@@ -116,17 +116,17 @@
#define OMAP_TAP_BASE (OMAP_L4_WKUP_BASE + 0xA000)
#define IDCODE_REG (OMAP_TAP_BASE + 0x204)
-/************ Generic Chip specific Definitions **********/
-/**
- * CHIP F number HAWKEYE (hex)
- * OMAP3430 ES1.0 F771609 B6D6
- * OMAP3430 ES2.0 F771609A B7AE
- */
+/** Masks to extract information from ID code register */
+#define IDCODE_HAWKEYE_MASK 0x0FFFF000
+#define IDCODE_VERSION_MASK 0xF0000000
+
+ #define get_hawkeye(v) (((v) & IDCODE_HAWKEYE_MASK) >> 12)
+ #define get_version(v) (((v) & IDCODE_VERSION_MASK) >> 28)
+
#define HAWKEYE_ES1 0x0B6D6000
#define HAWKEYE_ES2 0x0B7AE000
#define HAWKEYE_ES2_1 0x1B7AE000
-#define HAWKEYE_MASK 0x0FFFF000
-#define VERSION_MASK 0xF0000000
+
#define DEVICE_MASK ((0x1 << 8)|(0x1 << 9)|(0x1 << 10))
#define OMAP_SDRC_CS0 0x80000000
diff --git a/arch/arm/mach-omap/include/mach/sys_info.h b/arch/arm/mach-omap/include/mach/sys_info.h
index 43967209f1..f557068345 100644
--- a/arch/arm/mach-omap/include/mach/sys_info.h
+++ b/arch/arm/mach-omap/include/mach/sys_info.h
@@ -44,27 +44,27 @@
#define DDR_133 133 /* most combo, some mem d-boards */
#define DDR_165 165 /* future parts */
-#define CPU_3430 0x3430
-#define CPU_2430 0x2430
-#define CPU_2420 0x2420
-#define CPU_1710 0x1710
#define CPU_1610 0x1610
+#define CPU_1710 0x1710
+#define CPU_2420 0x2420
+#define CPU_2430 0x2430
+#define CPU_3430 0x3430
+#define CPU_3630 0x3630
/**
- * CPU revision
+ * Define CPU revisions
*/
-#define CPU_ES1 1
-#define CPU_ES1P1 2
-#define CPU_ES1P2 3
-#define CPU_ES2 4
-#define CPU_ES2P1 5
-#define CPU_ES2P2 6
-#define CPU_ES3 7
-#define CPU_ES3P1 8
-#define CPU_ES3P2 9
-#define CPU_ES4 10
-#define CPU_ES4P1 11
-#define CPU_ES4P2 12
+#define cpu_revision(cpu,rev) (((cpu) << 16) | (rev))
+
+#define OMAP34XX_ES1 cpu_revision(CPU_3430, 0)
+#define OMAP34XX_ES2 cpu_revision(CPU_3430, 1)
+#define OMAP34XX_ES2_1 cpu_revision(CPU_3430, 2)
+#define OMAP34XX_ES3 cpu_revision(CPU_3430, 3)
+#define OMAP34XX_ES3_1 cpu_revision(CPU_3430, 4)
+
+#define OMAP36XX_ES1 cpu_revision(CPU_3630, 0)
+#define OMAP36XX_ES1_1 cpu_revision(CPU_3630, 1)
+#define OMAP36XX_ES1_2 cpu_revision(CPU_3630, 2)
#define GPMC_MUXED 1
#define GPMC_NONMUXED 0
@@ -81,6 +81,12 @@
#define HS_DEVICE 0x2
#define GP_DEVICE 0x3
+/**
+ * Hawkeye definitions to identify silicon families
+ */
+#define OMAP_HAWKEYE_34XX 0xB7AE
+#define OMAP_HAWKEYE_36XX 0xB891
+
/** These are implemented by the System specific code in omapX-generic.c */
u32 get_cpu_type(void);
u32 get_cpu_rev(void);
diff --git a/arch/arm/mach-omap/omap3_clock.c b/arch/arm/mach-omap/omap3_clock.c
index 13e8729c3d..3a0ab24e58 100644
--- a/arch/arm/mach-omap/omap3_clock.c
+++ b/arch/arm/mach-omap/omap3_clock.c
@@ -65,12 +65,20 @@ static void per_clocks_enable(void);
*/
static u32 get_osc_clk_speed(void)
{
- u32 start, cstart, cend, cdiff, val;
+ u32 start, cstart, cend, cdiff, cdiv, val;
val = readl(PRM_REG(CLKSRC_CTRL));
- /* If SYS_CLK is being divided by 2, remove for now */
- val = (val & (~(0x1 << 7))) | (0x1 << 6);
- writel(val, PRM_REG(CLKSRC_CTRL));
+
+ if (val & SYSCLK_DIV_2)
+ cdiv = 2;
+ else if (val & SYSCLK_DIV_1)
+ cdiv = 1;
+ else
+ /*
+ * Should never reach here!
+ * To proceed, assume divider as 1.
+ */
+ cdiv = 1;
/* enable timer2 */
val = readl(CM_REG(CLKSEL_WKUP)) | (0x1 << 0);
@@ -97,6 +105,9 @@ static u32 get_osc_clk_speed(void)
cend = readl(OMAP_GPTIMER1_BASE + TCRR);
cdiff = cend - cstart; /* get elapsed ticks */
+ if (cdiv == 2)
+ cdiff *= 2;
+
/* based on number of ticks assign speed */
if (cdiff > 19000)
return S38_4M;
@@ -137,89 +148,294 @@ static void get_sys_clkin_sel(u32 osc_clk, u32 *sys_clkin_sel)
}
/**
- * @brief Inits clocks for PRCM
- *
- * This is called from SRAM, or Flash (using temp SRAM stack).
- * if CONFIG_OMAP3_COPY_CLOCK_SRAM is defined, @ref go_to_speed
+ * @brief Initialize CORE DPLL for OMAP34x
*
- * @return void
+ * @param[in] cpu_rev - Silicon revision
+ * @param[in] clk_sel - Clock selection used as index into the dpll table
*/
-void prcm_init(void)
+static void init_core_dpll_34x(u32 cpu_rev, u32 clk_sel)
{
- int xip_safe;
- u32 osc_clk = 0, sys_clkin_sel = 0;
- u32 clk_index, sil_index = 0;
- struct dpll_param *dpll_param_p;
+ struct dpll_param *dp = get_core_dpll_param_34x(cpu_rev);
#ifdef CONFIG_OMAP3_COPY_CLOCK_SRAM
int p0, p1, p2, p3;
- f_lock_pll = (void *)(OMAP_SRAM_INTVECT + OMAP_SRAM_INTVECT_COPYSIZE);
#endif
- xip_safe = running_in_sram();
+ dp += clk_sel;
- /* Gauge the input clock speed and find out the sys_clkin_sel
- * value corresponding to the input clock.
- */
- osc_clk = get_osc_clk_speed();
- get_sys_clkin_sel(osc_clk, &sys_clkin_sel);
- /* set input crystal speed */
- sr32(PRM_REG(CLKSEL), 0, 3, sys_clkin_sel);
+ if (running_in_sram()) {
+ sr32(CM_REG(CLKEN_PLL), 0, 3, PLL_FAST_RELOCK_BYPASS);
+ wait_on_value((0x1 << 0), 0, CM_REG(IDLEST_CKGEN), LDELAY);
- /* If the input clock is greater than 19.2M always divide/2 */
- if (sys_clkin_sel > 2) {
- /* input clock divider */
- sr32(PRM_REG(CLKSRC_CTRL), 6, 2, 2);
- clk_index = sys_clkin_sel / 2;
- } else {
- /* input clock divider */
- sr32(PRM_REG(CLKSRC_CTRL), 6, 2, 1);
- clk_index = sys_clkin_sel;
+ /*
+ * OMAP3430 ES1.0 Errata 1.50
+ * Writing default value doesn't work. First write a different
+ * value and then write the default value.
+ */
+
+ /* CM_CLKSEL1_EMU[DIV_DPLL3] */
+ sr32(CM_REG(CLKSEL1_EMU), 16, 5, CORE_M3X2 + 1);
+ sr32(CM_REG(CLKSEL1_EMU), 16, 5, CORE_M3X2);
+
+ /* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */
+ sr32(CM_REG(CLKSEL1_PLL), 27, 2, dp->m2);
+
+ /* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */
+ sr32(CM_REG(CLKSEL1_PLL), 16, 11, dp->m);
+
+ /* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */
+ sr32(CM_REG(CLKSEL1_PLL), 8, 7, dp->n);
+
+ /* Set source CM_96M_FCLK: CM_CLKSEL1_PLL[6] */
+ sr32(CM_REG(CLKSEL1_PLL), 6, 1, 0);
+
+ sr32(CM_REG(CLKSEL_CORE), 8, 4, CORE_SSI_DIV);
+ sr32(CM_REG(CLKSEL_CORE), 4, 2, CORE_FUSB_DIV);
+ sr32(CM_REG(CLKSEL_CORE), 2, 2, CORE_L4_DIV);
+ sr32(CM_REG(CLKSEL_CORE), 0, 2, CORE_L3_DIV);
+ sr32(CM_REG(CLKSEL_GFX), 0, 3, GFX_DIV_34X);
+ sr32(CM_REG(CLKSEL_WKUP), 1, 2, WKUP_RSM);
+
+ /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */
+ sr32(CM_REG(CLKEN_PLL), 4, 4, dp->fsel);
+
+ /* Lock Mode */
+ sr32(CM_REG(CLKEN_PLL), 0, 3, PLL_LOCK);
+ wait_on_value((0x1 << 0), 1, CM_REG(IDLEST_CKGEN), LDELAY);
+ } else if (running_in_flash()) {
+#ifdef CONFIG_OMAP3_COPY_CLOCK_SRAM
+ f_lock_pll = (void *)(OMAP_SRAM_INTVECT +
+ OMAP_SRAM_INTVECT_COPYSIZE);
+
+ /*
+ * Jump to small relocated code area in SRAM.
+ */
+ p0 = readl(CM_REG(CLKEN_PLL));
+ sr32((u32) &p0, 0, 3, PLL_FAST_RELOCK_BYPASS);
+
+ /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */
+ sr32((u32) &p0, 4, 4, dp->fsel);
+
+ p1 = readl(CM_REG(CLKSEL1_PLL));
+
+ /* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */
+ sr32((u32) &p1, 27, 2, dp->m2);
+
+ /* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */
+ sr32((u32) &p1, 16, 11, dp->m);
+
+ /* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */
+ sr32((u32) &p1, 8, 7, dp->n);
+
+ /* Set source CM_96M_FCLK: CM_CLKSEL1_PLL[6] */
+ sr32((u32) &p1, 6, 1, 0);
+
+ p2 = readl(CM_REG(CLKSEL_CORE));
+ sr32((u32) &p2, 8, 4, CORE_SSI_DIV);
+ sr32((u32) &p2, 4, 2, CORE_FUSB_DIV);
+ sr32((u32) &p2, 2, 2, CORE_L4_DIV);
+ sr32((u32) &p2, 0, 2, CORE_L3_DIV);
+
+ p3 = CM_REG(IDLEST_CKGEN);
+
+ (*f_lock_pll) (p0, p1, p2, p3);
+#else
+ /***Oopps.. Wrong .config!! *****/
+ hang();
+#endif
}
+}
- /* Unlock MPU DPLL (slows things down, and needed later) */
- sr32(CM_REG(CLKEN_PLL_MPU), 0, 3, PLL_LOW_POWER_BYPASS);
- wait_on_value((0x1 << 0), 0, CM_REG(IDLEST_PLL_MPU), LDELAY);
+/**
+ * @brief Initialize PER DPLL for OMAP34x
+ *
+ * @param[in] cpu_rev - Silicon revision
+ * @param[in] clk_sel - Clock selection used as index into the dpll table
+ */
+static void init_per_dpll_34x(u32 cpu_rev, u32 clk_sel)
+{
+ struct dpll_param *dp = get_per_dpll_param_34x(cpu_rev);
+
+ dp += clk_sel;
+
+ /*
+ * OMAP3430 ES1.0 Errata 1.50
+ * Writing default value doesn't work. First write a different
+ * value and then write the default value.
+ */
+
+ sr32(CM_REG(CLKEN_PLL), 16, 3, PLL_STOP);
+ wait_on_value((0x1 << 1), 0, CM_REG(IDLEST_CKGEN), LDELAY);
+
+ /* Set M6 */
+ sr32(CM_REG(CLKSEL1_EMU), 24, 5, PER_M6X2 + 1);
+ sr32(CM_REG(CLKSEL1_EMU), 24, 5, PER_M6X2);
+
+ /* Set M5 */
+ sr32(CM_REG(CLKSEL_CAM), 0, 5, PER_M5X2 + 1);
+ sr32(CM_REG(CLKSEL_CAM), 0, 5, PER_M5X2);
- /* Getting the base address of Core DPLL param table */
- dpll_param_p = (struct dpll_param *)get_core_dpll_param();
- /* Moving it to the right sysclk and ES rev base */
- dpll_param_p = dpll_param_p + MAX_SIL_INDEX * clk_index + sil_index;
- if (xip_safe) {
- /* CORE DPLL */
- /* sr32(CM_REG(CLKSEL2_EMU)) set override to work when asleep */
+ /* Set M4 */
+ sr32(CM_REG(CLKSEL_DSS), 0, 5, PER_M4X2 + 1);
+ sr32(CM_REG(CLKSEL_DSS), 0, 5, PER_M4X2);
+
+ /* Set M3 */
+ sr32(CM_REG(CLKSEL_DSS), 8, 5, PER_M3X2 + 1);
+ sr32(CM_REG(CLKSEL_DSS), 8, 5, PER_M3X2);
+
+ /* Set M2 */
+ sr32(CM_REG(CLKSEL3_PLL), 0, 5, dp->m2 + 1);
+ sr32(CM_REG(CLKSEL3_PLL), 0, 5, dp->m2);
+
+ /* M (PERIPH_DPLL_MULT): CM_CLKSEL2_PLL[8:18] */
+ sr32(CM_REG(CLKSEL2_PLL), 8, 11, dp->m);
+
+ /* N (PERIPH_DPLL_DIV): CM_CLKSEL2_PLL[0:6] */
+ sr32(CM_REG(CLKSEL2_PLL), 0, 7, dp->n);
+
+ /* FREQSEL (PERIPH_DPLL_FREQSEL): CM_CLKEN_PLL[20:23] */
+ sr32(CM_REG(CLKEN_PLL), 20, 4, dp->fsel);
+
+ /* LOCK MODE (EN_PERIPH_DPLL): CM_CLKEN_PLL[16:18] */
+ sr32(CM_REG(CLKEN_PLL), 16, 3, PLL_LOCK);
+ wait_on_value((0x1 << 1), 2, CM_REG(IDLEST_CKGEN), LDELAY);
+}
+
+/**
+ * @brief Initialize MPU DPLL for OMAP34x
+ *
+ * The MPU DPLL is already unlocked when control reaches here. This
+ * function doesn't lock the DPLL either - defers to the caller.
+ *
+ * @param[in] cpu_rev - Silicon revision
+ * @param[in] clk_sel - Clock selection used as index into the dpll table
+ */
+static void init_mpu_dpll_34x(u32 cpu_rev, u32 clk_sel)
+{
+ struct dpll_param *dp = get_mpu_dpll_param_34x(cpu_rev);
+
+ dp += clk_sel;
+
+ /* M2 (MPU_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_MPU[0:4] */
+ sr32(CM_REG(CLKSEL2_PLL_MPU), 0, 5, dp->m2);
+
+ /* M (MPU_DPLL_MULT) : CM_CLKSEL2_PLL_MPU[8:18] */
+ sr32(CM_REG(CLKSEL1_PLL_MPU), 8, 11, dp->m);
+
+ /* N (MPU_DPLL_DIV) : CM_CLKSEL2_PLL_MPU[0:6] */
+ sr32(CM_REG(CLKSEL1_PLL_MPU), 0, 7, dp->n);
+
+ /* FREQSEL (MPU_DPLL_FREQSEL) : CM_CLKEN_PLL_MPU[4:7] */
+ sr32(CM_REG(CLKEN_PLL_MPU), 4, 4, dp->fsel);
+}
+
+/**
+ * @brief Initialize IVA DPLL for OMAP34x
+ *
+ * @param[in] cpu_rev - Silicon revision
+ * @param[in] clk_sel - Clock selection used as index into the dpll table
+ */
+static void init_iva_dpll_34x(u32 cpu_rev, u32 clk_sel)
+{
+ struct dpll_param *dp = get_iva_dpll_param_34x(cpu_rev);
+
+ dp += clk_sel;
+
+ /* EN_IVA2_DPLL : CM_CLKEN_PLL_IVA2[0:2] */
+ sr32(CM_REG(CLKEN_PLL_IVA2), 0, 3, PLL_STOP);
+ wait_on_value((0x1 << 0), 0, CM_REG(IDLEST_PLL_IVA2), LDELAY);
+
+ /* M2 (IVA2_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_IVA2[0:4] */
+ sr32(CM_REG(CLKSEL2_PLL_IVA2), 0, 5, dp->m2);
+
+ /* M (IVA2_DPLL_MULT) : CM_CLKSEL1_PLL_IVA2[8:18] */
+ sr32(CM_REG(CLKSEL1_PLL_IVA2), 8, 11, dp->m);
+
+ /* N (IVA2_DPLL_DIV) : CM_CLKSEL1_PLL_IVA2[0:6] */
+ sr32(CM_REG(CLKSEL1_PLL_IVA2), 0, 7, dp->n);
+
+ /* FREQSEL (IVA2_DPLL_FREQSEL) : CM_CLKEN_PLL_IVA2[4:7] */
+ sr32(CM_REG(CLKEN_PLL_IVA2), 4, 4, dp->fsel);
+
+ /* LOCK (MODE (EN_IVA2_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */
+ sr32(CM_REG(CLKEN_PLL_IVA2), 0, 3, PLL_LOCK);
+ wait_on_value((0x1 << 0), 1, CM_REG(IDLEST_PLL_IVA2), LDELAY);
+}
+
+/**
+ * @brief Initialize CORE DPLL for OMAP36x
+ *
+ * @param[in] cpu_rev - Silicon revision
+ * @param[in] clk_sel - Clock selection used as index into the dpll table
+ */
+static void init_core_dpll_36x(u32 cpu_rev, u32 clk_sel)
+{
+ struct dpll_param *dp = get_core_dpll_param_36x(cpu_rev);
+#ifdef CONFIG_OMAP3_COPY_CLOCK_SRAM
+ int p0, p1, p2, p3;
+#endif
+
+ dp += clk_sel;
+
+ if (running_in_sram()) {
sr32(CM_REG(CLKEN_PLL), 0, 3, PLL_FAST_RELOCK_BYPASS);
wait_on_value((0x1 << 0), 0, CM_REG(IDLEST_CKGEN), LDELAY);
- /* For 3430 ES1.0 Errata 1.50, default value directly doesnt
- work. write another value and then default value. */
- sr32(CM_REG(CLKSEL1_EMU), 16, 5, CORE_M3X2 + 1);
+
+ /* CM_CLKSEL1_EMU[DIV_DPLL3] */
sr32(CM_REG(CLKSEL1_EMU), 16, 5, CORE_M3X2);
- sr32(CM_REG(CLKSEL1_PLL), 27, 2, dpll_param_p->m2);
- sr32(CM_REG(CLKSEL1_PLL), 16, 11, dpll_param_p->m);
- sr32(CM_REG(CLKSEL1_PLL), 8, 7, dpll_param_p->n);
+
+ /* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */
+ sr32(CM_REG(CLKSEL1_PLL), 27, 5, dp->m2);
+
+ /* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */
+ sr32(CM_REG(CLKSEL1_PLL), 16, 11, dp->m);
+
+ /* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */
+ sr32(CM_REG(CLKSEL1_PLL), 8, 7, dp->n);
+
+ /* Set source CM_96M_FCLK: CM_CLKSEL1_PLL[6] */
sr32(CM_REG(CLKSEL1_PLL), 6, 1, 0);
+
sr32(CM_REG(CLKSEL_CORE), 8, 4, CORE_SSI_DIV);
sr32(CM_REG(CLKSEL_CORE), 4, 2, CORE_FUSB_DIV);
sr32(CM_REG(CLKSEL_CORE), 2, 2, CORE_L4_DIV);
sr32(CM_REG(CLKSEL_CORE), 0, 2, CORE_L3_DIV);
- sr32(CM_REG(CLKSEL_GFX), 0, 3, GFX_DIV);
+ sr32(CM_REG(CLKSEL_GFX), 0, 3, GFX_DIV_36X);
sr32(CM_REG(CLKSEL_WKUP), 1, 2, WKUP_RSM);
- sr32(CM_REG(CLKEN_PLL), 4, 4, dpll_param_p->fsel);
+
+ /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */
+ sr32(CM_REG(CLKEN_PLL), 4, 4, dp->fsel);
+
+ /* Lock Mode */
sr32(CM_REG(CLKEN_PLL), 0, 3, PLL_LOCK);
wait_on_value((0x1 << 0), 1, CM_REG(IDLEST_CKGEN), LDELAY);
} else if (running_in_flash()) {
#ifdef CONFIG_OMAP3_COPY_CLOCK_SRAM
- /* if running from flash,
- * jump to small relocated code area in SRAM.
+ f_lock_pll = (void *)(OMAP_SRAM_INTVECT +
+ OMAP_SRAM_INTVECT_COPYSIZE);
+
+ /*
+ * Jump to small relocated code area in SRAM.
*/
p0 = readl(CM_REG(CLKEN_PLL));
sr32((u32) &p0, 0, 3, PLL_FAST_RELOCK_BYPASS);
- sr32((u32) &p0, 4, 4, dpll_param_p->fsel);
+
+ /* FREQSEL (CORE_DPLL_FREQSEL): CM_CLKEN_PLL[4:7] */
+ sr32((u32) &p0, 4, 4, dp->fsel);
p1 = readl(CM_REG(CLKSEL1_PLL));
- sr32((u32) &p1, 27, 2, dpll_param_p->m2);
- sr32((u32) &p1, 16, 11, dpll_param_p->m);
- sr32((u32) &p1, 8, 7, dpll_param_p->n);
- sr32((u32) &p1, 6, 1, 0); /* set source for 96M */
+
+ /* M2 (CORE_DPLL_CLKOUT_DIV): CM_CLKSEL1_PLL[27:31] */
+ sr32((u32) &p1, 27, 5, dp->m2);
+
+ /* M (CORE_DPLL_MULT): CM_CLKSEL1_PLL[16:26] */
+ sr32((u32) &p1, 16, 11, dp->m);
+
+ /* N (CORE_DPLL_DIV): CM_CLKSEL1_PLL[8:14] */
+ sr32((u32) &p1, 8, 7, dp->n);
+
+ /* Set source CM_96M_FCLK: CM_CLKSEL1_PLL[6] */
+ sr32((u32) &p1, 6, 1, 0);
+
p2 = readl(CM_REG(CLKSEL_CORE));
sr32((u32) &p2, 8, 4, CORE_SSI_DIV);
sr32((u32) &p2, 4, 2, CORE_FUSB_DIV);
@@ -234,70 +450,179 @@ void prcm_init(void)
hang();
#endif
}
+}
+
+/**
+ * @brief Initialize PER DPLL for OMAP36x
+ *
+ * @param[in] cpu_rev - Silicon revision
+ * @param[in] clk_sel - Clock selection used as index into the dpll table
+ */
+static void init_per_dpll_36x(u32 cpu_rev, u32 clk_sel)
+{
+ struct dpll_param_per_36x *dp = get_per_dpll_param_36x(cpu_rev);
+
+ dp += clk_sel;
- /* PER DPLL */
sr32(CM_REG(CLKEN_PLL), 16, 3, PLL_STOP);
wait_on_value((0x1 << 1), 0, CM_REG(IDLEST_CKGEN), LDELAY);
- /* Getting the base address to PER DPLL param table */
- /* Set N */
- dpll_param_p = (struct dpll_param *)get_per_dpll_param();
- /* Moving it to the right sysclk base */
- dpll_param_p = dpll_param_p + clk_index;
- /* Errata 1.50 Workaround for 3430 ES1.0 only */
- /* If using default divisors, write default divisor + 1
- and then the actual divisor value */
- /* Need to change it to silicon and revisino check */
- if (1) {
- sr32(CM_REG(CLKSEL1_EMU), 24, 5, PER_M6X2 + 1); /* set M6 */
- sr32(CM_REG(CLKSEL1_EMU), 24, 5, PER_M6X2); /* set M6 */
- sr32(CM_REG(CLKSEL_CAM), 0, 5, PER_M5X2 + 1); /* set M5 */
- sr32(CM_REG(CLKSEL_CAM), 0, 5, PER_M5X2); /* set M5 */
- sr32(CM_REG(CLKSEL_DSS), 0, 5, PER_M4X2 + 1); /* set M4 */
- sr32(CM_REG(CLKSEL_DSS), 0, 5, PER_M4X2); /* set M4 */
- sr32(CM_REG(CLKSEL_DSS), 8, 5, PER_M3X2 + 1); /* set M3 */
- sr32(CM_REG(CLKSEL_DSS), 8, 5, PER_M3X2); /* set M3 */
- /* set M2 */
- sr32(CM_REG(CLKSEL3_PLL), 0, 5, dpll_param_p->m2 + 1);
- sr32(CM_REG(CLKSEL3_PLL), 0, 5, dpll_param_p->m2);
- } else {
- sr32(CM_REG(CLKSEL1_EMU), 24, 5, PER_M6X2); /* set M6 */
- sr32(CM_REG(CLKSEL_CAM), 0, 5, PER_M5X2); /* set M5 */
- sr32(CM_REG(CLKSEL_DSS), 0, 5, PER_M4X2); /* set M4 */
- sr32(CM_REG(CLKSEL_DSS), 8, 5, PER_M3X2); /* set M3 */
- sr32(CM_REG(CLKSEL3_PLL), 0, 5, dpll_param_p->m2);
- }
- sr32(CM_REG(CLKSEL2_PLL), 8, 11, dpll_param_p->m); /* set m */
- sr32(CM_REG(CLKSEL2_PLL), 0, 7, dpll_param_p->n); /* set n */
- sr32(CM_REG(CLKEN_PLL), 20, 4, dpll_param_p->fsel); /* FREQSEL */
- sr32(CM_REG(CLKEN_PLL), 16, 3, PLL_LOCK); /* lock mode */
+ /* Set M6 (DIV_DPLL4): CM_CLKSEL1_EMU[24:29] */
+ sr32(CM_REG(CLKSEL1_EMU), 24, 6, dp->m6);
+
+ /* Set M5 (CLKSEL_CAM): CM_CLKSEL_CAM[0:5] */
+ sr32(CM_REG(CLKSEL_CAM), 0, 6, dp->m5);
+
+ /* Set M4 (CLKSEL_DSS1): CM_CLKSEL_DSS[0:5] */
+ sr32(CM_REG(CLKSEL_DSS), 0, 6, dp->m4);
+
+ /* Set M3 (CLKSEL_DSS2): CM_CLKSEL_DSS[8:13] */
+ sr32(CM_REG(CLKSEL_DSS), 8, 6, dp->m3);
+
+ /* Set M2: CM_CLKSEL3_PLL[0:4] */
+ sr32(CM_REG(CLKSEL3_PLL), 0, 5, dp->m2);
+
+ /* M (PERIPH_DPLL_MULT): CM_CLKSEL2_PLL[8:19] */
+ sr32(CM_REG(CLKSEL2_PLL), 8, 12, dp->m);
+
+ /* N (PERIPH_DPLL_DIV): CM_CLKSEL2_PLL[0:6] */
+ sr32(CM_REG(CLKSEL2_PLL), 0, 7, dp->n);
+
+ /* M2DIV (CLKSEL_96M): CM_CLKSEL_CORE[12:13] */
+ sr32(CM_REG(CLKSEL_CORE), 12, 2, dp->m2div);
+
+ /* LOCK MODE (EN_PERIPH_DPLL): CM_CLKEN_PLL[16:18] */
+ sr32(CM_REG(CLKEN_PLL), 16, 3, PLL_LOCK);
wait_on_value((0x1 << 1), 2, CM_REG(IDLEST_CKGEN), LDELAY);
+}
- /* Getting the base address to MPU DPLL param table */
- dpll_param_p = (struct dpll_param *)get_mpu_dpll_param();
- /* Moving it to the right sysclk and ES rev base */
- dpll_param_p = dpll_param_p + MAX_SIL_INDEX * clk_index + sil_index;
- /* MPU DPLL (unlocked already) */
- sr32(CM_REG(CLKSEL2_PLL_MPU), 0, 5, dpll_param_p->m2); /* Set M2 */
- sr32(CM_REG(CLKSEL1_PLL_MPU), 8, 11, dpll_param_p->m); /* Set M */
- sr32(CM_REG(CLKSEL1_PLL_MPU), 0, 7, dpll_param_p->n); /* Set N */
- sr32(CM_REG(CLKEN_PLL_MPU), 4, 4, dpll_param_p->fsel); /* FREQSEL */
- sr32(CM_REG(CLKEN_PLL_MPU), 0, 3, PLL_LOCK); /* lock mode */
- wait_on_value((0x1 << 0), 1, CM_REG(IDLEST_PLL_MPU), LDELAY);
+/**
+ * @brief Initialize MPU DPLL for OMAP36x
+ *
+ * @param[in] cpu_rev - Silicon revision
+ * @param[in] clk_sel - Clock selection used as index into the dpll table
+ */
+static void init_mpu_dpll_36x(u32 cpu_rev, u32 clk_sel)
+{
+ struct dpll_param *dp = get_mpu_dpll_param_36x(cpu_rev);
+
+ dp += clk_sel;
+
+ /* M2 (MPU_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_MPU[0:4] */
+ sr32(CM_REG(CLKSEL2_PLL_MPU), 0, 5, dp->m2);
- /* Getting the base address to IVA DPLL param table */
- dpll_param_p = (struct dpll_param *)get_iva_dpll_param();
- /* Moving it to the right sysclk and ES rev base */
- dpll_param_p = dpll_param_p + MAX_SIL_INDEX * clk_index + sil_index;
- /* IVA DPLL (set to 12*20=240MHz) */
+ /* M (MPU_DPLL_MULT) : CM_CLKSEL2_PLL_MPU[8:18] */
+ sr32(CM_REG(CLKSEL1_PLL_MPU), 8, 11, dp->m);
+
+ /* N (MPU_DPLL_DIV) : CM_CLKSEL2_PLL_MPU[0:6] */
+ sr32(CM_REG(CLKSEL1_PLL_MPU), 0, 7, dp->n);
+
+ /* FREQSEL (MPU_DPLL_FREQSEL) : CM_CLKEN_PLL_MPU[4:7] */
+ sr32(CM_REG(CLKEN_PLL_MPU), 4, 4, dp->fsel);
+}
+
+/**
+ * @brief Initialize IVA DPLL for OMAP36x
+ *
+ * @param[in] cpu_rev - Silicon revision
+ * @param[in] clk_sel - Clock selection used as index into the dpll table
+ */
+static void init_iva_dpll_36x(u32 cpu_rev, u32 clk_sel)
+{
+ struct dpll_param *dp = get_iva_dpll_param_36x(cpu_rev);
+
+ dp += clk_sel;
+
+ /* EN_IVA2_DPLL : CM_CLKEN_PLL_IVA2[0:2] */
sr32(CM_REG(CLKEN_PLL_IVA2), 0, 3, PLL_STOP);
wait_on_value((0x1 << 0), 0, CM_REG(IDLEST_PLL_IVA2), LDELAY);
- sr32(CM_REG(CLKSEL2_PLL_IVA2), 0, 5, dpll_param_p->m2); /* set M2 */
- sr32(CM_REG(CLKSEL1_PLL_IVA2), 8, 11, dpll_param_p->m); /* set M */
- sr32(CM_REG(CLKSEL1_PLL_IVA2), 0, 7, dpll_param_p->n); /* set N */
- sr32(CM_REG(CLKEN_PLL_IVA2), 4, 4, dpll_param_p->fsel); /* FREQSEL */
- sr32(CM_REG(CLKEN_PLL_IVA2), 0, 3, PLL_LOCK); /* lock mode */
+
+ /* M2 (IVA2_DPLL_CLKOUT_DIV) : CM_CLKSEL2_PLL_IVA2[0:4] */
+ sr32(CM_REG(CLKSEL2_PLL_IVA2), 0, 5, dp->m2);
+
+ /* M (IVA2_DPLL_MULT) : CM_CLKSEL1_PLL_IVA2[8:18] */
+ sr32(CM_REG(CLKSEL1_PLL_IVA2), 8, 11, dp->m);
+
+ /* N (IVA2_DPLL_DIV) : CM_CLKSEL1_PLL_IVA2[0:6] */
+ sr32(CM_REG(CLKSEL1_PLL_IVA2), 0, 7, dp->n);
+
+ /* FREQSEL (IVA2_DPLL_FREQSEL) : CM_CLKEN_PLL_IVA2[4:7] */
+ sr32(CM_REG(CLKEN_PLL_IVA2), 4, 4, dp->fsel);
+
+ /* LOCK (MODE (EN_IVA2_DPLL) : CM_CLKEN_PLL_IVA2[0:2] */
+ sr32(CM_REG(CLKEN_PLL_IVA2), 0, 3, PLL_LOCK);
wait_on_value((0x1 << 0), 1, CM_REG(IDLEST_PLL_IVA2), LDELAY);
+}
+
+/**
+ * @brief Inits clocks for PRCM
+ *
+ * This is called from SRAM, or Flash (using temp SRAM stack).
+ * if CONFIG_OMAP3_COPY_CLOCK_SRAM is defined, @ref go_to_speed
+ *
+ * @return void
+ */
+void prcm_init(void)
+{
+ u32 osc_clk = 0, sys_clkin_sel = 0;
+ u32 cpu_type = get_cpu_type();
+ u32 cpu_rev = get_cpu_rev();
+ u32 clk_index;
+
+ /* Gauge the input clock speed and find out the sys_clkin_sel
+ * value corresponding to the input clock.
+ */
+ osc_clk = get_osc_clk_speed();
+ get_sys_clkin_sel(osc_clk, &sys_clkin_sel);
+ /* set input crystal speed */
+ sr32(PRM_REG(CLKSEL), 0, 3, sys_clkin_sel);
+
+ /*
+ * OMAP3430:
+ * If the input clock is greater than 19.2M always divide/2
+ * OMAP3630:
+ * DDR corruption was observed on exit from OFF mode, when
+ * sys clock is lower than 26M. As workaround, it is maintained
+ * at 26M.
+ */
+ if ((cpu_type != CPU_3630) && (sys_clkin_sel > 2)) {
+ /* input clock divider */
+ sr32(PRM_REG(CLKSRC_CTRL), 6, 2, 2);
+ clk_index = sys_clkin_sel / 2;
+ } else {
+ /* input clock divider */
+ sr32(PRM_REG(CLKSRC_CTRL), 6, 2, 1);
+ clk_index = sys_clkin_sel;
+ }
+
+ /*
+ * Unlock the MPU PLL. Run slow while clocks are being configured.
+ */
+ sr32(CM_REG(CLKEN_PLL_MPU), 0, 3, PLL_LOW_POWER_BYPASS);
+ wait_on_value((0x1 << 0), 0, CM_REG(IDLEST_PLL_MPU), LDELAY);
+
+ if (cpu_type == CPU_3430) {
+ init_core_dpll_34x(cpu_rev, clk_index);
+ init_per_dpll_34x(cpu_rev, clk_index);
+ init_mpu_dpll_34x(cpu_rev, clk_index);
+ init_iva_dpll_34x(cpu_rev, clk_index);
+ }
+ else if (cpu_type == CPU_3630) {
+ init_core_dpll_36x(cpu_rev, clk_index);
+ init_per_dpll_36x(cpu_rev, clk_index);
+ init_mpu_dpll_36x(cpu_rev, clk_index);
+ init_iva_dpll_36x(cpu_rev, clk_index);
+ }
+ else {
+ /* Unknown CPU */
+ hang();
+ }
+
+ /*
+ * Clock configuration complete. Lock MPU PLL.
+ */
+ sr32(CM_REG(CLKEN_PLL_MPU), 0, 3, PLL_LOCK);
+ wait_on_value((0x1 << 0), 1, CM_REG(IDLEST_PLL_MPU), LDELAY);
/* Set up GPTimers to sys_clk source only */
sr32(CM_REG(CLKSEL_PER), 0, 8, 0xff);
diff --git a/arch/arm/mach-omap/omap3_clock_core.S b/arch/arm/mach-omap/omap3_clock_core.S
index 872ae5abcd..c8d04bbc29 100644
--- a/arch/arm/mach-omap/omap3_clock_core.S
+++ b/arch/arm/mach-omap/omap3_clock_core.S
@@ -194,7 +194,7 @@ pll_div_val3:
pll_div_add4:
.word CM_CLKSEL_GFX
pll_div_val4:
- .word (GFX_DIV << 0)
+ .word GFX_DIV_34X
pll_div_add5:
.word CM_CLKSEL1_EMU
pll_div_val5:
@@ -205,108 +205,222 @@ pll_div_val5:
/* the literal pools origin */
.ltorg
-/* DPLL(1-4) PARAM TABLES */
-/* Each of the tables has M, N, FREQSEL, M2 values defined for nominal
- * OPP (1.2V). The fields are defined according to dpll_param
- * struct(omap3_clock.c). MAX index is as per omap3_clock.h
+/* MPU DPLL Parameter table
+ *
+ * This table defines the DPLL parameter table for the MPU as defined by
+ * "struct dpll_param defined" in "omap3-clock.h"
+ *
+ * The tables are defined for separately each silicon revision.
*/
+.globl mpu_dpll_param_34x_es1
+mpu_dpll_param_34x_es1:
+/* M N FREQSEL M2 */
+.word 0x0FE, 0x07, 0x05, 0x01 /* 12 MHz */
+.word 0x17D, 0x0C, 0x03, 0x01 /* 13 MHz */
+.word 0x179, 0x12, 0x04, 0x01 /* 19.2 MHz */
+.word 0x17D, 0x19, 0x03, 0x01 /* 26 MHz */
+.word 0x1FA, 0x32, 0x03, 0x01 /* 38.4 MHz */
+
+.globl mpu_dpll_param_34x_es2
+mpu_dpll_param_34x_es2:
+/* M N FREQSEL M2 */
+.word 0x0FA, 0x05, 0x07, 0x01 /* 12 MHz */
+.word 0x1F4, 0x0C, 0x03, 0x01 /* 13 MHz */
+.word 0x271, 0x17, 0x03, 0x01 /* 19.2 MHz */
+.word 0x0FA, 0x0C, 0x07, 0x01 /* 26 MHz */
+.word 0x271, 0x2F, 0x03, 0x01 /* 38.4 MHz */
-mpu_dpll_param:
-/* 12MHz */
-/* ES2 */
-.word 0x0FA,0x05,0x07,0x01
-
-/* 13MHz */
-/* ES2 */
-.word 0x1F4,0x0C,0x03,0x01
+/**
+ * @brief Get address of MPU DPLL param table (OMAP34XX).
+ *
+ * @param rev Silicon revision.
+ *
+ * @return Address of the param table
+ */
+.globl get_mpu_dpll_param_34x
+get_mpu_dpll_param_34x:
+ mov r3, r0
+ lsl r3, r3, #16 /* Isolate silicon revision */
+ lsr r3, r3, #16
+ cmp r3, #0 /* Revision 1 ? */
+ adr r0, mpu_dpll_param_34x_es1
+ bxeq lr
+ adr r0, mpu_dpll_param_34x_es2
+ mov pc, lr
+
+iva_dpll_param_34x_es1:
+/* M N FREQSEL M2 */
+.word 0x07D, 0x05, 0x07, 0x01 /* 12 MHz */
+.word 0x0FA, 0x0C, 0x03, 0x01 /* 13 MHz */
+.word 0x082, 0x09, 0x07, 0x01 /* 19.2 MHz */
+.word 0x07D, 0x0C, 0x07, 0x01 /* 26 MHz */
+.word 0x13F, 0x30, 0x03, 0x01 /* 38.4 MHz */
+
+iva_dpll_param_34x_es2:
+/* M N FREQSEL M2 */
+.word 0x0B4, 0x05, 0x07, 0x01 /* 12 MHz */
+.word 0x168, 0x0C, 0x03, 0x01 /* 13 MHz */
+.word 0x0E1, 0x0B, 0x06, 0x01 /* 19.2 MHz */
+.word 0x0B4, 0x0C, 0x07, 0x01 /* 26 MHz */
+.word 0x0E1, 0x17, 0x06, 0x01 /* 38.4 MHz */
-/* 19.2MHz */
-/* ES2 */
-.word 0x271,0x17,0x03,0x01
+/**
+ * @brief Get address of IVA DPLL param table (OMAP34XX).
+ *
+ * @param rev Silicon revision.
+ *
+ * @return Address of the param table
+ */
+.globl get_iva_dpll_param_34x
+get_iva_dpll_param_34x:
+ mov r3, r0
+ lsl r3, r3, #16 /* Isolate silicon revision */
+ lsr r3, r3, #16
+ cmp r3, #0 /* Revision 1 ? */
+ adr r0, iva_dpll_param_34x_es1
+ bxeq lr
+ adr r0, iva_dpll_param_34x_es2
+ mov pc, lr
+
+core_dpll_param_34x_es1:
+/* M N FREQSEL M2 */
+.word 0x19F, 0x0E, 0x03, 0x01 /* 12 MHz */
+.word 0x1B2, 0x10, 0x03, 0x01 /* 13 MHz */
+.word 0x19F, 0x17, 0x03, 0x01 /* 19.2 MHz */
+.word 0x1B2, 0x21, 0x03, 0x01 /* 26 MHz */
+.word 0x19F, 0x2F, 0x03, 0x01 /* 38.4 MHz */
+
+core_dpll_param_34x_es2:
+/* M N FREQSEL M2 */
+.word 0x0A6, 0x05, 0x07, 0x01 /* 12 MHz */
+.word 0x14C, 0x0C, 0x03, 0x01 /* 13 MHz */
+.word 0x19F, 0x17, 0x03, 0x01 /* 19.2 MHz */
+.word 0x0A6, 0x0C, 0x07, 0x01 /* 26 MHz */
+.word 0x19F, 0x2F, 0x03, 0x01 /* 38.4 MHz */
-/* 26MHz */
-/* ES2 */
-.word 0x0FA,0x0C,0x07,0x01
+/**
+ * @brief Get address of CORE DPLL param table (OMAP34XX).
+ *
+ * @param rev Silicon revision.
+ *
+ * @return Address of the param table
+ */
+.globl get_core_dpll_param_34x
+get_core_dpll_param_34x:
+ mov r3, r0
+ lsl r3, r3, #16 /* Isolate silicon revision */
+ lsr r3, r3, #16
+ cmp r3, #0 /* Revision 1 ? */
+ adr r0, core_dpll_param_34x_es1
+ bxeq lr
+ adr r0, core_dpll_param_34x_es2
+ mov pc, lr
-/* 38.4MHz */
-/* ES2 */
-.word 0x271,0x2F,0x03,0x01
+/* PER DPLL values are same for both ES1 and ES2 */
+per_dpll_param_34x:
+/* M N FREQSEL M2 */
+.word 0x0D8, 0x05, 0x07, 0x09 /* 12 MHz */
+.word 0x1B0, 0x0C, 0x03, 0x09 /* 13 MHz */
+.word 0x0E1, 0x09, 0x07, 0x09 /* 19.2 MHz */
+.word 0x0D8, 0x0C, 0x07, 0x09 /* 26 MHz */
+.word 0x0E1, 0x13, 0x07, 0x09 /* 38.4 MHz */
-.globl get_mpu_dpll_param
-get_mpu_dpll_param:
- adr r0, mpu_dpll_param
+/**
+ * @brief Get address of PER DPLL param table (OMAP34XX).
+ *
+ * @param rev Silicon revision (not used).
+ *
+ * @return Address of the param table
+ */
+.globl get_per_dpll_param_34x
+get_per_dpll_param_34x:
+ adr r0, per_dpll_param_34x
mov pc, lr
-iva_dpll_param:
-/* 12MHz */
-/* ES2 */
-.word 0x0B4,0x05,0x07,0x01
-
-/* 13MHz */
-/* ES2 */
-.word 0x168,0x0C,0x03,0x01
-
-/* 19.2MHz */
-/* ES2 */
-.word 0x0E1,0x0B,0x06,0x01
-
-/* 26MHz */
-/* ES2 */
-.word 0x0B4,0x0C,0x07,0x01
-
-/* 38.4MHz */
-/* ES2 */
-.word 0x0E1,0x17,0x06,0x01
+.globl mpu_dpll_param_36x
+mpu_dpll_param_36x:
+/* FIXME: All values correspond to 26MHz only */
+/* M N FREQSEL M2 */
+.word 0x12C, 0x0C, 0x00, 0x01 /* 12 MHz */
+.word 0x12C, 0x0C, 0x00, 0x01 /* 13 MHz */
+.word 0x12C, 0x0C, 0x00, 0x01 /* 19.2 MHz */
+.word 0x12C, 0x0C, 0x00, 0x01 /* 26 MHz */
+.word 0x12C, 0x0C, 0x00, 0x01 /* 38.4 MHz */
-.globl get_iva_dpll_param
-get_iva_dpll_param:
- adr r0, iva_dpll_param
+/**
+ * @brief Get address of MPU DPLL param table (OMAP36XX).
+ *
+ * @param rev Silicon revision.
+ *
+ * @return Address of the param table
+ */
+.globl get_mpu_dpll_param_36x
+get_mpu_dpll_param_36x:
+ adr r0, mpu_dpll_param_36x
mov pc, lr
-core_dpll_param:
-/* 12MHz */
-/* ES2 */
-.word 0x0A6,0x05,0x07,0x01
-
-/* 13MHz */
-/* ES2 */
-.word 0x14C,0x0C,0x03,0x01
-
-/* 19.2MHz */
-/* ES2 */
-.word 0x19F,0x17,0x03,0x01
+.globl iva_dpll_param_36x
+iva_dpll_param_36x:
+/* FIXME: All values correspond to 26MHz only */
+/* M N FREQSEL M2 */
+.word 0x00A, 0x00, 0x00, 0x01 /* 12 MHz */
+.word 0x00A, 0x00, 0x00, 0x01 /* 13 MHz */
+.word 0x00A, 0x00, 0x00, 0x01 /* 19.2 MHz */
+.word 0x00A, 0x00, 0x00, 0x01 /* 26 MHz */
+.word 0x00A, 0x00, 0x00, 0x01 /* 38.4 MHz */
-/* 26MHz */
-/* ES2 */
-.word 0x0A6,0x0C,0x07,0x01
-
-/* 38.4MHz */
-/* ES2 */
-.word 0x19F,0x2F,0x03,0x01
-
-.globl get_core_dpll_param
-get_core_dpll_param:
- adr r0, core_dpll_param
+/**
+ * @brief Get address of IVA DPLL param table (OMAP36XX).
+ *
+ * @param rev Silicon revision.
+ *
+ * @return Address of the param table
+ */
+.globl get_iva_dpll_param_36x
+get_iva_dpll_param_36x:
+ adr r0, iva_dpll_param_36x
mov pc, lr
-/* PER DPLL values are same for both ES1 and ES2 */
-per_dpll_param:
-/* 12MHz */
-.word 0xD8,0x05,0x07,0x09
-
-/* 13MHz */
-.word 0x1B0,0x0C,0x03,0x09
-
-/* 19.2MHz */
-.word 0xE1,0x09,0x07,0x09
+.globl core_dpll_param_36x
+core_dpll_param_36x:
+/* FIXME: All values correspond to 26MHz only */
+/* M N FREQSEL M2 */
+.word 0x0C8, 0x0C, 0x00, 0x01 /* 12 MHz */
+.word 0x0C8, 0x0C, 0x00, 0x01 /* 13 MHz */
+.word 0x0C8, 0x0C, 0x00, 0x01 /* 19.2 MHz */
+.word 0x0C8, 0x0C, 0x00, 0x01 /* 26 MHz */
+.word 0x0C8, 0x0C, 0x00, 0x01 /* 38.4 MHz */
-/* 26MHz */
-.word 0xD8,0x0C,0x07,0x09
+/**
+ * @brief Get address of IVA DPLL param table (OMAP36XX).
+ *
+ * @param rev Silicon revision.
+ *
+ * @return Address of the param table
+ */
+.globl get_core_dpll_param_36x
+get_core_dpll_param_36x:
+ adr r0, core_dpll_param_36x
+ mov pc, lr
-/* 38.4MHz */
-.word 0xE1,0x13,0x07,0x09
+.globl per_dpll_param_36x
+per_dpll_param_36x:
+/* FIXME: All values correspond to 26MHz only */
+/* M N M2 M3 M4 M5 M6 m2DIV */
+.word 0x1B0, 0x0C, 9, 0x10, 9, 4, 3, 1 /* 12 MHz */
+.word 0x1B0, 0x0C, 9, 0x10, 9, 4, 3, 1 /* 13 MHz */
+.word 0x1B0, 0x0C, 9, 0x10, 9, 4, 3, 1 /* 19.2 MHz */
+.word 0x1B0, 0x0C, 9, 0x10, 9, 4, 3, 1 /* 26 MHz */
+.word 0x1B0, 0x0C, 9, 0x10, 9, 4, 3, 1 /* 38.4 MHz */
-.globl get_per_dpll_param
-get_per_dpll_param:
- adr r0, per_dpll_param
+/**
+ * @brief Get address of PER DPLL param table (OMAP36XX).
+ *
+ * @param rev Silicon revision.
+ *
+ * @return Address of the param table
+ */
+.globl get_per_dpll_param_36x
+get_per_dpll_param_36x:
+ adr r0, per_dpll_param_36x
mov pc, lr
diff --git a/arch/arm/mach-omap/omap3_generic.c b/arch/arm/mach-omap/omap3_generic.c
index f780794282..843143bab1 100644
--- a/arch/arm/mach-omap/omap3_generic.c
+++ b/arch/arm/mach-omap/omap3_generic.c
@@ -66,29 +66,98 @@ EXPORT_SYMBOL(reset_cpu);
/**
* @brief Low level CPU type
*
- * @return CPU_3430
+ * @return Detected CPU type
*/
u32 get_cpu_type(void)
{
- /* FIXME: need to get register defines for 3430 */
+ u32 idcode_val;
+ u16 hawkeye;
+
+ idcode_val = readl(IDCODE_REG);
+
+ hawkeye = get_hawkeye(idcode_val);
+
+ if (hawkeye == OMAP_HAWKEYE_34XX)
+ return CPU_3430;
+
+ if (hawkeye == OMAP_HAWKEYE_36XX)
+ return CPU_3630;
+
+ /*
+ * Fallback to OMAP3430 as default.
+ */
return CPU_3430;
}
/**
- * @brief Extract the OMAP ES rev
+ * @brief Extract the OMAP ES revision
+ *
+ * The significance of the CPU revision depends upon the cpu type.
+ * Latest known revision is considered default.
*
- * @return CPU_ES version
+ * @return silicon version
*/
u32 get_cpu_rev(void)
{
u32 idcode_val;
+ u32 version, retval;
+
idcode_val = readl(IDCODE_REG);
- if ((idcode_val & (HAWKEYE_MASK | VERSION_MASK)) == HAWKEYE_ES2_1)
- return CPU_ES2P1;
- if ((idcode_val & HAWKEYE_MASK) == HAWKEYE_ES2)
- return CPU_ES2;
- /* unsupported! */
- return CPU_ES1;
+
+ version = get_version(idcode_val);
+
+ switch (get_cpu_type()) {
+ case CPU_3630:
+ switch (version) {
+ case 0:
+ retval = OMAP36XX_ES1;
+ break;
+ case 1:
+ retval = OMAP36XX_ES1_1;
+ break;
+ case 2:
+ /*
+ * Fall through the default case.
+ */
+ default:
+ retval = OMAP36XX_ES1_2;
+ }
+ break;
+ case CPU_3430:
+ /*
+ * Same as default case
+ */
+ default:
+ /*
+ * On OMAP3430 ES1.0 the IDCODE register is not exposed on L4.
+ * Use CPU ID to check for the same.
+ */
+ __asm__ __volatile__("mrc p15, 0, %0, c0, c0, 0":"=r"(retval));
+ if ((retval & 0xf) == 0x0) {
+ retval = OMAP34XX_ES1;
+ } else {
+ switch (version) {
+ case 0: /* This field was not set in early samples */
+ case 1:
+ retval = OMAP34XX_ES2;
+ break;
+ case 2:
+ retval = OMAP34XX_ES2_1;
+ break;
+ case 3:
+ retval = OMAP34XX_ES3;
+ break;
+ case 4:
+ /*
+ * Same as default case
+ */
+ default:
+ retval = OMAP34XX_ES3_1;
+ }
+ }
+ }
+
+ return retval;
}
/**
diff --git a/arch/arm/mach-stm/Kconfig b/arch/arm/mach-stm/Kconfig
index 021919a8a8..e47d9f12a8 100644
--- a/arch/arm/mach-stm/Kconfig
+++ b/arch/arm/mach-stm/Kconfig
@@ -4,10 +4,12 @@ config ARCH_TEXT_BASE
hex
default 0x41000000 if MACH_MX23EVK
default 0x42000000 if MACH_CHUMBY
+ default 0x47000000 if MACH_TX28
config BOARDINFO
default "Freescale i.MX23-EVK" if MACH_MX23EVK
default "Chumby Falconwing" if MACH_CHUMBY
+ default "Karo TX28" if MACH_TX28
comment "SigmaTel/Freescale i.MX System-on-Chip"
@@ -18,6 +20,11 @@ config ARCH_IMX23
bool "i.MX23"
select CPU_ARM926T
+config ARCH_IMX28
+ bool "i.MX28"
+ select CPU_ARM926T
+ select ARCH_HAS_FEC_IMX
+
endchoice
if ARCH_IMX23
@@ -41,8 +48,37 @@ endchoice
endif
+if ARCH_IMX28
+
+choice
+ prompt "i.MX28 Board Type"
+
+config MACH_TX28
+ bool "KARO tx28"
+ help
+ Say Y here if you are using the KARO TX28 CPU module.
+
+endchoice
+
+endif
+
menu "Board specific settings "
+if MACH_TX28
+
+choice
+ prompt "TX28 Base Board Type"
+
+config MACH_TX28STK5
+ bool "TX28-stk5"
+ help
+ Select this entry if you are running the TX28 CPU module on the
+ KARO TX28 Starterkit5.
+
+endchoice
+
+endif
+
endmenu
endif
diff --git a/arch/arm/mach-stm/Makefile b/arch/arm/mach-stm/Makefile
index 59d70b6b55..0ff8fd16d6 100644
--- a/arch/arm/mach-stm/Makefile
+++ b/arch/arm/mach-stm/Makefile
@@ -1,2 +1,4 @@
-obj-$(CONFIG_ARCH_IMX23) += speed-imx23.o imx23.o iomux-imx23.o clocksource-imx23.o reset-imx23.o
-
+obj-y += imx.o iomux-imx.o reset-imx.o
+obj-$(CONFIG_DRIVER_VIDEO_STM) += imx_lcd_clk.o
+obj-$(CONFIG_ARCH_IMX23) += speed-imx23.o clocksource-imx23.o
+obj-$(CONFIG_ARCH_IMX28) += speed-imx28.o clocksource-imx28.o
diff --git a/arch/arm/mach-stm/clocksource-imx28.c b/arch/arm/mach-stm/clocksource-imx28.c
new file mode 100644
index 0000000000..15ae951004
--- /dev/null
+++ b/arch/arm/mach-stm/clocksource-imx28.c
@@ -0,0 +1,73 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <clock.h>
+#include <notifier.h>
+#include <mach/imx-regs.h>
+#include <mach/clock.h>
+#include <asm/io.h>
+
+#define TIMROTCTRL 0x00
+# define TIMROTCTRL_SFTRST
+# define TIMROTCTRL_CLKGATE
+# define TIMROTCTRL_DIVIDER(x) ((x & 0x3f) << 16)
+
+#define TIMCTRL1 0x60
+#define TIMCTRL1_SET 0x64
+#define TIMCTRL1_CLR 0x68
+#define TIMCTRL1_TOG 0x6c
+# define TIMCTRL_RELOAD (1 << 6)
+# define TIMCTRL_UPDATE (1 << 7)
+# define TIMCTRL_PRESCALE(x) ((x & 0x3) << 4)
+# define TIMCTRL_SELECT(x) (x & 0xf)
+#define TIMCOUNT1 0x70
+#define TIMFIX1 0x80
+
+static const void __iomem * timer_base = (void *)IMX_TIM1_BASE;
+
+/* we are using the 32 kHz reference */
+#define CLOCK_TICK_RATE 32000
+
+static uint64_t imx28_clocksource_read(void)
+{
+ return ~(readl(timer_base + TIMCOUNT1));
+}
+
+static struct clocksource imx28_cs = {
+ .read = imx28_clocksource_read,
+ .mask = CLOCKSOURCE_MASK(32),
+ .shift = 17,
+};
+
+static int imx28_clocksource_init(void)
+{
+ /* enable the whole timer block */
+ writel(0x00000000, timer_base + TIMROTCTRL);
+ /* setup start value of the general purpose timer */
+ writel(0x00000000, timer_base + TIMCTRL1);
+ writel(TIMCTRL_UPDATE, timer_base + TIMCTRL1);
+ /* setup the reload value of the general purpose timer */
+ writel(0xffffffff, timer_base + TIMFIX1);
+
+ writel(TIMCTRL_UPDATE | TIMCTRL_RELOAD | TIMCTRL_PRESCALE(0) |
+ TIMCTRL_SELECT(0xb), timer_base + TIMCTRL1);
+ imx28_cs.mult = clocksource_hz2mult(CLOCK_TICK_RATE, imx28_cs.shift);
+ init_clock(&imx28_cs);
+
+ return 0;
+}
+
+core_initcall(imx28_clocksource_init);
diff --git a/arch/arm/mach-stm/imx23.c b/arch/arm/mach-stm/imx.c
index 14a4249893..14a4249893 100644
--- a/arch/arm/mach-stm/imx23.c
+++ b/arch/arm/mach-stm/imx.c
diff --git a/arch/arm/mach-stm/imx_lcd_clk.c b/arch/arm/mach-stm/imx_lcd_clk.c
new file mode 100644
index 0000000000..89386640ad
--- /dev/null
+++ b/arch/arm/mach-stm/imx_lcd_clk.c
@@ -0,0 +1,149 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix <kernel@pengutronix.de>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <common.h>
+#include <init.h>
+#include <mach/imx-regs.h>
+#include <mach/clock.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_ARCH_IMX23
+
+# define HW_CLKCTRL_DIS_LCDIF 0x060
+# define CLKCTRL_DIS_LCDIF_GATE (1 << 31)
+# define CLKCTRL_DIS_LCDIF_BUSY (1 << 29)
+# define MASK_DIS_LCDIF_DIV 0xfff
+# define SET_DIS_LCDIF_DIV(x) ((x) & MASK_DIS_LCDIF_DIV)
+# define GET_DIS_LCDIF_DIV(x) ((x) & MASK_DIS_LCDIF_DIV)
+
+# define HW_CLKCTRL_FRAC 0xf0
+# define MASK_PIXFRAC 0x3f
+# define GET_PIXFRAC(x) (((x) >> 16) & MASK_PIXFRAC)
+# define SET_PIXFRAC(x) (((x) & MASK_PIXFRAC) << 16)
+# define CLKCTRL_FRAC_CLKGATEPIX (1 << 23)
+
+# define HW_CLKCTRL_CLKSEQ 0x110
+# define CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF (1 << 1)
+
+#endif
+
+#ifdef CONFIG_ARCH_IMX28
+
+# define HW_CLKCTRL_DIS_LCDIF 0x120
+# define CLKCTRL_DIS_LCDIF_GATE (1 << 31)
+# define CLKCTRL_DIS_LCDIF_BUSY (1 << 29)
+# define MASK_DIS_LCDIF_DIV 0x1fff
+# define SET_DIS_LCDIF_DIV(x) ((x) & MASK_DIS_LCDIF_DIV)
+# define GET_DIS_LCDIF_DIV(x) ((x) & MASK_DIS_LCDIF_DIV)
+
+/* note: On i.MX28 this is called 'FRAC1' */
+# define HW_CLKCTRL_FRAC 0x1c0
+# define MASK_PIXFRAC 0x3f
+# define GET_PIXFRAC(x) ((x) & MASK_PIXFRAC)
+# define SET_PIXFRAC(x) ((x) & MASK_PIXFRAC)
+# define CLKCTRL_FRAC_CLKGATEPIX (1 << 7)
+
+# define HW_CLKCTRL_CLKSEQ 0x1d0
+# define CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF (1 << 14)
+
+#endif
+
+unsigned imx_get_lcdifclk(void)
+{
+ unsigned rate = (imx_get_mpllclk() / 1000) * 18U;
+ unsigned div;
+
+ div = GET_PIXFRAC(readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC));
+ if (div != 0U) {
+ rate /= div;
+ div = GET_DIS_LCDIF_DIV(readl(IMX_CCM_BASE +
+ HW_CLKCTRL_DIS_LCDIF));
+ if (div != 0U)
+ rate /= div;
+ else
+ pr_debug("LCDIF clock has divisor 0!\n");
+ } else
+ pr_debug("LCDIF clock has frac divisor 0!\n");
+
+ return rate * 1000;
+}
+
+/*
+ * The source of the pixel clock can be the external 24 MHz crystal or the
+ * internal PLL running at 480 MHz. In order to support at least VGA sized
+ * displays/resolutions this routine forces the PLL as the clock source.
+ */
+unsigned imx_set_lcdifclk(unsigned nc)
+{
+ unsigned frac, best_frac = 0, div, best_div = 0, result;
+ int delta, best_delta = 0xffffff;
+ unsigned i, parent_rate = imx_get_mpllclk() / 1000;
+ uint32_t reg;
+
+#define SH_DIV(NOM, DEN, LSH) ((((NOM) / (DEN)) << (LSH)) + \
+ DIV_ROUND_CLOSEST(((NOM) % (DEN)) << (LSH), DEN))
+#define SHIFT 4
+
+ nc /= 1000;
+ nc <<= SHIFT;
+
+ for (frac = 18; frac <= 35; ++frac) {
+ for (div = 1; div <= 255; ++div) {
+ result = DIV_ROUND_CLOSEST(parent_rate *
+ SH_DIV(18U, frac, SHIFT), div);
+ delta = nc - result;
+ if (abs(delta) < abs(best_delta)) {
+ best_delta = delta;
+ best_frac = frac;
+ best_div = div;
+ }
+ }
+ }
+
+ if (best_delta == 0xffffff) {
+ pr_debug("Unable to match the pixelclock\n");
+ return 0;
+ }
+
+ pr_debug("Programming PFD=%u,DIV=%u ref_pix=%u MHz PIXCLK=%u kHz\n",
+ best_frac, best_div, 480 * 18 / best_frac,
+ 480000 * 18 / best_frac / best_div);
+
+ reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC) & ~MASK_PIXFRAC;
+ reg |= SET_PIXFRAC(best_frac);
+ writel(reg, IMX_CCM_BASE + HW_CLKCTRL_FRAC);
+ writel(reg & ~CLKCTRL_FRAC_CLKGATEPIX, IMX_CCM_BASE + HW_CLKCTRL_FRAC);
+
+ reg = readl(IMX_CCM_BASE + HW_CLKCTRL_DIS_LCDIF) & ~MASK_DIS_LCDIF_DIV;
+ reg &= ~CLKCTRL_DIS_LCDIF_GATE;
+ reg |= SET_DIS_LCDIF_DIV(best_div);
+ writel(reg, IMX_CCM_BASE + HW_CLKCTRL_DIS_LCDIF);
+
+ /* Wait for divider update */
+ for (i = 0; i < 10000; i++) {
+ if (!(readl(IMX_CCM_BASE + HW_CLKCTRL_DIS_LCDIF) &
+ CLKCTRL_DIS_LCDIF_BUSY))
+ break;
+ }
+
+ if (i >= 10000) {
+ pr_debug("Setting LCD clock failed\n");
+ return 0;
+ }
+
+ writel(CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF,
+ IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ + BIT_CLR);
+
+ return imx_get_lcdifclk();
+}
diff --git a/arch/arm/mach-stm/include/mach/clock-imx23.h b/arch/arm/mach-stm/include/mach/clock-imx23.h
new file mode 100644
index 0000000000..723f343566
--- /dev/null
+++ b/arch/arm/mach-stm/include/mach/clock-imx23.h
@@ -0,0 +1,28 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MACH_CLOCK_IMX23_H
+# define MACH_CLOCK_IMX23_H
+
+unsigned imx_get_mpllclk(void);
+unsigned imx_get_emiclk(void);
+unsigned imx_get_ioclk(void);
+unsigned imx_get_armclk(void);
+unsigned imx_get_hclk(void);
+unsigned imx_get_xclk(void);
+unsigned imx_get_sspclk(unsigned);
+unsigned imx_set_sspclk(unsigned, unsigned, int);
+unsigned imx_set_ioclk(unsigned);
+unsigned imx_set_lcdifclk(unsigned);
+unsigned imx_get_lcdifclk(void);
+
+#endif /* MACH_CLOCK_IMX23_H */
diff --git a/arch/arm/mach-stm/include/mach/clock-imx28.h b/arch/arm/mach-stm/include/mach/clock-imx28.h
new file mode 100644
index 0000000000..45fb043ac4
--- /dev/null
+++ b/arch/arm/mach-stm/include/mach/clock-imx28.h
@@ -0,0 +1,31 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef MACH_CLOCK_IMX28_H
+#define MACH_CLOCK_IMX28_H
+
+unsigned imx_get_mpllclk(void);
+unsigned imx_get_emiclk(void);
+unsigned imx_get_ioclk(unsigned);
+unsigned imx_get_armclk(void);
+unsigned imx_get_hclk(void);
+unsigned imx_get_xclk(void);
+unsigned imx_get_sspclk(unsigned);
+unsigned imx_set_sspclk(unsigned, unsigned, int);
+unsigned imx_set_ioclk(unsigned, unsigned);
+unsigned imx_set_lcdifclk(unsigned);
+unsigned imx_get_lcdifclk(void);
+unsigned imx_get_fecclk(void);
+void imx_enable_enetclk(void);
+
+#endif /* MACH_CLOCK_IMX28_H */
+
diff --git a/arch/arm/mach-stm/include/mach/clock.h b/arch/arm/mach-stm/include/mach/clock.h
index 0e1a6d6f42..bd1fa7c849 100644
--- a/arch/arm/mach-stm/include/mach/clock.h
+++ b/arch/arm/mach-stm/include/mach/clock.h
@@ -17,18 +17,14 @@
* MA 02111-1307 USA
*/
-#ifndef ASM_ARCH_CLOCK_IMX23_H
-#define ASM_ARCH_CLOCK_IMX23_H
+#ifndef __MACH_CLOCK_H
+# define __MACH_CLOCK_H
-unsigned imx_get_mpllclk(void);
-unsigned imx_get_emiclk(void);
-unsigned imx_get_ioclk(void);
-unsigned imx_get_armclk(void);
-unsigned imx_get_hclk(void);
-unsigned imx_get_xclk(void);
-unsigned imx_get_sspclk(unsigned);
-unsigned imx_set_sspclk(unsigned, unsigned, int);
-unsigned imx_set_ioclk(unsigned);
-
-#endif /* ASM_ARCH_CLOCK_IMX23_H */
+#if defined CONFIG_ARCH_IMX23
+# include <mach/clock-imx23.h>
+#endif
+#if defined CONFIG_ARCH_IMX28
+# include <mach/clock-imx28.h>
+#endif
+#endif /* __MACH_CLOCK_H */
diff --git a/arch/arm/mach-stm/include/mach/fb.h b/arch/arm/mach-stm/include/mach/fb.h
new file mode 100644
index 0000000000..65e3be226b
--- /dev/null
+++ b/arch/arm/mach-stm/include/mach/fb.h
@@ -0,0 +1,43 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __MACH_FB_H
+# define __MACH_FB_H
+
+#include <fb.h>
+
+#define STMLCDIF_8BIT 1 /** pixel data bus to the display is of 8 bit width */
+#define STMLCDIF_16BIT 0 /** pixel data bus to the display is of 16 bit width */
+#define STMLCDIF_18BIT 2 /** pixel data bus to the display is of 18 bit width */
+#define STMLCDIF_24BIT 3 /** pixel data bus to the display is of 24 bit width */
+
+/** LC display uses active high data enable signal */
+#define FB_SYNC_DE_HIGH_ACT (1 << 27)
+/** LC display will latch its data at clock's rising edge */
+#define FB_SYNC_CLK_INVERT (1 << 28)
+/** output RGB digital data inverted */
+#define FB_SYNC_DATA_INVERT (1 << 29)
+/** Stop clock if no data is sent (required for passive displays) */
+#define FB_SYNC_CLK_IDLE_DIS (1 << 30)
+/** swap RGB to BGR */
+#define FB_SYNC_SWAP_RGB (1 << 31)
+
+struct imx_fb_videomode {
+ struct fb_videomode *mode_list;
+ unsigned mode_cnt;
+
+ unsigned dotclk_delay; /**< refer manual HW_LCDIF_VDCTRL4 register */
+ unsigned ld_intf_width; /**< refer STMLCDIF_* macros */
+};
+
+#endif /* __MACH_FB_H */
+
diff --git a/arch/arm/mach-stm/include/mach/generic.h b/arch/arm/mach-stm/include/mach/generic.h
index 3a552a8979..50f25c5d1b 100644
--- a/arch/arm/mach-stm/include/mach/generic.h
+++ b/arch/arm/mach-stm/include/mach/generic.h
@@ -22,3 +22,9 @@
#else
# define cpu_is_mx23() (0)
#endif
+
+#ifdef CONFIG_ARCH_IMX28
+# define cpu_is_mx28() (1)
+#else
+# define cpu_is_mx28() (0)
+#endif
diff --git a/arch/arm/mach-stm/include/mach/gpio.h b/arch/arm/mach-stm/include/mach/gpio.h
index fa8263cc95..c419926214 100644
--- a/arch/arm/mach-stm/include/mach/gpio.h
+++ b/arch/arm/mach-stm/include/mach/gpio.h
@@ -20,10 +20,19 @@
#ifndef __ASM_MACH_GPIO_H
#define __ASM_MACH_GPIO_H
+#include <types.h>
+
#if defined CONFIG_ARCH_IMX23
# include <mach/iomux-imx23.h>
#endif
+#if defined CONFIG_ARCH_IMX28
+# include <mach/iomux-imx28.h>
+#endif
-void imx_gpio_mode(unsigned);
+void imx_gpio_mode(uint32_t);
+void gpio_set_value(unsigned, int);
+int gpio_direction_input(unsigned);
+int gpio_direction_output(unsigned, int);
+int gpio_get_value(unsigned);
#endif /* __ASM_MACH_GPIO_H */
diff --git a/arch/arm/mach-stm/include/mach/imx-regs.h b/arch/arm/mach-stm/include/mach/imx-regs.h
index 40dc74262e..9b33a0656c 100644
--- a/arch/arm/mach-stm/include/mach/imx-regs.h
+++ b/arch/arm/mach-stm/include/mach/imx-regs.h
@@ -20,8 +20,17 @@
#ifndef _IMX_REGS_H
# define _IMX_REGS_H
+/* Note: Some registers do not support this bit change feature! */
+#define BIT_SET 0x04
+#define BIT_CLR 0x08
+#define BIT_TGL 0x0C
+
#if defined CONFIG_ARCH_IMX23
# include <mach/imx23-regs.h>
#endif
+#if defined CONFIG_ARCH_IMX28
+# include <mach/imx28-regs.h>
+#endif
+
#endif /* _IMX_REGS_H */
diff --git a/arch/arm/mach-stm/include/mach/imx23-regs.h b/arch/arm/mach-stm/include/mach/imx23-regs.h
index 89ca45374d..caac19bc01 100644
--- a/arch/arm/mach-stm/include/mach/imx23-regs.h
+++ b/arch/arm/mach-stm/include/mach/imx23-regs.h
@@ -36,6 +36,7 @@
#define IMX_CCM_BASE 0x80040000
#define IMX_I2C1_BASE 0x80058000
#define IMX_SSP1_BASE 0x80010000
+#define IMX_FB_BASE 0x80030000
#define IMX_SSP2_BASE 0x80034000
#endif /* __ASM_ARCH_MX23_REGS_H */
diff --git a/arch/arm/mach-stm/include/mach/imx28-regs.h b/arch/arm/mach-stm/include/mach/imx28-regs.h
new file mode 100644
index 0000000000..0c97c4c2f2
--- /dev/null
+++ b/arch/arm/mach-stm/include/mach/imx28-regs.h
@@ -0,0 +1,47 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __ASM_ARCH_MX28_REGS_H
+#define __ASM_ARCH_MX28_REGS_H
+
+/*
+ * sanity check
+ */
+#ifndef _IMX_REGS_H
+# error "Please do not include directly. Use imx-regs.h instead."
+#endif
+
+#define IMX_SRAM_BASE 0x00000000
+#define IMX_MEMORY_BASE 0x40000000
+
+#define IMX_NFC_BASE 0x8000C000
+#define IMX_SSP0_BASE 0x80010000
+#define IMX_SSP1_BASE 0x80012000
+#define IMX_SSP2_BASE 0x80014000
+#define IMX_SSP3_BASE 0x80016000
+#define IMX_IOMUXC_BASE 0x80018000
+#define IMX_FB_BASE 0x80030000
+#define IMX_CCM_BASE 0x80040000
+#define IMX_WDT_BASE 0x80056000
+#define IMX_I2C0_BASE 0x80058000
+#define IMX_I2C1_BASE 0x8005a000
+#define IMX_TIM1_BASE 0x80068000
+#define IMX_UART0_BASE 0x8006a000
+#define IMX_UART1_BASE 0x8006c000
+#define IMX_UART2_BASE 0x8006e000
+#define IMX_UART3_BASE 0x80070000
+#define IMX_UART4_BASE 0x80072000
+#define IMX_DBGUART_BASE 0x80074000
+#define IMX_FEC0_BASE 0x800F0000
+#define IMX_FEC1_BASE 0x800F4000
+
+#endif /* __ASM_ARCH_MX28_REGS_H */
diff --git a/arch/arm/mach-stm/include/mach/iomux-imx28.h b/arch/arm/mach-stm/include/mach/iomux-imx28.h
new file mode 100644
index 0000000000..1e6d421c22
--- /dev/null
+++ b/arch/arm/mach-stm/include/mach/iomux-imx28.h
@@ -0,0 +1,552 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+/* 3322222222221111111111
+ * 10987654321098765432109876543210
+ * ^^^^^_ Bit offset
+ * ^^^______ Register Number
+ * ^^_________ Function
+ * ^___________ Drive strength feature present
+ * ^____________ Pull up / bit keeper present
+ * ^^_____________ Drive strength setting
+ * ^_______________ Pull up / bit keeper setting
+ * ^________________ Voltage select present
+ * ^_________________ Voltage selection
+ * ^_____________________ direction if enabled as GPIO (1 = output)
+ * ^______________________ initial output value if enabled as GPIO
+ * and configured as output
+ */
+#ifndef __MACH_IOMUX_IMX28_H
+#define __MACH_IOMUX_IMX28_H
+
+/* control pad's function */
+#define FBANK_SHIFT (5)
+#define PORTF(bank,bit) (((bank) << FBANK_SHIFT) | (bit))
+#define GET_GPIO_NO(x) ((x) & 0xff)
+#define FUNC_SHIFT 8
+#define FUNC(x) ((x) << FUNC_SHIFT)
+#define GET_FUNC(x) (((x) >> FUNC_SHIFT) & 3)
+#define IS_GPIO (3)
+
+/* control pad's GPIO feature if enabled */
+#define GPIO_OUT (1 << 20)
+#define GPIO_VALUE(x) ((x) << 21)
+#define GPIO_IN (0 << 20)
+#define GET_GPIODIR(x) (!!((x) & (1 << 20)))
+#define GET_GPIOVAL(x) (!!((x) & (1 << 21)))
+
+/* control pad's drive strength */
+#define SE (1 << 10)
+#define SE_PRESENT(x) (!!((x) & SE))
+#define STRENGTH(x) ((x) << 12)
+#define S4MA 0 /* used to define a 4 mA drive strength */
+#define S8MA 1 /* used to define a 8 mA drive strength */
+#define S12MA 2 /* used to define a 12 mA drive strength */
+#define S16MA 3 /* used to define a 16 mA drive strength,
+ not all pads can drive this current! */
+#define GET_STRENGTH(x) (((x) >> 12) & 0x3)
+
+/* control pad's pull up / bit keeper feature */
+#define PE (1 << 11)
+#define BK (1 << 11) /* FIXME useful to distinguish? */
+#define PE_PRESENT(x) (!!((x) & PE))
+#define BK_PRESENT(x) (!!((x) & BK))
+#define PULLUP(x) ((x) << 14)
+#define BITKEEPER(x) ((x) << 14)
+#define GET_PULLUP(x) (!!((x) & PULLUP(1)))
+#define GET_BITKEEPER(x) (!!((x) & BITKEEPER(1)))
+
+/* control pad's voltage feature */
+#define VE (1 << 15)
+#define VE_PRESENT(x) (!!((x) & VE))
+#define VE_1_8V (0 << 16)
+#define VE_3_3V (1 << 16)
+#define GET_VOLTAGE(x) (!!((x) & (1 << 16)))
+
+/* Bank 0, GPIO pins 0 ... 31 */
+#define GPMI_RESETN (FUNC(0) | PORTF(0, 28) | SE | VE | PE)
+#define GPMI_RESETN_SSP3_CMD (FUNC(1) | PORTF(0, 28) | SE | VE | PE)
+#define GPMI_RESETN_GPIO (FUNC(3) | PORTF(0, 28) | SE | VE | PE)
+#define GPMI_CLE (FUNC(0) | PORTF(0, 27) | SE | VE | PE)
+#define GPMI_CLE_SSP3_D2 (FUNC(1) | PORTF(0, 27) | SE | VE | PE)
+#define GPMI_CLE_SSP3_D5 (FUNC(2) | PORTF(0, 27) | SE | VE | PE)
+#define GPMI_CLE_GPIO (FUNC(3) | PORTF(0, 27) | SE | VE | PE)
+#define GPMI_ALE (FUNC(0) | PORTF(0, 26) | SE | VE | PE)
+#define GPMI_ALE_SSP3_D1 (FUNC(1) | PORTF(0, 26) | SE | VE | PE)
+#define GPMI_ALE_SSP3_D4 (FUNC(2) | PORTF(0, 26) | SE | VE | PE)
+#define GPMI_ALE_GPIO (FUNC(3) | PORTF(0, 26) | SE | VE | PE)
+#define GPMI_WRN (FUNC(0) | PORTF(0, 25) | SE | VE | BK)
+#define GPMI_WRN_SSP1_SCK (FUNC(1) | PORTF(0, 25) | SE | VE | BK)
+#define GPMI_WRN_GPIO (FUNC(3) | PORTF(0, 25) | SE | VE | BK)
+#define GPMI_RDN (FUNC(0) | PORTF(0, 24) | SE | VE | PE)
+#define GPMI_RDN_SSP3_SCK (FUNC(1) | PORTF(0, 24) | SE | VE | PE)
+#define GPMI_RDN_GPIO (FUNC(3) | PORTF(0, 24) | SE | VE | PE)
+#define GPMI_READY3 (FUNC(0) | PORTF(0, 23) | SE | VE | PE)
+#define GPMI_READY3_CAN0_RX (FUNC(1) | PORTF(0, 23) | SE | VE | PE)
+#define GPMI_READY3_HSDAC_TRIG (FUNC(2) | PORTF(0, 23) | SE | VE | PE)
+#define GPMI_READY3_GPIO (FUNC(3) | PORTF(0, 23) | SE | VE | PE)
+#define GPMI_READY2 (FUNC(0) | PORTF(0, 22) | SE | VE | PE)
+#define GPMI_READY2_CAN0_TX (FUNC(1) | PORTF(0, 22) | SE | VE | PE)
+#define GPMI_READY2_ENET0_TX_ER (FUNC(2) | PORTF(0, 22) | SE | VE | PE)
+#define GPMI_READY2_GPIO (FUNC(3) | PORTF(0, 22) | SE | VE | PE)
+#define GPMI_READY1 (FUNC(0) | PORTF(0, 21) | SE | VE | PE)
+#define GPMI_READY1_SSP1_CMD (FUNC(1) | PORTF(0, 21) | SE | VE | PE)
+#define GPMI_READY1_GPIO (FUNC(3) | PORTF(0, 21) | SE | VE | PE)
+#define GPMI_READY0 (FUNC(0) | PORTF(0, 20) | SE | VE | PE)
+#define GPMI_READY0_SSP1_CD (FUNC(1) | PORTF(0, 20) | SE | VE | PE)
+#define GPMI_READY0_USB0_ID (FUNC(2) | PORTF(0, 20) | SE | VE | PE)
+#define GPMI_READY0_GPIO (FUNC(3) | PORTF(0, 20) | SE | VE | PE)
+#define GPMI_CE3N (FUNC(0) | PORTF(0, 19) | SE | VE | PE)
+#define GPMI_CE3N_CAN1_RX (FUNC(1) | PORTF(0, 19) | SE | VE | PE)
+#define GPMI_CE3N_SAIF1_MCLK (FUNC(2) | PORTF(0, 19) | SE | VE | PE)
+#define GPMI_CE3N_GPIO (FUNC(3) | PORTF(0, 19) | SE | VE | PE)
+#define GPMI_CE2N (FUNC(0) | PORTF(0, 18) | SE | VE | PE)
+#define GPMI_CE2N_CAN1_TX (FUNC(1) | PORTF(0, 18) | SE | VE | PE)
+#define GPMI_CE2N_ENET0_RX_ER (FUNC(2) | PORTF(0, 18) | SE | VE | PE)
+#define GPMI_CE2N_GPIO (FUNC(3) | PORTF(0, 18) | SE | VE | PE)
+#define GPMI_CE1N (FUNC(0) | PORTF(0, 17) | SE | VE | PE)
+#define GPMI_CE1N_SSP3_D3 (FUNC(1) | PORTF(0, 17) | SE | VE | PE)
+#define GPMI_CE1N_GPIO (FUNC(3) | PORTF(0, 17) | SE | VE | PE)
+#define GPMI_CE0N (FUNC(0) | PORTF(0, 16) | SE | VE | PE)
+#define GPMI_CE0N_SSP3_D0 (FUNC(1) | PORTF(0, 16) | SE | VE | PE)
+#define GPMI_CE0N_GPIO (FUNC(3) | PORTF(0, 16) | SE | VE | PE)
+#define GPMI_D7 (FUNC(0) | PORTF(0, 7) | SE | VE | PE)
+#define GPMI_D7_SSP1_D7 (FUNC(1) | PORTF(0, 7) | SE | VE | PE)
+#define GPMI_D7_GPIO (FUNC(3) | PORTF(0, 7) | SE | VE | PE)
+#define GPMI_D6 (FUNC(0) | PORTF(0, 6) | SE | VE | PE)
+#define GPMI_D6_SSP1_D6 (FUNC(1) | PORTF(0, 6) | SE | VE | PE)
+#define GPMI_D6_GPIO (FUNC(3) | PORTF(0, 6) | SE | VE | PE)
+#define GPMI_D5 (FUNC(0) | PORTF(0, 5) | SE | VE | PE)
+#define GPMI_D5_SSP1_D5 (FUNC(1) | PORTF(0, 5) | SE | VE | PE)
+#define GPMI_D5_GPIO (FUNC(3) | PORTF(0, 5) | SE | VE | PE)
+#define GPMI_D4 (FUNC(0) | PORTF(0, 4) | SE | VE | PE)
+#define GPMI_D4_SSP1_D4 (FUNC(1) | PORTF(0, 4) | SE | VE | PE)
+#define GPMI_D4_GPIO (FUNC(3) | PORTF(0, 4) | SE | VE | PE)
+#define GPMI_D3 (FUNC(0) | PORTF(0, 3) | SE | VE | PE)
+#define GPMI_D3_SSP1_D3 (FUNC(1) | PORTF(0, 3) | SE | VE | PE)
+#define GPMI_D3_GPIO (FUNC(3) | PORTF(0, 3) | SE | VE | PE)
+#define GPMI_D2 (FUNC(0) | PORTF(0, 2) | SE | VE | PE)
+#define GPMI_D2_SSP1_D2 (FUNC(1) | PORTF(0, 2) | SE | VE | PE)
+#define GPMI_D2_GPIO (FUNC(3) | PORTF(0, 2) | SE | VE | PE)
+#define GPMI_D1 (FUNC(0) | PORTF(0, 1) | SE | VE | PE)
+#define GPMI_D1_SSP1_D1 (FUNC(1) | PORTF(0, 1) | SE | VE | PE)
+#define GPMI_D1_GPIO (FUNC(3) | PORTF(0, 1) | SE | VE | PE)
+#define GPMI_D0 (FUNC(0) | PORTF(0, 0) | SE | VE | PE)
+#define GPMI_D0_SSP1_D0 (FUNC(1) | PORTF(0, 0) | SE | VE | PE)
+#define GPMI_D0_GPIO (FUNC(3) | PORTF(0, 0) | SE | VE | PE)
+
+/* Bank 1, GPIO pins 32 ... 63 */
+
+#define LCD_ENABLE (FUNC(0) | PORTF(1, 31) | SE | VE | BK)
+#define LCD_ENABLE_GPIO (FUNC(3) | PORTF(1, 31) | SE | VE | BK)
+
+#define LCD_DOTCLK (FUNC(0) | PORTF(1, 30) | SE | VE | BK)
+
+#define LCD_HSYNC (FUNC(0) | PORTF(1, 29) | SE | VE | BK)
+
+#define LCD_VSYNC (FUNC(0) | PORTF(1, 28) | SE | VE | BK)
+
+#define LCD_CS (FUNC(0) | PORTF(1, 27) | SE | VE | BK)
+#define LCD_CS_LCD_ENABLE (FUNC(1) | PORTF(1, 27) | SE | VE | BK)
+#define LCD_CS_GPIO (FUNC(3) | PORTF(1, 27) | SE | VE | BK)
+
+#define LCD_RS (FUNC(0) | PORTF(1, 26) | SE | VE | BK)
+#define LCD_RS_LCD_DOTCLK (FUNC(1) | PORTF(1, 26) | SE | VE | BK)
+#define LCD_RS_GPIO (FUNC(3) | PORTF(1, 26) | SE | VE | BK)
+#define LCD_WR_RWN (FUNC(0) | PORTF(1, 25) | SE | VE | BK)
+#define LCD_WR_RWN_LCD_HSYNC (FUNC(1) | PORTF(1, 25) | SE | VE | BK)
+#define LCD_WR_RWN_ETM_TCLK (FUNC(2) | PORTF(1, 25) | SE | VE | BK)
+#define LCD_WR_RWN_GPIO (FUNC(3) | PORTF(1, 25) | SE | VE | BK)
+#define LCD_RD_E (FUNC(0) | PORTF(1, 24) | SE | VE | BK)
+#define LCD_RD_E_LCD_VSYNC (FUNC(1) | PORTF(1, 24) | SE | VE | BK)
+#define LCD_RD_E_ETM_TCTL (FUNC(2) | PORTF(1, 24) | SE | VE | BK)
+#define LCD_RD_E_GPIO (FUNC(3) | PORTF(1, 24) | SE | VE | BK)
+
+#define LCD_D23 (FUNC(0) | PORTF(1, 23) | SE | VE | BK)
+
+#define LCD_D22 (FUNC(0) | PORTF(1, 22) | SE | VE | BK)
+
+#define LCD_D21 (FUNC(0) | PORTF(1, 21) | SE | VE | BK)
+
+#define LCD_D20 (FUNC(0) | PORTF(1, 20) | SE | VE | BK)
+
+#define LCD_D19 (FUNC(0) | PORTF(1, 19) | SE | VE | BK)
+
+#define LCD_D18 (FUNC(0) | PORTF(1, 18) | SE | VE | BK)
+
+#define LCD_D17 (FUNC(0) | PORTF(1, 17) | SE | VE | BK)
+
+#define LCD_D16 (FUNC(0) | PORTF(1, 16) | SE | VE | BK)
+
+#define LCD_D15 (FUNC(0) | PORTF(1, 15) | SE | VE | BK)
+#define LCD_D15_ETM_DA15 (FUNC(2) | PORTF(1, 15) | SE | VE | BK)
+#define LCD_D15_GPIO (FUNC(3) | PORTF(1, 15) | SE | VE | BK)
+#define LCD_D14 (FUNC(0) | PORTF(1, 14) | SE | VE | BK)
+#define LCD_D14_ETM_DA14 (FUNC(2) | PORTF(1, 14) | SE | VE | BK)
+#define LCD_D14_GPIO (FUNC(3) | PORTF(1, 14) | SE | VE | BK)
+#define LCD_D13 (FUNC(0) | PORTF(1, 13) | SE | VE | BK)
+#define LCD_D13_ETM_DA13 (FUNC(2) | PORTF(1, 13) | SE | VE | BK)
+#define LCD_D13_GPIO (FUNC(3) | PORTF(1, 13) | SE | VE | BK)
+#define LCD_D12 (FUNC(0) | PORTF(1, 12) | SE | VE | BK)
+#define LCD_D12_ETM_DA12 (FUNC(2) | PORTF(1, 12) | SE | VE | BK)
+#define LCD_D12_GPIO (FUNC(3) | PORTF(1, 12) | SE | VE | BK)
+#define LCD_D11 (FUNC(0) | PORTF(1, 11) | SE | VE | BK)
+#define LCD_D11_ETM_DA11 (FUNC(2) | PORTF(1, 11) | SE | VE | BK)
+#define LCD_D11_GPIO (FUNC(3) | PORTF(1, 11) | SE | VE | BK)
+#define LCD_D10 (FUNC(0) | PORTF(1, 10) | SE | VE | BK)
+#define LCD_D10_ETM_DA10 (FUNC(2) | PORTF(1, 10) | SE | VE | BK)
+#define LCD_D10_GPIO (FUNC(3) | PORTF(1, 10) | SE | VE | BK)
+#define LCD_D9 (FUNC(0) | PORTF(1, 9) | SE | VE | BK)
+#define LCD_D9_ETM_DA4 (FUNC(1) | PORTF(1, 9) | SE | VE | BK)
+#define LCD_D9_ETM_DA9 (FUNC(2) | PORTF(1, 9) | SE | VE | BK)
+#define LCD_D9_GPIO (FUNC(3) | PORTF(1, 9) | SE | VE | BK)
+#define LCD_D8 (FUNC(0) | PORTF(1, 8) | SE | VE | BK)
+#define LCD_D8_ETM_DA3 (FUNC(1) | PORTF(1, 8) | SE | VE | BK)
+#define LCD_D8_ETM_DA8 (FUNC(2) | PORTF(1, 8) | SE | VE | BK)
+#define LCD_D8_GPIO (FUNC(3) | PORTF(1, 8) | SE | VE | BK)
+#define LCD_D7 (FUNC(0) | PORTF(1, 7) | SE | VE | BK)
+#define LCD_D7_ETM_DA7 (FUNC(2) | PORTF(1, 7) | SE | VE | BK)
+#define LCD_D7_GPIO (FUNC(3) | PORTF(1, 7) | SE | VE | BK)
+#define LCD_D6 (FUNC(0) | PORTF(1, 6) | SE | VE | BK)
+#define LCD_D6_ETM_DA6 (FUNC(2) | PORTF(1, 6) | SE | VE | BK)
+#define LCD_D6_GPIO (FUNC(3) | PORTF(1, 6) | SE | VE | BK)
+#define LCD_D5 (FUNC(0) | PORTF(1, 5) | SE | VE | BK)
+#define LCD_D5_ETM_DA5 (FUNC(2) | PORTF(1, 5) | SE | VE | BK)
+#define LCD_D5_GPIO (FUNC(3) | PORTF(1, 5) | SE | VE | BK)
+#define LCD_D4 (FUNC(0) | PORTF(1, 4) | SE | VE | BK)
+#define LCD_D4_ETM_DA9 (FUNC(1) | PORTF(1, 4) | SE | VE | BK)
+#define LCD_D4_ETM_DA4 (FUNC(2) | PORTF(1, 4) | SE | VE | BK)
+#define LCD_D4_GPIO (FUNC(3) | PORTF(1, 4) | SE | VE | BK)
+#define LCD_D3 (FUNC(0) | PORTF(1, 3) | SE | VE | BK)
+#define LCD_D3_ETM_DA8 (FUNC(1) | PORTF(1, 3) | SE | VE | BK)
+#define LCD_D3_ETM_DA3 (FUNC(2) | PORTF(1, 3) | SE | VE | BK)
+#define LCD_D3_GPIO (FUNC(3) | PORTF(1, 3) | SE | VE | BK)
+#define LCD_D2 (FUNC(0) | PORTF(1, 2) | SE | VE | BK)
+#define LCD_D2_ETM_DA2 (FUNC(2) | PORTF(1, 2) | SE | VE | BK)
+#define LCD_D2_GPIO (FUNC(3) | PORTF(1, 2) | SE | VE | BK)
+#define LCD_D1 (FUNC(0) | PORTF(1, 1) | SE | VE | BK)
+#define LCD_D1_ETM_DA1 (FUNC(2) | PORTF(1, 1) | SE | VE | BK)
+#define LCD_D1_GPIO (FUNC(3) | PORTF(1, 1) | SE | VE | BK)
+#define LCD_D0 (FUNC(0) | PORTF(1, 0) | SE | VE | BK)
+#define LCD_D0_ETM_DA0 (FUNC(2) | PORTF(1, 0) | SE | VE | BK)
+#define LCD_D0_GPIO (FUNC(3) | PORTF(1, 0) | SE | VE | BK)
+
+/* TODO */
+
+/* Bank 2, GPIO pins 64 ... 95 */
+
+/* TODO */
+
+#define SSP1_D3 (FUNC(0) | PORTF(2, 15) | SE | VE | PE)
+#define SSP1_D3_SSP2_D7 (FUNC(1) | PORTF(2, 15) | SE | VE | PE)
+#define SSP1_D3_ENET_1588_EVENT3_IN (FUNC(2) | PORTF(4, 15) | SE | VE | PE)
+#define SSP1_D3_GPIO (FUNC(3) | PORTF(2, 15) | SE | VE | PE)
+#define SSP1_D0 (FUNC(0) | PORTF(2, 14) | SE | VE | PE)
+#define SSP1_D0_SSP2_D6 (FUNC(1) | PORTF(2, 14) | SE | VE | PE)
+#define SSP1_D0_ENET_1588_EVENT3_OUT (FUNC(2) | PORTF(2, 14) | SE | VE | PE)
+#define SSP1_D0_GPIO (FUNC(3) | PORTF(2, 14) | SE | VE | PE)
+#define SSP1_CMD (FUNC(0) | PORTF(2, 13) | SE | VE | PE)
+#define SSP1_CMD_SSP2_D2 (FUNC(1) | PORTF(2, 13) | SE | VE | PE)
+#define SSP1_CMD_ENET_1588_EVENT2_IN (FUNC(2) | PORTF(2, 13) | SE | VE | PE)
+#define SSP1_CMD_GPIO (FUNC(3) | PORTF(2, 13) | SE | VE | PE)
+#define SSP1_SCK (FUNC(0) | PORTF(2, 12) | SE | VE | PE)
+#define SSP1_SCK_SSP2_D1 (FUNC(1) | PORTF(2, 12) | SE | VE | PE)
+#define SSP1_SCK_ENET_1588_EVENT2_OUT (FUNC(2) | PORTF(2, 12) | SE | VE | PE)
+#define SSP1_SCK_GPIO (FUNC(3) | PORTF(2, 12) | SE | VE | PE)
+#define SSP0_SCK (FUNC(0) | PORTF(2, 10) | SE | VE | BK)
+#define SSP0_SCK_GPIO (FUNC(3) | PORTF(2, 10) | SE | VE | BK)
+#define SSP0_CD (FUNC(0) | PORTF(2, 9) | SE | VE | PE)
+#define SSP0_CD_GPIO (FUNC(3) | PORTF(2, 9) | SE | VE | PE)
+#define SSP0_CMD (FUNC(0) | PORTF(2, 8) | SE | VE | PE)
+#define SSP0_CMD_GPIO (FUNC(3) | PORTF(2, 8) | SE | VE | PE)
+#define SSP0_D7 (FUNC(0) | PORTF(2, 7) | SE | VE | PE)
+#define SSP0_D7_SSP2_SCK (FUNC(1) | PORTF(2, 7) | SE | VE | PE)
+#define SSP0_D7_GPIO (FUNC(3) | PORTF(2, 7) | SE | VE | PE)
+#define SSP0_D6 (FUNC(0) | PORTF(2, 6) | SE | VE | PE)
+#define SSP0_D6_SSP2_CMD (FUNC(1) | PORTF(2, 6) | SE | VE | PE)
+#define SSP0_D6_GPIO (FUNC(3) | PORTF(2, 6) | SE | VE | PE)
+#define SSP0_D5 (FUNC(0) | PORTF(2, 5) | SE | VE | PE)
+#define SSP0_D5_SSP2_D3 (FUNC(1) | PORTF(2, 5) | SE | VE | PE)
+#define SSP0_D5_GPIO (FUNC(3) | PORTF(2, 5) | SE | VE | PE)
+#define SSP0_D4 (FUNC(0) | PORTF(2, 4) | SE | VE | PE)
+#define SSP0_D4_SSP2_D0 (FUNC(1) | PORTF(2, 4) | SE | VE | PE)
+#define SSP0_D4_GPIO (FUNC(3) | PORTF(2, 4) | SE | VE | PE)
+#define SSP0_D3 (FUNC(0) | PORTF(2, 3) | SE | VE | PE)
+#define SSP0_D3_GPIO (FUNC(3) | PORTF(2, 3) | SE | VE | PE)
+#define SSP0_D2 (FUNC(0) | PORTF(2, 2) | SE | VE | PE)
+#define SSP0_D2_GPIO (FUNC(3) | PORTF(2, 2) | SE | VE | PE)
+#define SSP0_D1 (FUNC(0) | PORTF(2, 1) | SE | VE | PE)
+#define SSP0_D1_GPIO (FUNC(3) | PORTF(2, 1) | SE | VE | PE)
+#define SSP0_D0 (FUNC(0) | PORTF(2, 0) | SE | VE | PE)
+#define SSP0_D0_GPIO (FUNC(3) | PORTF(2, 0) | SE | VE | PE)
+
+/* Bank 3, GPIO pins 96 ... 127 */
+
+#define LCD_RESET (FUNC(0) | PORTF(3, 30))
+#define LCD_RESET_LCD_VSYNC (FUNC(1) | PORTF(3, 30))
+#define LCD_RESET_GPIO (FUNC(3) | PORTF(3, 30))
+#define PWM4 (FUNC(0) | PORTF(3, 29))
+#define PWM4_GPIO (FUNC(3) | PORTF(3, 29))
+#define PWM3 (FUNC(0) | PORTF(3 28))
+#define PWM3_GPIO (FUNC(3) | PORTF(3, 28))
+
+#define PWM2 (FUNC(0) | PORTF(3, 18))
+
+#define PWM1 (FUNC(0) | PORTF(3, 17))
+
+#define PWM0 (FUNC(0) | PORTF(3, 16))
+#define PWM0_I2C1_SCL (FUNC(1) | PORTF(3, 16))
+#define PWM0_DUART_RX (FUNC(2) | PORTF(3, 16))
+#define PWM0_GPIO (FUNC(3) | PORTF(3, 16))
+#define AUART3_RTS (FUNC(0) | PORTF(3, 15) | SE | VE | BK)
+#define AUART3_RTS_CAN1_RX (FUNC(1) | PORTF(3, 15) | SE | VE | BK)
+#define AUART3_RTS_ENET0_1588_EVENT1_IN (FUNC(2) | PORTF(3, 15) | SE | VE | BK)
+#define AUART3_RTS_GPIO (FUNC(3) | PORTF(3, 15) | SE | VE | BK)
+#define AUART3_CTS (FUNC(0) | PORTF(3, 14) | SE | VE | BK | BK)
+#define AUART3_CTS_CAN1_TX (FUNC(1) | PORTF(3, 14) | SE | VE | BK)
+#define AUART3_CTS_ENET0_1588_EVENT1_OUT (FUNC(2) | PORTF(3, 14) | SE | VE | BK)
+#define AUART3_CTS_GPIO (FUNC(3) | PORTF(3, 14) | SE | VE | BK)
+#define AUART3_TX (FUNC(0) | PORTF(3, 13) | SE | VE | BK)
+#define AUART3_TX_CAN0_RX (FUNC(1) | PORTF(3, 13) | SE | VE | BK)
+#define AUART3_TX_ENET0_1588_EVENT0_IN (FUNC(2) | PORTF(3, 13) | SE | VE | BK)
+#define AUART3_TX_GPIO (FUNC(3) | PORTF(3, 13) | SE | VE | BK)
+#define AUART3_RX (FUNC(0) | PORTF(3, 12) | SE | VE | BK)
+#define AUART3_RX_CAN0_TX (FUNC(1) | PORTF(3, 12) | SE | VE | BK)
+#define AUART3_RX_ENET0_1588_EVENT0_OUT (FUNC(2) | PORTF(3, 12) | SE | VE | BK)
+#define AUART3_RX_GPIO (FUNC(3) | PORTF(3, 12) | SE | VE | BK)
+#define AUART2_RTS (FUNC(0) | PORTF(3, 11) | SE | VE | BK)
+#define AUART2_RTS_I2C1_SDA (FUNC(1) | PORTF(3, 11) | SE | VE | BK)
+#define AUART2_RTS_SAIF1_IRCLK (FUNC(2) | PORTF(3, 11) | SE | VE | BK)
+#define AUART2_RTS_GPIO (FUNC(3) | PORTF(3, 11) | SE | VE | BK)
+#define AUART2_CTS (FUNC(0) | PORTF(3, 10) | SE | VE | BK)
+#define AUART2_CTS_I2C1_SCL (FUNC(1) | PORTF(3, 10) | SE | VE | BK)
+#define AUART2_CTS_SAIF1_BITCLK (FUNC(2) | PORTF(3, 10) | SE | VE | BK)
+#define AUART2_CTS_GPIO (FUNC(3) | PORTF(3, 10) | SE | VE | BK)
+#define AUART2_TX (FUNC(0) | PORTF(3, 9) | SE | VE | PE)
+#define AUART2_TX_SSP3_D2 (FUNC(1) | PORTF(3, 9) | SE | VE | PE)
+#define AUART2_TX_SSP3_D5 (FUNC(2) | PORTF(3, 9) | SE | VE | PE)
+#define AUART2_TX_GPIO (FUNC(3) | PORTF(3, 9) | SE | VE | PE)
+#define AUART2_RX (FUNC(0) | PORTF(3, 8) | SE | VE | PE)
+#define AUART2_RX_SSP3_D1 (FUNC(1) | PORTF(3, 8) | SE | VE | PE)
+#define AUART2_RX_SSP3_D4 (FUNC(2) | PORTF(3, 8) | SE | VE | PE)
+#define AUART2_RX_GPIO (FUNC(3) | PORTF(3, 8) | SE | VE | PE)
+#define AUART1_RTS (FUNC(0) | PORTF(3, 7) | SE | VE | PE)
+#define AUART1_RTS_USB0_ID (FUNC(1) | PORTF(3, 7) | SE | VE | PE)
+#define AUART1_RTS_ROTARYB (FUNC(2) | PORTF(3, 7) | SE | VE | PE)
+#define AUART1_RTS_GPIO (FUNC(3) | PORTF(3, 7) | SE | VE | PE)
+#define AUART1_CTS (FUNC(0) | PORTF(3, 6) | SE | VE | PE)
+#define AUART1_CTS_USB0_OC (FUNC(1) | PORTF(3, 6) | SE | VE | PE)
+#define AUART1_CTS_ROTARYA (FUNC(2) | PORTF(3, 6) | SE | VE | PE)
+#define AUART1_CTS_GPIO (FUNC(3) | PORTF(3, 6) | SE | VE | PE)
+#define AUART1_TX (FUNC(0) | PORTF(3, 5) | SE | VE | BK)
+#define AUART1_TX_SSP3_CD (FUNC(1) | PORTF(3, 5) | SE | VE | BK)
+#define AUART1_TX_PWM1 (FUNC(2) | PORTF(3, 5) | SE | VE | BK)
+#define AUART1_TX_GPIO (FUNC(3) | PORTF(3, 5) | SE | VE | BK)
+#define AUART1_RX (FUNC(0) | PORTF(3, 4) | SE | VE | BK)
+#define AUART1_RX_SSP2_CD (FUNC(1) | PORTF(3, 4) | SE | VE | BK)
+#define AUART1_RX_PWM0 (FUNC(2) | PORTF(3, 4) | SE | VE | BK)
+#define AUART1_RX_GPIO (FUNC(3) | PORTF(3, 4) | SE | VE | BK)
+#define AUART0_RTS (FUNC(0) | PORTF(3, 3) | SE | VE | BK)
+#define AUART0_RTS_AUART4_TX (FUNC(1) | PORTF(3, 3) | SE | VE | BK)
+#define AUART0_RTS_DUART_TX (FUNC(2) | PORTF(3, 3) | SE | VE | BK)
+#define AUART0_RTS_GPIO (FUNC(3) | PORTF(3, 3) | SE | VE | BK)
+#define AUART0_CTS (FUNC(0) | PORTF(3, 2) | SE | VE | BK)
+#define AUART0_CTS_AUART4_RX (FUNC(1) | PORTF(3, 2) | SE | VE | BK)
+#define AUART0_CTS_DUART_RX (FUNC(2) | PORTF(3, 2) | SE | VE | BK)
+#define AUART0_CTS_GPIO (FUNC(3) | PORTF(3, 2) | SE | VE | BK)
+#define AUART0_TX (FUNC(0) | PORTF(3, 1) | SE | VE | BK)
+#define AUART0_TX_I2C0_SDA (FUNC(1) | PORTF(3, 1) | SE | VE | BK)
+#define AUART0_TX_DUART_RTS (FUNC(2) | PORTF(3, 1) | SE | VE | BK)
+#define AUART0_TX_GPIO (FUNC(3) | PORTF(3, 1) | SE | VE | BK)
+#define AUART0_RX (FUNC(0) | PORTF(3, 0) | SE | VE | BK)
+#define AUART0_RX_I2C0_SCL (FUNC(1) | PORTF(3, 0) | SE | VE | BK)
+#define AUART0_RX_DUART_CTS (FUNC(2) | PORTF(3, 0) | SE | VE | BK)
+#define AUART0_RX_GPIO (FUNC(3) | PORTF(3, 0) | SE | VE | BK)
+
+/* Bank 4, GPIO pins 128 ... 159 */
+
+#define JTAG_RTCK (FUNC(0) | PORTF(4, 20) | SE | VE | BK)
+#define JTAG_RTCK_GPIO (FUNC(3) | PORTF(4, 20) | SE | VE | BK)
+#define ENET_CLK (FUNC(0) | PORTF(4, 16) | SE | VE | BK)
+#define ENET_CLK_GPIO (FUNC(3) | PORTF(4, 16) | SE | VE | BK)
+
+#define ENET0_CRS (FUNC(0) | PORTF(4, 15) | SE | VE | BK)
+
+#define ENET0_COL (FUNC(0) | PORTF(4, 14) | SE | VE | BK)
+
+#define ENET0_RX_CLK (FUNC(0) | PORTF(4, 13) | SE | VE | BK)
+#define ENET0_RX_CLK_RX_ER (FUNC(1) | PORTF(4, 13) | SE | VE | BK)
+#define ENET0_RX_ENET0_1588_EVENT2_IN (FUNC(2) | PORTF(4, 13) | SE | VE | BK)
+#define ENET0_RX_CLK_GPIO (FUNC(3) | PORTF(4, 13) | SE | VE | BK)
+#define ENET0_TXD3 (FUNC(0) | PORTF(4, 12) | SE | VE | BK)
+#define ENET0_TXD3_ENET1_TXD1 (FUNC(1) | PORTF(4, 12) | SE | VE | BK)
+#define ENET0_TXD3_ENET0_1588_EVENT1_IN (FUNC(2) | PORTF(4, 12) | SE | VE | BK)
+#define ENET0_TXD3_GPIO (FUNC(3) | PORTF(4, 12) | SE | VE | BK)
+
+#define ENET0_TXD2 (FUNC(0) | PORTF(4, 11) | SE | VE | BK)
+
+#define ENET0_TXD2_GPIO (FUNC(3) | PORTF(4, 11) | SE | VE | BK)
+
+#define ENET0_RXD3 (FUNC(0) | PORTF(4, 10) | SE | VE | BK)
+#define ENET0_RXD3_ENET1_RXD1 (FUNC(1) | PORTF(4, 10) | SE | VE | BK)
+#define ENET0_RXD3_ENET0_1588_EVENT0_IN (FUNC(2) | PORTF(4, 10) | SE | VE | BK)
+#define ENET0_RXD3_GPIO (FUNC(3) | PORTF(4, 10) | SE | VE | BK)
+
+#define ENET0_RXD2 (FUNC(0) | PORTF(4, 9) | SE | VE | BK)
+
+#define ENET0_RXD2_GPIO (FUNC(3) | PORTF(4, 9) | SE | VE | BK)
+
+#define ENET0_TXD1 (FUNC(0) | PORTF(4, 8) | SE | VE | PE)
+
+#define ENET0_TXD1_GPIO (FUNC(3) | PORTF(4, 8) | SE | VE | PE)
+
+#define ENET0_TXD0 (FUNC(0) | PORTF(4, 7) | SE | VE | PE)
+
+#define ENET0_TXD0_GPIO (FUNC(3) | PORTF(4, 7) | SE | VE | PE)
+
+#define ENET0_TX_EN (FUNC(0) | PORTF(4, 6) | SE | VE | PE)
+
+#define ENET0_TX_EN_GPIO (FUNC(3) | PORTF(4, 6) | SE | VE | PE)
+
+#define ENET0_TX_CLK (FUNC(0) | PORTF(4, 5) | SE | VE | BK)
+
+#define ENET0_TX_CLK_GPIO (FUNC(3) | PORTF(4, 5) | SE | VE | BK)
+
+#define ENET0_RXD1 (FUNC(0) | PORTF(4, 4) | SE | VE | PE)
+#define ENET0_RXD1_GPMI_READY4 (FUNC(1) | PORTF(4, 4) | SE | VE | PE)
+#define ENET0_RXD1_GPIO (FUNC(3) | PORTF(4, 4) | SE | VE | PE)
+#define ENET0_RXD0 (FUNC(0) | PORTF(4, 3) | SE | VE | PE)
+#define ENET0_RXD0_GPMI_CE7N (FUNC(1) | PORTF(4, 3) | SE | VE | PE)
+#define ENET0_RXD0_SAIF1_SDATA2 (FUNC(2) | PORTF(4, 3) | SE | VE | PE)
+#define ENET0_RXD0_GPIO (FUNC(3) | PORTF(4, 3) | SE | VE | PE)
+#define ENET0_RX_EN (FUNC(0) | PORTF(4, 2) | SE | VE | PE)
+#define ENET0_RX_EN_GPMI_CE6N (FUNC(1) | PORTF(4, 2) | SE | VE | PE)
+#define ENET0_RX_EN_SAIF1_SDATA1 (FUNC(2) | PORTF(4, 2) | SE | VE | PE)
+#define ENET0_RX_EN_GPIO (FUNC(3) | PORTF(4, 2) | SE | VE | PE)
+#define ENET0_MDIO (FUNC(0) | PORTF(4, 1) | SE | VE | PE)
+#define ENET0_MDIO_GPMI_CE5N (FUNC(1) | PORTF(4, 1) | SE | VE | PE)
+#define ENET0_MDIO_SAIF0_SDATA2 (FUNC(2) | PORTF(4, 1) | SE | VE | PE)
+#define ENET0_MDIO_GPIO (FUNC(3) | PORTF(4, 1) | SE | VE | PE)
+#define ENET0_MDC (FUNC(0) | PORTF(4, 0) | SE | VE | PE)
+#define ENET0_MDC_GPMI_CE4N (FUNC(1) | PORTF(4, 0) | SE | VE | PE)
+#define ENET0_MDC_SAIF0_SDATA1 (FUNC(2) | PORTF(4, 0) | SE | VE | PE)
+#define ENET0_MDC_GPIO (FUNC(3) | PORTF(4, 0) | SE | VE | PE)
+
+/*
+ * Bank 5, GPIO pins 160 ... 191
+ * Note: These pins are disabled instead of being GPIOs
+ */
+#define EMI_DDR_OPEN (FUNC(0) | PORTF(5, 26) | BK)
+#define EMI_DDR_OPEN_OFF (FUNC(3) | PORTF(5, 26) | BK)
+#define EMI_DSQ1 (FUNC(0) | PORTF(5, 23) | BK)
+#define EMI_DSQ1_OFF (FUNC(3) | PORTF(5, 23) | BK)
+#define EMI_DSQ0 (FUNC(0) | PORTF(5, 22) | BK)
+#define EMI_DSQ0_OFF (FUNC(3) | PORTF(5, 22) | BK)
+#define EMI_CLK (FUNC(0) | PORTF(5, 21) | BK)
+#define EMI_CLK_OFF (FUNC(3) | PORTF(5, 21) | BK)
+#define EMI_DDR_OPEN_FB (FUNC(0) | PORTF(5, 20) | BK)
+#define EMI_DDR_OPEN_FB_OFF (FUNC(3) | PORTF(5, 20) | BK)
+#define EMI_DQM1 (FUNC(0) | PORTF(5, 19) | BK)
+#define EMI_DQM1_OFF (FUNC(3) | PORTF(5, 19) | BK)
+#define EMI_ODT1 (FUNC(0) | PORTF(5, 18) | BK)
+#define EMI_ODT1_OFF (FUNC(3) | PORTF(5, 18) | BK)
+#define EMI_DQM0 (FUNC(0) | PORTF(5, 17) | BK)
+#define EMI_DQM0_OFF (FUNC(3) | PORTF(5, 17) | BK)
+#define EMI_ODT0 (FUNC(0) | PORTF(5, 16) | BK)
+#define EMI_ODT0_OFF (FUNC(3) | PORTF(5, 16) | BK)
+#define EMI_DATA15 (FUNC(0) | PORTF(5, 15) | BK)
+#define EMI_DATA15_OFF (FUNC(3) | PORTF(5, 15) | BK)
+#define EMI_DATA14 (FUNC(0) | PORTF(5, 14) | BK)
+#define EMI_DATA14_OFF (FUNC(3) | PORTF(5, 14) | BK)
+#define EMI_DATA13 (FUNC(0) | PORTF(5, 13) | BK)
+#define EMI_DATA13_OFF (FUNC(3) | PORTF(5, 13) | BK)
+#define EMI_DATA12 (FUNC(0) | PORTF(5, 12) | BK)
+#define EMI_DATA12_OFF (FUNC(3) | PORTF(5, 12) | BK)
+#define EMI_DATA11 (FUNC(0) | PORTF(5, 11) | BK)
+#define EMI_DATA10_OFF (FUNC(3) | PORTF(5, 10) | BK)
+#define EMI_DATA10 (FUNC(0) | PORTF(5, 10) | BK)
+#define EMI_DATA10_OFF (FUNC(3) | PORTF(5, 10) | BK)
+#define EMI_DATA9 (FUNC(0) | PORTF(5, 9) | BK)
+#define EMI_DATA9_OFF (FUNC(3) | PORTF(5, 9) | BK)
+#define EMI_DATA8 (FUNC(0) | PORTF(5, 8) | BK)
+#define EMI_DATA8_OFF (FUNC(3) | PORTF(5, 8) | BK)
+#define EMI_DATA7 (FUNC(0) | PORTF(5, 7) | BK)
+#define EMI_DATA7_OFF (FUNC(3) | PORTF(5, 7) | BK)
+#define EMI_DATA6 (FUNC(0) | PORTF(5, 6) | BK)
+#define EMI_DATA6_OFF (FUNC(3) | PORTF(5, 6) | BK)
+#define EMI_DATA5 (FUNC(0) | PORTF(5, 5) | BK)
+#define EMI_DATA5_OFF (FUNC(3) | PORTF(5, 5) | BK)
+#define EMI_DATA4 (FUNC(0) | PORTF(5, 4) | BK)
+#define EMI_DATA4_OFF (FUNC(3) | PORTF(5, 4) | BK)
+#define EMI_DATA3 (FUNC(0) | PORTF(5, 3) | BK)
+#define EMI_DATA3_OFF (FUNC(3) | PORTF(5, 3) | BK)
+#define EMI_DATA2 (FUNC(0) | PORTF(5, 2) | BK)
+#define EMI_DATA2_OFF (FUNC(3) | PORTF(5, 2) | BK)
+#define EMI_DATA1 (FUNC(0) | PORTF(5, 1) | BK)
+#define EMI_DATA1_OFF (FUNC(3) | PORTF(5, 1) | BK)
+#define EMI_DATA0 (FUNC(0) | PORTF(5, 0) | BK)
+#define EMI_DATA0_OFF (FUNC(3) | PORTF(5, 0) | BK)
+
+/*
+ * Bank 6, GPIO pins 192 ... 223
+ * Note: This pins are disabled instead of being GPIOs
+ */
+#define EMI_CKE (FUNC(0) | PORTF(6, 24) | BK)
+#define EMI_CKE_OFF (FUNC(3) | PORTF(6, 24) | BK)
+#define EMI_CE1N (FUNC(0) | PORTF(6, 23) | BK)
+#define EMI_CE1N_OFF (FUNC(3) | PORTF(6, 23) | BK)
+#define EMI_CE0N (FUNC(0) | PORTF(6, 22) | BK)
+#define EMI_CE0N_OFF (FUNC(3) | PORTF(6, 22) | BK)
+#define EMI_WEN (FUNC(0) | PORTF(6, 21) | BK)
+#define EMI_WEN_OFF (FUNC(3) | PORTF(6, 21) | BK)
+#define EMI_RASN (FUNC(0) | PORTF(6, 20) | BK)
+#define EMI_RASN_OFF (FUNC(3) | PORTF(6, 20) | BK)
+#define EMI_CASN (FUNC(0) | PORTF(6, 19) | BK)
+#define EMI_CASN_OFF (FUNC(3) | PORTF(6, 19) | BK)
+#define EMI_BA2 (FUNC(0) | PORTF(6, 18) | BK)
+#define EMI_BA2_OFF (FUNC(3) | PORTF(6, 18) | BK)
+#define EMI_BA1 (FUNC(0) | PORTF(6, 17) | BK)
+#define EMI_BA1_OFF (FUNC(3) | PORTF(6, 17) | BK)
+#define EMI_BA0 (FUNC(0) | PORTF(6, 16) | BK)
+#define EMI_BA0_OFF (FUNC(3) | PORTF(6, 16) | BK)
+#define EMI_A14 (FUNC(0) | PORTF(6, 14) | BK)
+#define EMI_A14_OFF (FUNC(3) | PORTF(6, 14) | BK)
+#define EMI_A13 (FUNC(0) | PORTF(6, 13) | BK)
+#define EMI_A13_OFF (FUNC(3) | PORTF(6, 13) | BK)
+#define EMI_A12 (FUNC(0) | PORTF(6, 12) | BK)
+#define EMI_A12_OFF (FUNC(3) | PORTF(6, 12) | BK)
+#define EMI_A11 (FUNC(0) | PORTF(6, 11) | BK)
+#define EMI_A11_OFF (FUNC(3) | PORTF(6, 11) | BK)
+#define EMI_A10 (FUNC(0) | PORTF(6, 10) | BK)
+#define EMI_A10_OFF (FUNC(3) | PORTF(6, 10) | BK)
+#define EMI_A9 (FUNC(0) | PORTF(6, 9) | BK)
+#define EMI_A9_OFF (FUNC(3) | PORTF(6, 9) | BK)
+#define EMI_A8 (FUNC(0) | PORTF(6, 8) | BK)
+#define EMI_A8_OFF (FUNC(3) | PORTF(6, 8) | BK)
+#define EMI_A7 (FUNC(0) | PORTF(6, 7) | BK)
+#define EMI_A7_OFF (FUNC(3) | PORTF(6, 7) | BK)
+#define EMI_A6 (FUNC(0) | PORTF(6, 6) | BK)
+#define EMI_A6_OFF (FUNC(3) | PORTF(6, 6) | BK)
+#define EMI_A5 (FUNC(0) | PORTF(6, 5) | BK)
+#define EMI_A5_OFF (FUNC(3) | PORTF(6, 5) | BK)
+#define EMI_A4 (FUNC(0) | PORTF(6, 4) | BK)
+#define EMI_A4_OFF (FUNC(3) | PORTF(6, 4) | BK)
+#define EMI_A3 (FUNC(0) | PORTF(6, 3) | BK)
+#define EMI_A3_OFF (FUNC(3) | PORTF(6, 3) | BK)
+#define EMI_A2 (FUNC(0) | PORTF(6, 2) | BK)
+#define EMI_A2_OFF (FUNC(3) | PORTF(6, 2) | BK)
+#define EMI_A1 (FUNC(0) | PORTF(6, 1) | BK)
+#define EMI_A1_OFF (FUNC(3) | PORTF(6, 1) | BK)
+#define EMI_A0 (FUNC(0) | PORTF(6, 0) | BK)
+#define EMI_A0_OFF (FUNC(3) | PORTF(6, 0) | BK)
+
+#endif /* __MACH_IOMUX_IMX28_H */
diff --git a/arch/arm/mach-stm/iomux-imx23.c b/arch/arm/mach-stm/iomux-imx.c
index b0f4046e30..bf6165f8d2 100644
--- a/arch/arm/mach-stm/iomux-imx23.c
+++ b/arch/arm/mach-stm/iomux-imx.c
@@ -20,53 +20,76 @@
#include <common.h>
#include <init.h>
#include <gpio.h>
+#include <errno.h>
#include <asm/io.h>
#include <mach/imx-regs.h>
#define HW_PINCTRL_CTRL 0x000
#define HW_PINCTRL_MUXSEL0 0x100
+
+#ifdef CONFIG_ARCH_IMX23
#define HW_PINCTRL_DRIVE0 0x200
#define HW_PINCTRL_PULL0 0x400
#define HW_PINCTRL_DOUT0 0x500
#define HW_PINCTRL_DIN0 0x600
#define HW_PINCTRL_DOE0 0x700
-static uint32_t calc_mux_reg(uint32_t no)
+#define MAX_GPIO_NO 95
+#endif
+
+#ifdef CONFIG_ARCH_IMX28
+#define HW_PINCTRL_DRIVE0 0x300
+#define HW_PINCTRL_PULL0 0x600
+#define HW_PINCTRL_DOUT0 0x700
+#define HW_PINCTRL_DIN0 0x900
+#define HW_PINCTRL_DOE0 0xb00
+
+#define MAX_GPIO_NO 159
+#endif
+
+static unsigned calc_mux_reg(unsigned no)
{
/* each register controls 16 pads */
return ((no >> 4) << 4) + HW_PINCTRL_MUXSEL0;
}
-static uint32_t calc_strength_reg(uint32_t no)
+static unsigned calc_strength_reg(unsigned no)
{
/* each register controls 8 pads */
return ((no >> 3) << 4) + HW_PINCTRL_DRIVE0;
}
-static uint32_t calc_pullup_reg(uint32_t no)
+static unsigned calc_pullup_reg(unsigned no)
{
/* each register controls 32 pads */
return ((no >> 5) << 4) + HW_PINCTRL_PULL0;
}
-static uint32_t calc_output_enable_reg(uint32_t no)
+static unsigned calc_output_enable_reg(unsigned no)
{
/* each register controls 32 pads */
return ((no >> 5) << 4) + HW_PINCTRL_DOE0;
}
-static uint32_t calc_output_reg(uint32_t no)
+static unsigned calc_output_reg(unsigned no)
{
/* each register controls 32 pads */
return ((no >> 5) << 4) + HW_PINCTRL_DOUT0;
}
+static unsigned calc_input_reg(unsigned no)
+{
+ /* each register controls 32 pads */
+ return ((no >> 5) << 4) + HW_PINCTRL_DIN0;
+}
+
/**
- * @param[in] m One of the defines from iomux-mx23.h to configure *one* pin
+ * @param[in] m One pin define per call from iomux-mx23.h/iomux-mx28.h
*/
-void imx_gpio_mode(unsigned m)
+void imx_gpio_mode(uint32_t m)
{
- uint32_t reg_offset, gpio_pin, reg;
+ uint32_t reg;
+ unsigned gpio_pin, reg_offset;
gpio_pin = GET_GPIO_NO(m);
@@ -77,7 +100,7 @@ void imx_gpio_mode(unsigned m)
writel(reg, IMX_IOMUXC_BASE + reg_offset);
/* some pins are disabled when configured for GPIO */
- if ((gpio_pin > 95) && (GET_FUNC(m) == IS_GPIO)) {
+ if ((gpio_pin > MAX_GPIO_NO) && (GET_FUNC(m) == IS_GPIO)) {
printf("Cannot configure pad %d to GPIO\n", gpio_pin);
return;
}
@@ -92,26 +115,87 @@ void imx_gpio_mode(unsigned m)
if (VE_PRESENT(m)) {
reg_offset = calc_strength_reg(gpio_pin);
if (GET_VOLTAGE(m) == 1)
- writel(0x1 << (((gpio_pin % 8) << 2) + 2), IMX_IOMUXC_BASE + reg_offset + 4);
+ writel(0x1 << (((gpio_pin % 8) << 2) + 2),
+ IMX_IOMUXC_BASE + reg_offset + BIT_SET);
else
- writel(0x1 << (((gpio_pin % 8) << 2) + 2), IMX_IOMUXC_BASE + reg_offset + 8);
+ writel(0x1 << (((gpio_pin % 8) << 2) + 2),
+ IMX_IOMUXC_BASE + reg_offset + BIT_CLR);
}
if (PE_PRESENT(m)) {
reg_offset = calc_pullup_reg(gpio_pin);
- writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset + (GET_PULLUP(m) == 1 ? 4 : 8));
+ writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset +
+ (GET_PULLUP(m) == 1 ? BIT_SET : BIT_CLR));
}
if (GET_FUNC(m) == IS_GPIO) {
if (GET_GPIODIR(m) == 1) {
/* first set the output value */
reg_offset = calc_output_reg(gpio_pin);
- writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset + (GET_GPIOVAL(m) == 1 ? 4 : 8));
+ writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE +
+ reg_offset + (GET_GPIOVAL(m) == 1 ? BIT_SET : BIT_CLR));
/* then the direction */
reg_offset = calc_output_enable_reg(gpio_pin);
- writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset + 4);
+ writel(0x1 << (gpio_pin % 32),
+ IMX_IOMUXC_BASE + reg_offset + BIT_SET);
} else {
- writel(0x1 << (gpio_pin % 32), IMX_IOMUXC_BASE + reg_offset + 8);
+ /* then the direction */
+ reg_offset = calc_output_enable_reg(gpio_pin);
+ writel(0x1 << (gpio_pin % 32),
+ IMX_IOMUXC_BASE + reg_offset + BIT_CLR);
}
}
}
+
+int gpio_direction_input(unsigned gpio)
+{
+ unsigned reg_offset;
+
+ if (gpio > MAX_GPIO_NO)
+ return -EINVAL;
+
+ reg_offset = calc_output_enable_reg(gpio);
+ writel(0x1 << (gpio % 32), IMX_IOMUXC_BASE + reg_offset + BIT_CLR);
+
+ return 0;
+}
+
+int gpio_direction_output(unsigned gpio, int val)
+{
+ unsigned reg_offset;
+
+ if (gpio > MAX_GPIO_NO)
+ return -EINVAL;
+
+ /* first set the output value... */
+ reg_offset = calc_output_reg(gpio);
+ writel(0x1 << (gpio % 32), IMX_IOMUXC_BASE +
+ reg_offset + (val != 0 ? BIT_SET : BIT_CLR));
+ /* ...then the direction */
+ reg_offset = calc_output_enable_reg(gpio);
+ writel(0x1 << (gpio % 32), IMX_IOMUXC_BASE + reg_offset + BIT_SET);
+
+ return 0;
+}
+
+void gpio_set_value(unsigned gpio, int val)
+{
+ unsigned reg_offset;
+
+ reg_offset = calc_output_reg(gpio);
+ writel(0x1 << (gpio % 32), IMX_IOMUXC_BASE +
+ reg_offset + (val != 0 ? BIT_SET : BIT_CLR));
+}
+
+int gpio_get_value(unsigned gpio)
+{
+ uint32_t reg;
+ unsigned reg_offset;
+
+ reg_offset = calc_input_reg(gpio);
+ reg = readl(IMX_IOMUXC_BASE + reg_offset);
+ if (reg & (0x1 << (gpio % 32)))
+ return 1;
+
+ return 0;
+}
diff --git a/arch/arm/mach-stm/reset-imx23.c b/arch/arm/mach-stm/reset-imx.c
index b35f796b40..b35f796b40 100644
--- a/arch/arm/mach-stm/reset-imx23.c
+++ b/arch/arm/mach-stm/reset-imx.c
diff --git a/arch/arm/mach-stm/speed-imx23.c b/arch/arm/mach-stm/speed-imx23.c
index 7418ad57dd..a31139d7a7 100644
--- a/arch/arm/mach-stm/speed-imx23.c
+++ b/arch/arm/mach-stm/speed-imx23.c
@@ -29,8 +29,6 @@
#include <mach/generic.h>
#include <mach/clock.h>
-/* Note: all clock frequencies are returned in kHz */
-
#define HW_CLKCTRL_PLLCTRL0 0x000
#define HW_CLKCTRL_PLLCTRL1 0x010
#define HW_CLKCTRL_CPU 0x20
@@ -84,13 +82,13 @@
unsigned imx_get_mpllclk(void)
{
/* the main PLL runs at 480 MHz */
- return 480U * 1000U;
+ return 480000000;
}
unsigned imx_get_xtalclk(void)
{
/* the external reference runs at 24 MHz */
- return 24U * 1000U;
+ return 24000000;
}
/* used for the SDRAM controller */
@@ -105,14 +103,15 @@ unsigned imx_get_emiclk(void)
if (readl(IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ) & CLKCTRL_CLKSEQ_BYPASS_EMI)
return imx_get_xtalclk() / GET_EMI_XTAL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_EMI));
- rate = imx_get_mpllclk();
+ rate = imx_get_mpllclk() / 1000;
reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC);
if (!(reg & CLKCTRL_FRAC_CLKGATEEMI)) {
rate *= 18U;
rate /= GET_EMIFRAC(reg);
}
- return rate / GET_EMI_PLL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_EMI));
+ return (rate / GET_EMI_PLL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_EMI)))
+ * 1000;
}
/*
@@ -121,7 +120,7 @@ unsigned imx_get_emiclk(void)
unsigned imx_get_ioclk(void)
{
uint32_t reg;
- unsigned rate = imx_get_mpllclk();
+ unsigned rate = imx_get_mpllclk() / 1000;
reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC);
if (reg & CLKCTRL_FRAC_CLKGATEIO)
@@ -129,12 +128,12 @@ unsigned imx_get_ioclk(void)
rate *= 18U;
rate /= GET_IOFRAC(reg);
- return rate;
+ return rate * 1000;
}
/**
* Setup a new frequency to the IOCLK domain.
- * @param nc New frequency in [kHz]
+ * @param nc New frequency in [Hz]
*
* The FRAC divider for the IOCLK must be between 18 (* 18/18) and 35 (* 18/35)
*/
@@ -143,10 +142,9 @@ unsigned imx_set_ioclk(unsigned nc)
uint32_t reg;
unsigned div;
- div = imx_get_mpllclk();
- div *= 18U;
- div += nc >> 1;
- div /= nc;
+ nc /= 1000;
+ div = (imx_get_mpllclk() / 1000) * 18;
+ div = DIV_ROUND_CLOSEST(div, nc);
if (div > 0x3f)
div = 0x3f;
/* mask the current settings */
@@ -171,24 +169,25 @@ unsigned imx_get_armclk(void)
if (reg & CLKCTRL_FRAC_CLKGATECPU)
return 0U; /* should not possible, shouldn't it? */
- rate = imx_get_mpllclk();
+ rate = imx_get_mpllclk() / 1000;
rate *= 18U;
rate /= GET_CPUFRAC(reg);
- return rate / GET_CPU_PLL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_CPU));
+ return (rate / GET_CPU_PLL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_CPU)))
+ * 1000;
}
/* this is the AHB and APBH bus clock */
unsigned imx_get_hclk(void)
{
- unsigned rate = imx_get_armclk();
+ unsigned rate = imx_get_armclk() / 1000;
if (readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x20) {
rate *= readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x1f;
rate >>= 5U; /* / 32 */
} else
rate /= readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x1f;
- return rate;
+ return rate * 1000;
}
/*
@@ -219,7 +218,7 @@ unsigned imx_get_sspclk(unsigned index)
/**
* @param index Unit index (ignored on i.MX23)
- * @param nc New frequency in [kHz]
+ * @param nc New frequency in [Hz]
* @param high != 0 if ioclk should be the source
* @return The new possible frequency in [kHz]
*/
@@ -244,8 +243,7 @@ unsigned imx_set_sspclk(unsigned index, unsigned nc, int high)
printf("Cannot setup SSP unit clock to %u Hz, base clock is only %u Hz\n", nc, ssp_div);
ssp_div = 1U;
} else {
- ssp_div += nc - 1U;
- ssp_div /= nc;
+ ssp_div = DIV_ROUND_UP(ssp_div, nc);
if (ssp_div > CLKCTRL_SSP_DIV_MASK)
ssp_div = CLKCTRL_SSP_DIV_MASK;
}
@@ -270,11 +268,11 @@ unsigned imx_set_sspclk(unsigned index, unsigned nc, int high)
void imx_dump_clocks(void)
{
- printf("mpll: %10u kHz\n", imx_get_mpllclk());
- printf("arm: %10u kHz\n", imx_get_armclk());
- printf("ioclk: %10u kHz\n", imx_get_ioclk());
- printf("emiclk: %10u kHz\n", imx_get_emiclk());
- printf("hclk: %10u kHz\n", imx_get_hclk());
- printf("xclk: %10u kHz\n", imx_get_xclk());
- printf("ssp: %10u kHz\n", imx_get_sspclk(0));
+ printf("mpll: %10u kHz\n", imx_get_mpllclk() / 1000);
+ printf("arm: %10u kHz\n", imx_get_armclk() / 1000);
+ printf("ioclk: %10u kHz\n", imx_get_ioclk() / 1000);
+ printf("emiclk: %10u kHz\n", imx_get_emiclk() / 1000);
+ printf("hclk: %10u kHz\n", imx_get_hclk() / 1000);
+ printf("xclk: %10u kHz\n", imx_get_xclk() / 1000);
+ printf("ssp: %10u kHz\n", imx_get_sspclk(0) / 1000);
}
diff --git a/arch/arm/mach-stm/speed-imx28.c b/arch/arm/mach-stm/speed-imx28.c
new file mode 100644
index 0000000000..63c6b0754b
--- /dev/null
+++ b/arch/arm/mach-stm/speed-imx28.c
@@ -0,0 +1,392 @@
+/*
+ * (C) Copyright 2010 Juergen Beisert - Pengutronix <kernel@pengutronix.de>
+ *
+ * This code is based partially on code that has:
+ *
+ * (c) 2008 Embedded Alley Solutions, Inc.
+ * (C) Copyright 2009-2010 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <common.h>
+#include <init.h>
+#include <asm/io.h>
+#include <mach/imx-regs.h>
+#include <mach/generic.h>
+#include <mach/clock.h>
+
+#define HW_CLKCTRL_PLL0CTRL0 0x000
+#define HW_CLKCTRL_PLL0CTRL1 0x010
+#define HW_CLKCTRL_PLL1CTRL0 0x020
+#define HW_CLKCTRL_PLL1CTRL1 0x030
+#define HW_CLKCTRL_PLL2CTRL0 0x040
+# define CLKCTRL_PLL2CTRL0_CLKGATE (1 << 31)
+# define CLKCTRL_PLL2CTRL0_POWER (1 << 23)
+#define HW_CLKCTRL_CPU 0x50
+# define GET_CPU_XTAL_DIV(x) (((x) >> 16) & 0x3ff)
+# define GET_CPU_PLL_DIV(x) ((x) & 0x3f)
+#define HW_CLKCTRL_HBUS 0x60
+#define HW_CLKCTRL_XBUS 0x70
+#define HW_CLKCTRL_XTAL 0x080
+#define HW_CLKCTRL_SSP0 0x090
+#define HW_CLKCTRL_SSP1 0x0a0
+#define HW_CLKCTRL_SSP2 0x0b0
+#define HW_CLKCTRL_SSP3 0x0c0
+/* note: no set/clear register! */
+# define CLKCTRL_SSP_CLKGATE (1 << 31)
+# define CLKCTRL_SSP_BUSY (1 << 29)
+# define CLKCTRL_SSP_DIV_FRAC_EN (1 << 9)
+# define CLKCTRL_SSP_DIV_MASK 0x1ff
+# define GET_SSP_DIV(x) ((x) & CLKCTRL_SSP_DIV_MASK)
+# define SET_SSP_DIV(x) ((x) & CLKCTRL_SSP_DIV_MASK)
+#define HW_CLKCTRL_GPMI 0x0d0
+/* note: no set/clear register! */
+#define HW_CLKCTRL_SPDIF 0x0e0
+/* note: no set/clear register! */
+#define HW_CLKCTRL_EMI 0xf0
+/* note: no set/clear register! */
+# define CLKCTRL_EMI_CLKGATE (1 << 31)
+# define GET_EMI_XTAL_DIV(x) (((x) >> 8) & 0xf)
+# define GET_EMI_PLL_DIV(x) ((x) & 0x3f)
+#define HW_CLKCTRL_SAIF0 0x100
+#define HW_CLKCTRL_SAIF1 0x110
+#define HW_CLKCTRL_DIS_LCDIF 0x120
+# define CLKCTRL_DIS_LCDIF_GATE (1 << 31)
+# define CLKCTRL_DIS_LCDIF_BUSY (1 << 29)
+# define SET_DIS_LCDIF_DIV(x) ((x) & 0x1fff)
+# define GET_DIS_LCDIF_DIV(x) ((x) & 0x1fff)
+#define HW_CLKCTRL_ETM 0x130
+#define HW_CLKCTRL_ENET 0x140
+# define SET_CLKCTRL_ENET_DIV(x) (((x) & 0x3f) << 21)
+# define SET_CLKCTRL_ENET_SEL(x) (((x) & 0x3) << 19)
+# define CLKCTRL_ENET_CLK_OUT_EN (1 << 18)
+#define HW_CLKCTRL_HSADC 0x150
+#define HW_CLKCTRL_FLEXCAN 0x160
+#define HW_CLKCTRL_FRAC0 0x1b0
+# define CLKCTRL_FRAC_CLKGATEIO0 (1 << 31)
+# define GET_IO0FRAC(x) (((x) >> 24) & 0x3f)
+# define SET_IO0FRAC(x) (((x) & 0x3f) << 24)
+# define CLKCTRL_FRAC_CLKGATEIO1 (1 << 23)
+# define GET_IO1FRAC(x) (((x) >> 16) & 0x3f)
+# define SET_IO1FRAC(x) (((x) & 0x3f) << 16)
+# define CLKCTRL_FRAC_CLKGATEEMI (1 << 15)
+# define GET_EMIFRAC(x) (((x) >> 8) & 0x3f)
+# define CLKCTRL_FRAC_CLKGATECPU (1 << 7)
+# define GET_CPUFRAC(x) ((x) & 0x3f)
+#define HW_CLKCTRL_FRAC1 0x1c0
+# define CLKCTRL_FRAC_CLKGATEGPMI (1 << 23)
+# define GET_GPMIFRAC(x) (((x) >> 16) & 0x3f)
+# define CLKCTRL_FRAC_CLKGATEHSADC (1 << 15)
+# define GET_HSADCFRAC(x) (((x) >> 8) & 0x3f)
+# define CLKCTRL_FRAC_CLKGATEPIX (1 << 7)
+# define GET_PIXFRAC(x) ((x) & 0x3f)
+# define SET_PIXFRAC(x) ((x) & 0x3f)
+#define HW_CLKCTRL_CLKSEQ 0x1d0
+# define CLKCTRL_CLKSEQ_BYPASS_CPU (1 << 18)
+# define CLKCTRL_CLKSEQ_BYPASS_DIS_LCDIF (1 << 14)
+# define CLKCTRL_CLKSEQ_BYPASS_ETM (1 << 8)
+# define CLKCTRL_CLKSEQ_BYPASS_EMI (1 << 7)
+# define CLKCTRL_CLKSEQ_BYPASS_SSP3 (1 << 6)
+# define CLKCTRL_CLKSEQ_BYPASS_SSP2 (1 << 5)
+# define CLKCTRL_CLKSEQ_BYPASS_SSP1 (1 << 4)
+# define CLKCTRL_CLKSEQ_BYPASS_SSP0 (1 << 3)
+# define CLKCTRL_CLKSEQ_BYPASS_GPMI (1 << 2)
+# define CLKCTRL_CLKSEQ_BYPASS_SAIF1 (1 << 1)
+# define CLKCTRL_CLKSEQ_BYPASS_SAIF0 (1 << 0)
+#define HW_CLKCTRL_RESET 0x1e0
+#define HW_CLKCTRL_STATUS 0x1f0
+#define HW_CLKCTRL_VERSION 0x200
+
+unsigned imx_get_mpllclk(void)
+{
+ /* the main PLL runs at 480 MHz */
+ return 480000000;
+}
+
+unsigned imx_get_xtalclk(void)
+{
+ /* the external reference runs at 24 MHz */
+ return 24000000;
+}
+
+unsigned imx_get_fecclk(void)
+{
+ /* this PLL always runs at 50 MHz */
+ return 50000000;
+}
+
+
+/* used for the SDRAM controller */
+unsigned imx_get_emiclk(void)
+{
+ uint32_t reg;
+ unsigned rate;
+
+ if (readl(IMX_CCM_BASE + HW_CLKCTRL_EMI) & CLKCTRL_EMI_CLKGATE)
+ return 0; /* clock is off */
+
+ if (readl(IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ) & CLKCTRL_CLKSEQ_BYPASS_EMI)
+ return imx_get_xtalclk() /
+ GET_EMI_XTAL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_EMI));
+
+ rate = imx_get_mpllclk() / 1000;
+ reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC0);
+ if (!(reg & CLKCTRL_FRAC_CLKGATEEMI)) {
+ rate *= 18;
+ rate /= GET_EMIFRAC(reg);
+ }
+
+ return (rate / GET_EMI_PLL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_EMI)))
+ * 1000;
+}
+
+/*
+ * Source of ssp, gpmi, ir
+ * @param index 0 or 1 for ioclk0 or ioclock1
+ */
+unsigned imx_get_ioclk(unsigned index)
+{
+ uint32_t reg;
+ unsigned rate = imx_get_mpllclk() / 1000;
+
+ reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC0);
+ switch (index) {
+ case 0:
+ if (reg & CLKCTRL_FRAC_CLKGATEIO0)
+ return 0; /* clock is off */
+
+ rate *= 18;
+ rate /= GET_IO0FRAC(reg);
+ break;
+ case 1:
+ if (reg & CLKCTRL_FRAC_CLKGATEIO1)
+ return 0; /* clock is off */
+
+ rate *= 18;
+ rate /= GET_IO1FRAC(reg);
+ break;
+ }
+
+ return rate * 1000;
+}
+
+/**
+ * Setup a new frequency to the IOCLK domain.
+ * @param index 0 or 1 for ioclk0 or ioclock1
+ * @param nc New frequency in [Hz]
+ *
+ * The FRAC divider for the IOCLK must be between 18 (* 18/18) and 35 (* 18/35)
+ *
+ * ioclock0 is the shared clock source of SSP0/SSP1, ioclock1 the shared clock
+ * source of SSP2/SSP3
+ */
+unsigned imx_set_ioclk(unsigned index, unsigned nc)
+{
+ uint32_t reg;
+ unsigned div;
+
+ nc /= 1000;
+ div = (imx_get_mpllclk() / 1000) * 18;
+ div = DIV_ROUND_CLOSEST(div, nc);
+ if (div > 0x3f)
+ div = 0x3f;
+
+ switch (index) {
+ case 0:
+ reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC0) &
+ ~(SET_IO0FRAC(0x3f));
+ /* mask the current settings */
+ writel(reg | SET_IO0FRAC(div), IMX_CCM_BASE + HW_CLKCTRL_FRAC0);
+ /* enable the IO clock at its new frequency */
+ writel(CLKCTRL_FRAC_CLKGATEIO0,
+ IMX_CCM_BASE + HW_CLKCTRL_FRAC0 + BIT_CLR);
+ break;
+ case 1:
+ reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC0) &
+ ~(SET_IO1FRAC(0x3f));
+ /* mask the current settings */
+ writel(reg | SET_IO1FRAC(div), IMX_CCM_BASE + HW_CLKCTRL_FRAC0);
+ /* enable the IO clock at its new frequency */
+ writel(CLKCTRL_FRAC_CLKGATEIO1,
+ IMX_CCM_BASE + HW_CLKCTRL_FRAC0 + BIT_CLR);
+ break;
+ }
+
+ return imx_get_ioclk(index);
+}
+
+/* this is CPU core clock */
+unsigned imx_get_armclk(void)
+{
+ uint32_t reg;
+ unsigned rate;
+
+ if (readl(IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ) & CLKCTRL_CLKSEQ_BYPASS_CPU)
+ return imx_get_xtalclk() /
+ GET_CPU_XTAL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_CPU));
+
+ reg = readl(IMX_CCM_BASE + HW_CLKCTRL_FRAC0);
+ if (reg & CLKCTRL_FRAC_CLKGATECPU)
+ return 0; /* should not possible, shouldn't it? */
+
+ rate = (imx_get_mpllclk() / 1000) * 18;
+ rate /= GET_CPUFRAC(reg);
+
+ return (rate / GET_CPU_PLL_DIV(readl(IMX_CCM_BASE + HW_CLKCTRL_CPU)))
+ * 1000;
+}
+
+/* this is the AHB and APBH bus clock */
+unsigned imx_get_hclk(void)
+{
+ unsigned rate = imx_get_armclk() / 1000;
+
+ if (readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x20) {
+ rate *= readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x1f;
+ rate /= 32;
+ } else
+ rate /= readl(IMX_CCM_BASE + HW_CLKCTRL_HBUS) & 0x1f;
+ return rate * 1000;
+}
+
+/*
+ * Source of UART, debug UART, audio, PWM, dri, timer, digctl
+ */
+unsigned imx_get_xclk(void)
+{
+ /* runs from the 24 MHz crystal reference */
+ unsigned rate = imx_get_xtalclk();
+
+ return rate / (readl(IMX_CCM_BASE + HW_CLKCTRL_XBUS) & 0x3ff);
+}
+
+/**
+ * @param index The SSP unit (0...3)
+ */
+unsigned imx_get_sspclk(unsigned index)
+{
+ unsigned rate, offset, shift, ioclk_index;
+
+ if (index > 3) {
+ pr_debug("Unknown SSP unit: %u\n", index);
+ return 0;
+ }
+
+ ioclk_index = index >> 1;
+
+ offset = HW_CLKCTRL_SSP0 + (0x10 * index);
+ shift = CLKCTRL_CLKSEQ_BYPASS_SSP0 << index;
+
+ if (readl(IMX_CCM_BASE + offset) & CLKCTRL_SSP_CLKGATE)
+ return 0; /* clock is off */
+
+ if (readl(IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ) & shift)
+ rate = imx_get_xtalclk();
+ else
+ rate = imx_get_ioclk(ioclk_index);
+
+ return rate / GET_SSP_DIV(readl(IMX_CCM_BASE + offset));
+}
+
+/**
+ * @param index The SSP unit (0...3)
+ * @param nc New frequency in [Hz]
+ * @param high != 0 if ioclk should be the source
+ * @return The new possible frequency
+ */
+unsigned imx_set_sspclk(unsigned index, unsigned nc, int high)
+{
+ uint32_t reg;
+ unsigned ssp_div, offset, shift, ioclk_index;
+
+ if (index > 3) {
+ pr_debug("Unknown SSP unit: %u\n", index);
+ return 0;
+ }
+
+ ioclk_index = index >> 1;
+
+ offset = HW_CLKCTRL_SSP0 + (0x10 * index);
+ shift = CLKCTRL_CLKSEQ_BYPASS_SSP0 << index;
+
+ reg = readl(IMX_CCM_BASE + offset) & ~CLKCTRL_SSP_CLKGATE;
+ /* Datasheet says: Do not change the DIV setting if the clock is off */
+ writel(reg, IMX_CCM_BASE + offset);
+ /* Wait while clock is gated */
+ while (readl(IMX_CCM_BASE + offset) & CLKCTRL_SSP_CLKGATE)
+ ;
+
+ if (high)
+ ssp_div = imx_get_ioclk(ioclk_index);
+ else
+ ssp_div = imx_get_xtalclk();
+
+ if (nc > ssp_div) {
+ printf("Cannot setup SSP unit clock to %u kHz, base clock is "
+ "only %u kHz\n", nc, ssp_div);
+ ssp_div = 1;
+ } else {
+ ssp_div = DIV_ROUND_UP(ssp_div, nc);
+ if (ssp_div > CLKCTRL_SSP_DIV_MASK)
+ ssp_div = CLKCTRL_SSP_DIV_MASK;
+ }
+
+ /* Set new divider value */
+ reg = readl(IMX_CCM_BASE + offset) & ~CLKCTRL_SSP_DIV_MASK;
+ writel(reg | SET_SSP_DIV(ssp_div), IMX_CCM_BASE + offset);
+
+ /* Wait until new divider value is set */
+ while (readl(IMX_CCM_BASE + offset) & CLKCTRL_SSP_BUSY)
+ ;
+
+ if (high)
+ /* switch to ioclock */
+ writel(shift, IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ + BIT_CLR);
+ else
+ /* switch to 24 MHz crystal */
+ writel(shift, IMX_CCM_BASE + HW_CLKCTRL_CLKSEQ + BIT_SET);
+
+ return imx_get_sspclk(index);
+}
+
+void imx_enable_enetclk(void)
+{
+ uint32_t reg;
+
+ /* wake up main enet PLL */
+ reg = readl(IMX_CCM_BASE + HW_CLKCTRL_PLL2CTRL0);
+ if (!(reg & CLKCTRL_PLL2CTRL0_POWER)) {
+ reg |= CLKCTRL_PLL2CTRL0_POWER;
+ writel(reg, IMX_CCM_BASE + HW_CLKCTRL_PLL2CTRL0);
+ udelay(50); /* wait until this PLL locks */
+ }
+ reg &= ~CLKCTRL_PLL2CTRL0_CLKGATE;
+ writel(reg, IMX_CCM_BASE + HW_CLKCTRL_PLL2CTRL0);
+
+ writel(SET_CLKCTRL_ENET_DIV(1) | SET_CLKCTRL_ENET_SEL(0) |
+ CLKCTRL_ENET_CLK_OUT_EN, /* FIXME may be platform specific */
+ IMX_CCM_BASE + HW_CLKCTRL_ENET);
+}
+
+void imx_dump_clocks(void)
+{
+ printf("mpll: %10u kHz\n", imx_get_mpllclk() / 1000);
+ printf("arm: %10u kHz\n", imx_get_armclk() / 1000);
+ printf("ioclk0: %10u kHz\n", imx_get_ioclk(0) / 1000);
+ printf("ioclk1: %10u kHz\n", imx_get_ioclk(1) / 1000);
+ printf("emiclk: %10u kHz\n", imx_get_emiclk() / 1000);
+ printf("hclk: %10u kHz\n", imx_get_hclk() / 1000);
+ printf("xclk: %10u kHz\n", imx_get_xclk() / 1000);
+ printf("ssp0: %10u kHz\n", imx_get_sspclk(0) / 1000);
+ printf("ssp1: %10u kHz\n", imx_get_sspclk(1) / 1000);
+ printf("ssp2: %10u kHz\n", imx_get_sspclk(2) / 1000);
+ printf("ssp3: %10u kHz\n", imx_get_sspclk(3) / 1000);
+}
diff --git a/arch/arm/mach-versatile/Kconfig b/arch/arm/mach-versatile/Kconfig
new file mode 100644
index 0000000000..9a1bf953b0
--- /dev/null
+++ b/arch/arm/mach-versatile/Kconfig
@@ -0,0 +1,16 @@
+
+if ARCH_VERSATILE
+
+choice
+ prompt "ARM Board type"
+
+config MACH_VERSATILEPB
+ bool "ARM Versatile/PB (ARM926EJ-S)"
+ select ARM_AMBA
+ select CLKDEV_LOOKUP
+
+endchoice
+
+source arch/arm/boards/versatile/Kconfig
+
+endif
diff --git a/arch/arm/mach-versatile/Makefile b/arch/arm/mach-versatile/Makefile
new file mode 100644
index 0000000000..a8da54c27b
--- /dev/null
+++ b/arch/arm/mach-versatile/Makefile
@@ -0,0 +1,2 @@
+
+obj-y += core.o
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c
new file mode 100644
index 0000000000..ee14f5f7b2
--- /dev/null
+++ b/arch/arm/mach-versatile/core.c
@@ -0,0 +1,224 @@
+/*
+ * Copyright (C) 2010 B Labs Ltd,
+ * http://l4dev.org
+ * Author: Alexey Zaytsev <alexey.zaytsev@gmail.com>
+ *
+ * Based on mach-nomadik
+ * Copyright (C) 2009 Jean-Christophe PLAGNIOL-VILLARD <plagnio@jcrosoft.com>
+ *
+ * Copyright (C) 1999 - 2003 ARM Limited
+ * Copyright (C) 2000 Deep Blue Solutions Ltd
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ */
+
+#include <common.h>
+#include <init.h>
+#include <clock.h>
+#include <debug_ll.h>
+
+#include <linux/clkdev.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+
+#include <asm/io.h>
+#include <asm/hardware/arm_timer.h>
+#include <asm/armlinux.h>
+
+#include <mach/platform.h>
+#include <mach/init.h>
+
+static struct memory_platform_data ram_pdata = {
+ .name = "ram0",
+ .flags = DEVFS_RDWR,
+};
+
+static struct device_d sdram_dev = {
+ .id = -1,
+ .name = "mem",
+ .map_base = 0x00000000,
+ .platform_data = &ram_pdata,
+};
+
+void versatile_add_sdram(u32 size)
+{
+ sdram_dev.size = size;
+ register_device(&sdram_dev);
+ armlinux_add_dram(&sdram_dev);
+}
+
+static struct device_d uart0_serial_device = {
+ .id = 0,
+ .name = "uart-pl011",
+ .map_base = VERSATILE_UART0_BASE,
+ .size = 4096,
+};
+
+static struct device_d uart1_serial_device = {
+ .id = 1,
+ .name = "uart-pl011",
+ .map_base = VERSATILE_UART1_BASE,
+ .size = 4096,
+};
+
+static struct device_d uart2_serial_device = {
+ .id = 2,
+ .name = "uart-pl011",
+ .map_base = VERSATILE_UART2_BASE,
+ .size = 4096,
+};
+
+static struct device_d uart3_serial_device = {
+ .id = 3,
+ .name = "uart-pl011",
+ .map_base = VERSATILE_UART3_BASE,
+ .size = 4096,
+};
+
+struct clk {
+ unsigned long rate;
+};
+
+static struct clk ref_clk_24 = {
+ .rate = 24000000,
+};
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+/* enable and disable do nothing */
+int clk_enable(struct clk *clk)
+{
+ return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+}
+EXPORT_SYMBOL(clk_disable);
+
+/* Create a clock structure with the given name */
+int vpb_clk_create(struct clk *clk, const char *dev_id)
+{
+ struct clk_lookup *clkdev;
+
+ clkdev = clkdev_alloc(clk, NULL, dev_id);
+ if (!clkdev)
+ return -ENOMEM;
+
+ clkdev_add(clkdev);
+ return 0;
+}
+
+/* 1Mhz / 256 */
+#define TIMER_FREQ (1000000/256)
+
+#define TIMER0_BASE (VERSATILE_TIMER0_1_BASE)
+#define TIMER1_BASE ((VERSATILE_TIMER0_1_BASE) + 0x20)
+#define TIMER2_BASE (VERSATILE_TIMER2_3_BASE)
+#define TIMER3_BASE ((VERSATILE_TIMER2_3_BASE) + 0x20)
+
+static uint64_t vpb_clocksource_read(void)
+{
+ return ~readl(TIMER0_BASE + TIMER_VALUE);
+}
+
+static struct clocksource vpb_cs = {
+ .read = vpb_clocksource_read,
+ .mask = CLOCKSOURCE_MASK(32),
+ .shift = 10,
+};
+
+/* From Linux v2.6.35
+ * arch/arm/mach-versatile/core.c */
+static void versatile_timer_init (void)
+{
+ u32 val;
+
+ /*
+ * set clock frequency:
+ * VERSATILE_REFCLK is 32KHz
+ * VERSATILE_TIMCLK is 1MHz
+ */
+
+ val = readl(VERSATILE_SCTL_BASE);
+ val |= (VERSATILE_TIMCLK << VERSATILE_TIMER1_EnSel);
+ writel(val, VERSATILE_SCTL_BASE);
+
+ /*
+ * Disable all timers, just to be sure.
+ */
+
+ writel(0, TIMER0_BASE + TIMER_CTRL);
+ writel(0, TIMER1_BASE + TIMER_CTRL);
+ writel(0, TIMER2_BASE + TIMER_CTRL);
+ writel(0, TIMER3_BASE + TIMER_CTRL);
+
+ writel(TIMER_CTRL_32BIT | TIMER_CTRL_ENABLE | TIMER_CTRL_DIV256,
+ TIMER0_BASE + TIMER_CTRL);
+}
+
+static int vpb_clocksource_init(void)
+{
+ versatile_timer_init();
+ vpb_cs.mult = clocksource_hz2mult(TIMER_FREQ, vpb_cs.shift);
+
+ return init_clock(&vpb_cs);
+}
+
+core_initcall(vpb_clocksource_init);
+
+void versatile_register_uart(unsigned id)
+{
+ switch (id) {
+ case 0:
+ vpb_clk_create(&ref_clk_24, dev_name(&uart0_serial_device));
+ register_device(&uart0_serial_device);
+ break;
+ case 1:
+ vpb_clk_create(&ref_clk_24, dev_name(&uart1_serial_device));
+ register_device(&uart1_serial_device);
+ break;
+ case 2:
+ vpb_clk_create(&ref_clk_24, dev_name(&uart2_serial_device));
+ register_device(&uart2_serial_device);
+ break;
+ case 3:
+ vpb_clk_create(&ref_clk_24, dev_name(&uart3_serial_device));
+ register_device(&uart3_serial_device);
+ break;
+ }
+}
+
+void __noreturn reset_cpu (unsigned long ignored)
+{
+ u32 val;
+
+ val = __raw_readl(VERSATILE_SYS_RESETCTL) & ~0x7;
+ val |= 0x105;
+
+ __raw_writel(0xa05f, VERSATILE_SYS_LOCK);
+ __raw_writel(val, VERSATILE_SYS_RESETCTL);
+ __raw_writel(0, VERSATILE_SYS_LOCK);
+
+ while(1);
+}
+EXPORT_SYMBOL(reset_cpu);
diff --git a/arch/arm/mach-versatile/include/mach/clkdev.h b/arch/arm/mach-versatile/include/mach/clkdev.h
new file mode 100644
index 0000000000..04b37a8980
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/clkdev.h
@@ -0,0 +1,7 @@
+#ifndef __ASM_MACH_CLKDEV_H
+#define __ASM_MACH_CLKDEV_H
+
+#define __clk_get(clk) ({ 1; })
+#define __clk_put(clk) do { } while (0)
+
+#endif
diff --git a/arch/arm/mach-versatile/include/mach/debug_ll.h b/arch/arm/mach-versatile/include/mach/debug_ll.h
new file mode 100644
index 0000000000..514fcfb1a0
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/debug_ll.h
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2010 B Labs Ltd
+ * Author: Alexey Zaytsev <alexey.zaytsev@gmail.com>
+ *
+ * barebox is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * barebox is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with barebox. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __MACH_DEBUG_LL_H__
+#define __MACH_DEBUG_LL_H__
+
+#include <linux/amba/serial.h>
+#include <asm/io.h>
+
+static inline void putc(char c)
+{
+ /* Wait until there is space in the FIFO */
+ while (readl(0x101F1000 + UART01x_FR) & UART01x_FR_TXFF);
+
+ /* Send the character */
+ writel(c, 0x101F1000 + UART01x_DR);
+
+ /* Wait to make sure it hits the line, in case we die too soon. */
+ while (readl(0x101F1000 + UART01x_FR) & UART01x_FR_TXFF);
+}
+
+#endif
diff --git a/arch/arm/mach-versatile/include/mach/init.h b/arch/arm/mach-versatile/include/mach/init.h
new file mode 100644
index 0000000000..878cde0370
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/init.h
@@ -0,0 +1,8 @@
+
+#ifndef __VERSATILE_INIT_H__
+#define __VERSATILE_INIT_H__
+
+void versatile_add_sdram(u32 size);
+void versatile_register_uart(unsigned id);
+
+#endif
diff --git a/arch/arm/mach-versatile/include/mach/platform.h b/arch/arm/mach-versatile/include/mach/platform.h
new file mode 100644
index 0000000000..779b2fbb29
--- /dev/null
+++ b/arch/arm/mach-versatile/include/mach/platform.h
@@ -0,0 +1,417 @@
+/*
+ * ach-arm926ejs/include/mach/platform.h
+ *
+ * Borrowed from Linux v2.6.35
+ * arch/arm/mach-versatile/include/mach/platform.h
+ *
+ * Copyright (c) ARM Limited 2003. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __address_h
+#define __address_h 1
+
+/*
+ * Memory definitions
+ */
+#define VERSATILE_BOOT_ROM_LO 0x30000000 /* DoC Base (64Mb)...*/
+#define VERSATILE_BOOT_ROM_HI 0x30000000
+#define VERSATILE_BOOT_ROM_BASE VERSATILE_BOOT_ROM_HI /* Normal position */
+#define VERSATILE_BOOT_ROM_SIZE SZ_64M
+
+#define VERSATILE_SSRAM_BASE /* VERSATILE_SSMC_BASE ? */
+#define VERSATILE_SSRAM_SIZE SZ_2M
+
+#define VERSATILE_FLASH_BASE 0x34000000
+#define VERSATILE_FLASH_SIZE SZ_64M
+
+/*
+ * SDRAM
+ */
+#define VERSATILE_SDRAM_BASE 0x00000000
+
+/*
+ * Logic expansion modules
+ *
+ */
+
+
+/* ------------------------------------------------------------------------
+ * Versatile Registers
+ * ------------------------------------------------------------------------
+ *
+ */
+#define VERSATILE_SYS_ID_OFFSET 0x00
+#define VERSATILE_SYS_SW_OFFSET 0x04
+#define VERSATILE_SYS_LED_OFFSET 0x08
+#define VERSATILE_SYS_OSC0_OFFSET 0x0C
+
+#if defined(CONFIG_ARCH_VERSATILE_PB)
+#define VERSATILE_SYS_OSC1_OFFSET 0x10
+#define VERSATILE_SYS_OSC2_OFFSET 0x14
+#define VERSATILE_SYS_OSC3_OFFSET 0x18
+#define VERSATILE_SYS_OSC4_OFFSET 0x1C
+#elif defined(CONFIG_MACH_VERSATILE_AB)
+#define VERSATILE_SYS_OSC1_OFFSET 0x1C
+#endif
+
+#define VERSATILE_SYS_OSCCLCD_OFFSET 0x1c
+
+#define VERSATILE_SYS_LOCK_OFFSET 0x20
+#define VERSATILE_SYS_100HZ_OFFSET 0x24
+#define VERSATILE_SYS_CFGDATA1_OFFSET 0x28
+#define VERSATILE_SYS_CFGDATA2_OFFSET 0x2C
+#define VERSATILE_SYS_FLAGS_OFFSET 0x30
+#define VERSATILE_SYS_FLAGSSET_OFFSET 0x30
+#define VERSATILE_SYS_FLAGSCLR_OFFSET 0x34
+#define VERSATILE_SYS_NVFLAGS_OFFSET 0x38
+#define VERSATILE_SYS_NVFLAGSSET_OFFSET 0x38
+#define VERSATILE_SYS_NVFLAGSCLR_OFFSET 0x3C
+#define VERSATILE_SYS_RESETCTL_OFFSET 0x40
+#define VERSATILE_SYS_PCICTL_OFFSET 0x44
+#define VERSATILE_SYS_MCI_OFFSET 0x48
+#define VERSATILE_SYS_FLASH_OFFSET 0x4C
+#define VERSATILE_SYS_CLCD_OFFSET 0x50
+#define VERSATILE_SYS_CLCDSER_OFFSET 0x54
+#define VERSATILE_SYS_BOOTCS_OFFSET 0x58
+#define VERSATILE_SYS_24MHz_OFFSET 0x5C
+#define VERSATILE_SYS_MISC_OFFSET 0x60
+#define VERSATILE_SYS_TEST_OSC0_OFFSET 0x80
+#define VERSATILE_SYS_TEST_OSC1_OFFSET 0x84
+#define VERSATILE_SYS_TEST_OSC2_OFFSET 0x88
+#define VERSATILE_SYS_TEST_OSC3_OFFSET 0x8C
+#define VERSATILE_SYS_TEST_OSC4_OFFSET 0x90
+
+#define VERSATILE_SYS_BASE 0x10000000
+#define VERSATILE_SYS_ID (VERSATILE_SYS_BASE + VERSATILE_SYS_ID_OFFSET)
+#define VERSATILE_SYS_SW (VERSATILE_SYS_BASE + VERSATILE_SYS_SW_OFFSET)
+#define VERSATILE_SYS_LED (VERSATILE_SYS_BASE + VERSATILE_SYS_LED_OFFSET)
+#define VERSATILE_SYS_OSC0 (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC0_OFFSET)
+#define VERSATILE_SYS_OSC1 (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC1_OFFSET)
+
+#if defined(CONFIG_ARCH_VERSATILE_PB)
+#define VERSATILE_SYS_OSC2 (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC2_OFFSET)
+#define VERSATILE_SYS_OSC3 (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC3_OFFSET)
+#define VERSATILE_SYS_OSC4 (VERSATILE_SYS_BASE + VERSATILE_SYS_OSC4_OFFSET)
+#endif
+
+#define VERSATILE_SYS_LOCK (VERSATILE_SYS_BASE + VERSATILE_SYS_LOCK_OFFSET)
+#define VERSATILE_SYS_100HZ (VERSATILE_SYS_BASE + VERSATILE_SYS_100HZ_OFFSET)
+#define VERSATILE_SYS_CFGDATA1 (VERSATILE_SYS_BASE + VERSATILE_SYS_CFGDATA1_OFFSET)
+#define VERSATILE_SYS_CFGDATA2 (VERSATILE_SYS_BASE + VERSATILE_SYS_CFGDATA2_OFFSET)
+#define VERSATILE_SYS_FLAGS (VERSATILE_SYS_BASE + VERSATILE_SYS_FLAGS_OFFSET)
+#define VERSATILE_SYS_FLAGSSET (VERSATILE_SYS_BASE + VERSATILE_SYS_FLAGSSET_OFFSET)
+#define VERSATILE_SYS_FLAGSCLR (VERSATILE_SYS_BASE + VERSATILE_SYS_FLAGSCLR_OFFSET)
+#define VERSATILE_SYS_NVFLAGS (VERSATILE_SYS_BASE + VERSATILE_SYS_NVFLAGS_OFFSET)
+#define VERSATILE_SYS_NVFLAGSSET (VERSATILE_SYS_BASE + VERSATILE_SYS_NVFLAGSSET_OFFSET)
+#define VERSATILE_SYS_NVFLAGSCLR (VERSATILE_SYS_BASE + VERSATILE_SYS_NVFLAGSCLR_OFFSET)
+#define VERSATILE_SYS_RESETCTL (VERSATILE_SYS_BASE + VERSATILE_SYS_RESETCTL_OFFSET)
+#define VERSATILE_SYS_PCICTL (VERSATILE_SYS_BASE + VERSATILE_SYS_PCICTL_OFFSET)
+#define VERSATILE_SYS_MCI (VERSATILE_SYS_BASE + VERSATILE_SYS_MCI_OFFSET)
+#define VERSATILE_SYS_FLASH (VERSATILE_SYS_BASE + VERSATILE_SYS_FLASH_OFFSET)
+#define VERSATILE_SYS_CLCD (VERSATILE_SYS_BASE + VERSATILE_SYS_CLCD_OFFSET)
+#define VERSATILE_SYS_CLCDSER (VERSATILE_SYS_BASE + VERSATILE_SYS_CLCDSER_OFFSET)
+#define VERSATILE_SYS_BOOTCS (VERSATILE_SYS_BASE + VERSATILE_SYS_BOOTCS_OFFSET)
+#define VERSATILE_SYS_24MHz (VERSATILE_SYS_BASE + VERSATILE_SYS_24MHz_OFFSET)
+#define VERSATILE_SYS_MISC (VERSATILE_SYS_BASE + VERSATILE_SYS_MISC_OFFSET)
+#define VERSATILE_SYS_TEST_OSC0 (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC0_OFFSET)
+#define VERSATILE_SYS_TEST_OSC1 (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC1_OFFSET)
+#define VERSATILE_SYS_TEST_OSC2 (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC2_OFFSET)
+#define VERSATILE_SYS_TEST_OSC3 (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC3_OFFSET)
+#define VERSATILE_SYS_TEST_OSC4 (VERSATILE_SYS_BASE + VERSATILE_SYS_TEST_OSC4_OFFSET)
+
+/*
+ * Values for VERSATILE_SYS_RESET_CTRL
+ */
+#define VERSATILE_SYS_CTRL_RESET_CONFIGCLR 0x01
+#define VERSATILE_SYS_CTRL_RESET_CONFIGINIT 0x02
+#define VERSATILE_SYS_CTRL_RESET_DLLRESET 0x03
+#define VERSATILE_SYS_CTRL_RESET_PLLRESET 0x04
+#define VERSATILE_SYS_CTRL_RESET_POR 0x05
+#define VERSATILE_SYS_CTRL_RESET_DoC 0x06
+
+#define VERSATILE_SYS_CTRL_LED (1 << 0)
+
+
+/* ------------------------------------------------------------------------
+ * Versatile control registers
+ * ------------------------------------------------------------------------
+ */
+
+/*
+ * VERSATILE_IDFIELD
+ *
+ * 31:24 = manufacturer (0x41 = ARM)
+ * 23:16 = architecture (0x08 = AHB system bus, ASB processor bus)
+ * 15:12 = FPGA (0x3 = XVC600 or XVC600E)
+ * 11:4 = build value
+ * 3:0 = revision number (0x1 = rev B (AHB))
+ */
+
+/*
+ * VERSATILE_SYS_LOCK
+ * control access to SYS_OSCx, SYS_CFGDATAx, SYS_RESETCTL,
+ * SYS_CLD, SYS_BOOTCS
+ */
+#define VERSATILE_SYS_LOCK_LOCKED (1 << 16)
+#define VERSATILE_SYS_LOCKVAL_MASK 0xFFFF /* write 0xA05F to enable write access */
+
+/*
+ * VERSATILE_SYS_FLASH
+ */
+#define VERSATILE_FLASHPROG_FLVPPEN (1 << 0) /* Enable writing to flash */
+
+/*
+ * VERSATILE_INTREG
+ * - used to acknowledge and control MMCI and UART interrupts
+ */
+#define VERSATILE_INTREG_WPROT 0x00 /* MMC protection status (no interrupt generated) */
+#define VERSATILE_INTREG_RI0 0x01 /* Ring indicator UART0 is asserted, */
+#define VERSATILE_INTREG_CARDIN 0x08 /* MMCI card in detect */
+ /* write 1 to acknowledge and clear */
+#define VERSATILE_INTREG_RI1 0x02 /* Ring indicator UART1 is asserted, */
+#define VERSATILE_INTREG_CARDINSERT 0x03 /* Signal insertion of MMC card */
+
+/*
+ * VERSATILE peripheral addresses
+ */
+#define VERSATILE_PCI_CORE_BASE 0x10001000 /* PCI core control */
+#define VERSATILE_I2C_BASE 0x10002000 /* I2C control */
+#define VERSATILE_SIC_BASE 0x10003000 /* Secondary interrupt controller */
+#define VERSATILE_AACI_BASE 0x10004000 /* Audio */
+#define VERSATILE_MMCI0_BASE 0x10005000 /* MMC interface */
+#define VERSATILE_KMI0_BASE 0x10006000 /* KMI interface */
+#define VERSATILE_KMI1_BASE 0x10007000 /* KMI 2nd interface */
+#define VERSATILE_CHAR_LCD_BASE 0x10008000 /* Character LCD */
+#define VERSATILE_UART3_BASE 0x10009000 /* UART 3 */
+#define VERSATILE_SCI1_BASE 0x1000A000
+#define VERSATILE_MMCI1_BASE 0x1000B000 /* MMC Interface */
+ /* 0x1000C000 - 0x1000CFFF = reserved */
+#define VERSATILE_ETH_BASE 0x10010000 /* Ethernet */
+#define VERSATILE_USB_BASE 0x10020000 /* USB */
+ /* 0x10030000 - 0x100FFFFF = reserved */
+#define VERSATILE_SMC_BASE 0x10100000 /* SMC */
+#define VERSATILE_MPMC_BASE 0x10110000 /* MPMC */
+#define VERSATILE_CLCD_BASE 0x10120000 /* CLCD */
+#define VERSATILE_DMAC_BASE 0x10130000 /* DMA controller */
+#define VERSATILE_VIC_BASE 0x10140000 /* Vectored interrupt controller */
+#define VERSATILE_PERIPH_BASE 0x10150000 /* off-chip peripherals alias from */
+ /* 0x10000000 - 0x100FFFFF */
+#define VERSATILE_AHBM_BASE 0x101D0000 /* AHB monitor */
+#define VERSATILE_SCTL_BASE 0x101E0000 /* System controller */
+#define VERSATILE_WATCHDOG_BASE 0x101E1000 /* Watchdog */
+#define VERSATILE_TIMER0_1_BASE 0x101E2000 /* Timer 0 and 1 */
+#define VERSATILE_TIMER2_3_BASE 0x101E3000 /* Timer 2 and 3 */
+#define VERSATILE_GPIO0_BASE 0x101E4000 /* GPIO port 0 */
+#define VERSATILE_GPIO1_BASE 0x101E5000 /* GPIO port 1 */
+#define VERSATILE_GPIO2_BASE 0x101E6000 /* GPIO port 2 */
+#define VERSATILE_GPIO3_BASE 0x101E7000 /* GPIO port 3 */
+#define VERSATILE_RTC_BASE 0x101E8000 /* Real Time Clock */
+ /* 0x101E9000 - reserved */
+#define VERSATILE_SCI_BASE 0x101F0000 /* Smart card controller */
+#define VERSATILE_UART0_BASE 0x101F1000 /* Uart 0 */
+#define VERSATILE_UART1_BASE 0x101F2000 /* Uart 1 */
+#define VERSATILE_UART2_BASE 0x101F3000 /* Uart 2 */
+#define VERSATILE_SSP_BASE 0x101F4000 /* Synchronous Serial Port */
+
+#define VERSATILE_SSMC_BASE 0x20000000 /* SSMC */
+#define VERSATILE_IB2_BASE 0x24000000 /* IB2 module */
+#define VERSATILE_MBX_BASE 0x40000000 /* MBX */
+
+/* PCI space */
+#define VERSATILE_PCI_BASE 0x41000000 /* PCI Interface */
+#define VERSATILE_PCI_CFG_BASE 0x42000000
+#define VERSATILE_PCI_MEM_BASE0 0x44000000
+#define VERSATILE_PCI_MEM_BASE1 0x50000000
+#define VERSATILE_PCI_MEM_BASE2 0x60000000
+/* Sizes of above maps */
+#define VERSATILE_PCI_BASE_SIZE 0x01000000
+#define VERSATILE_PCI_CFG_BASE_SIZE 0x02000000
+#define VERSATILE_PCI_MEM_BASE0_SIZE 0x0c000000 /* 32Mb */
+#define VERSATILE_PCI_MEM_BASE1_SIZE 0x10000000 /* 256Mb */
+#define VERSATILE_PCI_MEM_BASE2_SIZE 0x10000000 /* 256Mb */
+
+#define VERSATILE_SDRAM67_BASE 0x70000000 /* SDRAM banks 6 and 7 */
+#define VERSATILE_LT_BASE 0x80000000 /* Logic Tile expansion */
+
+/*
+ * Disk on Chip
+ */
+#define VERSATILE_DOC_BASE 0x2C000000
+#define VERSATILE_DOC_SIZE (16 << 20)
+#define VERSATILE_DOC_PAGE_SIZE 512
+#define VERSATILE_DOC_TOTAL_PAGES (DOC_SIZE / PAGE_SIZE)
+
+#define ERASE_UNIT_PAGES 32
+#define START_PAGE 0x80
+
+/*
+ * LED settings, bits [7:0]
+ */
+#define VERSATILE_SYS_LED0 (1 << 0)
+#define VERSATILE_SYS_LED1 (1 << 1)
+#define VERSATILE_SYS_LED2 (1 << 2)
+#define VERSATILE_SYS_LED3 (1 << 3)
+#define VERSATILE_SYS_LED4 (1 << 4)
+#define VERSATILE_SYS_LED5 (1 << 5)
+#define VERSATILE_SYS_LED6 (1 << 6)
+#define VERSATILE_SYS_LED7 (1 << 7)
+
+#define ALL_LEDS 0xFF
+
+#define LED_BANK VERSATILE_SYS_LED
+
+/*
+ * Control registers
+ */
+#define VERSATILE_IDFIELD_OFFSET 0x0 /* Versatile build information */
+#define VERSATILE_FLASHPROG_OFFSET 0x4 /* Flash devices */
+#define VERSATILE_INTREG_OFFSET 0x8 /* Interrupt control */
+#define VERSATILE_DECODE_OFFSET 0xC /* Fitted logic modules */
+
+
+/* ------------------------------------------------------------------------
+ * Versatile Interrupt Controller - control registers
+ * ------------------------------------------------------------------------
+ *
+ * Offsets from interrupt controller base
+ *
+ * System Controller interrupt controller base is
+ *
+ * VERSATILE_IC_BASE
+ *
+ * Core Module interrupt controller base is
+ *
+ * VERSATILE_SYS_IC
+ *
+ */
+/* VIC definitions in include/asm-arm/hardware/vic.h */
+
+#define SIC_IRQ_STATUS 0
+#define SIC_IRQ_RAW_STATUS 0x04
+#define SIC_IRQ_ENABLE 0x08
+#define SIC_IRQ_ENABLE_SET 0x08
+#define SIC_IRQ_ENABLE_CLEAR 0x0C
+#define SIC_INT_SOFT_SET 0x10
+#define SIC_INT_SOFT_CLEAR 0x14
+#define SIC_INT_PIC_ENABLE 0x20 /* read status of pass through mask */
+#define SIC_INT_PIC_ENABLES 0x20 /* set interrupt pass through bits */
+#define SIC_INT_PIC_ENABLEC 0x24 /* Clear interrupt pass through bits */
+
+/* ------------------------------------------------------------------------
+ * Interrupts - bit assignment (primary)
+ * ------------------------------------------------------------------------
+ */
+
+#define INT_WDOGINT 0 /* Watchdog timer */
+#define INT_SOFTINT 1 /* Software interrupt */
+#define INT_COMMRx 2 /* Debug Comm Rx interrupt */
+#define INT_COMMTx 3 /* Debug Comm Tx interrupt */
+#define INT_TIMERINT0_1 4 /* Timer 0 and 1 */
+#define INT_TIMERINT2_3 5 /* Timer 2 and 3 */
+#define INT_GPIOINT0 6 /* GPIO 0 */
+#define INT_GPIOINT1 7 /* GPIO 1 */
+#define INT_GPIOINT2 8 /* GPIO 2 */
+#define INT_GPIOINT3 9 /* GPIO 3 */
+#define INT_RTCINT 10 /* Real Time Clock */
+#define INT_SSPINT 11 /* Synchronous Serial Port */
+#define INT_UARTINT0 12 /* UART 0 on development chip */
+#define INT_UARTINT1 13 /* UART 1 on development chip */
+#define INT_UARTINT2 14 /* UART 2 on development chip */
+#define INT_SCIINT 15 /* Smart Card Interface */
+#define INT_CLCDINT 16 /* CLCD controller */
+#define INT_DMAINT 17 /* DMA controller */
+#define INT_PWRFAILINT 18 /* Power failure */
+#define INT_MBXINT 19 /* Graphics processor */
+#define INT_GNDINT 20 /* Reserved */
+ /* External interrupt signals from logic tiles or secondary controller */
+#define INT_VICSOURCE21 21 /* Disk on Chip */
+#define INT_VICSOURCE22 22 /* MCI0A */
+#define INT_VICSOURCE23 23 /* MCI1A */
+#define INT_VICSOURCE24 24 /* AACI */
+#define INT_VICSOURCE25 25 /* Ethernet */
+#define INT_VICSOURCE26 26 /* USB */
+#define INT_VICSOURCE27 27 /* PCI 0 */
+#define INT_VICSOURCE28 28 /* PCI 1 */
+#define INT_VICSOURCE29 29 /* PCI 2 */
+#define INT_VICSOURCE30 30 /* PCI 3 */
+#define INT_VICSOURCE31 31 /* SIC source */
+
+#define VERSATILE_SC_VALID_INT 0x003FFFFF
+
+#define MAXIRQNUM 31
+#define MAXFIQNUM 31
+#define MAXSWINUM 31
+
+/* ------------------------------------------------------------------------
+ * Interrupts - bit assignment (secondary)
+ * ------------------------------------------------------------------------
+ */
+#define SIC_INT_MMCI0B 1 /* Multimedia Card 0B */
+#define SIC_INT_MMCI1B 2 /* Multimedia Card 1B */
+#define SIC_INT_KMI0 3 /* Keyboard/Mouse port 0 */
+#define SIC_INT_KMI1 4 /* Keyboard/Mouse port 1 */
+#define SIC_INT_SCI3 5 /* Smart Card interface */
+#define SIC_INT_UART3 6 /* UART 3 empty or data available */
+#define SIC_INT_CLCD 7 /* Character LCD */
+#define SIC_INT_TOUCH 8 /* Touchscreen */
+#define SIC_INT_KEYPAD 9 /* Key pressed on display keypad */
+ /* 10:20 - reserved */
+#define SIC_INT_DoC 21 /* Disk on Chip memory controller */
+#define SIC_INT_MMCI0A 22 /* MMC 0A */
+#define SIC_INT_MMCI1A 23 /* MMC 1A */
+#define SIC_INT_AACI 24 /* Audio Codec */
+#define SIC_INT_ETH 25 /* Ethernet controller */
+#define SIC_INT_USB 26 /* USB controller */
+#define SIC_INT_PCI0 27
+#define SIC_INT_PCI1 28
+#define SIC_INT_PCI2 29
+#define SIC_INT_PCI3 30
+
+
+/*
+ * System controller bit assignment
+ */
+#define VERSATILE_REFCLK 0
+#define VERSATILE_TIMCLK 1
+
+#define VERSATILE_TIMER1_EnSel 15
+#define VERSATILE_TIMER2_EnSel 17
+#define VERSATILE_TIMER3_EnSel 19
+#define VERSATILE_TIMER4_EnSel 21
+
+
+#define VERSATILE_CSR_BASE 0x10000000
+#define VERSATILE_CSR_SIZE 0x10000000
+
+#ifdef CONFIG_MACH_VERSATILE_AB
+/*
+ * IB2 Versatile/AB expansion board definitions
+ */
+#define VERSATILE_IB2_CAMERA_BANK VERSATILE_IB2_BASE
+#define VERSATILE_IB2_KBD_DATAREG (VERSATILE_IB2_BASE + 0x01000000)
+
+/* VICINTSOURCE27 */
+#define VERSATILE_IB2_INT_BASE (VERSATILE_IB2_BASE + 0x02000000)
+#define VERSATILE_IB2_IER (VERSATILE_IB2_INT_BASE + 0)
+#define VERSATILE_IB2_ISR (VERSATILE_IB2_INT_BASE + 4)
+
+#define VERSATILE_IB2_CTL_BASE (VERSATILE_IB2_BASE + 0x03000000)
+#define VERSATILE_IB2_CTRL (VERSATILE_IB2_CTL_BASE + 0)
+#define VERSATILE_IB2_STAT (VERSATILE_IB2_CTL_BASE + 4)
+#endif
+
+#endif
diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types
index 32d78335ea..43dbb8eb2a 100644
--- a/arch/arm/tools/mach-types
+++ b/arch/arm/tools/mach-types
@@ -12,7 +12,7 @@
#
# http://www.arm.linux.org.uk/developer/machines/?action=new
#
-# Last update: Mon May 24 21:27:47 2010
+# Last update: Fri Dec 10 03:31:36 2010
#
# machine_is_xxx CONFIG_xxxx MACH_TYPE_xxx number
#
@@ -1319,7 +1319,7 @@ mistral MACH_MISTRAL MISTRAL 1315
msm MACH_MSM MSM 1316
ct5910 MACH_CT5910 CT5910 1317
ct5912 MACH_CT5912 CT5912 1318
-argonst_foundation MACH_HYNET_INE HYNET_INE 1319
+argonst_mp MACH_HYNET_INE HYNET_INE 1319
hynet_app MACH_HYNET_APP HYNET_APP 1320
msm7200 MACH_MSM7200 MSM7200 1321
msm7600 MACH_MSM7600 MSM7600 1322
@@ -1877,7 +1877,7 @@ ued MACH_UED UED 1885
esiblade MACH_ESIBLADE ESIBLADE 1886
eye02 MACH_EYE02 EYE02 1887
imx27kbd MACH_IMX27KBD IMX27KBD 1888
-sst61vc010_fpga MACH_SST61VC010_FPGA SST61VC010_FPGA 1889
+p87_fpga MACH_SST61VC010_FPGA SST61VC010_FPGA 1889
kixvp435 MACH_KIXVP435 KIXVP435 1890
kixnp435 MACH_KIXNP435 KIXNP435 1891
africa MACH_AFRICA AFRICA 1892
@@ -1994,7 +1994,7 @@ spark MACH_SPARK SPARK 2002
benzina MACH_BENZINA BENZINA 2003
blaze MACH_BLAZE BLAZE 2004
linkstation_ls_hgl MACH_LINKSTATION_LS_HGL LINKSTATION_LS_HGL 2005
-htckovsky MACH_HTCVENUS HTCVENUS 2006
+htckovsky MACH_HTCKOVSKY HTCKOVSKY 2006
sony_prs505 MACH_SONY_PRS505 SONY_PRS505 2007
hanlin_v3 MACH_HANLIN_V3 HANLIN_V3 2008
sapphira MACH_SAPPHIRA SAPPHIRA 2009
@@ -2321,7 +2321,7 @@ mx31txtr MACH_MX31TXTR MX31TXTR 2332
u380 MACH_U380 U380 2333
oamp3_hualu MACH_HUALU_BOARD HUALU_BOARD 2334
npcmx50 MACH_NPCMX50 NPCMX50 2335
-mx51_lange51 MACH_MX51_LANGE51 MX51_LANGE51 2336
+mx51_efikamx MACH_MX51_EFIKAMX MX51_EFIKAMX 2336
mx51_lange52 MACH_MX51_LANGE52 MX51_LANGE52 2337
riom MACH_RIOM RIOM 2338
comcas MACH_COMCAS COMCAS 2339
@@ -2355,7 +2355,7 @@ at91sam9263cs MACH_AT91SAM9263CS AT91SAM9263CS 2366
csb732 MACH_CSB732 CSB732 2367
u8500 MACH_U8500 U8500 2368
huqiu MACH_HUQIU HUQIU 2369
-mx51_kunlun MACH_MX51_KUNLUN MX51_KUNLUN 2370
+mx51_efikasb MACH_MX51_EFIKASB MX51_EFIKASB 2370
pmt1g MACH_PMT1G PMT1G 2371
htcelf MACH_HTCELF HTCELF 2372
armadillo420 MACH_ARMADILLO420 ARMADILLO420 2373
@@ -2446,7 +2446,7 @@ siogentoo1 MACH_SIOGENTOO1 SIOGENTOO1 2458
siogentoo2 MACH_SIOGENTOO2 SIOGENTOO2 2459
sm3k MACH_SM3K SM3K 2460
acer_tempo_f900 MACH_ACER_TEMPO_F900 ACER_TEMPO_F900 2461
-sst61vc010_dev MACH_SST61VC010_DEV SST61VC010_DEV 2462
+p87_dev MACH_SST61VC010_DEV SST61VC010_DEV 2462
glittertind MACH_GLITTERTIND GLITTERTIND 2463
omap_zoom3 MACH_OMAP_ZOOM3 OMAP_ZOOM3 2464
omap_3630sdp MACH_OMAP_3630SDP OMAP_3630SDP 2465
@@ -2561,7 +2561,7 @@ magnolia2 MACH_MAGNOLIA2 MAGNOLIA2 2573
emxx MACH_EMXX EMXX 2574
outlaw MACH_OUTLAW OUTLAW 2575
riot_bei2 MACH_RIOT_BEI2 RIOT_BEI2 2576
-riot_vox MACH_RIOT_VOX RIOT_VOX 2577
+riot_gx2 MACH_RIOT_VOX RIOT_VOX 2577
riot_x37 MACH_RIOT_X37 RIOT_X37 2578
mega25mx MACH_MEGA25MX MEGA25MX 2579
benzina2 MACH_BENZINA2 BENZINA2 2580
@@ -2591,7 +2591,7 @@ wzl6410i MACH_WZL6410I WZL6410I 2603
spacecom1 MACH_SPACECOM1 SPACECOM1 2604
pingu920 MACH_PINGU920 PINGU920 2605
bravoc MACH_BRAVOC BRAVOC 2606
-cybo2440 MACH_CYBO2440 CYBO2440 2607
+mydev MACH_CYBO2440 CYBO2440 2607
vdssw MACH_VDSSW VDSSW 2608
romulus MACH_ROMULUS ROMULUS 2609
omap_magic MACH_OMAP_MAGIC OMAP_MAGIC 2610
@@ -2609,7 +2609,7 @@ fujitsu_tvstbsoc1 MACH_FUJITSU_TVSTBSOC1 FUJITSU_TVSTBSOC1 2621
lexikon MACH_LEXIKON LEXIKON 2622
mini2440v2 MACH_MINI2440V2 MINI2440V2 2623
icontrol MACH_ICONTROL ICONTROL 2624
-sheevad MACH_SHEEVAD SHEEVAD 2625
+gplugd MACH_SHEEVAD SHEEVAD 2625
qsd8x50a_st1_1 MACH_QSD8X50A_ST1_1 QSD8X50A_ST1_1 2626
qsd8x50a_st1_5 MACH_QSD8X50A_ST1_5 QSD8X50A_ST1_5 2627
bee MACH_BEE BEE 2628
@@ -2622,7 +2622,7 @@ kraken MACH_KRAKEN KRAKEN 2634
gw2388 MACH_GW2388 GW2388 2635
jadecpu MACH_JADECPU JADECPU 2636
carlisle MACH_CARLISLE CARLISLE 2637
-lux_sf9 MACH_LUX_SFT9 LUX_SFT9 2638
+lux_sf9 MACH_LUX_SF9 LUX_SF9 2638
nemid_tb MACH_NEMID_TB NEMID_TB 2639
terrier MACH_TERRIER TERRIER 2640
turbot MACH_TURBOT TURBOT 2641
@@ -2683,7 +2683,7 @@ lkevm MACH_LKEVM LKEVM 2695
mw6410 MACH_MW6410 MW6410 2696
terastation_wxl MACH_TERASTATION_WXL TERASTATION_WXL 2697
cpu8000e MACH_CPU8000E CPU8000E 2698
-catania MACH_CATANIA CATANIA 2699
+catania_s MACH_CATANIA CATANIA 2699
tokyo MACH_TOKYO TOKYO 2700
msm7201a_surf MACH_MSM7201A_SURF MSM7201A_SURF 2701
msm7201a_ffa MACH_MSM7201A_FFA MSM7201A_FFA 2702
@@ -2812,7 +2812,7 @@ p565 MACH_P565 P565 2824
acer_a4 MACH_ACER_A4 ACER_A4 2825
davinci_dm368_bip MACH_DAVINCI_DM368_BIP DAVINCI_DM368_BIP 2826
eshare MACH_ESHARE ESHARE 2827
-hw_omapl138_europa MACH_HW_OMAPL138_EUROPA HW_OMAPL138_EUROPA 2828
+omapl138_europa MACH_HW_OMAPL138_EUROPA HW_OMAPL138_EUROPA 2828
wlbargn MACH_WLBARGN WLBARGN 2829
bm170 MACH_BM170 BM170 2830
netspace_mini_v2 MACH_NETSPACE_MINI_V2 NETSPACE_MINI_V2 2831
@@ -2859,3 +2859,362 @@ autobot MACH_AUTOBOT AUTOBOT 2871
coconut MACH_COCONUT COCONUT 2872
durian MACH_DURIAN DURIAN 2873
cayenne MACH_CAYENNE CAYENNE 2874
+fuji MACH_FUJI FUJI 2875
+synology_6282 MACH_SYNOLOGY_6282 SYNOLOGY_6282 2876
+em1sy MACH_EM1SY EM1SY 2877
+m502 MACH_M502 M502 2878
+matrix518 MACH_MATRIX518 MATRIX518 2879
+tiny_gurnard MACH_TINY_GURNARD TINY_GURNARD 2880
+spear1310 MACH_SPEAR1310 SPEAR1310 2881
+bv07 MACH_BV07 BV07 2882
+mxt_td61 MACH_MXT_TD61 MXT_TD61 2883
+openrd_ultimate MACH_OPENRD_ULTIMATE OPENRD_ULTIMATE 2884
+devixp MACH_DEVIXP DEVIXP 2885
+miccpt MACH_MICCPT MICCPT 2886
+mic256 MACH_MIC256 MIC256 2887
+as1167 MACH_AS1167 AS1167 2888
+omap3_ibiza MACH_OMAP3_IBIZA OMAP3_IBIZA 2889
+u5500 MACH_U5500 U5500 2890
+davinci_picto MACH_DAVINCI_PICTO DAVINCI_PICTO 2891
+mecha MACH_MECHA MECHA 2892
+bubba3 MACH_BUBBA3 BUBBA3 2893
+pupitre MACH_PUPITRE PUPITRE 2894
+tegra_harmony MACH_TEGRA_HARMONY TEGRA_HARMONY 2895
+tegra_vogue MACH_TEGRA_VOGUE TEGRA_VOGUE 2896
+tegra_e1165 MACH_TEGRA_E1165 TEGRA_E1165 2897
+simplenet MACH_SIMPLENET SIMPLENET 2898
+ec4350tbm MACH_EC4350TBM EC4350TBM 2899
+pec_tc MACH_PEC_TC PEC_TC 2900
+pec_hc2 MACH_PEC_HC2 PEC_HC2 2901
+esl_mobilis_a MACH_ESL_MOBILIS_A ESL_MOBILIS_A 2902
+esl_mobilis_b MACH_ESL_MOBILIS_B ESL_MOBILIS_B 2903
+esl_wave_a MACH_ESL_WAVE_A ESL_WAVE_A 2904
+esl_wave_b MACH_ESL_WAVE_B ESL_WAVE_B 2905
+unisense_mmm MACH_UNISENSE_MMM UNISENSE_MMM 2906
+blueshark MACH_BLUESHARK BLUESHARK 2907
+e10 MACH_E10 E10 2908
+app3k_robin MACH_APP3K_ROBIN APP3K_ROBIN 2909
+pov15hd MACH_POV15HD POV15HD 2910
+stella MACH_STELLA STELLA 2911
+htc_iolite MACH_MACH_HTC_IOLITE MACH_HTC_IOLITE 2912
+linkstation_lschl MACH_LINKSTATION_LSCHL LINKSTATION_LSCHL 2913
+netwalker MACH_NETWALKER NETWALKER 2914
+acsx106 MACH_ACSX106 ACSX106 2915
+atlas5_c1 MACH_ATLAS5_C1 ATLAS5_C1 2916
+nsb3ast MACH_NSB3AST NSB3AST 2917
+gnet_slc MACH_GNET_SLC GNET_SLC 2918
+af4000 MACH_AF4000 AF4000 2919
+ark9431 MACH_ARK9431 ARK9431 2920
+fs_s5pc100 MACH_FS_S5PC100 FS_S5PC100 2921
+omap3505nova8 MACH_OMAP3505NOVA8 OMAP3505NOVA8 2922
+omap3621_edp1 MACH_OMAP3621_EDP1 OMAP3621_EDP1 2923
+oratisaes MACH_ORATISAES ORATISAES 2924
+smdkv310 MACH_SMDKV310 SMDKV310 2925
+siemens_l0 MACH_SIEMENS_L0 SIEMENS_L0 2926
+ventana MACH_VENTANA VENTANA 2927
+wm8505_7in_netbook MACH_WM8505_7IN_NETBOOK WM8505_7IN_NETBOOK 2928
+ec4350sdb MACH_EC4350SDB EC4350SDB 2929
+mimas MACH_MIMAS MIMAS 2930
+titan MACH_TITAN TITAN 2931
+craneboard MACH_CRANEBOARD CRANEBOARD 2932
+es2440 MACH_ES2440 ES2440 2933
+najay_a9263 MACH_NAJAY_A9263 NAJAY_A9263 2934
+htctornado MACH_HTCTORNADO HTCTORNADO 2935
+dimm_mx257 MACH_DIMM_MX257 DIMM_MX257 2936
+jigen301 MACH_JIGEN JIGEN 2937
+smdk6450 MACH_SMDK6450 SMDK6450 2938
+meno_qng MACH_MENO_QNG MENO_QNG 2939
+ns2416 MACH_NS2416 NS2416 2940
+rpc353 MACH_RPC353 RPC353 2941
+tq6410 MACH_TQ6410 TQ6410 2942
+sky6410 MACH_SKY6410 SKY6410 2943
+dynasty MACH_DYNASTY DYNASTY 2944
+vivo MACH_VIVO VIVO 2945
+bury_bl7582 MACH_BURY_BL7582 BURY_BL7582 2946
+bury_bps5270 MACH_BURY_BPS5270 BURY_BPS5270 2947
+basi MACH_BASI BASI 2948
+tn200 MACH_TN200 TN200 2949
+c2mmi MACH_C2MMI C2MMI 2950
+meson_6236m MACH_MESON_6236M MESON_6236M 2951
+meson_8626m MACH_MESON_8626M MESON_8626M 2952
+tube MACH_TUBE TUBE 2953
+messina MACH_MESSINA MESSINA 2954
+mx50_arm2 MACH_MX50_ARM2 MX50_ARM2 2955
+cetus9263 MACH_CETUS9263 CETUS9263 2956
+brownstone MACH_BROWNSTONE BROWNSTONE 2957
+vmx25 MACH_VMX25 VMX25 2958
+vmx51 MACH_VMX51 VMX51 2959
+abacus MACH_ABACUS ABACUS 2960
+cm4745 MACH_CM4745 CM4745 2961
+oratislink MACH_ORATISLINK ORATISLINK 2962
+davinci_dm365_dvr MACH_DAVINCI_DM365_DVR DAVINCI_DM365_DVR 2963
+netviz MACH_NETVIZ NETVIZ 2964
+flexibity MACH_FLEXIBITY FLEXIBITY 2965
+wlan_computer MACH_WLAN_COMPUTER WLAN_COMPUTER 2966
+lpc24xx MACH_LPC24XX LPC24XX 2967
+spica MACH_SPICA SPICA 2968
+gpsdisplay MACH_GPSDISPLAY GPSDISPLAY 2969
+bipnet MACH_BIPNET BIPNET 2970
+overo_ctu_inertial MACH_OVERO_CTU_INERTIAL OVERO_CTU_INERTIAL 2971
+davinci_dm355_mmm MACH_DAVINCI_DM355_MMM DAVINCI_DM355_MMM 2972
+pc9260_v2 MACH_PC9260_V2 PC9260_V2 2973
+ptx7545 MACH_PTX7545 PTX7545 2974
+tm_efdc MACH_TM_EFDC TM_EFDC 2975
+remove_me MACH_WALDO1 WALDO1 2976
+omap3_waldo1 MACH_OMAP3_WALDO1 OMAP3_WALDO1 2977
+flyer MACH_FLYER FLYER 2978
+tornado3240 MACH_TORNADO3240 TORNADO3240 2979
+soli_01 MACH_SOLI_01 SOLI_01 2980
+omapl138_europalc MACH_OMAPL138_EUROPALC OMAPL138_EUROPALC 2981
+helios_v1 MACH_HELIOS_V1 HELIOS_V1 2982
+netspace_lite_v2 MACH_NETSPACE_LITE_V2 NETSPACE_LITE_V2 2983
+ssc MACH_SSC SSC 2984
+premierwave_en MACH_PREMIERWAVE_EN PREMIERWAVE_EN 2985
+wasabi MACH_WASABI WASABI 2986
+vivo_w MACH_VIVOW VIVOW 2987
+mx50_rdp MACH_MX50_RDP MX50_RDP 2988
+universal_c210 MACH_UNIVERSAL_C210 UNIVERSAL_C210 2989
+real6410 MACH_REAL6410 REAL6410 2990
+spx_sakura MACH_SPX_SAKURA SPX_SAKURA 2991
+ij3k_2440 MACH_IJ3K_2440 IJ3K_2440 2992
+omap3_bc10 MACH_OMAP3_BC10 OMAP3_BC10 2993
+thebe MACH_THEBE THEBE 2994
+rv082 MACH_RV082 RV082 2995
+armlguest MACH_ARMLGUEST ARMLGUEST 2996
+tjinc1000 MACH_TJINC1000 TJINC1000 2997
+dockstar MACH_DOCKSTAR DOCKSTAR 2998
+ax8008 MACH_AX8008 AX8008 2999
+gnet_sgce MACH_GNET_SGCE GNET_SGCE 3000
+pxwnas_500_1000 MACH_PXWNAS_500_1000 PXWNAS_500_1000 3001
+ea20 MACH_EA20 EA20 3002
+awm2 MACH_AWM2 AWM2 3003
+ti8148evm MACH_TI8148EVM TI8148EVM 3004
+tegra_seaboard MACH_TEGRA_SEABOARD TEGRA_SEABOARD 3005
+linkstation_chlv2 MACH_LINKSTATION_CHLV2 LINKSTATION_CHLV2 3006
+tera_pro2_rack MACH_TERA_PRO2_RACK TERA_PRO2_RACK 3007
+rubys MACH_RUBYS RUBYS 3008
+aquarius MACH_AQUARIUS AQUARIUS 3009
+mx53_ard MACH_MX53_ARD MX53_ARD 3010
+mx53_smd MACH_MX53_SMD MX53_SMD 3011
+lswxl MACH_LSWXL LSWXL 3012
+dove_avng_v3 MACH_DOVE_AVNG_V3 DOVE_AVNG_V3 3013
+sdi_ess_9263 MACH_SDI_ESS_9263 SDI_ESS_9263 3014
+jocpu550 MACH_JOCPU550 JOCPU550 3015
+msm8x60_rumi3 MACH_MSM8X60_RUMI3 MSM8X60_RUMI3 3016
+msm8x60_ffa MACH_MSM8X60_FFA MSM8X60_FFA 3017
+yanomami MACH_YANOMAMI YANOMAMI 3018
+gta04 MACH_GTA04 GTA04 3019
+cm_a510 MACH_CM_A510 CM_A510 3020
+omap3_rfs200 MACH_OMAP3_RFS200 OMAP3_RFS200 3021
+kx33xx MACH_KX33XX KX33XX 3022
+ptx7510 MACH_PTX7510 PTX7510 3023
+top9000 MACH_TOP9000 TOP9000 3024
+teenote MACH_TEENOTE TEENOTE 3025
+ts3 MACH_TS3 TS3 3026
+a0 MACH_A0 A0 3027
+fsm9xxx_surf MACH_FSM9XXX_SURF FSM9XXX_SURF 3028
+fsm9xxx_ffa MACH_FSM9XXX_FFA FSM9XXX_FFA 3029
+frrhwcdma60w MACH_FRRHWCDMA60W FRRHWCDMA60W 3030
+remus MACH_REMUS REMUS 3031
+at91cap7xdk MACH_AT91CAP7XDK AT91CAP7XDK 3032
+at91cap7stk MACH_AT91CAP7STK AT91CAP7STK 3033
+kt_sbc_sam9_1 MACH_KT_SBC_SAM9_1 KT_SBC_SAM9_1 3034
+at91sam9263router MACH_ORATISROUTER ORATISROUTER 3035
+armada_xp_db MACH_ARMADA_XP_DB ARMADA_XP_DB 3036
+spdm MACH_SPDM SPDM 3037
+gtib MACH_GTIB GTIB 3038
+dgm3240 MACH_DGM3240 DGM3240 3039
+iv_atlas_i_lpe MACH_ATLAS_I_LPE ATLAS_I_LPE 3040
+htcmega MACH_HTCMEGA HTCMEGA 3041
+tricorder MACH_TRICORDER TRICORDER 3042
+tx28 MACH_TX28 TX28 3043
+bstbrd MACH_BSTBRD BSTBRD 3044
+pwb3090 MACH_PWB3090 PWB3090 3045
+idea6410 MACH_IDEA6410 IDEA6410 3046
+qbc9263 MACH_QBC9263 QBC9263 3047
+borabora MACH_BORABORA BORABORA 3048
+valdez MACH_VALDEZ VALDEZ 3049
+ls9g20 MACH_LS9G20 LS9G20 3050
+mios_v1 MACH_MIOS_V1 MIOS_V1 3051
+s5pc110_crespo MACH_S5PC110_CRESPO S5PC110_CRESPO 3052
+controltek9g20 MACH_CONTROLTEK9G20 CONTROLTEK9G20 3053
+tin307 MACH_TIN307 TIN307 3054
+tin510 MACH_TIN510 TIN510 3055
+ep3505 MACH_EP3517 EP3517 3056
+bluecheese MACH_BLUECHEESE BLUECHEESE 3057
+tem3x30 MACH_TEM3X30 TEM3X30 3058
+harvest_desoto MACH_HARVEST_DESOTO HARVEST_DESOTO 3059
+msm8x60_qrdc MACH_MSM8X60_QRDC MSM8X60_QRDC 3060
+spear900 MACH_SPEAR900 SPEAR900 3061
+pcontrol_g20 MACH_PCONTROL_G20 PCONTROL_G20 3062
+rdstor MACH_RDSTOR RDSTOR 3063
+usdloader MACH_USDLOADER USDLOADER 3064
+tsoploader MACH_TSOPLOADER TSOPLOADER 3065
+kronos MACH_KRONOS KRONOS 3066
+ffcore MACH_FFCORE FFCORE 3067
+mone MACH_MONE MONE 3068
+unit2s MACH_UNIT2S UNIT2S 3069
+acer_a5 MACH_ACER_A5 ACER_A5 3070
+etherpro_isp MACH_ETHERPRO_ISP ETHERPRO_ISP 3071
+stretchs7000 MACH_STRETCHS7000 STRETCHS7000 3072
+p87_smartsim MACH_P87_SMARTSIM P87_SMARTSIM 3073
+tulip MACH_TULIP TULIP 3074
+sunflower MACH_SUNFLOWER SUNFLOWER 3075
+rib MACH_RIB RIB 3076
+clod MACH_CLOD CLOD 3077
+rump MACH_RUMP RUMP 3078
+tenderloin MACH_TENDERLOIN TENDERLOIN 3079
+shortloin MACH_SHORTLOIN SHORTLOIN 3080
+roml1 MACH_CRESPO CRESPO 3081
+antares MACH_ANTARES ANTARES 3082
+wb40n MACH_WB40N WB40N 3083
+herring MACH_HERRING HERRING 3084
+naxy400 MACH_NAXY400 NAXY400 3085
+naxy1200 MACH_NAXY1200 NAXY1200 3086
+vpr200 MACH_VPR200 VPR200 3087
+bug20 MACH_BUG20 BUG20 3088
+goflexnet MACH_GOFLEXNET GOFLEXNET 3089
+torbreck MACH_TORBRECK TORBRECK 3090
+saarb_mg1 MACH_SAARB_MG1 SAARB_MG1 3091
+callisto MACH_CALLISTO CALLISTO 3092
+multhsu MACH_MULTHSU MULTHSU 3093
+saluda MACH_SALUDA SALUDA 3094
+pemp_omap3_apollo MACH_PEMP_OMAP3_APOLLO PEMP_OMAP3_APOLLO 3095
+vc0718 MACH_VC0718 VC0718 3096
+mvblx MACH_MVBLX MVBLX 3097
+inhand_apeiron MACH_INHAND_APEIRON INHAND_APEIRON 3098
+inhand_fury MACH_INHAND_FURY INHAND_FURY 3099
+inhand_siren MACH_INHAND_SIREN INHAND_SIREN 3100
+hdnvp MACH_HDNVP HDNVP 3101
+softwinner MACH_SOFTWINNER SOFTWINNER 3102
+prima2_evb MACH_PRIMA2_EVB PRIMA2_EVB 3103
+nas6210 MACH_NAS6210 NAS6210 3104
+unisdev MACH_UNISDEV UNISDEV 3105
+sbca11 MACH_SBCA11 SBCA11 3106
+saga MACH_SAGA SAGA 3107
+ns_k330 MACH_NS_K330 NS_K330 3108
+tanna MACH_TANNA TANNA 3109
+imate8502 MACH_IMATE8502 IMATE8502 3110
+aspen MACH_ASPEN ASPEN 3111
+daintree_cwac MACH_DAINTREE_CWAC DAINTREE_CWAC 3112
+zmx25 MACH_ZMX25 ZMX25 3113
+maple1 MACH_MAPLE1 MAPLE1 3114
+qsd8x72_surf MACH_QSD8X72_SURF QSD8X72_SURF 3115
+qsd8x72_ffa MACH_QSD8X72_FFA QSD8X72_FFA 3116
+abilene MACH_ABILENE ABILENE 3117
+eigen_ttr MACH_EIGEN_TTR EIGEN_TTR 3118
+iomega_ix2_200 MACH_IOMEGA_IX2_200 IOMEGA_IX2_200 3119
+coretec_vcx7400 MACH_CORETEC_VCX7400 CORETEC_VCX7400 3120
+santiago MACH_SANTIAGO SANTIAGO 3121
+mx257sol MACH_MX257SOL MX257SOL 3122
+strasbourg MACH_STRASBOURG STRASBOURG 3123
+msm8x60_fluid MACH_MSM8X60_FLUID MSM8X60_FLUID 3124
+smartqv5 MACH_SMARTQV5 SMARTQV5 3125
+smartqv3 MACH_SMARTQV3 SMARTQV3 3126
+smartqv7 MACH_SMARTQV7 SMARTQV7 3127
+tegra_paz00 MACH_PAZ00 PAZ00 3128
+acmenetusfoxg20 MACH_ACMENETUSFOXG20 ACMENETUSFOXG20 3129
+htc_willow MACH_HTCWILLOW HTCWILLOW 3130
+fwbd_0404 MACH_FWBD_0404 FWBD_0404 3131
+hdgu MACH_HDGU HDGU 3132
+pyramid MACH_PYRAMID PYRAMID 3133
+epiphan MACH_EPIPHAN EPIPHAN 3134
+omap_bender MACH_OMAP_BENDER OMAP_BENDER 3135
+gurnard MACH_GURNARD GURNARD 3136
+gtl_it5100 MACH_GTL_IT5100 GTL_IT5100 3137
+bcm2708 MACH_BCM2708 BCM2708 3138
+mx51_ggc MACH_MX51_GGC MX51_GGC 3139
+sharespace MACH_SHARESPACE SHARESPACE 3140
+haba_knx_explorer MACH_HABA_KNX_EXPLORER HABA_KNX_EXPLORER 3141
+simtec_kirkmod MACH_SIMTEC_KIRKMOD SIMTEC_KIRKMOD 3142
+crux MACH_CRUX CRUX 3143
+mx51_bravo MACH_MX51_BRAVO MX51_BRAVO 3144
+charon MACH_CHARON CHARON 3145
+picocom3 MACH_PICOCOM3 PICOCOM3 3146
+picocom4 MACH_PICOCOM4 PICOCOM4 3147
+serrano MACH_SERRANO SERRANO 3148
+doubleshot MACH_DOUBLESHOT DOUBLESHOT 3149
+evsy MACH_EVSY EVSY 3150
+huashan MACH_HUASHAN HUASHAN 3151
+lausanne MACH_LAUSANNE LAUSANNE 3152
+emerald MACH_EMERALD EMERALD 3153
+tqma35 MACH_TQMA35 TQMA35 3154
+marvel MACH_MARVEL MARVEL 3155
+manuae MACH_MANUAE MANUAE 3156
+chacha MACH_CHACHA CHACHA 3157
+lemon MACH_LEMON LEMON 3158
+csc MACH_CSC CSC 3159
+gira_knxip_router MACH_GIRA_KNXIP_ROUTER GIRA_KNXIP_ROUTER 3160
+t20 MACH_T20 T20 3161
+hdmini MACH_HDMINI HDMINI 3162
+sciphone_g2 MACH_SCIPHONE_G2 SCIPHONE_G2 3163
+express MACH_EXPRESS EXPRESS 3164
+express_kt MACH_EXPRESS_KT EXPRESS_KT 3165
+maximasp MACH_MAXIMASP MAXIMASP 3166
+nitrogen_imx51 MACH_NITROGEN_IMX51 NITROGEN_IMX51 3167
+nitrogen_imx53 MACH_NITROGEN_IMX53 NITROGEN_IMX53 3168
+sunfire MACH_SUNFIRE SUNFIRE 3169
+arowana MACH_AROWANA AROWANA 3170
+tegra_daytona MACH_TEGRA_DAYTONA TEGRA_DAYTONA 3171
+tegra_swordfish MACH_TEGRA_SWORDFISH TEGRA_SWORDFISH 3172
+edison MACH_EDISON EDISON 3173
+svp8500v1 MACH_SVP8500V1 SVP8500V1 3174
+svp8500v2 MACH_SVP8500V2 SVP8500V2 3175
+svp5500 MACH_SVP5500 SVP5500 3176
+b5500 MACH_B5500 B5500 3177
+s5500 MACH_S5500 S5500 3178
+icon MACH_ICON ICON 3179
+elephant MACH_ELEPHANT ELEPHANT 3180
+msm8x60_charm_surf MACH_MSM8X60_FUSION MSM8X60_FUSION 3181
+shooter MACH_SHOOTER SHOOTER 3182
+spade_lte MACH_SPADE_LTE SPADE_LTE 3183
+philhwani MACH_PHILHWANI PHILHWANI 3184
+gsncomm MACH_GSNCOMM GSNCOMM 3185
+strasbourg_a2 MACH_STRASBOURG_A2 STRASBOURG_A2 3186
+mmm MACH_MMM MMM 3187
+davinci_dm365_bv MACH_DAVINCI_DM365_BV DAVINCI_DM365_BV 3188
+ag5evm MACH_AG5EVM AG5EVM 3189
+sc575plc MACH_SC575PLC SC575PLC 3190
+sc575hmi MACH_SC575IPC SC575IPC 3191
+omap3_tdm3730 MACH_OMAP3_TDM3730 OMAP3_TDM3730 3192
+rover_g7 MACH_G7 G7 3193
+top9000_eval MACH_TOP9000_EVAL TOP9000_EVAL 3194
+top9000_su MACH_TOP9000_SU TOP9000_SU 3195
+utm300 MACH_UTM300 UTM300 3196
+tsunagi MACH_TSUNAGI TSUNAGI 3197
+ts75xx MACH_TS75XX TS75XX 3198
+msm8x60_charm_ffa MACH_MSM8X60_FUSN_FFA MSM8X60_FUSN_FFA 3199
+ts47xx MACH_TS47XX TS47XX 3200
+da850_k5 MACH_DA850_K5 DA850_K5 3201
+ax502 MACH_AX502 AX502 3202
+igep0032 MACH_IGEP0032 IGEP0032 3203
+antero MACH_ANTERO ANTERO 3204
+synergy MACH_SYNERGY SYNERGY 3205
+ics_if_voip MACH_ICS_IF_VOIP ICS_IF_VOIP 3206
+wlf_cragg_6410 MACH_WLF_CRAGG_6410 WLF_CRAGG_6410 3207
+punica MACH_PUNICA PUNICA 3208
+sbc_nt250 MACH_SBC_NT250 SBC_NT250 3209
+mx27_wmultra MACH_MX27_WMULTRA MX27_WMULTRA 3210
+mackerel MACH_MACKEREL MACKEREL 3211
+pvd_imx27 MACH_MACH_PVD_IMX27 MACH_PVD_IMX27 3212
+fa9x27 MACH_FA9X27 FA9X27 3213
+ns2816tb MACH_NS2816TB NS2816TB 3214
+ns2816_ntpad MACH_NS2816_NTPAD NS2816_NTPAD 3215
+ns2816_ntnb MACH_NS2816_NTNB NS2816_NTNB 3216
+kaen MACH_KAEN KAEN 3217
+nv1000 MACH_NV1000 NV1000 3218
+nuc950ts MACH_NUC950TS NUC950TS 3219
+nokia_rm680 MACH_NOKIA_RM680 NOKIA_RM680 3220
+ast2200 MACH_AST2200 AST2200 3221
+lead MACH_LEAD LEAD 3222
+unino1 MACH_UNINO1 UNINO1 3223
+greeco MACH_GREECO GREECO 3224
+verdi MACH_VERDI VERDI 3225
+dm6446_adbox MACH_DM6446_ADBOX DM6446_ADBOX 3226
+quad_salsa MACH_QUAD_SALSA QUAD_SALSA 3227
+abb_gma_1_1 MACH_ABB_GMA_1_1 ABB_GMA_1_1 3228
+svcid MACH_SVCID SVCID 3229
+msm8960_sim MACH_MSM8960_SIM MSM8960_SIM 3230
+msm8960_rumi3 MACH_MSM8960_RUMI3 MSM8960_RUMI3 3231
+icon_g MACH_ICON_G ICON_G 3232
+mb3 MACH_MB3 MB3 3233
diff --git a/commands/Kconfig b/commands/Kconfig
index 54160737b8..f137f47324 100644
--- a/commands/Kconfig
+++ b/commands/Kconfig
@@ -372,4 +372,19 @@ config CMD_I2C
include i2c_probe, i2c_read and i2c_write commands to communicate
on i2c bus.
+config CMD_LED
+ bool
+ depends on LED
+ prompt "led command"
+ help
+ include led command to control LEDs
+
+config CMD_LED_TRIGGER
+ bool
+ depends on LED_TRIGGERS
+ prompt "trigger command"
+ help
+ The trigger command allows to control LED triggers from the command
+ line.
+
endmenu
diff --git a/commands/Makefile b/commands/Makefile
index ca30b5f44d..c89adcfff0 100644
--- a/commands/Makefile
+++ b/commands/Makefile
@@ -53,3 +53,5 @@ obj-$(CONFIG_CMD_UBI) += ubi.o
obj-$(CONFIG_CMD_MENU) += menu.o
obj-$(CONFIG_CMD_PASSWD) += passwd.o
obj-$(CONFIG_CMD_LOGIN) += login.o
+obj-$(CONFIG_CMD_LED) += led.o
+obj-$(CONFIG_CMD_LED_TRIGGER) += trigger.o
diff --git a/commands/crc.c b/commands/crc.c
index 0873a1c07e..993074c746 100644
--- a/commands/crc.c
+++ b/commands/crc.c
@@ -134,7 +134,7 @@ static int do_crc(struct command *cmdtp, int argc, char *argv[])
#endif
if (verify && crc != vcrc) {
- printf(" != 0x%08x ** ERROR **", vcrc);
+ printf(" != 0x%08lx ** ERROR **", vcrc);
err = 1;
}
diff --git a/commands/flash.c b/commands/flash.c
index 9a0eb50371..a3f3508f2f 100644
--- a/commands/flash.c
+++ b/commands/flash.c
@@ -63,7 +63,7 @@ static int do_flerase(struct command *cmdtp, int argc, char *argv[])
fd = open(filename, O_WRONLY);
if (fd < 0) {
- printf("open %s:", filename, errno_str());
+ printf("open %s: %s", filename, errno_str());
return 1;
}
@@ -139,7 +139,7 @@ static int do_protect(struct command *cmdtp, int argc, char *argv[])
fd = open(filename, O_WRONLY);
if (fd < 0) {
- printf("open %s:", filename, errno_str());
+ printf("open %s: %s", filename, errno_str());
return 1;
}
diff --git a/commands/go.c b/commands/go.c
index 02629402ad..6082fe54e3 100644
--- a/commands/go.c
+++ b/commands/go.c
@@ -55,7 +55,7 @@ static int do_go(struct command *cmdtp, int argc, char *argv[])
} else
addr = (void *)simple_strtoul(argv[1], NULL, 16);
- printf("## Starting application at 0x%08lX ...\n", addr);
+ printf("## Starting application at 0x%p ...\n", addr);
console_flush();
diff --git a/commands/gpio.c b/commands/gpio.c
index 0cf19fefc9..073c9d3bac 100644
--- a/commands/gpio.c
+++ b/commands/gpio.c
@@ -148,7 +148,7 @@ between @b barebox releases.
- gpio_no: Architecture dependend GPIO number
- initial_value: Output value
-<p> To avoid glitches on the pad the routines will first sett up the
+<p> To avoid glitches on the pad the routines will first set up the
pad's value and afterwards switch the pad to output (if the silicon is
able to do so). If the pad is already configured in non-GPIO mode (if
available), this command may silently fail. </p>
diff --git a/commands/led.c b/commands/led.c
new file mode 100644
index 0000000000..360ce7c77f
--- /dev/null
+++ b/commands/led.c
@@ -0,0 +1,90 @@
+/*
+ * LED command support for barebox
+ *
+ * (C) Copyright 2010 Sascha Hauer, Pengutronix
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <led.h>
+#include <command.h>
+#include <getopt.h>
+#include <errno.h>
+
+static int do_led(struct command *cmdtp, int argc, char *argv[])
+{
+ unsigned long value;
+ struct led *led;
+ int ret;
+
+ if (argc == 1) {
+ int i = 0;
+
+ printf("registered LEDs:\n");
+
+ while ((led = led_by_number(i))) {
+ printf("%-2d: name: %-10s max_value: %d\n",
+ i, led->name ? led->name : "none",
+ led->max_value);
+ i++;
+ }
+ return 0;
+ }
+
+ if (argc != 3)
+ return COMMAND_ERROR_USAGE;
+
+ led = led_by_name_or_number(argv[1]);
+ if (!led) {
+ printf("no such LED: %s\n", argv[1]);
+ return 1;
+ }
+
+ value = simple_strtoul(argv[optind + 1], NULL, 0);
+
+ ret = led_set(led, value);
+ if (ret < 0) {
+ perror("led");
+ return 1;
+ }
+
+ return 0;
+}
+
+/**
+ * @page led_command
+
+The exact meaning of <value> is unspecified. It can be a color in case of rgb
+LEDs or a brightness if this is controllable. In most cases only 1 for enabled
+is allowed.
+
+*/
+
+BAREBOX_CMD_HELP_START(led)
+BAREBOX_CMD_HELP_USAGE("led <led> <value>\n")
+BAREBOX_CMD_HELP_SHORT("control the value of a LED. a value of 0 means disabled\n")
+BAREBOX_CMD_HELP_SHORT("without arguments the available LEDs are listed\n")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(led)
+ .cmd = do_led,
+ .usage = "led <led> <value>",
+ BAREBOX_CMD_HELP(cmd_led_help)
+BAREBOX_CMD_END
diff --git a/commands/loadb.c b/commands/loadb.c
index faf4a97f6b..439a83a45c 100644
--- a/commands/loadb.c
+++ b/commands/loadb.c
@@ -625,7 +625,6 @@ static ulong load_serial_ymodem(void)
int res, wr;
connection_info_t info;
char ymodemBuf[1024];
- ulong store_addr = ~0;
ulong addr = 0;
size = 0;
@@ -802,7 +801,7 @@ static const __maybe_unused char cmd_loadb_help[] =
" -f file - where to download to - defaults to " DEF_FILE "\n"
" -o offset - what offset to download - defaults to 0\n"
" -b baud - baudrate at which to download - defaults to "
- "console baudrate"
+ "console baudrate\n"
" -c - Create file if it is not present - default disabled";
#ifdef CONFIG_CMD_LOADB
BAREBOX_CMD_START(loadb)
diff --git a/commands/ls.c b/commands/ls.c
index 4f9c408b1d..278a8bcad2 100644
--- a/commands/ls.c
+++ b/commands/ls.c
@@ -32,10 +32,10 @@
static void ls_one(const char *path, struct stat *s)
{
char modestr[11];
- unsigned long namelen = strlen(path);
+ unsigned int namelen = strlen(path);
mkmodestr(s->st_mode, modestr);
- printf("%s %10u %*.*s\n", modestr, s->st_size, namelen, namelen, path);
+ printf("%s %10lu %*.*s\n", modestr, s->st_size, namelen, namelen, path);
}
int ls(const char *path, ulong flags)
diff --git a/commands/menu.c b/commands/menu.c
index b9d66996a4..c3e090170a 100644
--- a/commands/menu.c
+++ b/commands/menu.c
@@ -119,7 +119,7 @@ static int do_menu_entry_remove(struct cmd_menu *cm)
me = menu_entry_get_by_num(m, cm->num);
if (!me) {
- eprintf("Entry '%s' not found\n", cm->num);
+ eprintf("Entry '%i' not found\n", cm->num);
return -EINVAL;
}
diff --git a/commands/trigger.c b/commands/trigger.c
new file mode 100644
index 0000000000..162da97c9b
--- /dev/null
+++ b/commands/trigger.c
@@ -0,0 +1,107 @@
+/*
+ * LED trigger command support for barebox
+ *
+ * (C) Copyright 2010 Sascha Hauer, Pengutronix
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <led.h>
+#include <command.h>
+#include <getopt.h>
+#include <errno.h>
+
+#define LED_COMMAND_SET_TRIGGER 1
+#define LED_COMMAND_SHOW_INFO 2
+#define LED_COMMAND_DISABLE_TRIGGER 3
+
+static char *trigger_names[] = {
+ [LED_TRIGGER_PANIC] = "panic",
+ [LED_TRIGGER_HEARTBEAT] = "heartbeat",
+ [LED_TRIGGER_NET_RX] = "net rx",
+ [LED_TRIGGER_NET_TX] = "net tx",
+ [LED_TRIGGER_NET_TXRX] = "net",
+};
+
+static int do_trigger(struct command *cmdtp, int argc, char *argv[])
+{
+ struct led *led;
+ int i, opt, ret = 0;
+ int cmd = LED_COMMAND_SHOW_INFO;
+ unsigned long trigger = 0;
+
+ while((opt = getopt(argc, argv, "t:d:")) > 0) {
+ switch(opt) {
+ case 't':
+ trigger = simple_strtoul(optarg, NULL, 0);
+ cmd = LED_COMMAND_SET_TRIGGER;
+ break;
+ case 'd':
+ trigger = simple_strtoul(optarg, NULL, 0);
+ cmd = LED_COMMAND_DISABLE_TRIGGER;
+ }
+ }
+
+ switch (cmd) {
+ case LED_COMMAND_SHOW_INFO:
+ for (i = 0; i < LED_TRIGGER_MAX; i++) {
+ int led = led_get_trigger(i);
+ printf("%d: %s", i, trigger_names[i]);
+ if (led >= 0)
+ printf(" (led %d)", led);
+ printf("\n");
+ }
+ break;
+
+ case LED_COMMAND_DISABLE_TRIGGER:
+ led_set_trigger(trigger, NULL);
+ return 0;
+ case LED_COMMAND_SET_TRIGGER:
+ if (argc - optind != 1)
+ return COMMAND_ERROR_USAGE;
+ led = led_by_name_or_number(argv[optind]);
+
+ if (!led) {
+ printf("no such led: %d\n", argv[optind]);
+ return 1;
+ }
+
+ ret = led_set_trigger(trigger, led);
+ break;
+ }
+
+ if (ret)
+ printf("trigger failed: %s\n", strerror(-ret));
+ return ret ? 1 : 0;
+}
+
+BAREBOX_CMD_HELP_START(trigger)
+BAREBOX_CMD_HELP_USAGE("trigger [OPTIONS]\n")
+BAREBOX_CMD_HELP_SHORT("control a LED trigger. Without options the currently assigned triggers are shown.\n")
+BAREBOX_CMD_HELP_OPT ("-t <trigger> <led>", "set a trigger for a led\n")
+BAREBOX_CMD_HELP_OPT ("-d <trigger>", "disable a trigger\n")
+BAREBOX_CMD_HELP_END
+
+BAREBOX_CMD_START(trigger)
+ .cmd = do_trigger,
+ .usage = "handle LED triggers",
+ BAREBOX_CMD_HELP(cmd_trigger_help)
+BAREBOX_CMD_END
+
diff --git a/commands/xyzModem.c b/commands/xyzModem.c
index 1dd255d8e3..71d7d6864d 100644
--- a/commands/xyzModem.c
+++ b/commands/xyzModem.c
@@ -492,7 +492,7 @@ int xyzModem_stream_open(connection_info_t *info, int *err)
xyzModem_CHAR_TIMEOUT);
#else
/* TODO: CHECK ! */
- int dummy;
+ int dummy = 0;
xyz.__chan = &dummy;
#endif
xyz.len = 0;
diff --git a/common/Kconfig b/common/Kconfig
index 617f640a57..02bc67ed90 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -414,6 +414,9 @@ config DEFAULT_ENVIRONMENT_PATH
Relative pathes will be relative to the barebox Toplevel dir, but absolute
pathes are fine aswell.
+config POLLER
+ bool "generic polling infrastructure"
+
endmenu
menu "Debugging "
diff --git a/common/Makefile b/common/Makefile
index 753455b64f..98c9d36c12 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -5,6 +5,7 @@ obj-$(CONFIG_OF_FLAT_TREE) += ft_build.o
obj-$(CONFIG_KALLSYMS) += kallsyms.o
obj-$(CONFIG_ENV_HANDLING) += environment.o
obj-$(CONFIG_AUTO_COMPLETE) += complete.o
+obj-$(CONFIG_POLLER) += poller.o
obj-y += dlmalloc.o
obj-y += clock.o
diff --git a/common/console.c b/common/console.c
index 82786f2b03..39ead4b58b 100644
--- a/common/console.c
+++ b/common/console.c
@@ -34,6 +34,7 @@
#include <clock.h>
#include <kfifo.h>
#include <module.h>
+#include <poller.h>
#include <linux/list.h>
LIST_HEAD(console_list);
@@ -205,6 +206,8 @@ int getc(void)
*/
start = get_time_ns();
while (1) {
+ poller_call();
+
if (tstc()) {
kfifo_putc(console_input_buffer, getc_raw());
@@ -397,6 +400,8 @@ EXPORT_SYMBOL(vprintf);
/* test if ctrl-c was pressed */
int ctrlc (void)
{
+ poller_call();
+
if (tstc() && getc() == 3)
return 1;
return 0;
diff --git a/common/console_simple.c b/common/console_simple.c
index 7695e05ecb..1b58deaff7 100644
--- a/common/console_simple.c
+++ b/common/console_simple.c
@@ -3,6 +3,8 @@
#include <fs.h>
#include <errno.h>
+LIST_HEAD(console_list);
+EXPORT_SYMBOL(console_list);
static struct console_device *console;
int printf (const char *fmt, ...)
@@ -43,6 +45,25 @@ int vprintf (const char *fmt, va_list args)
}
EXPORT_SYMBOL(vprintf);
+void fprintf (int file, const char *fmt, ...)
+{
+ va_list args;
+ uint i;
+ char printbuffer[CFG_PBSIZE];
+
+ va_start (args, fmt);
+
+ /* For this to work, printbuffer must be larger than
+ * anything we ever want to print.
+ */
+ i = vsprintf (printbuffer, fmt, args);
+ va_end (args);
+
+ /* Print the string */
+ fputs(file, printbuffer);
+}
+EXPORT_SYMBOL(fprintf);
+
void console_puts(unsigned int ch, const char *str)
{
const char *s = str;
@@ -127,7 +148,10 @@ EXPORT_SYMBOL(ctrlc);
int console_register(struct console_device *newcdev)
{
- if (!console)
+ if (!console) {
console = newcdev;
+ console_list.prev = console_list.next = &newcdev->list;
+ newcdev->list.prev = newcdev->list.next = &console_list;
+ }
return 0;
}
diff --git a/common/poller.c b/common/poller.c
new file mode 100644
index 0000000000..0583a532cf
--- /dev/null
+++ b/common/poller.c
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2010 Marc Kleine-Budde <mkl@pengutronix.de>
+ *
+ * This file is released under the GPLv2
+ *
+ */
+
+#include <common.h>
+#include <driver.h>
+#include <malloc.h>
+#include <module.h>
+#include <param.h>
+#include <poller.h>
+
+static LIST_HEAD(poller_list);
+static int poller_active;
+
+int poller_register(struct poller_struct *poller)
+{
+ list_add_tail(&poller->list, &poller_list);
+
+ return 0;
+}
+
+int poller_unregister(struct poller_struct *poller)
+{
+ list_del(&poller->list);
+
+ return 0;
+}
+
+void poller_call(void)
+{
+ struct poller_struct *poller, *tmp;
+
+ if (poller_active)
+ return;
+
+ poller_active = 1;
+
+ list_for_each_entry_safe(poller, tmp, &poller_list, list)
+ poller->func(poller);
+
+ poller_active = 0;
+}
diff --git a/common/startup.c b/common/startup.c
index 84a59c5cae..0d7ccb9487 100644
--- a/common/startup.c
+++ b/common/startup.c
@@ -55,7 +55,7 @@ static void display_meminfo(void)
printf("Malloc space: 0x%08lx -> 0x%08lx (size %s)\n",
mstart, mend, size_human_readable(msize));
#ifdef CONFIG_ARM
- printf("Stack space : 0x%08lx -> 0x%08lx (size %s)\n",
+ printf("Stack space : 0x%08x -> 0x%08x (size %s)\n",
STACK_BASE, STACK_BASE + STACK_SIZE,
size_human_readable(STACK_SIZE));
#endif
diff --git a/drivers/Kconfig b/drivers/Kconfig
index d94017bfc1..86d8fb54cc 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -12,5 +12,6 @@ source "drivers/video/Kconfig"
source "drivers/mci/Kconfig"
source "drivers/clk/Kconfig"
source "drivers/mfd/Kconfig"
+source "drivers/led/Kconfig"
endmenu
diff --git a/drivers/Makefile b/drivers/Makefile
index 242a564dd7..b1b402fb49 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -10,3 +10,4 @@ obj-$(CONFIG_MCI) += mci/
obj-$(CONFIG_VIDEO) += video/
obj-y += clk/
obj-y += mfd/
+obj-$(CONFIG_LED) += led/
diff --git a/drivers/led/Kconfig b/drivers/led/Kconfig
new file mode 100644
index 0000000000..106093b722
--- /dev/null
+++ b/drivers/led/Kconfig
@@ -0,0 +1,21 @@
+menuconfig LED
+ bool "LED support"
+
+if LED
+
+config LED_GPIO
+ bool "gpio LED support"
+ depends on GENERIC_GPIO
+
+config LED_GPIO_RGB
+ bool "gpio rgb LED support"
+ depends on LED_GPIO
+
+config LED_TRIGGERS
+ select POLLER
+ bool "LED triggers support"
+ help
+ This allows to assign certain triggers like heartbeat or network
+ activity to LEDs.
+
+endif
diff --git a/drivers/led/Makefile b/drivers/led/Makefile
new file mode 100644
index 0000000000..6aafa6df05
--- /dev/null
+++ b/drivers/led/Makefile
@@ -0,0 +1,3 @@
+obj-$(CONFIG_LED) += core.o
+obj-$(CONFIG_LED_GPIO) += led-gpio.o
+obj-$(CONFIG_LED_TRIGGERS) += led-triggers.o
diff --git a/drivers/led/core.c b/drivers/led/core.c
new file mode 100644
index 0000000000..748a978b98
--- /dev/null
+++ b/drivers/led/core.c
@@ -0,0 +1,157 @@
+/*
+ * core LED support for barebox
+ *
+ * (C) Copyright 2010 Sascha Hauer, Pengutronix
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <command.h>
+#include <linux/list.h>
+#include <errno.h>
+#include <asm/gpio.h>
+#include <led.h>
+#include <poller.h>
+#include <clock.h>
+#include <linux/ctype.h>
+
+/**
+ * @file
+ * @brief LED framework
+ *
+ * This file contains the core LED framework for barebox.
+ *
+ * Each LED can be set to a value where 0 means disabled and values
+ * > 0 mean enabled. LEDs can have different enable values where the
+ * exact meaning depends on the LED, for example a gpio controlled rgb
+ * LED can have enable values from 1 to 7 which correspond to different
+ * colors. value could also mean a brightness.
+ * Each LED is assigned a number. numbers start with 0 and are increased
+ * with each registered LED. The number stays the same during lifecycle,
+ * gaps because of unregistered LEDs are not filled up.
+ */
+
+static LIST_HEAD(leds);
+static int num_leds;
+
+/**
+ * led_by_number - get the number of a LED
+ * @param num number of the LED to return
+ */
+struct led *led_by_number(int num)
+{
+ struct led *led;
+
+ list_for_each_entry(led, &leds, list) {
+ if (led->num == num)
+ return led;
+ }
+
+ return NULL;
+}
+
+/**
+ * led_by_name - get a LED with its name
+ * @param name name of the LED
+ */
+struct led *led_by_name(const char *name)
+{
+ struct led *led;
+
+ list_for_each_entry(led, &leds, list) {
+ if (led->name && !strcmp(led->name, name))
+ return led;
+ }
+
+ return NULL;
+}
+
+/**
+ * led_by_name_or_number - get a LED with its name or number
+ * @param str if first character of str is a digit led_by_number
+ * is returned, led_by_name otherwise.
+ */
+struct led *led_by_name_or_number(const char *str)
+{
+ if (isdigit(*str)) {
+ int l;
+
+ l = simple_strtoul(str, NULL, 0);
+
+ return led_by_number(l);
+ } else {
+ return led_by_name(str);
+ }
+}
+
+/**
+ * led_set - set the value of a LED
+ * @param led the led
+ * @param value the value of the LED (0 is disabled)
+ */
+int led_set(struct led *led, unsigned int value)
+{
+ if (value > led->max_value)
+ value = led->max_value;
+
+ led->set(led, value);
+
+ return 0;
+}
+
+/**
+ * led_set_num - set the value of a LED
+ * @param num the number of the LED
+ * @param value the value of the LED (0 is disabled)
+ */
+int led_set_num(int num, unsigned int value)
+{
+ struct led *led = led_by_number(num);
+
+ if (!led)
+ return -ENODEV;
+
+ return led_set(led, value);
+}
+
+/**
+ * led_register - Register a LED
+ * @param led the led
+ */
+int led_register(struct led *led)
+{
+ if (led->name && led_by_name(led->name))
+ return -EBUSY;
+
+ led->num = num_leds++;
+
+ list_add_tail(&led->list, &leds);
+
+ return 0;
+}
+
+/**
+ * led_unregister - Unegister a LED
+ * @param led the led
+ */
+void led_unregister(struct led *led)
+{
+ list_del(&led->list);
+}
diff --git a/drivers/led/led-gpio.c b/drivers/led/led-gpio.c
new file mode 100644
index 0000000000..10c25c6fbb
--- /dev/null
+++ b/drivers/led/led-gpio.c
@@ -0,0 +1,94 @@
+/*
+ * gpio LED support for barebox
+ *
+ * (C) Copyright 2010 Sascha Hauer, Pengutronix
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+#include <led.h>
+#include <asm/gpio.h>
+
+static void led_gpio_set(struct led *led, unsigned int value)
+{
+ struct gpio_led *gpio_led = container_of(led, struct gpio_led, led);
+
+ gpio_direction_output(gpio_led->gpio, !!value ^ gpio_led->active_low);
+}
+
+/**
+ * led_gpio_register - register a gpio controlled LED
+ * @param led The gpio LED
+ *
+ * This function registers a single gpio as a LED. led->gpio
+ * should be initialized to the gpio to control.
+ */
+int led_gpio_register(struct gpio_led *led)
+{
+ led->led.set = led_gpio_set;
+ led->led.max_value = 1;
+
+ return led_register(&led->led);
+}
+
+/**
+ * led_gpio_unregister - remove a gpio controlled LED from the framework
+ * @param led The gpio LED
+ */
+void led_gpio_unregister(struct gpio_led *led)
+{
+ led_unregister(&led->led);
+}
+
+#ifdef CONFIG_LED_GPIO_RGB
+
+static void led_gpio_rgb_set(struct led *led, unsigned int value)
+{
+ struct gpio_rgb_led *rgb = container_of(led, struct gpio_rgb_led, led);
+ int al = rgb->active_low;
+
+ gpio_direction_output(rgb->gpio_r, !!(value & 4) ^ al);
+ gpio_direction_output(rgb->gpio_g, !!(value & 2) ^ al);
+ gpio_direction_output(rgb->gpio_b, !!(value & 1) ^ al);
+}
+
+/**
+ * led_gpio_rgb_register - register three gpios as a rgb LED
+ * @param led The gpio rg LED
+ *
+ * This function registers three gpios as a rgb LED. led->gpio[rgb]
+ * should be initialized to the gpios to control.
+ */
+int led_gpio_rgb_register(struct gpio_rgb_led *led)
+{
+ led->led.set = led_gpio_rgb_set;
+ led->led.max_value = 7;
+
+ return led_register(&led->led);
+}
+
+/**
+ * led_gpio_rgb_unregister - remove a gpio controlled rgb LED from the framework
+ * @param led The gpio LED
+ */
+void led_gpio_rgb_unregister(struct gpio_led *led)
+{
+ led_unregister(&led->led);
+}
+#endif /* CONFIG_LED_GPIO_RGB */
diff --git a/drivers/led/led-triggers.c b/drivers/led/led-triggers.c
new file mode 100644
index 0000000000..764b4e79dc
--- /dev/null
+++ b/drivers/led/led-triggers.c
@@ -0,0 +1,153 @@
+/*
+ * LED trigger support for barebox
+ *
+ * (C) Copyright 2010 Sascha Hauer, Pengutronix
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <poller.h>
+#include <errno.h>
+#include <clock.h>
+#include <led.h>
+#include <init.h>
+
+/**
+ * @file
+ * @brief LED trigger framework
+ *
+ * This file contains triggers which can be associated to LEDs.
+ *
+ * With this framework LEDs can be associated to different events.
+ * An event can be a heartbeat, network activity or panic.
+ * led_trigger() is the central function which is called in the
+ * different barebox frameworks to trigger an event.
+ *
+ * currently there are the following triggers are defined:
+ *
+ * led_trigger_panic: triggered in panic()
+ * led_trigger_heartbeat: shows the heartbeat of barebox. Blinks as long
+ * barebox is up and running.
+ * led_trigger_net_rx: Triggered during network packet reception
+ * led_trigger_net_tx: Triggered during network packet transmission
+ * led_trigger_net_txrx: combination of the two above
+ */
+
+struct led_trigger_struct {
+ struct led *led;
+ uint64_t flash_start;
+};
+
+static struct led_trigger_struct triggers[LED_TRIGGER_MAX];
+
+static void trigger_func(struct poller_struct *poller)
+{
+ int i;
+
+ for (i = 0; i < LED_TRIGGER_MAX; i++) {
+ if (triggers[i].led &&
+ triggers[i].flash_start &&
+ is_timeout(triggers[i].flash_start, 200 * MSECOND)) {
+ led_set(triggers[i].led, 0);
+ }
+ }
+
+ if (triggers[LED_TRIGGER_HEARTBEAT].led &&
+ is_timeout(triggers[LED_TRIGGER_HEARTBEAT].flash_start, SECOND))
+ led_trigger(LED_TRIGGER_HEARTBEAT, TRIGGER_FLASH);
+}
+
+static struct poller_struct trigger_poller = {
+ .func = trigger_func,
+};
+
+/**
+ * led_trigger - triggers a trigger
+ * @param trigger The trigger to enable/disable
+ * @param enable true if enable
+ *
+ * Enable/disable a LED for a given trigger.
+ */
+void led_trigger(enum led_trigger trigger, enum trigger_type type)
+{
+ if (trigger >= LED_TRIGGER_MAX)
+ return;
+ if (!triggers[trigger].led)
+ return;
+
+ if (type == TRIGGER_FLASH) {
+ if (is_timeout(triggers[trigger].flash_start, 400 * MSECOND)) {
+ led_set(triggers[trigger].led, 1);
+ triggers[trigger].flash_start = get_time_ns();
+ }
+ return;
+ }
+
+ led_set(triggers[trigger].led, type == TRIGGER_ENABLE ? 1 : 0);
+}
+
+/**
+ * led_set_trigger - set the LED for a trigger
+ * @param trigger The trigger to set a LED for
+ * @param led The LED
+ *
+ * This function associates a trigger with a LED. Pass led = NULL
+ * to disable a trigger
+ */
+int led_set_trigger(enum led_trigger trigger, struct led *led)
+{
+ int i;
+
+ if (trigger >= LED_TRIGGER_MAX)
+ return -EINVAL;
+
+ if (led)
+ for (i = 0; i < LED_TRIGGER_MAX; i++)
+ if (triggers[i].led == led)
+ return -EBUSY;
+
+ if (triggers[trigger].led && !led)
+ led_set(triggers[trigger].led, 0);
+
+ triggers[trigger].led = led;
+
+ return 0;
+}
+
+/**
+ * led_get_trigger - get the LED for a trigger
+ * @param trigger The trigger to set a LED for
+ *
+ * return the LED number of a trigger.
+ */
+int led_get_trigger(enum led_trigger trigger)
+{
+ if (trigger >= LED_TRIGGER_MAX)
+ return -EINVAL;
+ if (!triggers[trigger].led)
+ return -ENODEV;
+ return led_get_number(triggers[trigger].led);
+}
+
+int trigger_init(void)
+{
+ return poller_register(&trigger_poller);
+}
+late_initcall(trigger_init);
diff --git a/drivers/mci/Kconfig b/drivers/mci/Kconfig
index b1f2773354..ee04079c38 100644
--- a/drivers/mci/Kconfig
+++ b/drivers/mci/Kconfig
@@ -28,11 +28,11 @@ config MCI_INFO
comment "--- MCI host drivers ---"
config MCI_STM378X
- bool "i.MX23"
+ bool "i.MX23/i.MX28"
depends on ARCH_STM
help
Enable this entry to add support to read and write SD cards on a
- i.MX23 based system.
+ i.MX23/i.MX28 based system.
config MCI_S3C
bool "S3C"
diff --git a/drivers/mci/stm378x.c b/drivers/mci/stm378x.c
index 420c2ea92b..94b0f4ad99 100644
--- a/drivers/mci/stm378x.c
+++ b/drivers/mci/stm378x.c
@@ -52,7 +52,7 @@
# define SSP_CTRL0_SFTRST (1 << 31)
# define SSP_CTRL0_CLKGATE (1 << 30)
# define SSP_CTRL0_RUN (1 << 29)
-# define SSP_CTRL0_LOCK_CS (1 << 29)
+# define SSP_CTRL0_LOCK_CS (1 << 27)
# define SSP_CTRL0_READ (1 << 25)
# define SSP_CTRL0_IGNORE_CRC (1 << 26)
# define SSP_CTRL0_DATA_XFER (1 << 24)
@@ -61,37 +61,77 @@
# define SSP_CTRL0_LONG_RESP (1 << 19)
# define SSP_CTRL0_GET_RESP (1 << 17)
# define SSP_CTRL0_ENABLE (1 << 16)
+#ifdef CONFIG_ARCH_IMX23
# define SSP_CTRL0_XFER_COUNT(x) ((x) & 0xffff)
+#endif
#define HW_SSP_CMD0 0x010
# define SSP_CMD0_SLOW_CLK (1 << 22)
# define SSP_CMD0_CONT_CLK (1 << 21)
# define SSP_CMD0_APPEND_8CYC (1 << 20)
+#ifdef CONFIG_ARCH_IMX23
# define SSP_CMD0_BLOCK_SIZE(x) (((x) & 0xf) << 16)
# define SSP_CMD0_BLOCK_COUNT(x) (((x) & 0xff) << 8)
+#endif
# define SSP_CMD0_CMD(x) ((x) & 0xff)
#define HW_SSP_CMD1 0x020
-#define HW_SSP_COMPREF 0x030
-#define HW_SSP_COMPMASK 0x040
-#define HW_SSP_TIMING 0x050
+
+#ifdef CONFIG_ARCH_IMX23
+# define HW_SSP_COMPREF 0x030
+# define HW_SSP_COMPMASK 0x040
+# define HW_SSP_TIMING 0x050
+# define HW_SSP_CTRL1 0x060
+# define HW_SSP_DATA 0x070
+#endif
+#ifdef CONFIG_ARCH_IMX28
+# define HW_SSP_XFER_COUNT 0x30
+# define HW_SSP_BLOCK_SIZE 0x40
+# define SSP_BLOCK_SIZE(x) ((x) & 0xf)
+# define SSP_BLOCK_COUNT(x) (((x) & 0xffffff) << 4)
+# define HW_SSP_COMPREF 0x050
+# define HW_SSP_COMPMASK 0x060
+# define HW_SSP_TIMING 0x070
+# define HW_SSP_CTRL1 0x080
+# define HW_SSP_DATA 0x090
+#endif
+/* bit definition for register HW_SSP_TIMING */
# define SSP_TIMING_TIMEOUT_MASK (0xffff0000)
# define SSP_TIMING_TIMEOUT(x) ((x) << 16)
# define SSP_TIMING_CLOCK_DIVIDE(x) (((x) & 0xff) << 8)
# define SSP_TIMING_CLOCK_RATE(x) ((x) & 0xff)
-#define HW_SSP_CTRL1 0x060
+/* bit definition for register HW_SSP_CTRL1 */
# define SSP_CTRL1_POLARITY (1 << 9)
# define SSP_CTRL1_WORD_LENGTH(x) (((x) & 0xf) << 4)
# define SSP_CTRL1_SSP_MODE(x) ((x) & 0xf)
-#define HW_SSP_DATA 0x070
-#define HW_SSP_SDRESP0 0x080
-#define HW_SSP_SDRESP1 0x090
-#define HW_SSP_SDRESP2 0x0A0
-#define HW_SSP_SDRESP3 0x0B0
+#ifdef CONFIG_ARCH_IMX23
+# define HW_SSP_SDRESP0 0x080
+# define HW_SSP_SDRESP1 0x090
+# define HW_SSP_SDRESP2 0x0A0
+# define HW_SSP_SDRESP3 0x0B0
+#endif
+#ifdef CONFIG_ARCH_IMX28
+# define HW_SSP_SDRESP0 0x0A0
+# define HW_SSP_SDRESP1 0x0B0
+# define HW_SSP_SDRESP2 0x0C0
+# define HW_SSP_SDRESP3 0x0D0
+#endif
+
+#ifdef CONFIG_ARCH_IMX28
+# define HW_SSP_DDR_CTRL 0x0E0
+# define HW_SSP_DLL_CTRL 0x0F0
+#endif
+
+#ifdef CONFIG_ARCH_IMX23
+# define HW_SSP_STATUS 0x0C0
+#endif
+#ifdef CONFIG_ARCH_IMX28
+# define HW_SSP_STATUS 0x100
+#endif
-#define HW_SSP_STATUS 0x0C0
+/* bit definition for register HW_SSP_STATUS */
# define SSP_STATUS_PRESENT (1 << 31)
# define SSP_STATUS_SD_PRESENT (1 << 29)
# define SSP_STATUS_CARD_DETECT (1 << 28)
@@ -111,11 +151,23 @@
SSP_STATUS_RESP_CRC_ERR | SSP_STATUS_RESP_ERR | \
SSP_STATUS_RESP_TIMEOUT | SSP_STATUS_DATA_CRC_ERR | SSP_STATUS_TIMEOUT)
-#define HW_SSP_DEBUG 0x100
-#define HW_SSP_VERSION 0x110
+#ifdef CONFIG_ARCH_IMX28
+# define HW_SSP_DLL_STS 0x110
+#endif
+
+#ifdef CONFIG_ARCH_IMX23
+# define HW_SSP_DEBUG 0x100
+# define HW_SSP_VERSION 0x110
+#endif
+
+#ifdef CONFIG_ARCH_IMX28
+# define HW_SSP_DEBUG 0x120
+# define HW_SSP_VERSION 0x130
+#endif
struct stm_mci_host {
unsigned clock; /* current clock speed in Hz ("0" if disabled) */
+ unsigned index;
#ifdef CONFIG_MCI_INFO
unsigned f_min;
unsigned f_max;
@@ -124,6 +176,18 @@ struct stm_mci_host {
};
/**
+ * Get the SSP clock rate
+ * @param hw_dev Host interface device instance
+ * @return Unit's clock in [Hz]
+ */
+static unsigned get_unit_clock(struct device_d *hw_dev)
+{
+ struct stm_mci_host *host_data = GET_HOST_DATA(hw_dev);
+
+ return imx_get_sspclk(host_data->index);
+}
+
+/**
* Get MCI cards response if defined for the type of command
* @param hw_dev Host interface device instance
* @param cmd Command description
@@ -417,6 +481,7 @@ static int stm_mci_adtc(struct device_d *hw_dev, struct mci_cmd *cmd,
xfer_cnt = log2blocksize = block_cnt = 0;
/* setup command and transfer parameters */
+#ifdef CONFIG_ARCH_IMX23
writel(prepare_transfer_setup(cmd->resp_type, data != NULL ? data->flags : 0) |
SSP_CTRL0_BUS_WIDTH(host_data->bus_width) |
(xfer_cnt != 0 ? SSP_CTRL0_DATA_XFER : 0) | /* command plus data */
@@ -430,6 +495,23 @@ static int stm_mci_adtc(struct device_d *hw_dev, struct mci_cmd *cmd,
SSP_CMD0_BLOCK_COUNT(block_cnt) |
(cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION ? SSP_CMD0_APPEND_8CYC : 0),
hw_dev->map_base + HW_SSP_CMD0);
+#endif
+#ifdef CONFIG_ARCH_IMX28
+ writel(prepare_transfer_setup(cmd->resp_type, data != NULL ? data->flags : 0) |
+ SSP_CTRL0_BUS_WIDTH(host_data->bus_width) |
+ (xfer_cnt != 0 ? SSP_CTRL0_DATA_XFER : 0) | /* command plus data */
+ SSP_CTRL0_ENABLE,
+ hw_dev->map_base + HW_SSP_CTRL0);
+ writel(xfer_cnt, hw_dev->map_base + HW_SSP_XFER_COUNT);
+
+ /* prepare the command and the transfered data count */
+ writel(SSP_CMD0_CMD(cmd->cmdidx) |
+ (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION ? SSP_CMD0_APPEND_8CYC : 0),
+ hw_dev->map_base + HW_SSP_CMD0);
+ writel(SSP_BLOCK_SIZE(log2blocksize) |
+ SSP_BLOCK_COUNT(block_cnt),
+ hw_dev->map_base + HW_SSP_BLOCK_SIZE);
+#endif
/* prepare command's arguments */
writel(cmd->cmdarg, hw_dev->map_base + HW_SSP_CMD1);
@@ -481,10 +563,10 @@ static unsigned setup_clock_speed(struct device_d *hw_dev, unsigned nc)
return 0;
}
- ssp = imx_get_sspclk(0) * 1000;
+ ssp = get_unit_clock(hw_dev);
for (div = 2; div < 255; div += 2) {
- rate = (((ssp + (nc >> 1) ) / nc) + (div >> 1)) / div;
+ rate = DIV_ROUND_CLOSEST(DIV_ROUND_CLOSEST(ssp, nc), div);
if (rate <= 0x100)
break;
}
@@ -657,21 +739,44 @@ static int stm_mci_probe(struct device_d *hw_dev)
host->voltages = pd->voltages;
host->host_caps = pd->caps;
+#ifdef CONFIG_ARCH_IMX23
+ host_data->index = 0; /* there is only one clock for all */
+#endif
+#ifdef CONFIG_ARCH_IMX28
+ /* one dedicated clock per unit */
+ switch (hw_dev->map_base) {
+ case IMX_SSP0_BASE:
+ host_data->index = 0;
+ break;
+ case IMX_SSP1_BASE:
+ host_data->index = 1;
+ break;
+ case IMX_SSP2_BASE:
+ host_data->index = 2;
+ break;
+ case IMX_SSP3_BASE:
+ host_data->index = 3;
+ break;
+ default:
+ pr_debug("Unknown SSP unit at address 0x%08x\n", hw_dev->map_base);
+ return 0;
+ }
+#endif
if (pd->f_min == 0) {
- host->f_min = imx_get_sspclk(0) / 254U / 256U * 1000U;
+ host->f_min = get_unit_clock(hw_dev) / 254 / 256;
pr_debug("Min. frequency is %u Hz\n", host->f_min);
} else {
host->f_min = pd->f_min;
pr_debug("Min. frequency is %u Hz, could be %u Hz\n",
- host->f_min, imx_get_sspclk(0) / 254U / 256U * 1000U);
+ host->f_min, get_unit_clock(hw_dev) / 254 / 256);
}
if (pd->f_max == 0) {
- host->f_max = imx_get_sspclk(0) / 2U / 1U * 1000U;
+ host->f_max = get_unit_clock(hw_dev) / 2 / 1;
pr_debug("Max. frequency is %u Hz\n", host->f_max);
} else {
host->f_max = pd->f_max;
pr_debug("Max. frequency is %u Hz, could be %u Hz\n",
- host->f_max, imx_get_sspclk(0) / 2U / 1U * 1000U);
+ host->f_max, get_unit_clock(hw_dev) / 2 / 1);
}
#ifdef CONFIG_MCI_INFO
diff --git a/drivers/net/fec_imx.c b/drivers/net/fec_imx.c
index 9c8de77dab..e63e42eb1c 100644
--- a/drivers/net/fec_imx.c
+++ b/drivers/net/fec_imx.c
@@ -29,10 +29,13 @@
#include <asm/mmu.h>
#include <asm/io.h>
+#include <mach/generic.h>
#include <mach/imx-regs.h>
#include <clock.h>
#include <mach/clock.h>
-#include <mach/iim.h>
+#ifndef CONFIG_ARCH_STM
+# include <mach/iim.h>
+#endif
#include <xfuncs.h>
#include "fec_imx.h"
@@ -151,6 +154,39 @@ static int fec_tx_task_disable(struct fec_priv *fec)
}
/**
+ * Swap endianess to send data on an i.MX28 based platform
+ * @param buf Pointer to little endian data
+ * @param len Size in words (max. 1500 bytes)
+ * @return Pointer to the big endian data
+ */
+static void *imx28_fix_endianess_wr(uint32_t *buf, unsigned wlen)
+{
+ unsigned u;
+ static uint32_t data[376]; /* = 1500 bytes + 4 bytes */
+
+ for (u = 0; u < wlen; u++, buf++)
+ data[u] = __swab32(*buf);
+
+ return data;
+}
+
+/**
+ * Swap endianess to read data on an i.MX28 based platform
+ * @param buf Pointer to little endian data
+ * @param len Size in words (max. 1500 bytes)
+ *
+ * TODO: Check for the risk of destroying some other data behind the buffer
+ * if its size is not a multiple of 4.
+ */
+static void imx28_fix_endianess_rd(uint32_t *buf, unsigned wlen)
+{
+ unsigned u;
+
+ for (u = 0; u < wlen; u++, buf++)
+ *buf = __swab32(*buf);
+}
+
+/**
* Initialize receive task's buffer descriptors
* @param[in] fec all we know about the device yet
* @param[in] count receive buffer count to be allocated
@@ -233,7 +269,11 @@ static void fec_rbd_clean(int last, struct buffer_descriptor __iomem *pRbd)
static int fec_get_hwaddr(struct eth_device *dev, unsigned char *mac)
{
+#ifdef CONFIG_ARCH_STM
+ return -1;
+#else
return imx_iim_get_mac(mac);
+#endif
}
static int fec_set_hwaddr(struct eth_device *dev, unsigned char *mac)
@@ -270,12 +310,13 @@ static int fec_init(struct eth_device *dev)
/*
* Frame length=1518; 7-wire mode
*/
- writel((1518 << 16), fec->regs + FEC_R_CNTRL);
+ writel(FEC_R_CNTRL_MAX_FL(1518), fec->regs + FEC_R_CNTRL);
} else {
/*
* Frame length=1518; MII mode;
*/
- writel((1518 << 16) | (1 << 2), fec->regs + FEC_R_CNTRL);
+ writel(FEC_R_CNTRL_MAX_FL(1518) | FEC_R_CNTRL_MII_MODE,
+ fec->regs + FEC_R_CNTRL);
/*
* Set MII_SPEED = (1/(mii_speed * 2)) * System Clock
* and do not drop the Preamble.
@@ -285,16 +326,26 @@ static int fec_init(struct eth_device *dev)
}
if (fec->xcv_type == RMII) {
- /* disable the gasket and wait */
- writel(0, fec->regs + FEC_MIIGSK_ENR);
- while (readl(fec->regs + FEC_MIIGSK_ENR) & FEC_MIIGSK_ENR_READY)
- udelay(1);
+ if (cpu_is_mx28()) {
+ /* just another way to enable RMII */
+ uint32_t reg = readl(fec->regs + FEC_R_CNTRL);
+ writel(reg | FEC_R_CNTRL_RMII_MODE
+ /* the linux driver add these bits, why not we? */
+ /* | FEC_R_CNTRL_FCE | */
+ /* FEC_R_CNTRL_NO_LGTH_CHECK */,
+ fec->regs + FEC_R_CNTRL);
+ } else {
+ /* disable the gasket and wait */
+ writel(0, fec->regs + FEC_MIIGSK_ENR);
+ while (readl(fec->regs + FEC_MIIGSK_ENR) & FEC_MIIGSK_ENR_READY)
+ udelay(1);
- /* configure the gasket for RMII, 50 MHz, no loopback, no echo */
- writel(FEC_MIIGSK_CFGR_IF_MODE_RMII, fec->regs + FEC_MIIGSK_CFGR);
+ /* configure the gasket for RMII, 50 MHz, no loopback, no echo */
+ writel(FEC_MIIGSK_CFGR_IF_MODE_RMII, fec->regs + FEC_MIIGSK_CFGR);
- /* re-enable the gasket */
- writel(FEC_MIIGSK_ENR_EN, fec->regs + FEC_MIIGSK_ENR);
+ /* re-enable the gasket */
+ writel(FEC_MIIGSK_ENR_EN, fec->regs + FEC_MIIGSK_ENR);
+ }
}
/*
@@ -419,6 +470,9 @@ static int fec_send(struct eth_device *dev, void *eth_data, int data_length)
* Note: We are always using the first buffer for transmission,
* the second will be empty and only used to stop the DMA engine
*/
+ if (cpu_is_mx28())
+ eth_data = imx28_fix_endianess_wr(eth_data, (data_length + 3) >> 2);
+
writew(data_length, &fec->tbd_base[fec->tbd_index].data_length);
writel((uint32_t)(eth_data), &fec->tbd_base[fec->tbd_index].data_pointer);
@@ -476,18 +530,19 @@ static int fec_recv(struct eth_device *dev)
ievent = readl(fec->regs + FEC_IEVENT);
writel(ievent, fec->regs + FEC_IEVENT);
- if (ievent & (FEC_IEVENT_BABT | FEC_IEVENT_XFIFO_ERROR |
- FEC_IEVENT_RFIFO_ERROR)) {
+ if (ievent & FEC_IEVENT_BABT) {
/* BABT, Rx/Tx FIFO errors */
fec_halt(dev);
fec_init(dev);
printf("some error: 0x%08x\n", ievent);
return 0;
}
- if (ievent & FEC_IEVENT_HBERR) {
- /* Heartbeat error */
- writel(readl(fec->regs + FEC_X_CNTRL) | 0x1,
- fec->regs + FEC_X_CNTRL);
+ if (!cpu_is_mx28()) {
+ if (ievent & FEC_IEVENT_HBERR) {
+ /* Heartbeat error */
+ writel(readl(fec->regs + FEC_X_CNTRL) | 0x1,
+ fec->regs + FEC_X_CNTRL);
+ }
}
if (ievent & FEC_IEVENT_GRA) {
/* Graceful stop complete */
@@ -507,6 +562,12 @@ static int fec_recv(struct eth_device *dev)
if (!(bd_status & FEC_RBD_EMPTY)) {
if ((bd_status & FEC_RBD_LAST) && !(bd_status & FEC_RBD_ERR) &&
((readw(&rbd->data_length) - 4) > 14)) {
+
+ if (cpu_is_mx28())
+ imx28_fix_endianess_rd(
+ (void *)readl(&rbd->data_pointer),
+ (readw(&rbd->data_length) + 3) >> 2);
+
/*
* Get buffer address and size
*/
diff --git a/drivers/net/fec_imx.h b/drivers/net/fec_imx.h
index ce0fd89ec4..e07071a883 100644
--- a/drivers/net/fec_imx.h
+++ b/drivers/net/fec_imx.h
@@ -63,8 +63,19 @@
#define FEC_MIIGSK_ENR_READY (1 << 2)
#define FEC_MIIGSK_ENR_EN (1 << 1)
-
-#define FEC_IEVENT_HBERR 0x80000000
+#define FEC_R_CNTRL_GRS (1 << 31)
+#define FEC_R_CNTRL_NO_LGTH_CHECK (1 << 30)
+#ifdef CONFIG_ARCH_IMX28
+# define FEC_R_CNTRL_MAX_FL(x) (((x) & 0x3fff) << 16)
+#else
+# define FEC_R_CNTRL_MAX_FL(x) (((x) & 0x7ff) << 16)
+#endif
+#define FEC_R_CNTRL_RMII_10T (1 << 9) /* i.MX28 specific */
+#define FEC_R_CNTRL_RMII_MODE (1 << 8) /* i.MX28 specific */
+#define FEC_R_CNTRL_FCE (1 << 5)
+#define FEC_R_CNTRL_MII_MODE (1 << 2)
+
+#define FEC_IEVENT_HBERR 0x80000000 /* Note: Not on i.MX28 */
#define FEC_IEVENT_BABR 0x40000000
#define FEC_IEVENT_BABT 0x20000000
#define FEC_IEVENT_GRA 0x10000000
@@ -73,10 +84,8 @@
#define FEC_IEVENT_LATE_COL 0x00200000
#define FEC_IEVENT_COL_RETRY_LIM 0x00100000
#define FEC_IEVENT_XFIFO_UN 0x00080000
-#define FEC_IEVENT_XFIFO_ERROR 0x00040000
-#define FEC_IEVENT_RFIFO_ERROR 0x00020000
-#define FEC_IMASK_HBERR 0x80000000
+#define FEC_IMASK_HBERR 0x80000000 /* Note: Not on i.MX28 */
#define FEC_IMASK_BABR 0x40000000
#define FEC_IMASK_BABT 0x20000000
#define FEC_IMASK_GRA 0x10000000
@@ -84,8 +93,6 @@
#define FEC_IMASK_LATE_COL 0x00200000
#define FEC_IMASK_COL_RETRY_LIM 0x00100000
#define FEC_IMASK_XFIFO_UN 0x00080000
-#define FEC_IMASK_XFIFO_ERROR 0x00040000
-#define FEC_IMASK_RFIFO_ERROR 0x00020000
#define FEC_RCNTRL_MAX_FL_SHIFT 16
#define FEC_RCNTRL_LOOP 0x01
@@ -124,6 +131,8 @@
* @brief Receive & Transmit Buffer Descriptor definitions
*
* Note: The first BD must be aligned (see DB_ALIGNMENT)
+ *
+ * BTW: Don't trust the i.MX27 and i.MX28 data sheet
*/
struct buffer_descriptor {
uint16_t data_length; /**< payload's length in bytes */
diff --git a/drivers/net/netx_eth.c b/drivers/net/netx_eth.c
index 7d55a61384..fd40f6271a 100644
--- a/drivers/net/netx_eth.c
+++ b/drivers/net/netx_eth.c
@@ -7,7 +7,6 @@
#include <mach/netx-eth.h>
#include <mach/netx-regs.h>
#include <xfuncs.h>
-#include <miidev.h>
#include <init.h>
#include <driver.h>
diff --git a/drivers/nor/cfi_flash.c b/drivers/nor/cfi_flash.c
index 2fa2c6b900..efe87856c4 100644
--- a/drivers/nor/cfi_flash.c
+++ b/drivers/nor/cfi_flash.c
@@ -77,59 +77,40 @@ static uint flash_offset_cfi[2]={FLASH_OFFSET_CFI,FLASH_OFFSET_CFI_ALT};
static void flash_add_byte (struct flash_info *info, cfiword_t * cword, uchar c)
{
-#if defined(__LITTLE_ENDIAN)
- unsigned short w;
- unsigned int l;
- unsigned long long ll;
-#endif
-
if (bankwidth_is_1(info)) {
- cword->c = c;
- } else if (bankwidth_is_2(info)) {
-#if defined(__LITTLE_ENDIAN)
- w = c;
- w <<= 8;
- cword->w = (cword->w >> 8) | w;
-#else
- cword->w = (cword->w << 8) | c;
-#endif
- } else if (bankwidth_is_4(info)) {
-#if defined(__LITTLE_ENDIAN)
- l = c;
- l <<= 24;
- cword->l = (cword->l >> 8) | l;
-#else
- cword->l = (cword->l << 8) | c;
-#endif
- } else if (bankwidth_is_8(info)) {
-#if defined(__LITTLE_ENDIAN)
- ll = c;
- ll <<= 56;
- cword->ll = (cword->ll >> 8) | ll;
+ *cword = c;
+ return;
+ }
+
+#if __BYTE_ORDER == __BIG_ENDIAN
+ *cword = (*cword << 8) | c;
#else
- cword->ll = (cword->ll << 8) | c;
+
+ if (bankwidth_is_2(info))
+ *cword = (*cword >> 8) | (u16)c << 8;
+ else if (bankwidth_is_4(info))
+ *cword = (*cword >> 8) | (u32)c << 24;
+ else if (bankwidth_is_8(info))
+ *cword = (*cword >> 8) | (u64)c << 56;
#endif
- }
}
static int flash_write_cfiword (struct flash_info *info, ulong dest,
cfiword_t cword)
{
- void *dstaddr;
+ void *dstaddr = (void *)dest;
int flag;
- dstaddr = (uchar *) dest;
-
/* Check if Flash is (sufficiently) erased */
- if (bankwidth_is_1(info)) {
- flag = ((flash_read8(dstaddr) & cword.c) == cword.c);
- } else if (bankwidth_is_2(info)) {
- flag = ((flash_read16(dstaddr) & cword.w) == cword.w);
- } else if (bankwidth_is_4(info)) {
- flag = ((flash_read32(dstaddr) & cword.l) == cword.l);
- } else if (bankwidth_is_8(info)) {
- flag = ((flash_read64(dstaddr) & cword.ll) == cword.ll);
- } else
+ if (bankwidth_is_1(info))
+ flag = ((flash_read8(dstaddr) & cword) == cword);
+ else if (bankwidth_is_2(info))
+ flag = ((flash_read16(dstaddr) & cword) == cword);
+ else if (bankwidth_is_4(info))
+ flag = ((flash_read32(dstaddr) & cword) == cword);
+ else if (bankwidth_is_8(info))
+ flag = ((flash_read64(dstaddr) & cword) == cword);
+ else
return 2;
if (!flag)
@@ -185,10 +166,8 @@ static void flash_printqry (struct cfi_qry *qry)
*/
uchar flash_read_uchar (struct flash_info *info, uint offset)
{
- uchar *cp;
-
- cp = flash_make_addr (info, 0, offset);
-#if defined(__LITTLE_ENDIAN)
+ uchar *cp = flash_make_addr(info, 0, offset);
+#if __BYTE_ORDER == __LITTLE_ENDIAN
return flash_read8(cp);
#else
return flash_read8(cp + info->portwidth - 1);
@@ -216,7 +195,7 @@ static ulong flash_read_long (struct flash_info *info, flash_sect_t sect, uint o
debug ("addr[%x] = 0x%x\n", x, flash_read8(addr + x));
}
#endif
-#if defined(__LITTLE_ENDIAN)
+#if __BYTE_ORDER == __LITTLE_ENDIAN
retval = ((flash_read8(addr) << 16) |
(flash_read8(addr + info->portwidth) << 24) |
(flash_read8(addr + 2 * info->portwidth)) |
@@ -485,7 +464,7 @@ static int __cfi_erase(struct cdev *cdev, size_t count, unsigned long offset,
unsigned long start, end;
int i, ret = 0;
- debug("%s: erase 0x%08x (size %d)\n", __func__, offset, count);
+ debug("%s: erase 0x%08lx (size %d)\n", __func__, offset, count);
start = find_sector(finfo, cdev->dev->map_base + offset);
end = find_sector(finfo, cdev->dev->map_base + offset + count - 1);
@@ -498,6 +477,11 @@ static int __cfi_erase(struct cdev *cdev, size_t count, unsigned long offset,
if (ret)
goto out;
+ if (ctrlc()) {
+ ret = -EINTR;
+ goto out;
+ }
+
if (verbose)
show_progress(i - start);
}
@@ -534,7 +518,7 @@ static int write_buff (struct flash_info *info, const uchar * src, ulong addr, u
/* handle unaligned start */
if ((aln = addr - wp) != 0) {
- cword.l = 0;
+ cword = 0;
p = (uchar*)wp;
for (i = 0; i < aln; ++i)
flash_add_byte (info, &cword, flash_read8(p + i));
@@ -560,7 +544,7 @@ static int write_buff (struct flash_info *info, const uchar * src, ulong addr, u
while (cnt >= info->portwidth) {
/* prohibit buffer write when buffer_size is 1 */
if (info->buffer_size == 1) {
- cword.l = 0;
+ cword = 0;
for (i = 0; i < info->portwidth; i++)
flash_add_byte (info, &cword, *src++);
if ((rc = flash_write_cfiword (info, wp, cword)) != 0)
@@ -583,7 +567,7 @@ static int write_buff (struct flash_info *info, const uchar * src, ulong addr, u
}
#else
while (cnt >= info->portwidth) {
- cword.l = 0;
+ cword = 0;
for (i = 0; i < info->portwidth; i++) {
flash_add_byte (info, &cword, *src++);
}
@@ -600,7 +584,7 @@ static int write_buff (struct flash_info *info, const uchar * src, ulong addr, u
/*
* handle unaligned tail bytes
*/
- cword.l = 0;
+ cword = 0;
p = (uchar*)wp;
for (i = 0; (i < info->portwidth) && (cnt > 0); ++i) {
flash_add_byte (info, &cword, *src++);
@@ -651,8 +635,8 @@ static int cfi_protect(struct cdev *cdev, size_t count, unsigned long offset, in
int i, ret = 0;
const char *action = (prot? "protect" : "unprotect");
- printf("%s: %s 0x%08x (size %d)\n", __FUNCTION__,
- action, cdev->dev->map_base + offset, count);
+ printf("%s: %s 0x%08lx (size %d)\n", __FUNCTION__,
+ action, cdev->dev->map_base + offset, count);
start = find_sector(finfo, cdev->dev->map_base + offset);
end = find_sector(finfo, cdev->dev->map_base + offset + count - 1);
@@ -672,7 +656,7 @@ static ssize_t cfi_write(struct cdev *cdev, const void *buf, size_t count, unsig
struct flash_info *finfo = (struct flash_info *)cdev->priv;
int ret;
- debug("cfi_write: buf=0x%08x addr=0x%08x count=0x%08x\n",buf, cdev->dev->map_base + offset, count);
+ debug("cfi_write: buf=0x%p addr=0x%08lx count=0x%08x\n",buf, cdev->dev->map_base + offset, count);
ret = write_buff (finfo, buf, cdev->dev->map_base + offset, count);
return ret == 0 ? count : -1;
@@ -836,17 +820,14 @@ int flash_generic_status_check (struct flash_info *info, flash_sect_t sector,
/*
* make a proper sized command based on the port and chip widths
*/
-void flash_make_cmd (struct flash_info *info, uchar cmd, void *cmdbuf)
+void flash_make_cmd(struct flash_info *info, u8 cmd, cfiword_t *cmdbuf)
{
- int i;
- uchar *cp = (uchar *) cmdbuf;
+ cfiword_t result = 0;
+ int i = info->portwidth / info->chipwidth;
-#if defined(__LITTLE_ENDIAN)
- for (i = info->portwidth; i > 0; i--)
-#else
- for (i = 1; i <= info->portwidth; i++)
-#endif
- *cp++ = (i & (info->chipwidth - 1)) ? '\0' : cmd;
+ while (i--)
+ result = (result << (8 * info->chipwidth)) | cmd;
+ *cmdbuf = result;
}
/*
@@ -860,6 +841,7 @@ void flash_write_cmd (struct flash_info *info, flash_sect_t sect, uint offset, u
addr = flash_make_addr (info, sect, offset);
flash_make_cmd (info, cmd, &cword);
+ debug("%s: %p %lX %X => %p %llX\n", __FUNCTION__, info, sect, offset, addr, cword);
flash_write_word(info, cword, addr);
}
@@ -874,14 +856,14 @@ int flash_isequal (struct flash_info *info, flash_sect_t sect, uint offset, ucha
debug ("is= cmd %x(%c) addr %p ", cmd, cmd, addr);
if (bankwidth_is_1(info)) {
- debug ("is= %x %x\n", flash_read8(addr), cword.c);
- retval = (flash_read8(addr) == cword.c);
+ debug ("is= %x %x\n", flash_read8(addr), (u8)cword);
+ retval = (flash_read8(addr) == cword);
} else if (bankwidth_is_2(info)) {
- debug ("is= %4.4x %4.4x\n", flash_read16(addr), cword.w);
- retval = (flash_read16(addr) == cword.w);
+ debug ("is= %4.4x %4.4x\n", flash_read16(addr), (u16)cword);
+ retval = (flash_read16(addr) == cword);
} else if (bankwidth_is_4(info)) {
- debug ("is= %8.8lx %8.8lx\n", flash_read32(addr), cword.l);
- retval = (flash_read32(addr) == cword.l);
+ debug ("is= %8.8lx %8.8lx\n", flash_read32(addr), (u32)cword);
+ retval = (flash_read32(addr) == cword);
} else if (bankwidth_is_8(info)) {
#ifdef DEBUG
{
@@ -889,11 +871,11 @@ int flash_isequal (struct flash_info *info, flash_sect_t sect, uint offset, ucha
char str2[20];
print_longlong (str1, flash_read32(addr));
- print_longlong (str2, cword.ll);
+ print_longlong (str2, cword);
debug ("is= %s %s\n", str1, str2);
}
#endif
- retval = (flash_read32(addr) == cword.ll);
+ retval = (flash_read64(addr) == cword);
} else
retval = 0;
@@ -902,20 +884,19 @@ int flash_isequal (struct flash_info *info, flash_sect_t sect, uint offset, ucha
int flash_isset (struct flash_info *info, flash_sect_t sect, uint offset, uchar cmd)
{
- void *addr;
+ void *addr = flash_make_addr (info, sect, offset);
cfiword_t cword;
int retval;
- addr = flash_make_addr (info, sect, offset);
flash_make_cmd (info, cmd, &cword);
if (bankwidth_is_1(info)) {
- retval = ((flash_read8(addr) & cword.c) == cword.c);
+ retval = ((flash_read8(addr) & cword) == cword);
} else if (bankwidth_is_2(info)) {
- retval = ((flash_read16(addr) & cword.w) == cword.w);
+ retval = ((flash_read16(addr) & cword) == cword);
} else if (bankwidth_is_4(info)) {
- retval = ((flash_read32(addr) & cword.l) == cword.l);
+ retval = ((flash_read32(addr) & cword) == cword);
} else if (bankwidth_is_8(info)) {
- retval = ((flash_read64(addr) & cword.ll) == cword.ll);
+ retval = ((flash_read64(addr) & cword) == cword);
} else
retval = 0;
@@ -995,7 +976,6 @@ static void cfi_init_mtd(struct flash_info *info)
static int cfi_probe (struct device_d *dev)
{
- unsigned long size = 0;
struct flash_info *info = xzalloc(sizeof(*info));
dev->priv = (void *)info;
@@ -1004,11 +984,12 @@ static int cfi_probe (struct device_d *dev)
/* Init: no FLASHes known */
info->flash_id = FLASH_UNKNOWN;
- size += info->size = flash_get_size(info, dev->map_base);
+ info->cmd_reset = FLASH_CMD_RESET;
+ info->size = flash_get_size(info, dev->map_base);
info->base = (void __iomem *)dev->map_base;
if (dev->size == 0) {
- printf("cfi_probe: size : 0x%08x\n", info->size);
+ printf("cfi_probe: size : 0x%08lx\n", info->size);
dev->size = info->size;
}
diff --git a/drivers/nor/cfi_flash.h b/drivers/nor/cfi_flash.h
index f9023dcafa..90980211e7 100644
--- a/drivers/nor/cfi_flash.h
+++ b/drivers/nor/cfi_flash.h
@@ -25,10 +25,12 @@
*/
#include <driver.h>
+#include <asm/byteorder.h>
#include <asm/io.h>
#include <linux/mtd/mtd.h>
typedef unsigned long flash_sect_t;
+typedef u64 cfiword_t;
struct cfi_cmd_set;
/*-----------------------------------------------------------------------
@@ -238,7 +240,7 @@ int flash_generic_status_check (struct flash_info *info, flash_sect_t sector,
uint64_t tout, char *prompt);
int flash_isequal (struct flash_info *info, flash_sect_t sect, uint offset, uchar cmd);
-void flash_make_cmd (struct flash_info *info, uchar cmd, void *cmdbuf);
+void flash_make_cmd(struct flash_info *info, uchar cmd, cfiword_t *cmdbuf);
static inline void flash_write8(u8 value, void *addr)
{
@@ -316,26 +318,19 @@ u32 jedec_read_mfr(struct flash_info *info);
#define bankwidth_is_8(info) 0
#endif
-typedef union {
- unsigned char c;
- unsigned short w;
- unsigned long l;
- unsigned long long ll;
-} cfiword_t;
-
static inline void flash_write_word(struct flash_info *info, cfiword_t datum, void *addr)
{
if (bankwidth_is_1(info)) {
- debug("fw addr %p val %02x\n", addr, datum.c);
- flash_write8(datum.c, addr);
+ debug("fw addr %p val %02x\n", addr, (u8)datum);
+ flash_write8(datum, addr);
} else if (bankwidth_is_2(info)) {
- debug("fw addr %p val %04x\n", addr, datum.w);
- flash_write16(datum.w, addr);
+ debug("fw addr %p val %04x\n", addr, (u16)datum);
+ flash_write16(datum, addr);
} else if (bankwidth_is_4(info)) {
- debug("fw addr %p val %08x\n", addr, datum.l);
- flash_write32(datum.l, addr);
+ debug("fw addr %p val %08x\n", addr, (u32)datum);
+ flash_write32(datum, addr);
} else if (bankwidth_is_8(info)) {
- flash_write64(datum.ll, addr);
+ flash_write64(datum, addr);
}
}
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index 3a8882fd1d..04d9b98174 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -21,7 +21,7 @@ config DRIVER_SERIAL_IMX
config DRIVER_SERIAL_STM378X
depends on ARCH_STM
default y
- bool "i.MX23 serial driver"
+ bool "i.MX23/i.MX28 serial driver"
config DRIVER_SERIAL_NETX
depends on ARCH_NETX
diff --git a/drivers/serial/stm-serial.c b/drivers/serial/stm-serial.c
index 90563f599e..a225e30cdb 100644
--- a/drivers/serial/stm-serial.c
+++ b/drivers/serial/stm-serial.c
@@ -108,7 +108,7 @@ static int stm_serial_setbaudrate(struct console_device *cdev, int new_baudrate)
writel(0, dev->map_base + UARTDBGCR);
/* Calculate and set baudrate */
- quot = (imx_get_xclk() * 4000) / new_baudrate;
+ quot = (imx_get_xclk() * 4) / new_baudrate;
writel(quot & 0x3f, dev->map_base + UARTDBGFBRD);
writel(quot >> 6, dev->map_base + UARTDBGIBRD);
@@ -134,13 +134,6 @@ static int stm_clocksource_clock_change(struct notifier_block *nb, unsigned long
static int stm_serial_init_port(struct console_device *cdev)
{
struct device_d *dev = cdev->dev;
- /*
- * If the board specific file registers this console we should force
- * the usage of the debug UART pins, to be able to let the user see
- * the output, even if the board file forgets to configure these pins.
- */
- imx_gpio_mode(PWM1_DUART_TX);
- imx_gpio_mode(PWM0_DUART_RX);
/* Disable UART */
writel(0, dev->map_base + UARTDBGCR);
diff --git a/drivers/spi/imx_spi.c b/drivers/spi/imx_spi.c
index 2ad1bfa499..1857d6c672 100644
--- a/drivers/spi/imx_spi.c
+++ b/drivers/spi/imx_spi.c
@@ -224,9 +224,6 @@ static unsigned int cspi_2_3_xchg_single(struct imx_spi *imx, unsigned int data)
return readl(base + CSPI_2_3_RXDATA);
}
-/* FIXME: include/linux/kernel.h */
-#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
-
static unsigned int cspi_2_3_clkdiv(unsigned int fin, unsigned int fspi)
{
/*
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 7a89a3f206..c69308e749 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -20,4 +20,11 @@ config DRIVER_VIDEO_IMX_IPU
Add support for the IPU framebuffer device found on
i.MX31 and i.MX35 CPUs.
+config DRIVER_VIDEO_STM
+ bool "i.MX23/28 framebuffer driver"
+ depends on ARCH_STM
+ help
+ Say 'Y' here to enable framebuffer and splash screen support for
+ i.MX23 and i.MX28 based systems.
+
endif
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 179f0c42f6..a217a0b92b 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -1,4 +1,5 @@
obj-$(CONFIG_VIDEO) += fb.o
+obj-$(CONFIG_DRIVER_VIDEO_STM) += stm.o
obj-$(CONFIG_DRIVER_VIDEO_IMX) += imx.o
obj-$(CONFIG_DRIVER_VIDEO_IMX_IPU) += imx-ipu-fb.o
diff --git a/drivers/video/fb.c b/drivers/video/fb.c
index ab2c5eb2f6..aad0e1f409 100644
--- a/drivers/video/fb.c
+++ b/drivers/video/fb.c
@@ -39,14 +39,13 @@ static int fb_enable_set(struct device_d *dev, struct param_d *param,
enable = simple_strtoul(val, NULL, 0);
- if (info->enabled == !!enable)
- return 0;
-
if (enable) {
- info->fbops->fb_enable(info);
+ if (!info->enabled)
+ info->fbops->fb_enable(info);
new = "1";
} else {
- info->fbops->fb_disable(info);
+ if (info->enabled)
+ info->fbops->fb_disable(info);
new = "0";
}
@@ -57,6 +56,35 @@ static int fb_enable_set(struct device_d *dev, struct param_d *param,
return 0;
}
+static int fb_setup_mode(struct device_d *dev, struct param_d *param,
+ const char *val)
+{
+ struct fb_info *info = dev->priv;
+ int mode, ret;
+
+ if (info->enabled != 0)
+ return -EPERM;
+
+ if (!val)
+ return dev_param_set_generic(dev, param, NULL);
+
+ for (mode = 0; mode < info->num_modes; mode++) {
+ if (!strcmp(info->mode_list[mode].name, val))
+ break;
+ }
+ if (mode >= info->num_modes)
+ return -EINVAL;
+
+ info->mode = &info->mode_list[mode];
+
+ ret = info->fbops->fb_activate_var(info);
+
+ if (ret == 0)
+ dev_param_set_generic(dev, param, val);
+
+ return ret;
+}
+
static struct file_operations fb_ops = {
.read = mem_read,
.write = mem_write,
@@ -88,6 +116,12 @@ int register_framebuffer(struct fb_info *info)
dev_add_param(dev, "enable", fb_enable_set, NULL, 0);
dev_set_param(dev, "enable", "0");
+ if (info->num_modes && (info->mode_list != NULL) &&
+ (info->fbops->fb_activate_var != NULL)) {
+ dev_add_param(dev, "mode_name", fb_setup_mode, NULL, 0);
+ dev_set_param(dev, "mode_name", info->mode_list[0].name);
+ }
+
devfs_create(&info->cdev);
return 0;
diff --git a/drivers/video/stm.c b/drivers/video/stm.c
new file mode 100644
index 0000000000..f0abe4c71e
--- /dev/null
+++ b/drivers/video/stm.c
@@ -0,0 +1,540 @@
+/*
+ * Copyright (C) 2010 Juergen Beisert, Pengutronix <jbe@pengutronix.de>
+ *
+ * This is based on code from:
+ * Author: Vitaly Wool <vital@embeddedalley.com>
+ *
+ * Copyright 2008-2009 Freescale Semiconductor, Inc. All Rights Reserved.
+ * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <common.h>
+#include <init.h>
+#include <driver.h>
+#include <malloc.h>
+#include <errno.h>
+#include <xfuncs.h>
+#include <asm/io.h>
+#include <mach/imx-regs.h>
+#include <mach/clock.h>
+#include <mach/fb.h>
+
+#define HW_LCDIF_CTRL 0x00
+# define CTRL_SFTRST (1 << 31)
+# define CTRL_CLKGATE (1 << 30)
+# define CTRL_BYPASS_COUNT (1 << 19)
+# define CTRL_VSYNC_MODE (1 << 18)
+# define CTRL_DOTCLK_MODE (1 << 17)
+# define CTRL_DATA_SELECT (1 << 16)
+# define SET_BUS_WIDTH(x) (((x) & 0x3) << 10)
+# define SET_WORD_LENGTH(x) (((x) & 0x3) << 8)
+# define GET_WORD_LENGTH(x) (((x) >> 8) & 0x3)
+# define CTRL_MASTER (1 << 5)
+# define CTRL_DF16 (1 << 3)
+# define CTRL_DF18 (1 << 2)
+# define CTRL_DF24 (1 << 1)
+# define CTRL_RUN (1 << 0)
+
+#define HW_LCDIF_CTRL1 0x10
+# define CTRL1_FIFO_CLEAR (1 << 21)
+# define SET_BYTE_PACKAGING(x) (((x) & 0xf) << 16)
+# define GET_BYTE_PACKAGING(x) (((x) >> 16) & 0xf)
+
+#ifdef CONFIG_ARCH_IMX28
+# define HW_LCDIF_CTRL2 0x20
+# define HW_LCDIF_TRANSFER_COUNT 0x30
+#endif
+#ifdef CONFIG_ARCH_IMX23
+# define HW_LCDIF_TRANSFER_COUNT 0x20
+#endif
+# define SET_VCOUNT(x) (((x) & 0xffff) << 16)
+# define SET_HCOUNT(x) ((x) & 0xffff)
+
+#ifdef CONFIG_ARCH_IMX28
+# define HW_LCDIF_CUR_BUF 0x40
+# define HW_LCDIF_NEXT_BUF 0x50
+#endif
+#ifdef CONFIG_ARCH_IMX23
+# define HW_LCDIF_CUR_BUF 0x30
+# define HW_LCDIF_NEXT_BUF 0x40
+#endif
+
+#define HW_LCDIF_TIMING 0x60
+# define SET_CMD_HOLD(x) (((x) & 0xff) << 24)
+# define SET_CMD_SETUP(x) (((x) & 0xff) << 16)
+# define SET_DATA_HOLD(x) (((x) & 0xff) << 8)
+# define SET_DATA_SETUP(x) ((x) & 0xff)
+
+#define HW_LCDIF_VDCTRL0 0x70
+# define VDCTRL0_ENABLE_PRESENT (1 << 28)
+# define VDCTRL0_VSYNC_POL (1 << 27) /* 0 = low active, 1 = high active */
+# define VDCTRL0_HSYNC_POL (1 << 26) /* 0 = low active, 1 = high active */
+# define VDCTRL0_DOTCLK_POL (1 << 25) /* 0 = output@falling, capturing@rising edge */
+# define VDCTRL0_ENABLE_POL (1 << 24) /* 0 = low active, 1 = high active */
+# define VDCTRL0_VSYNC_PERIOD_UNIT (1 << 21)
+# define VDCTRL0_VSYNC_PULSE_WIDTH_UNIT (1 << 20)
+# define VDCTRL0_HALF_LINE (1 << 19)
+# define VDCTRL0_HALF_LINE_MODE (1 << 18)
+# define SET_VSYNC_PULSE_WIDTH(x) ((x) & 0x3ffff)
+
+#define HW_LCDIF_VDCTRL1 0x80
+
+#define HW_LCDIF_VDCTRL2 0x90
+#ifdef CONFIG_ARCH_IMX28
+# define SET_HSYNC_PULSE_WIDTH(x) (((x) & 0x3fff) << 18)
+#endif
+#ifdef CONFIG_ARCH_IMX23
+# define SET_HSYNC_PULSE_WIDTH(x) (((x) & 0xff) << 24)
+#endif
+# define SET_HSYNC_PERIOD(x) ((x) & 0x3ffff)
+
+#define HW_LCDIF_VDCTRL3 0xa0
+# define VDCTRL3_MUX_SYNC_SIGNALS (1 << 29)
+# define VDCTRL3_VSYNC_ONLY (1 << 28)
+# define SET_HOR_WAIT_CNT(x) (((x) & 0xfff) << 16)
+# define SET_VERT_WAIT_CNT(x) ((x) & 0xffff)
+
+#define HW_LCDIF_VDCTRL4 0xb0
+#ifdef CONFIG_ARCH_IMX28
+# define SET_DOTCLK_DLY(x) (((x) & 0x7) << 29)
+#endif
+# define VDCTRL4_SYNC_SIGNALS_ON (1 << 18)
+# define SET_DOTCLK_H_VALID_DATA_CNT(x) ((x) & 0x3ffff)
+
+#define HW_LCDIF_DVICTRL0 0xc0
+#define HW_LCDIF_DVICTRL1 0xd0
+#define HW_LCDIF_DVICTRL2 0xe0
+#define HW_LCDIF_DVICTRL3 0xf0
+#define HW_LCDIF_DVICTRL4 0x100
+
+#ifdef CONFIG_ARCH_IMX28
+# define HW_LCDIF_DATA 0x180
+#endif
+#ifdef CONFIG_ARCH_IMX23
+# define HW_LCDIF_DATA 0x1b0
+#endif
+
+#ifdef CONFIG_ARCH_IMX28
+# define HW_LCDIF_DEBUG0 0x1d0
+#endif
+#ifdef CONFIG_ARCH_IMX23
+# define HW_LCDIF_DEBUG0 0x1f0
+#endif
+# define DEBUG_HSYNC (1 < 26)
+# define DEBUG_VSYNC (1 < 25)
+
+#define RED 0
+#define GREEN 1
+#define BLUE 2
+#define TRANSP 3
+
+struct imxfb_info {
+ void __iomem *base;
+ unsigned memory_size;
+ struct fb_info info;
+ struct device_d *hw_dev;
+ struct imx_fb_videomode *pdata;
+};
+
+/* the RGB565 true colour mode */
+static const struct fb_bitfield def_rgb565[] = {
+ [RED] = {
+ .offset = 11,
+ .length = 5,
+ },
+ [GREEN] = {
+ .offset = 5,
+ .length = 6,
+ },
+ [BLUE] = {
+ .offset = 0,
+ .length = 5,
+ },
+ [TRANSP] = { /* no support for transparency */
+ .length = 0,
+ }
+};
+
+/* the RGB666 true colour mode */
+static const struct fb_bitfield def_rgb666[] = {
+ [RED] = {
+ .offset = 16,
+ .length = 6,
+ },
+ [GREEN] = {
+ .offset = 8,
+ .length = 6,
+ },
+ [BLUE] = {
+ .offset = 0,
+ .length = 6,
+ },
+ [TRANSP] = { /* no support for transparency */
+ .length = 0,
+ }
+};
+
+/* the RGB888 true colour mode */
+static const struct fb_bitfield def_rgb888[] = {
+ [RED] = {
+ .offset = 16,
+ .length = 8,
+ },
+ [GREEN] = {
+ .offset = 8,
+ .length = 8,
+ },
+ [BLUE] = {
+ .offset = 0,
+ .length = 8,
+ },
+ [TRANSP] = { /* no support for transparency */
+ .length = 0,
+ }
+};
+
+static inline unsigned calc_line_length(unsigned ppl, unsigned bpp)
+{
+ if (bpp == 24)
+ bpp = 32;
+ return (ppl * bpp) >> 3;
+}
+
+static int stmfb_memory_mmgt(struct fb_info *fb_info, unsigned size)
+{
+ struct imxfb_info *fbi = fb_info->priv;
+
+ if (fbi->memory_size != 0) {
+ free(fb_info->screen_base);
+ fb_info->screen_base = NULL;
+ fbi->memory_size = 0;
+ }
+
+ if (fbi->memory_size == 0) {
+ fb_info->screen_base = xzalloc(size);
+ fbi->memory_size = size;
+ }
+
+ return 0;
+}
+
+static void stmfb_enable_controller(struct fb_info *fb_info)
+{
+ struct imxfb_info *fbi = fb_info->priv;
+ uint32_t reg, last_reg;
+ unsigned loop, edges;
+
+ /*
+ * Sometimes some data is still present in the FIFO. This leads into
+ * a correct but shifted picture. Clearing the FIFO helps
+ */
+ writel(CTRL1_FIFO_CLEAR, fbi->base + HW_LCDIF_CTRL1 + BIT_SET);
+
+ /* if it was disabled, re-enable the mode again */
+ reg = readl(fbi->base + HW_LCDIF_CTRL);
+ reg |= CTRL_DOTCLK_MODE;
+ writel(reg, fbi->base + HW_LCDIF_CTRL);
+
+ /* enable the SYNC signals first, then the DMA engine */
+ reg = readl(fbi->base + HW_LCDIF_VDCTRL4);
+ reg |= VDCTRL4_SYNC_SIGNALS_ON;
+ writel(reg, fbi->base + HW_LCDIF_VDCTRL4);
+
+ /*
+ * Give the attached LC display or monitor a chance to sync into
+ * our signals.
+ * Wait for at least 2 VSYNCs = four VSYNC edges
+ */
+ edges = 4;
+
+ while (edges != 0) {
+ loop = 800;
+ last_reg = readl(fbi->base + HW_LCDIF_DEBUG0) & DEBUG_VSYNC;
+ do {
+ reg = readl(fbi->base + HW_LCDIF_DEBUG0) & DEBUG_VSYNC;
+ if (reg != last_reg)
+ break;
+ last_reg = reg;
+ loop--;
+ } while (loop != 0);
+ edges--;
+ }
+
+ /* stop FIFO reset */
+ writel(CTRL1_FIFO_CLEAR, fbi->base + HW_LCDIF_CTRL1 + BIT_CLR);
+ /* start the engine right now */
+ writel(CTRL_RUN, fbi->base + HW_LCDIF_CTRL + BIT_SET);
+}
+
+static void stmfb_disable_controller(struct fb_info *fb_info)
+{
+ struct imxfb_info *fbi = fb_info->priv;
+ unsigned loop;
+ uint32_t reg;
+
+ /*
+ * Even if we disable the controller here, it will still continue
+ * until its FIFOs are running out of data
+ */
+ reg = readl(fbi->base + HW_LCDIF_CTRL);
+ reg &= ~CTRL_DOTCLK_MODE;
+ writel(reg, fbi->base + HW_LCDIF_CTRL);
+
+ loop = 1000;
+ while (loop) {
+ reg = readl(fbi->base + HW_LCDIF_CTRL);
+ if (!(reg & CTRL_RUN))
+ break;
+ loop--;
+ }
+
+ reg = readl(fbi->base + HW_LCDIF_VDCTRL4);
+ reg &= ~VDCTRL4_SYNC_SIGNALS_ON;
+ writel(reg, fbi->base + HW_LCDIF_VDCTRL4);
+}
+
+static int stmfb_activate_var(struct fb_info *fb_info)
+{
+ struct imxfb_info *fbi = fb_info->priv;
+ struct imx_fb_videomode *pdata = fbi->pdata;
+ struct fb_videomode *mode = fb_info->mode;
+ uint32_t reg;
+ int ret;
+ unsigned size;
+
+ /*
+ * we need at least this amount of memory for the framebuffer
+ */
+ size = calc_line_length(mode->xres, fb_info->bits_per_pixel) *
+ mode->yres;
+
+ ret = stmfb_memory_mmgt(fb_info, size);
+ if (ret != 0) {
+ dev_err(fbi->hw_dev, "Cannot allocate framebuffer memory\n");
+ return ret;
+ }
+
+ /** @todo ensure HCLK is active at this point of time! */
+
+ size = imx_set_lcdifclk(PICOS2KHZ(mode->pixclock) * 1000);
+ if (size == 0) {
+ dev_dbg(fbi->hw_dev, "Unable to set a valid pixel clock\n");
+ return -EINVAL;
+ }
+
+ /*
+ * bring the controller out of reset and
+ * configure it into DOTCLOCK mode
+ */
+ reg = CTRL_BYPASS_COUNT | /* always in DOTCLOCK mode */
+ CTRL_DOTCLK_MODE;
+ writel(reg, fbi->base + HW_LCDIF_CTRL);
+
+ /* master mode only */
+ reg |= CTRL_MASTER;
+
+ /*
+ * Configure videomode and interface mode
+ */
+ reg |= SET_BUS_WIDTH(pdata->ld_intf_width);
+ switch (fb_info->bits_per_pixel) {
+ case 8:
+ reg |= SET_WORD_LENGTH(1);
+ /** @todo refer manual page 2046 for 8 bpp modes */
+ dev_dbg(fbi->hw_dev, "8 bpp mode not supported yet\n");
+ break;
+ case 16:
+ pr_debug("Setting up an RGB565 mode\n");
+ reg |= SET_WORD_LENGTH(0);
+ reg &= ~CTRL_DF16; /* we assume RGB565 */
+ writel(SET_BYTE_PACKAGING(0xf), fbi->base + HW_LCDIF_CTRL1);
+ fb_info->red = def_rgb565[RED];
+ fb_info->green = def_rgb565[GREEN];
+ fb_info->blue = def_rgb565[BLUE];
+ fb_info->transp = def_rgb565[TRANSP];
+ break;
+ case 24:
+ case 32:
+ pr_debug("Setting up an RGB888/666 mode\n");
+ reg |= SET_WORD_LENGTH(3);
+ switch (pdata->ld_intf_width) {
+ case STMLCDIF_8BIT:
+ dev_dbg(fbi->hw_dev,
+ "Unsupported LCD bus width mapping\n");
+ break;
+ case STMLCDIF_16BIT:
+ case STMLCDIF_18BIT:
+ /* 24 bit to 18 bit mapping
+ * which means: ignore the upper 2 bits in
+ * each colour component
+ */
+ reg |= CTRL_DF24;
+ fb_info->red = def_rgb666[RED];
+ fb_info->green = def_rgb666[GREEN];
+ fb_info->blue = def_rgb666[BLUE];
+ fb_info->transp = def_rgb666[TRANSP];
+ break;
+ case STMLCDIF_24BIT:
+ /* real 24 bit */
+ fb_info->red = def_rgb888[RED];
+ fb_info->green = def_rgb888[GREEN];
+ fb_info->blue = def_rgb888[BLUE];
+ fb_info->transp = def_rgb888[TRANSP];
+ break;
+ }
+ /* do not use packed pixels = one pixel per word instead */
+ writel(SET_BYTE_PACKAGING(0x7), fbi->base + HW_LCDIF_CTRL1);
+ break;
+ default:
+ dev_dbg(fbi->hw_dev, "Unhandled colour depth of %u\n",
+ fb_info->bits_per_pixel);
+ return -EINVAL;
+ }
+ writel(reg, fbi->base + HW_LCDIF_CTRL);
+ pr_debug("Setting up CTRL to %08X\n", reg);
+
+ writel(SET_VCOUNT(mode->yres) |
+ SET_HCOUNT(mode->xres), fbi->base + HW_LCDIF_TRANSFER_COUNT);
+
+ reg = VDCTRL0_ENABLE_PRESENT | /* always in DOTCLOCK mode */
+ VDCTRL0_VSYNC_PERIOD_UNIT |
+ VDCTRL0_VSYNC_PULSE_WIDTH_UNIT;
+ if (mode->sync & FB_SYNC_HOR_HIGH_ACT)
+ reg |= VDCTRL0_HSYNC_POL;
+ if (mode->sync & FB_SYNC_VERT_HIGH_ACT)
+ reg |= VDCTRL0_VSYNC_POL;
+ if (mode->sync & FB_SYNC_DE_HIGH_ACT)
+ reg |= VDCTRL0_ENABLE_POL;
+ if (mode->sync & FB_SYNC_CLK_INVERT)
+ reg |= VDCTRL0_DOTCLK_POL;
+
+ reg |= SET_VSYNC_PULSE_WIDTH(mode->vsync_len);
+ writel(reg, fbi->base + HW_LCDIF_VDCTRL0);
+ pr_debug("Setting up VDCTRL0 to %08X\n", reg);
+
+ /* frame length in lines */
+ writel(mode->upper_margin + mode->vsync_len + mode->lower_margin +
+ mode->yres,
+ fbi->base + HW_LCDIF_VDCTRL1);
+
+ /* line length in units of clocks or pixels */
+ writel(SET_HSYNC_PULSE_WIDTH(mode->hsync_len) |
+ SET_HSYNC_PERIOD(mode->left_margin + mode->hsync_len +
+ mode->right_margin + mode->xres),
+ fbi->base + HW_LCDIF_VDCTRL2);
+
+ writel(SET_HOR_WAIT_CNT(mode->left_margin + mode->hsync_len) |
+ SET_VERT_WAIT_CNT(mode->upper_margin + mode->vsync_len),
+ fbi->base + HW_LCDIF_VDCTRL3);
+
+ writel(
+#ifdef CONFIG_ARCH_IMX28
+ SET_DOTCLK_DLY(pdata->dotclk_delay) |
+#endif
+ SET_DOTCLK_H_VALID_DATA_CNT(mode->xres),
+ fbi->base + HW_LCDIF_VDCTRL4);
+
+ writel((uint32_t)fb_info->screen_base, fbi->base + HW_LCDIF_CUR_BUF);
+ writel((uint32_t)fb_info->screen_base, fbi->base + HW_LCDIF_NEXT_BUF);
+
+ return 0;
+}
+
+static void stmfb_info(struct device_d *hw_dev)
+{
+ struct imx_fb_videomode *pdata = hw_dev->platform_data;
+ unsigned u;
+
+ printf(" Supported video modes:\n");
+ for (u = 0; u < pdata->mode_cnt; u++)
+ printf(" - '%s': %u x %u\n", pdata->mode_list[u].name,
+ pdata->mode_list[u].xres, pdata->mode_list[u].yres);
+}
+
+/*
+ * There is only one video hardware instance available.
+ * It makes no sense to dynamically allocate this data
+ */
+static struct fb_ops imxfb_ops = {
+ .fb_activate_var = stmfb_activate_var,
+ .fb_enable = stmfb_enable_controller,
+ .fb_disable = stmfb_disable_controller,
+};
+
+static struct imxfb_info fbi = {
+ .info = {
+ .fbops = &imxfb_ops,
+ },
+};
+
+static int stmfb_probe(struct device_d *hw_dev)
+{
+ struct imx_fb_videomode *pdata = hw_dev->platform_data;
+ int ret;
+
+ /* just init */
+ fbi.info.priv = &fbi;
+
+ /* add runtime hardware info */
+ fbi.hw_dev = hw_dev;
+ fbi.base = (void *)hw_dev->map_base;
+ fbi.pdata = pdata;
+
+ /* add runtime video info */
+ fbi.info.mode_list = pdata->mode_list;
+ fbi.info.num_modes = pdata->mode_cnt;
+ fbi.info.mode = &fbi.info.mode_list[0];
+ fbi.info.xres = fbi.info.mode->xres;
+ fbi.info.yres = fbi.info.mode->yres;
+ fbi.info.bits_per_pixel = 16;
+
+ ret = register_framebuffer(&fbi.info);
+ if (ret != 0) {
+ dev_err(hw_dev, "Failed to register framebuffer\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static struct driver_d stmfb_driver = {
+ .name = "stmfb",
+ .probe = stmfb_probe,
+ .info = stmfb_info,
+};
+
+static int stmfb_init(void)
+{
+ return register_driver(&stmfb_driver);
+}
+
+device_initcall(stmfb_init);
+
+/**
+ * @file
+ * @brief LCDIF driver for i.MX23 and i.MX28
+ *
+ * The LCDIF support four modes of operation
+ * - MPU interface (to drive smart displays) -> not supported yet
+ * - VSYNC interface (like MPU interface plus Vsync) -> not supported yet
+ * - Dotclock interface (to drive LC displays with RGB data and sync signals)
+ * - DVI (to drive ITU-R BT656) -> not supported yet
+ *
+ * This driver depends on a correct setup of the pins used for this purpose
+ * (platform specific).
+ *
+ * For the developer: Don't forget to set the data bus width to the display
+ * in the imx_fb_videomode structure. You will else end up with ugly colours.
+ * If you fight against jitter you can vary the clock delay. This is a feature
+ * of the i.MX28 and you can vary it between 2 ns ... 8 ns in 2 ns steps. Give
+ * the required value in the imx_fb_videomode structure.
+ */
diff --git a/include/common.h b/include/common.h
index a14bfc10ce..35ad7b994d 100644
--- a/include/common.h
+++ b/include/common.h
@@ -222,4 +222,23 @@ extern const char version_string[];
#define IOMEM(addr) ((void __force __iomem *)(addr))
+#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
+
+#define DIV_ROUND_CLOSEST(x, divisor)( \
+{ \
+ typeof(divisor) __divisor = divisor; \
+ (((x) + ((__divisor) / 2)) / (__divisor)); \
+} \
+)
+
+#define abs(x) ({ \
+ long __x = (x); \
+ (__x < 0) ? -__x : __x; \
+ })
+
+#define abs64(x) ({ \
+ s64 __x = (x); \
+ (__x < 0) ? -__x : __x; \
+ })
+
#endif /* __COMMON_H_ */
diff --git a/include/cramfs/cramfs_fs.h b/include/cramfs/cramfs_fs.h
index 5bf72c3a8b..3d3c56f5a3 100644
--- a/include/cramfs/cramfs_fs.h
+++ b/include/cramfs/cramfs_fs.h
@@ -88,7 +88,7 @@ struct cramfs_super {
#error "No byte order defined in __BYTE_ORDER"
#endif
-#ifdef __LITTLE_ENDIAN
+#if __BYTE_ORDER == __LITTLE_ENDIAN
#define CRAMFS_16(x) (x)
#define CRAMFS_24(x) (x)
#define CRAMFS_32(x) (x)
@@ -96,7 +96,7 @@ struct cramfs_super {
#define CRAMFS_GET_OFFSET(x) ((x)->offset)
#define CRAMFS_SET_OFFSET(x,y) ((x)->offset = (y))
#define CRAMFS_SET_NAMELEN(x,y) ((x)->namelen = (y))
-#elif defined __BIG_ENDIAN
+#elif __BYTE_ORDER ==__BIG_ENDIAN
#ifdef __KERNEL__
#define CRAMFS_16(x) swab16(x)
#define CRAMFS_24(x) ((swab32(x)) >> 8)
diff --git a/include/fb.h b/include/fb.h
index 379f931e9c..41deb8c696 100644
--- a/include/fb.h
+++ b/include/fb.h
@@ -73,10 +73,13 @@ struct fb_ops {
unsigned blue, unsigned transp, struct fb_info *info);
void (*fb_enable)(struct fb_info *info);
void (*fb_disable)(struct fb_info *info);
+ int (*fb_activate_var)(struct fb_info *info);
};
struct fb_info {
struct fb_videomode *mode;
+ struct fb_videomode *mode_list;
+ unsigned num_modes;
struct fb_ops *fbops;
struct device_d dev; /* This is this fb device */
diff --git a/include/led.h b/include/led.h
new file mode 100644
index 0000000000..9ec1f0d37b
--- /dev/null
+++ b/include/led.h
@@ -0,0 +1,102 @@
+#ifndef __LED_H
+#define __LED_H
+
+#include <errno.h>
+
+struct led {
+ void (*set)(struct led *, unsigned int value);
+ int max_value;
+ char *name;
+ int num;
+ struct list_head list;
+};
+
+struct led *led_by_number(int no);
+struct led *led_by_name(const char *name);
+struct led *led_by_name_or_number(const char *str);
+
+static inline int led_get_number(struct led *led)
+{
+ return led->num;
+}
+
+int led_set_num(int num, unsigned int value);
+int led_set(struct led *led, unsigned int value);
+int led_register(struct led *led);
+void led_unregister(struct led *led);
+void led_unregister(struct led *led);
+
+/* LED trigger support */
+enum led_trigger {
+ LED_TRIGGER_PANIC,
+ LED_TRIGGER_HEARTBEAT,
+ LED_TRIGGER_NET_RX,
+ LED_TRIGGER_NET_TX,
+ LED_TRIGGER_NET_TXRX,
+ LED_TRIGGER_MAX,
+};
+
+enum trigger_type {
+ TRIGGER_ENABLE,
+ TRIGGER_DISABLE,
+ TRIGGER_FLASH,
+};
+
+#ifdef CONFIG_LED_TRIGGERS
+int led_set_trigger(enum led_trigger trigger, struct led *led);
+void led_trigger(enum led_trigger trigger, enum trigger_type);
+#else
+static inline int led_set_trigger(enum led_trigger trigger, struct led *led)
+{
+ return 0;
+}
+
+static inline void led_trigger(enum led_trigger trigger, enum trigger_type type)
+{
+}
+#endif
+
+int led_get_trigger(enum led_trigger trigger);
+
+/* gpio LED support */
+struct gpio_led {
+ int gpio;
+ bool active_low;
+ struct led led;
+};
+
+struct gpio_rgb_led {
+ int gpio_r, gpio_g, gpio_b;
+ bool active_low;
+ struct led led;
+};
+
+#ifdef CONFIG_LED_GPIO
+int led_gpio_register(struct gpio_led *led);
+void led_gpio_unregister(struct gpio_led *led);
+#else
+static inline int led_gpio_register(struct gpio_led *led)
+{
+ return -ENOSYS;
+}
+
+static inline void led_gpio_unregister(struct gpio_led *led)
+{
+}
+#endif
+
+#ifdef CONFIG_LED_GPIO_RGB
+int led_gpio_rgb_register(struct gpio_rgb_led *led);
+void led_gpio_rgb_unregister(struct gpio_led *led);
+#else
+static inline int led_gpio_rgb_register(struct gpio_rgb_led *led)
+{
+ return -ENOSYS;
+}
+
+static inline void led_gpio_rgb_unregister(struct gpio_led *led)
+{
+}
+#endif
+
+#endif /* __LED_H */
diff --git a/include/net.h b/include/net.h
index c695e5f72a..2d28fee7da 100644
--- a/include/net.h
+++ b/include/net.h
@@ -18,6 +18,7 @@
#include <malloc.h>
#include <stdlib.h>
#include <clock.h>
+#include <led.h>
#include <asm/byteorder.h> /* for nton* / ntoh* stuff */
@@ -55,7 +56,6 @@ int eth_open(void); /* open the device */
int eth_send(void *packet, int length); /* Send a packet */
int eth_rx(void); /* Check for received packets */
void eth_halt(void); /* stop SCC */
-char *eth_get_name(void); /* get name of current device */
/*
* Ethernet header
@@ -417,4 +417,6 @@ static inline unsigned char *net_udp_get_payload(struct net_connection *con)
int net_udp_send(struct net_connection *con, int len);
int net_icmp_send(struct net_connection *con, int len);
+void led_trigger_network(enum led_trigger trigger);
+
#endif /* __NET_H__ */
diff --git a/include/poller.h b/include/poller.h
new file mode 100644
index 0000000000..dc981557db
--- /dev/null
+++ b/include/poller.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2010 Marc Kleine-Budde <mkl@pengutronix.de>
+ *
+ * This file is released under the GPLv2
+ *
+ */
+
+#ifndef POLLER_H
+#define POLLER_H
+
+#include <linux/list.h>
+
+struct poller_struct {
+ void (*func)(struct poller_struct *poller);
+
+ struct list_head list;
+};
+
+int poller_register(struct poller_struct *poller);
+int poller_unregister(struct poller_struct *poller);
+
+
+#ifdef CONFIG_POLLER
+void poller_call(void);
+#else
+static inline void poller_call(void)
+{
+}
+#endif /* CONFIG_POLLER */
+
+#endif /* !POLLER_H */
diff --git a/include/stdio.h b/include/stdio.h
index 8bc45fa60e..c824764689 100644
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -9,7 +9,7 @@
*/
/* serial stuff */
-void serial_printf (const char *fmt, ...);
+void serial_printf(const char *fmt, ...) __attribute__ ((format(printf, 1, 2)));
/* stdin */
int tstc(void);
@@ -20,20 +20,22 @@ int getc(void);
void console_puts(unsigned int ch, const char *s);
void console_flush(void);
-static inline void puts(const char *s) {
+static inline void puts(const char *s)
+{
console_puts(CONSOLE_STDOUT, s);
}
-static inline void putchar(char c) {
+static inline void putchar(char c)
+{
console_putc(CONSOLE_STDOUT, c);
}
-int printf(const char *fmt, ...);
+int printf(const char *fmt, ...) __attribute__ ((format(printf, 1, 2)));
int vprintf(const char *fmt, va_list args);
-int sprintf(char * buf, const char *fmt, ...);
-int snprintf(char *buf, size_t size, const char *fmt, ...);
+int sprintf(char *buf, const char *fmt, ...) __attribute__ ((format(printf, 2, 3)));
+int snprintf(char *buf, size_t size, const char *fmt, ...) __attribute__ ((format(printf, 3, 4)));
int vsprintf(char *buf, const char *fmt, va_list args);
-char *asprintf(const char *fmt, ...);
+char *asprintf(const char *fmt, ...) __attribute__ ((format(printf, 1, 2)));
char *vasprintf(const char *fmt, va_list ap);
int vsnprintf(char *buf, size_t size, const char *fmt, va_list args);
int vscnprintf(char *buf, size_t size, const char *fmt, va_list args);
@@ -52,7 +54,7 @@ int vscnprintf(char *buf, size_t size, const char *fmt, va_list args);
#define stderr 2
#define MAX_FILES 128
-void fprintf(int file, const char *fmt, ...);
+void fprintf(int file, const char *fmt, ...) __attribute__ ((format(printf, 2, 3)));
int fputs(int file, const char *s);
int fputc(int file, const char c);
int ftstc(int file);
diff --git a/include/usb/usb.h b/include/usb/usb.h
index 790d64da73..1b936ecab4 100644
--- a/include/usb/usb.h
+++ b/include/usb/usb.h
@@ -267,7 +267,7 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate);
((x_ & 0xFF000000UL) >> 24)); \
})
-#ifdef __LITTLE_ENDIAN
+#if __BYTE_ORDER == __LITTLE_ENDIAN
# define swap_16(x) (x)
# define swap_32(x) (x)
#else
diff --git a/lib/readline.c b/lib/readline.c
index b90de77fd7..a3e1de95e6 100644
--- a/lib/readline.c
+++ b/lib/readline.c
@@ -140,7 +140,7 @@ static char* hist_next(void)
static void cread_add_char(char ichar, int insert, unsigned long *num,
unsigned long *eol_num, char *buf, unsigned long len)
{
- unsigned long wlen;
+ unsigned wlen;
/* room ??? */
if (insert || *num == *eol_num) {
@@ -177,7 +177,7 @@ int readline(const char *prompt, char *buf, int len)
unsigned long num = 0;
unsigned long eol_num = 0;
unsigned long rlen;
- unsigned long wlen;
+ unsigned wlen;
int ichar;
int insert = 1;
int rc = 0;
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index e2ea84d6b6..fec87bac0b 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -17,6 +17,7 @@
#include <malloc.h>
#include <common.h>
+#include <led.h>
#include <reloc.h>
unsigned long simple_strtoul(const char *cp,char **endp,unsigned int base)
@@ -625,6 +626,9 @@ void __noreturn panic(const char *fmt, ...)
vprintf(fmt, args);
putchar('\n');
va_end(args);
+
+ led_trigger(LED_TRIGGER_PANIC, TRIGGER_ENABLE);
+
#if defined (CONFIG_PANIC_HANG)
hang();
#else
diff --git a/net/eth.c b/net/eth.c
index a82a263206..7502e98253 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -77,6 +77,8 @@ int eth_send(void *packet, int length)
eth_current->active = 1;
}
+ led_trigger_network(LED_TRIGGER_NET_TX);
+
return eth_current->send(eth_current, packet, length);
}
@@ -183,4 +185,8 @@ void eth_unregister(struct eth_device *edev)
list_del(&edev->list);
}
-
+void led_trigger_network(enum led_trigger trigger)
+{
+ led_trigger(trigger, TRIGGER_FLASH);
+ led_trigger(LED_TRIGGER_NET_TXRX, TRIGGER_FLASH);
+}
diff --git a/net/net.c b/net/net.c
index a613d1da74..9b4ab8904c 100644
--- a/net/net.c
+++ b/net/net.c
@@ -628,19 +628,29 @@ int net_receive(unsigned char *pkt, int len)
{
struct ethernet *et = (struct ethernet *)pkt;
int et_protlen = ntohs(et->et_protlen);
+ int ret;
- if (len < ETHER_HDR_SIZE)
- return 0;
+ led_trigger_network(LED_TRIGGER_NET_RX);
+
+ if (len < ETHER_HDR_SIZE) {
+ ret = 0;
+ goto out;
+ }
switch (et_protlen) {
case PROT_ARP:
- return net_handle_arp(pkt, len);
+ ret = net_handle_arp(pkt, len);
+ break;
case PROT_IP:
- return net_handle_ip(pkt, len);
+ ret = net_handle_ip(pkt, len);
+ break;
default:
debug("%s: got unknown protocol type: %d\n", __func__, et_protlen);
- return 1;
+ ret = 1;
+ break;
}
+out:
+ return ret;
}
static int net_init(void)
diff --git a/net/tftp.c b/net/tftp.c
index 6be8b8f623..0f38b6b9b0 100644
--- a/net/tftp.c
+++ b/net/tftp.c
@@ -218,7 +218,7 @@ static void tftp_handler(char *packet, unsigned len)
tftp_last_block = 0;
if (tftp_block != 1) { /* Assertion */
- printf("error: First block is not block 1 (%ld)\n",
+ printf("error: First block is not block 1 (%d)\n",
tftp_block);
tftp_err = -EINVAL;
tftp_state = STATE_DONE;