Re: [U-Boot] [PATCH v2 1/2] mtd: OMAP: Enable GPMC prefetch mode
Hi Daniel, While trying to enable GPMC prefetch myself I ran into your patch and tested it. Here's some comments. On Wed, Jun 25, 2014 at 02:43:32PM +0200, Daniel Mack wrote: Enable GPMC's prefetch feature for NAND access. This speeds up NAND read access a lot by pre-fetching contents in the background and reading them through the FIFO address. The current implementation has two limitations: a) it only works in 8-bit mode b) it only supports read access Both is easily fixable by someone who has hardware to implement it. Note that U-Boot code uses non word-aligned buffers to read data into, and request read lengths that are not multiples of 4, so both partial buffers (head and tail) have to be addressed. Tested on AM335x hardware. Signed-off-by: Daniel Mack zon...@gmail.com --- doc/README.nand | 5 ++ drivers/mtd/nand/omap_gpmc.c | 115 +- include/linux/mtd/omap_gpmc.h | 6 ++- 3 files changed, 123 insertions(+), 3 deletions(-) diff --git a/doc/README.nand b/doc/README.nand index 70cf768..6459f2a 100644 --- a/doc/README.nand +++ b/doc/README.nand @@ -292,6 +292,11 @@ Platform specific options Thus BCH16 can be supported on 4K page NAND. +CONFIG_NAND_OMAP_PREFETCH This doesn't match the actual config in omap_gpmc.c + On OMAP platforms that use the GPMC controller (CONFIG_NAND_OMAP_GPMC), + this options enables the code that uses the prefetch mode to speed up + read operations. + NOTE: = diff --git a/drivers/mtd/nand/omap_gpmc.c b/drivers/mtd/nand/omap_gpmc.c index 1acf06b..e2d57bd 100644 --- a/drivers/mtd/nand/omap_gpmc.c +++ b/drivers/mtd/nand/omap_gpmc.c @@ -446,6 +446,113 @@ static int omap_correct_data_bch(struct mtd_info *mtd, uint8_t *dat, return (err) ? err : error_count; } +#ifdef CONFIG_NAND_OMAP_GPMC_PREFETCH + +#define PREFETCH_CONFIG1_CS_SHIFT24 +#define PREFETCH_FIFOTHRESHOLD_MAX 0x40 +#define PREFETCH_FIFOTHRESHOLD(val) ((val) 8) +#define PREFETCH_STATUS_COUNT(val) (val 0x3fff) +#define PREFETCH_STATUS_FIFO_CNT(val)((val 24) 0x7F) +#define ENABLE_PREFETCH (1 7) + +/** + * omap_prefetch_enable - configures and starts prefetch transfer + * @fifo_th: fifo threshold to be used for read/ write + * @count: number of bytes to be transferred + * @is_write: prefetch read(0) or write post(1) mode + */ +static int omap_prefetch_enable(int fifo_th, unsigned int count, int is_write) +{ + uint32_t val; + + if (fifo_th PREFETCH_FIFOTHRESHOLD_MAX) + return -EINVAL; + + if (readl(gpmc_cfg-prefetch_control)) + return -EBUSY; + + /* Set the amount of bytes to be prefetched */ + writel(count, gpmc_cfg-prefetch_config2); + + val = (cs PREFETCH_CONFIG1_CS_SHIFT) | (is_write 1) | On a current U-boot cs doesn't exist. I think you might want to pass a struct omap_nand_info * and use info-cs. I fixed this last bit, and tested it. It results in 2.5x speed improvements on a Micron NAND. So, thanks :) ! If you resend, you have my Reviewed-by and Tested-by. + PREFETCH_FIFOTHRESHOLD(fifo_th) | ENABLE_PREFETCH; + writel(val, gpmc_cfg-prefetch_config1); + + /* Start the prefetch engine */ + writel(1, gpmc_cfg-prefetch_control); + + return 0; +} + +/** + * omap_prefetch_reset - disables and stops the prefetch engine + */ +static void omap_prefetch_reset(void) +{ + writel(0, gpmc_cfg-prefetch_control); + writel(0, gpmc_cfg-prefetch_config1); +} + +static int __read_prefetch_aligned(struct nand_chip *chip, uint32_t *buf, int len) +{ + int ret; + uint32_t cnt; + + ret = omap_prefetch_enable(PREFETCH_FIFOTHRESHOLD_MAX, len, 0); + if (ret 0) + return ret; + + do { + int i; + + cnt = readl(gpmc_cfg-prefetch_status); + cnt = PREFETCH_STATUS_FIFO_CNT(cnt); + + for (i = 0; i cnt / 4; i++) { + *buf++ = readl(CONFIG_SYS_NAND_BASE); + len -= 4; + } + } while (len); + + omap_prefetch_reset(); + + return 0; +} + +static void omap_nand_read_prefetch8(struct mtd_info *mtd, uint8_t *buf, int len) +{ + int ret; + uint32_t head, tail; + struct nand_chip *chip = mtd-priv; + + /* + * If the destination buffer is unaligned, start with reading + * the overlap byte-wise. + */ + head = ((uint32_t) buf) % 4; + if (head) { + nand_read_buf(mtd, buf, head); + buf += head; + len -= head; + } + + /* + * Only transfer multiples of 4 bytes in a pre-fetched fashion. + * If there's a residue, care for it byte-wise afterwards. + */ + tail = len % 4; + + ret = __read_prefetch_aligned(chip, (uint32_t *) buf,
Re: [U-Boot] [PATCH v2 1/2] mtd: OMAP: Enable GPMC prefetch mode
Hi Guido, thanks for your feedback! On 12/19/2014 05:27 PM, Guido MartÃnez wrote: +/** + * omap_prefetch_enable - configures and starts prefetch transfer + * @fifo_th: fifo threshold to be used for read/ write + * @count: number of bytes to be transferred + * @is_write: prefetch read(0) or write post(1) mode + */ +static int omap_prefetch_enable(int fifo_th, unsigned int count, int is_write) +{ +uint32_t val; + +if (fifo_th PREFETCH_FIFOTHRESHOLD_MAX) +return -EINVAL; + +if (readl(gpmc_cfg-prefetch_control)) +return -EBUSY; + +/* Set the amount of bytes to be prefetched */ +writel(count, gpmc_cfg-prefetch_config2); + +val = (cs PREFETCH_CONFIG1_CS_SHIFT) | (is_write 1) | On a current U-boot cs doesn't exist. I think you might want to pass a struct omap_nand_info * and use info-cs. I fixed this last bit, and tested it. It results in 2.5x speed improvements on a Micron NAND. So, thanks :) ! If you resend, you have my Reviewed-by and Tested-by. That's great to hear. However, I'm not currently working on this project, so I don't have a chance to respin the patch. In case any of the maintainers is interested, I guess that's easy enough to tweak on the fly when merging the patch :) Thanks, Daniel ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH v2 0/4] sun8i: Remaining sun8i SPL support patches
Hi Ian, et al, Here is a v2 of the A23 patches which did not pass review in v1 (so not a resend of the whole set). Changes: -sun6i: s/SUNXI_*P2WI*/SUN6I_*P2WI*/ -Not only change the prefix of the P2WI gpio mux defines from SUNXI to SUN6I, but also the prefix of the SUN6I_P2WI_BASE address define -sunxi: Add support for the rsb (Reduced Serial Bus) -Drop sun6i / sun8i comments from SUN6I_P2WI_BASE / SUNXI_RSB_BASE defines, use the prefix instead to make clear for which SoC family they are valid -sun8i: Add dram initialization support -white space fixes -Add a comment that the ddr phy bits look a lot like the ddr phy found in the TI Keystone2 and add a link to the TI Keystone2 documentation for future reference / cleanup work -Split out the Ippo_q8h_v5_defconfig patches into their own patch Regards, Hans p.s. I also still need an ack for sunxi: Fill memory before comparing it when doing dram init on sun6i, as you had some questions on that when reviewing v1 of the set. ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH v2 4/4] sun8i: Ippo_q8h_v5_defconfig: Enable SPL support
Now that we've sun8i dram-init support we can enable the SPL for sun8i boards. While at it also replace CONFIG_DEFAULT_DEVICE_TREE with CONFIG_FDTFILE, the former is for u-boot's own fdt usage, which we do not use (yet), the later specifies the fdt to pass to the kernel, which is the one we want. Signed-off-by: Hans de Goede hdego...@redhat.com --- configs/Ippo_q8h_v5_defconfig | 18 +- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/configs/Ippo_q8h_v5_defconfig b/configs/Ippo_q8h_v5_defconfig index 50c2f93..b8d3afe 100644 --- a/configs/Ippo_q8h_v5_defconfig +++ b/configs/Ippo_q8h_v5_defconfig @@ -1,8 +1,16 @@ +CONFIG_SPL=y CONFIG_SYS_EXTRA_OPTIONS=CONS_INDEX=5 -CONFIG_ARM=y -CONFIG_ARCH_SUNXI=y -CONFIG_MACH_SUN8I=y -CONFIG_TARGET_IPPO_Q8H_V5=y -CONFIG_DEFAULT_DEVICE_TREE=sun8i-a23-ippo-q8h-v5.dtb +CONFIG_FDTFILE=sun8i-a23-ippo-q8h-v5.dtb CONFIG_VIDEO=n CONFIG_USB_KEYBOARD=n ++S:CONFIG_ARM=y ++S:CONFIG_ARCH_SUNXI=y ++S:CONFIG_MACH_SUN8I=y ++S:CONFIG_TARGET_IPPO_Q8H_V5=y ++S:CONFIG_DRAM_CLK=480 +# zq = 0xf777 ++S:CONFIG_DRAM_ZQ=63351 +# Wifi power ++S:CONFIG_AXP221_DLDO1_VOLT=3300 +# aldo1 is connected to VCC-IO, VCC-PD, VCC-USB and VCC-HP ++S:CONFIG_AXP221_ALDO1_VOLT=3000 -- 2.1.0 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH v2 2/4] sunxi: Add support for the rsb (Reduced Serial Bus)
sun8i (A23) introduces a new bus for communicating with the pmic, the rsb, the rsb is also used to communicate with the pmic on the A80, and is documented in the A80 user manual. This commit adds support for this based on the rsb driver from the allwinner u-boot sources. Signed-off-by: Hans de Goede hdego...@redhat.com --- arch/arm/cpu/armv7/sunxi/Makefile | 1 + arch/arm/cpu/armv7/sunxi/rsb.c | 158 + arch/arm/include/asm/arch-sunxi/cpu.h | 1 + arch/arm/include/asm/arch-sunxi/gpio.h | 2 + arch/arm/include/asm/arch-sunxi/prcm.h | 3 +- arch/arm/include/asm/arch-sunxi/rsb.h | 55 6 files changed, 219 insertions(+), 1 deletion(-) create mode 100644 arch/arm/cpu/armv7/sunxi/rsb.c create mode 100644 arch/arm/include/asm/arch-sunxi/rsb.h diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile index 1337b60..3e8975a 100644 --- a/arch/arm/cpu/armv7/sunxi/Makefile +++ b/arch/arm/cpu/armv7/sunxi/Makefile @@ -15,6 +15,7 @@ obj-y += pinmux.o obj-$(CONFIG_MACH_SUN6I) += prcm.o obj-$(CONFIG_MACH_SUN8I) += prcm.o obj-$(CONFIG_MACH_SUN6I) += p2wi.o +obj-$(CONFIG_MACH_SUN8I) += rsb.o obj-$(CONFIG_MACH_SUN4I) += clock_sun4i.o obj-$(CONFIG_MACH_SUN5I) += clock_sun4i.o obj-$(CONFIG_MACH_SUN6I) += clock_sun6i.o diff --git a/arch/arm/cpu/armv7/sunxi/rsb.c b/arch/arm/cpu/armv7/sunxi/rsb.c new file mode 100644 index 000..b72bb9d --- /dev/null +++ b/arch/arm/cpu/armv7/sunxi/rsb.c @@ -0,0 +1,158 @@ +/* + * (C) Copyright 2014 Hans de Goede hdego...@redhat.com + * + * Based on allwinner u-boot sources rsb code which is: + * (C) Copyright 2007-2013 + * Allwinner Technology Co., Ltd. www.allwinnertech.com + * lixiang lixi...@allwinnertech.com + * + * SPDX-License-Identifier:GPL-2.0+ + */ + +#include common.h +#include errno.h +#include asm/arch/cpu.h +#include asm/arch/gpio.h +#include asm/arch/prcm.h +#include asm/arch/rsb.h + +static void rsb_cfg_io(void) +{ + sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN8I_GPL0_R_RSB_SCK); + sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN8I_GPL1_R_RSB_SDA); + sunxi_gpio_set_pull(SUNXI_GPL(0), 1); + sunxi_gpio_set_pull(SUNXI_GPL(1), 1); + sunxi_gpio_set_drv(SUNXI_GPL(0), 2); + sunxi_gpio_set_drv(SUNXI_GPL(1), 2); +} + +static void rsb_set_clk(void) +{ + struct sunxi_rsb_reg * const rsb = + (struct sunxi_rsb_reg *)SUNXI_RSB_BASE; + u32 div = 0; + u32 cd_odly = 0; + + /* Source is Hosc24M, set RSB clk to 3Mhz */ + div = 2400 / 300 / 2 - 1; + cd_odly = div 1; + if (!cd_odly) + cd_odly = 1; + + writel((cd_odly 8) | div, rsb-ccr); +} + +void rsb_init(void) +{ + struct sunxi_rsb_reg * const rsb = + (struct sunxi_rsb_reg *)SUNXI_RSB_BASE; + + rsb_cfg_io(); + + /* Enable RSB and PIO clk, and de-assert their resets */ + prcm_apb0_enable(PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_RSB); + + writel(RSB_CTRL_SOFT_RST, rsb-ctrl); + rsb_set_clk(); +} + +static int rsb_await_trans(void) +{ + struct sunxi_rsb_reg * const rsb = + (struct sunxi_rsb_reg *)SUNXI_RSB_BASE; + unsigned long tmo = timer_get_us() + 100; + u32 stat; + int ret; + + while (1) { + stat = readl(rsb-stat); + if (stat RSB_STAT_LBSY_INT) { + ret = -EBUSY; + break; + } + if (stat RSB_STAT_TERR_INT) { + ret = -EIO; + break; + } + if (stat RSB_STAT_TOVER_INT) { + ret = 0; + break; + } + if (timer_get_us() tmo) { + ret = -ETIME; + break; + } + } + writel(stat, rsb-stat); /* Clear status bits */ + + return ret; +} + +int rsb_set_device_mode(u32 device_mode_data) +{ + struct sunxi_rsb_reg * const rsb = + (struct sunxi_rsb_reg *)SUNXI_RSB_BASE; + unsigned long tmo = timer_get_us() + 100; + + writel(RSB_DMCR_DEVICE_MODE_START | device_mode_data, rsb-dmcr); + + while (readl(rsb-dmcr) RSB_DMCR_DEVICE_MODE_START) { + if (timer_get_us() tmo) + return -ETIME; + } + + return rsb_await_trans(); +} + +static int rsb_do_trans(void) +{ + struct sunxi_rsb_reg * const rsb = + (struct sunxi_rsb_reg *)SUNXI_RSB_BASE; + + setbits_le32(rsb-ctrl, RSB_CTRL_START_TRANS); + return rsb_await_trans(); +} + +int rsb_set_device_address(u16 device_addr, u16 runtime_addr) +{ + struct sunxi_rsb_reg * const rsb = + (struct sunxi_rsb_reg *)SUNXI_RSB_BASE; + + writel(RSB_DEVADDR_RUNTIME_ADDR(runtime_addr) | + RSB_DEVADDR_DEVICE_ADDR(device_addr),
[U-Boot] [PATCH v2 3/4] sun8i: Add dram initialization support
Based on the register / dram_para headers from the Allwinner u-boot / linux sources + the init sequences from boot0. Signed-off-by: Hans de Goede hdego...@redhat.com --- arch/arm/cpu/armv7/sunxi/Makefile | 1 + arch/arm/cpu/armv7/sunxi/board.c | 3 +- arch/arm/cpu/armv7/sunxi/dram_sun8i.c | 346 ++ arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 4 + arch/arm/include/asm/arch-sunxi/dram.h| 2 + arch/arm/include/asm/arch-sunxi/dram_sun8i.h | 266 board/sunxi/Kconfig | 3 +- include/configs/sun8i.h | 2 + 8 files changed, 625 insertions(+), 2 deletions(-) create mode 100644 arch/arm/cpu/armv7/sunxi/dram_sun8i.c create mode 100644 arch/arm/include/asm/arch-sunxi/dram_sun8i.h diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile index 3e8975a..1e89937 100644 --- a/arch/arm/cpu/armv7/sunxi/Makefile +++ b/arch/arm/cpu/armv7/sunxi/Makefile @@ -33,6 +33,7 @@ obj-$(CONFIG_MACH_SUN4I) += dram_sun4i.o obj-$(CONFIG_MACH_SUN5I) += dram_sun4i.o obj-$(CONFIG_MACH_SUN6I) += dram_sun6i.o obj-$(CONFIG_MACH_SUN7I) += dram_sun4i.o +obj-$(CONFIG_MACH_SUN8I) += dram_sun8i.o ifdef CONFIG_SPL_FEL obj-y += start.o endif diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index 9b3e80c..bc98c56 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -114,7 +114,8 @@ void reset_cpu(ulong addr) /* do some early init */ void s_init(void) { -#if defined CONFIG_SPL_BUILD defined CONFIG_MACH_SUN6I +#if defined CONFIG_SPL_BUILD \ + (defined CONFIG_MACH_SUN6I || defined CONFIG_MACH_SUN8I) /* Magic (undocmented) value taken from boot0, without this DRAM * access gets messed up (seems cache related) */ setbits_le32(SUNXI_SRAMC_BASE + 0x44, 0x1800); diff --git a/arch/arm/cpu/armv7/sunxi/dram_sun8i.c b/arch/arm/cpu/armv7/sunxi/dram_sun8i.c new file mode 100644 index 000..df9ff1f --- /dev/null +++ b/arch/arm/cpu/armv7/sunxi/dram_sun8i.c @@ -0,0 +1,346 @@ +/* + * Sun8i platform dram controller init. + * + * (C) Copyright 2014 Hans de Goede hdego...@redhat.com + * + * SPDX-License-Identifier:GPL-2.0+ + */ + +/* + * Note this code uses a lot of magic hex values, that is because this code + * simply replays the init sequence as done by the Allwinner boot0 code, so + * we do not know what these values mean. There are no symbolic constants for + * these magic values, since we do not know how to name them and making up + * names for them is not useful. + * + * The register-layout of the sunxi_mctl_phy_reg-s looks a lot like the one + * found in the TI Keystone2 documentation: + * http://www.ti.com/lit/ug/spruhn7a/spruhn7a.pdf + * Table4-2 DDR3 PHY Registers + * This may be used as a (possible) reference for future work / cleanups. + */ + +#include common.h +#include errno.h +#include asm/io.h +#include asm/arch/clock.h +#include asm/arch/dram.h +#include asm/arch/prcm.h + +static const struct dram_para dram_para = { + .clock = CONFIG_DRAM_CLK, + .type = 3, + .zq = CONFIG_DRAM_ZQ, + .odt_en = 1, + .para1 = 0, /* not used (only used when tpr13 bit 31 is set */ + .para2 = 0, /* not used (only used when tpr13 bit 31 is set */ + .mr0 = 6736, + .mr1 = 4, + .mr2 = 16, + .mr3 = 0, + /* tpr0 - 10 contain timing constants or-ed together in u32 vals */ + .tpr0 = 0x2ab83def, + .tpr1 = 0x18082356, + .tpr2 = 0x00034156, + .tpr3 = 0x448c5533, + .tpr4 = 0x08010d00, + .tpr5 = 0x0340b20f, + .tpr6 = 0x20d118cc, + .tpr7 = 0x14062485, + .tpr8 = 0x220d1d52, + .tpr9 = 0x1e078c22, + .tpr10 = 0x3c, + .tpr11 = 0, /* not used */ + .tpr12 = 0, /* not used */ + .tpr13 = 0x3, +}; + +static void mctl_sys_init(void) +{ + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + + /* enable pll5, note the divide by 2 is deliberate! */ + clock_set_pll5(dram_para.clock * 100 / 2, 1, 2, + dram_para.tpr13 0x4); + + /* deassert ahb mctl reset */ + setbits_le32(ccm-ahb_reset0_cfg, 1 AHB_RESET_OFFSET_MCTL); + + /* enable ahb mctl clock */ + setbits_le32(ccm-ahb_gate0, 1 AHB_GATE_OFFSET_MCTL); +} + +static void mctl_apply_odt_correction(u32 *reg, int correction) +{ + int val; + + val = (readl(reg) 8) 0xff; + val += correction; + + /* clamp */ + if (val 0) + val = 0; + else if (val 255) + val = 255; + + clrsetbits_le32(reg, 0xff00, val 8); +} + +static void mctl_init(u32 *bus_width) +{ + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + struct sunxi_mctl_com_reg * const mctl_com =
[U-Boot] [PATCH v2 1/4] sun6i: s/SUNXI_*P2WI*/SUN6I_*P2WI*/
The p2wi interface is only available on sun6i, adjust the gpio pinmux and base address defines for it to reflect this. Signed-off-by: Hans de Goede hdego...@redhat.com Acked-by: Ian Campbell i...@hellion.org.uk --- arch/arm/cpu/armv7/sunxi/p2wi.c| 14 +++--- arch/arm/include/asm/arch-sunxi/cpu.h | 2 +- arch/arm/include/asm/arch-sunxi/gpio.h | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/arch/arm/cpu/armv7/sunxi/p2wi.c b/arch/arm/cpu/armv7/sunxi/p2wi.c index 48613bd..26a9cfc 100644 --- a/arch/arm/cpu/armv7/sunxi/p2wi.c +++ b/arch/arm/cpu/armv7/sunxi/p2wi.c @@ -26,13 +26,13 @@ void p2wi_init(void) { - struct sunxi_p2wi_reg *p2wi = (struct sunxi_p2wi_reg *)SUNXI_P2WI_BASE; + struct sunxi_p2wi_reg *p2wi = (struct sunxi_p2wi_reg *)SUN6I_P2WI_BASE; /* Enable p2wi and PIO clk, and de-assert their resets */ prcm_apb0_enable(PRCM_APB0_GATE_PIO | PRCM_APB0_GATE_P2WI); - sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUNXI_GPL0_R_P2WI_SCK); - sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUNXI_GPL1_R_P2WI_SDA); + sunxi_gpio_set_cfgpin(SUNXI_GPL(0), SUN6I_GPL0_R_P2WI_SCK); + sunxi_gpio_set_cfgpin(SUNXI_GPL(1), SUN6I_GPL1_R_P2WI_SDA); /* Reset p2wi controller and set clock to CLKIN(12)/8 = 1.5 MHz */ writel(P2WI_CTRL_RESET, p2wi-ctrl); @@ -43,7 +43,7 @@ void p2wi_init(void) int p2wi_change_to_p2wi_mode(u8 slave_addr, u8 ctrl_reg, u8 init_data) { - struct sunxi_p2wi_reg *p2wi = (struct sunxi_p2wi_reg *)SUNXI_P2WI_BASE; + struct sunxi_p2wi_reg *p2wi = (struct sunxi_p2wi_reg *)SUN6I_P2WI_BASE; unsigned long tmo = timer_get_us() + 100; writel(P2WI_PM_DEV_ADDR(slave_addr) | @@ -62,7 +62,7 @@ int p2wi_change_to_p2wi_mode(u8 slave_addr, u8 ctrl_reg, u8 init_data) static int p2wi_await_trans(void) { - struct sunxi_p2wi_reg *p2wi = (struct sunxi_p2wi_reg *)SUNXI_P2WI_BASE; + struct sunxi_p2wi_reg *p2wi = (struct sunxi_p2wi_reg *)SUN6I_P2WI_BASE; unsigned long tmo = timer_get_us() + 100; int ret; u8 reg; @@ -88,7 +88,7 @@ static int p2wi_await_trans(void) int p2wi_read(const u8 addr, u8 *data) { - struct sunxi_p2wi_reg *p2wi = (struct sunxi_p2wi_reg *)SUNXI_P2WI_BASE; + struct sunxi_p2wi_reg *p2wi = (struct sunxi_p2wi_reg *)SUN6I_P2WI_BASE; int ret; writel(P2WI_DATADDR_BYTE_1(addr), p2wi-dataddr0); @@ -105,7 +105,7 @@ int p2wi_read(const u8 addr, u8 *data) int p2wi_write(const u8 addr, u8 data) { - struct sunxi_p2wi_reg *p2wi = (struct sunxi_p2wi_reg *)SUNXI_P2WI_BASE; + struct sunxi_p2wi_reg *p2wi = (struct sunxi_p2wi_reg *)SUN6I_P2WI_BASE; writel(P2WI_DATADDR_BYTE_1(addr), p2wi-dataddr0); writel(P2WI_DATA_BYTE_1(data), p2wi-data0); diff --git a/arch/arm/include/asm/arch-sunxi/cpu.h b/arch/arm/include/asm/arch-sunxi/cpu.h index 9500262..adf203a 100644 --- a/arch/arm/include/asm/arch-sunxi/cpu.h +++ b/arch/arm/include/asm/arch-sunxi/cpu.h @@ -128,7 +128,7 @@ #define SUN6I_CPUCFG_BASE 0x01f01c00 #define SUNXI_R_UART_BASE 0x01f02800 #define SUNXI_R_PIO_BASE 0x01f02c00 -#define SUNXI_P2WI_BASE0x01f03400 +#define SUN6I_P2WI_BASE0x01f03400 /* CoreSight Debug Module */ #define SUNXI_CSDM_BASE0x3f50 diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index 366c0dc..9f972ce 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -173,8 +173,8 @@ enum sunxi_gpio_number { #define SUN4I_GPI4_SDC32 -#define SUNXI_GPL0_R_P2WI_SCK 3 -#define SUNXI_GPL1_R_P2WI_SDA 3 +#define SUN6I_GPL0_R_P2WI_SCK 3 +#define SUN6I_GPL1_R_P2WI_SDA 3 #define SUN8I_GPL2_R_UART_TX 2 #define SUN8I_GPL3_R_UART_RX 2 -- 2.1.0 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 3/6] sunxi: video: Add sunxi_hdmi_edid_get_block helper function
Add a sunxi_hdmi_edid_get_block helper function, this is a preparation patch for adding support for parsing EDID extension blocks. Signed-off-by: Hans de Goede hdego...@redhat.com --- drivers/video/sunxi_display.c | 31 --- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c index 394153a..3048410 100644 --- a/drivers/video/sunxi_display.c +++ b/drivers/video/sunxi_display.c @@ -137,6 +137,24 @@ static int sunxi_hdmi_ddc_read(int offset, u8 *buf, int count) return 0; } +static int sunxi_hdmi_edid_get_block(int block, u8 *buf) +{ + int r, retries = 2; + + do { + r = sunxi_hdmi_ddc_read(block * 128, buf, 128); + if (r) + continue; + r = edid_check_checksum(buf); + if (r) { + printf(EDID block %d: checksum error%s\n, + block, retries ? , retrying : ); + } + } while (r retries--); + + return r; +} + static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode) { struct edid1_info edid1; @@ -146,7 +164,7 @@ static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode) (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE; struct sunxi_ccm_reg * const ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; - int i, r, retries = 2; + int i, r; /* SUNXI_HDMI_CTRL_ENABLE PAD_CTRL0 are already set by hpd_detect */ writel(SUNXI_HDMI_PAD_CTRL1 | SUNXI_HDMI_PAD_CTRL1_HALVE, @@ -170,16 +188,7 @@ static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode) SUNXI_HMDI_DDC_LINE_CTRL_SCL_ENABLE, hdmi-ddc_line_ctrl); #endif - do { - r = sunxi_hdmi_ddc_read(0, (u8 *)edid1, 128); - if (r) - continue; - r = edid_check_checksum((u8 *)edid1); - if (r) { - printf(EDID: checksum error%s\n, - retries ? , retrying : ); - } - } while (r retries--); + r = sunxi_hdmi_edid_get_block(0, (u8 *)edid1); /* Disable DDC engine, no longer needed */ clrbits_le32(hdmi-ddc_ctrl, SUNXI_HMDI_DDC_CTRL_ENABLE); -- 2.1.0 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 0/6] sunxi: video: Add hdmi output fmt support + misc fixes
Hi Anatolij Ian, Here is a second series of sunxi video support improvments. Anatolij, can you please review the first patch of the series? You're input on the rest is welcome too of course :) Regards, Hans ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 1/6] edid: Add struct and defines for cea681 extension blocks
Add a struct describing the (fixed) bits of cea681 edid extension blocks, and defines for accessing various bitfields. Signed-off-by: Hans de Goede hdego...@redhat.com --- include/edid.h | 19 +++ 1 file changed, 19 insertions(+) diff --git a/include/edid.h b/include/edid.h index a69f43a..18ec1d5 100644 --- a/include/edid.h +++ b/include/edid.h @@ -230,6 +230,25 @@ struct edid1_info { unsigned char checksum; } __attribute__ ((__packed__)); +struct edid_cea861_info { + unsigned char extension_tag; +#define EDID_CEA861_EXTENSION_TAG 0x02 + unsigned char revision; + unsigned char dtd_offset; + unsigned char dtd_count; +#define EDID_CEA861_SUPPORTS_UNDERSCAN(_x) \ + GET_BIT(((_x).dtd_count), 7) +#define EDID_CEA861_SUPPORTS_BASIC_AUDIO(_x) \ + GET_BIT(((_x).dtd_count), 6) +#define EDID_CEA861_SUPPORTS_YUV444(_x) \ + GET_BIT(((_x).dtd_count), 5) +#define EDID_CEA861_SUPPORTS_YUV422(_x) \ + GET_BIT(((_x).dtd_count), 4) +#define EDID_CEA861_DTD_COUNT(_x) \ + GET_BITS(((_x).dtd_count), 3, 0) + unsigned char data[124]; +} __attribute__ ((__packed__)); + /** * Print the EDID info. * -- 2.1.0 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 4/6] sunxi: video: When using edid use CEA681 extension blocks to select hdmi output
When using edid use CEA681 edid extension blocks to select between dvi and hdmi output formats, so that u-boot will automatically do the right thing. Signed-off-by: Hans de Goede hdego...@redhat.com --- drivers/video/sunxi_display.c | 43 ++- 1 file changed, 34 insertions(+), 9 deletions(-) diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c index 3048410..795835d 100644 --- a/drivers/video/sunxi_display.c +++ b/drivers/video/sunxi_display.c @@ -155,16 +155,17 @@ static int sunxi_hdmi_edid_get_block(int block, u8 *buf) return r; } -static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode) +static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode, char *monitor) { struct edid1_info edid1; + struct edid_cea861_info cea681[4]; struct edid_detailed_timing *t = (struct edid_detailed_timing *)edid1.monitor_details.timing; struct sunxi_hdmi_reg * const hdmi = (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE; struct sunxi_ccm_reg * const ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; - int i, r; + int i, r, ext_blocks = 0; /* SUNXI_HDMI_CTRL_ENABLE PAD_CTRL0 are already set by hpd_detect */ writel(SUNXI_HDMI_PAD_CTRL1 | SUNXI_HDMI_PAD_CTRL1_HALVE, @@ -189,6 +190,25 @@ static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode) #endif r = sunxi_hdmi_edid_get_block(0, (u8 *)edid1); + if (r == 0) { + r = edid_check_info(edid1); + if (r) { + printf(EDID: invalid EDID data\n); + r = -EINVAL; + } + } + if (r == 0) { + ext_blocks = edid1.extension_flag; + if (ext_blocks 4) + ext_blocks = 4; + for (i = 0; i ext_blocks; i++) { + if (sunxi_hdmi_edid_get_block(1 + i, + (u8 *)cea681[i]) != 0) { + ext_blocks = i; + break; + } + } + } /* Disable DDC engine, no longer needed */ clrbits_le32(hdmi-ddc_ctrl, SUNXI_HMDI_DDC_CTRL_ENABLE); @@ -197,12 +217,6 @@ static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode) if (r) return r; - r = edid_check_info(edid1); - if (r) { - printf(EDID: invalid EDID data\n); - return -EINVAL; - } - /* We want version 1.3 or 1.2 with detailed timing info */ if (edid1.version != 1 || (edid1.revision 3 !EDID1_INFO_FEATURE_PREFERRED_TIMING_MODE(edid1))) { @@ -222,6 +236,17 @@ static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode) return -ENOENT; } + /* Check for basic audio support, if found enable hdmi output */ + strcpy(monitor, dvi); + for (i = 0; i ext_blocks; i++) { + if (cea681[i].extension_tag != EDID_CEA861_EXTENSION_TAG || + cea681[i].revision 2) + continue; + + if (EDID_CEA861_SUPPORTS_BASIC_AUDIO(cea681[i])) + strcpy(monitor, hdmi); + } + return 0; } @@ -597,7 +622,7 @@ void *video_hw_init(void) /* Check edid if requested and we've a cable plugged in */ if (edid ret) { - if (sunxi_hdmi_edid_get_mode(edid_mode) == 0) + if (sunxi_hdmi_edid_get_mode(edid_mode, monitor) == 0) mode = edid_mode; } -- 2.1.0 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 6/6] sunxi: video: Set input sync enable
Add a write to the unknown (*) register to enable auto input sync, when initially adding sunxi hdmi output support this magic write from the android kernel code was missed, causing lcdc - hdmi encoder sync problems. With this write added, we can drop the modesetting retries and the extra delays added to work around these sync problems. *) unknown is the actual name of this register in the android kernel sources Signed-off-by: Hans de Goede hdego...@redhat.com --- arch/arm/include/asm/arch-sunxi/display.h | 1 + drivers/video/sunxi_display.c | 23 --- 2 files changed, 5 insertions(+), 19 deletions(-) diff --git a/arch/arm/include/asm/arch-sunxi/display.h b/arch/arm/include/asm/arch-sunxi/display.h index 838b217..00e3466 100644 --- a/arch/arm/include/asm/arch-sunxi/display.h +++ b/arch/arm/include/asm/arch-sunxi/display.h @@ -236,6 +236,7 @@ struct sunxi_hdmi_reg { #define SUNXI_HDMI_PKT_CTRL0 0x0f21 #define SUNXI_HDMI_PKT_CTRL1 0x000f +#define SUNXI_HDMI_UNKNOWN_INPUT_SYNC 0x0800 #ifdef CONFIG_MACH_SUN6I #define SUNXI_HMDI_DDC_CTRL_ENABLE (1 0) diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c index 5a14785..a0a0613 100644 --- a/drivers/video/sunxi_display.c +++ b/drivers/video/sunxi_display.c @@ -501,6 +501,9 @@ static void sunxi_hdmi_mode_set(const struct ctfb_res_modes *mode, if (hdmi_mode) sunxi_hdmi_setup_info_frames(mode); + /* Set input sync enable */ + writel(SUNXI_HDMI_UNKNOWN_INPUT_SYNC, hdmi-unknown); + /* Init various registers, select pll3 as clock source */ writel(SUNXI_HDMI_VIDEO_POL_TX_CLK, hdmi-video_polarity); writel(SUNXI_HDMI_PAD_CTRL0_RUN, hdmi-pad_ctrl0); @@ -556,10 +559,8 @@ static void sunxi_mode_set(const struct ctfb_res_modes *mode, char *monitor, struct sunxi_hdmi_reg * const hdmi = (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE; int clk_div, clk_double; - int retries = 3; bool hdmi_mode = strcmp(monitor, hdmi) == 0; -retry: clrbits_le32(hdmi-video_ctrl, SUNXI_HDMI_VIDEO_CTRL_ENABLE); clrbits_le32(lcdc-ctrl, SUNXI_LCDC_CTRL_TCON_ENABLE); clrbits_le32(de_be-mode, SUNXI_DE_BE_MODE_START); @@ -570,27 +571,11 @@ retry: setbits_le32(de_be-reg_ctrl, SUNXI_DE_BE_REG_CTRL_LOAD_REGS); setbits_le32(de_be-mode, SUNXI_DE_BE_MODE_START); - - udelay(100 / mode-refresh + 500); - setbits_le32(lcdc-ctrl, SUNXI_LCDC_CTRL_TCON_ENABLE); - udelay(100 / mode-refresh + 500); + udelay(100); setbits_le32(hdmi-video_ctrl, SUNXI_HDMI_VIDEO_CTRL_ENABLE); - - udelay(100 / mode-refresh + 500); - - /* -* Sometimes the display pipeline does not sync up properly, if -* this happens the hdmi fifo underrun or overrun bits are set. -*/ - if (readl(hdmi-irq) - (SUNXI_HDMI_IRQ_STATUS_FIFO_UF | SUNXI_HDMI_IRQ_STATUS_FIFO_OF)) { - if (retries--) - goto retry; - printf(HDMI fifo under or overrun\n); - } } void *video_hw_init(void) -- 2.1.0 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 5/6] sunxi: video: Give hotplug-detect (hpd) signal some time to show up
When using a hdmi powered hdmi to vga dongle, and cold booting a sunxi device, the hpd detect code would not see the dongle (until a warm reboot), because the dongle needs some time to boot. Testing has shown that this dongle needs 213ms to respond on a cold boot, so wait up to 300ms for a hpd signal to show up before giving up. Signed-off-by: Hans de Goede hdego...@redhat.com --- drivers/video/sunxi_display.c | 8 ++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c index 795835d..5a14785 100644 --- a/drivers/video/sunxi_display.c +++ b/drivers/video/sunxi_display.c @@ -48,6 +48,7 @@ static int sunxi_hdmi_hpd_detect(void) (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; struct sunxi_hdmi_reg * const hdmi = (struct sunxi_hdmi_reg *)SUNXI_HDMI_BASE; + unsigned long tmo = timer_get_us() + 30; /* Set pll3 to 300MHz */ clock_set_pll3(3); @@ -68,9 +69,12 @@ static int sunxi_hdmi_hpd_detect(void) writel(SUNXI_HDMI_CTRL_ENABLE, hdmi-ctrl); writel(SUNXI_HDMI_PAD_CTRL0_HDP, hdmi-pad_ctrl0); - udelay(1000); + while (timer_get_us() tmo) { + if (readl(hdmi-hpd) SUNXI_HDMI_HPD_DETECT) + return 1; + } - return (readl(hdmi-hpd) SUNXI_HDMI_HPD_DETECT) ? 1 : 0; + return 0; } static void sunxi_hdmi_shutdown(void) -- 2.1.0 ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
[U-Boot] [PATCH 2/6] sunxi: video: Add hdmi support
So far we've been programming the hdmi-encoder to send out dvi data over the hdmi connector. This works well for most devices, including hdmi devices, but not all devices accept dvi data on a hdmi input. Add support for sending proper hdmi data over the hdmi output found on most sunxi boards. This can be turned on by adding by adding monitor=hdmi as option to the video-mode env. variable. A follow up patch will determine wether to send dvi or hdmi automatically when EDID is used. Signed-off-by: Hans de Goede hdego...@redhat.com --- arch/arm/include/asm/arch-sunxi/display.h | 33 +++- drivers/video/sunxi_display.c | 66 --- 2 files changed, 84 insertions(+), 15 deletions(-) diff --git a/arch/arm/include/asm/arch-sunxi/display.h b/arch/arm/include/asm/arch-sunxi/display.h index 8c4835e..838b217 100644 --- a/arch/arm/include/asm/arch-sunxi/display.h +++ b/arch/arm/include/asm/arch-sunxi/display.h @@ -102,23 +102,30 @@ struct sunxi_hdmi_reg { u32 video_fp; /* 0x01c */ u32 video_spw; /* 0x020 */ u32 video_polarity; /* 0x024 */ - u8 res0[0x1d8]; /* 0x028 */ + u8 res0[0x58]; /* 0x028 */ + u8 avi_info_frame[0x14];/* 0x080 */ + u8 res1[0x4c]; /* 0x094 */ + u32 qcp_packet0;/* 0x0e0 */ + u32 qcp_packet1;/* 0x0e4 */ + u8 res2[0x118]; /* 0x0e8 */ u32 pad_ctrl0; /* 0x200 */ u32 pad_ctrl1; /* 0x204 */ u32 pll_ctrl; /* 0x208 */ u32 pll_dbg0; /* 0x20c */ u32 pll_dbg1; /* 0x210 */ u32 hpd_cec;/* 0x214 */ - u8 res1[0x28]; /* 0x218 */ - u32 spd_pkt;/* 0x240 */ - u8 res2[0xac]; /* 0x244 */ + u8 res3[0x28]; /* 0x218 */ + u8 vendor_info_frame[0x14]; /* 0x240 */ + u8 res4[0x9c]; /* 0x254 */ u32 pkt_ctrl0; /* 0x2f0 */ u32 pkt_ctrl1; /* 0x2f4 */ - u8 res3[0x18]; /* 0x2f8 */ + u8 res5[0x8]; /* 0x2f8 */ + u32 unknown;/* 0x300 */ + u8 res6[0xc]; /* 0x304 */ u32 audio_sample_count; /* 0x310 */ - u8 res4[0xec]; /* 0x314 */ + u8 res7[0xec]; /* 0x314 */ u32 audio_tx_fifo; /* 0x400 */ - u8 res5[0xfc]; /* 0x404 */ + u8 res8[0xfc]; /* 0x404 */ #ifndef CONFIG_MACH_SUN6I u32 ddc_ctrl; /* 0x500 */ u32 ddc_addr; /* 0x504 */ @@ -131,7 +138,7 @@ struct sunxi_hdmi_reg { u32 ddc_cmnd; /* 0x520 */ u32 ddc_exreg; /* 0x524 */ u32 ddc_clock; /* 0x528 */ - u8 res6[0x14]; /* 0x52c */ + u8 res9[0x14]; /* 0x52c */ u32 ddc_line_ctrl; /* 0x540 */ #else u32 ddc_ctrl; /* 0x500 */ @@ -144,9 +151,9 @@ struct sunxi_hdmi_reg { u32 ddc_fifo_status;/* 0x51c */ u32 ddc_clock; /* 0x520 */ u32 ddc_timeout;/* 0x524 */ - u8 res6[0x18]; /* 0x528 */ + u8 res9[0x18]; /* 0x528 */ u32 ddc_dbg;/* 0x540 */ - u8 res7[0x3c]; /* 0x544 */ + u8 res10[0x3c]; /* 0x544 */ u32 ddc_fifo_data; /* 0x580 */ #endif }; @@ -191,9 +198,12 @@ struct sunxi_hdmi_reg { #define SUNXI_HDMI_IRQ_STATUS_BITS 0x73 #define SUNXI_HDMI_HPD_DETECT (1 0) #define SUNXI_HDMI_VIDEO_CTRL_ENABLE (1 31) +#define SUNXI_HDMI_VIDEO_CTRL_HDMI (1 30) #define SUNXI_HDMI_VIDEO_POL_HOR (1 0) #define SUNXI_HDMI_VIDEO_POL_VER (1 1) #define SUNXI_HDMI_VIDEO_POL_TX_CLK(0x3e0 16) +#define SUNXI_HDMI_QCP_PACKET0 3 +#define SUNXI_HDMI_QCP_PACKET1 0 #ifdef CONFIG_MACH_SUN6I #define SUNXI_HDMI_PAD_CTRL0_HDP 0x7e8f @@ -224,6 +234,9 @@ struct sunxi_hdmi_reg { #define SUNXI_HDMI_PLL_DBG0_PLL3 (0 21) #define SUNXI_HDMI_PLL_DBG0_PLL7 (1 21) +#define SUNXI_HDMI_PKT_CTRL0 0x0f21 +#define SUNXI_HDMI_PKT_CTRL1 0x000f + #ifdef CONFIG_MACH_SUN6I #define SUNXI_HMDI_DDC_CTRL_ENABLE (1 0) #define SUNXI_HMDI_DDC_CTRL_SCL_ENABLE (1 4) diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c index 0997740..394153a 100644 ---
[U-Boot] linux-sunxi/u-boot-sunxi is no longer supported, time to switch to upstream u-boot
Hi All, There are 3 topics which I would like to cover in this mail: 1) Switching over to upstream u-boot for the linux-sunxi project 2) How to build upstream u-boot for use with linux-sunxi sunxi-3.4 kernels 3) Adding more boards to upstream u-boot 1. Switching over to upstream u-boot for the linux-sunxi project Upstream u-boot has had sunxi support for a while now, and has slowly been gaining a lot of features over the linux-sunxi/u-boot-sunxi version at: https://github.com/linux-sunxi/u-boot-sunxi/ Some of the new features supported upstream are booting from usb, booting from sata (ahci) and full sun6i (A31) support including SPL support. Also upstream u-boot supports using hdmi out + an usb keyboard as u-boot console, so that one does not need to solder a serial console to things like hdmi tv-dongles. Upstream u-boot also has full sun8i (A23) support in the pipeline including SPL support. One of the things which has stopped people from switching to upstream u-boot so far is that upstream u-boot did not work with the linux-sunxi sunxi-3.4 kernels, but current upstream u-boot git master: http://git.denx.de/?p=u-boot.git;a=summary Now also has support for booting older kernels, so it is time that we stop maintaining linux-sunxi/u-boot-sunxi and start focussing all our efforts on upstream u-boot. 2. How to build upstream u-boot for use with linux-sunxi sunxi-3.4 kernels == Here are some example instructions on how to build upstream u-boot for the Cubietruck: git clone git://git.denx.de/u-boot.git cd u-boot make -j4 CROSS_COMPILE=arm-linux-gnu- Cubietruck_defconfig # If you want to use an upstream kernel the next steps can be skipped (*) make -j4 CROSS_COMPILE=arm-linux-gnu- menuconfig # select ARM architecture - Enable workarounds for booting old kernels # exit save make -j4 CROSS_COMPILE=arm-linux-gnu- spl/menuconfig # select ARM architecture - Enable workarounds for booting old kernels # exit save # skip to here if you're using an upstream kernel make -j4 CROSS_COMPILE=arm-linux-gnu- And now you will have a u-boot-sunxi-with-spl.bin to dd to your sdcard as usual. If you look in the upstream configs directory you will already find defconfig files for a lot of popular boards there, replace Cubietruck_defconfig with the one for your board to build u-boot for your board. See below for instructions on how to add a new board if your board is missing. *) These steps can be skipped too when using sun4i (A10) or sun5i (A10s / A13) with a current linux-sunxi/stage/sunxi-3.4 kernel. 3. Adding more boards to upstream u-boot If you own a board which is already supported in linux-sunxi/u-boot-sunxi, and is not yet upstream, please add support for it, there are 3 simple steps to add a new board to upstream u-boot, see below. If you've any trouble with this, but are willing to be listed as a contact person for this board let me know and I'll create a patch adding the board for you to test. 1) Add the dram_foo.c file for your board from linux-sunxi/u-boot-sunxi/board/sunxi to upstream u-boot/board/sunxi and add a line for it to u-boot/board/sunxi/Makefile, see existing lines there for how this should look. 2) Create a configs/foo_defconfig file for your board, take a look at configs/Cubietruck_defconfig for an example, typically all the options found in linux-sunxi/u-boot-sunxi/boards.cfg for the board go in the CONFIG_SYS_EXTRA_OPTIONS field, except for the boardname define, which gets replaced with a line like this: +S:CONFIG_TARGET_CUBIETRUCK=y 3) Add an entry for the board to board/sunxi/MAINTAINERS, with yourself as contact person for the board. For upstream u-boot we want to have a contact person for each supported board, so that users have someone to mail who owns the actual board in case of questions. This is also why we've not simply copied all the boards from linux-sunxi/u-boot-sunxi to upstream u-boot. Regards, Hans ___ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot