Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [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


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox