[U-Boot] [PATCH v3 00/10] sunxi: Bug fixes, sun4i and sun5i support and network improvements

Hi All,
Here is v2 of my patch series to be applied on top of Ian's recently merged basic sun7i support.
This patch series begins with a few bug fixes found while working on preparing the rest of the series, adds sun4i and sun5i support and rounds things of with some networking fixes / additions.
Changes since v1: -Improved various commit messages -Various small typo fixes -Cleaned up the axp209 and axp152 drivers -Added Acked-by: Ian Campbell ... to the patches which got acked by Ian
Changes since v2: -Dropped the i2c + pmic support patches as they need more work -Split out the boards.cfg Cubietruck maintainer field changes from the axp209 support patch into its own patch -Added Acked-by: Ian Campbell ... to the patches which got acked by Ian
Regards,
Hans

We should not be aligning the amount of bytes which we try to read from the disk, this leads to trying to read more bytes then there are which fails.
file_size is already aligned to BLOCK_SIZE before being stored in img.header.length, so there is no need for load_size at all.
Signed-off-by: Hans de Goede hdegoede@redhat.com Acked-by: Ian Campbell ijc@hellion.org.uk --- tools/mksunxiboot.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/tools/mksunxiboot.c b/tools/mksunxiboot.c index da7c9f0..1f0fbae 100644 --- a/tools/mksunxiboot.c +++ b/tools/mksunxiboot.c @@ -77,7 +77,7 @@ int main(int argc, char *argv[]) { int fd_in, fd_out; struct boot_img img; - unsigned file_size, load_size; + unsigned file_size; int count;
if (argc < 2) { @@ -101,8 +101,6 @@ int main(int argc, char *argv[]) if (file_size > SRAM_LOAD_MAX_SIZE) { fprintf(stderr, "ERROR: File too large!\n"); return EXIT_FAILURE; - } else { - load_size = ALIGN(file_size, sizeof(int)); }
fd_out = open(argv[2], O_WRONLY | O_CREAT, 0666); @@ -113,8 +111,8 @@ int main(int argc, char *argv[])
/* read file to buffer to calculate checksum */ lseek(fd_in, 0, SEEK_SET); - count = read(fd_in, img.code, load_size); - if (count != load_size) { + count = read(fd_in, img.code, file_size); + if (count != file_size) { perror("Reading input image"); return EXIT_FAILURE; } @@ -126,7 +124,7 @@ int main(int argc, char *argv[]) & 0x00FFFFFF); memcpy(img.header.magic, BOOT0_MAGIC, 8); /* no '0' termination */ img.header.length = - ALIGN(load_size + sizeof(struct boot_file_head), BLOCK_SIZE); + ALIGN(file_size + sizeof(struct boot_file_head), BLOCK_SIZE); gen_check_sum(&img.header);
count = write(fd_out, &img, img.header.length);

Adjust the u-boot-spl.lds linker script to match the changes made in the 41623c91b09a0c865fab41acdaff30f060f29ad6 "arm: move exception handling out of start.S files" commit.
Signed-off-by: Hans de Goede hdegoede@redhat.com Acked-by: Ian Campbell ijc@hellion.org.uk --- arch/arm/cpu/armv7/sunxi/u-boot-spl.lds | 1 + 1 file changed, 1 insertion(+)
diff --git a/arch/arm/cpu/armv7/sunxi/u-boot-spl.lds b/arch/arm/cpu/armv7/sunxi/u-boot-spl.lds index 5008028..c1ae227 100644 --- a/arch/arm/cpu/armv7/sunxi/u-boot-spl.lds +++ b/arch/arm/cpu/armv7/sunxi/u-boot-spl.lds @@ -27,6 +27,7 @@ SECTIONS .text : { __start = .; + *(.vectors) arch/arm/cpu/armv7/start.o (.text) *(.text*) } > .sram

The DMA code in sunxi_mmc.c is broken. mmc_trans_data_by_dma() allocates the dma descriptors on the stack, and then exits while the dma transfer is in progress, so the dma engine is reading stack memory which at that point may be re-used. So far we've gotten away with this by luck, but recent u-boot changes have shifted the stack start address by 16 bytes, which combined with dma alignment now exposes this problem.
Since we end up just busy waiting for the dma engine anyway, this commit fixes things by simply removing the dma code, resulting in smaller bug-free code.
Signed-off-by: Hans de Goede hdegoede@redhat.com Acked-by: Ian Campbell ijc@hellion.org.uk --- drivers/mmc/sunxi_mmc.c | 140 ++--------------------------------------- include/configs/sunxi-common.h | 1 - 2 files changed, 6 insertions(+), 135 deletions(-)
diff --git a/drivers/mmc/sunxi_mmc.c b/drivers/mmc/sunxi_mmc.c index eb7b115..ae0cf1a 100644 --- a/drivers/mmc/sunxi_mmc.c +++ b/drivers/mmc/sunxi_mmc.c @@ -16,28 +16,6 @@ #include <asm/arch/cpu.h> #include <asm/arch/mmc.h>
-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 */ -#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; - u32 buf_addr_ptr1; - u32 buf_addr_ptr2; -}; - struct sunxi_mmc_host { unsigned mmc_no; uint32_t *mclkreg; @@ -189,6 +167,9 @@ static int mmc_core_init(struct mmc *mmc)
/* Reset controller */ writel(SUNXI_MMC_GCTRL_RESET, &mmchost->reg->gctrl); + udelay(1000); + /* Always read / write data through the CPU */ + writel(SUNXI_MMC_GCTRL_ACCESS_BY_AHB, &mmchost->reg->gctrl);
return 0; } @@ -220,85 +201,6 @@ static int mmc_trans_data_by_cpu(struct mmc *mmc, struct mmc_data *data) return 0; }
-static int mmc_trans_data_by_dma(struct mmc *mmc, struct mmc_data *data) -{ - struct sunxi_mmc_host *mmchost = mmc->priv; - unsigned byte_cnt = data->blocksize * data->blocks; - unsigned char *buff; - unsigned des_idx = 0; - unsigned buff_frag_num = - (byte_cnt + SDXC_DES_BUFFER_MAX_LEN - 1) >> SDXC_DES_NUM_SHIFT; - unsigned remain; - unsigned i, rval; - ALLOC_CACHE_ALIGN_BUFFER(struct sunxi_mmc_des, pdes, buff_frag_num); - - buff = data->flags & MMC_DATA_READ ? - (unsigned char *)data->dest : (unsigned char *)data->src; - remain = byte_cnt & (SDXC_DES_BUFFER_MAX_LEN - 1); - - 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 = 0; /* 0 == 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]; - } - } - flush_cache((unsigned long)pdes, - sizeof(struct sunxi_mmc_des) * (des_idx + 1)); - - rval = readl(&mmchost->reg->gctrl); - /* Enable DMA */ - writel(rval | SUNXI_MMC_GCTRL_DMA_RESET | SUNXI_MMC_GCTRL_DMA_ENABLE, - &mmchost->reg->gctrl); - /* Reset iDMA */ - writel(SUNXI_MMC_IDMAC_RESET, &mmchost->reg->dmac); - /* Enable iDMA */ - writel(SUNXI_MMC_IDMAC_FIXBURST | SUNXI_MMC_IDMAC_ENABLE, - &mmchost->reg->dmac); - rval = readl(&mmchost->reg->idie) & - ~(SUNXI_MMC_IDIE_TXIRQ|SUNXI_MMC_IDIE_RXIRQ); - if (data->flags & MMC_DATA_WRITE) - rval |= SUNXI_MMC_IDIE_TXIRQ; - else - rval |= SUNXI_MMC_IDIE_RXIRQ; - writel(rval, &mmchost->reg->idie); - writel((u32) pdes, &mmchost->reg->dlba); - writel((0x2 << 28) | (0x7 << 16) | (0x01 << 3), - &mmchost->reg->ftrglevel); - - return 0; -} - -static void mmc_enable_dma_accesses(struct mmc *mmc, int dma) -{ - struct sunxi_mmc_host *mmchost = mmc->priv; - - unsigned int gctrl = readl(&mmchost->reg->gctrl); - if (dma) - gctrl &= ~SUNXI_MMC_GCTRL_ACCESS_BY_AHB; - else - gctrl |= SUNXI_MMC_GCTRL_ACCESS_BY_AHB; - writel(gctrl, &mmchost->reg->gctrl); -} - static int mmc_rint_wait(struct mmc *mmc, unsigned int timeout_msecs, unsigned int done_bit, const char *what) { @@ -327,7 +229,6 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, unsigned int timeout_msecs; int error = 0; unsigned int status = 0; - unsigned int usedma = 0; unsigned int bytecnt = 0;
if (mmchost->fatal_err) @@ -378,20 +279,8 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
bytecnt = data->blocksize * data->blocks; debug("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; - mmc_enable_dma_accesses(mmc, 1); - ret = mmc_trans_data_by_dma(mmc, data); - writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd); - } else { - mmc_enable_dma_accesses(mmc, 0); - writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd); - ret = mmc_trans_data_by_cpu(mmc, data); - } + writel(cmdval | cmd->cmdidx, &mmchost->reg->cmd); + ret = mmc_trans_data_by_cpu(mmc, data); if (ret) { error = readl(&mmchost->reg->rint) & \ SUNXI_MMC_RINT_INTERRUPT_ERROR_BIT; @@ -405,7 +294,7 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, goto out;
if (data) { - timeout_msecs = usedma ? 120 * bytecnt : 120; + timeout_msecs = 120; debug("cacl timeout %x msec\n", timeout_msecs); error = mmc_rint_wait(mmc, timeout_msecs, data->blocks > 1 ? @@ -442,23 +331,6 @@ static int mmc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd, debug("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) & ~SUNXI_MMC_GCTRL_DMA_ENABLE, - &mmchost->reg->gctrl); - } if (error < 0) { writel(SUNXI_MMC_GCTRL_RESET, &mmchost->reg->gctrl); mmc_update_clk(mmc); diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index 5d72d62..fd02d0d 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -70,7 +70,6 @@ #define CONFIG_CMD_MMC #define CONFIG_MMC_SUNXI #define CONFIG_MMC_SUNXI_SLOT 0 -#define CONFIG_MMC_SUNXI_USE_DMA #define CONFIG_ENV_IS_IN_MMC #define CONFIG_SYS_MMC_ENV_DEV 0 /* first detected MMC controller */

On Mon, 9 Jun 2014 11:36:55 +0200 Hans de Goede hdegoede@redhat.com wrote:
The DMA code in sunxi_mmc.c is broken. mmc_trans_data_by_dma() allocates the dma descriptors on the stack, and then exits while the dma transfer is in progress, so the dma engine is reading stack memory which at that point may be re-used. So far we've gotten away with this by luck, but recent u-boot changes have shifted the stack start address by 16 bytes, which combined with dma alignment now exposes this problem.
Since we end up just busy waiting for the dma engine anyway, this commit fixes things by simply removing the dma code, resulting in smaller bug-free code.
Signed-off-by: Hans de Goede hdegoede@redhat.com Acked-by: Ian Campbell ijc@hellion.org.uk
Acked-by: Siarhei Siamashka siarhei.siamashka@gmail.com
Was it a good idea to keep v2014.07 release relying on luck without this patch?

Hi,
On 07/23/2014 07:35 PM, Siarhei Siamashka wrote:
On Mon, 9 Jun 2014 11:36:55 +0200 Hans de Goede hdegoede@redhat.com wrote:
The DMA code in sunxi_mmc.c is broken. mmc_trans_data_by_dma() allocates the dma descriptors on the stack, and then exits while the dma transfer is in progress, so the dma engine is reading stack memory which at that point may be re-used. So far we've gotten away with this by luck, but recent u-boot changes have shifted the stack start address by 16 bytes, which combined with dma alignment now exposes this problem.
Since we end up just busy waiting for the dma engine anyway, this commit fixes things by simply removing the dma code, resulting in smaller bug-free code.
Signed-off-by: Hans de Goede hdegoede@redhat.com Acked-by: Ian Campbell ijc@hellion.org.uk
Acked-by: Siarhei Siamashka siarhei.siamashka@gmail.com
Thanks for the review. Note Ian has already submitted a pull-request for these patches, so your ack won't make it upstream.
Was it a good idea to keep v2014.07 release relying on luck without this patch?
Considering that things just work there, and the timing of when I found this out, yes.
Regards,
Hans

There is no way to reset the cpu, so use the watchdog for this.
Signed-off-by: Hans de Goede hdegoede@redhat.com Acked-by: Ian Campbell ijc@hellion.org.uk --- arch/arm/cpu/armv7/sunxi/board.c | 7 +++++++ arch/arm/include/asm/arch-sunxi/timer.h | 5 +++++ 2 files changed, 12 insertions(+)
diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index 49c9448..c80b421 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -56,6 +56,13 @@ int gpio_init(void)
void reset_cpu(ulong addr) { + static const struct sunxi_wdog *wdog = + &((struct sunxi_timer_reg *)SUNXI_TIMER_BASE)->wdog; + + /* Set the watchdog for its shortest interval (.5s) and wait */ + writel(WDT_MODE_RESET_EN | WDT_MODE_EN, &wdog->mode); + writel(WDT_CTRL_KEY | WDT_CTRL_RESTART, &wdog->ctl); + while (1); }
/* do some early init */ diff --git a/arch/arm/include/asm/arch-sunxi/timer.h b/arch/arm/include/asm/arch-sunxi/timer.h index 6aacfd7..58e14fd 100644 --- a/arch/arm/include/asm/arch-sunxi/timer.h +++ b/arch/arm/include/asm/arch-sunxi/timer.h @@ -11,6 +11,11 @@ #ifndef _SUNXI_TIMER_H_ #define _SUNXI_TIMER_H_
+#define WDT_CTRL_RESTART (0x1 << 0) +#define WDT_CTRL_KEY (0x0a57 << 1) +#define WDT_MODE_EN (0x1 << 0) +#define WDT_MODE_RESET_EN (0x1 << 1) + #ifndef __ASSEMBLY__
#include <linux/types.h>

On Mon, 9 Jun 2014 11:36:56 +0200 Hans de Goede hdegoede@redhat.com wrote:
There is no way to reset the cpu, so use the watchdog for this.
Signed-off-by: Hans de Goede hdegoede@redhat.com Acked-by: Ian Campbell ijc@hellion.org.uk
Acked-by: Siarhei Siamashka siarhei.siamashka@gmail.com
However shouldn't this be squashed with http://patchwork.ozlabs.org/patch/359692/ ?
Otherwise there is a range of commits, where reset is broken on sun5i hardware in the middle of the patch set.

Hi,
On 07/23/2014 07:45 PM, Siarhei Siamashka wrote:
On Mon, 9 Jun 2014 11:36:56 +0200 Hans de Goede hdegoede@redhat.com wrote:
There is no way to reset the cpu, so use the watchdog for this.
Signed-off-by: Hans de Goede hdegoede@redhat.com Acked-by: Ian Campbell ijc@hellion.org.uk
Acked-by: Siarhei Siamashka siarhei.siamashka@gmail.com
However shouldn't this be squashed with http://patchwork.ozlabs.org/patch/359692/ ?
Good point, unfortunately the pull-req has already gone out.
Otherwise there is a range of commits, where reset is broken on sun5i hardware in the middle of the patch set.
True, but what are the chances people will be testing reset in a bisect? Other then for a bisect this should not be an issue as this is all part of a single pull-req.
Regards,
Hans

Add support for the Allwinner A10 SoC also known as the Allwinner sun4i family, and add the Cubieboard board which uses the A10 SoC.
Compared to sun7 only the DRAM controller is a bit different: -Controller reset bits are inverted, but only for Rev. A -Different hpcr values -No MBUS on sun4i -Various other initialization changes
Signed-off-by: Henrik Nordstrom henrik@henriknordstrom.net Signed-off-by: Stefan Roese sr@denx.de Signed-off-by: Oliver Schinagl oliver@schinagl.nl Signed-off-by: Hans de Goede hdegoede@redhat.com Acked-by: Ian Campbell ijc@hellion.org.uk --- arch/arm/cpu/armv7/sunxi/Makefile | 2 + arch/arm/cpu/armv7/sunxi/cpu_info.c | 7 ++++ arch/arm/cpu/armv7/sunxi/dram.c | 81 +++++++++++++++++++++++++++++++++++-- board/sunxi/Makefile | 1 + board/sunxi/dram_cubieboard.c | 31 ++++++++++++++ boards.cfg | 1 + include/configs/sun4i.h | 23 +++++++++++ 7 files changed, 143 insertions(+), 3 deletions(-) create mode 100644 board/sunxi/dram_cubieboard.c create mode 100644 include/configs/sun4i.h
diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile index a64bfa1..856d353 100644 --- a/arch/arm/cpu/armv7/sunxi/Makefile +++ b/arch/arm/cpu/armv7/sunxi/Makefile @@ -11,6 +11,7 @@ obj-y += timer.o obj-y += board.o obj-y += clock.o obj-y += pinmux.o +obj-$(CONFIG_SUN4I) += clock_sun4i.o obj-$(CONFIG_SUN7I) += clock_sun4i.o
ifndef CONFIG_SPL_BUILD @@ -18,6 +19,7 @@ obj-y += cpu_info.o endif
ifdef CONFIG_SPL_BUILD +obj-$(CONFIG_SUN4I) += dram.o obj-$(CONFIG_SUN7I) += dram.o ifdef CONFIG_SPL_FEL obj-y += start.o diff --git a/arch/arm/cpu/armv7/sunxi/cpu_info.c b/arch/arm/cpu/armv7/sunxi/cpu_info.c index b4c3d5c..b4b5089 100644 --- a/arch/arm/cpu/armv7/sunxi/cpu_info.c +++ b/arch/arm/cpu/armv7/sunxi/cpu_info.c @@ -13,7 +13,14 @@ #ifdef CONFIG_DISPLAY_CPUINFO int print_cpuinfo(void) { +#ifdef CONFIG_SUN4I + puts("CPU: Allwinner A10 (SUN4I)\n"); +#elif defined CONFIG_SUN7I puts("CPU: Allwinner A20 (SUN7I)\n"); +#else +#warning Please update cpu_info.c with correct CPU information + puts("CPU: SUNXI Family\n"); +#endif return 0; } #endif diff --git a/arch/arm/cpu/armv7/sunxi/dram.c b/arch/arm/cpu/armv7/sunxi/dram.c index b43c4b4..1de7529 100644 --- a/arch/arm/cpu/armv7/sunxi/dram.c +++ b/arch/arm/cpu/armv7/sunxi/dram.c @@ -53,16 +53,37 @@ static void mctl_ddr3_reset(void) struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
- clrbits_le32(&dram->mcr, DRAM_MCR_RESET); - udelay(2); - setbits_le32(&dram->mcr, DRAM_MCR_RESET); +#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); + + if ((reg_val & CPU_CFG_CHIP_VER_MASK) != + CPU_CFG_CHIP_VER(CPU_CFG_CHIP_REV_A)) { + setbits_le32(&dram->mcr, DRAM_MCR_RESET); + udelay(2); + clrbits_le32(&dram->mcr, DRAM_MCR_RESET); + } else +#endif + { + clrbits_le32(&dram->mcr, DRAM_MCR_RESET); + udelay(2); + setbits_le32(&dram->mcr, DRAM_MCR_RESET); + } }
static void mctl_set_drive(void) { struct sunxi_dram_reg *dram = (struct sunxi_dram_reg *)SUNXI_DRAMC_BASE;
+#ifdef CONFIG_SUN7I clrsetbits_le32(&dram->mcr, DRAM_MCR_MODE_NORM(0x3) | (0x3 << 28), +#else + clrsetbits_le32(&dram->mcr, DRAM_MCR_MODE_NORM(0x3), +#endif DRAM_MCR_MODE_EN(0x3) | 0xffc); } @@ -134,6 +155,16 @@ static void mctl_enable_dllx(u32 phase) }
static u32 hpcr_value[32] = { +#ifdef CONFIG_SUN4I + 0x0301, 0x0301, 0x0301, 0x0301, + 0x0301, 0x0301, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0x1031, 0x1031, 0x0735, 0x5031, + 0x1035, 0x0731, 0x1031, 0x0735, + 0x1035, 0x1031, 0x0731, 0x1035, + 0x1031, 0x0301, 0x0301, 0x0731 +#endif #ifdef CONFIG_SUN7I 0x0301, 0x0301, 0x0301, 0x0301, 0x0301, 0x0301, 0x0301, 0x0301, @@ -223,22 +254,32 @@ static void mctl_setup_dram_clock(u32 clk) clrbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_GPS); #endif
+#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I) /* setup MBUS clock */ reg_val = CCM_MBUS_CTRL_GATE | CCM_MBUS_CTRL_CLK_SRC(CCM_MBUS_CTRL_CLK_SRC_PLL6) | CCM_MBUS_CTRL_N(CCM_MBUS_CTRL_N_X(2)) | CCM_MBUS_CTRL_M(CCM_MBUS_CTRL_M_X(2)); writel(reg_val, &ccm->mbus_clk_cfg); +#endif
/* * open DRAMC AHB & DLL register clock * close it first */ +#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I) clrbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM | CCM_AHB_GATE_DLL); +#else + clrbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM); +#endif udelay(22);
/* then open it */ +#if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I) setbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM | CCM_AHB_GATE_DLL); +#else + setbits_le32(&ccm->ahb_gate0, CCM_AHB_GATE_SDRAM); +#endif udelay(22); }
@@ -385,6 +426,13 @@ static void dramc_clock_output_en(u32 on) else clrbits_le32(&dram->mcr, DRAM_MCR_DCLK_OUT); #endif +#ifdef CONFIG_SUN4I + struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + if (on) + setbits_le32(&ccm->dram_clk_cfg, CCM_DRAM_CTRL_DCLK_OUT); + else + clrbits_le32(&ccm->dram_clk_cfg, CCM_DRAM_CTRL_DCLK_OUT); +#endif }
static const u16 tRFC_table[2][6] = { @@ -421,11 +469,19 @@ unsigned long dramc_init(struct dram_para *para) mctl_setup_dram_clock(para->clock);
/* reset external DRAM */ +#ifndef CONFIG_SUN7I + mctl_ddr3_reset(); +#endif mctl_set_drive();
/* dram clock off */ dramc_clock_output_en(0);
+#ifdef CONFIG_SUN4I + /* select dram controller 1 */ + writel(DRAM_CSEL_MAGIC, &dram->csel); +#endif + mctl_itm_disable(); mctl_enable_dll0(para->tpr3);
@@ -482,6 +538,9 @@ unsigned long dramc_init(struct dram_para *para) mctl_ddr3_reset(); else setbits_le32(&dram->mcr, DRAM_MCR_RESET); +#else + /* dram clock on */ + dramc_clock_output_en(1); #endif
udelay(1); @@ -490,6 +549,22 @@ unsigned long dramc_init(struct dram_para *para)
mctl_enable_dllx(para->tpr3);
+#ifdef CONFIG_SUN4I + /* set odt impedance 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, para->type - 2, density);
diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile index cbf8f08..4902d70 100644 --- a/board/sunxi/Makefile +++ b/board/sunxi/Makefile @@ -10,4 +10,5 @@ # obj-y += board.o obj-$(CONFIG_SUNXI_GMAC) += gmac.o +obj-$(CONFIG_CUBIEBOARD) += dram_cubieboard.o obj-$(CONFIG_CUBIETRUCK) += dram_cubietruck.o diff --git a/board/sunxi/dram_cubieboard.c b/board/sunxi/dram_cubieboard.c new file mode 100644 index 0000000..399028c --- /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, +}; + +unsigned long sunxi_dram_init(void) +{ + return dramc_init(&dram_para); +} diff --git a/boards.cfg b/boards.cfg index 4df5781..6a5f8d1 100644 --- a/boards.cfg +++ b/boards.cfg @@ -374,6 +374,7 @@ Active arm armv7 rmobile renesas lager Active arm armv7 s5pc1xx samsung goni s5p_goni - Przemyslaw Marczak p.marczak@samsung.com Active arm armv7 s5pc1xx samsung smdkc100 smdkc100 - Minkyu Kang mk7.kang@samsung.com Active arm armv7 socfpga altera socfpga socfpga_cyclone5 - - +Active arm armv7 sunxi - sunxi Cubieboard sun4i:CUBIEBOARD,SPL Hans de Goede hdegoede@redhat.com Active arm armv7 sunxi - sunxi Cubietruck sun7i:CUBIETRUCK,SPL,SUNXI_GMAC,RGMII - Active arm armv7 sunxi - sunxi Cubietruck_FEL sun7i:CUBIETRUCK,SPL_FEL,SUNXI_GMAC,RGMII - Active arm armv7 u8500 st-ericsson snowball snowball - Mathieu Poirier mathieu.poirier@linaro.org diff --git a/include/configs/sun4i.h b/include/configs/sun4i.h new file mode 100644 index 0000000..6560b65 --- /dev/null +++ b/include/configs/sun4i.h @@ -0,0 +1,23 @@ +/* + * (C) Copyright 2012-2013 Henrik Nordstrom henrik@henriknordstrom.net + * + * Configuration settings for the Allwinner A10 (sun4i) CPU + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef __CONFIG_H +#define __CONFIG_H + +/* + * A10 specific configuration + */ +#define CONFIG_SUN4I /* sun4i SoC generation */ + +#define CONFIG_SYS_PROMPT "sun4i# " + +/* + * Include common sunxi configuration where most the settings are + */ +#include <configs/sunxi-common.h> + +#endif /* __CONFIG_H */

On Mon, 9 Jun 2014 11:36:57 +0200 Hans de Goede hdegoede@redhat.com wrote:
Add support for the Allwinner A10 SoC also known as the Allwinner sun4i family, and add the Cubieboard board which uses the A10 SoC.
Compared to sun7 only the DRAM controller is a bit different: -Controller reset bits are inverted, but only for Rev. A -Different hpcr values -No MBUS on sun4i -Various other initialization changes
Signed-off-by: Henrik Nordstrom henrik@henriknordstrom.net Signed-off-by: Stefan Roese sr@denx.de Signed-off-by: Oliver Schinagl oliver@schinagl.nl Signed-off-by: Hans de Goede hdegoede@redhat.com Acked-by: Ian Campbell ijc@hellion.org.uk
arch/arm/cpu/armv7/sunxi/Makefile | 2 + arch/arm/cpu/armv7/sunxi/cpu_info.c | 7 ++++ arch/arm/cpu/armv7/sunxi/dram.c | 81 +++++++++++++++++++++++++++++++++++-- board/sunxi/Makefile | 1 + board/sunxi/dram_cubieboard.c | 31 ++++++++++++++ boards.cfg | 1 + include/configs/sun4i.h | 23 +++++++++++ 7 files changed, 143 insertions(+), 3 deletions(-) create mode 100644 board/sunxi/dram_cubieboard.c create mode 100644 include/configs/sun4i.h
This patch is piling up a lot of various loosely related changes. Isn't the addition of Cubieboard to boards.cfg kind of orthogonal to the sun4i SoC variant support? This makes cherry picking or reverting the patch unnecessarily difficult.

Add support for the Allwinner A13 and A10s SoCs also know as the Allwinner sun5i family, and the A13-OLinuXinoM A13 based and r7-tv-dongle A10s based boards.
The only differences compared to the already supported sun4i and sun7i families are all in the DRAM controller initialization:
-Different hcpr values -Different MBUS settings -Some other small initialization changes
Signed-off-by: Henrik Nordstrom henrik@henriknordstrom.net Signed-off-by: Stefan Roese sr@denx.de Signed-off-by: Oliver Schinagl oliver@schinagl.nl Signed-off-by: Hans de Goede hdegoede@redhat.com Acked-by: Ian Campbell ijc@hellion.org.uk --- arch/arm/cpu/armv7/sunxi/Makefile | 2 ++ arch/arm/cpu/armv7/sunxi/board.c | 12 ++++++++++++ arch/arm/cpu/armv7/sunxi/cpu_info.c | 8 ++++++++ arch/arm/cpu/armv7/sunxi/dram.c | 21 +++++++++++++++++++++ board/sunxi/Makefile | 2 ++ board/sunxi/dram_a13_oli_micro.c | 32 ++++++++++++++++++++++++++++++++ board/sunxi/dram_r7dongle.c | 31 +++++++++++++++++++++++++++++++ boards.cfg | 2 ++ include/configs/sun5i.h | 23 +++++++++++++++++++++++ include/configs/sunxi-common.h | 2 ++ 10 files changed, 135 insertions(+) create mode 100644 board/sunxi/dram_a13_oli_micro.c create mode 100644 board/sunxi/dram_r7dongle.c create mode 100644 include/configs/sun5i.h
diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile index 856d353..6c70639 100644 --- a/arch/arm/cpu/armv7/sunxi/Makefile +++ b/arch/arm/cpu/armv7/sunxi/Makefile @@ -12,6 +12,7 @@ obj-y += board.o obj-y += clock.o obj-y += pinmux.o obj-$(CONFIG_SUN4I) += clock_sun4i.o +obj-$(CONFIG_SUN5I) += clock_sun4i.o obj-$(CONFIG_SUN7I) += clock_sun4i.o
ifndef CONFIG_SPL_BUILD @@ -20,6 +21,7 @@ endif
ifdef CONFIG_SPL_BUILD obj-$(CONFIG_SUN4I) += dram.o +obj-$(CONFIG_SUN5I) += dram.o obj-$(CONFIG_SUN7I) += dram.o ifdef CONFIG_SPL_FEL obj-y += start.o diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index c80b421..0118f5b 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -47,9 +47,21 @@ u32 spl_boot_mode(void)
int gpio_init(void) { +#if CONFIG_CONS_INDEX == 1 && (defined(CONFIG_SUN4I) || defined(CONFIG_SUN7I)) sunxi_gpio_set_cfgpin(SUNXI_GPB(22), SUN4I_GPB22_UART0_TX); sunxi_gpio_set_cfgpin(SUNXI_GPB(23), SUN4I_GPB23_UART0_RX); sunxi_gpio_set_pull(SUNXI_GPB(23), 1); +#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_SUN5I) + sunxi_gpio_set_cfgpin(SUNXI_GPB(19), SUN5I_GPB19_UART0_TX); + sunxi_gpio_set_cfgpin(SUNXI_GPB(20), SUN5I_GPB20_UART0_RX); + sunxi_gpio_set_pull(SUNXI_GPB(20), 1); +#elif CONFIG_CONS_INDEX == 2 && defined(CONFIG_SUN5I) + sunxi_gpio_set_cfgpin(SUNXI_GPG(3), SUN5I_GPG3_UART1_TX); + sunxi_gpio_set_cfgpin(SUNXI_GPG(4), SUN5I_GPG4_UART1_RX); + sunxi_gpio_set_pull(SUNXI_GPG(4), 1); +#else +#error Unsupported console port number. Please fix pin mux settings in board.c +#endif
return 0; } diff --git a/arch/arm/cpu/armv7/sunxi/cpu_info.c b/arch/arm/cpu/armv7/sunxi/cpu_info.c index b4b5089..5cf35ac 100644 --- a/arch/arm/cpu/armv7/sunxi/cpu_info.c +++ b/arch/arm/cpu/armv7/sunxi/cpu_info.c @@ -15,6 +15,14 @@ int print_cpuinfo(void) { #ifdef CONFIG_SUN4I puts("CPU: Allwinner A10 (SUN4I)\n"); +#elif defined CONFIG_SUN5I + u32 val = readl(SUNXI_SID_BASE + 0x08); + switch ((val >> 12) & 0xf) { + case 0: puts("CPU: Allwinner A12 (SUN5I)\n"); break; + case 3: puts("CPU: Allwinner A13 (SUN5I)\n"); break; + case 7: puts("CPU: Allwinner A10s (SUN5I)\n"); break; + default: puts("CPU: Allwinner A1X (SUN5I)\n"); + } #elif defined CONFIG_SUN7I puts("CPU: Allwinner A20 (SUN7I)\n"); #else diff --git a/arch/arm/cpu/armv7/sunxi/dram.c b/arch/arm/cpu/armv7/sunxi/dram.c index 1de7529..0f1ceec 100644 --- a/arch/arm/cpu/armv7/sunxi/dram.c +++ b/arch/arm/cpu/armv7/sunxi/dram.c @@ -155,6 +155,16 @@ static void mctl_enable_dllx(u32 phase) }
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, @@ -257,9 +267,15 @@ static void mctl_setup_dram_clock(u32 clk) #if defined(CONFIG_SUN5I) || defined(CONFIG_SUN7I) /* setup MBUS clock */ reg_val = CCM_MBUS_CTRL_GATE | +#ifdef CONFIG_SUN7I CCM_MBUS_CTRL_CLK_SRC(CCM_MBUS_CTRL_CLK_SRC_PLL6) | CCM_MBUS_CTRL_N(CCM_MBUS_CTRL_N_X(2)) | CCM_MBUS_CTRL_M(CCM_MBUS_CTRL_M_X(2)); +#else /* defined(CONFIG_SUN5I) */ + CCM_MBUS_CTRL_CLK_SRC(CCM_MBUS_CTRL_CLK_SRC_PLL5) | + CCM_MBUS_CTRL_N(CCM_MBUS_CTRL_N_X(1)) | + CCM_MBUS_CTRL_M(CCM_MBUS_CTRL_M_X(2)); +#endif writel(reg_val, &ccm->mbus_clk_cfg); #endif
@@ -468,6 +484,11 @@ unsigned long dramc_init(struct dram_para *para) /* 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 */ #ifndef CONFIG_SUN7I mctl_ddr3_reset(); diff --git a/board/sunxi/Makefile b/board/sunxi/Makefile index 4902d70..7083632 100644 --- a/board/sunxi/Makefile +++ b/board/sunxi/Makefile @@ -10,5 +10,7 @@ # obj-y += board.o obj-$(CONFIG_SUNXI_GMAC) += gmac.o +obj-$(CONFIG_A13_OLINUXINOM) += dram_a13_oli_micro.o obj-$(CONFIG_CUBIEBOARD) += dram_cubieboard.o obj-$(CONFIG_CUBIETRUCK) += dram_cubietruck.o +obj-$(CONFIG_R7DONGLE) += dram_r7dongle.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..8154ea2 --- /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, + +}; + +unsigned long sunxi_dram_init(void) +{ + return dramc_init(&dram_para); +} diff --git a/board/sunxi/dram_r7dongle.c b/board/sunxi/dram_r7dongle.c new file mode 100644 index 0000000..59343cb --- /dev/null +++ b/board/sunxi/dram_r7dongle.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 = 384, + .type = 3, + .rank_num = 1, + .density = 2048, + .io_width = 8, + .bus_width = 32, + .cas = 9, + .zq = 123, + .odt_en = 0, + .size = 1024, + .tpr0 = 0x42d899b7, + .tpr1 = 0xa090, + .tpr2 = 0x22a00, + .tpr3 = 0, + .tpr4 = 0, + .tpr5 = 0, + .emr1 = 0x04, + .emr2 = 0x10, + .emr3 = 0, +}; + +unsigned long sunxi_dram_init(void) +{ + return dramc_init(&dram_para); +} diff --git a/boards.cfg b/boards.cfg index 6a5f8d1..bbe2b04 100644 --- a/boards.cfg +++ b/boards.cfg @@ -374,9 +374,11 @@ Active arm armv7 rmobile renesas lager Active arm armv7 s5pc1xx samsung goni s5p_goni - Przemyslaw Marczak p.marczak@samsung.com Active arm armv7 s5pc1xx samsung smdkc100 smdkc100 - Minkyu Kang mk7.kang@samsung.com Active arm armv7 socfpga altera socfpga socfpga_cyclone5 - - +Active arm armv7 sunxi - sunxi A13-OLinuXinoM sun5i:A13_OLINUXINOM,SPL,CONS_INDEX=2 Hans de Goede hdegoede@redhat.com Active arm armv7 sunxi - sunxi Cubieboard sun4i:CUBIEBOARD,SPL Hans de Goede hdegoede@redhat.com Active arm armv7 sunxi - sunxi Cubietruck sun7i:CUBIETRUCK,SPL,SUNXI_GMAC,RGMII - Active arm armv7 sunxi - sunxi Cubietruck_FEL sun7i:CUBIETRUCK,SPL_FEL,SUNXI_GMAC,RGMII - +Active arm armv7 sunxi - sunxi r7-tv-dongle sun5i:R7DONGLE,SPL Hans de Goede hdegoede@redhat.com Active arm armv7 u8500 st-ericsson snowball snowball - Mathieu Poirier mathieu.poirier@linaro.org Active arm armv7 u8500 st-ericsson u8500 u8500_href - - Active arm armv7 vf610 freescale vf610twr vf610twr vf610twr:IMX_CONFIG=board/freescale/vf610twr/imximage.cfg Alison Wang b18965@freescale.com diff --git a/include/configs/sun5i.h b/include/configs/sun5i.h new file mode 100644 index 0000000..43f0d67 --- /dev/null +++ b/include/configs/sun5i.h @@ -0,0 +1,23 @@ +/* + * (C) Copyright 2012-2013 Henrik Nordstrom henrik@henriknordstrom.net + * + * Configuration settings for the Allwinner A13 (sun5i) CPU + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#ifndef __CONFIG_H +#define __CONFIG_H + +/* + * High Level Configuration Options + */ +#define CONFIG_SUN5I /* sun5i SoC generation */ + +#define CONFIG_SYS_PROMPT "sun5i# " + +/* + * Include common sunxi configuration where most the settings are + */ +#include <configs/sunxi-common.h> + +#endif /* __CONFIG_H */ diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index fd02d0d..1d1c87d 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -161,7 +161,9 @@ #undef CONFIG_CMD_NET #undef CONFIG_CMD_NFS
+#ifndef CONFIG_CONS_INDEX #define CONFIG_CONS_INDEX 1 /* UART0 */ +#endif
#ifdef CONFIG_SUNXI_GMAC #define CONFIG_DESIGNWARE_ETH /* GMAC can use designware driver */

On Mon, 9 Jun 2014 11:36:58 +0200 Hans de Goede hdegoede@redhat.com wrote:
Add support for the Allwinner A13 and A10s SoCs also know as the Allwinner sun5i family, and the A13-OLinuXinoM A13 based and r7-tv-dongle A10s based boards.
The only differences compared to the already supported sun4i and sun7i families are all in the DRAM controller initialization:
-Different hcpr values -Different MBUS settings -Some other small initialization changes
Signed-off-by: Henrik Nordstrom henrik@henriknordstrom.net Signed-off-by: Stefan Roese sr@denx.de Signed-off-by: Oliver Schinagl oliver@schinagl.nl Signed-off-by: Hans de Goede hdegoede@redhat.com Acked-by: Ian Campbell ijc@hellion.org.uk
arch/arm/cpu/armv7/sunxi/Makefile | 2 ++ arch/arm/cpu/armv7/sunxi/board.c | 12 ++++++++++++ arch/arm/cpu/armv7/sunxi/cpu_info.c | 8 ++++++++ arch/arm/cpu/armv7/sunxi/dram.c | 21 +++++++++++++++++++++ board/sunxi/Makefile | 2 ++ board/sunxi/dram_a13_oli_micro.c | 32 ++++++++++++++++++++++++++++++++ board/sunxi/dram_r7dongle.c | 31 +++++++++++++++++++++++++++++++ boards.cfg | 2 ++ include/configs/sun5i.h | 23 +++++++++++++++++++++++ include/configs/sunxi-common.h | 2 ++ 10 files changed, 135 insertions(+) create mode 100644 board/sunxi/dram_a13_oli_micro.c create mode 100644 board/sunxi/dram_r7dongle.c create mode 100644 include/configs/sun5i.h
Even if there is a valid reason to bundle the addition of some example sun5i based board to boards.cfg with the changes needed for sun5i SoC variant, why is it *two* boards this time?

Hi,
On 07/23/2014 08:02 PM, Siarhei Siamashka wrote:
On Mon, 9 Jun 2014 11:36:58 +0200 Hans de Goede hdegoede@redhat.com wrote:
Add support for the Allwinner A13 and A10s SoCs also know as the Allwinner sun5i family, and the A13-OLinuXinoM A13 based and r7-tv-dongle A10s based boards.
The only differences compared to the already supported sun4i and sun7i families are all in the DRAM controller initialization:
-Different hcpr values -Different MBUS settings -Some other small initialization changes
Signed-off-by: Henrik Nordstrom henrik@henriknordstrom.net Signed-off-by: Stefan Roese sr@denx.de Signed-off-by: Oliver Schinagl oliver@schinagl.nl Signed-off-by: Hans de Goede hdegoede@redhat.com Acked-by: Ian Campbell ijc@hellion.org.uk
arch/arm/cpu/armv7/sunxi/Makefile | 2 ++ arch/arm/cpu/armv7/sunxi/board.c | 12 ++++++++++++ arch/arm/cpu/armv7/sunxi/cpu_info.c | 8 ++++++++ arch/arm/cpu/armv7/sunxi/dram.c | 21 +++++++++++++++++++++ board/sunxi/Makefile | 2 ++ board/sunxi/dram_a13_oli_micro.c | 32 ++++++++++++++++++++++++++++++++ board/sunxi/dram_r7dongle.c | 31 +++++++++++++++++++++++++++++++ boards.cfg | 2 ++ include/configs/sun5i.h | 23 +++++++++++++++++++++++ include/configs/sunxi-common.h | 2 ++ 10 files changed, 135 insertions(+) create mode 100644 board/sunxi/dram_a13_oli_micro.c create mode 100644 board/sunxi/dram_r7dongle.c create mode 100644 include/configs/sun5i.h
Even if there is a valid reason to bundle the addition of some example sun5i based board to boards.cfg
To address this first, I believe that it is a good idea when adding functionality to also enable it, otherwise one is just adding dead code.
with the changes needed for sun5i SoC variant, why is it *two* boards this time?
Because there are 2 sun5i variants A13 and A10s
Regards,
Hans

From: Stefan Roese sr@denx.de
There have been 3 versions of the sunxi_emac support patch during its development. Somehow version 2 ended up in upstream u-boot where as the u-boot-sunxi git repo got version 3.
This bumps the version in upstream u-boot to version 3 of the patch: - Initialize MII clock earlier so mii access to allow independent use - Name change from WEMAC to EMAC to match mainline kernel & chip manual - Cosmetic code cleanup
Signed-off-by: Stefan Roese sr@denx.de Signed-off-by: Henrik Nordstrom henrik@henriknordstrom.net Signed-off-by: Oliver Schinagl oliver@schinagl.nl Signed-off-by: Hans de Goede hdegoede@redhat.com Acked-by: Ian Campbell ijc@hellion.org.uk --- drivers/net/Makefile | 2 +- drivers/net/sunxi_emac.c | 521 +++++++++++++++++++++++++++++++++++++++++++++ drivers/net/sunxi_wemac.c | 525 ---------------------------------------------- include/netdev.h | 2 +- 4 files changed, 523 insertions(+), 527 deletions(-) create mode 100644 drivers/net/sunxi_emac.c delete mode 100644 drivers/net/sunxi_wemac.c
diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 6005f7e..da2b5f8 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_DNET) += dnet.o obj-$(CONFIG_E1000) += e1000.o obj-$(CONFIG_E1000_SPI) += e1000_spi.o obj-$(CONFIG_EEPRO100) += eepro100.o +obj-$(CONFIG_SUNXI_EMAC) += sunxi_emac.o obj-$(CONFIG_ENC28J60) += enc28j60.o obj-$(CONFIG_EP93XX) += ep93xx_eth.o obj-$(CONFIG_ETHOC) += ethoc.o @@ -51,7 +52,6 @@ obj-$(CONFIG_RTL8169) += rtl8169.o obj-$(CONFIG_SH_ETHER) += sh_eth.o obj-$(CONFIG_SMC91111) += smc91111.o obj-$(CONFIG_SMC911X) += smc911x.o -obj-$(CONFIG_SUNXI_WEMAC) += sunxi_wemac.o obj-$(CONFIG_DRIVER_TI_EMAC) += davinci_emac.o obj-$(CONFIG_TSEC_ENET) += tsec.o fsl_mdio.o obj-$(CONFIG_DRIVER_TI_CPSW) += cpsw.o diff --git a/drivers/net/sunxi_emac.c b/drivers/net/sunxi_emac.c new file mode 100644 index 0000000..5a06d68 --- /dev/null +++ b/drivers/net/sunxi_emac.c @@ -0,0 +1,521 @@ +/* + * sunxi_emac.c -- Allwinner A10 ethernet driver + * + * (C) Copyright 2012, Stefan Roese sr@denx.de + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <linux/err.h> +#include <malloc.h> +#include <miiphy.h> +#include <net.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/gpio.h> + +/* EMAC register */ +struct emac_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 (0x1 << 4) +#define EMAC_LENERR (0x3 << 5) + +#define DMA_CPU_TRRESHOLD 2000 + +struct emac_eth_dev { + u32 speed; + u32 duplex; + u32 phy_configured; + int link_printed; +}; + +struct emac_rxhdr { + s16 rx_len; + u16 rx_status; +}; + +static void emac_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 emac_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 emac_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 emac_regs *regs = (struct emac_regs *)dev->iobase; + + /* issue the phy address and reg */ + writel(addr << 8 | reg, ®s->mac_madr); + + /* pull up the phy io line */ + writel(0x1, ®s->mac_mcmd); + + /* Wait read complete */ + mdelay(1); + + /* push down the phy io line */ + writel(0x0, ®s->mac_mcmd); + + /* and write data */ + *value = readl(®s->mac_mrdd); + + return 0; +} + +/* Write a word to phyxcer */ +static int emac_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 emac_regs *regs = (struct emac_regs *)dev->iobase; + + /* issue the phy address and reg */ + writel(addr << 8 | reg, ®s->mac_madr); + + /* pull up the phy io line */ + writel(0x1, ®s->mac_mcmd); + + /* Wait write complete */ + mdelay(1); + + /* push down the phy io line */ + writel(0x0, ®s->mac_mcmd); + + /* and write data */ + writel(value, ®s->mac_mwtd); + + return 0; +} + +static void emac_setup(struct eth_device *dev) +{ + struct emac_regs *regs = (struct emac_regs *)dev->iobase; + u32 reg_val; + u16 phy_val; + u32 duplex_flag; + + /* Set up TX */ + writel(EMAC_TX_SETUP, ®s->tx_mode); + + /* Set up RX */ + writel(EMAC_RX_SETUP, ®s->rx_ctl); + + /* Set MAC */ + /* Set MAC CTL0 */ + writel(EMAC_MAC_CTL0_SETUP, ®s->mac_ctl0); + + /* Set MAC CTL1 */ + emac_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, ®s->mac_ctl1); + + /* Set up IPGT */ + writel(EMAC_MAC_IPGT, ®s->mac_ipgt); + + /* Set up IPGR */ + writel(EMAC_MAC_NBTB_IPG2 | (EMAC_MAC_NBTB_IPG1 << 8), ®s->mac_ipgr); + + /* Set up Collison window */ + writel(EMAC_MAC_RM | (EMAC_MAC_CW << 8), ®s->mac_clrt); + + /* Set up Max Frame Length */ + writel(EMAC_MAC_MFL, ®s->mac_maxf); +} + +static void emac_reset(struct eth_device *dev) +{ + struct emac_regs *regs = (struct emac_regs *)dev->iobase; + + debug("resetting device\n"); + + /* RESET device */ + writel(0, ®s->ctl); + udelay(200); + + writel(1, ®s->ctl); + udelay(200); +} + +static int sunxi_emac_eth_init(struct eth_device *dev, bd_t *bd) +{ + struct emac_regs *regs = (struct emac_regs *)dev->iobase; + struct emac_eth_dev *priv = dev->priv; + u16 phy_reg; + + /* Init EMAC */ + + /* Flush RX FIFO */ + setbits_le32(®s->rx_ctl, 0x8); + udelay(1); + + /* Init MAC */ + + /* Soft reset MAC */ + clrbits_le32(®s->mac_ctl0, 0x1 << 15); + + /* Clear RX counter */ + writel(0x0, ®s->rx_fbc); + udelay(1); + + /* Set up EMAC */ + emac_setup(dev); + + writel(dev->enetaddr[0] << 16 | dev->enetaddr[1] << 8 | + dev->enetaddr[2], ®s->mac_a1); + writel(dev->enetaddr[3] << 16 | dev->enetaddr[4] << 8 | + dev->enetaddr[5], ®s->mac_a0); + + mdelay(1); + + emac_reset(dev); + + /* PHY POWER UP */ + emac_phy_read(dev->name, 1, 0, &phy_reg); + emac_phy_write(dev->name, 1, 0, phy_reg & (~(0x1 << 11))); + mdelay(1); + + emac_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(®s->mac_supp, 1 << 8, + ((phy_reg & (0x1 << 13)) >> 13) << 8); + + /* Set duplex depend on phy */ + clrsetbits_le32(®s->mac_ctl1, 1 << 0, + ((phy_reg & (0x1 << 8)) >> 8) << 0); + + /* Enable RX/TX */ + setbits_le32(®s->ctl, 0x7); + + return 0; +} + +static void sunxi_emac_eth_halt(struct eth_device *dev) +{ + /* Nothing to do here */ +} + +static int sunxi_emac_eth_recv(struct eth_device *dev) +{ + struct emac_regs *regs = (struct emac_regs *)dev->iobase; + struct emac_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(®s->rx_fbc); + if (!rxcount) { + /* Had one stuck? */ + rxcount = readl(®s->rx_fbc); + if (!rxcount) + return 0; + } + + reg_val = readl(®s->rx_io_data); + if (reg_val != 0x0143414d) { + /* Disable RX */ + clrbits_le32(®s->ctl, 0x1 << 2); + + /* Flush RX FIFO */ + setbits_le32(®s->rx_ctl, 0x1 << 3); + while (readl(®s->rx_ctl) & (0x1 << 3)) + ; + + /* Enable RX */ + setbits_le32(®s->ctl, 0x1 << 2); + + return 0; + } + + /* A packet ready now + * Get status/length + */ + good_packet = 1; + + emac_inblk_32bit(®s->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 EMAC */ + if (good_packet) { + if (rx_len > DMA_CPU_TRRESHOLD) { + printf("Received packet is too big (len=%d)\n", rx_len); + } else { + emac_inblk_32bit((void *)®s->rx_io_data, + NetRxPackets[0], rx_len); + + /* Pass to upper layer */ + NetReceive(NetRxPackets[0], rx_len); + return rx_len; + } + } + + return 0; +} + +static int sunxi_emac_eth_send(struct eth_device *dev, void *packet, int len) +{ + struct emac_regs *regs = (struct emac_regs *)dev->iobase; + + /* Select channel 0 */ + writel(0, ®s->tx_ins); + + /* Write packet */ + emac_outblk_32bit((void *)®s->tx_io_data, packet, len); + + /* Set TX len */ + writel(len, ®s->tx_pl0); + + /* Start translate from fifo to phy */ + setbits_le32(®s->tx_ctl0, 1); + + return 0; +} + +int sunxi_emac_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 emac_regs *regs = + (struct emac_regs *)SUNXI_EMAC_BASE; + struct eth_device *dev; + struct emac_eth_dev *priv; + int pin; + + dev = malloc(sizeof(*dev)); + if (dev == NULL) + return -ENOMEM; + + priv = (struct emac_eth_dev *)malloc(sizeof(struct emac_eth_dev)); + if (!priv) { + free(dev); + return -ENOMEM; + } + + memset(dev, 0, sizeof(*dev)); + memset(priv, 0, sizeof(struct emac_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, SUNXI_GPA0_EMAC); + + /* Set up clock gating */ + setbits_le32(&ccm->ahb_gate0, 0x1 << AHB_GATE_OFFSET_EMAC); + + /* Set MII clock */ + clrsetbits_le32(®s->mac_mcfg, 0xf << 2, 0xd << 2); + + dev->iobase = (int)regs; + dev->priv = priv; + dev->init = sunxi_emac_eth_init; + dev->halt = sunxi_emac_eth_halt; + dev->send = sunxi_emac_eth_send; + dev->recv = sunxi_emac_eth_recv; + strcpy(dev->name, "emac"); + + eth_register(dev); + + miiphy_register(dev->name, emac_phy_read, emac_phy_write); + + return 0; +} diff --git a/drivers/net/sunxi_wemac.c b/drivers/net/sunxi_wemac.c deleted file mode 100644 index 699a381..0000000 --- a/drivers/net/sunxi_wemac.c +++ /dev/null @@ -1,525 +0,0 @@ -/* - * sunxi_wemac.c -- Allwinner A10 ethernet driver - * - * (C) Copyright 2012, Stefan Roese sr@denx.de - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#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, ®s->mac_madr); - - /* pull up the phy io line */ - writel(0x1, ®s->mac_mcmd); - - /* Wait read complete */ - mdelay(1); - - /* push down the phy io line */ - writel(0x0, ®s->mac_mcmd); - - /* and write data */ - *value = readl(®s->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, ®s->mac_madr); - - /* pull up the phy io line */ - writel(0x1, ®s->mac_mcmd); - - /* Wait write complete */ - mdelay(1); - - /* push down the phy io line */ - writel(0x0, ®s->mac_mcmd); - - /* and write data */ - writel(value, ®s->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, ®s->tx_mode); - - /* Set up RX */ - writel(EMAC_RX_SETUP, ®s->rx_ctl); - - /* Set MAC */ - /* Set MAC CTL0 */ - writel(EMAC_MAC_CTL0_SETUP, ®s->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, ®s->mac_ctl1); - - /* Set up IPGT */ - writel(EMAC_MAC_IPGT, ®s->mac_ipgt); - - /* Set up IPGR */ - writel(EMAC_MAC_NBTB_IPG2 | (EMAC_MAC_NBTB_IPG1 << 8), ®s->mac_ipgr); - - /* Set up Collison window */ - writel(EMAC_MAC_RM | (EMAC_MAC_CW << 8), ®s->mac_clrt); - - /* Set up Max Frame Length */ - writel(EMAC_MAC_MFL, ®s->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, ®s->ctl); - udelay(200); - - writel(1, ®s->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(®s->rx_ctl, 0x8); - udelay(1); - - /* Init MAC */ - - /* Soft reset MAC */ - clrbits_le32(®s->mac_ctl0, 1 << 15); - - /* Set MII clock */ - clrsetbits_le32(®s->mac_mcfg, 0xf << 2, 0xd << 2); - - /* Clear RX counter */ - writel(0x0, ®s->rx_fbc); - udelay(1); - - /* Set up EMAC */ - emac_setup(dev); - - writel(dev->enetaddr[0] << 16 | dev->enetaddr[1] << 8 | - dev->enetaddr[2], ®s->mac_a1); - writel(dev->enetaddr[3] << 16 | dev->enetaddr[4] << 8 | - dev->enetaddr[5], ®s->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(®s->mac_supp, 1 << 8, - ((phy_reg & (1 << 13)) >> 13) << 8); - - /* Set duplex depend on phy */ - clrsetbits_le32(®s->mac_ctl1, 1 << 0, - ((phy_reg & (1 << 8)) >> 8) << 0); - - /* Enable RX/TX */ - setbits_le32(®s->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(®s->rx_fbc); - if (!rxcount) { - /* Had one stuck? */ - rxcount = readl(®s->rx_fbc); - if (!rxcount) - return 0; - } - - reg_val = readl(®s->rx_io_data); - if (reg_val != 0x0143414d) { - /* Disable RX */ - clrbits_le32(®s->ctl, 1 << 2); - - /* Flush RX FIFO */ - setbits_le32(®s->rx_ctl, 1 << 3); - while (readl(®s->rx_ctl) & (1 << 3)) - ; - - /* Enable RX */ - setbits_le32(®s->ctl, 1 << 2); - - return 0; - } - - /* - * A packet ready now - * Get status/length - */ - good_packet = 1; - - wemac_inblk_32bit(®s->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 *)®s->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, ®s->tx_ins); - - /* Write packet */ - wemac_outblk_32bit((void *)®s->tx_io_data, packet, len); - - /* Set TX len */ - writel(len, ®s->tx_pl0); - - /* Start translate from fifo to phy */ - setbits_le32(®s->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 63481ec..e45dd7a 100644 --- a/include/netdev.h +++ b/include/netdev.h @@ -78,8 +78,8 @@ 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_emac_initialize(bd_t *bis); int sunxi_gmac_initialize(bd_t *bis); -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);

On Mon, 9 Jun 2014 11:36:59 +0200 Hans de Goede hdegoede@redhat.com wrote:
From: Stefan Roese sr@denx.de
There have been 3 versions of the sunxi_emac support patch during its development. Somehow version 2 ended up in upstream u-boot where as the u-boot-sunxi git repo got version 3.
This bumps the version in upstream u-boot to version 3 of the patch:
- Initialize MII clock earlier so mii access to allow independent use
- Name change from WEMAC to EMAC to match mainline kernel & chip manual
- Cosmetic code cleanup
Signed-off-by: Stefan Roese sr@denx.de Signed-off-by: Henrik Nordstrom henrik@henriknordstrom.net Signed-off-by: Oliver Schinagl oliver@schinagl.nl Signed-off-by: Hans de Goede hdegoede@redhat.com Acked-by: Ian Campbell ijc@hellion.org.uk
Shouldn't the cosmetic and functional changes be normally split into separate patches? Indeed, it looks like the move of
+ /* Set MII clock */ + clrsetbits_le32(®s->mac_mcfg, 0xf << 2, 0xd << 2);
is the only functional change in this rather large patch.
And could you please elaborate on
- Initialize MII clock earlier so mii access to allow independent use
was this causing any user visible problems?

Hi,
On 07/23/2014 08:12 PM, Siarhei Siamashka wrote:
On Mon, 9 Jun 2014 11:36:59 +0200 Hans de Goede hdegoede@redhat.com wrote:
From: Stefan Roese sr@denx.de
There have been 3 versions of the sunxi_emac support patch during its development. Somehow version 2 ended up in upstream u-boot where as the u-boot-sunxi git repo got version 3.
This bumps the version in upstream u-boot to version 3 of the patch:
- Initialize MII clock earlier so mii access to allow independent use
- Name change from WEMAC to EMAC to match mainline kernel & chip manual
- Cosmetic code cleanup
Signed-off-by: Stefan Roese sr@denx.de Signed-off-by: Henrik Nordstrom henrik@henriknordstrom.net Signed-off-by: Oliver Schinagl oliver@schinagl.nl Signed-off-by: Hans de Goede hdegoede@redhat.com Acked-by: Ian Campbell ijc@hellion.org.uk
Shouldn't the cosmetic and functional changes be normally split into separate patches? Indeed, it looks like the move of
/* Set MII clock */
clrsetbits_le32(®s->mac_mcfg, 0xf << 2, 0xd << 2);
is the only functional change in this rather large patch.
And could you please elaborate on
- Initialize MII clock earlier so mii access to allow independent use
was this causing any user visible problems?
I'm not the author if the patch, so you will need to ask Stefan. Note though that the code after this patch is the code which we've been using in the linux-sunxi-u-boot for as long as I can remember, and the code which went upstream was never enabled / used as is.
Regards,
Hans

Hi,
On 26.07.2014 15:21, Hans de Goede wrote:
Hi,
On 07/23/2014 08:12 PM, Siarhei Siamashka wrote:
On Mon, 9 Jun 2014 11:36:59 +0200 Hans de Goede hdegoede@redhat.com wrote:
From: Stefan Roese sr@denx.de
There have been 3 versions of the sunxi_emac support patch during its development. Somehow version 2 ended up in upstream u-boot where as the u-boot-sunxi git repo got version 3.
This bumps the version in upstream u-boot to version 3 of the patch:
- Initialize MII clock earlier so mii access to allow independent use
- Name change from WEMAC to EMAC to match mainline kernel & chip manual
- Cosmetic code cleanup
Signed-off-by: Stefan Roese sr@denx.de Signed-off-by: Henrik Nordstrom henrik@henriknordstrom.net Signed-off-by: Oliver Schinagl oliver@schinagl.nl Signed-off-by: Hans de Goede hdegoede@redhat.com Acked-by: Ian Campbell ijc@hellion.org.uk
Shouldn't the cosmetic and functional changes be normally split into separate patches? Indeed, it looks like the move of
/* Set MII clock */
clrsetbits_le32(®s->mac_mcfg, 0xf << 2, 0xd << 2);
is the only functional change in this rather large patch.
And could you please elaborate on
- Initialize MII clock earlier so mii access to allow independent use
was this causing any user visible problems?
I'm not the author if the patch, so you will need to ask Stefan.
Yes. Sorry, but this was so long ago and I really can't remember the details here. I suggest to improve the code with follow-up patches if needed.
Thanks, Stefan

Signed-off-by: Hans de Goede hdegoede@redhat.com Acked-by: Ian Campbell ijc@hellion.org.uk --- arch/arm/cpu/armv7/sunxi/board.c | 8 ++++++++ boards.cfg | 2 +- include/configs/sunxi-common.h | 5 +++++ 3 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index 0118f5b..1e506b5 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -117,6 +117,14 @@ int cpu_eth_init(bd_t *bis) { int rc;
+#ifdef CONFIG_SUNXI_EMAC + rc = sunxi_emac_initialize(bis); + if (rc < 0) { + printf("sunxi: failed to initialize emac\n"); + return rc; + } +#endif + #ifdef CONFIG_SUNXI_GMAC rc = sunxi_gmac_initialize(bis); if (rc < 0) { diff --git a/boards.cfg b/boards.cfg index bbe2b04..1fe9f80 100644 --- a/boards.cfg +++ b/boards.cfg @@ -375,7 +375,7 @@ Active arm armv7 s5pc1xx samsung goni Active arm armv7 s5pc1xx samsung smdkc100 smdkc100 - Minkyu Kang mk7.kang@samsung.com Active arm armv7 socfpga altera socfpga socfpga_cyclone5 - - Active arm armv7 sunxi - sunxi A13-OLinuXinoM sun5i:A13_OLINUXINOM,SPL,CONS_INDEX=2 Hans de Goede hdegoede@redhat.com -Active arm armv7 sunxi - sunxi Cubieboard sun4i:CUBIEBOARD,SPL Hans de Goede hdegoede@redhat.com +Active arm armv7 sunxi - sunxi Cubieboard sun4i:CUBIEBOARD,SPL,SUNXI_EMAC Hans de Goede hdegoede@redhat.com Active arm armv7 sunxi - sunxi Cubietruck sun7i:CUBIETRUCK,SPL,SUNXI_GMAC,RGMII - Active arm armv7 sunxi - sunxi Cubietruck_FEL sun7i:CUBIETRUCK,SPL_FEL,SUNXI_GMAC,RGMII - Active arm armv7 sunxi - sunxi r7-tv-dongle sun5i:R7DONGLE,SPL Hans de Goede hdegoede@redhat.com diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index 1d1c87d..3f04890 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -165,6 +165,11 @@ #define CONFIG_CONS_INDEX 1 /* UART0 */ #endif
+/* Ethernet support */ +#ifdef CONFIG_SUNXI_EMAC +#define CONFIG_MII /* MII PHY management */ +#endif + #ifdef CONFIG_SUNXI_GMAC #define CONFIG_DESIGNWARE_ETH /* GMAC can use designware driver */ #define CONFIG_DW_AUTONEG

On Mon, 9 Jun 2014 11:37:00 +0200 Hans de Goede hdegoede@redhat.com wrote:
Signed-off-by: Hans de Goede hdegoede@redhat.com Acked-by: Ian Campbell ijc@hellion.org.uk
arch/arm/cpu/armv7/sunxi/board.c | 8 ++++++++ boards.cfg | 2 +- include/configs/sunxi-common.h | 5 +++++ 3 files changed, 14 insertions(+), 1 deletion(-)
Again, this may be not a valid reason to complain (sorry if this is the case), but combining generic sunxi code changes in sunxi/board.c with the individual board support tweaks in boards.cfg is rather cherry-pick/revert unfriendly.

From: Chen-Yu Tsai wens@csie.org
Many A20 boards (ie Cubieboard2, A20-OLinuXino_MICRO) use an 100 Mbit MII phy together with the GMAC nic found in the A20 SoC, add support for this (this will get used when we add these boards in a later patch).
Signed-off-by: Chen-Yu Tsai wens@csie.org Signed-off-by: Hans de Goede hdegoede@redhat.com Acked-by: Ian Campbell ijc@hellion.org.uk --- board/sunxi/gmac.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
diff --git a/board/sunxi/gmac.c b/board/sunxi/gmac.c index e48328d..e7ff952 100644 --- a/board/sunxi/gmac.c +++ b/board/sunxi/gmac.c @@ -16,17 +16,28 @@ int sunxi_gmac_initialize(bd_t *bis) setbits_le32(&ccm->ahb_gate1, 0x1 << AHB_GATE_OFFSET_GMAC);
/* Set MII clock */ +#ifdef CONFIG_RGMII setbits_le32(&ccm->gmac_clk_cfg, CCM_GMAC_CTRL_TX_CLK_SRC_INT_RGMII | CCM_GMAC_CTRL_GPIT_RGMII); +#else + setbits_le32(&ccm->gmac_clk_cfg, CCM_GMAC_CTRL_TX_CLK_SRC_MII | + CCM_GMAC_CTRL_GPIT_MII); +#endif
/* Configure pin mux settings for GMAC */ for (pin = SUNXI_GPA(0); pin <= SUNXI_GPA(16); pin++) { +#ifdef CONFIG_RGMII /* skip unused pins in RGMII mode */ if (pin == SUNXI_GPA(9) || pin == SUNXI_GPA(14)) continue; +#endif sunxi_gpio_set_cfgpin(pin, SUN7I_GPA0_GMAC); sunxi_gpio_set_drv(pin, 3); }
+#ifdef CONFIG_RGMII return designware_initialize(SUNXI_GMAC_BASE, PHY_INTERFACE_MODE_RGMII); +#else + return designware_initialize(SUNXI_GMAC_BASE, PHY_INTERFACE_MODE_MII); +#endif }

On Mon, 9 Jun 2014 11:37:01 +0200 Hans de Goede hdegoede@redhat.com wrote:
From: Chen-Yu Tsai wens@csie.org
Many A20 boards (ie Cubieboard2, A20-OLinuXino_MICRO) use an 100 Mbit MII phy together with the GMAC nic found in the A20 SoC, add support for this (this will get used when we add these boards in a later patch).
Signed-off-by: Chen-Yu Tsai wens@csie.org Signed-off-by: Hans de Goede hdegoede@redhat.com Acked-by: Ian Campbell ijc@hellion.org.uk
Acked-by: Siarhei Siamashka siarhei.siamashka@gmail.com

Signed-off-by: Hans de Goede hdegoede@redhat.com Acked-by: Ian Campbell ijc@hellion.org.uk --- boards.cfg | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/boards.cfg b/boards.cfg index 1fe9f80..983189e 100644 --- a/boards.cfg +++ b/boards.cfg @@ -376,8 +376,8 @@ Active arm armv7 s5pc1xx samsung smdkc100 Active arm armv7 socfpga altera socfpga socfpga_cyclone5 - - Active arm armv7 sunxi - sunxi A13-OLinuXinoM sun5i:A13_OLINUXINOM,SPL,CONS_INDEX=2 Hans de Goede hdegoede@redhat.com Active arm armv7 sunxi - sunxi Cubieboard sun4i:CUBIEBOARD,SPL,SUNXI_EMAC Hans de Goede hdegoede@redhat.com -Active arm armv7 sunxi - sunxi Cubietruck sun7i:CUBIETRUCK,SPL,SUNXI_GMAC,RGMII - -Active arm armv7 sunxi - sunxi Cubietruck_FEL sun7i:CUBIETRUCK,SPL_FEL,SUNXI_GMAC,RGMII - +Active arm armv7 sunxi - sunxi Cubietruck sun7i:CUBIETRUCK,SPL,SUNXI_GMAC,RGMII Ian Campbell ijc@hellion.org.uk:Hans de Goede hdegoede@redhat.com +Active arm armv7 sunxi - sunxi Cubietruck_FEL sun7i:CUBIETRUCK,SPL_FEL,SUNXI_GMAC,RGMII Ian Campbell ijc@hellion.org.uk:Hans de Goede hdegoede@redhat.com Active arm armv7 sunxi - sunxi r7-tv-dongle sun5i:R7DONGLE,SPL Hans de Goede hdegoede@redhat.com Active arm armv7 u8500 st-ericsson snowball snowball - Mathieu Poirier mathieu.poirier@linaro.org Active arm armv7 u8500 st-ericsson u8500 u8500_href - -

Hi Albert,
Any comments on these sunxi series from Hans and myself?
Thanks, Ian.
On Mon, 2014-06-09 at 11:36 +0200, Hans de Goede wrote:
Hi All,
Here is v2 of my patch series to be applied on top of Ian's recently merged basic sun7i support.
This patch series begins with a few bug fixes found while working on preparing the rest of the series, adds sun4i and sun5i support and rounds things of with some networking fixes / additions.
Changes since v1: -Improved various commit messages -Various small typo fixes -Cleaned up the axp209 and axp152 drivers -Added Acked-by: Ian Campbell ... to the patches which got acked by Ian
Changes since v2: -Dropped the i2c + pmic support patches as they need more work -Split out the boards.cfg Cubietruck maintainer field changes from the axp209 support patch into its own patch -Added Acked-by: Ian Campbell ... to the patches which got acked by Ian
Regards,
Hans _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

(re-adding Hans whose CC I seem to have dropped somehow, sorry)
On Wed, 2014-06-25 at 20:57 +0100, Ian Campbell wrote:
Hi Albert,
Any comments on these sunxi series from Hans and myself?
I wonder if Hans and I should be applying for a u-boot-sunxi.git custodian tree[0]?
Ian.
[0] http://www.denx.de/wiki/U-Boot/CustodianGitTrees
Thanks, Ian.
On Mon, 2014-06-09 at 11:36 +0200, Hans de Goede wrote:
Hi All,
Here is v2 of my patch series to be applied on top of Ian's recently merged basic sun7i support.
This patch series begins with a few bug fixes found while working on preparing the rest of the series, adds sun4i and sun5i support and rounds things of with some networking fixes / additions.
Changes since v1: -Improved various commit messages -Various small typo fixes -Cleaned up the axp209 and axp152 drivers -Added Acked-by: Ian Campbell ... to the patches which got acked by Ian
Changes since v2: -Dropped the i2c + pmic support patches as they need more work -Split out the boards.cfg Cubietruck maintainer field changes from the axp209 support patch into its own patch -Added Acked-by: Ian Campbell ... to the patches which got acked by Ian
Regards,
Hans _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot

On 26.06.2014 09:38, Ian Campbell wrote:
(re-adding Hans whose CC I seem to have dropped somehow, sorry)
On Wed, 2014-06-25 at 20:57 +0100, Ian Campbell wrote:
Hi Albert,
Any comments on these sunxi series from Hans and myself?
I wonder if Hans and I should be applying for a u-boot-sunxi.git custodian tree[0]?
Yes, I'm all for it. This would definitely help to speed up the process and reduce the load on other custodians.
Tom, Albert, what do you think?
Thanks, Stefan

On Mon, 2014-06-09 at 11:36 +0200, Hans de Goede wrote:
Here is v2 of my patch series to be applied on top of Ian's recently merged basic sun7i support.
For the A13-OLinuXinoM and r7-tv-dongle with this series I'm seeing:
arch/arm/cpu/armv7/sunxi/board.c: In function ‘cpu_eth_init’: arch/arm/cpu/armv7/sunxi/board.c:118:6: warning: unused variable ‘rc’ [-Wunused-variable] int rc; ^ because they both have neither EMAC or GMAC. This resolves it:
8<------------------
From 4eed69132de51d07586e7b070eda72297825a674 Mon Sep 17 00:00:00 2001 From: Ian Campbell ijc@hellion.org.uk Date: Sun, 6 Jul 2014 20:03:20 +0100 Subject: [PATCH] sunxi: Avoid unused variable warning
Signed-off-by: Ian Campbell ijc@hellion.org.uk --- arch/arm/cpu/armv7/sunxi/board.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index 1e506b5..f8db9e8 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -115,7 +115,9 @@ void enable_caches(void) */ int cpu_eth_init(bd_t *bis) { +#if defined(CONFIG_SUNXI_EMAC) || defined(CONFIG_SUNXI_GMAC) int rc; +#endif
#ifdef CONFIG_SUNXI_EMAC rc = sunxi_emac_initialize(bis);

Hi Ian,
Slightly off-topic, but... When you provide some code excerpt, you should make sure it doesn't look like a git patch, because if it does, then our Patchwork, which reads the list, will think it is actually a patch submission:
http://patchwork.ozlabs.org/patch/367391/
Amicalement, Albert.
On Sun, 06 Jul 2014 20:12:17 +0100, Ian Campbell ijc@hellion.org.uk wrote:
On Mon, 2014-06-09 at 11:36 +0200, Hans de Goede wrote:
Here is v2 of my patch series to be applied on top of Ian's recently merged basic sun7i support.
For the A13-OLinuXinoM and r7-tv-dongle with this series I'm seeing:
arch/arm/cpu/armv7/sunxi/board.c: In function ‘cpu_eth_init’: arch/arm/cpu/armv7/sunxi/board.c:118:6: warning: unused variable ‘rc’ [-Wunused-variable] int rc; ^ because they both have neither EMAC or GMAC. This resolves it:
8<------------------
From 4eed69132de51d07586e7b070eda72297825a674 Mon Sep 17 00:00:00 2001 From: Ian Campbell ijc@hellion.org.uk Date: Sun, 6 Jul 2014 20:03:20 +0100 Subject: [PATCH] sunxi: Avoid unused variable warning
Signed-off-by: Ian Campbell ijc@hellion.org.uk
arch/arm/cpu/armv7/sunxi/board.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index 1e506b5..f8db9e8 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -115,7 +115,9 @@ void enable_caches(void) */ int cpu_eth_init(bd_t *bis) { +#if defined(CONFIG_SUNXI_EMAC) || defined(CONFIG_SUNXI_GMAC) int rc; +#endif
#ifdef CONFIG_SUNXI_EMAC rc = sunxi_emac_initialize(bis);

On Sun, 2014-07-06 at 21:18 +0200, Albert ARIBAUD wrote:
Hi Ian,
Slightly off-topic, but... When you provide some code excerpt, you should make sure it doesn't look like a git patch, because if it does, then our Patchwork, which reads the list, will think it is actually a patch submission:
I suppose this was a submission, although I was mostly planning to short circuit it straight into the appropriate branch.
How much do I need to corrupt something before patchwork will ignore it?
Ian.

Hi Ian,
On Sun, 06 Jul 2014 20:22:31 +0100, Ian Campbell ijc@hellion.org.uk wrote:
On Sun, 2014-07-06 at 21:18 +0200, Albert ARIBAUD wrote:
Hi Ian,
Slightly off-topic, but... When you provide some code excerpt, you should make sure it doesn't look like a git patch, because if it does, then our Patchwork, which reads the list, will think it is actually a patch submission:
I suppose this was a submission, although I was mostly planning to short circuit it straight into the appropriate branch.
Hmm, short-circuiting a code change is risky -- all U-Boot code should go through the list and be reviewed.
If your post was a submission, then it should be the pure result of a git format-patch or of a patman command.
How much do I need to corrupt something before patchwork will ignore it?
Basically, if you can (try to) 'git apply' the post, chances are PW will consider it a submission.
Ian.
Amicalement,

On Sun, 2014-07-06 at 22:54 +0200, Albert ARIBAUD wrote:
Hi Ian,
On Sun, 06 Jul 2014 20:22:31 +0100, Ian Campbell ijc@hellion.org.uk wrote:
On Sun, 2014-07-06 at 21:18 +0200, Albert ARIBAUD wrote:
Hi Ian,
Slightly off-topic, but... When you provide some code excerpt, you should make sure it doesn't look like a git patch, because if it does, then our Patchwork, which reads the list, will think it is actually a patch submission:
I suppose this was a submission, although I was mostly planning to short circuit it straight into the appropriate branch.
Hmm, short-circuiting a code change is risky -- all U-Boot code should go through the list and be reviewed.
Oh, I didn't mean to suggest skipping all that good stuff, just that the patch is already in a local branch ready to go when it is acked so I don't need to fetch it from patchwork.
Getting it reviewed was why I posted it.
If your post was a submission, then it should be the pure result of a git format-patch or of a patman command.
The thing I posted was the output of git format-patch.
How much do I need to corrupt something before patchwork will ignore it?
Basically, if you can (try to) 'git apply' the post, chances are PW will consider it a submission.
I think that is what I wanted on this occasion.
Ian.

Dear Ian Campbell,
In message 1404682080.11284.33.camel@dagon.hellion.org.uk you wrote:
Oh, I didn't mean to suggest skipping all that good stuff, just that the patch is already in a local branch ready to go when it is acked so I don't need to fetch it from patchwork.
It is a very good thiong to fetch patches from PW, as this will allow you to automatically also fetch all ACKs you get from other people. If you don't use PW, you will have to track the mailing list and insert all Acked-by: and Tested-By: etc. manually. I don;t think you want to do that.
Best regards,
Wolfgang Denk

Hi Ian,
On 07/06/2014 09:12 PM, Ian Campbell wrote:
On Mon, 2014-06-09 at 11:36 +0200, Hans de Goede wrote:
Here is v2 of my patch series to be applied on top of Ian's recently merged basic sun7i support.
For the A13-OLinuXinoM and r7-tv-dongle with this series I'm seeing:
arch/arm/cpu/armv7/sunxi/board.c: In function ‘cpu_eth_init’: arch/arm/cpu/armv7/sunxi/board.c:118:6: warning: unused variable ‘rc’ [-Wunused-variable] int rc; ^ because they both have neither EMAC or GMAC. This resolves it:
8<------------------
From 4eed69132de51d07586e7b070eda72297825a674 Mon Sep 17 00:00:00 2001 From: Ian Campbell ijc@hellion.org.uk Date: Sun, 6 Jul 2014 20:03:20 +0100 Subject: [PATCH] sunxi: Avoid unused variable warning
Signed-off-by: Ian Campbell ijc@hellion.org.uk
arch/arm/cpu/armv7/sunxi/board.c | 2 ++ 1 file changed, 2 insertions(+)
diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index 1e506b5..f8db9e8 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -115,7 +115,9 @@ void enable_caches(void) */ int cpu_eth_init(bd_t *bis) { +#if defined(CONFIG_SUNXI_EMAC) || defined(CONFIG_SUNXI_GMAC) int rc; +#endif
#ifdef CONFIG_SUNXI_EMAC rc = sunxi_emac_initialize(bis);
AFAIK we will never define both EMAC and GMAC for the same board, so IMHO a better fix would be to change this line:
rc = sunxi_emac_initialize(bis);
to:
int rc = sunxi_emac_initialize(bis);
And the same for gmac.
Regards,
Hans

On Mon, 2014-07-07 at 14:50 +0200, Hans de Goede wrote:
AFAIK we will never define both EMAC and GMAC for the same board,
If we are sure of this (and I suspect this is the case, since IIRC they share some pins) then I agree with your suggestion.
so IMHO a better fix would be to change this line:
rc = sunxi_emac_initialize(bis);
to:
int rc = sunxi_emac_initialize(bis);
And the same for gmac.
Regards,
Hans

On Mon, Jul 07, 2014 at 04:10:42PM +0100, Ian Campbell wrote:
On Mon, 2014-07-07 at 14:50 +0200, Hans de Goede wrote:
AFAIK we will never define both EMAC and GMAC for the same board,
If we are sure of this (and I suspect this is the case, since IIRC they share some pins) then I agree with your suggestion.
so IMHO a better fix would be to change this line:
rc = sunxi_emac_initialize(bis);
to:
int rc = sunxi_emac_initialize(bis);
That's not how we like things to look however when we can help it. Just toss a __maybe_unused in front of the declaration (and make sure we have <linux/compiler.h> included.

On Mon, 2014-07-07 at 12:47 -0400, Tom Rini wrote:
That's not how we like things to look however when we can help it. Just toss a __maybe_unused in front of the declaration (and make sure we have <linux/compiler.h> included.
OK. How about the following?
Hans, BTW, I spotted this issue with: CROSS_COMPILE=arm-linux-gnueabihf- ./MAKEALL -s sunxi which is a very useful invocation indeed!
8<-------------------
From 5e0659b772380114a9e86624aefd1dcb09a90bd9 Mon Sep 17 00:00:00 2001
From: Ian Campbell ijc@hellion.org.uk Date: Sun, 6 Jul 2014 20:03:20 +0100 Subject: [PATCH] sunxi: Avoid unused variable warning.
Mark rc as __maybe_unused since it is infact unused on systems with neither EMAC nor GMAC.
Signed-off-by: Ian Campbell ijc@hellion.org.uk --- arch/arm/cpu/armv7/sunxi/board.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index 1e506b5..538ffa7 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -24,6 +24,8 @@ #include <asm/arch/sys_proto.h> #include <asm/arch/timer.h>
+#include <linux/compiler.h> + #ifdef CONFIG_SPL_BUILD /* Pointer to the global data structure for SPL */ DECLARE_GLOBAL_DATA_PTR; @@ -115,7 +117,7 @@ void enable_caches(void) */ int cpu_eth_init(bd_t *bis) { - int rc; + __maybe_unused int rc;
#ifdef CONFIG_SUNXI_EMAC rc = sunxi_emac_initialize(bis);

On Mon, Jul 07, 2014 at 09:23:13PM +0100, Ian Campbell wrote:
On Mon, 2014-07-07 at 12:47 -0400, Tom Rini wrote:
That's not how we like things to look however when we can help it. Just toss a __maybe_unused in front of the declaration (and make sure we have <linux/compiler.h> included.
OK. How about the following?
Hans, BTW, I spotted this issue with: CROSS_COMPILE=arm-linux-gnueabihf- ./MAKEALL -s sunxi which is a very useful invocation indeed!
FWIW, you might want to run -a arm from time to time since there's some shared drivers between sunxi and others.
From 5e0659b772380114a9e86624aefd1dcb09a90bd9 Mon Sep 17 00:00:00 2001 From: Ian Campbell ijc@hellion.org.uk Date: Sun, 6 Jul 2014 20:03:20 +0100 Subject: [PATCH] sunxi: Avoid unused variable warning.
Mark rc as __maybe_unused since it is infact unused on systems with neither EMAC nor GMAC.
Signed-off-by: Ian Campbell ijc@hellion.org.uk
Acked-by: Tom Rini trini@ti.com
Thanks.

On Mon, 2014-07-07 at 16:45 -0400, Tom Rini wrote:
On Mon, Jul 07, 2014 at 09:23:13PM +0100, Ian Campbell wrote:
On Mon, 2014-07-07 at 12:47 -0400, Tom Rini wrote:
That's not how we like things to look however when we can help it. Just toss a __maybe_unused in front of the declaration (and make sure we have <linux/compiler.h> included.
OK. How about the following?
Hans, BTW, I spotted this issue with: CROSS_COMPILE=arm-linux-gnueabihf- ./MAKEALL -s sunxi which is a very useful invocation indeed!
FWIW, you might want to run -a arm from time to time since there's some shared drivers between sunxi and others.
Ack.
I don't suppose there is a bot somewhere which provides baseline results for comparison?
From 5e0659b772380114a9e86624aefd1dcb09a90bd9 Mon Sep 17 00:00:00 2001 From: Ian Campbell ijc@hellion.org.uk Date: Sun, 6 Jul 2014 20:03:20 +0100 Subject: [PATCH] sunxi: Avoid unused variable warning.
Mark rc as __maybe_unused since it is infact unused on systems with neither EMAC nor GMAC.
Signed-off-by: Ian Campbell ijc@hellion.org.uk
Acked-by: Tom Rini trini@ti.com
Thanks.
Thank you.
Ian.

On Tue, Jul 08, 2014 at 08:23:11AM +0100, Ian Campbell wrote:
On Mon, 2014-07-07 at 16:45 -0400, Tom Rini wrote:
On Mon, Jul 07, 2014 at 09:23:13PM +0100, Ian Campbell wrote:
On Mon, 2014-07-07 at 12:47 -0400, Tom Rini wrote:
That's not how we like things to look however when we can help it. Just toss a __maybe_unused in front of the declaration (and make sure we have <linux/compiler.h> included.
OK. How about the following?
Hans, BTW, I spotted this issue with: CROSS_COMPILE=arm-linux-gnueabihf- ./MAKEALL -s sunxi which is a very useful invocation indeed!
FWIW, you might want to run -a arm from time to time since there's some shared drivers between sunxi and others.
Ack.
I don't suppose there is a bot somewhere which provides baseline results for comparison?
Marek, is your builder still going? Having more CI stuff available widely is something I'd like but not far along.

Hi,
On 07/07/2014 10:23 PM, Ian Campbell wrote:
On Mon, 2014-07-07 at 12:47 -0400, Tom Rini wrote:
That's not how we like things to look however when we can help it. Just toss a __maybe_unused in front of the declaration (and make sure we have <linux/compiler.h> included.
OK. How about the following?
Hans, BTW, I spotted this issue with: CROSS_COMPILE=arm-linux-gnueabihf- ./MAKEALL -s sunxi which is a very useful invocation indeed!
Indeed, I've saved it for future reference.
Regards,
Hans
8<-------------------
From 5e0659b772380114a9e86624aefd1dcb09a90bd9 Mon Sep 17 00:00:00 2001 From: Ian Campbell ijc@hellion.org.uk Date: Sun, 6 Jul 2014 20:03:20 +0100 Subject: [PATCH] sunxi: Avoid unused variable warning.
Mark rc as __maybe_unused since it is infact unused on systems with neither EMAC nor GMAC.
Signed-off-by: Ian Campbell ijc@hellion.org.uk
arch/arm/cpu/armv7/sunxi/board.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/arch/arm/cpu/armv7/sunxi/board.c b/arch/arm/cpu/armv7/sunxi/board.c index 1e506b5..538ffa7 100644 --- a/arch/arm/cpu/armv7/sunxi/board.c +++ b/arch/arm/cpu/armv7/sunxi/board.c @@ -24,6 +24,8 @@ #include <asm/arch/sys_proto.h> #include <asm/arch/timer.h>
+#include <linux/compiler.h>
#ifdef CONFIG_SPL_BUILD /* Pointer to the global data structure for SPL */ DECLARE_GLOBAL_DATA_PTR; @@ -115,7 +117,7 @@ void enable_caches(void) */ int cpu_eth_init(bd_t *bis) {
- int rc;
- __maybe_unused int rc;
#ifdef CONFIG_SUNXI_EMAC rc = sunxi_emac_initialize(bis);

On Mon, 2014-06-09 at 11:36 +0200, Hans de Goede wrote:
adds sun4i and sun5i support
Does this series omit FEL mode support or did you just not include it for the new boards?
I think in general we want a _FEL variant for every board except the minority which don't have an OTG port etc.
Ian.

Hi,
On 07/06/2014 09:26 PM, Ian Campbell wrote:
On Mon, 2014-06-09 at 11:36 +0200, Hans de Goede wrote:
adds sun4i and sun5i support
Does this series omit FEL mode support or did you just not include it for the new boards?
I just did not include it.
I think in general we want a _FEL variant for every board except the minority which don't have an OTG port etc.
I'm not sold on this idea. Normal users (and distros) will never use the FEL variants, and a developer needing a FEL build can just as easily edit boards.cfg, instead of us having 2 lines there for each and every sunxi board (of which there are *a lot*.
Regards,
Hans

On Mon, Jul 07, 2014 at 02:53:44PM +0200, Hans de Goede wrote:
Hi,
On 07/06/2014 09:26 PM, Ian Campbell wrote:
On Mon, 2014-06-09 at 11:36 +0200, Hans de Goede wrote:
adds sun4i and sun5i support
Does this series omit FEL mode support or did you just not include it for the new boards?
I just did not include it.
I think in general we want a _FEL variant for every board except the minority which don't have an OTG port etc.
I'm not sold on this idea. Normal users (and distros) will never use the FEL variants, and a developer needing a FEL build can just as easily edit boards.cfg, instead of us having 2 lines there for each and every sunxi board (of which there are *a lot*.
... and once we have Kconfig it will be an easy thing to enable as needed.

On Mon, 2014-07-07 at 14:53 +0200, Hans de Goede wrote:
Hi,
On 07/06/2014 09:26 PM, Ian Campbell wrote:
On Mon, 2014-06-09 at 11:36 +0200, Hans de Goede wrote:
adds sun4i and sun5i support
Does this series omit FEL mode support or did you just not include it for the new boards?
I just did not include it.
I think in general we want a _FEL variant for every board except the minority which don't have an OTG port etc.
I'm not sold on this idea. Normal users (and distros) will never use the FEL variants, and a developer needing a FEL build can just as easily edit boards.cfg, instead of us having 2 lines there for each and every sunxi board (of which there are *a lot*.
Actually Debian is providing the FEL binaries for CT in its u-boot packages already.
I was planning to provide a script to automatically install Debian starting from a bare board booted in FEL mode from a host system and getting the installer to put the bootloader on the MMC etc etc. (I'm a long way from actually having this working...)
Ian.

Hi,
On 07/07/2014 05:13 PM, Ian Campbell wrote:
On Mon, 2014-07-07 at 14:53 +0200, Hans de Goede wrote:
Hi,
On 07/06/2014 09:26 PM, Ian Campbell wrote:
On Mon, 2014-06-09 at 11:36 +0200, Hans de Goede wrote:
adds sun4i and sun5i support
Does this series omit FEL mode support or did you just not include it for the new boards?
I just did not include it.
I think in general we want a _FEL variant for every board except the minority which don't have an OTG port etc.
I'm not sold on this idea. Normal users (and distros) will never use the FEL variants, and a developer needing a FEL build can just as easily edit boards.cfg, instead of us having 2 lines there for each and every sunxi board (of which there are *a lot*.
Actually Debian is providing the FEL binaries for CT in its u-boot packages already.
Hmm, ok.
I was planning to provide a script to automatically install Debian starting from a bare board booted in FEL mode from a host system and getting the installer to put the bootloader on the MMC etc etc. (I'm a long way from actually having this working...)
Interesting (mostly for emmc devices, of which there are a few sunxi ones now).
I'm still not sold on having 2 entries for each and every board though.
Have you looked at extending the SPL buildsys bits, which in essence do 2 builds, to do 3 builds for sunxi, so that we simply always build both SPL flavors?
Regards,
Hans

On Tue, 2014-07-08 at 09:47 +0200, Hans de Goede wrote:
Have you looked at extending the SPL buildsys bits, which in essence do 2 builds, to do 3 builds for sunxi, so that we simply always build both SPL flavors?
I hadn't thought of it. Is it only the SPL binary which differs between FEL and non-FEL then?
Ian.

Hi,
On 07/09/2014 10:00 AM, Ian Campbell wrote:
On Tue, 2014-07-08 at 09:47 +0200, Hans de Goede wrote:
Have you looked at extending the SPL buildsys bits, which in essence do 2 builds, to do 3 builds for sunxi, so that we simply always build both SPL flavors?
I hadn't thought of it. Is it only the SPL binary which differs between FEL and non-FEL then?
AFAIK, Yes.
Note an alternative to doing 3 builds would be to move the load address for the mmc spl to 0x2000 too, and to change the mmc spl header to jump to 0x2000 instead of 0x20. The question here is if the spl with mmc support will fit if we don't use the first 0x2000 bytes. One thing we could do is move the stack to another sram area (the area where we later copy the PSCI code for example), which will free up some space.
We would then also need to modify the unified SPL to detect whether it has booted from mmc or FEL, and only try to load the real u-boot from mmc in the mmc boot case.
If we do this, we would just need to modify the final build steps of the SPL build a bit to produce both SPL flavors.
I guess the big question is if we can make the mmc spl fit if we load it at 0x2000. If you're interested in working on this you should probably talk to hno about this. Another complication is that the brom uses some of the 32k sram at address 0 when in fel mode, so I think you cannot use all of it. hno can probably give more details here about which bits of the first 32k sram are used by the brom in fel mode and in mmc mode.
Regards,
Hans

ons 2014-07-09 klockan 09:00 +0100 skrev Ian Campbell:
I hadn't thought of it. Is it only the SPL binary which differs between FEL and non-FEL then?
There is also a small difference in the default environment to enable boot-from-RAM in the FEL version of main u-boot. This is not enabled in the normal u-boot to avoid any risk of infinite looping boot failure from wrongly detected ram boot image.
Regards Henrik

Hi,
On 07/09/2014 03:03 PM, Henrik Nordström wrote:
ons 2014-07-09 klockan 09:00 +0100 skrev Ian Campbell:
I hadn't thought of it. Is it only the SPL binary which differs between FEL and non-FEL then?
There is also a small difference in the default environment to enable boot-from-RAM in the FEL version of main u-boot. This is not enabled in the normal u-boot to avoid any risk of infinite looping boot failure from wrongly detected ram boot image.
Henrik, can you provide us with some memorymap info of the first 32K of SRAM for when booted from FEL vs MMC for all of sun4i, sun5i and sun7i ?
It would be good to know which bits of SRAM actually get uses by the BROM, and thus should not be overwritten, and which ones are free to use.
Regards,
Hans
participants (8)
-
Albert ARIBAUD
-
Hans de Goede
-
Henrik Nordström
-
Ian Campbell
-
Siarhei Siamashka
-
Stefan Roese
-
Tom Rini
-
Wolfgang Denk