soc: xtensa: Add SoC definition for Audio DSP on Intel Apollolake

Create an SoC definition for the Audio DSP on Intel Apollolake

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
Johan Hedberg 2019-11-19 12:33:35 +02:00 committed by Anas Nashif
commit 31706c874e
18 changed files with 2224 additions and 0 deletions

View file

@ -0,0 +1,85 @@
/*
* Copyright (c) 2019 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <xtensa/xtensa.dtsi>
#include <dt-bindings/i2c/i2c.h>
#include <mem.h>
/ {
cpus {
#address-cells = <1>;
#size-cells = <0>;
cpu0: cpu@0 {
device_type = "cpu";
compatible = "cadence,tensilica-xtensa-lx4";
reg = <0>;
};
cpu1: cpu@1 {
device_type = "cpu";
compatible = "cadence,tensilica-xtensa-lx4";
reg = <1>;
};
};
sram0: memory@be000000 {
device_type = "memory";
compatible = "mmio-sram";
reg = <0xbe000000 DT_SIZE_K(512)>;
};
sram1: memory@be800000 {
device_type = "memory";
compatible = "mmio-sram";
reg = <0xbe800000 DT_SIZE_K(128)>;
};
soc {
core_intc: core_intc@0 {
compatible = "xtensa,core-intc";
reg = <0x00 0x400>;
interrupt-controller;
#interrupt-cells = <3>;
};
cavs0: cavs@1600 {
compatible = "intel,cavs-intc";
reg = <0x1600 0x10>;
interrupt-controller;
#interrupt-cells = <3>;
interrupts = <6 0 0>;
interrupt-parent = <&core_intc>;
};
cavs1: cavs@1610 {
compatible = "intel,cavs-intc";
reg = <0x1610 0x10>;
interrupt-controller;
#interrupt-cells = <3>;
interrupts = <0xA 0 0>;
interrupt-parent = <&core_intc>;
};
cavs2: cavs@1620 {
compatible = "intel,cavs-intc";
reg = <0x1620 0x10>;
interrupt-controller;
#interrupt-cells = <3>;
interrupts = <0XD 0 0>;
interrupt-parent = <&core_intc>;
};
cavs3: cavs@1630 {
compatible = "intel,cavs-intc";
reg = <0x1630 0x10>;
interrupt-controller;
#interrupt-cells = <3>;
interrupts = <0x10 0 0>;
interrupt-parent = <&core_intc>;
};
};
};

View file

@ -0,0 +1,7 @@
# SPDX-License-Identifier: Apache-2.0
zephyr_library()
zephyr_library_include_directories(${ZEPHYR_BASE}/drivers)
zephyr_library_sources(adsp.c)
zephyr_library_sources(soc.c)
zephyr_library_sources(main_entry.S)

View file

@ -0,0 +1,62 @@
# Xtensa board configuration
# Copyright (c) 2017 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
if SOC_INTEL_APL_ADSP
config SOC
string
default "intel_apl_adsp"
config IRQ_OFFLOAD_INTNUM
default 0
# S1000 does not have MISC0.
# Since EXCSAVE2 is unused by Zephyr, use it instead.
config XTENSA_KERNEL_CPU_PTR_SR
default "EXCSAVE2"
config KERNEL_ENTRY
default "_MainEntry"
config MULTI_LEVEL_INTERRUPTS
default y
config 2ND_LEVEL_INTERRUPTS
default y
config DYNAMIC_INTERRUPTS
default y
config LOG
default y
if TEST
# To prevent test uses TEST_LOGGING_MINIMAL
config TEST_LOGGING_DEFAULTS
default n
endif # TEST
if LOG
config LOG_PRINTK
default y
config LOG_IMMEDIATE
default y
config LOG_BACKEND_ADSP
default y
config LOG_BACKEND_ADSP_RINGBUF_BASE
default "0xBE008000"
config LOG_BACKEND_ADSP_RINGBUF_SIZE
default "0x2000"
endif # LOG
endif

View file

@ -0,0 +1,7 @@
# Copyright (c) 2017 Intel Corporation
# SPDX-License-Identifier: Apache-2.0
config SOC_INTEL_APL_ADSP
bool "intel_apl_adsp"
select XTENSA_RESET_VECTOR
select XTENSA_USE_CORE_CRT1

View file

@ -0,0 +1,119 @@
/*
* Copyright (c) 2019 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <device.h>
#include <init.h>
#include <platform/ipc.h>
#include <platform/mailbox.h>
#include <platform/shim.h>
#include "soc.h"
static const struct adsp_ipc_fw_ready fw_ready_apl
__attribute__((section(".fw_ready"))) __attribute__((used)) = {
.hdr = {
.cmd = ADSP_IPC_FW_READY,
.size = sizeof(struct adsp_ipc_fw_ready),
},
.version = {
.hdr.size = sizeof(struct adsp_ipc_fw_version),
.micro = 0,
.minor = 1,
.major = 0,
.build = 0,
.date = __DATE__,
.time = __TIME__,
.tag = "zephyr",
.abi_version = 0,
},
.flags = 0,
};
#define NUM_WINDOWS 2
static const struct adsp_ipc_window sram_window = {
.ext_hdr = {
.hdr.cmd = ADSP_IPC_FW_READY,
.hdr.size = sizeof(struct adsp_ipc_window) +
sizeof(struct adsp_ipc_window_elem) * NUM_WINDOWS,
.type = ADSP_IPC_EXT_WINDOW,
},
.num_windows = NUM_WINDOWS,
.window = {
{
.type = ADSP_IPC_REGION_REGS,
.id = 0, /* map to host window 0 */
.flags = 0,
.size = MAILBOX_SW_REG_SIZE,
.offset = 0,
},
{
.type = ADSP_IPC_REGION_TRACE,
.id = 3, /* map to host window 3 */
.flags = 0,
.size = MAILBOX_TRACE_SIZE,
.offset = 0,
},
},
};
/*
* Sets up the host windows so that the host can see the memory
* content on the DSP SRAM.
*/
static void prepare_host_windows(void)
{
/* window0, for fw status */
sys_write32((HP_SRAM_WIN0_SIZE | 0x7), DMWLO(0));
sys_write32((HP_SRAM_WIN0_BASE | DMWBA_READONLY | DMWBA_ENABLE),
DMWBA(0));
memset((void *)(HP_SRAM_WIN0_BASE + SRAM_REG_FW_END), 0,
HP_SRAM_WIN0_SIZE - SRAM_REG_FW_END);
SOC_DCACHE_FLUSH((void *)(HP_SRAM_WIN0_BASE + SRAM_REG_FW_END),
HP_SRAM_WIN0_SIZE - SRAM_REG_FW_END);
/* window3, for trace
* zeroed by trace initialization
*/
sys_write32((HP_SRAM_WIN3_SIZE | 0x7), DMWLO(3));
sys_write32((HP_SRAM_WIN3_BASE | DMWBA_READONLY | DMWBA_ENABLE),
DMWBA(3));
memset((void *)HP_SRAM_WIN3_BASE, 0, HP_SRAM_WIN3_SIZE);
SOC_DCACHE_FLUSH((void *)HP_SRAM_WIN3_BASE, HP_SRAM_WIN3_SIZE);
}
/*
* Sends the firmware ready message so the firmware loader can
* map the host windows.
*/
static void send_fw_ready(void)
{
memcpy((void *)MAILBOX_DSPBOX_BASE,
&fw_ready_apl, sizeof(fw_ready_apl));
memcpy((void *)(MAILBOX_DSPBOX_BASE + sizeof(fw_ready_apl)),
&sram_window,
(sizeof(sram_window) + sram_window.ext_hdr.hdr.size));
SOC_DCACHE_FLUSH((void *)MAILBOX_DSPBOX_BASE, MAILBOX_DSPBOX_SIZE);
ipc_write(IPC_DIPCIE, 0);
ipc_write(IPC_DIPCI, (0x80000000 | ADSP_IPC_FW_READY));
}
static int adsp_init(struct device *dev)
{
prepare_host_windows();
send_fw_ready();
return 0;
}
SYS_INIT(adsp_init, APPLICATION, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);

View file

@ -0,0 +1,32 @@
/*
* Copyright (c) 2019 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
/* SoC level DTS fixup file */
#define DT_L2_SRAM_BASE CONFIG_SRAM_BASE_ADDRESS
#define DT_L2_SRAM_SIZE (CONFIG_SRAM_SIZE * 1024)
#define DT_LP_SRAM_BASE DT_INST_1_MMIO_SRAM_BASE_ADDRESS
#define DT_LP_SRAM_SIZE DT_INST_1_MMIO_SRAM_SIZE
#define DT_CAVS_ICTL_BASE_ADDR DT_INTEL_CAVS_INTC_1600_BASE_ADDRESS
#define DT_CAVS_ICTL_0_IRQ DT_INTEL_CAVS_INTC_1600_IRQ_0
#define DT_CAVS_ICTL_0_IRQ_PRI DT_INTEL_CAVS_INTC_1600_IRQ_0_PRIORITY
#define DT_CAVS_ICTL_0_IRQ_FLAGS DT_INTEL_CAVS_INTC_1600_IRQ_0_SENSE
#define DT_CAVS_ICTL_1_IRQ DT_INTEL_CAVS_INTC_1610_IRQ_0
#define DT_CAVS_ICTL_1_IRQ_PRI DT_INTEL_CAVS_INTC_1610_IRQ_0_PRIORITY
#define DT_CAVS_ICTL_1_IRQ_FLAGS DT_INTEL_CAVS_INTC_1610_IRQ_0_SENSE
#define DT_CAVS_ICTL_2_IRQ DT_INTEL_CAVS_INTC_1620_IRQ_0
#define DT_CAVS_ICTL_2_IRQ_PRI DT_INTEL_CAVS_INTC_1620_IRQ_0_PRIORITY
#define DT_CAVS_ICTL_2_IRQ_FLAGS DT_INTEL_CAVS_INTC_1620_IRQ_0_SENSE
#define DT_CAVS_ICTL_3_IRQ DT_INTEL_CAVS_INTC_1630_IRQ_0
#define DT_CAVS_ICTL_3_IRQ_PRI DT_INTEL_CAVS_INTC_1630_IRQ_0_PRIORITY
#define DT_CAVS_ICTL_3_IRQ_FLAGS DT_INTEL_CAVS_INTC_1630_IRQ_0_SENSE
/* End of SoC Level DTS fixup file */

View file

@ -0,0 +1,265 @@
/*
* THIS FILE WAS AUTOMATICALLY GENERATED. DO NOT EDIT.
*
* Functions here are designed to produce efficient code to
* search an Xtensa bitmask of interrupts, inspecting only those bits
* declared to be associated with a given interrupt level. Each
* dispatcher will handle exactly one flagged interrupt, in numerical
* order (low bits first) and will return a mask of that bit that can
* then be cleared by the calling code. Unrecognized bits for the
* level will invoke an error handler.
*/
#include <xtensa/config/core-isa.h>
#include <sys/util.h>
#include <sw_isr_table.h>
#if !defined(XCHAL_INT0_LEVEL) || XCHAL_INT0_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT1_LEVEL) || XCHAL_INT1_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT2_LEVEL) || XCHAL_INT2_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT3_LEVEL) || XCHAL_INT3_LEVEL != 1
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT4_LEVEL) || XCHAL_INT4_LEVEL != 2
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT5_LEVEL) || XCHAL_INT5_LEVEL != 2
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT6_LEVEL) || XCHAL_INT6_LEVEL != 2
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT7_LEVEL) || XCHAL_INT7_LEVEL != 2
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT8_LEVEL) || XCHAL_INT8_LEVEL != 3
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT9_LEVEL) || XCHAL_INT9_LEVEL != 3
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT10_LEVEL) || XCHAL_INT10_LEVEL != 3
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT11_LEVEL) || XCHAL_INT11_LEVEL != 3
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT12_LEVEL) || XCHAL_INT12_LEVEL != 4
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT13_LEVEL) || XCHAL_INT13_LEVEL != 4
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT14_LEVEL) || XCHAL_INT14_LEVEL != 4
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT15_LEVEL) || XCHAL_INT15_LEVEL != 5
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT16_LEVEL) || XCHAL_INT16_LEVEL != 5
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT17_LEVEL) || XCHAL_INT17_LEVEL != 5
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT18_LEVEL) || XCHAL_INT18_LEVEL != 5
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT19_LEVEL) || XCHAL_INT19_LEVEL != 5
#error core-isa.h interrupt level does not match dispatcher!
#endif
#if !defined(XCHAL_INT20_LEVEL) || XCHAL_INT20_LEVEL != 7
#error core-isa.h interrupt level does not match dispatcher!
#endif
static inline int _xtensa_handle_one_int1(unsigned int mask)
{
int irq;
if (mask & 0x3) {
if (mask & BIT(0)) {
mask = BIT(0);
irq = 0;
goto handle_irq;
}
if (mask & BIT(1)) {
mask = BIT(1);
irq = 1;
goto handle_irq;
}
} else {
if (mask & BIT(2)) {
mask = BIT(2);
irq = 2;
goto handle_irq;
}
if (mask & BIT(3)) {
mask = BIT(3);
irq = 3;
goto handle_irq;
}
}
return 0;
handle_irq:
_sw_isr_table[irq].isr(_sw_isr_table[irq].arg);
return mask;
}
static inline int _xtensa_handle_one_int2(unsigned int mask)
{
int irq;
if (mask & 0x30) {
if (mask & BIT(4)) {
mask = BIT(4);
irq = 4;
goto handle_irq;
}
if (mask & BIT(5)) {
mask = BIT(5);
irq = 5;
goto handle_irq;
}
} else {
if (mask & BIT(6)) {
mask = BIT(6);
irq = 6;
goto handle_irq;
}
if (mask & BIT(7)) {
mask = BIT(7);
irq = 7;
goto handle_irq;
}
}
return 0;
handle_irq:
_sw_isr_table[irq].isr(_sw_isr_table[irq].arg);
return mask;
}
static inline int _xtensa_handle_one_int3(unsigned int mask)
{
int irq;
if (mask & 0x300) {
if (mask & BIT(8)) {
mask = BIT(8);
irq = 8;
goto handle_irq;
}
if (mask & BIT(9)) {
mask = BIT(9);
irq = 9;
goto handle_irq;
}
} else {
if (mask & BIT(10)) {
mask = BIT(10);
irq = 10;
goto handle_irq;
}
if (mask & BIT(11)) {
mask = BIT(11);
irq = 11;
goto handle_irq;
}
}
return 0;
handle_irq:
_sw_isr_table[irq].isr(_sw_isr_table[irq].arg);
return mask;
}
static inline int _xtensa_handle_one_int4(unsigned int mask)
{
int irq;
if (mask & BIT(12)) {
mask = BIT(12);
irq = 12;
goto handle_irq;
}
if (mask & BIT(13)) {
mask = BIT(13);
irq = 13;
goto handle_irq;
}
if (mask & BIT(14)) {
mask = BIT(14);
irq = 14;
goto handle_irq;
}
return 0;
handle_irq:
_sw_isr_table[irq].isr(_sw_isr_table[irq].arg);
return mask;
}
static inline int _xtensa_handle_one_int5(unsigned int mask)
{
int irq;
if (mask & 0x18000) {
if (mask & BIT(15)) {
mask = BIT(15);
irq = 15;
goto handle_irq;
}
if (mask & BIT(16)) {
mask = BIT(16);
irq = 16;
goto handle_irq;
}
} else {
if (mask & BIT(17)) {
mask = BIT(17);
irq = 17;
goto handle_irq;
}
if (mask & BIT(18)) {
mask = BIT(18);
irq = 18;
goto handle_irq;
}
if (mask & BIT(19)) {
mask = BIT(19);
irq = 19;
goto handle_irq;
}
}
return 0;
handle_irq:
_sw_isr_table[irq].isr(_sw_isr_table[irq].arg);
return mask;
}
static inline int _xtensa_handle_one_int7(unsigned int mask)
{
int irq;
if (mask & BIT(20)) {
mask = BIT(20);
irq = 20;
goto handle_irq;
}
return 0;
handle_irq:
_sw_isr_table[irq].isr(_sw_isr_table[irq].arg);
return mask;
}
static inline int _xtensa_handle_one_int0(unsigned int mask)
{
return 0;
}
static inline int _xtensa_handle_one_int6(unsigned int mask)
{
return 0;
}

View file

@ -0,0 +1,44 @@
/*
* Copyright(c) 2016 Intel Corporation. All rights reserved.
*
* SPDX-License-Identifier: Apache-2.0
*
* Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
*/
#ifndef __INCLUDE_IO__
#define __INCLUDE_IO__
#include <stdint.h>
#include <sys/sys_io.h>
#include <arch/common/sys_io.h>
static inline uint32_t io_reg_read(uint32_t reg)
{
return sys_read32(reg);
}
static inline void io_reg_write(uint32_t reg, uint32_t val)
{
/* Note: Parameters in different order */
sys_write32(val, reg);
}
static inline void io_reg_update_bits(uint32_t reg, uint32_t mask,
uint32_t value)
{
io_reg_write(reg, (io_reg_read(reg) & (~mask)) | (value & mask));
}
static inline uint16_t io_reg_read16(uint32_t reg)
{
return sys_read16(reg);
}
static inline void io_reg_write16(uint32_t reg, uint16_t val)
{
/* Note: Parameters in different order */
sys_write16(val, reg);
}
#endif

View file

@ -0,0 +1,114 @@
/*
* Copyright (c) 2019 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __INCLUDE_PLATFORM_IPC_H__
#define __INCLUDE_PLATFORM_IPC_H__
/** Shift-left bits to extract the global cmd type */
#define ADSP_GLB_TYPE_SHIFT 28
#define ADSP_GLB_TYPE_MASK (0xf << ADSP_GLB_TYPE_SHIFT)
#define ADSP_GLB_TYPE(x) ((x) << ADSP_GLB_TYPE_SHIFT)
/** Shift-left bits to extract the command type */
#define ADSP_CMD_TYPE_SHIFT 16
#define ADSP_CMD_TYPE_MASK (0xfff << ADSP_CMD_TYPE_SHIFT)
#define ADSP_CMD_TYPE(x) ((x) << ADSP_CMD_TYPE_SHIFT)
#define ADSP_IPC_FW_READY ADSP_GLB_TYPE(0x7U)
/* extended data types that can be appended onto end of adsp_ipc_fw_ready */
enum adsp_ipc_ext_data {
ADSP_IPC_EXT_DMA_BUFFER = 0,
ADSP_IPC_EXT_WINDOW,
};
enum adsp_ipc_region {
ADSP_IPC_REGION_DOWNBOX = 0,
ADSP_IPC_REGION_UPBOX,
ADSP_IPC_REGION_TRACE,
ADSP_IPC_REGION_DEBUG,
ADSP_IPC_REGION_STREAM,
ADSP_IPC_REGION_REGS,
ADSP_IPC_REGION_EXCEPTION,
};
/**
* Structure Header - Header for all IPC structures except command structs.
* The size can be greater than the structure size and that means there is
* extended bespoke data beyond the end of the structure including variable
* arrays.
*/
struct adsp_ipc_hdr {
uint32_t size; /**< size of structure */
} __packed;
/**
* Command Header - Header for all IPC commands. Identifies IPC message.
* The size can be greater than the structure size and that means there is
* extended bespoke data beyond the end of the structure including variable
* arrays.
*/
struct adsp_ipc_cmd_hdr {
uint32_t size; /**< size of structure */
uint32_t cmd; /**< command */
} __packed;
/* FW version */
struct adsp_ipc_fw_version {
struct adsp_ipc_hdr hdr;
uint16_t major;
uint16_t minor;
uint16_t micro;
uint16_t build;
uint8_t date[12];
uint8_t time[10];
uint8_t tag[6];
uint32_t abi_version;
/* reserved for future use */
uint32_t reserved[4];
} __packed;
/* FW ready Message - sent by firmware when boot has completed */
struct adsp_ipc_fw_ready {
struct adsp_ipc_cmd_hdr hdr;
uint32_t dspbox_offset; /* dsp initiated IPC mailbox */
uint32_t hostbox_offset; /* host initiated IPC mailbox */
uint32_t dspbox_size;
uint32_t hostbox_size;
struct adsp_ipc_fw_version version;
/* Miscellaneous flags */
uint64_t flags;
/* reserved for future use */
uint32_t reserved[4];
} __packed;
struct adsp_ipc_ext_data_hdr {
struct adsp_ipc_cmd_hdr hdr;
uint32_t type; /* ADSP_IPC_EXT_ */
} __packed;
struct adsp_ipc_window_elem {
struct adsp_ipc_hdr hdr;
uint32_t type; /* ADSP_IPC_REGION_ */
uint32_t id; /* platform specific */
uint32_t flags; /**< R, W, RW, etc */
uint32_t size; /* size of region in bytes */
/* offset in window region as windows can be partitioned */
uint32_t offset;
} __packed;
/* extended data memory windows for IPC, trace and debug */
struct adsp_ipc_window {
struct adsp_ipc_ext_data_hdr ext_hdr;
uint32_t num_windows;
struct adsp_ipc_window_elem window[];
} __packed;
#endif /* __INCLUDE_PLATFORM_IPC_H__ */

View file

@ -0,0 +1,61 @@
/* SPDX-License-Identifier: Apache-2.0
*
* Copyright(c) 2016 Intel Corporation. All rights reserved.
*
* Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
* Keyon Jie <yang.jie@linux.intel.com>
*/
#ifndef __INCLUDE_PLATFORM_MAILBOX__
#define __INCLUDE_PLATFORM_MAILBOX__
#include <platform/memory.h>
/*
* The Window Region on HPSRAM for cAVS platforms is organised like this :-
* +--------------------------------------------------------------------------+
* | Offset | Region | Size |
* +---------------------+----------------+-----------------------------------+
* | SRAM_TRACE_BASE | Trace Buffer W3| SRAM_TRACE_SIZE |
* +---------------------+----------------+-----------------------------------+
* | SRAM_DEBUG_BASE | Debug data W2 | SRAM_DEBUG_SIZE |
* +---------------------+----------------+-----------------------------------+
* | SRAM_INBOX_BASE | Inbox W1 | SRAM_INBOX_SIZE |
* +---------------------+----------------+-----------------------------------+
* | SRAM_OUTBOX_BASE | Outbox W0 | SRAM_MAILBOX_SIZE |
* +---------------------+----------------+-----------------------------------+
* | SRAM_SW_REG_BASE | SW Registers W0| SRAM_SW_REG_SIZE |
* +---------------------+----------------+-----------------------------------+
*
* Note: For suecreek SRAM_SW_REG window does not exist - MAILBOX_SW_REG_BASE
* and MAILBOX_SW_REG_BASE are equal to 0
*/
/* window 3 - trace */
#define MAILBOX_TRACE_SIZE SRAM_TRACE_SIZE
#define MAILBOX_TRACE_BASE SRAM_TRACE_BASE
/* window 2 debug, exception and stream */
#define MAILBOX_DEBUG_SIZE SRAM_DEBUG_SIZE
#define MAILBOX_DEBUG_BASE SRAM_DEBUG_BASE
#define MAILBOX_EXCEPTION_SIZE SRAM_EXCEPT_SIZE
#define MAILBOX_EXCEPTION_BASE SRAM_EXCEPT_BASE
#define MAILBOX_EXCEPTION_OFFSET SRAM_DEBUG_SIZE
#define MAILBOX_STREAM_SIZE SRAM_STREAM_SIZE
#define MAILBOX_STREAM_BASE SRAM_STREAM_BASE
#define MAILBOX_STREAM_OFFSET (SRAM_DEBUG_SIZE + SRAM_EXCEPT_SIZE)
/* window 1 inbox/downlink and FW registers */
#define MAILBOX_HOSTBOX_SIZE SRAM_INBOX_SIZE
#define MAILBOX_HOSTBOX_BASE SRAM_INBOX_BASE
/* window 0 */
#define MAILBOX_DSPBOX_SIZE SRAM_OUTBOX_SIZE
#define MAILBOX_DSPBOX_BASE SRAM_OUTBOX_BASE
#define MAILBOX_SW_REG_SIZE SRAM_SW_REG_SIZE
#define MAILBOX_SW_REG_BASE SRAM_SW_REG_BASE
#endif

View file

@ -0,0 +1,171 @@
/* SPDX-License-Identifier: Apache-2.0
*
* Copyright(c) 2016 Intel Corporation. All rights reserved.
*
* Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
* Keyon Jie <yang.jie@linux.intel.com>
*/
#ifndef __PLATFORM_MEMORY_H__
#define __PLATFORM_MEMORY_H__
/* Memory banks */
#define NUM_LP_MEMORY_BANKS 2
#define NUM_HP_MEMORY_BANKS 8
#define SRAM_BANK_SIZE (64 * 1024)
#define EBB_BANKS_IN_SEGMENT 32
#define EBB_SEGMENT_SIZE EBB_BANKS_IN_SEGMENT
#define PLATFORM_LPSRAM_EBB_COUNT NUM_LP_MEMORY_BANKS
#define PLATFORM_HPSRAM_EBB_COUNT NUM_HP_MEMORY_BANKS
#define LP_SRAM_SIZE (NUM_LP_MEMORY_BANKS * SRAM_BANK_SIZE)
#define HP_SRAM_SIZE (NUM_HP_MEMORY_BANKS * SRAM_BANK_SIZE)
#define LPSRAM_MASK(ignored) ((1 << PLATFORM_LPSRAM_EBB_COUNT) - 1)
#define HPSRAM_MASK(seg_idx) ((1 << (PLATFORM_HPSRAM_EBB_COUNT \
- EBB_BANKS_IN_SEGMENT * seg_idx)) - 1)
/* physical DSP addresses */
/* shim */
#define SHIM_BASE 0x00001000
#define SHIM_SIZE 0x00000100
/* IPC to the host */
#define IPC_HOST_BASE 0x00001180
#define IPC_HOST_SIZE 0x00000020
/* SRAM window for HOST */
#define HOST_WIN_SIZE 0x00000008
#define HOST_WIN_BASE(x) (0x00001580 + x * HOST_WIN_SIZE)
#define L2_VECTOR_SIZE 0x1000
/*
* The HP SRAM Region Apollolake is organised like this :-
* +--------------------------------------------------------------------------+
* | Offset | Region | Size |
* +---------------------+----------------+-----------------------------------+
* | HP_SRAM_BASE | DMA | HEAP_HP_BUFFER_SIZE |
* +---------------------+----------------+-----------------------------------+
* | SRAM_TRACE_BASE | Trace Buffer W3| SRAM_TRACE_SIZE |
* +---------------------+----------------+-----------------------------------+
* | SRAM_DEBUG_BASE | Debug data W2 | SRAM_DEBUG_SIZE |
* +---------------------+----------------+-----------------------------------+
* | SRAM_EXCEPT_BASE | Debug data W2 | SRAM_EXCEPT_SIZE |
* +---------------------+----------------+-----------------------------------+
* | SRAM_STREAM_BASE | Stream data W2 | SRAM_STREAM_SIZE |
* +---------------------+----------------+-----------------------------------+
* | SRAM_INBOX_BASE | Inbox W1 | SRAM_INBOX_SIZE |
* +---------------------+----------------+-----------------------------------+
* | SRAM_SW_REG_BASE | SW Registers W0| SRAM_SW_REG_SIZE |
* +---------------------+----------------+-----------------------------------+
* | SRAM_OUTBOX_BASE | Outbox W0 | SRAM_MAILBOX_SIZE |
* +---------------------+----------------+-----------------------------------+
*/
/* HP SRAM */
#define HP_SRAM_BASE 0xBE000000
#define HP_SRAM_MASK 0xFF000000
/* HP SRAM Heap */
#define HEAP_HP_BUFFER_BASE HP_SRAM_BASE
#define HEAP_HP_BUFFER_SIZE 0x8000
#define HEAP_HP_BUFFER_BLOCK_SIZE 0x180
#define HEAP_HP_BUFFER_COUNT \
(HEAP_HP_BUFFER_SIZE / HEAP_HP_BUFFER_BLOCK_SIZE)
/* HP SRAM windows */
/* window 3 */
#define SRAM_TRACE_BASE SRAM_WND_BASE
#define SRAM_TRACE_SIZE 0x2000
/* window 2 */
#define SRAM_DEBUG_BASE (SRAM_TRACE_BASE + SRAM_TRACE_SIZE)
#define SRAM_DEBUG_SIZE 0x800
#define SRAM_EXCEPT_BASE (SRAM_DEBUG_BASE + SRAM_DEBUG_SIZE)
#define SRAM_EXCEPT_SIZE 0x800
#define SRAM_STREAM_BASE (SRAM_EXCEPT_BASE + SRAM_EXCEPT_SIZE)
#define SRAM_STREAM_SIZE 0x1000
/* window 1 */
#define SRAM_INBOX_BASE (SRAM_STREAM_BASE + SRAM_STREAM_SIZE)
#define SRAM_INBOX_SIZE 0x2000
/* window 0 */
#define SRAM_SW_REG_BASE (SRAM_INBOX_BASE + SRAM_INBOX_SIZE)
#define SRAM_SW_REG_SIZE 0x1000
/* SRAM window 0 FW "registers" */
#define SRAM_REG_ROM_STATUS 0x0
#define SRAM_REG_FW_STATUS 0x4
#define SRAM_REG_FW_TRACEP 0x8
#define SRAM_REG_FW_IPC_RECEIVED_COUNT 0xc
#define SRAM_REG_FW_IPC_PROCESSED_COUNT 0x10
#define SRAM_REG_FW_END 0x14
#define SRAM_OUTBOX_BASE (SRAM_SW_REG_BASE + SRAM_SW_REG_SIZE)
#define SRAM_OUTBOX_SIZE 0x1000
#define HP_SRAM_WIN0_BASE SRAM_SW_REG_BASE
#define HP_SRAM_WIN0_SIZE (SRAM_SW_REG_SIZE + SRAM_OUTBOX_SIZE)
#define HP_SRAM_WIN1_BASE SRAM_INBOX_BASE
#define HP_SRAM_WIN1_SIZE SRAM_INBOX_SIZE
#define HP_SRAM_WIN2_BASE SRAM_DEBUG_BASE
#define HP_SRAM_WIN2_SIZE (SRAM_DEBUG_SIZE + SRAM_EXCEPT_SIZE + \
SRAM_STREAM_SIZE)
#define HP_SRAM_WIN3_BASE SRAM_TRACE_BASE
#define HP_SRAM_WIN3_SIZE SRAM_TRACE_SIZE
/* Apollolake HP-SRAM config */
#define SRAM_ALIAS_OFFSET 0x20000000
#define SRAM_WND_BASE (HEAP_HP_BUFFER_BASE + HEAP_HP_BUFFER_SIZE)
#define HP_SRAM_VECBASE_RESET (HP_SRAM_WIN0_BASE + HP_SRAM_WIN0_SIZE)
#define HP_SRAM_VECBASE_OFFSET 0x0
#define SOF_FW_START (HP_SRAM_VECBASE_RESET + 0x400)
#define SOF_FW_BASE (SOF_FW_START)
/* max size for all var-size sections (text/rodata/bss) */
#define SOF_FW_MAX_SIZE (0x41000 - 0x400)
#define SOF_TEXT_START (SOF_FW_START)
#define SOF_TEXT_BASE (SOF_FW_START)
/* Stack configuration */
#define SOF_STACK_BASE (HP_SRAM_BASE + HP_SRAM_SIZE)
#define SOF_STACK_END (SOF_STACK_BASE - SOF_STACK_TOTAL_SIZE)
#define SOF_MEMORY_SIZE (SOF_STACK_BASE - HP_SRAM_BASE)
/* LP SRAM */
#define LP_SRAM_BASE 0xBE800000
/* boot loader in IMR */
#define IMR_BOOT_LDR_TEXT_ENTRY_BASE 0xB000A000
#define IMR_BOOT_LDR_TEXT_ENTRY_SIZE 0x86
/* Manifest base address in IMR - used by boot loader copy procedure. */
#define IMR_BOOT_LDR_MANIFEST_BASE 0xB0004000
/* Manifest size (seems unused). */
#define IMR_BOOT_LDR_MANIFEST_SIZE 0x6000
#endif

View file

@ -0,0 +1,40 @@
/* SPDX-License-Identifier: Apache-2.0
*
* Copyright(c) 2016 Intel Corporation. All rights reserved.
*
* Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
* Keyon Jie <yang.jie@linux.intel.com>
* Xiuli Pan <xiuli.pan@linux.intel.com>
*/
#ifndef __PLATFORM_PLATFORM_H__
#define __PLATFORM_PLATFORM_H__
#include <xtensa/config/core.h>
#include <platform/memory.h>
#define PLATFORM_RESET_MHE_AT_BOOT 1
#define PLATFORM_DISABLE_L2CACHE_AT_BOOT 1
#define PLATFORM_MASTER_CORE_ID 0
#define MAX_CORE_COUNT 2
#if PLATFORM_CORE_COUNT > MAX_CORE_COUNT
#error "Invalid core count - exceeding core limit"
#endif
#if !defined(__ASSEMBLER__) && !defined(LINKER)
#include <platform/mailbox.h>
#include <platform/io.h>
#include <platform/shim.h>
/* Host page size */
#define HOST_PAGE_SIZE 4096
#endif /* !defined(__ASSEMBLER__) && !defined(LINKER) */
#endif /* __PLATFORM_PLATFORM_H__ */

View file

@ -0,0 +1,123 @@
/* SPDX-License-Identifier: Apache-2.0
*
* Copyright(c) 2016 Intel Corporation. All rights reserved.
*
* Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
* Keyon Jie <yang.jie@linux.intel.com>
*/
#ifndef __PLATFORM_SHIM_H__
#define __PLATFORM_SHIM_H__
#include <platform/memory.h>
#ifndef ASSEMBLY
#include <stdint.h>
#endif
#if !defined(__ASSEMBLER__) && !defined(LINKER)
#include <sys/sys_io.h>
#include <arch/common/sys_io.h>
#endif
#ifndef BIT
#define BIT(b) (1 << (b))
#endif
/* DSP IPC for Host Registers */
#define IPC_DIPCT 0x00
#define IPC_DIPCTE 0x04
#define IPC_DIPCI 0x08
#define IPC_DIPCIE 0x0c
#define IPC_DIPCCTL 0x10
/* DIPCT */
#define IPC_DIPCT_BUSY (1 << 31)
#define IPC_DIPCT_MSG_MASK 0x7FFFFFFF
/* DIPCTE */
#define IPC_DIPCTE_MSG_MASK 0x3FFFFFFF
/* DIPCI */
#define IPC_DIPCI_BUSY (1 << 31)
#define IPC_DIPCI_MSG_MASK 0x7FFFFFFF
/* DIPCIE */
#define IPC_DIPCIE_DONE (1 << 30)
#define IPC_DIPCIE_MSG_MASK 0x3FFFFFFF
/* DIPCCTL */
#define IPC_DIPCCTL_IPCIDIE (1 << 1)
#define IPC_DIPCCTL_IPCTBIE (1 << 0)
#define IPC_DSP_OFFSET 0x10
#define SHIM_PWRCTL 0x90
#define SHIM_PWRSTS 0x92
#define SHIM_LPSCTL 0x94
/* HP & LP SRAM Power Gating */
#define SHIM_HSPGCTL 0x80
#define SHIM_LSPGCTL 0x84
#define SHIM_SPSREQ 0xa0
#define LSPGCTL SHIM_LSPGCTL
#define SHIM_SPSREQ_RVNNP (0x1 << 0)
/** \brief LDO Control */
#define SHIM_LDOCTL 0xA4
#define SHIM_LDOCTL_HPSRAM_MASK (3 << 0)
#define SHIM_LDOCTL_LPSRAM_MASK (3 << 2)
#define SHIM_LDOCTL_HPSRAM_LDO_ON (3 << 0)
#define SHIM_LDOCTL_LPSRAM_LDO_ON (3 << 2)
#define SHIM_LDOCTL_HPSRAM_LDO_BYPASS BIT(0)
#define SHIM_LDOCTL_LPSRAM_LDO_BYPASS BIT(2)
#define SHIM_LDOCTL_HPSRAM_LDO_OFF (0 << 0)
#define SHIM_LDOCTL_LPSRAM_LDO_OFF (0 << 2)
#define SHIM_HSPGISTS 0xb0
#define SHIM_LSPGISTS 0xb4
#define LSPGISTS (SHIM_BASE + SHIM_LSPGISTS)
#define SHIM_LPSCTL_FDSPRUN (0X1 << 9)
#define SHIM_LPSCTL_FDMARUN (0X1 << 8)
#define SHIM_L2_MECS (SHIM_BASE + 0xd0)
#define SHIM_L2_CACHE_CTRL (SHIM_BASE + 0x500)
#define SHIM_L2_PREF_CFG (SHIM_BASE + 0x508)
#define SHIM_L2_CACHE_PREF (SHIM_BASE + 0x510)
/* host windows */
#define DMWBA(x) (HOST_WIN_BASE(x) + 0x0)
#define DMWLO(x) (HOST_WIN_BASE(x) + 0x4)
#define DMWBA_ENABLE (1 << 0)
#define DMWBA_READONLY (1 << 1)
#if !defined(__ASSEMBLER__) && !defined(LINKER)
static inline uint32_t shim_read(uint32_t reg)
{
return sys_read32(SHIM_BASE + reg);
}
static inline void shim_write(uint32_t reg, uint32_t val)
{
sys_write32(val, (SHIM_BASE + reg));
}
static inline uint32_t ipc_read(uint32_t reg)
{
return sys_read32(IPC_HOST_BASE + reg);
}
static inline void ipc_write(uint32_t reg, uint32_t val)
{
sys_write32(val, (IPC_HOST_BASE + reg));
}
#endif /* !defined(__ASSEMBLER__) && !defined(LINKER) */
#endif

View file

@ -0,0 +1,497 @@
/*
* Copyright (c) 2019 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief Linker command/script file
*
* Linker script for the intel_apl_adsp platform
*/
OUTPUT_ARCH(xtensa)
#include <devicetree.h>
#include "memory.h"
#include <autoconf.h>
#include <linker/sections.h>
#include <linker/linker-defs.h>
#include <linker/linker-tool.h>
PROVIDE(__memctl_default = 0x00000000);
PROVIDE(_MemErrorHandler = 0x00000000);
#define RAMABLE_REGION ram :ram_phdr
#define ROMABLE_REGION ram :ram_phdr
#define LPRAM_REGION lpram
MEMORY
{
vector_memory_lit :
org = XCHAL_MEMERROR_VECTOR_PADDR + MEM_ERROR_LIT_SIZE,
len = MEM_ERROR_LIT_SIZE
vector_memory_text :
org = XCHAL_MEMERROR_VECTOR_PADDR,
len = MEM_ERROR_TEXT_SIZE
vector_base_text :
org = XCHAL_VECBASE_RESET_PADDR_SRAM,
len = MEM_VECBASE_LIT_SIZE
vector_int2_lit :
org = XCHAL_INTLEVEL2_VECTOR_PADDR_SRAM - MEM_VECT_LIT_SIZE,
len = MEM_VECT_LIT_SIZE
vector_int2_text :
org = XCHAL_INTLEVEL2_VECTOR_PADDR_SRAM,
len = MEM_VECT_TEXT_SIZE
vector_int3_lit :
org = XCHAL_INTLEVEL3_VECTOR_PADDR_SRAM - MEM_VECT_LIT_SIZE,
len = MEM_VECT_LIT_SIZE
vector_int3_text :
org = XCHAL_INTLEVEL3_VECTOR_PADDR_SRAM,
len = MEM_VECT_TEXT_SIZE
vector_int4_lit :
org = XCHAL_INTLEVEL4_VECTOR_PADDR_SRAM - MEM_VECT_LIT_SIZE,
len = MEM_VECT_LIT_SIZE
vector_int4_text :
org = XCHAL_INTLEVEL4_VECTOR_PADDR_SRAM,
len = MEM_VECT_TEXT_SIZE
vector_int5_lit :
org = XCHAL_INTLEVEL5_VECTOR_PADDR_SRAM - MEM_VECT_LIT_SIZE,
len = MEM_VECT_LIT_SIZE
vector_int5_text :
org = XCHAL_INTLEVEL5_VECTOR_PADDR_SRAM,
len = MEM_VECT_TEXT_SIZE
vector_int6_lit :
org = XCHAL_INTLEVEL6_VECTOR_PADDR_SRAM - MEM_VECT_LIT_SIZE,
len = MEM_VECT_LIT_SIZE
vector_int6_text :
org = XCHAL_INTLEVEL6_VECTOR_PADDR_SRAM,
len = MEM_VECT_TEXT_SIZE
vector_int7_lit :
org = XCHAL_INTLEVEL7_VECTOR_PADDR_SRAM - MEM_VECT_LIT_SIZE,
len = MEM_VECT_LIT_SIZE
vector_int7_text :
org = XCHAL_INTLEVEL7_VECTOR_PADDR_SRAM,
len = MEM_VECT_TEXT_SIZE
vector_kernel_lit :
org = XCHAL_KERNEL_VECTOR_PADDR_SRAM - MEM_VECT_LIT_SIZE,
len = MEM_VECT_LIT_SIZE
vector_kernel_text :
org = XCHAL_KERNEL_VECTOR_PADDR_SRAM,
len = MEM_VECT_TEXT_SIZE
vector_user_lit :
org = XCHAL_USER_VECTOR_PADDR_SRAM - MEM_VECT_LIT_SIZE,
len = MEM_VECT_LIT_SIZE
vector_user_text :
org = XCHAL_USER_VECTOR_PADDR_SRAM,
len = MEM_VECT_TEXT_SIZE
vector_double_lit :
org = XCHAL_DOUBLEEXC_VECTOR_PADDR_SRAM - MEM_VECT_LIT_SIZE,
len = MEM_VECT_LIT_SIZE
vector_double_text :
org = XCHAL_DOUBLEEXC_VECTOR_PADDR_SRAM,
len = MEM_VECT_TEXT_SIZE
ram :
org = RAM_BASE,
len = RAM_SIZE
#ifdef CONFIG_GEN_ISR_TABLES
IDT_LIST :
org = IDT_BASE,
len = IDT_SIZE
#endif
lpram :
org = LPRAM_BASE,
len = LPRAM_SIZE
}
PHDRS
{
vector_memory_lit_phdr PT_LOAD;
vector_memory_text_phdr PT_LOAD;
vector_base_text_phdr PT_LOAD;
vector_int2_lit_phdr PT_LOAD;
vector_int2_text_phdr PT_LOAD;
vector_int3_lit_phdr PT_LOAD;
vector_int3_text_phdr PT_LOAD;
vector_int4_lit_phdr PT_LOAD;
vector_int4_text_phdr PT_LOAD;
vector_int5_lit_phdr PT_LOAD;
vector_int5_text_phdr PT_LOAD;
vector_int6_lit_phdr PT_LOAD;
vector_int6_text_phdr PT_LOAD;
vector_int7_lit_phdr PT_LOAD;
vector_int7_text_phdr PT_LOAD;
vector_kernel_lit_phdr PT_LOAD;
vector_kernel_text_phdr PT_LOAD;
vector_user_lit_phdr PT_LOAD;
vector_user_text_phdr PT_LOAD;
vector_double_lit_phdr PT_LOAD;
vector_double_text_phdr PT_LOAD;
ram_phdr PT_LOAD;
}
_rom_store_table = 0;
PROVIDE(_memmap_vecbase_reset = XCHAL_VECBASE_RESET_PADDR_SRAM);
ENTRY(CONFIG_KERNEL_ENTRY)
/* Various memory-map dependent cache attribute settings: */
_memmap_cacheattr_wb_base = 0x44024000;
_memmap_cacheattr_wt_base = 0x11021000;
_memmap_cacheattr_bp_base = 0x22022000;
_memmap_cacheattr_unused_mask = 0x00F00FFF;
_memmap_cacheattr_wb_trapnull = 0x4422422F;
_memmap_cacheattr_wba_trapnull = 0x4422422F;
_memmap_cacheattr_wbna_trapnull = 0x25222222;
_memmap_cacheattr_wt_trapnull = 0x1122122F;
_memmap_cacheattr_bp_trapnull = 0x2222222F;
_memmap_cacheattr_wb_strict = 0x44F24FFF;
_memmap_cacheattr_wt_strict = 0x11F21FFF;
_memmap_cacheattr_bp_strict = 0x22F22FFF;
_memmap_cacheattr_wb_allvalid = 0x44224222;
_memmap_cacheattr_wt_allvalid = 0x11221222;
_memmap_cacheattr_bp_allvalid = 0x22222222;
/*
* Cache attributes for memory addresses:
* (Each 4 bits correspond to 512MB of memory)
*
* 0x00000000 - 0x1FFFFFFF (bit 0 - 3) : Bypass cache
* (region for hardware registers)
* 0x20000000 - 0x3FFFFFFF (bit 4 - 7) : No access
* 0x40000000 - 0x5FFFFFFF (bit 8 - 11) : No access
* 0x60000000 - 0x7FFFFFFF (bit 12 - 15) : No access
* 0x80000000 - 0x9FFFFFFF (bit 16 - 19) : Bypass cache
* 0xA0000000 - 0xBFFFFFFF (bit 20 - 23) : Cached, write-back
* 0xC0000000 - 0xDFFFFFFF (bit 24 - 27) : No access
* 0xE0000000 - 0xFFFFFFFF (bit 28 - 31) : No access
*
* Note that this is both for instruction and data caches,
* as cacheattr_set macro sets them both to the same set of
* attributes.
*/
_memmap_cacheattr_intel_apl_adsp = 0xFF42FFF2;
PROVIDE(_memmap_cacheattr_reset = _memmap_cacheattr_intel_apl_adsp);
SECTIONS
{
#include <linker/rel-sections.ld>
.MemoryExceptionVector.literal : ALIGN(4)
{
_MemoryExceptionVector_literal_start = ABSOLUTE(.);
KEEP (*(.MemoryExceptionVector.literal))
_MemoryExceptionVector_literal_end = ABSOLUTE(.);
} >vector_memory_lit :vector_memory_lit_phdr
.MemoryExceptionVector.text : ALIGN(4)
{
_MemoryExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.MemoryExceptionVector.text))
_MemoryExceptionVector_text_end = ABSOLUTE(.);
} >vector_memory_text :vector_memory_text_phdr
.WindowVectors.text : ALIGN(4)
{
_WindowVectors_text_start = ABSOLUTE(.);
KEEP (*(.WindowVectors.text))
_WindowVectors_text_end = ABSOLUTE(.);
} >vector_base_text :vector_base_text_phdr
.Level2InterruptVector.literal : ALIGN(4)
{
_Level2InterruptVector_literal_start = ABSOLUTE(.);
*(.Level2InterruptVector.literal)
_Level2InterruptVector_literal_end = ABSOLUTE(.);
} >vector_int2_lit :vector_int2_lit_phdr
.Level2InterruptVector.text : ALIGN(4)
{
_Level2InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level2InterruptVector.text))
_Level2InterruptVector_text_end = ABSOLUTE(.);
} >vector_int2_text :vector_int2_text_phdr
.Level3InterruptVector.literal : ALIGN(4)
{
_Level3InterruptVector_literal_start = ABSOLUTE(.);
*(.Level3InterruptVector.literal)
_Level3InterruptVector_literal_end = ABSOLUTE(.);
} >vector_int3_lit :vector_int3_lit_phdr
.Level3InterruptVector.text : ALIGN(4)
{
_Level3InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level3InterruptVector.text))
_Level3InterruptVector_text_end = ABSOLUTE(.);
} >vector_int3_text :vector_int3_text_phdr
.Level4InterruptVector.literal : ALIGN(4)
{
_Level4InterruptVector_literal_start = ABSOLUTE(.);
*(.Level4InterruptVector.literal)
_Level4InterruptVector_literal_end = ABSOLUTE(.);
} >vector_int4_lit :vector_int4_lit_phdr
.Level4InterruptVector.text : ALIGN(4)
{
_Level4InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level4InterruptVector.text))
_Level4InterruptVector_text_end = ABSOLUTE(.);
} >vector_int4_text :vector_int4_text_phdr
.Level5InterruptVector.literal : ALIGN(4)
{
_Level5InterruptVector_literal_start = ABSOLUTE(.);
*(.Level5InterruptVector.literal)
_Level5InterruptVector_literal_end = ABSOLUTE(.);
} >vector_int5_lit :vector_int5_lit_phdr
.Level5InterruptVector.text : ALIGN(4)
{
_Level5InterruptVector_text_start = ABSOLUTE(.);
KEEP (*(.Level5InterruptVector.text))
_Level5InterruptVector_text_end = ABSOLUTE(.);
} >vector_int5_text :vector_int5_text_phdr
.DebugExceptionVector.literal : ALIGN(4)
{
_DebugExceptionVector_literal_start = ABSOLUTE(.);
*(.DebugExceptionVector.literal)
_DebugExceptionVector_literal_end = ABSOLUTE(.);
} >vector_int6_lit :vector_int6_lit_phdr
.DebugExceptionVector.text : ALIGN(4)
{
_DebugExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.DebugExceptionVector.text))
_DebugExceptionVector_text_end = ABSOLUTE(.);
} >vector_int6_text :vector_int6_text_phdr
.NMIExceptionVector.literal : ALIGN(4)
{
_NMIExceptionVector_literal_start = ABSOLUTE(.);
*(.NMIExceptionVector.literal)
_NMIExceptionVector_literal_end = ABSOLUTE(.);
} >vector_int7_lit :vector_int7_lit_phdr
.NMIExceptionVector.text : ALIGN(4)
{
_NMIExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.NMIExceptionVector.text))
_NMIExceptionVector_text_end = ABSOLUTE(.);
} >vector_int7_text :vector_int7_text_phdr
.KernelExceptionVector.literal : ALIGN(4)
{
_KernelExceptionVector_literal_start = ABSOLUTE(.);
*(.KernelExceptionVector.literal)
_KernelExceptionVector_literal_end = ABSOLUTE(.);
} >vector_kernel_lit :vector_kernel_lit_phdr
.KernelExceptionVector.text : ALIGN(4)
{
_KernelExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.KernelExceptionVector.text))
_KernelExceptionVector_text_end = ABSOLUTE(.);
} >vector_kernel_text :vector_kernel_text_phdr
.UserExceptionVector.literal : ALIGN(4)
{
_UserExceptionVector_literal_start = ABSOLUTE(.);
*(.UserExceptionVector.literal)
_UserExceptionVector_literal_end = ABSOLUTE(.);
} >vector_user_lit :vector_user_lit_phdr
.UserExceptionVector.text : ALIGN(4)
{
_UserExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.UserExceptionVector.text))
_UserExceptionVector_text_end = ABSOLUTE(.);
} >vector_user_text :vector_user_text_phdr
.DoubleExceptionVector.literal : ALIGN(4)
{
_DoubleExceptionVector_literal_start = ABSOLUTE(.);
*(.DoubleExceptionVector.literal)
_DoubleExceptionVector_literal_end = ABSOLUTE(.);
} >vector_double_lit :vector_double_lit_phdr
.DoubleExceptionVector.text : ALIGN(4)
{
_DoubleExceptionVector_text_start = ABSOLUTE(.);
KEEP (*(.DoubleExceptionVector.text))
_DoubleExceptionVector_text_end = ABSOLUTE(.);
} >vector_double_text :vector_double_text_phdr
.text : ALIGN(4)
{
_stext = .;
_text_start = ABSOLUTE(.);
KEEP(*(.MainEntry.text))
*(.MainEntry.literal)
KEEP (*(.ResetVector.text))
*(.ResetVector.literal)
*(.entry.text)
*(.init.literal)
*(.iram0.text)
KEEP(*(.init))
*(.literal .text .literal.* .text.* .stub .gnu.warning .gnu.linkonce.literal.* .gnu.linkonce.t.*.literal .gnu.linkonce.t.*)
*(.fini.literal)
KEEP(*(.fini))
*(.gnu.version)
_text_end = ABSOLUTE(.);
_etext = .;
. = ALIGN(4096);
} >ram :ram_phdr
.rodata : ALIGN(4096)
{
_rodata_start = ABSOLUTE(.);
*(.rodata)
*(.rodata.*)
*(.gnu.linkonce.r.*)
*(.rodata1)
__XT_EXCEPTION_TABLE__ = ABSOLUTE(.);
KEEP (*(.xt_except_table))
KEEP (*(.gcc_except_table .gcc_except_table.*))
*(.gnu.linkonce.e.*)
*(.gnu.version_r)
KEEP (*(.eh_frame))
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
__XT_EXCEPTION_DESCS__ = ABSOLUTE(.);
*(.xt_except_desc)
*(.gnu.linkonce.h.*)
__XT_EXCEPTION_DESCS_END__ = ABSOLUTE(.);
*(.xt_except_desc_end)
*(.dynamic)
*(.gnu.version_d)
. = ALIGN(4);
_bss_table_start = ABSOLUTE(.);
LONG(_bss_start)
LONG(_bss_end)
_bss_table_end = ABSOLUTE(.);
_rodata_end = ABSOLUTE(.);
} >ram :ram_phdr
#include <linker/common-rom.ld>
.fw_ready : ALIGN(4)
{
KEEP(*(".fw_ready"));
} >ram :ram_phdr
.noinit : ALIGN(4)
{
*(.noinit)
*(.noinit.*)
} >ram :ram_phdr
.data : ALIGN(4)
{
_data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
KEEP(*(.gnu.linkonce.d.*personality*))
*(.data1)
*(.sdata)
*(.sdata.*)
*(.gnu.linkonce.s.*)
*(.sdata2)
*(.sdata2.*)
*(.gnu.linkonce.s2.*)
KEEP(*(.jcr))
. = ALIGN(4096);
*(.gna_model)
_data_end = ABSOLUTE(.);
. = ALIGN(4096);
} >ram :ram_phdr
.lit4 : ALIGN(4)
{
_lit4_start = ABSOLUTE(.);
*(*.lit4)
*(.lit4.*)
*(.gnu.linkonce.lit4.*)
_lit4_end = ABSOLUTE(.);
} >ram :ram_phdr
#include <linker/common-ram.ld>
.bss (NOLOAD) : ALIGN(4096)
{
. = ALIGN(4096);
_bss_start = ABSOLUTE(.);
*(.dynsbss)
*(.sbss)
*(.sbss.*)
*(.gnu.linkonce.sb.*)
*(.scommon)
*(.sbss2)
*(.sbss2.*)
*(.gnu.linkonce.sb2.*)
*(.dynbss)
*(.bss)
*(.bss.*)
*(.gnu.linkonce.b.*)
*(COMMON)
. = ALIGN(8);
_bss_end = ABSOLUTE(.);
} >ram :ram_phdr
/* stack */
_end = ALIGN(8);
PROVIDE(end = ALIGN(8));
__stack = DT_L2_SRAM_BASE + DT_L2_SRAM_SIZE;
/* dma buffers */
.lpbuf (NOLOAD): ALIGN(4)
{
_dma_buf_start = ABSOLUTE(.);
*(.dma_buffers)
_dma_buf_end = ABSOLUTE(.);
} >LPRAM_REGION
_heap_sentry = DT_L2_SRAM_BASE + DT_L2_SRAM_SIZE;
.comment 0 : { *(.comment) }
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
.debug_info 0 : { *(.debug_info) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
.debug_ranges 0 : { *(.debug_ranges) }
.xtensa.info 0 : { *(.xtensa.info) }
.xt.insn 0 :
{
KEEP (*(.xt.insn))
KEEP (*(.gnu.linkonce.x.*))
}
.xt.prop 0 :
{
KEEP (*(.xt.prop))
KEEP (*(.xt.prop.*))
KEEP (*(.gnu.linkonce.prop.*))
}
.xt.lit 0 :
{
KEEP (*(.xt.lit))
KEEP (*(.xt.lit.*))
KEEP (*(.gnu.linkonce.p.*))
}
.xt.profile_range 0 :
{
KEEP (*(.xt.profile_range))
KEEP (*(.gnu.linkonce.profile_range.*))
}
.xt.profile_ranges 0 :
{
KEEP (*(.xt.profile_ranges))
KEEP (*(.gnu.linkonce.xt.profile_ranges.*))
}
.xt.profile_files 0 :
{
KEEP (*(.xt.profile_files))
KEEP (*(.gnu.linkonce.xt.profile_files.*))
}
#ifdef CONFIG_GEN_ISR_TABLES
#include <linker/intlist.ld>
#endif
}

View file

@ -0,0 +1,34 @@
/* SPDX-License-Identifier: Apache-2.0
*
* Copyright(c) 2017 Intel Corporation. All rights reserved.
*
* Author: Rander Wang <rander.wang@intel.com>
*/
/*
* Entry point from boot loader.
* Fix link address of this entry to SOF_TEXT_START so that
* it is easy for boot loader to jump to the baseFW because
* the boot loader and baseFW are in different elf file.
*/
// Exports
.global _MainEntry
/**************************************************************************/
.begin literal_prefix .MainEntry
.section .MainEntry.text, "ax"
.align 4
.global _MainEntry
_MainEntry:
j __start
.size _MainEntry, . - _MainEntry
.end literal_prefix

View file

@ -0,0 +1,99 @@
/*
* Copyright (c) 2019 Intel Corporation
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef __INC_MEMORY_H
#define __INC_MEMORY_H
/* L2 HP SRAM */
#define HP_RAM_RESERVE_HEADER_SPACE 0x00010000
#ifdef CONFIG_BOOTLOADER_MCUBOOT
#define SRAM_BASE (DT_L2_SRAM_BASE + CONFIG_BOOTLOADER_SRAM_SIZE * 1K)
#define SRAM_SIZE (DT_L2_SRAM_SIZE - CONFIG_BOOTLOADER_SRAM_SIZE * 1K)
#else
#define SRAM_BASE (DT_L2_SRAM_BASE)
#define SRAM_SIZE (DT_L2_SRAM_SIZE)
#endif
/* The reset vector address in SRAM and its size */
#define XCHAL_RESET_VECTOR0_PADDR_SRAM SRAM_BASE
#define MEM_RESET_TEXT_SIZE 0x268
#define MEM_RESET_LIT_SIZE 0x8
/* This is the base address of all the vectors defined in SRAM */
#define XCHAL_VECBASE_RESET_PADDR_SRAM \
(SRAM_BASE + HP_RAM_RESERVE_HEADER_SPACE)
#define MEM_VECBASE_LIT_SIZE 0x178
/* The addresses of the vectors in SRAM.
* Only the memerror vector continues to point to its ROM address.
*/
#define XCHAL_INTLEVEL2_VECTOR_PADDR_SRAM \
(XCHAL_VECBASE_RESET_PADDR_SRAM + 0x180)
#define XCHAL_INTLEVEL3_VECTOR_PADDR_SRAM \
(XCHAL_VECBASE_RESET_PADDR_SRAM + 0x1C0)
#define XCHAL_INTLEVEL4_VECTOR_PADDR_SRAM \
(XCHAL_VECBASE_RESET_PADDR_SRAM + 0x200)
#define XCHAL_INTLEVEL5_VECTOR_PADDR_SRAM \
(XCHAL_VECBASE_RESET_PADDR_SRAM + 0x240)
#define XCHAL_INTLEVEL6_VECTOR_PADDR_SRAM \
(XCHAL_VECBASE_RESET_PADDR_SRAM + 0x280)
#define XCHAL_INTLEVEL7_VECTOR_PADDR_SRAM \
(XCHAL_VECBASE_RESET_PADDR_SRAM + 0x2C0)
#define XCHAL_KERNEL_VECTOR_PADDR_SRAM \
(XCHAL_VECBASE_RESET_PADDR_SRAM + 0x300)
#define XCHAL_USER_VECTOR_PADDR_SRAM \
(XCHAL_VECBASE_RESET_PADDR_SRAM + 0x340)
#define XCHAL_DOUBLEEXC_VECTOR_PADDR_SRAM \
(XCHAL_VECBASE_RESET_PADDR_SRAM + 0x3C0)
#define VECTOR_TBL_SIZE 0x0400
/* Vector and literal sizes */
#define MEM_VECT_LIT_SIZE 0x8
#define MEM_VECT_TEXT_SIZE 0x38
#define MEM_VECT_SIZE (MEM_VECT_TEXT_SIZE +\
MEM_VECT_LIT_SIZE)
/* The memerror vector address is copied as is from core-isa.h */
#define XCHAL_MEMERROR_VECTOR_PADDR 0xBEFE0400
#define MEM_ERROR_TEXT_SIZE 0x180
#define MEM_ERROR_LIT_SIZE 0x8
/* text and data share the same L2 HP SRAM.
* So, they lie next to each other.
*/
#define RAM_BASE \
(SRAM_BASE + HP_RAM_RESERVE_HEADER_SPACE + VECTOR_TBL_SIZE)
#define RAM_SIZE \
(SRAM_SIZE - HP_RAM_RESERVE_HEADER_SPACE - VECTOR_TBL_SIZE)
/* Location for the intList section which is later used to construct the
* Interrupt Descriptor Table (IDT). This is a bogus address as this
* section will be stripped off in the final image.
*/
#define IDT_BASE (RAM_BASE + RAM_SIZE)
/* size of the Interrupt Descriptor Table (IDT) */
#define IDT_SIZE 0x2000
/* low power ram where DMA buffers are typically placed */
#define LPRAM_BASE (DT_LP_SRAM_BASE)
#define LPRAM_SIZE (DT_LP_SRAM_SIZE)
#include <platform/memory.h>
#endif /* __INC_MEMORY_H */

View file

@ -0,0 +1,235 @@
/*
* Copyright (c) 2019 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <device.h>
#include <arch/xtensa/xtensa_api.h>
#include <xtensa/xtruntime.h>
#include <irq_nextlevel.h>
#include <xtensa/hal.h>
#include <init.h>
#include "soc.h"
#ifdef CONFIG_DYNAMIC_INTERRUPTS
#include <sw_isr_table.h>
#endif
#define LOG_LEVEL CONFIG_SOC_LOG_LEVEL
#include <logging/log.h>
LOG_MODULE_REGISTER(soc);
void z_soc_irq_enable(u32_t irq)
{
struct device *dev_cavs;
switch (XTENSA_IRQ_NUMBER(irq)) {
case DT_CAVS_ICTL_0_IRQ:
dev_cavs = device_get_binding(CONFIG_CAVS_ICTL_0_NAME);
break;
case DT_CAVS_ICTL_1_IRQ:
dev_cavs = device_get_binding(CONFIG_CAVS_ICTL_1_NAME);
break;
case DT_CAVS_ICTL_2_IRQ:
dev_cavs = device_get_binding(CONFIG_CAVS_ICTL_2_NAME);
break;
case DT_CAVS_ICTL_3_IRQ:
dev_cavs = device_get_binding(CONFIG_CAVS_ICTL_3_NAME);
break;
default:
/* regular interrupt */
z_xtensa_irq_enable(XTENSA_IRQ_NUMBER(irq));
return;
}
if (!dev_cavs) {
LOG_DBG("board: CAVS device binding failed");
return;
}
/*
* The specified interrupt is in CAVS interrupt controller.
* So enable core interrupt first.
*/
z_xtensa_irq_enable(XTENSA_IRQ_NUMBER(irq));
/* Then enable the interrupt in CAVS interrupt controller */
irq_enable_next_level(dev_cavs, CAVS_IRQ_NUMBER(irq));
}
void z_soc_irq_disable(u32_t irq)
{
struct device *dev_cavs;
switch (XTENSA_IRQ_NUMBER(irq)) {
case DT_CAVS_ICTL_0_IRQ:
dev_cavs = device_get_binding(CONFIG_CAVS_ICTL_0_NAME);
break;
case DT_CAVS_ICTL_1_IRQ:
dev_cavs = device_get_binding(CONFIG_CAVS_ICTL_1_NAME);
break;
case DT_CAVS_ICTL_2_IRQ:
dev_cavs = device_get_binding(CONFIG_CAVS_ICTL_2_NAME);
break;
case DT_CAVS_ICTL_3_IRQ:
dev_cavs = device_get_binding(CONFIG_CAVS_ICTL_3_NAME);
break;
default:
/* regular interrupt */
z_xtensa_irq_disable(XTENSA_IRQ_NUMBER(irq));
return;
}
if (!dev_cavs) {
LOG_DBG("board: CAVS device binding failed");
return;
}
/*
* The specified interrupt is in CAVS interrupt controller.
* So disable the interrupt in CAVS interrupt controller.
*/
irq_disable_next_level(dev_cavs, CAVS_IRQ_NUMBER(irq));
/* Then disable the parent IRQ if all children are disabled */
if (!irq_is_enabled_next_level(dev_cavs)) {
z_xtensa_irq_disable(XTENSA_IRQ_NUMBER(irq));
}
}
int z_soc_irq_is_enabled(unsigned int irq)
{
struct device *dev_cavs;
int ret = 0;
switch (XTENSA_IRQ_NUMBER(irq)) {
case DT_CAVS_ICTL_0_IRQ:
dev_cavs = device_get_binding(CONFIG_CAVS_ICTL_0_NAME);
break;
case DT_CAVS_ICTL_1_IRQ:
dev_cavs = device_get_binding(CONFIG_CAVS_ICTL_1_NAME);
break;
case DT_CAVS_ICTL_2_IRQ:
dev_cavs = device_get_binding(CONFIG_CAVS_ICTL_2_NAME);
break;
case DT_CAVS_ICTL_3_IRQ:
dev_cavs = device_get_binding(CONFIG_CAVS_ICTL_3_NAME);
break;
default:
/* regular interrupt */
ret = z_xtensa_irq_is_enabled(XTENSA_IRQ_NUMBER(irq));
goto out;
}
if (!dev_cavs) {
LOG_DBG("board: CAVS device binding failed");
ret = -ENODEV;
goto out;
}
/* Then enable the interrupt in CAVS interrupt controller */
ret = irq_line_is_enabled_next_level(dev_cavs, CAVS_IRQ_NUMBER(irq));
out:
return ret;
}
#ifdef CONFIG_DYNAMIC_INTERRUPTS
int z_soc_irq_connect_dynamic(unsigned int irq, unsigned int priority,
void (*routine)(void *parameter),
void *parameter, u32_t flags)
{
uint32_t table_idx;
uint32_t cavs_irq;
int ret;
ARG_UNUSED(flags);
ARG_UNUSED(priority);
/* extract 2nd level interrupt number */
cavs_irq = CAVS_IRQ_NUMBER(irq);
ret = irq;
if (cavs_irq == 0) {
/* Not affecting 2nd level interrupts */
z_isr_install(irq, routine, parameter);
goto irq_connect_out;
}
/* Figure out the base index. */
switch (XTENSA_IRQ_NUMBER(irq)) {
case DT_CAVS_ICTL_0_IRQ:
table_idx = CONFIG_CAVS_ISR_TBL_OFFSET;
break;
case DT_CAVS_ICTL_1_IRQ:
table_idx = CONFIG_CAVS_ISR_TBL_OFFSET +
CONFIG_MAX_IRQ_PER_AGGREGATOR;
break;
case DT_CAVS_ICTL_2_IRQ:
table_idx = CONFIG_CAVS_ISR_TBL_OFFSET +
CONFIG_MAX_IRQ_PER_AGGREGATOR * 2;
break;
case DT_CAVS_ICTL_3_IRQ:
table_idx = CONFIG_CAVS_ISR_TBL_OFFSET +
CONFIG_MAX_IRQ_PER_AGGREGATOR * 3;
break;
default:
ret = -EINVAL;
goto irq_connect_out;
}
table_idx += cavs_irq;
_sw_isr_table[table_idx].arg = parameter;
_sw_isr_table[table_idx].isr = routine;
irq_connect_out:
return ret;
}
#endif
static inline void soc_set_power_and_clock(void)
{
volatile struct soc_dsp_shim_regs *dsp_shim_regs =
(volatile struct soc_dsp_shim_regs *)SOC_DSP_SHIM_REG_BASE;
/*
* DSP Core 0 PLL Clock Select divide by 1
* DSP Core 1 PLL Clock Select divide by 1
* Low Power Domain Clock Select depends on LMPCS bit
* High Power Domain Clock Select depands on HMPCS bit
* Low Power Domain PLL Clock Select device by 4
* High Power Domain PLL Clock Select device by 2
* Tensilica Core Prevent Audio PLL Shutdown (TCPAPLLS)
* Tensilica Core Prevent Local Clock Gating (Core 0)
* Tensilica Core Prevent Local Clock Gating (Core 1)
*/
dsp_shim_regs->clkctl =
SOC_CLKCTL_DPCS_DIV1(0) |
SOC_CLKCTL_DPCS_DIV1(1) |
SOC_CLKCTL_LDCS_LMPCS |
SOC_CLKCTL_HDCS_HMPCS |
SOC_CLKCTL_LPMEM_PLL_CLK_SEL_DIV4 |
SOC_CLKCTL_HPMEM_PLL_CLK_SEL_DIV2 |
SOC_CLKCTL_TCPAPLLS |
SOC_CLKCTL_TCPLCG_DIS(0) |
SOC_CLKCTL_TCPLCG_DIS(1);
/* Disable power gating for both cores */
dsp_shim_regs->pwrctl |= SOC_PWRCTL_DISABLE_PWR_GATING_DSP1 |
SOC_PWRCTL_DISABLE_PWR_GATING_DSP0;
/* Rewrite the low power sequencing control bits */
dsp_shim_regs->lpsctl = dsp_shim_regs->lpsctl;
}
static int soc_init(struct device *dev)
{
soc_set_power_and_clock();
return 0;
}
SYS_INIT(soc_init, PRE_KERNEL_1, 99);

View file

@ -0,0 +1,229 @@
/*
* Copyright (c) 2019 Intel Corporation
* SPDX-License-Identifier: Apache-2.0
*/
#include <string.h>
#include <errno.h>
#include <sys/sys_io.h>
#include "memory.h"
#ifndef __INC_SOC_H
#define __INC_SOC_H
/* macros related to interrupt handling */
#define XTENSA_IRQ_NUM_SHIFT 0
#define CAVS_IRQ_NUM_SHIFT 8
#define XTENSA_IRQ_NUM_MASK 0xff
#define CAVS_IRQ_NUM_MASK 0xff
/*
* IRQs are mapped on 2 levels. 3rd and 4th level are left as 0x00.
*
* 1. Peripheral Register bit offset.
* 2. CAVS logic bit offset.
*/
#define XTENSA_IRQ_NUMBER(_irq) \
((_irq >> XTENSA_IRQ_NUM_SHIFT) & XTENSA_IRQ_NUM_MASK)
#define CAVS_IRQ_NUMBER(_irq) \
(((_irq >> CAVS_IRQ_NUM_SHIFT) & CAVS_IRQ_NUM_MASK) - 1)
/* Macro that aggregates the bi-level interrupt into an IRQ number */
#define SOC_AGGREGATE_IRQ(cavs_irq, core_irq) \
( \
((core_irq & XTENSA_IRQ_NUM_MASK) << XTENSA_IRQ_NUM_SHIFT) | \
(((cavs_irq + 1) & CAVS_IRQ_NUM_MASK) << CAVS_IRQ_NUM_SHIFT) \
)
#define CAVS_L2_AGG_INT_LEVEL2 DT_CAVS_ICTL_0_IRQ
#define CAVS_L2_AGG_INT_LEVEL3 DT_CAVS_ICTL_1_IRQ
#define CAVS_L2_AGG_INT_LEVEL4 DT_CAVS_ICTL_2_IRQ
#define CAVS_L2_AGG_INT_LEVEL5 DT_CAVS_ICTL_3_IRQ
#define IOAPIC_EDGE 0
#define IOAPIC_HIGH 0
/* low power DMACs */
#define LP_GP_DMA_SIZE 0x00001000
#define DW_DMA0_BASE_ADDR 0x0000C000
#define DW_DMA1_BASE_ADDR (0x0000C000 +\
1 * LP_GP_DMA_SIZE)
#define DW_DMA2_BASE_ADDR (0x0000C000 +\
2 * LP_GP_DMA_SIZE)
#define DW_DMA0_IRQ 0x00001110
#define DW_DMA1_IRQ 0x0000010A
#define DW_DMA2_IRQ 0x0000010D
/* address of DMA ownership register. We need to properly configure
* this register in order to access the DMA registers.
*/
#define CAVS_DMA0_OWNERSHIP_REG (0x00071A60)
#define CAVS_DMA1_OWNERSHIP_REG (0x00071A62)
#define CAVS_DMA2_OWNERSHIP_REG (0x00071A64)
#define DMA_HANDSHAKE_DMIC_RXA 0
#define DMA_HANDSHAKE_DMIC_RXB 1
#define DMA_HANDSHAKE_SSP0_TX 2
#define DMA_HANDSHAKE_SSP0_RX 3
#define DMA_HANDSHAKE_SSP1_TX 4
#define DMA_HANDSHAKE_SSP1_RX 5
#define DMA_HANDSHAKE_SSP2_TX 6
#define DMA_HANDSHAKE_SSP2_RX 7
#define DMA_HANDSHAKE_SSP3_TX 8
#define DMA_HANDSHAKE_SSP3_RX 9
/* DMA Channel Allocation
* FIXME: I2S Driver assigns channel in Kconfig.
* Perhaps DTS is a better option
*/
#define DMIC_DMA_DEV_NAME CONFIG_DMA_0_NAME
#define DMA_CHANNEL_DMIC_RXA 0
#define DMA_CHANNEL_DMIC_RXB 1
/* I2S */
#define I2S_CAVS_IRQ(i2s_num) \
SOC_AGGREGATE_IRQ(0, (i2s_num), CAVS_L2_AGG_INT_LEVEL5)
#define I2S0_CAVS_IRQ I2S_CAVS_IRQ(0)
#define I2S1_CAVS_IRQ I2S_CAVS_IRQ(1)
#define I2S2_CAVS_IRQ I2S_CAVS_IRQ(2)
#define I2S3_CAVS_IRQ I2S_CAVS_IRQ(3)
#define SSP_MN_DIV_SIZE (8)
#define SSP_MN_DIV_BASE(x) \
(0x00078D00 + ((x) * SSP_MN_DIV_SIZE))
/* MCLK control */
#define SOC_MCLK_DIV_CTRL_BASE 0x00008E00
#define SOC_NUM_MCLK_OUTPUTS 2
#define SOC_MDIVCTRL_MCLK_OUT_EN(mclk) BIT(mclk)
#define SOC_MDIVXR_SET_DIVIDER_BYPASS BIT_MASK(12)
struct soc_mclk_control_regs {
u32_t mdivctrl;
u32_t reserved[31];
u32_t mdivxr[SOC_NUM_MCLK_OUTPUTS];
};
#define PDM_BASE 0x00010000
#define SOC_NUM_LPGPDMAC 3
#define SOC_NUM_CHANNELS_IN_DMAC 8
/* SOC Resource Allocation Registers */
#define SOC_RESOURCE_ALLOC_REG_BASE 0x00071A60
/* bit field definition for LP GPDMA ownership register */
#define SOC_LPGPDMAC_OWNER_DSP \
(BIT(15) | BIT_MASK(SOC_NUM_CHANNELS_IN_DMAC))
#define SOC_NUM_I2S_INSTANCES 4
/* bit field definition for IO peripheral ownership register */
#define SOC_DSPIOP_I2S_OWNSEL_DSP \
(BIT_MASK(SOC_NUM_I2S_INSTANCES) << 8)
#define SOC_DSPIOP_DMIC_OWNSEL_DSP BIT(0)
/* bit field definition for general ownership register */
#define SOC_GENO_TIMESTAMP_OWNER_DSP BIT(2)
#define SOC_GENO_MNDIV_OWNER_DSP BIT(1)
struct soc_resource_alloc_regs {
union {
u16_t lpgpdmacxo[SOC_NUM_LPGPDMAC];
u16_t reserved[4];
};
u32_t dspiopo;
u32_t geno;
};
/* DMIC SHIM Registers */
#define SOC_DMIC_SHIM_REG_BASE 0x00071E80
#define SOC_DMIC_SHIM_DMICLCTL_SPA BIT(0)
#define SOC_DMIC_SHIM_DMICLCTL_CPA BIT(8)
struct soc_dmic_shim_regs {
u32_t dmiclcap;
u32_t dmiclctl;
};
/* SOC DSP SHIM Registers */
#define SOC_DSP_SHIM_REG_BASE 0x00001000
/* SOC DSP SHIM Register - Clock Control */
#define SOC_CLKCTL_REQ_AUDIO_PLL_CLK BIT(31)
#define SOC_CLKCTL_REQ_XTAL_CLK BIT(30)
#define SOC_CLKCTL_REQ_FAST_CLK BIT(29)
#define SOC_CLKCTL_TCPLCG_POS(x) (16 + x)
#define SOC_CLKCTL_TCPLCG_DIS(x) (1 << SOC_CLKCTL_TCPLCG_POS(x))
#define SOC_CLKCTL_DPCS_POS(x) (8 + x)
#define SOC_CLKCTL_DPCS_DIV1(x) (0 << SOC_CLKCTL_DPCS_POS(x))
#define SOC_CLKCTL_DPCS_DIV2(x) (1 << SOC_CLKCTL_DPCS_POS(x))
#define SOC_CLKCTL_DPCS_DIV4(x) (3 << SOC_CLKCTL_DPCS_POS(x))
#define SOC_CLKCTL_TCPAPLLS BIT(7)
#define SOC_CLKCTL_LDCS_POS (5)
#define SOC_CLKCTL_LDCS_LMPCS (0 << SOC_CLKCTL_LDCS_POS)
#define SOC_CLKCTL_LDCS_LDOCS (1 << SOC_CLKCTL_LDCS_POS)
#define SOC_CLKCTL_HDCS_POS (4)
#define SOC_CLKCTL_HDCS_HMPCS (0 << SOC_CLKCTL_HDCS_POS)
#define SOC_CLKCTL_HDCS_HDOCS (1 << SOC_CLKCTL_HDCS_POS)
#define SOC_CLKCTL_LDOCS_POS (3)
#define SOC_CLKCTL_LDOCS_PLL (0 << SOC_CLKCTL_LDOCS_POS)
#define SOC_CLKCTL_LDOCS_FAST (1 << SOC_CLKCTL_LDOCS_POS)
#define SOC_CLKCTL_HDOCS_POS (2)
#define SOC_CLKCTL_HDOCS_PLL (0 << SOC_CLKCTL_HDOCS_POS)
#define SOC_CLKCTL_HDOCS_FAST (1 << SOC_CLKCTL_HDOCS_POS)
#define SOC_CLKCTL_LPMEM_PLL_CLK_SEL_POS (1)
#define SOC_CLKCTL_LPMEM_PLL_CLK_SEL_DIV2 \
(0 << SOC_CLKCTL_LPMEM_PLL_CLK_SEL_POS)
#define SOC_CLKCTL_LPMEM_PLL_CLK_SEL_DIV4 \
(1 << SOC_CLKCTL_LPMEM_PLL_CLK_SEL_POS)
#define SOC_CLKCTL_HPMEM_PLL_CLK_SEL_POS (0)
#define SOC_CLKCTL_HPMEM_PLL_CLK_SEL_DIV2 \
(0 << SOC_CLKCTL_HPMEM_PLL_CLK_SEL_POS)
#define SOC_CLKCTL_HPMEM_PLL_CLK_SEL_DIV4 \
(1 << SOC_CLKCTL_HPMEM_PLL_CLK_SEL_POS)
/* SOC DSP SHIM Register - Power Control */
#define SOC_PWRCTL_DISABLE_PWR_GATING_DSP0 BIT(0)
#define SOC_PWRCTL_DISABLE_PWR_GATING_DSP1 BIT(1)
struct soc_dsp_shim_regs {
u32_t reserved[8];
u64_t walclk;
u64_t dspwctcs;
u64_t dspwct0c;
u64_t dspwct1c;
u32_t reserved1[14];
u32_t clkctl;
u32_t clksts;
u32_t reserved2[4];
u16_t pwrctl;
u16_t pwrsts;
u32_t lpsctl;
u32_t lpsdmas0;
u32_t lpsdmas1;
u32_t reserved3[22];
};
/* macros for data cache operations */
#define SOC_DCACHE_FLUSH(addr, size) \
xthal_dcache_region_writeback((addr), (size))
#define SOC_DCACHE_INVALIDATE(addr, size) \
xthal_dcache_region_invalidate((addr), (size))
extern void z_soc_irq_enable(u32_t irq);
extern void z_soc_irq_disable(u32_t irq);
extern int z_soc_irq_is_enabled(unsigned int irq);
#endif /* __INC_SOC_H */