* [PATCH] mmc, ARM: Add zboot from MMC support for SuperH Mobile ARM
From: Pawel Moll @ 2011-01-10 10:10 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110109225042.GB29257@verge.net.au>
On Mon, 10 Jan 2011 07:50:42 +0900, Simon Horman <horms@verge.net.au>
wrote:
>> > Documentation/arm/SH-Mobile/Makefile | 8 +
>> > Documentation/arm/SH-Mobile/vrl4.c | 169
>> +++++++++++++++++++++
>> How about putting those two into "tools" (in particular "tools/arm")
>> instead of "Documentation"?
>> Just a thought... ;-)
>
> Thats fine by me except that tools/arm doesn't exist yet.
> It would be good to get some consensus before creating it.
I think there is consensus regarding "tools" as a place for user-space
tools - eg. perf tools used to live in "Documentation/..." and then were
moved to "tools/perf".
Now, whether your stuff should be in "tools/SH-Mobile" or
"tools/arm/SH-Mobile", I have no opinion ;-)
Cheers!
Pawe?
^ permalink raw reply
* [PATCH V2] ARM: S5PV310: Implement kernel timers using MCT
From: Kukjin Kim @ 2011-01-10 4:03 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110107121121.GR31708@n2100.arm.linux.org.uk>
Russell King - ARM Linux wrote:
>
> On Fri, Jan 07, 2011 at 09:05:11PM +0900, Kukjin Kim wrote:
> > Russell King - ARM Linux wrote:
> > >
> > > On Tue, Jan 04, 2011 at 11:18:47AM +0900, Kukjin Kim wrote:
> > > > From: Changhwan Youn <chaos.youn@samsung.com>
> > > >
> > > > The Multi-Core Timer(MCT) of S5PV310 is designed for implementing
> > > > clock source timer and clock event timers. This patch implements
> > > > 1 clock source timer with 64 bit free running counter of MCT and
> > > > 2 clock event timers with two of 31-bit tick counters.
> > >
> > > I want to wait until after this merge window before commenting too
much
> > > on this; some of this patch will be impacted by changes in this merge
> > > window.
> > >
> > Hmmm...Ok, I understood.
>
> That stuff is now in mainline - not only the new sched_clock() support
> but also the SMP changes (which impact on your MCT code.) Please rebase
> on latest mainline and re-send.
>
I found it in mainline...thanks...ok, will do it.
> > > > +static void s5pv310_frc_suspend(struct clocksource *cs)
> > > > +{
> > > > + time_suspended = s5pv310_frc_read(cs);
> > > > +};
> > > > +
> > > > +static void s5pv310_frc_resume(struct clocksource *cs)
> > > > +{
> > > > + s5pv310_mct_frc_start((u32)(time_suspended >> 32),
> > > (u32)time_suspended);
> > > > +};
> > >
> > > Is this something which other clocksource drivers need to do, or does
the
> > > core automatically deal with the clocksource being irregular across a
> > > suspend/resume event?
> > >
> > Normally this is not necessary because core deals with the irregularity
of
> > clocksource, but for sched_clock() implementation, clocksource had
better
> be
> > regular across a suspend/resume event. One example is "Show timing
> > information on printks" kernel configuration. Without this code, timing
> > information resets after suspend/resume event.
> >
> > Following is not submitted but will be submitted :-)
> >
> > unsigned long long sched_clock(void)
> > {
> > struct clocksource *cs = &mct_frc;
> >
> > return clocksource_cyc2ns(cs->read(NULL), sched_mult, sched_shift);
> > }
>
> Please use the new sched_clock stuff which guarantees to return a 64-bit
> cycle count (which is what sched_clock() is required to do.)
Ok.
Russell one more,
Is it possible that I send 'pull request' to you for 38 merge window on this
Wednesday?
Thanks.
Best regards,
Kgene.
--
Kukjin Kim <kgene.kim@samsung.com>, Senior Engineer,
SW Solution Development Team, Samsung Electronics Co., Ltd.
^ permalink raw reply
* [PATCH] ARM: sched_clock: improve mult/shift accuracy with high frequency clocks
From: Nicolas Pitre @ 2011-01-10 3:55 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110109105200.GC31708@n2100.arm.linux.org.uk>
On Sun, 9 Jan 2011, Russell King - ARM Linux wrote:
> Now, a Caesium fountain frequency standard may have an accuracy of
> approx. 1 part in 10^-14. Rubidium frequency standards are around
> 1 part in 10^-12.
>
> A standard crystal oscillator is around 1 part in 10^-6 to 10^-7. If
> you really care about accuracy, you might use an ovened crystal
> oscillator (OXCO) which'll get you to around 1 part in 10^-7..10^-9,
> still well short of the calculation inaccuracy. You wouldn't use an
> OXCO in a battery operated device though due to power consumption.
>
> We're generally don't have a Caesium or Rubidium frequency standard, not
> even a OXCO providing the clock source for the counter, so the accuracy
> of the counters clock is much more significant than the conversion
> factors by a factor of about one million.
>
> What I'm saying is that there becomes a time where it really doesn't
> matter if the conversion isn't accurate, provided it's accurate enough,
> and it would appear to be accurate enough.
It sure is, thanks for the demonstration.
However this begs the question about the actual meaning of the value for
the minsec argument to clocks_calc_mult_shift() (which IMHO should be
renamed to maxsec instead). In the ARM sched_clock code the value of 60
is totally arbitrary and may happen to be good enough, but a value of 0
would also be totally arbitrary and also work fine. But at least a 0
value wouldn't imply any false meaning. And in the case of the
sched_clock support code, we know the value we need: 90%
of the actual hardware clock period, so using that would at least make
the code self consistent even if in practice this doesn't change the
final results.
Nicolas
^ permalink raw reply
* [PATCH v4 00/10] net/fec: add dual fec support for i.MX28
From: Shawn Guo @ 2011-01-10 3:08 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110109.154409.242134862.davem@davemloft.net>
On Sun, Jan 09, 2011 at 03:44:09PM -0800, David Miller wrote:
> From: Shawn Guo <shawn.guo@freescale.com>
> Date: Thu, 6 Jan 2011 15:13:08 +0800
>
> > This patch series is to add dual fec support for mx28, which is
> > a mxs-based soc. Some code changes related to the following commits
> > are also made in this patch set for some reasons.
> >
> > e6b043d512fa8d9a3801bf5d72bfa3b8fc3b3cc8
> > netdev/fec.c: add phylib supporting to enable carrier detection (v2)
> >
> > e3fe8558c7fc182972c3d947d88744482111f304
> > net/fec: fix pm to survive to suspend/resume
> >
> > It's been tested on mx28 evk and mx51 babbage. For mx28, it has
> > to work against the tree
> >
> > git://git.pengutronix.de/git/imx/linux-2.6.git imx-for-2.6.38
> >
> > plus patch
> >
> > [PATCH v4] ARM: mxs: Change duart device to use amba-pl011
> >
> > The 3 patches below preceding with * have changes since v3, and
> > the detailed change log can be found in individual patch.
>
> I've applied all of the "net/fec:" patches (#1 to #5) to net-2.6,
> please push the ARM changes via the appropriate ARM tree.
>
> Thanks.
>
Thanks, David. I will ping Sascha for ARM changes.
--
Regards,
Shawn
^ permalink raw reply
* [PATCH 1/2] Add a common struct clk
From: Jeremy Kerr @ 2011-01-10 2:43 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110108131520.GE26617@pengutronix.de>
Hi Sascha,
> I'm currently thinking about how to get the locking right with this
> approach. In the current i.MX implementation we have a global lock which
> protects the clock enable counter and also the register accesses in the
> clock code. With the common struct clock we have a lock per clock which
> only protects the enable counter, so we have to introduce a second lock
> to protect the register accesses.
Are the registers shared between clocks? If not, you can just use the existing
per-clk lock. Otherwise it'd be reasonable to add a global register lock,
protecting accesses to the shared register set (and *only* protecting these
registers).
> The problem comes with nested calls to for example clk_enable which
> happens when the parent clock gets enabled. currently we do this with
> clk->enable(clk->parent) which results in an unlocked clk_enable of the
> parent. With common struct clk we would have to call
> clk_enable(clk_get_parent(clk) which results in taking the lock a second
> time.
> Any ideas how to solve this?
With the shared register lock, you just need to make sure that you don't
recurse to the parent while holding the lock.
For clocks with a shared register set, the general pattern would be something
like:
struct clk_foo {
struct clk clk;
u32 enable_reg;
u32 enable_mask;
struct clk *parent;
};
static DEFINE_SPINLOCK(clk_foo_register_lock);
/* called with _clk->lock held */
static int clk_foo_enable(struct clk *_clk)
{
struct clk_foo *clk = to_clk_foo(_clk);
int reg, rc;
/* enable parent - will acquire and release the parent's per-clk lock */
rc = clk_enable(clk->parent);
if (rc)
return rc;
/* do register update, under global register lock */
spin_lock(&clk_foo_register_lock);
reg = __raw_readl(clk->reg);
__raw_writel(clk->reg, reg | clk->enable_mask);
spin_unlock(&clk_foo_register_lock);
return 0;
}
struct clk_foo_ops = {
.enable = clk_foo_enable;
[...]
};
However, because clk_mxc introduces its own set of abstractions, there may be
some merging to do here. For my work on mx51, I've done a very basic port:
* changed plat-mxc's struct clk to struct clk_mxc
* embedded struct clk into struct clk_mxc (ie, making it use the common API)
* separated some of the simpler clocks to separate types (eg clk_fixed,
clk_pll, clk_ccgr).
The goal here is to separate all of the clocks into their most basic types,
leaving no clk_mxc clocks remaining, then the locking should be much simpler.
Cheers,
Jeremy
^ permalink raw reply
* [PATCH] [patch v5] mmc, ARM: Add zboot from MMC support for SuperH Mobile ARM
From: Simon Horman @ 2011-01-10 0:37 UTC (permalink / raw)
To: linux-arm-kernel
This allows a ROM-able zImage to be written to MMC and
for SuperH Mobile ARM to boot directly from the MMCIF
hardware block.
This is achieved by the MaskROM loading the first portion
of the image into MERAM and then jumping to it. This portion
contains loader code which copies the entire image to SDRAM
and jumps to it. From there the zImage boot code proceeds
as normal, uncompressing the image into its final location
and then jumping to it.
Cc: Magnus Damm <magnus.damm@gmail.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
This patch depends on:
* "ARM: 6514/1: mach-shmobile: Add zboot support for SuperH Mobile ARM"
which has been merged into the devel branch of Russell King's
linux-2.6-arm tree.
* "mmc, sh: Move MMCIF_PROGRESS_* into sh_mmcif.h"
which has been merged into the common/mmcif branch of
Paul Mundt's sh-2.6 tree
* "mmc, sh: Remove sh_mmcif_boot_slurp()"
which has been merged into the common/mmcif branch of
Paul Mundt's sh-2.6 tree
v2:
Addressed comments by Magnus Damm
* Fix copyright in vrl4.c
* Fix use of #define CONFIG_ZBOOT_ROM_MMCIF in mmcif-sh7372.c
* Initialise LED GPIO lines in head-ap4evb.txt instead of mmcif-sh7372.c
as this is considered board-specific.
v3:
Addressed comments made in person by Magnus Damm
* Move mmcif_loader to be earlier in the image and
reduce the number of blocks of boot program loaded by the MaskRom
from 40 to 8 accordingly.
* Move LED GPIO initialisation into mmcif_progress_init
- This leaves the partner jet script unbloated
Other
* inline mmcif_update_progress so it is a static inline in a header file
v4:
* Use htole16() and htole32() in v4rl.c to ensure
that the output is little endian
v5:
Addressed comments by Russell King
* Simplify assembly code
* Jump to code rather than an address <- bug fix
* Use (void __iomem *) as appropriate
Roll in mackerel support
* This was previously a separate patch, only because of the order
in which this code was developed
---
Documentation/arm/SH-Mobile/Makefile | 8 +
Documentation/arm/SH-Mobile/vrl4.c | 169 ++++++++++++++++++++
Documentation/arm/SH-Mobile/zboot-rom-mmcif.txt | 29 ++++
arch/arm/Kconfig | 12 ++
arch/arm/boot/compressed/Makefile | 13 ++-
arch/arm/boot/compressed/head-shmobile.S | 30 ++++
arch/arm/boot/compressed/mmcif-sh7372.c | 87 ++++++++++
arch/arm/mach-shmobile/include/mach/mmcif-ap4eb.h | 29 ++++
.../mach-shmobile/include/mach/mmcif-mackerel.h | 39 +++++
arch/arm/mach-shmobile/include/mach/mmcif.h | 18 ++
10 files changed, 433 insertions(+), 1 deletions(-)
create mode 100644 Documentation/arm/SH-Mobile/Makefile
create mode 100644 Documentation/arm/SH-Mobile/vrl4.c
create mode 100644 Documentation/arm/SH-Mobile/zboot-rom-mmcif.txt
create mode 100644 arch/arm/boot/compressed/mmcif-sh7372.c
create mode 100644 arch/arm/mach-shmobile/include/mach/mmcif-ap4eb.h
create mode 100644 arch/arm/mach-shmobile/include/mach/mmcif-mackerel.h
create mode 100644 arch/arm/mach-shmobile/include/mach/mmcif.h
diff --git a/Documentation/arm/SH-Mobile/Makefile b/Documentation/arm/SH-Mobile/Makefile
new file mode 100644
index 0000000..8771d83
--- /dev/null
+++ b/Documentation/arm/SH-Mobile/Makefile
@@ -0,0 +1,8 @@
+BIN := vrl4
+
+.PHONY: all
+all: $(BIN)
+
+.PHONY: clean
+clean:
+ rm -f *.o $(BIN)
diff --git a/Documentation/arm/SH-Mobile/vrl4.c b/Documentation/arm/SH-Mobile/vrl4.c
new file mode 100644
index 0000000..e8a1913
--- /dev/null
+++ b/Documentation/arm/SH-Mobile/vrl4.c
@@ -0,0 +1,169 @@
+/*
+ * vrl4 format generator
+ *
+ * Copyright (C) 2010 Simon Horman
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+/*
+ * usage: vrl4 < zImage > out
+ * dd if=out of=/dev/sdx bs=512 seek=1 # Write the image to sector 1
+ *
+ * Reads a zImage from stdin and writes a vrl4 image to stdout.
+ * In practice this means writing a padded vrl4 header to stdout followed
+ * by the zImage.
+ *
+ * The padding places the zImage at ALIGN bytes into the output.
+ * The vrl4 uses ALIGN + START_BASE as the start_address.
+ * This is where the mask ROM will jump to after verifying the header.
+ *
+ * The header sets copy_size to min(sizeof(zImage), MAX_BOOT_PROG_LEN) + ALIGN.
+ * That is, the mask ROM will load the padded header (ALIGN bytes)
+ * And then MAX_BOOT_PROG_LEN bytes of the image, or the entire image,
+ * whichever is smaller.
+ *
+ * The zImage is not modified in any way.
+ */
+
+#define _BSD_SOURCE
+#include <endian.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <errno.h>
+
+struct hdr {
+ uint32_t magic1;
+ uint32_t reserved1;
+ uint32_t magic2;
+ uint32_t reserved2;
+ uint16_t copy_size;
+ uint16_t boot_options;
+ uint32_t reserved3;
+ uint32_t start_address;
+ uint32_t reserved4;
+ uint32_t reserved5;
+ char reserved6[308];
+};
+
+#define DECLARE_HDR(h) \
+ struct hdr (h) = { \
+ .magic1 = htole32(0xea000000), \
+ .reserved1 = htole32(0x56), \
+ .magic2 = htole32(0xe59ff008), \
+ .reserved3 = htole16(0x1) }
+
+/* Align to 512 bytes, the MMCIF sector size */
+#define ALIGN_BITS 9
+#define ALIGN (1 << ALIGN_BITS)
+
+#define START_BASE 0xe55b0000
+
+/*
+ * With an alignment of 512 the header uses the first sector.
+ * There is a 128 sector (64kbyte) limit on the data loaded by the mask ROM.
+ * So there are 127 sectors left for the boot programme. But in practice
+ * Only a small portion of a zImage is needed, 16 sectors should be more
+ * than enough.
+ *
+ * Note that this sets how much of the zImage is copied by the mask ROM.
+ * The entire zImage is present after the header and is loaded
+ * by the code in the boot program (which is the first portion of the zImage).
+ */
+#define MAX_BOOT_PROG_LEN (16 * 512)
+
+#define ROUND_UP(x) ((x + ALIGN - 1) & ~(ALIGN - 1))
+
+ssize_t do_read(int fd, void *buf, size_t count)
+{
+ size_t offset = 0;
+ ssize_t l;
+
+ while (offset < count) {
+ l = read(fd, buf + offset, count - offset);
+ if (!l)
+ break;
+ if (l < 0) {
+ if (errno == EAGAIN || errno == EWOULDBLOCK)
+ continue;
+ perror("read");
+ return -1;
+ }
+ offset += l;
+ }
+
+ return offset;
+}
+
+ssize_t do_write(int fd, const void *buf, size_t count)
+{
+ size_t offset = 0;
+ ssize_t l;
+
+ while (offset < count) {
+ l = write(fd, buf + offset, count - offset);
+ if (l < 0) {
+ if (errno == EAGAIN || errno == EWOULDBLOCK)
+ continue;
+ perror("write");
+ return -1;
+ }
+ offset += l;
+ }
+
+ return offset;
+}
+
+ssize_t write_zero(int fd, size_t len)
+{
+ size_t i = len;
+
+ while (i--) {
+ const char x = 0;
+ if (do_write(fd, &x, 1) < 0)
+ return -1;
+ }
+
+ return len;
+}
+
+int main(void)
+{
+ DECLARE_HDR(hdr);
+ char boot_program[MAX_BOOT_PROG_LEN];
+ size_t aligned_hdr_len, alligned_prog_len;
+ ssize_t prog_len;
+
+ prog_len = do_read(0, boot_program, sizeof(boot_program));
+ if (prog_len <= 0)
+ return -1;
+
+ aligned_hdr_len = ROUND_UP(sizeof(hdr));
+ hdr.start_address = htole32(START_BASE + aligned_hdr_len);
+ alligned_prog_len = ROUND_UP(prog_len);
+ hdr.copy_size = htole16(aligned_hdr_len + alligned_prog_len);
+
+ if (do_write(1, &hdr, sizeof(hdr)) < 0)
+ return -1;
+ if (write_zero(1, aligned_hdr_len - sizeof(hdr)) < 0)
+ return -1;
+
+ if (do_write(1, boot_program, prog_len) < 0)
+ return 1;
+
+ /* Write out the rest of the kernel */
+ while (1) {
+ prog_len = do_read(0, boot_program, sizeof(boot_program));
+ if (prog_len < 0)
+ return 1;
+ if (prog_len == 0)
+ break;
+ if (do_write(1, boot_program, prog_len) < 0)
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/Documentation/arm/SH-Mobile/zboot-rom-mmcif.txt b/Documentation/arm/SH-Mobile/zboot-rom-mmcif.txt
new file mode 100644
index 0000000..efff8ae
--- /dev/null
+++ b/Documentation/arm/SH-Mobile/zboot-rom-mmcif.txt
@@ -0,0 +1,29 @@
+ROM-able zImage boot from MMC
+-----------------------------
+
+An ROM-able zImage compiled with ZBOOT_ROM_MMCIF may be written to MMC and
+SuperH Mobile ARM will to boot directly from the MMCIF hardware block.
+
+This is achieved by the mask ROM loading the first portion of the image into
+MERAM and then jumping to it. This portion contains loader code which
+copies the entire image to SDRAM and jumps to it. From there the zImage
+boot code proceeds as normal, uncompressing the image into its final
+location and then jumping to it.
+
+This code has been tested on an AP4EB board using the developer 1A eMMC
+boot mode which is configured using the following jumper settings.
+The board used for testing required a patched mask ROM in order for
+this mode to function.
+
+ 8 7 6 5 4 3 2 1
+ x|x|x|x|x| |x|
+S4 -+-+-+-+-+-+-+-
+ | | | | |x| |x on
+
+The zImage must be written to the MMC card@sector 1 (512 bytes) in
+vrl4 format. A utility vrl4 is supplied to accomplish this.
+
+e.g.
+ vrl4 < zImage | dd of=/dev/sdX bs=512 seek=1
+
+A dual-voltage MMC 4.0 card was used for testing.
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 81c71da..899c77c 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1582,6 +1582,18 @@ config ZBOOT_ROM
Say Y here if you intend to execute your compressed kernel image
(zImage) directly from ROM or flash. If unsure, say N.
+config ZBOOT_ROM_MMCIF
+ bool "Include MMCIF loader in zImage (EXPERIMENTAL)"
+ depends on ZBOOT_ROM && ARCH_SH7372 && EXPERIMENTAL
+ help
+ Say Y here to include experimental MMCIF loading code in the
+ ROM-able zImage. With this enabled it is possible to write the
+ the ROM-able zImage kernel image to an MMC card and boot the
+ kernel straight from the reset vector. At reset the processor
+ Mask ROM will load the first part of the the ROM-able zImage
+ which in turn loads the rest the kernel image to RAM using the
+ MMCIF hardware block.
+
config CMDLINE
string "Default kernel command string"
default ""
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 0a8f748..198007d 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -4,9 +4,20 @@
# create a compressed vmlinuz image from the original vmlinux
#
+OBJS =
+
+# Ensure that mmcif loader code appears early in the image
+# to minimise that number of bocks that have to be read in
+# order to load it.
+ifeq ($(CONFIG_ZBOOT_ROM_MMCIF),y)
+ifeq ($(CONFIG_ARCH_SH7372),y)
+OBJS += mmcif-sh7372.o
+endif
+endif
+
AFLAGS_head.o += -DTEXT_OFFSET=$(TEXT_OFFSET)
HEAD = head.o
-OBJS = misc.o decompress.o
+OBJS += misc.o decompress.o
FONTC = $(srctree)/drivers/video/console/font_acorn_8x8.c
#
diff --git a/arch/arm/boot/compressed/head-shmobile.S b/arch/arm/boot/compressed/head-shmobile.S
index 30973b7..c943d2e 100644
--- a/arch/arm/boot/compressed/head-shmobile.S
+++ b/arch/arm/boot/compressed/head-shmobile.S
@@ -25,6 +25,36 @@
/* load board-specific initialization code */
#include <mach/zboot.h>
+#ifdef CONFIG_ZBOOT_ROM_MMCIF
+ /* Load image from MMC */
+ adr sp, __tmp_stack + 128
+ ldr r0, __image_start
+ ldr r1, __image_end
+ subs r1, r1, r0
+ ldr r0, __load_base
+ bl mmcif_loader
+
+ /* Jump to loaded code */
+ ldr r0, __loaded
+ ldr r1, __image_start
+ sub r0, r0, r1
+ ldr r1, __load_base
+ add pc, r0, r1
+
+__image_start:
+ .long _start
+__image_end:
+ .long _got_end
+__load_base:
+ .long CONFIG_MEMORY_START + 0x02000000 @ Load at 32Mb into SDRAM
+__loaded:
+ .long __continue
+ .align
+__tmp_stack:
+ .space 128
+__continue:
+#endif /* CONFIG_ZBOOT_ROM_MMCIF */
+
b 1f
__atags:@ tag #1
.long 12 @ tag->hdr.size = tag_size(tag_core);
diff --git a/arch/arm/boot/compressed/mmcif-sh7372.c b/arch/arm/boot/compressed/mmcif-sh7372.c
new file mode 100644
index 0000000..e6180af
--- /dev/null
+++ b/arch/arm/boot/compressed/mmcif-sh7372.c
@@ -0,0 +1,87 @@
+/*
+ * sh7372 MMCIF loader
+ *
+ * Copyright (C) 2010 Magnus Damm
+ * Copyright (C) 2010 Simon Horman
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/mmc/sh_mmcif.h>
+#include <mach/mmcif.h>
+
+#define MMCIF_BASE (void __iomem *)0xe6bd0000
+
+#define PORT84CR (void __iomem *)0xe6050054
+#define PORT85CR (void __iomem *)0xe6050055
+#define PORT86CR (void __iomem *)0xe6050056
+#define PORT87CR (void __iomem *)0xe6050057
+#define PORT88CR (void __iomem *)0xe6050058
+#define PORT89CR (void __iomem *)0xe6050059
+#define PORT90CR (void __iomem *)0xe605005a
+#define PORT91CR (void __iomem *)0xe605005b
+#define PORT92CR (void __iomem *)0xe605005c
+#define PORT99CR (void __iomem *)0xe6050063
+
+#define SMSTPCR3 (void __iomem *)0xe615013c
+
+/* SH7372 specific MMCIF loader
+ *
+ * loads the zImage from an MMC card starting from block 1.
+ *
+ * The image must be start with a vrl4 header and
+ * the zImage must start at offset 512 of the image. That is,
+ * at block 2 (=byte 1024) on the media
+ *
+ * Use the following line to write the vrl4 formated zImage
+ * to an MMC card
+ * # dd if=vrl4.out of=/dev/sdx bs=512 seek=1
+ */
+asmlinkage void mmcif_loader(unsigned char *buf, unsigned long len)
+{
+ mmcif_init_progress();
+ mmcif_update_progress(MMCIF_PROGRESS_ENTER);
+
+ /* Initialise MMC
+ * registers: PORT84CR-PORT92CR
+ * (MMCD0_0-MMCD0_7,MMCCMD0 Control)
+ * value: 0x04 - select function 4
+ */
+ __raw_writeb(0x04, PORT84CR);
+ __raw_writeb(0x04, PORT85CR);
+ __raw_writeb(0x04, PORT86CR);
+ __raw_writeb(0x04, PORT87CR);
+ __raw_writeb(0x04, PORT88CR);
+ __raw_writeb(0x04, PORT89CR);
+ __raw_writeb(0x04, PORT90CR);
+ __raw_writeb(0x04, PORT91CR);
+ __raw_writeb(0x04, PORT92CR);
+
+ /* Initialise MMC
+ * registers: PORT99CR (MMCCLK0 Control)
+ * value: 0x10 | 0x04 - enable output | select function 4
+ */
+ __raw_writeb(0x14, PORT99CR);
+
+ /* Enable clock to MMC hardware block */
+ __raw_writel(__raw_readl(SMSTPCR3) & ~(1 << 12), SMSTPCR3);
+
+ mmcif_update_progress(MMCIF_PROGRESS_INIT);
+
+ /* setup MMCIF hardware */
+ sh_mmcif_boot_init(MMCIF_BASE);
+
+ mmcif_update_progress(MMCIF_PROGRESS_LOAD);
+
+ /* load kernel via MMCIF interface */
+ sh_mmcif_boot_do_read(MMCIF_BASE, 2, /* Kernel is@block 2 */
+ (len + SH_MMCIF_BBS - 1) / SH_MMCIF_BBS, buf);
+
+
+ /* Disable clock to MMC hardware block */
+ __raw_writel(__raw_readl(SMSTPCR3) & (1 << 12), SMSTPCR3);
+
+ mmcif_update_progress(MMCIF_PROGRESS_DONE);
+}
diff --git a/arch/arm/mach-shmobile/include/mach/mmcif-ap4eb.h b/arch/arm/mach-shmobile/include/mach/mmcif-ap4eb.h
new file mode 100644
index 0000000..a8d02be
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/mmcif-ap4eb.h
@@ -0,0 +1,29 @@
+#ifndef MMCIF_AP4EB_H
+#define MMCIF_AP4EB_H
+
+#define PORT185CR (void __iomem *)0xe60520b9
+#define PORT186CR (void __iomem *)0xe60520ba
+#define PORT187CR (void __iomem *)0xe60520bb
+#define PORT188CR (void __iomem *)0xe60520bc
+
+#define PORTR191_160DR (void __iomem *)0xe6056014
+
+static inline void mmcif_init_progress(void)
+{
+ /* Initialise LEDS1-4
+ * registers: PORT185CR-PORT188CR (LED1-LED4 Control)
+ * value: 0x10 - enable output
+ */
+ __raw_writeb(0x10, PORT185CR);
+ __raw_writeb(0x10, PORT186CR);
+ __raw_writeb(0x10, PORT187CR);
+ __raw_writeb(0x10, PORT188CR);
+}
+
+static inline void mmcif_update_progress(int n)
+{
+ __raw_writel((__raw_readl(PORTR191_160DR) & ~(0xf << 25)) |
+ (1 << (25 + n)), PORTR191_160DR);
+}
+
+#endif /* MMCIF_AP4EB_H */
diff --git a/arch/arm/mach-shmobile/include/mach/mmcif-mackerel.h b/arch/arm/mach-shmobile/include/mach/mmcif-mackerel.h
new file mode 100644
index 0000000..4b4f694
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/mmcif-mackerel.h
@@ -0,0 +1,39 @@
+#ifndef MMCIF_MACKEREL_H
+#define MMCIF_MACKEREL_H
+
+#define PORT0CR (void __iomem *)0xe6051000
+#define PORT1CR (void __iomem *)0xe6051001
+#define PORT2CR (void __iomem *)0xe6051002
+#define PORT159CR (void __iomem *)0xe605009f
+
+#define PORTR031_000DR (void __iomem *)0xe6055000
+#define PORTL159_128DR (void __iomem *)0xe6054010
+
+static inline void mmcif_init_progress(void)
+{
+ /* Initialise LEDS0-3
+ * registers: PORT0CR-PORT2CR,PORT159CR (LED0-LED3 Control)
+ * value: 0x10 - enable output
+ */
+ __raw_writeb(0x10, PORT0CR);
+ __raw_writeb(0x10, PORT1CR);
+ __raw_writeb(0x10, PORT2CR);
+ __raw_writeb(0x10, PORT159CR);
+}
+
+static inline void mmcif_update_progress(int n)
+{
+ unsigned a = 0, b = 0;
+
+ if (n < 3)
+ a = 1 << n;
+ else
+ b = 1 << 31;
+
+ __raw_writel((__raw_readl(PORTR031_000DR) & ~0x7) | a,
+ PORTR031_000DR);
+ __raw_writel((__raw_readl(PORTL159_128DR) & ~(1 << 31)) | b,
+ PORTL159_128DR);
+}
+
+#endif /* MMCIF_MACKEREL_H */
diff --git a/arch/arm/mach-shmobile/include/mach/mmcif.h b/arch/arm/mach-shmobile/include/mach/mmcif.h
new file mode 100644
index 0000000..f4dc327
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/mmcif.h
@@ -0,0 +1,18 @@
+#ifndef MMCIF_H
+#define MMCIF_H
+
+/**************************************************
+ *
+ * board specific settings
+ *
+ **************************************************/
+
+#ifdef CONFIG_MACH_AP4EVB
+#include "mach/mmcif-ap4eb.h"
+#elif CONFIG_MACH_MACKEREL
+#include "mach/mmcif-mackerel.h"
+#else
+#error "unsupported board."
+#endif
+
+#endif /* MMCIF_H */
--
1.7.2.3
^ permalink raw reply related
* [PATCH] Fix ep93xx-fb init/exit annotations
From: Ryan Mallon @ 2011-01-09 23:55 UTC (permalink / raw)
To: linux-arm-kernel
Fix section mismatch errors in the ep93xx-fb driver resulting from
incorrect init/exit annotations.
Reported-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Signed-off-by: Ryan Mallon <ryan@bluewatersys.com>
---
diff --git a/drivers/video/ep93xx-fb.c b/drivers/video/ep93xx-fb.c
index 0c99de0..b358d04 100644
--- a/drivers/video/ep93xx-fb.c
+++ b/drivers/video/ep93xx-fb.c
@@ -483,7 +483,7 @@ static void ep93xxfb_dealloc_videomem(struct fb_info *info)
info->screen_base, info->fix.smem_start);
}
-static int __init ep93xxfb_probe(struct platform_device *pdev)
+static int __devinit ep93xxfb_probe(struct platform_device *pdev)
{
struct ep93xxfb_mach_info *mach_info = pdev->dev.platform_data;
struct fb_info *info;
@@ -598,7 +598,7 @@ failed:
return err;
}
-static int ep93xxfb_remove(struct platform_device *pdev)
+static int __devexit ep93xxfb_remove(struct platform_device *pdev)
{
struct fb_info *info = platform_get_drvdata(pdev);
struct ep93xx_fbi *fbi = info->par;
@@ -622,7 +622,7 @@ static int ep93xxfb_remove(struct platform_device *pdev)
static struct platform_driver ep93xxfb_driver = {
.probe = ep93xxfb_probe,
- .remove = ep93xxfb_remove,
+ .remove = __devexit_p(ep93xxfb_remove),
.driver = {
.name = "ep93xx-fb",
.owner = THIS_MODULE,
^ permalink raw reply related
* [PATCH] mmc, ARM: Add zboot from MMC support for SuperH Mobile ARM
From: Simon Horman @ 2011-01-09 23:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110109231239.GE31708@n2100.arm.linux.org.uk>
On Sun, Jan 09, 2011 at 11:12:39PM +0000, Russell King - ARM Linux wrote:
> On Sun, Jan 09, 2011 at 09:49:28PM +0900, Simon Horman wrote:
> > diff --git a/arch/arm/boot/compressed/head-shmobile.S b/arch/arm/boot/compressed/head-shmobile.S
> > index 30973b7..de83c5a 100644
> > --- a/arch/arm/boot/compressed/head-shmobile.S
> > +++ b/arch/arm/boot/compressed/head-shmobile.S
> > @@ -25,6 +25,37 @@
> > /* load board-specific initialization code */
> > #include <mach/zboot.h>
> >
> > +#ifdef CONFIG_ZBOOT_ROM_MMCIF
> > + /* Load image from MMC */
> > + adr sp, __tmp_stack
> > + add sp, sp, #128
>
> This can be replaced with:
>
> adr sp, __tmp_stack + 128 ?
Thanks, changed.
> > + ldr r0, __image_start
> > + ldr r1, __image_end
> > + subs r1, r1, r0
> > + ldr r0, __load_base
>
> > + mov lr, pc
> > + b mmcif_loader
>
> No need for a separate mov instruction - this will do both in one go:
> bl mmcif_loader
Also changed.
> > +
> > + /* Jump to loaded code */
> > + ldr r0, __loaded
> > + ldr r1, __image_start
> > + sub r0, r0, r1
> > + ldr r1, __load_base
> > + add pc, r0, r1
>
> *__loaded - *__image_start + *__load_base
>
> &__loaded - &_start + CONFIG_MEMORY_START + 0x02000000
>
> So this jumps to the '__loaded' label in the just loaded image - are you
> sure you want to jump to a location that contains an address rather than
> code? I think you want the two changes below to correct that.
Thanks, I have verified that your change is correct.
Actually, I'm rather unsure how my (broken) code got this far.
I suspect that I moved __tmp_stack late in the game and
forgot to re-test the code. My bad.
> > +
> > +__image_start:
> > + .long _start
> > +__image_end:
> > + .long _got_end
> > +__load_base:
> > + .long CONFIG_MEMORY_START + 0x02000000 @ Load at 32Mb into SDRAM
> > +__loaded:
> > + .long __loaded
>
> change to
> .long __continue
>
> > + .align
> > +__tmp_stack:
> > + .space 128
>
> add __continue
>
> > +#endif /* CONFIG_ZBOOT_ROM_MMCIF */
> > +
> > b 1f
> > __atags:@ tag #1
> > .long 12 @ tag->hdr.size = tag_size(tag_core);
> > diff --git a/arch/arm/boot/compressed/mmcif-sh7372.c b/arch/arm/boot/compressed/mmcif-sh7372.c
> > new file mode 100644
> > index 0000000..c54df5c
> > --- /dev/null
> > +++ b/arch/arm/boot/compressed/mmcif-sh7372.c
> > @@ -0,0 +1,87 @@
> > +/*
> > + * sh7372 MMCIF loader
> > + *
> > + * Copyright (C) 2010 Magnus Damm
> > + * Copyright (C) 2010 Simon Horman
> > + *
> > + * This file is subject to the terms and conditions of the GNU General Public
> > + * License. See the file "COPYING" in the main directory of this archive
> > + * for more details.
> > + */
> > +
> > +#include <linux/mmc/sh_mmcif.h>
> > +#include <mach/mmcif.h>
> > +
> > +#define MMCIF_BASE (void __iomem *)0xe6bd0000
> > +
> > +#define PORT84CR 0xe6050054
> > +#define PORT85CR 0xe6050055
> > +#define PORT86CR 0xe6050056
> > +#define PORT87CR 0xe6050057
> > +#define PORT88CR 0xe6050058
> > +#define PORT89CR 0xe6050059
> > +#define PORT90CR 0xe605005a
> > +#define PORT91CR 0xe605005b
> > +#define PORT92CR 0xe605005c
> > +#define PORT99CR 0xe6050063
> > +
> > +#define SMSTPCR3 0xe615013c
>
> These should also be (void __iomem *).
>
> > diff --git a/arch/arm/mach-shmobile/include/mach/mmcif-ap4eb.h b/arch/arm/mach-shmobile/include/mach/mmcif-ap4eb.h
> > new file mode 100644
> > index 0000000..c6b10ee
> > --- /dev/null
> > +++ b/arch/arm/mach-shmobile/include/mach/mmcif-ap4eb.h
> > @@ -0,0 +1,29 @@
> > +#ifndef MMCIF_AP4EB_H
> > +#define MMCIF_AP4EB_H
> > +
> > +#define PORT185CR 0xe60520b9
> > +#define PORT186CR 0xe60520ba
> > +#define PORT187CR 0xe60520bb
> > +#define PORT188CR 0xe60520bc
> > +
> > +#define PORTR191_160DR 0xe6056014
>
> Ditto.
Thanks, I've fixed these.
^ permalink raw reply
* [PATCH v4 00/10] net/fec: add dual fec support for i.MX28
From: David Miller @ 2011-01-09 23:44 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1294297998-26930-1-git-send-email-shawn.guo@freescale.com>
From: Shawn Guo <shawn.guo@freescale.com>
Date: Thu, 6 Jan 2011 15:13:08 +0800
> This patch series is to add dual fec support for mx28, which is
> a mxs-based soc. Some code changes related to the following commits
> are also made in this patch set for some reasons.
>
> e6b043d512fa8d9a3801bf5d72bfa3b8fc3b3cc8
> netdev/fec.c: add phylib supporting to enable carrier detection (v2)
>
> e3fe8558c7fc182972c3d947d88744482111f304
> net/fec: fix pm to survive to suspend/resume
>
> It's been tested on mx28 evk and mx51 babbage. For mx28, it has
> to work against the tree
>
> git://git.pengutronix.de/git/imx/linux-2.6.git imx-for-2.6.38
>
> plus patch
>
> [PATCH v4] ARM: mxs: Change duart device to use amba-pl011
>
> The 3 patches below preceding with * have changes since v3, and
> the detailed change log can be found in individual patch.
I've applied all of the "net/fec:" patches (#1 to #5) to net-2.6,
please push the ARM changes via the appropriate ARM tree.
Thanks.
^ permalink raw reply
* [PATCH 5/5] ARM: pxa: Fix recursive call of pxa_(un)mask_low_gpio()
From: Marek Vasut @ 2011-01-09 23:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1294615746-27668-1-git-send-email-marek.vasut@gmail.com>
Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
---
arch/arm/mach-pxa/irq.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
index 81edf97..96571fe 100644
--- a/arch/arm/mach-pxa/irq.c
+++ b/arch/arm/mach-pxa/irq.c
@@ -112,14 +112,14 @@ static void pxa_mask_low_gpio(unsigned int irq)
{
struct irq_desc *desc = irq_to_desc(irq);
- desc->chip->mask(irq);
+ pxa_mask_irq(irq);
}
static void pxa_unmask_low_gpio(unsigned int irq)
{
struct irq_desc *desc = irq_to_desc(irq);
- desc->chip->unmask(irq);
+ pxa_unmask_irq(irq);
}
static struct irq_chip pxa_low_gpio_chip = {
--
1.7.2.3
^ permalink raw reply related
* [PATCH 4/5] ARM: pxa: Fix suspend/resume array index miscalculation
From: Marek Vasut @ 2011-01-09 23:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1294615746-27668-1-git-send-email-marek.vasut@gmail.com>
Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
---
arch/arm/mach-pxa/irq.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
index 78f0e0c..81edf97 100644
--- a/arch/arm/mach-pxa/irq.c
+++ b/arch/arm/mach-pxa/irq.c
@@ -194,14 +194,14 @@ void __init pxa_init_irq(int irq_nr, set_wake_t fn)
#ifdef CONFIG_PM
static unsigned long saved_icmr[MAX_INTERNAL_IRQS/32];
-static unsigned long saved_ipr[MAX_INTERNAL_IRQS];
+static unsigned long saved_ipr[MAX_INTERNAL_IRQS/32];
static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state)
{
int i;
- for (i = 0; i < pxa_internal_irq_nr; i += 32) {
- void __iomem *base = irq_base(i);
+ for (i = 0; i < pxa_internal_irq_nr; i++) {
+ void __iomem *base = irq_base(i << 5);
saved_icmr[i] = __raw_readl(base + ICMR);
__raw_writel(0, base + ICMR);
@@ -219,8 +219,8 @@ static int pxa_irq_resume(struct sys_device *dev)
{
int i;
- for (i = 0; i < pxa_internal_irq_nr; i += 32) {
- void __iomem *base = irq_base(i);
+ for (i = 0; i < pxa_internal_irq_nr; i++) {
+ void __iomem *base = irq_base(i << 5);
__raw_writel(saved_icmr[i], base + ICMR);
__raw_writel(0, base + ICLR);
--
1.7.2.3
^ permalink raw reply related
* [PATCH 3/5] ARM: pxa: Use cpu_has_ipr() consistently in irq.c
From: Marek Vasut @ 2011-01-09 23:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1294615746-27668-1-git-send-email-marek.vasut@gmail.com>
Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
---
arch/arm/mach-pxa/irq.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
index 54e91c9..78f0e0c 100644
--- a/arch/arm/mach-pxa/irq.c
+++ b/arch/arm/mach-pxa/irq.c
@@ -226,7 +226,7 @@ static int pxa_irq_resume(struct sys_device *dev)
__raw_writel(0, base + ICLR);
}
- if (!cpu_is_pxa25x())
+ if (cpu_has_ipr())
for (i = 0; i < pxa_internal_irq_nr; i++)
__raw_writel(saved_ipr[i], IRQ_BASE + IPR(i));
--
1.7.2.3
^ permalink raw reply related
* [PATCH 2/5] pxa: Remove unused variable in clock-pxa3xx.c
From: Marek Vasut @ 2011-01-09 23:29 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1294615746-27668-1-git-send-email-marek.vasut@gmail.com>
Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
---
arch/arm/mach-pxa/clock-pxa3xx.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-pxa/clock-pxa3xx.c b/arch/arm/mach-pxa/clock-pxa3xx.c
index 1b08a34..3f864cd 100644
--- a/arch/arm/mach-pxa/clock-pxa3xx.c
+++ b/arch/arm/mach-pxa/clock-pxa3xx.c
@@ -115,7 +115,6 @@ static unsigned long clk_pxa3xx_smemc_getrate(struct clk *clk)
{
unsigned long acsr = ACSR;
unsigned long memclkcfg = __raw_readl(MEMCLKCFG);
- unsigned int smcfs = (acsr >> 23) & 0x7;
return BASE_CLK * smcfs_mult[(acsr >> 23) & 0x7] /
df_clkdiv[(memclkcfg >> 16) & 0x3];
--
1.7.2.3
^ permalink raw reply related
* [PATCH 1/5] pxa: Fix warning in zeus.c
From: Marek Vasut @ 2011-01-09 23:29 UTC (permalink / raw)
To: linux-arm-kernel
Signed-off-by: Marek Vasut <marek.vasut@gmail.com>
---
arch/arm/mach-pxa/zeus.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-pxa/zeus.c b/arch/arm/mach-pxa/zeus.c
index c87f2b3..29830a3 100644
--- a/arch/arm/mach-pxa/zeus.c
+++ b/arch/arm/mach-pxa/zeus.c
@@ -830,8 +830,8 @@ static void __init zeus_init(void)
pr_info("Zeus CPLD V%dI%d\n", (system_rev & 0xf0) >> 4, (system_rev & 0x0f));
/* Fix timings for dm9000s (CS1/CS2)*/
- msc0 = __raw_readl(MSC0) & 0x0000ffff | (dm9000_msc << 16);
- msc1 = __raw_readl(MSC1) & 0xffff0000 | dm9000_msc;
+ msc0 = (__raw_readl(MSC0) & 0x0000ffff) | (dm9000_msc << 16);
+ msc1 = (__raw_readl(MSC1) & 0xffff0000) | dm9000_msc;
__raw_writel(msc0, MSC0);
__raw_writel(msc1, MSC1);
--
1.7.2.3
^ permalink raw reply related
* [PATCH] mmc, ARM: Add zboot from MMC support for SuperH Mobile ARM
From: Russell King - ARM Linux @ 2011-01-09 23:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110109124928.GC25591@verge.net.au>
On Sun, Jan 09, 2011 at 09:49:28PM +0900, Simon Horman wrote:
> diff --git a/arch/arm/boot/compressed/head-shmobile.S b/arch/arm/boot/compressed/head-shmobile.S
> index 30973b7..de83c5a 100644
> --- a/arch/arm/boot/compressed/head-shmobile.S
> +++ b/arch/arm/boot/compressed/head-shmobile.S
> @@ -25,6 +25,37 @@
> /* load board-specific initialization code */
> #include <mach/zboot.h>
>
> +#ifdef CONFIG_ZBOOT_ROM_MMCIF
> + /* Load image from MMC */
> + adr sp, __tmp_stack
> + add sp, sp, #128
This can be replaced with:
adr sp, __tmp_stack + 128 ?
> + ldr r0, __image_start
> + ldr r1, __image_end
> + subs r1, r1, r0
> + ldr r0, __load_base
> + mov lr, pc
> + b mmcif_loader
No need for a separate mov instruction - this will do both in one go:
bl mmcif_loader
> +
> + /* Jump to loaded code */
> + ldr r0, __loaded
> + ldr r1, __image_start
> + sub r0, r0, r1
> + ldr r1, __load_base
> + add pc, r0, r1
*__loaded - *__image_start + *__load_base
&__loaded - &_start + CONFIG_MEMORY_START + 0x02000000
So this jumps to the '__loaded' label in the just loaded image - are you
sure you want to jump to a location that contains an address rather than
code? I think you want the two changes below to correct that.
> +
> +__image_start:
> + .long _start
> +__image_end:
> + .long _got_end
> +__load_base:
> + .long CONFIG_MEMORY_START + 0x02000000 @ Load at 32Mb into SDRAM
> +__loaded:
> + .long __loaded
change to
.long __continue
> + .align
> +__tmp_stack:
> + .space 128
add __continue
> +#endif /* CONFIG_ZBOOT_ROM_MMCIF */
> +
> b 1f
> __atags:@ tag #1
> .long 12 @ tag->hdr.size = tag_size(tag_core);
> diff --git a/arch/arm/boot/compressed/mmcif-sh7372.c b/arch/arm/boot/compressed/mmcif-sh7372.c
> new file mode 100644
> index 0000000..c54df5c
> --- /dev/null
> +++ b/arch/arm/boot/compressed/mmcif-sh7372.c
> @@ -0,0 +1,87 @@
> +/*
> + * sh7372 MMCIF loader
> + *
> + * Copyright (C) 2010 Magnus Damm
> + * Copyright (C) 2010 Simon Horman
> + *
> + * This file is subject to the terms and conditions of the GNU General Public
> + * License. See the file "COPYING" in the main directory of this archive
> + * for more details.
> + */
> +
> +#include <linux/mmc/sh_mmcif.h>
> +#include <mach/mmcif.h>
> +
> +#define MMCIF_BASE (void __iomem *)0xe6bd0000
> +
> +#define PORT84CR 0xe6050054
> +#define PORT85CR 0xe6050055
> +#define PORT86CR 0xe6050056
> +#define PORT87CR 0xe6050057
> +#define PORT88CR 0xe6050058
> +#define PORT89CR 0xe6050059
> +#define PORT90CR 0xe605005a
> +#define PORT91CR 0xe605005b
> +#define PORT92CR 0xe605005c
> +#define PORT99CR 0xe6050063
> +
> +#define SMSTPCR3 0xe615013c
These should also be (void __iomem *).
> diff --git a/arch/arm/mach-shmobile/include/mach/mmcif-ap4eb.h b/arch/arm/mach-shmobile/include/mach/mmcif-ap4eb.h
> new file mode 100644
> index 0000000..c6b10ee
> --- /dev/null
> +++ b/arch/arm/mach-shmobile/include/mach/mmcif-ap4eb.h
> @@ -0,0 +1,29 @@
> +#ifndef MMCIF_AP4EB_H
> +#define MMCIF_AP4EB_H
> +
> +#define PORT185CR 0xe60520b9
> +#define PORT186CR 0xe60520ba
> +#define PORT187CR 0xe60520bb
> +#define PORT188CR 0xe60520bc
> +
> +#define PORTR191_160DR 0xe6056014
Ditto.
^ permalink raw reply
* [PATCH 4/5 v4] msm: convert 7x30 to gpiomux.
From: Dima Zavin @ 2011-01-09 22:53 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1283015148-10747-4-git-send-email-gbean@codeaurora.org>
Greg,
Just rebased on top of 2.6.37 and this patch is totally the wrong way
to go about this.
I should have commented at the appropriate time, so sorry for the late reply.
Having this msm_gpiomux_configs be always compiled in for all msm7x30
devices makes this entire system completely inflexible since you have
to modify common code to provide board specific initialization. The
definition of "msm_gpiomux_configs" belongs in the board file, not in
gpiomux-7x30.c. I think we need to delete this new file and move the
definition back into board-msm7x30.c, but just use the new gpiomux
APIs.
I can provide a patch if you like.
--Dima
On Sat, Aug 28, 2010 at 10:05 AM, Gregory Bean <gbean@codeaurora.org> wrote:
> Change deprecated gpio_tlmm_config calls to gpiomux calls.
>
> Signed-off-by: Gregory Bean <gbean@codeaurora.org>
> ---
> ?arch/arm/mach-msm/board-msm7x30.c | ? 20 --------------------
> ?arch/arm/mach-msm/gpiomux-7x30.c ?| ? 21 ++++++++++++++++++++-
> ?2 files changed, 20 insertions(+), 21 deletions(-)
>
> diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
> index e329819..74abb74 100644
> --- a/arch/arm/mach-msm/board-msm7x30.c
> +++ b/arch/arm/mach-msm/board-msm7x30.c
> @@ -39,22 +39,6 @@
>
> ?extern struct sys_timer msm_timer;
>
> -#ifdef CONFIG_SERIAL_MSM_CONSOLE
> -static struct msm_gpio uart2_config_data[] = {
> - ? ? ? { GPIO_CFG(49, 2, GPIO_OUTPUT, ?GPIO_PULL_DOWN, GPIO_2MA), "UART2_RFR"},
> - ? ? ? { GPIO_CFG(50, 2, GPIO_INPUT, ? GPIO_PULL_DOWN, GPIO_2MA), "UART2_CTS"},
> - ? ? ? { GPIO_CFG(51, 2, GPIO_INPUT, ? GPIO_PULL_DOWN, GPIO_2MA), "UART2_Rx"},
> - ? ? ? { GPIO_CFG(52, 2, GPIO_OUTPUT, ?GPIO_PULL_DOWN, GPIO_2MA), "UART2_Tx"},
> -};
> -
> -static void msm7x30_init_uart2(void)
> -{
> - ? ? ? msm_gpios_request_enable(uart2_config_data,
> - ? ? ? ? ? ? ? ? ? ? ? ARRAY_SIZE(uart2_config_data));
> -
> -}
> -#endif
> -
> ?static struct platform_device *devices[] __initdata = {
> ?#if defined(CONFIG_SERIAL_MSM) || defined(CONFIG_MSM_SERIAL_DEBUGGER)
> ? ? ? ? &msm_device_uart2,
> @@ -70,10 +54,6 @@ static void __init msm7x30_init_irq(void)
> ?static void __init msm7x30_init(void)
> ?{
> ? ? ? ?platform_add_devices(devices, ARRAY_SIZE(devices));
> -#ifdef CONFIG_SERIAL_MSM_CONSOLE
> - ? ? ? msm7x30_init_uart2();
> -#endif
> -
> ?}
>
> ?static void __init msm7x30_map_io(void)
> diff --git a/arch/arm/mach-msm/gpiomux-7x30.c b/arch/arm/mach-msm/gpiomux-7x30.c
> index 7b380b3..6ce41c5 100644
> --- a/arch/arm/mach-msm/gpiomux-7x30.c
> +++ b/arch/arm/mach-msm/gpiomux-7x30.c
> @@ -16,4 +16,23 @@
> ?*/
> ?#include "gpiomux.h"
>
> -struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = {};
> +struct msm_gpiomux_config msm_gpiomux_configs[GPIOMUX_NGPIOS] = {
> +#ifdef CONFIG_SERIAL_MSM_CONSOLE
> + ? ? ? [49] = { /* UART2 RFR */
> + ? ? ? ? ? ? ? .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?GPIOMUX_FUNC_2 | GPIOMUX_VALID,
> + ? ? ? },
> + ? ? ? [50] = { /* UART2 CTS */
> + ? ? ? ? ? ? ? .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?GPIOMUX_FUNC_2 | GPIOMUX_VALID,
> + ? ? ? },
> + ? ? ? [51] = { /* UART2 RX */
> + ? ? ? ? ? ? ? .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?GPIOMUX_FUNC_2 | GPIOMUX_VALID,
> + ? ? ? },
> + ? ? ? [52] = { /* UART2 TX */
> + ? ? ? ? ? ? ? .suspended = GPIOMUX_DRV_2MA | GPIOMUX_PULL_DOWN |
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ?GPIOMUX_FUNC_2 | GPIOMUX_VALID,
> + ? ? ? },
> +#endif
> +};
> --
> 1.7.0.4
>
> /usr2/gbean/.signature.codeaurora.org
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at ?http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at ?http://www.tux.org/lkml/
>
^ permalink raw reply
* [PATCH] mmc, ARM: Add zboot from MMC support for SuperH Mobile ARM
From: Simon Horman @ 2011-01-09 22:50 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1294589548.8897.1.camel@rojo>
On Sun, Jan 09, 2011 at 04:12:28PM +0000, Pawe? Moll wrote:
> Hi,
>
> > Documentation/arm/SH-Mobile/Makefile | 8 +
> > Documentation/arm/SH-Mobile/vrl4.c | 169 +++++++++++++++++++++
>
> How about putting those two into "tools" (in particular "tools/arm")
> instead of "Documentation"?
>
> Just a thought... ;-)
Thats fine by me except that tools/arm doesn't exist yet.
It would be good to get some consensus before creating it.
^ permalink raw reply
* [PATCH 08/11] ARM: pxa: sanitize IRQ registers access based on offset
From: Marek Vasut @ 2011-01-09 22:49 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1289546260-6208-8-git-send-email-haojian.zhuang@marvell.com>
On Friday 12 November 2010 08:17:37 Haojian Zhuang wrote:
> Signed-off-by: Eric Miao <eric.y.miao@gmail.com>
> Signed-off-by: Haojian Zhuang <haojian.zhuang@marvell.com>
I think there's something wrong with this patch. It crashes my ZipitZ2 (no crash
with this patch reverted). I'll investigate a bit and keep you informed, but see
below.
> ---
> arch/arm/mach-pxa/include/mach/regs-intc.h | 4 -
> arch/arm/mach-pxa/irq.c | 122
> ++++++++++++++++++---------- 2 files changed, 80 insertions(+), 46
> deletions(-)
>
> diff --git a/arch/arm/mach-pxa/include/mach/regs-intc.h
> b/arch/arm/mach-pxa/include/mach/regs-intc.h index 68464ce..662288e 100644
> --- a/arch/arm/mach-pxa/include/mach/regs-intc.h
> +++ b/arch/arm/mach-pxa/include/mach/regs-intc.h
> @@ -27,8 +27,4 @@
> #define ICFP3 __REG(0x40D0013C) /* Interrupt Controller FIQ Pending
> Register 3 */ #define ICPR3 __REG(0x40D00140) /* Interrupt Controller
> Pending Register 3 */
>
> -#define IPR(x) __REG(0x40D0001C + (x < 32 ? (x << 2) \
> - : (x < 64 ? (0x94 + ((x - 32) << 2)) \
> - : (0x128 + ((x - 64) << 2)))))
> -
> #endif /* __ASM_MACH_REGS_INTC_H */
> diff --git a/arch/arm/mach-pxa/irq.c b/arch/arm/mach-pxa/irq.c
> index b5cafe2..54e91c9 100644
> --- a/arch/arm/mach-pxa/irq.c
> +++ b/arch/arm/mach-pxa/irq.c
> @@ -16,20 +16,31 @@
> #include <linux/module.h>
> #include <linux/interrupt.h>
> #include <linux/sysdev.h>
> +#include <linux/io.h>
> +#include <linux/irq.h>
>
> #include <mach/hardware.h>
> -#include <asm/irq.h>
> -#include <asm/mach/irq.h>
> +#include <mach/irqs.h>
> #include <mach/gpio.h>
> -#include <mach/regs-intc.h>
>
> #include "generic.h"
>
> -#define MAX_INTERNAL_IRQS 128
> +#define IRQ_BASE (void __iomem *)io_p2v(0x40d00000)
> +
> +#define ICIP (0x000)
> +#define ICMR (0x004)
> +#define ICLR (0x008)
> +#define ICFR (0x00c)
> +#define ICPR (0x010)
> +#define ICCR (0x014)
> +#define ICHP (0x018)
> +#define IPR(i) (((i) < 32) ? (0x01c + ((i) << 2)) : \
> + ((i) < 64) ? (0x0b0 + (((i) - 32) << 2)) : \
> + (0x144 + (((i) - 64) << 2)))
> +#define IPR_VALID (1 << 31)
> +#define IRQ_BIT(n) (((n) - PXA_IRQ(0)) & 0x1f)
>
> -#define IRQ_BIT(n) (((n) - PXA_IRQ(0)) & 0x1f)
> -#define _ICMR(n) (*((((n) - PXA_IRQ(0)) & ~0x1f) ? &ICMR2 : &ICMR))
> -#define _ICLR(n) (*((((n) - PXA_IRQ(0)) & ~0x1f) ? &ICLR2 : &ICLR))
> +#define MAX_INTERNAL_IRQS 128
>
> /*
> * This is for peripheral IRQs internal to the PXA chip.
> @@ -44,12 +55,20 @@ static inline int cpu_has_ipr(void)
>
> static void pxa_mask_irq(unsigned int irq)
> {
> - _ICMR(irq) &= ~(1 << IRQ_BIT(irq));
> + void __iomem *base = get_irq_chip_data(irq);
> + uint32_t icmr = __raw_readl(base + ICMR);
> +
> + icmr &= ~(1 << IRQ_BIT(irq));
> + __raw_writel(icmr, base + ICMR);
> }
>
> static void pxa_unmask_irq(unsigned int irq)
> {
> - _ICMR(irq) |= 1 << IRQ_BIT(irq);
> + void __iomem *base = get_irq_chip_data(irq);
> + uint32_t icmr = __raw_readl(base + ICMR);
> +
> + icmr |= 1 << IRQ_BIT(irq);
> + __raw_writel(icmr, base + ICMR);
> }
>
> static struct irq_chip pxa_internal_irq_chip = {
> @@ -91,12 +110,16 @@ static void pxa_ack_low_gpio(unsigned int irq)
>
> static void pxa_mask_low_gpio(unsigned int irq)
> {
> - ICMR &= ~(1 << (irq - PXA_IRQ(0)));
> + struct irq_desc *desc = irq_to_desc(irq);
> +
> + desc->chip->mask(irq);
> }
>
> static void pxa_unmask_low_gpio(unsigned int irq)
> {
> - ICMR |= 1 << (irq - PXA_IRQ(0));
> + struct irq_desc *desc = irq_to_desc(irq);
> +
> + desc->chip->unmask(irq);
> }
>
> static struct irq_chip pxa_low_gpio_chip = {
> @@ -125,33 +148,45 @@ static void __init pxa_init_low_gpio_irq(set_wake_t
> fn) pxa_low_gpio_chip.set_wake = fn;
> }
>
> +static inline void __iomem *irq_base(int i)
> +{
> + static unsigned long phys_base[] = {
> + 0x40d00000,
> + 0x40d0009c,
> + 0x40d00130,
> + };
> +
> + return (void __iomem *)io_p2v(phys_base[i >> 5]);
> +}
> +
> void __init pxa_init_irq(int irq_nr, set_wake_t fn)
> {
> - int irq, i;
> + int irq, i, n;
>
> BUG_ON(irq_nr > MAX_INTERNAL_IRQS);
>
> pxa_internal_irq_nr = irq_nr;
>
> - for (irq = PXA_IRQ(0); irq < PXA_IRQ(irq_nr); irq += 32) {
> - _ICMR(irq) = 0; /* disable all IRQs */
> - _ICLR(irq) = 0; /* all IRQs are IRQ, not FIQ */
> - }
> -
> - /* initialize interrupt priority */
> - if (cpu_has_ipr()) {
> - for (i = 0; i < irq_nr; i++)
> - IPR(i) = i | (1 << 31);
> + for (n = 0; n < irq_nr; n += 32) {
> + void __iomem *base = irq_base(n);
> +
> + __raw_writel(0, base + ICMR); /* disable all IRQs */
> + __raw_writel(0, base + ICLR); /* all IRQs are IRQ, not FIQ */
> + for (i = n; (i < (n + 32)) && (i < irq_nr); i++) {
> + /* initialize interrupt priority */
> + if (cpu_has_ipr())
> + __raw_writel(i | IPR_VALID, IRQ_BASE + IPR(i));
> +
> + irq = PXA_IRQ(i);
> + set_irq_chip(irq, &pxa_internal_irq_chip);
> + set_irq_chip_data(irq, base);
> + set_irq_handler(irq, handle_level_irq);
> + set_irq_flags(irq, IRQF_VALID);
> + }
> }
>
> /* only unmasked interrupts kick us out of idle */
> - ICCR = 1;
> -
> - for (irq = PXA_IRQ(0); irq < PXA_IRQ(irq_nr); irq++) {
> - set_irq_chip(irq, &pxa_internal_irq_chip);
> - set_irq_handler(irq, handle_level_irq);
> - set_irq_flags(irq, IRQF_VALID);
> - }
> + __raw_writel(1, irq_base(0) + ICCR);
>
> pxa_internal_irq_chip.set_wake = fn;
> pxa_init_low_gpio_irq(fn);
> @@ -163,16 +198,18 @@ static unsigned long saved_ipr[MAX_INTERNAL_IRQS];
>
> static int pxa_irq_suspend(struct sys_device *dev, pm_message_t state)
> {
> - int i, irq = PXA_IRQ(0);
> + int i;
> +
> + for (i = 0; i < pxa_internal_irq_nr; i += 32) {
> + void __iomem *base = irq_base(i);
>
> - for (i = 0; irq < PXA_IRQ(pxa_internal_irq_nr); i++, irq += 32) {
> - saved_icmr[i] = _ICMR(irq);
> - _ICMR(irq) = 0;
> + saved_icmr[i] = __raw_readl(base + ICMR);
> + __raw_writel(0, base + ICMR);
> }
>
> if (cpu_has_ipr()) {
> for (i = 0; i < pxa_internal_irq_nr; i++)
> - saved_ipr[i] = IPR(i);
> + saved_ipr[i] = __raw_readl(IRQ_BASE + IPR(i));
> }
>
> return 0;
> @@ -180,19 +217,20 @@ static int pxa_irq_suspend(struct sys_device *dev,
> pm_message_t state)
>
> static int pxa_irq_resume(struct sys_device *dev)
> {
> - int i, irq = PXA_IRQ(0);
> + int i;
>
> - if (cpu_has_ipr()) {
> - for (i = 0; i < pxa_internal_irq_nr; i++)
> - IPR(i) = saved_ipr[i];
> - }
> + for (i = 0; i < pxa_internal_irq_nr; i += 32) {
> + void __iomem *base = irq_base(i);
>
> - for (i = 0; irq < PXA_IRQ(pxa_internal_irq_nr); i++, irq += 32) {
> - _ICMR(irq) = saved_icmr[i];
> - _ICLR(irq) = 0;
> + __raw_writel(saved_icmr[i], base + ICMR);
eg. here, it just so does out-of-bounds access (saved_icmr[32] is wrong).
> + __raw_writel(0, base + ICLR);
> }
>
> - ICCR = 1;
> + if (!cpu_is_pxa25x())
> + for (i = 0; i < pxa_internal_irq_nr; i++)
> + __raw_writel(saved_ipr[i], IRQ_BASE + IPR(i));
> +
> + __raw_writel(1, IRQ_BASE + ICCR);
> return 0;
> }
> #else
^ permalink raw reply
* [PATCH] omap3: clocks: Fix build error 'CK_3430ES2' undeclared here
From: Santosh Shilimkar @ 2011-01-09 22:16 UTC (permalink / raw)
To: linux-arm-kernel
At latest mainline commit 0c21e3aaf6a, omap2plus build is broken. This
patch is trivial fix for the missed usb clock node for CK_3430ES2PLUS
flag update.
CHK include/generated/compile.h
CC arch/arm/mach-omap2/clock3xxx_data.o
arch/arm/mach-omap2/clock3xxx_data.c:3289: error: 'CK_3430ES2' undeclared
here (not in a function)
make[1]: *** [arch/arm/mach-omap2/clock3xxx_data.o] Error 1
make: *** [arch/arm/mach-omap2] Error 2
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
---
arch/arm/mach-omap2/clock3xxx_data.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c
index d3ab1c9..c54cc33 100644
--- a/arch/arm/mach-omap2/clock3xxx_data.c
+++ b/arch/arm/mach-omap2/clock3xxx_data.c
@@ -3286,7 +3286,7 @@ static struct omap_clk omap3xxx_clks[] = {
CLK(NULL, "cpefuse_fck", &cpefuse_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
CLK(NULL, "ts_fck", &ts_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
CLK(NULL, "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX | CK_36XX),
- CLK("ehci-omap.0", "usbtll_fck", &usbtll_fck, CK_3430ES2 | CK_AM35XX),
+ CLK("ehci-omap.0", "usbtll_fck", &usbtll_fck, CK_3430ES2PLUS | CK_AM35XX),
CLK("omap-mcbsp.1", "prcm_fck", &core_96m_fck, CK_3XXX),
CLK("omap-mcbsp.5", "prcm_fck", &core_96m_fck, CK_3XXX),
CLK(NULL, "core_96m_fck", &core_96m_fck, CK_3XXX),
--
1.6.0.4
^ permalink raw reply related
* [PATCH] ARM: smp: Introduce ARCH_SKIP_SECONDARY_CALIBRATE to
From: Santosh Shilimkar @ 2011-01-09 21:28 UTC (permalink / raw)
To: linux-arm-kernel
speed-up boot
On some architectures, secondary cores shares clock with primiary
core and hence scale together. Hence secondary core lpj calibration
is not necessary and can be skipped to save considerable time.
This can speed up the secondary cpu boot and hotplug cpu online
paths.
Signed-off-by: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Russell King <rmk+kernel@arm.linux.org.uk>
---
arch/arm/Kconfig | 10 ++++++++++
arch/arm/kernel/smp.c | 17 ++++++++++++++++-
2 files changed, 26 insertions(+), 1 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 5cff165..677d87f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1418,6 +1418,16 @@ config ARCH_SPARSEMEM_DEFAULT
config ARCH_SELECT_MEMORY_MODEL
def_bool ARCH_SPARSEMEM_ENABLE
+config ARCH_SKIP_SECONDARY_CALIBRATE
+ bool "Skip secondary CPU calibration"
+ depends on SMP
+ help
+ On some architectures, secondary cores shares clock with
primiary
+ core and hence scale together. Hence secondary core lpj
calibration
+ is not necessary and can be skipped to save considerable time.
+
+ If unsure, say n.
+
config HIGHMEM
bool "High Memory Support (EXPERIMENTAL)"
depends on MMU && EXPERIMENTAL
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 4539ebc..baf2707 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -270,6 +270,20 @@ static void __cpuinit smp_store_cpu_info(unsigned int
cpuid)
}
/*
+ * Skip the secondary calibration on architectures sharing clock
+ * with primary cpu. Archs can use ARCH_SKIP_SECONDARY_CALIBRATE
+ * for this.
+ */
+static inline int skip_secondary_calibrate(void)
+{
+#ifdef CONFIG_ARCH_SKIP_SECONDARY_CALIBRATE
+ return 0;
+#else
+ return -ENXIO;
+#endif
+}
+
+/*
* This is the secondary CPU boot entry. We're using this CPUs
* idle thread stack, but a set of temporary page tables.
*/
@@ -312,7 +326,8 @@ asmlinkage void __cpuinit secondary_start_kernel(void)
*/
percpu_timer_setup();
- calibrate_delay();
+ if (skip_secondary_calibrate())
+ calibrate_delay();
smp_store_cpu_info(cpu);
--
1.6.0.4
--20cf30433ede5cd51b049a1c33a7
Content-Type: application/octet-stream;
name="0001-ARM-smp-Introduce-ARCH_SKIP_SECONDARY_CALIBRATE-to.patch"
Content-Disposition: attachment;
filename="0001-ARM-smp-Introduce-ARCH_SKIP_SECONDARY_CALIBRATE-to.patch"
Content-Transfer-Encoding: base64
X-Attachment-Id: 867a3d3748f4cb86_0.1
RnJvbSA0ODRhZDdiNThlNWJmN2YzNTIwNmNjYzA4OTJkY2Y2NTVmYzk1NzJmIE1vbiBTZXAgMTcg
MDA6MDA6MDAgMjAwMQpGcm9tOiBTYW50b3NoIFNoaWxpbWthciA8c2FudG9zaC5zaGlsaW1rYXJA
dGkuY29tPgpEYXRlOiBNb24sIDEwIEphbiAyMDExIDAyOjU4OjM5ICswNTMwClN1YmplY3Q6IFtQ
QVRDSF0gQVJNOiBzbXA6IEludHJvZHVjZSBBUkNIX1NLSVBfU0VDT05EQVJZX0NBTElCUkFURSB0
byBzcGVlZC11cCBib290CgpPbiBzb21lIGFyY2hpdGVjdHVyZXMsIHNlY29uZGFyeSBjb3JlcyBz
aGFyZXMgY2xvY2sgd2l0aCBwcmltaWFyeQpjb3JlIGFuZCBoZW5jZSBzY2FsZSB0b2dldGhlci4g
SGVuY2Ugc2Vjb25kYXJ5IGNvcmUgbHBqIGNhbGlicmF0aW9uCmlzIG5vdCBuZWNlc3NhcnkgYW5k
IGNhbiBiZSBza2lwcGVkIHRvIHNhdmUgY29uc2lkZXJhYmxlIHRpbWUuCgpUaGlzIGNhbiBzcGVl
ZCB1cCB0aGUgc2Vjb25kYXJ5IGNwdSBib290IGFuZCBob3RwbHVnIGNwdSBvbmxpbmUKcGF0aHMu
CgpTaWduZWQtb2ZmLWJ5OiBTYW50b3NoIFNoaWxpbWthciA8c2FudG9zaC5zaGlsaW1rYXJAdGku
Y29tPgpDYzogUnVzc2VsbCBLaW5nIDxybWsra2VybmVsQGFybS5saW51eC5vcmcudWs+Ci0tLQog
YXJjaC9hcm0vS2NvbmZpZyAgICAgIHwgICAxMCArKysrKysrKysrCiBhcmNoL2FybS9rZXJuZWwv
c21wLmMgfCAgIDE3ICsrKysrKysrKysrKysrKystCiAyIGZpbGVzIGNoYW5nZWQsIDI2IGluc2Vy
dGlvbnMoKyksIDEgZGVsZXRpb25zKC0pCgpkaWZmIC0tZ2l0IGEvYXJjaC9hcm0vS2NvbmZpZyBi
L2FyY2gvYXJtL0tjb25maWcKaW5kZXggNWNmZjE2NS4uNjc3ZDg3ZiAxMDA2NDQKLS0tIGEvYXJj
aC9hcm0vS2NvbmZpZworKysgYi9hcmNoL2FybS9LY29uZmlnCkBAIC0xNDE4LDYgKzE0MTgsMTYg
QEAgY29uZmlnIEFSQ0hfU1BBUlNFTUVNX0RFRkFVTFQKIGNvbmZpZyBBUkNIX1NFTEVDVF9NRU1P
UllfTU9ERUwKIAlkZWZfYm9vbCBBUkNIX1NQQVJTRU1FTV9FTkFCTEUKIAorY29uZmlnIEFSQ0hf
U0tJUF9TRUNPTkRBUllfQ0FMSUJSQVRFCisJYm9vbCAiU2tpcCBzZWNvbmRhcnkgQ1BVIGNhbGli
cmF0aW9uIgorCWRlcGVuZHMgb24gU01QCisJaGVscAorCSAgT24gc29tZSBhcmNoaXRlY3R1cmVz
LCBzZWNvbmRhcnkgY29yZXMgc2hhcmVzIGNsb2NrIHdpdGggcHJpbWlhcnkKKwkgIGNvcmUgYW5k
IGhlbmNlIHNjYWxlIHRvZ2V0aGVyLiBIZW5jZSBzZWNvbmRhcnkgY29yZSBscGogY2FsaWJyYXRp
b24KKwkgIGlzIG5vdCBuZWNlc3NhcnkgYW5kIGNhbiBiZSBza2lwcGVkIHRvIHNhdmUgY29uc2lk
ZXJhYmxlIHRpbWUuCisKKwkgIElmIHVuc3VyZSwgc2F5IG4uCisKIGNvbmZpZyBISUdITUVNCiAJ
Ym9vbCAiSGlnaCBNZW1vcnkgU3VwcG9ydCAoRVhQRVJJTUVOVEFMKSIKIAlkZXBlbmRzIG9uIE1N
VSAmJiBFWFBFUklNRU5UQUwKZGlmZiAtLWdpdCBhL2FyY2gvYXJtL2tlcm5lbC9zbXAuYyBiL2Fy
Y2gvYXJtL2tlcm5lbC9zbXAuYwppbmRleCA0NTM5ZWJjLi5iYWYyNzA3IDEwMDY0NAotLS0gYS9h
cmNoL2FybS9rZXJuZWwvc21wLmMKKysrIGIvYXJjaC9hcm0va2VybmVsL3NtcC5jCkBAIC0yNzAs
NiArMjcwLDIwIEBAIHN0YXRpYyB2b2lkIF9fY3B1aW5pdCBzbXBfc3RvcmVfY3B1X2luZm8odW5z
aWduZWQgaW50IGNwdWlkKQogfQogCiAvKgorICogU2tpcCB0aGUgc2Vjb25kYXJ5IGNhbGlicmF0
aW9uIG9uIGFyY2hpdGVjdHVyZXMgc2hhcmluZyBjbG9jaworICogd2l0aCBwcmltYXJ5IGNwdS4g
QXJjaHMgY2FuIHVzZSBBUkNIX1NLSVBfU0VDT05EQVJZX0NBTElCUkFURQorICogZm9yIHRoaXMu
CisgKi8KK3N0YXRpYyBpbmxpbmUgaW50IHNraXBfc2Vjb25kYXJ5X2NhbGlicmF0ZSh2b2lkKQor
eworI2lmZGVmIENPTkZJR19BUkNIX1NLSVBfU0VDT05EQVJZX0NBTElCUkFURQorCXJldHVybiAw
OworI2Vsc2UKKwlyZXR1cm4gLUVOWElPOworI2VuZGlmCit9CisKKy8qCiAgKiBUaGlzIGlzIHRo
ZSBzZWNvbmRhcnkgQ1BVIGJvb3QgZW50cnkuICBXZSdyZSB1c2luZyB0aGlzIENQVXMKICAqIGlk
bGUgdGhyZWFkIHN0YWNrLCBidXQgYSBzZXQgb2YgdGVtcG9yYXJ5IHBhZ2UgdGFibGVzLgogICov
CkBAIC0zMTIsNyArMzI2LDggQEAgYXNtbGlua2FnZSB2b2lkIF9fY3B1aW5pdCBzZWNvbmRhcnlf
c3RhcnRfa2VybmVsKHZvaWQpCiAJICovCiAJcGVyY3B1X3RpbWVyX3NldHVwKCk7CiAKLQljYWxp
YnJhdGVfZGVsYXkoKTsKKwlpZiAoc2tpcF9zZWNvbmRhcnlfY2FsaWJyYXRlKCkpCisJCWNhbGli
cmF0ZV9kZWxheSgpOwogCiAJc21wX3N0b3JlX2NwdV9pbmZvKGNwdSk7CiAKLS0gCjEuNi4wLjQK
Cg==
--20cf30433ede5cd51b049a1c33a7--
^ permalink raw reply related
* Bug: loops_per_jiffy based udelay() mostly shorter than requested
From: Russell King @ 2011-01-09 17:08 UTC (permalink / raw)
To: linux-arm-kernel
I've been looking at the ARM implementation of udelay(), as Moore's Law
may bite us in maybe the next six or so months. In doing so, I've been
comparing udelay() candidates against our replacement sched_clock()
implementation, which on the platform I've been using has a resolution of
about 41ns.
However, I'm having a hard time making it satisfy the requirement that
"udelay() must produce a delay of at least the requested duration." It
appears that it mostly produces a delay less than requested, particularly
if IRQs are off or for delays shorter than the jiffy interval (up to a
point). At the bottom of this message are the measured udelay() values
for a range of delays from 1us to 5ms.
It seems that loops_per_jiffy is being a little optimistic. The causes
seem to be:
1. the calibration loop in init/calibrate.c runs a successive
approximation on the value. This is biased towards producing a
shorter delay than one jiffy, as the last bit tested will be cleared
if __delay(loops_per_jiffy) produced a delay longer than one jiffy.
Eg, if on the penultimate iteration, loopbit = 0x800, and
__delay(0x7f800) produced a longer than desired duration, we clear
this bit and try the next bit: loopbit = 0x400, __delay(0x7f400).
If this produces a delay longer than the duration, we exit with
loops_per_jiffy = 0x7f000 - and __delay(0x7f000) will produce a
delay shorter than one jiffy. Otherwise, the delay was still
shorter and we exit with loops_per_jiffy leaving the bit set -
so again __delay(0x7f400) was shorter than one jiffy.
2. as a consequence of how this algorithm works, what we're actually
measuring is the time taken for __delay(loops_per_jiffy) plus the
overhead of one timer IRQ. So we end up with a loops_per_jiffy which
produces a delay equivalent to
(usec_per_jiffy - timer_interrupt_usec)
The error we're talking about is around .7% towards delays being "too
short" on the ARM926 test platform. To get correct results, I need (eg)
a lpj value to be increased from 521216 (0x7F400) to 5000000 / 4964033
* 521216 = 524993 (0x802C1).
For udelay(us), we - just like many architectures - calculate the number
of loops using the formula:
loops = us * loops_per_jiffy * HZ / 1000000
and we fall short on 'loops' - so that a requested 5ms delay becomes a
4.96ms delay. This error is also reflected as a %age in shorter delays
too, until about 2us delays where we finally produce delays longer than
requested due to the overheads in calculating the loops value.
Given the difference in values (0x7F400 vs 0x802C1) (1) doesn't really
come into it as the dominant error is from (2) - in this case, 0x7f800
was measured as too long so cleared, and the last trial of 0x7f400 was
measured as too short.
Obviously, we can't run the calibration with IRQs off, otherwise jiffies
won't increment and the calibration algorithm locks up. We also may not
have sched_clock() initialized at this point either (it may also be
jiffy based), so we can't use that.
Any suggestions or thoughts, or should we not care too much if udelay()
produces slightly shorter than desired delays? Or am I doing something
horribly wrong in the ARM code?
== results and code ===
Measured delays against sched_lock() counter running at 24MHz (41ns
resolution) with IRQs off, and with the patch below applied to ARM to
eliminate lost precision in the udelay conversion:
Calibrating delay loop... 104.24 BogoMIPS (lpj=521216)
udelay(1) = 1516ns
udelay(2) = 2424ns
udelay(5) = 5116ns
udelay(10) = 10091ns
udelay(20) = 20099ns
udelay(50) = 49766ns
udelay(100) = 99474ns
udelay(200) = 198674ns
udelay(500) = 496524ns
udelay(1000) = 992916ns
udelay(2000) = 1985766ns
udelay(5000) = 4964033ns
With loops_per_jiffy forced to 524993 (based on measured shortfall and
current lpj):
udelay(1) = 1166ns
udelay(2) = 2232ns
udelay(5) = 5141ns
udelay(10) = 10166ns
udelay(20) = 20250ns
udelay(50) = 50208ns
udelay(100) = 100232ns
udelay(200) = 200241ns
udelay(500) = 500424ns
udelay(1000) = 1000733ns
udelay(2000) = 2001391ns
udelay(5000) = 5003041ns
This was produced by:
static int __init test_udelay(void)
{
unsigned long long sc1, sc2, sd0, sd;
unsigned long delay, dm, d[3] = {1, 2, 5};
int i, j;
local_irq_disable();
sc1 = sched_clock();
sc2 = sched_clock();
sd0 = sc2 - sc1; /* eliminate sched_clock() overhead */
for (dm = 1; dm < 10000; dm *= 10) {
for (j = 0; j < 3; j++) {
delay = dm * d[j];
for (sd = 0, i = 0; i < 5; i++) {
sc1 = sched_clock();
udelay(delay);
sc2 = sched_clock();
sd += sc2 - sc1 - sd0;
}
printk("udelay(%lu) = %luns\n", delay,
(unsigned long)sd / 5);
}
}
local_irq_enable();
return 0;
}
subsys_initcall(test_udelay).
=== patch to fix loss of precision in calculating 'loops' ===
This affects only udelay() itself. The function used to calibrate lpj
(__delay()) uses the result of this calculation and is independent of
this error.
diff --git a/arch/arm/lib/delay.S b/arch/arm/lib/delay.S
index 8d6a876..3c9a05c 100644
--- a/arch/arm/lib/delay.S
+++ b/arch/arm/lib/delay.S
@@ -25,11 +25,15 @@ ENTRY(__udelay)
ldr r2, .LC1
mul r0, r2, r0
ENTRY(__const_udelay) @ 0 <= r0 <= 0x7fffff06
+ mov r1, #-1
ldr r2, .LC0
ldr r2, [r2] @ max = 0x01ffffff
+ add r0, r0, r1, lsr #32-14
mov r0, r0, lsr #14 @ max = 0x0001ffff
+ add r2, r2, r1, lsr #32-10
mov r2, r2, lsr #10 @ max = 0x00007fff
mul r0, r2, r0 @ max = 2^32-1
+ add r0, r0, r1, lsr #32-6
movs r0, r0, lsr #6
moveq pc, lr
--
Russell King
Linux kernel 2.6 ARM Linux - http://www.arm.linux.org.uk/
maintainer of:
^ permalink raw reply related
* [PATCH] mmc, ARM: Add zboot from MMC support for SuperH Mobile ARM
From: Paweł Moll @ 2011-01-09 16:12 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <20110109124928.GC25591@verge.net.au>
Hi,
> Documentation/arm/SH-Mobile/Makefile | 8 +
> Documentation/arm/SH-Mobile/vrl4.c | 169 +++++++++++++++++++++
How about putting those two into "tools" (in particular "tools/arm")
instead of "Documentation"?
Just a thought... ;-)
Cheers!
Pawe?
^ permalink raw reply
* [PATCH] mmc, ARM: Add zboot from MMC support for SuperH Mobile ARM
From: Simon Horman @ 2011-01-09 12:49 UTC (permalink / raw)
To: linux-arm-kernel
[ Reposted with correct addresses for arm and Paul ]
This allows a ROM-able zImage to be written to MMC and
for SuperH Mobile ARM to boot directly from the MMCIF
hardware block.
This is achieved by the MaskROM loading the first portion
of the image into MERAM and then jumping to it. This portion
contains loader code which copies the entire image to SDRAM
and jumps to it. From there the zImage boot code proceeds
as normal, uncompressing the image into its final location
and then jumping to it.
Cc: Magnus Damm <magnus.damm@gmail.com>
Signed-off-by: Simon Horman <horms@verge.net.au>
This patch depends on:
* "ARM: 6514/1: mach-shmobile: Add zboot support for SuperH Mobile ARM"
which has been merged into the devel branch of Russell King's
linux-2.6-arm tree.
* "mmc, sh: Move MMCIF_PROGRESS_* into sh_mmcif.h"
which has been merged into the common/mmcif branch of
Paul Mundt's sh-2.6 tree
* "mmc, sh: Remove sh_mmcif_boot_slurp()"
which has been merged into the common/mmcif branch of
Paul Mundt's sh-2.6 tree
v2:
Addressed comments by Magnus Damm
* Fix copyright in vrl4.c
* Fix use of #define CONFIG_ZBOOT_ROM_MMCIF in mmcif-sh7372.c
* Initialise LED GPIO lines in head-ap4evb.txt instead of mmcif-sh7372.c
as this is considered board-specific.
v3:
Addressed comments made in person by Magnus Damm
* Move mmcif_loader to be earlier in the image and
reduce the number of blocks of boot program loaded by the MaskRom
from 40 to 8 accordingly.
* Move LED GPIO initialisation into mmcif_progress_init
- This leaves the partner jet script unbloated
Other
* inline mmcif_update_progress so it is a static inline in a header file
v4
* Use htole16() and htole32() in v4rl.c to ensure
that the output is little endian
---
Documentation/arm/SH-Mobile/Makefile | 8 +
Documentation/arm/SH-Mobile/vrl4.c | 169 +++++++++++++++++++++
Documentation/arm/SH-Mobile/zboot-rom-mmcif.txt | 29 ++++
arch/arm/Kconfig | 12 ++
arch/arm/boot/compressed/Makefile | 13 ++-
arch/arm/boot/compressed/head-shmobile.S | 31 ++++
arch/arm/boot/compressed/mmcif-sh7372.c | 87 +++++++++++
arch/arm/mach-shmobile/include/mach/mmcif-ap4eb.h | 29 ++++
arch/arm/mach-shmobile/include/mach/mmcif.h | 16 ++
9 files changed, 393 insertions(+), 1 deletions(-)
create mode 100644 Documentation/arm/SH-Mobile/Makefile
create mode 100644 Documentation/arm/SH-Mobile/vrl4.c
create mode 100644 Documentation/arm/SH-Mobile/zboot-rom-mmcif.txt
create mode 100644 arch/arm/boot/compressed/mmcif-sh7372.c
create mode 100644 arch/arm/mach-shmobile/include/mach/mmcif-ap4eb.h
create mode 100644 arch/arm/mach-shmobile/include/mach/mmcif.h
diff --git a/Documentation/arm/SH-Mobile/Makefile b/Documentation/arm/SH-Mobile/Makefile
new file mode 100644
index 0000000..8771d83
--- /dev/null
+++ b/Documentation/arm/SH-Mobile/Makefile
@@ -0,0 +1,8 @@
+BIN := vrl4
+
+.PHONY: all
+all: $(BIN)
+
+.PHONY: clean
+clean:
+ rm -f *.o $(BIN)
diff --git a/Documentation/arm/SH-Mobile/vrl4.c b/Documentation/arm/SH-Mobile/vrl4.c
new file mode 100644
index 0000000..e8a1913
--- /dev/null
+++ b/Documentation/arm/SH-Mobile/vrl4.c
@@ -0,0 +1,169 @@
+/*
+ * vrl4 format generator
+ *
+ * Copyright (C) 2010 Simon Horman
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+/*
+ * usage: vrl4 < zImage > out
+ * dd if=out of=/dev/sdx bs=512 seek=1 # Write the image to sector 1
+ *
+ * Reads a zImage from stdin and writes a vrl4 image to stdout.
+ * In practice this means writing a padded vrl4 header to stdout followed
+ * by the zImage.
+ *
+ * The padding places the zImage at ALIGN bytes into the output.
+ * The vrl4 uses ALIGN + START_BASE as the start_address.
+ * This is where the mask ROM will jump to after verifying the header.
+ *
+ * The header sets copy_size to min(sizeof(zImage), MAX_BOOT_PROG_LEN) + ALIGN.
+ * That is, the mask ROM will load the padded header (ALIGN bytes)
+ * And then MAX_BOOT_PROG_LEN bytes of the image, or the entire image,
+ * whichever is smaller.
+ *
+ * The zImage is not modified in any way.
+ */
+
+#define _BSD_SOURCE
+#include <endian.h>
+#include <unistd.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <errno.h>
+
+struct hdr {
+ uint32_t magic1;
+ uint32_t reserved1;
+ uint32_t magic2;
+ uint32_t reserved2;
+ uint16_t copy_size;
+ uint16_t boot_options;
+ uint32_t reserved3;
+ uint32_t start_address;
+ uint32_t reserved4;
+ uint32_t reserved5;
+ char reserved6[308];
+};
+
+#define DECLARE_HDR(h) \
+ struct hdr (h) = { \
+ .magic1 = htole32(0xea000000), \
+ .reserved1 = htole32(0x56), \
+ .magic2 = htole32(0xe59ff008), \
+ .reserved3 = htole16(0x1) }
+
+/* Align to 512 bytes, the MMCIF sector size */
+#define ALIGN_BITS 9
+#define ALIGN (1 << ALIGN_BITS)
+
+#define START_BASE 0xe55b0000
+
+/*
+ * With an alignment of 512 the header uses the first sector.
+ * There is a 128 sector (64kbyte) limit on the data loaded by the mask ROM.
+ * So there are 127 sectors left for the boot programme. But in practice
+ * Only a small portion of a zImage is needed, 16 sectors should be more
+ * than enough.
+ *
+ * Note that this sets how much of the zImage is copied by the mask ROM.
+ * The entire zImage is present after the header and is loaded
+ * by the code in the boot program (which is the first portion of the zImage).
+ */
+#define MAX_BOOT_PROG_LEN (16 * 512)
+
+#define ROUND_UP(x) ((x + ALIGN - 1) & ~(ALIGN - 1))
+
+ssize_t do_read(int fd, void *buf, size_t count)
+{
+ size_t offset = 0;
+ ssize_t l;
+
+ while (offset < count) {
+ l = read(fd, buf + offset, count - offset);
+ if (!l)
+ break;
+ if (l < 0) {
+ if (errno == EAGAIN || errno == EWOULDBLOCK)
+ continue;
+ perror("read");
+ return -1;
+ }
+ offset += l;
+ }
+
+ return offset;
+}
+
+ssize_t do_write(int fd, const void *buf, size_t count)
+{
+ size_t offset = 0;
+ ssize_t l;
+
+ while (offset < count) {
+ l = write(fd, buf + offset, count - offset);
+ if (l < 0) {
+ if (errno == EAGAIN || errno == EWOULDBLOCK)
+ continue;
+ perror("write");
+ return -1;
+ }
+ offset += l;
+ }
+
+ return offset;
+}
+
+ssize_t write_zero(int fd, size_t len)
+{
+ size_t i = len;
+
+ while (i--) {
+ const char x = 0;
+ if (do_write(fd, &x, 1) < 0)
+ return -1;
+ }
+
+ return len;
+}
+
+int main(void)
+{
+ DECLARE_HDR(hdr);
+ char boot_program[MAX_BOOT_PROG_LEN];
+ size_t aligned_hdr_len, alligned_prog_len;
+ ssize_t prog_len;
+
+ prog_len = do_read(0, boot_program, sizeof(boot_program));
+ if (prog_len <= 0)
+ return -1;
+
+ aligned_hdr_len = ROUND_UP(sizeof(hdr));
+ hdr.start_address = htole32(START_BASE + aligned_hdr_len);
+ alligned_prog_len = ROUND_UP(prog_len);
+ hdr.copy_size = htole16(aligned_hdr_len + alligned_prog_len);
+
+ if (do_write(1, &hdr, sizeof(hdr)) < 0)
+ return -1;
+ if (write_zero(1, aligned_hdr_len - sizeof(hdr)) < 0)
+ return -1;
+
+ if (do_write(1, boot_program, prog_len) < 0)
+ return 1;
+
+ /* Write out the rest of the kernel */
+ while (1) {
+ prog_len = do_read(0, boot_program, sizeof(boot_program));
+ if (prog_len < 0)
+ return 1;
+ if (prog_len == 0)
+ break;
+ if (do_write(1, boot_program, prog_len) < 0)
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/Documentation/arm/SH-Mobile/zboot-rom-mmcif.txt b/Documentation/arm/SH-Mobile/zboot-rom-mmcif.txt
new file mode 100644
index 0000000..efff8ae
--- /dev/null
+++ b/Documentation/arm/SH-Mobile/zboot-rom-mmcif.txt
@@ -0,0 +1,29 @@
+ROM-able zImage boot from MMC
+-----------------------------
+
+An ROM-able zImage compiled with ZBOOT_ROM_MMCIF may be written to MMC and
+SuperH Mobile ARM will to boot directly from the MMCIF hardware block.
+
+This is achieved by the mask ROM loading the first portion of the image into
+MERAM and then jumping to it. This portion contains loader code which
+copies the entire image to SDRAM and jumps to it. From there the zImage
+boot code proceeds as normal, uncompressing the image into its final
+location and then jumping to it.
+
+This code has been tested on an AP4EB board using the developer 1A eMMC
+boot mode which is configured using the following jumper settings.
+The board used for testing required a patched mask ROM in order for
+this mode to function.
+
+ 8 7 6 5 4 3 2 1
+ x|x|x|x|x| |x|
+S4 -+-+-+-+-+-+-+-
+ | | | | |x| |x on
+
+The zImage must be written to the MMC card@sector 1 (512 bytes) in
+vrl4 format. A utility vrl4 is supplied to accomplish this.
+
+e.g.
+ vrl4 < zImage | dd of=/dev/sdX bs=512 seek=1
+
+A dual-voltage MMC 4.0 card was used for testing.
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 81c71da..899c77c 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1582,6 +1582,18 @@ config ZBOOT_ROM
Say Y here if you intend to execute your compressed kernel image
(zImage) directly from ROM or flash. If unsure, say N.
+config ZBOOT_ROM_MMCIF
+ bool "Include MMCIF loader in zImage (EXPERIMENTAL)"
+ depends on ZBOOT_ROM && ARCH_SH7372 && EXPERIMENTAL
+ help
+ Say Y here to include experimental MMCIF loading code in the
+ ROM-able zImage. With this enabled it is possible to write the
+ the ROM-able zImage kernel image to an MMC card and boot the
+ kernel straight from the reset vector. At reset the processor
+ Mask ROM will load the first part of the the ROM-able zImage
+ which in turn loads the rest the kernel image to RAM using the
+ MMCIF hardware block.
+
config CMDLINE
string "Default kernel command string"
default ""
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile
index 0a8f748..198007d 100644
--- a/arch/arm/boot/compressed/Makefile
+++ b/arch/arm/boot/compressed/Makefile
@@ -4,9 +4,20 @@
# create a compressed vmlinuz image from the original vmlinux
#
+OBJS =
+
+# Ensure that mmcif loader code appears early in the image
+# to minimise that number of bocks that have to be read in
+# order to load it.
+ifeq ($(CONFIG_ZBOOT_ROM_MMCIF),y)
+ifeq ($(CONFIG_ARCH_SH7372),y)
+OBJS += mmcif-sh7372.o
+endif
+endif
+
AFLAGS_head.o += -DTEXT_OFFSET=$(TEXT_OFFSET)
HEAD = head.o
-OBJS = misc.o decompress.o
+OBJS += misc.o decompress.o
FONTC = $(srctree)/drivers/video/console/font_acorn_8x8.c
#
diff --git a/arch/arm/boot/compressed/head-shmobile.S b/arch/arm/boot/compressed/head-shmobile.S
index 30973b7..de83c5a 100644
--- a/arch/arm/boot/compressed/head-shmobile.S
+++ b/arch/arm/boot/compressed/head-shmobile.S
@@ -25,6 +25,37 @@
/* load board-specific initialization code */
#include <mach/zboot.h>
+#ifdef CONFIG_ZBOOT_ROM_MMCIF
+ /* Load image from MMC */
+ adr sp, __tmp_stack
+ add sp, sp, #128
+ ldr r0, __image_start
+ ldr r1, __image_end
+ subs r1, r1, r0
+ ldr r0, __load_base
+ mov lr, pc
+ b mmcif_loader
+
+ /* Jump to loaded code */
+ ldr r0, __loaded
+ ldr r1, __image_start
+ sub r0, r0, r1
+ ldr r1, __load_base
+ add pc, r0, r1
+
+__image_start:
+ .long _start
+__image_end:
+ .long _got_end
+__load_base:
+ .long CONFIG_MEMORY_START + 0x02000000 @ Load at 32Mb into SDRAM
+__loaded:
+ .long __loaded
+ .align
+__tmp_stack:
+ .space 128
+#endif /* CONFIG_ZBOOT_ROM_MMCIF */
+
b 1f
__atags:@ tag #1
.long 12 @ tag->hdr.size = tag_size(tag_core);
diff --git a/arch/arm/boot/compressed/mmcif-sh7372.c b/arch/arm/boot/compressed/mmcif-sh7372.c
new file mode 100644
index 0000000..c54df5c
--- /dev/null
+++ b/arch/arm/boot/compressed/mmcif-sh7372.c
@@ -0,0 +1,87 @@
+/*
+ * sh7372 MMCIF loader
+ *
+ * Copyright (C) 2010 Magnus Damm
+ * Copyright (C) 2010 Simon Horman
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file "COPYING" in the main directory of this archive
+ * for more details.
+ */
+
+#include <linux/mmc/sh_mmcif.h>
+#include <mach/mmcif.h>
+
+#define MMCIF_BASE (void __iomem *)0xe6bd0000
+
+#define PORT84CR 0xe6050054
+#define PORT85CR 0xe6050055
+#define PORT86CR 0xe6050056
+#define PORT87CR 0xe6050057
+#define PORT88CR 0xe6050058
+#define PORT89CR 0xe6050059
+#define PORT90CR 0xe605005a
+#define PORT91CR 0xe605005b
+#define PORT92CR 0xe605005c
+#define PORT99CR 0xe6050063
+
+#define SMSTPCR3 0xe615013c
+
+/* SH7372 specific MMCIF loader
+ *
+ * loads the zImage from an MMC card starting from block 1.
+ *
+ * The image must be start with a vrl4 header and
+ * the zImage must start at offset 512 of the image. That is,
+ * at block 2 (=byte 1024) on the media
+ *
+ * Use the following line to write the vrl4 formated zImage
+ * to an MMC card
+ * # dd if=vrl4.out of=/dev/sdx bs=512 seek=1
+ */
+asmlinkage void mmcif_loader(unsigned char *buf, unsigned long len)
+{
+ mmcif_init_progress();
+ mmcif_update_progress(MMCIF_PROGRESS_ENTER);
+
+ /* Initialise MMC
+ * registers: PORT84CR-PORT92CR
+ * (MMCD0_0-MMCD0_7,MMCCMD0 Control)
+ * value: 0x04 - select function 4
+ */
+ __raw_writeb(0x04, PORT84CR);
+ __raw_writeb(0x04, PORT85CR);
+ __raw_writeb(0x04, PORT86CR);
+ __raw_writeb(0x04, PORT87CR);
+ __raw_writeb(0x04, PORT88CR);
+ __raw_writeb(0x04, PORT89CR);
+ __raw_writeb(0x04, PORT90CR);
+ __raw_writeb(0x04, PORT91CR);
+ __raw_writeb(0x04, PORT92CR);
+
+ /* Initialise MMC
+ * registers: PORT99CR (MMCCLK0 Control)
+ * value: 0x10 | 0x04 - enable output | select function 4
+ */
+ __raw_writeb(0x14, PORT99CR);
+
+ /* Enable clock to MMC hardware block */
+ __raw_writel(__raw_readl(SMSTPCR3) & ~(1 << 12), SMSTPCR3);
+
+ mmcif_update_progress(MMCIF_PROGRESS_INIT);
+
+ /* setup MMCIF hardware */
+ sh_mmcif_boot_init(MMCIF_BASE);
+
+ mmcif_update_progress(MMCIF_PROGRESS_LOAD);
+
+ /* load kernel via MMCIF interface */
+ sh_mmcif_boot_do_read(MMCIF_BASE, 2, /* Kernel is@block 2 */
+ (len + SH_MMCIF_BBS - 1) / SH_MMCIF_BBS, buf);
+
+
+ /* Disable clock to MMC hardware block */
+ __raw_writel(__raw_readl(SMSTPCR3) & (1 << 12), SMSTPCR3);
+
+ mmcif_update_progress(MMCIF_PROGRESS_DONE);
+}
diff --git a/arch/arm/mach-shmobile/include/mach/mmcif-ap4eb.h b/arch/arm/mach-shmobile/include/mach/mmcif-ap4eb.h
new file mode 100644
index 0000000..c6b10ee
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/mmcif-ap4eb.h
@@ -0,0 +1,29 @@
+#ifndef MMCIF_AP4EB_H
+#define MMCIF_AP4EB_H
+
+#define PORT185CR 0xe60520b9
+#define PORT186CR 0xe60520ba
+#define PORT187CR 0xe60520bb
+#define PORT188CR 0xe60520bc
+
+#define PORTR191_160DR 0xe6056014
+
+static inline void mmcif_init_progress(void)
+{
+ /* Initialise LEDS1-4
+ * registers: PORT185CR-PORT188CR (LED1-LED4 Control)
+ * value: 0x10 - enable output
+ */
+ __raw_writeb(0x10, PORT185CR);
+ __raw_writeb(0x10, PORT186CR);
+ __raw_writeb(0x10, PORT187CR);
+ __raw_writeb(0x10, PORT188CR);
+}
+
+static inline void mmcif_update_progress(int n)
+{
+ __raw_writel((__raw_readl(PORTR191_160DR) & ~(0xf << 25)) |
+ (1 << (25 + n)), PORTR191_160DR);
+}
+
+#endif /* MMCIF_AP4EB_H */
diff --git a/arch/arm/mach-shmobile/include/mach/mmcif.h b/arch/arm/mach-shmobile/include/mach/mmcif.h
new file mode 100644
index 0000000..0812f1e
--- /dev/null
+++ b/arch/arm/mach-shmobile/include/mach/mmcif.h
@@ -0,0 +1,16 @@
+#ifndef MMCIF_H
+#define MMCIF_H
+
+/**************************************************
+ *
+ * board specific settings
+ *
+ **************************************************/
+
+#ifdef CONFIG_MACH_AP4EVB
+#include "mach/mmcif-ap4eb.h"
+#else
+#error "unsupported board."
+#endif
+
+#endif /* MMCIF_H */
--
1.7.2.3
^ permalink raw reply related
* [PATCH] ARM: sched_clock: improve mult/shift accuracy with high frequency clocks
From: Russell King - ARM Linux @ 2011-01-09 10:52 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1294084049.2571.30.camel@work-vm>
On Mon, Jan 03, 2011 at 11:47:29AM -0800, john stultz wrote:
> Now, for sched_clock, there are a different set of expectations with
> regards to accuracy and expected idle times, and we'll probably need a
> similar consolidation effort to make sure the mult/shift calculations
> are correct and the resulting limits are taken into account by the
> scheduler when going into NOHZ mode.
However, it's exactly the same concerns wrt idle time. If you want
a 100% accurate sched_clock() and you're using the same counter
register for both sched_clock() and clocksource, then you might as
well have a 100% accurate clocksource too (it's essentially the same
conversion with the same upper bound.)
With a 32-bit counter at 200MHz, theoretically you have a wrap time of
slightly less than 21.5s, but with a 5ns accuracy (actually 5ns).
The existing sched_clock() code comes out with:
sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 178956ms
Versatile: shift = 26 mult = 2796202667
sched_clock: 32 bits at 3686kHz, resolution 271ns, wraps every 1165084ms
SA11x0: shift = 23 mult = 2275555556
sched_clock: 32 bits at 1000kHz, resolution 1000ns, wraps every 4294967ms
Tegra: shift = 22 mult = 4194304000
sched_clock: 32 bits at 32kHz, resolution 30517ns, wraps every 131071999ms
OMAP: shift = 17 mult = 4000000000
sched_clock: 32 bits at 200MHz, resolution 5ns, wraps every 21474ms
Orion: shift = 27 mult = 671088640
Reducing down the minsec from 60 to 5 gives:
sched_clock: 32 bits at 24MHz, resolution 41ns, wraps every 178956ms
Versatile: shift = 26 mult = 2796202667
sched_clock: 32 bits at 3686kHz, resolution 271ns, wraps every 1165084ms
SA11x0: shift = 23 mult = 2275555556
sched_clock: 32 bits at 1000kHz, resolution 1000ns, wraps every 4294967ms
Tegra: shift = 22 mult = 4194304000
sched_clock: 32 bits at 32kHz, resolution 30517ns, wraps every 131071999ms
OMAP: shift = 17 mult = 4000000000
sched_clock: 32 bits at 200MHz, resolution 5ns, wraps every 21474ms
Orion: shift = 29 mult = 2684354560
Note that the resolution and wrap periods are calculated using the chosen
constants. The constants for "Orion" do change, but it produces no visible
effect on the outcome - we still achieve the same resolution and the same
wrap period. Let's just check that with bc:
1 * 671088640 / 2^27
5.00000000000000000000
1 * 2684354560 / 2^29
5.00000000000000000000
Let's look at 183MHz, which is a value I've randomly picked to be obscure:
minsec=60
sched_clock: 32 bits at 183MHz, resolution 5ns, wraps every 23469ms
Orion: shift = 27 mult = 733430208
minsec=5
sched_clock: 32 bits at 183MHz, resolution 5ns, wraps every 23469ms
Orion: shift = 29 mult = 2933720831
1 * 733430208 / 2^27
5.46448087692260742187
1 * 2933720831 / 2^29
5.46448087505996227264
The difference between is 1.00000000034086406226 - so about 34 parts
per trillion. (34 * 10^-12)
Now, a Caesium fountain frequency standard may have an accuracy of
approx. 1 part in 10^-14. Rubidium frequency standards are around
1 part in 10^-12.
A standard crystal oscillator is around 1 part in 10^-6 to 10^-7. If
you really care about accuracy, you might use an ovened crystal
oscillator (OXCO) which'll get you to around 1 part in 10^-7..10^-9,
still well short of the calculation inaccuracy. You wouldn't use an
OXCO in a battery operated device though due to power consumption.
We're generally don't have a Caesium or Rubidium frequency standard, not
even a OXCO providing the clock source for the counter, so the accuracy
of the counters clock is much more significant than the conversion
factors by a factor of about one million.
What I'm saying is that there becomes a time where it really doesn't
matter if the conversion isn't accurate, provided it's accurate enough,
and it would appear to be accurate enough.
^ permalink raw reply
* [PATCHv3] watchdog: add support for the Synopsys DesignWare WDT
From: Wim Van Sebroeck @ 2011-01-09 10:07 UTC (permalink / raw)
To: linux-arm-kernel
In-Reply-To: <1294401797-24158-1-git-send-email-jamie@jamieiles.com>
Hi Jamie,
On top of other comments from Viresh:
> +static int dw_wdt_open(struct inode *inode, struct file *filp)
> +{
> + /* Make sure we don't get unloaded. */
> + __module_get(THIS_MODULE);
> +
> + spin_lock(&dw_wdt.lock);
> + if (!dw_wdt_is_enabled()) {
> + /*
> + * The watchdog is not currently enabled. Set the timeout to
> + * the maximum and then start it.
> + */
> + dw_wdt_set_top(DW_WDT_MAX_TOP);
> + writel(WDOG_CONTROL_REG_WDT_EN_MASK,
> + dw_wdt.regs + WDOG_CONTROL_REG_OFFSET);
> + }
> + spin_unlock(&dw_wdt.lock);
> +
> + return nonseekable_open(inode, filp);
> +}
Would be nice to have the open /dev/watchdog once protection here also.
> +static int __devexit dw_wdt_drv_remove(struct platform_device *pdev)
> +{
> + clk_disable(dw_wdt.clk);
> + clk_put(dw_wdt.clk);
> +
> + misc_deregister(&dw_wdt_miscdev);
> +
> + return 0;
> +}
misc_deregister (=link to user-space) should be called before the clk_disabel calls.
Kind regards,
Wim.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox