Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions arch/arm/dts/sun8i-v831-openipc.dts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@

&spi0 {
status = "okay";
/* The controller's own limit: without it the driver clamps to 1 MHz */
spi-max-frequency = <24000000>;

flash@0 {
#address-cells = <1>;
Expand Down
3 changes: 0 additions & 3 deletions arch/arm/include/asm/arch-sunxi/clock_sun50i_h6.h
Original file line number Diff line number Diff line change
Expand Up @@ -278,9 +278,6 @@ struct sunxi_ccm_reg {
/* apb1 bit field */
#define CCM_APB1_DEFAULT 0x03000102
#elif CONFIG_MACH_SUN8I_V831
/* PLL_PERI0(2X) 1200 MHz, as boot0 sets it */
#define CCM_PLL6_DEFAULT 0xa0003100

/* psi_ahb1_ahb2 bit field: PLL_PERI0(1X) / 3 = 200 MHz */
#define CCM_PSI_AHB1_AHB2_DEFAULT 0x03000002

Expand Down
107 changes: 93 additions & 14 deletions arch/arm/mach-sunxi/clock_sun50i_h6.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,80 @@
#include <asm/arch/cpu.h>
#include <asm/arch/clock.h>
#include <asm/arch/prcm.h>
#include <asm/arch/sys_proto.h>

#ifdef CONFIG_SPL_BUILD
#ifdef CONFIG_MACH_SUN8I_V831
/* boot0's wait_pll_stable(): retry the enable until the PLL locks */
static void v831_pll_lock(u32 *reg)
{
unsigned int i;

while (1) {
setbits_le32(reg, BIT(31) | BIT(29));
for (i = 0; i < 0x7ff; i++)
if (readl(reg) & BIT(28))
return;
clrbits_le32(reg, BIT(31) | BIT(29));
}
}

/*
* The order of boot0's sunxi_board_pll_init(). PLL_PERI0 is
* read-modify-written: its reset value holds bits a plain write would
* clear, and the buses stop when they move onto it without them. The
* timer is not running yet, hence sdelay().
*/
void clock_init_safe(void)
{
struct sunxi_ccm_reg *const ccm =
(struct sunxi_ccm_reg *)SUNXI_CCM_BASE;
struct sunxi_prcm_reg *const prcm =
(struct sunxi_prcm_reg *)SUNXI_PRCM_BASE;

/* the analog (ADDA) supply and the calibration circuit */
setbits_le32(&prcm->sys_pwroff_gating, 0x10);
setbits_le32(&prcm->res_cal_ctrl, 1);
/* PLL_CPUX tuning step */
clrsetbits_le32(SUNXI_CCM_BASE + 0x400, 0x7 << 28, 0x1 << 28);

/* the CPU's dividers first, while still on OSC24M */
writel(0x302, &ccm->cpu_axi_cfg);
sdelay(0x100);
clock_set_pll1(408000000);

/* PLL_PERI0: lock at N=0x4f, then settle at N=0x31, 1200 MHz (2X) */
clrbits_le32(&ccm->psi_ahb1_ahb2_cfg, 0x3 << 24);
clrbits_le32(&ccm->pll6_cfg, BIT(31));
clrsetbits_le32(&ccm->pll6_cfg, (0xff << 8) | 0x3, 0x4f << 8);
sdelay(0x400);
setbits_le32(&ccm->pll6_cfg, BIT(27)); /* output enable */
v831_pll_lock(&ccm->pll6_cfg);
sdelay(0x400);
clrbits_le32(&ccm->pll6_cfg, BIT(29));
clrsetbits_le32(&ccm->pll6_cfg, (0xff << 8) | 0x3, 0x31 << 8);
setbits_le32(&ccm->pll6_cfg, BIT(29));
sdelay(0x400);
while (!(readl(&ccm->pll6_cfg) & CCM_PLL6_LOCK))
;
sdelay(0x800);

/* the buses: the factors, then the source */
writel(CCM_PSI_AHB1_AHB2_DEFAULT & ~(0x3 << 24),
&ccm->psi_ahb1_ahb2_cfg);
setbits_le32(&ccm->psi_ahb1_ahb2_cfg, 0x3 << 24);
sdelay(0x100);
writel(CCM_AHB3_DEFAULT & ~(0x3 << 24), &ccm->ahb3_cfg);
setbits_le32(&ccm->ahb3_cfg, 0x3 << 24);
writel(CCM_APB1_DEFAULT & ~(0x3 << 24), &ccm->apb1_cfg);
setbits_le32(&ccm->apb1_cfg, 0x3 << 24);
sdelay(0x100);

/* the MBUS runs at a quarter of the DRAM clock: no mux */
writel(MBUS_RESET, &ccm->mbus_cfg);
sdelay(0x100);
}
#else
void clock_init_safe(void)
{
struct sunxi_ccm_reg *const ccm =
Expand All @@ -18,13 +90,6 @@ void clock_init_safe(void)
setbits_le32(&prcm->res_cal_ctrl, 2);
}

if (IS_ENABLED(CONFIG_MACH_SUN8I_V831)) {
/* boot0: the analog (ADDA) supply and the calibration circuit */
setbits_le32(&prcm->sys_pwroff_gating, 0x10);
/* boot0: PLL_CPUX tuning step */
clrsetbits_le32(SUNXI_CCM_BASE + 0x400, 0x7 << 28, 0x1 << 28);
}

if (!IS_ENABLED(CONFIG_SUNXI_GEN_NCAT2)) {
clrbits_le32(&prcm->res_cal_ctrl, 1);
setbits_le32(&prcm->res_cal_ctrl, 1);
Expand All @@ -44,7 +109,6 @@ void clock_init_safe(void)
;

clrsetbits_le32(&ccm->cpu_axi_cfg, CCM_CPU_AXI_APB_MASK | CCM_CPU_AXI_AXI_MASK,
IS_ENABLED(CONFIG_MACH_SUN8I_V831) ? 0x302 :
CCM_CPU_AXI_DEFAULT_FACTORS);

writel(CCM_PSI_AHB1_AHB2_DEFAULT, &ccm->psi_ahb1_ahb2_cfg);
Expand All @@ -53,18 +117,13 @@ void clock_init_safe(void)
#endif
writel(CCM_APB1_DEFAULT, &ccm->apb1_cfg);

if (IS_ENABLED(CONFIG_MACH_SUN8I_V831)) {
/* the MBUS runs at a quarter of the DRAM clock: no mux */
writel(MBUS_RESET, &ccm->mbus_cfg);
return;
}

/*
* The mux and factor are set, but the clock will be enabled in
* DRAM initialization code.
*/
writel(MBUS_CLK_SRC_PLL6X2 | MBUS_CLK_M(3), &ccm->mbus_cfg);
}
#endif /* CONFIG_MACH_SUN8I_V831 */
#endif

void clock_init_uart(void)
Expand Down Expand Up @@ -103,6 +162,26 @@ void clock_set_pll1(unsigned int clk)
val |= CCM_CPU_AXI_MUX_OSC24M;
writel(val, &ccm->cpu_axi_cfg);

if (IS_ENABLED(CONFIG_MACH_SUN8I_V831)) {
/* boot0's order: factors, lock enable, PLL enable, wait */
sdelay(0x100);
writel(CCM_PLL1_OUT_EN | CCM_PLL1_CLOCK_TIME_2 |
CCM_PLL1_CTRL_N(clk / 24000000), &ccm->pll1_cfg);
setbits_le32(&ccm->pll1_cfg, CCM_PLL1_LOCK_EN);
setbits_le32(&ccm->pll1_cfg, CCM_PLL1_CTRL_EN);
while (!(readl(&ccm->pll1_cfg) & CCM_PLL1_LOCK))
;
sdelay(0x100);
clrbits_le32(&ccm->pll1_cfg, CCM_PLL1_LOCK_EN);

val = readl(&ccm->cpu_axi_cfg);
val &= ~CCM_CPU_AXI_MUX_MASK;
val |= CCM_CPU_AXI_MUX_PLL_CPUX;
writel(val, &ccm->cpu_axi_cfg);
sdelay(0x100);
return;
}

/* clk = 24*n/p, p is ignored if clock is >288MHz */
writel(CCM_PLL1_CTRL_EN | CCM_PLL1_LOCK_EN | CCM_PLL1_CLOCK_TIME_2 |
#ifdef CONFIG_MACH_SUN50I_H616
Expand Down
16 changes: 16 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,22 @@ build_v83x() {
return 1
fi

# V831/V833 on NOR: an eGON image as long as the vendor's boot0
# (32 KiB, the length booted on silicon); mkimage pads only to 8 KiB
case "${soc}-${kind}" in
v831-nor|v833-nor)
splbin=${builddir}/spl/u-boot-spl.bin
{ cat "${splbin}"
head -c $((UBOOT_OFFSET - 0x60 - $(stat -c %s "${splbin}"))) \
/dev/zero | tr '\0' '\377'; } > "${splbin}.pad" || return 1
"${builddir}/tools/mkimage" -A arm -T sunxi_egon \
-a "$(sed -n 's/^CONFIG_SPL_TEXT_BASE=//p' "${builddir}/.config")" \
-n "$(sed -n 's/^CONFIG_DEFAULT_DEVICE_TREE="\(.*\)"$/\1/p' \
"${builddir}/.config")" \
-d "${splbin}.pad" "${spl}" >/dev/null || return 1
;;
esac

text=$(sed -n 's/^CONFIG_SYS_TEXT_BASE=//p' "${builddir}/.config")
xz --format=lzma -9 -c "${builddir}/u-boot.bin" \
> "${builddir}/u-boot.bin.lzma" || return 1
Expand Down
8 changes: 6 additions & 2 deletions openipc/v831_config
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ CONFIG_PRODUCT_SOC="v831"
CONFIG_MACH_SUN8I_V831=y
CONFIG_DEFAULT_DEVICE_TREE="sun8i-v831-openipc"
CONFIG_IDENT_STRING=" Allwinner V83x"
# SPL stack: the end of SRAM A2, as on the H6
CONFIG_SPL_STACK=0x118000
# SPL stack: top of SRAM C, the region vendor boot0 stacks in (0x58ffc)
CONFIG_SPL_STACK=0x58000
# SPI NOR at 12 MHz (24 MHz HOSC / 2), not the 1 MHz default: the
# firmware scan reads up to 3.7 MiB of flash on every boot
CONFIG_SF_DEFAULT_SPEED=12000000
CONFIG_ENV_SPI_MAX_HZ=12000000
# Kernel hand-off: non-secure, PSCI 1.0 from U-Boot's own monitor, as
# the vendor kernels expect from OP-TEE
CONFIG_ARMV7_NONSEC=y
Expand Down
8 changes: 6 additions & 2 deletions openipc/v833_config
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@ CONFIG_PRODUCT_SOC="v833"
CONFIG_MACH_SUN8I_V831=y
CONFIG_DEFAULT_DEVICE_TREE="sun8i-v831-openipc"
CONFIG_IDENT_STRING=" Allwinner V83x"
# SPL stack: the end of SRAM A2, as on the H6
CONFIG_SPL_STACK=0x118000
# SPL stack: top of SRAM C, the region vendor boot0 stacks in (0x58ffc)
CONFIG_SPL_STACK=0x58000
# SPI NOR at 12 MHz (24 MHz HOSC / 2), not the 1 MHz default: the
# firmware scan reads up to 3.7 MiB of flash on every boot
CONFIG_SF_DEFAULT_SPEED=12000000
CONFIG_ENV_SPI_MAX_HZ=12000000
# Kernel hand-off: non-secure, PSCI 1.0 from U-Boot's own monitor, as
# the vendor kernels expect from OP-TEE
CONFIG_ARMV7_NONSEC=y
Expand Down
Loading