1
0
Fork 0

Merge branch 'master' of git://git.denx.de/u-boot-arm

utp
Tom Rini 2014-08-28 13:03:25 -04:00
commit 3e1b36bd58
48 changed files with 982 additions and 13 deletions

View File

@ -17,6 +17,9 @@ obj-$(CONFIG_SUN7I) += clock_sun4i.o
ifndef CONFIG_SPL_BUILD
obj-y += cpu_info.o
ifdef CONFIG_ARMV7_PSCI
obj-y += psci.o
endif
endif
ifdef CONFIG_SPL_BUILD

View File

@ -129,6 +129,11 @@ int cpu_eth_init(bd_t *bis)
{
__maybe_unused int rc;
#ifdef CONFIG_MACPWR
gpio_direction_output(CONFIG_MACPWR, 1);
mdelay(200);
#endif
#ifdef CONFIG_SUNXI_EMAC
rc = sunxi_emac_initialize(bis);
if (rc < 0) {

View File

@ -39,6 +39,10 @@ void clock_init_safe(void)
setbits_le32(&ccm->ahb_gate0, 0x1 << AHB_GATE_OFFSET_DMA);
#endif
writel(PLL6_CFG_DEFAULT, &ccm->pll6_cfg);
#ifdef CONFIG_SUNXI_AHCI
setbits_le32(&ccm->ahb_gate0, 0x1 << AHB_GATE_OFFSET_SATA);
setbits_le32(&ccm->pll6_cfg, 0x1 << CCM_PLL6_CTRL_SATA_EN_SHIFT);
#endif
}
#endif

View File

@ -0,0 +1,162 @@
/*
* Copyright (C) 2013 - ARM Ltd
* Author: Marc Zyngier <marc.zyngier@arm.com>
*
* Based on code by Carl van Schaik <carl@ok-labs.com>.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include <asm/psci.h>
#include <asm/arch/cpu.h>
/*
* Memory layout:
*
* SECURE_RAM to text_end :
* ._secure_text section
* text_end to ALIGN_PAGE(text_end):
* nothing
* ALIGN_PAGE(text_end) to ALIGN_PAGE(text_end) + 0x1000)
* 1kB of stack per CPU (4 CPUs max).
*/
.pushsection ._secure.text, "ax"
.arch_extension sec
#define ONE_MS (CONFIG_SYS_CLK_FREQ / 1000)
#define TEN_MS (10 * ONE_MS)
.macro timer_wait reg, ticks
@ Program CNTP_TVAL
movw \reg, #(\ticks & 0xffff)
movt \reg, #(\ticks >> 16)
mcr p15, 0, \reg, c14, c2, 0
isb
@ Enable physical timer, mask interrupt
mov \reg, #3
mcr p15, 0, \reg, c14, c2, 1
@ Poll physical timer until ISTATUS is on
1: isb
mrc p15, 0, \reg, c14, c2, 1
ands \reg, \reg, #4
bne 1b
@ Disable timer
mov \reg, #0
mcr p15, 0, \reg, c14, c2, 1
isb
.endm
.globl psci_arch_init
psci_arch_init:
mrc p15, 0, r5, c1, c1, 0 @ Read SCR
bic r5, r5, #1 @ Secure mode
mcr p15, 0, r5, c1, c1, 0 @ Write SCR
isb
mrc p15, 0, r4, c0, c0, 5 @ MPIDR
and r4, r4, #3 @ cpu number in cluster
mov r5, #400 @ 1kB of stack per CPU
mul r4, r4, r5
adr r5, text_end @ end of text
add r5, r5, #0x2000 @ Skip two pages
lsr r5, r5, #12 @ Align to start of page
lsl r5, r5, #12
sub sp, r5, r4 @ here's our stack!
bx lr
@ r1 = target CPU
@ r2 = target PC
.globl psci_cpu_on
psci_cpu_on:
adr r0, _target_pc
str r2, [r0]
dsb
movw r0, #(SUNXI_CPUCFG_BASE & 0xffff)
movt r0, #(SUNXI_CPUCFG_BASE >> 16)
@ CPU mask
and r1, r1, #3 @ only care about first cluster
mov r4, #1
lsl r4, r4, r1
adr r6, _sunxi_cpu_entry
str r6, [r0, #0x1a4] @ PRIVATE_REG (boot vector)
@ Assert reset on target CPU
mov r6, #0
lsl r5, r1, #6 @ 64 bytes per CPU
add r5, r5, #0x40 @ Offset from base
add r5, r5, r0 @ CPU control block
str r6, [r5] @ Reset CPU
@ l1 invalidate
ldr r6, [r0, #0x184]
bic r6, r6, r4
str r6, [r0, #0x184]
@ Lock CPU
ldr r6, [r0, #0x1e4]
bic r6, r6, r4
str r6, [r0, #0x1e4]
@ Release power clamp
movw r6, #0x1ff
movt r6, #0
1: lsrs r6, r6, #1
str r6, [r0, #0x1b0]
bne 1b
timer_wait r1, TEN_MS
@ Clear power gating
ldr r6, [r0, #0x1b4]
bic r6, r6, #1
str r6, [r0, #0x1b4]
@ Deassert reset on target CPU
mov r6, #3
str r6, [r5]
@ Unlock CPU
ldr r6, [r0, #0x1e4]
orr r6, r6, r4
str r6, [r0, #0x1e4]
mov r0, #ARM_PSCI_RET_SUCCESS @ Return PSCI_RET_SUCCESS
mov pc, lr
_target_pc:
.word 0
_sunxi_cpu_entry:
@ Set SMP bit
mrc p15, 0, r0, c1, c0, 1
orr r0, r0, #0x40
mcr p15, 0, r0, c1, c0, 1
isb
bl _nonsec_init
bl psci_arch_init
adr r0, _target_pc
ldr r0, [r0]
b _do_nonsec_entry
text_end:
.popsection

View File

@ -218,10 +218,13 @@ struct sunxi_ccm_reg {
#define CCM_PLL5_CTRL_BYPASS (0x1 << 30)
#define CCM_PLL5_CTRL_EN (0x1 << 31)
#define CCM_PLL6_CTRL_N_SHIFT 8
#define CCM_PLL6_CTRL_N_MASK (0x1f << CCM_PLL6_CTRL_N_SHIFT)
#define CCM_PLL6_CTRL_K_SHIFT 4
#define CCM_PLL6_CTRL_K_MASK (0x3 << CCM_PLL6_CTRL_K_SHIFT)
#define CCM_PLL6_CTRL_EN 31
#define CCM_PLL6_CTRL_BYPASS_EN 30
#define CCM_PLL6_CTRL_SATA_EN_SHIFT 14
#define CCM_PLL6_CTRL_N_SHIFT 8
#define CCM_PLL6_CTRL_N_MASK (0x1f << CCM_PLL6_CTRL_N_SHIFT)
#define CCM_PLL6_CTRL_K_SHIFT 4
#define CCM_PLL6_CTRL_K_MASK (0x3 << CCM_PLL6_CTRL_K_SHIFT)
#define CCM_GPS_CTRL_RESET (0x1 << 0)
#define CCM_GPS_CTRL_GATE (0x1 << 1)
@ -253,4 +256,8 @@ struct sunxi_ccm_reg {
#define CCM_GMAC_CTRL_GPIT_MII (0x0 << 2)
#define CCM_GMAC_CTRL_GPIT_RGMII (0x1 << 2)
#define CCM_USB_CTRL_PHY1_RST (0x1 << 1)
#define CCM_USB_CTRL_PHY2_RST (0x1 << 2)
#define CCM_USB_CTRL_PHYGATE (0x1 << 8)
#endif /* _SUNXI_CLOCK_SUN4I_H */

View File

@ -2,11 +2,26 @@ SUNXI BOARD
M: Hans de Goede <hdegoede@redhat.com>
S: Maintained
F: board/sunxi/
F: include/configs/sun5i.h
F: configs/A13-OLinuXinoM_defconfig
F: include/configs/sun4i.h
F: configs/A10-OLinuXino-Lime_defconfig
F: configs/ba10_tv_box_defconfig
F: configs/Cubieboard_defconfig
F: configs/Mele_A1000_defconfig
F: configs/Mele_A1000G_defconfig
F: configs/Mini-X_defconfig
F: configs/Mini-X-1Gb_defconfig
F: include/configs/sun5i.h
F: configs/A10s-OLinuXino-M_defconfig
F: configs/A13-OLinuXino_defconfig
F: configs/A13-OLinuXinoM_defconfig
F: configs/Auxtek-T004_defconfig
F: configs/r7-tv-dongle_defconfig
F: include/configs/sun7i.h
F: configs/A20-OLinuXino_MICRO_defconfig
F: configs/Bananapi_defconfig
F: configs/i12-tvbox_defconfig
F: configs/Linksprite_pcDuino3_defconfig
F: configs/qt840a_defconfig
CUBIEBOARD2 BOARD
M: Ian Campbell <ijc@hellion.org.uk>

View File

@ -10,8 +10,24 @@
#
obj-y += board.o
obj-$(CONFIG_SUNXI_GMAC) += gmac.o
obj-$(CONFIG_SUNXI_AHCI) += ahci.o
obj-$(CONFIG_A10_OLINUXINO_L) += dram_a10_olinuxino_l.o
obj-$(CONFIG_A10S_OLINUXINO_M) += dram_a10s_olinuxino_m.o
obj-$(CONFIG_A13_OLINUXINO) += dram_a13_olinuxino.o
obj-$(CONFIG_A13_OLINUXINOM) += dram_a13_oli_micro.o
obj-$(CONFIG_A20_OLINUXINO_M) += dram_sun7i_384_1024_iow16.o
# This is not a typo, uses the same mem settings as the a10s-olinuxino-m
obj-$(CONFIG_AUXTEK_T004) += dram_a10s_olinuxino_m.o
obj-$(CONFIG_BA10_TV_BOX) += dram_sun4i_384_1024_iow8.o
obj-$(CONFIG_BANANAPI) += dram_bananapi.o
obj-$(CONFIG_CUBIEBOARD) += dram_cubieboard.o
obj-$(CONFIG_CUBIEBOARD2) += dram_cubieboard2.o
obj-$(CONFIG_CUBIETRUCK) += dram_cubietruck.o
obj-$(CONFIG_I12_TVBOX) += dram_sun7i_384_1024_iow16.o
obj-$(CONFIG_MELE_A1000) += dram_sun4i_360_512.o
obj-$(CONFIG_MELE_A1000G) += dram_sun4i_360_1024_iow8.o
obj-$(CONFIG_MINI_X) += dram_sun4i_360_512.o
obj-$(CONFIG_MINI_X_1GB) += dram_sun4i_360_1024_iow16.o
obj-$(CONFIG_PCDUINO3) += dram_linksprite_pcduino3.o
obj-$(CONFIG_QT840A) += dram_sun7i_384_512_busw16_iow16.o
obj-$(CONFIG_R7DONGLE) += dram_r7dongle.o

84
board/sunxi/ahci.c 100644
View File

@ -0,0 +1,84 @@
#include <common.h>
#include <ahci.h>
#include <scsi.h>
#include <errno.h>
#include <asm/io.h>
#include <asm/gpio.h>
#define AHCI_PHYCS0R 0x00c0
#define AHCI_PHYCS1R 0x00c4
#define AHCI_PHYCS2R 0x00c8
#define AHCI_RWCR 0x00fc
/* This magic PHY initialisation was taken from the Allwinner releases
* and Linux driver, but is completely undocumented.
*/
static int sunxi_ahci_phy_init(u32 base)
{
u8 *reg_base = (u8 *)base;
u32 reg_val;
int timeout;
writel(0, reg_base + AHCI_RWCR);
mdelay(5);
setbits_le32(reg_base + AHCI_PHYCS1R, 0x1 << 19);
clrsetbits_le32(reg_base + AHCI_PHYCS0R,
(0x7 << 24),
(0x5 << 24) | (0x1 << 23) | (0x1 << 18));
clrsetbits_le32(reg_base + AHCI_PHYCS1R,
(0x3 << 16) | (0x1f << 8) | (0x3 << 6),
(0x2 << 16) | (0x6 << 8) | (0x2 << 6));
setbits_le32(reg_base + AHCI_PHYCS1R, (0x1 << 28) | (0x1 << 15));
clrbits_le32(reg_base + AHCI_PHYCS1R, (0x1 << 19));
clrsetbits_le32(reg_base + AHCI_PHYCS0R, (0x7 << 20), (0x3 << 20));
clrsetbits_le32(reg_base + AHCI_PHYCS2R, (0x1f << 5), (0x19 << 5));
mdelay(5);
setbits_le32(reg_base + AHCI_PHYCS0R, (0x1 << 19));
timeout = 250; /* Power up takes approx 50 us */
for (;;) {
reg_val = readl(reg_base + AHCI_PHYCS0R) & (0x7 << 28);
if (reg_val == (0x2 << 28))
break;
if (--timeout == 0) {
printf("AHCI PHY power up failed.\n");
return -EIO;
}
udelay(1);
};
setbits_le32(reg_base + AHCI_PHYCS2R, (0x1 << 24));
timeout = 100; /* Calibration takes approx 10 us */
for (;;) {
reg_val = readl(reg_base + AHCI_PHYCS2R) & (0x1 << 24);
if (reg_val == 0x0)
break;
if (--timeout == 0) {
printf("AHCI PHY calibration failed.\n");
return -EIO;
}
udelay(1);
}
mdelay(15);
writel(0x7, reg_base + AHCI_RWCR);
return 0;
}
void scsi_init(void)
{
printf("SUNXI SCSI INIT\n");
#ifdef CONFIG_SATAPWR
gpio_direction_output(CONFIG_SATAPWR, 1);
#endif
if (sunxi_ahci_phy_init(SUNXI_SATA_BASE) < 0)
return;
ahci_init(SUNXI_SATA_BASE);
}

View File

@ -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 = 16,
.cas = 6,
.zq = 123,
.odt_en = 0,
.size = 512,
.tpr0 = 0x30926692,
.tpr1 = 0x1090,
.tpr2 = 0x1a0c8,
.tpr3 = 0,
.tpr4 = 0,
.tpr5 = 0,
.emr1 = 0x4,
.emr2 = 0,
.emr3 = 0,
};
unsigned long sunxi_dram_init(void)
{
return dramc_init(&dram_para);
}

View File

@ -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 = 432,
.type = 3,
.rank_num = 1,
.density = 4096,
.io_width = 16,
.bus_width = 16,
.cas = 9,
.zq = 123,
.odt_en = 0,
.size = 512,
.tpr0 = 0x42d899b7,
.tpr1 = 0xa090,
.tpr2 = 0x22a00,
.tpr3 = 0,
.tpr4 = 0,
.tpr5 = 0,
.emr1 = 0x4,
.emr2 = 0x10,
.emr3 = 0,
};
unsigned long sunxi_dram_init(void)
{
return dramc_init(&dram_para);
}

View File

@ -0,0 +1,31 @@
/* this file is generated, don't edit it yourself */
#include <common.h>
#include <asm/arch/dram.h>
static struct dram_para dram_para = {
.clock = 408,
.type = 3,
.rank_num = 1,
.density = 2048,
.io_width = 8,
.bus_width = 16,
.cas = 9,
.zq = 123,
.odt_en = 0,
.size = 512,
.tpr0 = 0x42d899b7,
.tpr1 = 0xa090,
.tpr2 = 0x22a00,
.tpr3 = 0,
.tpr4 = 0,
.tpr5 = 0,
.emr1 = 0,
.emr2 = 0x10,
.emr3 = 0,
};
unsigned long sunxi_dram_init(void)
{
return dramc_init(&dram_para);
}

View File

@ -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 = 432,
.type = 3,
.rank_num = 1,
.density = 4096,
.io_width = 16,
.bus_width = 32,
.cas = 9,
.zq = 0x7f,
.odt_en = 0,
.size = 1024,
.tpr0 = 0x42d899b7,
.tpr1 = 0xa090,
.tpr2 = 0x22a00,
.tpr3 = 0x0,
.tpr4 = 0x1,
.tpr5 = 0x0,
.emr1 = 0x4,
.emr2 = 0x10,
.emr3 = 0x0,
};
unsigned long sunxi_dram_init(void)
{
return dramc_init(&dram_para);
}

View File

@ -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 = 9,
.zq = 0x7a,
.odt_en = 0,
.size = 1024,
.tpr0 = 0x42d899b7,
.tpr1 = 0xa090,
.tpr2 = 0x22a00,
.tpr3 = 0,
.tpr4 = 0,
.tpr5 = 0,
.emr1 = 0x4,
.emr2 = 0x10,
.emr3 = 0x0,
};
unsigned long sunxi_dram_init(void)
{
return dramc_init(&dram_para);
}

View File

@ -0,0 +1,31 @@
/* this file is generated, don't edit it yourself */
#include <common.h>
#include <asm/arch/dram.h>
static struct dram_para dram_para = {
.clock = 360,
.type = 3,
.rank_num = 1,
.density = 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);
}

View File

@ -0,0 +1,31 @@
/* this file is generated, don't edit it yourself */
#include <common.h>
#include <asm/arch/dram.h>
static struct dram_para dram_para = {
.clock = 360,
.type = 3,
.rank_num = 1,
.density = 2048,
.io_width = 8,
.bus_width = 32,
.cas = 6,
.zq = 123,
.odt_en = 0,
.size = 1024,
.tpr0 = 0x30926692,
.tpr1 = 0x1090,
.tpr2 = 0x1a0c8,
.tpr3 = 0,
.tpr4 = 0,
.tpr5 = 0,
.emr1 = 0,
.emr2 = 0,
.emr3 = 0,
};
unsigned long sunxi_dram_init(void)
{
return dramc_init(&dram_para);
}

View File

@ -0,0 +1,31 @@
/* this file is generated, don't edit it yourself */
#include <common.h>
#include <asm/arch/dram.h>
static struct dram_para dram_para = {
.clock = 360,
.type = 3,
.rank_num = 1,
.density = 2048,
.io_width = 16,
.bus_width = 32,
.cas = 6,
.zq = 123,
.odt_en = 0,
.size = 512,
.tpr0 = 0x30926692,
.tpr1 = 0x1090,
.tpr2 = 0x1a0c8,
.tpr3 = 0,
.tpr4 = 0,
.tpr5 = 0,
.emr1 = 0,
.emr2 = 0,
.emr3 = 0,
};
unsigned long sunxi_dram_init(void)
{
return dramc_init(&dram_para);
}

View File

@ -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 = 6,
.zq = 123,
.odt_en = 0,
.size = 1024,
.tpr0 = 0x30926692,
.tpr1 = 0x1090,
.tpr2 = 0x1a0c8,
.tpr3 = 0,
.tpr4 = 0,
.tpr5 = 0,
.emr1 = 0x4,
.emr2 = 0,
.emr3 = 0,
};
unsigned long sunxi_dram_init(void)
{
return dramc_init(&dram_para);
}

View File

@ -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 = 4096,
.io_width = 16,
.bus_width = 32,
.cas = 9,
.zq = 0x7f,
.odt_en = 0,
.size = 1024,
.tpr0 = 0x42d899b7,
.tpr1 = 0xa090,
.tpr2 = 0x22a00,
.tpr3 = 0,
.tpr4 = 0,
.tpr5 = 0,
.emr1 = 0x4,
.emr2 = 0x10,
.emr3 = 0,
};
unsigned long sunxi_dram_init(void)
{
return dramc_init(&dram_para);
}

View File

@ -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 = 4096,
.io_width = 16,
.bus_width = 16,
.cas = 9,
.zq = 0x7f,
.odt_en = 0,
.size = 512,
.tpr0 = 0x42d899b7,
.tpr1 = 0xa090,
.tpr2 = 0x22a00,
.tpr3 = 0,
.tpr4 = 0,
.tpr5 = 0,
.emr1 = 0x4,
.emr2 = 0x10,
.emr3 = 0,
};
unsigned long sunxi_dram_init(void)
{
return dramc_init(&dram_para);
}

View File

@ -0,0 +1,4 @@
CONFIG_SPL=y
CONFIG_SYS_EXTRA_OPTIONS="A10_OLINUXINO_L,SPL,AXP209_POWER,SUNXI_EMAC,AHCI,SATAPWR=SUNXI_GPC(3),USB_EHCI"
+S:CONFIG_ARM=y
+S:CONFIG_TARGET_SUN4I=y

View File

@ -0,0 +1,4 @@
CONFIG_SPL=y
CONFIG_SYS_EXTRA_OPTIONS="A10S_OLINUXINO_M,SPL,AXP152_POWER,SUNXI_EMAC,USB_EHCI,SUNXI_USB_VBUS0_GPIO=SUNXI_GPB(10)"
+S:CONFIG_ARM=y
+S:CONFIG_TARGET_SUN5I=y

View File

@ -1,4 +1,4 @@
CONFIG_SPL=y
CONFIG_SYS_EXTRA_OPTIONS="A13_OLINUXINOM,SPL,CONS_INDEX=2"
CONFIG_SYS_EXTRA_OPTIONS="A13_OLINUXINOM,SPL,CONS_INDEX=2,USB_EHCI,SUNXI_USB_VBUS0_GPIO=SUNXI_GPG(11)"
+S:CONFIG_ARM=y
+S:CONFIG_TARGET_SUN5I=y

View File

@ -0,0 +1,4 @@
CONFIG_SPL=y
CONFIG_SYS_EXTRA_OPTIONS="A13_OLINUXINO,SPL,CONS_INDEX=2,AXP209_POWER,USB_EHCI,SUNXI_USB_VBUS0_GPIO=SUNXI_GPG(11)"
+S:CONFIG_ARM=y
+S:CONFIG_TARGET_SUN5I=y

View File

@ -0,0 +1,4 @@
CONFIG_SPL=y
CONFIG_SYS_EXTRA_OPTIONS="A20_OLINUXINO_M,SPL,AXP209_POWER,SUNXI_GMAC,AHCI,SATAPWR=SUNXI_GPB(8),USB_EHCI"
+S:CONFIG_ARM=y
+S:CONFIG_TARGET_SUN7I=y

View File

@ -0,0 +1,4 @@
CONFIG_SPL=y
CONFIG_SYS_EXTRA_OPTIONS="AUXTEK_T004,SPL,AXP152_POWER,USB_EHCI,SUNXI_USB_VBUS0_GPIO=SUNXI_GPG(13)"
+S:CONFIG_ARM=y
+S:CONFIG_TARGET_SUN5I=y

View File

@ -0,0 +1,4 @@
CONFIG_SPL=y
CONFIG_SYS_EXTRA_OPTIONS="BANANAPI,SPL,AXP209_POWER,SUNXI_GMAC,RGMII,MACPWR=SUNXI_GPH(23),AHCI,USB_EHCI"
+S:CONFIG_ARM=y
+S:CONFIG_TARGET_SUN7I=y

View File

@ -1,4 +1,4 @@
CONFIG_SPL=y
CONFIG_SYS_EXTRA_OPTIONS="CUBIEBOARD2,SPL_FEL,SUNXI_GMAC"
CONFIG_SYS_EXTRA_OPTIONS="CUBIEBOARD2,SPL_FEL,AXP209_POWER,SUNXI_GMAC,AHCI,SATAPWR=SUNXI_GPB(8),USB_EHCI"
+S:CONFIG_ARM=y
+S:CONFIG_TARGET_SUN7I=y

View File

@ -1,4 +1,4 @@
CONFIG_SPL=y
CONFIG_SYS_EXTRA_OPTIONS="CUBIEBOARD2,SPL,SUNXI_GMAC"
CONFIG_SYS_EXTRA_OPTIONS="CUBIEBOARD2,SPL,AXP209_POWER,SUNXI_GMAC,AHCI,SATAPWR=SUNXI_GPB(8),USB_EHCI"
+S:CONFIG_ARM=y
+S:CONFIG_TARGET_SUN7I=y

View File

@ -1,4 +1,4 @@
CONFIG_SPL=y
CONFIG_SYS_EXTRA_OPTIONS="CUBIEBOARD,SPL,AXP209_POWER,SUNXI_EMAC"
CONFIG_SYS_EXTRA_OPTIONS="CUBIEBOARD,SPL,AXP209_POWER,SUNXI_EMAC,AHCI,SATAPWR=SUNXI_GPB(8),USB_EHCI"
+S:CONFIG_ARM=y
+S:CONFIG_TARGET_SUN4I=y

View File

@ -1,4 +1,4 @@
CONFIG_SPL=y
CONFIG_SYS_EXTRA_OPTIONS="CUBIETRUCK,SPL_FEL,AXP209_POWER,SUNXI_GMAC,RGMII"
CONFIG_SYS_EXTRA_OPTIONS="CUBIETRUCK,SPL_FEL,AXP209_POWER,SUNXI_GMAC,RGMII,AHCI,SATAPWR=SUNXI_GPH(12),USB_EHCI"
+S:CONFIG_ARM=y
+S:CONFIG_TARGET_SUN7I=y

View File

@ -1,4 +1,4 @@
CONFIG_SPL=y
CONFIG_SYS_EXTRA_OPTIONS="CUBIETRUCK,SPL,AXP209_POWER,SUNXI_GMAC,RGMII"
CONFIG_SYS_EXTRA_OPTIONS="CUBIETRUCK,SPL,AXP209_POWER,SUNXI_GMAC,RGMII,AHCI,SATAPWR=SUNXI_GPH(12),USB_EHCI"
+S:CONFIG_ARM=y
+S:CONFIG_TARGET_SUN7I=y

View File

@ -0,0 +1,4 @@
CONFIG_SPL=y
CONFIG_SYS_EXTRA_OPTIONS="PCDUINO3,SPL,AXP209_POWER,SUNXI_GMAC,AHCI,SATAPWR=SUNXI_GPH(2),USB_EHCI"
+S:CONFIG_ARM=y
+S:CONFIG_TARGET_SUN7I=y

View File

@ -0,0 +1,4 @@
CONFIG_SPL=y
CONFIG_SYS_EXTRA_OPTIONS="MELE_A1000G,SPL,AXP209_POWER,SUNXI_EMAC,MACPWR=SUNXI_GPH(15),AHCI,USB_EHCI"
+S:CONFIG_ARM=y
+S:CONFIG_TARGET_SUN4I=y

View File

@ -0,0 +1,4 @@
CONFIG_SPL=y
CONFIG_SYS_EXTRA_OPTIONS="MELE_A1000,SPL,AXP209_POWER,SUNXI_EMAC,MACPWR=SUNXI_GPH(15),AHCI,USB_EHCI"
+S:CONFIG_ARM=y
+S:CONFIG_TARGET_SUN4I=y

View File

@ -0,0 +1,4 @@
CONFIG_SPL=y
CONFIG_SYS_EXTRA_OPTIONS="MINI_X_1GB,SPL,AXP209_POWER,USB_EHCI"
+S:CONFIG_ARM=y
+S:CONFIG_TARGET_SUN4I=y

View File

@ -0,0 +1,4 @@
CONFIG_SPL=y
CONFIG_SYS_EXTRA_OPTIONS="MINI_X,SPL,AXP209_POWER,USB_EHCI"
+S:CONFIG_ARM=y
+S:CONFIG_TARGET_SUN4I=y

View File

@ -0,0 +1,4 @@
CONFIG_SPL=y
CONFIG_SYS_EXTRA_OPTIONS="BA10_TV_BOX,SPL,AXP209_POWER,SUNXI_EMAC,USB_EHCI,SUNXI_USB_VBUS1_GPIO=SUNXI_GPH(12)"
+S:CONFIG_ARM=y
+S:CONFIG_TARGET_SUN4I=y

View File

@ -0,0 +1,4 @@
CONFIG_SPL=y
CONFIG_SYS_EXTRA_OPTIONS="I12_TVBOX,SPL,AXP209_POWER,SUNXI_GMAC,MACPWR=SUNXI_GPH(21),USB_EHCI"
+S:CONFIG_ARM=y
+S:CONFIG_TARGET_SUN7I=y

View File

@ -0,0 +1,4 @@
CONFIG_SPL=y
CONFIG_SYS_EXTRA_OPTIONS="QT840A,SPL,AXP209_POWER,SUNXI_GMAC,MACPWR=SUNXI_GPH(21),USB_EHCI"
+S:CONFIG_ARM=y
+S:CONFIG_TARGET_SUN7I=y

View File

@ -1,4 +1,4 @@
CONFIG_SPL=y
CONFIG_SYS_EXTRA_OPTIONS="R7DONGLE,SPL,AXP152_POWER"
CONFIG_SYS_EXTRA_OPTIONS="R7DONGLE,SPL,AXP152_POWER,USB_EHCI,SUNXI_USB_VBUS0_GPIO=SUNXI_GPG(13)"
+S:CONFIG_ARM=y
+S:CONFIG_TARGET_SUN5I=y

View File

@ -129,6 +129,14 @@ int __weak ahci_link_up(struct ahci_probe_ent *probe_ent, u8 port)
return 1;
}
#ifdef CONFIG_SUNXI_AHCI
/* The sunxi AHCI controller requires this undocumented setup */
static void sunxi_dma_init(volatile u8 *port_mmio)
{
clrsetbits_le32(port_mmio + PORT_P0DMACR, 0x0000ff00, 0x00004400);
}
#endif
static int ahci_host_init(struct ahci_probe_ent *probe_ent)
{
#ifndef CONFIG_SCSI_AHCI_PLAT
@ -213,6 +221,10 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent)
msleep(500);
}
#ifdef CONFIG_SUNXI_AHCI
sunxi_dma_init(port_mmio);
#endif
/* Add the spinup command to whatever mode bits may
* already be on in the command register.
*/
@ -545,6 +557,10 @@ static int ahci_port_start(u8 port)
writel_with_flush(pp->rx_fis, port_mmio + PORT_FIS_ADDR);
#ifdef CONFIG_SUNXI_AHCI
sunxi_dma_init(port_mmio);
#endif
writel_with_flush(PORT_CMD_ICC_ACTIVE | PORT_CMD_FIS_RX |
PORT_CMD_POWER_ON | PORT_CMD_SPIN_UP |
PORT_CMD_START, port_mmio + PORT_CMD);

View File

@ -35,6 +35,7 @@ obj-$(CONFIG_USB_EHCI_PPC4XX) += ehci-ppc4xx.o
obj-$(CONFIG_USB_EHCI_MARVELL) += ehci-marvell.o
obj-$(CONFIG_USB_EHCI_PCI) += ehci-pci.o
obj-$(CONFIG_USB_EHCI_SPEAR) += ehci-spear.o
obj-$(CONFIG_USB_EHCI_SUNXI) += ehci-sunxi.o
obj-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o
obj-$(CONFIG_USB_EHCI_VCT) += ehci-vct.o
obj-$(CONFIG_USB_EHCI_RMOBILE) += ehci-rmobile.o

View File

@ -0,0 +1,201 @@
/*
* Copyright (C) 2014 Roman Byshko
*
* Roman Byshko <rbyshko@gmail.com>
*
* Based on code from
* Allwinner Technology Co., Ltd. <www.allwinnertech.com>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <asm/arch/clock.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <common.h>
#include "ehci.h"
#define SUNXI_USB1_IO_BASE 0x01c14000
#define SUNXI_USB2_IO_BASE 0x01c1c000
#define SUNXI_USB_PMU_IRQ_ENABLE 0x800
#define SUNXI_USB_CSR 0x01c13404
#define SUNXI_USB_PASSBY_EN 1
#define SUNXI_EHCI_AHB_ICHR8_EN (1 << 10)
#define SUNXI_EHCI_AHB_INCR4_BURST_EN (1 << 9)
#define SUNXI_EHCI_AHB_INCRX_ALIGN_EN (1 << 8)
#define SUNXI_EHCI_ULPI_BYPASS_EN (1 << 0)
static struct sunxi_ehci_hcd {
struct usb_hcd *hcd;
int usb_rst_mask;
int ahb_clk_mask;
int gpio_vbus;
void *csr;
int irq;
int id;
} sunxi_echi_hcd[] = {
{
.usb_rst_mask = CCM_USB_CTRL_PHY1_RST,
.ahb_clk_mask = 1 << AHB_GATE_OFFSET_USB_EHCI0,
.gpio_vbus = CONFIG_SUNXI_USB_VBUS0_GPIO,
.csr = (void *)SUNXI_USB_CSR,
.irq = 39,
.id = 1,
},
#if (CONFIG_USB_MAX_CONTROLLER_COUNT > 1)
{
.usb_rst_mask = CCM_USB_CTRL_PHY2_RST,
.ahb_clk_mask = 1 << AHB_GATE_OFFSET_USB_EHCI1,
.gpio_vbus = CONFIG_SUNXI_USB_VBUS1_GPIO,
.csr = (void *)SUNXI_USB_CSR,
.irq = 40,
.id = 2,
}
#endif
};
static int enabled_hcd_count;
static void *get_io_base(int hcd_id)
{
if (hcd_id == 1)
return (void *)SUNXI_USB1_IO_BASE;
else if (hcd_id == 2)
return (void *)SUNXI_USB2_IO_BASE;
else
return NULL;
}
static void usb_phy_write(struct sunxi_ehci_hcd *sunxi_ehci, int addr,
int data, int len)
{
int j = 0, usbc_bit = 0;
void *dest = sunxi_ehci->csr;
usbc_bit = 1 << (sunxi_ehci->id * 2);
for (j = 0; j < len; j++) {
/* set the bit address to be written */
clrbits_le32(dest, 0xff << 8);
setbits_le32(dest, (addr + j) << 8);
clrbits_le32(dest, usbc_bit);
/* set data bit */
if (data & 0x1)
setbits_le32(dest, 1 << 7);
else
clrbits_le32(dest, 1 << 7);
setbits_le32(dest, usbc_bit);
clrbits_le32(dest, usbc_bit);
data >>= 1;
}
}
static void sunxi_usb_phy_init(struct sunxi_ehci_hcd *sunxi_ehci)
{
/* The following comments are machine
* translated from Chinese, you have been warned!
*/
/* adjust PHY's magnitude and rate */
usb_phy_write(sunxi_ehci, 0x20, 0x14, 5);
/* threshold adjustment disconnect */
#ifdef CONFIG_SUN4I
usb_phy_write(sunxi_ehci, 0x2a, 3, 2);
#else
usb_phy_write(sunxi_ehci, 0x2a, 2, 2);
#endif
return;
}
static void sunxi_usb_passby(struct sunxi_ehci_hcd *sunxi_ehci, int enable)
{
unsigned long bits = 0;
void *addr = get_io_base(sunxi_ehci->id) + SUNXI_USB_PMU_IRQ_ENABLE;
bits = SUNXI_EHCI_AHB_ICHR8_EN |
SUNXI_EHCI_AHB_INCR4_BURST_EN |
SUNXI_EHCI_AHB_INCRX_ALIGN_EN |
SUNXI_EHCI_ULPI_BYPASS_EN;
if (enable)
setbits_le32(addr, bits);
else
clrbits_le32(addr, bits);
return;
}
static void sunxi_ehci_enable(struct sunxi_ehci_hcd *sunxi_ehci)
{
struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
setbits_le32(&ccm->usb_clk_cfg, sunxi_ehci->usb_rst_mask);
setbits_le32(&ccm->ahb_gate0, sunxi_ehci->ahb_clk_mask);
sunxi_usb_phy_init(sunxi_ehci);
sunxi_usb_passby(sunxi_ehci, SUNXI_USB_PASSBY_EN);
gpio_direction_output(sunxi_ehci->gpio_vbus, 1);
}
static void sunxi_ehci_disable(struct sunxi_ehci_hcd *sunxi_ehci)
{
struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
gpio_direction_output(sunxi_ehci->gpio_vbus, 0);
sunxi_usb_passby(sunxi_ehci, !SUNXI_USB_PASSBY_EN);
clrbits_le32(&ccm->ahb_gate0, sunxi_ehci->ahb_clk_mask);
clrbits_le32(&ccm->usb_clk_cfg, sunxi_ehci->usb_rst_mask);
}
int ehci_hcd_init(int index, enum usb_init_type init, struct ehci_hccr **hccr,
struct ehci_hcor **hcor)
{
struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
struct sunxi_ehci_hcd *sunxi_ehci = &sunxi_echi_hcd[index];
/* enable common PHY only once */
if (index == 0)
setbits_le32(&ccm->usb_clk_cfg, CCM_USB_CTRL_PHYGATE);
sunxi_ehci_enable(sunxi_ehci);
*hccr = get_io_base(sunxi_ehci->id);
*hcor = (struct ehci_hcor *)((uint32_t) *hccr
+ HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
debug("sunxi-ehci: init hccr %x and hcor %x hc_length %d\n",
(uint32_t)*hccr, (uint32_t)*hcor,
(uint32_t)HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase)));
enabled_hcd_count++;
return 0;
}
int ehci_hcd_stop(int index)
{
struct sunxi_ccm_reg *ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
struct sunxi_ehci_hcd *sunxi_ehci = &sunxi_echi_hcd[index];
sunxi_ehci_disable(sunxi_ehci);
/* disable common PHY only once, for the last enabled hcd */
if (enabled_hcd_count == 1)
clrbits_le32(&ccm->usb_clk_cfg, CCM_USB_CTRL_PHYGATE);
enabled_hcd_count--;
return 0;
}

View File

@ -58,6 +58,10 @@
#define PORT_SCR_ERR 0x30 /* SATA phy register: SError */
#define PORT_SCR_ACT 0x34 /* SATA phy register: SActive */
#ifdef CONFIG_SUNXI_AHCI
#define PORT_P0DMACR 0x70 /* SUNXI specific "DMA register" */
#endif
/* PORT_IRQ_{STAT,MASK} bits */
#define PORT_IRQ_COLD_PRES (1 << 31) /* cold presence detect */
#define PORT_IRQ_TF_ERR (1 << 30) /* task file error */

View File

@ -16,6 +16,18 @@
#define CONFIG_SYS_PROMPT "sun4i# "
#ifdef CONFIG_USB_EHCI
#define CONFIG_USB_EHCI_SUNXI
#define CONFIG_USB_MAX_CONTROLLER_COUNT 2
#ifndef CONFIG_SUNXI_USB_VBUS0_GPIO
#define CONFIG_SUNXI_USB_VBUS0_GPIO SUNXI_GPH(6)
#endif
#ifndef CONFIG_SUNXI_USB_VBUS1_GPIO
#define CONFIG_SUNXI_USB_VBUS1_GPIO SUNXI_GPH(3)
#endif
#endif
/*
* Include common sunxi configuration where most the settings are
*/

View File

@ -16,6 +16,11 @@
#define CONFIG_SYS_PROMPT "sun5i# "
#ifdef CONFIG_USB_EHCI
#define CONFIG_USB_EHCI_SUNXI
#define CONFIG_USB_MAX_CONTROLLER_COUNT 1
#endif
/*
* Include common sunxi configuration where most the settings are
*/

View File

@ -17,6 +17,25 @@
#define CONFIG_SYS_PROMPT "sun7i# "
#ifdef CONFIG_USB_EHCI
#define CONFIG_USB_EHCI_SUNXI
#define CONFIG_USB_MAX_CONTROLLER_COUNT 2
#ifndef CONFIG_SUNXI_USB_VBUS0_GPIO
#define CONFIG_SUNXI_USB_VBUS0_GPIO SUNXI_GPH(6)
#endif
#ifndef CONFIG_SUNXI_USB_VBUS1_GPIO
#define CONFIG_SUNXI_USB_VBUS1_GPIO SUNXI_GPH(3)
#endif
#endif
#define CONFIG_ARMV7_VIRT 1
#define CONFIG_ARMV7_NONSEC 1
#define CONFIG_ARMV7_PSCI 1
#define CONFIG_ARMV7_PSCI_NR_CPUS 2
#define CONFIG_ARMV7_SECURE_BASE SUNXI_SRAM_B_BASE
#define CONFIG_SYS_CLK_FREQ 24000000
/*
* Include common sunxi configuration where most the settings are
*/

View File

@ -57,6 +57,18 @@
#define PHYS_SDRAM_0 CONFIG_SYS_SDRAM_BASE
#define PHYS_SDRAM_0_SIZE 0x80000000 /* 2 GiB */
#ifdef CONFIG_AHCI
#define CONFIG_LIBATA
#define CONFIG_SCSI_AHCI
#define CONFIG_SCSI_AHCI_PLAT
#define CONFIG_SUNXI_AHCI
#define CONFIG_SYS_SCSI_MAX_SCSI_ID 1
#define CONFIG_SYS_SCSI_MAX_LUN 1
#define CONFIG_SYS_SCSI_MAX_DEVICE (CONFIG_SYS_SCSI_MAX_SCSI_ID * \
CONFIG_SYS_SCSI_MAX_LUN)
#define CONFIG_CMD_SCSI
#endif
#define CONFIG_CMD_MEMORY
#define CONFIG_CMD_SETEXPR
@ -203,6 +215,12 @@
#define CONFIG_BOOTP_SEND_HOSTNAME
#endif
#ifdef CONFIG_USB_EHCI
#define CONFIG_CMD_USB
#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 1
#define CONFIG_USB_STORAGE
#endif
#if !defined CONFIG_ENV_IS_IN_MMC && \
!defined CONFIG_ENV_IS_IN_NAND && \
!defined CONFIG_ENV_IS_IN_FAT && \