All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH 01/22] ARM: sunxi: Basic Allwinner A10/A13 (sun4i/sun5i) support
       [not found] <cover.1353842684.git.henrik@henriknordstrom.net>
@ 2012-11-25 11:37 ` Henrik Nordström
  2012-11-25 12:23   ` Luka Perkov
                     ` (3 more replies)
  2012-11-25 11:37 ` [U-Boot] [PATCH 02/22] ARM: sunxi: MMC driver Henrik Nordström
                   ` (20 subsequent siblings)
  21 siblings, 4 replies; 68+ messages in thread
From: Henrik Nordström @ 2012-11-25 11:37 UTC (permalink / raw)
  To: u-boot

This adds support for the Allwinner A10/A13 SoC's. Additionally
board support for the dev-boards sun4i/sun5i is added.

Signed-off-by: Tom Cubie <tangliang@allwinnertech.com>
Signed-off-by: Henrik Nordstr?m <henrik@henriknordstrom.net>
Signed-off-by: Stefan Roese <sr@denx.de>
---
 MAINTAINERS                                 |   13 ++
 arch/arm/cpu/armv7/Makefile                 |    2 +-
 arch/arm/cpu/armv7/sunxi/Makefile           |   51 +++++++
 arch/arm/cpu/armv7/sunxi/board.c            |   77 +++++++++++
 arch/arm/cpu/armv7/sunxi/clock.c            |   57 ++++++++
 arch/arm/cpu/armv7/sunxi/pinmux.c           |   61 +++++++++
 arch/arm/cpu/armv7/sunxi/reset.S            |   39 ++++++
 arch/arm/cpu/armv7/sunxi/timer.c            |  117 +++++++++++++++++
 arch/arm/include/asm/arch-sunxi/clock.h     |  179 +++++++++++++++++++++++++
 arch/arm/include/asm/arch-sunxi/cpu.h       |  146 +++++++++++++++++++++
 arch/arm/include/asm/arch-sunxi/dram.h      |  114 ++++++++++++++++
 arch/arm/include/asm/arch-sunxi/gpio.h      |  164 +++++++++++++++++++++++
 arch/arm/include/asm/arch-sunxi/sys_proto.h |   32 +++++
 arch/arm/include/asm/arch-sunxi/timer.h     |  102 ++++++++++++++
 board/sunxi/Makefile                        |   46 +++++++
 board/sunxi/board.c                         |   57 ++++++++
 boards.cfg                                  |    4 +
 include/configs/sun4i.h                     |   47 +++++++
 include/configs/sun5i.h                     |   56 ++++++++
 include/configs/sunxi-common.h              |  189 +++++++++++++++++++++++++++
 20 files changed, 1552 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/sunxi/Makefile
 create mode 100644 arch/arm/cpu/armv7/sunxi/board.c
 create mode 100644 arch/arm/cpu/armv7/sunxi/clock.c
 create mode 100644 arch/arm/cpu/armv7/sunxi/pinmux.c
 create mode 100644 arch/arm/cpu/armv7/sunxi/reset.S
 create mode 100644 arch/arm/cpu/armv7/sunxi/timer.c
 create mode 100644 arch/arm/include/asm/arch-sunxi/clock.h
 create mode 100644 arch/arm/include/asm/arch-sunxi/cpu.h
 create mode 100644 arch/arm/include/asm/arch-sunxi/dram.h
 create mode 100644 arch/arm/include/asm/arch-sunxi/gpio.h
 create mode 100644 arch/arm/include/asm/arch-sunxi/sys_proto.h
 create mode 100644 arch/arm/include/asm/arch-sunxi/timer.h
 create mode 100644 board/sunxi/Makefile
 create mode 100644 board/sunxi/board.c
 create mode 100644 include/configs/sun4i.h
 create mode 100644 include/configs/sun5i.h
 create mode 100644 include/configs/sunxi-common.h

diff --git a/MAINTAINERS b/MAINTAINERS
index c430574..80c1bd7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -331,6 +331,19 @@ Reinhard Meyer <reinhard.meyer@emk-elektronik.de>
 	TOP5200		MPC5200
 	TOP9000		ARM926EJS (AT91SAM9xxx SoC)
 
+Henrik Nordstrom <henrik@henriknordstrom.net>
+	A13_OLINUXINO	ARM V7 (Allwinner A13 SoC)
+	A13_MID		ARM V7 (Allwinner A13 SoC)
+	CUBIEBOARD	ARM V7 (Allwinner A10 SoC)
+	CUBIEBOARD_512	ARM V7 (Allwinner A10 SoC)
+	HACKBERRY	ARM V7 (Allwinner A10 SoC)
+	MELE_A1000	ARM V7 (Allwinner A10 SoC)
+	MINI-X		ARM V7 (Allwinner A10 SoC)
+	SUN4I		ARM V7 (Allwinner A10 SoC)
+	SUN4I_SDCON	ARM V7 (Allwinner A10 SoC)
+	SUN5I		ARM V7 (Allwinner A13 SoC)
+	SUN5I_SDCON	ARM V7 (Allwinner A13 SoC)
+
 Kyle Moffett <Kyle.D.Moffett@boeing.com>
 
 	HWW1U1A		P2020
diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile
index da1b5e8..56f51b5 100644
--- a/arch/arm/cpu/armv7/Makefile
+++ b/arch/arm/cpu/armv7/Makefile
@@ -33,7 +33,7 @@ COBJS	+= cpu.o
 COBJS	+= syslib.o
 COBJS	+= cmd_boot.o
 
-ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA20),)
+ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA20)$(CONFIG_SUNXI),)
 SOBJS	+= lowlevel_init.o
 endif
 
diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile
new file mode 100644
index 0000000..cbe1015
--- /dev/null
+++ b/arch/arm/cpu/armv7/sunxi/Makefile
@@ -0,0 +1,51 @@
+#
+# (C) Copyright 2000-2003
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	=  $(obj)lib$(SOC).o
+
+SOBJS	+= reset.o
+
+COBJS	+= timer.o
+COBJS	+= dram.o
+COBJS	+= board.o
+COBJS	+= clock.o
+COBJS	+= pinmux.o
+
+SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
+OBJS	:= $(addprefix $(obj),$(COBJS) $(COBJS-y) $(SOBJS))
+
+all:	 $(obj).depend $(LIB)
+
+$(LIB):	$(OBJS)
+	$(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+#########################################################################
diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c
new file mode 100644
index 0000000..652c19d
--- /dev/null
+++ b/arch/arm/cpu/armv7/sunxi/board.c
@@ -0,0 +1,77 @@
+/*
+ * (C) Copyright 2007-2011
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Tom Cubie <tangliang@allwinnertech.com>
+ *
+ * Some init for sunxi platform.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <serial.h>
+#include <asm/gpio.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/timer.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/sys_proto.h>
+
+int gpio_init(void)
+{
+#if CONFIG_CONS_INDEX == 1 && defined(CONFIG_UART0_PORT_F)
+#ifdef CONFIG_SUN4I
+	/* disable GPB22,23 as uart0 tx,rx to avoid conflict */
+	gpio_direction_input(SUNXI_GPB(22));
+	gpio_direction_input(SUNXI_GPB(23));
+#endif
+	sunxi_gpio_set_cfgpin(SUNXI_GPF(2), SUNXI_GPF2_UART0_TX);
+	sunxi_gpio_set_cfgpin(SUNXI_GPF(4), SUNXI_GPF4_UART0_RX);
+#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_SUN4I)
+	sunxi_gpio_set_cfgpin(SUNXI_GPB(22), SUN4I_GPB22_UART0_TX);
+	sunxi_gpio_set_cfgpin(SUNXI_GPB(23), SUN4I_GPB23_UART0_RX);
+#elif CONFIG_CONS_INDEX == 2 && defined(CONFIG_SUN5I)
+	sunxi_gpio_set_cfgpin(SUNXI_GPG(3), SUN5I_GPG3_UART0_TX);
+	sunxi_gpio_set_cfgpin(SUNXI_GPG(4), SUN5I_GPG4_UART0_RX);
+#else
+#error Unsupported console port number. Please fix pin mux settings in board.c
+#endif
+
+	return 0;
+}
+
+/* do some early init */
+void s_init(void)
+{
+	clock_init();
+	gpio_init();
+}
+
+void reset_cpu(ulong addr)
+{
+	sunxi_reset();
+}
+
+#ifndef CONFIG_SYS_DCACHE_OFF
+void enable_caches(void)
+{
+	/* Enable D-cache. I-cache is already enabled in start.S */
+	dcache_enable();
+}
+#endif
diff --git a/arch/arm/cpu/armv7/sunxi/clock.c b/arch/arm/cpu/armv7/sunxi/clock.c
new file mode 100644
index 0000000..424acfc
--- /dev/null
+++ b/arch/arm/cpu/armv7/sunxi/clock.c
@@ -0,0 +1,57 @@
+/*
+ * (C) Copyright 2007-2012
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Tom Cubie <tangliang@allwinnertech.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/sys_proto.h>
+
+int clock_init(void)
+{
+	struct sunxi_ccm_reg *const ccm =
+		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+
+	/* uart clock source is apb1 */
+	sr32(&ccm->apb1_clk_div_cfg, 24, 2, APB1_CLK_SRC_OSC24M);
+	sr32(&ccm->apb1_clk_div_cfg, 16, 2, APB1_FACTOR_N);
+	sr32(&ccm->apb1_clk_div_cfg, 0, 5, APB1_FACTOR_M);
+
+	/* open the clock for uart */
+	sr32(&ccm->apb1_gate, 16 + CONFIG_CONS_INDEX - 1, 1, CLK_GATE_OPEN);
+
+	return 0;
+}
+
+/* Return PLL5 frequency in Hz
+ * Note: Assumes PLL5 reference is 24MHz clock
+ */
+unsigned int clock_get_pll5(void)
+{
+	struct sunxi_ccm_reg *const ccm =
+		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+	uint32_t rval = readl(&ccm->pll5_cfg);
+	int n = (rval >> 8) & 0x1f;
+	int k = ((rval >> 4) & 3) + 1;
+	int p = 1 << ((rval >> 16) & 3);
+	return 24000000 * n * k / p;
+}
diff --git a/arch/arm/cpu/armv7/sunxi/pinmux.c b/arch/arm/cpu/armv7/sunxi/pinmux.c
new file mode 100644
index 0000000..77e1d90
--- /dev/null
+++ b/arch/arm/cpu/armv7/sunxi/pinmux.c
@@ -0,0 +1,61 @@
+/*
+ * (C) Copyright 2007-2011
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Tom Cubie <tangliang@allwinnertech.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/gpio.h>
+
+int sunxi_gpio_set_cfgpin(u32 pin, u32 val)
+{
+	u32 cfg;
+	u32 bank = GPIO_BANK(pin);
+	u32 index = GPIO_CFG_INDEX(pin);
+	u32 offset = GPIO_CFG_OFFSET(pin);
+	struct sunxi_gpio *pio =
+	    &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank];
+
+	cfg = readl(&pio->cfg[0] + index);
+	cfg &= ~(0xf << offset);
+	cfg |= val << offset;
+
+	writel(cfg, &pio->cfg[0] + index);
+
+	return 0;
+}
+
+int sunxi_gpio_get_cfgpin(u32 pin)
+{
+	u32 cfg;
+	u32 bank = GPIO_BANK(pin);
+	u32 index = GPIO_CFG_INDEX(pin);
+	u32 offset = GPIO_CFG_OFFSET(pin);
+	struct sunxi_gpio *pio =
+	    &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank];
+
+	cfg = readl(&pio->cfg[0] + index);
+	cfg >>= offset;
+
+	return cfg & 0xf;
+}
+
diff --git a/arch/arm/cpu/armv7/sunxi/reset.S b/arch/arm/cpu/armv7/sunxi/reset.S
new file mode 100644
index 0000000..36714e7
--- /dev/null
+++ b/arch/arm/cpu/armv7/sunxi/reset.S
@@ -0,0 +1,39 @@
+/*
+ * (C) Copyright 2007-2011
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Tom Cubie <tangliang@allwinnertech.com>
+ *
+ * Configuration settings for the Allwinner A10-evb board.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <asm/arch/cpu.h>
+
+#define SUNXI_WDOG_CTL		0x01C20C90
+#define SUNXI_WDOG_MODE		0x01C20C94
+
+.globl sunxi_reset
+sunxi_reset:
+	ldr r1, =SUNXI_WDOG_MODE
+	mov r3, #0x3
+	str r3, [r1]
+	mov r0, r0
+_loop_forever:
+	b	_loop_forever
diff --git a/arch/arm/cpu/armv7/sunxi/timer.c b/arch/arm/cpu/armv7/sunxi/timer.c
new file mode 100644
index 0000000..e19df09
--- /dev/null
+++ b/arch/arm/cpu/armv7/sunxi/timer.c
@@ -0,0 +1,117 @@
+/*
+ * (C) Copyright 2007-2011
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Tom Cubie <tangliang@allwinnertech.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/timer.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define TIMER_MODE   (0 << 7)	/* continuous mode */
+#define TIMER_DIV    (0 << 4)	/* pre scale 1 */
+#define TIMER_SRC    (1 << 2)	/* osc24m */
+#define TIMER_RELOAD (1 << 1)	/* reload internal value */
+#define TIMER_EN     (1 << 0)	/* enable timer */
+
+#define TIMER_CLOCK		(24 * 1000 * 1000)
+#define COUNT_TO_USEC(x)	((x) / 24)
+#define USEC_TO_COUNT(x)	((x) * 24)
+#define TICKS_PER_HZ		(TIMER_CLOCK / CONFIG_SYS_HZ)
+#define TICKS_TO_HZ(x)		((x) / TICKS_PER_HZ)
+
+#define TIMER_LOAD_VAL		0xffffffff
+
+#define TIMER_NUM		0	/* we use timer 0 */
+
+static struct sunxi_timer *timer_base =
+	&((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->timer[TIMER_NUM];
+
+/* macro to read the 32 bit timer: since it decrements, we invert read value */
+#define READ_TIMER() (~readl(&timer_base->val))
+
+/* init timer register */
+int timer_init(void)
+{
+	writel(TIMER_LOAD_VAL, &timer_base->inter);
+	writel(TIMER_MODE | TIMER_DIV | TIMER_SRC | TIMER_RELOAD | TIMER_EN,
+	       &timer_base->ctl);
+
+	return 0;
+}
+
+/* timer without interrupts */
+ulong get_timer(ulong base)
+{
+	return get_timer_masked() - base;
+}
+
+ulong get_timer_masked(void)
+{
+	/* current tick value */
+	ulong now = TICKS_TO_HZ(READ_TIMER());
+
+	if (now >= gd->lastinc)	/* normal (non rollover) */
+		gd->tbl += (now - gd->lastinc);
+	else			/* rollover */
+		gd->tbl += (TICKS_TO_HZ(TIMER_LOAD_VAL) - gd->lastinc) + now;
+	gd->lastinc = now;
+
+	return gd->tbl;
+}
+
+/* delay x useconds */
+void __udelay(unsigned long usec)
+{
+	long tmo = usec * (TIMER_CLOCK / 1000) / 1000;
+	ulong now, last = READ_TIMER();
+
+	while (tmo > 0) {
+		now = READ_TIMER();
+		if (now > last)	/* normal (non rollover) */
+			tmo -= now - last;
+		else		/* rollover */
+			tmo -= TIMER_LOAD_VAL - last + now;
+		last = now;
+	}
+}
+
+/*
+ * This function is derived from PowerPC code (read timebase as long long).
+ * On ARM it just returns the timer value.
+ */
+unsigned long long get_ticks(void)
+{
+	return get_timer(0);
+}
+
+/*
+ * This function is derived from PowerPC code (timebase clock frequency).
+ * On ARM it returns the number of timer ticks per second.
+ */
+ulong get_tbclk(void)
+{
+	ulong tbclk;
+	tbclk = CONFIG_SYS_HZ;
+	return tbclk;
+}
diff --git a/arch/arm/include/asm/arch-sunxi/clock.h b/arch/arm/include/asm/arch-sunxi/clock.h
new file mode 100644
index 0000000..863e59e
--- /dev/null
+++ b/arch/arm/include/asm/arch-sunxi/clock.h
@@ -0,0 +1,179 @@
+/*
+ * (C) Copyright 2007-2011
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Tom Cubie <tangliang@allwinnertech.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _SUNXI_CLOCK_H
+#define _SUNXI_CLOCK_H
+
+/* clock control module regs definition */
+
+struct sunxi_ccm_reg {
+	u32 pll1_cfg;		/* 0x00 pll1 control */
+	u32 pll1_tun;		/* 0x04 pll1 tuning */
+	u32 pll2_cfg;		/* 0x08 pll2 control */
+	u32 pll2_tun;		/* 0x0c pll2 tuning */
+	u32 pll3_cfg;		/* 0x10 pll3 control */
+	u8 res0[0x4];
+	u32 pll4_cfg;		/* 0x18 pll4 control */
+	u8 res1[0x4];
+	u32 pll5_cfg;		/* 0x20 pll5 control */
+	u32 pll5_tun;		/* 0x24 pll5 tuning */
+	u32 pll6_cfg;		/* 0x28 pll6 control */
+	u32 pll6_tun;		/* 0x2c pll6 tuning */
+	u32 pll7_cfg;		/* 0x30 pll7 control */
+	u32 pll1_tun2;		/* 0x34 pll5 tuning2 */
+	u8 res2[0x4];
+	u32 pll5_tun2;		/* 0x3c pll5 tuning2 */
+	u8 res3[0xc];
+	u32 pll_lock_dbg;	/* 0x4c pll lock time debug */
+	u32 osc24m_cfg;		/* 0x50 osc24m control */
+	u32 cpu_ahb_apb0_cfg;	/* 0x54 cpu,ahb and apb0 divide ratio */
+	u32 apb1_clk_div_cfg;	/* 0x58 apb1 clock dividor */
+	u32 axi_gate;		/* 0x5c axi module clock gating */
+	u32 ahb_gate0;		/* 0x60 ahb module clock gating 0 */
+	u32 ahb_gate1;		/* 0x64 ahb module clock gating 1 */
+	u32 apb0_gate;		/* 0x68 apb0 module clock gating */
+	u32 apb1_gate;		/* 0x6c apb1 module clock gating */
+	u8 res4[0x10];
+	u32 nand_sclk_cfg;	/* 0x80 nand sub clock control */
+	u32 ms_sclk_cfg;	/* 0x84 memory stick sub clock control */
+	u32 sd0_clk_cfg;	/* 0x88 sd0 clock control */
+	u32 sd1_clk_cfg;	/* 0x8c sd1 clock control */
+	u32 sd2_clk_cfg;	/* 0x90 sd2 clock control */
+	u32 sd3_clk_cfg;	/* 0x94 sd3 clock control */
+	u32 ts_clk_cfg;		/* 0x98 transport stream clock control */
+	u32 ss_clk_cfg;		/* 0x9c */
+	u32 spi0_clk_cfg;	/* 0xa0 */
+	u32 spi1_clk_cfg;	/* 0xa4 */
+	u32 spi2_clk_cfg;	/* 0xa8 */
+	u32 pata_clk_cfg;	/* 0xac */
+	u32 ir0_clk_cfg;	/* 0xb0 */
+	u32 ir1_clk_cfg;	/* 0xb4 */
+	u32 iis_clk_cfg;	/* 0xb8 */
+	u32 ac97_clk_cfg;	/* 0xbc */
+	u32 spdif_clk_cfg;	/* 0xc0 */
+	u32 keypad_clk_cfg;	/* 0xc4 */
+	u32 sata_clk_cfg;	/* 0xc8 */
+	u32 usb_clk_cfg;	/* 0xcc */
+	u32 gps_clk_cfg;	/* 0xd0 */
+	u32 spi3_clk_cfg;	/* 0xd4 */
+	u8 res5[0x28];
+	u32 dram_clk_cfg;	/* 0x100 */
+	u32 be0_clk_cfg;	/* 0x104 */
+	u32 be1_clk_cfg;	/* 0x108 */
+	u32 fe0_clk_cfg;	/* 0x10c */
+	u32 fe1_clk_cfg;	/* 0x110 */
+	u32 mp_clk_cfg;		/* 0x114 */
+	u32 lcd0_ch0_clk_cfg;	/* 0x118 */
+	u32 lcd1_ch0_clk_cfg;	/* 0x11c */
+	u32 csi_isp_clk_cfg;	/* 0x120 */
+	u8 res6[0x4];
+	u32 tvd_clk_reg;	/* 0x128 */
+	u32 lcd0_ch1_clk_cfg;	/* 0x12c */
+	u32 lcd1_ch1_clk_cfg;	/* 0x130 */
+	u32 csi0_clk_cfg;	/* 0x134 */
+	u32 csi1_clk_cfg;	/* 0x138 */
+	u32 ve_clk_cfg;		/* 0x13c */
+	u32 audio_codec_clk_cfg;	/* 0x140 */
+	u32 avs_clk_cfg;	/* 0x144 */
+	u32 ace_clk_cfg;	/* 0x148 */
+	u32 lvds_clk_cfg;	/* 0x14c */
+	u32 hdmi_clk_cfg;	/* 0x150 */
+	u32 mali_clk_cfg;	/* 0x154 */
+	u8 res7[0x4];
+	u32 mbus_clk_cfg;	/* 0x15c */
+};
+
+/* apb1 bit field */
+#define APB1_CLK_SRC_OSC24M		0
+#define APB1_FACTOR_M			0
+#define APB1_FACTOR_N			0
+
+/* clock divide */
+#define CPU_CLK_SRC_OSC24M		1
+#define CPU_CLK_SRC_PLL1		2
+#define AXI_DIV_1			0
+#define AXI_DIV_2			1
+#define AXI_DIV_3			2
+#define AXI_DIV_4			3
+#define AHB_DIV_1			0
+#define AHB_DIV_2			1
+#define AHB_DIV_4			2
+#define AHB_DIV_8			3
+#define APB0_DIV_1			0
+#define APB0_DIV_2			1
+#define APB0_DIV_4			2
+#define APB0_DIV_8			3
+
+#ifdef CONFIG_SUN5I
+#define AHB_CLK_SRC_AXI			0
+#endif
+
+#define CLK_GATE_OPEN			0x1
+#define CLK_GATE_CLOSE			0x0
+
+/* nand clock */
+#define NAND_CLK_SRC_OSC24		0
+#define NAND_CLK_DIV_N			0
+#define NAND_CLK_DIV_M			0
+
+/* gps clock */
+#define GPS_SCLK_GATING_OFF		0
+#define GPS_RESET			0
+
+/* ahb clock gate bit offset */
+#define AHB_GATE_OFFSET_GPS		26
+#define AHB_GATE_OFFSET_SATA		25
+#define AHB_GATE_OFFSET_PATA		24
+#define AHB_GATE_OFFSET_SPI3		23
+#define AHB_GATE_OFFSET_SPI2		22
+#define AHB_GATE_OFFSET_SPI1		21
+#define AHB_GATE_OFFSET_SPI0		20
+#define AHB_GATE_OFFSET_TS0		18
+#define AHB_GATE_OFFSET_EMAC		17
+#define AHB_GATE_OFFSET_ACE		16
+#define AHB_GATE_OFFSET_DLL		15
+#define AHB_GATE_OFFSET_SDRAM		14
+#define AHB_GATE_OFFSET_NAND		13
+#define AHB_GATE_OFFSET_MS		12
+#define AHB_GATE_OFFSET_MMC3		11
+#define AHB_GATE_OFFSET_MMC2		10
+#define AHB_GATE_OFFSET_MMC1		9
+#define AHB_GATE_OFFSET_MMC0		8
+#define AHB_GATE_OFFSET_BIST		7
+#define AHB_GATE_OFFSET_DMA		6
+#define AHB_GATE_OFFSET_SS		5
+#define AHB_GATE_OFFSET_USB_OHCI1	4
+#define AHB_GATE_OFFSET_USB_EHCI1	3
+#define AHB_GATE_OFFSET_USB_OHCI0	2
+#define AHB_GATE_OFFSET_USB_EHCI0	1
+#define AHB_GATE_OFFSET_USB		0
+
+#ifndef __ASSEMBLY__
+int clock_init(void);
+int clock_twi_onoff(int port, int state);
+void clock_set_pll1(int mhz);
+unsigned int clock_get_pll5(void);
+#endif
+
+#endif /* _SUNXI_CLOCK_H */
diff --git a/arch/arm/include/asm/arch-sunxi/cpu.h b/arch/arm/include/asm/arch-sunxi/cpu.h
new file mode 100644
index 0000000..6c8eaeb
--- /dev/null
+++ b/arch/arm/include/asm/arch-sunxi/cpu.h
@@ -0,0 +1,146 @@
+/*
+ * (C) Copyright 2007-2011
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Tom Cubie <tangliang@allwinnertech.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _SUNXI_CPU_H
+#define _SUNXI_CPU_H
+
+#define SUNXI_SRAM_A1_BASE		0x00000000
+#define SUNXI_SRAM_A1_SIZE		(16 * 1024)	/* 16k */
+
+#define SUNXI_SRAM_A2_BASE		0x00004000	/* 16k */
+#define SUNXI_SRAM_A3_BASE		0x00008000	/* 13k */
+#define SUNXI_SRAM_A4_BASE		0x0000B400	/* 3k */
+#define SUNXI_SRAM_D_BASE		0x01C00000
+#define SUNXI_SRAM_B_BASE		0x01C00000	/* 64k(secure) */
+
+#define SUNXI_SRAMC_BASE		0x01C00000
+#define SUNXI_DRAMC_BASE		0x01C01000
+#define SUNXI_DMA_BASE			0x01C02000
+#define SUNXI_NFC_BASE			0x01C03000
+#define SUNXI_TS_BASE			0x01C04000
+#define SUNXI_SPI0_BASE			0x01C05000
+#define SUNXI_SPI1_BASE			0x01C06000
+#define SUNXI_MS_BASE			0x01C07000
+#define SUNXI_TVD_BASE			0x01C08000
+#define SUNXI_CSI0_BASE			0x01C09000
+#define SUNXI_TVE0_BASE			0x01C0A000
+#define SUNXI_EMAC_BASE			0x01C0B000
+#define SUNXI_LCD0_BASE			0x01C0C000
+#define SUNXI_LCD1_BASE			0x01C0D000
+#define SUNXI_VE_BASE			0x01C0E000
+#define SUNXI_MMC0_BASE			0x01C0F000
+#define SUNXI_MMC1_BASE			0x01C10000
+#define SUNXI_MMC2_BASE			0x01C11000
+#define SUNXI_MMC3_BASE			0x01C12000
+#define SUNXI_USB0_BASE			0x01C13000
+#define SUNXI_USB1_BASE			0x01C14000
+#define SUNXI_SS_BASE			0x01C15000
+#define SUNXI_HDMI_BASE			0x01C16000
+#define SUNXI_SPI2_BASE			0x01C17000
+#define SUNXI_SATA_BASE			0x01C18000
+#define SUNXI_PATA_BASE			0x01C19000
+#define SUNXI_ACE_BASE			0x01C1A000
+#define SUNXI_TVE1_BASE			0x01C1B000
+#define SUNXI_USB2_BASE			0x01C1C000
+#define SUNXI_CSI1_BASE			0x01C1D000
+#define SUNXI_TZASC_BASE		0x01C1E000
+#define SUNXI_SPI3_BASE			0x01C1F000
+
+#define SUNXI_CCM_BASE			0x01C20000
+#define SUNXI_INTC_BASE			0x01C20400
+#define SUNXI_PIO_BASE			0x01C20800
+#define SUNXI_TIMER_BASE		0x01C20C00
+#define SUNXI_SPDIF_BASE		0x01C21000
+#define SUNXI_AC97_BASE			0x01C21400
+#define SUNXI_IR0_BASE			0x01C21800
+#define SUNXI_IR1_BASE			0x01C21C00
+
+#define SUNXI_IIS_BASE			0x01C22400
+#define SUNXI_LRADC_BASE		0x01C22800
+#define SUNXI_AD_DA_BASE		0x01C22C00
+#define SUNXI_KEYPAD_BASE		0x01C23000
+#define SUNXI_TZPC_BASE			0x01C23400
+#define SUNXI_SID_BASE			0x01C23800
+#define SUNXI_SJTAG_BASE		0x01C23C00
+
+#define SUNXI_TP_BASE			0x01C25000
+#define SUNXI_PMU_BASE			0x01C25400
+
+#define SUNXI_UART0_BASE		0x01C28000
+#define SUNXI_UART1_BASE		0x01C28400
+#define SUNXI_UART2_BASE		0x01C28800
+#define SUNXI_UART3_BASE		0x01C28C00
+#define SUNXI_UART4_BASE		0x01C29000
+#define SUNXI_UART5_BASE		0x01C29400
+#define SUNXI_UART6_BASE		0x01C29800
+#define SUNXI_UART7_BASE		0x01C29C00
+#define SUNXI_PS2_0_BASE		0x01C2A000
+#define SUNXI_PS2_1_BASE		0x01C2A400
+
+#define SUNXI_TWI0_BASE			0x01C2AC00
+#define SUNXI_TWI1_BASE			0x01C2B000
+#define SUNXI_TWI2_BASE			0x01C2B400
+
+#define SUNXI_CAN_BASE			0x01C2BC00
+
+#define SUNXI_SCR_BASE			0x01C2C400
+
+#define SUNXI_GPS_BASE			0x01C30000
+#define SUNXI_MALI400_BASE		0x01C40000
+
+/* module sram */
+#define SUNXI_SRAM_C_BASE		0x01D00000
+
+#define SUNXI_DE_FE0_BASE		0x01E00000
+#define SUNXI_DE_FE1_BASE		0x01E20000
+#define SUNXI_DE_BE0_BASE		0x01E60000
+#define SUNXI_DE_BE1_BASE		0x01E40000
+#define SUNXI_MP_BASE			0x01E80000
+#define SUNXI_AVG_BASE			0x01EA0000
+
+/* CoreSight Debug Module */
+#define SUNXI_CSDM_BASE			0x3F500000
+
+#define SUNXI_DDRII_DDRIII_BASE		0x40000000	/* 2G */
+
+#define SUNXI_BROM_BASE			0xFFFF0000	/* 32K */
+
+#define SUNXI_CPU_CFG			(SUNXI_TIMER_BASE + 0x13c)
+
+#ifndef __ASSEMBLY__
+/* boot type */
+enum sunxi_boot_type_t {
+	SUNXI_BOOT_TYPE_NULL,
+	SUNXI_BOOT_TYPE_MMC0,
+	SUNXI_BOOT_TYPE_NAND,
+	SUNXI_BOOT_TYPE_MMC2,
+	SUNXI_BOOT_TYPE_SPI
+};
+
+sunxi_boot_type_t get_boot_type(void);
+void sunxi_board_init(void);
+extern void sunxi_reset(void);
+#endif /* __ASSEMBLY__ */
+
+#endif /* _CPU_H */
diff --git a/arch/arm/include/asm/arch-sunxi/dram.h b/arch/arm/include/asm/arch-sunxi/dram.h
new file mode 100644
index 0000000..d3c0e9f
--- /dev/null
+++ b/arch/arm/include/asm/arch-sunxi/dram.h
@@ -0,0 +1,114 @@
+/*
+ * (C) Copyright 2007-2012
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Berg Xing <bergxing@allwinnertech.com>
+ * Tom Cubie <tangliang@allwinnertech.com>
+ *
+ * Sunxi platform dram register definition.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _SUNXI_DRAM_H
+#define _SUNXI_DRAM_H
+
+struct sunxi_dram_reg {
+	u32 ccr;		/* 0x00 controller configuration register */
+	u32 dcr;		/* 0x04 dram configuration register */
+	u32 iocr;		/* 0x08 i/o configuration register */
+	u32 csr;		/* 0x0c controller status register */
+	u32 drr;		/* 0x10 dram refresh register */
+	u32 tpr0;		/* 0x14 dram timing parameters register 0 */
+	u32 tpr1;		/* 0x18 dram timing parameters register 1 */
+	u32 tpr2;		/* 0x1c dram timing parameters register 2 */
+	u32 gdllcr;		/* 0x20 global dll control register */
+	u8 res0[0x28];
+	u32 rslr0;		/* 0x4c rank system latency register */
+	u32 rslr1;		/* 0x50 rank system latency register */
+	u8 res1[0x8];
+	u32 rdgr0;		/* 0x5c rank dqs gating register */
+	u32 rdgr1;		/* 0x60 rank dqs gating register */
+	u8 res2[0x34];
+	u32 odtcr;		/* 0x98 odt configuration register */
+	u32 dtr0;		/* 0x9c data training register 0 */
+	u32 dtr1;		/* 0xa0 data training register 1 */
+	u32 dtar;		/* 0xa4 data training address register */
+	u32 zqcr0;		/* 0xa8 zq control register 0 */
+	u32 zqcr1;		/* 0xac zq control register 1 */
+	u32 zqsr;		/* 0xb0 zq status register */
+	u32 idcr;		/* 0xb4 initializaton delay configure reg */
+	u8 res3[0x138];
+	u32 mr;			/* 0x1f0 mode register */
+	u32 emr;		/* 0x1f4 extended mode register */
+	u32 emr2;		/* 0x1f8 extended mode register */
+	u32 emr3;		/* 0x1fc extended mode register */
+	u32 dllctr;		/* 0x200 dll control register */
+	u32 dllcr[5];		/* 0x204 dll control register 0(byte 0) */
+	/* 0x208 dll control register 1(byte 1) */
+	/* 0x20c dll control register 2(byte 2) */
+	/* 0x210 dll control register 3(byte 3) */
+	/* 0x214 dll control register 4(byte 4) */
+	u32 dqtr0;		/* 0x218 dq timing register */
+	u32 dqtr1;		/* 0x21c dq timing register */
+	u32 dqtr2;		/* 0x220 dq timing register */
+	u32 dqtr3;		/* 0x224 dq timing register */
+	u32 dqstr;		/* 0x228 dqs timing register */
+	u32 dqsbtr;		/* 0x22c dqsb timing register */
+	u32 mcr;		/* 0x230 mode configure register */
+	u8 res[0x8];
+	u32 ppwrsctl;		/* 0x23c pad power save control */
+	u32 apr;		/* 0x240 arbiter period register */
+	u32 pldtr;		/* 0x244 priority level data threshold reg */
+	u8 res5[0x8];
+	u32 hpcr[32];		/* 0x250 host port configure register */
+	u8 res6[0x10];
+	u32 csel;		/* 0x2e0 controller select register */
+};
+
+struct dram_para {
+	u32 clock;
+	u32 type;
+	u32 rank_num;
+	u32 density;
+	u32 io_width;
+	u32 bus_width;
+	u32 cas;
+	u32 zq;
+	u32 odt_en;
+	u32 size;
+	u32 tpr0;
+	u32 tpr1;
+	u32 tpr2;
+	u32 tpr3;
+	u32 tpr4;
+	u32 tpr5;
+	u32 emr1;
+	u32 emr2;
+	u32 emr3;
+};
+
+#define SUN5I_DRAM_MCR_DCLK_OUT_OFFSET	16
+#define SUN4I_CCM_SDRAM_DCLK_OUT_OFFSET  15
+
+#define DRAM_CTRL_SELECT_MAGIC	0x16237495
+
+int sunxi_dram_init(void);
+int dramc_init(struct dram_para *para);
+
+#endif /* _SUNXI_DRAM_H */
diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
new file mode 100644
index 0000000..fceee6b
--- /dev/null
+++ b/arch/arm/include/asm/arch-sunxi/gpio.h
@@ -0,0 +1,164 @@
+/*
+ * (C) Copyright 2007-2012
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Tom Cubie <tangliang@allwinnertech.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _SUNXI_GPIO_H
+#define _SUNXI_GPIO_H
+
+/*
+ * sunxi has 9 banks of gpio, they are:
+ * PA0 - PA17 | PB0 - PB23 | PC0 - PC24
+ * PD0 - PD27 | PE0 - PE31 | PF0 - PF5
+ * PG0 - PG9  | PH0 - PH27 | PI0 - PI12
+ */
+
+#define SUNXI_GPIO_A	0
+#define SUNXI_GPIO_B	1
+#define SUNXI_GPIO_C	2
+#define SUNXI_GPIO_D	3
+#define SUNXI_GPIO_E	4
+#define SUNXI_GPIO_F	5
+#define SUNXI_GPIO_G	6
+#define SUNXI_GPIO_H	7
+#define SUNXI_GPIO_I	8
+
+struct sunxi_gpio {
+	u32 cfg[4];
+	u32 dat;
+	u32 drv[2];
+	u32 pull[2];
+};
+
+/* gpio interrupt control */
+struct sunxi_gpio_int {
+	u32 cfg[3];
+	u32 ctl;
+	u32 sta;
+	u32 deb;		/* interrupt debounce */
+};
+
+struct sunxi_gpio_reg {
+	struct sunxi_gpio gpio_bank[9];
+	u8 res[0xbc];
+	struct sunxi_gpio_int gpio_int;
+};
+
+#define GPIO_BANK(pin)		((pin) >> 5)
+#define GPIO_NUM(pin)		((pin) & 0x1F)
+
+#define GPIO_CFG_INDEX(pin)	(((pin) & 0x1F) >> 3)
+#define GPIO_CFG_OFFSET(pin)	((((pin) & 0x1F) & 0x7) << 2)
+
+/* GPIO bank sizes */
+#define SUNXI_GPIO_A_NR		32
+#define SUNXI_GPIO_B_NR		32
+#define SUNXI_GPIO_C_NR		32
+#define SUNXI_GPIO_D_NR		32
+#define SUNXI_GPIO_E_NR		32
+#define SUNXI_GPIO_F_NR		32
+#define SUNXI_GPIO_G_NR		32
+#define SUNXI_GPIO_H_NR		32
+#define SUNXI_GPIO_I_NR		32
+
+#define SUNXI_GPIO_NEXT(__gpio) \
+	((__gpio##_START) + (__gpio##_NR) + 0)
+
+enum sunxi_gpio_number {
+	SUNXI_GPIO_A_START = 0,
+	SUNXI_GPIO_B_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_A),
+	SUNXI_GPIO_C_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_B),
+	SUNXI_GPIO_D_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_C),
+	SUNXI_GPIO_E_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_D),
+	SUNXI_GPIO_F_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_E),
+	SUNXI_GPIO_G_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_F),
+	SUNXI_GPIO_H_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_G),
+	SUNXI_GPIO_I_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_H),
+};
+
+/* SUNXI GPIO number definitions */
+#define SUNXI_GPA(_nr)	(SUNXI_GPIO_A_START + (_nr))
+#define SUNXI_GPB(_nr)	(SUNXI_GPIO_B_START + (_nr))
+#define SUNXI_GPC(_nr)	(SUNXI_GPIO_C_START + (_nr))
+#define SUNXI_GPD(_nr)	(SUNXI_GPIO_D_START + (_nr))
+#define SUNXI_GPE(_nr)	(SUNXI_GPIO_E_START + (_nr))
+#define SUNXI_GPF(_nr)	(SUNXI_GPIO_F_START + (_nr))
+#define SUNXI_GPG(_nr)	(SUNXI_GPIO_G_START + (_nr))
+#define SUNXI_GPH(_nr)	(SUNXI_GPIO_H_START + (_nr))
+#define SUNXI_GPI(_nr)	(SUNXI_GPIO_I_START + (_nr))
+
+/* GPIO pin function config */
+#define SUNXI_GPIO_INPUT	0
+#define SUNXI_GPIO_OUTPUT	1
+
+#define SUNXI_GPA0_ERXD3	2
+#define SUNXI_GPA0_SPI1_CS0	3
+#define SUNXI_GPA0_UART2_RTS	4
+
+#define SUNXI_GPA1_ERXD2	2
+#define SUNXI_GPA1_SPI1_CLK	3
+#define SUNXI_GPA1_UART2_CTS	4
+
+#define SUNXI_GPA2_ERXD1	2
+#define SUNXI_GPA2_SPI1_MOSI	3
+#define SUNXI_GPA2_UART2_TX	4
+
+#define SUNXI_GPA10_UART1_TX	4
+#define SUNXI_GPA11_UART1_RX	4
+
+#define SUN4I_GPB22_UART0_TX	2
+#define SUN4I_GPB23_UART0_RX	2
+
+#define SUN5I_GPG3_UART0_TX	4
+#define SUN5I_GPG4_UART0_RX	4
+
+#define SUNXI_GPC2_NCLE		2
+#define SUNXI_GPC2_SPI0_CLK	3
+
+#define SUNXI_GPC6_NRB0		2
+#define SUNXI_GPC6_SDC2_CMD	3
+
+#define SUNXI_GPC7_NRB1		2
+#define SUNXI_GPC7_SDC2_CLK	3
+
+#define SUNXI_GPC8_NDQ0		2
+#define SUNXI_GPC8_SDC2_D0	3
+
+#define SUNXI_GPC9_NDQ1		2
+#define SUNXI_GPC9_SDC2_D1	3
+
+#define SUNXI_GPC10_NDQ2	2
+#define SUNXI_GPC10_SDC2_D2	3
+
+#define SUNXI_GPC11_NDQ3	2
+#define SUNXI_GPC11_SDC2_D3	3
+
+#define SUNXI_GPF2_SDC0_CLK	2
+#define SUNXI_GPF2_UART0_TX	4
+
+#define SUNXI_GPF4_SDC0_D3	2
+#define SUNXI_GPF4_UART0_RX	4
+
+int sunxi_gpio_set_cfgpin(u32 pin, u32 val);
+int sunxi_gpio_get_cfgpin(u32 pin);
+
+#endif /* _SUNXI_GPIO_H */
diff --git a/arch/arm/include/asm/arch-sunxi/sys_proto.h b/arch/arm/include/asm/arch-sunxi/sys_proto.h
new file mode 100644
index 0000000..1e8ae5d
--- /dev/null
+++ b/arch/arm/include/asm/arch-sunxi/sys_proto.h
@@ -0,0 +1,32 @@
+/*
+ * (C) Copyright 2007-2012
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Tom Cubie <tangliang@allwinnertech.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _SYS_PROTO_H_
+#define _SYS_PROTO_H_
+
+void sr32(u32 *, u32, u32, u32);
+void sdelay(unsigned long);
+void watchdog_init(void);
+
+#endif
diff --git a/arch/arm/include/asm/arch-sunxi/timer.h b/arch/arm/include/asm/arch-sunxi/timer.h
new file mode 100644
index 0000000..cbfec53
--- /dev/null
+++ b/arch/arm/include/asm/arch-sunxi/timer.h
@@ -0,0 +1,102 @@
+/*
+ * (C) Copyright 2007-2011
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Tom Cubie <tangliang@allwinnertech.com>
+ *
+ * Configuration settings for the Allwinner A10-evb board.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _SUNXI_TIMER_H_
+#define _SUNXI_TIMER_H_
+
+#ifndef __ASSEMBLY__
+
+/* General purpose timer */
+struct sunxi_timer {
+	u32 ctl;
+	u32 inter;
+	u32 val;
+	u8 res[4];
+};
+
+/* Audio video sync*/
+struct sunxi_avs {
+	u32 ctl;		/* 0x80 */
+	u32 cnt0;		/* 0x84 */
+	u32 cnt1;		/* 0x88 */
+	u32 div;		/* 0x8c */
+};
+
+/* 64 bit counter */
+struct sunxi_64cnt {
+	u32 ctl;		/* 0xa0 */
+	u32 lo;			/* 0xa4 */
+	u32 hi;			/* 0xa8 */
+};
+
+/* Watchdog */
+struct sunxi_wdog {
+	u32 ctl;		/* 0x90 */
+	u32 mode;		/* 0x94 */
+};
+
+/* Rtc */
+struct sunxi_rtc {
+	u32 ctl;		/* 0x100 */
+	u32 yymmdd;		/* 0x104 */
+	u32 hhmmss;		/* 0x108 */
+};
+
+/* Alarm */
+struct sunxi_alarm {
+	u32 ddhhmmss;		/* 0x10c */
+	u32 hhmmss;		/* 0x110 */
+	u32 en;			/* 0x114 */
+	u32 irqen;		/* 0x118 */
+	u32 irqsta;		/* 0x11c */
+};
+
+/* Timer general purpose register */
+struct sunxi_tgp {
+	u32 tgpd;
+};
+
+struct sunxi_timer_reg {
+	u32 tirqen;		/* 0x00 */
+	u32 tirqsta;		/* 0x04 */
+	u8 res1[8];
+	struct sunxi_timer timer[6];	/* We have 6 timers */
+	u8 res2[16];
+	struct sunxi_avs avs;
+	struct sunxi_wdog wdog;
+	u8 res3[8];
+	struct sunxi_64cnt cnt64;
+	u8 res4[0x58];
+	struct sunxi_rtc rtc;
+	struct sunxi_alarm alarm;
+	struct sunxi_tgp tgp[4];
+	u8 res5[8];
+	u32 cpu_cfg;
+};
+
+#endif /* __ASSEMBLY__ */
+
+#endif
diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile
new file mode 100644
index 0000000..43acbab
--- /dev/null
+++ b/board/sunxi/Makefile
@@ -0,0 +1,46 @@
+#
+# (C) Copyright 2000-2003
+# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
+#
+# See file CREDITS for list of people who contributed to this
+# project.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of
+# the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+# MA 02111-1307 USA
+#
+
+include $(TOPDIR)/config.mk
+
+LIB	:= $(obj)lib$(BOARD).o
+
+COBJS-y	:= board.o
+
+COBJS	:= $(COBJS-y)
+SRCS 	:= $(COBJS:.o=.c)
+OBJS 	:= $(addprefix $(obj),$(COBJS))
+
+all:	$(LIB)
+
+$(LIB):	$(obj).depend $(OBJS)
+	$(call cmd_link_o_target, $(OBJS))
+
+#########################################################################
+
+# defines $(obj).depend target
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
+
+########################################################################
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
new file mode 100644
index 0000000..ae05953
--- /dev/null
+++ b/board/sunxi/board.c
@@ -0,0 +1,57 @@
+/*
+ * (C) Copyright 2007-2011
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Tom Cubie <tangliang@allwinnertech.com>
+ *
+ * Some board init for the Allwinner A10-evb board.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/arch/dram.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/mmc.h>
+#include <axp209.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* add board specific code here */
+int board_init(void)
+{
+	gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100);
+
+	return 0;
+}
+
+#ifdef CONFIG_DISPLAY_BOARDINFO
+int checkboard(void)
+{
+	printf("Board: %s\n", CONFIG_SYS_BOARD_NAME);
+
+	return 0;
+}
+#endif
+
+int dram_init(void)
+{
+	gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, 1 << 30);
+
+	return 0;
+}
diff --git a/boards.cfg b/boards.cfg
index 7ae663c..13d1f74 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -288,6 +288,10 @@ whistler                     arm         armv7:arm720t whistler          nvidia
 colibri_t20_iris             arm         armv7:arm720t colibri_t20_iris  toradex        tegra20
 u8500_href                   arm         armv7       u8500               st-ericsson    u8500
 snowball                     arm         armv7       snowball               st-ericsson    u8500
+sun4i                        arm         armv7       sunxi               -              sunxi       sun4i
+sun4i_sdcon                  arm         armv7       sunxi               -              sunxi       sun4i:UART0_PORT_F
+sun5i                        arm         armv7       sunxi               -              sunxi       sun5i
+sun5i_sdcon                  arm         armv7       sunxi               -              sunxi       sun5i:UART0_PORT_F
 kzm9g                        arm         armv7       kzm9g               kmc            rmobile
 armadillo-800eva             arm         armv7       armadillo-800eva    atmark-techno  rmobile
 zynq                         arm         armv7       zynq                xilinx         zynq
diff --git a/include/configs/sun4i.h b/include/configs/sun4i.h
new file mode 100644
index 0000000..513f618
--- /dev/null
+++ b/include/configs/sun4i.h
@@ -0,0 +1,47 @@
+/*
+ * (C) Copyright 2012
+ * Henrik Nordstrom <henrik@henriknordstrom.net>
+ *
+ * Configuration settings for the Allwinner A10 (sun4i) CPU
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * Include common sunxi configuration where most the settings are
+ */
+#include <configs/sunxi-common.h>
+
+/*
+ * A10 specific configuration
+ */
+#define CONFIG_SUN4I		/* sun4i SoC generation */
+
+#define CONFIG_SYS_PROMPT		"sun4i#"
+#define CONFIG_MACH_TYPE		4104
+
+/* Define this to have console redirected to SD port */
+/* #define CONFIG_UART0_PORT_F */
+
+#define CONFIG_CONS_INDEX		1	/* UART0 */
+
+#endif /* __CONFIG_H */
diff --git a/include/configs/sun5i.h b/include/configs/sun5i.h
new file mode 100644
index 0000000..dc84aba
--- /dev/null
+++ b/include/configs/sun5i.h
@@ -0,0 +1,56 @@
+/*
+ * (C) Copyright 2012
+ * Henrik Nordstrom <henrik@henriknordstrom.net>
+ *
+ * Configuration settings for the Allwinner A13 (sun5i) CPU
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+/*
+ * Include common sunxi configuration where most the settings are
+ */
+#include <configs/sunxi-common.h>
+
+/*
+ * High Level Configuration Options
+ */
+#define CONFIG_SUN5I		/* sun5i SoC generation */
+
+#define CONFIG_SYS_PROMPT		"sun5i#"
+#define CONFIG_MACH_TYPE		4138
+
+/* Define this to have serial channel 1 (UART0) redirected to SD port */
+/* #define CONFIG_UART0_PORT_F */
+
+#ifndef CONFIG_CONS_INDEX
+#ifdef CONFIG_UART0_PORT_F
+#define CONFIG_CONS_INDEX		1	/* UART0 on PORT_F (sdcard) */
+#else
+#define CONFIG_CONS_INDEX		2	/* UART1 */
+#endif
+#endif
+
+/* Leave ICACHE off while debugging with OpenOCD */
+#define CONFIG_SYS_ICACHE_OFF
+
+#endif /* __CONFIG_H */
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
new file mode 100644
index 0000000..33309f3
--- /dev/null
+++ b/include/configs/sunxi-common.h
@@ -0,0 +1,189 @@
+/*
+ * (C) Copyright 2007-2011
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Tom Cubie <tangliang@allwinnertech.com>
+ *
+ * Configuration settings for the Allwinner A10-evb board.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _SUNXI_CONFIG_H
+#define _SUNXI_CONFIG_H
+
+/*
+ * High Level Configuration Options
+ */
+#define CONFIG_ALLWINNER	/* It's a Allwinner chip */
+#define	CONFIG_SUNXI		/* which is sunxi family */
+
+#include <asm/arch/cpu.h>	/* get chip and board defs */
+
+#define CONFIG_SYS_TEXT_BASE		0x4A000000
+
+/*
+ * Display CPU and Board information
+ */
+#define CONFIG_DISPLAY_BOARDINFO
+
+/* Clock Defines */
+
+/* Serial & console */
+#define CONFIG_SYS_NS16550
+#define CONFIG_SYS_NS16550_SERIAL
+/* ns16550 reg in the low bits of cpu reg */
+#define CONFIG_SYS_NS16550_REG_SIZE	(-4)
+#define CONFIG_SYS_NS16550_CLK		(24000000)
+#define CONFIG_SYS_NS16550_COM1		SUNXI_UART0_BASE
+#define CONFIG_SYS_NS16550_COM2		SUNXI_UART1_BASE
+#define CONFIG_SYS_NS16550_COM3		SUNXI_UART2_BASE
+#define CONFIG_SYS_NS16550_COM4		SUNXI_UART3_BASE
+
+/* DRAM Base */
+#define CONFIG_SYS_SDRAM_BASE		0x40000000
+#define CONFIG_SYS_INIT_RAM_ADDR	0x0
+#define CONFIG_SYS_INIT_RAM_SIZE	0x8000	/* 32K */
+
+#define CONFIG_SYS_INIT_SP_OFFSET \
+	(CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)
+#define CONFIG_SYS_INIT_SP_ADDR \
+	(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET)
+
+/* A10-EVB has 1 banks of DRAM, we use only one in U-Boot */
+#define CONFIG_NR_DRAM_BANKS		1
+#define PHYS_SDRAM_1			CONFIG_SYS_SDRAM_BASE
+
+#define CONFIG_CMD_MEMORY
+#define CONFIG_CMD_SETEXPR
+
+#define CONFIG_SETUP_MEMORY_TAGS
+#define CONFIG_CMDLINE_TAG
+#define CONFIG_INITRD_TAG
+#define CONFIG_CMDLINE_EDITING
+
+/*
+ * Size of malloc() pool
+ * 1MB = 0x100000, 0x100000 = 1024 * 1024
+ */
+#define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + (1 << 20))
+
+/* Flat Device Tree (FDT/DT) support */
+#define CONFIG_OF_LIBFDT
+#define CONFIG_SYS_BOOTMAPSZ		(16 << 20)
+
+/*
+ * Miscellaneous configurable options
+ */
+#define CONFIG_SYS_LONGHELP	/* undef to save memory */
+#define CONFIG_SYS_HUSH_PARSER	/* use "hush" command parser    */
+#define CONFIG_CMD_ECHO
+#define CONFIG_SYS_PROMPT_HUSH_PS2	"> "
+#define CONFIG_SYS_CBSIZE	256	/* Console I/O Buffer Size */
+#define CONFIG_SYS_PBSIZE	384	/* Print Buffer Size */
+#define CONFIG_SYS_MAXARGS	16	/* max number of command args */
+
+/* Boot Argument Buffer Size */
+#define CONFIG_SYS_BARGSIZE		CONFIG_SYS_CBSIZE
+
+/* memtest works on */
+#define CONFIG_SYS_MEMTEST_START	CONFIG_SYS_SDRAM_BASE
+#define CONFIG_SYS_MEMTEST_END		(CONFIG_SYS_SDRAM_BASE + (256 << 20))
+#define CONFIG_SYS_LOAD_ADDR		0x50000000 /* default load address */
+
+#define CONFIG_SYS_HZ			1000
+
+/* valid baudrates */
+#define CONFIG_BAUDRATE			115200
+#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
+
+/*-----------------------------------------------------------------------
+ * Stack sizes
+ *
+ * The stack sizes are set up in start.S using the settings below
+ */
+#define CONFIG_STACKSIZE		(256 << 10)	/* 256 KB */
+
+/*-----------------------------------------------------------------------
+ * FLASH and environment organization
+ */
+#define CONFIG_SYS_NO_FLASH
+
+#define CONFIG_SYS_MONITOR_LEN		(256 << 10)	/* 256 KB */
+#define CONFIG_IDENT_STRING		" Allwinner Technology "
+
+#define CONFIG_ENV_IS_NOWHERE	/* No storage defined yet */
+
+#define CONFIG_ENV_OFFSET		(544 << 10)	/* (8 + 24 + 512)KB */
+#define CONFIG_ENV_SIZE			(128 << 10)	/* 128KB */
+
+#define CONFIG_BOOTCOMMAND \
+	"if run loadbootenv; then " \
+		"echo Loaded environment from ${bootenv};" \
+		"env import -t ${scriptaddr} ${filesize};" \
+	"fi;" \
+	"if test -n ${uenvcmd}; then " \
+		"echo Running uenvcmd ...;" \
+		"run uenvcmd;" \
+	"fi;" \
+	"if run loadbootscr; then "\
+		"echo Jumping to ${bootscr};" \
+		"source ${scriptaddr};" \
+	"fi;" \
+	"run setargs boot_mmc;" \
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+	"console=ttyS0,115200\0" \
+	"root=/dev/mmcblk0p2 rootwait\0" \
+	"panicarg=panic=10\0" \
+	"extraargs=\0" \
+	"loglevel=8\0" \
+	"scriptaddr=0x44000000\0" \
+	"setargs=setenv bootargs console=${console} root=${root}" \
+		" loglevel=${loglevel} ${panicarg} ${extraargs}\0" \
+	"kernel=uImage\0" \
+	"bootenv=uEnv.txt\0" \
+	"bootscr=boot.scr\0" \
+	"loadbootscr=fatload mmc 0 $scriptaddr ${bootscr} ||" \
+		" ext2load mmc 0 $scriptaddr ${bootscr} ||" \
+		" ext2load mmc 0 $scriptaddr boot/${bootscr}\0" \
+	"loadbootenv=fatload mmc 0 $scriptaddr ${bootenv} ||" \
+		" ext2load mmc 0 $scriptaddr ${bootenv} ||" \
+		" ext2load mmc 0 $scriptaddr boot/${bootenv}\0" \
+	"boot_mmc=fatload mmc 0 0x43000000 script.bin &&" \
+		" fatload mmc 0 0x48000000 ${kernel} &&" \
+		" bootm 0x48000000\0"
+
+#define CONFIG_BOOTDELAY	3
+#define CONFIG_SYS_BOOT_GET_CMDLINE
+#define CONFIG_AUTO_COMPLETE
+
+#include <config_cmd_default.h>
+
+#define CONFIG_DOS_PARTITION
+#define CONFIG_CMD_FAT		/* with this we can access fat bootfs */
+#define CONFIG_FAT_WRITE	/* enable write access */
+#define CONFIG_CMD_EXT2		/* with this we can access ext2 bootfs */
+#define CONFIG_CMD_EXT4		/* with this we can access ext4 bootfs */
+#define CONFIG_CMD_ZFS		/* with this we can access ZFS bootfs */
+
+#undef CONFIG_CMD_FPGA
+#undef CONFIG_CMD_NET
+#undef CONFIG_CMD_NFS
+
+#endif /* __CONFIG_H */
-- 
1.7.7.6

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 02/22] ARM: sunxi: MMC driver
       [not found] <cover.1353842684.git.henrik@henriknordstrom.net>
  2012-11-25 11:37 ` [U-Boot] [PATCH 01/22] ARM: sunxi: Basic Allwinner A10/A13 (sun4i/sun5i) support Henrik Nordström
@ 2012-11-25 11:37 ` Henrik Nordström
  2012-11-25 14:33   ` Luka Perkov
                     ` (2 more replies)
  2012-11-25 11:38 ` [U-Boot] [PATCH 03/22] ARM sunxi: I2C driver Henrik Nordström
                   ` (19 subsequent siblings)
  21 siblings, 3 replies; 68+ messages in thread
From: Henrik Nordström @ 2012-11-25 11:37 UTC (permalink / raw)
  To: u-boot

This adds a basic MMC driver for Allwinner sun4i/sun5i family of SoC
this driver is limited to a single MMC channel.

Signed-off-by: Tom Cubie <tangliang@allwinnertech.com>
Signed-off-by: Henrik Nodstrom <henrik@henriknordstrom.net>
Signed-off-by: Stefan Roese <sr@denx.de>
---
 arch/arm/include/asm/arch-sunxi/mmc.h |   64 +++
 board/sunxi/board.c                   |    9 +
 drivers/mmc/Makefile                  |    1 +
 drivers/mmc/sunxi_mmc.c               |  674 +++++++++++++++++++++++++++++++++
 include/configs/sunxi-common.h        |   14 +-
 5 files changed, 759 insertions(+), 3 deletions(-)
 create mode 100644 arch/arm/include/asm/arch-sunxi/mmc.h
 create mode 100644 drivers/mmc/sunxi_mmc.c

diff --git a/arch/arm/include/asm/arch-sunxi/mmc.h b/arch/arm/include/asm/arch-sunxi/mmc.h
new file mode 100644
index 0000000..e96e7d2
--- /dev/null
+++ b/arch/arm/include/asm/arch-sunxi/mmc.h
@@ -0,0 +1,64 @@
+/*
+ * (C) Copyright 2007-2011
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Aaron <leafy.myeh@allwinnertech.com>
+ *
+ * MMC register definition for allwinner sunxi platform.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#ifndef _SUNXI_MMC_H
+#define _SUNXI_MMC_H
+
+struct sunxi_mmc {
+	u32 gctrl;		/* (0x00) SMC Global Control Register */
+	u32 clkcr;		/* (0x04) SMC Clock Control Register */
+	u32 timeout;		/* (0x08) SMC Time Out Register */
+	u32 width;		/* (0x0C) SMC Bus Width Register */
+	u32 blksz;		/* (0x10) SMC Block Size Register */
+	u32 bytecnt;		/* (0x14) SMC Byte Count Register */
+	u32 cmd;		/* (0x18) SMC Command Register */
+	u32 arg;		/* (0x1C) SMC Argument Register */
+	u32 resp0;		/* (0x20) SMC Response Register 0 */
+	u32 resp1;		/* (0x24) SMC Response Register 1 */
+	u32 resp2;		/* (0x28) SMC Response Register 2 */
+	u32 resp3;		/* (0x2C) SMC Response Register 3 */
+	u32 imask;		/* (0x30) SMC Interrupt Mask Register */
+	u32 mint;		/* (0x34) SMC Masked Interrupt Status Reg */
+	u32 rint;		/* (0x38) SMC Raw Interrupt Status Register */
+	u32 status;		/* (0x3C) SMC Status Register */
+	u32 ftrglevel;		/* (0x40) SMC FIFO Threshold Watermark Reg */
+	u32 funcsel;		/* (0x44) SMC Function Select Register */
+	u32 cbcr;		/* (0x48) SMC CIU Byte Count Register */
+	u32 bbcr;		/* (0x4C) SMC BIU Byte Count Register */
+	u32 dbgc;		/* (0x50) SMC Debug Enable Register */
+	u32 res0[11];		/* (0x54~0x7c) */
+	u32 dmac;		/* (0x80) SMC IDMAC Control Register */
+	u32 dlba;		/* (0x84) SMC IDMAC Descr List Base Addr Reg */
+	u32 idst;		/* (0x88) SMC IDMAC Status Register */
+	u32 idie;		/* (0x8C) SMC IDMAC Interrupt Enable Register */
+	u32 chda;		/* (0x90) */
+	u32 cbda;		/* (0x94) */
+	u32 res1[26];		/* (0x98~0xff) */
+	u32 fifo;		/* (0x100) SMC FIFO Access Address */
+};
+
+int sunxi_mmc_init(int sdc_no);
+#endif /* _SUNXI_MMC_H */
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index ae05953..50fb40f 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -55,3 +55,12 @@ int dram_init(void)
 
 	return 0;
 }
+
+#ifdef CONFIG_GENERIC_MMC
+int board_mmc_init(bd_t *bis)
+{
+	sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT);
+
+	return 0;
+}
+#endif
diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
index a1dd730..6128910 100644
--- a/drivers/mmc/Makefile
+++ b/drivers/mmc/Makefile
@@ -47,6 +47,7 @@ COBJS-$(CONFIG_S5P_SDHCI) += s5p_sdhci.o
 COBJS-$(CONFIG_SH_MMCIF) += sh_mmcif.o
 COBJS-$(CONFIG_TEGRA_MMC) += tegra_mmc.o
 COBJS-$(CONFIG_DWMMC) += dw_mmc.o
+COBJS-$(CONFIG_MMC_SUNXI) += sunxi_mmc.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
new file mode 100644
index 0000000..05bc231
--- /dev/null
+++ b/drivers/mmc/sunxi_mmc.c
@@ -0,0 +1,674 @@
+/*
+ * (C) Copyright 2007-2011
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Aaron <leafy.myeh@allwinnertech.com>
+ *
+ * MMC driver for allwinner sunxi platform.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/mmc.h>
+#include <malloc.h>
+#include <mmc.h>
+
+#undef SUNXI_MMCDBG
+
+#ifdef SUNXI_MMCDBG
+#define MMCDBG(fmt...)	printf("[mmc]: "fmt)
+
+static void dumphex32(char *name, char *base, int len)
+{
+	__u32 i;
+
+	printf("dump %s registers:", name);
+	for (i = 0; i < len; i += 4) {
+		if (!(i & 0xf))
+			printf("\n0x%p : ", base + i);
+		printf("0x%08x ", readl(base + i));
+	}
+	printf("\n");
+}
+
+static void dumpmmcreg(struct sunxi_mmc *reg)
+{
+	printf("dump mmc registers:\n");
+	printf("gctrl     0x%08x\n", reg->gctrl);
+	printf("clkcr     0x%08x\n", reg->clkcr);
+	printf("timeout   0x%08x\n", reg->timeout);
+	printf("width     0x%08x\n", reg->width);
+	printf("blksz     0x%08x\n", reg->blksz);
+	printf("bytecnt   0x%08x\n", reg->bytecnt);
+	printf("cmd       0x%08x\n", reg->cmd);
+	printf("arg       0x%08x\n", reg->arg);
+	printf("resp0     0x%08x\n", reg->resp0);
+	printf("resp1     0x%08x\n", reg->resp1);
+	printf("resp2     0x%08x\n", reg->resp2);
+	printf("resp3     0x%08x\n", reg->resp3);
+	printf("imask     0x%08x\n", reg->imask);
+	printf("mint      0x%08x\n", reg->mint);
+	printf("rint      0x%08x\n", reg->rint);
+	printf("status    0x%08x\n", reg->status);
+	printf("ftrglevel 0x%08x\n", reg->ftrglevel);
+	printf("funcsel   0x%08x\n", reg->funcsel);
+	printf("dmac      0x%08x\n", reg->dmac);
+	printf("dlba      0x%08x\n", reg->dlba);
+	printf("idst      0x%08x\n", reg->idst);
+	printf("idie      0x%08x\n", reg->idie);
+}
+#else
+#define MMCDBG(fmt...)
+#define dumphex32(fmt...)
+#define dumpmmcreg(fmt...)
+#endif /* SUNXI_MMCDBG */
+
+struct sunxi_mmc_des {
+	u32 reserved1_1:1;
+	u32 dic:1;		/* disable interrupt on completion */
+	u32 last_des:1;		/* 1-this data buffer is the last buffer */
+	u32 first_des:1;		/* 1-data buffer is the first buffer,
+				   0-data buffer contained in the next
+				   descriptor is 1st buffer */
+	u32 des_chain:1;	/* 1-the 2nd address in the descriptor is the
+				   next descriptor address */
+	u32 end_of_ring:1;	/* 1-last descriptor flag when using dual
+				   data buffer in descriptor */
+	u32 reserved1_2:24;
+	u32 card_err_sum:1;	/* transfer error flag */
+	u32 own:1;		/* des owner:1-idma owns it, 0-host owns it */
+#if defined CONFIG_SUN4I
+#define SDXC_DES_NUM_SHIFT 13
+#define SDXC_DES_BUFFER_MAX_LEN	(1 << SDXC_DES_NUM_SHIFT)
+	u32 data_buf1_sz:13;
+	u32 data_buf2_sz:13;
+	u32 reserverd2_1:6;
+#elif defined CONFIG_SUN5I
+#define SDXC_DES_NUM_SHIFT 16
+#define SDXC_DES_BUFFER_MAX_LEN	(1 << SDXC_DES_NUM_SHIFT)
+	u32 data_buf1_sz:16;
+	u32 data_buf2_sz:16;
+#else
+#error ">>>> Wrong Platform for MMC <<<<"
+#endif
+	u32 buf_addr_ptr1;
+	u32 buf_addr_ptr2;
+};
+
+struct sunxi_mmc_host {
+	unsigned mmc_no;
+	uint32_t *mclkreg;
+	unsigned database;
+	unsigned fatal_err;
+	unsigned mod_clk;
+	struct sunxi_mmc *reg;
+	struct sunxi_mmc_des *pdes;
+};
+
+/* support 4 mmc hosts */
+struct mmc mmc_dev[4];
+struct sunxi_mmc_host mmc_host[4];
+
+static int mmc_resource_init(int sdc_no)
+{
+	struct sunxi_mmc_host *mmchost = &mmc_host[sdc_no];
+	struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+
+	MMCDBG("init mmc %d resource\n", sdc_no);
+
+	switch (sdc_no) {
+	case 0:
+		mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC0_BASE;
+		mmchost->mclkreg = &ccm->sd0_clk_cfg;
+		break;
+	case 1:
+		mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC1_BASE;
+		mmchost->mclkreg = &ccm->sd1_clk_cfg;
+		break;
+	case 2:
+		mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC2_BASE;
+		mmchost->mclkreg = &ccm->sd2_clk_cfg;
+		break;
+	case 3:
+		mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC3_BASE;
+		mmchost->mclkreg = &ccm->sd3_clk_cfg;
+		break;
+	default:
+		printf("Wrong mmc number %d\n", sdc_no);
+		return -1;
+	}
+	mmchost->database = (unsigned int)mmchost->reg + 0x100;
+	mmchost->mmc_no = sdc_no;
+
+	return 0;
+}
+
+static int mmc_clk_io_on(int sdc_no)
+{
+	unsigned int rval;
+	unsigned int pll5_clk;
+	unsigned int divider;
+	struct sunxi_mmc_host *mmchost = &mmc_host[sdc_no];
+	static struct sunxi_gpio *gpio_c =
+	    &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[SUNXI_GPIO_C];
+	static struct sunxi_gpio *gpio_f =
+	    &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[SUNXI_GPIO_F];
+#if CONFIG_MMC1_PG
+	static struct sunxi_gpio *gpio_g =
+	    &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[SUNXI_GPIO_G];
+#endif
+	static struct sunxi_gpio *gpio_h =
+	    &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[SUNXI_GPIO_H];
+	static struct sunxi_gpio *gpio_i =
+	    &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[SUNXI_GPIO_I];
+	struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+
+	MMCDBG("init mmc %d clock and io\n", sdc_no);
+
+	/* config gpio */
+	switch (sdc_no) {
+	case 0:
+		/* D1-PF0, D0-PF1, CLK-PF2, CMD-PF3, D3-PF4, D4-PF5 */
+		writel(0x222222, &gpio_f->cfg[0]);
+		writel(0x555, &gpio_f->pull[0]);
+		writel(0xaaa, &gpio_f->drv[0]);
+		break;
+
+	case 1:
+#if CONFIG_MMC1_PG
+		/* PG0-CMD, PG1-CLK, PG2~5-D0~3 : 4 */
+		writel(0x444444, &gpio_g->cfg[0]);
+		writel(0x555, &gpio_g->pull[0]);
+		writel(0xaaa, &gpio_g->drv[0]);
+#else
+		/* PH22-CMD, PH23-CLK, PH24~27-D0~D3 : 5 */
+		writel(0x55 << 24, &gpio_h->cfg[2]);
+		writel(0x5555, &gpio_h->cfg[3]);
+		writel(0x555 << 12, &gpio_h->pull[1]);
+		writel(0xaaa << 12, &gpio_h->drv[1]);
+#endif
+		break;
+
+	case 2:
+		/* CMD-PC6, CLK-PC7, D0-PC8, D1-PC9, D2-PC10, D3-PC11 */
+		writel(0x33 << 24, &gpio_c->cfg[0]);
+		writel(0x3333, &gpio_c->cfg[1]);
+		writel(0x555 << 12, &gpio_c->pull[0]);
+		writel(0xaaa << 12, &gpio_c->drv[0]);
+		break;
+
+	case 3:
+		/* PI4-CMD, PI5-CLK, PI6~9-D0~D3 : 2 */
+		writel(0x2222 << 16, &gpio_i->cfg[0]);
+		writel(0x22, &gpio_i->cfg[1]);
+		writel(0x555 << 8, &gpio_i->pull[0]);
+		writel(0x555 << 8, &gpio_i->drv[0]);
+		break;
+
+	default:
+		return -1;
+	}
+
+	/* config ahb clock */
+	rval = readl(&ccm->ahb_gate0);
+	rval |= (1 << (8 + sdc_no));
+	writel(rval, &ccm->ahb_gate0);
+
+	/* config mod clock */
+	pll5_clk = clock_get_pll5();
+	if (pll5_clk > 400000000)
+		divider = 4;
+	else
+		divider = 3;
+	writel((1U << 31) | (2U << 24) | divider, mmchost->mclkreg);
+	mmchost->mod_clk = pll5_clk / (divider + 1);
+
+	dumphex32("ccmu", (char *)SUNXI_CCM_BASE, 0x100);
+	dumphex32("gpio", (char *)SUNXI_PIO_BASE, 0x100);
+	dumphex32("mmc", (char *)mmchost->reg, 0x100);
+
+	return 0;
+}
+
+static int mmc_update_clk(struct mmc *mmc)
+{
+	struct sunxi_mmc_host *mmchost = (struct sunxi_mmc_host *)mmc->priv;
+	unsigned int cmd;
+	unsigned timeout = 0xfffff;
+
+	cmd = (1U << 31) | (1 << 21) | (1 << 13);
+	writel(cmd, &mmchost->reg->cmd);
+	while ((readl(&mmchost->reg->cmd) & 0x80000000) && timeout--)
+		;
+	if (!timeout)
+		return -1;
+
+	writel(readl(&mmchost->reg->rint), &mmchost->reg->rint);
+
+	return 0;
+}
+
+static int mmc_config_clock(struct mmc *mmc, unsigned div)
+{
+	struct sunxi_mmc_host *mmchost = (struct sunxi_mmc_host *)mmc->priv;
+	unsigned rval = readl(&mmchost->reg->clkcr);
+
+	/*
+	 * CLKCREG[7:0]: divider
+	 * CLKCREG[16]:  on/off
+	 * CLKCREG[17]:  power save
+	 */
+	/* Disable Clock */
+	rval &= ~(1 << 16);
+	writel(rval, &mmchost->reg->clkcr);
+	if (mmc_update_clk(mmc))
+		return -1;
+
+	/* Change Divider Factor */
+	rval &= ~(0xFF);
+	rval |= div;
+	writel(rval, &mmchost->reg->clkcr);
+	if (mmc_update_clk(mmc))
+		return -1;
+	/* Re-enable Clock */
+	rval |= (1 << 16);
+	writel(rval, &mmchost->reg->clkcr);
+
+	if (mmc_update_clk(mmc))
+		return -1;
+
+	return 0;
+}
+
+static void mmc_set_ios(struct mmc *mmc)
+{
+	struct sunxi_mmc_host *mmchost = (struct sunxi_mmc_host *)mmc->priv;
+	unsigned int clkdiv = 0;
+
+	MMCDBG("set ios: bus_width: %x, clock: %d, mod_clk\n", mmc->bus_width,
+	       mmc->clock, mmchost->mod_clk);
+
+	/* Change clock first */
+	clkdiv = (mmchost->mod_clk + (mmc->clock >> 1)) / mmc->clock / 2;
+	if (mmc->clock)
+		if (mmc_config_clock(mmc, clkdiv)) {
+			mmchost->fatal_err = 1;
+			return;
+		}
+
+	/* Change bus width */
+	if (mmc->bus_width == 8)
+		writel(2, &mmchost->reg->width);
+	else if (mmc->bus_width == 4)
+		writel(1, &mmchost->reg->width);
+	else
+		writel(0, &mmchost->reg->width);
+}
+
+static int mmc_core_init(struct mmc *mmc)
+{
+	struct sunxi_mmc_host *mmchost = (struct sunxi_mmc_host *)mmc->priv;
+
+	/* Reset controller */
+	writel(0x7, &mmchost->reg->gctrl);
+
+	return 0;
+}
+
+static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data)
+{
+	struct sunxi_mmc_host *mmchost = (struct sunxi_mmc_host *)mmc->priv;
+	unsigned i;
+	unsigned byte_cnt = data->blocksize * data->blocks;
+	unsigned *buff;
+	unsigned timeout = 0xfffff;
+
+	if (data->flags & MMC_DATA_READ) {
+		buff = (unsigned int *)data->dest;
+		for (i = 0; i < (byte_cnt >> 2); i++) {
+			while (--timeout
+			       && (readl(&mmchost->reg->status) & (1 << 2)))
+				;
+			if (timeout <= 0)
+				goto out;
+			buff[i] = readl(mmchost->database);
+			timeout = 0xfffff;
+		}
+	} else {
+		buff = (unsigned int *)data->src;
+		for (i = 0; i < (byte_cnt >> 2); i++) {
+			while (--timeout
+			       && (readl(&mmchost->reg->status) & (1 << 3)))
+				;
+			if (timeout <= 0)
+				goto out;
+			writel(buff[i], mmchost->database);
+			timeout = 0xfffff;
+		}
+	}
+
+out:
+	if (timeout <= 0)
+		return -1;
+
+	return 0;
+}
+
+static int mmc_trans_data_by_dma(struct mmc *mmc, struct mmc_data *data)
+{
+	struct sunxi_mmc_host *mmchost = (struct sunxi_mmc_host *)mmc->priv;
+	struct sunxi_mmc_des *pdes = mmchost->pdes;
+	unsigned byte_cnt = data->blocksize * data->blocks;
+	unsigned char *buff;
+	unsigned des_idx = 0;
+	unsigned buff_frag_num = 0;
+	unsigned remain;
+	unsigned i, rval;
+
+	buff = data->flags & MMC_DATA_READ ?
+	    (unsigned char *)data->dest : (unsigned char *)data->src;
+	buff_frag_num = byte_cnt >> SDXC_DES_NUM_SHIFT;
+
+	remain = byte_cnt & (SDXC_DES_BUFFER_MAX_LEN - 1);
+	if (remain)
+		buff_frag_num++;
+	else
+		remain = SDXC_DES_BUFFER_MAX_LEN;
+
+	flush_cache((unsigned long)buff, (unsigned long)byte_cnt);
+	for (i = 0; i < buff_frag_num; i++, des_idx++) {
+		memset((void *)&pdes[des_idx], 0, sizeof(struct sunxi_mmc_des));
+		pdes[des_idx].des_chain = 1;
+		pdes[des_idx].own = 1;
+		pdes[des_idx].dic = 1;
+		if (buff_frag_num > 1 && i != buff_frag_num - 1)
+			pdes[des_idx].data_buf1_sz =
+			    (SDXC_DES_BUFFER_MAX_LEN -
+			     1) & SDXC_DES_BUFFER_MAX_LEN;
+		else
+			pdes[des_idx].data_buf1_sz = remain;
+
+		pdes[des_idx].buf_addr_ptr1 =
+		    (u32) buff + i * SDXC_DES_BUFFER_MAX_LEN;
+		if (i == 0)
+			pdes[des_idx].first_des = 1;
+
+		if (i == buff_frag_num - 1) {
+			pdes[des_idx].dic = 0;
+			pdes[des_idx].last_des = 1;
+			pdes[des_idx].end_of_ring = 1;
+			pdes[des_idx].buf_addr_ptr2 = 0;
+		} else {
+			pdes[des_idx].buf_addr_ptr2 = (u32)&pdes[des_idx + 1];
+		}
+		MMCDBG("frag %d, remain %d, des[%d](%08x): "
+			"[0] = %08x, [1] = %08x, [2] = %08x, [3] = %08x\n",
+			i, remain, des_idx, (u32)&pdes[des_idx],
+			(u32)((u32 *)&pdes[des_idx])[0],
+			(u32)((u32 *)&pdes[des_idx])[1],
+			(u32)((u32 *)&pdes[des_idx])[2],
+			(u32)((u32 *)&pdes[des_idx])[3]);
+	}
+	flush_cache((unsigned long)pdes,
+		    sizeof(struct sunxi_mmc_des) * (des_idx + 1));
+
+	/*
+	 * GCTRLREG
+	 * GCTRL[2]     : DMA reset
+	 * GCTRL[5]     : DMA enable
+	 *
+	 * IDMACREG
+	 * IDMAC[0]     : IDMA soft reset
+	 * IDMAC[1]     : IDMA fix burst flag
+	 * IDMAC[7]     : IDMA on
+	 *
+	 * IDIECREG
+	 * IDIE[0]      : IDMA transmit interrupt flag
+	 * IDIE[1]      : IDMA receive interrupt flag
+	 */
+	rval = readl(&mmchost->reg->gctrl);
+	writel(rval | (1 << 5) | (1 << 2), &mmchost->reg->gctrl); /* dma enable */
+	writel((1 << 0), &mmchost->reg->dmac);	/* idma reset */
+	writel((1 << 1) | (1 << 7), &mmchost->reg->dmac);	/* idma on */
+	rval = readl(&mmchost->reg->idie) & (~3);
+	if (data->flags & MMC_DATA_WRITE)
+		rval |= (1 << 0);
+	else
+		rval |= (1 << 1);
+	writel(rval, &mmchost->reg->idie);
+	writel((u32) pdes, &mmchost->reg->dlba);
+	writel((2U << 28) | (7 << 16) | 8, &mmchost->reg->ftrglevel);
+
+	return 0;
+}
+
+static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
+			struct mmc_data *data)
+{
+	struct sunxi_mmc_host *mmchost = (struct sunxi_mmc_host *)mmc->priv;
+	unsigned int cmdval = 0x80000000;
+	signed int timeout = 0;
+	int error = 0;
+	unsigned int status = 0;
+	unsigned int usedma = 0;
+	unsigned int bytecnt = 0;
+
+	if (mmchost->fatal_err)
+		return -1;
+	if (cmd->resp_type & MMC_RSP_BUSY)
+		MMCDBG("mmc cmd %d check rsp busy\n", cmd->cmdidx);
+	if (cmd->cmdidx == 12)
+		return 0;
+
+	/*
+	 * CMDREG
+	 * CMD[5:0]     : Command index
+	 * CMD[6]       : Has response
+	 * CMD[7]       : Long response
+	 * CMD[8]       : Check response CRC
+	 * CMD[9]       : Has data
+	 * CMD[10]      : Write
+	 * CMD[11]      : Steam mode
+	 * CMD[12]      : Auto stop
+	 * CMD[13]      : Wait previous over
+	 * CMD[14]      : About cmd
+	 * CMD[15]      : Send initialization
+	 * CMD[21]      : Update clock
+	 * CMD[31]      : Load cmd
+	 */
+	if (!cmd->cmdidx)
+		cmdval |= (1 << 15);
+	if (cmd->resp_type & MMC_RSP_PRESENT)
+		cmdval |= (1 << 6);
+	if (cmd->resp_type & MMC_RSP_136)
+		cmdval |= (1 << 7);
+	if (cmd->resp_type & MMC_RSP_CRC)
+		cmdval |= (1 << 8);
+
+	if (data) {
+		if ((u32) data->dest & 0x3) {
+			error = -1;
+			goto out;
+		}
+
+		cmdval |= (1 << 9) | (1 << 13);
+		if (data->flags & MMC_DATA_WRITE)
+			cmdval |= (1 << 10);
+		if (data->blocks > 1)
+			cmdval |= (1 << 12);
+		writel(data->blocksize, &mmchost->reg->blksz);
+		writel(data->blocks * data->blocksize, &mmchost->reg->bytecnt);
+	}
+
+	MMCDBG("mmc %d, cmd %d(0x%08x), arg 0x%08x\n", mmchost->mmc_no,
+	       cmd->cmdidx, cmdval | cmd->cmdidx, cmd->cmdarg);
+	writel(cmd->cmdarg, &mmchost->reg->arg);
+
+	if (!data)
+		writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd);
+
+	/*
+	 * transfer data and check status
+	 * STATREG[2] : FIFO empty
+	 * STATREG[3] : FIFO full
+	 */
+	if (data) {
+		int ret = 0;
+
+		bytecnt = data->blocksize * data->blocks;
+		MMCDBG("trans data %d bytes\n", bytecnt);
+#if defined(CONFIG_MMC_SUNXI_USE_DMA) && !defined(CONFIG_SPL_BUILD)
+		if (bytecnt > 64) {
+#else
+		if (0) {
+#endif
+			usedma = 1;
+			writel(readl(&mmchost->reg->gctrl) & (~0x80000000),
+			       &mmchost->reg->gctrl);
+			ret = mmc_trans_data_by_dma(mmc, data);
+			writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd);
+		} else {
+			writel(readl(&mmchost->reg->gctrl) | 0x80000000,
+			       &mmchost->reg->gctrl);
+			writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd);
+			ret = mmc_trans_data_by_cpu(mmc, data);
+		}
+		if (ret) {
+			error = readl(&mmchost->reg->rint) & 0xbfc2;
+			goto out;
+		}
+	}
+
+	timeout = 0xfffff;
+	do {
+		status = readl(&mmchost->reg->rint);
+		if (!timeout-- || (status & 0xbfc2)) {
+			error = status & 0xbfc2;
+			MMCDBG("cmd timeout %x\n", error);
+			goto out;
+		}
+	} while (!(status & 0x4));
+
+	if (data) {
+		unsigned done = 0;
+		timeout = usedma ? 0xffff * bytecnt : 0xffff;
+		MMCDBG("cacl timeout %x\n", timeout);
+		do {
+			status = readl(&mmchost->reg->rint);
+			if (!timeout-- || (status & 0xbfc2)) {
+				error = status & 0xbfc2;
+				MMCDBG("data timeout %x\n", error);
+				goto out;
+			}
+			if (data->blocks > 1)
+				done = status & (1 << 14);
+			else
+				done = status & (1 << 3);
+		} while (!done);
+	}
+
+	if (cmd->resp_type & MMC_RSP_BUSY) {
+		timeout = 0xfffff;
+		do {
+			status = readl(&mmchost->reg->status);
+			if (!timeout--) {
+				error = -1;
+				MMCDBG("busy timeout\n");
+				goto out;
+			}
+		} while (status & (1 << 9));
+	}
+
+	if (cmd->resp_type & MMC_RSP_136) {
+		cmd->response[0] = readl(&mmchost->reg->resp3);
+		cmd->response[1] = readl(&mmchost->reg->resp2);
+		cmd->response[2] = readl(&mmchost->reg->resp1);
+		cmd->response[3] = readl(&mmchost->reg->resp0);
+		MMCDBG("mmc resp 0x%08x 0x%08x 0x%08x 0x%08x\n",
+		       cmd->response[3], cmd->response[2],
+		       cmd->response[1], cmd->response[0]);
+	} else {
+		cmd->response[0] = readl(&mmchost->reg->resp0);
+		MMCDBG("mmc resp 0x%08x\n", cmd->response[0]);
+	}
+out:
+	if (data && usedma) {
+		/* IDMASTAREG
+		 * IDST[0] : idma tx int
+		 * IDST[1] : idma rx int
+		 * IDST[2] : idma fatal bus error
+		 * IDST[4] : idma descriptor invalid
+		 * IDST[5] : idma error summary
+		 * IDST[8] : idma normal interrupt sumary
+		 * IDST[9] : idma abnormal interrupt sumary
+		 */
+		status = readl(&mmchost->reg->idst);
+		writel(status, &mmchost->reg->idst);
+		writel(0, &mmchost->reg->idie);
+		writel(0, &mmchost->reg->dmac);
+		writel(readl(&mmchost->reg->gctrl) & (~(1 << 5)),
+		       &mmchost->reg->gctrl);
+	}
+	if (error) {
+		writel(0x7, &mmchost->reg->gctrl);
+		mmc_update_clk(mmc);
+		MMCDBG("mmc cmd %d err 0x%08x\n", cmd->cmdidx, error);
+	}
+	writel(0xffffffff, &mmchost->reg->rint);
+	writel(readl(&mmchost->reg->gctrl) | (1 << 1), &mmchost->reg->gctrl);
+
+	if (error)
+		return -1;
+	else
+		return 0;
+}
+
+int sunxi_mmc_init(int sdc_no)
+{
+	struct mmc *mmc;
+
+	memset(&mmc_dev[sdc_no], 0, sizeof(struct mmc));
+	memset(&mmc_host[sdc_no], 0, sizeof(struct sunxi_mmc_host));
+	mmc = &mmc_dev[sdc_no];
+
+	sprintf(mmc->name, "SUNXI SD/MMC");
+	mmc->priv = &mmc_host[sdc_no];
+	mmc->send_cmd = mmc_send_cmd;
+	mmc->set_ios = mmc_set_ios;
+	mmc->init = mmc_core_init;
+
+	mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
+	mmc->host_caps = MMC_MODE_4BIT;
+	mmc->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
+
+	mmc->f_min = 400000;
+	mmc->f_max = 52000000;
+
+	mmc_host[sdc_no].pdes = (struct sunxi_mmc_des *)0x50000000;
+	mmc_resource_init(sdc_no);
+	mmc_clk_io_on(sdc_no);
+
+	mmc_register(mmc);
+
+	return 0;
+}
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index 33309f3..8a026e0 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -77,6 +77,16 @@
 #define CONFIG_INITRD_TAG
 #define CONFIG_CMDLINE_EDITING
 
+/* mmc config */
+#define CONFIG_MMC
+#define CONFIG_GENERIC_MMC
+#define CONFIG_CMD_MMC
+#define CONFIG_MMC_SUNXI
+#define CONFIG_MMC_SUNXI_SLOT		0		/* which mmc slot to use, could be 0,1,2,3 */
+#define CONFIG_MMC_SUNXI_USE_DMA
+#define CONFIG_ENV_IS_IN_MMC
+#define CONFIG_SYS_MMC_ENV_DEV		CONFIG_MMC_SUNXI_SLOT		/* env in which mmc */
+
 /*
  * Size of malloc() pool
  * 1MB = 0x100000, 0x100000 = 1024 * 1024
@@ -127,9 +137,7 @@
 #define CONFIG_SYS_MONITOR_LEN		(256 << 10)	/* 256 KB */
 #define CONFIG_IDENT_STRING		" Allwinner Technology "
 
-#define CONFIG_ENV_IS_NOWHERE	/* No storage defined yet */
-
-#define CONFIG_ENV_OFFSET		(544 << 10)	/* (8 + 24 + 512)KB */
+#define CONFIG_ENV_OFFSET		(544 << 10) /* (8 + 24 + 512)KB */
 #define CONFIG_ENV_SIZE			(128 << 10)	/* 128KB */
 
 #define CONFIG_BOOTCOMMAND \
-- 
1.7.7.6

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 03/22] ARM sunxi: I2C driver
       [not found] <cover.1353842684.git.henrik@henriknordstrom.net>
  2012-11-25 11:37 ` [U-Boot] [PATCH 01/22] ARM: sunxi: Basic Allwinner A10/A13 (sun4i/sun5i) support Henrik Nordström
  2012-11-25 11:37 ` [U-Boot] [PATCH 02/22] ARM: sunxi: MMC driver Henrik Nordström
@ 2012-11-25 11:38 ` Henrik Nordström
  2012-11-25 14:41   ` Luka Perkov
                     ` (3 more replies)
  2012-11-25 11:39 ` [U-Boot] [PATCH 05/22] power: Add AXP209 Power Management controller (I2C) Henrik Nordström
                   ` (18 subsequent siblings)
  21 siblings, 4 replies; 68+ messages in thread
From: Henrik Nordström @ 2012-11-25 11:38 UTC (permalink / raw)
  To: u-boot

A basic basic driver for the I2C controller found in Allwinner
sunXi (A10 & A13) SoCs.

Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>
Signed-off-by: Stefan Roese <sr@denx.de>
---
 arch/arm/cpu/armv7/sunxi/clock.c      |   15 ++
 arch/arm/include/asm/arch-sunxi/i2c.h |  185 ++++++++++++++++++++++
 drivers/i2c/Makefile                  |    1 +
 drivers/i2c/sunxi_i2c.c               |  278 +++++++++++++++++++++++++++++++++
 include/configs/sunxi-common.h        |    8 +
 5 files changed, 487 insertions(+), 0 deletions(-)
 create mode 100644 arch/arm/include/asm/arch-sunxi/i2c.h
 create mode 100644 drivers/i2c/sunxi_i2c.c

diff --git a/arch/arm/cpu/armv7/sunxi/clock.c b/arch/arm/cpu/armv7/sunxi/clock.c
index 424acfc..b9bbb7d 100644
--- a/arch/arm/cpu/armv7/sunxi/clock.c
+++ b/arch/arm/cpu/armv7/sunxi/clock.c
@@ -42,6 +42,7 @@ int clock_init(void)
 	return 0;
 }
 
+
 /* Return PLL5 frequency in Hz
  * Note: Assumes PLL5 reference is 24MHz clock
  */
@@ -55,3 +56,17 @@ unsigned int clock_get_pll5(void)
 	int p = 1 << ((rval >> 16) & 3);
 	return 24000000 * n * k / p;
 }
+
+int clock_twi_onoff(int port, int state)
+{
+	struct sunxi_ccm_reg *const ccm =
+		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+
+	if (port > 2)
+		return -1;
+
+	/* set the apb1 clock gate for twi */
+	sr32(&ccm->apb1_gate, 0 + port, 1, state);
+
+	return 0;
+}
diff --git a/arch/arm/include/asm/arch-sunxi/i2c.h b/arch/arm/include/asm/arch-sunxi/i2c.h
new file mode 100644
index 0000000..9a6e168
--- /dev/null
+++ b/arch/arm/include/asm/arch-sunxi/i2c.h
@@ -0,0 +1,185 @@
+/*
+ * (C) Copyright 2012 Henrik Nordstrom <henrik@henriknordstrom.net>
+ *
+ * Based on sun4i linux kernle i2c.h
+ * (C) Copyright 2007-2012
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Tom Cubie <tanglaing@allwinnertech.com>
+ * Victor Wei <weiziheng@allwinnertech.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#ifndef _SUNXI_I2C_H_
+#define _SUNXI_I2C_H_
+
+struct i2c {
+	u32 saddr;	/*  31:8bit res,7-1bit for slave addr,0 bit for GCE */
+	u32 xsaddr;	/*  31:8bit res,7-0bit for second addr in 10bit addr */
+	u32 data;	/*  31:8bit res, 7-0bit send or receive data byte */
+	u32 ctl;	/*  INT_EN,BUS_EN,M_STA,INT_FLAG,A_ACK */
+	u32 status;	/*  28 interrupt types + 0xF8 normal type = 29  */
+	u32 clkr;	/*  31:7bit res,6-3bit,CLK_M,2-0bit CLK_N */
+	u32 reset;	/*  31:1bit res;0bit,write 1 to clear 0. */
+	u32 efr;	/*  31:2bit res,1:0 bit data byte follow read comand */
+	u32 lctl;	/*  31:6bits res 5:0bit for sda&scl control */
+};
+
+/* TWI address register */
+#define TWI_GCE_EN	(0x1 << 0)	/* gen call addr enable slave mode */
+#define TWI_ADDR_MASK	(0x7f << 1)	/* 7:1bits */
+#define TWI_XADDR_MASK	0xff		/* 7:0bits for extend slave address */
+
+#define TWI_DATA_MASK	0xff		/* 7:0bits for send or received */
+
+/* TWI Control Register Bit Fields */
+/* 1:0 bits reserved */
+/* set 1 to send A_ACK,then low level on SDA */
+#define TWI_CTL_ACK	(0x1 << 2)
+/* INT_FLAG,interrupt status flag: set '1' when interrupt coming */
+#define TWI_CTL_INTFLG	(0x1 << 3)
+#define TWI_CTL_STP	(0x1 << 4)	/* M_STP,Automatic clear 0 */
+#define TWI_CTL_STA	(0x1 << 5)	/* M_STA,atutomatic clear 0 */
+#define TWI_CTL_BUSEN	(0x1 << 6)	/* BUS_EN, mastr mode should be set 1 */
+#define TWI_CTL_INTEN	(0x1 << 7)	/* INT_EN */
+/* 31:8 bit reserved */
+
+/*
+ * TWI Clock Register Bit Fields & Masks,default value:0x0000_0000
+ * Fin is APB CLOCK INPUT;
+ * Fsample = F0 = Fin/2^CLK_N;
+ *           F1 = F0/(CLK_M+1);
+ *
+ * Foscl = F1/10 = Fin/(2^CLK_N * (CLK_M+1)*10);
+ * Foscl is clock SCL;standard mode:100KHz or fast mode:400KHz
+ */
+
+#define TWI_CLK_DIV_M		(0xF << 3)	/* 6:3bit  */
+#define TWI_CLK_DIV_N		(0x7 << 0)	/* 2:0bit */
+#define TWI_CLK_DIV(N, M)	((((N) & 0xF) << 3) | (((M) & 0x7) << 0))
+
+/* TWI Soft Reset Register Bit Fields & Masks  */
+/* write 1 to clear 0, when complete soft reset clear 0 */
+#define TWI_SRST_SRST		(0x1 << 0)
+
+/* TWI Enhance Feature Register Bit Fields & Masks  */
+/* default -- 0x0 */
+/* 00:no,01: 1byte, 10:2 bytes, 11: 3bytes */
+#define TWI_EFR_MASK		(0x3 << 0)
+#define TWI_EFR_WARC_0		(0x0 << 0)
+#define TWI_EFR_WARC_1		(0x1 << 0)
+#define TWI_EFR_WARC_2		(0x2 << 0)
+#define TWI_EFR_WARC_3		(0x3 << 0)
+
+/* twi line control register -default value: 0x0000_003a */
+/* SDA line state control enable ,1:enable;0:disable */
+#define TWI_LCR_SDA_EN		(0x01 << 0)
+/* SDA line state control bit, 1:high level;0:low level */
+#define TWI_LCR_SDA_CTL		(0x01 << 1)
+/* SCL line state control enable ,1:enable;0:disable */
+#define TWI_LCR_SCL_EN		(0x01 << 2)
+/* SCL line state control bit, 1:high level;0:low level */
+#define TWI_LCR_SCL_CTL		(0x01 << 3)
+/* current state of SDA,readonly bit */
+#define TWI_LCR_SDA_STATE_MASK	(0x01 << 4)
+/* current state of SCL,readonly bit */
+#define TWI_LCR_SCL_STATE_MASK	(0x01 << 5)
+/* 31:6bits reserved */
+#define TWI_LCR_IDLE_STATUS	0x3a
+
+/* TWI Status Register Bit Fields & Masks  */
+#define TWI_STAT_MASK		0xff
+/* 7:0 bits use only,default is 0xF8 */
+#define TWI_STAT_BUS_ERR	0x00	/* BUS ERROR */
+
+/* Master mode use only */
+#define TWI_STAT_TX_STA		0x08	/* START condition transmitted */
+/* Repeated START condition transmitted */
+#define TWI_STAT_TX_RESTA	0x10
+/* Address+Write bit transmitted, ACK received */
+#define TWI_STAT_TX_AW_ACK	0x18
+/* Address+Write bit transmitted, ACK not received */
+#define TWI_STAT_TX_AW_NAK	0x20
+/* data byte transmitted in master mode,ack received */
+#define TWI_STAT_TXD_ACK	0x28
+/* data byte transmitted in master mode ,ack not received */
+#define TWI_STAT_TXD_NAK	0x30
+/* arbitration lost in address or data byte */
+#define TWI_STAT_ARBLOST	0x38
+/* Address+Read bit transmitted, ACK received */
+#define TWI_STAT_TX_AR_ACK	0x40
+/* Address+Read bit transmitted, ACK not received */
+#define TWI_STAT_TX_AR_NAK	0x48
+/* Second Address byte + Write bit transmitted, ACK received */
+#define TWI_STAT_TX_2AW_ACK	0xD0
+/* Second Address byte + Write bit transmitted, ACK received */
+#define TWI_STAT_TX_2AW_NAK	0xD8
+/* data byte received in master mode ,ack transmitted */
+#define TWI_STAT_RXD_ACK	0x50
+/* date byte received in master mode,not ack transmitted */
+#define TWI_STAT_RXD_NAK	0x58
+
+/* Slave mode use only */
+/* Slave address+Write bit received, ACK transmitted */
+#define TWI_STAT_RXWS_ACK	0x60
+/*
+ * Arbitration lost in address as master, slave address + Write bit received,
+ * ACK transmitted
+ */
+#define TWI_STAT_ARBLOST_RXWS_ACK 0x68
+/* General Call address received, ACK transmitted */
+#define TWI_STAT_RXGCAS_ACK	0x70
+/*
+ * Arbitration lost in address as master, General Call address received,
+ * ACK transmitted
+ */
+#define TWI_STAT_ARBLOST_RXGCAS_ACK 0x78
+/* Data byte received after slave address received, ACK transmitted */
+#define TWI_STAT_RXDS_ACK	0x80
+/* Data byte received after slave address received, not ACK transmitted */
+#define TWI_STAT_RXDS_NAK	0x88
+/* Data byte received after General Call received, ACK transmitted */
+#define TWI_STAT_RXDGCAS_ACK	0x90
+/* Data byte received after General Call received, not ACK transmitted */
+#define TWI_STAT_RXDGCAS_NAK	0x98
+/* STOP or repeated START condition received in slave  */
+#define TWI_STAT_RXSTPS_RXRESTAS 0xA0
+/* Slave address + Read bit received, ACK transmitted */
+#define TWI_STAT_RXRS_ACK	0xA8
+/*
+ * Arbitration lost in address as master, slave address + Read bit received,
+ * ACK transmitted
+ */
+#define TWI_STAT_ARBLOST_SLAR_ACK 0xB0
+/* Data byte transmitted in slave mode, ACK received */
+#define TWI_STAT_TXDS_ACK	0xB8
+/* Data byte transmitted in slave mode, ACK not received */
+#define TWI_STAT_TXDS_NAK	0xC0
+/* Last byte transmitted in slave mode, ACK received */
+#define TWI_STAT_TXDSL_ACK	0xC8
+
+/* 10bit Address, second part of address */
+/* Second Address byte+Write bit transmitted,ACK received */
+#define TWI_STAT_TX_SAW_ACK	0xD0
+/* Second Address byte+Write bit transmitted,ACK not received */
+#define TWI_STAT_TX_SAW_NAK	0xD8
+
+/* No relevant status infomation,INT_FLAG = 0 */
+#define TWI_STAT_IDLE		0xF8
+
+#endif
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 5dbdbe3..9f929e6 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -46,6 +46,7 @@ COBJS-$(CONFIG_TSI108_I2C) += tsi108_i2c.o
 COBJS-$(CONFIG_U8500_I2C) += u8500_i2c.o
 COBJS-$(CONFIG_SH_I2C) += sh_i2c.o
 COBJS-$(CONFIG_SH_SH7734_I2C) += sh_sh7734_i2c.o
+COBJS-$(CONFIG_SUNXI_I2C) += sunxi_i2c.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff --git a/drivers/i2c/sunxi_i2c.c b/drivers/i2c/sunxi_i2c.c
new file mode 100644
index 0000000..6bf5309
--- /dev/null
+++ b/drivers/i2c/sunxi_i2c.c
@@ -0,0 +1,278 @@
+/*
+ * Copyright (c) 2012 Henrik Nordstrom <henrik@henriknordstrom.net>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <asm/io.h>
+#include <asm/arch/cpu.h>
+#include <asm/arch/i2c.h>
+#include <asm/arch/gpio.h>
+#include <asm/arch/clock.h>
+
+static struct i2c __attribute__ ((section(".data"))) *i2c_base =
+	(struct i2c *)0x1c2ac00;
+
+void i2c_init(int speed, int slaveaddr)
+{
+	sunxi_gpio_set_cfgpin(SUNXI_GPB(0), 2);
+	sunxi_gpio_set_cfgpin(SUNXI_GPB(1), 2);
+	clock_twi_onoff(0, 1);
+
+	/* Enable the i2c bus */
+	writel(TWI_CTL_BUSEN, &i2c_base->ctl);
+
+	/* 400KHz operation M=2, N=1, 24MHz APB clock */
+	writel(TWI_CLK_DIV(2, 1), &i2c_base->clkr);
+	writel(TWI_SRST_SRST, &i2c_base->reset);
+
+	while ((readl(&i2c_base->reset) & TWI_SRST_SRST))
+		;
+}
+
+int i2c_probe(uchar chip)
+{
+	return -1;
+}
+
+static int i2c_wait_ctl(int mask, int state)
+{
+	int timeout = 0x2ff;
+	int value = state ? mask : 0;
+
+	debug("i2c_wait_ctl(%x == %x), ctl=%x, status=%x\n", mask, value,
+	      i2c_base->ctl, i2c_base->status);
+
+	while (((readl(&i2c_base->ctl) & mask) != value) && timeout-- > 0)
+		;
+
+	debug("i2c_wait_ctl(), timeout=%d, ctl=%x, status=%x\n", timeout,
+	      i2c_base->ctl, i2c_base->status);
+
+	if (timeout != 0)
+		return 0;
+	else
+		return -1;
+}
+
+static void i2c_clear_irq(void)
+{
+	writel(readl(&i2c_base->ctl) & ~TWI_CTL_INTFLG, &i2c_base->ctl);
+}
+
+static int i2c_wait_irq(void)
+{
+	return i2c_wait_ctl(TWI_CTL_INTFLG, 1);
+}
+
+static int i2c_wait_status(int status)
+{
+	int timeout = 0x2ff;
+
+	while (readl(&i2c_base->status) != status && timeout-- > 0)
+		;
+
+	if (timeout != 0)
+		return 0;
+	else
+		return -1;
+}
+
+static int i2c_wait_irq_status(int status)
+{
+	if (i2c_wait_irq() != 0)
+		return -1;
+
+	if (readl(&i2c_base->status) != status)
+		return -1;
+
+	return 0;
+}
+
+static int i2c_wait_bus_idle(void)
+{
+	int timeout = 0x2ff;
+
+	while (readl(&i2c_base->lctl) != 0x3a && timeout-- > 0)
+		;
+
+	if (timeout != 0)
+		return 0;
+	else
+		return -1;
+}
+
+static int i2c_stop(void)
+{
+	u32 ctl;
+
+	ctl = readl(&i2c_base->ctl) & 0xc0;
+	ctl |= TWI_CTL_STP;
+
+	writel(ctl, &i2c_base->ctl);
+
+	/* dummy to delay one I/O operation to make sure it's started */
+	(void)readl(&i2c_base->ctl);
+
+	if (i2c_wait_ctl(TWI_CTL_STP, 0) != 0)
+		return -1;
+	if (i2c_wait_status(TWI_STAT_IDLE))
+		return -1;
+	if (i2c_wait_bus_idle() != 0)
+		return -1;
+
+	return 0;
+}
+
+static int i2c_send_data(u8 data, u8 status)
+{
+	debug("i2c_write(%02x, %x), ctl=%x, status=%x\n", data, status,
+	      i2c_base->ctl, i2c_base->status);
+
+	writel(data, &i2c_base->data);
+	i2c_clear_irq();
+
+	if (i2c_wait_irq_status(status) != 0)
+		return -1;
+
+	return 0;
+}
+
+static int i2c_start(int status)
+{
+	u32 ctl;
+
+	debug("i2c_start(%x), ctl=%x, status=%x\n", status, i2c_base->ctl,
+	      i2c_base->status);
+	/* Check that the controller is idle */
+	if (status == TWI_STAT_TX_STA
+	    && readl(&i2c_base->status) != TWI_STAT_IDLE) {
+		return -1;
+	}
+
+	writel(0, &i2c_base->efr);
+
+	/* Send start */
+	ctl = readl(&i2c_base->ctl);
+	ctl |= TWI_CTL_STA;	/* Set start bit */
+	ctl &= ~TWI_CTL_INTFLG;	/* Clear int flag */
+	writel(ctl, &i2c_base->ctl);
+
+	if (i2c_wait_ctl(TWI_CTL_STA, 0) != 0)
+		return -1;
+	if (i2c_wait_irq_status(status) != 0)
+		return -1;
+
+	return 0;
+}
+
+int i2c_do_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	u32 status;
+	u32 ctl;
+
+	if (i2c_start(TWI_STAT_TX_STA) != 0)
+		return -1;
+
+	/* Send chip address */
+	if (i2c_send_data(chip << 1 | 0, TWI_STAT_TX_AW_ACK) != 0)
+		return -1;
+
+	/* Send data address */
+	if (i2c_send_data(addr, TWI_STAT_TXD_ACK) != 0)
+		return -1;
+
+	/* Send restart for read */
+	if (i2c_start(TWI_STAT_TX_RESTA) != 0)
+		return -1;
+
+	/* Send chip address */
+	if (i2c_send_data(chip << 1 | 1, TWI_STAT_TX_AR_ACK) != 0)
+		return -1;
+
+	/* Set ACK mode */
+	ctl = readl(&i2c_base->ctl);
+	ctl |= TWI_CTL_ACK;
+	writel(ctl, &i2c_base->ctl);
+	status = TWI_STAT_RXD_ACK;
+
+	/* Read data */
+	while (len > 0) {
+		if (len == 1) {
+			/* Set NACK mode (last byte) */
+			ctl = readl(&i2c_base->ctl);
+			ctl &= ~TWI_CTL_ACK;
+			writel(ctl, &i2c_base->ctl);
+			status = TWI_STAT_RXD_NAK;
+		}
+
+		i2c_clear_irq();
+		if (i2c_wait_irq_status(status) != 0)
+			return -1;
+
+		*buffer++ = readl(&i2c_base->data);
+		len--;
+	}
+
+	return 0;
+}
+
+int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	int rc = i2c_do_read(chip, addr, alen, buffer, len);
+
+	i2c_stop();
+
+	return rc;
+}
+
+static int i2c_do_write(uchar chip, uint addr, int alen, uchar *buffer,
+			int len)
+{
+	if (i2c_start(TWI_STAT_TX_STA) != 0)
+		return -1;
+
+	/* Send chip address */
+	if (i2c_send_data(chip << 1 | 0, TWI_STAT_TX_AW_ACK) != 0)
+		return -1;
+
+	/* Send data address */
+	if (i2c_send_data(addr, TWI_STAT_TXD_ACK) != 0)
+		return -1;
+
+	/* Send data */
+	while (len > 0) {
+		if (i2c_send_data(*buffer++, TWI_STAT_TXD_ACK) != 0)
+			return -1;
+		len--;
+	}
+
+	return 0;
+}
+
+int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
+{
+	int rc = i2c_do_write(chip, addr, alen, buffer, len);
+
+	i2c_stop();
+
+	return rc;
+}
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index 8a026e0..c2d16fb 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -194,4 +194,12 @@
 #undef CONFIG_CMD_NET
 #undef CONFIG_CMD_NFS
 
+/* I2C */
+#define CONFIG_SPL_I2C_SUPPORT
+#define CONFIG_SYS_I2C_SPEED		400000
+#define CONFIG_HARD_I2C
+#define CONFIG_SUNXI_I2C
+#define CONFIG_SYS_I2C_SLAVE		0x7f
+#define CONFIG_CMD_I2C
+
 #endif /* __CONFIG_H */
-- 
1.7.7.6

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 05/22] power: Add AXP209 Power Management controller (I2C)
       [not found] <cover.1353842684.git.henrik@henriknordstrom.net>
                   ` (2 preceding siblings ...)
  2012-11-25 11:38 ` [U-Boot] [PATCH 03/22] ARM sunxi: I2C driver Henrik Nordström
@ 2012-11-25 11:39 ` Henrik Nordström
  2012-11-25 14:44   ` Luka Perkov
                     ` (2 more replies)
  2012-11-25 11:40 ` [U-Boot] [PATCH 06/22] ARM sunxi: Basic GPIO driver Henrik Nordström
                   ` (17 subsequent siblings)
  21 siblings, 3 replies; 68+ messages in thread
From: Henrik Nordström @ 2012-11-25 11:39 UTC (permalink / raw)
  To: u-boot

This adds support for AXP209 Power Management controller,
used by most sunxi (Allwinner A10/A13) based boards.

From: Henrik Nordstrom <henrik@henriknordstrom.net>
Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>
Signed-off-by: Stefan Roese <sr@denx.de>
---
 drivers/power/Makefile |    1 +
 drivers/power/axp209.c |  183 ++++++++++++++++++++++++++++++++++++++++++++++++
 include/axp209.h       |   29 ++++++++
 3 files changed, 213 insertions(+), 0 deletions(-)
 create mode 100644 drivers/power/axp209.c
 create mode 100644 include/axp209.h

diff --git a/drivers/power/Makefile b/drivers/power/Makefile
index 8c71901..ad768ff 100644
--- a/drivers/power/Makefile
+++ b/drivers/power/Makefile
@@ -25,6 +25,7 @@ include $(TOPDIR)/config.mk
 
 LIB	:= $(obj)libpower.o
 
+COBJS-$(CONFIG_AXP209_POWER)	+= axp209.o
 COBJS-$(CONFIG_FTPMU010_POWER)	+= ftpmu010.o
 COBJS-$(CONFIG_TPS6586X_POWER)	+= tps6586x.o
 COBJS-$(CONFIG_TWL4030_POWER)	+= twl4030.o
diff --git a/drivers/power/axp209.c b/drivers/power/axp209.c
new file mode 100644
index 0000000..be98d80
--- /dev/null
+++ b/drivers/power/axp209.c
@@ -0,0 +1,183 @@
+/*
+ * (C) Copyright 2012
+ * Henrik Nordstrom <henrik@henriknordstrom.net>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <i2c.h>
+#include <axp209.h>
+
+enum axp209_reg {
+	AXP209_CHIP_VERSION = 0x3,
+	AXP209_DCDC2_VOLTAGE = 0x23,
+	AXP209_DCDC3_VOLTAGE = 0x27,
+	AXP209_LDO24_VOLTAGE = 0x28,
+	AXP209_LDO3_VOLTAGE = 0x29,
+	AXP209_SHUTDOWN = 0x32,
+};
+
+int axp209_write(enum axp209_reg reg, u8 val)
+{
+	return i2c_write(0x34, reg, 1, &val, 1);
+}
+
+int axp209_read(enum axp209_reg reg, u8 *val)
+{
+	return i2c_read(0x34, reg, 1, val, 1);
+}
+
+int axp209_set_dcdc2(int mvolt)
+{
+	int cfg = (mvolt - 700) / 25;
+	int rc;
+	u8 current;
+
+	if (cfg < 0)
+		cfg = 0;
+	if (cfg > (1 << 6) - 1)
+		cfg = (1 << 6) - 1;
+
+	/* Do we really need to be this gentle? It has built-in voltage slope */
+	while ((rc = axp209_read(AXP209_DCDC2_VOLTAGE, &current)) == 0
+	       && current != cfg) {
+		if (current < cfg)
+			current++;
+		else
+			current--;
+
+		rc = axp209_write(AXP209_DCDC2_VOLTAGE, current);
+		if (rc)
+			break;
+	}
+
+	return rc;
+}
+
+int axp209_set_dcdc3(int mvolt)
+{
+	int cfg = (mvolt - 700) / 25;
+	u8 reg;
+	int rc;
+
+	if (cfg < 0)
+		cfg = 0;
+	if (cfg > (1 << 7) - 1)
+		cfg = (1 << 7) - 1;
+
+	rc = axp209_write(AXP209_DCDC3_VOLTAGE, cfg);
+	rc |= axp209_read(AXP209_DCDC3_VOLTAGE, &reg);
+
+	return rc;
+}
+
+int axp209_set_ldo2(int mvolt)
+{
+	int cfg = (mvolt - 1800) / 100;
+	int rc;
+	u8 reg;
+
+	if (cfg < 0)
+		cfg = 0;
+	if (cfg > 15)
+		cfg = 15;
+
+	rc = axp209_read(AXP209_LDO24_VOLTAGE, &reg);
+	if (rc)
+		return rc;
+
+	reg = (reg & 0x0f) | (cfg << 4);
+	rc = axp209_write(AXP209_LDO24_VOLTAGE, reg);
+	if (rc)
+		return rc;
+
+	return 0;
+}
+
+int axp209_set_ldo3(int mvolt)
+{
+	int cfg = (mvolt - 700) / 25;
+
+	if (cfg < 0)
+		cfg = 0;
+	if (cfg > 127)
+		cfg = 127;
+	if (mvolt == -1)
+		cfg = 0x80;	/* detemined by LDO3IN pin */
+
+	return axp209_write(AXP209_LDO3_VOLTAGE, cfg);
+}
+
+int axp209_set_ldo4(int mvolt)
+{
+	int cfg = (mvolt - 1800) / 100;
+	int rc;
+	static const int vindex[] = {
+		1250, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000, 2500,
+		2700, 2800, 3000, 3100, 3200, 3300
+	};
+	u8 reg;
+
+	/* Translate mvolt to register cfg value, requested <= selected */
+	for (cfg = 0; mvolt < vindex[cfg] && cfg < 15; cfg++)
+		;
+
+	rc = axp209_read(AXP209_LDO24_VOLTAGE, &reg);
+	if (rc)
+		return rc;
+
+	/* LDO4 configuration is in lower 4 bits */
+	reg = (reg & 0xf0) | (cfg << 0);
+	rc = axp209_write(AXP209_LDO24_VOLTAGE, reg);
+	if (rc)
+		return rc;
+
+	return 0;
+}
+
+void axp209_poweroff(void)
+{
+	u8 val;
+
+	if (axp209_read(AXP209_SHUTDOWN, &val) != 0)
+		return;
+
+	val |= 1 << 7;
+
+	if (axp209_write(AXP209_SHUTDOWN, val) != 0)
+		return;
+
+	udelay(10000);		/* wait for power to drain */
+}
+
+int axp209_init(void)
+{
+	u8 ver;
+	int rc;
+
+	rc = axp209_read(AXP209_CHIP_VERSION, &ver);
+	if (rc)
+		return rc;
+
+	if (ver != 0x21)
+		return -1;
+
+	return 0;
+}
diff --git a/include/axp209.h b/include/axp209.h
new file mode 100644
index 0000000..61338ac
--- /dev/null
+++ b/include/axp209.h
@@ -0,0 +1,29 @@
+/*
+ * (C) Copyright 2012 Henrik Nordstrom <henrik@henriknordstrom.net>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+extern int axp209_set_dcdc2(int mvolt);
+extern int axp209_set_dcdc3(int mvolt);
+extern int axp209_set_ldo2(int mvolt);
+extern int axp209_set_ldo3(int mvolt);
+extern int axp209_set_ldo4(int mvolt);
+extern void axp209_poweroff(void);
+extern int axp209_init(void);
-- 
1.7.7.6

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 06/22] ARM sunxi: Basic GPIO driver
       [not found] <cover.1353842684.git.henrik@henriknordstrom.net>
                   ` (3 preceding siblings ...)
  2012-11-25 11:39 ` [U-Boot] [PATCH 05/22] power: Add AXP209 Power Management controller (I2C) Henrik Nordström
@ 2012-11-25 11:40 ` Henrik Nordström
  2012-11-25 14:52   ` Luka Perkov
                     ` (2 more replies)
  2012-11-25 11:40 ` [U-Boot] [PATCH 07/22] tools: mksunixboot adding a Allwinner boot header Henrik Nordström
                   ` (16 subsequent siblings)
  21 siblings, 3 replies; 68+ messages in thread
From: Henrik Nordström @ 2012-11-25 11:40 UTC (permalink / raw)
  To: u-boot

GPIO driver for Allwinner sun4i/sun5i family of SoCs

GPIO Pins are named by their symbolic pin names P<g><#>
such as PH19 or H19.

Note: This do not perform any validation if the pin is in use
for some other I/O function. Use with care.
---
 arch/arm/include/asm/arch-sunxi/gpio.h |    2 +
 drivers/gpio/Makefile                  |    1 +
 drivers/gpio/sunxi_gpio.c              |  116 ++++++++++++++++++++++++++++++++
 include/configs/sunxi-common.h         |    4 +
 4 files changed, 123 insertions(+), 0 deletions(-)
 create mode 100644 drivers/gpio/sunxi_gpio.c

diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
index fceee6b..a3f8a74 100644
--- a/arch/arm/include/asm/arch-sunxi/gpio.h
+++ b/arch/arm/include/asm/arch-sunxi/gpio.h
@@ -160,5 +160,7 @@ enum sunxi_gpio_number {
 
 int sunxi_gpio_set_cfgpin(u32 pin, u32 val);
 int sunxi_gpio_get_cfgpin(u32 pin);
+int name_to_gpio(const char *name);
+#define name_to_gpio	name_to_gpio
 
 #endif /* _SUNXI_GPIO_H */
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index d50ac3b..6d692e6 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -45,6 +45,7 @@ COBJS-$(CONFIG_OMAP_GPIO)	+= omap_gpio.o
 COBJS-$(CONFIG_DB8500_GPIO)	+= db8500_gpio.o
 COBJS-$(CONFIG_BCM2835_GPIO)	+= bcm2835_gpio.o
 COBJS-$(CONFIG_S3C2440_GPIO)	+= s3c2440_gpio.o
+COBJS-$(CONFIG_SUNXI_GPIO)	+= sunxi_gpio.o
 
 COBJS	:= $(COBJS-y)
 SRCS 	:= $(COBJS:.o=.c)
diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c
new file mode 100644
index 0000000..d99071e
--- /dev/null
+++ b/drivers/gpio/sunxi_gpio.c
@@ -0,0 +1,116 @@
+/*
+ * (C) Copyright 2007-2011
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Tom Cubie <tangliang@allwinnertech.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/gpio.h>
+
+static int sunxi_gpio_output(u32 pin, u32 val)
+{
+	u32 dat;
+	u32 bank = GPIO_BANK(pin);
+	u32 num = GPIO_NUM(pin);
+	struct sunxi_gpio *pio =
+	    &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank];
+
+	dat = readl(&pio->dat);
+	if (val)
+		dat |= 1 << num;
+	else
+		dat &= ~(1 << num);
+
+	writel(dat, &pio->dat);
+
+	return 0;
+}
+
+static int sunxi_gpio_input(u32 pin)
+{
+	u32 dat;
+	u32 bank = GPIO_BANK(pin);
+	u32 num = GPIO_NUM(pin);
+	struct sunxi_gpio *pio =
+	    &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank];
+
+	dat = readl(&pio->dat);
+	dat >>= num;
+
+	return dat & 0x1;
+}
+
+int gpio_request(unsigned gpio, const char *label)
+{
+	return 0;
+}
+
+int gpio_free(unsigned gpio)
+{
+	return 0;
+}
+
+int gpio_direction_input(unsigned gpio)
+{
+	sunxi_gpio_set_cfgpin(gpio, SUNXI_GPIO_INPUT);
+
+	return sunxi_gpio_input(gpio);
+}
+
+int gpio_direction_output(unsigned gpio, int value)
+{
+	sunxi_gpio_set_cfgpin(gpio, SUNXI_GPIO_OUTPUT);
+
+	return sunxi_gpio_output(gpio, value);
+}
+
+int gpio_get_value(unsigned gpio)
+{
+	return sunxi_gpio_input(gpio);
+}
+
+int gpio_set_value(unsigned gpio, int value)
+{
+	return sunxi_gpio_output(gpio, value);
+}
+
+int name_to_gpio(const char *name)
+{
+	int group = 0;
+	int groupsize = 9 * 32;
+	long pin;
+	const char *eptr;
+	if (*name == 'P' || *name == 'p')
+		name++;
+	if (*name >= 'A') {
+		group = *name - (*name > 'a' ? 'a' : 'A');
+		groupsize = 32;
+		name++;
+	}
+
+	pin = simple_strtol(name, &eptr, 10);
+	if (!*name || *eptr)
+		return -1;
+	if (pin < 0 || pin > groupsize || group >= 9)
+		return -1;
+	return group * 32 + pin;
+}
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index 5bf8eea..bc1f200 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -206,4 +206,8 @@
 /* #define CONFIG_WATCHDOG */
 /* #define CONFIG_SUNXI_WATCHDOG */
 
+/* GPIO */
+#define CONFIG_SUNXI_GPIO
+#define CONFIG_CMD_GPIO
+
 #endif /* __CONFIG_H */
-- 
1.7.7.6

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 07/22] tools: mksunixboot adding a Allwinner boot header
       [not found] <cover.1353842684.git.henrik@henriknordstrom.net>
                   ` (4 preceding siblings ...)
  2012-11-25 11:40 ` [U-Boot] [PATCH 06/22] ARM sunxi: Basic GPIO driver Henrik Nordström
@ 2012-11-25 11:40 ` Henrik Nordström
  2012-11-25 15:01   ` Luka Perkov
  2012-11-25 17:47   ` Wolfgang Denk
  2012-11-25 11:41 ` [U-Boot] [PATCH 08/22] net: Add sunxi (Allwinner) wemac driver Henrik Nordström
                   ` (15 subsequent siblings)
  21 siblings, 2 replies; 68+ messages in thread
From: Henrik Nordström @ 2012-11-25 11:40 UTC (permalink / raw)
  To: u-boot

This tool adds a boot header to the supplied file, for booting
code directly from the SoC embedded boot rom. Needed for making
the SPL loader bootable.

From: Tom Cubie <Mr.hipboi@gmail.com>
Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>
Signed-off-by: Stefan Roese <sr@denx.de>
---
 Makefile                 |    1 +
 tools/.gitignore         |    1 +
 tools/Makefile           |    6 ++
 tools/mksunxiboot.README |   13 ++++
 tools/mksunxiboot.c      |  162 ++++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 183 insertions(+), 0 deletions(-)
 create mode 100644 tools/mksunxiboot.README
 create mode 100644 tools/mksunxiboot.c

diff --git a/Makefile b/Makefile
index 5a98745..81fe532 100644
--- a/Makefile
+++ b/Makefile
@@ -799,6 +799,7 @@ clean:
 	       $(obj)tools/gen_eth_addr    $(obj)tools/img2srec		  \
 	       $(obj)tools/mk{env,}image   $(obj)tools/mpc86x_clk	  \
 	       $(obj)tools/mk{smdk5250,}spl				  \
+	       $(obj)tools/mksunxiboot					  \
 	       $(obj)tools/mxsboot					  \
 	       $(obj)tools/ncb		   $(obj)tools/ubsha1		  \
 	       $(obj)tools/kernel-doc/docproc
diff --git a/tools/.gitignore b/tools/.gitignore
index 9bce719..92fcbbd 100644
--- a/tools/.gitignore
+++ b/tools/.gitignore
@@ -7,6 +7,7 @@
 /mkimage
 /mpc86x_clk
 /mxsboot
+/mksunxiboot
 /ncb
 /ncp
 /ubsha1
diff --git a/tools/Makefile b/tools/Makefile
index 686840a..508112d 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -69,6 +69,7 @@ BIN_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes$(SFX)
 BIN_FILES-y += mkenvimage$(SFX)
 BIN_FILES-y += mkimage$(SFX)
 BIN_FILES-$(CONFIG_SMDK5250) += mksmdk5250spl$(SFX)
+BIN_FILES-$(CONFIG_SUNXI) += mksunxiboot$(SFX)
 BIN_FILES-$(CONFIG_MX28) += mxsboot$(SFX)
 BIN_FILES-$(CONFIG_NETCONSOLE) += ncb$(SFX)
 BIN_FILES-$(CONFIG_SHA1_CHECK_UB_IMG) += ubsha1$(SFX)
@@ -98,6 +99,7 @@ NOPED_OBJ_FILES-y += omapimage.o
 NOPED_OBJ_FILES-y += mkenvimage.o
 NOPED_OBJ_FILES-y += mkimage.o
 OBJ_FILES-$(CONFIG_SMDK5250) += mkexynosspl.o
+OBJ_FILES-$(CONFIG_SUNXI) += mksunxiboot.o
 OBJ_FILES-$(CONFIG_MX28) += mxsboot.o
 OBJ_FILES-$(CONFIG_NETCONSOLE) += ncb.o
 NOPED_OBJ_FILES-y += os_support.o
@@ -228,6 +230,10 @@ $(obj)mpc86x_clk$(SFX):	$(obj)mpc86x_clk.o
 	$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
 	$(HOSTSTRIP) $@
 
+$(obj)mksunxiboot$(SFX):	$(obj)mksunxiboot.o
+	$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
+	$(HOSTSTRIP) $@
+
 $(obj)mxsboot$(SFX):	$(obj)mxsboot.o
 	$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
 	$(HOSTSTRIP) $@
diff --git a/tools/mksunxiboot.README b/tools/mksunxiboot.README
new file mode 100644
index 0000000..9a4b379
--- /dev/null
+++ b/tools/mksunxiboot.README
@@ -0,0 +1,13 @@
+This program make a arm binary file can be loaded by Allwinner A10 and releated
+chips from storage media such as nand and mmc.
+
+More information about A10 boot, please refer to
+http://rhombus-tech.net/allwinner_a10/a10_boot_process/
+
+To compile this program, just type make, you will get 'mksunxiboot'.
+
+To use it,
+$./mksunxiboot u-boot.bin u-boot-mmc.bin
+then you can write it to a mmc card with dd.
+$sudo dd if=u-boot-mmc.bin of=/dev/sdb bs=1024 seek=8
+then insert your mmc card to your A10 tablet, you can boot from mmc card.
diff --git a/tools/mksunxiboot.c b/tools/mksunxiboot.c
new file mode 100644
index 0000000..fd81529
--- /dev/null
+++ b/tools/mksunxiboot.c
@@ -0,0 +1,162 @@
+/*
+ * (C) Copyright 2007-2011
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Tom Cubie <tangliang@allwinnertech.com>
+ *
+ * a simple tool to generate bootable image for sunxi platform.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+typedef unsigned char u8;
+typedef unsigned int u32;
+
+/* boot head definition from sun4i boot code */
+typedef struct boot_file_head {
+	u32 jump_instruction;	/* one intruction jumping to real code */
+	u8 magic[8];		/* ="eGON.BT0" or "eGON.BT1", not C-style str */
+	u32 check_sum;		/* generated by PC */
+	u32 length;		/* generated by PC */
+#if 1
+	/* We use a simplified header, only filling in what is needed by the
+	 * boot ROM. To be compatible with Allwinner tools the larger header
+	 * below should be used, followed by a custom header if desired. */
+	u8 pad[12];		/* align to 32 bytes */
+#else
+	u32 pub_head_size;	/* the size of boot_file_head_t */
+	u8 pub_head_vsn[4];	/* the version of boot_file_head_t */
+	u8 file_head_vsn[4];	/* the version of boot0_file_head_t or
+				   boot1_file_head_t */
+	u8 Boot_vsn[4];		/* Boot version */
+	u8 eGON_vsn[4];		/* eGON version */
+	u8 platform[8];		/* platform information */
+#endif
+} boot_file_head_t;
+
+#define BOOT0_MAGIC                     "eGON.BT0"
+#define STAMP_VALUE                     0x5F0A6C39
+
+/* check sum functon from sun4i boot code */
+int gen_check_sum(void *boot_buf)
+{
+	boot_file_head_t *head_p;
+	u32 length;
+	u32 *buf;
+	u32 loop;
+	u32 i;
+	u32 sum;
+
+	head_p = (boot_file_head_t *) boot_buf;
+	length = head_p->length;
+	if ((length & 0x3) != 0)	/* must 4-byte-aligned */
+		return -1;
+	buf = (u32 *) boot_buf;
+	head_p->check_sum = STAMP_VALUE;	/* fill stamp */
+	loop = length >> 2;
+
+	/* calculate the sum */
+	for (i = 0, sum = 0; i < loop; i++)
+		sum += buf[i];
+
+	/* write back check sum */
+	head_p->check_sum = sum;
+
+	return 0;
+}
+
+#define ALIGN(x, a) __ALIGN_MASK((x), (typeof(x))(a)-1)
+#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask))
+
+#define SUN4I_SRAM_SIZE (24 * 1024)
+#define SRAM_LOAD_MAX_SIZE (SUN4I_SRAM_SIZE - sizeof(boot_file_head_t))
+#define BLOCK_SIZE 512
+
+struct boot_img {
+	boot_file_head_t header;
+	char code[SRAM_LOAD_MAX_SIZE];
+	char pad[BLOCK_SIZE];
+};
+
+int main(int argc, char *argv[])
+{
+	int fd_in, fd_out;
+	struct boot_img img;
+	unsigned file_size, load_size;
+	int count;
+
+	if (argc < 2) {
+		printf
+			("\tThis program makes an input bin file to sun4i bootable image.\n"
+			 "\tUsage: %s input_file out_putfile\n", argv[0]);
+		return EXIT_FAILURE;
+	}
+
+	fd_in = open(argv[1], O_RDONLY);
+	if (fd_in < 0) {
+		perror("Open input file:");
+		return EXIT_FAILURE;
+	}
+
+	fd_out = open(argv[2], O_WRONLY | O_CREAT, 0666);
+	if (fd_out < 0) {
+		perror("Open output file:");
+		return EXIT_FAILURE;
+	}
+
+	memset((void *)img.pad, 0, BLOCK_SIZE);
+
+	/* get input file size */
+	file_size = lseek(fd_in, 0, SEEK_END);
+	printf("File size: 0x%x\n", file_size);
+
+	if (file_size > SRAM_LOAD_MAX_SIZE)
+		load_size = SRAM_LOAD_MAX_SIZE;
+	else
+		load_size = ALIGN(file_size, sizeof(int));
+	printf("Load size: 0x%x\n", load_size);
+
+	/* read file to buffer to calculate checksum */
+	lseek(fd_in, 0, SEEK_SET);
+	count = read(fd_in, img.code, load_size);
+	printf("Read 0x%x bytes\n", count);
+
+	/* fill the header */
+	img.header.jump_instruction =	/* b instruction */
+		0xEA000000 |	/* jump to the first instr after the header */
+		((sizeof(boot_file_head_t) / sizeof(int) - 2)
+		 & 0x00FFFFFF);
+	memcpy(img.header.magic, BOOT0_MAGIC, 8);	/* no '0' termination */
+	img.header.length =
+		ALIGN(load_size + sizeof(boot_file_head_t), BLOCK_SIZE);
+	gen_check_sum((void *)&img);
+
+	count = write(fd_out, (void *)&img, img.header.length);
+	printf("Write 0x%x bytes\n", count);
+
+	close(fd_in);
+	close(fd_out);
+
+	return EXIT_SUCCESS;
+}
-- 
1.7.7.6

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 08/22] net: Add sunxi (Allwinner) wemac driver
       [not found] <cover.1353842684.git.henrik@henriknordstrom.net>
                   ` (5 preceding siblings ...)
  2012-11-25 11:40 ` [U-Boot] [PATCH 07/22] tools: mksunixboot adding a Allwinner boot header Henrik Nordström
@ 2012-11-25 11:41 ` Henrik Nordström
  2013-07-08 15:43   ` Joe Hershberger
  2012-11-25 11:42 ` [U-Boot] [PATCH 09/22] ARM: sun4i: Enable ethernet support (wemac) on A10 boards Henrik Nordström
                   ` (14 subsequent siblings)
  21 siblings, 1 reply; 68+ messages in thread
From: Henrik Nordström @ 2012-11-25 11:41 UTC (permalink / raw)
  To: u-boot

This patch adds support for the WEMAC, the ethernet controller included
in the Allwinner A10 SoC. It will get used in the upcoming A10 board
support.

From: Stefan Roese <sr@denx.de>
Signed-off-by: Stefan Roese <sr@denx.de>
Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>
---
 drivers/net/Makefile      |    1 +
 drivers/net/sunxi_wemac.c |  533 +++++++++++++++++++++++++++++++++++++++++++++
 include/netdev.h          |    1 +
 3 files changed, 535 insertions(+), 0 deletions(-)
 create mode 100644 drivers/net/sunxi_wemac.c

diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 786a656..9255155 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -68,6 +68,7 @@ COBJS-$(CONFIG_RTL8169) += rtl8169.o
 COBJS-$(CONFIG_SH_ETHER) += sh_eth.o
 COBJS-$(CONFIG_SMC91111) += smc91111.o
 COBJS-$(CONFIG_SMC911X) += smc911x.o
+COBJS-$(CONFIG_SUNXI_WEMAC) += sunxi_wemac.o
 COBJS-$(CONFIG_DRIVER_TI_EMAC) += davinci_emac.o
 COBJS-$(CONFIG_TSEC_ENET) += tsec.o fsl_mdio.o
 COBJS-$(CONFIG_DRIVER_TI_CPSW) += cpsw.o
diff --git a/drivers/net/sunxi_wemac.c b/drivers/net/sunxi_wemac.c
new file mode 100644
index 0000000..1db3529
--- /dev/null
+++ b/drivers/net/sunxi_wemac.c
@@ -0,0 +1,533 @@
+/*
+ * sunxi_wemac.c -- Allwinner A10 ethernet driver
+ *
+ * (C) Copyright 2012, Stefan Roese <sr@denx.de>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <common.h>
+#include <malloc.h>
+#include <net.h>
+#include <miiphy.h>
+#include <linux/err.h>
+#include <asm/io.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/gpio.h>
+
+/* EMAC register  */
+struct wemac_regs {
+	u32 ctl;	/* 0x00 */
+	u32 tx_mode;	/* 0x04 */
+	u32 tx_flow;	/* 0x08 */
+	u32 tx_ctl0;	/* 0x0c */
+	u32 tx_ctl1;	/* 0x10 */
+	u32 tx_ins;	/* 0x14 */
+	u32 tx_pl0;	/* 0x18 */
+	u32 tx_pl1;	/* 0x1c */
+	u32 tx_sta;	/* 0x20 */
+	u32 tx_io_data;	/* 0x24 */
+	u32 tx_io_data1; /* 0x28 */
+	u32 tx_tsvl0;	/* 0x2c */
+	u32 tx_tsvh0;	/* 0x30 */
+	u32 tx_tsvl1;	/* 0x34 */
+	u32 tx_tsvh1;	/* 0x38 */
+	u32 rx_ctl;	/* 0x3c */
+	u32 rx_hash0;	/* 0x40 */
+	u32 rx_hash1;	/* 0x44 */
+	u32 rx_sta;	/* 0x48 */
+	u32 rx_io_data;	/* 0x4c */
+	u32 rx_fbc;	/* 0x50 */
+	u32 int_ctl;	/* 0x54 */
+	u32 int_sta;	/* 0x58 */
+	u32 mac_ctl0;	/* 0x5c */
+	u32 mac_ctl1;	/* 0x60 */
+	u32 mac_ipgt;	/* 0x64 */
+	u32 mac_ipgr;	/* 0x68 */
+	u32 mac_clrt;	/* 0x6c */
+	u32 mac_maxf;	/* 0x70 */
+	u32 mac_supp;	/* 0x74 */
+	u32 mac_test;	/* 0x78 */
+	u32 mac_mcfg;	/* 0x7c */
+	u32 mac_mcmd;	/* 0x80 */
+	u32 mac_madr;	/* 0x84 */
+	u32 mac_mwtd;	/* 0x88 */
+	u32 mac_mrdd;	/* 0x8c */
+	u32 mac_mind;	/* 0x90 */
+	u32 mac_ssrr;	/* 0x94 */
+	u32 mac_a0;	/* 0x98 */
+	u32 mac_a1;	/* 0x9c */
+};
+
+/* SRAMC register  */
+struct sunxi_sramc_regs {
+	u32 ctrl0;
+	u32 ctrl1;
+};
+
+/* 0: Disable       1: Aborted frame enable(default) */
+#define EMAC_TX_AB_M		(0x1 << 0)
+/* 0: CPU           1: DMA(default) */
+#define EMAC_TX_TM		(0x1 << 1)
+
+#define EMAC_TX_SETUP		(0)
+
+/* 0: DRQ asserted  1: DRQ automatically(default) */
+#define EMAC_RX_DRQ_MODE	(0x1 << 1)
+/* 0: CPU           1: DMA(default) */
+#define EMAC_RX_TM		(0x1 << 2)
+/* 0: Normal(default)        1: Pass all Frames */
+#define EMAC_RX_PA		(0x1 << 4)
+/* 0: Normal(default)        1: Pass Control Frames */
+#define EMAC_RX_PCF		(0x1 << 5)
+/* 0: Normal(default)        1: Pass Frames with CRC Error */
+#define EMAC_RX_PCRCE		(0x1 << 6)
+/* 0: Normal(default)        1: Pass Frames with Length Error */
+#define EMAC_RX_PLE		(0x1 << 7)
+/* 0: Normal                 1: Pass Frames length out of range(default) */
+#define EMAC_RX_POR		(0x1 << 8)
+/* 0: Not accept             1: Accept unicast Packets(default) */
+#define EMAC_RX_UCAD		(0x1 << 16)
+/* 0: Normal(default)        1: DA Filtering */
+#define EMAC_RX_DAF		(0x1 << 17)
+/* 0: Not accept             1: Accept multicast Packets(default) */
+#define EMAC_RX_MCO		(0x1 << 20)
+/* 0: Disable(default)       1: Enable Hash filter */
+#define EMAC_RX_MHF		(0x1 << 21)
+/* 0: Not accept             1: Accept Broadcast Packets(default) */
+#define EMAC_RX_BCO		(0x1 << 22)
+/* 0: Disable(default)       1: Enable SA Filtering */
+#define EMAC_RX_SAF		(0x1 << 24)
+/* 0: Normal(default)        1: Inverse Filtering */
+#define EMAC_RX_SAIF		(0x1 << 25)
+
+#define EMAC_RX_SETUP		(EMAC_RX_POR | EMAC_RX_UCAD | EMAC_RX_DAF | \
+				 EMAC_RX_MCO | EMAC_RX_BCO)
+
+/* 0: Disable                1: Enable Receive Flow Control(default) */
+#define EMAC_MAC_CTL0_RFC	(0x1 << 2)
+/* 0: Disable                1: Enable Transmit Flow Control(default) */
+#define EMAC_MAC_CTL0_TFC	(0x1 << 3)
+
+#define EMAC_MAC_CTL0_SETUP	(EMAC_MAC_CTL0_RFC | EMAC_MAC_CTL0_TFC)
+
+/* 0: Disable                1: Enable MAC Frame Length Checking(default) */
+#define EMAC_MAC_CTL1_FLC	(0x1 << 1)
+/* 0: Disable(default)       1: Enable Huge Frame */
+#define EMAC_MAC_CTL1_HF	(0x1 << 2)
+/* 0: Disable(default)       1: Enable MAC Delayed CRC */
+#define EMAC_MAC_CTL1_DCRC	(0x1 << 3)
+/* 0: Disable                1: Enable MAC CRC(default) */
+#define EMAC_MAC_CTL1_CRC	(0x1 << 4)
+/* 0: Disable                1: Enable MAC PAD Short frames(default) */
+#define EMAC_MAC_CTL1_PC	(0x1 << 5)
+/* 0: Disable(default)       1: Enable MAC PAD Short frames and append CRC */
+#define EMAC_MAC_CTL1_VC	(0x1 << 6)
+/* 0: Disable(default)       1: Enable MAC auto detect Short frames */
+#define EMAC_MAC_CTL1_ADP	(0x1 << 7)
+/* 0: Disable(default)       1: Enable */
+#define EMAC_MAC_CTL1_PRE	(0x1 << 8)
+/* 0: Disable(default)       1: Enable */
+#define EMAC_MAC_CTL1_LPE	(0x1 << 9)
+/* 0: Disable(default)       1: Enable no back off */
+#define EMAC_MAC_CTL1_NB	(0x1 << 12)
+/* 0: Disable(default)       1: Enable */
+#define EMAC_MAC_CTL1_BNB	(0x1 << 13)
+/* 0: Disable(default)       1: Enable */
+#define EMAC_MAC_CTL1_ED	(0x1 << 14)
+
+#define EMAC_MAC_CTL1_SETUP	(EMAC_MAC_CTL1_FLC | EMAC_MAC_CTL1_CRC | \
+				 EMAC_MAC_CTL1_PC)
+
+#define EMAC_MAC_IPGT		0x15
+
+#define EMAC_MAC_NBTB_IPG1	0xC
+#define EMAC_MAC_NBTB_IPG2	0x12
+
+#define EMAC_MAC_CW		0x37
+#define EMAC_MAC_RM		0xF
+
+#define EMAC_MAC_MFL		0x0600
+
+/* Receive status */
+#define EMAC_CRCERR		(1 << 4)
+#define EMAC_LENERR		(3 << 5)
+
+#define DMA_CPU_TRRESHOLD	2000
+
+struct wemac_eth_dev {
+	u32 speed;
+	u32 duplex;
+	u32 phy_configured;
+	int link_printed;
+};
+
+struct wemac_rxhdr {
+	s16 rx_len;
+	u16 rx_status;
+};
+
+static void wemac_inblk_32bit(void *reg, void *data, int count)
+{
+	int cnt = (count + 3) >> 2;
+
+	if (cnt) {
+		u32 *buf = data;
+
+		do {
+			u32 x = readl(reg);
+			*buf++ = x;
+		} while (--cnt);
+	}
+}
+
+static void wemac_outblk_32bit(void *reg, void *data, int count)
+{
+	int cnt = (count + 3) >> 2;
+
+	if (cnt) {
+		const u32 *buf = data;
+
+		do {
+			writel(*buf++, reg);
+		} while (--cnt);
+	}
+}
+
+/*
+ * Read a word from phyxcer
+ */
+static int wemac_phy_read(const char *devname, unsigned char addr,
+			  unsigned char reg, unsigned short *value)
+{
+	struct eth_device *dev = eth_get_dev_by_name(devname);
+	struct wemac_regs *regs = (struct wemac_regs *)dev->iobase;
+
+	/* issue the phy address and reg */
+	writel(addr << 8 | reg, &regs->mac_madr);
+
+	/* pull up the phy io line */
+	writel(0x1, &regs->mac_mcmd);
+
+	/* Wait read complete */
+	mdelay(1);
+
+	/* push down the phy io line */
+	writel(0x0, &regs->mac_mcmd);
+
+	/* and write data */
+	*value = readl(&regs->mac_mrdd);
+
+	return 0;
+}
+
+/*
+ * Write a word to phyxcer
+ */
+static int wemac_phy_write(const char *devname, unsigned char addr,
+			   unsigned char reg, unsigned short value)
+{
+	struct eth_device *dev = eth_get_dev_by_name(devname);
+	struct wemac_regs *regs = (struct wemac_regs *)dev->iobase;
+
+	/* issue the phy address and reg */
+	writel(addr << 8 | reg, &regs->mac_madr);
+
+	/* pull up the phy io line */
+	writel(0x1, &regs->mac_mcmd);
+
+	/* Wait write complete */
+	mdelay(1);
+
+	/* push down the phy io line */
+	writel(0x0, &regs->mac_mcmd);
+
+	/* and write data */
+	writel(value, &regs->mac_mwtd);
+
+	return 0;
+}
+
+static void emac_setup(struct eth_device *dev)
+{
+	struct wemac_regs *regs = (struct wemac_regs *)dev->iobase;
+	u32 reg_val;
+	u16 phy_val;
+	u32 duplex_flag;
+
+	/* Set up TX */
+	writel(EMAC_TX_SETUP, &regs->tx_mode);
+
+	/* Set up RX */
+	writel(EMAC_RX_SETUP, &regs->rx_ctl);
+
+	/* Set MAC */
+	/* Set MAC CTL0 */
+	writel(EMAC_MAC_CTL0_SETUP, &regs->mac_ctl0);
+
+	/* Set MAC CTL1 */
+	wemac_phy_read(dev->name, 1, 0, &phy_val);
+	debug("PHY SETUP, reg 0 value: %x\n", phy_val);
+	duplex_flag = !!(phy_val & (1 << 8));
+
+	reg_val = 0;
+	if (duplex_flag)
+		reg_val = (0x1 << 0);
+	writel(EMAC_MAC_CTL1_SETUP | reg_val, &regs->mac_ctl1);
+
+	/* Set up IPGT */
+	writel(EMAC_MAC_IPGT, &regs->mac_ipgt);
+
+	/* Set up IPGR */
+	writel(EMAC_MAC_NBTB_IPG2 | (EMAC_MAC_NBTB_IPG1 << 8), &regs->mac_ipgr);
+
+	/* Set up Collison window */
+	writel(EMAC_MAC_RM | (EMAC_MAC_CW << 8), &regs->mac_clrt);
+
+	/* Set up Max Frame Length */
+	writel(EMAC_MAC_MFL, &regs->mac_maxf);
+}
+
+static void wemac_reset(struct eth_device *dev)
+{
+	struct wemac_regs *regs = (struct wemac_regs *)dev->iobase;
+
+	debug("resetting device\n");
+
+	/* RESET device */
+	writel(0, &regs->ctl);
+	udelay(200);
+
+	writel(1, &regs->ctl);
+	udelay(200);
+}
+
+static int sunxi_wemac_eth_init(struct eth_device *dev, bd_t *bd)
+{
+	struct wemac_regs *regs = (struct wemac_regs *)dev->iobase;
+	struct wemac_eth_dev *priv = dev->priv;
+	u16 phy_reg;
+
+	/* Init EMAC */
+
+	/* Flush RX FIFO */
+	setbits_le32(&regs->rx_ctl, 0x8);
+	udelay(1);
+
+	/* Init MAC */
+
+	/* Soft reset MAC */
+	clrbits_le32(&regs->mac_ctl0, 1 << 15);
+
+	/* Set MII clock */
+	clrsetbits_le32(&regs->mac_mcfg, 0xf << 2, 0xd << 2);
+
+	/* Clear RX counter */
+	writel(0x0, &regs->rx_fbc);
+	udelay(1);
+
+	/* Set up EMAC */
+	emac_setup(dev);
+
+	writel(dev->enetaddr[0] << 16 | dev->enetaddr[1] << 8 |
+	       dev->enetaddr[2], &regs->mac_a1);
+	writel(dev->enetaddr[3] << 16 | dev->enetaddr[4] << 8 |
+	       dev->enetaddr[5], &regs->mac_a0);
+
+	mdelay(1);
+
+	wemac_reset(dev);
+
+	/* PHY POWER UP */
+	wemac_phy_read(dev->name, 1, 0, &phy_reg);
+	wemac_phy_write(dev->name, 1, 0, phy_reg & (~(1 << 11)));
+	mdelay(1);
+
+	wemac_phy_read(dev->name, 1, 0, &phy_reg);
+
+	priv->speed = miiphy_speed(dev->name, 0);
+	priv->duplex = miiphy_duplex(dev->name, 0);
+
+	/* Print link status only once */
+	if (!priv->link_printed) {
+		printf("ENET Speed is %d Mbps - %s duplex connection\n",
+		       priv->speed, (priv->duplex == HALF) ? "HALF" : "FULL");
+		priv->link_printed = 1;
+	}
+
+	/* Set EMAC SPEED depend on PHY */
+	clrsetbits_le32(&regs->mac_supp, 1 << 8,
+			((phy_reg & (1 << 13)) >> 13) << 8);
+
+	/* Set duplex depend on phy */
+	clrsetbits_le32(&regs->mac_ctl1, 1 << 0,
+			((phy_reg & (1 << 8)) >> 8) << 0);
+
+	/* Enable RX/TX */
+	setbits_le32(&regs->ctl, 0x7);
+
+	return 0;
+}
+
+static void sunxi_wemac_eth_halt(struct eth_device *dev)
+{
+	/* Nothing to do here */
+}
+
+static int sunxi_wemac_eth_recv(struct eth_device *dev)
+{
+	struct wemac_regs *regs = (struct wemac_regs *)dev->iobase;
+	struct wemac_rxhdr rxhdr;
+	u32 rxcount;
+	u32 reg_val;
+	int rx_len;
+	int rx_status;
+	int good_packet;
+
+	/* Check packet ready or not */
+
+	/*
+	 * Race warning: The first packet might arrive with
+	 * the interrupts disabled, but the second will fix
+	 */
+	rxcount = readl(&regs->rx_fbc);
+	if (!rxcount) {
+		/* Had one stuck? */
+		rxcount = readl(&regs->rx_fbc);
+		if (!rxcount)
+			return 0;
+	}
+
+	reg_val = readl(&regs->rx_io_data);
+	if (reg_val != 0x0143414d) {
+		/* Disable RX */
+		clrbits_le32(&regs->ctl, 1 << 2);
+
+		/* Flush RX FIFO */
+		setbits_le32(&regs->rx_ctl, 1 << 3);
+		while (readl(&regs->rx_ctl) & (1 << 3))
+			;
+
+		/* Enable RX */
+		setbits_le32(&regs->ctl, 1 << 2);
+
+		return 0;
+	}
+
+	/*
+	 * A packet ready now
+	 * Get status/length
+	 */
+	good_packet = 1;
+
+	wemac_inblk_32bit(&regs->rx_io_data, &rxhdr, sizeof(rxhdr));
+
+	rx_len = rxhdr.rx_len;
+	rx_status = rxhdr.rx_status;
+
+	/* Packet Status check */
+	if (rx_len < 0x40) {
+		good_packet = 0;
+		debug("RX: Bad Packet (runt)\n");
+	}
+
+	/* rx_status is identical to RSR register. */
+	if (0 & rx_status & (EMAC_CRCERR | EMAC_LENERR)) {
+		good_packet = 0;
+		if (rx_status & EMAC_CRCERR)
+			printf("crc error\n");
+		if (rx_status & EMAC_LENERR)
+			printf("length error\n");
+	}
+
+	/* Move data from WEMAC */
+	if (good_packet) {
+		if (rx_len > DMA_CPU_TRRESHOLD) {
+			printf("Received packet is too big (len=%d)\n", rx_len);
+		} else {
+			wemac_inblk_32bit((void *)&regs->rx_io_data,
+					  NetRxPackets[0], rx_len);
+
+			/* Pass to upper layer */
+			NetReceive(NetRxPackets[0], rx_len);
+			return rx_len;
+		}
+	}
+
+	return 0;
+}
+
+static int sunxi_wemac_eth_send(struct eth_device *dev, void *packet, int len)
+{
+	struct wemac_regs *regs = (struct wemac_regs *)dev->iobase;
+
+	/* Select channel 0 */
+	writel(0, &regs->tx_ins);
+
+	/* Write packet */
+	wemac_outblk_32bit((void *)&regs->tx_io_data, packet, len);
+
+	/* Set TX len */
+	writel(len, &regs->tx_pl0);
+
+	/* Start translate from fifo to phy */
+	setbits_le32(&regs->tx_ctl0, 1);
+
+	return 0;
+}
+
+int sunxi_wemac_initialize(void)
+{
+	struct sunxi_ccm_reg *const ccm =
+		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+	struct sunxi_sramc_regs *sram =
+		(struct sunxi_sramc_regs *)SUNXI_SRAMC_BASE;
+	struct eth_device *dev;
+	struct wemac_eth_dev *priv;
+	int pin;
+
+	dev = malloc(sizeof(*dev));
+	if (dev == NULL)
+		return -ENOMEM;
+
+	priv = (struct wemac_eth_dev *)malloc(sizeof(struct wemac_eth_dev));
+	if (!priv) {
+		free(dev);
+		return -ENOMEM;
+	}
+
+	memset(dev, 0, sizeof(*dev));
+	memset(priv, 0, sizeof(struct wemac_eth_dev));
+
+	/* Map SRAM to EMAC */
+	setbits_le32(&sram->ctrl1, 0x5 << 2);
+
+	/* Configure pin mux settings for MII Ethernet */
+	for (pin = SUNXI_GPA(0); pin <= SUNXI_GPA(17); pin++)
+		sunxi_gpio_set_cfgpin(pin, 2);
+
+	/* Set up clock gating */
+	setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_EMAC);
+
+	dev->iobase = SUNXI_EMAC_BASE;
+	dev->priv = priv;
+	dev->init = sunxi_wemac_eth_init;
+	dev->halt = sunxi_wemac_eth_halt;
+	dev->send = sunxi_wemac_eth_send;
+	dev->recv = sunxi_wemac_eth_recv;
+	strcpy(dev->name, "wemac");
+
+	eth_register(dev);
+
+	miiphy_register(dev->name, wemac_phy_read, wemac_phy_write);
+
+	return 0;
+}
diff --git a/include/netdev.h b/include/netdev.h
index b8d303d..207f2a4 100644
--- a/include/netdev.h
+++ b/include/netdev.h
@@ -94,6 +94,7 @@ int sh_eth_initialize(bd_t *bis);
 int skge_initialize(bd_t *bis);
 int smc91111_initialize(u8 dev_num, int base_addr);
 int smc911x_initialize(u8 dev_num, int base_addr);
+int sunxi_wemac_initialize(bd_t *bis);
 int tsi108_eth_initialize(bd_t *bis);
 int uec_standard_init(bd_t *bis);
 int uli526x_initialize(bd_t *bis);
-- 
1.7.7.6

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 09/22] ARM: sun4i: Enable ethernet support (wemac) on A10 boards
       [not found] <cover.1353842684.git.henrik@henriknordstrom.net>
                   ` (6 preceding siblings ...)
  2012-11-25 11:41 ` [U-Boot] [PATCH 08/22] net: Add sunxi (Allwinner) wemac driver Henrik Nordström
@ 2012-11-25 11:42 ` Henrik Nordström
  2012-11-25 15:05   ` Luka Perkov
  2012-11-25 11:43 ` [U-Boot] [PATCH 10/22] sunxi: Add more network commands and netconsole support Henrik Nordström
                   ` (13 subsequent siblings)
  21 siblings, 1 reply; 68+ messages in thread
From: Henrik Nordström @ 2012-11-25 11:42 UTC (permalink / raw)
  To: u-boot

From: Stefan Roese <sr@denx.de>
Signed-off-by: Stefan Roese <sr@denx.de>
Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>
---
 arch/arm/cpu/armv7/sunxi/board.c |   14 ++++++++++++++
 include/configs/sun4i.h          |    8 ++++++++
 2 files changed, 22 insertions(+), 0 deletions(-)

diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c
index 5c94110..29cc4bd 100644
--- a/arch/arm/cpu/armv7/sunxi/board.c
+++ b/arch/arm/cpu/armv7/sunxi/board.c
@@ -32,6 +32,7 @@
 #include <asm/arch/timer.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/sys_proto.h>
+#include <netdev.h>
 
 int gpio_init(void)
 {
@@ -78,3 +79,16 @@ void enable_caches(void)
 	dcache_enable();
 }
 #endif
+
+#if defined(CONFIG_SUNXI_WEMAC)
+/*
+ * Initializes on-chip ethernet controllers.
+ * to override, implement board_eth_init()
+ */
+int cpu_eth_init(bd_t *bis)
+{
+	sunxi_wemac_initialize(bis);
+
+	return 0;
+}
+#endif
diff --git a/include/configs/sun4i.h b/include/configs/sun4i.h
index 513f618..ad51446 100644
--- a/include/configs/sun4i.h
+++ b/include/configs/sun4i.h
@@ -44,4 +44,12 @@
 
 #define CONFIG_CONS_INDEX		1	/* UART0 */
 
+/* Ethernet support on A10 */
+#define CONFIG_SUNXI_WEMAC
+#define CONFIG_MII			/* MII PHY management		*/
+
+#define CONFIG_CMD_MII
+#define CONFIG_CMD_NET
+#define CONFIG_CMD_PING
+
 #endif /* __CONFIG_H */
-- 
1.7.7.6

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 10/22] sunxi: Add more network commands and netconsole support
       [not found] <cover.1353842684.git.henrik@henriknordstrom.net>
                   ` (7 preceding siblings ...)
  2012-11-25 11:42 ` [U-Boot] [PATCH 09/22] ARM: sun4i: Enable ethernet support (wemac) on A10 boards Henrik Nordström
@ 2012-11-25 11:43 ` Henrik Nordström
  2012-11-25 15:07   ` Luka Perkov
  2012-11-25 11:44 ` [U-Boot] [PATCH 11/22] ARM: sunxi: U-Boot SPL capable of booting directly from MMC Henrik Nordström
                   ` (12 subsequent siblings)
  21 siblings, 1 reply; 68+ messages in thread
From: Henrik Nordström @ 2012-11-25 11:43 UTC (permalink / raw)
  To: u-boot

Add most network related commands

Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>

---
 include/configs/sun4i.h |   21 ++++++++++++++++++++-
 1 files changed, 20 insertions(+), 1 deletions(-)

diff --git a/include/configs/sun4i.h b/include/configs/sun4i.h
index ad51446..a58f82b 100644
--- a/include/configs/sun4i.h
+++ b/include/configs/sun4i.h
@@ -47,9 +47,28 @@
 /* Ethernet support on A10 */
 #define CONFIG_SUNXI_WEMAC
 #define CONFIG_MII			/* MII PHY management		*/
-
 #define CONFIG_CMD_MII
 #define CONFIG_CMD_NET
 #define CONFIG_CMD_PING
+#define CONFIG_CMD_DHCP
+#define CONFIG_CMD_NFS
+#define CONFIG_CMD_SNTP
+#define CONFIG_CMD_DNS
+#define CONFIG_NETCONSOLE
+#define CONFIG_BOOTP_SUBNETMASK
+#define CONFIG_BOOTP_GATEWAY
+#define CONFIG_BOOTP_HOSTNAME
+#define CONFIG_BOOTP_NISDOMAIN
+#define CONFIG_BOOTP_BOOTPATH
+#define CONFIG_BOOTP_BOOTFILESIZE
+#define CONFIG_BOOTP_DNS
+#define CONFIG_BOOTP_DNS2
+#define CONFIG_BOOTP_SEND_HOSTNAME
+#define CONFIG_BOOTP_NTPSERVER
+#define CONFIG_BOOTP_TIMEOFFSET
+#define CONFIG_BOOTP_MAY_FAIL
+#define CONFIG_BOOTP_SERVERIP
+#define CONFIG_BOOTP_DHCP_REQUEST_DELAY		50000
+#define CONFIG_TIMESTAMP
 
 #endif /* __CONFIG_H */
-- 
1.7.7.6

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 11/22] ARM: sunxi: U-Boot SPL capable of booting directly from MMC
       [not found] <cover.1353842684.git.henrik@henriknordstrom.net>
                   ` (8 preceding siblings ...)
  2012-11-25 11:43 ` [U-Boot] [PATCH 10/22] sunxi: Add more network commands and netconsole support Henrik Nordström
@ 2012-11-25 11:44 ` Henrik Nordström
  2012-11-25 15:11   ` Luka Perkov
  2012-11-25 11:44 ` [U-Boot] [PATCH 12/22] ARM sunxi: SPL support for Olimex A13-OLinuXino board Henrik Nordström
                   ` (11 subsequent siblings)
  21 siblings, 1 reply; 68+ messages in thread
From: Henrik Nordström @ 2012-11-25 11:44 UTC (permalink / raw)
  To: u-boot

Allwinner sunxi family of SoCs boots from MMC0/NAND/NOR/MMC2 loading
boot code into an embedded 32KB SRAM.

This patch adds support for booting u-boot SPL from MMC0

We first initializes the console UART, then DRAM controller with board
specific DRAM configuration details, configure CPU core voltage and
clocks before loading the full u-boot image into DRAM.

From: Henrik Nordstrom <henrik@henriknordstrom.net>
Signed-off-by: Tom Cubie <tangliang@allwinnertech.com>
Signed-off-by: Stefan Roese <sr@denx.de>
Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>
---
 Makefile                                |   11 +
 arch/arm/cpu/armv7/sunxi/board.c        |   38 +++
 arch/arm/cpu/armv7/sunxi/clock.c        |   99 +++++++
 arch/arm/cpu/armv7/sunxi/dram.c         |  445 +++++++++++++++++++++++++++++++
 arch/arm/cpu/armv7/sunxi/u-boot-spl.lds |   63 +++++
 arch/arm/include/asm/arch-sunxi/spl.h   |   34 +++
 board/sunxi/board.c                     |   46 ++++
 include/configs/sunxi-common.h          |   30 ++-
 spl/Makefile                            |   10 +
 9 files changed, 775 insertions(+), 1 deletions(-)
 create mode 100644 arch/arm/cpu/armv7/sunxi/dram.c
 create mode 100644 arch/arm/cpu/armv7/sunxi/u-boot-spl.lds
 create mode 100644 arch/arm/include/asm/arch-sunxi/spl.h

diff --git a/Makefile b/Makefile
index 81fe532..d1b7f97 100644
--- a/Makefile
+++ b/Makefile
@@ -517,6 +517,16 @@ $(obj)u-boot.spr:	$(obj)u-boot.img $(obj)spl/u-boot-spl.bin
 			conv=notrunc 2>/dev/null
 		cat $(obj)spl/u-boot-spl-pad.img $(obj)u-boot.img > $@
 
+# sunxi: Combined object with SPL U-Boot with sunxi header (sunxi-spl.bin)
+# and the full-blown U-Boot attached to it
+$(obj)u-boot-sunxi-with-spl.bin: $(obj)spl/sunxi-spl.bin $(obj)u-boot.bin
+		tr "\000" "\377" < /dev/zero | dd ibs=1 count=$(CONFIG_SPL_PAD_TO) \
+			of=$(obj)spl/sunxi-spl-pad.bin 2>/dev/null
+		dd if=$(obj)spl/sunxi-spl.bin of=$(obj)spl/sunxi-spl-pad.bin \
+			conv=notrunc 2>/dev/null
+		cat $(obj)spl/sunxi-spl-pad.bin $(obj)u-boot.bin > $@
+		rm $(obj)spl/sunxi-spl-pad.bin
+
 ifeq ($(SOC),tegra20)
 ifeq ($(CONFIG_OF_SEPARATE),y)
 nodtb=dtb
@@ -854,6 +864,7 @@ clobber:	tidy
 	@[ ! -d $(obj)nand_spl ] || find $(obj)nand_spl -name "*" -type l -print | xargs rm -f
 	@rm -f $(obj)dts/*.tmp
 	@rm -f $(obj)spl/u-boot-spl{,-pad}.ais
+	@rm -f $(obj)spl/sun?i-spl.bin
 
 mrproper \
 distclean:	clobber unconfig
diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c
index 29cc4bd..6dc2bd0 100644
--- a/arch/arm/cpu/armv7/sunxi/board.c
+++ b/arch/arm/cpu/armv7/sunxi/board.c
@@ -27,12 +27,37 @@
 #include <common.h>
 #include <asm/io.h>
 #include <serial.h>
+#include <i2c.h>
 #include <asm/gpio.h>
 #include <asm/arch/clock.h>
 #include <asm/arch/timer.h>
 #include <asm/arch/gpio.h>
 #include <asm/arch/sys_proto.h>
 #include <netdev.h>
+#ifdef CONFIG_SPL_BUILD
+#include <spl.h>
+#endif
+
+#ifdef CONFIG_SPL_BUILD
+/* Pointer to the global data structure for SPL */
+DECLARE_GLOBAL_DATA_PTR;
+
+/* The sunxi internal brom will try to loader external bootloader
+ * from mmc0, nannd flash, mmc2.
+ * Unfortunately we can't check how SPL was loaded so assume
+ * it's always the first SD/MMC controller
+ */
+u32 spl_boot_device(void)
+{
+	return BOOT_DEVICE_MMC1;
+}
+
+/* No confiration data available in SPL yet. Hardcode bootmode */
+u32 spl_boot_mode(void)
+{
+	return MMCSD_MODE_RAW;
+}
+#endif
 
 int gpio_init(void)
 {
@@ -65,6 +90,19 @@ void s_init(void)
 #endif
 	clock_init();
 	gpio_init();
+
+#ifdef CONFIG_SPL_BUILD
+	gd = &gdata;
+	preloader_console_init();
+
+#ifdef CONFIG_SPL_I2C_SUPPORT
+	/* Needed early by sunxi_board_init if PMU is enabled */
+	i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
+#endif
+
+	sunxi_board_init();
+#endif
+
 }
 
 void reset_cpu(ulong addr)
diff --git a/arch/arm/cpu/armv7/sunxi/clock.c b/arch/arm/cpu/armv7/sunxi/clock.c
index b9bbb7d..91cfae3 100644
--- a/arch/arm/cpu/armv7/sunxi/clock.c
+++ b/arch/arm/cpu/armv7/sunxi/clock.c
@@ -24,13 +24,34 @@
 #include <common.h>
 #include <asm/io.h>
 #include <asm/arch/clock.h>
+#include <asm/arch/gpio.h>
 #include <asm/arch/sys_proto.h>
 
+#ifdef CONFIG_SPL_BUILD
+static void clock_init_safe(void)
+{
+	struct sunxi_ccm_reg * const ccm =
+		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+
+	/* Set safe defaults until PMU is configured */
+	writel(AXI_DIV_1 << 0 | AHB_DIV_2 << 4 | APB0_DIV_1 << 8 |
+	       CPU_CLK_SRC_OSC24M << 16, &ccm->cpu_ahb_apb0_cfg);
+	writel(0xa1005000, &ccm->pll1_cfg);
+	sdelay(200);
+	writel(AXI_DIV_1 << 0 | AHB_DIV_2 << 4 | APB0_DIV_1 << 8 |
+	       CPU_CLK_SRC_PLL1 << 16, &ccm->cpu_ahb_apb0_cfg);
+}
+#endif
+
 int clock_init(void)
 {
 	struct sunxi_ccm_reg *const ccm =
 		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
 
+#ifdef CONFIG_SPL_BUILD
+	clock_init_safe();
+#endif
+
 	/* uart clock source is apb1 */
 	sr32(&ccm->apb1_clk_div_cfg, 24, 2, APB1_CLK_SRC_OSC24M);
 	sr32(&ccm->apb1_clk_div_cfg, 16, 2, APB1_FACTOR_N);
@@ -70,3 +91,81 @@ int clock_twi_onoff(int port, int state)
 
 	return 0;
 }
+
+#ifdef CONFIG_SPL_BUILD
+#define PLL1_CFG(N, K, M, P)	(1 << 31 | 0 << 30 | 8 << 26 | 0 << 25 | \
+				 16 << 20 | (P) << 16 | 2 << 13 | (N) << 8 | \
+				 (K) << 4 | 0 << 3 | 0 << 2 | (M) << 0)
+#define RDIV(a, b)		((a + (b) - 1) / (b))
+
+struct {
+	u32 pll1_cfg;
+	unsigned int freq;
+} pll1_para[] = {
+	{ PLL1_CFG(16, 0, 0, 0), 384000000 },
+	{ PLL1_CFG(16, 1, 0, 0), 768000000 },
+	{ PLL1_CFG(20, 1, 0, 0), 960000000 },
+	{ PLL1_CFG(21, 1, 0, 0), 1008000000},
+	{ PLL1_CFG(22, 1, 0, 0), 1056000000},
+	{ PLL1_CFG(23, 1, 0, 0), 1104000000},
+	{ PLL1_CFG(24, 1, 0, 0), 1152000000},
+	{ PLL1_CFG(25, 1, 0, 0), 1200000000},
+	{ PLL1_CFG(26, 1, 0, 0), 1248000000},
+	{ PLL1_CFG(27, 1, 0, 0), 1296000000},
+	{ PLL1_CFG(28, 1, 0, 0), 1344000000},
+	{ PLL1_CFG(29, 1, 0, 0), 1392000000},
+	{ PLL1_CFG(30, 1, 0, 0), 1440000000},
+	{ PLL1_CFG(31, 1, 0, 0), 1488000000},
+	{ PLL1_CFG(31, 1, 0, 0), ~0},
+};
+
+void clock_set_pll1(int hz)
+{
+	int i = 0;
+	int axi, ahb, apb0;
+	struct sunxi_ccm_reg * const ccm =
+		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+
+	/* Find target frequency */
+	while (pll1_para[i].freq < hz)
+		i++;
+
+	hz = pll1_para[i].freq;
+
+	/* Calculate system clock divisors */
+	axi = RDIV(hz, 432000000);		/* Max 450MHz */
+	ahb = RDIV(hz/axi, 204000000);		/* Max 250MHz */
+	apb0 = 2;				/* Max 150MHz */
+
+	/* Map divisors to register values */
+	axi = axi - 1;
+	if (ahb > 4)
+		ahb = 3;
+	else if (ahb > 2)
+		ahb = 2;
+	else if (ahb > 1)
+		ahb = 1;
+	else
+		ahb = 0;
+
+	apb0 = apb0 - 1;
+
+	/* Switch to 24MHz clock while changing PLL1 */
+	writel(AXI_DIV_1 << 0 | AHB_DIV_2 << 4 | APB0_DIV_1 << 8 |
+	       CPU_CLK_SRC_OSC24M << 16, &ccm->cpu_ahb_apb0_cfg);
+	sdelay(20);
+
+	/* Configure sys clock divisors */
+	writel(axi << 0 | ahb << 4 | apb0 << 8 | CPU_CLK_SRC_OSC24M << 16,
+	       &ccm->cpu_ahb_apb0_cfg);
+
+	/* Configure PLL1 at the desired frequency */
+	writel(pll1_para[i].pll1_cfg, &ccm->pll1_cfg);
+	sdelay(200);
+
+	/* Switch CPU to PLL1 */
+	writel(axi << 0 | ahb << 4 | apb0 << 8 | CPU_CLK_SRC_PLL1 << 16,
+	       &ccm->cpu_ahb_apb0_cfg);
+	sdelay(20);
+}
+#endif
diff --git a/arch/arm/cpu/armv7/sunxi/dram.c b/arch/arm/cpu/armv7/sunxi/dram.c
new file mode 100644
index 0000000..f169b7b
--- /dev/null
+++ b/arch/arm/cpu/armv7/sunxi/dram.c
@@ -0,0 +1,445 @@
+/*
+ * sunxi DRAM controller initialization
+ * (C) Copyright 2012 Henrik Nordstrom <henrik@henriknordstrom.net>
+ *
+ * Based on sun4i Linux kernel sources mach-sunxi/pm/standby/dram*.c
+ * and earlier U-Boot Allwiner A10 SPL work
+ *
+ * (C) Copyright 2007-2012
+ * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
+ * Berg Xing <bergxing@allwinnertech.com>
+ * Tom Cubie <tangliang@allwinnertech.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/dram.h>
+#include <asm/arch/timer.h>
+#include <asm/arch/clock.h>
+#include <asm/arch/sys_proto.h>
+
+static void mctl_ddr3_reset(void)
+{
+	struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
+
+#ifdef CONFIG_SUN4I
+	struct sunxi_timer_reg *timer = (struct sunxi_timer_reg *)SUNXI_TIMER_BASE;
+	u32 reg_val;
+
+	writel(0, &timer->cpu_cfg);
+	reg_val = readl(&timer->cpu_cfg);
+	reg_val >>= 6;
+	reg_val &= 0x3;
+
+	if (reg_val != 0) {
+		setbits_le32(&dram->mcr, 0x1 << 12);
+		sdelay(0x100);
+		clrbits_le32(&dram->mcr, 0x1 << 12);
+	} else
+#endif
+	{
+		clrbits_le32(&dram->mcr, 0x1 << 12);
+		sdelay(0x100);
+		setbits_le32(&dram->mcr, 0x1 << 12);
+	}
+}
+
+static void mctl_set_drive(void)
+{
+	struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
+
+	clrsetbits_le32(&dram->mcr, 0x3, (0x6 << 12) | 0xFFC);
+}
+
+static void mctl_itm_disable(void)
+{
+	struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
+
+	setbits_le32(&dram->ccr, 0x1 << 28);
+}
+
+static void mctl_itm_enable(void)
+{
+	struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
+
+	clrbits_le32(&dram->ccr, 0x1 << 28);
+}
+
+static void mctl_enable_dll0(void)
+{
+	struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
+
+	clrsetbits_le32(&dram->dllcr[0], 0x40000000, 0x80000000);
+	sdelay(0x100);
+
+	clrbits_le32(&dram->dllcr[0], 0xC0000000);
+	sdelay(0x1000);
+
+	clrsetbits_le32(&dram->dllcr[0], 0x80000000, 0x40000000);
+	sdelay(0x1000);
+}
+
+/*
+ * Note: This differs from pm/standby in that it checks the bus width
+ */
+static void mctl_enable_dllx(void)
+{
+	struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
+	u32 i, n, bus_width;
+
+	bus_width = readl(&dram->dcr);
+	bus_width >>= 6;
+	bus_width &= 7;
+
+	if (bus_width == 3)
+		n = 5;
+	else
+		n = 3;
+
+	for (i = 1; i < n; i++)
+		clrsetbits_le32(&dram->dllcr[i], 0x40000000, 0x80000000);
+	sdelay(0x100);
+
+	for (i = 1; i < n; i++)
+		clrbits_le32(&dram->dllcr[i], 0xC0000000);
+	sdelay(0x1000);
+
+	for (i = 1; i < n; i++)
+		clrsetbits_le32(&dram->dllcr[i], 0x80000000, 0x40000000);
+	sdelay(0x1000);
+}
+
+static u32 hpcr_value[32] = {
+#ifdef CONFIG_SUN5I
+	0, 0, 0, 0,
+	0, 0, 0, 0,
+	0, 0, 0, 0,
+	0, 0, 0, 0,
+	0x1031, 0x1031, 0x0735, 0x1035,
+	0x1035, 0x0731, 0x1031, 0,
+	0x0301, 0x0301, 0x0301, 0x0301,
+	0x0301, 0x0301, 0x0301, 0
+#endif
+#ifdef CONFIG_SUN4I
+	0x0301, 0x0301, 0x0301, 0x0301,
+	0x0301, 0x0301, 0, 0,
+	0, 0, 0, 0,
+	0, 0, 0, 0,
+	0x1031, 0x1031, 0x0735, 0x1035,
+	0x1035, 0x0731, 0x1031, 0x0735,
+	0x1035, 0x1031, 0x0731, 0x1035,
+	0x1031, 0x0301, 0x0301, 0x0731
+#endif
+};
+
+static void mctl_configure_hostport(void)
+{
+	struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
+	u32 i;
+
+	for (i = 0; i < 32; i++)
+		writel(hpcr_value[i], &dram->hpcr[i]);
+}
+
+static void mctl_setup_dram_clock(u32 clk)
+{
+	u32 reg_val;
+	struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+
+	/* setup DRAM PLL */
+	reg_val = readl(&ccm->pll5_cfg);
+	reg_val &= ~0x3;
+	reg_val |= 0x1;			/* m factor */
+	reg_val &= ~(0x3 << 4);
+	reg_val |= 0x1 << 4;		/* k factor */
+	reg_val &= ~(0x1f << 8);
+	reg_val |= ((clk / 24) & 0x1f) << 8;	/* n factor */
+	reg_val &= ~(0x3 << 16);
+	reg_val |= 0x1 << 16;		/* p factor */
+	reg_val &= ~(0x1 << 29);	/* PLL on */
+	reg_val |= (u32) 0x1 << 31;	/* PLL En */
+	writel(reg_val, &ccm->pll5_cfg);
+	sdelay(0x100000);
+
+	setbits_le32(&ccm->pll5_cfg, 0x1 << 29);
+
+#ifdef CONFIG_SUN4I
+	/* reset GPS */
+	clrbits_le32(&ccm->gps_clk_cfg, 0x3);
+	setbits_le32(&ccm->ahb_gate0, 0x1 << 26);
+	sdelay(0x20);
+	clrbits_le32(&ccm->ahb_gate0, 0x1 << 26);
+#endif
+
+	/* setup MBUS clock */
+	reg_val = (0x1 << 31) | (0x2 << 24) | (0x1);
+	writel(reg_val, &ccm->mbus_clk_cfg);
+
+	/*
+	 * open DRAMC AHB & DLL register clock
+	 * close it first
+	 */
+#ifdef CONFIG_SUN5I
+	clrbits_le32(&ccm->ahb_gate0, 0x3 << 14);
+#else
+	clrbits_le32(&ccm->ahb_gate0, 0x1 << 14);
+#endif
+	sdelay(0x1000);
+
+	/* then open it */
+#ifdef CONFIG_SUN5I
+	setbits_le32(&ccm->ahb_gate0, 0x3 << 14);
+#else
+	setbits_le32(&ccm->ahb_gate0, 0x1 << 14);
+#endif
+	sdelay(0x1000);
+}
+
+static int dramc_scan_readpipe(void)
+{
+	struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
+	u32 reg_val;
+
+	/* data training trigger */
+	setbits_le32(&dram->ccr, 0x1 << 30);
+
+	/* check whether data training process is end */
+	while (readl(&dram->ccr) & (0x1 << 30))
+		;
+
+	/* check data training result */
+	reg_val = readl(&dram->csr);
+	if (reg_val & (0x1 << 20))
+		return -1;
+
+	return 0;
+}
+
+static void dramc_clock_output_en(u32 on)
+{
+#ifdef CONFIG_SUN5I
+	struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
+
+	if (on)
+		setbits_le32(&dram->mcr, 0x1 << SUN5I_DRAM_MCR_DCLK_OUT_OFFSET);
+	else
+		clrbits_le32(&dram->mcr, 0x1 << SUN5I_DRAM_MCR_DCLK_OUT_OFFSET);
+#endif
+#ifdef CONFIG_SUN4I
+	struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
+	if (on)
+		setbits_le32(&ccm->dram_clk_cfg, 0x1 << SUN4I_CCM_SDRAM_DCLK_OUT_OFFSET);
+	else
+		clrbits_le32(&ccm->dram_clk_cfg, 0x1 << SUN4I_CCM_SDRAM_DCLK_OUT_OFFSET);
+#endif
+}
+
+#ifdef CONFIG_SUN4I
+static void dramc_set_autorefresh_cycle(u32 clk)
+{
+	struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
+	u32 reg_val;
+	u32 tmp_val;
+	u32 dram_size;
+
+	if (clk < 600) {
+		dram_size = readl(&dram->dcr);
+		dram_size >>= 3;
+		dram_size &= 0x7;
+		if (dram_size <= 0x2)
+			reg_val = (131 * clk) >> 10;
+		else
+			reg_val = (336 * clk) >> 10;
+
+		tmp_val = (7987 * clk) >> 10;
+		tmp_val = tmp_val * 9 - 200;
+		reg_val |= tmp_val << 8;
+		reg_val |= 0x8 << 24;
+		writel(reg_val, &dram->drr);
+	} else {
+		writel(0x0, &dram->drr);
+	}
+}
+#endif /* SUN4I */
+
+#ifdef CONFIG_SUN5I
+static void dramc_set_autorefresh_cycle(u32 clk)
+{
+	struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
+	u32 reg_val;
+	u32 tmp_val;
+	reg_val = 131;
+
+	tmp_val = (7987 * clk) >> 10;
+	tmp_val = tmp_val * 9 - 200;
+	reg_val |= tmp_val << 8;
+	reg_val |= 0x8 << 24;
+	writel(reg_val, &dram->drr);
+}
+#endif /* SUN5I */
+
+int dramc_init(struct dram_para *para)
+{
+	struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
+	u32 reg_val;
+	int ret_val;
+
+	/* check input dram parameter structure */
+	if (!para)
+		return -1;
+
+	/* setup DRAM relative clock */
+	mctl_setup_dram_clock(para->clock);
+
+#ifdef CONFIG_SUN5I
+	/* Disable any pad power save control */
+	writel(0, &dram->ppwrsctl);
+#endif
+
+	/* reset external DRAM */
+	mctl_ddr3_reset();
+	mctl_set_drive();
+
+	/* dram clock off */
+	dramc_clock_output_en(0);
+
+#ifdef CONFIG_SUN4I
+	/* select dram controller 1 */
+	writel(0x16237495, &dram->csel);
+#endif
+
+	mctl_itm_disable();
+	mctl_enable_dll0();
+
+	/* configure external DRAM */
+	reg_val = 0;
+	if (para->type == 3)
+		reg_val |= 0x1;
+	reg_val |= (para->io_width >> 3) << 1;
+
+	if (para->density == 256)
+		reg_val |= 0x0 << 3;
+	else if (para->density == 512)
+		reg_val |= 0x1 << 3;
+	else if (para->density == 1024)
+		reg_val |= 0x2 << 3;
+	else if (para->density == 2048)
+		reg_val |= 0x3 << 3;
+	else if (para->density == 4096)
+		reg_val |= 0x4 << 3;
+	else if (para->density == 8192)
+		reg_val |= 0x5 << 3;
+	else
+		reg_val |= 0x0 << 3;
+
+	reg_val |= ((para->bus_width >> 3) - 1) << 6;
+
+	reg_val |= (para->rank_num - 1) << 10;
+
+	reg_val |= 0x1 << 12;
+	reg_val |= ((0x1) & 0x3) << 13;
+
+	writel(reg_val, &dram->dcr);
+
+#ifdef CONFIG_SUN5I
+	/* set odt impendance divide ratio */
+	reg_val = ((para->zq) >> 8) & 0xfffff;
+	reg_val |= ((para->zq) & 0xff) << 20;
+	reg_val |= (para->zq) & 0xf0000000;
+	writel(reg_val, &dram->zqcr0);
+#endif
+
+	/* dram clock on */
+	dramc_clock_output_en(1);
+
+	sdelay(0x10);
+
+	while (readl(&dram->ccr) & (0x1U << 31))
+		;
+
+	mctl_enable_dllx();
+
+#ifdef CONFIG_SUN4I
+	/* set odt impendance divide ratio */
+	reg_val = ((para->zq) >> 8) & 0xfffff;
+	reg_val |= ((para->zq) & 0xff) << 20;
+	reg_val |= (para->zq) & 0xf0000000;
+	writel(reg_val, &dram->zqcr0);
+#endif
+
+#ifdef CONFIG_SUN4I
+	/* set I/O configure register */
+	reg_val = 0x00cc0000;
+	reg_val |= (para->odt_en) & 0x3;
+	reg_val |= ((para->odt_en) & 0x3) << 30;
+	writel(reg_val, &dram->iocr);
+#endif
+
+	/* set refresh period */
+	dramc_set_autorefresh_cycle(para->clock);
+
+	/* set timing parameters */
+	writel(para->tpr0, &dram->tpr0);
+	writel(para->tpr1, &dram->tpr1);
+	writel(para->tpr2, &dram->tpr2);
+
+	/* set mode register */
+	if (para->type == 3) {
+		/* ddr3 */
+		reg_val = 0x0;
+#ifdef CONFIG_SUN5I
+		reg_val |= 0x1000;
+#endif
+		reg_val |= (para->cas - 4) << 4;
+		reg_val |= 0x5 << 9;
+	} else if (para->type == 2) {
+		/* ddr2 */
+		reg_val = 0x2;
+		reg_val |= para->cas << 4;
+		reg_val |= 0x5 << 9;
+	}
+	writel(reg_val, &dram->mr);
+
+	writel(para->emr1, &dram->emr);
+	writel(para->emr2, &dram->emr2);
+	writel(para->emr3, &dram->emr3);
+
+	/* set DQS window mode */
+	clrsetbits_le32(&dram->ccr, 0x1U << 17, 0x1U << 14);
+
+	/* initial external DRAM */
+	setbits_le32(&dram->ccr, 0x1U << 31);
+
+	while (readl(&dram->ccr) & (0x1U << 31))
+		;
+
+	/* scan read pipe value */
+	mctl_itm_enable();
+	ret_val = dramc_scan_readpipe();
+
+	if (ret_val < 0)
+		return 0;
+
+	/* configure all host port */
+	mctl_configure_hostport();
+
+	return get_ram_size((long *)PHYS_SDRAM_1, 1 << 30);
+}
diff --git a/arch/arm/cpu/armv7/sunxi/u-boot-spl.lds b/arch/arm/cpu/armv7/sunxi/u-boot-spl.lds
new file mode 100644
index 0000000..cb418e1
--- /dev/null
+++ b/arch/arm/cpu/armv7/sunxi/u-boot-spl.lds
@@ -0,0 +1,63 @@
+/*
+ * (C) Copyright 2002
+ * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
+ *
+ * (C) Copyright 2010
+ * Texas Instruments, <www.ti.com>
+ *	Aneesh V <aneesh@ti.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE,\
+		LENGTH = CONFIG_SPL_MAX_SIZE }
+MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \
+		LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+	.text      :
+	{
+		__start = .;
+		arch/arm/cpu/armv7/start.o	(.text)
+		*(.text*)
+	} > .sram
+
+	. = ALIGN(4);
+	.rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram
+
+	. = ALIGN(4);
+	.data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram
+
+	. = ALIGN(4);
+	__image_copy_end = .;
+	_end = .;
+
+	.bss :
+	{
+		. = ALIGN(4);
+		__bss_start = .;
+		*(.bss*)
+		. = ALIGN(4);
+		__bss_end__ = .;
+	} > .sdram
+}
diff --git a/arch/arm/include/asm/arch-sunxi/spl.h b/arch/arm/include/asm/arch-sunxi/spl.h
new file mode 100644
index 0000000..404e16a
--- /dev/null
+++ b/arch/arm/include/asm/arch-sunxi/spl.h
@@ -0,0 +1,34 @@
+/*
+ * (C) Copyright 2012
+ * Texas Instruments, <www.ti.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+#ifndef	_ASM_ARCH_SPL_H_
+#define	_ASM_SPL_H_
+
+#define BOOT_DEVICE_NONE	0
+#define BOOT_DEVICE_XIP		1
+#define BOOT_DEVICE_NAND	2
+#define BOOT_DEVICE_ONE_NAND	3
+#define BOOT_DEVICE_MMC2	5 /*emmc*/
+#define BOOT_DEVICE_MMC1	6
+#define BOOT_DEVICE_XIPWAIT	7
+#define BOOT_DEVICE_MMC2_2      0xFF
+#endif
diff --git a/board/sunxi/board.c b/board/sunxi/board.c
index 50fb40f..b917a0a 100644
--- a/board/sunxi/board.c
+++ b/board/sunxi/board.c
@@ -64,3 +64,49 @@ int board_mmc_init(bd_t *bis)
 	return 0;
 }
 #endif
+
+#ifdef CONFIG_SPL_BUILD
+void sunxi_board_init(void)
+{
+	int power_failed = 0;
+	int ramsize;
+
+	printf("DRAM:");
+	ramsize = sunxi_dram_init();
+	if (!ramsize) {
+		printf(" ?");
+		ramsize = sunxi_dram_init();
+	}
+	if (!ramsize) {
+		printf(" ?");
+		ramsize = sunxi_dram_init();
+	}
+	printf(" %dMB\n", ramsize>>20);
+	if (!ramsize)
+		hang();
+
+#ifdef CONFIG_AXP209_POWER
+	power_failed |= axp209_init();
+	power_failed |= axp209_set_dcdc2(1400);
+	power_failed |= axp209_set_dcdc3(1250);
+	power_failed |= axp209_set_ldo2(3000);
+	power_failed |= axp209_set_ldo3(2800);
+	power_failed |= axp209_set_ldo4(2800);
+#endif
+
+	/*
+	 * Only clock up the CPU to full speed if we are reasonably
+	 * assured it's being powered with suitable core voltage
+	 */
+	if (!power_failed)
+		clock_set_pll1(1008000000);
+}
+
+#ifdef CONFIG_SPL_DISPLAY_PRINT
+void spl_display_print(void)
+{
+	printf("Board: %s\n", CONFIG_SYS_BOARD_NAME);
+}
+#endif
+
+#endif
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index bc1f200..b0dcfdb 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -134,7 +134,7 @@
  */
 #define CONFIG_SYS_NO_FLASH
 
-#define CONFIG_SYS_MONITOR_LEN		(256 << 10)	/* 256 KB */
+#define CONFIG_SYS_MONITOR_LEN		(512 << 10)	/* 512 KB */
 #define CONFIG_IDENT_STRING		" Allwinner Technology "
 
 #define CONFIG_ENV_OFFSET		(544 << 10) /* (8 + 24 + 512)KB */
@@ -190,6 +190,30 @@
 #define CONFIG_CMD_EXT4		/* with this we can access ext4 bootfs */
 #define CONFIG_CMD_ZFS		/* with this we can access ZFS bootfs */
 
+#define CONFIG_SPL_FRAMEWORK
+#define CONFIG_SPL_BSS_START_ADDR	0x50000000
+#define CONFIG_SPL_BSS_MAX_SIZE		0x80000		/* 512 KB */
+
+#define CONFIG_SPL_TEXT_BASE		0x20		/* sram start+header */
+#define CONFIG_SPL_MAX_SIZE		0x8000		/* 32 KB */
+
+#define CONFIG_SPL_LIBCOMMON_SUPPORT
+#define CONFIG_SPL_LIBDISK_SUPPORT
+#define CONFIG_SPL_SERIAL_SUPPORT
+#define CONFIG_SPL_LIBGENERIC_SUPPORT
+#define CONFIG_SPL_MMC_SUPPORT
+#define CONFIG_SPL_DISPLAY_PRINT
+
+/* end of 24KB in sram */
+#define LOW_LEVEL_SRAM_STACK		0x00006000
+#define CONFIG_SPL_STACK		LOW_LEVEL_SRAM_STACK
+#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv7/sunxi/u-boot-spl.lds"
+
+/* 32KB offset */
+#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR	64
+/* SPL starts@offset 8KiB im MMC and has the size of 24KiB */
+#define CONFIG_SPL_PAD_TO		24576		/* decimal for 'dd' */
+
 #undef CONFIG_CMD_FPGA
 #undef CONFIG_CMD_NET
 #undef CONFIG_CMD_NFS
@@ -210,4 +234,8 @@
 #define CONFIG_SUNXI_GPIO
 #define CONFIG_CMD_GPIO
 
+/* PMU */
+#define CONFIG_SPL_POWER_SUPPORT
+#define CONFIG_AXP209_POWER
+
 #endif /* __CONFIG_H */
diff --git a/spl/Makefile b/spl/Makefile
index 3195390..74d27b1 100644
--- a/spl/Makefile
+++ b/spl/Makefile
@@ -126,6 +126,10 @@ ifdef CONFIG_SAMSUNG
 ALL-y	+= $(obj)$(BOARD)-spl.bin
 endif
 
+ifdef CONFIG_SUNXI
+ALL-y	+= $(obj)sunxi-spl.bin
+endif
+
 all:	$(ALL-y)
 
 ifdef CONFIG_SAMSUNG
@@ -134,6 +138,12 @@ $(obj)$(BOARD)-spl.bin: $(obj)u-boot-spl.bin
 		$(obj)u-boot-spl.bin $(obj)$(BOARD)-spl.bin
 endif
 
+ifdef CONFIG_SUNXI
+$(obj)sunxi-spl.bin: $(obj)u-boot-spl.bin
+	$(OBJTREE)/tools/mksunxiboot \
+		$(obj)u-boot-spl.bin $(obj)sunxi-spl.bin
+endif
+
 $(obj)u-boot-spl.bin:	$(obj)u-boot-spl
 	$(OBJCOPY) $(OBJCFLAGS) -O binary $< $@
 
-- 
1.7.7.6

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 12/22] ARM sunxi: SPL support for Olimex A13-OLinuXino board
       [not found] <cover.1353842684.git.henrik@henriknordstrom.net>
                   ` (9 preceding siblings ...)
  2012-11-25 11:44 ` [U-Boot] [PATCH 11/22] ARM: sunxi: U-Boot SPL capable of booting directly from MMC Henrik Nordström
@ 2012-11-25 11:44 ` Henrik Nordström
  2012-11-25 15:17   ` Luka Perkov
  2012-11-25 11:44 ` [U-Boot] [PATCH 13/22] ARM sunxi: SPL support for Mele A1000 board Henrik Nordström
                   ` (10 subsequent siblings)
  21 siblings, 1 reply; 68+ messages in thread
From: Henrik Nordström @ 2012-11-25 11:44 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>
---
 board/sunxi/Makefile             |    1 +
 board/sunxi/dram_a13_olinuxino.c |   31 +++++++++++++++++++++++++++++++
 boards.cfg                       |    1 +
 3 files changed, 33 insertions(+), 0 deletions(-)
 create mode 100644 board/sunxi/dram_a13_olinuxino.c

diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile
index 43acbab..0351935 100644
--- a/board/sunxi/Makefile
+++ b/board/sunxi/Makefile
@@ -26,6 +26,7 @@ include $(TOPDIR)/config.mk
 LIB	:= $(obj)lib$(BOARD).o
 
 COBJS-y	:= board.o
+COBJS-$(CONFIG_A13_OLINUXINO)	+= dram_a13_olinuxino.o
 
 COBJS	:= $(COBJS-y)
 SRCS 	:= $(COBJS:.o=.c)
diff --git a/board/sunxi/dram_a13_olinuxino.c b/board/sunxi/dram_a13_olinuxino.c
new file mode 100644
index 0000000..12b66d9
--- /dev/null
+++ b/board/sunxi/dram_a13_olinuxino.c
@@ -0,0 +1,31 @@
+/* this file is generated, don't edit it yourself */
+
+#include <common.h>
+#include <asm/arch/dram.h>
+
+static struct dram_para dram_para = {
+	.clock = 408,
+	.type = 3,
+	.rank_num = 1,
+	.density = 2048,
+	.io_width = 8,
+	.bus_width = 16,
+	.cas = 9,
+	.zq = 123,
+	.odt_en = 0,
+	.size = 512,
+	.tpr0 = 0x42d899b7,
+	.tpr1 = 0xa090,
+	.tpr2 = 0x22a00,
+	.tpr3 = 0,
+	.tpr4 = 0,
+	.tpr5 = 0,
+	.emr1 = 0,
+	.emr2 = 0x10,
+	.emr3 = 0,
+};
+
+int sunxi_dram_init(void)
+{
+	return dramc_init(&dram_para);
+}
diff --git a/boards.cfg b/boards.cfg
index 13d1f74..0db382d 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -288,6 +288,7 @@ whistler                     arm         armv7:arm720t whistler          nvidia
 colibri_t20_iris             arm         armv7:arm720t colibri_t20_iris  toradex        tegra20
 u8500_href                   arm         armv7       u8500               st-ericsson    u8500
 snowball                     arm         armv7       snowball               st-ericsson    u8500
+A13-OLinuXino                arm         armv7       sunxi               -              sunxi       sun5i:A13_OLINUXINO,SPL
 sun4i                        arm         armv7       sunxi               -              sunxi       sun4i
 sun4i_sdcon                  arm         armv7       sunxi               -              sunxi       sun4i:UART0_PORT_F
 sun5i                        arm         armv7       sunxi               -              sunxi       sun5i
-- 
1.7.7.6

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 13/22] ARM sunxi: SPL support for Mele A1000 board
       [not found] <cover.1353842684.git.henrik@henriknordstrom.net>
                   ` (10 preceding siblings ...)
  2012-11-25 11:44 ` [U-Boot] [PATCH 12/22] ARM sunxi: SPL support for Olimex A13-OLinuXino board Henrik Nordström
@ 2012-11-25 11:44 ` Henrik Nordström
  2012-11-25 11:45 ` [U-Boot] [PATCH 14/22] ARM sunxi: SPL support for Cubieboard board Henrik Nordström
                   ` (9 subsequent siblings)
  21 siblings, 0 replies; 68+ messages in thread
From: Henrik Nordström @ 2012-11-25 11:44 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>
---
 board/sunxi/Makefile          |    1 +
 board/sunxi/dram_mele_a1000.c |   24 ++++++++++++++++++++++++
 boards.cfg                    |    1 +
 3 files changed, 26 insertions(+), 0 deletions(-)
 create mode 100644 board/sunxi/dram_mele_a1000.c

diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile
index 0351935..b386b2b 100644
--- a/board/sunxi/Makefile
+++ b/board/sunxi/Makefile
@@ -27,6 +27,7 @@ LIB	:= $(obj)lib$(BOARD).o
 
 COBJS-y	:= board.o
 COBJS-$(CONFIG_A13_OLINUXINO)	+= dram_a13_olinuxino.o
+COBJS-$(CONFIG_MELE_A1000)	+= dram_mele_a1000.o
 
 COBJS	:= $(COBJS-y)
 SRCS 	:= $(COBJS:.o=.c)
diff --git a/board/sunxi/dram_mele_a1000.c b/board/sunxi/dram_mele_a1000.c
new file mode 100644
index 0000000..a6779b0
--- /dev/null
+++ b/board/sunxi/dram_mele_a1000.c
@@ -0,0 +1,24 @@
+/* this file is generated, don't edit it yourself */
+
+#include <common.h>
+#include <asm/arch/dram.h>
+
+static struct dram_para dram_para = {
+	.clock = 360,
+	.type = 3,
+	.rank_num = 1,
+	.density = 2048,
+	.io_width = 16,
+	.bus_width = 32,
+	.cas = 6,
+	.zq = 123,
+	.size = 512,
+	.tpr0 = 0x30926692,
+	.tpr1 = 0x1090,
+	.tpr2 = 0x1a0c8,
+};
+
+int sunxi_dram_init(void)
+{
+	return dramc_init(&dram_para);
+}
diff --git a/boards.cfg b/boards.cfg
index 0db382d..8371a12 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -289,6 +289,7 @@ colibri_t20_iris             arm         armv7:arm720t colibri_t20_iris  toradex
 u8500_href                   arm         armv7       u8500               st-ericsson    u8500
 snowball                     arm         armv7       snowball               st-ericsson    u8500
 A13-OLinuXino                arm         armv7       sunxi               -              sunxi       sun5i:A13_OLINUXINO,SPL
+Mele_A1000                   arm         armv7       sunxi               -              sunxi       sun4i:MELE_A1000,SPL
 sun4i                        arm         armv7       sunxi               -              sunxi       sun4i
 sun4i_sdcon                  arm         armv7       sunxi               -              sunxi       sun4i:UART0_PORT_F
 sun5i                        arm         armv7       sunxi               -              sunxi       sun5i
-- 
1.7.7.6

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 14/22] ARM sunxi: SPL support for Cubieboard board
       [not found] <cover.1353842684.git.henrik@henriknordstrom.net>
                   ` (11 preceding siblings ...)
  2012-11-25 11:44 ` [U-Boot] [PATCH 13/22] ARM sunxi: SPL support for Mele A1000 board Henrik Nordström
@ 2012-11-25 11:45 ` Henrik Nordström
  2012-11-25 11:45 ` [U-Boot] [PATCH 15/22] ARM sunxi: SPL support for Hackberry 1GB board Henrik Nordström
                   ` (8 subsequent siblings)
  21 siblings, 0 replies; 68+ messages in thread
From: Henrik Nordström @ 2012-11-25 11:45 UTC (permalink / raw)
  To: u-boot

From: Henrik Nordstrom <henrik@henriknordstrom.net>
Signed-off-by: Alejandro Mery <amery@geeks.cl>
Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>
Signed-off-by: Stefan Roese <sr@denx.de>
---
 board/sunxi/Makefile              |    2 ++
 board/sunxi/dram_cubieboard.c     |   31 +++++++++++++++++++++++++++++++
 board/sunxi/dram_cubieboard_512.c |   31 +++++++++++++++++++++++++++++++
 boards.cfg                        |    2 ++
 4 files changed, 66 insertions(+), 0 deletions(-)
 create mode 100644 board/sunxi/dram_cubieboard.c
 create mode 100644 board/sunxi/dram_cubieboard_512.c

diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile
index b386b2b..c2c6c65 100644
--- a/board/sunxi/Makefile
+++ b/board/sunxi/Makefile
@@ -27,6 +27,8 @@ LIB	:= $(obj)lib$(BOARD).o
 
 COBJS-y	:= board.o
 COBJS-$(CONFIG_A13_OLINUXINO)	+= dram_a13_olinuxino.o
+COBJS-$(CONFIG_CUBIEBOARD)	+= dram_cubieboard.o
+COBJS-$(CONFIG_CUBIEBOARD_512)	+= dram_cubieboard_512.o
 COBJS-$(CONFIG_MELE_A1000)	+= dram_mele_a1000.o
 
 COBJS	:= $(COBJS-y)
diff --git a/board/sunxi/dram_cubieboard.c b/board/sunxi/dram_cubieboard.c
new file mode 100644
index 0000000..7e71b35
--- /dev/null
+++ b/board/sunxi/dram_cubieboard.c
@@ -0,0 +1,31 @@
+/* this file is generated, don't edit it yourself */
+
+#include <common.h>
+#include <asm/arch/dram.h>
+
+static struct dram_para dram_para = {
+	.clock = 480,
+	.type = 3,
+	.rank_num = 1,
+	.density = 4096,
+	.io_width = 16,
+	.bus_width = 32,
+	.cas = 6,
+	.zq = 123,
+	.odt_en = 0,
+	.size = 1024,
+	.tpr0 = 0x30926692,
+	.tpr1 = 0x1090,
+	.tpr2 = 0x1a0c8,
+	.tpr3 = 0,
+	.tpr4 = 0,
+	.tpr5 = 0,
+	.emr1 = 0,
+	.emr2 = 0,
+	.emr3 = 0,
+};
+
+int sunxi_dram_init(void)
+{
+	return dramc_init(&dram_para);
+}
diff --git a/board/sunxi/dram_cubieboard_512.c b/board/sunxi/dram_cubieboard_512.c
new file mode 100644
index 0000000..3377fba
--- /dev/null
+++ b/board/sunxi/dram_cubieboard_512.c
@@ -0,0 +1,31 @@
+/* this file is generated, don't edit it yourself */
+
+#include <common.h>
+#include <asm/arch/dram.h>
+
+static struct dram_para dram_para = {
+	.clock = 480,
+	.type = 3,
+	.rank_num = 1,
+	.density = 2048,
+	.io_width = 16,
+	.bus_width = 32,
+	.cas = 6,
+	.zq = 123,
+	.odt_en = 0,
+	.size = 512,
+	.tpr0 = 0x30926692,
+	.tpr1 = 0x1090,
+	.tpr2 = 0x1a0c8,
+	.tpr3 = 0,
+	.tpr4 = 0,
+	.tpr5 = 0,
+	.emr1 = 0,
+	.emr2 = 0,
+	.emr3 = 0,
+};
+
+int sunxi_dram_init(void)
+{
+	return dramc_init(&dram_para);
+}
diff --git a/boards.cfg b/boards.cfg
index 8371a12..207af34 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -289,6 +289,8 @@ colibri_t20_iris             arm         armv7:arm720t colibri_t20_iris  toradex
 u8500_href                   arm         armv7       u8500               st-ericsson    u8500
 snowball                     arm         armv7       snowball               st-ericsson    u8500
 A13-OLinuXino                arm         armv7       sunxi               -              sunxi       sun5i:A13_OLINUXINO,SPL
+Cubieboard                   arm         armv7       sunxi               -              sunxi       sun4i:CUBIEBOARD,SPL
+Cubieboard_512               arm         armv7       sunxi               -              sunxi       sun4i:CUBIEBOARD_512,SPL
 Mele_A1000                   arm         armv7       sunxi               -              sunxi       sun4i:MELE_A1000,SPL
 sun4i                        arm         armv7       sunxi               -              sunxi       sun4i
 sun4i_sdcon                  arm         armv7       sunxi               -              sunxi       sun4i:UART0_PORT_F
-- 
1.7.7.6

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 15/22] ARM sunxi: SPL support for Hackberry 1GB board
       [not found] <cover.1353842684.git.henrik@henriknordstrom.net>
                   ` (12 preceding siblings ...)
  2012-11-25 11:45 ` [U-Boot] [PATCH 14/22] ARM sunxi: SPL support for Cubieboard board Henrik Nordström
@ 2012-11-25 11:45 ` Henrik Nordström
  2012-11-25 11:45 ` [U-Boot] [PATCH 16/22] ARM sunxi: SPL support for a13_mid board Henrik Nordström
                   ` (7 subsequent siblings)
  21 siblings, 0 replies; 68+ messages in thread
From: Henrik Nordström @ 2012-11-25 11:45 UTC (permalink / raw)
  To: u-boot

From: Henrik Nordstrom <henrik@henriknordstrom.net>
Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>
Signed-off-by: J M <mtx512jm@gmail.com>
---
 board/sunxi/Makefile         |    1 +
 board/sunxi/dram_hackberry.c |   31 +++++++++++++++++++++++++++++++
 boards.cfg                   |    1 +
 3 files changed, 33 insertions(+), 0 deletions(-)
 create mode 100644 board/sunxi/dram_hackberry.c

diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile
index c2c6c65..e8b9ef8 100644
--- a/board/sunxi/Makefile
+++ b/board/sunxi/Makefile
@@ -29,6 +29,7 @@ COBJS-y	:= board.o
 COBJS-$(CONFIG_A13_OLINUXINO)	+= dram_a13_olinuxino.o
 COBJS-$(CONFIG_CUBIEBOARD)	+= dram_cubieboard.o
 COBJS-$(CONFIG_CUBIEBOARD_512)	+= dram_cubieboard_512.o
+COBJS-$(CONFIG_HACKBERRY)	+= dram_hackberry.o
 COBJS-$(CONFIG_MELE_A1000)	+= dram_mele_a1000.o
 
 COBJS	:= $(COBJS-y)
diff --git a/board/sunxi/dram_hackberry.c b/board/sunxi/dram_hackberry.c
new file mode 100644
index 0000000..188b5cb
--- /dev/null
+++ b/board/sunxi/dram_hackberry.c
@@ -0,0 +1,31 @@
+/* this file is generated, don't edit it yourself */
+
+#include <common.h>
+#include <asm/arch/dram.h>
+
+static struct dram_para dram_para = {
+	.clock = 408,
+	.type = 3,
+	.rank_num = 1,
+	.density = 4096,
+	.io_width = 16,
+	.bus_width = 32,
+	.cas = 6,
+	.zq = 123,
+	.odt_en = 1,
+	.size = 1024,
+	.tpr0 = 0x30926692,
+	.tpr1 = 0x1090,
+	.tpr2 = 0x1a0c8,
+	.tpr3 = 0,
+	.tpr4 = 0,
+	.tpr5 = 0,
+	.emr1 = 0,
+	.emr2 = 0,
+	.emr3 = 0,
+};
+
+int sunxi_dram_init(void)
+{
+	return dramc_init(&dram_para);
+}
diff --git a/boards.cfg b/boards.cfg
index 207af34..08ded68 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -291,6 +291,7 @@ snowball                     arm         armv7       snowball               st-e
 A13-OLinuXino                arm         armv7       sunxi               -              sunxi       sun5i:A13_OLINUXINO,SPL
 Cubieboard                   arm         armv7       sunxi               -              sunxi       sun4i:CUBIEBOARD,SPL
 Cubieboard_512               arm         armv7       sunxi               -              sunxi       sun4i:CUBIEBOARD_512,SPL
+Hackberry                    arm         armv7       sunxi               -              sunxi       sun4i:HACKBERRY,SPL
 Mele_A1000                   arm         armv7       sunxi               -              sunxi       sun4i:MELE_A1000,SPL
 sun4i                        arm         armv7       sunxi               -              sunxi       sun4i
 sun4i_sdcon                  arm         armv7       sunxi               -              sunxi       sun4i:UART0_PORT_F
-- 
1.7.7.6

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 16/22] ARM sunxi: SPL support for a13_mid board
       [not found] <cover.1353842684.git.henrik@henriknordstrom.net>
                   ` (13 preceding siblings ...)
  2012-11-25 11:45 ` [U-Boot] [PATCH 15/22] ARM sunxi: SPL support for Hackberry 1GB board Henrik Nordström
@ 2012-11-25 11:45 ` Henrik Nordström
  2012-11-25 11:45 ` [U-Boot] [PATCH 17/22] ARM sunxi: SPL support for Mini-X board Henrik Nordström
                   ` (6 subsequent siblings)
  21 siblings, 0 replies; 68+ messages in thread
From: Henrik Nordström @ 2012-11-25 11:45 UTC (permalink / raw)
  To: u-boot

From:    Jari Helaakoski <tekkuli@gmail.com>
Signed-off-by: Jari Helaakoski <tekkuli@gmail.com>
Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>
---
 board/sunxi/Makefile       |    1 +
 board/sunxi/dram_a13_mid.c |   31 +++++++++++++++++++++++++++++++
 boards.cfg                 |    1 +
 3 files changed, 33 insertions(+), 0 deletions(-)
 create mode 100644 board/sunxi/dram_a13_mid.c

diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile
index e8b9ef8..f6a836f 100644
--- a/board/sunxi/Makefile
+++ b/board/sunxi/Makefile
@@ -27,6 +27,7 @@ LIB	:= $(obj)lib$(BOARD).o
 
 COBJS-y	:= board.o
 COBJS-$(CONFIG_A13_OLINUXINO)	+= dram_a13_olinuxino.o
+COBJS-$(CONFIG_A13_MID)		+= dram_a13_mid.o
 COBJS-$(CONFIG_CUBIEBOARD)	+= dram_cubieboard.o
 COBJS-$(CONFIG_CUBIEBOARD_512)	+= dram_cubieboard_512.o
 COBJS-$(CONFIG_HACKBERRY)	+= dram_hackberry.o
diff --git a/board/sunxi/dram_a13_mid.c b/board/sunxi/dram_a13_mid.c
new file mode 100644
index 0000000..3b0e595
--- /dev/null
+++ b/board/sunxi/dram_a13_mid.c
@@ -0,0 +1,31 @@
+/* this file is generated, don't edit it yourself */
+
+#include <common.h>
+#include <asm/arch/dram.h>
+
+static struct dram_para dram_para = {
+	.clock = 408,
+	.type = 3,
+	.rank_num = 1,
+	.density = 2048,
+	.io_width = 8,
+	.bus_width = 16,
+	.cas = 9,
+	.zq = 123,
+	.odt_en = 1,
+	.size = 512,
+	.tpr0 = 0x42d899b7,
+	.tpr1 = 0xa090,
+	.tpr2 = 0x22a00,
+	.tpr3 = 0,
+	.tpr4 = 0,
+	.tpr5 = 0,
+	.emr1 = 0x4,
+	.emr2 = 0x10,
+	.emr3 = 0,
+};
+
+int sunxi_dram_init(void)
+{
+	return dramc_init(&dram_para);
+}
diff --git a/boards.cfg b/boards.cfg
index 08ded68..0a8b938 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -289,6 +289,7 @@ colibri_t20_iris             arm         armv7:arm720t colibri_t20_iris  toradex
 u8500_href                   arm         armv7       u8500               st-ericsson    u8500
 snowball                     arm         armv7       snowball               st-ericsson    u8500
 A13-OLinuXino                arm         armv7       sunxi               -              sunxi       sun5i:A13_OLINUXINO,SPL
+A13_MID                      arm         armv7       sunxi               -              sunxi       sun5i:A13_MID,SPL
 Cubieboard                   arm         armv7       sunxi               -              sunxi       sun4i:CUBIEBOARD,SPL
 Cubieboard_512               arm         armv7       sunxi               -              sunxi       sun4i:CUBIEBOARD_512,SPL
 Hackberry                    arm         armv7       sunxi               -              sunxi       sun4i:HACKBERRY,SPL
-- 
1.7.7.6

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 17/22] ARM sunxi: SPL support for Mini-X board
       [not found] <cover.1353842684.git.henrik@henriknordstrom.net>
                   ` (14 preceding siblings ...)
  2012-11-25 11:45 ` [U-Boot] [PATCH 16/22] ARM sunxi: SPL support for a13_mid board Henrik Nordström
@ 2012-11-25 11:45 ` Henrik Nordström
  2012-11-25 11:46 ` [U-Boot] [PATCH 18/22] ARM sunxi: SPL support for hyundai A7HD board Henrik Nordström
                   ` (5 subsequent siblings)
  21 siblings, 0 replies; 68+ messages in thread
From: Henrik Nordström @ 2012-11-25 11:45 UTC (permalink / raw)
  To: u-boot

From: Jari Helaakoski <tekkuli@gmail.com>
Signed-off-by: Jari Helaakoski <tekkuli@gmail.com>
Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>
---
 board/sunxi/Makefile      |    1 +
 board/sunxi/dram_mini_x.c |   31 +++++++++++++++++++++++++++++++
 boards.cfg                |    1 +
 3 files changed, 33 insertions(+), 0 deletions(-)
 create mode 100644 board/sunxi/dram_mini_x.c

diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile
index f6a836f..9c6c875 100644
--- a/board/sunxi/Makefile
+++ b/board/sunxi/Makefile
@@ -32,6 +32,7 @@ COBJS-$(CONFIG_CUBIEBOARD)	+= dram_cubieboard.o
 COBJS-$(CONFIG_CUBIEBOARD_512)	+= dram_cubieboard_512.o
 COBJS-$(CONFIG_HACKBERRY)	+= dram_hackberry.o
 COBJS-$(CONFIG_MELE_A1000)	+= dram_mele_a1000.o
+COBJS-$(CONFIG_MINI_X)		+= dram_mini_x.o
 
 COBJS	:= $(COBJS-y)
 SRCS 	:= $(COBJS:.o=.c)
diff --git a/board/sunxi/dram_mini_x.c b/board/sunxi/dram_mini_x.c
new file mode 100644
index 0000000..fc8cc92
--- /dev/null
+++ b/board/sunxi/dram_mini_x.c
@@ -0,0 +1,31 @@
+/* this file is generated, don't edit it yourself */
+
+#include <common.h>
+#include <asm/arch/dram.h>
+
+static struct dram_para dram_para = {
+	.clock = 360,
+	.type = 3,
+	.rank_num = 1,
+	.density = 2048,
+	.io_width = 16,
+	.bus_width = 32,
+	.cas = 6,
+	.zq = 123,
+	.odt_en = 0,
+	.size = 512,
+	.tpr0 = 0x30926692,
+	.tpr1 = 0x1090,
+	.tpr2 = 0x1a0c8,
+	.tpr3 = 0,
+	.tpr4 = 0,
+	.tpr5 = 0,
+	.emr1 = 0,
+	.emr2 = 0,
+	.emr3 = 0,
+};
+
+int sunxi_dram_init(void)
+{
+	return dramc_init(&dram_para);
+}
diff --git a/boards.cfg b/boards.cfg
index 0a8b938..d9b3d87 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -294,6 +294,7 @@ Cubieboard                   arm         armv7       sunxi               -
 Cubieboard_512               arm         armv7       sunxi               -              sunxi       sun4i:CUBIEBOARD_512,SPL
 Hackberry                    arm         armv7       sunxi               -              sunxi       sun4i:HACKBERRY,SPL
 Mele_A1000                   arm         armv7       sunxi               -              sunxi       sun4i:MELE_A1000,SPL
+Mini-X                       arm         armv7       sunxi               -              sunxi       sun4i:MINI_X,SPL
 sun4i                        arm         armv7       sunxi               -              sunxi       sun4i
 sun4i_sdcon                  arm         armv7       sunxi               -              sunxi       sun4i:UART0_PORT_F
 sun5i                        arm         armv7       sunxi               -              sunxi       sun5i
-- 
1.7.7.6

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 18/22] ARM sunxi: SPL support for hyundai A7HD board
       [not found] <cover.1353842684.git.henrik@henriknordstrom.net>
                   ` (15 preceding siblings ...)
  2012-11-25 11:45 ` [U-Boot] [PATCH 17/22] ARM sunxi: SPL support for Mini-X board Henrik Nordström
@ 2012-11-25 11:46 ` Henrik Nordström
  2012-11-25 11:46 ` [U-Boot] [PATCH 19/22] ARM sunxi: SPL support for MK802 board Henrik Nordström
                   ` (4 subsequent siblings)
  21 siblings, 0 replies; 68+ messages in thread
From: Henrik Nordström @ 2012-11-25 11:46 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Luc Verhaegen <libv@skynet.be>
Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>
Signed-off-by: Stefan Roese <sr@denx.de>
---
 board/sunxi/Makefile            |    1 +
 board/sunxi/dram_hyundai_a7hd.c |   31 +++++++++++++++++++++++++++++++
 boards.cfg                      |    1 +
 3 files changed, 33 insertions(+), 0 deletions(-)
 create mode 100644 board/sunxi/dram_hyundai_a7hd.c

diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile
index 9c6c875..091db59 100644
--- a/board/sunxi/Makefile
+++ b/board/sunxi/Makefile
@@ -33,6 +33,7 @@ COBJS-$(CONFIG_CUBIEBOARD_512)	+= dram_cubieboard_512.o
 COBJS-$(CONFIG_HACKBERRY)	+= dram_hackberry.o
 COBJS-$(CONFIG_MELE_A1000)	+= dram_mele_a1000.o
 COBJS-$(CONFIG_MINI_X)		+= dram_mini_x.o
+COBJS-$(CONFIG_A7HD)		+= dram_hyundai_a7hd.o
 
 COBJS	:= $(COBJS-y)
 SRCS 	:= $(COBJS:.o=.c)
diff --git a/board/sunxi/dram_hyundai_a7hd.c b/board/sunxi/dram_hyundai_a7hd.c
new file mode 100644
index 0000000..56a9d64
--- /dev/null
+++ b/board/sunxi/dram_hyundai_a7hd.c
@@ -0,0 +1,31 @@
+/* this file is generated, don't edit it yourself */
+
+#include <common.h>
+#include <asm/arch/dram.h>
+
+static struct dram_para dram_para = {
+	.clock = 360,
+	.type = 3,
+	.rank_num = 1,
+	.density = 2048,
+	.io_width = 8,
+	.bus_width = 32,
+	.cas = 6,
+	.zq = 123,
+	.odt_en = 0,
+	.size = 1024,
+	.tpr0 = 0x30926692,
+	.tpr1 = 0x1090,
+	.tpr2 = 0x1a0c8,
+	.tpr3 = 0,
+	.tpr4 = 0,
+	.tpr5 = 0,
+	.emr1 = 0,
+	.emr2 = 0,
+	.emr3 = 0,
+};
+
+int sunxi_dram_init(void)
+{
+	return dramc_init(&dram_para);
+}
diff --git a/boards.cfg b/boards.cfg
index d9b3d87..b8a5375 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -293,6 +293,7 @@ A13_MID                      arm         armv7       sunxi               -
 Cubieboard                   arm         armv7       sunxi               -              sunxi       sun4i:CUBIEBOARD,SPL
 Cubieboard_512               arm         armv7       sunxi               -              sunxi       sun4i:CUBIEBOARD_512,SPL
 Hackberry                    arm         armv7       sunxi               -              sunxi       sun4i:HACKBERRY,SPL
+Hyundai_A7HD                 arm         armv7       sunxi               -              sunxi       sun4i:A7HD,SPL
 Mele_A1000                   arm         armv7       sunxi               -              sunxi       sun4i:MELE_A1000,SPL
 Mini-X                       arm         armv7       sunxi               -              sunxi       sun4i:MINI_X,SPL
 sun4i                        arm         armv7       sunxi               -              sunxi       sun4i
-- 
1.7.7.6

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 19/22] ARM sunxi: SPL support for MK802 board
       [not found] <cover.1353842684.git.henrik@henriknordstrom.net>
                   ` (16 preceding siblings ...)
  2012-11-25 11:46 ` [U-Boot] [PATCH 18/22] ARM sunxi: SPL support for hyundai A7HD board Henrik Nordström
@ 2012-11-25 11:46 ` Henrik Nordström
  2012-11-25 11:46 ` [U-Boot] [PATCH 20/22] ARM sunxi: SPL support for Rikomagic MK802II board Henrik Nordström
                   ` (3 subsequent siblings)
  21 siblings, 0 replies; 68+ messages in thread
From: Henrik Nordström @ 2012-11-25 11:46 UTC (permalink / raw)
  To: u-boot

From: Sergey Lapin <slapin@ossfans.org>
Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>
---
 board/sunxi/Makefile     |    1 +
 board/sunxi/dram_mk802.c |   24 ++++++++++++++++++++++++
 boards.cfg               |    1 +
 3 files changed, 26 insertions(+), 0 deletions(-)
 create mode 100644 board/sunxi/dram_mk802.c

diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile
index 091db59..b3a40f4 100644
--- a/board/sunxi/Makefile
+++ b/board/sunxi/Makefile
@@ -34,6 +34,7 @@ COBJS-$(CONFIG_HACKBERRY)	+= dram_hackberry.o
 COBJS-$(CONFIG_MELE_A1000)	+= dram_mele_a1000.o
 COBJS-$(CONFIG_MINI_X)		+= dram_mini_x.o
 COBJS-$(CONFIG_A7HD)		+= dram_hyundai_a7hd.o
+COBJS-$(CONFIG_MK802)		+= dram_mk802.o
 
 COBJS	:= $(COBJS-y)
 SRCS 	:= $(COBJS:.o=.c)
diff --git a/board/sunxi/dram_mk802.c b/board/sunxi/dram_mk802.c
new file mode 100644
index 0000000..a6779b0
--- /dev/null
+++ b/board/sunxi/dram_mk802.c
@@ -0,0 +1,24 @@
+/* this file is generated, don't edit it yourself */
+
+#include <common.h>
+#include <asm/arch/dram.h>
+
+static struct dram_para dram_para = {
+	.clock = 360,
+	.type = 3,
+	.rank_num = 1,
+	.density = 2048,
+	.io_width = 16,
+	.bus_width = 32,
+	.cas = 6,
+	.zq = 123,
+	.size = 512,
+	.tpr0 = 0x30926692,
+	.tpr1 = 0x1090,
+	.tpr2 = 0x1a0c8,
+};
+
+int sunxi_dram_init(void)
+{
+	return dramc_init(&dram_para);
+}
diff --git a/boards.cfg b/boards.cfg
index b8a5375..12fbcc9 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -300,6 +300,7 @@ sun4i                        arm         armv7       sunxi               -
 sun4i_sdcon                  arm         armv7       sunxi               -              sunxi       sun4i:UART0_PORT_F
 sun5i                        arm         armv7       sunxi               -              sunxi       sun5i
 sun5i_sdcon                  arm         armv7       sunxi               -              sunxi       sun5i:UART0_PORT_F
+mk802                        arm         armv7       sunxi               -              sunxi       sun4i:MK802,SPL
 kzm9g                        arm         armv7       kzm9g               kmc            rmobile
 armadillo-800eva             arm         armv7       armadillo-800eva    atmark-techno  rmobile
 zynq                         arm         armv7       zynq                xilinx         zynq
-- 
1.7.7.6

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 20/22] ARM sunxi: SPL support for Rikomagic MK802II board
       [not found] <cover.1353842684.git.henrik@henriknordstrom.net>
                   ` (17 preceding siblings ...)
  2012-11-25 11:46 ` [U-Boot] [PATCH 19/22] ARM sunxi: SPL support for MK802 board Henrik Nordström
@ 2012-11-25 11:46 ` Henrik Nordström
  2012-11-25 11:46 ` [U-Boot] [PATCH 21/22] ARM sunxi: SPL support for Mele A3700 board Henrik Nordström
                   ` (2 subsequent siblings)
  21 siblings, 0 replies; 68+ messages in thread
From: Henrik Nordström @ 2012-11-25 11:46 UTC (permalink / raw)
  To: u-boot

From: j <j@mailb.org>
Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>
---
 board/sunxi/Makefile       |    1 +
 board/sunxi/dram_mk802ii.c |   31 +++++++++++++++++++++++++++++++
 boards.cfg                 |    1 +
 3 files changed, 33 insertions(+), 0 deletions(-)
 create mode 100644 board/sunxi/dram_mk802ii.c

diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile
index b3a40f4..95826f2 100644
--- a/board/sunxi/Makefile
+++ b/board/sunxi/Makefile
@@ -35,6 +35,7 @@ COBJS-$(CONFIG_MELE_A1000)	+= dram_mele_a1000.o
 COBJS-$(CONFIG_MINI_X)		+= dram_mini_x.o
 COBJS-$(CONFIG_A7HD)		+= dram_hyundai_a7hd.o
 COBJS-$(CONFIG_MK802)		+= dram_mk802.o
+COBJS-$(CONFIG_MK802II)		+= dram_mk802ii.o
 
 COBJS	:= $(COBJS-y)
 SRCS 	:= $(COBJS:.o=.c)
diff --git a/board/sunxi/dram_mk802ii.c b/board/sunxi/dram_mk802ii.c
new file mode 100644
index 0000000..4fc1398
--- /dev/null
+++ b/board/sunxi/dram_mk802ii.c
@@ -0,0 +1,31 @@
+/* this file is generated, don't edit it yourself */
+
+#include <common.h>
+#include <asm/arch/dram.h>
+
+static struct dram_para dram_para = {
+	.clock = 408,
+	.type = 3,
+	.rank_num = 1,
+	.density = 4096,
+	.io_width = 16,
+	.bus_width = 32,
+	.cas = 6,
+	.zq = 123,
+	.odt_en = 0,
+	.size = 1024,
+	.tpr0 = 0x30926692,
+	.tpr1 = 0x1090,
+	.tpr2 = 0x1a0c8,
+	.tpr3 = 0,
+	.tpr4 = 0,
+	.tpr5 = 0,
+	.emr1 = 0x4,
+	.emr2 = 0,
+	.emr3 = 0,
+};
+
+int sunxi_dram_init(void)
+{
+	return dramc_init(&dram_para);
+}
diff --git a/boards.cfg b/boards.cfg
index 12fbcc9..14d6c67 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -301,6 +301,7 @@ sun4i_sdcon                  arm         armv7       sunxi               -
 sun5i                        arm         armv7       sunxi               -              sunxi       sun5i
 sun5i_sdcon                  arm         armv7       sunxi               -              sunxi       sun5i:UART0_PORT_F
 mk802                        arm         armv7       sunxi               -              sunxi       sun4i:MK802,SPL
+mk802ii                      arm         armv7       sunxi               -              sunxi       sun4i:MK802II,SPL
 kzm9g                        arm         armv7       kzm9g               kmc            rmobile
 armadillo-800eva             arm         armv7       armadillo-800eva    atmark-techno  rmobile
 zynq                         arm         armv7       zynq                xilinx         zynq
-- 
1.7.7.6

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 21/22] ARM sunxi: SPL support for Mele A3700 board
       [not found] <cover.1353842684.git.henrik@henriknordstrom.net>
                   ` (18 preceding siblings ...)
  2012-11-25 11:46 ` [U-Boot] [PATCH 20/22] ARM sunxi: SPL support for Rikomagic MK802II board Henrik Nordström
@ 2012-11-25 11:46 ` Henrik Nordström
  2012-11-25 11:46 ` [U-Boot] [PATCH 22/22] ARM sunxi: SPL support for Olinuxino A13 Micro Henrik Nordström
  2012-11-25 11:47 ` [U-Boot] [PATCH 04/22] ARM: sunxi: watchdog support Henrik Nordström
  21 siblings, 0 replies; 68+ messages in thread
From: Henrik Nordström @ 2012-11-25 11:46 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>
---
 board/sunxi/Makefile          |    1 +
 board/sunxi/dram_mele_a3700.c |   31 +++++++++++++++++++++++++++++++
 boards.cfg                    |    1 +
 3 files changed, 33 insertions(+), 0 deletions(-)
 create mode 100644 board/sunxi/dram_mele_a3700.c

diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile
index 95826f2..c7d7268 100644
--- a/board/sunxi/Makefile
+++ b/board/sunxi/Makefile
@@ -36,6 +36,7 @@ COBJS-$(CONFIG_MINI_X)		+= dram_mini_x.o
 COBJS-$(CONFIG_A7HD)		+= dram_hyundai_a7hd.o
 COBJS-$(CONFIG_MK802)		+= dram_mk802.o
 COBJS-$(CONFIG_MK802II)		+= dram_mk802ii.o
+COBJS-$(CONFIG_MELE_A3700)	+= dram_mele_a3700.o
 
 COBJS	:= $(COBJS-y)
 SRCS 	:= $(COBJS:.o=.c)
diff --git a/board/sunxi/dram_mele_a3700.c b/board/sunxi/dram_mele_a3700.c
new file mode 100644
index 0000000..56a9d64
--- /dev/null
+++ b/board/sunxi/dram_mele_a3700.c
@@ -0,0 +1,31 @@
+/* this file is generated, don't edit it yourself */
+
+#include <common.h>
+#include <asm/arch/dram.h>
+
+static struct dram_para dram_para = {
+	.clock = 360,
+	.type = 3,
+	.rank_num = 1,
+	.density = 2048,
+	.io_width = 8,
+	.bus_width = 32,
+	.cas = 6,
+	.zq = 123,
+	.odt_en = 0,
+	.size = 1024,
+	.tpr0 = 0x30926692,
+	.tpr1 = 0x1090,
+	.tpr2 = 0x1a0c8,
+	.tpr3 = 0,
+	.tpr4 = 0,
+	.tpr5 = 0,
+	.emr1 = 0,
+	.emr2 = 0,
+	.emr3 = 0,
+};
+
+int sunxi_dram_init(void)
+{
+	return dramc_init(&dram_para);
+}
diff --git a/boards.cfg b/boards.cfg
index 14d6c67..1704a9a 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -295,6 +295,7 @@ Cubieboard_512               arm         armv7       sunxi               -
 Hackberry                    arm         armv7       sunxi               -              sunxi       sun4i:HACKBERRY,SPL
 Hyundai_A7HD                 arm         armv7       sunxi               -              sunxi       sun4i:A7HD,SPL
 Mele_A1000                   arm         armv7       sunxi               -              sunxi       sun4i:MELE_A1000,SPL
+Mele_A3700                   arm         armv7       sunxi               -              sunxi       sun4i:MELE_A3700,SPL
 Mini-X                       arm         armv7       sunxi               -              sunxi       sun4i:MINI_X,SPL
 sun4i                        arm         armv7       sunxi               -              sunxi       sun4i
 sun4i_sdcon                  arm         armv7       sunxi               -              sunxi       sun4i:UART0_PORT_F
-- 
1.7.7.6

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 22/22] ARM sunxi: SPL support for Olinuxino A13 Micro
       [not found] <cover.1353842684.git.henrik@henriknordstrom.net>
                   ` (19 preceding siblings ...)
  2012-11-25 11:46 ` [U-Boot] [PATCH 21/22] ARM sunxi: SPL support for Mele A3700 board Henrik Nordström
@ 2012-11-25 11:46 ` Henrik Nordström
  2012-11-25 11:47 ` [U-Boot] [PATCH 04/22] ARM: sunxi: watchdog support Henrik Nordström
  21 siblings, 0 replies; 68+ messages in thread
From: Henrik Nordström @ 2012-11-25 11:46 UTC (permalink / raw)
  To: u-boot

From: hehopmajieh <gamishev@gmail.com>
Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>
---
 board/sunxi/Makefile             |    1 +
 board/sunxi/dram_a13_oli_micro.c |   32 ++++++++++++++++++++++++++++++++
 boards.cfg                       |    1 +
 include/configs/sunxi-common.h   |    2 ++
 4 files changed, 36 insertions(+), 0 deletions(-)
 create mode 100644 board/sunxi/dram_a13_oli_micro.c

diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile
index c7d7268..8f6b984 100644
--- a/board/sunxi/Makefile
+++ b/board/sunxi/Makefile
@@ -27,6 +27,7 @@ LIB	:= $(obj)lib$(BOARD).o
 
 COBJS-y	:= board.o
 COBJS-$(CONFIG_A13_OLINUXINO)	+= dram_a13_olinuxino.o
+COBJS-$(CONFIG_A13_OLINUXINOM)	+= dram_a13_oli_micro.o
 COBJS-$(CONFIG_A13_MID)		+= dram_a13_mid.o
 COBJS-$(CONFIG_CUBIEBOARD)	+= dram_cubieboard.o
 COBJS-$(CONFIG_CUBIEBOARD_512)	+= dram_cubieboard_512.o
diff --git a/board/sunxi/dram_a13_oli_micro.c b/board/sunxi/dram_a13_oli_micro.c
new file mode 100644
index 0000000..09653df
--- /dev/null
+++ b/board/sunxi/dram_a13_oli_micro.c
@@ -0,0 +1,32 @@
+/* this file is generated, don't edit it yourself */
+
+#include <common.h>
+#include <asm/arch/dram.h>
+
+static struct dram_para dram_para = {
+	.clock = 408,
+	.type = 3,
+	.rank_num = 1,
+	.density = 2048,
+	.io_width = 16,
+	.bus_width = 16,
+	.cas = 9,
+	.zq = 123,
+	.odt_en = 0,
+	.size = 256,
+	.tpr0 = 0x42d899b7,
+	.tpr1 = 0xa090,
+	.tpr2 = 0x22a00,
+	.tpr3 = 0,
+	.tpr4 = 0,
+	.tpr5 = 0,
+	.emr1 = 0,
+	.emr2 = 0x10,
+	.emr3 = 0,
+
+};
+
+int sunxi_dram_init(void)
+{
+	return dramc_init(&dram_para);
+}
diff --git a/boards.cfg b/boards.cfg
index 1704a9a..ae6d05e 100644
--- a/boards.cfg
+++ b/boards.cfg
@@ -289,6 +289,7 @@ colibri_t20_iris             arm         armv7:arm720t colibri_t20_iris  toradex
 u8500_href                   arm         armv7       u8500               st-ericsson    u8500
 snowball                     arm         armv7       snowball               st-ericsson    u8500
 A13-OLinuXino                arm         armv7       sunxi               -              sunxi       sun5i:A13_OLINUXINO,SPL
+A13-OLinuXinoM               arm         armv7       sunxi               -              sunxi       sun5i:A13_OLINUXINOM,SPL,NO_AXP
 A13_MID                      arm         armv7       sunxi               -              sunxi       sun5i:A13_MID,SPL
 Cubieboard                   arm         armv7       sunxi               -              sunxi       sun4i:CUBIEBOARD,SPL
 Cubieboard_512               arm         armv7       sunxi               -              sunxi       sun4i:CUBIEBOARD_512,SPL
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index b0dcfdb..c2976f0 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -236,6 +236,8 @@
 
 /* PMU */
 #define CONFIG_SPL_POWER_SUPPORT
+#ifndef CONFIG_NO_AXP
 #define CONFIG_AXP209_POWER
+#endif
 
 #endif /* __CONFIG_H */
-- 
1.7.7.6

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 04/22] ARM: sunxi: watchdog support
       [not found] <cover.1353842684.git.henrik@henriknordstrom.net>
                   ` (20 preceding siblings ...)
  2012-11-25 11:46 ` [U-Boot] [PATCH 22/22] ARM sunxi: SPL support for Olinuxino A13 Micro Henrik Nordström
@ 2012-11-25 11:47 ` Henrik Nordström
  2013-02-02 23:55   ` Albert ARIBAUD
  21 siblings, 1 reply; 68+ messages in thread
From: Henrik Nordström @ 2012-11-25 11:47 UTC (permalink / raw)
  To: u-boot

This adds support for the hardware watchdog in Allwinner
sun4i & sun5i (sunxi) SoC familiy.

From: Henrik Nordstrom <henrik@henriknordstrom.net>

Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>
Signed-off-by: Stefan Roese <sr@denx.de>
---
 arch/arm/cpu/armv7/sunxi/board.c            |    3 ++
 arch/arm/include/asm/arch-sunxi/sys_proto.h |    1 -
 drivers/watchdog/Makefile                   |    1 +
 drivers/watchdog/sunxi_watchdog.c           |   49 +++++++++++++++++++++++++++
 include/configs/sunxi-common.h              |    4 ++
 5 files changed, 57 insertions(+), 1 deletions(-)
 create mode 100644 drivers/watchdog/sunxi_watchdog.c

diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c
index 652c19d..5c94110 100644
--- a/arch/arm/cpu/armv7/sunxi/board.c
+++ b/arch/arm/cpu/armv7/sunxi/board.c
@@ -59,6 +59,9 @@ int gpio_init(void)
 /* do some early init */
 void s_init(void)
 {
+#if defined(CONFIG_WATCHDOG) && defined(CONFIG_SUNXI_WATCHDOG)
+	watchdog_set(23);	/* max possible timeout */
+#endif
 	clock_init();
 	gpio_init();
 }
diff --git a/arch/arm/include/asm/arch-sunxi/sys_proto.h b/arch/arm/include/asm/arch-sunxi/sys_proto.h
index 1e8ae5d..9729100 100644
--- a/arch/arm/include/asm/arch-sunxi/sys_proto.h
+++ b/arch/arm/include/asm/arch-sunxi/sys_proto.h
@@ -27,6 +27,5 @@
 
 void sr32(u32 *, u32, u32, u32);
 void sdelay(unsigned long);
-void watchdog_init(void);
 
 #endif
diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
index 923acb9..50b5fae 100644
--- a/drivers/watchdog/Makefile
+++ b/drivers/watchdog/Makefile
@@ -28,6 +28,7 @@ LIB	:= $(obj)libwatchdog.o
 COBJS-$(CONFIG_AT91SAM9_WATCHDOG) += at91sam9_wdt.o
 COBJS-$(CONFIG_FTWDT010_WATCHDOG) += ftwdt010_wdt.o
 COBJS-$(CONFIG_TNETV107X_WATCHDOG) += tnetv107x_wdt.o
+COBJS-$(CONFIG_SUNXI_WATCHDOG)    += sunxi_watchdog.o
 
 COBJS	:= $(COBJS-y)
 SRCS	:= $(COBJS:.o=.c)
diff --git a/drivers/watchdog/sunxi_watchdog.c b/drivers/watchdog/sunxi_watchdog.c
new file mode 100644
index 0000000..65a763d
--- /dev/null
+++ b/drivers/watchdog/sunxi_watchdog.c
@@ -0,0 +1,49 @@
+/*
+ * (C) Copyright 2012 Henrik Nordstrom <henrik@hno.se>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <asm/arch/timer.h>
+#include <asm/armv7.h>
+#include <asm/io.h>
+
+void watchdog_reset(void)
+{
+	static struct sunxi_wdog *const wdog =
+		&((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->wdog;
+
+	/* a little magic to reload the watchdog */
+	writel(0xA57 << 1 | 1 << 0, &wdog->ctl);
+}
+
+static void watchdog_set(int interval)
+{
+	static struct sunxi_wdog *const wdog =
+		&((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->wdog;
+
+	/* Set timeout, reset & enable */
+	writel(interval << 2 | 1 << 1 | 1 << 0, &wdog->mode);
+	watchdog_reset();
+}
+
+void watchdog_init(void)
+{
+#ifdef CONFIG_WATCHDOG
+	watchdog_set(23);	/* max possible timeout */
+#endif
+}
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index c2d16fb..5bf8eea 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -202,4 +202,8 @@
 #define CONFIG_SYS_I2C_SLAVE		0x7f
 #define CONFIG_CMD_I2C
 
+/* Watchdog */
+/* #define CONFIG_WATCHDOG */
+/* #define CONFIG_SUNXI_WATCHDOG */
+
 #endif /* __CONFIG_H */
-- 
1.7.7.6

^ permalink raw reply related	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 01/22] ARM: sunxi: Basic Allwinner A10/A13 (sun4i/sun5i) support
  2012-11-25 11:37 ` [U-Boot] [PATCH 01/22] ARM: sunxi: Basic Allwinner A10/A13 (sun4i/sun5i) support Henrik Nordström
@ 2012-11-25 12:23   ` Luka Perkov
  2012-11-25 13:08     ` Henrik Nordström
  2012-11-25 19:52     ` [U-Boot] [PATCH 01/22] ARM: sunxi: Basic Allwinner A10/A13 (sun4i/sun5i) support Wolfgang Denk
  2012-11-25 18:06   ` Marek Vasut
                     ` (2 subsequent siblings)
  3 siblings, 2 replies; 68+ messages in thread
From: Luka Perkov @ 2012-11-25 12:23 UTC (permalink / raw)
  To: u-boot

Hi Henrik,

I have few comments bellow.

On Sun, Nov 25, 2012 at 12:37:30PM +0100, Henrik Nordstr?m wrote:
> This adds support for the Allwinner A10/A13 SoC's. Additionally
> board support for the dev-boards sun4i/sun5i is added.
> 
> Signed-off-by: Tom Cubie <tangliang@allwinnertech.com>
> Signed-off-by: Henrik Nordstr?m <henrik@henriknordstrom.net>
> Signed-off-by: Stefan Roese <sr@denx.de>
> ---
>  MAINTAINERS                                 |   13 ++
>  arch/arm/cpu/armv7/Makefile                 |    2 +-
>  arch/arm/cpu/armv7/sunxi/Makefile           |   51 +++++++
>  arch/arm/cpu/armv7/sunxi/board.c            |   77 +++++++++++
>  arch/arm/cpu/armv7/sunxi/clock.c            |   57 ++++++++
>  arch/arm/cpu/armv7/sunxi/pinmux.c           |   61 +++++++++
>  arch/arm/cpu/armv7/sunxi/reset.S            |   39 ++++++
>  arch/arm/cpu/armv7/sunxi/timer.c            |  117 +++++++++++++++++
>  arch/arm/include/asm/arch-sunxi/clock.h     |  179 +++++++++++++++++++++++++
>  arch/arm/include/asm/arch-sunxi/cpu.h       |  146 +++++++++++++++++++++
>  arch/arm/include/asm/arch-sunxi/dram.h      |  114 ++++++++++++++++
>  arch/arm/include/asm/arch-sunxi/gpio.h      |  164 +++++++++++++++++++++++
>  arch/arm/include/asm/arch-sunxi/sys_proto.h |   32 +++++
>  arch/arm/include/asm/arch-sunxi/timer.h     |  102 ++++++++++++++
>  board/sunxi/Makefile                        |   46 +++++++
>  board/sunxi/board.c                         |   57 ++++++++
>  boards.cfg                                  |    4 +
>  include/configs/sun4i.h                     |   47 +++++++
>  include/configs/sun5i.h                     |   56 ++++++++
>  include/configs/sunxi-common.h              |  189 +++++++++++++++++++++++++++
>  20 files changed, 1552 insertions(+), 1 deletions(-)
>  create mode 100644 arch/arm/cpu/armv7/sunxi/Makefile
>  create mode 100644 arch/arm/cpu/armv7/sunxi/board.c
>  create mode 100644 arch/arm/cpu/armv7/sunxi/clock.c
>  create mode 100644 arch/arm/cpu/armv7/sunxi/pinmux.c
>  create mode 100644 arch/arm/cpu/armv7/sunxi/reset.S
>  create mode 100644 arch/arm/cpu/armv7/sunxi/timer.c
>  create mode 100644 arch/arm/include/asm/arch-sunxi/clock.h
>  create mode 100644 arch/arm/include/asm/arch-sunxi/cpu.h
>  create mode 100644 arch/arm/include/asm/arch-sunxi/dram.h
>  create mode 100644 arch/arm/include/asm/arch-sunxi/gpio.h
>  create mode 100644 arch/arm/include/asm/arch-sunxi/sys_proto.h
>  create mode 100644 arch/arm/include/asm/arch-sunxi/timer.h
>  create mode 100644 board/sunxi/Makefile
>  create mode 100644 board/sunxi/board.c
>  create mode 100644 include/configs/sun4i.h
>  create mode 100644 include/configs/sun5i.h
>  create mode 100644 include/configs/sunxi-common.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index c430574..80c1bd7 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -331,6 +331,19 @@ Reinhard Meyer <reinhard.meyer@emk-elektronik.de>
>  	TOP5200		MPC5200
>  	TOP9000		ARM926EJS (AT91SAM9xxx SoC)
>  
> +Henrik Nordstrom <henrik@henriknordstrom.net>
> +	A13_OLINUXINO	ARM V7 (Allwinner A13 SoC)
> +	A13_MID		ARM V7 (Allwinner A13 SoC)
> +	CUBIEBOARD	ARM V7 (Allwinner A10 SoC)
> +	CUBIEBOARD_512	ARM V7 (Allwinner A10 SoC)
> +	HACKBERRY	ARM V7 (Allwinner A10 SoC)
> +	MELE_A1000	ARM V7 (Allwinner A10 SoC)
> +	MINI-X		ARM V7 (Allwinner A10 SoC)
> +	SUN4I		ARM V7 (Allwinner A10 SoC)
> +	SUN4I_SDCON	ARM V7 (Allwinner A10 SoC)
> +	SUN5I		ARM V7 (Allwinner A13 SoC)
> +	SUN5I_SDCON	ARM V7 (Allwinner A13 SoC)
> +
>  Kyle Moffett <Kyle.D.Moffett@boeing.com>
>  
>  	HWW1U1A		P2020
> diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile
> index da1b5e8..56f51b5 100644
> --- a/arch/arm/cpu/armv7/Makefile
> +++ b/arch/arm/cpu/armv7/Makefile
> @@ -33,7 +33,7 @@ COBJS	+= cpu.o
>  COBJS	+= syslib.o
>  COBJS	+= cmd_boot.o
>  
> -ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA20),)
> +ifneq ($(CONFIG_AM33XX)$(CONFIG_OMAP44XX)$(CONFIG_OMAP54XX)$(CONFIG_TEGRA20)$(CONFIG_SUNXI),)
>  SOBJS	+= lowlevel_init.o
>  endif
>  
> diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile
> new file mode 100644
> index 0000000..cbe1015
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/sunxi/Makefile
> @@ -0,0 +1,51 @@
> +#
> +# (C) Copyright 2000-2003

I don't know about the dates. It's 2012 now... Same goes for all other files.

> +# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
> +#
> +# See file CREDITS for list of people who contributed to this
> +# project.
> +#
> +# This program is free software; you can redistribute it and/or
> +# modify it under the terms of the GNU General Public License as
> +# published by the Free Software Foundation; either version 2 of
> +# the License, or (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program; if not, write to the Free Software
> +# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> +# MA 02111-1307 USA
> +#
> +
> +include $(TOPDIR)/config.mk
> +
> +LIB	=  $(obj)lib$(SOC).o
> +
> +SOBJS	+= reset.o
> +
> +COBJS	+= timer.o
> +COBJS	+= dram.o
> +COBJS	+= board.o
> +COBJS	+= clock.o
> +COBJS	+= pinmux.o
> +
> +SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
> +OBJS	:= $(addprefix $(obj),$(COBJS) $(COBJS-y) $(SOBJS))
> +
> +all:	 $(obj).depend $(LIB)
> +
> +$(LIB):	$(OBJS)
> +	$(call cmd_link_o_target, $(OBJS))
> +
> +#########################################################################
> +
> +# defines $(obj).depend target
> +include $(SRCTREE)/rules.mk
> +
> +sinclude $(obj).depend
> +
> +#########################################################################
> diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c
> new file mode 100644
> index 0000000..652c19d
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/sunxi/board.c
> @@ -0,0 +1,77 @@
> +/*
> + * (C) Copyright 2007-2011
> + * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
> + * Tom Cubie <tangliang@allwinnertech.com>
> + *
> + * Some init for sunxi platform.
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include <common.h>
> +#include <asm/io.h>
> +#include <serial.h>
> +#include <asm/gpio.h>
> +#include <asm/arch/clock.h>
> +#include <asm/arch/timer.h>
> +#include <asm/arch/gpio.h>
> +#include <asm/arch/sys_proto.h>
> +
> +int gpio_init(void)
> +{
> +#if CONFIG_CONS_INDEX == 1 && defined(CONFIG_UART0_PORT_F)
> +#ifdef CONFIG_SUN4I
> +	/* disable GPB22,23 as uart0 tx,rx to avoid conflict */
> +	gpio_direction_input(SUNXI_GPB(22));
> +	gpio_direction_input(SUNXI_GPB(23));
> +#endif
> +	sunxi_gpio_set_cfgpin(SUNXI_GPF(2), SUNXI_GPF2_UART0_TX);
> +	sunxi_gpio_set_cfgpin(SUNXI_GPF(4), SUNXI_GPF4_UART0_RX);
> +#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_SUN4I)
> +	sunxi_gpio_set_cfgpin(SUNXI_GPB(22), SUN4I_GPB22_UART0_TX);
> +	sunxi_gpio_set_cfgpin(SUNXI_GPB(23), SUN4I_GPB23_UART0_RX);
> +#elif CONFIG_CONS_INDEX == 2 && defined(CONFIG_SUN5I)
> +	sunxi_gpio_set_cfgpin(SUNXI_GPG(3), SUN5I_GPG3_UART0_TX);
> +	sunxi_gpio_set_cfgpin(SUNXI_GPG(4), SUN5I_GPG4_UART0_RX);
> +#else
> +#error Unsupported console port number. Please fix pin mux settings in board.c
> +#endif
> +
> +	return 0;
> +}
> +
> +/* do some early init */
> +void s_init(void)
> +{
> +	clock_init();
> +	gpio_init();
> +}
> +
> +void reset_cpu(ulong addr)
> +{
> +	sunxi_reset();
> +}
> +
> +#ifndef CONFIG_SYS_DCACHE_OFF
> +void enable_caches(void)
> +{
> +	/* Enable D-cache. I-cache is already enabled in start.S */
> +	dcache_enable();
> +}
> +#endif
> diff --git a/arch/arm/cpu/armv7/sunxi/clock.c b/arch/arm/cpu/armv7/sunxi/clock.c
> new file mode 100644
> index 0000000..424acfc
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/sunxi/clock.c
> @@ -0,0 +1,57 @@
> +/*
> + * (C) Copyright 2007-2012
> + * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
> + * Tom Cubie <tangliang@allwinnertech.com>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +#include <common.h>
> +#include <asm/io.h>
> +#include <asm/arch/clock.h>
> +#include <asm/arch/sys_proto.h>
> +
> +int clock_init(void)
> +{
> +	struct sunxi_ccm_reg *const ccm =
> +		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
> +
> +	/* uart clock source is apb1 */
> +	sr32(&ccm->apb1_clk_div_cfg, 24, 2, APB1_CLK_SRC_OSC24M);
> +	sr32(&ccm->apb1_clk_div_cfg, 16, 2, APB1_FACTOR_N);
> +	sr32(&ccm->apb1_clk_div_cfg, 0, 5, APB1_FACTOR_M);
> +
> +	/* open the clock for uart */
> +	sr32(&ccm->apb1_gate, 16 + CONFIG_CONS_INDEX - 1, 1, CLK_GATE_OPEN);
> +
> +	return 0;
> +}
> +
> +/* Return PLL5 frequency in Hz
> + * Note: Assumes PLL5 reference is 24MHz clock
> + */
> +unsigned int clock_get_pll5(void)
> +{
> +	struct sunxi_ccm_reg *const ccm =
> +		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
> +	uint32_t rval = readl(&ccm->pll5_cfg);
> +	int n = (rval >> 8) & 0x1f;
> +	int k = ((rval >> 4) & 3) + 1;
> +	int p = 1 << ((rval >> 16) & 3);
> +	return 24000000 * n * k / p;
> +}
> diff --git a/arch/arm/cpu/armv7/sunxi/pinmux.c b/arch/arm/cpu/armv7/sunxi/pinmux.c
> new file mode 100644
> index 0000000..77e1d90
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/sunxi/pinmux.c
> @@ -0,0 +1,61 @@
> +/*
> + * (C) Copyright 2007-2011
> + * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
> + * Tom Cubie <tangliang@allwinnertech.com>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include <common.h>
> +#include <asm/io.h>
> +#include <asm/arch/gpio.h>
> +
> +int sunxi_gpio_set_cfgpin(u32 pin, u32 val)
> +{
> +	u32 cfg;
> +	u32 bank = GPIO_BANK(pin);
> +	u32 index = GPIO_CFG_INDEX(pin);
> +	u32 offset = GPIO_CFG_OFFSET(pin);
> +	struct sunxi_gpio *pio =
> +	    &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank];
> +
> +	cfg = readl(&pio->cfg[0] + index);
> +	cfg &= ~(0xf << offset);
> +	cfg |= val << offset;
> +
> +	writel(cfg, &pio->cfg[0] + index);
> +
> +	return 0;
> +}
> +
> +int sunxi_gpio_get_cfgpin(u32 pin)
> +{
> +	u32 cfg;
> +	u32 bank = GPIO_BANK(pin);
> +	u32 index = GPIO_CFG_INDEX(pin);
> +	u32 offset = GPIO_CFG_OFFSET(pin);
> +	struct sunxi_gpio *pio =
> +	    &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank];
> +
> +	cfg = readl(&pio->cfg[0] + index);
> +	cfg >>= offset;
> +
> +	return cfg & 0xf;
> +}
> +
> diff --git a/arch/arm/cpu/armv7/sunxi/reset.S b/arch/arm/cpu/armv7/sunxi/reset.S
> new file mode 100644
> index 0000000..36714e7
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/sunxi/reset.S
> @@ -0,0 +1,39 @@
> +/*
> + * (C) Copyright 2007-2011
> + * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
> + * Tom Cubie <tangliang@allwinnertech.com>
> + *
> + * Configuration settings for the Allwinner A10-evb board.
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include <asm/arch/cpu.h>
> +
> +#define SUNXI_WDOG_CTL		0x01C20C90
> +#define SUNXI_WDOG_MODE		0x01C20C94
> +
> +.globl sunxi_reset
> +sunxi_reset:
> +	ldr r1, =SUNXI_WDOG_MODE
> +	mov r3, #0x3
> +	str r3, [r1]
> +	mov r0, r0
> +_loop_forever:
> +	b	_loop_forever
> diff --git a/arch/arm/cpu/armv7/sunxi/timer.c b/arch/arm/cpu/armv7/sunxi/timer.c
> new file mode 100644
> index 0000000..e19df09
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/sunxi/timer.c
> @@ -0,0 +1,117 @@
> +/*
> + * (C) Copyright 2007-2011
> + * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
> + * Tom Cubie <tangliang@allwinnertech.com>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include <common.h>
> +#include <asm/io.h>
> +#include <asm/arch/timer.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +#define TIMER_MODE   (0 << 7)	/* continuous mode */
> +#define TIMER_DIV    (0 << 4)	/* pre scale 1 */
> +#define TIMER_SRC    (1 << 2)	/* osc24m */
> +#define TIMER_RELOAD (1 << 1)	/* reload internal value */
> +#define TIMER_EN     (1 << 0)	/* enable timer */
> +
> +#define TIMER_CLOCK		(24 * 1000 * 1000)
> +#define COUNT_TO_USEC(x)	((x) / 24)
> +#define USEC_TO_COUNT(x)	((x) * 24)
> +#define TICKS_PER_HZ		(TIMER_CLOCK / CONFIG_SYS_HZ)
> +#define TICKS_TO_HZ(x)		((x) / TICKS_PER_HZ)
> +
> +#define TIMER_LOAD_VAL		0xffffffff
> +
> +#define TIMER_NUM		0	/* we use timer 0 */
> +
> +static struct sunxi_timer *timer_base =
> +	&((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->timer[TIMER_NUM];
> +
> +/* macro to read the 32 bit timer: since it decrements, we invert read value */
> +#define READ_TIMER() (~readl(&timer_base->val))
> +
> +/* init timer register */
> +int timer_init(void)
> +{
> +	writel(TIMER_LOAD_VAL, &timer_base->inter);
> +	writel(TIMER_MODE | TIMER_DIV | TIMER_SRC | TIMER_RELOAD | TIMER_EN,
> +	       &timer_base->ctl);
> +
> +	return 0;
> +}
> +
> +/* timer without interrupts */
> +ulong get_timer(ulong base)
> +{
> +	return get_timer_masked() - base;
> +}
> +
> +ulong get_timer_masked(void)
> +{
> +	/* current tick value */
> +	ulong now = TICKS_TO_HZ(READ_TIMER());
> +
> +	if (now >= gd->lastinc)	/* normal (non rollover) */
> +		gd->tbl += (now - gd->lastinc);
> +	else			/* rollover */
> +		gd->tbl += (TICKS_TO_HZ(TIMER_LOAD_VAL) - gd->lastinc) + now;
> +	gd->lastinc = now;
> +
> +	return gd->tbl;
> +}
> +
> +/* delay x useconds */
> +void __udelay(unsigned long usec)
> +{
> +	long tmo = usec * (TIMER_CLOCK / 1000) / 1000;
> +	ulong now, last = READ_TIMER();
> +
> +	while (tmo > 0) {
> +		now = READ_TIMER();
> +		if (now > last)	/* normal (non rollover) */
> +			tmo -= now - last;
> +		else		/* rollover */
> +			tmo -= TIMER_LOAD_VAL - last + now;
> +		last = now;
> +	}
> +}
> +
> +/*
> + * This function is derived from PowerPC code (read timebase as long long).
> + * On ARM it just returns the timer value.
> + */
> +unsigned long long get_ticks(void)
> +{
> +	return get_timer(0);
> +}
> +
> +/*
> + * This function is derived from PowerPC code (timebase clock frequency).
> + * On ARM it returns the number of timer ticks per second.
> + */
> +ulong get_tbclk(void)
> +{
> +	ulong tbclk;
> +	tbclk = CONFIG_SYS_HZ;
> +	return tbclk;
> +}
> diff --git a/arch/arm/include/asm/arch-sunxi/clock.h b/arch/arm/include/asm/arch-sunxi/clock.h
> new file mode 100644
> index 0000000..863e59e
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-sunxi/clock.h
> @@ -0,0 +1,179 @@
> +/*
> + * (C) Copyright 2007-2011
> + * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
> + * Tom Cubie <tangliang@allwinnertech.com>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#ifndef _SUNXI_CLOCK_H
> +#define _SUNXI_CLOCK_H
> +
> +/* clock control module regs definition */
> +
> +struct sunxi_ccm_reg {
> +	u32 pll1_cfg;		/* 0x00 pll1 control */
> +	u32 pll1_tun;		/* 0x04 pll1 tuning */
> +	u32 pll2_cfg;		/* 0x08 pll2 control */
> +	u32 pll2_tun;		/* 0x0c pll2 tuning */
> +	u32 pll3_cfg;		/* 0x10 pll3 control */
> +	u8 res0[0x4];
> +	u32 pll4_cfg;		/* 0x18 pll4 control */
> +	u8 res1[0x4];
> +	u32 pll5_cfg;		/* 0x20 pll5 control */
> +	u32 pll5_tun;		/* 0x24 pll5 tuning */
> +	u32 pll6_cfg;		/* 0x28 pll6 control */
> +	u32 pll6_tun;		/* 0x2c pll6 tuning */
> +	u32 pll7_cfg;		/* 0x30 pll7 control */
> +	u32 pll1_tun2;		/* 0x34 pll5 tuning2 */
> +	u8 res2[0x4];
> +	u32 pll5_tun2;		/* 0x3c pll5 tuning2 */
> +	u8 res3[0xc];
> +	u32 pll_lock_dbg;	/* 0x4c pll lock time debug */
> +	u32 osc24m_cfg;		/* 0x50 osc24m control */
> +	u32 cpu_ahb_apb0_cfg;	/* 0x54 cpu,ahb and apb0 divide ratio */
> +	u32 apb1_clk_div_cfg;	/* 0x58 apb1 clock dividor */
> +	u32 axi_gate;		/* 0x5c axi module clock gating */
> +	u32 ahb_gate0;		/* 0x60 ahb module clock gating 0 */
> +	u32 ahb_gate1;		/* 0x64 ahb module clock gating 1 */
> +	u32 apb0_gate;		/* 0x68 apb0 module clock gating */
> +	u32 apb1_gate;		/* 0x6c apb1 module clock gating */
> +	u8 res4[0x10];
> +	u32 nand_sclk_cfg;	/* 0x80 nand sub clock control */
> +	u32 ms_sclk_cfg;	/* 0x84 memory stick sub clock control */
> +	u32 sd0_clk_cfg;	/* 0x88 sd0 clock control */
> +	u32 sd1_clk_cfg;	/* 0x8c sd1 clock control */
> +	u32 sd2_clk_cfg;	/* 0x90 sd2 clock control */
> +	u32 sd3_clk_cfg;	/* 0x94 sd3 clock control */
> +	u32 ts_clk_cfg;		/* 0x98 transport stream clock control */
> +	u32 ss_clk_cfg;		/* 0x9c */
> +	u32 spi0_clk_cfg;	/* 0xa0 */
> +	u32 spi1_clk_cfg;	/* 0xa4 */
> +	u32 spi2_clk_cfg;	/* 0xa8 */
> +	u32 pata_clk_cfg;	/* 0xac */
> +	u32 ir0_clk_cfg;	/* 0xb0 */
> +	u32 ir1_clk_cfg;	/* 0xb4 */
> +	u32 iis_clk_cfg;	/* 0xb8 */
> +	u32 ac97_clk_cfg;	/* 0xbc */
> +	u32 spdif_clk_cfg;	/* 0xc0 */
> +	u32 keypad_clk_cfg;	/* 0xc4 */
> +	u32 sata_clk_cfg;	/* 0xc8 */
> +	u32 usb_clk_cfg;	/* 0xcc */
> +	u32 gps_clk_cfg;	/* 0xd0 */
> +	u32 spi3_clk_cfg;	/* 0xd4 */
> +	u8 res5[0x28];
> +	u32 dram_clk_cfg;	/* 0x100 */
> +	u32 be0_clk_cfg;	/* 0x104 */
> +	u32 be1_clk_cfg;	/* 0x108 */
> +	u32 fe0_clk_cfg;	/* 0x10c */
> +	u32 fe1_clk_cfg;	/* 0x110 */
> +	u32 mp_clk_cfg;		/* 0x114 */
> +	u32 lcd0_ch0_clk_cfg;	/* 0x118 */
> +	u32 lcd1_ch0_clk_cfg;	/* 0x11c */
> +	u32 csi_isp_clk_cfg;	/* 0x120 */
> +	u8 res6[0x4];
> +	u32 tvd_clk_reg;	/* 0x128 */
> +	u32 lcd0_ch1_clk_cfg;	/* 0x12c */
> +	u32 lcd1_ch1_clk_cfg;	/* 0x130 */
> +	u32 csi0_clk_cfg;	/* 0x134 */
> +	u32 csi1_clk_cfg;	/* 0x138 */
> +	u32 ve_clk_cfg;		/* 0x13c */
> +	u32 audio_codec_clk_cfg;	/* 0x140 */
> +	u32 avs_clk_cfg;	/* 0x144 */
> +	u32 ace_clk_cfg;	/* 0x148 */
> +	u32 lvds_clk_cfg;	/* 0x14c */
> +	u32 hdmi_clk_cfg;	/* 0x150 */
> +	u32 mali_clk_cfg;	/* 0x154 */
> +	u8 res7[0x4];
> +	u32 mbus_clk_cfg;	/* 0x15c */
> +};
> +
> +/* apb1 bit field */
> +#define APB1_CLK_SRC_OSC24M		0
> +#define APB1_FACTOR_M			0
> +#define APB1_FACTOR_N			0
> +
> +/* clock divide */
> +#define CPU_CLK_SRC_OSC24M		1
> +#define CPU_CLK_SRC_PLL1		2
> +#define AXI_DIV_1			0
> +#define AXI_DIV_2			1
> +#define AXI_DIV_3			2
> +#define AXI_DIV_4			3
> +#define AHB_DIV_1			0
> +#define AHB_DIV_2			1
> +#define AHB_DIV_4			2
> +#define AHB_DIV_8			3
> +#define APB0_DIV_1			0
> +#define APB0_DIV_2			1
> +#define APB0_DIV_4			2
> +#define APB0_DIV_8			3
> +
> +#ifdef CONFIG_SUN5I
> +#define AHB_CLK_SRC_AXI			0
> +#endif
> +
> +#define CLK_GATE_OPEN			0x1
> +#define CLK_GATE_CLOSE			0x0
> +
> +/* nand clock */
> +#define NAND_CLK_SRC_OSC24		0
> +#define NAND_CLK_DIV_N			0
> +#define NAND_CLK_DIV_M			0
> +
> +/* gps clock */
> +#define GPS_SCLK_GATING_OFF		0
> +#define GPS_RESET			0
> +
> +/* ahb clock gate bit offset */
> +#define AHB_GATE_OFFSET_GPS		26
> +#define AHB_GATE_OFFSET_SATA		25
> +#define AHB_GATE_OFFSET_PATA		24
> +#define AHB_GATE_OFFSET_SPI3		23
> +#define AHB_GATE_OFFSET_SPI2		22
> +#define AHB_GATE_OFFSET_SPI1		21
> +#define AHB_GATE_OFFSET_SPI0		20
> +#define AHB_GATE_OFFSET_TS0		18
> +#define AHB_GATE_OFFSET_EMAC		17
> +#define AHB_GATE_OFFSET_ACE		16
> +#define AHB_GATE_OFFSET_DLL		15
> +#define AHB_GATE_OFFSET_SDRAM		14
> +#define AHB_GATE_OFFSET_NAND		13
> +#define AHB_GATE_OFFSET_MS		12
> +#define AHB_GATE_OFFSET_MMC3		11
> +#define AHB_GATE_OFFSET_MMC2		10
> +#define AHB_GATE_OFFSET_MMC1		9
> +#define AHB_GATE_OFFSET_MMC0		8
> +#define AHB_GATE_OFFSET_BIST		7
> +#define AHB_GATE_OFFSET_DMA		6
> +#define AHB_GATE_OFFSET_SS		5
> +#define AHB_GATE_OFFSET_USB_OHCI1	4
> +#define AHB_GATE_OFFSET_USB_EHCI1	3
> +#define AHB_GATE_OFFSET_USB_OHCI0	2
> +#define AHB_GATE_OFFSET_USB_EHCI0	1
> +#define AHB_GATE_OFFSET_USB		0
> +
> +#ifndef __ASSEMBLY__
> +int clock_init(void);
> +int clock_twi_onoff(int port, int state);
> +void clock_set_pll1(int mhz);
> +unsigned int clock_get_pll5(void);
> +#endif
> +
> +#endif /* _SUNXI_CLOCK_H */
> diff --git a/arch/arm/include/asm/arch-sunxi/cpu.h b/arch/arm/include/asm/arch-sunxi/cpu.h
> new file mode 100644
> index 0000000..6c8eaeb
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-sunxi/cpu.h
> @@ -0,0 +1,146 @@
> +/*
> + * (C) Copyright 2007-2011
> + * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
> + * Tom Cubie <tangliang@allwinnertech.com>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#ifndef _SUNXI_CPU_H
> +#define _SUNXI_CPU_H
> +
> +#define SUNXI_SRAM_A1_BASE		0x00000000
> +#define SUNXI_SRAM_A1_SIZE		(16 * 1024)	/* 16k */
> +
> +#define SUNXI_SRAM_A2_BASE		0x00004000	/* 16k */
> +#define SUNXI_SRAM_A3_BASE		0x00008000	/* 13k */
> +#define SUNXI_SRAM_A4_BASE		0x0000B400	/* 3k */
> +#define SUNXI_SRAM_D_BASE		0x01C00000
> +#define SUNXI_SRAM_B_BASE		0x01C00000	/* 64k(secure) */
> +
> +#define SUNXI_SRAMC_BASE		0x01C00000
> +#define SUNXI_DRAMC_BASE		0x01C01000
> +#define SUNXI_DMA_BASE			0x01C02000
> +#define SUNXI_NFC_BASE			0x01C03000
> +#define SUNXI_TS_BASE			0x01C04000
> +#define SUNXI_SPI0_BASE			0x01C05000
> +#define SUNXI_SPI1_BASE			0x01C06000
> +#define SUNXI_MS_BASE			0x01C07000
> +#define SUNXI_TVD_BASE			0x01C08000
> +#define SUNXI_CSI0_BASE			0x01C09000
> +#define SUNXI_TVE0_BASE			0x01C0A000
> +#define SUNXI_EMAC_BASE			0x01C0B000
> +#define SUNXI_LCD0_BASE			0x01C0C000
> +#define SUNXI_LCD1_BASE			0x01C0D000
> +#define SUNXI_VE_BASE			0x01C0E000
> +#define SUNXI_MMC0_BASE			0x01C0F000
> +#define SUNXI_MMC1_BASE			0x01C10000
> +#define SUNXI_MMC2_BASE			0x01C11000
> +#define SUNXI_MMC3_BASE			0x01C12000
> +#define SUNXI_USB0_BASE			0x01C13000
> +#define SUNXI_USB1_BASE			0x01C14000
> +#define SUNXI_SS_BASE			0x01C15000
> +#define SUNXI_HDMI_BASE			0x01C16000
> +#define SUNXI_SPI2_BASE			0x01C17000
> +#define SUNXI_SATA_BASE			0x01C18000
> +#define SUNXI_PATA_BASE			0x01C19000
> +#define SUNXI_ACE_BASE			0x01C1A000
> +#define SUNXI_TVE1_BASE			0x01C1B000
> +#define SUNXI_USB2_BASE			0x01C1C000
> +#define SUNXI_CSI1_BASE			0x01C1D000
> +#define SUNXI_TZASC_BASE		0x01C1E000
> +#define SUNXI_SPI3_BASE			0x01C1F000
> +
> +#define SUNXI_CCM_BASE			0x01C20000
> +#define SUNXI_INTC_BASE			0x01C20400
> +#define SUNXI_PIO_BASE			0x01C20800
> +#define SUNXI_TIMER_BASE		0x01C20C00
> +#define SUNXI_SPDIF_BASE		0x01C21000
> +#define SUNXI_AC97_BASE			0x01C21400
> +#define SUNXI_IR0_BASE			0x01C21800
> +#define SUNXI_IR1_BASE			0x01C21C00
> +
> +#define SUNXI_IIS_BASE			0x01C22400
> +#define SUNXI_LRADC_BASE		0x01C22800
> +#define SUNXI_AD_DA_BASE		0x01C22C00
> +#define SUNXI_KEYPAD_BASE		0x01C23000
> +#define SUNXI_TZPC_BASE			0x01C23400
> +#define SUNXI_SID_BASE			0x01C23800
> +#define SUNXI_SJTAG_BASE		0x01C23C00
> +
> +#define SUNXI_TP_BASE			0x01C25000
> +#define SUNXI_PMU_BASE			0x01C25400
> +
> +#define SUNXI_UART0_BASE		0x01C28000
> +#define SUNXI_UART1_BASE		0x01C28400
> +#define SUNXI_UART2_BASE		0x01C28800
> +#define SUNXI_UART3_BASE		0x01C28C00
> +#define SUNXI_UART4_BASE		0x01C29000
> +#define SUNXI_UART5_BASE		0x01C29400
> +#define SUNXI_UART6_BASE		0x01C29800
> +#define SUNXI_UART7_BASE		0x01C29C00
> +#define SUNXI_PS2_0_BASE		0x01C2A000
> +#define SUNXI_PS2_1_BASE		0x01C2A400
> +
> +#define SUNXI_TWI0_BASE			0x01C2AC00
> +#define SUNXI_TWI1_BASE			0x01C2B000
> +#define SUNXI_TWI2_BASE			0x01C2B400
> +
> +#define SUNXI_CAN_BASE			0x01C2BC00
> +
> +#define SUNXI_SCR_BASE			0x01C2C400
> +
> +#define SUNXI_GPS_BASE			0x01C30000
> +#define SUNXI_MALI400_BASE		0x01C40000
> +
> +/* module sram */
> +#define SUNXI_SRAM_C_BASE		0x01D00000
> +
> +#define SUNXI_DE_FE0_BASE		0x01E00000
> +#define SUNXI_DE_FE1_BASE		0x01E20000
> +#define SUNXI_DE_BE0_BASE		0x01E60000
> +#define SUNXI_DE_BE1_BASE		0x01E40000
> +#define SUNXI_MP_BASE			0x01E80000
> +#define SUNXI_AVG_BASE			0x01EA0000
> +
> +/* CoreSight Debug Module */
> +#define SUNXI_CSDM_BASE			0x3F500000
> +
> +#define SUNXI_DDRII_DDRIII_BASE		0x40000000	/* 2G */
> +
> +#define SUNXI_BROM_BASE			0xFFFF0000	/* 32K */
> +
> +#define SUNXI_CPU_CFG			(SUNXI_TIMER_BASE + 0x13c)
> +
> +#ifndef __ASSEMBLY__
> +/* boot type */
> +enum sunxi_boot_type_t {
> +	SUNXI_BOOT_TYPE_NULL,
> +	SUNXI_BOOT_TYPE_MMC0,
> +	SUNXI_BOOT_TYPE_NAND,
> +	SUNXI_BOOT_TYPE_MMC2,
> +	SUNXI_BOOT_TYPE_SPI
> +};
> +
> +sunxi_boot_type_t get_boot_type(void);
> +void sunxi_board_init(void);
> +extern void sunxi_reset(void);
> +#endif /* __ASSEMBLY__ */
> +
> +#endif /* _CPU_H */
> diff --git a/arch/arm/include/asm/arch-sunxi/dram.h b/arch/arm/include/asm/arch-sunxi/dram.h
> new file mode 100644
> index 0000000..d3c0e9f
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-sunxi/dram.h
> @@ -0,0 +1,114 @@
> +/*
> + * (C) Copyright 2007-2012
> + * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
> + * Berg Xing <bergxing@allwinnertech.com>
> + * Tom Cubie <tangliang@allwinnertech.com>
> + *
> + * Sunxi platform dram register definition.
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#ifndef _SUNXI_DRAM_H
> +#define _SUNXI_DRAM_H
> +
> +struct sunxi_dram_reg {
> +	u32 ccr;		/* 0x00 controller configuration register */
> +	u32 dcr;		/* 0x04 dram configuration register */
> +	u32 iocr;		/* 0x08 i/o configuration register */
> +	u32 csr;		/* 0x0c controller status register */
> +	u32 drr;		/* 0x10 dram refresh register */
> +	u32 tpr0;		/* 0x14 dram timing parameters register 0 */
> +	u32 tpr1;		/* 0x18 dram timing parameters register 1 */
> +	u32 tpr2;		/* 0x1c dram timing parameters register 2 */
> +	u32 gdllcr;		/* 0x20 global dll control register */
> +	u8 res0[0x28];
> +	u32 rslr0;		/* 0x4c rank system latency register */
> +	u32 rslr1;		/* 0x50 rank system latency register */
> +	u8 res1[0x8];
> +	u32 rdgr0;		/* 0x5c rank dqs gating register */
> +	u32 rdgr1;		/* 0x60 rank dqs gating register */
> +	u8 res2[0x34];
> +	u32 odtcr;		/* 0x98 odt configuration register */
> +	u32 dtr0;		/* 0x9c data training register 0 */
> +	u32 dtr1;		/* 0xa0 data training register 1 */
> +	u32 dtar;		/* 0xa4 data training address register */
> +	u32 zqcr0;		/* 0xa8 zq control register 0 */
> +	u32 zqcr1;		/* 0xac zq control register 1 */
> +	u32 zqsr;		/* 0xb0 zq status register */
> +	u32 idcr;		/* 0xb4 initializaton delay configure reg */
> +	u8 res3[0x138];
> +	u32 mr;			/* 0x1f0 mode register */
> +	u32 emr;		/* 0x1f4 extended mode register */
> +	u32 emr2;		/* 0x1f8 extended mode register */
> +	u32 emr3;		/* 0x1fc extended mode register */
> +	u32 dllctr;		/* 0x200 dll control register */
> +	u32 dllcr[5];		/* 0x204 dll control register 0(byte 0) */
> +	/* 0x208 dll control register 1(byte 1) */
> +	/* 0x20c dll control register 2(byte 2) */
> +	/* 0x210 dll control register 3(byte 3) */
> +	/* 0x214 dll control register 4(byte 4) */
> +	u32 dqtr0;		/* 0x218 dq timing register */
> +	u32 dqtr1;		/* 0x21c dq timing register */
> +	u32 dqtr2;		/* 0x220 dq timing register */
> +	u32 dqtr3;		/* 0x224 dq timing register */
> +	u32 dqstr;		/* 0x228 dqs timing register */
> +	u32 dqsbtr;		/* 0x22c dqsb timing register */
> +	u32 mcr;		/* 0x230 mode configure register */
> +	u8 res[0x8];
> +	u32 ppwrsctl;		/* 0x23c pad power save control */
> +	u32 apr;		/* 0x240 arbiter period register */
> +	u32 pldtr;		/* 0x244 priority level data threshold reg */
> +	u8 res5[0x8];
> +	u32 hpcr[32];		/* 0x250 host port configure register */
> +	u8 res6[0x10];
> +	u32 csel;		/* 0x2e0 controller select register */
> +};
> +
> +struct dram_para {
> +	u32 clock;
> +	u32 type;
> +	u32 rank_num;
> +	u32 density;
> +	u32 io_width;
> +	u32 bus_width;
> +	u32 cas;
> +	u32 zq;
> +	u32 odt_en;
> +	u32 size;
> +	u32 tpr0;
> +	u32 tpr1;
> +	u32 tpr2;
> +	u32 tpr3;
> +	u32 tpr4;
> +	u32 tpr5;
> +	u32 emr1;
> +	u32 emr2;
> +	u32 emr3;
> +};
> +
> +#define SUN5I_DRAM_MCR_DCLK_OUT_OFFSET	16
> +#define SUN4I_CCM_SDRAM_DCLK_OUT_OFFSET  15
> +
> +#define DRAM_CTRL_SELECT_MAGIC	0x16237495
> +
> +int sunxi_dram_init(void);
> +int dramc_init(struct dram_para *para);
> +
> +#endif /* _SUNXI_DRAM_H */
> diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
> new file mode 100644
> index 0000000..fceee6b
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-sunxi/gpio.h
> @@ -0,0 +1,164 @@
> +/*
> + * (C) Copyright 2007-2012
> + * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
> + * Tom Cubie <tangliang@allwinnertech.com>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#ifndef _SUNXI_GPIO_H
> +#define _SUNXI_GPIO_H
> +
> +/*
> + * sunxi has 9 banks of gpio, they are:
> + * PA0 - PA17 | PB0 - PB23 | PC0 - PC24
> + * PD0 - PD27 | PE0 - PE31 | PF0 - PF5
> + * PG0 - PG9  | PH0 - PH27 | PI0 - PI12
> + */
> +
> +#define SUNXI_GPIO_A	0
> +#define SUNXI_GPIO_B	1
> +#define SUNXI_GPIO_C	2
> +#define SUNXI_GPIO_D	3
> +#define SUNXI_GPIO_E	4
> +#define SUNXI_GPIO_F	5
> +#define SUNXI_GPIO_G	6
> +#define SUNXI_GPIO_H	7
> +#define SUNXI_GPIO_I	8
> +
> +struct sunxi_gpio {
> +	u32 cfg[4];
> +	u32 dat;
> +	u32 drv[2];
> +	u32 pull[2];
> +};
> +
> +/* gpio interrupt control */
> +struct sunxi_gpio_int {
> +	u32 cfg[3];
> +	u32 ctl;
> +	u32 sta;
> +	u32 deb;		/* interrupt debounce */
> +};
> +
> +struct sunxi_gpio_reg {
> +	struct sunxi_gpio gpio_bank[9];
> +	u8 res[0xbc];
> +	struct sunxi_gpio_int gpio_int;
> +};
> +
> +#define GPIO_BANK(pin)		((pin) >> 5)
> +#define GPIO_NUM(pin)		((pin) & 0x1F)
> +
> +#define GPIO_CFG_INDEX(pin)	(((pin) & 0x1F) >> 3)
> +#define GPIO_CFG_OFFSET(pin)	((((pin) & 0x1F) & 0x7) << 2)
> +
> +/* GPIO bank sizes */
> +#define SUNXI_GPIO_A_NR		32
> +#define SUNXI_GPIO_B_NR		32
> +#define SUNXI_GPIO_C_NR		32
> +#define SUNXI_GPIO_D_NR		32
> +#define SUNXI_GPIO_E_NR		32
> +#define SUNXI_GPIO_F_NR		32
> +#define SUNXI_GPIO_G_NR		32
> +#define SUNXI_GPIO_H_NR		32
> +#define SUNXI_GPIO_I_NR		32
> +
> +#define SUNXI_GPIO_NEXT(__gpio) \
> +	((__gpio##_START) + (__gpio##_NR) + 0)
> +
> +enum sunxi_gpio_number {
> +	SUNXI_GPIO_A_START = 0,
> +	SUNXI_GPIO_B_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_A),
> +	SUNXI_GPIO_C_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_B),
> +	SUNXI_GPIO_D_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_C),
> +	SUNXI_GPIO_E_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_D),
> +	SUNXI_GPIO_F_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_E),
> +	SUNXI_GPIO_G_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_F),
> +	SUNXI_GPIO_H_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_G),
> +	SUNXI_GPIO_I_START = SUNXI_GPIO_NEXT(SUNXI_GPIO_H),
> +};
> +
> +/* SUNXI GPIO number definitions */
> +#define SUNXI_GPA(_nr)	(SUNXI_GPIO_A_START + (_nr))
> +#define SUNXI_GPB(_nr)	(SUNXI_GPIO_B_START + (_nr))
> +#define SUNXI_GPC(_nr)	(SUNXI_GPIO_C_START + (_nr))
> +#define SUNXI_GPD(_nr)	(SUNXI_GPIO_D_START + (_nr))
> +#define SUNXI_GPE(_nr)	(SUNXI_GPIO_E_START + (_nr))
> +#define SUNXI_GPF(_nr)	(SUNXI_GPIO_F_START + (_nr))
> +#define SUNXI_GPG(_nr)	(SUNXI_GPIO_G_START + (_nr))
> +#define SUNXI_GPH(_nr)	(SUNXI_GPIO_H_START + (_nr))
> +#define SUNXI_GPI(_nr)	(SUNXI_GPIO_I_START + (_nr))
> +
> +/* GPIO pin function config */
> +#define SUNXI_GPIO_INPUT	0
> +#define SUNXI_GPIO_OUTPUT	1
> +
> +#define SUNXI_GPA0_ERXD3	2
> +#define SUNXI_GPA0_SPI1_CS0	3
> +#define SUNXI_GPA0_UART2_RTS	4
> +
> +#define SUNXI_GPA1_ERXD2	2
> +#define SUNXI_GPA1_SPI1_CLK	3
> +#define SUNXI_GPA1_UART2_CTS	4
> +
> +#define SUNXI_GPA2_ERXD1	2
> +#define SUNXI_GPA2_SPI1_MOSI	3
> +#define SUNXI_GPA2_UART2_TX	4
> +
> +#define SUNXI_GPA10_UART1_TX	4
> +#define SUNXI_GPA11_UART1_RX	4
> +
> +#define SUN4I_GPB22_UART0_TX	2
> +#define SUN4I_GPB23_UART0_RX	2
> +
> +#define SUN5I_GPG3_UART0_TX	4
> +#define SUN5I_GPG4_UART0_RX	4
> +
> +#define SUNXI_GPC2_NCLE		2
> +#define SUNXI_GPC2_SPI0_CLK	3
> +
> +#define SUNXI_GPC6_NRB0		2
> +#define SUNXI_GPC6_SDC2_CMD	3
> +
> +#define SUNXI_GPC7_NRB1		2
> +#define SUNXI_GPC7_SDC2_CLK	3
> +
> +#define SUNXI_GPC8_NDQ0		2
> +#define SUNXI_GPC8_SDC2_D0	3
> +
> +#define SUNXI_GPC9_NDQ1		2
> +#define SUNXI_GPC9_SDC2_D1	3
> +
> +#define SUNXI_GPC10_NDQ2	2
> +#define SUNXI_GPC10_SDC2_D2	3
> +
> +#define SUNXI_GPC11_NDQ3	2
> +#define SUNXI_GPC11_SDC2_D3	3
> +
> +#define SUNXI_GPF2_SDC0_CLK	2
> +#define SUNXI_GPF2_UART0_TX	4
> +
> +#define SUNXI_GPF4_SDC0_D3	2
> +#define SUNXI_GPF4_UART0_RX	4
> +
> +int sunxi_gpio_set_cfgpin(u32 pin, u32 val);
> +int sunxi_gpio_get_cfgpin(u32 pin);
> +
> +#endif /* _SUNXI_GPIO_H */
> diff --git a/arch/arm/include/asm/arch-sunxi/sys_proto.h b/arch/arm/include/asm/arch-sunxi/sys_proto.h
> new file mode 100644
> index 0000000..1e8ae5d
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-sunxi/sys_proto.h
> @@ -0,0 +1,32 @@
> +/*
> + * (C) Copyright 2007-2012
> + * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
> + * Tom Cubie <tangliang@allwinnertech.com>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#ifndef _SYS_PROTO_H_
> +#define _SYS_PROTO_H_
> +
> +void sr32(u32 *, u32, u32, u32);
> +void sdelay(unsigned long);
> +void watchdog_init(void);
> +
> +#endif
> diff --git a/arch/arm/include/asm/arch-sunxi/timer.h b/arch/arm/include/asm/arch-sunxi/timer.h
> new file mode 100644
> index 0000000..cbfec53
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-sunxi/timer.h
> @@ -0,0 +1,102 @@
> +/*
> + * (C) Copyright 2007-2011
> + * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
> + * Tom Cubie <tangliang@allwinnertech.com>
> + *
> + * Configuration settings for the Allwinner A10-evb board.
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#ifndef _SUNXI_TIMER_H_
> +#define _SUNXI_TIMER_H_
> +
> +#ifndef __ASSEMBLY__
> +
> +/* General purpose timer */
> +struct sunxi_timer {
> +	u32 ctl;
> +	u32 inter;
> +	u32 val;
> +	u8 res[4];
> +};
> +
> +/* Audio video sync*/
> +struct sunxi_avs {
> +	u32 ctl;		/* 0x80 */
> +	u32 cnt0;		/* 0x84 */
> +	u32 cnt1;		/* 0x88 */
> +	u32 div;		/* 0x8c */
> +};
> +
> +/* 64 bit counter */
> +struct sunxi_64cnt {
> +	u32 ctl;		/* 0xa0 */
> +	u32 lo;			/* 0xa4 */
> +	u32 hi;			/* 0xa8 */
> +};
> +
> +/* Watchdog */
> +struct sunxi_wdog {
> +	u32 ctl;		/* 0x90 */
> +	u32 mode;		/* 0x94 */
> +};
> +
> +/* Rtc */
> +struct sunxi_rtc {
> +	u32 ctl;		/* 0x100 */
> +	u32 yymmdd;		/* 0x104 */
> +	u32 hhmmss;		/* 0x108 */
> +};
> +
> +/* Alarm */
> +struct sunxi_alarm {
> +	u32 ddhhmmss;		/* 0x10c */
> +	u32 hhmmss;		/* 0x110 */
> +	u32 en;			/* 0x114 */
> +	u32 irqen;		/* 0x118 */
> +	u32 irqsta;		/* 0x11c */
> +};
> +
> +/* Timer general purpose register */
> +struct sunxi_tgp {
> +	u32 tgpd;
> +};
> +
> +struct sunxi_timer_reg {
> +	u32 tirqen;		/* 0x00 */
> +	u32 tirqsta;		/* 0x04 */
> +	u8 res1[8];
> +	struct sunxi_timer timer[6];	/* We have 6 timers */
> +	u8 res2[16];
> +	struct sunxi_avs avs;
> +	struct sunxi_wdog wdog;
> +	u8 res3[8];
> +	struct sunxi_64cnt cnt64;
> +	u8 res4[0x58];
> +	struct sunxi_rtc rtc;
> +	struct sunxi_alarm alarm;
> +	struct sunxi_tgp tgp[4];
> +	u8 res5[8];
> +	u32 cpu_cfg;
> +};
> +
> +#endif /* __ASSEMBLY__ */
> +
> +#endif
> diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile
> new file mode 100644
> index 0000000..43acbab
> --- /dev/null
> +++ b/board/sunxi/Makefile
> @@ -0,0 +1,46 @@
> +#
> +# (C) Copyright 2000-2003
> +# Wolfgang Denk, DENX Software Engineering, wd at denx.de.
> +#
> +# See file CREDITS for list of people who contributed to this
> +# project.
> +#
> +# This program is free software; you can redistribute it and/or
> +# modify it under the terms of the GNU General Public License as
> +# published by the Free Software Foundation; either version 2 of
> +# the License, or (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program; if not, write to the Free Software
> +# Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> +# MA 02111-1307 USA
> +#
> +
> +include $(TOPDIR)/config.mk
> +
> +LIB	:= $(obj)lib$(BOARD).o
> +
> +COBJS-y	:= board.o
> +
> +COBJS	:= $(COBJS-y)
> +SRCS 	:= $(COBJS:.o=.c)
> +OBJS 	:= $(addprefix $(obj),$(COBJS))
> +
> +all:	$(LIB)
> +
> +$(LIB):	$(obj).depend $(OBJS)
> +	$(call cmd_link_o_target, $(OBJS))
> +
> +#########################################################################
> +
> +# defines $(obj).depend target
> +include $(SRCTREE)/rules.mk
> +
> +sinclude $(obj).depend
> +
> +########################################################################
> diff --git a/board/sunxi/board.c b/board/sunxi/board.c
> new file mode 100644
> index 0000000..ae05953
> --- /dev/null
> +++ b/board/sunxi/board.c
> @@ -0,0 +1,57 @@
> +/*
> + * (C) Copyright 2007-2011
> + * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
> + * Tom Cubie <tangliang@allwinnertech.com>
> + *
> + * Some board init for the Allwinner A10-evb board.
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include <common.h>
> +#include <asm/arch/dram.h>
> +#include <asm/arch/clock.h>
> +#include <asm/arch/mmc.h>
> +#include <axp209.h>
> +
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +/* add board specific code here */
> +int board_init(void)
> +{
> +	gd->bd->bi_boot_params = (PHYS_SDRAM_1 + 0x100);
> +
> +	return 0;
> +}
> +
> +#ifdef CONFIG_DISPLAY_BOARDINFO
> +int checkboard(void)
> +{
> +	printf("Board: %s\n", CONFIG_SYS_BOARD_NAME);
> +
> +	return 0;
> +}
> +#endif
> +
> +int dram_init(void)
> +{
> +	gd->ram_size = get_ram_size((long *)PHYS_SDRAM_1, 1 << 30);
> +
> +	return 0;
> +}
> diff --git a/boards.cfg b/boards.cfg
> index 7ae663c..13d1f74 100644
> --- a/boards.cfg
> +++ b/boards.cfg
> @@ -288,6 +288,10 @@ whistler                     arm         armv7:arm720t whistler          nvidia
>  colibri_t20_iris             arm         armv7:arm720t colibri_t20_iris  toradex        tegra20
>  u8500_href                   arm         armv7       u8500               st-ericsson    u8500
>  snowball                     arm         armv7       snowball               st-ericsson    u8500
> +sun4i                        arm         armv7       sunxi               -              sunxi       sun4i
> +sun4i_sdcon                  arm         armv7       sunxi               -              sunxi       sun4i:UART0_PORT_F
> +sun5i                        arm         armv7       sunxi               -              sunxi       sun5i
> +sun5i_sdcon                  arm         armv7       sunxi               -              sunxi       sun5i:UART0_PORT_F
>  kzm9g                        arm         armv7       kzm9g               kmc            rmobile
>  armadillo-800eva             arm         armv7       armadillo-800eva    atmark-techno  rmobile
>  zynq                         arm         armv7       zynq                xilinx         zynq
> diff --git a/include/configs/sun4i.h b/include/configs/sun4i.h
> new file mode 100644
> index 0000000..513f618
> --- /dev/null
> +++ b/include/configs/sun4i.h
> @@ -0,0 +1,47 @@
> +/*
> + * (C) Copyright 2012
> + * Henrik Nordstrom <henrik@henriknordstrom.net>
> + *
> + * Configuration settings for the Allwinner A10 (sun4i) CPU
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#ifndef __CONFIG_H
> +#define __CONFIG_H
> +
> +/*
> + * Include common sunxi configuration where most the settings are
> + */
> +#include <configs/sunxi-common.h>
> +
> +/*
> + * A10 specific configuration
> + */
> +#define CONFIG_SUN4I		/* sun4i SoC generation */
> +
> +#define CONFIG_SYS_PROMPT		"sun4i#"
> +#define CONFIG_MACH_TYPE		4104
> +
> +/* Define this to have console redirected to SD port */
> +/* #define CONFIG_UART0_PORT_F */
> +
> +#define CONFIG_CONS_INDEX		1	/* UART0 */
> +
> +#endif /* __CONFIG_H */
> diff --git a/include/configs/sun5i.h b/include/configs/sun5i.h
> new file mode 100644
> index 0000000..dc84aba
> --- /dev/null
> +++ b/include/configs/sun5i.h
> @@ -0,0 +1,56 @@
> +/*
> + * (C) Copyright 2012
> + * Henrik Nordstrom <henrik@henriknordstrom.net>
> + *
> + * Configuration settings for the Allwinner A13 (sun5i) CPU
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#ifndef __CONFIG_H
> +#define __CONFIG_H
> +
> +/*
> + * Include common sunxi configuration where most the settings are
> + */
> +#include <configs/sunxi-common.h>
> +
> +/*
> + * High Level Configuration Options
> + */
> +#define CONFIG_SUN5I		/* sun5i SoC generation */
> +
> +#define CONFIG_SYS_PROMPT		"sun5i#"
> +#define CONFIG_MACH_TYPE		4138
> +
> +/* Define this to have serial channel 1 (UART0) redirected to SD port */
> +/* #define CONFIG_UART0_PORT_F */
> +
> +#ifndef CONFIG_CONS_INDEX
> +#ifdef CONFIG_UART0_PORT_F
> +#define CONFIG_CONS_INDEX		1	/* UART0 on PORT_F (sdcard) */
> +#else
> +#define CONFIG_CONS_INDEX		2	/* UART1 */
> +#endif
> +#endif
> +
> +/* Leave ICACHE off while debugging with OpenOCD */
> +#define CONFIG_SYS_ICACHE_OFF
> +
> +#endif /* __CONFIG_H */
> diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
> new file mode 100644
> index 0000000..33309f3
> --- /dev/null
> +++ b/include/configs/sunxi-common.h
> @@ -0,0 +1,189 @@
> +/*
> + * (C) Copyright 2007-2011
> + * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
> + * Tom Cubie <tangliang@allwinnertech.com>
> + *
> + * Configuration settings for the Allwinner A10-evb board.
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#ifndef _SUNXI_CONFIG_H
> +#define _SUNXI_CONFIG_H
> +
> +/*
> + * High Level Configuration Options
> + */
> +#define CONFIG_ALLWINNER	/* It's a Allwinner chip */
> +#define	CONFIG_SUNXI		/* which is sunxi family */

Space, not tab here.

> +#include <asm/arch/cpu.h>	/* get chip and board defs */
> +
> +#define CONFIG_SYS_TEXT_BASE		0x4A000000
> +
> +/*
> + * Display CPU and Board information
> + */
> +#define CONFIG_DISPLAY_BOARDINFO
> +
> +/* Clock Defines */

Why not remove this comment when there is no defines under it ?

> +
> +/* Serial & console */
> +#define CONFIG_SYS_NS16550
> +#define CONFIG_SYS_NS16550_SERIAL
> +/* ns16550 reg in the low bits of cpu reg */
> +#define CONFIG_SYS_NS16550_REG_SIZE	(-4)
> +#define CONFIG_SYS_NS16550_CLK		(24000000)
> +#define CONFIG_SYS_NS16550_COM1		SUNXI_UART0_BASE
> +#define CONFIG_SYS_NS16550_COM2		SUNXI_UART1_BASE
> +#define CONFIG_SYS_NS16550_COM3		SUNXI_UART2_BASE
> +#define CONFIG_SYS_NS16550_COM4		SUNXI_UART3_BASE
> +
> +/* DRAM Base */
> +#define CONFIG_SYS_SDRAM_BASE		0x40000000
> +#define CONFIG_SYS_INIT_RAM_ADDR	0x0
> +#define CONFIG_SYS_INIT_RAM_SIZE	0x8000	/* 32K */
> +
> +#define CONFIG_SYS_INIT_SP_OFFSET \
> +	(CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)
> +#define CONFIG_SYS_INIT_SP_ADDR \
> +	(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET)
> +
> +/* A10-EVB has 1 banks of DRAM, we use only one in U-Boot */
> +#define CONFIG_NR_DRAM_BANKS		1
> +#define PHYS_SDRAM_1			CONFIG_SYS_SDRAM_BASE
> +
> +#define CONFIG_CMD_MEMORY
> +#define CONFIG_CMD_SETEXPR
> +
> +#define CONFIG_SETUP_MEMORY_TAGS
> +#define CONFIG_CMDLINE_TAG
> +#define CONFIG_INITRD_TAG
> +#define CONFIG_CMDLINE_EDITING
> +
> +/*
> + * Size of malloc() pool
> + * 1MB = 0x100000, 0x100000 = 1024 * 1024
> + */
> +#define CONFIG_SYS_MALLOC_LEN		(CONFIG_ENV_SIZE + (1 << 20))
> +
> +/* Flat Device Tree (FDT/DT) support */
> +#define CONFIG_OF_LIBFDT
> +#define CONFIG_SYS_BOOTMAPSZ		(16 << 20)
> +
> +/*
> + * Miscellaneous configurable options
> + */
> +#define CONFIG_SYS_LONGHELP	/* undef to save memory */
> +#define CONFIG_SYS_HUSH_PARSER	/* use "hush" command parser    */
> +#define CONFIG_CMD_ECHO
> +#define CONFIG_SYS_PROMPT_HUSH_PS2	"> "
> +#define CONFIG_SYS_CBSIZE	256	/* Console I/O Buffer Size */
> +#define CONFIG_SYS_PBSIZE	384	/* Print Buffer Size */
> +#define CONFIG_SYS_MAXARGS	16	/* max number of command args */
> +
> +/* Boot Argument Buffer Size */
> +#define CONFIG_SYS_BARGSIZE		CONFIG_SYS_CBSIZE
> +
> +/* memtest works on */
> +#define CONFIG_SYS_MEMTEST_START	CONFIG_SYS_SDRAM_BASE
> +#define CONFIG_SYS_MEMTEST_END		(CONFIG_SYS_SDRAM_BASE + (256 << 20))
> +#define CONFIG_SYS_LOAD_ADDR		0x50000000 /* default load address */
> +
> +#define CONFIG_SYS_HZ			1000
> +
> +/* valid baudrates */
> +#define CONFIG_BAUDRATE			115200
> +#define CONFIG_SYS_BAUDRATE_TABLE	{ 9600, 19200, 38400, 57600, 115200 }
> +
> +/*-----------------------------------------------------------------------

I don't think we need "----" chars above.

> + * Stack sizes
> + *
> + * The stack sizes are set up in start.S using the settings below
> + */
> +#define CONFIG_STACKSIZE		(256 << 10)	/* 256 KB */
> +
> +/*-----------------------------------------------------------------------

I don't think we need "----" chars above.

> + * FLASH and environment organization
> + */
> +#define CONFIG_SYS_NO_FLASH
> +
> +#define CONFIG_SYS_MONITOR_LEN		(256 << 10)	/* 256 KB */
> +#define CONFIG_IDENT_STRING		" Allwinner Technology "

Why do you need trailing space ?

> +
> +#define CONFIG_ENV_IS_NOWHERE	/* No storage defined yet */
> +
> +#define CONFIG_ENV_OFFSET		(544 << 10)	/* (8 + 24 + 512)KB */
> +#define CONFIG_ENV_SIZE			(128 << 10)	/* 128KB */
> +
> +#define CONFIG_BOOTCOMMAND \
> +	"if run loadbootenv; then " \
> +		"echo Loaded environment from ${bootenv};" \
> +		"env import -t ${scriptaddr} ${filesize};" \
> +	"fi;" \
> +	"if test -n ${uenvcmd}; then " \
> +		"echo Running uenvcmd ...;" \
> +		"run uenvcmd;" \
> +	"fi;" \
> +	"if run loadbootscr; then "\
> +		"echo Jumping to ${bootscr};" \
> +		"source ${scriptaddr};" \
> +	"fi;" \
> +	"run setargs boot_mmc;" \
> +
> +#define CONFIG_EXTRA_ENV_SETTINGS \
> +	"console=ttyS0,115200\0" \
> +	"root=/dev/mmcblk0p2 rootwait\0" \
> +	"panicarg=panic=10\0" \
> +	"extraargs=\0" \
> +	"loglevel=8\0" \
> +	"scriptaddr=0x44000000\0" \
> +	"setargs=setenv bootargs console=${console} root=${root}" \
> +		" loglevel=${loglevel} ${panicarg} ${extraargs}\0" \
> +	"kernel=uImage\0" \
> +	"bootenv=uEnv.txt\0" \
> +	"bootscr=boot.scr\0" \
> +	"loadbootscr=fatload mmc 0 $scriptaddr ${bootscr} ||" \
> +		" ext2load mmc 0 $scriptaddr ${bootscr} ||" \
> +		" ext2load mmc 0 $scriptaddr boot/${bootscr}\0" \
> +	"loadbootenv=fatload mmc 0 $scriptaddr ${bootenv} ||" \
> +		" ext2load mmc 0 $scriptaddr ${bootenv} ||" \
> +		" ext2load mmc 0 $scriptaddr boot/${bootenv}\0" \
> +	"boot_mmc=fatload mmc 0 0x43000000 script.bin &&" \
> +		" fatload mmc 0 0x48000000 ${kernel} &&" \
> +		" bootm 0x48000000\0"
> +
> +#define CONFIG_BOOTDELAY	3
> +#define CONFIG_SYS_BOOT_GET_CMDLINE
> +#define CONFIG_AUTO_COMPLETE
> +
> +#include <config_cmd_default.h>
> +
> +#define CONFIG_DOS_PARTITION
> +#define CONFIG_CMD_FAT		/* with this we can access fat bootfs */
> +#define CONFIG_FAT_WRITE	/* enable write access */
> +#define CONFIG_CMD_EXT2		/* with this we can access ext2 bootfs */
> +#define CONFIG_CMD_EXT4		/* with this we can access ext4 bootfs */
> +#define CONFIG_CMD_ZFS		/* with this we can access ZFS bootfs */
> +
> +#undef CONFIG_CMD_FPGA
> +#undef CONFIG_CMD_NET
> +#undef CONFIG_CMD_NFS
> +
> +#endif /* __CONFIG_H */

Luka

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 01/22] ARM: sunxi: Basic Allwinner A10/A13 (sun4i/sun5i) support
  2012-11-25 12:23   ` Luka Perkov
@ 2012-11-25 13:08     ` Henrik Nordström
  2012-11-25 19:55       ` Wolfgang Denk
  2012-11-25 19:52     ` [U-Boot] [PATCH 01/22] ARM: sunxi: Basic Allwinner A10/A13 (sun4i/sun5i) support Wolfgang Denk
  1 sibling, 1 reply; 68+ messages in thread
From: Henrik Nordström @ 2012-11-25 13:08 UTC (permalink / raw)
  To: u-boot

s?n 2012-11-25 klockan 13:23 +0100 skrev Luka Perkov:
> Hi Henrik,
> 
> I have few comments bellow.
> 
> > +++ b/arch/arm/cpu/armv7/sunxi/Makefile

> > +# (C) Copyright 2000-2003
> 
> I don't know about the dates. It's 2012 now... Same goes for all other files.

Heh.. Not sure which board that was copied from.

Not sure what to set as copyright here. Can't say there have been any
significant contributions by anyone in this file, but have updated the
year to 2011-2012 to match current use.

Reviewing the others to see if copyright should be bumped, but some are
really published in 2011 and have only received non-copyrightable
cleanups after.

There is some doubt on the earlier span of the copyright on Allwinner
code, quite likely many are originally from 2011 and not 2007-2011 as
their copyright template says, but not in a position to tell for sure.

> > +#define	CONFIG_SUNXI		/* which is sunxi family */
> 
> Space, not tab here.

Fixed.

> > +/* Clock Defines */
> 
> Why not remove this comment when there is no defines under it ?

Removed.

> > +/*-----------------------------------------------------------------------
> 
> I don't think we need "----" chars above.

Fixed.

> > +/*-----------------------------------------------------------------------
> 
> I don't think we need "----" chars above.

Fixed.


> > +#define CONFIG_IDENT_STRING		" Allwinner Technology "
> 
> Why do you need trailing space ?

We don't. Fixed.


Revised patch coming shortly.

Regards
Henrik

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 02/22] ARM: sunxi: MMC driver
  2012-11-25 11:37 ` [U-Boot] [PATCH 02/22] ARM: sunxi: MMC driver Henrik Nordström
@ 2012-11-25 14:33   ` Luka Perkov
  2012-11-25 15:39     ` Henrik Nordström
  2012-11-25 19:56     ` Wolfgang Denk
  2012-11-25 18:09   ` Marek Vasut
  2012-11-25 19:44   ` Wolfgang Denk
  2 siblings, 2 replies; 68+ messages in thread
From: Luka Perkov @ 2012-11-25 14:33 UTC (permalink / raw)
  To: u-boot

On Sun, Nov 25, 2012 at 12:37:59PM +0100, Henrik Nordstr?m wrote:
> This adds a basic MMC driver for Allwinner sun4i/sun5i family of SoC
> this driver is limited to a single MMC channel.
> 
> Signed-off-by: Tom Cubie <tangliang@allwinnertech.com>
> Signed-off-by: Henrik Nodstrom <henrik@henriknordstrom.net>
> Signed-off-by: Stefan Roese <sr@denx.de>
> ---
>  arch/arm/include/asm/arch-sunxi/mmc.h |   64 +++
>  board/sunxi/board.c                   |    9 +
>  drivers/mmc/Makefile                  |    1 +
>  drivers/mmc/sunxi_mmc.c               |  674 +++++++++++++++++++++++++++++++++
>  include/configs/sunxi-common.h        |   14 +-
>  5 files changed, 759 insertions(+), 3 deletions(-)
>  create mode 100644 arch/arm/include/asm/arch-sunxi/mmc.h
>  create mode 100644 drivers/mmc/sunxi_mmc.c
> 
> diff --git a/arch/arm/include/asm/arch-sunxi/mmc.h b/arch/arm/include/asm/arch-sunxi/mmc.h
> new file mode 100644
> index 0000000..e96e7d2
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-sunxi/mmc.h
> @@ -0,0 +1,64 @@
> +/*
> + * (C) Copyright 2007-2011
> + * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
> + * Aaron <leafy.myeh@allwinnertech.com>
> + *
> + * MMC register definition for allwinner sunxi platform.
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#ifndef _SUNXI_MMC_H
> +#define _SUNXI_MMC_H
> +
> +struct sunxi_mmc {
> +	u32 gctrl;		/* (0x00) SMC Global Control Register */
> +	u32 clkcr;		/* (0x04) SMC Clock Control Register */
> +	u32 timeout;		/* (0x08) SMC Time Out Register */
> +	u32 width;		/* (0x0C) SMC Bus Width Register */
> +	u32 blksz;		/* (0x10) SMC Block Size Register */
> +	u32 bytecnt;		/* (0x14) SMC Byte Count Register */
> +	u32 cmd;		/* (0x18) SMC Command Register */
> +	u32 arg;		/* (0x1C) SMC Argument Register */
> +	u32 resp0;		/* (0x20) SMC Response Register 0 */
> +	u32 resp1;		/* (0x24) SMC Response Register 1 */
> +	u32 resp2;		/* (0x28) SMC Response Register 2 */
> +	u32 resp3;		/* (0x2C) SMC Response Register 3 */
> +	u32 imask;		/* (0x30) SMC Interrupt Mask Register */
> +	u32 mint;		/* (0x34) SMC Masked Interrupt Status Reg */
> +	u32 rint;		/* (0x38) SMC Raw Interrupt Status Register */
> +	u32 status;		/* (0x3C) SMC Status Register */
> +	u32 ftrglevel;		/* (0x40) SMC FIFO Threshold Watermark Reg */
> +	u32 funcsel;		/* (0x44) SMC Function Select Register */
> +	u32 cbcr;		/* (0x48) SMC CIU Byte Count Register */
> +	u32 bbcr;		/* (0x4C) SMC BIU Byte Count Register */
> +	u32 dbgc;		/* (0x50) SMC Debug Enable Register */
> +	u32 res0[11];		/* (0x54~0x7c) */
> +	u32 dmac;		/* (0x80) SMC IDMAC Control Register */
> +	u32 dlba;		/* (0x84) SMC IDMAC Descr List Base Addr Reg */
> +	u32 idst;		/* (0x88) SMC IDMAC Status Register */
> +	u32 idie;		/* (0x8C) SMC IDMAC Interrupt Enable Register */
> +	u32 chda;		/* (0x90) */
> +	u32 cbda;		/* (0x94) */
> +	u32 res1[26];		/* (0x98~0xff) */
> +	u32 fifo;		/* (0x100) SMC FIFO Access Address */
> +};
> +
> +int sunxi_mmc_init(int sdc_no);
> +#endif /* _SUNXI_MMC_H */
> diff --git a/board/sunxi/board.c b/board/sunxi/board.c
> index ae05953..50fb40f 100644
> --- a/board/sunxi/board.c
> +++ b/board/sunxi/board.c
> @@ -55,3 +55,12 @@ int dram_init(void)
>  
>  	return 0;
>  }
> +
> +#ifdef CONFIG_GENERIC_MMC
> +int board_mmc_init(bd_t *bis)
> +{
> +	sunxi_mmc_init(CONFIG_MMC_SUNXI_SLOT);
> +
> +	return 0;
> +}
> +#endif
> diff --git a/drivers/mmc/Makefile b/drivers/mmc/Makefile
> index a1dd730..6128910 100644
> --- a/drivers/mmc/Makefile
> +++ b/drivers/mmc/Makefile
> @@ -47,6 +47,7 @@ COBJS-$(CONFIG_S5P_SDHCI) += s5p_sdhci.o
>  COBJS-$(CONFIG_SH_MMCIF) += sh_mmcif.o
>  COBJS-$(CONFIG_TEGRA_MMC) += tegra_mmc.o
>  COBJS-$(CONFIG_DWMMC) += dw_mmc.o
> +COBJS-$(CONFIG_MMC_SUNXI) += sunxi_mmc.o
>  
>  COBJS	:= $(COBJS-y)
>  SRCS	:= $(COBJS:.o=.c)
> diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
> new file mode 100644
> index 0000000..05bc231
> --- /dev/null
> +++ b/drivers/mmc/sunxi_mmc.c
> @@ -0,0 +1,674 @@
> +/*
> + * (C) Copyright 2007-2011
> + * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
> + * Aaron <leafy.myeh@allwinnertech.com>
> + *
> + * MMC driver for allwinner sunxi platform.
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include <common.h>
> +#include <asm/io.h>
> +#include <asm/arch/cpu.h>
> +#include <asm/arch/clock.h>
> +#include <asm/arch/gpio.h>
> +#include <asm/arch/mmc.h>
> +#include <malloc.h>
> +#include <mmc.h>
> +
> +#undef SUNXI_MMCDBG
> +
> +#ifdef SUNXI_MMCDBG
> +#define MMCDBG(fmt...)	printf("[mmc]: "fmt)

Why not reuse something from existing uboot code ? (exaple from api/api.c):

 36 #define DEBUG
 37 #undef DEBUG
 
 ...
 
 53 #ifdef DEBUG
 54 #define debugf(fmt, args...) do { printf("%s(): ", __func__); printf(fmt, ##args); } while (0)
 55 #else
 56 #define debugf(fmt, args...)
 57 #endif

> +
> +static void dumphex32(char *name, char *base, int len)
> +{
> +	__u32 i;
> +
> +	printf("dump %s registers:", name);
> +	for (i = 0; i < len; i += 4) {
> +		if (!(i & 0xf))
> +			printf("\n0x%p : ", base + i);
> +		printf("0x%08x ", readl(base + i));
> +	}
> +	printf("\n");
> +}
> +
> +static void dumpmmcreg(struct sunxi_mmc *reg)
> +{

I dont see this function is called anywhere...

> +	printf("dump mmc registers:\n");
> +	printf("gctrl     0x%08x\n", reg->gctrl);
> +	printf("clkcr     0x%08x\n", reg->clkcr);
> +	printf("timeout   0x%08x\n", reg->timeout);
> +	printf("width     0x%08x\n", reg->width);
> +	printf("blksz     0x%08x\n", reg->blksz);
> +	printf("bytecnt   0x%08x\n", reg->bytecnt);
> +	printf("cmd       0x%08x\n", reg->cmd);
> +	printf("arg       0x%08x\n", reg->arg);
> +	printf("resp0     0x%08x\n", reg->resp0);
> +	printf("resp1     0x%08x\n", reg->resp1);
> +	printf("resp2     0x%08x\n", reg->resp2);
> +	printf("resp3     0x%08x\n", reg->resp3);
> +	printf("imask     0x%08x\n", reg->imask);
> +	printf("mint      0x%08x\n", reg->mint);
> +	printf("rint      0x%08x\n", reg->rint);
> +	printf("status    0x%08x\n", reg->status);
> +	printf("ftrglevel 0x%08x\n", reg->ftrglevel);
> +	printf("funcsel   0x%08x\n", reg->funcsel);
> +	printf("dmac      0x%08x\n", reg->dmac);
> +	printf("dlba      0x%08x\n", reg->dlba);
> +	printf("idst      0x%08x\n", reg->idst);
> +	printf("idie      0x%08x\n", reg->idie);
> +}
> +#else
> +#define MMCDBG(fmt...)
> +#define dumphex32(fmt...)
> +#define dumpmmcreg(fmt...)
> +#endif /* SUNXI_MMCDBG */
> +
> +struct sunxi_mmc_des {
> +	u32 reserved1_1:1;
> +	u32 dic:1;		/* disable interrupt on completion */
> +	u32 last_des:1;		/* 1-this data buffer is the last buffer */
> +	u32 first_des:1;		/* 1-data buffer is the first buffer,
> +				   0-data buffer contained in the next
> +				   descriptor is 1st buffer */
> +	u32 des_chain:1;	/* 1-the 2nd address in the descriptor is the
> +				   next descriptor address */
> +	u32 end_of_ring:1;	/* 1-last descriptor flag when using dual
> +				   data buffer in descriptor */
> +	u32 reserved1_2:24;
> +	u32 card_err_sum:1;	/* transfer error flag */
> +	u32 own:1;		/* des owner:1-idma owns it, 0-host owns it */
> +#if defined CONFIG_SUN4I
> +#define SDXC_DES_NUM_SHIFT 13
> +#define SDXC_DES_BUFFER_MAX_LEN	(1 << SDXC_DES_NUM_SHIFT)
> +	u32 data_buf1_sz:13;
> +	u32 data_buf2_sz:13;
> +	u32 reserverd2_1:6;
> +#elif defined CONFIG_SUN5I
> +#define SDXC_DES_NUM_SHIFT 16
> +#define SDXC_DES_BUFFER_MAX_LEN	(1 << SDXC_DES_NUM_SHIFT)
> +	u32 data_buf1_sz:16;
> +	u32 data_buf2_sz:16;
> +#else
> +#error ">>>> Wrong Platform for MMC <<<<"
> +#endif
> +	u32 buf_addr_ptr1;
> +	u32 buf_addr_ptr2;
> +};
> +
> +struct sunxi_mmc_host {
> +	unsigned mmc_no;
> +	uint32_t *mclkreg;
> +	unsigned database;
> +	unsigned fatal_err;
> +	unsigned mod_clk;
> +	struct sunxi_mmc *reg;
> +	struct sunxi_mmc_des *pdes;
> +};
> +
> +/* support 4 mmc hosts */
> +struct mmc mmc_dev[4];
> +struct sunxi_mmc_host mmc_host[4];
> +
> +static int mmc_resource_init(int sdc_no)
> +{
> +	struct sunxi_mmc_host *mmchost = &mmc_host[sdc_no];
> +	struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
> +
> +	MMCDBG("init mmc %d resource\n", sdc_no);
> +
> +	switch (sdc_no) {
> +	case 0:
> +		mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC0_BASE;
> +		mmchost->mclkreg = &ccm->sd0_clk_cfg;
> +		break;
> +	case 1:
> +		mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC1_BASE;
> +		mmchost->mclkreg = &ccm->sd1_clk_cfg;
> +		break;
> +	case 2:
> +		mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC2_BASE;
> +		mmchost->mclkreg = &ccm->sd2_clk_cfg;
> +		break;
> +	case 3:
> +		mmchost->reg = (struct sunxi_mmc *)SUNXI_MMC3_BASE;
> +		mmchost->mclkreg = &ccm->sd3_clk_cfg;
> +		break;
> +	default:
> +		printf("Wrong mmc number %d\n", sdc_no);
> +		return -1;
> +	}
> +	mmchost->database = (unsigned int)mmchost->reg + 0x100;
> +	mmchost->mmc_no = sdc_no;
> +
> +	return 0;
> +}
> +
> +static int mmc_clk_io_on(int sdc_no)
> +{
> +	unsigned int rval;
> +	unsigned int pll5_clk;
> +	unsigned int divider;
> +	struct sunxi_mmc_host *mmchost = &mmc_host[sdc_no];
> +	static struct sunxi_gpio *gpio_c =
> +	    &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[SUNXI_GPIO_C];
> +	static struct sunxi_gpio *gpio_f =
> +	    &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[SUNXI_GPIO_F];
> +#if CONFIG_MMC1_PG
> +	static struct sunxi_gpio *gpio_g =
> +	    &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[SUNXI_GPIO_G];
> +#endif
> +	static struct sunxi_gpio *gpio_h =
> +	    &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[SUNXI_GPIO_H];
> +	static struct sunxi_gpio *gpio_i =
> +	    &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[SUNXI_GPIO_I];
> +	struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
> +
> +	MMCDBG("init mmc %d clock and io\n", sdc_no);
> +
> +	/* config gpio */
> +	switch (sdc_no) {
> +	case 0:
> +		/* D1-PF0, D0-PF1, CLK-PF2, CMD-PF3, D3-PF4, D4-PF5 */
> +		writel(0x222222, &gpio_f->cfg[0]);
> +		writel(0x555, &gpio_f->pull[0]);
> +		writel(0xaaa, &gpio_f->drv[0]);
> +		break;
> +
> +	case 1:
> +#if CONFIG_MMC1_PG
> +		/* PG0-CMD, PG1-CLK, PG2~5-D0~3 : 4 */
> +		writel(0x444444, &gpio_g->cfg[0]);
> +		writel(0x555, &gpio_g->pull[0]);
> +		writel(0xaaa, &gpio_g->drv[0]);
> +#else
> +		/* PH22-CMD, PH23-CLK, PH24~27-D0~D3 : 5 */
> +		writel(0x55 << 24, &gpio_h->cfg[2]);
> +		writel(0x5555, &gpio_h->cfg[3]);
> +		writel(0x555 << 12, &gpio_h->pull[1]);
> +		writel(0xaaa << 12, &gpio_h->drv[1]);
> +#endif
> +		break;
> +
> +	case 2:
> +		/* CMD-PC6, CLK-PC7, D0-PC8, D1-PC9, D2-PC10, D3-PC11 */
> +		writel(0x33 << 24, &gpio_c->cfg[0]);
> +		writel(0x3333, &gpio_c->cfg[1]);
> +		writel(0x555 << 12, &gpio_c->pull[0]);
> +		writel(0xaaa << 12, &gpio_c->drv[0]);
> +		break;
> +
> +	case 3:
> +		/* PI4-CMD, PI5-CLK, PI6~9-D0~D3 : 2 */
> +		writel(0x2222 << 16, &gpio_i->cfg[0]);
> +		writel(0x22, &gpio_i->cfg[1]);
> +		writel(0x555 << 8, &gpio_i->pull[0]);
> +		writel(0x555 << 8, &gpio_i->drv[0]);
> +		break;
> +
> +	default:
> +		return -1;
> +	}
> +
> +	/* config ahb clock */
> +	rval = readl(&ccm->ahb_gate0);
> +	rval |= (1 << (8 + sdc_no));
> +	writel(rval, &ccm->ahb_gate0);
> +
> +	/* config mod clock */
> +	pll5_clk = clock_get_pll5();
> +	if (pll5_clk > 400000000)
> +		divider = 4;
> +	else
> +		divider = 3;
> +	writel((1U << 31) | (2U << 24) | divider, mmchost->mclkreg);
> +	mmchost->mod_clk = pll5_clk / (divider + 1);
> +
> +	dumphex32("ccmu", (char *)SUNXI_CCM_BASE, 0x100);
> +	dumphex32("gpio", (char *)SUNXI_PIO_BASE, 0x100);
> +	dumphex32("mmc", (char *)mmchost->reg, 0x100);
> +
> +	return 0;
> +}
> +
> +static int mmc_update_clk(struct mmc *mmc)
> +{
> +	struct sunxi_mmc_host *mmchost = (struct sunxi_mmc_host *)mmc->priv;
> +	unsigned int cmd;
> +	unsigned timeout = 0xfffff;
> +
> +	cmd = (1U << 31) | (1 << 21) | (1 << 13);
> +	writel(cmd, &mmchost->reg->cmd);
> +	while ((readl(&mmchost->reg->cmd) & 0x80000000) && timeout--)
> +		;
> +	if (!timeout)
> +		return -1;
> +
> +	writel(readl(&mmchost->reg->rint), &mmchost->reg->rint);
> +
> +	return 0;
> +}
> +
> +static int mmc_config_clock(struct mmc *mmc, unsigned div)
> +{
> +	struct sunxi_mmc_host *mmchost = (struct sunxi_mmc_host *)mmc->priv;
> +	unsigned rval = readl(&mmchost->reg->clkcr);
> +
> +	/*
> +	 * CLKCREG[7:0]: divider
> +	 * CLKCREG[16]:  on/off
> +	 * CLKCREG[17]:  power save
> +	 */
> +	/* Disable Clock */
> +	rval &= ~(1 << 16);
> +	writel(rval, &mmchost->reg->clkcr);
> +	if (mmc_update_clk(mmc))
> +		return -1;
> +
> +	/* Change Divider Factor */
> +	rval &= ~(0xFF);
> +	rval |= div;
> +	writel(rval, &mmchost->reg->clkcr);
> +	if (mmc_update_clk(mmc))
> +		return -1;
> +	/* Re-enable Clock */
> +	rval |= (1 << 16);
> +	writel(rval, &mmchost->reg->clkcr);
> +
> +	if (mmc_update_clk(mmc))
> +		return -1;
> +
> +	return 0;
> +}
> +
> +static void mmc_set_ios(struct mmc *mmc)
> +{
> +	struct sunxi_mmc_host *mmchost = (struct sunxi_mmc_host *)mmc->priv;
> +	unsigned int clkdiv = 0;
> +
> +	MMCDBG("set ios: bus_width: %x, clock: %d, mod_clk\n", mmc->bus_width,
> +	       mmc->clock, mmchost->mod_clk);
> +
> +	/* Change clock first */
> +	clkdiv = (mmchost->mod_clk + (mmc->clock >> 1)) / mmc->clock / 2;
> +	if (mmc->clock)
> +		if (mmc_config_clock(mmc, clkdiv)) {
> +			mmchost->fatal_err = 1;
> +			return;
> +		}
> +
> +	/* Change bus width */
> +	if (mmc->bus_width == 8)
> +		writel(2, &mmchost->reg->width);
> +	else if (mmc->bus_width == 4)
> +		writel(1, &mmchost->reg->width);
> +	else
> +		writel(0, &mmchost->reg->width);
> +}
> +
> +static int mmc_core_init(struct mmc *mmc)
> +{
> +	struct sunxi_mmc_host *mmchost = (struct sunxi_mmc_host *)mmc->priv;
> +
> +	/* Reset controller */
> +	writel(0x7, &mmchost->reg->gctrl);
> +
> +	return 0;
> +}
> +
> +static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data)
> +{
> +	struct sunxi_mmc_host *mmchost = (struct sunxi_mmc_host *)mmc->priv;
> +	unsigned i;
> +	unsigned byte_cnt = data->blocksize * data->blocks;
> +	unsigned *buff;
> +	unsigned timeout = 0xfffff;
> +
> +	if (data->flags & MMC_DATA_READ) {
> +		buff = (unsigned int *)data->dest;
> +		for (i = 0; i < (byte_cnt >> 2); i++) {
> +			while (--timeout
> +			       && (readl(&mmchost->reg->status) & (1 << 2)))
> +				;
> +			if (timeout <= 0)
> +				goto out;
> +			buff[i] = readl(mmchost->database);
> +			timeout = 0xfffff;
> +		}
> +	} else {
> +		buff = (unsigned int *)data->src;
> +		for (i = 0; i < (byte_cnt >> 2); i++) {
> +			while (--timeout
> +			       && (readl(&mmchost->reg->status) & (1 << 3)))
> +				;
> +			if (timeout <= 0)
> +				goto out;
> +			writel(buff[i], mmchost->database);
> +			timeout = 0xfffff;
> +		}
> +	}
> +
> +out:
> +	if (timeout <= 0)
> +		return -1;
> +
> +	return 0;
> +}
> +
> +static int mmc_trans_data_by_dma(struct mmc *mmc, struct mmc_data *data)
> +{
> +	struct sunxi_mmc_host *mmchost = (struct sunxi_mmc_host *)mmc->priv;
> +	struct sunxi_mmc_des *pdes = mmchost->pdes;
> +	unsigned byte_cnt = data->blocksize * data->blocks;
> +	unsigned char *buff;
> +	unsigned des_idx = 0;
> +	unsigned buff_frag_num = 0;
> +	unsigned remain;
> +	unsigned i, rval;
> +
> +	buff = data->flags & MMC_DATA_READ ?
> +	    (unsigned char *)data->dest : (unsigned char *)data->src;
> +	buff_frag_num = byte_cnt >> SDXC_DES_NUM_SHIFT;
> +
> +	remain = byte_cnt & (SDXC_DES_BUFFER_MAX_LEN - 1);
> +	if (remain)
> +		buff_frag_num++;
> +	else
> +		remain = SDXC_DES_BUFFER_MAX_LEN;
> +
> +	flush_cache((unsigned long)buff, (unsigned long)byte_cnt);
> +	for (i = 0; i < buff_frag_num; i++, des_idx++) {
> +		memset((void *)&pdes[des_idx], 0, sizeof(struct sunxi_mmc_des));
> +		pdes[des_idx].des_chain = 1;
> +		pdes[des_idx].own = 1;
> +		pdes[des_idx].dic = 1;
> +		if (buff_frag_num > 1 && i != buff_frag_num - 1)
> +			pdes[des_idx].data_buf1_sz =
> +			    (SDXC_DES_BUFFER_MAX_LEN -
> +			     1) & SDXC_DES_BUFFER_MAX_LEN;
> +		else
> +			pdes[des_idx].data_buf1_sz = remain;
> +
> +		pdes[des_idx].buf_addr_ptr1 =
> +		    (u32) buff + i * SDXC_DES_BUFFER_MAX_LEN;
> +		if (i == 0)
> +			pdes[des_idx].first_des = 1;
> +
> +		if (i == buff_frag_num - 1) {
> +			pdes[des_idx].dic = 0;
> +			pdes[des_idx].last_des = 1;
> +			pdes[des_idx].end_of_ring = 1;
> +			pdes[des_idx].buf_addr_ptr2 = 0;
> +		} else {
> +			pdes[des_idx].buf_addr_ptr2 = (u32)&pdes[des_idx + 1];
> +		}
> +		MMCDBG("frag %d, remain %d, des[%d](%08x): "
> +			"[0] = %08x, [1] = %08x, [2] = %08x, [3] = %08x\n",
> +			i, remain, des_idx, (u32)&pdes[des_idx],
> +			(u32)((u32 *)&pdes[des_idx])[0],
> +			(u32)((u32 *)&pdes[des_idx])[1],
> +			(u32)((u32 *)&pdes[des_idx])[2],
> +			(u32)((u32 *)&pdes[des_idx])[3]);
> +	}
> +	flush_cache((unsigned long)pdes,
> +		    sizeof(struct sunxi_mmc_des) * (des_idx + 1));
> +
> +	/*
> +	 * GCTRLREG
> +	 * GCTRL[2]     : DMA reset
> +	 * GCTRL[5]     : DMA enable
> +	 *
> +	 * IDMACREG
> +	 * IDMAC[0]     : IDMA soft reset
> +	 * IDMAC[1]     : IDMA fix burst flag
> +	 * IDMAC[7]     : IDMA on
> +	 *
> +	 * IDIECREG
> +	 * IDIE[0]      : IDMA transmit interrupt flag
> +	 * IDIE[1]      : IDMA receive interrupt flag
> +	 */
> +	rval = readl(&mmchost->reg->gctrl);
> +	writel(rval | (1 << 5) | (1 << 2), &mmchost->reg->gctrl); /* dma enable */
> +	writel((1 << 0), &mmchost->reg->dmac);	/* idma reset */
> +	writel((1 << 1) | (1 << 7), &mmchost->reg->dmac);	/* idma on */
> +	rval = readl(&mmchost->reg->idie) & (~3);
> +	if (data->flags & MMC_DATA_WRITE)
> +		rval |= (1 << 0);
> +	else
> +		rval |= (1 << 1);
> +	writel(rval, &mmchost->reg->idie);
> +	writel((u32) pdes, &mmchost->reg->dlba);
> +	writel((2U << 28) | (7 << 16) | 8, &mmchost->reg->ftrglevel);
> +
> +	return 0;
> +}
> +
> +static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
> +			struct mmc_data *data)
> +{
> +	struct sunxi_mmc_host *mmchost = (struct sunxi_mmc_host *)mmc->priv;
> +	unsigned int cmdval = 0x80000000;
> +	signed int timeout = 0;
> +	int error = 0;
> +	unsigned int status = 0;
> +	unsigned int usedma = 0;
> +	unsigned int bytecnt = 0;
> +
> +	if (mmchost->fatal_err)
> +		return -1;
> +	if (cmd->resp_type & MMC_RSP_BUSY)
> +		MMCDBG("mmc cmd %d check rsp busy\n", cmd->cmdidx);
> +	if (cmd->cmdidx == 12)
> +		return 0;
> +
> +	/*
> +	 * CMDREG
> +	 * CMD[5:0]     : Command index
> +	 * CMD[6]       : Has response
> +	 * CMD[7]       : Long response
> +	 * CMD[8]       : Check response CRC
> +	 * CMD[9]       : Has data
> +	 * CMD[10]      : Write
> +	 * CMD[11]      : Steam mode
> +	 * CMD[12]      : Auto stop
> +	 * CMD[13]      : Wait previous over
> +	 * CMD[14]      : About cmd
> +	 * CMD[15]      : Send initialization
> +	 * CMD[21]      : Update clock
> +	 * CMD[31]      : Load cmd
> +	 */
> +	if (!cmd->cmdidx)
> +		cmdval |= (1 << 15);
> +	if (cmd->resp_type & MMC_RSP_PRESENT)
> +		cmdval |= (1 << 6);
> +	if (cmd->resp_type & MMC_RSP_136)
> +		cmdval |= (1 << 7);
> +	if (cmd->resp_type & MMC_RSP_CRC)
> +		cmdval |= (1 << 8);
> +
> +	if (data) {
> +		if ((u32) data->dest & 0x3) {
> +			error = -1;
> +			goto out;
> +		}
> +
> +		cmdval |= (1 << 9) | (1 << 13);
> +		if (data->flags & MMC_DATA_WRITE)
> +			cmdval |= (1 << 10);
> +		if (data->blocks > 1)
> +			cmdval |= (1 << 12);
> +		writel(data->blocksize, &mmchost->reg->blksz);
> +		writel(data->blocks * data->blocksize, &mmchost->reg->bytecnt);
> +	}
> +
> +	MMCDBG("mmc %d, cmd %d(0x%08x), arg 0x%08x\n", mmchost->mmc_no,
> +	       cmd->cmdidx, cmdval | cmd->cmdidx, cmd->cmdarg);
> +	writel(cmd->cmdarg, &mmchost->reg->arg);
> +
> +	if (!data)
> +		writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd);
> +
> +	/*
> +	 * transfer data and check status
> +	 * STATREG[2] : FIFO empty
> +	 * STATREG[3] : FIFO full
> +	 */
> +	if (data) {
> +		int ret = 0;
> +
> +		bytecnt = data->blocksize * data->blocks;
> +		MMCDBG("trans data %d bytes\n", bytecnt);
> +#if defined(CONFIG_MMC_SUNXI_USE_DMA) && !defined(CONFIG_SPL_BUILD)
> +		if (bytecnt > 64) {
> +#else
> +		if (0) {
> +#endif
> +			usedma = 1;
> +			writel(readl(&mmchost->reg->gctrl) & (~0x80000000),
> +			       &mmchost->reg->gctrl);
> +			ret = mmc_trans_data_by_dma(mmc, data);
> +			writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd);
> +		} else {
> +			writel(readl(&mmchost->reg->gctrl) | 0x80000000,
> +			       &mmchost->reg->gctrl);
> +			writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd);
> +			ret = mmc_trans_data_by_cpu(mmc, data);
> +		}
> +		if (ret) {
> +			error = readl(&mmchost->reg->rint) & 0xbfc2;
> +			goto out;
> +		}
> +	}
> +
> +	timeout = 0xfffff;
> +	do {
> +		status = readl(&mmchost->reg->rint);
> +		if (!timeout-- || (status & 0xbfc2)) {
> +			error = status & 0xbfc2;
> +			MMCDBG("cmd timeout %x\n", error);
> +			goto out;
> +		}
> +	} while (!(status & 0x4));
> +
> +	if (data) {
> +		unsigned done = 0;
> +		timeout = usedma ? 0xffff * bytecnt : 0xffff;
> +		MMCDBG("cacl timeout %x\n", timeout);
> +		do {
> +			status = readl(&mmchost->reg->rint);
> +			if (!timeout-- || (status & 0xbfc2)) {
> +				error = status & 0xbfc2;
> +				MMCDBG("data timeout %x\n", error);
> +				goto out;
> +			}
> +			if (data->blocks > 1)
> +				done = status & (1 << 14);
> +			else
> +				done = status & (1 << 3);
> +		} while (!done);
> +	}
> +
> +	if (cmd->resp_type & MMC_RSP_BUSY) {
> +		timeout = 0xfffff;
> +		do {
> +			status = readl(&mmchost->reg->status);
> +			if (!timeout--) {
> +				error = -1;
> +				MMCDBG("busy timeout\n");
> +				goto out;
> +			}
> +		} while (status & (1 << 9));
> +	}
> +
> +	if (cmd->resp_type & MMC_RSP_136) {
> +		cmd->response[0] = readl(&mmchost->reg->resp3);
> +		cmd->response[1] = readl(&mmchost->reg->resp2);
> +		cmd->response[2] = readl(&mmchost->reg->resp1);
> +		cmd->response[3] = readl(&mmchost->reg->resp0);
> +		MMCDBG("mmc resp 0x%08x 0x%08x 0x%08x 0x%08x\n",
> +		       cmd->response[3], cmd->response[2],
> +		       cmd->response[1], cmd->response[0]);
> +	} else {
> +		cmd->response[0] = readl(&mmchost->reg->resp0);
> +		MMCDBG("mmc resp 0x%08x\n", cmd->response[0]);
> +	}
> +out:
> +	if (data && usedma) {
> +		/* IDMASTAREG
> +		 * IDST[0] : idma tx int
> +		 * IDST[1] : idma rx int
> +		 * IDST[2] : idma fatal bus error
> +		 * IDST[4] : idma descriptor invalid
> +		 * IDST[5] : idma error summary
> +		 * IDST[8] : idma normal interrupt sumary
> +		 * IDST[9] : idma abnormal interrupt sumary
> +		 */
> +		status = readl(&mmchost->reg->idst);
> +		writel(status, &mmchost->reg->idst);
> +		writel(0, &mmchost->reg->idie);
> +		writel(0, &mmchost->reg->dmac);
> +		writel(readl(&mmchost->reg->gctrl) & (~(1 << 5)),
> +		       &mmchost->reg->gctrl);
> +	}
> +	if (error) {
> +		writel(0x7, &mmchost->reg->gctrl);
> +		mmc_update_clk(mmc);
> +		MMCDBG("mmc cmd %d err 0x%08x\n", cmd->cmdidx, error);
> +	}
> +	writel(0xffffffff, &mmchost->reg->rint);
> +	writel(readl(&mmchost->reg->gctrl) | (1 << 1), &mmchost->reg->gctrl);
> +
> +	if (error)
> +		return -1;
> +	else
> +		return 0;
> +}
> +
> +int sunxi_mmc_init(int sdc_no)
> +{
> +	struct mmc *mmc;
> +
> +	memset(&mmc_dev[sdc_no], 0, sizeof(struct mmc));
> +	memset(&mmc_host[sdc_no], 0, sizeof(struct sunxi_mmc_host));
> +	mmc = &mmc_dev[sdc_no];
> +
> +	sprintf(mmc->name, "SUNXI SD/MMC");
> +	mmc->priv = &mmc_host[sdc_no];
> +	mmc->send_cmd = mmc_send_cmd;
> +	mmc->set_ios = mmc_set_ios;
> +	mmc->init = mmc_core_init;
> +
> +	mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
> +	mmc->host_caps = MMC_MODE_4BIT;
> +	mmc->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
> +
> +	mmc->f_min = 400000;
> +	mmc->f_max = 52000000;
> +
> +	mmc_host[sdc_no].pdes = (struct sunxi_mmc_des *)0x50000000;
> +	mmc_resource_init(sdc_no);
> +	mmc_clk_io_on(sdc_no);
> +
> +	mmc_register(mmc);
> +
> +	return 0;
> +}
> diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
> index 33309f3..8a026e0 100644
> --- a/include/configs/sunxi-common.h
> +++ b/include/configs/sunxi-common.h
> @@ -77,6 +77,16 @@
>  #define CONFIG_INITRD_TAG
>  #define CONFIG_CMDLINE_EDITING
>  
> +/* mmc config */
> +#define CONFIG_MMC
> +#define CONFIG_GENERIC_MMC
> +#define CONFIG_CMD_MMC
> +#define CONFIG_MMC_SUNXI
> +#define CONFIG_MMC_SUNXI_SLOT		0		/* which mmc slot to use, could be 0,1,2,3 */
> +#define CONFIG_MMC_SUNXI_USE_DMA
> +#define CONFIG_ENV_IS_IN_MMC
> +#define CONFIG_SYS_MMC_ENV_DEV		CONFIG_MMC_SUNXI_SLOT		/* env in which mmc */
> +
>  /*
>   * Size of malloc() pool
>   * 1MB = 0x100000, 0x100000 = 1024 * 1024
> @@ -127,9 +137,7 @@
>  #define CONFIG_SYS_MONITOR_LEN		(256 << 10)	/* 256 KB */
>  #define CONFIG_IDENT_STRING		" Allwinner Technology "
>  
> -#define CONFIG_ENV_IS_NOWHERE	/* No storage defined yet */
> -
> -#define CONFIG_ENV_OFFSET		(544 << 10)	/* (8 + 24 + 512)KB */
> +#define CONFIG_ENV_OFFSET		(544 << 10) /* (8 + 24 + 512)KB */

The comment moving should go in the first patch.

>  #define CONFIG_ENV_SIZE			(128 << 10)	/* 128KB */
>  
>  #define CONFIG_BOOTCOMMAND \
> -- 
> 1.7.7.6

Luka

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 03/22] ARM sunxi: I2C driver
  2012-11-25 11:38 ` [U-Boot] [PATCH 03/22] ARM sunxi: I2C driver Henrik Nordström
@ 2012-11-25 14:41   ` Luka Perkov
  2012-11-25 15:47     ` Henrik Nordström
  2012-11-25 18:11   ` Marek Vasut
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 68+ messages in thread
From: Luka Perkov @ 2012-11-25 14:41 UTC (permalink / raw)
  To: u-boot

Hi Henrik,

On Sun, Nov 25, 2012 at 12:38:46PM +0100, Henrik Nordstr?m wrote:
> A basic basic driver for the I2C controller found in Allwinner
> sunXi (A10 & A13) SoCs.
> 
> Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>
> Signed-off-by: Stefan Roese <sr@denx.de>
> ---
>  arch/arm/cpu/armv7/sunxi/clock.c      |   15 ++
>  arch/arm/include/asm/arch-sunxi/i2c.h |  185 ++++++++++++++++++++++
>  drivers/i2c/Makefile                  |    1 +
>  drivers/i2c/sunxi_i2c.c               |  278 +++++++++++++++++++++++++++++++++
>  include/configs/sunxi-common.h        |    8 +
>  5 files changed, 487 insertions(+), 0 deletions(-)
>  create mode 100644 arch/arm/include/asm/arch-sunxi/i2c.h
>  create mode 100644 drivers/i2c/sunxi_i2c.c
> 
> diff --git a/arch/arm/cpu/armv7/sunxi/clock.c b/arch/arm/cpu/armv7/sunxi/clock.c
> index 424acfc..b9bbb7d 100644
> --- a/arch/arm/cpu/armv7/sunxi/clock.c
> +++ b/arch/arm/cpu/armv7/sunxi/clock.c
> @@ -42,6 +42,7 @@ int clock_init(void)
>  	return 0;
>  }
>  
> +

No need to add extra newline here.

>  /* Return PLL5 frequency in Hz
>   * Note: Assumes PLL5 reference is 24MHz clock
>   */
> @@ -55,3 +56,17 @@ unsigned int clock_get_pll5(void)
>  	int p = 1 << ((rval >> 16) & 3);
>  	return 24000000 * n * k / p;
>  }
> +
> +int clock_twi_onoff(int port, int state)
> +{
> +	struct sunxi_ccm_reg *const ccm =
> +		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
> +
> +	if (port > 2)
> +		return -1;
> +
> +	/* set the apb1 clock gate for twi */
> +	sr32(&ccm->apb1_gate, 0 + port, 1, state);
> +
> +	return 0;
> +}
> diff --git a/arch/arm/include/asm/arch-sunxi/i2c.h b/arch/arm/include/asm/arch-sunxi/i2c.h
> new file mode 100644
> index 0000000..9a6e168
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-sunxi/i2c.h
> @@ -0,0 +1,185 @@
> +/*
> + * (C) Copyright 2012 Henrik Nordstrom <henrik@henriknordstrom.net>
> + *
> + * Based on sun4i linux kernle i2c.h
> + * (C) Copyright 2007-2012
> + * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
> + * Tom Cubie <tanglaing@allwinnertech.com>
> + * Victor Wei <weiziheng@allwinnertech.com>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */

Add one newline here like in all other .h files.

> +#ifndef _SUNXI_I2C_H_
> +#define _SUNXI_I2C_H_
> +
> +struct i2c {
> +	u32 saddr;	/*  31:8bit res,7-1bit for slave addr,0 bit for GCE */
> +	u32 xsaddr;	/*  31:8bit res,7-0bit for second addr in 10bit addr */
> +	u32 data;	/*  31:8bit res, 7-0bit send or receive data byte */
> +	u32 ctl;	/*  INT_EN,BUS_EN,M_STA,INT_FLAG,A_ACK */
> +	u32 status;	/*  28 interrupt types + 0xF8 normal type = 29  */
> +	u32 clkr;	/*  31:7bit res,6-3bit,CLK_M,2-0bit CLK_N */
> +	u32 reset;	/*  31:1bit res;0bit,write 1 to clear 0. */
> +	u32 efr;	/*  31:2bit res,1:0 bit data byte follow read comand */
> +	u32 lctl;	/*  31:6bits res 5:0bit for sda&scl control */
> +};
> +
> +/* TWI address register */
> +#define TWI_GCE_EN	(0x1 << 0)	/* gen call addr enable slave mode */
> +#define TWI_ADDR_MASK	(0x7f << 1)	/* 7:1bits */
> +#define TWI_XADDR_MASK	0xff		/* 7:0bits for extend slave address */
> +
> +#define TWI_DATA_MASK	0xff		/* 7:0bits for send or received */
> +
> +/* TWI Control Register Bit Fields */
> +/* 1:0 bits reserved */
> +/* set 1 to send A_ACK,then low level on SDA */
> +#define TWI_CTL_ACK	(0x1 << 2)
> +/* INT_FLAG,interrupt status flag: set '1' when interrupt coming */
> +#define TWI_CTL_INTFLG	(0x1 << 3)
> +#define TWI_CTL_STP	(0x1 << 4)	/* M_STP,Automatic clear 0 */
> +#define TWI_CTL_STA	(0x1 << 5)	/* M_STA,atutomatic clear 0 */
> +#define TWI_CTL_BUSEN	(0x1 << 6)	/* BUS_EN, mastr mode should be set 1 */
> +#define TWI_CTL_INTEN	(0x1 << 7)	/* INT_EN */
> +/* 31:8 bit reserved */
> +
> +/*
> + * TWI Clock Register Bit Fields & Masks,default value:0x0000_0000
> + * Fin is APB CLOCK INPUT;
> + * Fsample = F0 = Fin/2^CLK_N;
> + *           F1 = F0/(CLK_M+1);
> + *
> + * Foscl = F1/10 = Fin/(2^CLK_N * (CLK_M+1)*10);
> + * Foscl is clock SCL;standard mode:100KHz or fast mode:400KHz
> + */
> +
> +#define TWI_CLK_DIV_M		(0xF << 3)	/* 6:3bit  */
> +#define TWI_CLK_DIV_N		(0x7 << 0)	/* 2:0bit */
> +#define TWI_CLK_DIV(N, M)	((((N) & 0xF) << 3) | (((M) & 0x7) << 0))
> +
> +/* TWI Soft Reset Register Bit Fields & Masks  */
> +/* write 1 to clear 0, when complete soft reset clear 0 */
> +#define TWI_SRST_SRST		(0x1 << 0)
> +
> +/* TWI Enhance Feature Register Bit Fields & Masks  */
> +/* default -- 0x0 */
> +/* 00:no,01: 1byte, 10:2 bytes, 11: 3bytes */
> +#define TWI_EFR_MASK		(0x3 << 0)
> +#define TWI_EFR_WARC_0		(0x0 << 0)
> +#define TWI_EFR_WARC_1		(0x1 << 0)
> +#define TWI_EFR_WARC_2		(0x2 << 0)
> +#define TWI_EFR_WARC_3		(0x3 << 0)
> +
> +/* twi line control register -default value: 0x0000_003a */
> +/* SDA line state control enable ,1:enable;0:disable */
> +#define TWI_LCR_SDA_EN		(0x01 << 0)
> +/* SDA line state control bit, 1:high level;0:low level */
> +#define TWI_LCR_SDA_CTL		(0x01 << 1)
> +/* SCL line state control enable ,1:enable;0:disable */
> +#define TWI_LCR_SCL_EN		(0x01 << 2)
> +/* SCL line state control bit, 1:high level;0:low level */
> +#define TWI_LCR_SCL_CTL		(0x01 << 3)
> +/* current state of SDA,readonly bit */
> +#define TWI_LCR_SDA_STATE_MASK	(0x01 << 4)
> +/* current state of SCL,readonly bit */
> +#define TWI_LCR_SCL_STATE_MASK	(0x01 << 5)
> +/* 31:6bits reserved */
> +#define TWI_LCR_IDLE_STATUS	0x3a
> +
> +/* TWI Status Register Bit Fields & Masks  */
> +#define TWI_STAT_MASK		0xff
> +/* 7:0 bits use only,default is 0xF8 */
> +#define TWI_STAT_BUS_ERR	0x00	/* BUS ERROR */
> +
> +/* Master mode use only */
> +#define TWI_STAT_TX_STA		0x08	/* START condition transmitted */
> +/* Repeated START condition transmitted */
> +#define TWI_STAT_TX_RESTA	0x10
> +/* Address+Write bit transmitted, ACK received */
> +#define TWI_STAT_TX_AW_ACK	0x18
> +/* Address+Write bit transmitted, ACK not received */
> +#define TWI_STAT_TX_AW_NAK	0x20
> +/* data byte transmitted in master mode,ack received */
> +#define TWI_STAT_TXD_ACK	0x28
> +/* data byte transmitted in master mode ,ack not received */
> +#define TWI_STAT_TXD_NAK	0x30
> +/* arbitration lost in address or data byte */
> +#define TWI_STAT_ARBLOST	0x38
> +/* Address+Read bit transmitted, ACK received */
> +#define TWI_STAT_TX_AR_ACK	0x40
> +/* Address+Read bit transmitted, ACK not received */
> +#define TWI_STAT_TX_AR_NAK	0x48
> +/* Second Address byte + Write bit transmitted, ACK received */
> +#define TWI_STAT_TX_2AW_ACK	0xD0
> +/* Second Address byte + Write bit transmitted, ACK received */
> +#define TWI_STAT_TX_2AW_NAK	0xD8
> +/* data byte received in master mode ,ack transmitted */
> +#define TWI_STAT_RXD_ACK	0x50
> +/* date byte received in master mode,not ack transmitted */
> +#define TWI_STAT_RXD_NAK	0x58
> +
> +/* Slave mode use only */
> +/* Slave address+Write bit received, ACK transmitted */
> +#define TWI_STAT_RXWS_ACK	0x60
> +/*
> + * Arbitration lost in address as master, slave address + Write bit received,
> + * ACK transmitted
> + */
> +#define TWI_STAT_ARBLOST_RXWS_ACK 0x68
> +/* General Call address received, ACK transmitted */
> +#define TWI_STAT_RXGCAS_ACK	0x70
> +/*
> + * Arbitration lost in address as master, General Call address received,
> + * ACK transmitted
> + */
> +#define TWI_STAT_ARBLOST_RXGCAS_ACK 0x78
> +/* Data byte received after slave address received, ACK transmitted */
> +#define TWI_STAT_RXDS_ACK	0x80
> +/* Data byte received after slave address received, not ACK transmitted */
> +#define TWI_STAT_RXDS_NAK	0x88
> +/* Data byte received after General Call received, ACK transmitted */
> +#define TWI_STAT_RXDGCAS_ACK	0x90
> +/* Data byte received after General Call received, not ACK transmitted */
> +#define TWI_STAT_RXDGCAS_NAK	0x98
> +/* STOP or repeated START condition received in slave  */
> +#define TWI_STAT_RXSTPS_RXRESTAS 0xA0
> +/* Slave address + Read bit received, ACK transmitted */
> +#define TWI_STAT_RXRS_ACK	0xA8
> +/*
> + * Arbitration lost in address as master, slave address + Read bit received,
> + * ACK transmitted
> + */
> +#define TWI_STAT_ARBLOST_SLAR_ACK 0xB0
> +/* Data byte transmitted in slave mode, ACK received */
> +#define TWI_STAT_TXDS_ACK	0xB8
> +/* Data byte transmitted in slave mode, ACK not received */
> +#define TWI_STAT_TXDS_NAK	0xC0
> +/* Last byte transmitted in slave mode, ACK received */
> +#define TWI_STAT_TXDSL_ACK	0xC8
> +
> +/* 10bit Address, second part of address */
> +/* Second Address byte+Write bit transmitted,ACK received */
> +#define TWI_STAT_TX_SAW_ACK	0xD0
> +/* Second Address byte+Write bit transmitted,ACK not received */
> +#define TWI_STAT_TX_SAW_NAK	0xD8
> +
> +/* No relevant status infomation,INT_FLAG = 0 */
> +#define TWI_STAT_IDLE		0xF8
> +
> +#endif
> diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
> index 5dbdbe3..9f929e6 100644
> --- a/drivers/i2c/Makefile
> +++ b/drivers/i2c/Makefile
> @@ -46,6 +46,7 @@ COBJS-$(CONFIG_TSI108_I2C) += tsi108_i2c.o
>  COBJS-$(CONFIG_U8500_I2C) += u8500_i2c.o
>  COBJS-$(CONFIG_SH_I2C) += sh_i2c.o
>  COBJS-$(CONFIG_SH_SH7734_I2C) += sh_sh7734_i2c.o
> +COBJS-$(CONFIG_SUNXI_I2C) += sunxi_i2c.o
>  
>  COBJS	:= $(COBJS-y)
>  SRCS	:= $(COBJS:.o=.c)
> diff --git a/drivers/i2c/sunxi_i2c.c b/drivers/i2c/sunxi_i2c.c
> new file mode 100644
> index 0000000..6bf5309
> --- /dev/null
> +++ b/drivers/i2c/sunxi_i2c.c
> @@ -0,0 +1,278 @@
> +/*
> + * Copyright (c) 2012 Henrik Nordstrom <henrik@henriknordstrom.net>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include <common.h>
> +#include <i2c.h>
> +#include <asm/io.h>
> +#include <asm/arch/cpu.h>
> +#include <asm/arch/i2c.h>
> +#include <asm/arch/gpio.h>
> +#include <asm/arch/clock.h>
> +
> +static struct i2c __attribute__ ((section(".data"))) *i2c_base =
> +	(struct i2c *)0x1c2ac00;
> +
> +void i2c_init(int speed, int slaveaddr)
> +{
> +	sunxi_gpio_set_cfgpin(SUNXI_GPB(0), 2);
> +	sunxi_gpio_set_cfgpin(SUNXI_GPB(1), 2);
> +	clock_twi_onoff(0, 1);
> +
> +	/* Enable the i2c bus */
> +	writel(TWI_CTL_BUSEN, &i2c_base->ctl);
> +
> +	/* 400KHz operation M=2, N=1, 24MHz APB clock */
> +	writel(TWI_CLK_DIV(2, 1), &i2c_base->clkr);
> +	writel(TWI_SRST_SRST, &i2c_base->reset);
> +
> +	while ((readl(&i2c_base->reset) & TWI_SRST_SRST))
> +		;
> +}
> +
> +int i2c_probe(uchar chip)
> +{
> +	return -1;
> +}
> +
> +static int i2c_wait_ctl(int mask, int state)
> +{
> +	int timeout = 0x2ff;
> +	int value = state ? mask : 0;
> +
> +	debug("i2c_wait_ctl(%x == %x), ctl=%x, status=%x\n", mask, value,
> +	      i2c_base->ctl, i2c_base->status);
> +
> +	while (((readl(&i2c_base->ctl) & mask) != value) && timeout-- > 0)
> +		;
> +
> +	debug("i2c_wait_ctl(), timeout=%d, ctl=%x, status=%x\n", timeout,
> +	      i2c_base->ctl, i2c_base->status);
> +
> +	if (timeout != 0)
> +		return 0;
> +	else
> +		return -1;
> +}
> +
> +static void i2c_clear_irq(void)
> +{
> +	writel(readl(&i2c_base->ctl) & ~TWI_CTL_INTFLG, &i2c_base->ctl);
> +}
> +
> +static int i2c_wait_irq(void)
> +{
> +	return i2c_wait_ctl(TWI_CTL_INTFLG, 1);
> +}
> +
> +static int i2c_wait_status(int status)
> +{
> +	int timeout = 0x2ff;
> +
> +	while (readl(&i2c_base->status) != status && timeout-- > 0)
> +		;
> +
> +	if (timeout != 0)
> +		return 0;
> +	else
> +		return -1;
> +}
> +
> +static int i2c_wait_irq_status(int status)
> +{
> +	if (i2c_wait_irq() != 0)
> +		return -1;
> +
> +	if (readl(&i2c_base->status) != status)
> +		return -1;
> +
> +	return 0;
> +}
> +
> +static int i2c_wait_bus_idle(void)
> +{
> +	int timeout = 0x2ff;
> +
> +	while (readl(&i2c_base->lctl) != 0x3a && timeout-- > 0)
> +		;
> +
> +	if (timeout != 0)
> +		return 0;
> +	else
> +		return -1;
> +}
> +
> +static int i2c_stop(void)
> +{
> +	u32 ctl;
> +
> +	ctl = readl(&i2c_base->ctl) & 0xc0;
> +	ctl |= TWI_CTL_STP;
> +
> +	writel(ctl, &i2c_base->ctl);
> +
> +	/* dummy to delay one I/O operation to make sure it's started */
> +	(void)readl(&i2c_base->ctl);
> +
> +	if (i2c_wait_ctl(TWI_CTL_STP, 0) != 0)
> +		return -1;
> +	if (i2c_wait_status(TWI_STAT_IDLE))
> +		return -1;
> +	if (i2c_wait_bus_idle() != 0)
> +		return -1;
> +
> +	return 0;
> +}
> +
> +static int i2c_send_data(u8 data, u8 status)
> +{
> +	debug("i2c_write(%02x, %x), ctl=%x, status=%x\n", data, status,
> +	      i2c_base->ctl, i2c_base->status);
> +
> +	writel(data, &i2c_base->data);
> +	i2c_clear_irq();
> +
> +	if (i2c_wait_irq_status(status) != 0)
> +		return -1;
> +
> +	return 0;
> +}
> +
> +static int i2c_start(int status)
> +{
> +	u32 ctl;
> +
> +	debug("i2c_start(%x), ctl=%x, status=%x\n", status, i2c_base->ctl,
> +	      i2c_base->status);
> +	/* Check that the controller is idle */
> +	if (status == TWI_STAT_TX_STA
> +	    && readl(&i2c_base->status) != TWI_STAT_IDLE) {
> +		return -1;
> +	}
> +
> +	writel(0, &i2c_base->efr);
> +
> +	/* Send start */
> +	ctl = readl(&i2c_base->ctl);
> +	ctl |= TWI_CTL_STA;	/* Set start bit */
> +	ctl &= ~TWI_CTL_INTFLG;	/* Clear int flag */
> +	writel(ctl, &i2c_base->ctl);
> +
> +	if (i2c_wait_ctl(TWI_CTL_STA, 0) != 0)
> +		return -1;
> +	if (i2c_wait_irq_status(status) != 0)
> +		return -1;
> +
> +	return 0;
> +}
> +
> +int i2c_do_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
> +{
> +	u32 status;
> +	u32 ctl;
> +
> +	if (i2c_start(TWI_STAT_TX_STA) != 0)
> +		return -1;
> +
> +	/* Send chip address */
> +	if (i2c_send_data(chip << 1 | 0, TWI_STAT_TX_AW_ACK) != 0)
> +		return -1;
> +
> +	/* Send data address */
> +	if (i2c_send_data(addr, TWI_STAT_TXD_ACK) != 0)
> +		return -1;
> +
> +	/* Send restart for read */
> +	if (i2c_start(TWI_STAT_TX_RESTA) != 0)
> +		return -1;
> +
> +	/* Send chip address */
> +	if (i2c_send_data(chip << 1 | 1, TWI_STAT_TX_AR_ACK) != 0)
> +		return -1;
> +
> +	/* Set ACK mode */
> +	ctl = readl(&i2c_base->ctl);
> +	ctl |= TWI_CTL_ACK;
> +	writel(ctl, &i2c_base->ctl);
> +	status = TWI_STAT_RXD_ACK;
> +
> +	/* Read data */
> +	while (len > 0) {
> +		if (len == 1) {
> +			/* Set NACK mode (last byte) */
> +			ctl = readl(&i2c_base->ctl);
> +			ctl &= ~TWI_CTL_ACK;
> +			writel(ctl, &i2c_base->ctl);
> +			status = TWI_STAT_RXD_NAK;
> +		}
> +
> +		i2c_clear_irq();
> +		if (i2c_wait_irq_status(status) != 0)
> +			return -1;
> +
> +		*buffer++ = readl(&i2c_base->data);
> +		len--;
> +	}
> +
> +	return 0;
> +}
> +
> +int i2c_read(uchar chip, uint addr, int alen, uchar *buffer, int len)
> +{
> +	int rc = i2c_do_read(chip, addr, alen, buffer, len);
> +
> +	i2c_stop();
> +
> +	return rc;
> +}
> +
> +static int i2c_do_write(uchar chip, uint addr, int alen, uchar *buffer,
> +			int len)
> +{
> +	if (i2c_start(TWI_STAT_TX_STA) != 0)
> +		return -1;
> +
> +	/* Send chip address */
> +	if (i2c_send_data(chip << 1 | 0, TWI_STAT_TX_AW_ACK) != 0)
> +		return -1;
> +
> +	/* Send data address */
> +	if (i2c_send_data(addr, TWI_STAT_TXD_ACK) != 0)
> +		return -1;
> +
> +	/* Send data */
> +	while (len > 0) {
> +		if (i2c_send_data(*buffer++, TWI_STAT_TXD_ACK) != 0)
> +			return -1;
> +		len--;
> +	}
> +
> +	return 0;
> +}
> +
> +int i2c_write(uchar chip, uint addr, int alen, uchar *buffer, int len)
> +{
> +	int rc = i2c_do_write(chip, addr, alen, buffer, len);
> +
> +	i2c_stop();
> +
> +	return rc;
> +}
> diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
> index 8a026e0..c2d16fb 100644
> --- a/include/configs/sunxi-common.h
> +++ b/include/configs/sunxi-common.h
> @@ -194,4 +194,12 @@
>  #undef CONFIG_CMD_NET
>  #undef CONFIG_CMD_NFS
>  
> +/* I2C */
> +#define CONFIG_SPL_I2C_SUPPORT
> +#define CONFIG_SYS_I2C_SPEED		400000
> +#define CONFIG_HARD_I2C
> +#define CONFIG_SUNXI_I2C
> +#define CONFIG_SYS_I2C_SLAVE		0x7f
> +#define CONFIG_CMD_I2C

Why don't you do it like this:

#ifdef CONFIG_CMD_I2C
#define CONFIG_SPL_I2C_SUPPORT
#define CONFIG_SYS_I2C_SPEED		400000
#define CONFIG_HARD_I2C
#define CONFIG_SUNXI_I2C
#define CONFIG_SYS_I2C_SLAVE		0x7f
#endif /* CONFIG_CMD_I2C */

That way you can simply turn on i2c support in board configuration file.
If users don't want/need i2c they don't need to use it.

> +
>  #endif /* __CONFIG_H */
> -- 
> 1.7.7.6

Luka

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 05/22] power: Add AXP209 Power Management controller (I2C)
  2012-11-25 11:39 ` [U-Boot] [PATCH 05/22] power: Add AXP209 Power Management controller (I2C) Henrik Nordström
@ 2012-11-25 14:44   ` Luka Perkov
  2012-11-25 18:13   ` Marek Vasut
  2012-11-25 19:48   ` Wolfgang Denk
  2 siblings, 0 replies; 68+ messages in thread
From: Luka Perkov @ 2012-11-25 14:44 UTC (permalink / raw)
  To: u-boot

Hi Henrik,

On Sun, Nov 25, 2012 at 12:39:39PM +0100, Henrik Nordstr?m wrote:
> This adds support for AXP209 Power Management controller,
> used by most sunxi (Allwinner A10/A13) based boards.
> 
> From: Henrik Nordstrom <henrik@henriknordstrom.net>
> Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>
> Signed-off-by: Stefan Roese <sr@denx.de>
> ---
>  drivers/power/Makefile |    1 +
>  drivers/power/axp209.c |  183 ++++++++++++++++++++++++++++++++++++++++++++++++
>  include/axp209.h       |   29 ++++++++
>  3 files changed, 213 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/power/axp209.c
>  create mode 100644 include/axp209.h
> 
> diff --git a/drivers/power/Makefile b/drivers/power/Makefile
> index 8c71901..ad768ff 100644
> --- a/drivers/power/Makefile
> +++ b/drivers/power/Makefile
> @@ -25,6 +25,7 @@ include $(TOPDIR)/config.mk
>  
>  LIB	:= $(obj)libpower.o
>  
> +COBJS-$(CONFIG_AXP209_POWER)	+= axp209.o
>  COBJS-$(CONFIG_FTPMU010_POWER)	+= ftpmu010.o
>  COBJS-$(CONFIG_TPS6586X_POWER)	+= tps6586x.o
>  COBJS-$(CONFIG_TWL4030_POWER)	+= twl4030.o
> diff --git a/drivers/power/axp209.c b/drivers/power/axp209.c
> new file mode 100644
> index 0000000..be98d80
> --- /dev/null
> +++ b/drivers/power/axp209.c
> @@ -0,0 +1,183 @@
> +/*
> + * (C) Copyright 2012
> + * Henrik Nordstrom <henrik@henriknordstrom.net>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include <common.h>
> +#include <i2c.h>
> +#include <axp209.h>
> +
> +enum axp209_reg {
> +	AXP209_CHIP_VERSION = 0x3,
> +	AXP209_DCDC2_VOLTAGE = 0x23,
> +	AXP209_DCDC3_VOLTAGE = 0x27,
> +	AXP209_LDO24_VOLTAGE = 0x28,
> +	AXP209_LDO3_VOLTAGE = 0x29,
> +	AXP209_SHUTDOWN = 0x32,
> +};
> +
> +int axp209_write(enum axp209_reg reg, u8 val)
> +{
> +	return i2c_write(0x34, reg, 1, &val, 1);
> +}
> +
> +int axp209_read(enum axp209_reg reg, u8 *val)
> +{
> +	return i2c_read(0x34, reg, 1, val, 1);
> +}
> +
> +int axp209_set_dcdc2(int mvolt)
> +{
> +	int cfg = (mvolt - 700) / 25;
> +	int rc;
> +	u8 current;
> +
> +	if (cfg < 0)
> +		cfg = 0;
> +	if (cfg > (1 << 6) - 1)
> +		cfg = (1 << 6) - 1;
> +
> +	/* Do we really need to be this gentle? It has built-in voltage slope */
> +	while ((rc = axp209_read(AXP209_DCDC2_VOLTAGE, &current)) == 0
> +	       && current != cfg) {
> +		if (current < cfg)
> +			current++;
> +		else
> +			current--;
> +
> +		rc = axp209_write(AXP209_DCDC2_VOLTAGE, current);
> +		if (rc)
> +			break;
> +	}
> +
> +	return rc;
> +}
> +
> +int axp209_set_dcdc3(int mvolt)
> +{
> +	int cfg = (mvolt - 700) / 25;
> +	u8 reg;
> +	int rc;
> +
> +	if (cfg < 0)
> +		cfg = 0;
> +	if (cfg > (1 << 7) - 1)
> +		cfg = (1 << 7) - 1;
> +
> +	rc = axp209_write(AXP209_DCDC3_VOLTAGE, cfg);
> +	rc |= axp209_read(AXP209_DCDC3_VOLTAGE, &reg);
> +
> +	return rc;
> +}
> +
> +int axp209_set_ldo2(int mvolt)
> +{
> +	int cfg = (mvolt - 1800) / 100;
> +	int rc;
> +	u8 reg;
> +
> +	if (cfg < 0)
> +		cfg = 0;
> +	if (cfg > 15)
> +		cfg = 15;
> +
> +	rc = axp209_read(AXP209_LDO24_VOLTAGE, &reg);
> +	if (rc)
> +		return rc;
> +
> +	reg = (reg & 0x0f) | (cfg << 4);
> +	rc = axp209_write(AXP209_LDO24_VOLTAGE, reg);
> +	if (rc)
> +		return rc;
> +
> +	return 0;
> +}
> +
> +int axp209_set_ldo3(int mvolt)
> +{
> +	int cfg = (mvolt - 700) / 25;
> +
> +	if (cfg < 0)
> +		cfg = 0;
> +	if (cfg > 127)
> +		cfg = 127;
> +	if (mvolt == -1)
> +		cfg = 0x80;	/* detemined by LDO3IN pin */
> +
> +	return axp209_write(AXP209_LDO3_VOLTAGE, cfg);
> +}
> +
> +int axp209_set_ldo4(int mvolt)
> +{
> +	int cfg = (mvolt - 1800) / 100;
> +	int rc;
> +	static const int vindex[] = {
> +		1250, 1300, 1400, 1500, 1600, 1700, 1800, 1900, 2000, 2500,
> +		2700, 2800, 3000, 3100, 3200, 3300
> +	};
> +	u8 reg;
> +
> +	/* Translate mvolt to register cfg value, requested <= selected */
> +	for (cfg = 0; mvolt < vindex[cfg] && cfg < 15; cfg++)
> +		;
> +
> +	rc = axp209_read(AXP209_LDO24_VOLTAGE, &reg);
> +	if (rc)
> +		return rc;
> +
> +	/* LDO4 configuration is in lower 4 bits */
> +	reg = (reg & 0xf0) | (cfg << 0);
> +	rc = axp209_write(AXP209_LDO24_VOLTAGE, reg);
> +	if (rc)
> +		return rc;
> +
> +	return 0;
> +}
> +
> +void axp209_poweroff(void)
> +{
> +	u8 val;
> +
> +	if (axp209_read(AXP209_SHUTDOWN, &val) != 0)
> +		return;
> +
> +	val |= 1 << 7;
> +
> +	if (axp209_write(AXP209_SHUTDOWN, val) != 0)
> +		return;
> +
> +	udelay(10000);		/* wait for power to drain */
> +}
> +
> +int axp209_init(void)
> +{
> +	u8 ver;
> +	int rc;
> +
> +	rc = axp209_read(AXP209_CHIP_VERSION, &ver);
> +	if (rc)
> +		return rc;
> +
> +	if (ver != 0x21)
> +		return -1;
> +
> +	return 0;
> +}
> diff --git a/include/axp209.h b/include/axp209.h
> new file mode 100644
> index 0000000..61338ac
> --- /dev/null
> +++ b/include/axp209.h
> @@ -0,0 +1,29 @@
> +/*
> + * (C) Copyright 2012 Henrik Nordstrom <henrik@henriknordstrom.net>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +

Please add:

#ifndef
#define 

> +extern int axp209_set_dcdc2(int mvolt);
> +extern int axp209_set_dcdc3(int mvolt);
> +extern int axp209_set_ldo2(int mvolt);
> +extern int axp209_set_ldo3(int mvolt);
> +extern int axp209_set_ldo4(int mvolt);
> +extern void axp209_poweroff(void);
> +extern int axp209_init(void);

And end with:

#endif

> -- 
> 1.7.7.6

Luka

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 06/22] ARM sunxi: Basic GPIO driver
  2012-11-25 11:40 ` [U-Boot] [PATCH 06/22] ARM sunxi: Basic GPIO driver Henrik Nordström
@ 2012-11-25 14:52   ` Luka Perkov
  2012-11-25 18:14   ` Marek Vasut
  2012-11-25 19:50   ` Wolfgang Denk
  2 siblings, 0 replies; 68+ messages in thread
From: Luka Perkov @ 2012-11-25 14:52 UTC (permalink / raw)
  To: u-boot

Hi Henrik,

On Sun, Nov 25, 2012 at 12:40:23PM +0100, Henrik Nordstr?m wrote:
> GPIO driver for Allwinner sun4i/sun5i family of SoCs
> 
> GPIO Pins are named by their symbolic pin names P<g><#>
> such as PH19 or H19.
> 
> Note: This do not perform any validation if the pin is in use
> for some other I/O function. Use with care.
> ---
>  arch/arm/include/asm/arch-sunxi/gpio.h |    2 +
>  drivers/gpio/Makefile                  |    1 +
>  drivers/gpio/sunxi_gpio.c              |  116 ++++++++++++++++++++++++++++++++
>  include/configs/sunxi-common.h         |    4 +
>  4 files changed, 123 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/gpio/sunxi_gpio.c
> 
> diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h
> index fceee6b..a3f8a74 100644
> --- a/arch/arm/include/asm/arch-sunxi/gpio.h
> +++ b/arch/arm/include/asm/arch-sunxi/gpio.h
> @@ -160,5 +160,7 @@ enum sunxi_gpio_number {
>  
>  int sunxi_gpio_set_cfgpin(u32 pin, u32 val);
>  int sunxi_gpio_get_cfgpin(u32 pin);
> +int name_to_gpio(const char *name);
> +#define name_to_gpio	name_to_gpio

Are you sure we need this define ?

>  
>  #endif /* _SUNXI_GPIO_H */
> diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
> index d50ac3b..6d692e6 100644
> --- a/drivers/gpio/Makefile
> +++ b/drivers/gpio/Makefile
> @@ -45,6 +45,7 @@ COBJS-$(CONFIG_OMAP_GPIO)	+= omap_gpio.o
>  COBJS-$(CONFIG_DB8500_GPIO)	+= db8500_gpio.o
>  COBJS-$(CONFIG_BCM2835_GPIO)	+= bcm2835_gpio.o
>  COBJS-$(CONFIG_S3C2440_GPIO)	+= s3c2440_gpio.o
> +COBJS-$(CONFIG_SUNXI_GPIO)	+= sunxi_gpio.o
>  
>  COBJS	:= $(COBJS-y)
>  SRCS 	:= $(COBJS:.o=.c)
> diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c
> new file mode 100644
> index 0000000..d99071e
> --- /dev/null
> +++ b/drivers/gpio/sunxi_gpio.c
> @@ -0,0 +1,116 @@
> +/*
> + * (C) Copyright 2007-2011
> + * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
> + * Tom Cubie <tangliang@allwinnertech.com>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include <common.h>
> +#include <asm/io.h>
> +#include <asm/gpio.h>
> +
> +static int sunxi_gpio_output(u32 pin, u32 val)
> +{
> +	u32 dat;
> +	u32 bank = GPIO_BANK(pin);
> +	u32 num = GPIO_NUM(pin);
> +	struct sunxi_gpio *pio =
> +	    &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank];
> +
> +	dat = readl(&pio->dat);
> +	if (val)
> +		dat |= 1 << num;
> +	else
> +		dat &= ~(1 << num);
> +
> +	writel(dat, &pio->dat);
> +
> +	return 0;
> +}
> +
> +static int sunxi_gpio_input(u32 pin)
> +{
> +	u32 dat;
> +	u32 bank = GPIO_BANK(pin);
> +	u32 num = GPIO_NUM(pin);
> +	struct sunxi_gpio *pio =
> +	    &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank];
> +
> +	dat = readl(&pio->dat);
> +	dat >>= num;
> +
> +	return dat & 0x1;
> +}
> +
> +int gpio_request(unsigned gpio, const char *label)
> +{
> +	return 0;
> +}
> +
> +int gpio_free(unsigned gpio)
> +{
> +	return 0;
> +}
> +
> +int gpio_direction_input(unsigned gpio)
> +{
> +	sunxi_gpio_set_cfgpin(gpio, SUNXI_GPIO_INPUT);
> +
> +	return sunxi_gpio_input(gpio);
> +}
> +
> +int gpio_direction_output(unsigned gpio, int value)
> +{
> +	sunxi_gpio_set_cfgpin(gpio, SUNXI_GPIO_OUTPUT);
> +
> +	return sunxi_gpio_output(gpio, value);
> +}
> +
> +int gpio_get_value(unsigned gpio)
> +{
> +	return sunxi_gpio_input(gpio);
> +}
> +
> +int gpio_set_value(unsigned gpio, int value)
> +{
> +	return sunxi_gpio_output(gpio, value);
> +}
> +
> +int name_to_gpio(const char *name)
> +{
> +	int group = 0;
> +	int groupsize = 9 * 32;
> +	long pin;
> +	const char *eptr;
> +	if (*name == 'P' || *name == 'p')
> +		name++;
> +	if (*name >= 'A') {
> +		group = *name - (*name > 'a' ? 'a' : 'A');
> +		groupsize = 32;
> +		name++;
> +	}
> +
> +	pin = simple_strtol(name, &eptr, 10);
> +	if (!*name || *eptr)
> +		return -1;
> +	if (pin < 0 || pin > groupsize || group >= 9)
> +		return -1;
> +	return group * 32 + pin;
> +}
> diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
> index 5bf8eea..bc1f200 100644
> --- a/include/configs/sunxi-common.h
> +++ b/include/configs/sunxi-common.h
> @@ -206,4 +206,8 @@
>  /* #define CONFIG_WATCHDOG */
>  /* #define CONFIG_SUNXI_WATCHDOG */
>  
> +/* GPIO */
> +#define CONFIG_SUNXI_GPIO
> +#define CONFIG_CMD_GPIO

Why don't you use:

#ifdef CONFIG_CMD_GPIO
#define CONFIG_SUNXI_GPIO
#endif /* CONFIG_CMD_GPIO */

> +
>  #endif /* __CONFIG_H */
> -- 
> 1.7.7.6

Luka

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 07/22] tools: mksunixboot adding a Allwinner boot header
  2012-11-25 11:40 ` [U-Boot] [PATCH 07/22] tools: mksunixboot adding a Allwinner boot header Henrik Nordström
@ 2012-11-25 15:01   ` Luka Perkov
  2012-11-25 17:47   ` Wolfgang Denk
  1 sibling, 0 replies; 68+ messages in thread
From: Luka Perkov @ 2012-11-25 15:01 UTC (permalink / raw)
  To: u-boot

Hi Henrik,

On Sun, Nov 25, 2012 at 12:40:50PM +0100, Henrik Nordstr?m wrote:
> This tool adds a boot header to the supplied file, for booting
> code directly from the SoC embedded boot rom. Needed for making
> the SPL loader bootable.
> 
> From: Tom Cubie <Mr.hipboi@gmail.com>
> Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>
> Signed-off-by: Stefan Roese <sr@denx.de>
> ---
>  Makefile                 |    1 +
>  tools/.gitignore         |    1 +
>  tools/Makefile           |    6 ++
>  tools/mksunxiboot.README |   13 ++++
>  tools/mksunxiboot.c      |  162 ++++++++++++++++++++++++++++++++++++++++++++++
>  5 files changed, 183 insertions(+), 0 deletions(-)
>  create mode 100644 tools/mksunxiboot.README
>  create mode 100644 tools/mksunxiboot.c
> 
> diff --git a/Makefile b/Makefile
> index 5a98745..81fe532 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -799,6 +799,7 @@ clean:
>  	       $(obj)tools/gen_eth_addr    $(obj)tools/img2srec		  \
>  	       $(obj)tools/mk{env,}image   $(obj)tools/mpc86x_clk	  \
>  	       $(obj)tools/mk{smdk5250,}spl				  \
> +	       $(obj)tools/mksunxiboot					  \
>  	       $(obj)tools/mxsboot					  \
>  	       $(obj)tools/ncb		   $(obj)tools/ubsha1		  \
>  	       $(obj)tools/kernel-doc/docproc
> diff --git a/tools/.gitignore b/tools/.gitignore
> index 9bce719..92fcbbd 100644
> --- a/tools/.gitignore
> +++ b/tools/.gitignore
> @@ -7,6 +7,7 @@
>  /mkimage
>  /mpc86x_clk
>  /mxsboot
> +/mksunxiboot
>  /ncb
>  /ncp
>  /ubsha1
> diff --git a/tools/Makefile b/tools/Makefile
> index 686840a..508112d 100644
> --- a/tools/Makefile
> +++ b/tools/Makefile
> @@ -69,6 +69,7 @@ BIN_FILES-$(CONFIG_XWAY_SWAP_BYTES) += xway-swap-bytes$(SFX)
>  BIN_FILES-y += mkenvimage$(SFX)
>  BIN_FILES-y += mkimage$(SFX)
>  BIN_FILES-$(CONFIG_SMDK5250) += mksmdk5250spl$(SFX)
> +BIN_FILES-$(CONFIG_SUNXI) += mksunxiboot$(SFX)
>  BIN_FILES-$(CONFIG_MX28) += mxsboot$(SFX)
>  BIN_FILES-$(CONFIG_NETCONSOLE) += ncb$(SFX)
>  BIN_FILES-$(CONFIG_SHA1_CHECK_UB_IMG) += ubsha1$(SFX)
> @@ -98,6 +99,7 @@ NOPED_OBJ_FILES-y += omapimage.o
>  NOPED_OBJ_FILES-y += mkenvimage.o
>  NOPED_OBJ_FILES-y += mkimage.o
>  OBJ_FILES-$(CONFIG_SMDK5250) += mkexynosspl.o
> +OBJ_FILES-$(CONFIG_SUNXI) += mksunxiboot.o
>  OBJ_FILES-$(CONFIG_MX28) += mxsboot.o
>  OBJ_FILES-$(CONFIG_NETCONSOLE) += ncb.o
>  NOPED_OBJ_FILES-y += os_support.o
> @@ -228,6 +230,10 @@ $(obj)mpc86x_clk$(SFX):	$(obj)mpc86x_clk.o
>  	$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
>  	$(HOSTSTRIP) $@
>  
> +$(obj)mksunxiboot$(SFX):	$(obj)mksunxiboot.o
> +	$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
> +	$(HOSTSTRIP) $@
> +
>  $(obj)mxsboot$(SFX):	$(obj)mxsboot.o
>  	$(HOSTCC) $(HOSTCFLAGS) $(HOSTLDFLAGS) -o $@ $^
>  	$(HOSTSTRIP) $@
> diff --git a/tools/mksunxiboot.README b/tools/mksunxiboot.README
> new file mode 100644
> index 0000000..9a4b379
> --- /dev/null
> +++ b/tools/mksunxiboot.README
> @@ -0,0 +1,13 @@
> +This program make a arm binary file can be loaded by Allwinner A10 and releated
> +chips from storage media such as nand and mmc.
> +
> +More information about A10 boot, please refer to
> +http://rhombus-tech.net/allwinner_a10/a10_boot_process/
> +
> +To compile this program, just type make, you will get 'mksunxiboot'.
> +
> +To use it,
> +$./mksunxiboot u-boot.bin u-boot-mmc.bin
> +then you can write it to a mmc card with dd.
> +$sudo dd if=u-boot-mmc.bin of=/dev/sdb bs=1024 seek=8
> +then insert your mmc card to your A10 tablet, you can boot from mmc card.

To use it:

$ ./mksunxiboot u-boot.bin u-boot-mmc.bin

Then you can write it to a mmc card with dd. For example if your mmc
card is located in /dev/sdb:

$ sudo dd if=u-boot-mmc.bin of=/dev/sdb bs=1024 seek=8

After inserting your mmc card into your A10 tablet it will boot from it.



Also, it would be nice to see more information here.

> diff --git a/tools/mksunxiboot.c b/tools/mksunxiboot.c
> new file mode 100644
> index 0000000..fd81529
> --- /dev/null
> +++ b/tools/mksunxiboot.c
> @@ -0,0 +1,162 @@
> +/*
> + * (C) Copyright 2007-2011
> + * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
> + * Tom Cubie <tangliang@allwinnertech.com>
> + *
> + * a simple tool to generate bootable image for sunxi platform.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include <fcntl.h>
> +#include <stdio.h>
> +#include <unistd.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <errno.h>
> +#include <sys/types.h>
> +#include <sys/stat.h>
> +
> +typedef unsigned char u8;
> +typedef unsigned int u32;
> +
> +/* boot head definition from sun4i boot code */
> +typedef struct boot_file_head {
> +	u32 jump_instruction;	/* one intruction jumping to real code */
> +	u8 magic[8];		/* ="eGON.BT0" or "eGON.BT1", not C-style str */
> +	u32 check_sum;		/* generated by PC */
> +	u32 length;		/* generated by PC */
> +#if 1

Please use a define on the top of file and use it here then.

> +	/* We use a simplified header, only filling in what is needed by the
> +	 * boot ROM. To be compatible with Allwinner tools the larger header
> +	 * below should be used, followed by a custom header if desired. */
> +	u8 pad[12];		/* align to 32 bytes */
> +#else
> +	u32 pub_head_size;	/* the size of boot_file_head_t */
> +	u8 pub_head_vsn[4];	/* the version of boot_file_head_t */
> +	u8 file_head_vsn[4];	/* the version of boot0_file_head_t or
> +				   boot1_file_head_t */
> +	u8 Boot_vsn[4];		/* Boot version */
> +	u8 eGON_vsn[4];		/* eGON version */
> +	u8 platform[8];		/* platform information */
> +#endif
> +} boot_file_head_t;
> +
> +#define BOOT0_MAGIC                     "eGON.BT0"
> +#define STAMP_VALUE                     0x5F0A6C39
> +
> +/* check sum functon from sun4i boot code */
> +int gen_check_sum(void *boot_buf)
> +{
> +	boot_file_head_t *head_p;
> +	u32 length;
> +	u32 *buf;
> +	u32 loop;
> +	u32 i;
> +	u32 sum;
> +
> +	head_p = (boot_file_head_t *) boot_buf;
> +	length = head_p->length;
> +	if ((length & 0x3) != 0)	/* must 4-byte-aligned */
> +		return -1;
> +	buf = (u32 *) boot_buf;
> +	head_p->check_sum = STAMP_VALUE;	/* fill stamp */
> +	loop = length >> 2;
> +
> +	/* calculate the sum */
> +	for (i = 0, sum = 0; i < loop; i++)
> +		sum += buf[i];
> +
> +	/* write back check sum */
> +	head_p->check_sum = sum;
> +
> +	return 0;
> +}
> +
> +#define ALIGN(x, a) __ALIGN_MASK((x), (typeof(x))(a)-1)
> +#define __ALIGN_MASK(x, mask) (((x)+(mask))&~(mask))
> +
> +#define SUN4I_SRAM_SIZE (24 * 1024)
> +#define SRAM_LOAD_MAX_SIZE (SUN4I_SRAM_SIZE - sizeof(boot_file_head_t))
> +#define BLOCK_SIZE 512
> +
> +struct boot_img {
> +	boot_file_head_t header;
> +	char code[SRAM_LOAD_MAX_SIZE];
> +	char pad[BLOCK_SIZE];
> +};
> +
> +int main(int argc, char *argv[])
> +{
> +	int fd_in, fd_out;
> +	struct boot_img img;
> +	unsigned file_size, load_size;
> +	int count;
> +
> +	if (argc < 2) {
> +		printf
> +			("\tThis program makes an input bin file to sun4i bootable image.\n"
> +			 "\tUsage: %s input_file out_putfile\n", argv[0]);

You mean output_file, right ?

> +		return EXIT_FAILURE;
> +	}
> +
> +	fd_in = open(argv[1], O_RDONLY);
> +	if (fd_in < 0) {
> +		perror("Open input file:");
> +		return EXIT_FAILURE;
> +	}
> +
> +	fd_out = open(argv[2], O_WRONLY | O_CREAT, 0666);
> +	if (fd_out < 0) {
> +		perror("Open output file:");
> +		return EXIT_FAILURE;
> +	}
> +
> +	memset((void *)img.pad, 0, BLOCK_SIZE);
> +
> +	/* get input file size */
> +	file_size = lseek(fd_in, 0, SEEK_END);
> +	printf("File size: 0x%x\n", file_size);
> +
> +	if (file_size > SRAM_LOAD_MAX_SIZE)
> +		load_size = SRAM_LOAD_MAX_SIZE;
> +	else
> +		load_size = ALIGN(file_size, sizeof(int));
> +	printf("Load size: 0x%x\n", load_size);
> +
> +	/* read file to buffer to calculate checksum */
> +	lseek(fd_in, 0, SEEK_SET);
> +	count = read(fd_in, img.code, load_size);
> +	printf("Read 0x%x bytes\n", count);
> +
> +	/* fill the header */
> +	img.header.jump_instruction =	/* b instruction */
> +		0xEA000000 |	/* jump to the first instr after the header */
> +		((sizeof(boot_file_head_t) / sizeof(int) - 2)
> +		 & 0x00FFFFFF);
> +	memcpy(img.header.magic, BOOT0_MAGIC, 8);	/* no '0' termination */
> +	img.header.length =
> +		ALIGN(load_size + sizeof(boot_file_head_t), BLOCK_SIZE);
> +	gen_check_sum((void *)&img);
> +
> +	count = write(fd_out, (void *)&img, img.header.length);
> +	printf("Write 0x%x bytes\n", count);
> +
> +	close(fd_in);
> +	close(fd_out);
> +
> +	return EXIT_SUCCESS;
> +}
> -- 
> 1.7.7.6

Luka

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 09/22] ARM: sun4i: Enable ethernet support (wemac) on A10 boards
  2012-11-25 11:42 ` [U-Boot] [PATCH 09/22] ARM: sun4i: Enable ethernet support (wemac) on A10 boards Henrik Nordström
@ 2012-11-25 15:05   ` Luka Perkov
  0 siblings, 0 replies; 68+ messages in thread
From: Luka Perkov @ 2012-11-25 15:05 UTC (permalink / raw)
  To: u-boot

Hi Henrik,

On Sun, Nov 25, 2012 at 12:42:15PM +0100, Henrik Nordstr?m wrote:
> From: Stefan Roese <sr@denx.de>
> Signed-off-by: Stefan Roese <sr@denx.de>
> Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>
> ---
>  arch/arm/cpu/armv7/sunxi/board.c |   14 ++++++++++++++
>  include/configs/sun4i.h          |    8 ++++++++
>  2 files changed, 22 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c
> index 5c94110..29cc4bd 100644
> --- a/arch/arm/cpu/armv7/sunxi/board.c
> +++ b/arch/arm/cpu/armv7/sunxi/board.c
> @@ -32,6 +32,7 @@
>  #include <asm/arch/timer.h>
>  #include <asm/arch/gpio.h>
>  #include <asm/arch/sys_proto.h>
> +#include <netdev.h>
>  
>  int gpio_init(void)
>  {
> @@ -78,3 +79,16 @@ void enable_caches(void)
>  	dcache_enable();
>  }
>  #endif
> +
> +#if defined(CONFIG_SUNXI_WEMAC)
> +/*
> + * Initializes on-chip ethernet controllers.
> + * to override, implement board_eth_init()
> + */
> +int cpu_eth_init(bd_t *bis)
> +{
> +	sunxi_wemac_initialize(bis);
> +
> +	return 0;
> +}
> +#endif
> diff --git a/include/configs/sun4i.h b/include/configs/sun4i.h
> index 513f618..ad51446 100644
> --- a/include/configs/sun4i.h
> +++ b/include/configs/sun4i.h
> @@ -44,4 +44,12 @@
>  
>  #define CONFIG_CONS_INDEX		1	/* UART0 */
>  
> +/* Ethernet support on A10 */
> +#define CONFIG_SUNXI_WEMAC
> +#define CONFIG_MII			/* MII PHY management		*/

I would remove trailing tab and use one space.

> +
> +#define CONFIG_CMD_MII
> +#define CONFIG_CMD_NET
> +#define CONFIG_CMD_PING
> +
>  #endif /* __CONFIG_H */
> -- 
> 1.7.7.6

Luka

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 10/22] sunxi: Add more network commands and netconsole support
  2012-11-25 11:43 ` [U-Boot] [PATCH 10/22] sunxi: Add more network commands and netconsole support Henrik Nordström
@ 2012-11-25 15:07   ` Luka Perkov
  0 siblings, 0 replies; 68+ messages in thread
From: Luka Perkov @ 2012-11-25 15:07 UTC (permalink / raw)
  To: u-boot

Hi Henrik,

On Sun, Nov 25, 2012 at 12:43:41PM +0100, Henrik Nordstr?m wrote:
> Add most network related commands
> 
> Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>
> 
> ---
>  include/configs/sun4i.h |   21 ++++++++++++++++++++-
>  1 files changed, 20 insertions(+), 1 deletions(-)
> 
> diff --git a/include/configs/sun4i.h b/include/configs/sun4i.h
> index ad51446..a58f82b 100644
> --- a/include/configs/sun4i.h
> +++ b/include/configs/sun4i.h
> @@ -47,9 +47,28 @@
>  /* Ethernet support on A10 */
>  #define CONFIG_SUNXI_WEMAC
>  #define CONFIG_MII			/* MII PHY management		*/
> -

Remove this line in previous patch please.

>  #define CONFIG_CMD_MII
>  #define CONFIG_CMD_NET
>  #define CONFIG_CMD_PING
> +#define CONFIG_CMD_DHCP
> +#define CONFIG_CMD_NFS
> +#define CONFIG_CMD_SNTP
> +#define CONFIG_CMD_DNS
> +#define CONFIG_NETCONSOLE
> +#define CONFIG_BOOTP_SUBNETMASK
> +#define CONFIG_BOOTP_GATEWAY
> +#define CONFIG_BOOTP_HOSTNAME
> +#define CONFIG_BOOTP_NISDOMAIN
> +#define CONFIG_BOOTP_BOOTPATH
> +#define CONFIG_BOOTP_BOOTFILESIZE
> +#define CONFIG_BOOTP_DNS
> +#define CONFIG_BOOTP_DNS2
> +#define CONFIG_BOOTP_SEND_HOSTNAME
> +#define CONFIG_BOOTP_NTPSERVER
> +#define CONFIG_BOOTP_TIMEOFFSET
> +#define CONFIG_BOOTP_MAY_FAIL
> +#define CONFIG_BOOTP_SERVERIP
> +#define CONFIG_BOOTP_DHCP_REQUEST_DELAY		50000
> +#define CONFIG_TIMESTAMP
>  
>  #endif /* __CONFIG_H */
> -- 
> 1.7.7.6

Luka

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 11/22] ARM: sunxi: U-Boot SPL capable of booting directly from MMC
  2012-11-25 11:44 ` [U-Boot] [PATCH 11/22] ARM: sunxi: U-Boot SPL capable of booting directly from MMC Henrik Nordström
@ 2012-11-25 15:11   ` Luka Perkov
  0 siblings, 0 replies; 68+ messages in thread
From: Luka Perkov @ 2012-11-25 15:11 UTC (permalink / raw)
  To: u-boot

Hi Henrik,

On Sun, Nov 25, 2012 at 12:44:17PM +0100, Henrik Nordstr?m wrote:
> Allwinner sunxi family of SoCs boots from MMC0/NAND/NOR/MMC2 loading
> boot code into an embedded 32KB SRAM.
> 
> This patch adds support for booting u-boot SPL from MMC0
> 
> We first initializes the console UART, then DRAM controller with board
> specific DRAM configuration details, configure CPU core voltage and
> clocks before loading the full u-boot image into DRAM.
> 
> From: Henrik Nordstrom <henrik@henriknordstrom.net>
> Signed-off-by: Tom Cubie <tangliang@allwinnertech.com>
> Signed-off-by: Stefan Roese <sr@denx.de>
> Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>
> ---
>  Makefile                                |   11 +
>  arch/arm/cpu/armv7/sunxi/board.c        |   38 +++
>  arch/arm/cpu/armv7/sunxi/clock.c        |   99 +++++++
>  arch/arm/cpu/armv7/sunxi/dram.c         |  445 +++++++++++++++++++++++++++++++
>  arch/arm/cpu/armv7/sunxi/u-boot-spl.lds |   63 +++++
>  arch/arm/include/asm/arch-sunxi/spl.h   |   34 +++
>  board/sunxi/board.c                     |   46 ++++
>  include/configs/sunxi-common.h          |   30 ++-
>  spl/Makefile                            |   10 +
>  9 files changed, 775 insertions(+), 1 deletions(-)
>  create mode 100644 arch/arm/cpu/armv7/sunxi/dram.c
>  create mode 100644 arch/arm/cpu/armv7/sunxi/u-boot-spl.lds
>  create mode 100644 arch/arm/include/asm/arch-sunxi/spl.h
> 
> diff --git a/Makefile b/Makefile
> index 81fe532..d1b7f97 100644
> --- a/Makefile
> +++ b/Makefile
> @@ -517,6 +517,16 @@ $(obj)u-boot.spr:	$(obj)u-boot.img $(obj)spl/u-boot-spl.bin
>  			conv=notrunc 2>/dev/null
>  		cat $(obj)spl/u-boot-spl-pad.img $(obj)u-boot.img > $@
>  
> +# sunxi: Combined object with SPL U-Boot with sunxi header (sunxi-spl.bin)
> +# and the full-blown U-Boot attached to it
> +$(obj)u-boot-sunxi-with-spl.bin: $(obj)spl/sunxi-spl.bin $(obj)u-boot.bin
> +		tr "\000" "\377" < /dev/zero | dd ibs=1 count=$(CONFIG_SPL_PAD_TO) \
> +			of=$(obj)spl/sunxi-spl-pad.bin 2>/dev/null
> +		dd if=$(obj)spl/sunxi-spl.bin of=$(obj)spl/sunxi-spl-pad.bin \
> +			conv=notrunc 2>/dev/null
> +		cat $(obj)spl/sunxi-spl-pad.bin $(obj)u-boot.bin > $@
> +		rm $(obj)spl/sunxi-spl-pad.bin
> +
>  ifeq ($(SOC),tegra20)
>  ifeq ($(CONFIG_OF_SEPARATE),y)
>  nodtb=dtb
> @@ -854,6 +864,7 @@ clobber:	tidy
>  	@[ ! -d $(obj)nand_spl ] || find $(obj)nand_spl -name "*" -type l -print | xargs rm -f
>  	@rm -f $(obj)dts/*.tmp
>  	@rm -f $(obj)spl/u-boot-spl{,-pad}.ais
> +	@rm -f $(obj)spl/sun?i-spl.bin
>  
>  mrproper \
>  distclean:	clobber unconfig
> diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c
> index 29cc4bd..6dc2bd0 100644
> --- a/arch/arm/cpu/armv7/sunxi/board.c
> +++ b/arch/arm/cpu/armv7/sunxi/board.c
> @@ -27,12 +27,37 @@
>  #include <common.h>
>  #include <asm/io.h>
>  #include <serial.h>
> +#include <i2c.h>
>  #include <asm/gpio.h>
>  #include <asm/arch/clock.h>
>  #include <asm/arch/timer.h>
>  #include <asm/arch/gpio.h>
>  #include <asm/arch/sys_proto.h>
>  #include <netdev.h>
> +#ifdef CONFIG_SPL_BUILD
> +#include <spl.h>
> +#endif
> +
> +#ifdef CONFIG_SPL_BUILD
> +/* Pointer to the global data structure for SPL */
> +DECLARE_GLOBAL_DATA_PTR;
> +
> +/* The sunxi internal brom will try to loader external bootloader
> + * from mmc0, nannd flash, mmc2.
> + * Unfortunately we can't check how SPL was loaded so assume
> + * it's always the first SD/MMC controller
> + */
> +u32 spl_boot_device(void)
> +{
> +	return BOOT_DEVICE_MMC1;
> +}
> +
> +/* No confiration data available in SPL yet. Hardcode bootmode */
> +u32 spl_boot_mode(void)
> +{
> +	return MMCSD_MODE_RAW;
> +}
> +#endif
>  
>  int gpio_init(void)
>  {
> @@ -65,6 +90,19 @@ void s_init(void)
>  #endif
>  	clock_init();
>  	gpio_init();
> +
> +#ifdef CONFIG_SPL_BUILD
> +	gd = &gdata;
> +	preloader_console_init();
> +
> +#ifdef CONFIG_SPL_I2C_SUPPORT
> +	/* Needed early by sunxi_board_init if PMU is enabled */
> +	i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
> +#endif
> +
> +	sunxi_board_init();
> +#endif
> +
>  }
>  
>  void reset_cpu(ulong addr)
> diff --git a/arch/arm/cpu/armv7/sunxi/clock.c b/arch/arm/cpu/armv7/sunxi/clock.c
> index b9bbb7d..91cfae3 100644
> --- a/arch/arm/cpu/armv7/sunxi/clock.c
> +++ b/arch/arm/cpu/armv7/sunxi/clock.c
> @@ -24,13 +24,34 @@
>  #include <common.h>
>  #include <asm/io.h>
>  #include <asm/arch/clock.h>
> +#include <asm/arch/gpio.h>
>  #include <asm/arch/sys_proto.h>
>  
> +#ifdef CONFIG_SPL_BUILD
> +static void clock_init_safe(void)
> +{
> +	struct sunxi_ccm_reg * const ccm =
> +		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
> +
> +	/* Set safe defaults until PMU is configured */
> +	writel(AXI_DIV_1 << 0 | AHB_DIV_2 << 4 | APB0_DIV_1 << 8 |
> +	       CPU_CLK_SRC_OSC24M << 16, &ccm->cpu_ahb_apb0_cfg);
> +	writel(0xa1005000, &ccm->pll1_cfg);
> +	sdelay(200);
> +	writel(AXI_DIV_1 << 0 | AHB_DIV_2 << 4 | APB0_DIV_1 << 8 |
> +	       CPU_CLK_SRC_PLL1 << 16, &ccm->cpu_ahb_apb0_cfg);
> +}
> +#endif
> +
>  int clock_init(void)
>  {
>  	struct sunxi_ccm_reg *const ccm =
>  		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
>  
> +#ifdef CONFIG_SPL_BUILD
> +	clock_init_safe();
> +#endif
> +
>  	/* uart clock source is apb1 */
>  	sr32(&ccm->apb1_clk_div_cfg, 24, 2, APB1_CLK_SRC_OSC24M);
>  	sr32(&ccm->apb1_clk_div_cfg, 16, 2, APB1_FACTOR_N);
> @@ -70,3 +91,81 @@ int clock_twi_onoff(int port, int state)
>  
>  	return 0;
>  }
> +
> +#ifdef CONFIG_SPL_BUILD
> +#define PLL1_CFG(N, K, M, P)	(1 << 31 | 0 << 30 | 8 << 26 | 0 << 25 | \
> +				 16 << 20 | (P) << 16 | 2 << 13 | (N) << 8 | \
> +				 (K) << 4 | 0 << 3 | 0 << 2 | (M) << 0)
> +#define RDIV(a, b)		((a + (b) - 1) / (b))
> +
> +struct {
> +	u32 pll1_cfg;
> +	unsigned int freq;
> +} pll1_para[] = {
> +	{ PLL1_CFG(16, 0, 0, 0), 384000000 },
> +	{ PLL1_CFG(16, 1, 0, 0), 768000000 },
> +	{ PLL1_CFG(20, 1, 0, 0), 960000000 },
> +	{ PLL1_CFG(21, 1, 0, 0), 1008000000},
> +	{ PLL1_CFG(22, 1, 0, 0), 1056000000},
> +	{ PLL1_CFG(23, 1, 0, 0), 1104000000},
> +	{ PLL1_CFG(24, 1, 0, 0), 1152000000},
> +	{ PLL1_CFG(25, 1, 0, 0), 1200000000},
> +	{ PLL1_CFG(26, 1, 0, 0), 1248000000},
> +	{ PLL1_CFG(27, 1, 0, 0), 1296000000},
> +	{ PLL1_CFG(28, 1, 0, 0), 1344000000},
> +	{ PLL1_CFG(29, 1, 0, 0), 1392000000},
> +	{ PLL1_CFG(30, 1, 0, 0), 1440000000},
> +	{ PLL1_CFG(31, 1, 0, 0), 1488000000},
> +	{ PLL1_CFG(31, 1, 0, 0), ~0},
> +};
> +
> +void clock_set_pll1(int hz)
> +{
> +	int i = 0;
> +	int axi, ahb, apb0;
> +	struct sunxi_ccm_reg * const ccm =
> +		(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
> +
> +	/* Find target frequency */
> +	while (pll1_para[i].freq < hz)
> +		i++;
> +
> +	hz = pll1_para[i].freq;
> +
> +	/* Calculate system clock divisors */
> +	axi = RDIV(hz, 432000000);		/* Max 450MHz */
> +	ahb = RDIV(hz/axi, 204000000);		/* Max 250MHz */
> +	apb0 = 2;				/* Max 150MHz */
> +
> +	/* Map divisors to register values */
> +	axi = axi - 1;
> +	if (ahb > 4)
> +		ahb = 3;
> +	else if (ahb > 2)
> +		ahb = 2;
> +	else if (ahb > 1)
> +		ahb = 1;
> +	else
> +		ahb = 0;
> +
> +	apb0 = apb0 - 1;
> +
> +	/* Switch to 24MHz clock while changing PLL1 */
> +	writel(AXI_DIV_1 << 0 | AHB_DIV_2 << 4 | APB0_DIV_1 << 8 |
> +	       CPU_CLK_SRC_OSC24M << 16, &ccm->cpu_ahb_apb0_cfg);
> +	sdelay(20);
> +
> +	/* Configure sys clock divisors */
> +	writel(axi << 0 | ahb << 4 | apb0 << 8 | CPU_CLK_SRC_OSC24M << 16,
> +	       &ccm->cpu_ahb_apb0_cfg);
> +
> +	/* Configure PLL1 at the desired frequency */
> +	writel(pll1_para[i].pll1_cfg, &ccm->pll1_cfg);
> +	sdelay(200);
> +
> +	/* Switch CPU to PLL1 */
> +	writel(axi << 0 | ahb << 4 | apb0 << 8 | CPU_CLK_SRC_PLL1 << 16,
> +	       &ccm->cpu_ahb_apb0_cfg);
> +	sdelay(20);
> +}
> +#endif
> diff --git a/arch/arm/cpu/armv7/sunxi/dram.c b/arch/arm/cpu/armv7/sunxi/dram.c
> new file mode 100644
> index 0000000..f169b7b
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/sunxi/dram.c
> @@ -0,0 +1,445 @@
> +/*
> + * sunxi DRAM controller initialization
> + * (C) Copyright 2012 Henrik Nordstrom <henrik@henriknordstrom.net>
> + *
> + * Based on sun4i Linux kernel sources mach-sunxi/pm/standby/dram*.c
> + * and earlier U-Boot Allwiner A10 SPL work
> + *
> + * (C) Copyright 2007-2012
> + * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
> + * Berg Xing <bergxing@allwinnertech.com>
> + * Tom Cubie <tangliang@allwinnertech.com>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include <common.h>
> +#include <asm/io.h>
> +#include <asm/arch/dram.h>
> +#include <asm/arch/timer.h>
> +#include <asm/arch/clock.h>
> +#include <asm/arch/sys_proto.h>
> +
> +static void mctl_ddr3_reset(void)
> +{
> +	struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
> +
> +#ifdef CONFIG_SUN4I
> +	struct sunxi_timer_reg *timer = (struct sunxi_timer_reg *)SUNXI_TIMER_BASE;
> +	u32 reg_val;
> +
> +	writel(0, &timer->cpu_cfg);
> +	reg_val = readl(&timer->cpu_cfg);
> +	reg_val >>= 6;
> +	reg_val &= 0x3;
> +
> +	if (reg_val != 0) {
> +		setbits_le32(&dram->mcr, 0x1 << 12);
> +		sdelay(0x100);
> +		clrbits_le32(&dram->mcr, 0x1 << 12);
> +	} else
> +#endif
> +	{
> +		clrbits_le32(&dram->mcr, 0x1 << 12);
> +		sdelay(0x100);
> +		setbits_le32(&dram->mcr, 0x1 << 12);
> +	}
> +}
> +
> +static void mctl_set_drive(void)
> +{
> +	struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
> +
> +	clrsetbits_le32(&dram->mcr, 0x3, (0x6 << 12) | 0xFFC);
> +}
> +
> +static void mctl_itm_disable(void)
> +{
> +	struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
> +
> +	setbits_le32(&dram->ccr, 0x1 << 28);
> +}
> +
> +static void mctl_itm_enable(void)
> +{
> +	struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
> +
> +	clrbits_le32(&dram->ccr, 0x1 << 28);
> +}
> +
> +static void mctl_enable_dll0(void)
> +{
> +	struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
> +
> +	clrsetbits_le32(&dram->dllcr[0], 0x40000000, 0x80000000);
> +	sdelay(0x100);
> +
> +	clrbits_le32(&dram->dllcr[0], 0xC0000000);
> +	sdelay(0x1000);
> +
> +	clrsetbits_le32(&dram->dllcr[0], 0x80000000, 0x40000000);
> +	sdelay(0x1000);
> +}
> +
> +/*
> + * Note: This differs from pm/standby in that it checks the bus width
> + */
> +static void mctl_enable_dllx(void)
> +{
> +	struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
> +	u32 i, n, bus_width;
> +
> +	bus_width = readl(&dram->dcr);
> +	bus_width >>= 6;
> +	bus_width &= 7;
> +
> +	if (bus_width == 3)
> +		n = 5;
> +	else
> +		n = 3;
> +
> +	for (i = 1; i < n; i++)
> +		clrsetbits_le32(&dram->dllcr[i], 0x40000000, 0x80000000);
> +	sdelay(0x100);
> +
> +	for (i = 1; i < n; i++)
> +		clrbits_le32(&dram->dllcr[i], 0xC0000000);
> +	sdelay(0x1000);
> +
> +	for (i = 1; i < n; i++)
> +		clrsetbits_le32(&dram->dllcr[i], 0x80000000, 0x40000000);
> +	sdelay(0x1000);
> +}
> +
> +static u32 hpcr_value[32] = {
> +#ifdef CONFIG_SUN5I
> +	0, 0, 0, 0,
> +	0, 0, 0, 0,
> +	0, 0, 0, 0,
> +	0, 0, 0, 0,
> +	0x1031, 0x1031, 0x0735, 0x1035,
> +	0x1035, 0x0731, 0x1031, 0,
> +	0x0301, 0x0301, 0x0301, 0x0301,
> +	0x0301, 0x0301, 0x0301, 0
> +#endif
> +#ifdef CONFIG_SUN4I
> +	0x0301, 0x0301, 0x0301, 0x0301,
> +	0x0301, 0x0301, 0, 0,
> +	0, 0, 0, 0,
> +	0, 0, 0, 0,
> +	0x1031, 0x1031, 0x0735, 0x1035,
> +	0x1035, 0x0731, 0x1031, 0x0735,
> +	0x1035, 0x1031, 0x0731, 0x1035,
> +	0x1031, 0x0301, 0x0301, 0x0731
> +#endif
> +};
> +
> +static void mctl_configure_hostport(void)
> +{
> +	struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
> +	u32 i;
> +
> +	for (i = 0; i < 32; i++)
> +		writel(hpcr_value[i], &dram->hpcr[i]);
> +}
> +
> +static void mctl_setup_dram_clock(u32 clk)
> +{
> +	u32 reg_val;
> +	struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
> +
> +	/* setup DRAM PLL */
> +	reg_val = readl(&ccm->pll5_cfg);
> +	reg_val &= ~0x3;
> +	reg_val |= 0x1;			/* m factor */
> +	reg_val &= ~(0x3 << 4);
> +	reg_val |= 0x1 << 4;		/* k factor */
> +	reg_val &= ~(0x1f << 8);
> +	reg_val |= ((clk / 24) & 0x1f) << 8;	/* n factor */
> +	reg_val &= ~(0x3 << 16);
> +	reg_val |= 0x1 << 16;		/* p factor */
> +	reg_val &= ~(0x1 << 29);	/* PLL on */
> +	reg_val |= (u32) 0x1 << 31;	/* PLL En */
> +	writel(reg_val, &ccm->pll5_cfg);
> +	sdelay(0x100000);
> +
> +	setbits_le32(&ccm->pll5_cfg, 0x1 << 29);
> +
> +#ifdef CONFIG_SUN4I
> +	/* reset GPS */
> +	clrbits_le32(&ccm->gps_clk_cfg, 0x3);
> +	setbits_le32(&ccm->ahb_gate0, 0x1 << 26);
> +	sdelay(0x20);
> +	clrbits_le32(&ccm->ahb_gate0, 0x1 << 26);
> +#endif
> +
> +	/* setup MBUS clock */
> +	reg_val = (0x1 << 31) | (0x2 << 24) | (0x1);
> +	writel(reg_val, &ccm->mbus_clk_cfg);
> +
> +	/*
> +	 * open DRAMC AHB & DLL register clock
> +	 * close it first
> +	 */
> +#ifdef CONFIG_SUN5I
> +	clrbits_le32(&ccm->ahb_gate0, 0x3 << 14);
> +#else
> +	clrbits_le32(&ccm->ahb_gate0, 0x1 << 14);
> +#endif
> +	sdelay(0x1000);
> +
> +	/* then open it */
> +#ifdef CONFIG_SUN5I
> +	setbits_le32(&ccm->ahb_gate0, 0x3 << 14);
> +#else
> +	setbits_le32(&ccm->ahb_gate0, 0x1 << 14);
> +#endif
> +	sdelay(0x1000);
> +}
> +
> +static int dramc_scan_readpipe(void)
> +{
> +	struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
> +	u32 reg_val;
> +
> +	/* data training trigger */
> +	setbits_le32(&dram->ccr, 0x1 << 30);
> +
> +	/* check whether data training process is end */
> +	while (readl(&dram->ccr) & (0x1 << 30))
> +		;
> +
> +	/* check data training result */
> +	reg_val = readl(&dram->csr);
> +	if (reg_val & (0x1 << 20))
> +		return -1;
> +
> +	return 0;
> +}
> +
> +static void dramc_clock_output_en(u32 on)
> +{
> +#ifdef CONFIG_SUN5I
> +	struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
> +
> +	if (on)
> +		setbits_le32(&dram->mcr, 0x1 << SUN5I_DRAM_MCR_DCLK_OUT_OFFSET);
> +	else
> +		clrbits_le32(&dram->mcr, 0x1 << SUN5I_DRAM_MCR_DCLK_OUT_OFFSET);
> +#endif
> +#ifdef CONFIG_SUN4I
> +	struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
> +	if (on)
> +		setbits_le32(&ccm->dram_clk_cfg, 0x1 << SUN4I_CCM_SDRAM_DCLK_OUT_OFFSET);
> +	else
> +		clrbits_le32(&ccm->dram_clk_cfg, 0x1 << SUN4I_CCM_SDRAM_DCLK_OUT_OFFSET);
> +#endif
> +}
> +
> +#ifdef CONFIG_SUN4I
> +static void dramc_set_autorefresh_cycle(u32 clk)
> +{
> +	struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
> +	u32 reg_val;
> +	u32 tmp_val;
> +	u32 dram_size;
> +
> +	if (clk < 600) {
> +		dram_size = readl(&dram->dcr);
> +		dram_size >>= 3;
> +		dram_size &= 0x7;
> +		if (dram_size <= 0x2)
> +			reg_val = (131 * clk) >> 10;
> +		else
> +			reg_val = (336 * clk) >> 10;
> +
> +		tmp_val = (7987 * clk) >> 10;
> +		tmp_val = tmp_val * 9 - 200;
> +		reg_val |= tmp_val << 8;
> +		reg_val |= 0x8 << 24;
> +		writel(reg_val, &dram->drr);
> +	} else {
> +		writel(0x0, &dram->drr);
> +	}
> +}
> +#endif /* SUN4I */
> +
> +#ifdef CONFIG_SUN5I
> +static void dramc_set_autorefresh_cycle(u32 clk)
> +{
> +	struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
> +	u32 reg_val;
> +	u32 tmp_val;
> +	reg_val = 131;
> +
> +	tmp_val = (7987 * clk) >> 10;
> +	tmp_val = tmp_val * 9 - 200;
> +	reg_val |= tmp_val << 8;
> +	reg_val |= 0x8 << 24;
> +	writel(reg_val, &dram->drr);
> +}
> +#endif /* SUN5I */
> +
> +int dramc_init(struct dram_para *para)
> +{
> +	struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
> +	u32 reg_val;
> +	int ret_val;
> +
> +	/* check input dram parameter structure */
> +	if (!para)
> +		return -1;
> +
> +	/* setup DRAM relative clock */
> +	mctl_setup_dram_clock(para->clock);
> +
> +#ifdef CONFIG_SUN5I
> +	/* Disable any pad power save control */
> +	writel(0, &dram->ppwrsctl);
> +#endif
> +
> +	/* reset external DRAM */
> +	mctl_ddr3_reset();
> +	mctl_set_drive();
> +
> +	/* dram clock off */
> +	dramc_clock_output_en(0);
> +
> +#ifdef CONFIG_SUN4I
> +	/* select dram controller 1 */
> +	writel(0x16237495, &dram->csel);
> +#endif
> +
> +	mctl_itm_disable();
> +	mctl_enable_dll0();
> +
> +	/* configure external DRAM */
> +	reg_val = 0;
> +	if (para->type == 3)
> +		reg_val |= 0x1;
> +	reg_val |= (para->io_width >> 3) << 1;
> +
> +	if (para->density == 256)
> +		reg_val |= 0x0 << 3;
> +	else if (para->density == 512)
> +		reg_val |= 0x1 << 3;
> +	else if (para->density == 1024)
> +		reg_val |= 0x2 << 3;
> +	else if (para->density == 2048)
> +		reg_val |= 0x3 << 3;
> +	else if (para->density == 4096)
> +		reg_val |= 0x4 << 3;
> +	else if (para->density == 8192)
> +		reg_val |= 0x5 << 3;
> +	else
> +		reg_val |= 0x0 << 3;
> +
> +	reg_val |= ((para->bus_width >> 3) - 1) << 6;
> +
> +	reg_val |= (para->rank_num - 1) << 10;
> +
> +	reg_val |= 0x1 << 12;
> +	reg_val |= ((0x1) & 0x3) << 13;
> +
> +	writel(reg_val, &dram->dcr);
> +
> +#ifdef CONFIG_SUN5I
> +	/* set odt impendance divide ratio */
> +	reg_val = ((para->zq) >> 8) & 0xfffff;
> +	reg_val |= ((para->zq) & 0xff) << 20;
> +	reg_val |= (para->zq) & 0xf0000000;
> +	writel(reg_val, &dram->zqcr0);
> +#endif
> +
> +	/* dram clock on */
> +	dramc_clock_output_en(1);
> +
> +	sdelay(0x10);
> +
> +	while (readl(&dram->ccr) & (0x1U << 31))
> +		;
> +
> +	mctl_enable_dllx();
> +
> +#ifdef CONFIG_SUN4I
> +	/* set odt impendance divide ratio */
> +	reg_val = ((para->zq) >> 8) & 0xfffff;
> +	reg_val |= ((para->zq) & 0xff) << 20;
> +	reg_val |= (para->zq) & 0xf0000000;
> +	writel(reg_val, &dram->zqcr0);
> +#endif
> +
> +#ifdef CONFIG_SUN4I
> +	/* set I/O configure register */
> +	reg_val = 0x00cc0000;
> +	reg_val |= (para->odt_en) & 0x3;
> +	reg_val |= ((para->odt_en) & 0x3) << 30;
> +	writel(reg_val, &dram->iocr);
> +#endif
> +
> +	/* set refresh period */
> +	dramc_set_autorefresh_cycle(para->clock);
> +
> +	/* set timing parameters */
> +	writel(para->tpr0, &dram->tpr0);
> +	writel(para->tpr1, &dram->tpr1);
> +	writel(para->tpr2, &dram->tpr2);
> +
> +	/* set mode register */
> +	if (para->type == 3) {
> +		/* ddr3 */
> +		reg_val = 0x0;
> +#ifdef CONFIG_SUN5I
> +		reg_val |= 0x1000;
> +#endif
> +		reg_val |= (para->cas - 4) << 4;
> +		reg_val |= 0x5 << 9;
> +	} else if (para->type == 2) {
> +		/* ddr2 */
> +		reg_val = 0x2;
> +		reg_val |= para->cas << 4;
> +		reg_val |= 0x5 << 9;
> +	}
> +	writel(reg_val, &dram->mr);
> +
> +	writel(para->emr1, &dram->emr);
> +	writel(para->emr2, &dram->emr2);
> +	writel(para->emr3, &dram->emr3);
> +
> +	/* set DQS window mode */
> +	clrsetbits_le32(&dram->ccr, 0x1U << 17, 0x1U << 14);
> +
> +	/* initial external DRAM */
> +	setbits_le32(&dram->ccr, 0x1U << 31);
> +
> +	while (readl(&dram->ccr) & (0x1U << 31))
> +		;
> +
> +	/* scan read pipe value */
> +	mctl_itm_enable();
> +	ret_val = dramc_scan_readpipe();
> +
> +	if (ret_val < 0)
> +		return 0;
> +
> +	/* configure all host port */
> +	mctl_configure_hostport();
> +
> +	return get_ram_size((long *)PHYS_SDRAM_1, 1 << 30);
> +}
> diff --git a/arch/arm/cpu/armv7/sunxi/u-boot-spl.lds b/arch/arm/cpu/armv7/sunxi/u-boot-spl.lds
> new file mode 100644
> index 0000000..cb418e1
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/sunxi/u-boot-spl.lds
> @@ -0,0 +1,63 @@
> +/*
> + * (C) Copyright 2002
> + * Gary Jennejohn, DENX Software Engineering, <garyj@denx.de>
> + *
> + * (C) Copyright 2010
> + * Texas Instruments, <www.ti.com>
> + *	Aneesh V <aneesh@ti.com>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +MEMORY { .sram : ORIGIN = CONFIG_SPL_TEXT_BASE,\
> +		LENGTH = CONFIG_SPL_MAX_SIZE }
> +MEMORY { .sdram : ORIGIN = CONFIG_SPL_BSS_START_ADDR, \
> +		LENGTH = CONFIG_SPL_BSS_MAX_SIZE }
> +
> +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
> +OUTPUT_ARCH(arm)
> +ENTRY(_start)
> +SECTIONS
> +{
> +	.text      :
> +	{
> +		__start = .;
> +		arch/arm/cpu/armv7/start.o	(.text)
> +		*(.text*)
> +	} > .sram
> +
> +	. = ALIGN(4);
> +	.rodata : { *(SORT_BY_ALIGNMENT(.rodata*)) } >.sram
> +
> +	. = ALIGN(4);
> +	.data : { *(SORT_BY_ALIGNMENT(.data*)) } >.sram
> +
> +	. = ALIGN(4);
> +	__image_copy_end = .;
> +	_end = .;
> +
> +	.bss :
> +	{
> +		. = ALIGN(4);
> +		__bss_start = .;
> +		*(.bss*)
> +		. = ALIGN(4);
> +		__bss_end__ = .;
> +	} > .sdram
> +}
> diff --git a/arch/arm/include/asm/arch-sunxi/spl.h b/arch/arm/include/asm/arch-sunxi/spl.h
> new file mode 100644
> index 0000000..404e16a
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-sunxi/spl.h
> @@ -0,0 +1,34 @@
> +/*
> + * (C) Copyright 2012
> + * Texas Instruments, <www.ti.com>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +#ifndef	_ASM_ARCH_SPL_H_
> +#define	_ASM_SPL_H_
> +
> +#define BOOT_DEVICE_NONE	0
> +#define BOOT_DEVICE_XIP		1
> +#define BOOT_DEVICE_NAND	2
> +#define BOOT_DEVICE_ONE_NAND	3
> +#define BOOT_DEVICE_MMC2	5 /*emmc*/

Add spaces in comment above.

> +#define BOOT_DEVICE_MMC1	6
> +#define BOOT_DEVICE_XIPWAIT	7
> +#define BOOT_DEVICE_MMC2_2      0xFF
> +#endif
> diff --git a/board/sunxi/board.c b/board/sunxi/board.c
> index 50fb40f..b917a0a 100644
> --- a/board/sunxi/board.c
> +++ b/board/sunxi/board.c
> @@ -64,3 +64,49 @@ int board_mmc_init(bd_t *bis)
>  	return 0;
>  }
>  #endif
> +
> +#ifdef CONFIG_SPL_BUILD
> +void sunxi_board_init(void)
> +{
> +	int power_failed = 0;
> +	int ramsize;
> +
> +	printf("DRAM:");
> +	ramsize = sunxi_dram_init();
> +	if (!ramsize) {
> +		printf(" ?");
> +		ramsize = sunxi_dram_init();
> +	}
> +	if (!ramsize) {
> +		printf(" ?");
> +		ramsize = sunxi_dram_init();
> +	}
> +	printf(" %dMB\n", ramsize>>20);
> +	if (!ramsize)
> +		hang();
> +
> +#ifdef CONFIG_AXP209_POWER
> +	power_failed |= axp209_init();
> +	power_failed |= axp209_set_dcdc2(1400);
> +	power_failed |= axp209_set_dcdc3(1250);
> +	power_failed |= axp209_set_ldo2(3000);
> +	power_failed |= axp209_set_ldo3(2800);
> +	power_failed |= axp209_set_ldo4(2800);
> +#endif
> +
> +	/*
> +	 * Only clock up the CPU to full speed if we are reasonably
> +	 * assured it's being powered with suitable core voltage
> +	 */
> +	if (!power_failed)
> +		clock_set_pll1(1008000000);
> +}
> +
> +#ifdef CONFIG_SPL_DISPLAY_PRINT
> +void spl_display_print(void)
> +{
> +	printf("Board: %s\n", CONFIG_SYS_BOARD_NAME);
> +}
> +#endif
> +
> +#endif
> diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
> index bc1f200..b0dcfdb 100644
> --- a/include/configs/sunxi-common.h
> +++ b/include/configs/sunxi-common.h
> @@ -134,7 +134,7 @@
>   */
>  #define CONFIG_SYS_NO_FLASH
>  
> -#define CONFIG_SYS_MONITOR_LEN		(256 << 10)	/* 256 KB */
> +#define CONFIG_SYS_MONITOR_LEN		(512 << 10)	/* 512 KB */
>  #define CONFIG_IDENT_STRING		" Allwinner Technology "
>  
>  #define CONFIG_ENV_OFFSET		(544 << 10) /* (8 + 24 + 512)KB */
> @@ -190,6 +190,30 @@
>  #define CONFIG_CMD_EXT4		/* with this we can access ext4 bootfs */
>  #define CONFIG_CMD_ZFS		/* with this we can access ZFS bootfs */
>  
> +#define CONFIG_SPL_FRAMEWORK
> +#define CONFIG_SPL_BSS_START_ADDR	0x50000000
> +#define CONFIG_SPL_BSS_MAX_SIZE		0x80000		/* 512 KB */
> +
> +#define CONFIG_SPL_TEXT_BASE		0x20		/* sram start+header */
> +#define CONFIG_SPL_MAX_SIZE		0x8000		/* 32 KB */
> +
> +#define CONFIG_SPL_LIBCOMMON_SUPPORT
> +#define CONFIG_SPL_LIBDISK_SUPPORT
> +#define CONFIG_SPL_SERIAL_SUPPORT
> +#define CONFIG_SPL_LIBGENERIC_SUPPORT
> +#define CONFIG_SPL_MMC_SUPPORT
> +#define CONFIG_SPL_DISPLAY_PRINT
> +
> +/* end of 24KB in sram */
> +#define LOW_LEVEL_SRAM_STACK		0x00006000
> +#define CONFIG_SPL_STACK		LOW_LEVEL_SRAM_STACK
> +#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv7/sunxi/u-boot-spl.lds"
> +
> +/* 32KB offset */
> +#define CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR	64
> +/* SPL starts at offset 8KiB im MMC and has the size of 24KiB */
> +#define CONFIG_SPL_PAD_TO		24576		/* decimal for 'dd' */
> +
>  #undef CONFIG_CMD_FPGA
>  #undef CONFIG_CMD_NET
>  #undef CONFIG_CMD_NFS
> @@ -210,4 +234,8 @@
>  #define CONFIG_SUNXI_GPIO
>  #define CONFIG_CMD_GPIO
>  
> +/* PMU */
> +#define CONFIG_SPL_POWER_SUPPORT
> +#define CONFIG_AXP209_POWER
> +
>  #endif /* __CONFIG_H */
> diff --git a/spl/Makefile b/spl/Makefile
> index 3195390..74d27b1 100644
> --- a/spl/Makefile
> +++ b/spl/Makefile
> @@ -126,6 +126,10 @@ ifdef CONFIG_SAMSUNG
>  ALL-y	+= $(obj)$(BOARD)-spl.bin
>  endif
>  
> +ifdef CONFIG_SUNXI
> +ALL-y	+= $(obj)sunxi-spl.bin
> +endif
> +
>  all:	$(ALL-y)
>  
>  ifdef CONFIG_SAMSUNG
> @@ -134,6 +138,12 @@ $(obj)$(BOARD)-spl.bin: $(obj)u-boot-spl.bin
>  		$(obj)u-boot-spl.bin $(obj)$(BOARD)-spl.bin
>  endif
>  
> +ifdef CONFIG_SUNXI
> +$(obj)sunxi-spl.bin: $(obj)u-boot-spl.bin
> +	$(OBJTREE)/tools/mksunxiboot \
> +		$(obj)u-boot-spl.bin $(obj)sunxi-spl.bin
> +endif
> +
>  $(obj)u-boot-spl.bin:	$(obj)u-boot-spl
>  	$(OBJCOPY) $(OBJCFLAGS) -O binary $< $@
>  
> -- 
> 1.7.7.6

Luka

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 12/22] ARM sunxi: SPL support for Olimex A13-OLinuXino board
  2012-11-25 11:44 ` [U-Boot] [PATCH 12/22] ARM sunxi: SPL support for Olimex A13-OLinuXino board Henrik Nordström
@ 2012-11-25 15:17   ` Luka Perkov
  0 siblings, 0 replies; 68+ messages in thread
From: Luka Perkov @ 2012-11-25 15:17 UTC (permalink / raw)
  To: u-boot

Hi Henrik,

On Sun, Nov 25, 2012 at 12:44:40PM +0100, Henrik Nordstr?m wrote:
> Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>
> ---
>  board/sunxi/Makefile             |    1 +
>  board/sunxi/dram_a13_olinuxino.c |   31 +++++++++++++++++++++++++++++++
>  boards.cfg                       |    1 +
>  3 files changed, 33 insertions(+), 0 deletions(-)
>  create mode 100644 board/sunxi/dram_a13_olinuxino.c
> 
> diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile
> index 43acbab..0351935 100644
> --- a/board/sunxi/Makefile
> +++ b/board/sunxi/Makefile
> @@ -26,6 +26,7 @@ include $(TOPDIR)/config.mk
>  LIB	:= $(obj)lib$(BOARD).o
>  
>  COBJS-y	:= board.o
> +COBJS-$(CONFIG_A13_OLINUXINO)	+= dram_a13_olinuxino.o
>  
>  COBJS	:= $(COBJS-y)
>  SRCS 	:= $(COBJS:.o=.c)
> diff --git a/board/sunxi/dram_a13_olinuxino.c b/board/sunxi/dram_a13_olinuxino.c
> new file mode 100644
> index 0000000..12b66d9
> --- /dev/null
> +++ b/board/sunxi/dram_a13_olinuxino.c
> @@ -0,0 +1,31 @@
> +/* this file is generated, don't edit it yourself */

How is was file generated ?

Despite the file being generated I think we should add copyrigt on top.

Same goes for all other board files...

> +
> +#include <common.h>
> +#include <asm/arch/dram.h>
> +
> +static struct dram_para dram_para = {
> +	.clock = 408,
> +	.type = 3,
> +	.rank_num = 1,
> +	.density = 2048,
> +	.io_width = 8,
> +	.bus_width = 16,
> +	.cas = 9,
> +	.zq = 123,
> +	.odt_en = 0,
> +	.size = 512,
> +	.tpr0 = 0x42d899b7,
> +	.tpr1 = 0xa090,
> +	.tpr2 = 0x22a00,
> +	.tpr3 = 0,
> +	.tpr4 = 0,
> +	.tpr5 = 0,
> +	.emr1 = 0,
> +	.emr2 = 0x10,
> +	.emr3 = 0,
> +};
> +
> +int sunxi_dram_init(void)
> +{
> +	return dramc_init(&dram_para);
> +}
> diff --git a/boards.cfg b/boards.cfg
> index 13d1f74..0db382d 100644
> --- a/boards.cfg
> +++ b/boards.cfg
> @@ -288,6 +288,7 @@ whistler                     arm         armv7:arm720t whistler          nvidia
>  colibri_t20_iris             arm         armv7:arm720t colibri_t20_iris  toradex        tegra20
>  u8500_href                   arm         armv7       u8500               st-ericsson    u8500
>  snowball                     arm         armv7       snowball               st-ericsson    u8500
> +A13-OLinuXino                arm         armv7       sunxi               -              sunxi       sun5i:A13_OLINUXINO,SPL
>  sun4i                        arm         armv7       sunxi               -              sunxi       sun4i
>  sun4i_sdcon                  arm         armv7       sunxi               -              sunxi       sun4i:UART0_PORT_F
>  sun5i                        arm         armv7       sunxi               -              sunxi       sun5i
> -- 
> 1.7.7.6
> 
> 
> _______________________________________________
> U-Boot mailing list
> U-Boot at lists.denx.de
> http://lists.denx.de/mailman/listinfo/u-boot

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 02/22] ARM: sunxi: MMC driver
  2012-11-25 14:33   ` Luka Perkov
@ 2012-11-25 15:39     ` Henrik Nordström
  2012-11-25 17:07       ` Luka Perkov
  2012-11-25 19:58       ` Wolfgang Denk
  2012-11-25 19:56     ` Wolfgang Denk
  1 sibling, 2 replies; 68+ messages in thread
From: Henrik Nordström @ 2012-11-25 15:39 UTC (permalink / raw)
  To: u-boot

s?n 2012-11-25 klockan 15:33 +0100 skrev Luka Perkov:
> > +#define MMCDBG(fmt...)	printf("[mmc]: "fmt)
> 
> Why not reuse something from existing uboot code ? (exaple from api/api.c):
> 
>  
>  53 #ifdef DEBUG
>  54 #define debugf(fmt, args...) do { printf("%s(): ", __func__); printf(fmt, ##args); } while (0)
>  55 #else
>  56 #define debugf(fmt, args...)
>  57 #endif

Because it's not in a reusable header?

But should at least use up to date syntax, and debug() instead of
printf, and less #ifdefs.

What about this:

#define MMCDBG(fmt, args...)        debug("[sunxi_mmc] " fmt, ##args)

and printf() changed to debug() in the other debug helpers, and no
#ifdefs, the compiler will sort it out nicely at -OS


> > +static void dumpmmcreg(struct sunxi_mmc *reg)
> > +{
> 
> I dont see this function is called anywhere...

Indeed. Current debug code dumps the register space in hex instead.

Added back a call as it's easier to decipher than the hex dump.

> > -#define CONFIG_ENV_OFFSET		(544 << 10)	/* (8 + 24 + 512)KB */
> > +#define CONFIG_ENV_OFFSET		(544 << 10) /* (8 + 24 + 512)KB */
> 
> The comment moving should go in the first patch.

Fixed.

Regards
Henrik

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 03/22] ARM sunxi: I2C driver
  2012-11-25 14:41   ` Luka Perkov
@ 2012-11-25 15:47     ` Henrik Nordström
  0 siblings, 0 replies; 68+ messages in thread
From: Henrik Nordström @ 2012-11-25 15:47 UTC (permalink / raw)
  To: u-boot

s?n 2012-11-25 klockan 15:41 +0100 skrev Luka Perkov:

> Why don't you do it like this:
> 
> #ifdef CONFIG_CMD_I2C
> #define CONFIG_SPL_I2C_SUPPORT
> #define CONFIG_SYS_I2C_SPEED		400000
> #define CONFIG_HARD_I2C
> #define CONFIG_SUNXI_I2C
> #define CONFIG_SYS_I2C_SLAVE		0x7f
> #endif /* CONFIG_CMD_I2C */
> 
> That way you can simply turn on i2c support in board configuration file.
> If users don't want/need i2c they don't need to use it.

SPL I2C support is orthogonal to CMD_I2C.

SPL needs I2C support for PMU control to configure the right CPU core
voltage and some other parameters.

Right now we only have one board which do not really need I2C driver in
SPL, all the others always need I2C driver enabled in SPL.

And we don't really have any board specific config files at the moment.
sunxi-common.h is the shared-by-all board config file, with sun4i.h and
sun5i.h being SoC generation dependent. The known boards are all so
similar that they can use the same main u-boot binary, almost even in
both SoC generations. 

SPL do differ noticeably in parameters from board to board.

Regards
Henrik

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 02/22] ARM: sunxi: MMC driver
  2012-11-25 15:39     ` Henrik Nordström
@ 2012-11-25 17:07       ` Luka Perkov
  2012-11-25 19:58       ` Wolfgang Denk
  1 sibling, 0 replies; 68+ messages in thread
From: Luka Perkov @ 2012-11-25 17:07 UTC (permalink / raw)
  To: u-boot

On Sun, Nov 25, 2012 at 04:39:03PM +0100, Henrik Nordstr?m wrote:
> s?n 2012-11-25 klockan 15:33 +0100 skrev Luka Perkov:
> > > +#define MMCDBG(fmt...)	printf("[mmc]: "fmt)
> > 
> > Why not reuse something from existing uboot code ? (exaple from api/api.c):
> > 
> >  
> >  53 #ifdef DEBUG
> >  54 #define debugf(fmt, args...) do { printf("%s(): ", __func__); printf(fmt, ##args); } while (0)
> >  55 #else
> >  56 #define debugf(fmt, args...)
> >  57 #endif
> 
> Because it's not in a reusable header?

I know, but it might be a good idea to put it somewhere there.

> But should at least use up to date syntax, and debug() instead of
> printf, and less #ifdefs.
> 
> What about this:
> 
> #define MMCDBG(fmt, args...)        debug("[sunxi_mmc] " fmt, ##args)
> 
> and printf() changed to debug() in the other debug helpers, and no
> #ifdefs, the compiler will sort it out nicely at -OS

I don't know. Maybe u-boot developers could tell us what is the best way
to do it...

Luka

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 07/22] tools: mksunixboot adding a Allwinner boot header
  2012-11-25 11:40 ` [U-Boot] [PATCH 07/22] tools: mksunixboot adding a Allwinner boot header Henrik Nordström
  2012-11-25 15:01   ` Luka Perkov
@ 2012-11-25 17:47   ` Wolfgang Denk
  1 sibling, 0 replies; 68+ messages in thread
From: Wolfgang Denk @ 2012-11-25 17:47 UTC (permalink / raw)
  To: u-boot

Dear Henrik Nordstr?m,

In message <1353843650.17518.18.camel@home.hno.se> you wrote:
> This tool adds a boot header to the supplied file, for booting
> code directly from the SoC embedded boot rom. Needed for making
> the SPL loader bootable.

Why do we need yet another "make file header" tool?  Why cannot this
be part of mkimage, for example?

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
My brother sent me a postcard the other day with this  big  sattelite
photo  of the entire earth on it. On the back it said: "Wish you were
here".                                                - Steven Wright

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 01/22] ARM: sunxi: Basic Allwinner A10/A13 (sun4i/sun5i) support
  2012-11-25 11:37 ` [U-Boot] [PATCH 01/22] ARM: sunxi: Basic Allwinner A10/A13 (sun4i/sun5i) support Henrik Nordström
  2012-11-25 12:23   ` Luka Perkov
@ 2012-11-25 18:06   ` Marek Vasut
  2012-11-26  0:21     ` Henrik Nordström
  2012-11-25 19:33   ` Wolfgang Denk
  2012-11-25 19:40   ` Wolfgang Denk
  3 siblings, 1 reply; 68+ messages in thread
From: Marek Vasut @ 2012-11-25 18:06 UTC (permalink / raw)
  To: u-boot

Dear Henrik Nordstr?m,

> This adds support for the Allwinner A10/A13 SoC's. Additionally
> board support for the dev-boards sun4i/sun5i is added.
> 
> Signed-off-by: Tom Cubie <tangliang@allwinnertech.com>
> Signed-off-by: Henrik Nordstr?m <henrik@henriknordstrom.net>
> Signed-off-by: Stefan Roese <sr@denx.de>

[..]

> +Henrik Nordstrom <henrik@henriknordstrom.net>
> +	A13_OLINUXINO	ARM V7 (Allwinner A13 SoC)
> +	A13_MID		ARM V7 (Allwinner A13 SoC)
> +	CUBIEBOARD	ARM V7 (Allwinner A10 SoC)
> +	CUBIEBOARD_512	ARM V7 (Allwinner A10 SoC)
> +	HACKBERRY	ARM V7 (Allwinner A10 SoC)
> +	MELE_A1000	ARM V7 (Allwinner A10 SoC)
> +	MINI-X		ARM V7 (Allwinner A10 SoC)
> +	SUN4I		ARM V7 (Allwinner A10 SoC)
> +	SUN4I_SDCON	ARM V7 (Allwinner A10 SoC)
> +	SUN5I		ARM V7 (Allwinner A13 SoC)
> +	SUN5I_SDCON	ARM V7 (Allwinner A13 SoC)

You're not adding these boards here yet ...

>  Kyle Moffett <Kyle.D.Moffett@boeing.com>
> 
>  	HWW1U1A		P2020
[...]

> diff --git a/arch/arm/cpu/armv7/sunxi/Makefile
> b/arch/arm/cpu/armv7/sunxi/Makefile new file mode 100644
> index 0000000..cbe1015
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/sunxi/Makefile
[...]

> +include $(TOPDIR)/config.mk
> +
> +LIB	=  $(obj)lib$(SOC).o
> +
> +SOBJS	+= reset.o
> +
> +COBJS	+= timer.o
> +COBJS	+= dram.o
> +COBJS	+= board.o
> +COBJS	+= clock.o
> +COBJS	+= pinmux.o

COBJS = x.o y.o z.o
works just fine

> +SRCS	:= $(SOBJS:.o=.S) $(COBJS:.o=.c)
> +OBJS	:= $(addprefix $(obj),$(COBJS) $(COBJS-y) $(SOBJS))
> +
> +all:	 $(obj).depend $(LIB)
> +
> +$(LIB):	$(OBJS)
> +	$(call cmd_link_o_target, $(OBJS))
> +
[...]

> +#ifndef CONFIG_SYS_DCACHE_OFF
> +void enable_caches(void)
> +{
> +	/* Enable D-cache. I-cache is already enabled in start.S */
> +	dcache_enable();

Why don't you enable them both? What if someone fiddled with them prior to 
reset?

> +}
> +#endif
[...]

> +	cfg = readl(&pio->cfg[0] + index);
> +	cfg &= ~(0xf << offset);
> +	cfg |= val << offset;
> +
> +	writel(cfg, &pio->cfg[0] + index);

clrsetbits_le32()

> +	return 0;
> +}
> +
> +int sunxi_gpio_get_cfgpin(u32 pin)
> +{
> +	u32 cfg;
> +	u32 bank = GPIO_BANK(pin);
> +	u32 index = GPIO_CFG_INDEX(pin);
> +	u32 offset = GPIO_CFG_OFFSET(pin);
> +	struct sunxi_gpio *pio =
> +	    &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank];
> +
> +	cfg = readl(&pio->cfg[0] + index);
> +	cfg >>= offset;

I think you want to put this into drivers/gpio, no?

> +	return cfg & 0xf;
> +}
> +
> diff --git a/arch/arm/cpu/armv7/sunxi/reset.S
> b/arch/arm/cpu/armv7/sunxi/reset.S new file mode 100644
> index 0000000..36714e7
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/sunxi/reset.S
[...]

> +#include <asm/arch/cpu.h>
> +
> +#define SUNXI_WDOG_CTL		0x01C20C90
> +#define SUNXI_WDOG_MODE		0x01C20C94
> +
> +.globl sunxi_reset
> +sunxi_reset:
> +	ldr r1, =SUNXI_WDOG_MODE
> +	mov r3, #0x3
> +	str r3, [r1]
> +	mov r0, r0
> +_loop_forever:
> +	b	_loop_forever

Put this into proper C code.

> diff --git a/arch/arm/cpu/armv7/sunxi/timer.c
> b/arch/arm/cpu/armv7/sunxi/timer.c new file mode 100644
> index 0000000..e19df09
> --- /dev/null
> +++ b/arch/arm/cpu/armv7/sunxi/timer.c
> @@ -0,0 +1,117 @@
[...]

> +/* delay x useconds */

proper kerneldoc all around won't hurt.

> +void __udelay(unsigned long usec)
> +{
> +	long tmo = usec * (TIMER_CLOCK / 1000) / 1000;
> +	ulong now, last = READ_TIMER();
> +
> +	while (tmo > 0) {
> +		now = READ_TIMER();
> +		if (now > last)	/* normal (non rollover) */
> +			tmo -= now - last;
> +		else		/* rollover */
> +			tmo -= TIMER_LOAD_VAL - last + now;
> +		last = now;
> +	}
> +}
> +
> +/*
> + * This function is derived from PowerPC code (read timebase as long
> long). + * On ARM it just returns the timer value.
> + */
> +unsigned long long get_ticks(void)
> +{
> +	return get_timer(0);
> +}
[...]

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 02/22] ARM: sunxi: MMC driver
  2012-11-25 11:37 ` [U-Boot] [PATCH 02/22] ARM: sunxi: MMC driver Henrik Nordström
  2012-11-25 14:33   ` Luka Perkov
@ 2012-11-25 18:09   ` Marek Vasut
  2012-11-25 19:44   ` Wolfgang Denk
  2 siblings, 0 replies; 68+ messages in thread
From: Marek Vasut @ 2012-11-25 18:09 UTC (permalink / raw)
  To: u-boot

Dear Henrik Nordstr?m,

> This adds a basic MMC driver for Allwinner sun4i/sun5i family of SoC
> this driver is limited to a single MMC channel.
> 
> Signed-off-by: Tom Cubie <tangliang@allwinnertech.com>
> Signed-off-by: Henrik Nodstrom <henrik@henriknordstrom.net>
> Signed-off-by: Stefan Roese <sr@denx.de>
> ---
[...]

> +#undef SUNXI_MMCDBG

debug_cond() won't work for you ?
[...]

> +	case 0:
> +		/* D1-PF0, D0-PF1, CLK-PF2, CMD-PF3, D3-PF4, D4-PF5 */

Magic goo below?

> +		writel(0x222222, &gpio_f->cfg[0]);
> +		writel(0x555, &gpio_f->pull[0]);
> +		writel(0xaaa, &gpio_f->drv[0]);
> +		break;
> +
> +	case 1:
> +#if CONFIG_MMC1_PG
> +		/* PG0-CMD, PG1-CLK, PG2~5-D0~3 : 4 */
> +		writel(0x444444, &gpio_g->cfg[0]);
> +		writel(0x555, &gpio_g->pull[0]);
> +		writel(0xaaa, &gpio_g->drv[0]);
> +#else
> +		/* PH22-CMD, PH23-CLK, PH24~27-D0~D3 : 5 */
> +		writel(0x55 << 24, &gpio_h->cfg[2]);
> +		writel(0x5555, &gpio_h->cfg[3]);
> +		writel(0x555 << 12, &gpio_h->pull[1]);
> +		writel(0xaaa << 12, &gpio_h->drv[1]);
> +#endif
> +		break;
> +
> +	case 2:
> +		/* CMD-PC6, CLK-PC7, D0-PC8, D1-PC9, D2-PC10, D3-PC11 */
> +		writel(0x33 << 24, &gpio_c->cfg[0]);
> +		writel(0x3333, &gpio_c->cfg[1]);
> +		writel(0x555 << 12, &gpio_c->pull[0]);
> +		writel(0xaaa << 12, &gpio_c->drv[0]);
> +		break;
> +
> +	case 3:
> +		/* PI4-CMD, PI5-CLK, PI6~9-D0~D3 : 2 */
> +		writel(0x2222 << 16, &gpio_i->cfg[0]);
> +		writel(0x22, &gpio_i->cfg[1]);
> +		writel(0x555 << 8, &gpio_i->pull[0]);
> +		writel(0x555 << 8, &gpio_i->drv[0]);
> +		break;
> +
> +	default:
> +		return -1;
> +	}
> +
> +	/* config ahb clock */
> +	rval = readl(&ccm->ahb_gate0);
> +	rval |= (1 << (8 + sdc_no));
> +	writel(rval, &ccm->ahb_gate0);
> +
> +	/* config mod clock */
> +	pll5_clk = clock_get_pll5();
> +	if (pll5_clk > 400000000)
> +		divider = 4;
> +	else
> +		divider = 3;
> +	writel((1U << 31) | (2U << 24) | divider, mmchost->mclkreg);
> +	mmchost->mod_clk = pll5_clk / (divider + 1);
> +
> +	dumphex32("ccmu", (char *)SUNXI_CCM_BASE, 0x100);
> +	dumphex32("gpio", (char *)SUNXI_PIO_BASE, 0x100);
> +	dumphex32("mmc", (char *)mmchost->reg, 0x100);
> +
> +	return 0;
> +}
> +
> +static int mmc_update_clk(struct mmc *mmc)
> +{
> +	struct sunxi_mmc_host *mmchost = (struct sunxi_mmc_host *)mmc->priv;
> +	unsigned int cmd;
> +	unsigned timeout = 0xfffff;
> +
> +	cmd = (1U << 31) | (1 << 21) | (1 << 13);
> +	writel(cmd, &mmchost->reg->cmd);
> +	while ((readl(&mmchost->reg->cmd) & 0x80000000) && timeout--)
> +		;
> +	if (!timeout)
> +		return -1;
> +
> +	writel(readl(&mmchost->reg->rint), &mmchost->reg->rint);
> +
> +	return 0;
> +}
> +
> +static int mmc_config_clock(struct mmc *mmc, unsigned div)
> +{
> +	struct sunxi_mmc_host *mmchost = (struct sunxi_mmc_host *)mmc->priv;
> +	unsigned rval = readl(&mmchost->reg->clkcr);
> +
> +	/*
> +	 * CLKCREG[7:0]: divider
> +	 * CLKCREG[16]:  on/off
> +	 * CLKCREG[17]:  power save
> +	 */
> +	/* Disable Clock */
> +	rval &= ~(1 << 16);
> +	writel(rval, &mmchost->reg->clkcr);
> +	if (mmc_update_clk(mmc))
> +		return -1;
> +
> +	/* Change Divider Factor */
> +	rval &= ~(0xFF);
> +	rval |= div;
> +	writel(rval, &mmchost->reg->clkcr);
> +	if (mmc_update_clk(mmc))
> +		return -1;
> +	/* Re-enable Clock */
> +	rval |= (1 << 16);
> +	writel(rval, &mmchost->reg->clkcr);
> +
> +	if (mmc_update_clk(mmc))
> +		return -1;
> +
> +	return 0;
> +}
> +
> +static void mmc_set_ios(struct mmc *mmc)
> +{
> +	struct sunxi_mmc_host *mmchost = (struct sunxi_mmc_host *)mmc->priv;
> +	unsigned int clkdiv = 0;
> +
> +	MMCDBG("set ios: bus_width: %x, clock: %d, mod_clk\n", mmc->bus_width,
> +	       mmc->clock, mmchost->mod_clk);
> +
> +	/* Change clock first */
> +	clkdiv = (mmchost->mod_clk + (mmc->clock >> 1)) / mmc->clock / 2;
> +	if (mmc->clock)
> +		if (mmc_config_clock(mmc, clkdiv)) {
> +			mmchost->fatal_err = 1;
> +			return;
> +		}
> +
> +	/* Change bus width */
> +	if (mmc->bus_width == 8)
> +		writel(2, &mmchost->reg->width);
> +	else if (mmc->bus_width == 4)
> +		writel(1, &mmchost->reg->width);
> +	else
> +		writel(0, &mmchost->reg->width);
> +}
> +
> +static int mmc_core_init(struct mmc *mmc)
> +{
> +	struct sunxi_mmc_host *mmchost = (struct sunxi_mmc_host *)mmc->priv;
> +
> +	/* Reset controller */
> +	writel(0x7, &mmchost->reg->gctrl);
> +
> +	return 0;
> +}
> +
> +static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data)
> +{
> +	struct sunxi_mmc_host *mmchost = (struct sunxi_mmc_host *)mmc->priv;
> +	unsigned i;
> +	unsigned byte_cnt = data->blocksize * data->blocks;
> +	unsigned *buff;
> +	unsigned timeout = 0xfffff;
> +
> +	if (data->flags & MMC_DATA_READ) {
> +		buff = (unsigned int *)data->dest;
> +		for (i = 0; i < (byte_cnt >> 2); i++) {
> +			while (--timeout
> +			       && (readl(&mmchost->reg->status) & (1 << 2)))

More magic.

> +				;
> +			if (timeout <= 0)
> +				goto out;
> +			buff[i] = readl(mmchost->database);
> +			timeout = 0xfffff;
> +		}
> +	} else {
> +		buff = (unsigned int *)data->src;
> +		for (i = 0; i < (byte_cnt >> 2); i++) {
> +			while (--timeout
> +			       && (readl(&mmchost->reg->status) & (1 << 3)))
> +				;
> +			if (timeout <= 0)
> +				goto out;
> +			writel(buff[i], mmchost->database);
> +			timeout = 0xfffff;
> +		}
> +	}
> +
> +out:
> +	if (timeout <= 0)
> +		return -1;
> +
> +	return 0;
> +}
> +
[...]

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 03/22] ARM sunxi: I2C driver
  2012-11-25 11:38 ` [U-Boot] [PATCH 03/22] ARM sunxi: I2C driver Henrik Nordström
  2012-11-25 14:41   ` Luka Perkov
@ 2012-11-25 18:11   ` Marek Vasut
  2012-11-25 19:47   ` Wolfgang Denk
  2012-11-26 11:13   ` Heiko Schocher
  3 siblings, 0 replies; 68+ messages in thread
From: Marek Vasut @ 2012-11-25 18:11 UTC (permalink / raw)
  To: u-boot

Dear Henrik Nordstr?m,

[...]

> +static struct i2c __attribute__ ((section(".data"))) *i2c_base =
> +	(struct i2c *)0x1c2ac00;

I dont think you need this workaround at all ... just stick it into the 
function, it's a static constant (and #define the constant please)

> +
> +void i2c_init(int speed, int slaveaddr)
> +{
> +	sunxi_gpio_set_cfgpin(SUNXI_GPB(0), 2);
> +	sunxi_gpio_set_cfgpin(SUNXI_GPB(1), 2);
> +	clock_twi_onoff(0, 1);
> +
> +	/* Enable the i2c bus */
> +	writel(TWI_CTL_BUSEN, &i2c_base->ctl);
> +
> +	/* 400KHz operation M=2, N=1, 24MHz APB clock */
> +	writel(TWI_CLK_DIV(2, 1), &i2c_base->clkr);
> +	writel(TWI_SRST_SRST, &i2c_base->reset);
> +
> +	while ((readl(&i2c_base->reset) & TWI_SRST_SRST))
> +		;
> +}
> +
> +int i2c_probe(uchar chip)
> +{

How can this even work?

> +	return -1;
> +}
> +
> +static int i2c_wait_ctl(int mask, int state)
> +{
> +	int timeout = 0x2ff;
> +	int value = state ? mask : 0;
> +
> +	debug("i2c_wait_ctl(%x == %x), ctl=%x, status=%x\n", mask, value,
> +	      i2c_base->ctl, i2c_base->status);
> +
> +	while (((readl(&i2c_base->ctl) & mask) != value) && timeout-- > 0)
> +		;


What about you change these to :

while (!--timeout) {
 if (readl...)
  break;
}

To make it more readable ?

> +
> +	debug("i2c_wait_ctl(), timeout=%d, ctl=%x, status=%x\n", timeout,
> +	      i2c_base->ctl, i2c_base->status);
> +
> +	if (timeout != 0)
> +		return 0;
> +	else
> +		return -1;
> +}
> +
> +static void i2c_clear_irq(void)
> +{
> +	writel(readl(&i2c_base->ctl) & ~TWI_CTL_INTFLG, &i2c_base->ctl);

clrbits_le32()

> +}
> +
[...]

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 05/22] power: Add AXP209 Power Management controller (I2C)
  2012-11-25 11:39 ` [U-Boot] [PATCH 05/22] power: Add AXP209 Power Management controller (I2C) Henrik Nordström
  2012-11-25 14:44   ` Luka Perkov
@ 2012-11-25 18:13   ` Marek Vasut
  2012-11-25 19:48   ` Wolfgang Denk
  2 siblings, 0 replies; 68+ messages in thread
From: Marek Vasut @ 2012-11-25 18:13 UTC (permalink / raw)
  To: u-boot

Dear Henrik Nordstr?m,

> This adds support for AXP209 Power Management controller,
> used by most sunxi (Allwinner A10/A13) based boards.
> 
> From: Henrik Nordstrom <henrik@henriknordstrom.net>
> Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>
> Signed-off-by: Stefan Roese <sr@denx.de>
> ---
>  drivers/power/Makefile |    1 +
>  drivers/power/axp209.c |  183
> ++++++++++++++++++++++++++++++++++++++++++++++++ include/axp209.h       | 
>  29 ++++++++
>  3 files changed, 213 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/power/axp209.c
>  create mode 100644 include/axp209.h

Did you not reference this header in 01/22 ?

[...]

Is it possible to at least #define the magic constants ?

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 06/22] ARM sunxi: Basic GPIO driver
  2012-11-25 11:40 ` [U-Boot] [PATCH 06/22] ARM sunxi: Basic GPIO driver Henrik Nordström
  2012-11-25 14:52   ` Luka Perkov
@ 2012-11-25 18:14   ` Marek Vasut
  2012-11-25 19:50   ` Wolfgang Denk
  2 siblings, 0 replies; 68+ messages in thread
From: Marek Vasut @ 2012-11-25 18:14 UTC (permalink / raw)
  To: u-boot

Dear Henrik Nordstr?m,

> GPIO driver for Allwinner sun4i/sun5i family of SoCs
> 
> GPIO Pins are named by their symbolic pin names P<g><#>
> such as PH19 or H19.
> 
> Note: This do not perform any validation if the pin is in use
> for some other I/O function. Use with care.
> ---
>  arch/arm/include/asm/arch-sunxi/gpio.h |    2 +
>  drivers/gpio/Makefile                  |    1 +
>  drivers/gpio/sunxi_gpio.c              |  116
> ++++++++++++++++++++++++++++++++ include/configs/sunxi-common.h         | 
>   4 +
>  4 files changed, 123 insertions(+), 0 deletions(-)
>  create mode 100644 drivers/gpio/sunxi_gpio.c
> 
> diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h
> b/arch/arm/include/asm/arch-sunxi/gpio.h index fceee6b..a3f8a74 100644
> --- a/arch/arm/include/asm/arch-sunxi/gpio.h
> +++ b/arch/arm/include/asm/arch-sunxi/gpio.h
> @@ -160,5 +160,7 @@ enum sunxi_gpio_number {
> 
>  int sunxi_gpio_set_cfgpin(u32 pin, u32 val);
>  int sunxi_gpio_get_cfgpin(u32 pin);
> +int name_to_gpio(const char *name);
> +#define name_to_gpio	name_to_gpio
> 
>  #endif /* _SUNXI_GPIO_H */
> diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
> index d50ac3b..6d692e6 100644
> --- a/drivers/gpio/Makefile
> +++ b/drivers/gpio/Makefile
> @@ -45,6 +45,7 @@ COBJS-$(CONFIG_OMAP_GPIO)	+= omap_gpio.o
>  COBJS-$(CONFIG_DB8500_GPIO)	+= db8500_gpio.o
>  COBJS-$(CONFIG_BCM2835_GPIO)	+= bcm2835_gpio.o
>  COBJS-$(CONFIG_S3C2440_GPIO)	+= s3c2440_gpio.o
> +COBJS-$(CONFIG_SUNXI_GPIO)	+= sunxi_gpio.o
> 
>  COBJS	:= $(COBJS-y)
>  SRCS 	:= $(COBJS:.o=.c)
> diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c
> new file mode 100644
> index 0000000..d99071e
> --- /dev/null
> +++ b/drivers/gpio/sunxi_gpio.c
> @@ -0,0 +1,116 @@
> +/*
> + * (C) Copyright 2007-2011
> + * Allwinner Technology Co., Ltd. <www.allwinnertech.com>
> + * Tom Cubie <tangliang@allwinnertech.com>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include <common.h>
> +#include <asm/io.h>
> +#include <asm/gpio.h>
> +
> +static int sunxi_gpio_output(u32 pin, u32 val)
> +{
> +	u32 dat;
> +	u32 bank = GPIO_BANK(pin);
> +	u32 num = GPIO_NUM(pin);
> +	struct sunxi_gpio *pio =
> +	    &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank];
> +
> +	dat = readl(&pio->dat);
> +	if (val)
> +		dat |= 1 << num;
> +	else
> +		dat &= ~(1 << num);


clrbits_le32() / setbits_le32() ...

> +	writel(dat, &pio->dat);
> +
> +	return 0;
> +}
[...]

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 01/22] ARM: sunxi: Basic Allwinner A10/A13 (sun4i/sun5i) support
  2012-11-25 11:37 ` [U-Boot] [PATCH 01/22] ARM: sunxi: Basic Allwinner A10/A13 (sun4i/sun5i) support Henrik Nordström
  2012-11-25 12:23   ` Luka Perkov
  2012-11-25 18:06   ` Marek Vasut
@ 2012-11-25 19:33   ` Wolfgang Denk
  2012-11-25 23:53     ` Henrik Nordström
  2012-11-25 19:40   ` Wolfgang Denk
  3 siblings, 1 reply; 68+ messages in thread
From: Wolfgang Denk @ 2012-11-25 19:33 UTC (permalink / raw)
  To: u-boot

Dear Henrik Nordstr?m,

In message <1353843450.17518.13.camel@home.hno.se> you wrote:
> This adds support for the Allwinner A10/A13 SoC's. Additionally
> board support for the dev-boards sun4i/sun5i is added.
> 
> Signed-off-by: Tom Cubie <tangliang@allwinnertech.com>
> Signed-off-by: Henrik Nordstr?m <henrik@henriknordstrom.net>
> Signed-off-by: Stefan Roese <sr@denx.de>

Where exactly is Stefan's SoB coming from?  I don't think I have seen
this here on the list before?

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Philosophy:  A route of many roads leading from nowhere to nothing.
- Ambrose Bierce

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 01/22] ARM: sunxi: Basic Allwinner A10/A13 (sun4i/sun5i) support
  2012-11-25 11:37 ` [U-Boot] [PATCH 01/22] ARM: sunxi: Basic Allwinner A10/A13 (sun4i/sun5i) support Henrik Nordström
                     ` (2 preceding siblings ...)
  2012-11-25 19:33   ` Wolfgang Denk
@ 2012-11-25 19:40   ` Wolfgang Denk
  3 siblings, 0 replies; 68+ messages in thread
From: Wolfgang Denk @ 2012-11-25 19:40 UTC (permalink / raw)
  To: u-boot

Dear Henrik Nordstr?m,

In message <1353843450.17518.13.camel@home.hno.se> you wrote:
> This adds support for the Allwinner A10/A13 SoC's. Additionally
> board support for the dev-boards sun4i/sun5i is added.
...
> +/* Return PLL5 frequency in Hz
> + * Note: Assumes PLL5 reference is 24MHz clock
> + */

Incorrect multiline comment style. Please fix globally.


> diff --git a/include/configs/sun4i.h b/include/configs/sun4i.h
> new file mode 100644
> index 0000000..513f618
...
> +#define CONFIG_MACH_TYPE		4104

NAK.

Please use value from mach-types.h ; if needed, ask for an update.

> diff --git a/include/configs/sun5i.h b/include/configs/sun5i.h
> new file mode 100644
> index 0000000..dc84aba
...
> +#define CONFIG_MACH_TYPE		4138

Ditto.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
"It may be that our role on this planet is not to worship God but  to
create him."                                       - Arthur C. Clarke

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 02/22] ARM: sunxi: MMC driver
  2012-11-25 11:37 ` [U-Boot] [PATCH 02/22] ARM: sunxi: MMC driver Henrik Nordström
  2012-11-25 14:33   ` Luka Perkov
  2012-11-25 18:09   ` Marek Vasut
@ 2012-11-25 19:44   ` Wolfgang Denk
  2 siblings, 0 replies; 68+ messages in thread
From: Wolfgang Denk @ 2012-11-25 19:44 UTC (permalink / raw)
  To: u-boot

Dear Henrik Nordstr?m,

In message <1353843479.17518.14.camel@home.hno.se> you wrote:
> This adds a basic MMC driver for Allwinner sun4i/sun5i family of SoC
> this driver is limited to a single MMC channel.
> 
> Signed-off-by: Tom Cubie <tangliang@allwinnertech.com>
> Signed-off-by: Henrik Nodstrom <henrik@henriknordstrom.net>
> Signed-off-by: Stefan Roese <sr@denx.de>

???

> --- a/drivers/mmc/Makefile
> +++ b/drivers/mmc/Makefile
> @@ -47,6 +47,7 @@ COBJS-$(CONFIG_S5P_SDHCI) += s5p_sdhci.o
>  COBJS-$(CONFIG_SH_MMCIF) += sh_mmcif.o
>  COBJS-$(CONFIG_TEGRA_MMC) += tegra_mmc.o
>  COBJS-$(CONFIG_DWMMC) += dw_mmc.o
> +COBJS-$(CONFIG_MMC_SUNXI) += sunxi_mmc.o

Please keep / make list sorted.

> diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c
> new file mode 100644
> index 0000000..05bc231
> --- /dev/null
> +++ b/drivers/mmc/sunxi_mmc.c
...
> +#undef SUNXI_MMCDBG
> +
> +#ifdef SUNXI_MMCDBG
> +#define MMCDBG(fmt...)	printf("[mmc]: "fmt)

Please do not invent your own debug facilities;  instead, use the
default ones.

As is, this all is dead code and should be removed.

> +static void dumphex32(char *name, char *base, int len)
> +{
> +	__u32 i;
> +
> +	printf("dump %s registers:", name);
> +	for (i = 0; i < len; i += 4) {
> +		if (!(i & 0xf))
> +			printf("\n0x%p : ", base + i);
> +		printf("0x%08x ", readl(base + i));
> +	}
> +	printf("\n");
> +}

And we do not have any code like that yet that could be reused?


Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Let the programmers be many and the managers few -- then all will  be
productive.               -- Geoffrey James, "The Tao of Programming"

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 03/22] ARM sunxi: I2C driver
  2012-11-25 11:38 ` [U-Boot] [PATCH 03/22] ARM sunxi: I2C driver Henrik Nordström
  2012-11-25 14:41   ` Luka Perkov
  2012-11-25 18:11   ` Marek Vasut
@ 2012-11-25 19:47   ` Wolfgang Denk
  2012-11-26 11:13   ` Heiko Schocher
  3 siblings, 0 replies; 68+ messages in thread
From: Wolfgang Denk @ 2012-11-25 19:47 UTC (permalink / raw)
  To: u-boot

Dear Henrik Nordstr?m,

In message <1353843526.17518.15.camel@home.hno.se> you wrote:
> A basic basic driver for the I2C controller found in Allwinner
> sunXi (A10 & A13) SoCs.
> 
> Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>
> Signed-off-by: Stefan Roese <sr@denx.de>

???

> +static struct i2c __attribute__ ((section(".data"))) *i2c_base =
> +	(struct i2c *)0x1c2ac00;

Why would the __attribute__ ((section(".data"))) be needed here???

> +	while ((readl(&i2c_base->reset) & TWI_SRST_SRST))
> +		;

No timeout?

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Ernest asks Frank how long he has been working for the company.
        "Ever since they threatened to fire me."

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 05/22] power: Add AXP209 Power Management controller (I2C)
  2012-11-25 11:39 ` [U-Boot] [PATCH 05/22] power: Add AXP209 Power Management controller (I2C) Henrik Nordström
  2012-11-25 14:44   ` Luka Perkov
  2012-11-25 18:13   ` Marek Vasut
@ 2012-11-25 19:48   ` Wolfgang Denk
  2 siblings, 0 replies; 68+ messages in thread
From: Wolfgang Denk @ 2012-11-25 19:48 UTC (permalink / raw)
  To: u-boot

Dear Henrik Nordstr?m,

In message <1353843579.17518.16.camel@home.hno.se> you wrote:
> This adds support for AXP209 Power Management controller,
> used by most sunxi (Allwinner A10/A13) based boards.
> 
> From: Henrik Nordstrom <henrik@henriknordstrom.net>
> Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>
> Signed-off-by: Stefan Roese <sr@denx.de>
...
> +extern int axp209_set_dcdc2(int mvolt);
> +extern int axp209_set_dcdc3(int mvolt);
> +extern int axp209_set_ldo2(int mvolt);
> +extern int axp209_set_ldo3(int mvolt);
> +extern int axp209_set_ldo4(int mvolt);
> +extern void axp209_poweroff(void);
> +extern int axp209_init(void);

Drop extern?

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Celestial navigation is based on the premise that the  Earth  is  the
center  of  the  universe.  The  premise is wrong, but the navigation
works. An incorrect model can be a useful tool.   - Kelvin Throop III

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 06/22] ARM sunxi: Basic GPIO driver
  2012-11-25 11:40 ` [U-Boot] [PATCH 06/22] ARM sunxi: Basic GPIO driver Henrik Nordström
  2012-11-25 14:52   ` Luka Perkov
  2012-11-25 18:14   ` Marek Vasut
@ 2012-11-25 19:50   ` Wolfgang Denk
  2012-11-25 21:47     ` Marek Vasut
  2012-11-25 23:41     ` Henrik Nordström
  2 siblings, 2 replies; 68+ messages in thread
From: Wolfgang Denk @ 2012-11-25 19:50 UTC (permalink / raw)
  To: u-boot

Dear Henrik Nordstr?m,

In message <1353843623.17518.17.camel@home.hno.se> you wrote:
> GPIO driver for Allwinner sun4i/sun5i family of SoCs
> 
> GPIO Pins are named by their symbolic pin names P<g><#>
> such as PH19 or H19.
> 
> Note: This do not perform any validation if the pin is in use
> for some other I/O function. Use with care.

SoB missing.


Um.... are these patches actually bisectable???  It appears not; for
example, you reference gpio_direction_input() in ealier patches, but
define it only now.

This patch series need a full rework.

Review stops here.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Knowledge, sir, should be free to all!
	-- Harry Mudd, "I, Mudd", stardate 4513.3

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 01/22] ARM: sunxi: Basic Allwinner A10/A13 (sun4i/sun5i) support
  2012-11-25 12:23   ` Luka Perkov
  2012-11-25 13:08     ` Henrik Nordström
@ 2012-11-25 19:52     ` Wolfgang Denk
  1 sibling, 0 replies; 68+ messages in thread
From: Wolfgang Denk @ 2012-11-25 19:52 UTC (permalink / raw)
  To: u-boot

Dear Luka Perkov,

In message <20121125122328-24964@mutt-kz> you wrote:
> 
> I have few comments bellow.

OK, but it is definitely NOT necessary to quote nearly 2000 lines of
the original patch, right?

Please restrict quoting to the minimum needed to provide context.

Thanks.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
"Virtual" means never knowing where your next byte is coming from.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 01/22] ARM: sunxi: Basic Allwinner A10/A13 (sun4i/sun5i) support
  2012-11-25 13:08     ` Henrik Nordström
@ 2012-11-25 19:55       ` Wolfgang Denk
  2012-11-26  1:05         ` [U-Boot] [PATCH 01/22] Re: Copyright on board makefiles Henrik Nordström
  0 siblings, 1 reply; 68+ messages in thread
From: Wolfgang Denk @ 2012-11-25 19:55 UTC (permalink / raw)
  To: u-boot

Dear Henrik Nordstr?m,

In message <1353848939.28559.13.camel@home.hno.se> you wrote:
>
> > > +# (C) Copyright 2000-2003
> > 
> > I don't know about the dates. It's 2012 now... Same goes for all other files.
> 
> Heh.. Not sure which board that was copied from.
> 
> Not sure what to set as copyright here. Can't say there have been any
> significant contributions by anyone in this file, but have updated the
> year to 2011-2012 to match current use.

You have changed a Copyright entry that was attributed to me?

Who exactly gave you the right to do that? 


Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
This is an unauthorized cybernetic announcement.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 02/22] ARM: sunxi: MMC driver
  2012-11-25 14:33   ` Luka Perkov
  2012-11-25 15:39     ` Henrik Nordström
@ 2012-11-25 19:56     ` Wolfgang Denk
  1 sibling, 0 replies; 68+ messages in thread
From: Wolfgang Denk @ 2012-11-25 19:56 UTC (permalink / raw)
  To: u-boot

Dear Luka Perkov,

In message <20121125143332-9180@mutt-kz> you wrote:
>
...
> Why not reuse something from existing uboot code ? (exaple from api/api.c):
> 
>  36 #define DEBUG
>  37 #undef DEBUG

NAK.  Please never ever do that. 

>  53 #ifdef DEBUG
>  54 #define debugf(fmt, args...) do { printf("%s(): ", __func__); printf(fm=
> t, ##args); } while (0)
>  55 #else
>  56 #define debugf(fmt, args...)
>  57 #endif

More NAK!!! We have standard debug utilities, and do not need to
reinvent the wheel every time we come around.


Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Looks clean and obviously correct to me, but then _everything_ I
write always looks obviously correct to me.  - Linus Torvalds in
<Pine.LNX.4.10.10012090054360.791-100000@penguin.transmeta.com>

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 02/22] ARM: sunxi: MMC driver
  2012-11-25 15:39     ` Henrik Nordström
  2012-11-25 17:07       ` Luka Perkov
@ 2012-11-25 19:58       ` Wolfgang Denk
  1 sibling, 0 replies; 68+ messages in thread
From: Wolfgang Denk @ 2012-11-25 19:58 UTC (permalink / raw)
  To: u-boot

Dear Henrik Nordstr?m,

In message <1353857943.28559.24.camel@home.hno.se> you wrote:
>
> What about this:
> 
> #define MMCDBG(fmt, args...)        debug("[sunxi_mmc] " fmt, ##args)

NAK.  Just use debug() in your code.  No need for new macros.


Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
It is undignified for a woman to play servant to a man who is not
hers.
	-- Spock, "Amok Time", stardate 3372.7

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 06/22] ARM sunxi: Basic GPIO driver
  2012-11-25 19:50   ` Wolfgang Denk
@ 2012-11-25 21:47     ` Marek Vasut
  2012-11-25 23:41     ` Henrik Nordström
  1 sibling, 0 replies; 68+ messages in thread
From: Marek Vasut @ 2012-11-25 21:47 UTC (permalink / raw)
  To: u-boot

Dear Wolfgang Denk,

> Dear Henrik Nordstr?m,
> 
> In message <1353843623.17518.17.camel@home.hno.se> you wrote:
> > GPIO driver for Allwinner sun4i/sun5i family of SoCs
> > 
> > GPIO Pins are named by their symbolic pin names P<g><#>
> > such as PH19 or H19.
> > 
> > Note: This do not perform any validation if the pin is in use
> > for some other I/O function. Use with care.
> 
> SoB missing.
> 
> 
> Um.... are these patches actually bisectable???  It appears not; for
> example, you reference gpio_direction_input() in ealier patches, but
> define it only now.
> 
> This patch series need a full rework.

It needs a bit of polishing ;-)

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 06/22] ARM sunxi: Basic GPIO driver
  2012-11-25 19:50   ` Wolfgang Denk
  2012-11-25 21:47     ` Marek Vasut
@ 2012-11-25 23:41     ` Henrik Nordström
  1 sibling, 0 replies; 68+ messages in thread
From: Henrik Nordström @ 2012-11-25 23:41 UTC (permalink / raw)
  To: u-boot

s?n 2012-11-25 klockan 20:50 +0100 skrev Wolfgang Denk:
> Dear Henrik Nordstr?m,
> 
> In message <1353843623.17518.17.camel@home.hno.se> you wrote:
> > GPIO driver for Allwinner sun4i/sun5i family of SoCs
> > 
> > GPIO Pins are named by their symbolic pin names P<g><#>
> > such as PH19 or H19.
> > 
> > Note: This do not perform any validation if the pin is in use
> > for some other I/O function. Use with care.
> 
> SoB missing.

Sorry about that.

> Um.... are these patches actually bisectable???  It appears not; for
> example, you reference gpio_direction_input() in ealier patches, but
> define it only now.

Um.. right, on sun4i_sdcon with console redirected to the SD pins the
uart code uses that as a shorthand for sunxi_gpio_set_cfgpin(). Fixing.
Thanks for noticing.

And sorry for not doing a full matrix bisect validation, only did bisect
test on the basic targets when splitting the patch series. Will run a
full bisect matrix test for next round.

Regards
Henrik

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 01/22] ARM: sunxi: Basic Allwinner A10/A13 (sun4i/sun5i) support
  2012-11-25 19:33   ` Wolfgang Denk
@ 2012-11-25 23:53     ` Henrik Nordström
  2012-11-26  8:00       ` Stefan Roese
  0 siblings, 1 reply; 68+ messages in thread
From: Henrik Nordström @ 2012-11-25 23:53 UTC (permalink / raw)
  To: u-boot

s?n 2012-11-25 klockan 20:33 +0100 skrev Wolfgang Denk:
> Dear Henrik Nordstr?m,
> 
> In message <1353843450.17518.13.camel@home.hno.se> you wrote:
> > This adds support for the Allwinner A10/A13 SoC's. Additionally
> > board support for the dev-boards sun4i/sun5i is added.
> > 
> > Signed-off-by: Tom Cubie <tangliang@allwinnertech.com>
> > Signed-off-by: Henrik Nordstr?m <henrik@henriknordstrom.net>
> > Signed-off-by: Stefan Roese <sr@denx.de>
> 
> Where exactly is Stefan's SoB coming from?  I don't think I have seen
> this here on the list before?

He has been helping off-list to clean up the worst things and adding
ethernet support and adding Signed-off-by in the process.

Regards
Henrik

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 01/22] ARM: sunxi: Basic Allwinner A10/A13 (sun4i/sun5i) support
  2012-11-25 18:06   ` Marek Vasut
@ 2012-11-26  0:21     ` Henrik Nordström
  2012-11-26  0:33       ` Marek Vasut
  2012-11-26  5:52       ` Wolfgang Denk
  0 siblings, 2 replies; 68+ messages in thread
From: Henrik Nordström @ 2012-11-26  0:21 UTC (permalink / raw)
  To: u-boot

s?n 2012-11-25 klockan 19:06 +0100 skrev Marek Vasut:
> > +COBJS	+= timer.o
> > +COBJS	+= dram.o
> > +COBJS	+= board.o
> > +COBJS	+= clock.o
> > +COBJS	+= pinmux.o
> 
> COBJS = x.o y.o z.o
> works just fine

Does it matter?

+= is easier to deal with when adding/removing files.

> > +void enable_caches(void)
> > +{
> > +	/* Enable D-cache. I-cache is already enabled in start.S */
> > +	dcache_enable();
> 
> Why don't you enable them both? What if someone fiddled with them prior to 
> reset?

Because as the comment says, u-boot already enables I-cache in armv7
start.S.

> > +}
> > +#endif
> [...]
> 
> > +	cfg = readl(&pio->cfg[0] + index);
> > +	cfg &= ~(0xf << offset);
> > +	cfg |= val << offset;
> > +
> > +	writel(cfg, &pio->cfg[0] + index);
> 
> clrsetbits_le32()

Yes. Need to fix those in many places. Will do a full review.

> > +	return 0;
> > +}
> > +
> > +int sunxi_gpio_get_cfgpin(u32 pin)
> > +{
> > +	u32 cfg;
> > +	u32 bank = GPIO_BANK(pin);
> > +	u32 index = GPIO_CFG_INDEX(pin);
> > +	u32 offset = GPIO_CFG_OFFSET(pin);
> > +	struct sunxi_gpio *pio =
> > +	    &((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank];
> > +
> > +	cfg = readl(&pio->cfg[0] + index);
> > +	cfg >>= offset;
> 
> I think you want to put this into drivers/gpio, no?

Why? It is accessing the pinmux setting of the pin, not GPIO value.

May want to rename the whole family of functions to _pinmux_

> > +++ b/arch/arm/cpu/armv7/sunxi/reset.S

> Put this into proper C code.

Agreed. Inherited it as asm but there is no need for asm here. Will
replace by parts from the watchdog code, which also sets the register
proper.

> > diff --git a/arch/arm/cpu/armv7/sunxi/timer.c
> > b/arch/arm/cpu/armv7/sunxi/timer.c new file mode 100644
> > index 0000000..e19df09
> > --- /dev/null
> > +++ b/arch/arm/cpu/armv7/sunxi/timer.c
> > @@ -0,0 +1,117 @@
> [...]
> 
> > +/* delay x useconds */
> 
> proper kerneldoc all around won't hurt.
>
>> +void __udelay(unsigned long usec)
> 

It's the same level of documentation or better as used pretty much
everywhere else. Most don't have a comment at all here.

Any example of the level of documentation you'd like to see?

Regards
Henrik

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 01/22] ARM: sunxi: Basic Allwinner A10/A13 (sun4i/sun5i) support
  2012-11-26  0:21     ` Henrik Nordström
@ 2012-11-26  0:33       ` Marek Vasut
  2012-11-26  5:52       ` Wolfgang Denk
  1 sibling, 0 replies; 68+ messages in thread
From: Marek Vasut @ 2012-11-26  0:33 UTC (permalink / raw)
  To: u-boot

Dear Henrik Nordstr?m,

[...]

> > > +/* delay x useconds */
> > 
> > proper kerneldoc all around won't hurt.
> > 
> >> +void __udelay(unsigned long usec)
> 
> It's the same level of documentation or better as used pretty much
> everywhere else. Most don't have a comment at all here.
> 
> Any example of the level of documentation you'd like to see?

See here http://www.denx.de/wiki/U-Boot/CodingStyle

Best regards,
Marek Vasut

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 01/22] Re: Copyright on board makefiles.
  2012-11-25 19:55       ` Wolfgang Denk
@ 2012-11-26  1:05         ` Henrik Nordström
  2012-11-26  5:54           ` Wolfgang Denk
  0 siblings, 1 reply; 68+ messages in thread
From: Henrik Nordström @ 2012-11-26  1:05 UTC (permalink / raw)
  To: u-boot

s?n 2012-11-25 klockan 20:55 +0100 skrev Wolfgang Denk:
> Dear Henrik Nordstr?m,
> 
> In message <1353848939.28559.13.camel@home.hno.se> you wrote:
> >
> > > > +# (C) Copyright 2000-2003
> > > 
> > > I don't know about the dates. It's 2012 now... Same goes for all other files.
> > 
> > Heh.. Not sure which board that was copied from.
> > 
> > Not sure what to set as copyright here. Can't say there have been any
> > significant contributions by anyone in this file, but have updated the
> > year to 2011-2012 to match current use.
> 
> You have changed a Copyright entry that was attributed to me?
> 
> Who exactly gave you the right to do that? 

We copied one of your Makefiles as template. There is still some generic
board Makefile lines left ofcourse. Same as is used on every board.

The intention here was to give you the copyright to the changed file as
it's more part of the build system than any board specifics. I
presonally do not consider the board specific additions as
copyrightable.

You want me to keep your old copyright from 2003 and add my own?

Or only keep your old copyright from 2003?

Regards
Henrik

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 01/22] ARM: sunxi: Basic Allwinner A10/A13 (sun4i/sun5i) support
  2012-11-26  0:21     ` Henrik Nordström
  2012-11-26  0:33       ` Marek Vasut
@ 2012-11-26  5:52       ` Wolfgang Denk
  1 sibling, 0 replies; 68+ messages in thread
From: Wolfgang Denk @ 2012-11-26  5:52 UTC (permalink / raw)
  To: u-boot

Dear Henrik Nordstr?m,

In message <1353889294.28559.103.camel@home.hno.se> you wrote:
> s?n 2012-11-25 klockan 19:06 +0100 skrev Marek Vasut:
> > > +COBJS	+= timer.o
> > > +COBJS	+= dram.o
> > > +COBJS	+= board.o
> > > +COBJS	+= clock.o
> > > +COBJS	+= pinmux.o
> > 
> > COBJS = x.o y.o z.o
> > works just fine
> 
> Does it matter?
> 
> += is easier to deal with when adding/removing files.

Please always sort such lists.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Madness has no purpose.  Or reason.  But it may have a goal.
	-- Spock, "The Alternative Factor", stardate 3088.7

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 01/22] Re: Copyright on board makefiles.
  2012-11-26  1:05         ` [U-Boot] [PATCH 01/22] Re: Copyright on board makefiles Henrik Nordström
@ 2012-11-26  5:54           ` Wolfgang Denk
  0 siblings, 0 replies; 68+ messages in thread
From: Wolfgang Denk @ 2012-11-26  5:54 UTC (permalink / raw)
  To: u-boot

Dear Henrik Nordstr?m,

In message <1353891927.6436.16.camel@home.hno.se> you wrote:
>
> > You have changed a Copyright entry that was attributed to me?
> > 
> > Who exactly gave you the right to do that? 
...
> You want me to keep your old copyright from 2003 and add my own?

Correct.  You must never meddle with sombody elses copyright entries.
But, for any significant additions, you can add your own.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
I express preference for a chronological  sequence  of  events  which
precludes a violence.   - Terry Pratchett, _The Dark Side of the Sun_

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 01/22] ARM: sunxi: Basic Allwinner A10/A13 (sun4i/sun5i) support
  2012-11-25 23:53     ` Henrik Nordström
@ 2012-11-26  8:00       ` Stefan Roese
  0 siblings, 0 replies; 68+ messages in thread
From: Stefan Roese @ 2012-11-26  8:00 UTC (permalink / raw)
  To: u-boot

On 11/26/2012 12:53 AM, Henrik Nordstr?m wrote:
> s?n 2012-11-25 klockan 20:33 +0100 skrev Wolfgang Denk:
>> Dear Henrik Nordstr?m,
>>
>> In message <1353843450.17518.13.camel@home.hno.se> you wrote:
>>> This adds support for the Allwinner A10/A13 SoC's. Additionally
>>> board support for the dev-boards sun4i/sun5i is added.
>>>
>>> Signed-off-by: Tom Cubie <tangliang@allwinnertech.com>
>>> Signed-off-by: Henrik Nordstr?m <henrik@henriknordstrom.net>
>>> Signed-off-by: Stefan Roese <sr@denx.de>
>>
>> Where exactly is Stefan's SoB coming from?  I don't think I have seen
>> this here on the list before?
> 
> He has been helping off-list to clean up the worst things and adding
> ethernet support and adding Signed-off-by in the process.

Yes. But I would have liked to have a "final" review before submission
to this list. Sorry, I have missed saying this explicitly.

Thanks,
Stefan

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 03/22] ARM sunxi: I2C driver
  2012-11-25 11:38 ` [U-Boot] [PATCH 03/22] ARM sunxi: I2C driver Henrik Nordström
                     ` (2 preceding siblings ...)
  2012-11-25 19:47   ` Wolfgang Denk
@ 2012-11-26 11:13   ` Heiko Schocher
  2012-11-26 13:39     ` Henrik Nordström
  3 siblings, 1 reply; 68+ messages in thread
From: Heiko Schocher @ 2012-11-26 11:13 UTC (permalink / raw)
  To: u-boot

Hello Hendrik,

On 25.11.2012 12:38, Henrik Nordstr?m wqrote:
> A basic basic driver for the I2C controller found in Allwinner
> sunXi (A10&  A13) SoCs.
>
> Signed-off-by: Henrik Nordstrom<henrik@henriknordstrom.net>
> Signed-off-by: Stefan Roese<sr@denx.de>
> ---
>   arch/arm/cpu/armv7/sunxi/clock.c      |   15 ++
>   arch/arm/include/asm/arch-sunxi/i2c.h |  185 ++++++++++++++++++++++
>   drivers/i2c/Makefile                  |    1 +
>   drivers/i2c/sunxi_i2c.c               |  278 +++++++++++++++++++++++++++++++++
>   include/configs/sunxi-common.h        |    8 +
>   5 files changed, 487 insertions(+), 0 deletions(-)
>   create mode 100644 arch/arm/include/asm/arch-sunxi/i2c.h
>   create mode 100644 drivers/i2c/sunxi_i2c.c

One question: Did you looked at the i2c driver in
drivers/i2c/mvtwsi.c ? I just looked roughly over
it, there seems some differences, but there are
some equal defines, for example the TWI_CTL_*, TWI_STAT_*
defines, not too big difference in the register structure ...
maybe it is worth to check, if it is possible to extend the
existing driver to fit in your needs?

Beside of that, only some more nitpicking comments (beside of the
comments from Wolfgang, Marek, Henrik, Luka) ...

[...]
> diff --git a/arch/arm/include/asm/arch-sunxi/i2c.h b/arch/arm/include/asm/arch-sunxi/i2c.h
> new file mode 100644
> index 0000000..9a6e168
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-sunxi/i2c.h
> @@ -0,0 +1,185 @@
> +/*
> + * (C) Copyright 2012 Henrik Nordstrom<henrik@henriknordstrom.net>
> + *
> + * Based on sun4i linux kernle i2c.h
> + * (C) Copyright 2007-2012
> + * Allwinner Technology Co., Ltd.<www.allwinnertech.com>
> + * Tom Cubie<tanglaing@allwinnertech.com>
> + * Victor Wei<weiziheng@allwinnertech.com>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +#ifndef _SUNXI_I2C_H_
> +#define _SUNXI_I2C_H_
> +
> +struct i2c {
> +	u32 saddr;	/*  31:8bit res,7-1bit for slave addr,0 bit for GCE */
> +	u32 xsaddr;	/*  31:8bit res,7-0bit for second addr in 10bit addr */
> +	u32 data;	/*  31:8bit res, 7-0bit send or receive data byte */
> +	u32 ctl;	/*  INT_EN,BUS_EN,M_STA,INT_FLAG,A_ACK */
> +	u32 status;	/*  28 interrupt types + 0xF8 normal type = 29  */
> +	u32 clkr;	/*  31:7bit res,6-3bit,CLK_M,2-0bit CLK_N */
> +	u32 reset;	/*  31:1bit res;0bit,write 1 to clear 0. */
> +	u32 efr;	/*  31:2bit res,1:0 bit data byte follow read comand */
> +	u32 lctl;	/*  31:6bits res 5:0bit for sda&scl control */
> +};
> +
> +/* TWI address register */
> +#define TWI_GCE_EN	(0x1<<  0)	/* gen call addr enable slave mode */
                             ^
                             space, please fix all places.

> +#define TWI_ADDR_MASK	(0x7f<<  1)	/* 7:1bits */
> +#define TWI_XADDR_MASK	0xff		/* 7:0bits for extend slave address */
[...]
> +/*
> + * TWI Clock Register Bit Fields&  Masks,default value:0x0000_0000
> + * Fin is APB CLOCK INPUT;
> + * Fsample = F0 = Fin/2^CLK_N;
> + *           F1 = F0/(CLK_M+1);
> + *
> + * Foscl = F1/10 = Fin/(2^CLK_N * (CLK_M+1)*10);
> + * Foscl is clock SCL;standard mode:100KHz or fast mode:400KHz
> + */
> +
> +#define TWI_CLK_DIV_M		(0xF<<  3)	/* 6:3bit  */
> +#define TWI_CLK_DIV_N		(0x7<<  0)	/* 2:0bit */
> +#define TWI_CLK_DIV(N, M)	((((N)&  0xF)<<  3) | (((M)&  0x7)<<  0))
                                       ^
                                       here space too.

[...]
> diff --git a/drivers/i2c/sunxi_i2c.c b/drivers/i2c/sunxi_i2c.c
> new file mode 100644
> index 0000000..6bf5309
> --- /dev/null
> +++ b/drivers/i2c/sunxi_i2c.c
> @@ -0,0 +1,278 @@
> +/*
> + * Copyright (c) 2012 Henrik Nordstrom<henrik@henriknordstrom.net>
> + *
> + * See file CREDITS for list of people who contributed to this
> + * project.
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include<common.h>
> +#include<i2c.h>
> +#include<asm/io.h>
> +#include<asm/arch/cpu.h>
> +#include<asm/arch/i2c.h>
> +#include<asm/arch/gpio.h>
> +#include<asm/arch/clock.h>
> +
> +static struct i2c __attribute__ ((section(".data"))) *i2c_base =
> +	(struct i2c *)0x1c2ac00;

please use a define.

> +void i2c_init(int speed, int slaveaddr)
> +{
> +	sunxi_gpio_set_cfgpin(SUNXI_GPB(0), 2);
> +	sunxi_gpio_set_cfgpin(SUNXI_GPB(1), 2);
> +	clock_twi_onoff(0, 1);
> +
> +	/* Enable the i2c bus */
> +	writel(TWI_CTL_BUSEN,&i2c_base->ctl);
> +
> +	/* 400KHz operation M=2, N=1, 24MHz APB clock */
> +	writel(TWI_CLK_DIV(2, 1),&i2c_base->clkr);

Hmm.. could we make this configurable?

> +	writel(TWI_SRST_SRST,&i2c_base->reset);
> +
> +	while ((readl(&i2c_base->reset)&  TWI_SRST_SRST))
> +		;
> +}
> +
> +int i2c_probe(uchar chip)
> +{
> +	return -1;
> +}
> +
> +static int i2c_wait_ctl(int mask, int state)
> +{
> +	int timeout = 0x2ff;

Fix timeout, why?

> +	int value = state ? mask : 0;
> +
> +	debug("i2c_wait_ctl(%x == %x), ctl=%x, status=%x\n", mask, value,
> +	      i2c_base->ctl, i2c_base->status);
> +
> +	while (((readl(&i2c_base->ctl)&  mask) != value)&&  timeout-->  0)
> +		;
> +
> +	debug("i2c_wait_ctl(), timeout=%d, ctl=%x, status=%x\n", timeout,
> +	      i2c_base->ctl, i2c_base->status);
> +
> +	if (timeout != 0)
> +		return 0;
> +	else
> +		return -1;
> +}
> +
> +static void i2c_clear_irq(void)
> +{
> +	writel(readl(&i2c_base->ctl)&  ~TWI_CTL_INTFLG,&i2c_base->ctl);
                                     ^                  ^
                                     space
> +}
> +
> +static int i2c_wait_irq(void)
> +{
> +	return i2c_wait_ctl(TWI_CTL_INTFLG, 1);
> +}
> +
> +static int i2c_wait_status(int status)
> +{
> +	int timeout = 0x2ff;
> +
> +	while (readl(&i2c_base->status) != status&&  timeout-->  0)
> +		;
> +
> +	if (timeout != 0)
> +		return 0;
> +	else
> +		return -1;
> +}
> +
> +static int i2c_wait_irq_status(int status)
> +{
> +	if (i2c_wait_irq() != 0)
> +		return -1;
> +
> +	if (readl(&i2c_base->status) != status)
> +		return -1;
> +
> +	return 0;
> +}
> +
> +static int i2c_wait_bus_idle(void)
> +{
> +	int timeout = 0x2ff;
> +
> +	while (readl(&i2c_base->lctl) != 0x3a&&  timeout-->  0)
                                          ^
                                          please use a define here
> +		;
> +
> +	if (timeout != 0)
> +		return 0;
> +	else
> +		return -1;
> +}
> +
> +static int i2c_stop(void)
> +{
> +	u32 ctl;
> +
> +	ctl = readl(&i2c_base->ctl)&  0xc0;
                                       ^
                                       please use a define here, too
> +	ctl |= TWI_CTL_STP;
> +
> +	writel(ctl,&i2c_base->ctl);
> +
> +	/* dummy to delay one I/O operation to make sure it's started */
> +	(void)readl(&i2c_base->ctl);
> +
> +	if (i2c_wait_ctl(TWI_CTL_STP, 0) != 0)
> +		return -1;
> +	if (i2c_wait_status(TWI_STAT_IDLE))
> +		return -1;
> +	if (i2c_wait_bus_idle() != 0)
> +		return -1;
> +
> +	return 0;
> +}
> +
> +static int i2c_send_data(u8 data, u8 status)
> +{
> +	debug("i2c_write(%02x, %x), ctl=%x, status=%x\n", data, status,
> +	      i2c_base->ctl, i2c_base->status);
> +
> +	writel(data,&i2c_base->data);
> +	i2c_clear_irq();
> +
> +	if (i2c_wait_irq_status(status) != 0)
> +		return -1;
> +
> +	return 0;
> +}
> +
> +static int i2c_start(int status)
> +{
> +	u32 ctl;
> +
> +	debug("i2c_start(%x), ctl=%x, status=%x\n", status, i2c_base->ctl,
> +	      i2c_base->status);
> +	/* Check that the controller is idle */
> +	if (status == TWI_STAT_TX_STA
> +	&&  readl(&i2c_base->status) != TWI_STAT_IDLE) {
> +		return -1;
> +	}
> +
> +	writel(0,&i2c_base->efr);
> +
> +	/* Send start */
> +	ctl = readl(&i2c_base->ctl);
> +	ctl |= TWI_CTL_STA;	/* Set start bit */
> +	ctl&= ~TWI_CTL_INTFLG;	/* Clear int flag */
            ^
            space

> +	writel(ctl,&i2c_base->ctl);
                    ^
                    space
> +
> +	if (i2c_wait_ctl(TWI_CTL_STA, 0) != 0)
> +		return -1;
> +	if (i2c_wait_irq_status(status) != 0)
> +		return -1;
> +
> +	return 0;
> +}

bye,
Heiko
-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 03/22] ARM sunxi: I2C driver
  2012-11-26 11:13   ` Heiko Schocher
@ 2012-11-26 13:39     ` Henrik Nordström
  0 siblings, 0 replies; 68+ messages in thread
From: Henrik Nordström @ 2012-11-26 13:39 UTC (permalink / raw)
  To: u-boot

m?n 2012-11-26 klockan 12:13 +0100 skrev Heiko Schocher:

> One question: Did you looked at the i2c driver in
> drivers/i2c/mvtwsi.c? I just looked roughly over
> it, there seems some differences, but there are
> some equal defines, for example the TWI_CTL_*, TWI_STAT_*
> defines, not too big difference in the register structure ...
> maybe it is worth to check, if it is possible to extend the
> existing driver to fit in your needs?

I hadn?t noticed, but indeed there is many similarities, and some
differences. The two controllers are clearly of related origin.


Regards
Henrik

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 04/22] ARM: sunxi: watchdog support
  2012-11-25 11:47 ` [U-Boot] [PATCH 04/22] ARM: sunxi: watchdog support Henrik Nordström
@ 2013-02-02 23:55   ` Albert ARIBAUD
  0 siblings, 0 replies; 68+ messages in thread
From: Albert ARIBAUD @ 2013-02-02 23:55 UTC (permalink / raw)
  To: u-boot

Hi Henrik,

On Sun, 25 Nov 2012 12:47:11 +0100, Henrik Nordstr?m
<henrik@henriknordstrom.net> wrote:

> This adds support for the hardware watchdog in Allwinner
> sun4i & sun5i (sunxi) SoC familiy.
> 
> From: Henrik Nordstrom <henrik@henriknordstrom.net>
> 
> Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>
> Signed-off-by: Stefan Roese <sr@denx.de>
> ---
>  arch/arm/cpu/armv7/sunxi/board.c            |    3 ++
>  arch/arm/include/asm/arch-sunxi/sys_proto.h |    1 -
>  drivers/watchdog/Makefile                   |    1 +
>  drivers/watchdog/sunxi_watchdog.c           |   49 +++++++++++++++++++++++++++
>  include/configs/sunxi-common.h              |    4 ++
>  5 files changed, 57 insertions(+), 1 deletions(-)
>  create mode 100644 drivers/watchdog/sunxi_watchdog.c
> 
> diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c
> index 652c19d..5c94110 100644
> --- a/arch/arm/cpu/armv7/sunxi/board.c
> +++ b/arch/arm/cpu/armv7/sunxi/board.c
> @@ -59,6 +59,9 @@ int gpio_init(void)
>  /* do some early init */
>  void s_init(void)
>  {
> +#if defined(CONFIG_WATCHDOG) && defined(CONFIG_SUNXI_WATCHDOG)
> +	watchdog_set(23);	/* max possible timeout */
> +#endif
>  	clock_init();
>  	gpio_init();
>  }
> diff --git a/arch/arm/include/asm/arch-sunxi/sys_proto.h b/arch/arm/include/asm/arch-sunxi/sys_proto.h
> index 1e8ae5d..9729100 100644
> --- a/arch/arm/include/asm/arch-sunxi/sys_proto.h
> +++ b/arch/arm/include/asm/arch-sunxi/sys_proto.h
> @@ -27,6 +27,5 @@
>  
>  void sr32(u32 *, u32, u32, u32);
>  void sdelay(unsigned long);
> -void watchdog_init(void);

Why remove this proto, and why not keep a single watchdog init code?

>  #endif
> diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile
> index 923acb9..50b5fae 100644
> --- a/drivers/watchdog/Makefile
> +++ b/drivers/watchdog/Makefile
> @@ -28,6 +28,7 @@ LIB	:= $(obj)libwatchdog.o
>  COBJS-$(CONFIG_AT91SAM9_WATCHDOG) += at91sam9_wdt.o
>  COBJS-$(CONFIG_FTWDT010_WATCHDOG) += ftwdt010_wdt.o
>  COBJS-$(CONFIG_TNETV107X_WATCHDOG) += tnetv107x_wdt.o
> +COBJS-$(CONFIG_SUNXI_WATCHDOG)    += sunxi_watchdog.o
>  
>  COBJS	:= $(COBJS-y)
>  SRCS	:= $(COBJS:.o=.c)
> diff --git a/drivers/watchdog/sunxi_watchdog.c b/drivers/watchdog/sunxi_watchdog.c
> new file mode 100644
> index 0000000..65a763d
> --- /dev/null
> +++ b/drivers/watchdog/sunxi_watchdog.c
> @@ -0,0 +1,49 @@
> +/*
> + * (C) Copyright 2012 Henrik Nordstrom <henrik@hno.se>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of
> + * the License, or (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> + * GNU General Public License for more details.
> + *
> + * You should have received a copy of the GNU General Public License
> + * along with this program; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
> + * MA 02111-1307 USA
> + */
> +
> +#include <common.h>
> +#include <asm/arch/timer.h>
> +#include <asm/armv7.h>
> +#include <asm/io.h>
> +
> +void watchdog_reset(void)
> +{
> +	static struct sunxi_wdog *const wdog =
> +		&((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->wdog;
> +
> +	/* a little magic to reload the watchdog */
> +	writel(0xA57 << 1 | 1 << 0, &wdog->ctl);
> +}
> +
> +static void watchdog_set(int interval)
> +{
> +	static struct sunxi_wdog *const wdog =
> +		&((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->wdog;
> +
> +	/* Set timeout, reset & enable */
> +	writel(interval << 2 | 1 << 1 | 1 << 0, &wdog->mode);
> +	watchdog_reset();
> +}
> +
> +void watchdog_init(void)
> +{
> +#ifdef CONFIG_WATCHDOG
> +	watchdog_set(23);	/* max possible timeout */
> +#endif
> +}
> diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
> index c2d16fb..5bf8eea 100644
> --- a/include/configs/sunxi-common.h
> +++ b/include/configs/sunxi-common.h
> @@ -202,4 +202,8 @@
>  #define CONFIG_SYS_I2C_SLAVE		0x7f
>  #define CONFIG_CMD_I2C
>  
> +/* Watchdog */
> +/* #define CONFIG_WATCHDOG */
> +/* #define CONFIG_SUNXI_WATCHDOG */
> +
>  #endif /* __CONFIG_H */


Amicalement,
-- 
Albert.

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 08/22] net: Add sunxi (Allwinner) wemac driver
  2012-11-25 11:41 ` [U-Boot] [PATCH 08/22] net: Add sunxi (Allwinner) wemac driver Henrik Nordström
@ 2013-07-08 15:43   ` Joe Hershberger
  2013-07-08 16:16     ` Tom Rini
  0 siblings, 1 reply; 68+ messages in thread
From: Joe Hershberger @ 2013-07-08 15:43 UTC (permalink / raw)
  To: u-boot

On Sun, Nov 25, 2012 at 5:41 AM, Henrik Nordstr?m
<henrik@henriknordstrom.net> wrote:
> This patch adds support for the WEMAC, the ethernet controller included
> in the Allwinner A10 SoC. It will get used in the upcoming A10 board
> support.
>
> From: Stefan Roese <sr@denx.de>
> Signed-off-by: Stefan Roese <sr@denx.de>
> Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>

Applied, Thanks.
-Joe

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 08/22] net: Add sunxi (Allwinner) wemac driver
  2013-07-08 15:43   ` Joe Hershberger
@ 2013-07-08 16:16     ` Tom Rini
  2013-07-08 16:29       ` Joe Hershberger
  0 siblings, 1 reply; 68+ messages in thread
From: Tom Rini @ 2013-07-08 16:16 UTC (permalink / raw)
  To: u-boot

On Mon, Jul 08, 2013 at 10:43:03AM -0500, Joe Hershberger wrote:
> On Sun, Nov 25, 2012 at 5:41 AM, Henrik Nordstr?m
> <henrik@henriknordstrom.net> wrote:
> > This patch adds support for the WEMAC, the ethernet controller included
> > in the Allwinner A10 SoC. It will get used in the upcoming A10 board
> > support.
> >
> > From: Stefan Roese <sr@denx.de>
> > Signed-off-by: Stefan Roese <sr@denx.de>
> > Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>
> 
> Applied, Thanks.

Hold up here Joe, the rest of the Allwinner code isn't in yet.  I'm
hoping for a resubmission from Henrik soon :)

-- 
Tom
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 836 bytes
Desc: Digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20130708/b4d97245/attachment.pgp>

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 08/22] net: Add sunxi (Allwinner) wemac driver
  2013-07-08 16:16     ` Tom Rini
@ 2013-07-08 16:29       ` Joe Hershberger
  2013-07-08 19:03         ` Tom Rini
  0 siblings, 1 reply; 68+ messages in thread
From: Joe Hershberger @ 2013-07-08 16:29 UTC (permalink / raw)
  To: u-boot

Hi Tom,

On Mon, Jul 8, 2013 at 11:16 AM, Tom Rini <trini@ti.com> wrote:
> On Mon, Jul 08, 2013 at 10:43:03AM -0500, Joe Hershberger wrote:
>> On Sun, Nov 25, 2012 at 5:41 AM, Henrik Nordstr?m
>> <henrik@henriknordstrom.net> wrote:
>> > This patch adds support for the WEMAC, the ethernet controller included
>> > in the Allwinner A10 SoC. It will get used in the upcoming A10 board
>> > support.
>> >
>> > From: Stefan Roese <sr@denx.de>
>> > Signed-off-by: Stefan Roese <sr@denx.de>
>> > Signed-off-by: Henrik Nordstrom <henrik@henriknordstrom.net>
>>
>> Applied, Thanks.
>
> Hold up here Joe, the rest of the Allwinner code isn't in yet.  I'm
> hoping for a resubmission from Henrik soon :)

I didn't realize that when I was processing all my assigned patches in
patchwork.  I guess you can revert the this patch before accepting his
new series.

I've noticed that several of the patches I applied in the last PR had
been superseded, but were delegated to other people, so I didn't see
them.  I guess we need to figure out who should be delegated such
patches and do so consistently.

Apologies,
-Joe

^ permalink raw reply	[flat|nested] 68+ messages in thread

* [U-Boot] [PATCH 08/22] net: Add sunxi (Allwinner) wemac driver
  2013-07-08 16:29       ` Joe Hershberger
@ 2013-07-08 19:03         ` Tom Rini
  0 siblings, 0 replies; 68+ messages in thread
From: Tom Rini @ 2013-07-08 19:03 UTC (permalink / raw)
  To: u-boot

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 07/08/2013 12:29 PM, Joe Hershberger wrote:
> Hi Tom,
> 
> On Mon, Jul 8, 2013 at 11:16 AM, Tom Rini <trini@ti.com> wrote:
>> On Mon, Jul 08, 2013 at 10:43:03AM -0500, Joe Hershberger wrote:
>>> On Sun, Nov 25, 2012 at 5:41 AM, Henrik Nordstr?m 
>>> <henrik@henriknordstrom.net> wrote:
>>>> This patch adds support for the WEMAC, the ethernet
>>>> controller included in the Allwinner A10 SoC. It will get
>>>> used in the upcoming A10 board support.
>>>> 
>>>> From: Stefan Roese <sr@denx.de> Signed-off-by: Stefan Roese
>>>> <sr@denx.de> Signed-off-by: Henrik Nordstrom
>>>> <henrik@henriknordstrom.net>
>>> 
>>> Applied, Thanks.
>> 
>> Hold up here Joe, the rest of the Allwinner code isn't in yet.
>> I'm hoping for a resubmission from Henrik soon :)
> 
> I didn't realize that when I was processing all my assigned patches
> in patchwork.  I guess you can revert the this patch before
> accepting his new series.
> 
> I've noticed that several of the patches I applied in the last PR
> had been superseded, but were delegated to other people, so I
> didn't see them.  I guess we need to figure out who should be
> delegated such patches and do so consistently.
> 
> Apologies,

As the most frequent assigner on patchwork, that's on me, sorry.ian.

- -- 
Tom
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQIcBAEBAgAGBQJR2w0ZAAoJENk4IS6UOR1Wx0UP/0OQ2kDx0ktMqnyEIGeq5riw
2WaOj8d1q8Avh5oDXpqnhegqWE4IWBD8gzHnsXYFnGM8acubtuE+BD6aHZT6R9SF
MJfSRKDJTxWbOrK6p2y2GXIKdwxETS0bJvP5UwrGrJRKI59kOL/m6xEmIQjCGeS5
gq10K75KiGjvmdWgy9O26KOjtGyNY5kqok1MCxqbE0deeQvEoOAxzcV4LQREJFZ8
Aq6xGuZ6dQOTsA3o20PhqT7n2nNSc0R9yhA08Nlrz1ulCtBEcwpi4aPOYg5t12ub
HFT3mEvN7tJfAorvjOhwGTZkkVrxDj0LtDhlbxmqnzWZp6LdEt6QfPcdYHjgXZnj
/e1Ojf9VFKE7V1866xzyuMuvXk/oWix4c57XV1KgsX4j6WdsDraeaEcdRif2RrKi
onoaFBcIgu2p1Z/2ULj82k1OjOuF0vfIae/op0J2mWD2//bHfV/3/ToW3LtEePwA
6sFk2WK1WixYXYt2QztKxzI5NdTeKt5Nn60EQhsZ8O4ht5OSiG9rxEjhW6LNmJlw
9i3aRrqbVhGlwzu4RpsDog6rkJcVX0fhK16Dj4gRbAuoQMayBC7hb6zNc6P6OxpP
azMDyXBdkj56M4sKTgXPYBGKPTKQ6t8p+PLuKSq5tqGPCS+B6i7i/c9Qr3ENqTYG
OSktPGoncCf08C5Ox8Ui
=9mTl
-----END PGP SIGNATURE-----

^ permalink raw reply	[flat|nested] 68+ messages in thread

end of thread, other threads:[~2013-07-08 19:03 UTC | newest]

Thread overview: 68+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <cover.1353842684.git.henrik@henriknordstrom.net>
2012-11-25 11:37 ` [U-Boot] [PATCH 01/22] ARM: sunxi: Basic Allwinner A10/A13 (sun4i/sun5i) support Henrik Nordström
2012-11-25 12:23   ` Luka Perkov
2012-11-25 13:08     ` Henrik Nordström
2012-11-25 19:55       ` Wolfgang Denk
2012-11-26  1:05         ` [U-Boot] [PATCH 01/22] Re: Copyright on board makefiles Henrik Nordström
2012-11-26  5:54           ` Wolfgang Denk
2012-11-25 19:52     ` [U-Boot] [PATCH 01/22] ARM: sunxi: Basic Allwinner A10/A13 (sun4i/sun5i) support Wolfgang Denk
2012-11-25 18:06   ` Marek Vasut
2012-11-26  0:21     ` Henrik Nordström
2012-11-26  0:33       ` Marek Vasut
2012-11-26  5:52       ` Wolfgang Denk
2012-11-25 19:33   ` Wolfgang Denk
2012-11-25 23:53     ` Henrik Nordström
2012-11-26  8:00       ` Stefan Roese
2012-11-25 19:40   ` Wolfgang Denk
2012-11-25 11:37 ` [U-Boot] [PATCH 02/22] ARM: sunxi: MMC driver Henrik Nordström
2012-11-25 14:33   ` Luka Perkov
2012-11-25 15:39     ` Henrik Nordström
2012-11-25 17:07       ` Luka Perkov
2012-11-25 19:58       ` Wolfgang Denk
2012-11-25 19:56     ` Wolfgang Denk
2012-11-25 18:09   ` Marek Vasut
2012-11-25 19:44   ` Wolfgang Denk
2012-11-25 11:38 ` [U-Boot] [PATCH 03/22] ARM sunxi: I2C driver Henrik Nordström
2012-11-25 14:41   ` Luka Perkov
2012-11-25 15:47     ` Henrik Nordström
2012-11-25 18:11   ` Marek Vasut
2012-11-25 19:47   ` Wolfgang Denk
2012-11-26 11:13   ` Heiko Schocher
2012-11-26 13:39     ` Henrik Nordström
2012-11-25 11:39 ` [U-Boot] [PATCH 05/22] power: Add AXP209 Power Management controller (I2C) Henrik Nordström
2012-11-25 14:44   ` Luka Perkov
2012-11-25 18:13   ` Marek Vasut
2012-11-25 19:48   ` Wolfgang Denk
2012-11-25 11:40 ` [U-Boot] [PATCH 06/22] ARM sunxi: Basic GPIO driver Henrik Nordström
2012-11-25 14:52   ` Luka Perkov
2012-11-25 18:14   ` Marek Vasut
2012-11-25 19:50   ` Wolfgang Denk
2012-11-25 21:47     ` Marek Vasut
2012-11-25 23:41     ` Henrik Nordström
2012-11-25 11:40 ` [U-Boot] [PATCH 07/22] tools: mksunixboot adding a Allwinner boot header Henrik Nordström
2012-11-25 15:01   ` Luka Perkov
2012-11-25 17:47   ` Wolfgang Denk
2012-11-25 11:41 ` [U-Boot] [PATCH 08/22] net: Add sunxi (Allwinner) wemac driver Henrik Nordström
2013-07-08 15:43   ` Joe Hershberger
2013-07-08 16:16     ` Tom Rini
2013-07-08 16:29       ` Joe Hershberger
2013-07-08 19:03         ` Tom Rini
2012-11-25 11:42 ` [U-Boot] [PATCH 09/22] ARM: sun4i: Enable ethernet support (wemac) on A10 boards Henrik Nordström
2012-11-25 15:05   ` Luka Perkov
2012-11-25 11:43 ` [U-Boot] [PATCH 10/22] sunxi: Add more network commands and netconsole support Henrik Nordström
2012-11-25 15:07   ` Luka Perkov
2012-11-25 11:44 ` [U-Boot] [PATCH 11/22] ARM: sunxi: U-Boot SPL capable of booting directly from MMC Henrik Nordström
2012-11-25 15:11   ` Luka Perkov
2012-11-25 11:44 ` [U-Boot] [PATCH 12/22] ARM sunxi: SPL support for Olimex A13-OLinuXino board Henrik Nordström
2012-11-25 15:17   ` Luka Perkov
2012-11-25 11:44 ` [U-Boot] [PATCH 13/22] ARM sunxi: SPL support for Mele A1000 board Henrik Nordström
2012-11-25 11:45 ` [U-Boot] [PATCH 14/22] ARM sunxi: SPL support for Cubieboard board Henrik Nordström
2012-11-25 11:45 ` [U-Boot] [PATCH 15/22] ARM sunxi: SPL support for Hackberry 1GB board Henrik Nordström
2012-11-25 11:45 ` [U-Boot] [PATCH 16/22] ARM sunxi: SPL support for a13_mid board Henrik Nordström
2012-11-25 11:45 ` [U-Boot] [PATCH 17/22] ARM sunxi: SPL support for Mini-X board Henrik Nordström
2012-11-25 11:46 ` [U-Boot] [PATCH 18/22] ARM sunxi: SPL support for hyundai A7HD board Henrik Nordström
2012-11-25 11:46 ` [U-Boot] [PATCH 19/22] ARM sunxi: SPL support for MK802 board Henrik Nordström
2012-11-25 11:46 ` [U-Boot] [PATCH 20/22] ARM sunxi: SPL support for Rikomagic MK802II board Henrik Nordström
2012-11-25 11:46 ` [U-Boot] [PATCH 21/22] ARM sunxi: SPL support for Mele A3700 board Henrik Nordström
2012-11-25 11:46 ` [U-Boot] [PATCH 22/22] ARM sunxi: SPL support for Olinuxino A13 Micro Henrik Nordström
2012-11-25 11:47 ` [U-Boot] [PATCH 04/22] ARM: sunxi: watchdog support Henrik Nordström
2013-02-02 23:55   ` Albert ARIBAUD

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.