Skip to content
Snippets Groups Projects
Commit ace97d26 authored by Tom Rini's avatar Tom Rini
Browse files
parents 1692515e 5ca269a4
No related branches found
No related tags found
No related merge requests found
Showing
with 583 additions and 26 deletions
......@@ -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/
#
# 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
/*
* (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
......
/*
* 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>;
};
};
/*
* Copyright (c) 2013 Xilinx, Inc.
*
* SPDX-License-Identifier: GPL-2.0+
*/
#ifndef _ZYNQ_GPIO_H
#define _ZYNQ_GPIO_H
#endif /* _ZYNQ_GPIO_H */
/*
* 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 */
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
File moved
File moved
File moved
/*
* 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 */
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment