Merge branch 'zynq' of git://www.denx.de/git/u-boot-microblaze
This commit is contained in:
commit
ace97d2617
@ -649,7 +649,7 @@ config TARGET_COLIBRI_VF
|
||||
bool "Support Colibri VF50/61"
|
||||
select CPU_V7
|
||||
|
||||
config ZYNQ
|
||||
config ARCH_ZYNQ
|
||||
bool "Xilinx Zynq Platform"
|
||||
select CPU_V7
|
||||
select SUPPORT_SPL
|
||||
@ -837,7 +837,7 @@ source "arch/arm/mach-uniphier/Kconfig"
|
||||
|
||||
source "arch/arm/mach-versatile/Kconfig"
|
||||
|
||||
source "arch/arm/cpu/armv7/zynq/Kconfig"
|
||||
source "arch/arm/mach-zynq/Kconfig"
|
||||
|
||||
source "arch/arm/cpu/armv7/Kconfig"
|
||||
|
||||
|
@ -55,6 +55,7 @@ machine-$(CONFIG_ORION5X) += orion5x
|
||||
machine-$(CONFIG_TEGRA) += tegra
|
||||
machine-$(CONFIG_ARCH_UNIPHIER) += uniphier
|
||||
machine-$(CONFIG_ARCH_VERSATILE) += versatile
|
||||
machine-$(CONFIG_ARCH_ZYNQ) += zynq
|
||||
|
||||
machdirs := $(patsubst %,arch/arm/mach-%/,$(machine-y))
|
||||
|
||||
|
@ -56,4 +56,3 @@ obj-$(if $(filter stv0991,$(SOC)),y) += stv0991/
|
||||
obj-$(CONFIG_ARCH_SUNXI) += sunxi/
|
||||
obj-$(CONFIG_U8500) += u8500/
|
||||
obj-$(CONFIG_VF610) += vf610/
|
||||
obj-$(CONFIG_ZYNQ) += zynq/
|
||||
|
@ -1,7 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2013 - 2015 Xilinx, Inc. All rights reserved.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
# Allow NEON instructions (needed for lowlevel_init.S with GNU toolchain)
|
||||
PLATFORM_RELFLAGS += -mfpu=neon
|
@ -7,3 +7,4 @@
|
||||
|
||||
obj-y += clk.o
|
||||
obj-y += cpu.o
|
||||
obj-$(CONFIG_MP) += mp.o
|
||||
|
@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/clk.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
|
||||
@ -16,6 +17,8 @@ unsigned long get_uart_clk(int dev_id)
|
||||
u32 ver = zynqmp_get_silicon_version();
|
||||
|
||||
switch (ver) {
|
||||
case ZYNQMP_CSU_VERSION_VELOCE:
|
||||
return 48000;
|
||||
case ZYNQMP_CSU_VERSION_EP108:
|
||||
return 25000000;
|
||||
}
|
||||
|
@ -20,9 +20,175 @@ unsigned int zynqmp_get_silicon_version(void)
|
||||
gd->cpu_clk = get_tbclk();
|
||||
|
||||
switch (gd->cpu_clk) {
|
||||
case 0 ... 1000000:
|
||||
return ZYNQMP_CSU_VERSION_VELOCE;
|
||||
case 50000000:
|
||||
return ZYNQMP_CSU_VERSION_QEMU;
|
||||
}
|
||||
|
||||
return ZYNQMP_CSU_VERSION_EP108;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_SYS_DCACHE_OFF
|
||||
#include <asm/armv8/mmu.h>
|
||||
|
||||
#define SECTION_SHIFT_L1 30UL
|
||||
#define SECTION_SHIFT_L2 21UL
|
||||
#define BLOCK_SIZE_L0 0x8000000000UL
|
||||
#define BLOCK_SIZE_L1 (1 << SECTION_SHIFT_L1)
|
||||
#define BLOCK_SIZE_L2 (1 << SECTION_SHIFT_L2)
|
||||
|
||||
#define TCR_TG1_4K (1 << 31)
|
||||
#define TCR_EPD1_DISABLE (1 << 23)
|
||||
#define ZYNQMO_VA_BITS 40
|
||||
#define ZYNQMP_TCR TCR_TG1_4K | \
|
||||
TCR_EPD1_DISABLE | \
|
||||
TCR_SHARED_OUTER | \
|
||||
TCR_SHARED_INNER | \
|
||||
TCR_IRGN_WBWA | \
|
||||
TCR_ORGN_WBWA | \
|
||||
TCR_T0SZ(ZYNQMO_VA_BITS)
|
||||
|
||||
#define MEMORY_ATTR PMD_SECT_AF | PMD_SECT_INNER_SHARE | \
|
||||
PMD_ATTRINDX(MT_NORMAL) | \
|
||||
PMD_TYPE_SECT
|
||||
#define DEVICE_ATTR PMD_SECT_AF | PMD_SECT_PXN | \
|
||||
PMD_SECT_UXN | PMD_ATTRINDX(MT_DEVICE_NGNRNE) | \
|
||||
PMD_TYPE_SECT
|
||||
|
||||
/* 4K size is required to place 512 entries in each level */
|
||||
#define TLB_TABLE_SIZE 0x1000
|
||||
|
||||
struct attr_tbl {
|
||||
u32 num;
|
||||
u64 attr;
|
||||
};
|
||||
|
||||
static struct attr_tbl attr_tbll1t0[4] = { {16, 0x0},
|
||||
{8, DEVICE_ATTR},
|
||||
{32, MEMORY_ATTR},
|
||||
{456, DEVICE_ATTR}
|
||||
};
|
||||
static struct attr_tbl attr_tbll2t3[4] = { {0x180, DEVICE_ATTR},
|
||||
{0x40, 0x0},
|
||||
{0x3F, DEVICE_ATTR},
|
||||
{0x1, MEMORY_ATTR}
|
||||
};
|
||||
|
||||
/*
|
||||
* This mmu table looks as below
|
||||
* Level 0 table contains two entries to 512GB sizes. One is Level1 Table 0
|
||||
* and other Level1 Table1.
|
||||
* Level1 Table0 contains entries for each 1GB from 0 to 511GB.
|
||||
* Level1 Table1 contains entries for each 1GB from 512GB to 1TB.
|
||||
* Level2 Table0, Level2 Table1, Level2 Table2 and Level2 Table3 contains
|
||||
* entries for each 2MB starting from 0GB, 1GB, 2GB and 3GB respectively.
|
||||
*/
|
||||
static void zynqmp_mmu_setup(void)
|
||||
{
|
||||
int el;
|
||||
u32 index_attr;
|
||||
u64 i, section_l1t0, section_l1t1;
|
||||
u64 section_l2t0, section_l2t1, section_l2t2, section_l2t3;
|
||||
u64 *level0_table = (u64 *)gd->arch.tlb_addr;
|
||||
u64 *level1_table_0 = (u64 *)(gd->arch.tlb_addr + TLB_TABLE_SIZE);
|
||||
u64 *level1_table_1 = (u64 *)(gd->arch.tlb_addr + (2 * TLB_TABLE_SIZE));
|
||||
u64 *level2_table_0 = (u64 *)(gd->arch.tlb_addr + (3 * TLB_TABLE_SIZE));
|
||||
u64 *level2_table_1 = (u64 *)(gd->arch.tlb_addr + (4 * TLB_TABLE_SIZE));
|
||||
u64 *level2_table_2 = (u64 *)(gd->arch.tlb_addr + (5 * TLB_TABLE_SIZE));
|
||||
u64 *level2_table_3 = (u64 *)(gd->arch.tlb_addr + (6 * TLB_TABLE_SIZE));
|
||||
|
||||
level0_table[0] =
|
||||
(u64)level1_table_0 | PMD_TYPE_TABLE;
|
||||
level0_table[1] =
|
||||
(u64)level1_table_1 | PMD_TYPE_TABLE;
|
||||
|
||||
/*
|
||||
* set level 1 table 0, covering 0 to 512GB
|
||||
* set level 1 table 1, covering 512GB to 1TB
|
||||
*/
|
||||
section_l1t0 = 0;
|
||||
section_l1t1 = BLOCK_SIZE_L0;
|
||||
|
||||
index_attr = 0;
|
||||
for (i = 0; i < 512; i++) {
|
||||
level1_table_0[i] = section_l1t0;
|
||||
level1_table_0[i] |= attr_tbll1t0[index_attr].attr;
|
||||
attr_tbll1t0[index_attr].num--;
|
||||
if (attr_tbll1t0[index_attr].num == 0)
|
||||
index_attr++;
|
||||
level1_table_1[i] = section_l1t1;
|
||||
level1_table_1[i] |= DEVICE_ATTR;
|
||||
section_l1t0 += BLOCK_SIZE_L1;
|
||||
section_l1t1 += BLOCK_SIZE_L1;
|
||||
}
|
||||
|
||||
level1_table_0[0] =
|
||||
(u64)level2_table_0 | PMD_TYPE_TABLE;
|
||||
level1_table_0[1] =
|
||||
(u64)level2_table_1 | PMD_TYPE_TABLE;
|
||||
level1_table_0[2] =
|
||||
(u64)level2_table_2 | PMD_TYPE_TABLE;
|
||||
level1_table_0[3] =
|
||||
(u64)level2_table_3 | PMD_TYPE_TABLE;
|
||||
|
||||
section_l2t0 = 0;
|
||||
section_l2t1 = section_l2t0 + BLOCK_SIZE_L1; /* 1GB */
|
||||
section_l2t2 = section_l2t1 + BLOCK_SIZE_L1; /* 2GB */
|
||||
section_l2t3 = section_l2t2 + BLOCK_SIZE_L1; /* 3GB */
|
||||
|
||||
index_attr = 0;
|
||||
|
||||
for (i = 0; i < 512; i++) {
|
||||
level2_table_0[i] = section_l2t0 | MEMORY_ATTR;
|
||||
level2_table_1[i] = section_l2t1 | MEMORY_ATTR;
|
||||
level2_table_2[i] = section_l2t2 | DEVICE_ATTR;
|
||||
level2_table_3[i] = section_l2t3 |
|
||||
attr_tbll2t3[index_attr].attr;
|
||||
attr_tbll2t3[index_attr].num--;
|
||||
if (attr_tbll2t3[index_attr].num == 0)
|
||||
index_attr++;
|
||||
section_l2t0 += BLOCK_SIZE_L2;
|
||||
section_l2t1 += BLOCK_SIZE_L2;
|
||||
section_l2t2 += BLOCK_SIZE_L2;
|
||||
section_l2t3 += BLOCK_SIZE_L2;
|
||||
}
|
||||
|
||||
/* flush new MMU table */
|
||||
flush_dcache_range(gd->arch.tlb_addr,
|
||||
gd->arch.tlb_addr + gd->arch.tlb_size);
|
||||
|
||||
/* point TTBR to the new table */
|
||||
el = current_el();
|
||||
set_ttbr_tcr_mair(el, gd->arch.tlb_addr,
|
||||
ZYNQMP_TCR, MEMORY_ATTRIBUTES);
|
||||
|
||||
set_sctlr(get_sctlr() | CR_M);
|
||||
}
|
||||
|
||||
int arch_cpu_init(void)
|
||||
{
|
||||
icache_enable();
|
||||
__asm_invalidate_dcache_all();
|
||||
__asm_invalidate_tlb_all();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is called from lib/board.c.
|
||||
* It recreates MMU table in main memory. MMU and d-cache are enabled earlier.
|
||||
* There is no need to disable d-cache for this operation.
|
||||
*/
|
||||
void enable_caches(void)
|
||||
{
|
||||
/* The data cache is not active unless the mmu is enabled */
|
||||
if (!(get_sctlr() & CR_M)) {
|
||||
invalidate_dcache_all();
|
||||
__asm_invalidate_tlb_all();
|
||||
zynqmp_mmu_setup();
|
||||
}
|
||||
puts("Enabling Caches...\n");
|
||||
|
||||
set_sctlr(get_sctlr() | CR_C);
|
||||
}
|
||||
#endif
|
||||
|
242
arch/arm/cpu/armv8/zynqmp/mp.c
Normal file
242
arch/arm/cpu/armv8/zynqmp/mp.c
Normal file
@ -0,0 +1,242 @@
|
||||
/*
|
||||
* (C) Copyright 2014 - 2015 Xilinx, Inc.
|
||||
* Michal Simek <michal.simek@xilinx.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/hardware.h>
|
||||
#include <asm/arch/sys_proto.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#define LOCK 0
|
||||
#define SPLIT 1
|
||||
|
||||
#define HALT 0
|
||||
#define RELEASE 1
|
||||
|
||||
#define ZYNQMP_BOOTADDR_HIGH_MASK 0xFFFFFFFF
|
||||
#define ZYNQMP_R5_HIVEC_ADDR 0xFFFF0000
|
||||
#define ZYNQMP_R5_LOVEC_ADDR 0x0
|
||||
#define ZYNQMP_RPU_CFG_CPU_HALT_MASK 0x01
|
||||
#define ZYNQMP_RPU_CFG_HIVEC_MASK 0x04
|
||||
#define ZYNQMP_RPU_GLBL_CTRL_SPLIT_LOCK_MASK 0x08
|
||||
#define ZYNQMP_RPU_GLBL_CTRL_TCM_COMB_MASK 0x40
|
||||
#define ZYNQMP_RPU_GLBL_CTRL_SLCLAMP_MASK 0x10
|
||||
|
||||
#define ZYNQMP_CRLAPB_RST_LPD_AMBA_RST_MASK 0x04
|
||||
#define ZYNQMP_CRLAPB_RST_LPD_R50_RST_MASK 0x01
|
||||
#define ZYNQMP_CRLAPB_RST_LPD_R51_RST_MASK 0x02
|
||||
#define ZYNQMP_CRLAPB_CPU_R5_CTRL_CLKACT_MASK 0x1000000
|
||||
|
||||
#define ZYNQMP_TCM_START_ADDRESS 0xFFE00000
|
||||
#define ZYNQMP_TCM_BOTH_SIZE 0x40000
|
||||
|
||||
#define ZYNQMP_CORE_APU0 0
|
||||
#define ZYNQMP_CORE_APU3 3
|
||||
|
||||
#define ZYNQMP_MAX_CORES 6
|
||||
|
||||
int is_core_valid(unsigned int core)
|
||||
{
|
||||
if (core < ZYNQMP_MAX_CORES)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cpu_reset(int nr)
|
||||
{
|
||||
puts("Feature is not implemented.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void set_r5_halt_mode(u8 halt, u8 mode)
|
||||
{
|
||||
u32 tmp;
|
||||
|
||||
tmp = readl(&rpu_base->rpu0_cfg);
|
||||
if (halt == HALT)
|
||||
tmp &= ~ZYNQMP_RPU_CFG_CPU_HALT_MASK;
|
||||
else
|
||||
tmp |= ZYNQMP_RPU_CFG_CPU_HALT_MASK;
|
||||
writel(tmp, &rpu_base->rpu0_cfg);
|
||||
|
||||
if (mode == LOCK) {
|
||||
tmp = readl(&rpu_base->rpu1_cfg);
|
||||
if (halt == HALT)
|
||||
tmp &= ~ZYNQMP_RPU_CFG_CPU_HALT_MASK;
|
||||
else
|
||||
tmp |= ZYNQMP_RPU_CFG_CPU_HALT_MASK;
|
||||
writel(tmp, &rpu_base->rpu1_cfg);
|
||||
}
|
||||
}
|
||||
|
||||
static void set_r5_tcm_mode(u8 mode)
|
||||
{
|
||||
u32 tmp;
|
||||
|
||||
tmp = readl(&rpu_base->rpu_glbl_ctrl);
|
||||
if (mode == LOCK) {
|
||||
tmp &= ~ZYNQMP_RPU_GLBL_CTRL_SPLIT_LOCK_MASK;
|
||||
tmp |= ZYNQMP_RPU_GLBL_CTRL_TCM_COMB_MASK |
|
||||
ZYNQMP_RPU_GLBL_CTRL_SLCLAMP_MASK;
|
||||
} else {
|
||||
tmp |= ZYNQMP_RPU_GLBL_CTRL_SPLIT_LOCK_MASK;
|
||||
tmp &= ~(ZYNQMP_RPU_GLBL_CTRL_TCM_COMB_MASK |
|
||||
ZYNQMP_RPU_GLBL_CTRL_SLCLAMP_MASK);
|
||||
}
|
||||
|
||||
writel(tmp, &rpu_base->rpu_glbl_ctrl);
|
||||
}
|
||||
|
||||
static void set_r5_reset(u8 mode)
|
||||
{
|
||||
u32 tmp;
|
||||
|
||||
tmp = readl(&crlapb_base->rst_lpd_top);
|
||||
tmp |= (ZYNQMP_CRLAPB_RST_LPD_AMBA_RST_MASK |
|
||||
ZYNQMP_CRLAPB_RST_LPD_R50_RST_MASK);
|
||||
|
||||
if (mode == LOCK)
|
||||
tmp |= ZYNQMP_CRLAPB_RST_LPD_R51_RST_MASK;
|
||||
|
||||
writel(tmp, &crlapb_base->rst_lpd_top);
|
||||
}
|
||||
|
||||
static void release_r5_reset(u8 mode)
|
||||
{
|
||||
u32 tmp;
|
||||
|
||||
tmp = readl(&crlapb_base->rst_lpd_top);
|
||||
tmp &= ~(ZYNQMP_CRLAPB_RST_LPD_AMBA_RST_MASK |
|
||||
ZYNQMP_CRLAPB_RST_LPD_R50_RST_MASK);
|
||||
|
||||
if (mode == LOCK)
|
||||
tmp &= ~ZYNQMP_CRLAPB_RST_LPD_R51_RST_MASK;
|
||||
|
||||
writel(tmp, &crlapb_base->rst_lpd_top);
|
||||
}
|
||||
|
||||
static void enable_clock_r5(void)
|
||||
{
|
||||
u32 tmp;
|
||||
|
||||
tmp = readl(&crlapb_base->cpu_r5_ctrl);
|
||||
tmp |= ZYNQMP_CRLAPB_CPU_R5_CTRL_CLKACT_MASK;
|
||||
writel(tmp, &crlapb_base->cpu_r5_ctrl);
|
||||
|
||||
/* Give some delay for clock
|
||||
* to propogate */
|
||||
udelay(0x500);
|
||||
}
|
||||
|
||||
int cpu_disable(int nr)
|
||||
{
|
||||
if (nr >= ZYNQMP_CORE_APU0 && nr <= ZYNQMP_CORE_APU3) {
|
||||
u32 val = readl(&crfapb_base->rst_fpd_apu);
|
||||
val |= 1 << nr;
|
||||
writel(val, &crfapb_base->rst_fpd_apu);
|
||||
} else {
|
||||
set_r5_reset(LOCK);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cpu_status(int nr)
|
||||
{
|
||||
if (nr >= ZYNQMP_CORE_APU0 && nr <= ZYNQMP_CORE_APU3) {
|
||||
u32 addr_low = readl(((u8 *)&apu_base->rvbar_addr0_l) + nr * 8);
|
||||
u32 addr_high = readl(((u8 *)&apu_base->rvbar_addr0_h) +
|
||||
nr * 8);
|
||||
u32 val = readl(&crfapb_base->rst_fpd_apu);
|
||||
val &= 1 << nr;
|
||||
printf("APU CPU%d %s - starting address HI: %x, LOW: %x\n",
|
||||
nr, val ? "OFF" : "ON" , addr_high, addr_low);
|
||||
} else {
|
||||
u32 val = readl(&crlapb_base->rst_lpd_top);
|
||||
val &= 1 << (nr - 4);
|
||||
printf("RPU CPU%d %s\n", nr - 4, val ? "OFF" : "ON");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void set_r5_start(u8 high)
|
||||
{
|
||||
u32 tmp;
|
||||
|
||||
tmp = readl(&rpu_base->rpu0_cfg);
|
||||
if (high)
|
||||
tmp |= ZYNQMP_RPU_CFG_HIVEC_MASK;
|
||||
else
|
||||
tmp &= ~ZYNQMP_RPU_CFG_HIVEC_MASK;
|
||||
writel(tmp, &rpu_base->rpu0_cfg);
|
||||
|
||||
tmp = readl(&rpu_base->rpu1_cfg);
|
||||
if (high)
|
||||
tmp |= ZYNQMP_RPU_CFG_HIVEC_MASK;
|
||||
else
|
||||
tmp &= ~ZYNQMP_RPU_CFG_HIVEC_MASK;
|
||||
writel(tmp, &rpu_base->rpu1_cfg);
|
||||
}
|
||||
|
||||
int cpu_release(int nr, int argc, char * const argv[])
|
||||
{
|
||||
if (nr >= ZYNQMP_CORE_APU0 && nr <= ZYNQMP_CORE_APU3) {
|
||||
u64 boot_addr = simple_strtoull(argv[0], NULL, 16);
|
||||
/* HIGH */
|
||||
writel((u32)(boot_addr >> 32),
|
||||
((u8 *)&apu_base->rvbar_addr0_h) + nr * 8);
|
||||
/* LOW */
|
||||
writel((u32)(boot_addr & ZYNQMP_BOOTADDR_HIGH_MASK),
|
||||
((u8 *)&apu_base->rvbar_addr0_l) + nr * 8);
|
||||
|
||||
u32 val = readl(&crfapb_base->rst_fpd_apu);
|
||||
val &= ~(1 << nr);
|
||||
writel(val, &crfapb_base->rst_fpd_apu);
|
||||
} else {
|
||||
if (argc != 2) {
|
||||
printf("Invalid number of arguments to release.\n");
|
||||
printf("<addr> <mode>-Start addr lockstep or split\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
u32 boot_addr = simple_strtoul(argv[0], NULL, 16);
|
||||
if (!(boot_addr == ZYNQMP_R5_LOVEC_ADDR ||
|
||||
boot_addr == ZYNQMP_R5_HIVEC_ADDR)) {
|
||||
printf("Invalid starting address 0x%x\n", boot_addr);
|
||||
printf("0 or 0xffff0000 are permitted\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!strncmp(argv[1], "lockstep", 8)) {
|
||||
printf("R5 lockstep mode\n");
|
||||
set_r5_tcm_mode(LOCK);
|
||||
set_r5_halt_mode(HALT, LOCK);
|
||||
|
||||
if (boot_addr == 0)
|
||||
set_r5_start(0);
|
||||
else
|
||||
set_r5_start(1);
|
||||
|
||||
enable_clock_r5();
|
||||
release_r5_reset(LOCK);
|
||||
set_r5_halt_mode(RELEASE, LOCK);
|
||||
} else if (!strncmp(argv[1], "split", 5)) {
|
||||
printf("R5 split mode\n");
|
||||
set_r5_tcm_mode(SPLIT);
|
||||
set_r5_halt_mode(HALT, SPLIT);
|
||||
enable_clock_r5();
|
||||
release_r5_reset(SPLIT);
|
||||
set_r5_halt_mode(RELEASE, SPLIT);
|
||||
} else {
|
||||
printf("Unsupported mode\n");
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -39,11 +39,12 @@ dtb-$(CONFIG_ARCH_UNIPHIER) += \
|
||||
uniphier-ph1-pro4-ref.dtb \
|
||||
uniphier-ph1-ld4-ref.dtb \
|
||||
uniphier-ph1-sld8-ref.dtb
|
||||
dtb-$(CONFIG_ZYNQ) += zynq-zc702.dtb \
|
||||
dtb-$(CONFIG_ARCH_ZYNQ) += zynq-zc702.dtb \
|
||||
zynq-zc706.dtb \
|
||||
zynq-zed.dtb \
|
||||
zynq-zybo.dtb \
|
||||
zynq-microzed.dtb \
|
||||
zynq-picozed.dtb \
|
||||
zynq-zc770-xm010.dtb \
|
||||
zynq-zc770-xm012.dtb \
|
||||
zynq-zc770-xm013.dtb
|
||||
|
23
arch/arm/dts/zynq-picozed.dts
Normal file
23
arch/arm/dts/zynq-picozed.dts
Normal file
@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Avnet PicoZed board DTS
|
||||
*
|
||||
* Copyright (C) 2015 Xilinx, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
/dts-v1/;
|
||||
#include "zynq-7000.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Zynq PicoZed Board";
|
||||
compatible = "xlnx,zynq-picozed", "xlnx,zynq-7000";
|
||||
|
||||
aliases {
|
||||
serial0 = &uart1;
|
||||
};
|
||||
|
||||
memory {
|
||||
device_type = "memory";
|
||||
reg = <0 0x40000000>;
|
||||
};
|
||||
};
|
@ -1,10 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Xilinx, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef _ZYNQ_GPIO_H
|
||||
#define _ZYNQ_GPIO_H
|
||||
|
||||
#endif /* _ZYNQ_GPIO_H */
|
12
arch/arm/include/asm/arch-zynqmp/gpio.h
Normal file
12
arch/arm/include/asm/arch-zynqmp/gpio.h
Normal file
@ -0,0 +1,12 @@
|
||||
/*
|
||||
* Copyright 2015 Xilinx, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef __ARCH_ZYNQMP_GPIO_H
|
||||
#define __ARCH_ZYNQMP_GPIO_H
|
||||
|
||||
/* Empty file - sdhci requires this. */
|
||||
|
||||
#endif
|
@ -11,6 +11,12 @@
|
||||
#define ZYNQ_SERIAL_BASEADDR0 0xFF000000
|
||||
#define ZYNQ_SERIAL_BASEADDR1 0xFF001000
|
||||
|
||||
#define ZYNQ_SPI_BASEADDR0 0xFF040000
|
||||
#define ZYNQ_SPI_BASEADDR1 0xFF050000
|
||||
|
||||
#define ZYNQ_I2C_BASEADDR0 0xFF020000
|
||||
#define ZYNQ_I2C_BASEADDR1 0xFF030000
|
||||
|
||||
#define ZYNQ_SDHCI_BASEADDR0 0xFF160000
|
||||
#define ZYNQ_SDHCI_BASEADDR1 0xFF170000
|
||||
|
||||
@ -18,11 +24,15 @@
|
||||
#define ZYNQMP_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT 0x1000000
|
||||
|
||||
struct crlapb_regs {
|
||||
u32 reserved0[74];
|
||||
u32 reserved0[36];
|
||||
u32 cpu_r5_ctrl; /* 0x90 */
|
||||
u32 reserved1[37];
|
||||
u32 timestamp_ref_ctrl; /* 0x128 */
|
||||
u32 reserved0_1[53];
|
||||
u32 reserved2[53];
|
||||
u32 boot_mode; /* 0x200 */
|
||||
u32 reserved1[26];
|
||||
u32 reserved3[14];
|
||||
u32 rst_lpd_top; /* 0x23C */
|
||||
u32 reserved4[26];
|
||||
};
|
||||
|
||||
#define crlapb_base ((struct crlapb_regs *)ZYNQMP_CRL_APB_BASEADDR)
|
||||
@ -41,12 +51,47 @@ struct iou_scntr {
|
||||
|
||||
/* Bootmode setting values */
|
||||
#define BOOT_MODES_MASK 0x0000000F
|
||||
#define SD_MODE 0x00000005
|
||||
#define SD_MODE 0x00000003
|
||||
#define EMMC_MODE 0x00000006
|
||||
#define JTAG_MODE 0x00000000
|
||||
|
||||
#define ZYNQMP_RPU_BASEADDR 0xFF9A0000
|
||||
|
||||
struct rpu_regs {
|
||||
u32 rpu_glbl_ctrl;
|
||||
u32 reserved0[63];
|
||||
u32 rpu0_cfg; /* 0x100 */
|
||||
u32 reserved1[63];
|
||||
u32 rpu1_cfg; /* 0x200 */
|
||||
};
|
||||
|
||||
#define rpu_base ((struct rpu_regs *)ZYNQMP_RPU_BASEADDR)
|
||||
|
||||
#define ZYNQMP_CRF_APB_BASEADDR 0xFD1A0000
|
||||
|
||||
struct crfapb_regs {
|
||||
u32 reserved0[65];
|
||||
u32 rst_fpd_apu; /* 0x104 */
|
||||
u32 reserved1;
|
||||
};
|
||||
|
||||
#define crfapb_base ((struct crfapb_regs *)ZYNQMP_CRF_APB_BASEADDR)
|
||||
|
||||
#define ZYNQMP_APU_BASEADDR 0xFD5C0000
|
||||
|
||||
struct apu_regs {
|
||||
u32 reserved0[16];
|
||||
u32 rvbar_addr0_l; /* 0x40 */
|
||||
u32 rvbar_addr0_h; /* 0x44 */
|
||||
u32 reserved1[20];
|
||||
};
|
||||
|
||||
#define apu_base ((struct apu_regs *)ZYNQMP_APU_BASEADDR)
|
||||
|
||||
/* Board version value */
|
||||
#define ZYNQMP_CSU_VERSION_SILICON 0x0
|
||||
#define ZYNQMP_CSU_VERSION_EP108 0x1
|
||||
#define ZYNQMP_CSU_VERSION_VELOCE 0x2
|
||||
#define ZYNQMP_CSU_VERSION_QEMU 0x3
|
||||
|
||||
#endif /* _ASM_ARCH_HARDWARE_H */
|
||||
|
@ -1,4 +1,4 @@
|
||||
if ZYNQ
|
||||
if ARCH_ZYNQ
|
||||
|
||||
choice
|
||||
prompt "Xilinx Zynq board select"
|
||||
@ -9,6 +9,9 @@ config TARGET_ZYNQ_ZED
|
||||
config TARGET_ZYNQ_MICROZED
|
||||
bool "Zynq MicroZed"
|
||||
|
||||
config TARGET_ZYNQ_PICOZED
|
||||
bool "Zynq PicoZed"
|
||||
|
||||
config TARGET_ZYNQ_ZC70X
|
||||
bool "Zynq ZC702/ZC706 Board"
|
||||
|
||||
@ -32,6 +35,7 @@ config SYS_SOC
|
||||
config SYS_CONFIG_NAME
|
||||
default "zynq_zed" if TARGET_ZYNQ_ZED
|
||||
default "zynq_microzed" if TARGET_ZYNQ_MICROZED
|
||||
default "zynq_picozed" if TARGET_ZYNQ_PICOZED
|
||||
default "zynq_zc70x" if TARGET_ZYNQ_ZC70X
|
||||
default "zynq_zc770" if TARGET_ZYNQ_ZC770
|
||||
default "zynq_zybo" if TARGET_ZYNQ_ZYBO
|
@ -14,4 +14,5 @@ obj-y += ddrc.o
|
||||
obj-y += slcr.o
|
||||
obj-y += clk.o
|
||||
obj-y += lowlevel_init.o
|
||||
AFLAGS_lowlevel_init.o := -mfpu=neon
|
||||
obj-$(CONFIG_SPL_BUILD) += spl.o
|
76
arch/arm/mach-zynq/include/mach/gpio.h
Normal file
76
arch/arm/mach-zynq/include/mach/gpio.h
Normal file
@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (c) 2013 Xilinx, Inc.
|
||||
* Copyright (c) 2015 DAVE Embedded Systems
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef _ZYNQ_GPIO_H
|
||||
#define _ZYNQ_GPIO_H
|
||||
|
||||
#define ZYNQ_GPIO_BASE_ADDRESS 0xE000A000
|
||||
|
||||
/* Maximum banks */
|
||||
#define ZYNQ_GPIO_MAX_BANK 4
|
||||
|
||||
#define ZYNQ_GPIO_BANK0_NGPIO 32
|
||||
#define ZYNQ_GPIO_BANK1_NGPIO 22
|
||||
#define ZYNQ_GPIO_BANK2_NGPIO 32
|
||||
#define ZYNQ_GPIO_BANK3_NGPIO 32
|
||||
|
||||
#define ZYNQ_GPIO_NR_GPIOS (ZYNQ_GPIO_BANK0_NGPIO + \
|
||||
ZYNQ_GPIO_BANK1_NGPIO + \
|
||||
ZYNQ_GPIO_BANK2_NGPIO + \
|
||||
ZYNQ_GPIO_BANK3_NGPIO)
|
||||
|
||||
#define ZYNQ_GPIO_BANK0_PIN_MIN 0
|
||||
#define ZYNQ_GPIO_BANK0_PIN_MAX (ZYNQ_GPIO_BANK0_PIN_MIN + \
|
||||
ZYNQ_GPIO_BANK0_NGPIO - 1)
|
||||
#define ZYNQ_GPIO_BANK1_PIN_MIN (ZYNQ_GPIO_BANK0_PIN_MAX + 1)
|
||||
#define ZYNQ_GPIO_BANK1_PIN_MAX (ZYNQ_GPIO_BANK1_PIN_MIN + \
|
||||
ZYNQ_GPIO_BANK1_NGPIO - 1)
|
||||
#define ZYNQ_GPIO_BANK2_PIN_MIN (ZYNQ_GPIO_BANK1_PIN_MAX + 1)
|
||||
#define ZYNQ_GPIO_BANK2_PIN_MAX (ZYNQ_GPIO_BANK2_PIN_MIN + \
|
||||
ZYNQ_GPIO_BANK2_NGPIO - 1)
|
||||
#define ZYNQ_GPIO_BANK3_PIN_MIN (ZYNQ_GPIO_BANK2_PIN_MAX + 1)
|
||||
#define ZYNQ_GPIO_BANK3_PIN_MAX (ZYNQ_GPIO_BANK3_PIN_MIN + \
|
||||
ZYNQ_GPIO_BANK3_NGPIO - 1)
|
||||
|
||||
/* Register offsets for the GPIO device */
|
||||
/* LSW Mask & Data -WO */
|
||||
#define ZYNQ_GPIO_DATA_LSW_OFFSET(BANK) (0x000 + (8 * BANK))
|
||||
/* MSW Mask & Data -WO */
|
||||
#define ZYNQ_GPIO_DATA_MSW_OFFSET(BANK) (0x004 + (8 * BANK))
|
||||
/* Data Register-RW */
|
||||
#define ZYNQ_GPIO_DATA_RO_OFFSET(BANK) (0x060 + (4 * BANK))
|
||||
/* Direction mode reg-RW */
|
||||
#define ZYNQ_GPIO_DIRM_OFFSET(BANK) (0x204 + (0x40 * BANK))
|
||||
/* Output enable reg-RW */
|
||||
#define ZYNQ_GPIO_OUTEN_OFFSET(BANK) (0x208 + (0x40 * BANK))
|
||||
/* Interrupt mask reg-RO */
|
||||
#define ZYNQ_GPIO_INTMASK_OFFSET(BANK) (0x20C + (0x40 * BANK))
|
||||
/* Interrupt enable reg-WO */
|
||||
#define ZYNQ_GPIO_INTEN_OFFSET(BANK) (0x210 + (0x40 * BANK))
|
||||
/* Interrupt disable reg-WO */
|
||||
#define ZYNQ_GPIO_INTDIS_OFFSET(BANK) (0x214 + (0x40 * BANK))
|
||||
/* Interrupt status reg-RO */
|
||||
#define ZYNQ_GPIO_INTSTS_OFFSET(BANK) (0x218 + (0x40 * BANK))
|
||||
/* Interrupt type reg-RW */
|
||||
#define ZYNQ_GPIO_INTTYPE_OFFSET(BANK) (0x21C + (0x40 * BANK))
|
||||
/* Interrupt polarity reg-RW */
|
||||
#define ZYNQ_GPIO_INTPOL_OFFSET(BANK) (0x220 + (0x40 * BANK))
|
||||
/* Interrupt on any, reg-RW */
|
||||
#define ZYNQ_GPIO_INTANY_OFFSET(BANK) (0x224 + (0x40 * BANK))
|
||||
|
||||
/* Disable all interrupts mask */
|
||||
#define ZYNQ_GPIO_IXR_DISABLE_ALL 0xFFFFFFFF
|
||||
|
||||
/* Mid pin number of a bank */
|
||||
#define ZYNQ_GPIO_MID_PIN_NUM 16
|
||||
|
||||
/* GPIO upper 16 bit mask */
|
||||
#define ZYNQ_GPIO_UPPER_MASK 0xFFFF0000
|
||||
|
||||
#define BIT(x) (1<<x)
|
||||
|
||||
#endif /* _ZYNQ_GPIO_H */
|
@ -129,11 +129,18 @@ out:
|
||||
|
||||
void zynq_slcr_devcfg_disable(void)
|
||||
{
|
||||
u32 reg_val;
|
||||
|
||||
zynq_slcr_unlock();
|
||||
|
||||
/* Disable AXI interface by asserting FPGA resets */
|
||||
writel(0xF, &slcr_base->fpga_rst_ctrl);
|
||||
|
||||
/* Disable Level shifters before setting PS-PL */
|
||||
reg_val = readl(&slcr_base->lvl_shftr_en);
|
||||
reg_val &= ~0xF;
|
||||
writel(reg_val, &slcr_base->lvl_shftr_en);
|
||||
|
||||
/* Set Level Shifters DT618760 */
|
||||
writel(0xA, &slcr_base->lvl_shftr_en);
|
||||
|
@ -85,6 +85,6 @@ __weak void ps7_init(void)
|
||||
{
|
||||
/*
|
||||
* This function is overridden by the one in
|
||||
* board/xilinx/zynq/ps7_init.c, if it exists.
|
||||
* board/xilinx/zynq/ps7_init_gpl.c, if it exists.
|
||||
*/
|
||||
}
|
@ -93,7 +93,9 @@ ulong get_timer_masked(void)
|
||||
gd->arch.tbl += gd->arch.lastinc - now;
|
||||
} else {
|
||||
/* We have an overflow ... */
|
||||
gd->arch.tbl += gd->arch.lastinc + TIMER_LOAD_VAL - now + 1;
|
||||
gd->arch.tbl += gd->arch.lastinc + (TIMER_LOAD_VAL /
|
||||
(gd->arch.timer_rate_hz / CONFIG_SYS_HZ)) -
|
||||
now + 1;
|
||||
}
|
||||
gd->arch.lastinc = now;
|
||||
|
1
board/xilinx/zynq/.gitignore
vendored
1
board/xilinx/zynq/.gitignore
vendored
@ -1,2 +1 @@
|
||||
ps7_init.[ch]
|
||||
ps7_init_gpl.[ch]
|
||||
|
@ -9,9 +9,7 @@ obj-y := board.o
|
||||
|
||||
# Please copy ps7_init_gpl.c/h from hw project to this directory
|
||||
obj-$(CONFIG_SPL_BUILD) += \
|
||||
$(if $(wildcard $(srctree)/$(src)/ps7_init_gpl.c), ps7_init_gpl.o, \
|
||||
$(if $(wildcard $(srctree)/$(src)/ps7_init.c), ps7_init.o legacy.o))
|
||||
$(if $(wildcard $(srctree)/$(src)/ps7_init_gpl.c), ps7_init_gpl.o)
|
||||
|
||||
# Suppress "warning: function declaration isn't a prototype"
|
||||
CFLAGS_REMOVE_ps7_init_gpl.o := -Wstrict-prototypes
|
||||
CFLAGS_REMOVE_ps7_init.o := -Wstrict-prototypes
|
||||
|
@ -1,2 +0,0 @@
|
||||
|
||||
#warning usage of ps7_init files is deprecated please use ps7_init_gpl
|
@ -56,14 +56,18 @@ int board_mmc_init(bd_t *bd)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
u32 ver = zynqmp_get_silicon_version();
|
||||
|
||||
if (ver != ZYNQMP_CSU_VERSION_VELOCE) {
|
||||
#if defined(CONFIG_ZYNQ_SDHCI)
|
||||
# if defined(CONFIG_ZYNQ_SDHCI0)
|
||||
ret = zynq_sdhci_init(ZYNQ_SDHCI_BASEADDR0);
|
||||
ret = zynq_sdhci_init(ZYNQ_SDHCI_BASEADDR0);
|
||||
# endif
|
||||
# if defined(CONFIG_ZYNQ_SDHCI1)
|
||||
ret |= zynq_sdhci_init(ZYNQ_SDHCI_BASEADDR1);
|
||||
ret |= zynq_sdhci_init(ZYNQ_SDHCI_BASEADDR1);
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -79,6 +83,7 @@ int board_late_init(void)
|
||||
|
||||
switch (bootmode) {
|
||||
case SD_MODE:
|
||||
case EMMC_MODE:
|
||||
setenv("modeboot", "sdboot");
|
||||
break;
|
||||
default:
|
||||
|
@ -1,6 +1,6 @@
|
||||
CONFIG_SPL=y
|
||||
CONFIG_ARM=y
|
||||
CONFIG_ZYNQ=y
|
||||
CONFIG_ARCH_ZYNQ=y
|
||||
CONFIG_TARGET_ZYNQ_MICROZED=y
|
||||
CONFIG_OF_CONTROL=y
|
||||
# CONFIG_SYS_MALLOC_F is not set
|
||||
|
6
configs/zynq_picozed_defconfig
Normal file
6
configs/zynq_picozed_defconfig
Normal file
@ -0,0 +1,6 @@
|
||||
CONFIG_SPL=y
|
||||
CONFIG_ARM=y
|
||||
CONFIG_ARCH_ZYNQ=y
|
||||
CONFIG_TARGET_ZYNQ_PICOZED=y
|
||||
CONFIG_OF_CONTROL=n
|
||||
CONFIG_DEFAULT_DEVICE_TREE="zynq-picozed"
|
@ -1,6 +1,6 @@
|
||||
CONFIG_SPL=y
|
||||
CONFIG_ARM=y
|
||||
CONFIG_ZYNQ=y
|
||||
CONFIG_ARCH_ZYNQ=y
|
||||
CONFIG_TARGET_ZYNQ_ZC70X=y
|
||||
CONFIG_OF_CONTROL=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="zynq-zc702"
|
||||
|
@ -1,7 +1,7 @@
|
||||
CONFIG_SPL=y
|
||||
CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM010"
|
||||
CONFIG_ARM=y
|
||||
CONFIG_ZYNQ=y
|
||||
CONFIG_ARCH_ZYNQ=y
|
||||
CONFIG_TARGET_ZYNQ_ZC770=y
|
||||
CONFIG_OF_CONTROL=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm010"
|
||||
|
@ -1,7 +1,7 @@
|
||||
CONFIG_SPL=y
|
||||
CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM012"
|
||||
CONFIG_ARM=y
|
||||
CONFIG_ZYNQ=y
|
||||
CONFIG_ARCH_ZYNQ=y
|
||||
CONFIG_TARGET_ZYNQ_ZC770=y
|
||||
CONFIG_OF_CONTROL=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm012"
|
||||
|
@ -1,7 +1,7 @@
|
||||
CONFIG_SPL=y
|
||||
CONFIG_SYS_EXTRA_OPTIONS="ZC770_XM013"
|
||||
CONFIG_ARM=y
|
||||
CONFIG_ZYNQ=y
|
||||
CONFIG_ARCH_ZYNQ=y
|
||||
CONFIG_TARGET_ZYNQ_ZC770=y
|
||||
CONFIG_OF_CONTROL=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm013"
|
||||
|
@ -1,6 +1,6 @@
|
||||
CONFIG_SPL=y
|
||||
CONFIG_ARM=y
|
||||
CONFIG_ZYNQ=y
|
||||
CONFIG_ARCH_ZYNQ=y
|
||||
CONFIG_TARGET_ZYNQ_ZED=y
|
||||
CONFIG_OF_CONTROL=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="zynq-zed"
|
||||
|
@ -1,6 +1,6 @@
|
||||
CONFIG_SPL=y
|
||||
CONFIG_ARM=y
|
||||
CONFIG_ZYNQ=y
|
||||
CONFIG_ARCH_ZYNQ=y
|
||||
CONFIG_TARGET_ZYNQ_ZYBO=y
|
||||
CONFIG_OF_CONTROL=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="zynq-zybo"
|
||||
|
@ -43,3 +43,4 @@ oby-$(CONFIG_SX151X) += sx151x.o
|
||||
obj-$(CONFIG_SUNXI_GPIO) += sunxi_gpio.o
|
||||
obj-$(CONFIG_LPC32XX_GPIO) += lpc32xx_gpio.o
|
||||
obj-$(CONFIG_STM32_GPIO) += stm32_gpio.o
|
||||
obj-$(CONFIG_ZYNQ_GPIO) += zynq_gpio.o
|
||||
|
220
drivers/gpio/zynq_gpio.c
Normal file
220
drivers/gpio/zynq_gpio.c
Normal file
@ -0,0 +1,220 @@
|
||||
/*
|
||||
* Xilinx Zynq GPIO device driver
|
||||
*
|
||||
* Copyright (C) 2015 DAVE Embedded Systems <devel@dave.eu>
|
||||
*
|
||||
* Most of code taken from linux kernel driver (linux/drivers/gpio/gpio-zynq.c)
|
||||
* Copyright (C) 2009 - 2014 Xilinx, Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/gpio.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/errno.h>
|
||||
|
||||
/**
|
||||
* zynq_gpio_get_bank_pin - Get the bank number and pin number within that bank
|
||||
* for a given pin in the GPIO device
|
||||
* @pin_num: gpio pin number within the device
|
||||
* @bank_num: an output parameter used to return the bank number of the gpio
|
||||
* pin
|
||||
* @bank_pin_num: an output parameter used to return pin number within a bank
|
||||
* for the given gpio pin
|
||||
*
|
||||
* Returns the bank number and pin offset within the bank.
|
||||
*/
|
||||
static inline void zynq_gpio_get_bank_pin(unsigned int pin_num,
|
||||
unsigned int *bank_num,
|
||||
unsigned int *bank_pin_num)
|
||||
{
|
||||
switch (pin_num) {
|
||||
case ZYNQ_GPIO_BANK0_PIN_MIN ... ZYNQ_GPIO_BANK0_PIN_MAX:
|
||||
*bank_num = 0;
|
||||
*bank_pin_num = pin_num;
|
||||
break;
|
||||
case ZYNQ_GPIO_BANK1_PIN_MIN ... ZYNQ_GPIO_BANK1_PIN_MAX:
|
||||
*bank_num = 1;
|
||||
*bank_pin_num = pin_num - ZYNQ_GPIO_BANK1_PIN_MIN;
|
||||
break;
|
||||
case ZYNQ_GPIO_BANK2_PIN_MIN ... ZYNQ_GPIO_BANK2_PIN_MAX:
|
||||
*bank_num = 2;
|
||||
*bank_pin_num = pin_num - ZYNQ_GPIO_BANK2_PIN_MIN;
|
||||
break;
|
||||
case ZYNQ_GPIO_BANK3_PIN_MIN ... ZYNQ_GPIO_BANK3_PIN_MAX:
|
||||
*bank_num = 3;
|
||||
*bank_pin_num = pin_num - ZYNQ_GPIO_BANK3_PIN_MIN;
|
||||
break;
|
||||
default:
|
||||
printf("invalid GPIO pin number: %u\n", pin_num);
|
||||
*bank_num = 0;
|
||||
*bank_pin_num = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int gpio_is_valid(unsigned gpio)
|
||||
{
|
||||
return (gpio >= 0) && (gpio < ZYNQ_GPIO_NR_GPIOS);
|
||||
}
|
||||
|
||||
static int check_gpio(unsigned gpio)
|
||||
{
|
||||
if (!gpio_is_valid(gpio)) {
|
||||
printf("ERROR : check_gpio: invalid GPIO %d\n", gpio);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* gpio_get_value - Get the state of the specified pin of GPIO device
|
||||
* @gpio: gpio pin number within the device
|
||||
*
|
||||
* This function reads the state of the specified pin of the GPIO device.
|
||||
*
|
||||
* Return: 0 if the pin is low, 1 if pin is high.
|
||||
*/
|
||||
int gpio_get_value(unsigned gpio)
|
||||
{
|
||||
u32 data;
|
||||
unsigned int bank_num, bank_pin_num;
|
||||
|
||||
if (check_gpio(gpio) < 0)
|
||||
return -1;
|
||||
|
||||
zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num);
|
||||
|
||||
data = readl(ZYNQ_GPIO_BASE_ADDRESS +
|
||||
ZYNQ_GPIO_DATA_RO_OFFSET(bank_num));
|
||||
|
||||
return (data >> bank_pin_num) & 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* gpio_set_value - Modify the value of the pin with specified value
|
||||
* @gpio: gpio pin number within the device
|
||||
* @value: value used to modify the value of the specified pin
|
||||
*
|
||||
* This function calculates the register offset (i.e to lower 16 bits or
|
||||
* upper 16 bits) based on the given pin number and sets the value of a
|
||||
* gpio pin to the specified value. The value is either 0 or non-zero.
|
||||
*/
|
||||
int gpio_set_value(unsigned gpio, int value)
|
||||
{
|
||||
unsigned int reg_offset, bank_num, bank_pin_num;
|
||||
|
||||
if (check_gpio(gpio) < 0)
|
||||
return -1;
|
||||
|
||||
zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num);
|
||||
|
||||
if (bank_pin_num >= ZYNQ_GPIO_MID_PIN_NUM) {
|
||||
/* only 16 data bits in bit maskable reg */
|
||||
bank_pin_num -= ZYNQ_GPIO_MID_PIN_NUM;
|
||||
reg_offset = ZYNQ_GPIO_DATA_MSW_OFFSET(bank_num);
|
||||
} else {
|
||||
reg_offset = ZYNQ_GPIO_DATA_LSW_OFFSET(bank_num);
|
||||
}
|
||||
|
||||
/*
|
||||
* get the 32 bit value to be written to the mask/data register where
|
||||
* the upper 16 bits is the mask and lower 16 bits is the data
|
||||
*/
|
||||
value = !!value;
|
||||
value = ~(1 << (bank_pin_num + ZYNQ_GPIO_MID_PIN_NUM)) &
|
||||
((value << bank_pin_num) | ZYNQ_GPIO_UPPER_MASK);
|
||||
|
||||
writel(value, ZYNQ_GPIO_BASE_ADDRESS + reg_offset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* gpio_direction_input - Set the direction of the specified GPIO pin as input
|
||||
* @gpio: gpio pin number within the device
|
||||
*
|
||||
* This function uses the read-modify-write sequence to set the direction of
|
||||
* the gpio pin as input.
|
||||
*
|
||||
* Return: -1 if invalid gpio specified, 0 if successul
|
||||
*/
|
||||
int gpio_direction_input(unsigned gpio)
|
||||
{
|
||||
u32 reg;
|
||||
unsigned int bank_num, bank_pin_num;
|
||||
|
||||
if (check_gpio(gpio) < 0)
|
||||
return -1;
|
||||
|
||||
zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num);
|
||||
|
||||
/* bank 0 pins 7 and 8 are special and cannot be used as inputs */
|
||||
if (bank_num == 0 && (bank_pin_num == 7 || bank_pin_num == 8))
|
||||
return -1;
|
||||
|
||||
/* clear the bit in direction mode reg to set the pin as input */
|
||||
reg = readl(ZYNQ_GPIO_BASE_ADDRESS + ZYNQ_GPIO_DIRM_OFFSET(bank_num));
|
||||
reg &= ~BIT(bank_pin_num);
|
||||
writel(reg, ZYNQ_GPIO_BASE_ADDRESS + ZYNQ_GPIO_DIRM_OFFSET(bank_num));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* gpio_direction_output - Set the direction of the specified GPIO pin as output
|
||||
* @gpio: gpio pin number within the device
|
||||
* @value: value to be written to specified pin
|
||||
*
|
||||
* This function sets the direction of specified GPIO pin as output, configures
|
||||
* the Output Enable register for the pin and uses zynq_gpio_set to set
|
||||
* the value of the pin to the value specified.
|
||||
*
|
||||
* Return: 0 always
|
||||
*/
|
||||
int gpio_direction_output(unsigned gpio, int value)
|
||||
{
|
||||
u32 reg;
|
||||
unsigned int bank_num, bank_pin_num;
|
||||
|
||||
if (check_gpio(gpio) < 0)
|
||||
return -1;
|
||||
|
||||
zynq_gpio_get_bank_pin(gpio, &bank_num, &bank_pin_num);
|
||||
|
||||
/* set the GPIO pin as output */
|
||||
reg = readl(ZYNQ_GPIO_BASE_ADDRESS + ZYNQ_GPIO_DIRM_OFFSET(bank_num));
|
||||
reg |= BIT(bank_pin_num);
|
||||
writel(reg, ZYNQ_GPIO_BASE_ADDRESS + ZYNQ_GPIO_DIRM_OFFSET(bank_num));
|
||||
|
||||
/* configure the output enable reg for the pin */
|
||||
reg = readl(ZYNQ_GPIO_BASE_ADDRESS + ZYNQ_GPIO_OUTEN_OFFSET(bank_num));
|
||||
reg |= BIT(bank_pin_num);
|
||||
writel(reg, ZYNQ_GPIO_BASE_ADDRESS + ZYNQ_GPIO_OUTEN_OFFSET(bank_num));
|
||||
|
||||
/* set the state of the pin */
|
||||
gpio_set_value(gpio, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request a gpio before using it.
|
||||
*
|
||||
* NOTE: Argument 'label' is unused.
|
||||
*/
|
||||
int gpio_request(unsigned gpio, const char *label)
|
||||
{
|
||||
if (check_gpio(gpio) < 0)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset and free the gpio after using it.
|
||||
*/
|
||||
int gpio_free(unsigned gpio)
|
||||
{
|
||||
return 0;
|
||||
}
|
@ -25,7 +25,7 @@ int zynq_sdhci_init(phys_addr_t regbase)
|
||||
|
||||
host->name = "zynq_sdhci";
|
||||
host->ioaddr = (void *)regbase;
|
||||
host->quirks = SDHCI_QUIRK_NO_CD | SDHCI_QUIRK_WAIT_SEND_CMD |
|
||||
host->quirks = SDHCI_QUIRK_WAIT_SEND_CMD |
|
||||
SDHCI_QUIRK_BROKEN_R1B;
|
||||
host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
|
||||
|
||||
|
@ -48,10 +48,16 @@ static void uart_zynq_serial_setbrg(const int port)
|
||||
/* Calculation results. */
|
||||
unsigned int calc_bauderror, bdiv, bgen;
|
||||
unsigned long calc_baud = 0;
|
||||
unsigned long baud = gd->baudrate;
|
||||
unsigned long baud;
|
||||
unsigned long clock = get_uart_clk(port);
|
||||
struct uart_zynq *regs = uart_zynq_ports[port];
|
||||
|
||||
/* Covering case where input clock is so slow */
|
||||
if (clock < 1000000 && gd->baudrate > 4800)
|
||||
gd->baudrate = 4800;
|
||||
|
||||
baud = gd->baudrate;
|
||||
|
||||
/* master clock
|
||||
* Baud rate = ------------------
|
||||
* bgen * (bdiv + 1)
|
||||
|
@ -36,7 +36,7 @@
|
||||
#define CPU_RELEASE_ADDR 0xFFFFFF0
|
||||
|
||||
/* Cache Definitions */
|
||||
#define CONFIG_SYS_DCACHE_OFF
|
||||
#define CONFIG_SYS_CACHELINE_SIZE 64
|
||||
|
||||
#define CONFIG_IDENT_STRING " Xilinx ZynqMP"
|
||||
|
||||
@ -61,13 +61,25 @@
|
||||
#define CONFIG_SYS_BAUDRATE_TABLE \
|
||||
{ 4800, 9600, 19200, 38400, 57600, 115200 }
|
||||
|
||||
#define CONFIG_ZYNQ_SDHCI0
|
||||
|
||||
/* Command line configuration */
|
||||
#define CONFIG_CMD_ENV
|
||||
#define CONFIG_CMD_EXT2
|
||||
#define CONFIG_CMD_EXT4
|
||||
#define CONFIG_CMD_FAT
|
||||
#define CONFIG_CMD_FS_GENERIC
|
||||
#define CONFIG_CMD_MEMORY
|
||||
#define CONFIG_DOS_PARTITION
|
||||
#define CONFIG_CMD_ELF
|
||||
#define CONFIG_MP
|
||||
|
||||
/* SPI */
|
||||
#ifdef CONFIG_ZYNQ_SPI
|
||||
# define CONFIG_SPI_FLASH
|
||||
# define CONFIG_SPI_FLASH_SST
|
||||
# define CONFIG_CMD_SF
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_ZYNQ_SDHCI0) || defined(CONFIG_ZYNQ_SDHCI1)
|
||||
# define CONFIG_MMC
|
||||
@ -90,8 +102,8 @@
|
||||
"kernel_addr=0x80000\0" \
|
||||
"fdt_addr=0x7000000\0" \
|
||||
"fdt_high=0x10000000\0" \
|
||||
"sdboot=mmcinfo && fatload mmc 0:0 $fdt_addr system.dtb && " \
|
||||
"fatload mmc 0:0 $kernel_addr Image && booti $kernel_addr - $fdt_addr\0"
|
||||
"sdboot=mmcinfo && load mmc 0:0 $fdt_addr system.dtb && " \
|
||||
"load mmc 0:0 $kernel_addr Image && booti $kernel_addr - $fdt_addr\0"
|
||||
|
||||
#define CONFIG_BOOTARGS "setenv bootargs console=ttyPS0,${baudrate} " \
|
||||
"earlycon=cdns,mmio,0xff000000,${baudrate}n8"
|
||||
@ -117,6 +129,29 @@
|
||||
#define CONFIG_CMDLINE_EDITING
|
||||
#define CONFIG_SYS_MAXARGS 64
|
||||
|
||||
#define CONFIG_ZYNQ_I2C0
|
||||
#define CONFIG_SYS_I2C_ZYNQ
|
||||
|
||||
/* I2C */
|
||||
#if defined(CONFIG_SYS_I2C_ZYNQ)
|
||||
# define CONFIG_CMD_I2C
|
||||
# define CONFIG_SYS_I2C
|
||||
# define CONFIG_SYS_I2C_ZYNQ_SPEED 100000
|
||||
# define CONFIG_SYS_I2C_ZYNQ_SLAVE 0
|
||||
#endif
|
||||
|
||||
#define CONFIG_ZYNQMP_EEPROM
|
||||
|
||||
/* EEPROM */
|
||||
#ifdef CONFIG_ZYNQMP_EEPROM
|
||||
# define CONFIG_CMD_EEPROM
|
||||
# define CONFIG_SYS_I2C_EEPROM_ADDR_LEN 2
|
||||
# define CONFIG_SYS_I2C_EEPROM_ADDR 0x54
|
||||
# define CONFIG_SYS_EEPROM_PAGE_WRITE_BITS 4
|
||||
# define CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS 5
|
||||
# define CONFIG_SYS_EEPROM_SIZE (64 * 1024)
|
||||
#endif
|
||||
|
||||
#define CONFIG_FIT
|
||||
#define CONFIG_FIT_VERBOSE /* enable fit_format_{error,warning}() */
|
||||
|
||||
|
@ -39,6 +39,9 @@
|
||||
# define CONFIG_ZYNQ_SERIAL
|
||||
#endif
|
||||
|
||||
#define CONFIG_ZYNQ_GPIO
|
||||
#define CONFIG_CMD_GPIO
|
||||
|
||||
/* Ethernet driver */
|
||||
#if defined(CONFIG_ZYNQ_GEM0) || defined(CONFIG_ZYNQ_GEM1)
|
||||
# define CONFIG_NET_MULTI
|
||||
@ -291,7 +294,7 @@
|
||||
# define CONFIG_SYS_MMC_MAX_DEVICE 1
|
||||
#endif
|
||||
|
||||
#define CONFIG_SYS_LDSCRIPT "arch/arm/cpu/armv7/zynq/u-boot.lds"
|
||||
#define CONFIG_SYS_LDSCRIPT "arch/arm/mach-zynq/u-boot.lds"
|
||||
|
||||
/* Commands */
|
||||
#include <config_cmd_default.h>
|
||||
@ -309,7 +312,7 @@
|
||||
#define CONFIG_SPL_SERIAL_SUPPORT
|
||||
#define CONFIG_SPL_BOARD_INIT
|
||||
|
||||
#define CONFIG_SPL_LDSCRIPT "arch/arm/cpu/armv7/zynq/u-boot-spl.lds"
|
||||
#define CONFIG_SPL_LDSCRIPT "arch/arm/mach-zynq/u-boot-spl.lds"
|
||||
|
||||
/* MMC support */
|
||||
#ifdef CONFIG_ZYNQ_SDHCI0
|
||||
|
27
include/configs/zynq_picozed.h
Normal file
27
include/configs/zynq_picozed.h
Normal file
@ -0,0 +1,27 @@
|
||||
/*
|
||||
* (C) Copyright 2015 Xilinx, Inc.
|
||||
*
|
||||
* Configuration for PicoZed
|
||||
* See zynq-common.h for Zynq common configs
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef __CONFIG_ZYNQ_PICOZED_H
|
||||
#define __CONFIG_ZYNQ_PICOZED_H
|
||||
|
||||
#define CONFIG_SYS_SDRAM_SIZE (1024 * 1024 * 1024)
|
||||
|
||||
#define CONFIG_ZYNQ_SERIAL_UART1
|
||||
#define CONFIG_ZYNQ_GEM0
|
||||
#define CONFIG_ZYNQ_GEM_PHY_ADDR0 0
|
||||
|
||||
#define CONFIG_SYS_NO_FLASH
|
||||
|
||||
#define CONFIG_ZYNQ_SDHCI1
|
||||
#define CONFIG_ZYNQ_USB
|
||||
#define CONFIG_ZYNQ_BOOT_FREEBSD
|
||||
|
||||
#include <configs/zynq-common.h>
|
||||
|
||||
#endif /* __CONFIG_ZYNQ_PICOZED_H */
|
Loading…
Reference in New Issue
Block a user