Introduce support for the Alpine PoC from Annapurna Labs

The Alpine Platform-On-Chip offers multicore processing
(quad ARM Cortex-A15), 1/10Gb Ethernet, SATA 3, PCI-E 3,
DMA engines, Virtualization, Advanced Power Management and other.

This code drop involves basic platform support including:
SMP, IRQs, SerDes, SATA. As of now it is missing the PCIe support.
Part of the functionality is provided by the low-level code (HAL)
delivered by the chip vendor (Annapurna Labs) and is a subject to
change in the future (is planned to be moved to sys/contrib directory).

The review log for this commit is available here:
https://reviews.freebsd.org/D2340

Reviewed by:    andrew, ian, imp
Obtained from:  Semihalf
Sponsored by:   Annapurna Labs
This commit is contained in:
zbb 2015-05-15 18:25:48 +00:00
parent ff64c3f311
commit a03bdb9d16
23 changed files with 14948 additions and 0 deletions

View File

@ -0,0 +1,148 @@
/*-
* Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com>
* Copyright (c) 2015 Semihalf
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#define _ARM32_BUS_DMA_PRIVATE
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <machine/bus.h>
#include <machine/frame.h> /* For trapframe_t, used in <machine/machdep.h> */
#include <machine/machdep.h>
#include <machine/pmap.h>
#include <machine/devmap.h>
#include <machine/platform.h>
#include <machine/fdt.h>
#include <dev/fdt/fdt_common.h>
#include "opt_ddb.h"
#include "opt_platform.h"
struct mtx al_dbg_lock;
#define DEVMAP_MAX_VA_ADDRESS 0xF0000000
bus_addr_t al_devmap_pa;
bus_addr_t al_devmap_size;
#define AL_NB_SERVICE_OFFSET 0x70000
#define AL_NB_CCU_OFFSET 0x90000
#define AL_CCU_SNOOP_CONTROL_IOFAB_0_OFFSET 0x4000
#define AL_CCU_SNOOP_CONTROL_IOFAB_1_OFFSET 0x5000
#define AL_CCU_SPECULATION_CONTROL_OFFSET 0x4
#define AL_NB_ACF_MISC_OFFSET 0xD0
#define AL_NB_ACF_MISC_READ_BYPASS (1 << 30)
int alpine_get_devmap_base(bus_addr_t *pa, bus_addr_t *size);
vm_offset_t
platform_lastaddr(void)
{
return (DEVMAP_MAX_VA_ADDRESS);
}
void
platform_probe_and_attach(void)
{
}
void
platform_gpio_init(void)
{
}
void
platform_late_init(void)
{
bus_addr_t reg_baddr;
uint32_t val;
if (!mtx_initialized(&al_dbg_lock))
mtx_init(&al_dbg_lock, "ALDBG", "ALDBG", MTX_SPIN);
/* configure system fabric */
if (bus_space_map(fdtbus_bs_tag, al_devmap_pa, al_devmap_size, 0,
&reg_baddr))
panic("Couldn't map Register Space area");
/* do not allow reads to bypass writes to different addresses */
val = bus_space_read_4(fdtbus_bs_tag, reg_baddr,
AL_NB_SERVICE_OFFSET + AL_NB_ACF_MISC_OFFSET);
val &= ~AL_NB_ACF_MISC_READ_BYPASS;
bus_space_write_4(fdtbus_bs_tag, reg_baddr,
AL_NB_SERVICE_OFFSET + AL_NB_ACF_MISC_OFFSET, val);
/* enable cache snoop */
bus_space_write_4(fdtbus_bs_tag, reg_baddr,
AL_NB_CCU_OFFSET + AL_CCU_SNOOP_CONTROL_IOFAB_0_OFFSET, 1);
bus_space_write_4(fdtbus_bs_tag, reg_baddr,
AL_NB_CCU_OFFSET + AL_CCU_SNOOP_CONTROL_IOFAB_1_OFFSET, 1);
/* disable speculative fetches from masters */
bus_space_write_4(fdtbus_bs_tag, reg_baddr,
AL_NB_CCU_OFFSET + AL_CCU_SPECULATION_CONTROL_OFFSET, 7);
bus_space_unmap(fdtbus_bs_tag, reg_baddr, al_devmap_size);
}
/*
* Construct pmap_devmap[] with DT-derived config data.
*/
int
platform_devmap_init(void)
{
alpine_get_devmap_base(&al_devmap_pa, &al_devmap_size);
arm_devmap_add_entry(al_devmap_pa, al_devmap_size);
return (0);
}
struct arm32_dma_range *
bus_dma_get_range(void)
{
return (NULL);
}
int
bus_dma_get_range_nb(void)
{
return (0);
}

View File

@ -0,0 +1,335 @@
/*-
* Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com>
* Copyright (c) 2015 Semihalf
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/smp.h>
#include <sys/cpuset.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <machine/smp.h>
#include <machine/fdt.h>
#include <machine/intr.h>
#include <machine/cpu-v6.h>
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/ofw_cpu.h>
#include <dev/ofw/ofw_bus_subr.h>
#define AL_CPU_RESUME_WATERMARK_REG 0x00
#define AL_CPU_RESUME_FLAGS_REG 0x04
#define AL_CPU_RESUME_PCPU_RADDR_REG(cpu) (0x08 + 0x04 + 8*(cpu))
#define AL_CPU_RESUME_PCPU_FLAGS(cpu) (0x08 + 8*(cpu))
/* Per-CPU flags */
#define AL_CPU_RESUME_FLG_PERCPU_DONT_RESUME (1 << 2)
/* The expected magic number for validating the resume addresses */
#define AL_CPU_RESUME_MAGIC_NUM 0xf0e1d200
#define AL_CPU_RESUME_MAGIC_NUM_MASK 0xffffff00
/* The expected minimal version number for validating the capabilities */
#define AL_CPU_RESUME_MIN_VER 0x000000c3
#define AL_CPU_RESUME_MIN_VER_MASK 0x000000ff
/* Field controlling the boot-up of companion cores */
#define AL_NB_INIT_CONTROL (0x8)
#define AL_NB_CONFIG_STATUS_PWR_CTRL(cpu) (0x2020 + (cpu)*0x100)
#define SERDES_NUM_GROUPS 4
#define SERDES_GROUP_SIZE 0x400
extern bus_addr_t al_devmap_pa;
extern bus_addr_t al_devmap_size;
extern void mpentry(void);
int alpine_serdes_resource_get(uint32_t group, bus_space_tag_t *tag,
bus_addr_t *baddr);
static int platform_mp_get_core_cnt(void);
static int alpine_get_cpu_resume_base(u_long *pbase, u_long *psize);
static int alpine_get_nb_base(u_long *pbase, u_long *psize);
static int alpine_get_serdes_base(u_long *pbase, u_long *psize);
int alpine_serdes_resource_get(uint32_t group, bus_space_tag_t *tag,
bus_addr_t *baddr);
static boolean_t alpine_validate_cpu(u_int, phandle_t, u_int, pcell_t *);
static boolean_t
alpine_validate_cpu(u_int id, phandle_t child, u_int addr_cell, pcell_t *reg)
{
return fdt_is_compatible(child, "arm,cortex-a15");
}
static int
platform_mp_get_core_cnt(void)
{
static int ncores = 0;
int nchilds;
uint32_t reg;
/* Calculate ncores value only once */
if (ncores)
return (ncores);
reg = cp15_l2ctlr_get();
ncores = CPUV7_L2CTLR_NPROC(reg);
nchilds = ofw_cpu_early_foreach(alpine_validate_cpu, false);
/* Limit CPUs if DTS has configured less than available */
if ((nchilds > 0) && (nchilds < ncores)) {
printf("SMP: limiting number of active CPUs to %d out of %d\n",
nchilds, ncores);
ncores = nchilds;
}
return (ncores);
}
void
platform_mp_init_secondary(void)
{
arm_init_secondary_ic();
}
void
platform_mp_setmaxid(void)
{
int core_cnt;
core_cnt = platform_mp_get_core_cnt();
mp_maxid = core_cnt - 1;
}
int
platform_mp_probe(void)
{
mp_ncpus = platform_mp_get_core_cnt();
return (1);
}
static int
alpine_get_cpu_resume_base(u_long *pbase, u_long *psize)
{
phandle_t node;
u_long base = 0;
u_long size = 0;
if (pbase == NULL || psize == NULL)
return (EINVAL);
if ((node = OF_finddevice("/")) == -1)
return (EFAULT);
if ((node =
ofw_bus_find_compatible(node, "annapurna-labs,al-cpu-resume")) == 0)
return (EFAULT);
if (fdt_regsize(node, &base, &size))
return (EFAULT);
*pbase = base;
*psize = size;
return (0);
}
static int
alpine_get_nb_base(u_long *pbase, u_long *psize)
{
phandle_t node;
u_long base = 0;
u_long size = 0;
if (pbase == NULL || psize == NULL)
return (EINVAL);
if ((node = OF_finddevice("/")) == -1)
return (EFAULT);
if ((node =
ofw_bus_find_compatible(node, "annapurna-labs,al-nb-service")) == 0)
return (EFAULT);
if (fdt_regsize(node, &base, &size))
return (EFAULT);
*pbase = base;
*psize = size;
return (0);
}
void
platform_mp_start_ap(void)
{
uint32_t physaddr;
vm_offset_t vaddr;
uint32_t val;
uint32_t start_mask;
u_long cpu_resume_base;
u_long nb_base;
u_long cpu_resume_size;
u_long nb_size;
bus_addr_t cpu_resume_baddr;
bus_addr_t nb_baddr;
int a;
if (alpine_get_cpu_resume_base(&cpu_resume_base, &cpu_resume_size))
panic("Couldn't resolve cpu_resume_base address\n");
if (alpine_get_nb_base(&nb_base, &nb_size))
panic("Couldn't resolve_nb_base address\n");
/* Proceed with start addresses for additional CPUs */
if (bus_space_map(fdtbus_bs_tag, al_devmap_pa + cpu_resume_base,
cpu_resume_size, 0, &cpu_resume_baddr))
panic("Couldn't map CPU-resume area");
if (bus_space_map(fdtbus_bs_tag, al_devmap_pa + nb_base,
nb_size, 0, &nb_baddr))
panic("Couldn't map NB-service area");
/* Proceed with start addresses for additional CPUs */
val = bus_space_read_4(fdtbus_bs_tag, cpu_resume_baddr,
AL_CPU_RESUME_WATERMARK_REG);
if (((val & AL_CPU_RESUME_MAGIC_NUM_MASK) != AL_CPU_RESUME_MAGIC_NUM) ||
((val & AL_CPU_RESUME_MIN_VER_MASK) < AL_CPU_RESUME_MIN_VER)) {
panic("CPU-resume device is not compatible");
}
vaddr = (vm_offset_t)mpentry;
physaddr = pmap_kextract(vaddr);
for (a = 1; a < platform_mp_get_core_cnt(); a++) {
/* Power up the core */
bus_space_write_4(fdtbus_bs_tag, nb_baddr,
AL_NB_CONFIG_STATUS_PWR_CTRL(a), 0);
mb();
/* Enable resume */
val = bus_space_read_4(fdtbus_bs_tag, cpu_resume_baddr,
AL_CPU_RESUME_PCPU_FLAGS(a));
val &= ~AL_CPU_RESUME_FLG_PERCPU_DONT_RESUME;
bus_space_write_4(fdtbus_bs_tag, cpu_resume_baddr,
AL_CPU_RESUME_PCPU_FLAGS(a), val);
mb();
/* Set resume physical address */
bus_space_write_4(fdtbus_bs_tag, cpu_resume_baddr,
AL_CPU_RESUME_PCPU_RADDR_REG(a), physaddr);
mb();
}
/* Release cores from reset */
if (bus_space_map(fdtbus_bs_tag, al_devmap_pa + nb_base,
nb_size, 0, &nb_baddr))
panic("Couldn't map NB-service area");
start_mask = (1 << platform_mp_get_core_cnt()) - 1;
/* Release cores from reset */
val = bus_space_read_4(fdtbus_bs_tag, nb_baddr, AL_NB_INIT_CONTROL);
val |= start_mask;
bus_space_write_4(fdtbus_bs_tag, nb_baddr, AL_NB_INIT_CONTROL, val);
dsb();
bus_space_unmap(fdtbus_bs_tag, nb_baddr, nb_size);
bus_space_unmap(fdtbus_bs_tag, cpu_resume_baddr, cpu_resume_size);
}
static int
alpine_get_serdes_base(u_long *pbase, u_long *psize)
{
phandle_t node;
u_long base = 0;
u_long size = 0;
if (pbase == NULL || psize == NULL)
return (EINVAL);
if ((node = OF_finddevice("/")) == -1)
return (EFAULT);
if ((node =
ofw_bus_find_compatible(node, "annapurna-labs,al-serdes")) == 0)
return (EFAULT);
if (fdt_regsize(node, &base, &size))
return (EFAULT);
*pbase = base;
*psize = size;
return (0);
}
int
alpine_serdes_resource_get(uint32_t group, bus_space_tag_t *tag, bus_addr_t *baddr)
{
u_long serdes_base, serdes_size;
int ret;
static bus_addr_t baddr_mapped[SERDES_NUM_GROUPS];
if (group >= SERDES_NUM_GROUPS)
return (EINVAL);
if (baddr_mapped[group]) {
*tag = fdtbus_bs_tag;
*baddr = baddr_mapped[group];
return (0);
}
ret = alpine_get_serdes_base(&serdes_base, &serdes_size);
if (ret)
return (ret);
ret = bus_space_map(fdtbus_bs_tag,
al_devmap_pa + serdes_base + group * SERDES_GROUP_SIZE,
(SERDES_NUM_GROUPS - group) * SERDES_GROUP_SIZE, 0, baddr);
if (ret)
return (ret);
baddr_mapped[group] = *baddr;
return (0);
}
void
platform_ipi_send(cpuset_t cpus, u_int ipi)
{
pic_ipi_send(cpus, ipi);
}

View File

@ -0,0 +1,158 @@
/*-
* Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com>
* Copyright (c) 2015 Semihalf.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/bus.h>
#include <sys/kernel.h>
#include <dev/fdt/fdt_common.h>
#include <dev/ofw/openfirm.h>
#include <machine/bus.h>
#include <machine/fdt.h>
#include <machine/intr.h>
#define WDTLOAD 0x000
#define LOAD_MIN 0x00000001
#define LOAD_MAX 0xFFFFFFFF
#define WDTVALUE 0x004
#define WDTCONTROL 0x008
/* control register masks */
#define INT_ENABLE (1 << 0)
#define RESET_ENABLE (1 << 1)
#define WDTLOCK 0xC00
#define UNLOCK 0x1ACCE551
#define LOCK 0x00000001
extern bus_addr_t al_devmap_pa;
struct fdt_fixup_entry fdt_fixup_table[] = {
{ NULL, NULL }
};
static int alpine_get_wdt_base(uint32_t *pbase, uint32_t *psize);
static int alpine_pic_decode_fdt(uint32_t iparent, uint32_t *intr,
int *interrupt, int *trig, int *pol);
int alpine_get_devmap_base(bus_addr_t *pa, bus_addr_t *size);
int alpine_get_devmap_base(bus_addr_t *pa, bus_addr_t *size)
{
phandle_t node;
if ((node = OF_finddevice("/")) == 0)
return (ENXIO);
if ((node = fdt_find_compatible(node, "simple-bus", 1)) == 0)
return (ENXIO);
return fdt_get_range(node, 0, pa, size);
}
static int
alpine_get_wdt_base(uint32_t *pbase, uint32_t *psize)
{
phandle_t node;
u_long base = 0;
u_long size = 0;
if (pbase == NULL || psize == NULL)
return (EINVAL);
if ((node = OF_finddevice("/")) == -1)
return (EFAULT);
if ((node = fdt_find_compatible(node, "simple-bus", 1)) == 0)
return (EFAULT);
if ((node =
fdt_find_compatible(node, "arm,sp805", 1)) == 0)
return (EFAULT);
if (fdt_regsize(node, &base, &size))
return (EFAULT);
*pbase = base;
*psize = size;
return (0);
}
void
cpu_reset(void)
{
uint32_t wdbase, wdsize;
bus_addr_t wdbaddr;
int ret;
ret = alpine_get_wdt_base(&wdbase, &wdsize);
if (ret) {
printf("Unable to get WDT base, do power down manually...");
goto infinite;
}
ret = bus_space_map(fdtbus_bs_tag, al_devmap_pa + wdbase,
wdsize, 0, &wdbaddr);
if (ret) {
printf("Unable to map WDT base, do power down manually...");
goto infinite;
}
bus_space_write_4(fdtbus_bs_tag, wdbaddr, WDTLOCK, UNLOCK);
bus_space_write_4(fdtbus_bs_tag, wdbaddr, WDTLOAD, LOAD_MIN);
bus_space_write_4(fdtbus_bs_tag, wdbaddr, WDTCONTROL, INT_ENABLE | RESET_ENABLE);
infinite:
while (1) {}
}
static int
alpine_pic_decode_fdt(uint32_t iparent, uint32_t *intr, int *interrupt,
int *trig, int *pol)
{
int rv = 0;
rv = gic_decode_fdt(iparent, intr, interrupt, trig, pol);
if (rv == 0) {
/* This was recognized as our PIC and decoded. */
interrupt = FDT_MAP_IRQ(iparent, interrupt);
/* Configure the interrupt if callback provided */
if (arm_config_irq)
(*arm_config_irq)(*interrupt, *trig, *pol);
}
return (rv);
}
fdt_pic_decode_t fdt_pic_table[] = {
&alpine_pic_decode_fdt,
NULL
};

View File

@ -0,0 +1,16 @@
# $FreeBSD$
kern/kern_clocksource.c standard
arm/arm/bus_space_base.c standard
arm/arm/bus_space_generic.c standard
arm/arm/bus_space_asm_generic.S standard
arm/versatile/sp804.c standard
arm/versatile/versatile_timer.c standard
dev/uart/uart_dev_ns8250.c optional uart
dev/ofw/ofw_cpu.c standard
arm/annapurna/alpine/common.c standard
arm/annapurna/alpine/alpine_machdep.c standard
arm/annapurna/alpine/alpine_machdep_mp.c optional smp

View File

@ -0,0 +1,70 @@
/*-
********************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @defgroup group_common HAL Common Layer
* Includes all common header files used by HAL
* @{
* @file al_hal_common.h
*
*/
#ifndef __AL_HAL_COMMON_H__
#define __AL_HAL_COMMON_H__
#include "al_hal_plat_types.h"
#include "al_hal_plat_services.h"
#include "al_hal_types.h"
#include "al_hal_reg_utils.h"
/* Get the maximal value out of two typed values */
#define al_max_t(type, x, y) ({ \
type __max1 = (x); \
type __max2 = (y); \
__max1 > __max2 ? __max1 : __max2; })
/* Get the minimal value out of two typed values */
#define al_min_t(type, x, y) ({ \
type __min1 = (x); \
type __min2 = (y); \
__min1 < __min2 ? __min1 : __min2; })
/* Get the number of elements in an array */
#define AL_ARR_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
/** @} end of Common group */
#endif /* __AL_HAL_COMMON_H__ */

View File

@ -0,0 +1,222 @@
/*-
********************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @defgroup group_interrupts Common I/O Fabric Interrupt Controller
* This HAL provides the API for programming the Common I/O Fabric Interrupt
* Controller (IOFIC) found in most of the units attached to the I/O Fabric of
* Alpine platform
* @{
* @file al_hal_iofic.h
*
* @brief Header file for the interrupt controller that's embedded in various units
*
*/
#ifndef __AL_HAL_IOFIC_H__
#define __AL_HAL_IOFIC_H__
#include <al_hal_common.h>
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
#define AL_IOFIC_MAX_GROUPS 4
/*
* Configurations
*/
/**
* Configure the interrupt controller registers, actual interrupts are still
* masked at this stage.
*
* @param regs_base regs pointer to interrupt controller registers
* @param group the interrupt group.
* @param flags flags of Interrupt Control Register
*
* @return 0 on success. -EINVAL otherwise.
*/
int al_iofic_config(void __iomem *regs_base, int group,
uint32_t flags);
/**
* configure the moderation timer resolution for a given group
* Applies for both msix and legacy mode.
*
* @param regs_base pointer to unit registers
* @param group the interrupt group
* @param resolution resolution of the timer interval, the resolution determines the rate
* of decrementing the interval timer, setting value N means that the interval
* timer will be decremented each (N+1) * (0.68) micro seconds.
*
* @return 0 on success. -EINVAL otherwise.
*/
int al_iofic_moder_res_config(void __iomem *regs_base, int group,
uint8_t resolution);
/**
* configure the moderation timer interval for a given legacy interrupt group
*
* @param regs_base regs pointer to unit registers
* @param group the interrupt group
* @param interval between interrupts in resolution units. 0 disable
*
* @return 0 on success. -EINVAL otherwise.
*/
int al_iofic_legacy_moder_interval_config(void __iomem *regs_base, int group,
uint8_t interval);
/**
* configure the moderation timer interval for a given msix vector
*
* @param regs_base pointer to unit registers
* @param group the interrupt group
* @param vector vector index
* @param interval interval between interrupts, 0 disable
*
* @return 0 on success. -EINVAL otherwise.
*/
int al_iofic_msix_moder_interval_config(void __iomem *regs_base, int group,
uint8_t vector, uint8_t interval);
/**
* configure the vmid attributes for a given msix vector.
*
* @param group the interrupt group
* @param vector index
* @param vmid the vmid value
* @param vmid_en take vmid from the intc
*
* @return 0 on success. -EINVAL otherwise.
*/
int al_iofic_msix_vmid_attributes_config(void __iomem *regs_base, int group,
uint8_t vector, uint32_t vmid, uint8_t vmid_en);
/**
* return the offset of the unmask register for a given group.
* this function can be used when the upper layer wants to directly
* access the unmask regiter and bypass the al_iofic_unmask() API.
*
* @param regs_base regs pointer to unit registers
* @param group the interrupt group
* @return the offset of the unmask register.
*/
uint32_t __iomem * al_iofic_unmask_offset_get(void __iomem *regs_base, int group);
/**
* unmask specific interrupts for a given group
* this functions guarantees atomic operations, it is performance optimized as
* it will not require read-modify-write. The unmask done using the interrupt
* mask clear register, so it's safe to call it while the mask is changed by
* the HW (auto mask) or another core.
*
* @param regs_base pointer to unit registers
* @param group the interrupt group
* @param mask bitwise of interrupts to unmask, set bits will be unmasked.
*/
void al_iofic_unmask(void __iomem *regs_base, int group, uint32_t mask);
/**
* mask specific interrupts for a given group
* this functions modifies interrupt mask register, the callee must make sure
* the mask is not changed by another cpu.
*
* @param regs_base pointer to unit registers
* @param group the interrupt group
* @param mask bitwise of interrupts to mask, set bits will be masked.
*/
void al_iofic_mask(void __iomem *regs_base, int group, uint32_t mask);
/**
* read the mask register for a given group
* this functions return the interrupt mask register
*
* @param regs_base pointer to unit registers
* @param group the interrupt group
*/
uint32_t al_iofic_read_mask(void __iomem *regs_base, int group);
/**
* read interrupt cause register for a given group
* this will clear the set bits if the Clear on Read mode enabled.
* @param regs_base pointer to unit registers
* @param group the interrupt group
*/
uint32_t al_iofic_read_cause(void __iomem *regs_base, int group);
/**
* clear bits in the interrupt cause register for a given group
*
* @param regs_base pointer to unit registers
* @param group the interrupt group
* @param mask bitwise of bits to be cleared, set bits will be cleared.
*/
void al_iofic_clear_cause(void __iomem *regs_base, int group, uint32_t mask);
/**
* set the cause register for a given group
* this function set the cause register. It will generate an interrupt (if
* the the interrupt isn't masked )
*
* @param regs_base pointer to unit registers
* @param group the interrupt group
* @param mask bitwise of bits to be set.
*/
void al_iofic_set_cause(void __iomem *regs_base, int group, uint32_t mask);
/**
* unmask specific interrupts from aborting the udma a given group
*
* @param regs_base pointer to unit registers
* @param group the interrupt group
* @param mask bitwise of interrupts to mask
*/
void al_iofic_abort_mask(void __iomem *regs_base, int group, uint32_t mask);
/**
* trigger all interrupts that are waiting for moderation timers to expire
*
* @param regs_base pointer to unit registers
* @param group the interrupt group
*/
void al_iofic_interrupt_moderation_reset(void __iomem *regs_base, int group);
#endif
/** @} end of interrupt controller group */

View File

@ -0,0 +1,127 @@
/*_
********************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef __AL_HAL_IOFIC_REG_H
#define __AL_HAL_IOFIC_REG_H
#ifdef __cplusplus
extern "C" {
#endif
/*
* Unit Registers
*/
struct al_iofic_grp_ctrl {
uint32_t int_cause_grp; /* Interrupt Cause RegisterSet by hardware */
uint32_t rsrvd1;
uint32_t int_cause_set_grp; /* Interrupt Cause Set RegisterWriting 1 to a bit in t ... */
uint32_t rsrvd2;
uint32_t int_mask_grp; /* Interrupt Mask RegisterIf Auto-mask control bit =TR ... */
uint32_t rsrvd3;
uint32_t int_mask_clear_grp; /* Interrupt Mask Clear RegisterUsed when auto-mask co ... */
uint32_t rsrvd4;
uint32_t int_status_grp; /* Interrupt status RegisterThis register latch the st ... */
uint32_t rsrvd5;
uint32_t int_control_grp; /* Interrupt Control Register */
uint32_t rsrvd6;
uint32_t int_abort_msk_grp; /* Interrupt Mask RegisterEach bit in this register ma ... */
uint32_t rsrvd7;
uint32_t int_log_msk_grp; /* Interrupt Log RegisterEach bit in this register mas ... */
uint32_t rsrvd8;
};
struct al_iofic_grp_mod {
uint32_t grp_int_mod_reg; /* Interrupt moderation registerDedicated moderation in ... */
uint32_t grp_int_vmid_reg;
};
struct al_iofic_regs {
struct al_iofic_grp_ctrl ctrl[0];
uint32_t rsrvd1[0x400 >> 2];
struct al_iofic_grp_mod grp_int_mod[0][32];
};
/*
* Registers Fields
*/
/**** int_control_grp register ****/
/* When Clear_on_Read =1, All bits of Cause register ... */
#define INT_CONTROL_GRP_CLEAR_ON_READ (1 << 0)
/* (must be set only when MSIX is enabled)When Auto-Ma ... */
#define INT_CONTROL_GRP_AUTO_MASK (1 << 1)
/* Auto_Clear (RW)When Auto-Clear =1, the bits in the ... */
#define INT_CONTROL_GRP_AUTO_CLEAR (1 << 2)
/* When Set_on_Posedge =1, the bits in the interrupt c ... */
#define INT_CONTROL_GRP_SET_ON_POSEDGE (1 << 3)
/* When Moderation_Reset =1, all Moderation timers ass ... */
#define INT_CONTROL_GRP_MOD_RST (1 << 4)
/* When mask_msi_x =1, No MSI-X from this group is sen ... */
#define INT_CONTROL_GRP_MASK_MSI_X (1 << 5)
/* MSI-X AWID value, same ID for all cause bits */
#define INT_CONTROL_GRP_AWID_MASK 0x00000F00
#define INT_CONTROL_GRP_AWID_SHIFT 8
/* This value determines the interval between interrup ... */
#define INT_CONTROL_GRP_MOD_INTV_MASK 0x00FF0000
#define INT_CONTROL_GRP_MOD_INTV_SHIFT 16
/* This value determines the Moderation_Timer_Clock sp ... */
#define INT_CONTROL_GRP_MOD_RES_MASK 0x0F000000
#define INT_CONTROL_GRP_MOD_RES_SHIFT 24
/**** grp_int_mod_reg register ****/
/* Interrupt Moderation Interval registerDedicated reg ... */
#define INT_MOD_INTV_MASK 0x000000FF
#define INT_MOD_INTV_SHIFT 0
/**** grp_int_vmid_reg register ****/
/* Interrupt vmid value registerDedicated reg ... */
#define INT_MSIX_VMID_MASK 0x0000FFFF
#define INT_MSIX_VMID_SHIFT 0
/* Interrupt vmid_en value registerDedicated reg ... */
#define INT_MSIX_VMID_EN_SHIFT 31
#ifdef __cplusplus
}
#endif
#endif /* __AL_HAL_IOFIC_REG_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,271 @@
/*-
********************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef _AL_HAL_PCIE_INTERRUPTS_H_
#define _AL_HAL_PCIE_INTERRUPTS_H_
#include "al_hal_common.h"
#include "al_hal_pcie.h"
#include "al_hal_iofic.h"
/**
* @defgroup group_pcie_interrupts PCIe interrupts
* @ingroup grouppcie
* @{
* The PCIe interrupts HAL can be used to control PCIe unit interrupts.
* There are 5 groups of interrupts: app group A, B, C, D and AXI.
* Only 2 interrupts go from the pcie unit to the GIC:
* 1. Summary for all the int groups (AXI+APP CORE).
* 2. INTA assert/deassert (RC only).
* For the specific GIC interrupt line, please check the architecture reference
* manual.
* The reset mask state of all interrupts is: Masked
*
* @file al_hal_pcie_interrupts.h
*
*/
/**
* PCIe interrupt groups
*/
enum al_pcie_int_group {
AL_PCIE_INT_GRP_A,
AL_PCIE_INT_GRP_B,
AL_PCIE_INT_GRP_C, /* Rev3 only */
AL_PCIE_INT_GRP_D, /* Rev3 only */
AL_PCIE_INT_GRP_AXI_A,
};
/**
* App group A interrupts mask - don't change
* All interrupts not listed below should be masked
*/
enum al_pcie_app_int_grp_a {
/** [RC only] Deassert_INTD received */
AL_PCIE_APP_INT_DEASSERT_INTD = AL_BIT(0),
/** [RC only] Deassert_INTC received */
AL_PCIE_APP_INT_DEASSERT_INTC = AL_BIT(1),
/** [RC only] Deassert_INTB received */
AL_PCIE_APP_INT_DEASSERT_INTB = AL_BIT(2),
/**
* [RC only] Deassert_INTA received - there's a didcated GIC interrupt
* line that reflects the status of ASSERT/DEASSERT of INTA
*/
AL_PCIE_APP_INT_DEASSERT_INTA = AL_BIT(3),
/** [RC only] Assert_INTD received */
AL_PCIE_APP_INT_ASSERT_INTD = AL_BIT(4),
/** [RC only] Assert_INTC received */
AL_PCIE_APP_INT_ASSERT_INTC = AL_BIT(5),
/** [RC only] Assert_INTB received */
AL_PCIE_APP_INT_ASSERT_INTB = AL_BIT(6),
/**
* [RC only] Assert_INTA received - there's a didcated GIC interrupt
* line that reflects the status of ASSERT/DEASSERT of INTA
*/
AL_PCIE_APP_INT_ASSERT_INTA = AL_BIT(7),
/** [RC only] MSI Controller Interrupt */
AL_PCIE_APP_INT_MSI_CNTR_RCV_INT = AL_BIT(8),
/** [EP only] MSI sent grant */
AL_PCIE_APP_INT_MSI_TRNS_GNT = AL_BIT(9),
/** [RC only] System error detected (ERR_COR, ERR_FATAL, ERR_NONFATAL) */
AL_PCIE_APP_INT_SYS_ERR_RC = AL_BIT(10),
/** [EP only] Software initiates FLR on a Physical Function */
AL_PCIE_APP_INT_FLR_PF_ACTIVE = AL_BIT(11),
/** [RC only] Root Error Command register assertion notification */
AL_PCIE_APP_INT_AER_RC_ERR = AL_BIT(12),
/** [RC only] Root Error Command register assertion notification With MSI or MSIX enabled */
AL_PCIE_APP_INT_AER_RC_ERR_MSI = AL_BIT(13),
/** [RC only] PME Status bit assertion in the Root Status register With INTA */
AL_PCIE_APP_INT_PME_INT = AL_BIT(15),
/** [RC only] PME Status bit assertion in the Root Status register With MSI or MSIX enabled */
AL_PCIE_APP_INT_PME_MSI = AL_BIT(16),
/** [RC/EP] The core assert link down event, whenever the link is going down */
AL_PCIE_APP_INT_LINK_DOWN = AL_BIT(21),
/** [EP only] When the EP gets a command to shut down, signal the software to block any new TLP. */
AL_PCIE_APP_INT_PM_XTLH_BLOCK_TLP = AL_BIT(22),
/** [RC/EP] PHY/MAC link up */
AL_PCIE_APP_INT_XMLH_LINK_UP = AL_BIT(23),
/** [RC/EP] Data link up */
AL_PCIE_APP_INT_RDLH_LINK_UP = AL_BIT(24),
/** [RC/EP] The LTSSM is in RCVRY_LOCK state. */
AL_PCIE_APP_INT_LTSSM_RCVRY_STATE = AL_BIT(25),
/**
* [RC/EP] CFG write transaction to the configuration space by the RC peer
* For RC the int/ will be set from DBI write (internal SoC write)]
*/
AL_PCIE_APP_INT_CFG_WR = AL_BIT(26),
/** [EP only] CFG access in EP mode */
AL_PCIE_APP_INT_CFG_ACCESS = AL_BIT(31),
};
/**
* App group B interrupts mask - don't change
* All interrupts not listed below should be masked
*/
enum al_pcie_app_int_grp_b {
/** [RC only] PM_PME Message received */
AL_PCIE_APP_INT_GRP_B_PM_PME_MSG_RCVD = AL_BIT(0),
/** [RC only] PME_TO_Ack Message received */
AL_PCIE_APP_INT_GRP_B_PME_TO_ACK_MSG_RCVD = AL_BIT(1),
/** [EP only] PME_Turn_Off Message received */
AL_PCIE_APP_INT_GRP_B_PME_TURN_OFF_MSG_RCVD = AL_BIT(2),
/** [RC only] ERR_CORR Message received */
AL_PCIE_APP_INT_GRP_B_CORR_ERR_MSG_RCVD = AL_BIT(3),
/** [RC only] ERR_NONFATAL Message received */
AL_PCIE_APP_INT_GRP_B_NON_FTL_ERR_MSG_RCVD = AL_BIT(4),
/** [RC only] ERR_FATAL Message received */
AL_PCIE_APP_INT_GRP_B_FTL_ERR_MSG_RCVD = AL_BIT(5),
/**
* [RC/EP] Vendor Defined Message received
* Asserted when a vevdor message is received (with no data), buffers 2
* messages only, and latch the headers in registers
*/
AL_PCIE_APP_INT_GRP_B_VNDR_MSG_A_RCVD = AL_BIT(6),
/**
* [RC/EP] Vendor Defined Message received
* Asserted when a vevdor message is received (with no data), buffers 2
* messages only, and latch the headers in registers
*/
AL_PCIE_APP_INT_GRP_B_VNDR_MSG_B_RCVD = AL_BIT(7),
/** [EP only] Link Autonomous Bandwidth Status is updated */
AL_PCIE_APP_INT_GRP_B_LNK_BW_UPD = AL_BIT(12),
/** [EP only] Link Equalization Request bit in the Link Status 2 Register has been set */
AL_PCIE_APP_INT_GRP_B_LNK_EQ_REQ = AL_BIT(13),
/** [RC/EP] OB Vendor message request is granted by the PCIe core */
AL_PCIE_APP_INT_GRP_B_OB_VNDR_MSG_REQ_GRNT = AL_BIT(14),
/** [RC only] CPL timeout from the PCIe core indiication */
AL_PCIE_APP_INT_GRP_B_CPL_TO = AL_BIT(15),
/** [RC/EP] Slave Response Composer Lookup Error */
AL_PCIE_APP_INT_GRP_B_SLV_RESP_COMP_LKUP_ERR = AL_BIT(16),
/** [RC/EP] Parity Error */
AL_PCIE_APP_INT_GRP_B_PARITY_ERR = AL_BIT(17),
/** [EP only] Speed change request */
AL_PCIE_APP_INT_GRP_B_SPEED_CHANGE = AL_BIT(31),
};
/**
* AXI interrupts mask - don't change
* These are internal errors that can happen on the internal chip interface
* between the PCIe port and the I/O Fabric over the AXI bus. The notion of
* master and slave refer to the PCIe port master interface towards the I/O
* Fabric (i.e. for inbound PCIe writes/reads toward the I/O Fabric), while the
* slave interface refer to the I/O Fabric to PCIe port interface where the
* internal chip DMAs and CPU cluster is initiating transactions.
* All interrupts not listed below should be masked.
*/
enum al_pcie_axi_int {
/** [RC/EP] Master Response Composer Lookup Error */
AL_PCIE_AXI_INT_MSTR_RESP_COMP_LKUP_ERR = AL_BIT(0),
/** [RC/EP] PARITY ERROR on the master data read channel */
AL_PCIE_AXI_INT_PARITY_ERR_MSTR_DATA_RD_CHNL = AL_BIT(2),
/** [RC/EP] PARITY ERROR on the slave addr read channel */
AL_PCIE_AXI_INT_PARITY_ERR_SLV_ADDR_RD_CHNL = AL_BIT(3),
/** [RC/EP] PARITY ERROR on the slave addr write channel */
AL_PCIE_AXI_INT_PARITY_ERR_SLV_ADDR_WR_CHNL = AL_BIT(4),
/** [RC/EP] PARITY ERROR on the slave data write channel */
AL_PCIE_AXI_INT_PARITY_ERR_SLV_DATA_WR_CHNL = AL_BIT(5),
/** [RC only] Software error: ECAM write request with invalid bus number */
AL_PCIE_AXI_INT_ECAM_WR_REQ_INVLD_BUS_NUM = AL_BIT(7),
/** [RC only] Software error: ECAM read request with invalid bus number */
AL_PCIE_AXI_INT_ECAM_RD_REQ_INVLD_BUS_NUM = AL_BIT(8),
/** [RC/EP] Read AXI completion has ERROR */
AL_PCIE_AXI_INT_RD_AXI_COMPL_ERR = AL_BIT(11),
/** [RC/EP] Write AXI completion has ERROR */
AL_PCIE_AXI_INT_WR_AXI_COMPL_ERR = AL_BIT(12),
/** [RC/EP] Read AXI completion has timed out */
AL_PCIE_AXI_INT_RD_AXI_COMPL_TO = AL_BIT(13),
/** [RC/EP] Write AXI completion has timed out */
AL_PCIE_AXI_INT_WR_AXI_COMPL_TO = AL_BIT(14),
/** [RC/EP] Parity error AXI domain */
AL_PCIE_AXI_INT_AXI_DOM_PARITY_ERR = AL_BIT(15),
/** [RC/EP] POS error interrupt */
AL_PCIE_AXI_INT_POS_ERR = AL_BIT(16),
};
/**
* @brief Initialize and configure PCIe controller interrupts
* Doesn't change the mask state of the interrupts
* The reset mask state of all interrupts is: Masked
*
* @param pcie_port pcie port handle
*/
void al_pcie_ints_config(struct al_pcie_port *pcie_port);
/**
* Unmask PCIe app group interrupts
* @param pcie_port pcie_port pcie port handle
* @param int_group interrupt group
* @param int_mask int_mask interrupts to unmask ('1' to unmask)
*/
void al_pcie_app_int_grp_unmask(
struct al_pcie_port *pcie_port,
enum al_pcie_int_group int_group,
uint32_t int_mask);
/**
* Mask PCIe app group interrupts
* @param pcie_port pcie_port pcie port handle
* @param int_group interrupt group
* @param int_mask int_mask interrupts to unmask ('1' to mask)
*/
void al_pcie_app_int_grp_mask(
struct al_pcie_port *pcie_port,
enum al_pcie_int_group int_group,
uint32_t int_mask);
/**
* Clear the PCIe app group interrupt cause
* @param pcie_port pcie port handle
* @param int_group interrupt group
* @param int_cause interrupt cause
*/
void al_pcie_app_int_grp_cause_clear(
struct al_pcie_port *pcie_port,
enum al_pcie_int_group int_group,
uint32_t int_cause);
/**
* Read PCIe app group interrupt cause
* @param pcie_port pcie port handle
* @param int_group interrupt group
* @return interrupt cause or 0 in case the group is not supported
*/
uint32_t al_pcie_app_int_grp_cause_read(
struct al_pcie_port *pcie_port,
enum al_pcie_int_group int_group);
#endif
/** @} end of group_pcie_interrupts group */

View File

@ -0,0 +1,594 @@
/*-
********************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef __AL_HAL_PCIE_REGS_H__
#define __AL_HAL_PCIE_REGS_H__
/* Note: Definitions before the includes so axi/wrapper regs sees them */
/** Maximum physical functions supported */
#define REV1_2_MAX_NUM_OF_PFS 1
#define REV3_MAX_NUM_OF_PFS 4
#define AL_MAX_NUM_OF_PFS 4 /* the maximum between all Revisions */
#include "al_hal_pcie_axi_reg.h"
#ifndef AL_PCIE_EX
#include "al_hal_pcie_w_reg.h"
#else
#include "al_hal_pcie_w_reg_ex.h"
#endif
/**
* Revision IDs:
* ID_0: SlickRock M0
* ID_1: SlickRock A0
* ID_2: PeakRock x4
* ID_3: PeakRock x8
*/
#define AL_PCIE_REV_ID_0 0
#define AL_PCIE_REV_ID_1 1
#define AL_PCIE_REV_ID_2 2
#define AL_PCIE_REV_ID_3 3
#define AL_PCIE_AXI_REGS_OFFSET 0x0
#define AL_PCIE_REV_1_2_APP_REGS_OFFSET 0x1000
#define AL_PCIE_REV_3_APP_REGS_OFFSET 0x2000
#define AL_PCIE_REV_1_2_CORE_CONF_BASE_OFFSET 0x2000
#define AL_PCIE_REV_3_CORE_CONF_BASE_OFFSET 0x10000
/** Maximum number of lanes supported */
#define REV1_2_MAX_NUM_LANES 4
#define REV3_MAX_NUM_LANES 8
#define AL_MAX_NUM_OF_LANES 8 /* the maximum between all Revisions */
struct al_pcie_core_iatu_regs {
uint32_t index;
uint32_t cr1;
uint32_t cr2;
uint32_t lower_base_addr;
uint32_t upper_base_addr;
uint32_t limit_addr;
uint32_t lower_target_addr;
uint32_t upper_target_addr;
uint32_t cr3;
uint32_t rsrvd[(0x270 - 0x224) >> 2];
};
struct al_pcie_core_port_regs {
uint32_t ack_lat_rply_timer;
uint32_t reserved1[(0x10 - 0x4) >> 2];
uint32_t port_link_ctrl;
uint32_t reserved2[(0x18 - 0x14) >> 2];
uint32_t timer_ctrl_max_func_num;
uint32_t filter_mask_reg_1;
uint32_t reserved3[(0x48 - 0x20) >> 2];
uint32_t vc0_posted_rcv_q_ctrl;
uint32_t vc0_non_posted_rcv_q_ctrl;
uint32_t vc0_comp_rcv_q_ctrl;
uint32_t reserved4[(0x10C - 0x54) >> 2];
uint32_t gen2_ctrl;
uint32_t reserved5[(0x190 - 0x110) >> 2];
uint32_t gen3_ctrl;
uint32_t gen3_eq_fs_lf;
uint32_t gen3_eq_preset_to_coef_map;
uint32_t gen3_eq_preset_idx;
uint32_t reserved6;
uint32_t gen3_eq_status;
uint32_t gen3_eq_ctrl;
uint32_t reserved7[(0x1B8 - 0x1AC) >> 2];
uint32_t pipe_loopback_ctrl;
uint32_t rd_only_wr_en;
uint32_t reserved8[(0x1D0 - 0x1C0) >> 2];
uint32_t axi_slave_err_resp;
uint32_t reserved9[(0x200 - 0x1D4) >> 2];
struct al_pcie_core_iatu_regs iatu;
uint32_t reserved10[(0x448 - 0x270) >> 2];
};
struct al_pcie_core_aer_regs {
/* 0x0 - PCI Express Extended Capability Header */
uint32_t header;
/* 0x4 - Uncorrectable Error Status Register */
uint32_t uncorr_err_stat;
/* 0x8 - Uncorrectable Error Mask Register */
uint32_t uncorr_err_mask;
/* 0xc - Uncorrectable Error Severity Register */
uint32_t uncorr_err_severity;
/* 0x10 - Correctable Error Status Register */
uint32_t corr_err_stat;
/* 0x14 - Correctable Error Mask Register */
uint32_t corr_err_mask;
/* 0x18 - Advanced Error Capabilities and Control Register */
uint32_t cap_and_ctrl;
/* 0x1c - Header Log Registers */
uint32_t header_log[4];
/* 0x2c - Root Error Command Register */
uint32_t root_err_cmd;
/* 0x30 - Root Error Status Register */
uint32_t root_err_stat;
/* 0x34 - Error Source Identification Register */
uint32_t err_src_id;
};
struct al_pcie_core_reg_space_rev_1_2 {
uint32_t config_header[0x40 >> 2];
uint32_t pcie_pm_cap_base;
uint32_t reserved1[(0x70 - 0x44) >> 2];
uint32_t pcie_cap_base;
uint32_t pcie_dev_cap_base;
uint32_t pcie_dev_ctrl_status;
uint32_t pcie_link_cap_base;
uint32_t reserved2[(0xB0 - 0x80) >> 2];
uint32_t msix_cap_base;
uint32_t reserved3[(0x100 - 0xB4) >> 2];
struct al_pcie_core_aer_regs aer;
uint32_t reserved4[(0x150 -
(0x100 +
sizeof(struct al_pcie_core_aer_regs))) >> 2];
uint32_t pcie_sec_ext_cap_base;
uint32_t reserved5[(0x700 - 0x154) >> 2];
struct al_pcie_core_port_regs port_regs;
uint32_t reserved6[(0x1000 -
(0x700 +
sizeof(struct al_pcie_core_port_regs))) >> 2];
};
struct al_pcie_core_reg_space_rev_3 {
uint32_t config_header[0x40 >> 2];
uint32_t pcie_pm_cap_base;
uint32_t reserved1[(0x70 - 0x44) >> 2];
uint32_t pcie_cap_base;
uint32_t pcie_dev_cap_base;
uint32_t pcie_dev_ctrl_status;
uint32_t pcie_link_cap_base;
uint32_t reserved2[(0xB0 - 0x80) >> 2];
uint32_t msix_cap_base;
uint32_t reserved3[(0x100 - 0xB4) >> 2];
struct al_pcie_core_aer_regs aer;
uint32_t reserved4[(0x158 -
(0x100 +
sizeof(struct al_pcie_core_aer_regs))) >> 2];
/* pcie_sec_cap is only applicable for function 0 */
uint32_t pcie_sec_ext_cap_base;
uint32_t reserved5[(0x178 - 0x15C) >> 2];
/* tph capability is only applicable for rev3 */
uint32_t tph_cap_base;
uint32_t reserved6[(0x700 - 0x17C) >> 2];
/* port_regs is only applicable for function 0 */
struct al_pcie_core_port_regs port_regs;
uint32_t reserved7[(0x1000 -
(0x700 +
sizeof(struct al_pcie_core_port_regs))) >> 2];
};
struct al_pcie_rev3_core_reg_space {
struct al_pcie_core_reg_space_rev_3 func[REV3_MAX_NUM_OF_PFS];
};
struct al_pcie_core_reg_space {
uint32_t *config_header;
uint32_t *pcie_pm_cap_base;
uint32_t *pcie_cap_base;
uint32_t *pcie_dev_cap_base;
uint32_t *pcie_dev_ctrl_status;
uint32_t *pcie_link_cap_base;
uint32_t *msix_cap_base;
struct al_pcie_core_aer_regs *aer;
uint32_t *pcie_sec_ext_cap_base;
uint32_t *tph_cap_base;
};
struct al_pcie_revx_regs {
struct al_pcie_revx_axi_regs __iomem axi;
};
struct al_pcie_rev1_regs {
struct al_pcie_rev1_axi_regs __iomem axi;
uint32_t reserved1[(AL_PCIE_REV_1_2_APP_REGS_OFFSET -
(AL_PCIE_AXI_REGS_OFFSET +
sizeof(struct al_pcie_rev1_axi_regs))) >> 2];
struct al_pcie_rev1_w_regs __iomem app;
uint32_t reserved2[(AL_PCIE_REV_1_2_CORE_CONF_BASE_OFFSET -
(AL_PCIE_REV_1_2_APP_REGS_OFFSET +
sizeof(struct al_pcie_rev1_w_regs))) >> 2];
struct al_pcie_core_reg_space_rev_1_2 core_space;
};
struct al_pcie_rev2_regs {
struct al_pcie_rev2_axi_regs __iomem axi;
uint32_t reserved1[(AL_PCIE_REV_1_2_APP_REGS_OFFSET -
(AL_PCIE_AXI_REGS_OFFSET +
sizeof(struct al_pcie_rev2_axi_regs))) >> 2];
struct al_pcie_rev2_w_regs __iomem app;
uint32_t reserved2[(AL_PCIE_REV_1_2_CORE_CONF_BASE_OFFSET -
(AL_PCIE_REV_1_2_APP_REGS_OFFSET +
sizeof(struct al_pcie_rev2_w_regs))) >> 2];
struct al_pcie_core_reg_space_rev_1_2 core_space;
};
struct al_pcie_rev3_regs {
struct al_pcie_rev3_axi_regs __iomem axi;
uint32_t reserved1[(AL_PCIE_REV_3_APP_REGS_OFFSET -
(AL_PCIE_AXI_REGS_OFFSET +
sizeof(struct al_pcie_rev3_axi_regs))) >> 2];
struct al_pcie_rev3_w_regs __iomem app;
uint32_t reserved2[(AL_PCIE_REV_3_CORE_CONF_BASE_OFFSET -
(AL_PCIE_REV_3_APP_REGS_OFFSET +
sizeof(struct al_pcie_rev3_w_regs))) >> 2];
struct al_pcie_rev3_core_reg_space core_space;
};
struct al_pcie_axi_ctrl {
uint32_t *global;
uint32_t *master_arctl;
uint32_t *master_awctl;
uint32_t *slv_ctl;
};
struct al_pcie_axi_ob_ctrl {
uint32_t *cfg_target_bus;
uint32_t *cfg_control;
uint32_t *io_start_l;
uint32_t *io_start_h;
uint32_t *io_limit_l;
uint32_t *io_limit_h;
};
struct al_pcie_axi_pcie_global {
uint32_t *conf;
};
struct al_pcie_axi_conf {
uint32_t *zero_lane0;
uint32_t *zero_lane1;
uint32_t *zero_lane2;
uint32_t *zero_lane3;
uint32_t *zero_lane4;
uint32_t *zero_lane5;
uint32_t *zero_lane6;
uint32_t *zero_lane7;
};
struct al_pcie_axi_status {
uint32_t *lane[AL_MAX_NUM_OF_LANES];
};
struct al_pcie_axi_parity {
uint32_t *en_axi;
};
struct al_pcie_axi_ordering {
uint32_t *pos_cntl;
};
struct al_pcie_axi_pre_configuration {
uint32_t *pcie_core_setup;
};
struct al_pcie_axi_init_fc {
uint32_t *cfg;
};
struct al_pcie_axi_attr_ovrd {
uint32_t *write_msg_ctrl_0;
uint32_t *write_msg_ctrl_1;
uint32_t *pf_sel;
};
struct al_pcie_axi_pf_axi_attr_ovrd {
uint32_t *func_ctrl_0;
uint32_t *func_ctrl_1;
uint32_t *func_ctrl_2;
uint32_t *func_ctrl_3;
uint32_t *func_ctrl_4;
uint32_t *func_ctrl_5;
uint32_t *func_ctrl_6;
uint32_t *func_ctrl_7;
uint32_t *func_ctrl_8;
uint32_t *func_ctrl_9;
};
struct al_pcie_axi_msg_attr_axuser_table {
uint32_t *entry_vec;
};
struct al_pcie_axi_regs {
struct al_pcie_axi_ctrl ctrl;
struct al_pcie_axi_ob_ctrl ob_ctrl;
struct al_pcie_axi_pcie_global pcie_global;
struct al_pcie_axi_conf conf;
struct al_pcie_axi_status status;
struct al_pcie_axi_parity parity;
struct al_pcie_axi_ordering ordering;
struct al_pcie_axi_pre_configuration pre_configuration;
struct al_pcie_axi_init_fc init_fc;
struct al_pcie_revx_axi_int_grp_a_axi *int_grp_a;
/* Rev3 only */
struct al_pcie_axi_attr_ovrd axi_attr_ovrd;
struct al_pcie_axi_pf_axi_attr_ovrd pf_axi_attr_ovrd[REV3_MAX_NUM_OF_PFS];
struct al_pcie_axi_msg_attr_axuser_table msg_attr_axuser_table;
};
struct al_pcie_w_global_ctrl {
uint32_t *port_init;
uint32_t *pm_control;
uint32_t *events_gen[REV3_MAX_NUM_OF_PFS];
uint32_t *corr_err_sts_int;
uint32_t *uncorr_err_sts_int;
uint32_t *sris_kp_counter;
};
struct al_pcie_w_soc_int {
uint32_t *mask_inta_leg_0;
uint32_t *mask_inta_leg_3; /* Rev 2/3 only */
uint32_t *mask_msi_leg_0;
uint32_t *mask_msi_leg_3; /* Rev 2/3 only */
};
struct al_pcie_w_atu {
uint32_t *in_mask_pair;
uint32_t *out_mask_pair;
};
struct al_pcie_w_regs {
struct al_pcie_w_global_ctrl global_ctrl;
struct al_pcie_revx_w_debug *debug;
struct al_pcie_revx_w_ap_user_send_msg *ap_user_send_msg;
struct al_pcie_w_soc_int soc_int[REV3_MAX_NUM_OF_PFS];
struct al_pcie_revx_w_cntl_gen *ctrl_gen;
struct al_pcie_revx_w_parity *parity;
struct al_pcie_w_atu atu;
struct al_pcie_revx_w_status_per_func *status_per_func[REV3_MAX_NUM_OF_PFS];
struct al_pcie_revx_w_int_grp *int_grp_a;
struct al_pcie_revx_w_int_grp *int_grp_b;
struct al_pcie_revx_w_int_grp *int_grp_c;
struct al_pcie_revx_w_int_grp *int_grp_d;
};
struct al_pcie_regs {
struct al_pcie_axi_regs axi;
struct al_pcie_w_regs app;
struct al_pcie_core_port_regs *port_regs;
struct al_pcie_core_reg_space core_space[REV3_MAX_NUM_OF_PFS];
};
#define PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_EP 0
#define PCIE_AXI_MISC_PCIE_GLOBAL_CONF_DEV_TYPE_RC 4
#define PCIE_PORT_GEN2_CTRL_DIRECT_SPEED_CHANGE AL_BIT(17)
#define PCIE_PORT_GEN2_CTRL_TX_SWING_LOW_SHIFT 18
#define PCIE_PORT_GEN2_CTRL_TX_COMPLIANCE_RCV_SHIFT 19
#define PCIE_PORT_GEN2_CTRL_DEEMPHASIS_SET_SHIFT 20
#define PCIE_PORT_GEN2_CTRL_NUM_OF_LANES_MASK AL_FIELD_MASK(12, 8)
#define PCIE_PORT_GEN2_CTRL_NUM_OF_LANES_SHIFT 8
#define PCIE_PORT_GEN3_CTRL_EQ_PHASE_2_3_DISABLE_SHIFT 9
#define PCIE_PORT_GEN3_CTRL_EQ_DISABLE_SHIFT 16
#define PCIE_PORT_GEN3_EQ_LF_SHIFT 0
#define PCIE_PORT_GEN3_EQ_LF_MASK 0x3f
#define PCIE_PORT_GEN3_EQ_FS_SHIFT 6
#define PCIE_PORT_GEN3_EQ_FS_MASK (0x3f << PCIE_PORT_GEN3_EQ_FS_SHIFT)
#define PCIE_PORT_LINK_CTRL_LB_EN_SHIFT 2
#define PCIE_PORT_LINK_CTRL_FAST_LINK_EN_SHIFT 7
#define PCIE_PORT_LINK_CTRL_LINK_CAPABLE_MASK AL_FIELD_MASK(21, 16)
#define PCIE_PORT_LINK_CTRL_LINK_CAPABLE_SHIFT 16
#define PCIE_PORT_PIPE_LOOPBACK_CTRL_PIPE_LB_EN_SHIFT 31
#define PCIE_PORT_AXI_SLAVE_ERR_RESP_ALL_MAPPING_SHIFT 0
/** timer_ctrl_max_func_num register
* Max physical function number (for example: 0 for 1PF, 3 for 4PFs)
*/
#define PCIE_PORT_GEN3_MAX_FUNC_NUM AL_FIELD_MASK(7, 0)
/* filter_mask_reg_1 register */
/**
* SKP Interval Value.
* The number of symbol times to wait between transmitting SKP ordered sets
*/
#define PCIE_FLT_MASK_SKP_INT_VAL_MASK AL_FIELD_MASK(10, 0)
/*
* 0: Treat Function MisMatched TLPs as UR
* 1: Treat Function MisMatched TLPs as Supported
*/
#define CX_FLT_MASK_UR_FUNC_MISMATCH AL_BIT(16)
/*
* 0: Treat CFG type1 TLPs as UR for EP; Supported for RC
* 1: Treat CFG type1 TLPs as Supported for EP; UR for RC
*/
#define CX_FLT_MASK_CFG_TYPE1_RE_AS_UR AL_BIT(19)
/*
* 0: Enforce requester id match for received CPL TLPs.
* A violation results in cpl_abort, and possibly AER of unexp_cpl_err,
* cpl_rcvd_ur, cpl_rcvd_ca
* 1: Mask requester id match for received CPL TLPs
*/
#define CX_FLT_MASK_CPL_REQID_MATCH AL_BIT(22)
/*
* 0: Enforce function match for received CPL TLPs.
* A violation results in cpl_abort, and possibly AER of unexp_cpl_err,
* cpl_rcvd_ur, cpl_rcvd_ca
* 1: Mask function match for received CPL TLPs
*/
#define CX_FLT_MASK_CPL_FUNC_MATCH AL_BIT(23)
/* vc0_posted_rcv_q_ctrl register */
#define RADM_PQ_HCRD_VC0_MASK AL_FIELD_MASK(19, 12)
#define RADM_PQ_HCRD_VC0_SHIFT 12
/* vc0_non_posted_rcv_q_ctrl register */
#define RADM_NPQ_HCRD_VC0_MASK AL_FIELD_MASK(19, 12)
#define RADM_NPQ_HCRD_VC0_SHIFT 12
/* vc0_comp_rcv_q_ctrl register */
#define RADM_CPLQ_HCRD_VC0_MASK AL_FIELD_MASK(19, 12)
#define RADM_CPLQ_HCRD_VC0_SHIFT 12
/**** iATU, Control Register 1 ****/
/**
* When the Address and BAR matching logic in the core indicate that a MEM-I/O
* transaction matches a BAR in the function corresponding to this value, then
* address translation proceeds. This check is only performed if the "Function
* Number Match Enable" bit of the "iATU Control 2 Register" is set
*/
#define PCIE_IATU_CR1_FUNC_NUM_MASK AL_FIELD_MASK(24, 20)
#define PCIE_IATU_CR1_FUNC_NUM_SHIFT 20
/**** iATU, Control Register 2 ****/
/** For outbound regions, the Function Number Translation Bypass mode enables
* taking the function number of the translated TLP from the PCIe core
* interface and not from the "Function Number" field of CR1.
* For inbound regions, this bit should be asserted when physical function
* match mode needs to be enabled
*/
#define PCIE_IATU_CR2_FUNC_NUM_TRANS_BYPASS_FUNC_MATCH_ENABLE_MASK AL_BIT(19)
#define PCIE_IATU_CR2_FUNC_NUM_TRANS_BYPASS_FUNC_MATCH_ENABLE_SHIFT 19
/* pcie_dev_ctrl_status register */
#define PCIE_PORT_DEV_CTRL_STATUS_CORR_ERR_REPORT_EN AL_BIT(0)
#define PCIE_PORT_DEV_CTRL_STATUS_NON_FTL_ERR_REPORT_EN AL_BIT(1)
#define PCIE_PORT_DEV_CTRL_STATUS_FTL_ERR_REPORT_EN AL_BIT(2)
#define PCIE_PORT_DEV_CTRL_STATUS_UNSUP_REQ_REPORT_EN AL_BIT(3)
#define PCIE_PORT_DEV_CTRL_STATUS_MPS_MASK AL_FIELD_MASK(7, 5)
#define PCIE_PORT_DEV_CTRL_STATUS_MPS_SHIFT 5
#define PCIE_PORT_DEV_CTRL_STATUS_MPS_VAL_256 (1 << PCIE_PORT_DEV_CTRL_STATUS_MPS_SHIFT)
#define PCIE_PORT_DEV_CTRL_STATUS_MRRS_MASK AL_FIELD_MASK(14, 12)
#define PCIE_PORT_DEV_CTRL_STATUS_MRRS_SHIFT 12
#define PCIE_PORT_DEV_CTRL_STATUS_MRRS_VAL_256 (1 << PCIE_PORT_DEV_CTRL_STATUS_MRRS_SHIFT)
/******************************************************************************
* AER registers
******************************************************************************/
/* PCI Express Extended Capability ID */
#define PCIE_AER_CAP_ID_MASK AL_FIELD_MASK(15, 0)
#define PCIE_AER_CAP_ID_SHIFT 0
#define PCIE_AER_CAP_ID_VAL 1
/* Capability Version */
#define PCIE_AER_CAP_VER_MASK AL_FIELD_MASK(19, 16)
#define PCIE_AER_CAP_VER_SHIFT 16
#define PCIE_AER_CAP_VER_VAL 2
/* First Error Pointer */
#define PCIE_AER_CTRL_STAT_FIRST_ERR_PTR_MASK AL_FIELD_MASK(4, 0)
#define PCIE_AER_CTRL_STAT_FIRST_ERR_PTR_SHIFT 0
/* ECRC Generation Capability */
#define PCIE_AER_CTRL_STAT_ECRC_GEN_SUPPORTED AL_BIT(5)
/* ECRC Generation Enable */
#define PCIE_AER_CTRL_STAT_ECRC_GEN_EN AL_BIT(6)
/* ECRC Check Capable */
#define PCIE_AER_CTRL_STAT_ECRC_CHK_SUPPORTED AL_BIT(7)
/* ECRC Check Enable */
#define PCIE_AER_CTRL_STAT_ECRC_CHK_EN AL_BIT(8)
/* Correctable Error Reporting Enable */
#define PCIE_AER_ROOT_ERR_CMD_CORR_ERR_RPRT_EN AL_BIT(0)
/* Non-Fatal Error Reporting Enable */
#define PCIE_AER_ROOT_ERR_CMD_NON_FTL_ERR_RPRT_EN AL_BIT(1)
/* Fatal Error Reporting Enable */
#define PCIE_AER_ROOT_ERR_CMD_FTL_ERR_RPRT_EN AL_BIT(2)
/* ERR_COR Received */
#define PCIE_AER_ROOT_ERR_STAT_CORR_ERR AL_BIT(0)
/* Multiple ERR_COR Received */
#define PCIE_AER_ROOT_ERR_STAT_CORR_ERR_MULTI AL_BIT(1)
/* ERR_FATAL/NONFATAL Received */
#define PCIE_AER_ROOT_ERR_STAT_FTL_NON_FTL_ERR AL_BIT(2)
/* Multiple ERR_FATAL/NONFATAL Received */
#define PCIE_AER_ROOT_ERR_STAT_FTL_NON_FTL_ERR_MULTI AL_BIT(3)
/* First Uncorrectable Fatal */
#define PCIE_AER_ROOT_ERR_STAT_FIRST_UNCORR_FTL AL_BIT(4)
/* Non-Fatal Error Messages Received */
#define PCIE_AER_ROOT_ERR_STAT_NON_FTL_RCVD AL_BIT(5)
/* Fatal Error Messages Received */
#define PCIE_AER_ROOT_ERR_STAT_FTL_RCVD AL_BIT(6)
/* Advanced Error Interrupt Message Number */
#define PCIE_AER_ROOT_ERR_STAT_ERR_INT_MSG_NUM_MASK AL_FIELD_MASK(31, 27)
#define PCIE_AER_ROOT_ERR_STAT_ERR_INT_MSG_NUM_SHIFT 27
/* ERR_COR Source Identification */
#define PCIE_AER_SRC_ID_CORR_ERR_MASK AL_FIELD_MASK(15, 0)
#define PCIE_AER_SRC_ID_CORR_ERR_SHIFT 0
/* ERR_FATAL/NONFATAL Source Identification */
#define PCIE_AER_SRC_ID_CORR_ERR_FTL_NON_FTL_MASK AL_FIELD_MASK(31, 16)
#define PCIE_AER_SRC_ID_CORR_ERR_FTL_NON_FTL_SHIFT 16
/* AER message */
#define PCIE_AER_MSG_REQID_MASK AL_FIELD_MASK(31, 16)
#define PCIE_AER_MSG_REQID_SHIFT 16
#define PCIE_AER_MSG_TYPE_MASK AL_FIELD_MASK(15, 8)
#define PCIE_AER_MSG_TYPE_SHIFT 8
#define PCIE_AER_MSG_RESERVED AL_FIELD_MASK(7, 1)
#define PCIE_AER_MSG_VALID AL_BIT(0)
/* AER message ack */
#define PCIE_AER_MSG_ACK AL_BIT(0)
/* AER errors definitions */
#define AL_PCIE_AER_TYPE_CORR (0x30)
#define AL_PCIE_AER_TYPE_NON_FATAL (0x31)
#define AL_PCIE_AER_TYPE_FATAL (0x33)
/* Requester ID Bus */
#define AL_PCIE_REQID_BUS_NUM_SHIFT (8)
/******************************************************************************
* TPH registers
******************************************************************************/
#define PCIE_TPH_NEXT_POINTER AL_FIELD_MASK(31, 20)
/******************************************************************************
* Config Header registers
******************************************************************************/
/**
* see BIST_HEADER_TYPE_LATENCY_CACHE_LINE_SIZE_REG in core spec
* Note: valid only for EP mode
*/
#define PCIE_BIST_HEADER_TYPE_BASE 0xc
#define PCIE_BIST_HEADER_TYPE_MULTI_FUNC_MASK AL_BIT(23)
/******************************************************************************
* SRIS KP counters default values
******************************************************************************/
#define PCIE_SRIS_KP_COUNTER_GEN3_DEFAULT_VAL (0x24)
#define PCIE_SRIS_KP_COUNTER_GEN21_DEFAULT_VAL (0x4B)
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,419 @@
/*-
*******************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @defgroup group_services Platform Services API
* @{
* The Platform Services API provides miscellaneous system services to HAL
* drivers, such as:
* - Registers read/write
* - Assertions
* - Memory barriers
* - Endianness conversions
*
* And more.
* @file plat_api/sample/al_hal_plat_services.h
*
* @brief API for Platform services provided for to HAL drivers
*
*
*/
#ifndef __PLAT_SERVICES_H__
#define __PLAT_SERVICES_H__
#include <machine/atomic.h>
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/endian.h>
#include <sys/errno.h>
#include <sys/lock.h>
#include <sys/mutex.h>
/* Prototypes for all the bus_space structure functions */
bs_protos(generic);
bs_protos(generic_armv4);
#define __UNUSED __attribute__((unused))
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
/*
* WMA: This is a hack which allows not modifying the __iomem accessing HAL code.
* On ARMv7, bus_handle holds the information about VA of accessed memory. It
* is possible to use direct load/store instruction instead of bus_dma machinery.
* WARNING: This is not guaranteed to stay that way forever, nor that
* on other architectures these variables behave similarly. Keep that
* in mind during porting to other systems.
*/
/**
* Read MMIO 8 bits register
* @param offset register offset
*
* @return register value
*/
static uint8_t al_reg_read8(uint8_t * offset);
/**
* Read MMIO 16 bits register
* @param offset register offset
*
* @return register value
*/
static uint16_t al_reg_read16(uint16_t * offset);
/**
* Read MMIO 32 bits register
* @param offset register offset
*
* @return register value
*/
static uint32_t al_reg_read32(uint32_t * offset);
/**
* Read MMIO 64 bits register
* @param offset register offset
*
* @return register value
*/
uint64_t al_reg_read64(uint64_t * offset);
/**
* Relaxed read MMIO 32 bits register
*
* Relaxed register read/write functions don't involve cpu instructions that
* force syncronization, nor ordering between the register access and memory
* data access.
* These instructions are used in performance critical code to avoid the
* overhead of the synchronization instructions.
*
* @param offset register offset
*
* @return register value
*/
#define al_bus_dma_to_va(bus_tag, bus_handle) ((void*)bus_handle)
/**
* Relaxed read MMIO 32 bits register
*
* Relaxed register read/write functions don't involve cpu instructions that
* force syncronization, nor ordering between the register access and memory
* data access.
* These instructions are used in performance critical code to avoid the
* overhead of the synchronization instructions.
*
* @param offset register offset
*
* @return register value
*/
#define al_reg_read32_relaxed(l) generic_bs_r_4(NULL, (bus_space_handle_t)l, 0)
/**
* Relaxed write to MMIO 32 bits register
*
* Relaxed register read/write functions don't involve cpu instructions that
* force syncronization, nor ordering between the register access and memory
* data access.
* These instructions are used in performance critical code to avoid the
* overhead of the synchronization instructions.
*
* @param offset register offset
* @param val value to write to the register
*/
#define al_reg_write32_relaxed(l,v) generic_bs_w_4(NULL, (bus_space_handle_t)l, 0, v)
/**
* Write to MMIO 8 bits register
* @param offset register offset
* @param val value to write to the register
*/
#define al_reg_write8(l,v) do { dsb(); generic_bs_w_1(NULL, (bus_space_handle_t)l, 0, v); dmb(); } while (0)
/**
* Write to MMIO 16 bits register
* @param offset register offset
* @param val value to write to the register
*/
#define al_reg_write16(l,v) do { dsb(); generic_bs_w_2(NULL, (bus_space_handle_t)l, 0, v); dmb(); } while (0)
/**
* Write to MMIO 32 bits register
* @param offset register offset
* @param val value to write to the register
*/
#define al_reg_write32(l,v) do { dsb(); generic_bs_w_4(NULL, (bus_space_handle_t)l, 0, v); dmb(); } while (0)
/**
* Write to MMIO 64 bits register
* @param offset register offset
* @param val value to write to the register
*/
#define al_reg_write64(l,v) do { dsb(); generic_bs_w_8(NULL, (bus_space_handle_t)l, 0, v); dmb(); } while (0)
static inline uint8_t
al_reg_read8(uint8_t *l)
{
dsb();
return (generic_bs_r_1(NULL, (bus_space_handle_t)l, 0));
}
static inline uint16_t
al_reg_read16(uint16_t *l)
{
dsb();
return (generic_bs_r_2(NULL, (bus_space_handle_t)l, 0));
}
static inline uint32_t
al_reg_read32(uint32_t *l)
{
dsb();
return (generic_bs_r_4(NULL, (bus_space_handle_t)l, 0));
}
#define AL_DBG_LEVEL_NONE 0
#define AL_DBG_LEVEL_ERR 1
#define AL_DBG_LEVEL_WARN 2
#define AL_DBG_LEVEL_INFO 3
#define AL_DBG_LEVEL_DBG 4
#define AL_DBG_LEVEL AL_DBG_LEVEL_ERR
extern struct mtx al_dbg_lock;
#define AL_DBG_LOCK() mtx_lock_spin(&al_dbg_lock)
#define AL_DBG_UNLOCK() mtx_unlock_spin(&al_dbg_lock)
/**
* print message
*
* @param format The format string
* @param ... Additional arguments
*/
#define al_print(type, fmt, ...) do { if (AL_DBG_LEVEL >= AL_DBG_LEVEL_NONE) { AL_DBG_LOCK(); printf(fmt, ##__VA_ARGS__); AL_DBG_UNLOCK(); } } while(0)
/**
* print error message
*
* @param format
*/
#define al_err(...) do { if (AL_DBG_LEVEL >= AL_DBG_LEVEL_ERR) { AL_DBG_LOCK(); printf(__VA_ARGS__); AL_DBG_UNLOCK(); } } while(0)
/**
* print warning message
*
* @param format
*/
#define al_warn(...) do { if (AL_DBG_LEVEL >= AL_DBG_LEVEL_WARN) { AL_DBG_LOCK(); printf(__VA_ARGS__); AL_DBG_UNLOCK(); } } while(0)
/**
* print info message
*
* @param format
*/
#define al_info(...) do { if (AL_DBG_LEVEL >= AL_DBG_LEVEL_INFO) { AL_DBG_LOCK(); printf(__VA_ARGS__); AL_DBG_UNLOCK(); } } while(0)
/**
* print debug message
*
* @param format
*/
#define al_dbg(...) do { if (AL_DBG_LEVEL >= AL_DBG_LEVEL_DBG) { AL_DBG_LOCK(); printf(__VA_ARGS__); AL_DBG_UNLOCK(); } } while(0)
/**
* Assertion
*
* @param condition
*/
#define al_assert(COND) \
do { \
if (!(COND)) \
al_err( \
"%s:%d:%s: Assertion failed! (%s)\n", \
__FILE__, __LINE__, __func__, #COND); \
} while(AL_FALSE)
/**
* Make sure data will be visible by other masters (other CPUS and DMA).
* usually this is achieved by the ARM DMB instruction.
*/
static void al_data_memory_barrier(void);
/**
* Make sure data will be visible by DMA masters, no restriction for other cpus
*/
static inline void
al_data_memory_barrier(void)
{
dsb();
}
/**
* Make sure data will be visible in order by other cpus masters.
*/
static inline void
al_smp_data_memory_barrier(void)
{
dsb();
}
/**
* Make sure write data will be visible in order by other cpus masters.
*/
static inline void
al_local_data_memory_barrier(void)
{
dsb();
}
/**
* al_udelay - micro sec delay
*/
#define al_udelay(u) DELAY(u)
/**
* al_msleep - mili sec delay
*/
#define al_msleep(m) DELAY((m) * 1000)
/**
* swap half word to little endian
*
* @param x 16 bit value
*
* @return the value in little endian
*/
#define swap16_to_le(x) htole16(x)
/**
* swap word to little endian
*
* @param x 32 bit value
*
* @return the value in little endian
*/
#define swap32_to_le(x) htole32(x)
/**
* swap 8 bytes to little endian
*
* @param x 64 bit value
*
* @return the value in little endian
*/
#define swap64_to_le(x) htole64(x)
/**
* swap half word from little endian
*
* @param x 16 bit value
*
* @return the value in the cpu endianess
*/
#define swap16_from_le(x) le16toh(x)
/**
* swap word from little endian
*
* @param x 32 bit value
*
* @return the value in the cpu endianess
*/
#define swap32_from_le(x) le32toh(x)
/**
* swap 8 bytes from little endian
*
* @param x 64 bit value
*
* @return the value in the cpu endianess
*/
#define swap64_from_le(x) le64toh(x)
/**
* Memory set
*
* @param p memory pointer
* @param val value for setting
* @param cnt number of bytes to set
*/
#define al_memset(p, val, cnt) memset(p, val, cnt)
/**
* Memory copy
*
* @param p1 memory pointer
* @param p2 memory pointer
* @param cnt number of bytes to copy
*/
#define al_memcpy(p1, p2, cnt) memcpy(p1, p2, cnt)
/**
* Memory compare
*
* @param p1 memory pointer
* @param p2 memory pointer
* @param cnt number of bytes to compare
*/
#define al_memcmp(p1, p2, cnt) memcmp(p1, p2, cnt)
/**
* String compare
*
* @param s1 string pointer
* @param s2 string pointer
*/
#define al_strcmp(s1, s2) strcmp(s1, s2)
#define al_get_cpu_id() 0
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
/** @} end of Platform Services API group */
#endif /* __PLAT_SERVICES_H__ */

View File

@ -0,0 +1,94 @@
/*-
********************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @defgroup group_services Platform Services API
* @{
* @file plat_api/sample/al_hal_plat_types.h
*
*/
#ifndef __PLAT_TYPES_H__
#define __PLAT_TYPES_H__
#include <sys/cdefs.h>
#include <sys/param.h>
#include <machine/bus.h>
#include <sys/bus.h>
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
/* Basic data types */
typedef int al_bool; /** boolean */
#define AL_TRUE 1
#define AL_FALSE 0
/* define types */
#ifndef AL_HAVE_TYPES
typedef unsigned char uint8_t; /** unsigned 8 bits */
typedef unsigned short uint16_t; /** unsigned 16 bits */
typedef unsigned int uint32_t; /** unsigned 32 bits */
typedef unsigned long long uint64_t; /** unsigned 64 bits */
typedef signed char int8_t; /** signed 8 bits */
typedef short int int16_t; /** signed 16 bits */
typedef signed int int32_t; /** signed 32 bits */
/** An unsigned int that is guaranteed to be the same size as a pointer */
/** C99 standard */
typedef unsigned long uintptr_t;
#endif
/** in LPAE mode, the address address is 40 bit, we extend it to 64 bit */
typedef uint64_t al_phys_addr_t;
/** this defines the cpu endiancess. */
#define PLAT_ARCH_IS_LITTLE() AL_TRUE
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
/** @} end of Platform Services API group */
#endif /* __PLAT_TYPES_H__ */

View File

@ -0,0 +1,188 @@
/*-
********************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @defgroup group_common HAL Common Layer
* @{
* @file al_hal_reg_utils.h
*
* @brief Register utilities used by HALs and platform layer
*
*
*/
#ifndef __AL_HAL_REG_UTILS_H__
#define __AL_HAL_REG_UTILS_H__
#include "al_hal_plat_types.h"
#include "al_hal_plat_services.h"
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
#define AL_BIT(b) (1UL << (b))
#define AL_ADDR_LOW(x) ((uint32_t)((al_phys_addr_t)(x)))
#define AL_ADDR_HIGH(x) ((uint32_t)((((al_phys_addr_t)(x)) >> 16) >> 16))
/** get field out of 32 bit register */
#define AL_REG_FIELD_GET(reg, mask, shift) (((reg) & (mask)) >> (shift))
/** set field of 32 bit register */
#define AL_REG_FIELD_SET(reg, mask, shift, val) \
(reg) = \
(((reg) & (~(mask))) | \
((((unsigned)(val)) << (shift)) & (mask)))
/** set field of 64 bit register */
#define AL_REG_FIELD_SET_64(reg, mask, shift, val) \
((reg) = \
(((reg) & (~(mask))) | \
((((uint64_t)(val)) << (shift)) & (mask))))
/** get single bit out of 32 bit register */
#define AL_REG_BIT_GET(reg, shift) \
AL_REG_FIELD_GET(reg, AL_BIT(shift), shift)
#define AL_REG_BITS_FIELD(shift, val) \
(((unsigned)(val)) << (shift))
/** set single bit field of 32 bit register to a given value */
#define AL_REG_BIT_VAL_SET(reg, shift, val) \
AL_REG_FIELD_SET(reg, AL_BIT(shift), shift, val)
/** set single bit of 32 bit register to 1 */
#define AL_REG_BIT_SET(reg, shift) \
AL_REG_BIT_VAL_SET(reg, shift, 1)
/** clear single bit of 32 bit register */
#define AL_REG_BIT_CLEAR(reg, shift) \
AL_REG_BIT_VAL_SET(reg, shift, 0)
#define AL_BIT_MASK(n) \
(AL_BIT(n) - 1)
#define AL_FIELD_MASK(msb, lsb) \
(AL_BIT(msb) + AL_BIT_MASK(msb) - AL_BIT_MASK(lsb))
/** clear bits specified by clear_mask */
#define AL_REG_MASK_CLEAR(reg, clear_mask) \
((reg) = (((reg) & (~(clear_mask)))))
/** set bits specified by clear_mask */
#define AL_REG_MASK_SET(reg, clear_mask) \
((reg) = (((reg) | (clear_mask))))
/** clear bits specified by clear_mask, and set bits specified by set_mask */
#define AL_REG_CLEAR_AND_SET(reg, clear_mask, set_mask) \
(reg) = (((reg) & (~(clear_mask))) | (set_mask))
#define AL_ALIGN_UP(val, size) \
((size) * (((val) + (size) - 1) / (size)))
/** take bits selected by mask from one data, the rest from background */
#define AL_MASK_VAL(mask, data, background) \
(((mask) & (data)) | ((~mask) & (background)))
/**
* 8 bits register masked write
*
* @param reg
* register address
* @param mask
* bits not selected (1) by mask will be left unchanged
* @param data
* data to write. bits not selected by mask ignored.
*/
static inline void
al_reg_write8_masked(uint8_t __iomem *reg, uint8_t mask, uint8_t data)
{
uint8_t temp;
temp = al_reg_read8(reg);
al_reg_write8(reg, AL_MASK_VAL(mask, data, temp));
}
/**
* 16 bits register masked write
*
* @param reg
* register address
* @param mask
* bits not selected (1) by mask will be left unchanged
* @param data
* data to write. bits not selected by mask ignored.
*/
static inline void
al_reg_write16_masked(uint16_t __iomem *reg, uint16_t mask, uint16_t data)
{
uint16_t temp;
temp = al_reg_read16(reg);
al_reg_write16(reg, AL_MASK_VAL(mask, data, temp));
}
/**
* 32 bits register masked write
*
* @param reg
* register address
* @param mask
* bits not selected (1) by mask will be left unchanged
* @param data
* data to write. bits not selected by mask ignored.
*/
static inline void
al_reg_write32_masked(uint32_t __iomem *reg, uint32_t mask, uint32_t data)
{
uint32_t temp;
temp = al_reg_read32(reg);
al_reg_write32(reg, AL_MASK_VAL(mask, data, temp));
}
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
/** @} end of Common group */
#endif

View File

@ -0,0 +1,117 @@
/*-
********************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
/**
* @defgroup group_common HAL Common Layer
* @{
* @file al_hal_types.h
*
* @brief macros used by HALs and platform layer
*
*/
#ifndef __AL_HAL_TYPES_H__
#define __AL_HAL_TYPES_H__
#include "al_hal_plat_types.h"
#include "al_hal_plat_services.h"
/* *INDENT-OFF* */
#ifdef __cplusplus
extern "C" {
#endif
/* *INDENT-ON* */
/* Common defines */
#if (!AL_TRUE) || (AL_FALSE)
#error "AL_TRUE must be non zero and AL_FALSE must be zero"
#endif
typedef int AL_RETURN;
#if !defined(NULL)
#define NULL (void *)0
#endif
#if !defined(likely)
#define likely(x) (__builtin_expect(!!(x), 1))
#define unlikely(x) (__builtin_expect(!!(x), 0))
#endif
#ifdef __GNUC__
#if !defined(__packed)
#define __packed __attribute__ ((packed))
#endif
/* packed and alinged types */
#define __packed_a4 __attribute__ ((packed, aligned(4)))
#define __packed_a8 __attribute__ ((packed, aligned(8)))
#define __packed_a16 __attribute__ ((packed, aligned(16)))
#else
#if !defined(__packed)
#error "__packed is not defined!!"
#endif
#endif
#if !defined(__iomem)
#define __iomem
#endif
#if !defined(__cache_aligned)
#ifdef __GNUC__
#define __cache_aligned __attribute__ ((__aligned__(64)))
#else
#define __cache_aligned
#endif
#endif
#if !defined(INLINE)
#ifdef __GNUC__
#define INLINE inline
#else
#define INLINE
#endif
#endif
/* *INDENT-OFF* */
#ifdef __cplusplus
}
#endif
/* *INDENT-ON* */
/** @} end of Common group */
#endif /* __TYPES_H__ */

View File

@ -0,0 +1,314 @@
/*-
********************************************************************************
Copyright (C) 2015 Annapurna Labs Ltd.
This file may be licensed under the terms of the Annapurna Labs Commercial
License Agreement.
Alternatively, this file can be distributed under the terms of the GNU General
Public License V2 as published by the Free Software Foundation and can be
found at http://www.gnu.org/licenses/gpl-2.0.html
Alternatively, redistribution and use in source and binary forms, with or
without modification, are permitted provided that the following conditions are
met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in
the documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*******************************************************************************/
#ifndef __AL_HAL_UNIT_ADAPTER_REGS_H__
#define __AL_HAL_UNIT_ADAPTER_REGS_H__
#ifdef __cplusplus
extern "C" {
#endif
#define AL_PCI_COMMAND 0x04 /* 16 bits */
#define AL_PCI_COMMAND_IO 0x1 /* Enable response in I/O space */
#define AL_PCI_COMMAND_MEMORY 0x2 /* Enable response in Memory space */
#define AL_PCI_COMMAND_MASTER 0x4 /* Enable bus mastering */
#define PCI_CLASS_REVISION 0x08 /* High 24 bits are class, low 8 revision */
#define AL_PCI_BASE_ADDRESS_SPACE_IO 0x01
#define AL_PCI_BASE_ADDRESS_MEM_TYPE_64 0x04 /* 64 bit address */
#define AL_PCI_BASE_ADDRESS_MEM_PREFETCH 0x08 /* prefetchable? */
#define AL_PCI_BASE_ADDRESS_DEVICE_ID 0x0c
#define AL_PCI_BASE_ADDRESS_0 0x10
#define AL_PCI_BASE_ADDRESS_0_HI 0x14
#define AL_PCI_BASE_ADDRESS_2 0x18
#define AL_PCI_BASE_ADDRESS_2_HI 0x1c
#define AL_PCI_BASE_ADDRESS_4 0x20
#define AL_PCI_BASE_ADDRESS_4_HI 0x24
#define AL_PCI_EXP_ROM_BASE_ADDRESS 0x30
#define AL_PCI_AXI_CFG_AND_CTR_0 0x110
#define AL_PCI_AXI_CFG_AND_CTR_1 0x130
#define AL_PCI_AXI_CFG_AND_CTR_2 0x150
#define AL_PCI_AXI_CFG_AND_CTR_3 0x170
#define AL_PCI_APP_CONTROL 0x220
#define AL_PCI_SRIOV_TOTAL_AND_INITIAL_VFS 0x30c
#define AL_PCI_VF_BASE_ADDRESS_0 0x324
#define AL_PCI_EXP_CAP_BASE 0x40
#define AL_PCI_EXP_DEVCAP 4 /* Device capabilities */
#define AL_PCI_EXP_DEVCAP_PAYLOAD 0x07 /* Max_Payload_Size */
#define AL_PCI_EXP_DEVCAP_PHANTOM 0x18 /* Phantom functions */
#define AL_PCI_EXP_DEVCAP_EXT_TAG 0x20 /* Extended tags */
#define AL_PCI_EXP_DEVCAP_L0S 0x1c0 /* L0s Acceptable Latency */
#define AL_PCI_EXP_DEVCAP_L1 0xe00 /* L1 Acceptable Latency */
#define AL_PCI_EXP_DEVCAP_ATN_BUT 0x1000 /* Attention Button Present */
#define AL_PCI_EXP_DEVCAP_ATN_IND 0x2000 /* Attention Indicator Present */
#define AL_PCI_EXP_DEVCAP_PWR_IND 0x4000 /* Power Indicator Present */
#define AL_PCI_EXP_DEVCAP_RBER 0x8000 /* Role-Based Error Reporting */
#define AL_PCI_EXP_DEVCAP_PWR_VAL 0x3fc0000 /* Slot Power Limit Value */
#define AL_PCI_EXP_DEVCAP_PWR_SCL 0xc000000 /* Slot Power Limit Scale */
#define AL_PCI_EXP_DEVCAP_FLR 0x10000000 /* Function Level Reset */
#define AL_PCI_EXP_DEVCTL 8 /* Device Control */
#define AL_PCI_EXP_DEVCTL_CERE 0x0001 /* Correctable Error Reporting En. */
#define AL_PCI_EXP_DEVCTL_NFERE 0x0002 /* Non-Fatal Error Reporting Enable */
#define AL_PCI_EXP_DEVCTL_FERE 0x0004 /* Fatal Error Reporting Enable */
#define AL_PCI_EXP_DEVCTL_URRE 0x0008 /* Unsupported Request Reporting En. */
#define AL_PCI_EXP_DEVCTL_RELAX_EN 0x0010 /* Enable relaxed ordering */
#define AL_PCI_EXP_DEVCTL_PAYLOAD 0x00e0 /* Max_Payload_Size */
#define AL_PCI_EXP_DEVCTL_EXT_TAG 0x0100 /* Extended Tag Field Enable */
#define AL_PCI_EXP_DEVCTL_PHANTOM 0x0200 /* Phantom Functions Enable */
#define AL_PCI_EXP_DEVCTL_AUX_PME 0x0400 /* Auxiliary Power PM Enable */
#define AL_PCI_EXP_DEVCTL_NOSNOOP_EN 0x0800 /* Enable No Snoop */
#define AL_PCI_EXP_DEVCTL_READRQ 0x7000 /* Max_Read_Request_Size */
#define AL_PCI_EXP_DEVCTL_BCR_FLR 0x8000 /* Bridge Configuration Retry / FLR */
#define AL_PCI_EXP_DEVSTA 0xA /* Device Status */
#define AL_PCI_EXP_DEVSTA_CED 0x01 /* Correctable Error Detected */
#define AL_PCI_EXP_DEVSTA_NFED 0x02 /* Non-Fatal Error Detected */
#define AL_PCI_EXP_DEVSTA_FED 0x04 /* Fatal Error Detected */
#define AL_PCI_EXP_DEVSTA_URD 0x08 /* Unsupported Request Detected */
#define AL_PCI_EXP_DEVSTA_AUXPD 0x10 /* AUX Power Detected */
#define AL_PCI_EXP_DEVSTA_TRPND 0x20 /* Transactions Pending */
#define AL_PCI_EXP_LNKCAP 0xC /* Link Capabilities */
#define AL_PCI_EXP_LNKCAP_SLS 0xf /* Supported Link Speeds */
#define AL_PCI_EXP_LNKCAP_SLS_2_5GB 0x1 /* LNKCAP2 SLS Vector bit 0 (2.5GT/s) */
#define AL_PCI_EXP_LNKCAP_SLS_5_0GB 0x2 /* LNKCAP2 SLS Vector bit 1 (5.0GT/s) */
#define AL_PCI_EXP_LNKCAP_MLW 0x3f0 /* Maximum Link Width */
#define AL_PCI_EXP_LNKCAP_ASPMS 0xc00 /* ASPM Support */
#define AL_PCI_EXP_LNKCAP_L0SEL 0x7000 /* L0s Exit Latency */
#define AL_PCI_EXP_LNKCAP_L1EL 0x38000 /* L1 Exit Latency */
#define AL_PCI_EXP_LNKCAP_CLKPM 0x40000 /* L1 Clock Power Management */
#define AL_PCI_EXP_LNKCAP_SDERC 0x80000 /* Surprise Down Error Reporting Capable */
#define AL_PCI_EXP_LNKCAP_DLLLARC 0x100000 /* Data Link Layer Link Active Reporting Capable */
#define AL_PCI_EXP_LNKCAP_LBNC 0x200000 /* Link Bandwidth Notification Capability */
#define AL_PCI_EXP_LNKCAP_PN 0xff000000 /* Port Number */
#define AL_PCI_EXP_LNKCTL 0x10 /* Link Control */
#define AL_PCI_EXP_LNKCTL_LNK_DIS 0x4 /* Link Disable Status */
#define AL_PCI_EXP_LNKCTL_LNK_RTRN 0x5 /* Link Retrain Status */
#define AL_PCI_EXP_LNKSTA 0x12 /* Link Status */
#define AL_PCI_EXP_LNKSTA_CLS 0x000f /* Current Link Speed */
#define AL_PCI_EXP_LNKSTA_CLS_2_5GB 0x01 /* Current Link Speed 2.5GT/s */
#define AL_PCI_EXP_LNKSTA_CLS_5_0GB 0x02 /* Current Link Speed 5.0GT/s */
#define AL_PCI_EXP_LNKSTA_CLS_8_0GB 0x03 /* Current Link Speed 8.0GT/s */
#define AL_PCI_EXP_LNKSTA_NLW 0x03f0 /* Nogotiated Link Width */
#define AL_PCI_EXP_LNKSTA_NLW_SHIFT 4 /* start of NLW mask in link status */
#define AL_PCI_EXP_LNKSTA_LT 0x0800 /* Link Training */
#define AL_PCI_EXP_LNKSTA_SLC 0x1000 /* Slot Clock Configuration */
#define AL_PCI_EXP_LNKSTA_DLLLA 0x2000 /* Data Link Layer Link Active */
#define AL_PCI_EXP_LNKSTA_LBMS 0x4000 /* Link Bandwidth Management Status */
#define AL_PCI_EXP_LNKSTA_LABS 0x8000 /* Link Autonomous Bandwidth Status */
#define AL_PCI_EXP_LNKCTL2 0x30 /* Link Control 2 */
#define AL_PCI_MSIX_MSGCTRL 0 /* MSIX message control reg */
#define AL_PCI_MSIX_MSGCTRL_TBL_SIZE 0x7ff /* MSIX table size */
#define AL_PCI_MSIX_MSGCTRL_TBL_SIZE_SHIFT 16 /* MSIX table size shift */
#define AL_PCI_MSIX_MSGCTRL_EN 0x80000000 /* MSIX enable */
#define AL_PCI_MSIX_MSGCTRL_MASK 0x40000000 /* MSIX mask */
#define AL_PCI_MSIX_TABLE 0x4 /* MSIX table offset and bar reg */
#define AL_PCI_MSIX_TABLE_OFFSET 0xfffffff8 /* MSIX table offset */
#define AL_PCI_MSIX_TABLE_BAR 0x7 /* MSIX table BAR */
#define AL_PCI_MSIX_PBA 0x8 /* MSIX pba offset and bar reg */
#define AL_PCI_MSIX_PBA_OFFSET 0xfffffff8 /* MSIX pba offset */
#define AL_PCI_MSIX_PBA_BAR 0x7 /* MSIX pba BAR */
/* Adapter power management register 0 */
#define AL_ADAPTER_PM_0 0x80
#define AL_ADAPTER_PM_0_PM_NEXT_CAP_MASK 0xff00
#define AL_ADAPTER_PM_0_PM_NEXT_CAP_SHIFT 8
#define AL_ADAPTER_PM_0_PM_NEXT_CAP_VAL_MSIX 0x90
/* Adapter power management register 1 */
#define AL_ADAPTER_PM_1 0x84
#define AL_ADAPTER_PM_1_PME_EN 0x100 /* PM enable */
#define AL_ADAPTER_PM_1_PWR_STATE_MASK 0x3 /* PM state mask */
#define AL_ADAPTER_PM_1_PWR_STATE_D3 0x3 /* PM D3 state */
/* Sub Master Configuration & Control */
#define AL_ADAPTER_SMCC 0x110
#define AL_ADAPTER_SMCC_CONF_2 0x114
/* Interrupt_Cause register */
#define AL_ADAPTER_INT_CAUSE 0x1B0
#define AL_ADAPTER_INT_CAUSE_WR_ERR AL_BIT(1)
#define AL_ADAPTER_INT_CAUSE_RD_ERR AL_BIT(0)
/* AXI_Master_Write_Error_Attribute_Latch register */
/* AXI_Master_Read_Error_Attribute_Latch register */
#define AL_ADAPTER_AXI_MSTR_WR_ERR_ATTR 0x1B4
#define AL_ADAPTER_AXI_MSTR_RD_ERR_ATTR 0x1B8
#define AL_ADAPTER_AXI_MSTR_RD_WR_ERR_ATTR_COMP_STAT_MASK AL_FIELD_MASK(1, 0)
#define AL_ADAPTER_AXI_MSTR_RD_WR_ERR_ATTR_COMP_STAT_SHIFT 0
#define AL_ADAPTER_AXI_MSTR_RD_WR_ERR_ATTR_MSTR_ID_MASK AL_FIELD_MASK(4, 2)
#define AL_ADAPTER_AXI_MSTR_RD_WR_ERR_ATTR_MSTR_ID_SHIFT 2
#define AL_ADAPTER_AXI_MSTR_RD_WR_ERR_ATTR_ADDR_TO AL_BIT(8)
#define AL_ADAPTER_AXI_MSTR_RD_WR_ERR_ATTR_COMP_ERR AL_BIT(9)
#define AL_ADAPTER_AXI_MSTR_RD_WR_ERR_ATTR_COMP_TO AL_BIT(10)
#define AL_ADAPTER_AXI_MSTR_RD_WR_ERR_ATTR_ERR_BLK AL_BIT(11)
#define AL_ADAPTER_AXI_MSTR_RD_ERR_ATTR_RD_PARITY_ERR AL_BIT(12)
/* Interrupt_Cause_mask register */
#define AL_ADAPTER_INT_CAUSE_MASK 0x1BC
#define AL_ADAPTER_INT_CAUSE_MASK_WR_ERR AL_BIT(1)
#define AL_ADAPTER_INT_CAUSE_MASK_RD_ERR AL_BIT(0)
/* AXI_Master_write_error_address_Latch register */
#define AL_ADAPTER_AXI_MSTR_WR_ERR_LO_LATCH 0x1C0
/* AXI_Master_write_error_address_high_Latch register */
#define AL_ADAPTER_AXI_MSTR_WR_ERR_HI_LATCH 0x1C4
/* AXI_Master_read_error_address_Latch register */
#define AL_ADAPTER_AXI_MSTR_RD_ERR_LO_LATCH 0x1C8
/* AXI_Master_read_error_address_high_Latch register */
#define AL_ADAPTER_AXI_MSTR_RD_ERR_HI_LATCH 0x1CC
/* AXI_Master_Timeout register */
#define AL_ADAPTER_AXI_MSTR_TO 0x1D0
#define AL_ADAPTER_AXI_MSTR_TO_WR_MASK AL_FIELD_MASK(31, 16)
#define AL_ADAPTER_AXI_MSTR_TO_WR_SHIFT 16
#define AL_ADAPTER_AXI_MSTR_TO_RD_MASK AL_FIELD_MASK(15, 0)
#define AL_ADAPTER_AXI_MSTR_TO_RD_SHIFT 0
/*
* Generic control registers
*/
/* Control 0 */
#define AL_ADAPTER_GENERIC_CONTROL_0 0x1E0
/* Control 2 */
#define AL_ADAPTER_GENERIC_CONTROL_2 0x1E8
/* Control 3 */
#define AL_ADAPTER_GENERIC_CONTROL_3 0x1EC
/* Control 9 */
#define AL_ADAPTER_GENERIC_CONTROL_9 0x218
/* Control 10 */
#define AL_ADAPTER_GENERIC_CONTROL_10 0x21C
/* Control 11 */
#define AL_ADAPTER_GENERIC_CONTROL_11 0x220
/* Control 12 */
#define AL_ADAPTER_GENERIC_CONTROL_12 0x224
/* Control 13 */
#define AL_ADAPTER_GENERIC_CONTROL_13 0x228
/* Control 14 */
#define AL_ADAPTER_GENERIC_CONTROL_14 0x22C
/* Control 15 */
#define AL_ADAPTER_GENERIC_CONTROL_15 0x230
/* Control 16 */
#define AL_ADAPTER_GENERIC_CONTROL_16 0x234
/* Control 17 */
#define AL_ADAPTER_GENERIC_CONTROL_17 0x238
/* Control 18 */
#define AL_ADAPTER_GENERIC_CONTROL_18 0x23C
/* Control 19 */
#define AL_ADAPTER_GENERIC_CONTROL_19 0x240
/* Enable clock gating */
#define AL_ADAPTER_GENERIC_CONTROL_0_CLK_GATE_EN 0x01
/* When set, all transactions through the PCI conf & mem BARs get timeout */
#define AL_ADAPTER_GENERIC_CONTROL_0_ADAPTER_DIS 0x40
#define AL_ADAPTER_GENERIC_CONTROL_0_ETH_RESET_1GMAC AL_BIT(18)
#define AL_ADAPTER_GENERIC_CONTROL_0_ETH_RESET_1GMAC_ON_FLR AL_BIT(26)
/*
* SATA registers only
*/
/* Select 125MHz free running clock from IOFAB main PLL as SATA OOB clock
* instead of using power management ref clock
*/
#define AL_ADAPTER_GENERIC_CONTROL_10_SATA_OOB_CLK_SEL AL_BIT(26)
/* AXUSER selection and value per bit (1 = address, 0 = register) */
/* Rx */
#define AL_ADPTR_GEN_CTL_12_SATA_AWUSER_VAL_MASK AL_FIELD_MASK(15, 0)
#define AL_ADPTR_GEN_CTL_12_SATA_AWUSER_VAL_SHIFT 0
#define AL_ADPTR_GEN_CTL_12_SATA_AWUSER_SEL_MASK AL_FIELD_MASK(31, 16)
#define AL_ADPTR_GEN_CTL_12_SATA_AWUSER_SEL_SHIFT 16
/* Tx */
#define AL_ADPTR_GEN_CTL_13_SATA_ARUSER_VAL_MASK AL_FIELD_MASK(15, 0)
#define AL_ADPTR_GEN_CTL_13_SATA_ARUSER_VAL_SHIFT 0
#define AL_ADPTR_GEN_CTL_13_SATA_ARUSER_SEL_MASK AL_FIELD_MASK(31, 16)
#define AL_ADPTR_GEN_CTL_13_SATA_ARUSER_SEL_SHIFT 16
/* Central VMID enabler. If set, then each entry will be used as programmed */
#define AL_ADPTR_GEN_CTL_14_SATA_MSIX_VMID_SEL AL_BIT(0)
/* Allow access to store VMID values per entry */
#define AL_ADPTR_GEN_CTL_14_SATA_MSIX_VMID_ACCESS_EN AL_BIT(1)
/* VMID Address select */
/* Tx */
#define AL_ADPTR_GEN_CTL_14_SATA_VM_ARADDR_SEL_MASK AL_FIELD_MASK(13, 8)
#define AL_ADPTR_GEN_CTL_14_SATA_VM_ARADDR_SEL_SHIFT 8
/* Rx */
#define AL_ADPTR_GEN_CTL_14_SATA_VM_AWADDR_SEL_MASK AL_FIELD_MASK(21, 16)
#define AL_ADPTR_GEN_CTL_14_SATA_VM_AWADDR_SEL_SHIFT 16
/* Address Value */
/* Rx */
#define AL_ADPTR_GEN_CTL_15_SATA_VM_AWDDR_HI AL_FIELD_MASK(31, 0)
/* Tx */
#define AL_ADPTR_GEN_CTL_16_SATA_VM_ARDDR_HI AL_FIELD_MASK(31, 0)
/*
* ROB registers
*/
/* Read ROB_Enable, when disabled the read ROB is bypassed */
#define AL_ADPTR_GEN_CTL_19_READ_ROB_EN AL_BIT(0)
/* Read force in-order of every read transaction */
#define AL_ADPTR_GEN_CTL_19_READ_ROB_FORCE_INORDER AL_BIT(1)
/* Read software reset */
#define AL_ADPTR_GEN_CTL_19_READ_ROB_SW_RESET AL_BIT(15)
/* Write ROB_Enable, when disabled_the_Write ROB is bypassed */
#define AL_ADPTR_GEN_CTL_19_WRITE_ROB_EN AL_BIT(16)
/* Write force in-order of every write transaction */
#define AL_ADPTR_GEN_CTL_19_WRITE_ROB_FORCE_INORDER AL_BIT(17)
/* Write software reset */
#define AL_ADPTR_GEN_CTL_19_WRITE_ROB_SW_RESET AL_BIT(31)
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,23 @@
# $FreeBSD$
makeoption ARM_LITTLE_ENDIAN
cpu CPU_CORTEXA
machine arm armv6
makeoptions CONF_CFLAGS="-march=armv7a -DAL_HAVE_TYPES"
makeoptions KERNPHYSADDR=0x00200000
options KERNPHYSADDR=0x00200000
makeoptions KERNVIRTADDR=0xa0200000
options KERNVIRTADDR=0xa0200000
makeoptions KERNBASE=0xa0000000
options KERNBASE=0xa0000000
options ARM_L2_PIPT
options IPI_IRQ_START=0
options IPI_IRQ_END=15
files "../annapurna/alpine/files.alpine"

83
sys/arm/conf/ALPINE Normal file
View File

@ -0,0 +1,83 @@
# Kernel configuration for Alpine Board.
#
# For more information on this file, please read the config(5) manual page,
# and/or the handbook section on Kernel Configuration Files:
#
# http://www.FreeBSD.org/doc/en_US.ISO8859-1/books/handbook/kernelconfig-config.html
#
# The handbook is also available locally in /usr/share/doc/handbook
# if you've installed the doc distribution, otherwise always see the
# FreeBSD World Wide Web server (http://www.FreeBSD.org/) for the
# latest information.
#
# An exhaustive list of options and more detailed explanations of the
# device lines is also present in the ../../conf/NOTES and NOTES files.
# If you are in doubt as to the purpose or necessity of a line, check first
# in NOTES.
#
# $FreeBSD$
ident ALPINE
include "std.armv6"
include "../annapurna/alpine/std.alpine"
makeoptions MODULES_OVERRIDE=""
makeoptions WERROR="-Werror"
options HZ=100
options SCHED_4BSD # 4BSD scheduler
options SMP # Enable multiple cores
# Debugging
makeoptions DEBUG=-g #Build kernel with gdb(1) debug symbols
options BREAK_TO_DEBUGGER
options KDB
options DDB #Enable the kernel debugger
# NFS support
options NFSCL #Network Filesystem Client
options NFSLOCKD #Network Lock Manager
options NFS_ROOT #NFS usable as /, requires NFSCLIENT
# Interrupt controller
device gic
# Pseudo devices
device loop
device random
device pty
device md
device gpio
# ATA controllers
device ahci # AHCI-compatible SATA controllers
device ata # Legacy ATA/SATA controllers
options ATA_STATIC_ID # Static device numbering
# ATA/SCSI peripherals
device scbus # SCSI bus (required for ATA/SCSI)
device ch # SCSI media changers
device da # Direct Access (disks)
device sa # Sequential Access (tape etc)
device cd # CD
device pass # Passthrough device (direct ATA/SCSI access)
device ses # Enclosure Services (SES and SAF-TE)
#device ctl # CAM Target Layer
# Serial ports
device uart
# Ethernet
device ether
device mii
device bpf
options DEVICE_POLLING
# USB ethernet support, requires miibus
device miibus
#FDT
options FDT
options FDT_DTB_STATIC
makeoptions FDT_DTS_FILE=annapurna-alpine.dts

View File

@ -0,0 +1,244 @@
/*-
* Copyright (c) 2013 Ruslan Bukin <br@bsdpad.com>
* Copyright (c) 2015 Semihalf
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $FreeBSD$
*/
/dts-v1/;
/ {
model = "annapurna,alpine";
#address-cells = <1>;
#size-cells = <1>;
aliases {
serial0 = &serial0;
};
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu@0 {
device_type = "cpu";
compatible = "arm,cortex-a15";
reg = <0x0>;
d-cache-line-size = <64>; // 64 bytes
i-cache-line-size = <64>; // 64 bytes
d-cache-size = <0x8000>; // L1, 32K
i-cache-size = <0x8000>; // L1, 32K
timebase-frequency = <0>;
bus-frequency = <375000000>;
clock-frequency = <0>;
};
cpu@1 {
device_type = "cpu";
compatible = "arm,cortex-a15";
reg = <0x0>;
d-cache-line-size = <64>; // 64 bytes
i-cache-line-size = <64>; // 64 bytes
d-cache-size = <0x8000>; // L1, 32K
i-cache-size = <0x8000>; // L1, 32K
timebase-frequency = <0>;
bus-frequency = <375000000>;
clock-frequency = <0>;
};
cpu@2 {
device_type = "cpu";
compatible = "arm,cortex-a15";
reg = <0x0>;
d-cache-line-size = <64>; // 64 bytes
i-cache-line-size = <64>; // 64 bytes
d-cache-size = <0x8000>; // L1, 32K
i-cache-size = <0x8000>; // L1, 32K
timebase-frequency = <0>;
bus-frequency = <375000000>;
clock-frequency = <0>;
};
cpu@3 {
device_type = "cpu";
compatible = "arm,cortex-a15";
reg = <0x0>;
d-cache-line-size = <64>; // 64 bytes
i-cache-line-size = <64>; // 64 bytes
d-cache-size = <0x8000>; // L1, 32K
i-cache-size = <0x8000>; // L1, 32K
timebase-frequency = <0>;
bus-frequency = <375000000>;
clock-frequency = <0>;
};
};
memory {
device_type = "memory";
reg = <0x00100000 0x7ff00000>; // 2047MB at 1MB
};
soc {
#address-cells = <1>;
#size-cells = <1>;
compatible = "simple-bus";
ranges = <0x0 0xfb000000 0x03000000>;
bus-frequency = <0>;
MPIC: interrupt-controller {
compatible = "arm,gic";
reg = < 0x1000 0x1000 >, /* Distributor Registers */
< 0x2000 0x2000 >; /* CPU Interface Registers */
interrupt-controller;
#address-cells = <0>;
#interrupt-cells = <3>;
// In intr[2], bits[3:0] are trigger type and level flags.
// 1 = low-to-high edge triggered
// 2 = high-to-low edge triggered
// 4 = active high level-sensitive
// 8 = active low level-sensitive
// The hardware only supports active-high-level or rising-edge.
};
generic_timer {
compatible = "arm,sp804";
reg = <0x02890000 0x1000>;
interrupts = <0 9 4>;
interrupt-parent = <&MPIC>;
clock-frequency = <375000000>;
};
cpu_resume {
compatible = "annapurna-labs,al-cpu-resume";
reg = <0x00ff5ec0 0x30>;
};
nb_service {
compatible = "annapurna-labs,al-nb-service";
reg = <0x00070000 0x10000>;
interrupts = <0 32 4>,
<0 33 4>,
<0 34 4>,
<0 35 4>;
interrupt-parent = <&MPIC>;
};
wdt0 {
compatible = "arm,sp805", "arm,primecell";
reg = <0x288c000 0x1000>;
interrupt-parent = <&MPIC>;
};
serial0: serial@2883000 {
compatible = "ns16550";
reg = <0x2883000 0x20>;
reg-shift = <2>;
current-speed = <115200>;
clock-frequency = <375000000>;
interrupts = <0 17 4>;
interrupt-parent = <&MPIC>;
};
};
pcie-internal {
compatible = "annapurna-labs,al-internal-pcie";
device_type = "pci";
#size-cells = <2>;
#address-cells = <3>;
interrupt-parent = <&MPIC>;
interrupt-map-mask = <0xf800 0 0 7>;
interrupt-map = <0x3000 0 0 1 &MPIC 0 32 4>, // USB adapter
<0x3800 0 0 1 &MPIC 0 36 4>,
<0x4000 0 0 1 &MPIC 0 43 4>, // SATA 0 (PCIe expander)
<0x4800 0 0 1 &MPIC 0 44 1>; // SATA 1 (onboard)
// ranges:
// - ECAM - non prefetchable config space
// - 32 bit non prefetchable memory space
ranges = <0x00000000 0x0 0xfbc00000 0xfbc00000 0x0 0x100000
0x02000000 0x0 0xfe000000 0xfe000000 0x0 0x1000000>;
bus-range = <0x00 0x00>;
};
// WORKAROUND: enabling PCIe controller when no card is plugged in
// leads to kernel panic because u-boot disables PCIe controller if no link
// is detected. Just be kind and compatible with Linux
/* // External PCIe Controller 0
pcie-external0 {
compatible = "annapurna-labs,al-external-pcie";
reg = <0xfd800000 0x00020000>;
device_type = "pci";
#size-cells = <2>;
#address-cells = <3>;
interrupt-parent = <&MPIC>;
interrupt-map-mask = <0x00 0 0 7>;
interrupt-map = <0x0000 0 0 1 &MPIC 0 40 4>;
// ranges:
// Controller 0:
// - ECAM - non prefetchable config space: 2MB
// - IO - IO port space 64KB, reserve 64KB from target memory windows
// real IO address on the pci bus starts at 0x10000
// - 32 bit non prefetchable memory space: 128MB - 64KB
ranges = <0x00000000 0x0 0xfb600000 0xfb600000 0x0 0x00200000
0x01000000 0x0 0x00010000 0xe0000000 0x0 0x00010000
0x02000000 0x0 0xe1000000 0xe1000000 0x0 0x06f00000>;
bus-range = <0x00 0xff>;
};
// External PCIe Controllers 1
pcie-external1 {
compatible = "annapurna-labs,al-external-pcie";
reg = <0xfd820000 0x00020000>;
device_type = "pci";
#size-cells = <2>;
#address-cells = <3>;
interrupt-parent = <&MPIC>;
interrupt-map-mask = <0x0 0 0 7>;
interrupt-map = <0x0000 0 0 1 &MPIC 0 41 4>;
// ranges:
// - ECAM - non prefetchable config space: 2MB
// - IO - IO port space 64KB, reserve 64KB from target memory windows
// real IO address on the pci bus starts at 0x20000
// - 32 bit non prefetchable memory space: 64MB - 64KB
ranges = <0x00000000 0x0 0xfb800000 0xfb800000 0x0 0x00200000
0x01000000 0x0 0x00020000 0xe8000000 0x0 0x00010000
0x02000000 0x0 0xe8100000 0xe8100000 0x0 0x02ff0000>;
bus-range = <0x00 0xff>;
}; */
chosen {
stdin = "serial0";
stdout = "serial0";
stddbg = "serial0";
};
};