Support XiZi_AIoT

This commit is contained in:
TXuian
2024-01-31 10:30:34 +08:00
parent f6cf46027d
commit 494312183b
351 changed files with 46408 additions and 450091 deletions
@@ -1,3 +1,3 @@
SRC_DIR := $(ARCH)
SRC_DIR := arm
include $(KERNEL_ROOT)/compiler.mk
@@ -1,4 +1,4 @@
# The following three platforms support compatiable instructions.
SRC_DIR := $(ARCH_ARMV)
SRC_DIR := armv7-a
include $(KERNEL_ROOT)/compiler.mk
@@ -1,8 +1,4 @@
# The following three platforms support compatiable instructions.
ifeq ($(CONFIG_BOARD_IMX6Q_SABRELITE_EVB),y)
SRC_DIR := cortex-a9
endif
include $(KERNEL_ROOT)/compiler.mk
@@ -1,87 +0,0 @@
.equ Mode_USR, 0x10
.equ Mode_FIQ, 0x11
.equ Mode_IRQ, 0x12
.equ Mode_SVC, 0x13
.equ Mode_ABT, 0x17
.equ Mode_UND, 0x1B
.equ Mode_SYS, 0x1F
.equ I_Bit, 0x80 @ when I bit is set, IRQ is disabled
.equ F_Bit, 0x40 @ when F bit is set, FIQ is disabled
.equ STACK_SIZE, 0x00000100
.globl _start
_start:
/* set the cpu to SVC32 mode and disable interrupt */
mrs r0, cpsr
bic r0, r0, #0x1f
orr r0, r0, #0x13
msr cpsr_c, r0
mrc p15, 0, r0, c1, c0, 0
bic r0, #(1 << 12) /* i cache */
bic r0, #(1 << 2) /* d cache */
bic r0, #(1 << 0) /* mmu */
mcr p15, 0, r0, c1, c0, 0
ldr r0, =stack_top
@ Set the startup stack for svc
mov sp, r0
@ Enter Undefined Instruction Mode and set its Stack Pointer
msr cpsr_c, #Mode_UND|I_Bit|F_Bit
mov sp, r0
sub r0, r0, #STACK_SIZE
@ Enter Abort Mode and set its Stack Pointer
msr cpsr_c, #Mode_ABT|I_Bit|F_Bit
mov sp, r0
sub r0, r0, #STACK_SIZE
@ Enter FIQ Mode and set its Stack Pointer
msr cpsr_c, #Mode_FIQ|I_Bit|F_Bit
mov sp, r0
sub r0, r0, #STACK_SIZE
@ Enter IRQ Mode and set its Stack Pointer
msr cpsr_c, #Mode_IRQ|I_Bit|F_Bit
mov sp, r0
sub r0, r0, #STACK_SIZE
/* come back to SVC mode */
msr cpsr_c, #Mode_SVC|I_Bit|F_Bit
/* clear .bss */
mov r0, #0 /* get a zero */
ldr r1,=BSS_START /* bss start */
ldr r2,=BSS_END /* bss end */
bss_loop:
cmp r1,r2 /* check if data to clear */
strlo r0,[r1],#4 /* clear 4 bytes */
blo bss_loop /* loop until done */
/* call C++ constructors of global objects */
ldr r0, =__ctors_start__
ldr r1, =__ctors_end__
bss_end:
ctor_loop:
cmp r0, r1
beq ctor_end
ldr r2, [r0], #4
stmfd sp!, {r0-r1}
mov lr, pc
bx r2
ldmfd sp!, {r0-r1}
b ctor_loop
ctor_end:
bl start_kernel
_loop_here:
b _loop_here
@@ -1,66 +0,0 @@
.section .vectors, "ax"
.code 32
.globl ExceptionVectors
ExceptionVectors:
ldr pc, _ResetException
ldr pc, _UndefInstrException
ldr pc, _SwiException
ldr pc, _PrefetchAbortException
ldr pc, _DataAbortAbortException
ldr pc, _ResvException
ldr pc, _IrqException
ldr pc, _FiqException
.globl Reset_Handler
.globl UndefInstrExceptionHandle
.globl SwiExceptionHandle
.globl PrefetchAbortExceptionHandle
.globl DataAbortExceptionHandle
.globl ResvExceptionHandle
.globl ExceptionIsrEntry
.globl FiqExceptionHandle
_ResetException:
.word Reset_Handler
_UndefInstrException:
.word UndefInstrExceptionHandle
_SwiException:
.word SwiExceptionHandle
_PrefetchAbortException:
.word PrefetchAbortExceptionHandle
_DataAbortAbortException:
.word DataAbortExceptionHandle
_ResvException:
.word ResvExceptionHandle
_IrqException:
.word ExceptionIsrEntry
_FiqException:
.word FiqExceptionHandle
.globl _start
Reset_Handler:
b _start
UndefInstrExceptionHandle:
b UndefInstrIsrEntry
SwiExceptionHandle:
b SvcIsrEntry
PrefetchAbortExceptionHandle:
b PrefetchAbortIsrEntry
DataAbortExceptionHandle:
b UndefInstrIsrEntry
ResvExceptionHandle:
b DataAbortIsrEntry
ExceptionIsrEntry:
stmfd sp!, {r0-r12,lr}
bl IsrEntry
FiqExceptionHandle:
b FiqIsrEntry
@@ -1,3 +1,4 @@
SRC_FILES := boot.S cache.S exception.S cortexA9.S gic.c interrupt.c mmu.c ccm_pll.c
SRC_DIR := preboot_for_nxp_imx6q_sabrelite
SRC_FILES := boot.S context_switch.S core.c
include $(KERNEL_ROOT)/compiler.mk
@@ -1,54 +0,0 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
#ifndef ARCH_INTERRUPT_H__
#define ARCH_INTERRUPT_H__
#include <stdint.h>
#include <board.h>
#include "gic.h"
#define ARCH_MAX_IRQ_NUM PLATFORM_MAX_IRQ_NR
int32_t ArchEnableHwIrq(uint32_t irq_num, uint32_t cpu_id);
int32_t ArchDisableHwIrq(uint32_t irq_num, uint32_t cpu_id);
//! @brief
typedef enum {
CPU_0,
CPU_1,
CPU_2,
CPU_3,
} cpuid_e;
struct ExceptionStackRegister
{
uint32_t r0;
uint32_t r1;
uint32_t r2;
uint32_t r3;
uint32_t r4;
uint32_t r5;
uint32_t r6;
uint32_t r7;
uint32_t r8;
uint32_t r9;
uint32_t r10;
uint32_t r11;
uint32_t r12;
uint32_t r13_sp;
uint32_t r14_lr;
uint32_t r15_pc;
uint32_t cpsr;
};
#endif
@@ -1,85 +0,0 @@
/*
* Copyright (c) 2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 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 HOLDER 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.
*/
//! @addtogroup cortexa9
//! @{
/*!
* @file arm_cp_registers.h
* @brief Definitions for ARM coprocessor registers.
*/
#ifndef __ARM_CP_REGISTERS_H__
#define __ARM_CP_REGISTERS_H__
////////////////////////////////////////////////////////////////////////////////
// Definitions
////////////////////////////////////////////////////////////////////////////////
//! @name ACTLR
//@{
#define BM_ACTLR_SMP (1 << 6)
//@}
//! @name DFSR
//@{
#define BM_DFSR_WNR (1 << 11) //!< Write not Read bit. 0=read, 1=write.
#define BM_DFSR_FS4 (0x400) //!< Fault status bit 4..
#define BP_DFSR_FS4 (10) //!< Bit position for FS[4].
#define BM_DFSR_FS (0xf) //!< Fault status bits [3:0].
//@}
//! @name SCTLR
//@{
#define BM_SCTLR_TE (1 << 30) //!< Thumb exception enable.
#define BM_SCTLR_AFE (1 << 29) //!< Access flag enable.
#define BM_SCTLR_TRE (1 << 28) //!< TEX remap enable.
#define BM_SCTLR_NMFI (1 << 27) //!< Non-maskable FIQ support.
#define BM_SCTLR_EE (1 << 25) //!< Exception endianess.
#define BM_SCTLR_VE (1 << 24) //!< Interrupt vectors enable.
#define BM_SCTLR_FI (1 << 21) //!< Fast interrupt configurable enable.
#define BM_SCTLR_RR (1 << 14) //!< Round Robin
#define BM_SCTLR_V (1 << 13) //!< Vectors
#define BM_SCTLR_I (1 << 12) //!< Instruction cache enable
#define BM_SCTLR_Z (1 << 11) //!< Branch prediction enable
#define BM_SCTLR_SW (1 << 10) //!< SWP and SWPB enable
#define BM_SCTLR_CP15BEN (1 << 5) //!< CP15 barrier enable
#define BM_SCTLR_C (1 << 2) //!< Data cache enable
#define BM_SCTLR_A (1 << 1) //!< Alignment check enable
#define BM_SCTLR_M (1 << 0) //!< MMU enable
//@}
//! @}
#endif // __ARM_CP_REGISTERS_H__
////////////////////////////////////////////////////////////////////////////////
// EOF
////////////////////////////////////////////////////////////////////////////////
@@ -1,97 +1,109 @@
#include <asm_defines.h>
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
.global ExceptionVectors
/**
* @file start_boot.S
* @brief boot function
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023.08.15
*/
.section ".startup","ax"
.globl _reset
.extern init
_reset:
/*************************************************
File name: start_boot.S
Description: cortex-a9 start boot function
Others:
History:
1. Date: 2023-08-28
Author: AIIT XUOS Lab
Modification:
1. first version
*************************************************/
#include "core.h"
/* set the cpu to SVC32 mode and disable interrupt */
mrs r0, cpsr
bic r0, r0, #0x1f
orr r0, r0, #0x13
msr cpsr_c, r0
.global _boot_start
.global CpuInitCrit
/* disable i/d cache mmu*/
mrc p15, 0, r0, c1, c0, 0
bic r0, #(1 << 12) /* i cache */
bic r0, #(1 << 2) /* d cache */
bic r0, #(1 << 0) /* mmu */
mcr p15, 0, r0, c1, c0, 0
.global primary_cpu_init
_boot_start:
@ save r0 for cores 1-3, r0 arg field passed by ROM
@ r0 is a function pointer for secondary cpus
mov r4, r0
mrs r0, cpsr /*Enter SVC mode*/
bic r0, r0, #0x1f
orr r0, r0, #0xd3
msr cpsr, r0
bl CpuInitCrit
/* set NSACR, both Secure and Non-secure access are allowed to NEON */
MRC p15, 0, r0, c1, c1, 2
ORR r0, r0, #(0x3<<10) @ enable fpu/neon
MCR p15, 0, r0, c1, c1, 2
/* Set the CPACR for access to CP10 and CP11*/
LDR r0, =0xF00000
MCR p15, 0, r0, c1, c0, 2
/* Set the FPEXC EN bit to enable the FPU */
MOV r3, #0x40000000
@VMSR FPEXC, r3
MCR p10, 7, r3, c8, c0, 0
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #(0x1<<1) @clear A bit of SCTLR
mcr p15, 0, r0, c1, c0, 0
@ clear some registers
mov r11, #0
mov r12, #0
mov lr, #0
ldr r0, =stack_top
ldr r0, =stacks_top @ symbol defined in linker file
mov r1, #MODE_STACK_SIZE
@ get cpu id, and subtract the offset from the stacks base address
mrc p15,0,r2,c0,c0,5 @ read multiprocessor affinity register
and r2, r2, #3 @ mask off, leaving CPU ID field
mov r5, r2 @ save cpu id for later
mrc p15, 0, r2, c0, c0, 5 @ read multiprocessor affinity register
and r2, r2, #3 @ mask off, leaving CPU ID field
mov r5, r2 @ save cpu id for later
mul r3, r2, r1
sub r0, r0, r3
msr CPSR_c, #ARM_MODE_SVC | I_BIT | F_BIT
mov sp, r0
sub r0, r0, r1
@ check cpu id - cpu0 is primary cpu
cmp r5, #0
beq primary_cpu_init
bx r4 @ for secondary cpus, jump to argument function pointer passed in by ROM
@ control should not return from the secondary cpu entry point
b .
@ Set the startup stack for svc
mov sp, r0
@ Enter Undefined Instruction Mode and set its Stack Pointer
msr cpsr_c, #MODE_UND|I_BIT|F_BIT
mov sp, r0
sub r0, r0, #EXCEPTION_STACK_SIZE
@ Enter Abort Mode and set its Stack Pointer
msr cpsr_c, #MODE_ABT|I_BIT|F_BIT
mov sp, r0
sub r0, r0, #EXCEPTION_STACK_SIZE
@ Enter FIQ Mode and set its Stack Pointer
msr cpsr_c, #MODE_FIQ|I_BIT|F_BIT
mov sp, r0
sub r0, r0, #EXCEPTION_STACK_SIZE
@ Enter IRQ Mode and set its Stack Pointer
msr cpsr_c, #MODE_IRQ|I_BIT|F_BIT
mov sp, r0
sub r0, r0, #EXCEPTION_STACK_SIZE
/* come back to SVC mode */
msr cpsr_c, #MODE_SVC|I_BIT|F_BIT
/*
* copy the vector table into the RAM vectors
* this assumes that the RAM vectors size is divisible by 3 words (12 bytes)
*/
ldr r1,=__ram_vectors_start
ldr r2,=__ram_vectors_end
ldr r3,=ExceptionVectors
1: cmp r1,r2
ldmlt r3!,{r4,r5,r6}
stmlt r1!,{r4,r5,r6}
primary_cpu_init:
/* init .bss */
/* clear the .bss section (zero init) */
ldr r1, =boot_start_addr
ldr r2, =boot_end_addr
mov r3, #0
1: cmp r1, r2
stmltia r1!, {r3}
blt 1b
@ branch to c library entry point
mov r0, #0 @ argc
mov r1, #0 @ argv
mov r2, #0 @ env
bl bootmain
/* clear .bss */
mov r0, #0 /* get a zero */
ldr r1,=__bss_start /* bss start */
ldr r2,=__bss_end /* bss end */
bss_loop:
cmp r1,r2 /* check if data to clear */
strlo r0,[r1],#4 /* clear 4 bytes */
blo bss_loop /* loop until done */
/* call C++ constructors of global objects */
ldr r0, =__ctors_start__
ldr r1, =__ctors_end__
bss_end:
ctor_loop:
cmp r0, r1
beq ctor_end
ldr r2, [r0], #4
stmfd sp!, {r0-r1}
mov lr, pc
bx r2
ldmfd sp!, {r0-r1}
b ctor_loop
ctor_end:
bl init
_loop_here:
b _loop_here
.end
@@ -1,442 +0,0 @@
/*
* Copyright (c) 2011-2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 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 HOLDER 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 "sdk.h"
#include "registers/regsccm.h"
#include "registers/regsccmanalog.h"
#include "registers/regsgpc.h"
#include "registers/regsiomuxc.h"
#include "registers/regsuart.h"
#include "registers/regsssi.h"
#include "registers/regsepit.h"
#include "registers/regsgpt.h"
#include "registers/regsi2c.h"
#include "registers/regsspdif.h"
#include "registers/regsspba.h"
#include "registers/regssdmaarm.h"
#include "registers/regsecspi.h"
#if defined(CHIP_MX6DQ)
#include "registers/regssata.h"
#endif
#if !defined(CHIP_MX6SL)
#include "registers/regsgpmi.h"
#include "registers/regsesai.h"
#endif
////////////////////////////////////////////////////////////////////////////////
// Variables
////////////////////////////////////////////////////////////////////////////////
const uint32_t PLL1_OUTPUT = 792000000;
const uint32_t PLL2_OUTPUT[] = { 528000000, 396000000, 352000000, 198000000, 594000000 };
const uint32_t PLL3_OUTPUT[] = { 480000000, 720000000, 540000000, 508235294, 454736842 };
const uint32_t PLL4_OUTPUT = 650000000;
const uint32_t PLL5_OUTPUT = 650000000;
////////////////////////////////////////////////////////////////////////////////
// Code
////////////////////////////////////////////////////////////////////////////////
void ccm_init(void)
{
// ETHNET
HW_CCM_ANALOG_PLL_ENET_CLR(BM_CCM_ANALOG_PLL_ENET_POWERDOWN);
HW_CCM_ANALOG_PLL_ENET_SET(BM_CCM_ANALOG_PLL_ENET_ENABLE);
HW_CCM_ANALOG_PLL_ENET_CLR(BM_CCM_ANALOG_PLL_ENET_BYPASS);
#if !defined (CHIP_MX6SL)
HW_CCM_ANALOG_PLL_ENET.B.DIV_SELECT = 0x3;
#else
HW_CCM_ANALOG_PLL_ENET.B.DIV_SELECT = 0x1;
#endif
// Ungate clocks that are not enabled in a driver - need to be updated
HW_CCM_CCGR0_WR(0xffffffff);
HW_CCM_CCGR1_WR(0xFFCF0FFF); // EPIT, ESAI, GPT enabled by driver
HW_CCM_CCGR2_WR(0xFFFFF03F); // I2C enabled by driver
HW_CCM_CCGR3_WR(0xffffffff);
HW_CCM_CCGR4_WR(0x00FFFF03); // GPMI, Perfmon enabled by driver
HW_CCM_CCGR5_WR(0xF0FFFFCF); // UART, SATA enabled by driver
HW_CCM_CCGR6_WR(0xffffffff);
/*
* Keep default settings at reset.
* pre_periph_clk_sel is by default at 0, so the selected output
* of PLL2 is the main output at 528MHz.
* => by default, ahb_podf divides by 4 => AHB_CLK@132MHz.
* => by default, ipg_podf divides by 2 => IPG_CLK@66MHz.
*/
HW_CCM_CBCDR.U = BF_CCM_CBCDR_AHB_PODF(3)
#if !defined (CHIP_MX6SL)
| BF_CCM_CBCDR_AXI_PODF(1)
#endif
| BF_CCM_CBCDR_IPG_PODF(1);
/*
* UART clock tree: PLL3 (480MHz) div-by-6: 80MHz
* 80MHz uart_clk_podf (div-by-1) = 80MHz (UART module clock input)
*/
// writel(readl(CCM_CSCDR1) & 0x0000003F, CCM_CSCDR1);
// HW_CCM_CSCDR1.U =
/* Mask all interrupt sources that could wake up the processor when in
a low power mode. A source is individually masked/unmasked when the
interrupt is enabled/disabled by the GIC/interrupt driver. */
HW_GPC_IMR1_WR(0xFFFFFFFF);
HW_GPC_IMR2_WR(0xFFFFFFFF);
HW_GPC_IMR3_WR(0xFFFFFFFF);
HW_GPC_IMR4_WR(0xFFFFFFFF);
}
uint32_t get_main_clock(main_clocks_t clock)
{
uint32_t ret_val = 0;
uint32_t pre_periph_clk_sel = HW_CCM_CBCMR.B.PRE_PERIPH_CLK_SEL;
switch (clock) {
case CPU_CLK:
ret_val = PLL1_OUTPUT;
break;
#if !defined (CHIP_MX6SL)
case AXI_CLK:
ret_val = PLL2_OUTPUT[pre_periph_clk_sel] / (HW_CCM_CBCDR.B.AXI_PODF + 1);
break;
case MMDC_CH0_AXI_CLK:
ret_val = PLL2_OUTPUT[pre_periph_clk_sel] / (HW_CCM_CBCDR.B.MMDC_CH0_AXI_PODF + 1);
break;
#endif
case AHB_CLK:
ret_val = PLL2_OUTPUT[pre_periph_clk_sel] / (HW_CCM_CBCDR.B.AHB_PODF + 1);
break;
case IPG_CLK:
ret_val =
PLL2_OUTPUT[pre_periph_clk_sel] / (HW_CCM_CBCDR.B.AHB_PODF +
1) / (HW_CCM_CBCDR.B.IPG_PODF + 1);
break;
case IPG_PER_CLK:
ret_val =
PLL2_OUTPUT[pre_periph_clk_sel] / (HW_CCM_CBCDR.B.AHB_PODF +
1) / (HW_CCM_CBCDR.B.IPG_PODF +
1) / (HW_CCM_CSCMR1.B.PERCLK_PODF + 1);
break;
#if !defined (CHIP_MX6SL)
case MMDC_CH1_AXI_CLK:
ret_val = PLL2_OUTPUT[pre_periph_clk_sel] / (HW_CCM_CBCDR.B.MMDC_CH1_AXI_PODF + 1);
break;
#endif
default:
break;
}
return ret_val;
}
uint32_t get_peri_clock(peri_clocks_t clock)
{
uint32_t ret_val = 0;
switch (clock)
{
case UART1_MODULE_CLK:
case UART2_MODULE_CLK:
case UART3_MODULE_CLK:
case UART4_MODULE_CLK:
// UART source clock is a fixed PLL3 / 6
ret_val = PLL3_OUTPUT[0] / 6 / (HW_CCM_CSCDR1.B.UART_CLK_PODF + 1);
break;
// eCSPI clock:
// PLL3(480) -> /8 -> CSCDR2[ECSPI_CLK_PODF]
case SPI_CLK:
ret_val = PLL3_OUTPUT[0] / 8 / (HW_CCM_CSCDR2.B.ECSPI_CLK_PODF + 1);
break;
#if !defined (CHIP_MX6SL)
case RAWNAND_CLK:
ret_val =
PLL3_OUTPUT[0] / (HW_CCM_CS2CDR.B.ENFC_CLK_PRED + 1) / (HW_CCM_CS2CDR.B.ENFC_CLK_PODF +
1);
break;
case CAN_CLK:
// For i.mx6dq/sdl CAN source clock is a fixed PLL3 / 8
ret_val = PLL3_OUTPUT[0] / 8 / (HW_CCM_CSCMR2.B.CAN_CLK_PODF + 1);
break;
#endif
default:
break;
}
return ret_val;
}
/*!
* Set/unset clock gating for a peripheral.
* @param ccm_ccgrx Address of the clock gating register: CCM_CCGR1,...
* @param cgx_offset Offset of the clock gating field: CG(x).
* @param gating_mode Clock gating mode: CLOCK_ON or CLOCK_OFF.
*/
void ccm_ccgr_config(uint32_t ccm_ccgrx, uint32_t cgx_offset, uint32_t gating_mode)
{
if (gating_mode == CLOCK_ON)
{
*(volatile uint32_t *)(ccm_ccgrx) |= cgx_offset;
}
else
{
*(volatile uint32_t *)(ccm_ccgrx) &= ~cgx_offset;
}
}
void clock_gating_config(uint32_t base_address, uint32_t gating_mode)
{
uint32_t ccm_ccgrx = 0;
uint32_t cgx_offset = 0;
switch (base_address)
{
case REGS_UART1_BASE:
case REGS_UART2_BASE:
case REGS_UART3_BASE:
case REGS_UART4_BASE:
case REGS_UART5_BASE:
ccm_ccgrx = HW_CCM_CCGR5_ADDR;
cgx_offset = CG(13) | CG(12);
break;
case REGS_SSI3_BASE:
ccm_ccgrx = HW_CCM_CCGR5_ADDR;
cgx_offset = CG(11);
break;
case REGS_SSI2_BASE:
ccm_ccgrx = HW_CCM_CCGR5_ADDR;
cgx_offset = CG(10);
break;
case REGS_SSI1_BASE:
ccm_ccgrx = HW_CCM_CCGR5_ADDR;
cgx_offset = CG(9);
break;
case REGS_SPDIF_BASE:
ccm_ccgrx = HW_CCM_CCGR5_ADDR;
cgx_offset = CG(7);
break;
case REGS_SPBA_BASE:
ccm_ccgrx = HW_CCM_CCGR5_ADDR;
cgx_offset = CG(6);
break;
case REGS_SDMAARM_BASE:
ccm_ccgrx = HW_CCM_CCGR5_ADDR;
cgx_offset = CG(3);
break;
#if CHIP_MX6DQ
case REGS_SATA_BASE:
ccm_ccgrx = HW_CCM_CCGR5_ADDR;
cgx_offset = CG(2);
break;
#endif // CHIP_MX6DQ
case REGS_EPIT1_BASE:
ccm_ccgrx = HW_CCM_CCGR1_ADDR;
cgx_offset = CG(6);
break;
case REGS_EPIT2_BASE:
ccm_ccgrx = HW_CCM_CCGR1_ADDR;
cgx_offset = CG(7);
break;
case REGS_GPT_BASE:
ccm_ccgrx = HW_CCM_CCGR1_ADDR;
cgx_offset = CG(10);
break;
case REGS_I2C1_BASE:
ccm_ccgrx = HW_CCM_CCGR2_ADDR;
cgx_offset = CG(3);
break;
case REGS_I2C2_BASE:
ccm_ccgrx = HW_CCM_CCGR2_ADDR;
cgx_offset = CG(4);
break;
case REGS_I2C3_BASE:
ccm_ccgrx = HW_CCM_CCGR2_ADDR;
cgx_offset = CG(5);
break;
case REGS_ECSPI1_BASE:
ccm_ccgrx = HW_CCM_CCGR1_ADDR;
cgx_offset = CG(0);
break;
case REGS_ECSPI2_BASE:
ccm_ccgrx = HW_CCM_CCGR1_ADDR;
cgx_offset = CG(1);
break;
case REGS_ECSPI3_BASE:
ccm_ccgrx = HW_CCM_CCGR1_ADDR;
cgx_offset = CG(2);
break;
case REGS_ECSPI4_BASE:
ccm_ccgrx = HW_CCM_CCGR1_ADDR;
cgx_offset = CG(3);
break;
#if CHIP_MX6DQ
case REGS_ECSPI5_BASE:
ccm_ccgrx = HW_CCM_CCGR1_ADDR;
cgx_offset = CG(4);
break;
#endif // CHIP_MX6DQ
#if !defined (CHIP_MX6SL)
case REGS_GPMI_BASE:
ccm_ccgrx = HW_CCM_CCGR4_ADDR;
cgx_offset = CG(15) | CG(14) | CG(13) | CG(12);
break;
case REGS_ESAI_BASE:
ccm_ccgrx = HW_CCM_CCGR1_ADDR;
cgx_offset = CG(8);
break;
case CAAM_BASE_ADDR:
ccm_ccgrx = HW_CCM_CCGR0_ADDR;
cgx_offset = CG(6) | CG(5) | CG(4);
break;
#endif // !defined (CHIP_MX6SL)
default:
break;
}
// apply changes only if a valid address was found
if (ccm_ccgrx != 0)
{
ccm_ccgr_config(ccm_ccgrx, cgx_offset, gating_mode);
}
}
void ccm_set_lpm_wakeup_source(uint32_t irq_id, bool doEnable)
{
uint32_t reg_offset = 0;
uint32_t bit_offset = 0;
uint32_t gpc_imr = 0;
// calculate the offset of the register handling that interrupt ID
// ID starts at 32, so for instance ID=89 is handled by IMR2 because
// the integer part of the division is reg_offset = 2
reg_offset = (irq_id / 32);
// and the rest of the previous division is used to calculate the bit
// offset in the register, so for ID=89 this is bit_offset = 25
bit_offset = irq_id - 32 * reg_offset;
// get the current value of the corresponding GPC_IMRx register
gpc_imr = readl(HW_GPC_IMR1_ADDR + (reg_offset - 1) * 4);
if (doEnable) {
// clear the corresponding bit to unmask the interrupt source
gpc_imr &= ~(1 << bit_offset);
// write the new mask
writel(gpc_imr, HW_GPC_IMR1_ADDR + (reg_offset - 1) * 4);
} else {
// set the corresponding bit to mask the interrupt source
gpc_imr |= (1 << bit_offset);
// write the new mask
writel(gpc_imr, HW_GPC_IMR1_ADDR + (reg_offset - 1) * 4);
}
}
void ccm_enter_low_power(lp_modes_t lp_mode)
{
uint32_t ccm_clpcr = 0;
// if MMDC channel 1 is not used, the handshake must be masked
// set disable core clock in wait - set disable oscillator in stop
ccm_clpcr =
#if !defined (CHIP_MX6SL)
BM_CCM_CLPCR_BYPASS_MMDC_CH1_LPM_HS |
#endif
BM_CCM_CLPCR_SBYOS | BM_CCM_CLPCR_ARM_CLK_DIS_ON_LPM | lp_mode;
if (lp_mode == STOP_MODE) {
// enable peripherals well-biased
ccm_clpcr |= BM_CCM_CLPCR_WB_PER_AT_LPM;
}
HW_CCM_CLPCR_WR(ccm_clpcr);
__asm(
// data synchronization barrier (caches, TLB maintenance, ...)
"dsb;"
// wait for interrupt instruction
"wfi;"
// instruction synchronization barrier (flush the pipe-line)
"isb;");
return;
}
#if !defined (CHIP_MX6SL)
/*!
* @brief Configure ipu 1 and 2 hsp clk to default 264MHz
*
* ipu_hsp_clk is derived from mmdc_ch0 divided by 2.
*/
void ipu_hsp_clk_config(void)
{
// clk_sel from mmdc_ch0, podf=1
HW_CCM_CSCDR3_WR(BF_CCM_CSCDR3_IPU1_HSP_CLK_SEL(0)
| BF_CCM_CSCDR3_IPU1_HSP_PODF(1)
#if CHIP_MX6DQ
| BF_CCM_CSCDR3_IPU2_HSP_CLK_SEL(0)
| BF_CCM_CSCDR3_IPU2_HSP_PODF(1)
#endif // CHIP_MX6DQ
);
}
void gpu_clock_config(void)
{
HW_CCM_ANALOG_PLL_VIDEO_NUM_WR(0xFF0D6C3);
HW_CCM_ANALOG_PLL_VIDEO_WR(BF_CCM_ANALOG_PLL_VIDEO_DIV_SELECT(2) |
BF_CCM_ANALOG_PLL_VIDEO_ENABLE(1) |
BF_CCM_ANALOG_PLL_VIDEO_BYPASS(1));
while (!HW_CCM_ANALOG_PLL_VIDEO.B.LOCK) ; //waiting for PLL lock
BF_CLR(CCM_ANALOG_PLL_VIDEO, BYPASS);
//ldb_di0_clk select PLL5
HW_CCM_CS2CDR.B.LDB_DI0_CLK_SEL = 0; // PLL5
HW_IOMUXC_GPR3.B.LVDS1_MUX_CTL = 0; // LVDS1 source is IPU1 DI0 port
HW_IOMUXC_GPR3.B.LVDS0_MUX_CTL = 2; // LVDS0 source is IPU2 DI0 port
HW_CCM_CHSCCDR.B.IPU1_DI0_CLK_SEL = 3; // derive clock from ldb_di0_clk
HW_CCM_CSCMR2_SET(BM_CCM_CSCMR2_LDB_DI0_IPU_DIV | BM_CCM_CSCMR2_LDB_DI1_IPU_DIV); // ldb_di0 divided by 3.5
#if CHIP_MX6DQ
HW_CCM_CSCDR2.B.IPU2_DI0_CLK_SEL = 3; // derive clock from ldb_di0_clk
HW_CCM_CSCDR2.B.IPU2_DI1_CLK_SEL = 3; // derive clock from 352M PFD
#endif // CHIP_MX6DQ
}
#endif
////////////////////////////////////////////////////////////////////////////////
// End of file
////////////////////////////////////////////////////////////////////////////////
@@ -1,150 +0,0 @@
/*
* Copyright (c) 2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 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 HOLDER 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 _CCM_PLL_H_
#define _CCM_PLL_H_
#include "sdk_types.h"
//! @addtogroup diag_clocks
//! @{
////////////////////////////////////////////////////////////////////////////////
// Definitions
////////////////////////////////////////////////////////////////////////////////
#define CLK_SRC_32K 32768
//! @brief Create a clock gate bit mask value.
//! @param x 0..15, for CG0 to CG15
#define CG(x) (3 << (x*2))
//! @brief Constants for CCM CCGR register fields.
enum _clock_gate_constants
{
CLOCK_ON = 0x3, //!< Clock always on in both run and stop modes.
CLOCK_ON_RUN = 0x1, //!< Clock on only in run mode.
CLOCK_OFF = 0x0 //!< Clocked gated off.
};
//! @brief Low power mdoes.
typedef enum _lp_modes {
RUN_MODE,
WAIT_MODE,
STOP_MODE,
} lp_modes_t;
//! @brief Main clock sources.
typedef enum _main_clocks {
CPU_CLK,
AXI_CLK,
MMDC_CH0_AXI_CLK,
AHB_CLK,
IPG_CLK,
IPG_PER_CLK,
MMDC_CH1_AXI_CLK,
} main_clocks_t;
//! @brief Peripheral clocks.
typedef enum _peri_clocks {
UART1_MODULE_CLK,
UART2_MODULE_CLK,
UART3_MODULE_CLK,
UART4_MODULE_CLK,
SSI1_BAUD,
SSI2_BAUD,
CSI_BAUD,
MSTICK1_CLK,
MSTICK2_CLK,
RAWNAND_CLK,
USB_CLK,
VPU_CLK,
SPI_CLK,
CAN_CLK
} peri_clocks_t;
//! @brief Available PLLs.
typedef enum plls {
PLL1,
PLL2,
PLL3,
PLL4,
PLL5,
} plls_t;
extern const uint32_t PLL1_OUTPUT;
extern const uint32_t PLL2_OUTPUT[];
extern const uint32_t PLL3_OUTPUT[];
extern const uint32_t PLL4_OUTPUT;
extern const uint32_t PLL5_OUTPUT;
////////////////////////////////////////////////////////////////////////////////
// API
////////////////////////////////////////////////////////////////////////////////
#if defined(__cplusplus)
extern "C" {
#endif
//! @brief Set/unset clock gating for a peripheral.
//! @param base_address configure clock gating for that module from the base address.
//! @param gating_mode clock gating mode: CLOCK_ON or CLOCK_OFF.
void clock_gating_config(uint32_t base_address, uint32_t gating_mode);
//! @brief Returns the frequency of a clock in megahertz.
uint32_t get_main_clock(main_clocks_t clk);
//! @brief Returns the frequency of a clock in megahertz.
uint32_t get_peri_clock(peri_clocks_t clk);
//! @brief Inits clock sources.
void ccm_init(void);
//! @brief Prepare and enter in a low power mode.
//! @param lp_mode low power mode : WAIT_MODE or STOP_MODE.
void ccm_enter_low_power(lp_modes_t lp_mode);
//! @brief Mask/unmask an interrupt source that can wake up the processor when in a
//! low power mode.
//!
//! @param irq_id ID of the interrupt to mask/unmask.
//! @param doEnable Pass true to unmask the source ID.
void ccm_set_lpm_wakeup_source(uint32_t irq_id, bool doEnable);
#if defined(__cplusplus)
}
#endif
//! @}
#endif
////////////////////////////////////////////////////////////////////////////////
// EOF
////////////////////////////////////////////////////////////////////////////////
@@ -0,0 +1,44 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
.global context_switch
context_switch:
# store original context to stack
str lr, [r13, #-4]!
str r12, [r13, #-4]!
str r11, [r13, #-4]!
str r10, [r13, #-4]!
str r9, [r13, #-4]!
str r8, [r13, #-4]!
str r7, [r13, #-4]!
str r6, [r13, #-4]!
str r5, [r13, #-4]!
str r4, [r13, #-4]!
# switch the stack
str r13, [r0] // save current sp to the old PCB (**old)
mov r13, r1 // load the next stack
# restore context from stack
ldr r4, [r13], #4
ldr r5, [r13], #4
ldr r6, [r13], #4
ldr r7, [r13], #4
ldr r8, [r13], #4
ldr r9, [r13], #4
ldr r10, [r13], #4
ldr r11, [r13], #4
ldr r12, [r13], #4
ldr lr, [r13], #4
# return to the caller
bx lr
@@ -0,0 +1,80 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file core.c
* @brief spl boot function
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023.09.07
*/
/*************************************************
File name: core.c
Description: cortex-a9 core function, include cpu registers operations、core boot
Others:
History:
1. Date: 2023-08-28
Author: AIIT XUOS Lab
Modification:
1. first version
*************************************************/
/*********cortex-a9 general register************
Applications level view System level view
| User | Syetem | Hyp | Svc | Abort | Undefined | IRQ | FIQ
r0 r0 r0 r0 r0 r0 r0 r0 r0
r1 r1 r1 r1 r1 r1 r1 r1 r1
r2 r2 r2 r2 r2 r2 r2 r2 r2
r3 r3 r3 r3 r3 r3 r3 r3 r3
r4 r4 r4 r4 r4 r4 r4 r4 r4
r5 r5 r5 r5 r5 r5 r5 r5 r5
r6 r6 r6 r6 r6 r6 r6 r6 r6
r7 r7 r7 r7 r7 r7 r7 r7 r7
r8 r8 r8 r8 r8 r8 r8 r8 r8_fiq
r9 r9 r9 r9 r9 r9 r9 r9 r9_fiq
r10 r10 r10 r10 r10 r10 r10 r10 r10_fiq
r11 r11 r11 r11 r11 r11 r11 r11 r11_fiq
r12 r12 r12 r12 r12 r12 r12 r12 r12_fiq
SP SP SP SP_hyp SP_svc SP_abt SP_und SP_irq SP_fiq
LR LR LR LR LR_svc LR_abt LR_und LR_irq LR_fiq
PC PC PC PC PC PC PC PC PC
APSR CPSR CPSR CPSR CPSR CPSR CPSR CPSR CPSR
SPSR_hyp SPSR_svc SPSR_abt SPSR_und SPSR_irq SPSR_fiq
ELR_hyp
************************************************/
/*********cortex-a9 CP15 register***************
CRn / opc1 / CRm / opc2 / description
c0 0,1,2 c0-c7 0,1,2,3,4,5,6,7 ID寄存器相关操作
c1 0,4 c0,c1 0,1,2,3,4,5,6,7 SCTLR系统控制寄存器等
c2 0,4 c0,c1 0,1,2 TTBR0、TTBR1、TTBCR寄存器
c3 0 c0 0 DACR域控制寄存器
c5 0,4 c0,c1 0,1 DFSR数据异常状态寄存器、IFSR指令异常状态寄存器
c6 0,4 c0 0,2,4 DFAR数据异常地址寄存器、IFAR指令异常地址寄存器
c7 0,4 c0,c1,c4,c5,c6,c8,c10,c11,c14 0,1,2,3,4,5,6,7 cache操作相关寄存器
c8 0,4 c3,c5,c6,c7 0,1,2,3 TLB操作相关寄存器
c9 0,1,2,3,4,5,6,7 c12,c13,c14 0,1,2,3,4,5,6,7 性能监测寄存器
c10 0,1,2,3,4,5,6,7 c0,c2 0,1,2,3,4,5,6,7 TLB权限控制寄存器、内存重映射
c11 0,1,2,3,4,5,6,7 c0,c1,c2,c3,c4,c5,c6,c7,c7,c15 0,1,2,3,4,5,6,7 紧密耦合内存TCM的DMA控制寄存器
c12 0,4 c0,c1 0,1 安全扩展寄存器
c13 0,4 c0 0,1,2,3,4 上下文ID保存寄存器,用于快速上下文切换
c14 0,1,2,3,4,5,6,7 c0-c15 0,1,2,3,4,5,6,7 定时器控制寄存器
c15 0,1,2,3,4,5,6,7 c0-c15 0,1,2,3,4,5,6,7 (svc mode only)自定义寄存器
汇编指令格式:
MRC p15, opc1, r0, CRn, CRm, opc2 -------- 将CP15内寄存器CRn的值读到指定通用寄存器r0中
MCR p15, opc1, r0, CRn, CRm, opc2 -------- 将指定通用寄存器r0的值写到CP15内寄存器CRn中
************************************************/
#include "core.h"
@@ -0,0 +1,196 @@
/*
* Copyright (c) 2020 AIIT XUOS Lab
* XiUOS is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
* http://license.coscl.org.cn/MulanPSL2
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
*/
/**
* @file core.h
* @brief cortex-a9 core function
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023.11.20
*/
/*************************************************
File name: core.h
Description: cortex-a9 core function
Others:
History:
1. Date: 2023-11-20
Author: AIIT XUOS Lab
Modification:
1. first version
*************************************************/
#pragma once
// Interrupt control bits
#define NO_INT 0xc0 // disable IRQ.
#define DIS_INT 0x80 // disable both IRQ and FIQ.
//! @name CPSR fields
//@{
#define CPSR_N (1 << 31) //!< Negative
#define CPSR_Z (1 << 30) //!< Zero
#define CPSR_C (1 << 29) //!< Carry
#define CPSR_V (1 << 28) //!< Overflow
#define CPSR_Q (1 << 27) //!< Saturation
#define CPSR_E (1 << 9) //!< Endianness
#define CPSR_A (1 << 8) //!< Async abort mask
#define CPSR_I (1 << 7) //!< IRQ mask
#define CPSR_F (1 << 6) //!< FIQ mask
#define CPSR_T (1 << 5) //!< Thumb mode
#define CPSR_MODE (0x1f) //!< Current processor mode
//@}
#define MODE_STACK_SIZE 0x4000
//! @name Interrupt enable bits in CPSR
//@{
#define I_BIT 0x80 //!< When I bit is set, IRQ is disabled
#define F_BIT 0x40 //!< When F bit is set, FIQ is disabled
//@}
// ARM modes.
#define ARM_CPSR_MODE_MASK 0x1f
#define ARM_MODE_USR 0x10
#define ARM_MODE_FIQ 0x11
#define ARM_MODE_IRQ 0x12
#define ARM_MODE_SVC 0x13
#define ARM_MODE_ABT 0x17
#define ARM_MODE_UND 0x1b
#define ARM_MODE_SYS 0x1f
#ifndef __ASSEMBLER__
#include <stdint.h>
#include <string.h>
#include "cortex_a9.h"
#define NR_CPU 4
__attribute__((always_inline)) static inline uint32_t user_mode()
{
uint32_t val;
__asm__ __volatile__(
"mrs %0, cpsr"
: "=r"(val)
:
:);
val &= ~DIS_INT;
val &= ~ARM_CPSR_MODE_MASK;
val |= ARM_MODE_USR;
return val;
}
struct context {
uint32_t r4;
uint32_t r5;
uint32_t r6;
uint32_t r7;
uint32_t r8;
uint32_t r9;
uint32_t r10;
uint32_t r11;
uint32_t r12;
uint32_t lr;
};
/// @brief init task context, set return address to trap return
/// @param
extern void trap_return(void);
__attribute__((__always_inline__)) static inline void arch_init_context(struct context* ctx)
{
memset(ctx, 0, sizeof(*ctx));
ctx->lr = (uint32_t)(trap_return);
}
struct trapframe {
uint32_t sp_usr;
uint32_t lr_usr;
uint32_t lr_svc;
uint32_t spsr;
uint32_t r0;
uint32_t r1;
uint32_t r2;
uint32_t r3;
uint32_t r4;
uint32_t r5;
uint32_t r6;
uint32_t r7;
uint32_t r8;
uint32_t r9;
uint32_t r10;
uint32_t r11;
uint32_t r12;
uint32_t pc;
};
/// @brief init task trapframe (*especially the user mode cpsr)
/// @param tf
/// @param sp
/// @param pc
__attribute__((__always_inline__)) static inline void arch_init_trapframe(struct trapframe* tf, uintptr_t sp, uintptr_t pc)
{
memset(tf, 0, sizeof(*tf));
tf->spsr = user_mode();
tf->sp_usr = sp;
tf->lr_svc = 0;
tf->lr_usr = 0;
tf->pc = pc;
}
/// @brief set pc and sp to trapframe
/// @param tf
/// @param sp
/// @param pc
__attribute__((__always_inline__)) static inline void arch_trapframe_set_sp_pc(struct trapframe* tf, uintptr_t sp, uintptr_t pc)
{
tf->sp_usr = sp;
tf->pc = pc;
}
/// @brief set params of main(int argc, char** argv) to trapframe (argc, argv)
/// @param tf
/// @param argc
/// @param argv
__attribute__((__always_inline__)) static inline void arch_set_main_params(struct trapframe* tf, int argc, uintptr_t argv)
{
tf->r0 = (uint32_t)argc;
tf->r1 = (uint32_t)argv;
}
/// @brief retrieve params to trapframe (up to max number of 6) and pass it to syscall()
/// @param sys_num
/// @param param1
/// @param param2
/// @param param3
/// @param param4
/// @param param5
/// @return
extern int syscall(int sys_num, uintptr_t param1, uintptr_t param2, uintptr_t param3, uintptr_t param4);
__attribute__((__always_inline__)) static inline int arch_syscall(struct trapframe* tf, int* syscall_num)
{
// call syscall
*syscall_num = tf->r0;
return syscall(*syscall_num, tf->r1, tf->r2, tf->r3, tf->r4);
}
/// @brief set return reg to trapframe
/// @param tf
/// @param ret
__attribute__((__always_inline__)) static inline void arch_set_return(struct trapframe* tf, int ret)
{
tf->r0 = (uint32_t)ret;
}
#endif
@@ -1,145 +0,0 @@
#include <asm_defines.h>
.section .text.vectors, "ax"
.code 32
.globl ExceptionVectors
ExceptionVectors:
ldr pc, _ResetException
ldr pc, _UndefInstrException
ldr pc, _SwiException
ldr pc, _PrefetchAbortException
ldr pc, _DataAbortAbortException
ldr pc, _ResvException
ldr pc, _IrqException
ldr pc, _FiqException
.globl _reset
.globl UndefInstrExceptionHandle
.globl SwiExceptionHandle
.globl PrefetchAbortExceptionHandle
.globl DataAbortExceptionHandle
.globl ResvExceptionHandle
.globl ExceptionIsrEntry
.globl FiqExceptionHandle
_ResetException:
.word _reset
_UndefInstrException:
.word UndefInstrExceptionHandle
_SwiException:
.word SwiExceptionHandle
_PrefetchAbortException:
.word PrefetchAbortExceptionHandle
_DataAbortAbortException:
.word DataAbortExceptionHandle
_ResvException:
.word ResvExceptionHandle
_IrqException:
.word ExceptionIsrEntry
_FiqException:
.word FiqExceptionHandle
.word 0 // extra word in RAM vectors
.macro push_svc_reg
sub sp, sp, #17 * 4 @/* Sizeof(struct rt_hw_exp_stack) */
stmia sp, {r0 - r12} @/* Calling r0-r12 */
mov r0, sp
mrs r6, spsr @/* Save CPSR */
str lr, [r0, #15*4] @/* Push PC */
str r6, [r0, #16*4] @/* Push CPSR */
cps #MODE_SVC
str sp, [r0, #13*4] @/* Save calling SP */
str lr, [r0, #14*4] @/* Save calling PC */
.endm
.align 5
.globl UndefInstrExceptionHandle
UndefInstrExceptionHandle:
1:
b 1b
.align 5
.globl SwiExceptionHandle
SwiExceptionHandle:
push_svc_reg
bl DoSvcCallProcess
b .
.align 5
.globl PrefetchAbortExceptionHandle
PrefetchAbortExceptionHandle:
1:
b 1b
.align 5
.globl DataAbortExceptionHandle
DataAbortExceptionHandle:
1:
b 1b
.align 5
.globl ResvExceptionHandle
ResvExceptionHandle:
1:
b 1b
.section .text.isr, "ax"
.align 5
.globl ExceptionIsrEntry
ExceptionIsrEntry:
stmfd sp!, {r0-r12,lr}
bl DoIrqProcess
@ ldr r0, =rt_thread_switch_interrupt_flag
@ ldr r1, [r0]
@ cmp r1, #1
@ beq rt_hw_context_switch_interrupt_do
ldmfd sp!, {r0-r12,lr}
subs pc, lr, #4
@ rt_hw_context_switch_interrupt_do:
@ mov r1, #0 @ clear flag
@ str r1, [r0]
@ mov r1, sp @ r1 point to {r0-r3} in stack
@ add sp, sp, #4*4
@ ldmfd sp!, {r4-r12,lr}@ reload saved registers
@ mrs r0, spsr @ get cpsr of interrupt thread
@ sub r2, lr, #4 @ save old task's pc to r2
@ @ Switch to SVC mode with no interrupt. If the usr mode guest is
@ @ interrupted, this will just switch to the stack of kernel space.
@ @ save the registers in kernel space won't trigger data abort.
@ msr cpsr_c, #I_Bit|F_Bit|Mode_SVC
@ stmfd sp!, {r2} @ push old task's pc
@ stmfd sp!, {r4-r12,lr}@ push old task's lr,r12-r4
@ ldmfd r1, {r1-r4} @ restore r0-r3 of the interrupt thread
@ stmfd sp!, {r1-r4} @ push old task's r0-r3
@ stmfd sp!, {r0} @ push old task's cpsr
@ ldr r4, =rt_interrupt_from_thread
@ ldr r5, [r4]
@ str sp, [r5] @ store sp in preempted tasks's TCB
@ ldr r6, =rt_interrupt_to_thread
@ ldr r6, [r6]
@ ldr sp, [r6] @ get new task's stack pointer
@ ldmfd sp!, {r4} @ pop new task's cpsr to spsr
@ msr spsr_cxsf, r4
@ ldmfd sp!, {r0-r12,lr,pc}^ @ pop new task's r0-r12,lr & pc, copy spsr to cpsr
.align 5
.globl FiqExceptionHandle
FiqExceptionHandle:
1:
b 1b
@@ -1,243 +0,0 @@
/*
* Copyright (c) 2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 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 HOLDER 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 <assert.h>
#include "gic.h"
#include "gic_registers.h"
#include "cortex_a9.h"
////////////////////////////////////////////////////////////////////////////////
// Prototypes
////////////////////////////////////////////////////////////////////////////////
static inline gicd_t * gic_get_gicd(void);
static inline gicc_t * gic_get_gicc(void);
static inline uint32_t irq_get_register_offset(uint32_t irqID);
static inline uint32_t irq_get_bit_offset(uint32_t irqID);
static inline uint32_t irq_get_bit_mask(uint32_t irqID);
////////////////////////////////////////////////////////////////////////////////
// Code
////////////////////////////////////////////////////////////////////////////////
static inline gicd_t * gic_get_gicd(void)
{
uint32_t base = get_arm_private_peripheral_base() + kGICDBaseOffset;
return (gicd_t *)base;
}
static inline gicc_t * gic_get_gicc(void)
{
uint32_t base = get_arm_private_peripheral_base() + kGICCBaseOffset;
return (gicc_t *)base;
}
static inline uint32_t irq_get_register_offset(uint32_t irqID)
{
return irqID / 32;
}
static inline uint32_t irq_get_bit_offset(uint32_t irqID)
{
return irqID & 0x1f;
}
static inline uint32_t irq_get_bit_mask(uint32_t irqID)
{
return 1 << irq_get_bit_offset(irqID);
}
void gic_enable(bool enableIt)
{
gicd_t * gicd = gic_get_gicd();
if (enableIt)
{
// Enable both secure and non-secure.
gicd->CTLR |= kBM_GICD_CTLR_EnableGrp0 | kBM_GICD_CTLR_EnableGrp1;
}
else
{
// Clear the enable bits.
gicd->CTLR &= ~(kBM_GICD_CTLR_EnableGrp0 | kBM_GICD_CTLR_EnableGrp1);
}
}
void gic_set_irq_security(uint32_t irqID, bool isSecure)
{
gicd_t * gicd = gic_get_gicd();
uint32_t reg = irq_get_register_offset(irqID);
uint32_t mask = irq_get_bit_mask(irqID);
uint32_t value = gicd->IGROUPRn[reg];
if (!isSecure)
{
value &= ~mask;
}
else
{
value |= mask;
}
gicd->IGROUPRn[reg] = value;
}
void gic_enable_irq(uint32_t irqID, bool isEnabled)
{
gicd_t * gicd = gic_get_gicd();
uint32_t reg = irq_get_register_offset(irqID);
uint32_t mask = irq_get_bit_mask(irqID);
// Select set-enable or clear-enable register based on enable flag.
if (isEnabled)
{
gicd->ISENABLERn[reg] = mask;
}
else
{
gicd->ICENABLERn[reg] = mask;
}
}
void gic_set_irq_priority(uint32_t ID, uint32_t priority)
{
gicd_t * gicd = gic_get_gicd();
// Update the priority register. The priority registers are byte accessible, and the register
// struct has the priority registers as a byte array, so we can just index directly by the
// interrupt ID.
gicd->IPRIORITYRn[ID] = priority & 0xff;
}
void gic_set_cpu_target(uint32_t irqID, unsigned cpuNumber, bool enableIt)
{
// Make sure the CPU number is valid.
assert(cpuNumber <= 7);
gicd_t * gicd = gic_get_gicd();
uint8_t cpuMask = 1 << cpuNumber;
// Like the priority registers, the target registers are byte accessible, and the register
// struct has the them as a byte array, so we can just index directly by the
// interrupt ID.
if (enableIt)
{
gicd->ITARGETSRn[irqID] |= (cpuMask & 0xff);
}
else
{
gicd->ITARGETSRn[irqID] &= ~(cpuMask & 0xff);
}
}
void gic_send_sgi(uint32_t irqID, uint32_t target_list, uint32_t filter_list)
{
gicd_t * gicd = gic_get_gicd();
gicd->SGIR = (filter_list << kBP_GICD_SGIR_TargetListFilter)
| (target_list << kBP_GICD_SGIR_CPUTargetList)
| (irqID & 0xf);
}
void gic_cpu_enable(bool enableIt)
{
gicc_t * gicc = gic_get_gicc();
if (enableIt)
{
gicc->CTLR |= kBM_GICC_CTLR_EnableS | kBM_GICC_CTLR_EnableNS;
}
else
{
gicc->CTLR &= ~(kBM_GICC_CTLR_EnableS | kBM_GICC_CTLR_EnableNS);
}
}
void gic_set_cpu_priority_mask(uint32_t priority)
{
gicc_t * gicc = gic_get_gicc();
gicc->PMR = priority & 0xff;
}
uint32_t gic_read_irq_ack(void)
{
gicc_t * gicc = gic_get_gicc();
return gicc->IAR;
}
void gic_write_end_of_irq(uint32_t irqID)
{
gicc_t * gicc = gic_get_gicc();
gicc->EOIR = irqID;
}
void gic_init(void)
{
gicd_t * gicd = gic_get_gicd();
// First disable the distributor.
gic_enable(false);
// Clear all pending interrupts.
int i;
for (i = 0; i < 32; ++i)
{
gicd->ICPENDRn[i] = 0xffffffff;
}
// Set all interrupts to secure.
for (i = 0; i < 8; ++i)
{
gicd->IGROUPRn[i] = 0;
}
// Init the GIC CPU interface.
gic_init_cpu();
// Now enable the distributor.
gic_enable(true);
}
void gic_init_cpu(void)
{
// Init the GIC CPU interface.
gic_set_cpu_priority_mask(0xff);
// Disable preemption.
gicc_t * gicc = gic_get_gicc();
gicc->BPR = 7;
// Enable signaling the CPU.
gic_cpu_enable(true);
}
////////////////////////////////////////////////////////////////////////////////
// EOF
////////////////////////////////////////////////////////////////////////////////
@@ -1,183 +0,0 @@
/*
* Copyright (c) 2011-2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 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 HOLDER 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 __GIC_H__
#define __GIC_H__
#include "sdk_types.h"
//! @addtogroup gic
//! @{
////////////////////////////////////////////////////////////////////////////////
// Definitions
////////////////////////////////////////////////////////////////////////////////
//! @brief Options for sending a software generated interrupt.
//!
//! These options are used for the @a filter_list parameter of the gic_send_sgi()
//! function. They control how to select which CPUs that the interrupt is
//! sent to.
enum _gicd_sgi_filter
{
//! Forward the interrupt to the CPU interfaces specified in the @a target_list parameter.
kGicSgiFilter_UseTargetList = 0,
//! Forward the interrupt to all CPU interfaces except that of the processor that requested
//! the interrupt.
kGicSgiFilter_AllOtherCPUs = 1,
//! Forward the interrupt only to the CPU interface of the processor that requested the
//! interrupt.
kGicSgiFilter_OnlyThisCPU = 2
};
////////////////////////////////////////////////////////////////////////////////
// API
////////////////////////////////////////////////////////////////////////////////
#if defined(__cplusplus)
extern "C" {
#endif
//! @name Initialization
//@{
//! @brief Init interrupt handling.
//!
//! This function is intended to be called only by the primary CPU init code, so it will
//! only be called once during system bootup.
//!
//! Also inits the current CPU. You don't need to call gic_init_cpu() separately.
//!
//! @post The interrupt distributor and the current CPU interface are enabled. All interrupts
//! that were pending are cleared, and all interrupts are made secure (group 0).
void gic_init(void);
//! @brief Init the current CPU's GIC interface.
//!
//! @post Enables the CPU interface and sets the priority mask to 255. Interrupt preemption
//! is disabled by setting the Binary Point to a value of 7.
void gic_init_cpu(void);
//@}
//! @name GIC Interrupt Distributor Functions
//@{
//! @brief Enable or disable the GIC Distributor.
//!
//! Enables or disables the GIC distributor passing both secure (group 0) and non-secure
//! (group 1) interrupts to the CPU interfaces.
//!
//! @param enableIt Pass true to enable or false to disable.
void gic_enable(bool enableIt);
//! @brief Set the security mode for an interrupt.
//!
//! @param irqID The interrupt number.
//! @param isSecure Whether the interrupt is taken to secure mode.
void gic_set_irq_security(uint32_t irqID, bool isSecure);
//! @brief Enable or disable an interrupt.
//!
//! @param irqID The number of the interrupt to control.
//! @param isEnabled Pass true to enable or false to disable.
void gic_enable_irq(uint32_t irqID, bool isEnabled);
//! @brief Set whether a CPU will receive a particular interrupt.
//!
//! @param irqID The interrupt number.
//! @param cpuNumber The CPU number. The first CPU core is 0.
//! @param enableIt Whether to send the interrupt to the specified CPU. Pass true to enable
//! or false to disable.
void gic_set_cpu_target(uint32_t irqID, unsigned cpuNumber, bool enableIt);
//! @brief Set an interrupt's priority.
//!
//! @param irq_id The interrupt number.
//! @param priority The priority for the interrupt. In the range of 0 through 0xff, with
//! 0 being the highest priority.
void gic_set_irq_priority(uint32_t irq_id, uint32_t priority);
//! @brief Send a software generated interrupt to a specific CPU.
//!
//! @param irq_id The interrupt number to send.
//! @param target_list Each bit indicates a CPU to which the interrupt will be forwarded.
//! Bit 0 is CPU 0, bit 1 is CPU 1, and so on. If the value is 0, then the interrupt
//! will not be forwarded to any CPUs. This parameter is only used if @a filter_list
//! is set to #kGicSgiFilter_UseTargetList.
//! @param filter_list One of the enums of the #_gicd_sgi_filter enumeration. The selected
//! option determines which CPUs the interrupt will be sent to. If the value
//! is #kGicSgiFilter_UseTargetList, then the @a target_list parameter is used.
void gic_send_sgi(uint32_t irq_id, uint32_t target_list, uint32_t filter_list);
//@}
//! @name GIC CPU Interface Functions
//@{
//! @brief Enable or disable the interface to the GIC for the current CPU.
//!
//! @param enableIt Pass true to enable or false to disable.
void gic_cpu_enable(bool enableIt);
//! @brief Set the mask of which interrupt priorities the CPU will receive.
//!
//! @param priority The lowest priority that will be passed to the current CPU. Pass 0xff to
//! allow all priority interrupts to signal the CPU.
void gic_set_cpu_priority_mask(uint32_t priority);
//! @brief Acknowledge starting of interrupt handling and get the interrupt number.
//!
//! Normally, this function is called at the beginning of the IRQ handler. It tells the GIC
//! that you are starting to handle an interupt, and returns the number of the interrupt you
//! need to handle. After the interrupt is handled, you should call gic_write_end_of_irq()
//! to signal that the interrupt is completely handled.
//!
//! In some cases, a spurious interrupt might happen. One possibility is if another CPU handles
//! the interrupt. When a spurious interrupt occurs, the end of the interrupt should be indicated
//! but nothing else.
//!
//! @return The number for the highest priority interrupt available for the calling CPU. If
//! the return value is 1022 or 1023, a spurious interrupt has occurred.
uint32_t gic_read_irq_ack(void);
//! @brief Signal the end of handling an interrupt.
//!
//! @param irq_id The number of the interrupt for which handling has finished.
void gic_write_end_of_irq(uint32_t irq_id);
//@}
#if defined(__cplusplus)
}
#endif
//! @}
#endif // __GIC_H__
////////////////////////////////////////////////////////////////////////////////
// EOF
////////////////////////////////////////////////////////////////////////////////
@@ -1,140 +0,0 @@
/*
* Copyright (c) 2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 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 HOLDER 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 "sdk_types.h"
////////////////////////////////////////////////////////////////////////////////
// Definitions
////////////////////////////////////////////////////////////////////////////////
//! @brief Offsets to the GIC registers.
enum _gic_base_offsets
{
kGICDBaseOffset = 0x1000, //!< GIC distributor offset.
kGICCBaseOffset = 0x100 //!< GIC CPU interface offset.
};
//! @brief GIC distributor registers.
//!
//! Uses the GICv2 register names, but does not include GICv2 registers.
//!
//! The IPRIORITYRn and ITARGETSRn registers are byte accessible, so their types are uint8_t
//! instead of uint32_t to reflect this. These members are indexed directly with the interrupt
//! number.
struct _gicd_registers
{
uint32_t CTLR; //!< Distributor Control Register.
uint32_t TYPER; //!< Interrupt Controller Type Register.
uint32_t IIDR; //!< Distributor Implementer Identification Register.
uint32_t _reserved0[29];
uint32_t IGROUPRn[8]; //!< Interrupt Group Registers.
uint32_t _reserved1[24];
uint32_t ISENABLERn[32]; //!< Interrupt Set-Enable Registers.
uint32_t ICENABLERn[32]; //!< Interrupt Clear-Enable Registers.
uint32_t ISPENDRn[32]; //!< Interrupt Set-Pending Registers.
uint32_t ICPENDRn[32]; //!< Interrupt Clear-Pending Registers.
uint32_t ICDABRn[32]; //!< Active Bit Registers.
uint32_t _reserved2[32];
uint8_t IPRIORITYRn[255 * sizeof(uint32_t)]; //!< Interrupt Priority Registers. (Byte accessible)
uint32_t _reserved3;
uint8_t ITARGETSRn[255 * sizeof(uint32_t)]; //!< Interrupt Processor Targets Registers. (Byte accessible)
uint32_t _reserved4;
uint32_t ICFGRn[64]; //!< Interrupt Configuration Registers.
uint32_t _reserved5[128];
uint32_t SGIR; //!< Software Generated Interrupt Register
};
//! @brief Bitfields constants for the GICD_CTLR register.
enum _gicd_ctlr_fields
{
kBM_GICD_CTLR_EnableGrp1 = (1 << 1),
kBM_GICD_CTLR_EnableGrp0 = (1 << 0)
};
//! @brief Bitfields constants for the GICD_SGIR register.
enum _gicd_sgir_fields
{
kBP_GICD_SGIR_TargetListFilter = 24,
kBM_GICD_SGIR_TargetListFilter = (0x3 << kBP_GICD_SGIR_TargetListFilter),
kBP_GICD_SGIR_CPUTargetList = 16,
kBM_GICD_SGIR_CPUTargetList = (0xff << kBP_GICD_SGIR_CPUTargetList),
kBP_GICD_SGIR_NSATT = 15,
kBM_GICD_SGIR_NSATT = (1 << kBP_GICD_SGIR_NSATT),
kBP_GICD_SGIR_SGIINTID = 0,
kBM_GICD_SGIR_SGIINTID = 0xf
};
//! @brief GIC CPU interface registers.
//!
//! Uses the GICv2 register names. Does not include GICv2 registers.
struct _gicc_registers
{
uint32_t CTLR; //!< CPU Interface Control Register.
uint32_t PMR; //!< Interrupt Priority Mask Register.
uint32_t BPR; //!< Binary Point Register.
uint32_t IAR; //!< Interrupt Acknowledge Register.
uint32_t EOIR; //!< End of Interrupt Register.
uint32_t RPR; //!< Running Priority Register.
uint32_t HPPIR; //!< Highest Priority Pending Interrupt Register.
uint32_t ABPR; //!< Aliased Binary Point Register. (only visible with a secure access)
uint32_t _reserved[56];
uint32_t IIDR; //!< CPU Interface Identification Register.
};
//! @brief Bitfields constants for the GICC_CTLR register.
enum _gicc_ctlr_fields
{
kBP_GICC_CTLR_EnableS = 0,
kBM_GICC_CTLR_EnableS = (1 << 0),
kBP_GICC_CTLR_EnableNS = 1,
kBM_GICC_CTLR_EnableNS = (1 << 1),
kBP_GICC_CTLR_AckCtl = 2,
kBM_GICC_CTLR_AckCtl = (1 << 2),
kBP_GICC_CTLR_FIQEn = 3,
kBM_GICC_CTLR_FIQEn = (1 << 3),
kBP_GICC_CTLR_SBPR = 4,
kBM_GICC_CTLR_SBPR = (1 << 4)
};
//! @brier Type for the GIC distributor registers.
typedef volatile struct _gicd_registers gicd_t;
//! @brier Type for the GIC CPU interface registers.
typedef volatile struct _gicc_registers gicc_t;
////////////////////////////////////////////////////////////////////////////////
// EOF
////////////////////////////////////////////////////////////////////////////////
@@ -1,111 +0,0 @@
// extern void _svcall(uintptr_t* contex);
#include <stdint.h>
#include <stddef.h>
#include <isr.h>
uint32_t DisableLocalInterrupt(void)
{
uint32_t intSave;
__asm__ __volatile__(
"mrs %0, cpsr \n"
"cpsid if "
: "=r"(intSave)
:
: "memory");
return intSave;
}
void EnableLocalInterrupt(unsigned long level)
{
uint32_t intSave;
__asm__ __volatile__(
"mrs %0, cpsr \n"
"cpsie if "
: "=r"(intSave)
:
: "memory");
return;
}
int32_t ArchEnableHwIrq(uint32_t irq_num, uint32_t cpu_id)
{
// gic_set_irq_priority(irq_num, priority);
gic_set_irq_security(irq_num, false); // set IRQ as non-secure
gic_set_cpu_target(irq_num, cpu_id, true);
gic_enable_irq(irq_num, true);
return 0;
}
int32_t ArchDisableHwIrq(uint32_t irq_num, uint32_t cpu_id)
{
gic_enable_irq(irq_num, false);
gic_set_cpu_target(irq_num, cpu_id, false);
return 0;
}
extern void KTaskOsAssignAfterIrq(void *context);
void IsrEntry(uint32_t irq_num)
{
isrManager.done->incCounter();
isrManager.done->handleIrq(irq_num);
// KTaskOsAssignAfterIrq(NULL);
isrManager.done->decCounter();
}
/**
* this function will show registers of CPU
*
* @param regs the registers point
*/
void PrintStackFrame(struct ExceptionStackRegister *regs)
{
// KPrintf("Execption:\n");
// KPrintf("r0: 0x%08x\n", regs->r0);
// KPrintf("r1: 0x%08x\n", regs->r1);
// KPrintf("r2: 0x%08x\n", regs->r2);
// KPrintf("r3: 0x%08x\n", regs->r3);
// KPrintf("r4: 0x%08x\n", regs->r4);
// KPrintf("r5: 0x%08x\n", regs->r5);
// KPrintf("r6: 0x%08x\n", regs->r6);
// KPrintf("r7: 0x%08x\n", regs->r7);
// KPrintf("r8: 0x%08x\n", regs->r8);
// KPrintf("r9: 0x%08x\n", regs->r9);
// KPrintf("r10: 0x%08x\n", regs->r10);
// KPrintf("r11: 0x%08x\n", regs->r11);
// KPrintf("r12: 0x%08x\n", regs->r12);
// KPrintf("r13_sp: 0x%08x\n", regs->r13_sp);
// KPrintf("r14_lr: 0x%08x\n", regs->r14_lr);
// KPrintf("r15_pc: 0x%08x\n", regs->r15_pc);
// KPrintf("cpsr: 0x%08x\n", regs->cpsr);
}
void DoSvcCallProcess(struct ExceptionStackRegister *regs)
{
}
void DoIrqProcess(void)
{
uint32_t iar = gic_read_irq_ack();
uint32_t irq_num = iar & 0x3ff;
if(irq_num >= ARCH_MAX_IRQ_NUM)
{
gic_write_end_of_irq(irq_num);
return;
}
IsrEntry(irq_num);
gic_write_end_of_irq(irq_num);
}
// uintptr_t *Svcall(unsigned int ipsr, uintptr_t* contex )
// {
// #ifdef TASK_ISOLATION
// _svcall(contex);
// #endif
// return contex;
// }
@@ -1,285 +0,0 @@
/*
* Copyright (c) 2008-2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 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 HOLDER 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.
*/
/*!
* @file mmu.c
* @brief System memory arangement.
*/
#include "cortex_a9.h"
#include "mmu.h"
#include "arm_cp_registers.h"
////////////////////////////////////////////////////////////////////////////////
// Definitions
////////////////////////////////////////////////////////////////////////////////
//! @brief Size in bytes of the first-level page table.
#define MMU_L1_PAGE_TABLE_SIZE (16 * 1024)
//! @brief First-level 1MB section descriptor entry.
typedef union mmu_l1_section {
uint32_t u;
struct {
uint32_t id:2; //!< ID
uint32_t b:1; //!< Bufferable
uint32_t c:1; //!< Cacheable
uint32_t xn:1; //!< Execute-not
uint32_t domain:4; //!< Domain
uint32_t _impl_defined:1; //!< Implementation defined, should be zero.
uint32_t ap1_0:2; //!< Access permissions AP[1:0]
uint32_t tex:3; //!< TEX remap
uint32_t ap2:1; //!< Access permissions AP[2]
uint32_t s:1; //!< Shareable
uint32_t ng:1; //!< Not-global
uint32_t _zero:1; //!< Should be zero.
uint32_t ns:1; //!< Non-secure
uint32_t address:12; //!< Physical base address
};
} mmu_l1_section_t;
enum {
kMMU_L1_Section_ID = 2, //!< ID value for a 1MB section first-level entry.
kMMU_L1_Section_Address_Shift = 20 //!< Bit offset of the physical base address field.
};
////////////////////////////////////////////////////////////////////////////////
// Externs
////////////////////////////////////////////////////////////////////////////////
extern char __l1_page_table_start;
////////////////////////////////////////////////////////////////////////////////
// Code
////////////////////////////////////////////////////////////////////////////////
void mmu_enable()
{
// invalidate all tlb
arm_unified_tlb_invalidate();
// read SCTLR
uint32_t sctlr;
_ARM_MRC(15, 0, sctlr, 1, 0, 0);
// set MMU enable bit
sctlr |= BM_SCTLR_M;
// write modified SCTLR
_ARM_MCR(15, 0, sctlr, 1, 0, 0);
}
void mmu_disable()
{
// read current SCTLR
uint32_t sctlr;
_ARM_MRC(15, 0, sctlr, 1, 0, 0);
// clear MMU enable bit
sctlr &=~ BM_SCTLR_M;
// write modified SCTLR
_ARM_MCR(15, 0, sctlr, 1, 0, 0);
}
void mmu_init()
{
// Get the L1 page table base address.
uint32_t * table = (uint32_t *)&__l1_page_table_start;
uint32_t share_attr = kShareable;
// write table address to TTBR0
_ARM_MCR(15, 0, table, 2, 0, 0);
// set Client mode for all Domains
uint32_t dacr = 0x55555555;
_ARM_MCR(15, 0, dacr, 3, 0, 0); // MCR p15, 0, <Rd>, c3, c0, 0 ; Write DACR
// Clear the L1 table.
bzero(table, MMU_L1_PAGE_TABLE_SIZE);
// Create default mappings.
mmu_map_l1_range(0x00000000, 0x00000000, 0x00900000, kStronglyOrdered, kShareable, kRWAccess); // ROM and peripherals
mmu_map_l1_range(0x00900000, 0x00900000, 0x00100000, kStronglyOrdered, kShareable, kRWAccess); // OCRAM
mmu_map_l1_range(0x00a00000, 0x00a00000, 0x0f600000, kStronglyOrdered, kShareable, kRWAccess); // More peripherals
// Check whether SMP is enabled. If it is not, then we don't want to make SDRAM shareable.
uint32_t actlr = 0x0;
_ARM_MRC(15, 0, actlr, 1, 0, 1);
if (actlr & BM_ACTLR_SMP)
{
share_attr = kShareable;
}
else
{
share_attr = kNonshareable;
}
#if defined(CHIP_MX6DQ) || defined(CHIP_MX6SDL)
mmu_map_l1_range(0x10000000, 0x10000000, 0x80000000, kOuterInner_WB_WA, share_attr, kRWAccess); // 2GB DDR
#elif defined(CHIP_MX6SL)
mmu_map_l1_range(0x80000000, 0x80000000, 0x40000000, kOuterInner_WB_WA, share_attr, kRWAccess); // 1GB DDR
#else
#error Unknown chip type!
#endif
}
void mmu_map_l1_range(uint32_t pa, uint32_t va, uint32_t length, mmu_memory_type_t memoryType, mmu_shareability_t isShareable, mmu_access_t access)
{
register mmu_l1_section_t entry;
entry.u = 0;
// Set constant attributes.
entry.id = kMMU_L1_Section_ID;
entry.xn = 0; // Allow execution
entry.domain = 0; // Domain 0
entry.ng = 0; // Global
entry.ns = 0; // Secure
// Set attributes based on the selected memory type.
switch (memoryType)
{
case kStronglyOrdered:
entry.c = 0;
entry.b = 0;
entry.tex = 0;
entry.s = 1; // Ignored
break;
case kDevice:
if (isShareable)
{
entry.c = 0;
entry.b = 1;
entry.tex = 0;
entry.s = 1; // Ignored
}
else
{
entry.c = 0;
entry.b = 0;
entry.tex = 2;
entry.s = 0; // Ignored
}
break;
case kOuterInner_WB_WA:
entry.c = 1;
entry.b = 1;
entry.tex = 1;
entry.s = isShareable;
break;
case kOuterInner_WT:
entry.c = 1;
entry.b = 0;
entry.tex = 0;
entry.s = isShareable;
break;
case kNoncacheable:
entry.c = 0;
entry.b = 0;
entry.tex = 1;
entry.s = isShareable;
break;
}
// Set attributes from specified access mode.
switch (access)
{
case kNoAccess:
entry.ap2 = 0;
entry.ap1_0 = 0;
break;
case kROAccess:
entry.ap2 = 1;
entry.ap1_0 = 3;
break;
case kRWAccess:
entry.ap2 = 0;
entry.ap1_0 = 3;
break;
}
// Get the L1 page table base address.
uint32_t * table = (uint32_t *)&__l1_page_table_start;
// Convert addresses to 12-bit bases.
uint32_t vbase = va >> kMMU_L1_Section_Address_Shift;
uint32_t pbase = pa >> kMMU_L1_Section_Address_Shift;
uint32_t entries = length >> kMMU_L1_Section_Address_Shift;
// Fill in L1 page table entries.
for (; entries > 0; ++pbase, ++vbase, --entries)
{
entry.address = pbase;
table[vbase] = entry.u;
}
// Invalidate TLB
arm_unified_tlb_invalidate();
}
bool mmu_virtual_to_physical(uint32_t virtualAddress, uint32_t * physicalAddress)
{
uint32_t pa = 0;
// VA to PA translation with privileged read permission check
_ARM_MCR(15, 0, virtualAddress & 0xfffffc00, 7, 8, 0);
// Read PA register
_ARM_MRC(15, 0, pa, 7, 4, 0);
// First bit of returned value is Result of conversion (0 is successful translation)
if (pa & 1)
{
// We can try write permission also
// VA to PA translation with privileged write permission check
_ARM_MCR(15, 0, virtualAddress & 0xfffffc00, 7, 8, 1);
// Read PA register
_ARM_MRC(15, 0, pa, 7, 4, 0);
// First bit of returned value is Result of conversion (0 is successful translation)
if (pa & 1)
{
return false;
}
}
if (physicalAddress)
{
// complete address returning base + offset
pa = (pa & 0xfffff000) | (virtualAddress & 0x00000fff);
*physicalAddress = pa;
}
return true;
}
////////////////////////////////////////////////////////////////////////////////
// EOF
////////////////////////////////////////////////////////////////////////////////
@@ -1,157 +0,0 @@
/*
* Copyright (c) 2008-2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 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 HOLDER 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.
*/
//! @addtogroup diag_mmu
//! @{
/*!
* @file mmu.h
* @brief System memory arrangement.
*/
#ifndef _MMU_H_
#define _MMU_H_
#include "sdk.h"
////////////////////////////////////////////////////////////////////////////////
// Definitions
////////////////////////////////////////////////////////////////////////////////
//! @brief Memory region attributes.
typedef enum _mmu_memory_type
{
kStronglyOrdered,
kDevice,
kOuterInner_WB_WA,
kOuterInner_WT,
kNoncacheable,
} mmu_memory_type_t;
//! @brief Memory region shareability options.
typedef enum _mmu_shareability
{
kShareable = 1,
kNonshareable = 0
} mmu_shareability_t;
//! @brief Access permissions for a memory region.
typedef enum _mmu_access
{
kNoAccess,
kROAccess,
kRWAccess
} mmu_access_t;
////////////////////////////////////////////////////////////////////////////////
// Prototypes
////////////////////////////////////////////////////////////////////////////////
#if defined(__cplusplus)
extern "C" {
#endif
/*!
* @brief Enable the MMU.
*
* The L1 page tables and MMU settings must have already been configured by
* calling mmu_init() before the MMU is enabled.
*/
void mmu_enable();
/*!
* @brief Disable the MMU.
*/
void mmu_disable();
/*!
* @brief Set up the default first-level page table.
*
* Initializes the L1 page table with the following regions:
* - 0x00000000...0x00900000 : ROM and peripherals, strongly-ordered
* - 0x00900000...0x00a00000 : OCRAM, strongly-ordered
* - For MX6DQ or MX6SDL: 0x10000000...0x90000000 : DDR, normal, outer inner, write-back, write-allocate
* - For MX6SL: 0x80000000...0xc0000000 : DDR, normal, outer inner, write-back, write-allocate
*
* If the CPU is participating in SMP, then the DDR regions are made shareable. Otherwise they
* are marked as non-shareable.
*
* The TTBR0 register is set to the base of the L1 table.
*
* All memory domains are configured to allow client access. However, note that only domain 0 is
* used by mmu_map_l1_range().
*/
void mmu_init();
/*!
* @brief Maps a range of memory in the first-level page table.
*
* Entries in the first-level page table are filled in for the range of virtual addresses
* starting at @a va and continuing for @a length bytes. These virtual addreses are mapped
* to the physical addresses starting at @a pa and continuing for @a length bytes. All table
* entries for the range of mapped memory have the same attributes, which are selected with
* the @a memoryType, @a isShareable, and @a access parameters.
*
* @param pa The base physical address of the range to which the virtual address will be mapped.
* @param va The base virtual address of the range.
* @param length The size of the range to be mapped, in bytes. This value must be divisible by 1MB.
* @param memoryType The type of the memory region. This controls caching, buffering, ordering of
* memory accesses, and other attributes of the region.
* @param isShareable The shareability of the physical memory. Ignored for strongly-ordered memory.
* @param access Access permissions.
*/
void mmu_map_l1_range(uint32_t pa, uint32_t va, uint32_t length, mmu_memory_type_t memoryType, mmu_shareability_t isShareable, mmu_access_t access);
/*!
* @brief Convert virtual address to physical.
*
* First attempts a priviledged read translation for the current security mode. If that fails,
* a priviledged write translation, also for the current security mode, is attempted. If this
* second attempt at translation fails, then false will be returned.
*
* @param virtualAddress Virtual address to convert to a physical address.
* @param[out] physicalAddress This parameter is filled in with the physical address corresponding
* to the virtual address passed in @a virtualAddress.
* @retval true The address returned through @a physicalAddress is valid.
* @retval false The conversion failed for some reason.
*/
bool mmu_virtual_to_physical(uint32_t virtualAddress, uint32_t * physicalAddress);
#if defined(__cplusplus)
}
#endif
//! @}
#endif // _MMU_H_
////////////////////////////////////////////////////////////////////////////////
// EOF
////////////////////////////////////////////////////////////////////////////////
@@ -0,0 +1,3 @@
SRC_FILES := ivt.c dcd.c imx6q_lowlevel_init.S cortexA9.S
include $(KERNEL_ROOT)/compiler.mk
@@ -0,0 +1,20 @@
export CROSS_COMPILE ?= arm-none-eabi-
export DEVICE = -march=armv7-a -mtune=cortex-a9 -mfpu=vfpv3-d16 -ftree-vectorize -ffast-math -mfloat-abi=softfp
export CFLAGS := $(DEVICE) -Wall -O0 -g -gdwarf-2
export AFLAGS := -c $(DEVICE) -x assembler-with-cpp -D__ASSEMBLY__ -gdwarf-2
# export LFLAGS := $(DEVICE) -Wl,-Map=XiZi-imx6q-sabrelite.map,-cref,-u,_boot_start -T $(KERNEL_ROOT)/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_nxp_imx6q_sabrelite/nxp_imx6q_sabrelite.lds
export LFLAGS := $(DEVICE) --specs=nosys.specs -Wl,-Map=XiZi-imx6q-sabrelite.map,-cref,-u,_boot_start -T $(KERNEL_ROOT)/hardkernel/arch/arm/armv7-a/cortex-a9/preboot_for_nxp_imx6q_sabrelite/nxp_imx6q_sabrelite.lds
export CXXFLAGS :=
ifeq ($(CONFIG_LIB_MUSLLIB), y)
export LFLAGS += -nostdlib -nostdinc -fno-builtin -nodefaultlibs
export LIBCC := -lgcc
export LINK_MUSLLIB := $(KERNEL_ROOT)/lib/musllib/libmusl.a
endif
export DEFINES := -DHAVE_CCONFIG_H -DCHIP_MX6DQ
export USING_NEWLIB =1
export USING_VFS = 1
export ARCH = arm
export ARCH_ARMV = armv7-a
@@ -119,6 +119,7 @@ get_arm_private_peripheral_base:
@ Get base address of private perpherial space
mrc p15, 4, r0, c15, c0, 0 @ Read periph base address
@ mov r0, #0x00A00000
bx lr
.endfunc @get_arm_private_peripheral_base()@
@@ -201,7 +202,8 @@ arm_branch_target_cache_invalidate_is:
.func scu_enable
scu_enable:
mrc p15, 4, r0, c15, c0, 0 @ Read periph base address
@ mrc p15, 4, r0, c15, c0, 0 @ Read periph base address
mov r0, #0x00A00000
ldr r1, [r0, #0x0] @ Read the SCU Control Register
orr r1, r1, #0x1 @ Set bit 0 (The Enable bit)
@@ -255,7 +257,8 @@ scu_leave_smp:
.func scu_get_cpus_in_smp
scu_get_cpus_in_smp:
mrc p15, 4, r0, c15, c0, 0 @ Read periph base address
@ mrc p15, 4, r0, c15, c0, 0 @ Read periph base address
mov r0, #0x00A00000
ldr r0, [r0, #0x004] @ Read SCU Configuration register
mov r0, r0, lsr #4 @ Bits 7:4 gives the cores in SMP mode, shift then mask
@@ -0,0 +1,191 @@
/*
* Copyright (c) 2010-2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 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 HOLDER 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.
*/
/**
* @file dcd.c
* @brief device configuration data function for imx6q
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023.08.25
*/
/*************************************************
File name: dcd.c
Description: imx6q device configuration data
Others:
History:
1. Date: 2023-08-28
Author: AIIT XUOS Lab
Modification:
1. first version
*************************************************/
#include <hab_defines.h>
#include <soc_memory_map.h>
#include <iomux_register.h>
#include <registers.h>
//! @brief dcd data, list of (register, value) pairs to initialize ddr
uint8_t input_dcd[] __attribute__ ((section (".dcd_data")))= {
/*Use default DDR frequency: 528MHz*/
/* configure the IOMUX for the DDR3 interface */
//DATA STROBE:
DCD_DATA(IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL, 0x00020000),
DCD_DATA(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0, 0x00000030),
DCD_DATA(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1, 0x00000030),
DCD_DATA(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS2, 0x00000030),
DCD_DATA(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS3, 0x00000030),
DCD_DATA(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS4, 0x00000030),
DCD_DATA(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS5, 0x00000030),
DCD_DATA(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS6, 0x00000030),
DCD_DATA(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS7, 0x00000030),
//DATA
DCD_DATA(IOMUXC_SW_PAD_CTL_GRP_DDRMODE, 0x00020000),
DCD_DATA(IOMUXC_SW_PAD_CTL_GRP_B0DS, 0x00000030),
DCD_DATA(IOMUXC_SW_PAD_CTL_GRP_B1DS, 0x00000030),
DCD_DATA(IOMUXC_SW_PAD_CTL_GRP_B2DS, 0x00000030),
DCD_DATA(IOMUXC_SW_PAD_CTL_GRP_B3DS, 0x00000030),
DCD_DATA(IOMUXC_SW_PAD_CTL_GRP_B4DS, 0x00000030),
DCD_DATA(IOMUXC_SW_PAD_CTL_GRP_B5DS, 0x00000030),
DCD_DATA(IOMUXC_SW_PAD_CTL_GRP_B6DS, 0x00000030),
DCD_DATA(IOMUXC_SW_PAD_CTL_GRP_B7DS, 0x00000030),
DCD_DATA(IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM0, 0x00020030),
DCD_DATA(IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM1, 0x00020030),
DCD_DATA(IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM2, 0x00020030),
DCD_DATA(IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM3, 0x00020030),
DCD_DATA(IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM4, 0x00020030),
DCD_DATA(IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM5, 0x00020030),
DCD_DATA(IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM6, 0x00020030),
DCD_DATA(IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM7, 0x00020030),
//ADDRESS:
DCD_DATA(IOMUXC_SW_PAD_CTL_PAD_DRAM_CAS, 0x00020030),
DCD_DATA(IOMUXC_SW_PAD_CTL_PAD_DRAM_RAS, 0x00020030),
DCD_DATA(IOMUXC_SW_PAD_CTL_GRP_ADDDS, 0x00000030),
//CLOCK:
DCD_DATA(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_0, 0x00020030),
DCD_DATA(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_1, 0x00020030),
//CONTROL:
DCD_DATA(IOMUXC_SW_PAD_CTL_PAD_DRAM_RESET, 0x00020030),
DCD_DATA(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCKE0, 0x00003000),
DCD_DATA(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCKE1, 0x00003000),
DCD_DATA(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDBA2, 0x00000000),
DCD_DATA(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT0, 0x00003030),
DCD_DATA(IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT1, 0x00003030),
DCD_DATA(IOMUXC_SW_PAD_CTL_GRP_CTLDS, 0x00000030),
//DDR IO TYPE:
DCD_DATA(IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE, 0x000c0000),
DCD_DATA(IOMUXC_SW_PAD_CTL_GRP_DDRPKE, 0x00000000),
//read data bit delay: (3 is the reccommended default value)
DCD_DATA(MMDC_P0_BASE_ADDR + MPRDDQBY0DL_OFFSET, 0x33333333),
DCD_DATA(MMDC_P0_BASE_ADDR + MPRDDQBY1DL_OFFSET, 0x33333333),
DCD_DATA(MMDC_P0_BASE_ADDR + MPRDDQBY2DL_OFFSET, 0x33333333),
DCD_DATA(MMDC_P0_BASE_ADDR + MPRDDQBY3DL_OFFSET, 0x33333333),
DCD_DATA(MMDC_P1_BASE_ADDR + MPRDDQBY0DL_OFFSET, 0x33333333),
DCD_DATA(MMDC_P1_BASE_ADDR + MPRDDQBY1DL_OFFSET, 0x33333333),
DCD_DATA(MMDC_P1_BASE_ADDR + MPRDDQBY2DL_OFFSET, 0x33333333),
DCD_DATA(MMDC_P1_BASE_ADDR + MPRDDQBY3DL_OFFSET, 0x33333333),
// reset the MMDC and disable the chip selects.
DCD_DATA(MMDC_P0_BASE_ADDR + MDMISC_OFFSET, 0x00081740),
/* configure the MMDC */
//DDR3, 528MHz, 64-bit mode, only MMDC0 is initiated:
DCD_DATA(MMDC_P0_BASE_ADDR + MDSCR_OFFSET, 0x00008000),
DCD_DATA(MMDC_P0_BASE_ADDR + MDCFG0_OFFSET, 0x555A7975),
DCD_DATA(MMDC_P0_BASE_ADDR + MDCFG1_OFFSET, 0xFF538E64),
DCD_DATA(MMDC_P0_BASE_ADDR + MDCFG2_OFFSET, 0x01FF00DB),
DCD_DATA(MMDC_P0_BASE_ADDR + MDRWD_OFFSET, 0x000026D2),
DCD_DATA(MMDC_P0_BASE_ADDR + MDOR_OFFSET, 0x005B0E21),
DCD_DATA(MMDC_P0_BASE_ADDR + MDOTC_OFFSET, 0x09444040),
DCD_DATA(MMDC_P0_BASE_ADDR + MDPDC_OFFSET, 0x00025576),
DCD_DATA(MMDC_P0_BASE_ADDR + MDASP_OFFSET, 0x00000027),
DCD_DATA(MMDC_P0_BASE_ADDR + MDCTL_OFFSET, 0x831A0000),
/* Initialize 2GB DDR3 - Micron MT41J128M */
//MR2:
DCD_DATA(MMDC_P0_BASE_ADDR + MDSCR_OFFSET, 0x04088032),
DCD_DATA(MMDC_P0_BASE_ADDR + MDSCR_OFFSET, 0x0408803A),
//MR3:
DCD_DATA(MMDC_P0_BASE_ADDR + MDSCR_OFFSET, 0x00008033),
DCD_DATA(MMDC_P0_BASE_ADDR + MDSCR_OFFSET, 0x0000803B),
//MR1:
DCD_DATA(MMDC_P0_BASE_ADDR + MDSCR_OFFSET, 0x00428031),
DCD_DATA(MMDC_P0_BASE_ADDR + MDSCR_OFFSET, 0x00428039),
//MR0:
DCD_DATA(MMDC_P0_BASE_ADDR + MDSCR_OFFSET, 0x09408030),
DCD_DATA(MMDC_P0_BASE_ADDR + MDSCR_OFFSET, 0x09408038),
//DDR device ZQ calibration:
DCD_DATA(MMDC_P0_BASE_ADDR + MDSCR_OFFSET, 0x04008040),
DCD_DATA(MMDC_P0_BASE_ADDR + MDSCR_OFFSET, 0x04008048),
/* DDR3 calibrations */
//ZQ:
DCD_DATA(MMDC_P0_BASE_ADDR + MPZQHWCTRL_OFFSET, 0xA1380003),
DCD_DATA(MMDC_P1_BASE_ADDR + MPZQHWCTRL_OFFSET, 0xA1380003),
//final DDR setup, before operation start:
DCD_DATA(MMDC_P0_BASE_ADDR + MDREF_OFFSET, 0x00005800),
DCD_DATA(MMDC_P0_BASE_ADDR + MPODTCTRL_OFFSET, 0x00000007),
DCD_DATA(MMDC_P1_BASE_ADDR + MPODTCTRL_OFFSET, 0x00000007),
//Read DQS Gating calibration:
DCD_DATA(MMDC_P0_BASE_ADDR + MPDGCTRL0_OFFSET, 0x42720306),
DCD_DATA(MMDC_P0_BASE_ADDR + MPDGCTRL1_OFFSET, 0x026F0266),
DCD_DATA(MMDC_P1_BASE_ADDR + MPDGCTRL0_OFFSET, 0x4273030A),
DCD_DATA(MMDC_P1_BASE_ADDR + MPDGCTRL1_OFFSET, 0x02740240),
//Read calibration:
DCD_DATA(MMDC_P0_BASE_ADDR + MPRDDLCTL_OFFSET, 0x45393B3E),
DCD_DATA(MMDC_P1_BASE_ADDR + MPRDDLCTL_OFFSET, 0x403A3747),
//Write calibration:
DCD_DATA(MMDC_P0_BASE_ADDR + MPWRDLCTL_OFFSET, 0x40434541),
DCD_DATA(MMDC_P1_BASE_ADDR + MPWRDLCTL_OFFSET, 0x473E4A3B),
//write leveling:
DCD_DATA(MMDC_P0_BASE_ADDR + MPWLDECTRL0_OFFSET, 0x0011000E),
DCD_DATA(MMDC_P0_BASE_ADDR + MPWLDECTRL1_OFFSET, 0x000E001B),
DCD_DATA(MMDC_P1_BASE_ADDR + MPWLDECTRL0_OFFSET, 0x00190015),
DCD_DATA(MMDC_P1_BASE_ADDR + MPWLDECTRL1_OFFSET, 0x00070018),
//complete calibrations by forcing measurement
DCD_DATA(MMDC_P0_BASE_ADDR + MPMUR0_OFFSET, 0x00000800),
DCD_DATA(MMDC_P1_BASE_ADDR + MPMUR0_OFFSET, 0x00000800),
/* Initialize 2GB DDR3 - Micron MT41J128M */
DCD_DATA(MMDC_P0_BASE_ADDR + MDSCR_OFFSET, 0x00000000),
//final DDR setup, before operation start:
DCD_DATA(MMDC_P0_BASE_ADDR + MAPSR_OFFSET, 0x00011006),
};
//! @brief HAB command write data header, with tag,
//! size of dcd data with hdr,
//! parameter field (size of register value and flag)
uint8_t input_dcd_wrt_cmd[] __attribute__ ((section (".dcd_wrt_cmd")))= {
HAB_CMD_WRT_DAT,
EXPAND_UINT16(sizeof(input_dcd) + HDR_BYTES),
WRT_DAT_PAR(0, HAB_DATA_WIDTH_WORD) //!< flag 0, width 4
};
//! @brief HAB dcd header with dcd tag, size of entire dcd and version.
uint8_t input_dcd_hdr[] __attribute__ ((section (".dcd_hdr")))= {
HAB_TAG_DCD,
EXPAND_UINT16(sizeof(input_dcd) + sizeof(input_dcd_wrt_cmd) + HDR_BYTES),
HAB_VER(4,0)
};
@@ -0,0 +1,211 @@
/*
* Copyright (C) 2011 Freescale Semiconductor, Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
*/
/**
* @file imx6q_lowlevel_init.S
* @brief support imx6q lowlevel init function
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023.08.15
*/
/*************************************************
File name: imx6q_lowlevel_init.S
Description: imx6q board init function, , reference from board/freescale/mx6q_sabrelite/lowlevel_init.S
Others:
History:
1. Date: 2023-08-28
Author: AIIT XUOS Lab
Modification:
1. first version
*************************************************/
#include <soc_memory_map.h>
.global CpuInitCrit
CpuInitCrit:
/*
* Invalidate L1 I/D
*/
mov r0, #0 @ set up for MCR
mcr p15, 0, r0, c8, c7, 0 @ invalidate TLBs
mcr p15, 0, r0, c7, c5, 0 @ invalidate icache
/*
* disable MMU stuff and caches
*/
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00002000 @ clear bits 13 (--V-)
bic r0, r0, #0x00000007 @ clear bits 2:0 (-CAM)
orr r0, r0, #0x00000002 @ set bit 1 (--A-) Align
orr r0, r0, #0x00000800 @ set bit 12 (Z---) BTB
mcr p15, 0, r0, c1, c0, 0
/*
* Jump to board specific initialization...
* The Mask ROM will have already initialized
* basic memory. Go here to bump up clock rate and handle
* wake up conditions.
*/
mov ip, lr @ persevere link reg across call
bl lowlevel_init @ go setup pll,mux,memory
mov lr, ip @ restore link
mov pc, lr @ back to my caller
/*
Disable L2Cache because ROM turn it on when uboot use plug-in.
If L2Cache is on default, there are cache coherence problem if kernel have
not config L2Cache.
*/
.macro init_l2cc
ldr r1, =0xa02000
ldr r0, =0x0
str r0, [r1, #0x100]
.endm /* init_l2cc */
/* invalidate the D-CACHE */
.macro inv_dcache
mov r0,#0
mcr p15,2,r0,c0,c0,0 /* cache size selection register, select dcache */
mrc p15,1,r0,c0,c0,0 /* cache size ID register */
mov r0,r0,ASR #13
ldr r3,=0xfff
and r0,r0,r3
cmp r0,#0x7f
moveq r6,#0x1000
beq size_done
cmp r0,#0xff
moveq r6,#0x2000
movne r6,#0x4000
size_done:
mov r2,#0
mov r3,#0x40000000
mov r4,#0x80000000
mov r5,#0xc0000000
d_inv_loop:
mcr p15,0,r2,c7,c6,2 /* invalidate dcache by set / way */
mcr p15,0,r3,c7,c6,2 /* invalidate dcache by set / way */
mcr p15,0,r4,c7,c6,2 /* invalidate dcache by set / way */
mcr p15,0,r5,c7,c6,2 /* invalidate dcache by set / way */
add r2,r2,#0x20
add r3,r3,#0x20
add r4,r4,#0x20
add r5,r5,#0x20
cmp r2,r6
bne d_inv_loop
.endm
/* AIPS setup - Only setup MPROTx registers.
* The PACR default values are good.*/
.macro init_aips
/*
* Set all MPROTx to be non-bufferable, trusted for R/W,
* not forced to user-mode.
*/
ldr r0, =AIPS1_ON_BASE_ADDR
ldr r1, =0x77777777
str r1, [r0, #0x0]
str r1, [r0, #0x4]
ldr r1, =0x0
str r1, [r0, #0x40]
str r1, [r0, #0x44]
str r1, [r0, #0x48]
str r1, [r0, #0x4C]
str r1, [r0, #0x50]
ldr r0, =AIPS2_ON_BASE_ADDR
ldr r1, =0x77777777
str r1, [r0, #0x0]
str r1, [r0, #0x4]
ldr r1, =0x0
str r1, [r0, #0x40]
str r1, [r0, #0x44]
str r1, [r0, #0x48]
str r1, [r0, #0x4C]
str r1, [r0, #0x50]
.endm /* init_aips */
.macro setup_pll pll, freq
.endm
.macro init_clock
/* PLL1, PLL2, and PLL3 are enabled by ROM */
#ifdef CONFIG_PLL3
/* enable PLL3 for UART */
ldr r0, ANATOP_BASE_ADDR_W
/* power up PLL */
ldr r1, [r0, #ANATOP_USB1]
orr r1, r1, #0x1000
str r1, [r0, #ANATOP_USB1]
/* enable PLL */
ldr r1, [r0, #ANATOP_USB1]
orr r1, r1, #0x2000
str r1, [r0, #ANATOP_USB1]
/* wait PLL lock */
100:
ldr r1, [r0, #ANATOP_USB1]
mov r1, r1, lsr #31
cmp r1, #0x1
bne 100b
/* clear bypass bit */
ldr r1, [r0, #ANATOP_USB1]
and r1, r1, #0xfffeffff
str r1, [r0, #ANATOP_USB1]
#endif
/* Restore the default values in the Gate registers */
ldr r1, =0xFFFFFFFF
ldr r0, CCM_BASE_ADDR_W
str r1, [r0, #CLKCTL_CCGR0]
str r1, [r0, #CLKCTL_CCGR1]
str r1, [r0, #CLKCTL_CCGR2]
str r1, [r0, #CLKCTL_CCGR3]
str r1, [r0, #CLKCTL_CCGR4]
str r1, [r0, #CLKCTL_CCGR5]
str r1, [r0, #CLKCTL_CCGR6]
str r1, [r0, #CLKCTL_CCGR7]
.endm
.section ".text.init", "x"
.globl lowlevel_init
lowlevel_init:
inv_dcache
init_l2cc
init_aips
init_clock
mov pc, lr
/* Board level setting value */
ANATOP_BASE_ADDR_W: .word ANATOP_BASE_ADDR
CCM_BASE_ADDR_W: .word CCM_BASE_ADDR
@@ -43,18 +43,22 @@
//! @name Instruction macros
//@{
#define _ARM_NOP() asm volatile ("nop\n\t")
#define _ARM_WFI() asm volatile ("wfi\n\t")
#define _ARM_WFE() asm volatile ("wfe\n\t")
#define _ARM_SEV() asm volatile ("sev\n\t")
#define _ARM_DSB() asm volatile ("dsb\n\t")
#define _ARM_ISB() asm volatile ("isb\n\t")
#define NOP() __asm__ volatile("nop\n\t")
#define WFI() __asm__ volatile("wfi\n\t")
#define WFE() __asm__ volatile("wfe\n\t")
#define SEV() __asm__ volatile("sev\n\t")
#define DMB() __asm__ volatile("dmb\n\t")
#define DSB() __asm__ volatile("dsb\n\t")
#define ISB() __asm__ volatile("isb\n\t")
#define _ARM_MRC(coproc, opcode1, Rt, CRn, CRm, opcode2) \
asm volatile ("mrc p" #coproc ", " #opcode1 ", %[output], c" #CRn ", c" #CRm ", " #opcode2 "\n" : [output] "=r" (Rt))
#define _ARM_MCR(coproc, opcode1, Rt, CRn, CRm, opcode2) \
asm volatile ("mcr p" #coproc ", " #opcode1 ", %[input], c" #CRn ", c" #CRm ", " #opcode2 "\n" :: [input] "r" (Rt))
#define _ARM_MRC(coproc, opcode1, Rt, CRn, CRm, opcode2) \
asm volatile("mrc p" #coproc ", " #opcode1 ", %[output], c" #CRn ", c" #CRm ", " #opcode2 "\n" : [output] "=r"(Rt))
#define _ARM_MCR(coproc, opcode1, Rt, CRn, CRm, opcode2) \
asm volatile("mcr p" #coproc ", " #opcode1 ", %[input], c" #CRn ", c" #CRm ", " #opcode2 "\n" ::[input] "r"(Rt))
#define WriteReg(value, address) (*(volatile unsigned int*)(address) = (value))
#define ReadReg(address) (*(volatile unsigned int*)(address))
//@}
////////////////////////////////////////////////////////////////////////////////
@@ -80,12 +84,11 @@ void enable_neon_fpu(void);
void disable_strict_align_check(void);
//! @brief Get base address of private perpherial space.
//!
//!
//! @return The address of the ARM CPU's private peripherals.
uint32_t get_arm_private_peripheral_base(void);
// uint32_t get_arm_private_peripheral_base(void);
//@}
//! @name Data cache operations
//@{
@@ -0,0 +1,653 @@
/*
* Copyright (c) 2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 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 HOLDER 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.
*/
// File: iomux_register.h
#ifndef _IOMUX_REGISTER_H_
#define _IOMUX_REGISTER_H_
//
// IOMUXC_GPR*
//
// #define IOMUXC_GPR0 0x020E0000
// #define IOMUXC_GPR1 0x020E0004
// #define IOMUXC_GPR2 0x020E0008
// #define IOMUXC_GPR3 0x020E000C
// #define IOMUXC_GPR4 0x020E0010
// #define IOMUXC_GPR5 0x020E0014
// #define IOMUXC_GPR6 0x020E0018
// #define IOMUXC_GPR7 0x020E001C
// #define IOMUXC_GPR8 0x020E0020
// #define IOMUXC_GPR9 0x020E0024
// #define IOMUXC_GPR10 0x020E0028
// #define IOMUXC_GPR11 0x020E002C
// #define IOMUXC_GPR12 0x020E0030
// #define IOMUXC_GPR13 0x020E0034
// //
// // IOMUXC_OBSERVE_MUX_*
// //
// #define IOMUXC_OBSERVE_MUX_0 0x020E0038
// #define IOMUXC_OBSERVE_MUX_1 0x020E003C
// #define IOMUXC_OBSERVE_MUX_2 0x020E0040
// #define IOMUXC_OBSERVE_MUX_3 0x020E0044
// #define IOMUXC_OBSERVE_MUX_4 0x020E0048
// //
// // IOMUXC_SW_MUX_CTL_PAD_*
// //
// #define IOMUXC_SW_MUX_CTL_PAD_SD2_DAT1 0x020E004C
// #define IOMUXC_SW_MUX_CTL_PAD_SD2_DAT2 0x020E0050
// #define IOMUXC_SW_MUX_CTL_PAD_SD2_DAT0 0x020E0054
// #define IOMUXC_SW_MUX_CTL_PAD_RGMII_TXC 0x020E0058
// #define IOMUXC_SW_MUX_CTL_PAD_RGMII_TD0 0x020E005C
// #define IOMUXC_SW_MUX_CTL_PAD_RGMII_TD1 0x020E0060
// #define IOMUXC_SW_MUX_CTL_PAD_RGMII_TD2 0x020E0064
// #define IOMUXC_SW_MUX_CTL_PAD_RGMII_TD3 0x020E0068
// #define IOMUXC_SW_MUX_CTL_PAD_RGMII_RX_CTL 0x020E006C
// #define IOMUXC_SW_MUX_CTL_PAD_RGMII_RD0 0x020E0070
// #define IOMUXC_SW_MUX_CTL_PAD_RGMII_TX_CTL 0x020E0074
// #define IOMUXC_SW_MUX_CTL_PAD_RGMII_RD1 0x020E0078
// #define IOMUXC_SW_MUX_CTL_PAD_RGMII_RD2 0x020E007C
// #define IOMUXC_SW_MUX_CTL_PAD_RGMII_RD3 0x020E0080
// #define IOMUXC_SW_MUX_CTL_PAD_RGMII_RXC 0x020E0084
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_A25 0x020E0088
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_EB2 0x020E008C
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_D16 0x020E0090
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_D17 0x020E0094
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_D18 0x020E0098
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_D19 0x020E009C
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_D20 0x020E00A0
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_D21 0x020E00A4
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_D22 0x020E00A8
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_D23 0x020E00AC
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_EB3 0x020E00B0
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_D24 0x020E00B4
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_D25 0x020E00B8
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_D26 0x020E00BC
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_D27 0x020E00C0
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_D28 0x020E00C4
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_D29 0x020E00C8
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_D30 0x020E00CC
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_D31 0x020E00D0
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_A24 0x020E00D4
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_A23 0x020E00D8
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_A22 0x020E00DC
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_A21 0x020E00E0
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_A20 0x020E00E4
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_A19 0x020E00E8
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_A18 0x020E00EC
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_A17 0x020E00F0
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_A16 0x020E00F4
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_CS0 0x020E00F8
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_CS1 0x020E00FC
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_OE 0x020E0100
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_RW 0x020E0104
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_LBA 0x020E0108
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_EB0 0x020E010C
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_EB1 0x020E0110
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_DA0 0x020E0114
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_DA1 0x020E0118
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_DA2 0x020E011C
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_DA3 0x020E0120
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_DA4 0x020E0124
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_DA5 0x020E0128
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_DA6 0x020E012C
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_DA7 0x020E0130
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_DA8 0x020E0134
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_DA9 0x020E0138
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_DA10 0x020E013C
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_DA11 0x020E0140
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_DA12 0x020E0144
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_DA13 0x020E0148
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_DA14 0x020E014C
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_DA15 0x020E0150
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_WAIT 0x020E0154
// #define IOMUXC_SW_MUX_CTL_PAD_EIM_BCLK 0x020E0158
// #define IOMUXC_SW_MUX_CTL_PAD_DI0_DISP_CLK 0x020E015C
// #define IOMUXC_SW_MUX_CTL_PAD_DI0_PIN15 0x020E0160
// #define IOMUXC_SW_MUX_CTL_PAD_DI0_PIN2 0x020E0164
// #define IOMUXC_SW_MUX_CTL_PAD_DI0_PIN3 0x020E0168
// #define IOMUXC_SW_MUX_CTL_PAD_DI0_PIN4 0x020E016C
// #define IOMUXC_SW_MUX_CTL_PAD_DISP0_DAT0 0x020E0170
// #define IOMUXC_SW_MUX_CTL_PAD_DISP0_DAT1 0x020E0174
// #define IOMUXC_SW_MUX_CTL_PAD_DISP0_DAT2 0x020E0178
// #define IOMUXC_SW_MUX_CTL_PAD_DISP0_DAT3 0x020E017C
// #define IOMUXC_SW_MUX_CTL_PAD_DISP0_DAT4 0x020E0180
// #define IOMUXC_SW_MUX_CTL_PAD_DISP0_DAT5 0x020E0184
// #define IOMUXC_SW_MUX_CTL_PAD_DISP0_DAT6 0x020E0188
// #define IOMUXC_SW_MUX_CTL_PAD_DISP0_DAT7 0x020E018C
// #define IOMUXC_SW_MUX_CTL_PAD_DISP0_DAT8 0x020E0190
// #define IOMUXC_SW_MUX_CTL_PAD_DISP0_DAT9 0x020E0194
// #define IOMUXC_SW_MUX_CTL_PAD_DISP0_DAT10 0x020E0198
// #define IOMUXC_SW_MUX_CTL_PAD_DISP0_DAT11 0x020E019C
// #define IOMUXC_SW_MUX_CTL_PAD_DISP0_DAT12 0x020E01A0
// #define IOMUXC_SW_MUX_CTL_PAD_DISP0_DAT13 0x020E01A4
// #define IOMUXC_SW_MUX_CTL_PAD_DISP0_DAT14 0x020E01A8
// #define IOMUXC_SW_MUX_CTL_PAD_DISP0_DAT15 0x020E01AC
// #define IOMUXC_SW_MUX_CTL_PAD_DISP0_DAT16 0x020E01B0
// #define IOMUXC_SW_MUX_CTL_PAD_DISP0_DAT17 0x020E01B4
// #define IOMUXC_SW_MUX_CTL_PAD_DISP0_DAT18 0x020E01B8
// #define IOMUXC_SW_MUX_CTL_PAD_DISP0_DAT19 0x020E01BC
// #define IOMUXC_SW_MUX_CTL_PAD_DISP0_DAT20 0x020E01C0
// #define IOMUXC_SW_MUX_CTL_PAD_DISP0_DAT21 0x020E01C4
// #define IOMUXC_SW_MUX_CTL_PAD_DISP0_DAT22 0x020E01C8
// #define IOMUXC_SW_MUX_CTL_PAD_DISP0_DAT23 0x020E01CC
// #define IOMUXC_SW_MUX_CTL_PAD_ENET_MDIO 0x020E01D0
// #define IOMUXC_SW_MUX_CTL_PAD_ENET_REF_CLK 0x020E01D4
// #define IOMUXC_SW_MUX_CTL_PAD_ENET_RX_ER 0x020E01D8
// #define IOMUXC_SW_MUX_CTL_PAD_ENET_CRS_DV 0x020E01DC
// #define IOMUXC_SW_MUX_CTL_PAD_ENET_RXD1 0x020E01E0
// #define IOMUXC_SW_MUX_CTL_PAD_ENET_RXD0 0x020E01E4
// #define IOMUXC_SW_MUX_CTL_PAD_ENET_TX_EN 0x020E01E8
// #define IOMUXC_SW_MUX_CTL_PAD_ENET_TXD1 0x020E01EC
// #define IOMUXC_SW_MUX_CTL_PAD_ENET_TXD0 0x020E01F0
// #define IOMUXC_SW_MUX_CTL_PAD_ENET_MDC 0x020E01F4
// #define IOMUXC_SW_MUX_CTL_PAD_KEY_COL0 0x020E01F8
// #define IOMUXC_SW_MUX_CTL_PAD_KEY_ROW0 0x020E01FC
// #define IOMUXC_SW_MUX_CTL_PAD_KEY_COL1 0x020E0200
// #define IOMUXC_SW_MUX_CTL_PAD_KEY_ROW1 0x020E0204
// #define IOMUXC_SW_MUX_CTL_PAD_KEY_COL2 0x020E0208
// #define IOMUXC_SW_MUX_CTL_PAD_KEY_ROW2 0x020E020C
// #define IOMUXC_SW_MUX_CTL_PAD_KEY_COL3 0x020E0210
// #define IOMUXC_SW_MUX_CTL_PAD_KEY_ROW3 0x020E0214
// #define IOMUXC_SW_MUX_CTL_PAD_KEY_COL4 0x020E0218
// #define IOMUXC_SW_MUX_CTL_PAD_KEY_ROW4 0x020E021C
// #define IOMUXC_SW_MUX_CTL_PAD_GPIO_0 0x020E0220
// #define IOMUXC_SW_MUX_CTL_PAD_GPIO_1 0x020E0224
// #define IOMUXC_SW_MUX_CTL_PAD_GPIO_9 0x020E0228
// #define IOMUXC_SW_MUX_CTL_PAD_GPIO_3 0x020E022C
// #define IOMUXC_SW_MUX_CTL_PAD_GPIO_6 0x020E0230
// #define IOMUXC_SW_MUX_CTL_PAD_GPIO_2 0x020E0234
// #define IOMUXC_SW_MUX_CTL_PAD_GPIO_4 0x020E0238
// #define IOMUXC_SW_MUX_CTL_PAD_GPIO_5 0x020E023C
// #define IOMUXC_SW_MUX_CTL_PAD_GPIO_7 0x020E0240
// #define IOMUXC_SW_MUX_CTL_PAD_GPIO_8 0x020E0244
// #define IOMUXC_SW_MUX_CTL_PAD_GPIO_16 0x020E0248
// #define IOMUXC_SW_MUX_CTL_PAD_GPIO_17 0x020E024C
// #define IOMUXC_SW_MUX_CTL_PAD_GPIO_18 0x020E0250
// #define IOMUXC_SW_MUX_CTL_PAD_GPIO_19 0x020E0254
// #define IOMUXC_SW_MUX_CTL_PAD_CSI0_PIXCLK 0x020E0258
// #define IOMUXC_SW_MUX_CTL_PAD_CSI0_MCLK 0x020E025C
// #define IOMUXC_SW_MUX_CTL_PAD_CSI0_DATA_EN 0x020E0260
// #define IOMUXC_SW_MUX_CTL_PAD_CSI0_VSYNC 0x020E0264
// #define IOMUXC_SW_MUX_CTL_PAD_CSI0_DAT4 0x020E0268
// #define IOMUXC_SW_MUX_CTL_PAD_CSI0_DAT5 0x020E026C
// #define IOMUXC_SW_MUX_CTL_PAD_CSI0_DAT6 0x020E0270
// #define IOMUXC_SW_MUX_CTL_PAD_CSI0_DAT7 0x020E0274
// #define IOMUXC_SW_MUX_CTL_PAD_CSI0_DAT8 0x020E0278
// #define IOMUXC_SW_MUX_CTL_PAD_CSI0_DAT9 0x020E027C
// #define IOMUXC_SW_MUX_CTL_PAD_CSI0_DAT10 0x020E0280
// #define IOMUXC_SW_MUX_CTL_PAD_CSI0_DAT11 0x020E0284
// #define IOMUXC_SW_MUX_CTL_PAD_CSI0_DAT12 0x020E0288
// #define IOMUXC_SW_MUX_CTL_PAD_CSI0_DAT13 0x020E028C
// #define IOMUXC_SW_MUX_CTL_PAD_CSI0_DAT14 0x020E0290
// #define IOMUXC_SW_MUX_CTL_PAD_CSI0_DAT15 0x020E0294
// #define IOMUXC_SW_MUX_CTL_PAD_CSI0_DAT16 0x020E0298
// #define IOMUXC_SW_MUX_CTL_PAD_CSI0_DAT17 0x020E029C
// #define IOMUXC_SW_MUX_CTL_PAD_CSI0_DAT18 0x020E02A0
// #define IOMUXC_SW_MUX_CTL_PAD_CSI0_DAT19 0x020E02A4
// #define IOMUXC_SW_MUX_CTL_PAD_SD3_DAT7 0x020E02A8
// #define IOMUXC_SW_MUX_CTL_PAD_SD3_DAT6 0x020E02AC
// #define IOMUXC_SW_MUX_CTL_PAD_SD3_DAT5 0x020E02B0
// #define IOMUXC_SW_MUX_CTL_PAD_SD3_DAT4 0x020E02B4
// #define IOMUXC_SW_MUX_CTL_PAD_SD3_CMD 0x020E02B8
// #define IOMUXC_SW_MUX_CTL_PAD_SD3_CLK 0x020E02BC
// #define IOMUXC_SW_MUX_CTL_PAD_SD3_DAT0 0x020E02C0
// #define IOMUXC_SW_MUX_CTL_PAD_SD3_DAT1 0x020E02C4
// #define IOMUXC_SW_MUX_CTL_PAD_SD3_DAT2 0x020E02C8
// #define IOMUXC_SW_MUX_CTL_PAD_SD3_DAT3 0x020E02CC
// #define IOMUXC_SW_MUX_CTL_PAD_SD3_RST 0x020E02D0
// #define IOMUXC_SW_MUX_CTL_PAD_NANDF_CLE 0x020E02D4
// #define IOMUXC_SW_MUX_CTL_PAD_NANDF_ALE 0x020E02D8
// #define IOMUXC_SW_MUX_CTL_PAD_NANDF_WP_B 0x020E02DC
// #define IOMUXC_SW_MUX_CTL_PAD_NANDF_RB0 0x020E02E0
// #define IOMUXC_SW_MUX_CTL_PAD_NANDF_CS0 0x020E02E4
// #define IOMUXC_SW_MUX_CTL_PAD_NANDF_CS1 0x020E02E8
// #define IOMUXC_SW_MUX_CTL_PAD_NANDF_CS2 0x020E02EC
// #define IOMUXC_SW_MUX_CTL_PAD_NANDF_CS3 0x020E02F0
// #define IOMUXC_SW_MUX_CTL_PAD_SD4_CMD 0x020E02F4
// #define IOMUXC_SW_MUX_CTL_PAD_SD4_CLK 0x020E02F8
// #define IOMUXC_SW_MUX_CTL_PAD_NANDF_D0 0x020E02FC
// #define IOMUXC_SW_MUX_CTL_PAD_NANDF_D1 0x020E0300
// #define IOMUXC_SW_MUX_CTL_PAD_NANDF_D2 0x020E0304
// #define IOMUXC_SW_MUX_CTL_PAD_NANDF_D3 0x020E0308
// #define IOMUXC_SW_MUX_CTL_PAD_NANDF_D4 0x020E030C
// #define IOMUXC_SW_MUX_CTL_PAD_NANDF_D5 0x020E0310
// #define IOMUXC_SW_MUX_CTL_PAD_NANDF_D6 0x020E0314
// #define IOMUXC_SW_MUX_CTL_PAD_NANDF_D7 0x020E0318
// #define IOMUXC_SW_MUX_CTL_PAD_SD4_DAT0 0x020E031C
// #define IOMUXC_SW_MUX_CTL_PAD_SD4_DAT1 0x020E0320
// #define IOMUXC_SW_MUX_CTL_PAD_SD4_DAT2 0x020E0324
// #define IOMUXC_SW_MUX_CTL_PAD_SD4_DAT3 0x020E0328
// #define IOMUXC_SW_MUX_CTL_PAD_SD4_DAT4 0x020E032C
// #define IOMUXC_SW_MUX_CTL_PAD_SD4_DAT5 0x020E0330
// #define IOMUXC_SW_MUX_CTL_PAD_SD4_DAT6 0x020E0334
// #define IOMUXC_SW_MUX_CTL_PAD_SD4_DAT7 0x020E0338
// #define IOMUXC_SW_MUX_CTL_PAD_SD1_DAT1 0x020E033C
// #define IOMUXC_SW_MUX_CTL_PAD_SD1_DAT0 0x020E0340
// #define IOMUXC_SW_MUX_CTL_PAD_SD1_DAT3 0x020E0344
// #define IOMUXC_SW_MUX_CTL_PAD_SD1_CMD 0x020E0348
// #define IOMUXC_SW_MUX_CTL_PAD_SD1_DAT2 0x020E034C
// #define IOMUXC_SW_MUX_CTL_PAD_SD1_CLK 0x020E0350
// #define IOMUXC_SW_MUX_CTL_PAD_SD2_CLK 0x020E0354
// #define IOMUXC_SW_MUX_CTL_PAD_SD2_CMD 0x020E0358
// #define IOMUXC_SW_MUX_CTL_PAD_SD2_DAT3 0x020E035C
// //
// // IOMUXC_SW_PAD_CTL_PAD_*
// // IOMUXC_SW_PAD_CTL_GRP_*
// //
// #define IOMUXC_SW_PAD_CTL_PAD_SD2_DAT1 0x020E0360
// #define IOMUXC_SW_PAD_CTL_PAD_SD2_DAT2 0x020E0364
// #define IOMUXC_SW_PAD_CTL_PAD_SD2_DAT0 0x020E0368
// #define IOMUXC_SW_PAD_CTL_PAD_RGMII_TXC 0x020E036C
// #define IOMUXC_SW_PAD_CTL_PAD_RGMII_TD0 0x020E0370
// #define IOMUXC_SW_PAD_CTL_PAD_RGMII_TD1 0x020E0374
// #define IOMUXC_SW_PAD_CTL_PAD_RGMII_TD2 0x020E0378
// #define IOMUXC_SW_PAD_CTL_PAD_RGMII_TD3 0x020E037C
// #define IOMUXC_SW_PAD_CTL_PAD_RGMII_RX_CTL 0x020E0380
// #define IOMUXC_SW_PAD_CTL_PAD_RGMII_RD0 0x020E0384
// #define IOMUXC_SW_PAD_CTL_PAD_RGMII_TX_CTL 0x020E0388
// #define IOMUXC_SW_PAD_CTL_PAD_RGMII_RD1 0x020E038C
// #define IOMUXC_SW_PAD_CTL_PAD_RGMII_RD2 0x020E0390
// #define IOMUXC_SW_PAD_CTL_PAD_RGMII_RD3 0x020E0394
// #define IOMUXC_SW_PAD_CTL_PAD_RGMII_RXC 0x020E0398
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_A25 0x020E039C
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_EB2 0x020E03A0
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_D16 0x020E03A4
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_D17 0x020E03A8
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_D18 0x020E03AC
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_D19 0x020E03B0
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_D20 0x020E03B4
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_D21 0x020E03B8
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_D22 0x020E03BC
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_D23 0x020E03C0
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_EB3 0x020E03C4
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_D24 0x020E03C8
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_D25 0x020E03CC
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_D26 0x020E03D0
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_D27 0x020E03D4
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_D28 0x020E03D8
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_D29 0x020E03DC
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_D30 0x020E03E0
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_D31 0x020E03E4
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_A24 0x020E03E8
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_A23 0x020E03EC
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_A22 0x020E03F0
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_A21 0x020E03F4
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_A20 0x020E03F8
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_A19 0x020E03FC
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_A18 0x020E0400
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_A17 0x020E0404
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_A16 0x020E0408
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_CS0 0x020E040C
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_CS1 0x020E0410
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_OE 0x020E0414
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_RW 0x020E0418
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_LBA 0x020E041C
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_EB0 0x020E0420
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_EB1 0x020E0424
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_DA0 0x020E0428
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_DA1 0x020E042C
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_DA2 0x020E0430
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_DA3 0x020E0434
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_DA4 0x020E0438
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_DA5 0x020E043C
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_DA6 0x020E0440
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_DA7 0x020E0444
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_DA8 0x020E0448
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_DA9 0x020E044C
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_DA10 0x020E0450
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_DA11 0x020E0454
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_DA12 0x020E0458
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_DA13 0x020E045C
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_DA14 0x020E0460
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_DA15 0x020E0464
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_WAIT 0x020E0468
// #define IOMUXC_SW_PAD_CTL_PAD_EIM_BCLK 0x020E046C
// #define IOMUXC_SW_PAD_CTL_PAD_DI0_DISP_CLK 0x020E0470
// #define IOMUXC_SW_PAD_CTL_PAD_DI0_PIN15 0x020E0474
// #define IOMUXC_SW_PAD_CTL_PAD_DI0_PIN2 0x020E0478
// #define IOMUXC_SW_PAD_CTL_PAD_DI0_PIN3 0x020E047C
// #define IOMUXC_SW_PAD_CTL_PAD_DI0_PIN4 0x020E0480
// #define IOMUXC_SW_PAD_CTL_PAD_DISP0_DAT0 0x020E0484
// #define IOMUXC_SW_PAD_CTL_PAD_DISP0_DAT1 0x020E0488
// #define IOMUXC_SW_PAD_CTL_PAD_DISP0_DAT2 0x020E048C
// #define IOMUXC_SW_PAD_CTL_PAD_DISP0_DAT3 0x020E0490
// #define IOMUXC_SW_PAD_CTL_PAD_DISP0_DAT4 0x020E0494
// #define IOMUXC_SW_PAD_CTL_PAD_DISP0_DAT5 0x020E0498
// #define IOMUXC_SW_PAD_CTL_PAD_DISP0_DAT6 0x020E049C
// #define IOMUXC_SW_PAD_CTL_PAD_DISP0_DAT7 0x020E04A0
// #define IOMUXC_SW_PAD_CTL_PAD_DISP0_DAT8 0x020E04A4
// #define IOMUXC_SW_PAD_CTL_PAD_DISP0_DAT9 0x020E04A8
// #define IOMUXC_SW_PAD_CTL_PAD_DISP0_DAT10 0x020E04AC
// #define IOMUXC_SW_PAD_CTL_PAD_DISP0_DAT11 0x020E04B0
// #define IOMUXC_SW_PAD_CTL_PAD_DISP0_DAT12 0x020E04B4
// #define IOMUXC_SW_PAD_CTL_PAD_DISP0_DAT13 0x020E04B8
// #define IOMUXC_SW_PAD_CTL_PAD_DISP0_DAT14 0x020E04BC
// #define IOMUXC_SW_PAD_CTL_PAD_DISP0_DAT15 0x020E04C0
// #define IOMUXC_SW_PAD_CTL_PAD_DISP0_DAT16 0x020E04C4
// #define IOMUXC_SW_PAD_CTL_PAD_DISP0_DAT17 0x020E04C8
// #define IOMUXC_SW_PAD_CTL_PAD_DISP0_DAT18 0x020E04CC
// #define IOMUXC_SW_PAD_CTL_PAD_DISP0_DAT19 0x020E04D0
// #define IOMUXC_SW_PAD_CTL_PAD_DISP0_DAT20 0x020E04D4
// #define IOMUXC_SW_PAD_CTL_PAD_DISP0_DAT21 0x020E04D8
// #define IOMUXC_SW_PAD_CTL_PAD_DISP0_DAT22 0x020E04DC
// #define IOMUXC_SW_PAD_CTL_PAD_DISP0_DAT23 0x020E04E0
// #define IOMUXC_SW_PAD_CTL_PAD_ENET_MDIO 0x020E04E4
// #define IOMUXC_SW_PAD_CTL_PAD_ENET_REF_CLK 0x020E04E8
// #define IOMUXC_SW_PAD_CTL_PAD_ENET_RX_ER 0x020E04EC
// #define IOMUXC_SW_PAD_CTL_PAD_ENET_CRS_DV 0x020E04F0
// #define IOMUXC_SW_PAD_CTL_PAD_ENET_RXD1 0x020E04F4
// #define IOMUXC_SW_PAD_CTL_PAD_ENET_RXD0 0x020E04F8
// #define IOMUXC_SW_PAD_CTL_PAD_ENET_TX_EN 0x020E04FC
// #define IOMUXC_SW_PAD_CTL_PAD_ENET_TXD1 0x020E0500
// #define IOMUXC_SW_PAD_CTL_PAD_ENET_TXD0 0x020E0504
// #define IOMUXC_SW_PAD_CTL_PAD_ENET_MDC 0x020E0508
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS5 0x020E050C
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM5 0x020E0510
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM4 0x020E0514
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS4 0x020E0518
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS3 0x020E051C
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM3 0x020E0520
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS2 0x020E0524
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM2 0x020E0528
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_A0 0x020E052C
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_A1 0x020E0530
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_A2 0x020E0534
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_A3 0x020E0538
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_A4 0x020E053C
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_A5 0x020E0540
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_A6 0x020E0544
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_A7 0x020E0548
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_A8 0x020E054C
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_A9 0x020E0550
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_A10 0x020E0554
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_A11 0x020E0558
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_A12 0x020E055C
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_A13 0x020E0560
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_A14 0x020E0564
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_A15 0x020E0568
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_CAS 0x020E056C
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_CS0 0x020E0570
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_CS1 0x020E0574
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_RAS 0x020E0578
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_RESET 0x020E057C
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDBA0 0x020E0580
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDBA1 0x020E0584
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_0 0x020E0588
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDBA2 0x020E058C
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCKE0 0x020E0590
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCLK_1 0x020E0594
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDCKE1 0x020E0598
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT0 0x020E059C
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDODT1 0x020E05A0
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDWE 0x020E05A4
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS0 0x020E05A8
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM0 0x020E05AC
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS1 0x020E05B0
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM1 0x020E05B4
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS6 0x020E05B8
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM6 0x020E05BC
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_SDQS7 0x020E05C0
#define IOMUXC_SW_PAD_CTL_PAD_DRAM_DQM7 0x020E05C4
// #define IOMUXC_SW_PAD_CTL_PAD_KEY_COL0 0x020E05C8
// #define IOMUXC_SW_PAD_CTL_PAD_KEY_ROW0 0x020E05CC
// #define IOMUXC_SW_PAD_CTL_PAD_KEY_COL1 0x020E05D0
// #define IOMUXC_SW_PAD_CTL_PAD_KEY_ROW1 0x020E05D4
// #define IOMUXC_SW_PAD_CTL_PAD_KEY_COL2 0x020E05D8
// #define IOMUXC_SW_PAD_CTL_PAD_KEY_ROW2 0x020E05DC
// #define IOMUXC_SW_PAD_CTL_PAD_KEY_COL3 0x020E05E0
// #define IOMUXC_SW_PAD_CTL_PAD_KEY_ROW3 0x020E05E4
// #define IOMUXC_SW_PAD_CTL_PAD_KEY_COL4 0x020E05E8
// #define IOMUXC_SW_PAD_CTL_PAD_KEY_ROW4 0x020E05EC
// #define IOMUXC_SW_PAD_CTL_PAD_GPIO_0 0x020E05F0
// #define IOMUXC_SW_PAD_CTL_PAD_GPIO_1 0x020E05F4
// #define IOMUXC_SW_PAD_CTL_PAD_GPIO_9 0x020E05F8
// #define IOMUXC_SW_PAD_CTL_PAD_GPIO_3 0x020E05FC
// #define IOMUXC_SW_PAD_CTL_PAD_GPIO_6 0x020E0600
// #define IOMUXC_SW_PAD_CTL_PAD_GPIO_2 0x020E0604
// #define IOMUXC_SW_PAD_CTL_PAD_GPIO_4 0x020E0608
// #define IOMUXC_SW_PAD_CTL_PAD_GPIO_5 0x020E060C
// #define IOMUXC_SW_PAD_CTL_PAD_GPIO_7 0x020E0610
// #define IOMUXC_SW_PAD_CTL_PAD_GPIO_8 0x020E0614
// #define IOMUXC_SW_PAD_CTL_PAD_GPIO_16 0x020E0618
// #define IOMUXC_SW_PAD_CTL_PAD_GPIO_17 0x020E061C
// #define IOMUXC_SW_PAD_CTL_PAD_GPIO_18 0x020E0620
// #define IOMUXC_SW_PAD_CTL_PAD_GPIO_19 0x020E0624
// #define IOMUXC_SW_PAD_CTL_PAD_CSI0_PIXCLK 0x020E0628
// #define IOMUXC_SW_PAD_CTL_PAD_CSI0_MCLK 0x020E062C
// #define IOMUXC_SW_PAD_CTL_PAD_CSI0_DATA_EN 0x020E0630
// #define IOMUXC_SW_PAD_CTL_PAD_CSI0_VSYNC 0x020E0634
// #define IOMUXC_SW_PAD_CTL_PAD_CSI0_DAT4 0x020E0638
// #define IOMUXC_SW_PAD_CTL_PAD_CSI0_DAT5 0x020E063C
// #define IOMUXC_SW_PAD_CTL_PAD_CSI0_DAT6 0x020E0640
// #define IOMUXC_SW_PAD_CTL_PAD_CSI0_DAT7 0x020E0644
// #define IOMUXC_SW_PAD_CTL_PAD_CSI0_DAT8 0x020E0648
// #define IOMUXC_SW_PAD_CTL_PAD_CSI0_DAT9 0x020E064C
// #define IOMUXC_SW_PAD_CTL_PAD_CSI0_DAT10 0x020E0650
// #define IOMUXC_SW_PAD_CTL_PAD_CSI0_DAT11 0x020E0654
// #define IOMUXC_SW_PAD_CTL_PAD_CSI0_DAT12 0x020E0658
// #define IOMUXC_SW_PAD_CTL_PAD_CSI0_DAT13 0x020E065C
// #define IOMUXC_SW_PAD_CTL_PAD_CSI0_DAT14 0x020E0660
// #define IOMUXC_SW_PAD_CTL_PAD_CSI0_DAT15 0x020E0664
// #define IOMUXC_SW_PAD_CTL_PAD_CSI0_DAT16 0x020E0668
// #define IOMUXC_SW_PAD_CTL_PAD_CSI0_DAT17 0x020E066C
// #define IOMUXC_SW_PAD_CTL_PAD_CSI0_DAT18 0x020E0670
// #define IOMUXC_SW_PAD_CTL_PAD_CSI0_DAT19 0x020E0674
// #define IOMUXC_SW_PAD_CTL_PAD_JTAG_TMS 0x020E0678
// #define IOMUXC_SW_PAD_CTL_PAD_JTAG_MOD 0x020E067C
// #define IOMUXC_SW_PAD_CTL_PAD_JTAG_TRSTB 0x020E0680
// #define IOMUXC_SW_PAD_CTL_PAD_JTAG_TDI 0x020E0684
// #define IOMUXC_SW_PAD_CTL_PAD_JTAG_TCK 0x020E0688
// #define IOMUXC_SW_PAD_CTL_PAD_JTAG_TDO 0x020E068C
// #define IOMUXC_SW_PAD_CTL_PAD_SD3_DAT7 0x020E0690
// #define IOMUXC_SW_PAD_CTL_PAD_SD3_DAT6 0x020E0694
// #define IOMUXC_SW_PAD_CTL_PAD_SD3_DAT5 0x020E0698
// #define IOMUXC_SW_PAD_CTL_PAD_SD3_DAT4 0x020E069C
// #define IOMUXC_SW_PAD_CTL_PAD_SD3_CMD 0x020E06A0
// #define IOMUXC_SW_PAD_CTL_PAD_SD3_CLK 0x020E06A4
// #define IOMUXC_SW_PAD_CTL_PAD_SD3_DAT0 0x020E06A8
// #define IOMUXC_SW_PAD_CTL_PAD_SD3_DAT1 0x020E06AC
// #define IOMUXC_SW_PAD_CTL_PAD_SD3_DAT2 0x020E06B0
// #define IOMUXC_SW_PAD_CTL_PAD_SD3_DAT3 0x020E06B4
// #define IOMUXC_SW_PAD_CTL_PAD_SD3_RST 0x020E06B8
// #define IOMUXC_SW_PAD_CTL_PAD_NANDF_CLE 0x020E06BC
// #define IOMUXC_SW_PAD_CTL_PAD_NANDF_ALE 0x020E06C0
// #define IOMUXC_SW_PAD_CTL_PAD_NANDF_WP_B 0x020E06C4
// #define IOMUXC_SW_PAD_CTL_PAD_NANDF_RB0 0x020E06C8
// #define IOMUXC_SW_PAD_CTL_PAD_NANDF_CS0 0x020E06CC
// #define IOMUXC_SW_PAD_CTL_PAD_NANDF_CS1 0x020E06D0
// #define IOMUXC_SW_PAD_CTL_PAD_NANDF_CS2 0x020E06D4
// #define IOMUXC_SW_PAD_CTL_PAD_NANDF_CS3 0x020E06D8
// #define IOMUXC_SW_PAD_CTL_PAD_SD4_CMD 0x020E06DC
// #define IOMUXC_SW_PAD_CTL_PAD_SD4_CLK 0x020E06E0
// #define IOMUXC_SW_PAD_CTL_PAD_NANDF_D0 0x020E06E4
// #define IOMUXC_SW_PAD_CTL_PAD_NANDF_D1 0x020E06E8
// #define IOMUXC_SW_PAD_CTL_PAD_NANDF_D2 0x020E06EC
// #define IOMUXC_SW_PAD_CTL_PAD_NANDF_D3 0x020E06F0
// #define IOMUXC_SW_PAD_CTL_PAD_NANDF_D4 0x020E06F4
// #define IOMUXC_SW_PAD_CTL_PAD_NANDF_D5 0x020E06F8
// #define IOMUXC_SW_PAD_CTL_PAD_NANDF_D6 0x020E06FC
// #define IOMUXC_SW_PAD_CTL_PAD_NANDF_D7 0x020E0700
// #define IOMUXC_SW_PAD_CTL_PAD_SD4_DAT0 0x020E0704
// #define IOMUXC_SW_PAD_CTL_PAD_SD4_DAT1 0x020E0708
// #define IOMUXC_SW_PAD_CTL_PAD_SD4_DAT2 0x020E070C
// #define IOMUXC_SW_PAD_CTL_PAD_SD4_DAT3 0x020E0710
// #define IOMUXC_SW_PAD_CTL_PAD_SD4_DAT4 0x020E0714
// #define IOMUXC_SW_PAD_CTL_PAD_SD4_DAT5 0x020E0718
// #define IOMUXC_SW_PAD_CTL_PAD_SD4_DAT6 0x020E071C
// #define IOMUXC_SW_PAD_CTL_PAD_SD4_DAT7 0x020E0720
// #define IOMUXC_SW_PAD_CTL_PAD_SD1_DAT1 0x020E0724
// #define IOMUXC_SW_PAD_CTL_PAD_SD1_DAT0 0x020E0728
// #define IOMUXC_SW_PAD_CTL_PAD_SD1_DAT3 0x020E072C
// #define IOMUXC_SW_PAD_CTL_PAD_SD1_CMD 0x020E0730
// #define IOMUXC_SW_PAD_CTL_PAD_SD1_DAT2 0x020E0734
// #define IOMUXC_SW_PAD_CTL_PAD_SD1_CLK 0x020E0738
// #define IOMUXC_SW_PAD_CTL_PAD_SD2_CLK 0x020E073C
// #define IOMUXC_SW_PAD_CTL_PAD_SD2_CMD 0x020E0740
// #define IOMUXC_SW_PAD_CTL_PAD_SD2_DAT3 0x020E0744
#define IOMUXC_SW_PAD_CTL_GRP_B7DS 0x020E0748
#define IOMUXC_SW_PAD_CTL_GRP_ADDDS 0x020E074C
#define IOMUXC_SW_PAD_CTL_GRP_DDRMODE_CTL 0x020E0750
#define IOMUXC_SW_PAD_CTL_GRP_TERM_CTL0 0x020E0754
#define IOMUXC_SW_PAD_CTL_GRP_DDRPKE 0x020E0758
#define IOMUXC_SW_PAD_CTL_GRP_TERM_CTL1 0x020E075C
#define IOMUXC_SW_PAD_CTL_GRP_TERM_CTL2 0x020E0760
#define IOMUXC_SW_PAD_CTL_GRP_TERM_CTL3 0x020E0764
#define IOMUXC_SW_PAD_CTL_GRP_DDRPK 0x020E0768
#define IOMUXC_SW_PAD_CTL_GRP_TERM_CTL4 0x020E076C
#define IOMUXC_SW_PAD_CTL_GRP_DDRHYS 0x020E0770
#define IOMUXC_SW_PAD_CTL_GRP_DDRMODE 0x020E0774
#define IOMUXC_SW_PAD_CTL_GRP_TERM_CTL5 0x020E0778
#define IOMUXC_SW_PAD_CTL_GRP_TERM_CTL6 0x020E077C
#define IOMUXC_SW_PAD_CTL_GRP_TERM_CTL7 0x020E0780
#define IOMUXC_SW_PAD_CTL_GRP_B0DS 0x020E0784
#define IOMUXC_SW_PAD_CTL_GRP_B1DS 0x020E0788
#define IOMUXC_SW_PAD_CTL_GRP_CTLDS 0x020E078C
#define IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE_RGMII 0x020E0790
#define IOMUXC_SW_PAD_CTL_GRP_B2DS 0x020E0794
#define IOMUXC_SW_PAD_CTL_GRP_DDR_TYPE 0x020E0798
#define IOMUXC_SW_PAD_CTL_GRP_B3DS 0x020E079C
#define IOMUXC_SW_PAD_CTL_GRP_B4DS 0x020E07A0
#define IOMUXC_SW_PAD_CTL_GRP_B5DS 0x020E07A4
#define IOMUXC_SW_PAD_CTL_GRP_B6DS 0x020E07A8
// #define IOMUXC_SW_PAD_CTL_GRP_RGMII_TERM 0x020E07AC
// //
// // IOMUXC_*_SELECT_INPUT
// //
// #define IOMUXC_ASRC_ASRCK_CLOCK_6_SELECT_INPUT 0x020E07B0
// #define IOMUXC_AUDMUX_P4_INPUT_DA_AMX_SELECT_INPUT 0x020E07B4
// #define IOMUXC_AUDMUX_P4_INPUT_DB_AMX_SELECT_INPUT 0x020E07B8
// #define IOMUXC_AUDMUX_P4_INPUT_RXCLK_AMX_SELECT_INPUT 0x020E07BC
// #define IOMUXC_AUDMUX_P4_INPUT_RXFS_AMX_SELECT_INPUT 0x020E07C0
// #define IOMUXC_AUDMUX_P4_INPUT_TXCLK_AMX_SELECT_INPUT 0x020E07C4
// #define IOMUXC_AUDMUX_P4_INPUT_TXFS_AMX_SELECT_INPUT 0x020E07C8
// #define IOMUXC_AUDMUX_P5_INPUT_DA_AMX_SELECT_INPUT 0x020E07CC
// #define IOMUXC_AUDMUX_P5_INPUT_DB_AMX_SELECT_INPUT 0x020E07D0
// #define IOMUXC_AUDMUX_P5_INPUT_RXCLK_AMX_SELECT_INPUT 0x020E07D4
// #define IOMUXC_AUDMUX_P5_INPUT_RXFS_AMX_SELECT_INPUT 0x020E07D8
// #define IOMUXC_AUDMUX_P5_INPUT_TXCLK_AMX_SELECT_INPUT 0x020E07DC
// #define IOMUXC_AUDMUX_P5_INPUT_TXFS_AMX_SELECT_INPUT 0x020E07E0
// #define IOMUXC_CAN1_IPP_IND_CANRX_SELECT_INPUT 0x020E07E4
// #define IOMUXC_CAN2_IPP_IND_CANRX_SELECT_INPUT 0x020E07E8
// #define IOMUXC_CCM_IPP_DI1_CLK_SELECT_INPUT 0x020E07EC
// #define IOMUXC_CCM_PMIC_VFUNCIONAL_READY_SELECT_INPUT 0x020E07F0
// #define IOMUXC_ECSPI1_IPP_CSPI_CLK_IN_SELECT_INPUT 0x020E07F4
// #define IOMUXC_ECSPI1_IPP_IND_MISO_SELECT_INPUT 0x020E07F8
// #define IOMUXC_ECSPI1_IPP_IND_MOSI_SELECT_INPUT 0x020E07FC
// #define IOMUXC_ECSPI1_IPP_IND_SS_B_0_SELECT_INPUT 0x020E0800
// #define IOMUXC_ECSPI1_IPP_IND_SS_B_1_SELECT_INPUT 0x020E0804
// #define IOMUXC_ECSPI1_IPP_IND_SS_B_2_SELECT_INPUT 0x020E0808
// #define IOMUXC_ECSPI1_IPP_IND_SS_B_3_SELECT_INPUT 0x020E080C
// #define IOMUXC_ECSPI2_IPP_CSPI_CLK_IN_SELECT_INPUT 0x020E0810
// #define IOMUXC_ECSPI2_IPP_IND_MISO_SELECT_INPUT 0x020E0814
// #define IOMUXC_ECSPI2_IPP_IND_MOSI_SELECT_INPUT 0x020E0818
// #define IOMUXC_ECSPI2_IPP_IND_SS_B_0_SELECT_INPUT 0x020E081C
// #define IOMUXC_ECSPI2_IPP_IND_SS_B_1_SELECT_INPUT 0x020E0820
// #define IOMUXC_ECSPI4_IPP_IND_SS_B_0_SELECT_INPUT 0x020E0824
// #define IOMUXC_ECSPI5_IPP_CSPI_CLK_IN_SELECT_INPUT 0x020E0828
// #define IOMUXC_ECSPI5_IPP_IND_MISO_SELECT_INPUT 0x020E082C
// #define IOMUXC_ECSPI5_IPP_IND_MOSI_SELECT_INPUT 0x020E0830
// #define IOMUXC_ECSPI5_IPP_IND_SS_B_0_SELECT_INPUT 0x020E0834
// #define IOMUXC_ECSPI5_IPP_IND_SS_B_1_SELECT_INPUT 0x020E0838
// #define IOMUXC_ENET_IPG_CLK_RMII_SELECT_INPUT 0x020E083C
// #define IOMUXC_ENET_IPP_IND_MAC0_MDIO_SELECT_INPUT 0x020E0840
// #define IOMUXC_ENET_IPP_IND_MAC0_RXCLK_SELECT_INPUT 0x020E0844
// #define IOMUXC_ENET_IPP_IND_MAC0_RXDATA_0_SELECT_INPUT 0x020E0848
// #define IOMUXC_ENET_IPP_IND_MAC0_RXDATA_1_SELECT_INPUT 0x020E084C
// #define IOMUXC_ENET_IPP_IND_MAC0_RXDATA_2_SELECT_INPUT 0x020E0850
// #define IOMUXC_ENET_IPP_IND_MAC0_RXDATA_3_SELECT_INPUT 0x020E0854
// #define IOMUXC_ENET_IPP_IND_MAC0_RXEN_SELECT_INPUT 0x020E0858
// #define IOMUXC_ESAI_IPP_IND_FSR_SELECT_INPUT 0x020E085C
// #define IOMUXC_ESAI_IPP_IND_FST_SELECT_INPUT 0x020E0860
// #define IOMUXC_ESAI_IPP_IND_HCKR_SELECT_INPUT 0x020E0864
// #define IOMUXC_ESAI_IPP_IND_HCKT_SELECT_INPUT 0x020E0868
// #define IOMUXC_ESAI_IPP_IND_SCKR_SELECT_INPUT 0x020E086C
// #define IOMUXC_ESAI_IPP_IND_SCKT_SELECT_INPUT 0x020E0870
// #define IOMUXC_ESAI_IPP_IND_SDO0_SELECT_INPUT 0x020E0874
// #define IOMUXC_ESAI_IPP_IND_SDO1_SELECT_INPUT 0x020E0878
// #define IOMUXC_ESAI_IPP_IND_SDO2_SDI3_SELECT_INPUT 0x020E087C
// #define IOMUXC_ESAI_IPP_IND_SDO3_SDI2_SELECT_INPUT 0x020E0880
// #define IOMUXC_ESAI_IPP_IND_SDO4_SDI1_SELECT_INPUT 0x020E0884
// #define IOMUXC_ESAI_IPP_IND_SDO5_SDI0_SELECT_INPUT 0x020E0888
// #define IOMUXC_HDMI_TX_ICECIN_SELECT_INPUT 0x020E088C
// #define IOMUXC_HDMI_TX_II2C_MSTH13TDDC_SCLIN_SELECT_INPUT 0x020E0890
// #define IOMUXC_HDMI_TX_II2C_MSTH13TDDC_SDAIN_SELECT_INPUT 0x020E0894
// #define IOMUXC_I2C1_IPP_SCL_IN_SELECT_INPUT 0x020E0898
// #define IOMUXC_I2C1_IPP_SDA_IN_SELECT_INPUT 0x020E089C
// #define IOMUXC_I2C2_IPP_SCL_IN_SELECT_INPUT 0x020E08A0
// #define IOMUXC_I2C2_IPP_SDA_IN_SELECT_INPUT 0x020E08A4
// #define IOMUXC_I2C3_IPP_SCL_IN_SELECT_INPUT 0x020E08A8
// #define IOMUXC_I2C3_IPP_SDA_IN_SELECT_INPUT 0x020E08AC
// #define IOMUXC_IPU2_IPP_IND_SENS1_DATA_10_SELECT_INPUT 0x020E08B0
// #define IOMUXC_IPU2_IPP_IND_SENS1_DATA_11_SELECT_INPUT 0x020E08B4
// #define IOMUXC_IPU2_IPP_IND_SENS1_DATA_12_SELECT_INPUT 0x020E08B8
// #define IOMUXC_IPU2_IPP_IND_SENS1_DATA_13_SELECT_INPUT 0x020E08BC
// #define IOMUXC_IPU2_IPP_IND_SENS1_DATA_14_SELECT_INPUT 0x020E08C0
// #define IOMUXC_IPU2_IPP_IND_SENS1_DATA_15_SELECT_INPUT 0x020E08C4
// #define IOMUXC_IPU2_IPP_IND_SENS1_DATA_16_SELECT_INPUT 0x020E08C8
// #define IOMUXC_IPU2_IPP_IND_SENS1_DATA_17_SELECT_INPUT 0x020E08CC
// #define IOMUXC_IPU2_IPP_IND_SENS1_DATA_18_SELECT_INPUT 0x020E08D0
// #define IOMUXC_IPU2_IPP_IND_SENS1_DATA_19_SELECT_INPUT 0x020E08D4
// #define IOMUXC_IPU2_IPP_IND_SENS1_DATA_EN_SELECT_INPUT 0x020E08D8
// #define IOMUXC_IPU2_IPP_IND_SENS1_HSYNC_SELECT_INPUT 0x020E08DC
// #define IOMUXC_IPU2_IPP_IND_SENS1_PIX_CLK_SELECT_INPUT 0x020E08E0
// #define IOMUXC_IPU2_IPP_IND_SENS1_VSYNC_SELECT_INPUT 0x020E08E4
// #define IOMUXC_KPP_IPP_IND_COL_5_SELECT_INPUT 0x020E08E8
// #define IOMUXC_KPP_IPP_IND_COL_6_SELECT_INPUT 0x020E08EC
// #define IOMUXC_KPP_IPP_IND_COL_7_SELECT_INPUT 0x020E08F0
// #define IOMUXC_KPP_IPP_IND_ROW_5_SELECT_INPUT 0x020E08F4
// #define IOMUXC_KPP_IPP_IND_ROW_6_SELECT_INPUT 0x020E08F8
// #define IOMUXC_KPP_IPP_IND_ROW_7_SELECT_INPUT 0x020E08FC
// #define IOMUXC_MLB_MLB_CLK_IN_SELECT_INPUT 0x020E0900
// #define IOMUXC_MLB_MLB_DATA_IN_SELECT_INPUT 0x020E0904
// #define IOMUXC_MLB_MLB_SIG_IN_SELECT_INPUT 0x020E0908
// #define IOMUXC_SDMA_EVENTS_14_SELECT_INPUT 0x020E090C
// #define IOMUXC_SDMA_EVENTS_15_SELECT_INPUT 0x020E0910
// #define IOMUXC_SPDIF_SPDIF_IN1_SELECT_INPUT 0x020E0914
// #define IOMUXC_SPDIF_TX_CLK2_SELECT_INPUT 0x020E0918
// #define IOMUXC_UART1_IPP_UART_RTS_B_SELECT_INPUT 0x020E091C
// #define IOMUXC_UART1_IPP_UART_RXD_MUX_SELECT_INPUT 0x020E0920
// #define IOMUXC_UART2_IPP_UART_RTS_B_SELECT_INPUT 0x020E0924
// #define IOMUXC_UART2_IPP_UART_RXD_MUX_SELECT_INPUT 0x020E0928
// #define IOMUXC_UART3_IPP_UART_RTS_B_SELECT_INPUT 0x020E092C
// #define IOMUXC_UART3_IPP_UART_RXD_MUX_SELECT_INPUT 0x020E0930
// #define IOMUXC_UART4_IPP_UART_RTS_B_SELECT_INPUT 0x020E0934
// #define IOMUXC_UART4_IPP_UART_RXD_MUX_SELECT_INPUT 0x020E0938
// #define IOMUXC_UART5_IPP_UART_RTS_B_SELECT_INPUT 0x020E093C
// #define IOMUXC_UART5_IPP_UART_RXD_MUX_SELECT_INPUT 0x020E0940
// #define IOMUXC_USBOH3_IPP_IND_OTG_OC_SELECT_INPUT 0x020E0944
// #define IOMUXC_USBOH3_IPP_IND_UH1_OC_SELECT_INPUT 0x020E0948
// #define IOMUXC_USDHC1_IPP_WP_ON_SELECT_INPUT 0x020E094C
#endif // _IOMUX_REGISTER_H_
@@ -0,0 +1,479 @@
/*
* Copyright (c) 2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "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 FREESCALE 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 _REGS_H
#define _REGS_H 1
//
// define base address of the register block only if it is not already
// defined, which allows the compiler to override at build time for
// users who've mapped their registers to locations other than the
// physical location
//
#ifndef REGS_BASE
#define REGS_BASE 0x00000000
#endif
//
// common register types
//
#ifndef __LANGUAGE_ASM__
typedef unsigned char reg8_t;
typedef unsigned short reg16_t;
typedef unsigned int reg32_t;
#endif
//
// Typecast macro for C or asm. In C, the cast is applied, while in asm it is excluded. This is
// used to simplify macro definitions in the module register headers.
//
#ifndef __REG_VALUE_TYPE
#ifndef __LANGUAGE_ASM__
#define __REG_VALUE_TYPE(v, t) ((t)(v))
#else
#define __REG_VALUE_TYPE(v, t) (v)
#endif
#endif
//
// macros for single instance registers
//
/*
#define BF_SET(reg, field) HW_##reg##_SET(BM_##reg##_##field)
#define BF_CLR(reg, field) HW_##reg##_CLR(BM_##reg##_##field)
#define BF_TOG(reg, field) HW_##reg##_TOG(BM_##reg##_##field)
#define BF_SETV(reg, field, v) HW_##reg##_SET(BF_##reg##_##field(v))
#define BF_CLRV(reg, field, v) HW_##reg##_CLR(BF_##reg##_##field(v))
#define BF_TOGV(reg, field, v) HW_##reg##_TOG(BF_##reg##_##field(v))
#define BV_FLD(reg, field, sym) BF_##reg##_##field(BV_##reg##_##field##__##sym)
#define BV_VAL(reg, field, sym) BV_##reg##_##field##__##sym
#define BF_RD(reg, field) HW_##reg.B.field
#define BF_WR(reg, field, v) BW_##reg##_##field(v)
#define BF_CS1(reg, f1, v1) \
(HW_##reg##_CLR(BM_##reg##_##f1), \
HW_##reg##_SET(BF_##reg##_##f1(v1)))
#define BF_CS2(reg, f1, v1, f2, v2) \
(HW_##reg##_CLR(BM_##reg##_##f1 | \
BM_##reg##_##f2), \
HW_##reg##_SET(BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2)))
#define BF_CS3(reg, f1, v1, f2, v2, f3, v3) \
(HW_##reg##_CLR(BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3), \
HW_##reg##_SET(BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3)))
#define BF_CS4(reg, f1, v1, f2, v2, f3, v3, f4, v4) \
(HW_##reg##_CLR(BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4), \
HW_##reg##_SET(BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4)))
#define BF_CS5(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5) \
(HW_##reg##_CLR(BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4 | \
BM_##reg##_##f5), \
HW_##reg##_SET(BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4) | \
BF_##reg##_##f5(v5)))
#define BF_CS6(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6) \
(HW_##reg##_CLR(BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4 | \
BM_##reg##_##f5 | \
BM_##reg##_##f6), \
HW_##reg##_SET(BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4) | \
BF_##reg##_##f5(v5) | \
BF_##reg##_##f6(v6)))
#define BF_CS7(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7) \
(HW_##reg##_CLR(BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4 | \
BM_##reg##_##f5 | \
BM_##reg##_##f6 | \
BM_##reg##_##f7), \
HW_##reg##_SET(BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4) | \
BF_##reg##_##f5(v5) | \
BF_##reg##_##f6(v6) | \
BF_##reg##_##f7(v7)))
#define BF_CS8(reg, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8) \
(HW_##reg##_CLR(BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4 | \
BM_##reg##_##f5 | \
BM_##reg##_##f6 | \
BM_##reg##_##f7 | \
BM_##reg##_##f8), \
HW_##reg##_SET(BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4) | \
BF_##reg##_##f5(v5) | \
BF_##reg##_##f6(v6) | \
BF_##reg##_##f7(v7) | \
BF_##reg##_##f8(v8)))
//
// macros for multiple instance registers
//
#define BF_SETn(reg, n, field) HW_##reg##_SET(n, BM_##reg##_##field)
#define BF_CLRn(reg, n, field) HW_##reg##_CLR(n, BM_##reg##_##field)
#define BF_TOGn(reg, n, field) HW_##reg##_TOG(n, BM_##reg##_##field)
#define BF_SETVn(reg, n, field, v) HW_##reg##_SET(n, BF_##reg##_##field(v))
#define BF_CLRVn(reg, n, field, v) HW_##reg##_CLR(n, BF_##reg##_##field(v))
#define BF_TOGVn(reg, n, field, v) HW_##reg##_TOG(n, BF_##reg##_##field(v))
#define BV_FLDn(reg, n, field, sym) BF_##reg##_##field(BV_##reg##_##field##__##sym)
#define BV_VALn(reg, n, field, sym) BV_##reg##_##field##__##sym
#define BF_RDn(reg, n, field) HW_##reg(n).B.field
#define BF_WRn(reg, n, field, v) BW_##reg##_##field(n, v)
#define BF_CS1n(reg, n, f1, v1) \
(HW_##reg##_CLR(n, (BM_##reg##_##f1)), \
HW_##reg##_SET(n, (BF_##reg##_##f1(v1))))
#define BF_CS2n(reg, n, f1, v1, f2, v2) \
(HW_##reg##_CLR(n, (BM_##reg##_##f1 | \
BM_##reg##_##f2)), \
HW_##reg##_SET(n, (BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2))))
#define BF_CS3n(reg, n, f1, v1, f2, v2, f3, v3) \
(HW_##reg##_CLR(n, (BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3)), \
HW_##reg##_SET(n, (BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3))))
#define BF_CS4n(reg, n, f1, v1, f2, v2, f3, v3, f4, v4) \
(HW_##reg##_CLR(n, (BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4)), \
HW_##reg##_SET(n, (BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4))))
#define BF_CS5n(reg, n, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5) \
(HW_##reg##_CLR(n, (BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4 | \
BM_##reg##_##f5)), \
HW_##reg##_SET(n, (BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4) | \
BF_##reg##_##f5(v5))))
#define BF_CS6n(reg, n, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6) \
(HW_##reg##_CLR(n, (BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4 | \
BM_##reg##_##f5 | \
BM_##reg##_##f6)), \
HW_##reg##_SET(n, (BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4) | \
BF_##reg##_##f5(v5) | \
BF_##reg##_##f6(v6))))
#define BF_CS7n(reg, n, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7) \
(HW_##reg##_CLR(n, (BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4 | \
BM_##reg##_##f5 | \
BM_##reg##_##f6 | \
BM_##reg##_##f7)), \
HW_##reg##_SET(n, (BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4) | \
BF_##reg##_##f5(v5) | \
BF_##reg##_##f6(v6) | \
BF_##reg##_##f7(v7))))
#define BF_CS8n(reg, n, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8) \
(HW_##reg##_CLR(n, (BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4 | \
BM_##reg##_##f5 | \
BM_##reg##_##f6 | \
BM_##reg##_##f7 | \
BM_##reg##_##f8)), \
HW_##reg##_SET(n, (BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4) | \
BF_##reg##_##f5(v5) | \
BF_##reg##_##f6(v6) | \
BF_##reg##_##f7(v7) | \
BF_##reg##_##f8(v8))))
//
// macros for single instance MULTI-BLOCK registers
//
#define BFn_SET(reg, blk, field) HW_##reg##_SET(blk, BM_##reg##_##field)
#define BFn_CLR(reg, blk, field) HW_##reg##_CLR(blk, BM_##reg##_##field)
#define BFn_TOG(reg, blk, field) HW_##reg##_TOG(blk, BM_##reg##_##field)
#define BFn_SETV(reg, blk, field, v) HW_##reg##_SET(blk, BF_##reg##_##field(v))
#define BFn_CLRV(reg, blk, field, v) HW_##reg##_CLR(blk, BF_##reg##_##field(v))
#define BFn_TOGV(reg, blk, field, v) HW_##reg##_TOG(blk, BF_##reg##_##field(v))
#define BVn_FLD(reg, field, sym) BF_##reg##_##field(BV_##reg##_##field##__##sym)
#define BVn_VAL(reg, field, sym) BV_##reg##_##field##__##sym
#define BFn_RD(reg, blk, field) HW_##reg(blk).B.field
#define BFn_WR(reg, blk, field, v) BW_##reg##_##field(blk, v)
#define BFn_CS1(reg, blk, f1, v1) \
(HW_##reg##_CLR(blk, BM_##reg##_##f1), \
HW_##reg##_SET(blk, BF_##reg##_##f1(v1)))
#define BFn_CS2(reg, blk, f1, v1, f2, v2) \
(HW_##reg##_CLR(blk, BM_##reg##_##f1 | \
BM_##reg##_##f2), \
HW_##reg##_SET(blk, BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2)))
#define BFn_CS3(reg, blk, f1, v1, f2, v2, f3, v3) \
(HW_##reg##_CLR(blk, BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3), \
HW_##reg##_SET(blk, BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3)))
#define BFn_CS4(reg, blk, f1, v1, f2, v2, f3, v3, f4, v4) \
(HW_##reg##_CLR(blk, BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4), \
HW_##reg##_SET(blk, BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4)))
#define BFn_CS5(reg, blk, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5) \
(HW_##reg##_CLR(blk, BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4 | \
BM_##reg##_##f5), \
HW_##reg##_SET(blk, BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4) | \
BF_##reg##_##f5(v5)))
#define BFn_CS6(reg, blk, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6) \
(HW_##reg##_CLR(blk, BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4 | \
BM_##reg##_##f5 | \
BM_##reg##_##f6), \
HW_##reg##_SET(blk, BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4) | \
BF_##reg##_##f5(v5) | \
BF_##reg##_##f6(v6)))
#define BFn_CS7(reg, blk, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7) \
(HW_##reg##_CLR(blk, BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4 | \
BM_##reg##_##f5 | \
BM_##reg##_##f6 | \
BM_##reg##_##f7), \
HW_##reg##_SET(blk, BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4) | \
BF_##reg##_##f5(v5) | \
BF_##reg##_##f6(v6) | \
BF_##reg##_##f7(v7)))
#define BFn_CS8(reg, blk, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8) \
(HW_##reg##_CLR(blk, BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4 | \
BM_##reg##_##f5 | \
BM_##reg##_##f6 | \
BM_##reg##_##f7 | \
BM_##reg##_##f8), \
HW_##reg##_SET(blk, BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4) | \
BF_##reg##_##f5(v5) | \
BF_##reg##_##f6(v6) | \
BF_##reg##_##f7(v7) | \
BF_##reg##_##f8(v8)))
//
// macros for MULTI-BLOCK multiple instance registers
//
#define BFn_SETn(reg, blk, n, field) HW_##reg##_SET(blk, n, BM_##reg##_##field)
#define BFn_CLRn(reg, blk, n, field) HW_##reg##_CLR(blk, n, BM_##reg##_##field)
#define BFn_TOGn(reg, blk, n, field) HW_##reg##_TOG(blk, n, BM_##reg##_##field)
#define BFn_SETVn(reg, blk, n, field, v) HW_##reg##_SET(blk, n, BF_##reg##_##field(v))
#define BFn_CLRVn(reg, blk, n, field, v) HW_##reg##_CLR(blk, n, BF_##reg##_##field(v))
#define BFn_TOGVn(reg, blk, n, field, v) HW_##reg##_TOG(blk, n, BF_##reg##_##field(v))
#define BVn_FLDn(reg, blk, n, field, sym) BF_##reg##_##field(BV_##reg##_##field##__##sym)
#define BVn_VALn(reg, blk, n, field, sym) BV_##reg##_##field##__##sym
#define BFn_RDn(reg, blk, n, field) HW_##reg(n).B.field
#define BFn_WRn(reg, blk, n, field, v) BW_##reg##_##field(n, v)
#define BFn_CS1n(reg, blk, n, f1, v1) \
(HW_##reg##_CLR(blk, n, (BM_##reg##_##f1)), \
HW_##reg##_SET(blk, n, (BF_##reg##_##f1(v1))))
#define BFn_CS2n(reg, blk, n, f1, v1, f2, v2) \
(HW_##reg##_CLR(blk, n, (BM_##reg##_##f1 | \
BM_##reg##_##f2)), \
HW_##reg##_SET(blk, n, (BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2))))
#define BFn_CS3n(reg, blk, n, f1, v1, f2, v2, f3, v3) \
(HW_##reg##_CLR(blk, n, (BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3)), \
HW_##reg##_SET(blk, n, (BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3))))
#define BFn_CS4n(reg, blk, n, f1, v1, f2, v2, f3, v3, f4, v4) \
(HW_##reg##_CLR(blk, n, (BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4)), \
HW_##reg##_SET(blk, n, (BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4))))
#define BFn_CS5n(reg, blk, n, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5) \
(HW_##reg##_CLR(blk, n, (BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4 | \
BM_##reg##_##f5)), \
HW_##reg##_SET(blk, n, (BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4) | \
BF_##reg##_##f5(v5))))
#define BFn_CS6n(reg, blk, n, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6) \
(HW_##reg##_CLR(blk, n, (BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4 | \
BM_##reg##_##f5 | \
BM_##reg##_##f6)), \
HW_##reg##_SET(blk, n, (BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4) | \
BF_##reg##_##f5(v5) | \
BF_##reg##_##f6(v6))))
#define BFn_CS7n(reg, blk, n, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7) \
(HW_##reg##_CLR(blk, n, (BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4 | \
BM_##reg##_##f5 | \
BM_##reg##_##f6 | \
BM_##reg##_##f7)), \
HW_##reg##_SET(blk, n, (BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4) | \
BF_##reg##_##f5(v5) | \
BF_##reg##_##f6(v6) | \
BF_##reg##_##f7(v7))))
#define BFn_CS8n(reg, blk, n, f1, v1, f2, v2, f3, v3, f4, v4, f5, v5, f6, v6, f7, v7, f8, v8) \
(HW_##reg##_CLR(blk, n, (BM_##reg##_##f1 | \
BM_##reg##_##f2 | \
BM_##reg##_##f3 | \
BM_##reg##_##f4 | \
BM_##reg##_##f5 | \
BM_##reg##_##f6 | \
BM_##reg##_##f7 | \
BM_##reg##_##f8)), \
HW_##reg##_SET(blk, n, (BF_##reg##_##f1(v1) | \
BF_##reg##_##f2(v2) | \
BF_##reg##_##f3(v3) | \
BF_##reg##_##f4(v4) | \
BF_##reg##_##f5(v5) | \
BF_##reg##_##f6(v6) | \
BF_##reg##_##f7(v7) | \
BF_##reg##_##f8(v8))))
*/
#endif // _REGS_H
////////////////////////////////////////////////////////////////////////////////
@@ -0,0 +1,831 @@
/*
* Copyright (C) 2011-2012 Freescale Semiconductor, Inc. All Rights Reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/**
* @file soc_memory_map.h
* @brief support imx6q soc memory map define, reference from u-boot-2009-08/include/asm-arm/arch-mx6/mx6.h
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023.09.08
*/
#ifndef SOC_MEMORY_MAP_H
#define SOC_MEMORY_MAP_H
// clang-format off
/*
* Some of i.MX 6 Series SoC registers are associated with four addresses
* used for different operations - read/write, set, clear and toggle bits.
*
* Some of registers do not implement such feature and, thus, should be
* accessed/manipulated via single address in common way.
*/
#define REG_RD(base, reg) \
(*(volatile unsigned int *)((base) + (reg)))
#define REG_WR(base, reg, value) \
((*(volatile unsigned int *)((base) + (reg))) = (value))
#define REG_SET(base, reg, value) \
((*(volatile unsigned int *)((base) + (reg ## _SET))) = (value))
#define REG_CLR(base, reg, value) \
((*(volatile unsigned int *)((base) + (reg ## _CLR))) = (value))
#define REG_TOG(base, reg, value) \
((*(volatile unsigned int *)((base) + (reg ## _TOG))) = (value))
#define REG_RD_ADDR(addr) \
(*(volatile unsigned int *)((addr)))
#define REG_WR_ADDR(addr, value) \
((*(volatile unsigned int *)((addr))) = (value))
#define REG_SET_ADDR(addr, value) \
((*(volatile unsigned int *)((addr) + 0x4)) = (value))
#define REG_CLR_ADDR(addr, value) \
((*(volatile unsigned int *)((addr) + 0x8)) = (value))
#define REG_TOG_ADDR(addr, value) \
((*(volatile unsigned int *)((addr) + 0xc)) = (value))
#define __REG(x) (*((volatile u32 *)(x)))
#define __REG16(x) (*((volatile u16 *)(x)))
#define __REG8(x) (*((volatile u8 *)(x)))
/*
*ROM address which denotes silicon rev
*/
#define ROM_SI_REV 0x48
/*!
* @file arch-mxc/mx6.h
* @brief This file contains register definitions.
*
* @ingroup MSL_MX6
*/
/*
* IPU
*/
#define IPU_CTRL_BASE_ADDR 0x02400000
/*!
* Register an interrupt handler for the SMN as well as the SCC. In some
* implementations, the SMN is not connected at all, and in others, it is
* on the same interrupt line as the SCM. Comment this line out accordingly
*/
#define USE_SMN_INTERRUPT
/*!
* This option is used to set or clear the RXDMUXSEL bit in control reg 3.
* Certain platforms need this bit to be set in order to receive Irda data.
*/
#define MXC_UART_IR_RXDMUX 0x0004
/*!
* This option is used to set or clear the RXDMUXSEL bit in control reg 3.
* Certain platforms need this bit to be set in order to receive UART data.
*/
#define MXC_UART_RXDMUX 0x0004
/*!
* This option is used to set or clear the dspdma bit in the SDMA config
* register.
*/
#define MXC_DMA_REQ_DSPDMA 0
/*!
* Define this option to specify we are using the newer SDMA module.
*/
#define MXC_DMA_REQ_V2
/*!
* The maximum frequency that the pixel clock can be at so as to
* activate DVFS-PER.
*/
#define DVFS_MAX_PIX_CLK 54000000
/*!
* The Low 32 bits of CPU Serial Number Fuse Index
*/
#define CPU_UID_LOW_FUSE_INDEX 1
/*!
* The High 32 bits of CPU Serial Number Fuse Index
*/
#define CPU_UID_HIGH_FUSE_INDEX 2
// /* IROM
// */
// #define IROM_BASE_ADDR 0x0
// #define IROM_SIZE SZ_64K
// /* CPU Memory Map */
// #ifdef CONFIG_MX6SL
// #define MMDC0_ARB_BASE_ADDR 0x80000000
// #define MMDC0_ARB_END_ADDR 0xFFFFFFFF
// #define MMDC1_ARB_BASE_ADDR 0xC0000000
// #define MMDC1_ARB_END_ADDR 0xFFFFFFFF
// #else
// #define MMDC0_ARB_BASE_ADDR 0x10000000
// #define MMDC0_ARB_END_ADDR 0x7FFFFFFF
// #define MMDC1_ARB_BASE_ADDR 0x80000000
// #define MMDC1_ARB_END_ADDR 0xFFFFFFFF
// #endif
// #define OCRAM_ARB_BASE_ADDR 0x00900000
// #define OCRAM_ARB_END_ADDR 0x009FFFFF
// #define IRAM_BASE_ADDR OCRAM_ARB_BASE_ADDR
// #define PCIE_ARB_BASE_ADDR 0x01000000
// #define PCIE_ARB_END_ADDR 0x01FFFFFF
// /* Blocks connected via pl301periph */
// #define ROMCP_ARB_BASE_ADDR 0x00000000
// #define ROMCP_ARB_END_ADDR 0x00017FFF
// #define BOOT_ROM_BASE_ADDR ROMCP_ARB_BASE_ADDR
// #ifdef CONFIG_MX6SL
// #define GPU_2D_ARB_BASE_ADDR 0x02200000
// #define GPU_2D_ARB_END_ADDR 0x02203FFF
// #define OPENVG_ARB_BASE_ADDR 0x02204000
// #define OPENVG_ARB_END_ADDR 0x02207FFF
// #else
// #define CAAM_ARB_BASE_ADDR 0x00100000
// #define CAAM_ARB_END_ADDR 0x00103FFF
// #define APBH_DMA_ARB_BASE_ADDR 0x00110000
// #define APBH_DMA_ARB_END_ADDR 0x00117FFF
// #define HDMI_ARB_BASE_ADDR 0x00120000
// #define HDMI_ARB_END_ADDR 0x00128FFF
// #define GPU_3D_ARB_BASE_ADDR 0x00130000
// #define GPU_3D_ARB_END_ADDR 0x00133FFF
// #define GPU_2D_ARB_BASE_ADDR 0x00134000
// #define GPU_2D_ARB_END_ADDR 0x00137FFF
// #define DTCP_ARB_BASE_ADDR 0x00138000
// #define DTCP_ARB_END_ADDR 0x0013BFFF
// #define GPU_MEM_BASE_ADDR GPU_3D_ARB_BASE_ADDR
// #endif
// /* GPV - PL301 configuration ports */
// #define GPV0_BASE_ADDR 0x00B00000
// #define GPV1_BASE_ADDR 0x00C00000
// #ifdef CONFIG_MX6SL
// #define GPV2_BASE_ADDR 0x00D00000
// #else
// #define GPV2_BASE_ADDR 0x00200000
// #define GPV3_BASE_ADDR 0x00300000
// #define GPV4_BASE_ADDR 0x00800000
// #endif
#define AIPS1_ARB_BASE_ADDR 0x02000000
#define AIPS1_ARB_END_ADDR 0x020FFFFF
#define AIPS2_ARB_BASE_ADDR 0x02100000
#define AIPS2_ARB_END_ADDR 0x021FFFFF
// #define SATA_ARB_BASE_ADDR 0x02200000
// #define SATA_ARB_END_ADDR 0x02203FFF
// #define OPENVG_ARB_BASE_ADDR 0x02204000
// #define OPENVG_ARB_END_ADDR 0x02207FFF
// #define HSI_ARB_BASE_ADDR 0x02208000
// #define HSI_ARB_END_ADDR 0x0220BFFF
// #define IPU1_ARB_BASE_ADDR 0x02400000
// #define IPU1_ARB_END_ADDR 0x027FFFFF
// #define IPU2_ARB_BASE_ADDR 0x02800000
// #define IPU2_ARB_END_ADDR 0x02BFFFFF
// #define WEIM_ARB_BASE_ADDR 0x08000000
// #define WEIM_ARB_END_ADDR 0x0FFFFFFF
// /* Legacy Defines */
// #define CSD0_DDR_BASE_ADDR MMDC0_ARB_BASE_ADDR
// #define CSD1_DDR_BASE_ADDR MMDC1_ARB_BASE_ADDR
// #define CS0_BASE_ADDR WEIM_ARB_BASE_ADDR
// #define NAND_FLASH_BASE_ADDR APBH_DMA_ARB_BASE_ADDR
// #define ABPHDMA_BASE_ADDR APBH_DMA_ARB_BASE_ADDR
// #define GPMI_BASE_ADDR (APBH_DMA_ARB_BASE_ADDR + 0x02000)
// #define BCH_BASE_ADDR (APBH_DMA_ARB_BASE_ADDR + 0x04000)
/* Defines for Blocks connected via AIPS (SkyBlue) */
#define ATZ1_BASE_ADDR AIPS1_ARB_BASE_ADDR
#define ATZ2_BASE_ADDR AIPS2_ARB_BASE_ADDR
// /* slots 0,7 of SDMA reserved, therefore left unused in IPMUX3 */
// #define SPDIF_BASE_ADDR (ATZ1_BASE_ADDR + 0x04000)
// #define ECSPI1_BASE_ADDR (ATZ1_BASE_ADDR + 0x08000)
// #define ECSPI2_BASE_ADDR (ATZ1_BASE_ADDR + 0x0C000)
// #define ECSPI3_BASE_ADDR (ATZ1_BASE_ADDR + 0x10000)
// #define ECSPI4_BASE_ADDR (ATZ1_BASE_ADDR + 0x14000)
// #ifdef CONFIG_MX6SL
// #define UART5_IPS_BASE_ADDR (ATZ1_BASE_ADDR + 0x18000)
// #define UART1_IPS_BASE_ADDR (ATZ1_BASE_ADDR + 0x20000)
// #define UART2_IPS_BASE_ADDR (ATZ1_BASE_ADDR + 0x24000)
// #define SSI1_IPS_BASE_ADDR (ATZ1_BASE_ADDR + 0x28000)
// #define SSI2_IPS_BASE_ADDR (ATZ1_BASE_ADDR + 0x2C000)
// #define SSI3_IPS_BASE_ADDR (ATZ1_BASE_ADDR + 0x30000)
// #define UART3_IPS_BASE_ADDR (ATZ1_BASE_ADDR + 0x34000)
// #define UART4_IPS_BASE_ADDR (ATZ1_BASE_ADDR + 0x38000)
// #else
// #define ECSPI5_BASE_ADDR (ATZ1_BASE_ADDR + 0x18000)
// #define UART1_BASE_ADDR (ATZ1_BASE_ADDR + 0x20000)
// #define ESAI1_BASE_ADDR (ATZ1_BASE_ADDR + 0x24000)
// #define SSI1_BASE_ADDR (ATZ1_BASE_ADDR + 0x28000)
// #define SSI2_BASE_ADDR (ATZ1_BASE_ADDR + 0x2C000)
// #define SSI3_BASE_ADDR (ATZ1_BASE_ADDR + 0x30000)
// #define ASRC_BASE_ADDR (ATZ1_BASE_ADDR + 0x34000)
// #endif
// #define SPBA_BASE_ADDR (ATZ1_BASE_ADDR + 0x3C000)
// #define VPU_BASE_ADDR (ATZ1_BASE_ADDR + 0x40000)
// /* ATZ#1- On Platform */
#define AIPS1_ON_BASE_ADDR (ATZ1_BASE_ADDR + 0x7C000)
/* ATZ#1- Off Platform */
#define AIPS1_OFF_BASE_ADDR (ATZ1_BASE_ADDR + 0x80000)
// #define PWM1_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x0000)
// #define PWM2_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x4000)
// #define PWM3_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x8000)
// #define PWM4_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0xC000)
// #ifdef CONFIG_MX6SL
// #define DBGMON_IPS_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x10000)
// #define QOSC_IPS_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x14000)
// #else
// #define CAN1_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x10000)
// #define CAN2_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x14000)
// #endif
#define GPT_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x18000)
// #define GPIO1_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x1C000)
// #define GPIO2_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x20000)
// #define GPIO3_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x24000)
// #define GPIO4_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x28000)
// #define GPIO5_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x2C000)
// #define GPIO6_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x30000)
// #define GPIO7_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x34000)
// #define KPP_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x38000)
// #define WDOG1_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x3C000)
// #define WDOG2_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x40000)
#define CCM_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x44000)
#define ANATOP_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x48000)
// #define USB_PHY0_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x49000)
// #define USB_PHY1_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x4A000)
// #define SNVS_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x4C000)
// #define EPIT1_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x50000)
// #define EPIT2_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x54000)
// #define SRC_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x58000)
// #define GPC_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x5C000)
#define IOMUXC_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x60000)
// #ifdef CONFIG_MX6SL
// #define CSI_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x64000)
// #define SIPIX_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x68000)
// #define SDMA_PORT_HOST_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x6C000)
// #else
// #define DCIC1_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x64000)
// #define DCIC2_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x68000)
// #define DMA_REQ_PORT_HOST_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x6C000)
// #endif
// #define EPXP_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x70000)
// #define EPDC_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x74000)
// #define ELCDIF_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x78000)
// #define DCP_BASE_ADDR (AIPS1_OFF_BASE_ADDR + 0x7C000)
/* ATZ#2- On Platform */
#define AIPS2_ON_BASE_ADDR (ATZ2_BASE_ADDR + 0x7C000)
/* ATZ#2- Off Platform */
#define AIPS2_OFF_BASE_ADDR (ATZ2_BASE_ADDR + 0x80000)
// /* ATZ#2 - Global enable (0) */
// #define CAAM_BASE_ADDR (ATZ2_BASE_ADDR)
// #define ARM_BASE_ADDR (ATZ2_BASE_ADDR + 0x40000)
// #ifdef CONFIG_MX6SL
// #define USBO2H_PL301_IPS_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x0000)
// #define USBO2H_USB_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x4000)
// #else
// #define USBOH3_PL301_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x0000)
// #define USBOH3_USB_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x4000)
// #endif
// #define ENET_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x8000)
// /* Frank Li Need IC confirm OTG base address*/
// #ifdef CONFIG_MX6SL
// #define OTG_BASE_ADDR USBO2H_USB_BASE_ADDR
// #define MSHC_IPS_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0xC000)
// #else
// #define OTG_BASE_ADDR USBOH3_USB_BASE_ADDR
// #define MLB_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0xC000)
// #endif
// #define USDHC1_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x10000)
// #define USDHC2_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x14000)
// #define USDHC3_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x18000)
// #define USDHC4_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x1C000)
// #define I2C1_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x20000)
// #define I2C2_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x24000)
// #define I2C3_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x28000)
// #define ROMCP_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x2C000)
#define MMDC_P0_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x30000)
#ifdef CONFIG_MX6SL
#define RNGB_IPS_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x34000)
#else
#define MMDC_P1_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x34000)
#endif
// #define WEIM_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x38000)
// #define OCOTP_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x3C000)
// #define CSU_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x40000)
// #define IP2APB_PERFMON1_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x44000)
// #define IP2APB_PERFMON2_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x48000)
// #define IP2APB_PERFMON3_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x4C000)
// #define IP2APB_TZASC1_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x50000)
// #define IP2APB_TZASC2_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x54000)
// #define AUDMUX_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x58000)
// #define MIPI_CSI2_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x5C000)
// #define MIPI_DSI_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x60000)
// #define VDOA_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x64000)
// #define UART2_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x68000)
// #define UART3_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x6C000)
// #define UART4_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x70000)
// #define UART5_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x74000)
// #define IP2APB_USBPHY1_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x78000)
// #define IP2APB_USBPHY2_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x7C000)
// /* Cortex-A9 MPCore private memory region */
// #define ARM_PERIPHBASE 0x00A00000
// #define SCU_BASE_ADDR (ARM_PERIPHBASE)
// #define IC_INTERFACES_BASE_ADDR (ARM_PERIPHBASE + 0x0100)
// #define GLOBAL_TIMER_BASE_ADDR (ARM_PERIPHBASE + 0x0200)
// #define PRIVATE_TIMERS_WD_BASE_ADDR (ARM_PERIPHBASE + 0x0600)
// #define IC_DISTRIBUTOR_BASE_ADDR (ARM_PERIPHBASE + 0x1000)
// /*!
// * Defines for modules using static and dynamic DMA channels
// */
// #define MXC_DMA_CHANNEL_IRAM 30
// #define MXC_DMA_CHANNEL_SPDIF_TX MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_SPDIF_RX MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_UART1_RX MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_UART1_TX MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_UART2_RX MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_UART2_TX MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_UART3_RX MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_UART3_TX MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_UART4_RX MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_UART4_TX MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_UART5_RX MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_UART5_TX MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_MMC1 MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_MMC2 MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_SSI1_RX MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_SSI1_TX MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_SSI2_RX MXC_DMA_DYNAMIC_CHANNEL
// #ifdef CONFIG_DMA_REQ_IRAM
// #define MXC_DMA_CHANNEL_SSI2_TX (MXC_DMA_CHANNEL_IRAM + 1)
// #else /*CONFIG_DMA_REQ_IRAM */
// #define MXC_DMA_CHANNEL_SSI2_TX MXC_DMA_DYNAMIC_CHANNEL
// #endif /*CONFIG_DMA_REQ_IRAM */
// #define MXC_DMA_CHANNEL_SSI3_RX MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_SSI3_TX MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_CSPI1_RX MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_CSPI1_TX MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_CSPI2_RX MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_CSPI2_TX MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_CSPI3_RX MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_CSPI3_TX MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_ATA_RX MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_ATA_TX MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_MEMORY MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_ASRCA_RX MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_ASRCA_TX MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_ASRCB_RX MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_ASRCB_TX MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_ASRCC_RX MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_ASRCC_TX MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_ESAI_RX MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_ESAI_TX MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_ASRCA_ESAI MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_ASRCB_ESAI MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_ASRCC_ESAI MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_ASRCA_SSI1_TX0 MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_ASRCA_SSI1_TX1 MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_ASRCA_SSI2_TX0 MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_ASRCA_SSI2_TX1 MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_ASRCB_SSI1_TX0 MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_ASRCB_SSI1_TX1 MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_ASRCB_SSI2_TX0 MXC_DMA_DYNAMIC_CHANNEL
// #define MXC_DMA_CHANNEL_ASRCB_SSI2_TX1 MXC_DMA_DYNAMIC_CHANNEL
// /* define virtual address */
// #define PERIPBASE_VIRT 0xF0000000
// #define AIPS1_BASE_ADDR_VIRT (PERIPBASE_VIRT + AIPS1_ARB_BASE_ADDR)
// #define AIPS2_BASE_ADDR_VIRT (PERIPBASE_VIRT + AIPS2_ARB_BASE_ADDR)
// #define ARM_PERIPHBASE_VIRT (PERIPBASE_VIRT + ARM_PERIPHBASE)
// #define AIPS1_SIZE SZ_1M
// #define AIPS2_SIZE SZ_1M
// #define ARM_PERIPHBASE_SIZE SZ_8K
// #define MX6_IO_ADDRESS(x) ((x) - PERIPBASE_VIRT)
/*!
* This macro defines the physical to virtual address mapping for all the
* peripheral modules. It is used by passing in the physical address as x
* and returning the virtual address. If the physical address is not mapped,
* it returns 0xDEADBEEF
*/
#define IO_ADDRESS(x) \
(void __force __iomem *) \
(((((x) >= (unsigned long)AIPS1_ARB_BASE_ADDR) && \
((x) <= (unsigned long)AIPS2_ARB_END_ADDR)) || \
((x) >= (unsigned long)ARM_PERIPHBASE && \
((x) <= (unsigned long)(ARM_PERIPHBASE + ARM_PERIPHBASE)))) ? \
MX6_IO_ADDRESS(x) : 0xDEADBEEF)
// /*
// * DMA request assignments
// */
// #define DMA_REQ_VPU 0
// #define DMA_REQ_GPC 1
// #define DMA_REQ_IPU1 2
// #define DMA_REQ_EXT_DMA_REQ_0 2
// #define DMA_REQ_CSPI1_RX 3
// #define DMA_REQ_I2C3_A 3
// #define DMA_REQ_CSPI1_TX 4
// #define DMA_REQ_I2C2_A 4
// #define DMA_REQ_CSPI2_RX 5
// #define DMA_REQ_I2C1_A 5
// #define DMA_REQ_CSPI2_TX 6
// #define DMA_REQ_CSPI3_RX 7
// #define DMA_REQ_CSPI3_TX 8
// #define DMA_REQ_CSPI4_RX 9
// #define DMA_REQ_EPIT2 9
// #define DMA_REQ_CSPI4_TX 10
// #define DMA_REQ_I2C1_B 10
// #define DMA_REQ_CSPI5_RX 11
// #define DMA_REQ_CSPI5_TX 12
// #define DMA_REQ_GPT 13
// #define DMA_REQ_SPDIF_RX 14
// #define DMA_REQ_EXT_DMA_REQ_1 14
// #define DMA_REQ_SPDIF_TX 15
// #define DMA_REQ_EPIT1 16
// #define DMA_REQ_ASRC_RX1 17
// #define DMA_REQ_ASRC_RX2 18
// #define DMA_REQ_ASRC_RX3 19
// #define DMA_REQ_ASRC_TX1 20
// #define DMA_REQ_ASRC_TX2 21
// #define DMA_REQ_ASRC_TX3 22
// #define DMA_REQ_ESAI_RX 23
// #define DMA_REQ_I2C3_B 23
// #define DMA_REQ_ESAI_TX 24
// #define DMA_REQ_UART1_RX 25
// #define DMA_REQ_UART1_TX 26
// #define DMA_REQ_UART2_RX 27
// #define DMA_REQ_UART2_TX 28
// #define DMA_REQ_UART3_RX 29
// #define DMA_REQ_UART3_TX 30
// #define DMA_REQ_UART4_RX 31
// #define DMA_REQ_UART4_TX 32
// #define DMA_REQ_UART5_RX 33
// #define DMA_REQ_UART5_TX 34
// #define DMA_REQ_SSI1_RX1 35
// #define DMA_REQ_SSI1_TX1 36
// #define DMA_REQ_SSI1_RX0 37
// #define DMA_REQ_SSI1_TX0 38
// #define DMA_REQ_SSI2_RX1 39
// #define DMA_REQ_SSI2_TX1 40
// #define DMA_REQ_SSI2_RX0 41
// #define DMA_REQ_SSI2_TX0 42
// #define DMA_REQ_SSI3_RX1 43
// #define DMA_REQ_SSI3_TX1 44
// #define DMA_REQ_SSI3_RX0 45
// #define DMA_REQ_SSI3_TX0 46
// #define DMA_REQ_DTCP 47
// /*
// * Interrupt numbers
// */
// #define MXC_INT_GPR 32
// #define MXC_INT_CHEETAH_CSYSPWRUPREQ 33
// #define MXC_INT_SDMA 34
// #ifndef CONFIG_MX6SL
// #define MXC_INT_VPU_JPG 35
// #define MXC_INT_INTERRUPT_36_NUM 36
// #define MXC_INT_IPU1_ERR 37
// #define MXC_INT_IPU1_FUNC 38
// #define MXC_INT_IPU2_ERR 39
// #define MXC_INT_IPU2_FUNC 40
// #define MXC_INT_GPU3D_IRQ 41
// #else
// #define MXC_INT_MSHC 35
// #define MXC_INT_SNVS_PMIC_OFF 36
// #define MXC_INT_RNGB 37
// #define MXC_INT_SPDC 38
// #define MXC_INT_CSI 39
// #endif
// #define MXC_INT_GPU2D_IRQ 42
// #define MXC_INT_OPENVG_XAQ2 43
// #define MXC_INT_VPU_IPI 44
// #define MXC_INT_APBHDMA_DMA 45
// #define MXC_INT_WEIM 46
// #define MXC_INT_RAWNAND_BCH 47
// #define MXC_INT_RAWNAND_GPMI 48
// #define MXC_INT_DTCP 49
// #define MXC_INT_VDOA 50
// #define MXC_INT_SNVS 51
// #define MXC_INT_SNVS_SEC 52
// #define MXC_INT_CSU 53
// #define MXC_INT_USDHC1 54
// #define MXC_INT_USDHC2 55
// #define MXC_INT_USDHC3 56
// #define MXC_INT_USDHC4 57
// #define MXC_INT_UART1_ANDED 58
// #define MXC_INT_UART2_ANDED 59
// #define MXC_INT_UART3_ANDED 60
// #define MXC_INT_UART4_ANDED 61
// #define MXC_INT_UART5_ANDED 62
// #define MXC_INT_ECSPI1 63
// #define MXC_INT_ECSPI2 64
// #define MXC_INT_ECSPI3 65
// #define MXC_INT_ECSPI4 66
// #define MXC_INT_ECSPI5 67
// #define MXC_INT_I2C1 68
// #define MXC_INT_I2C2 69
// #define MXC_INT_I2C3 70
// #ifdef CONFIG_MX6Q
// #define MXC_INT_SATA 71
// #define MXC_INT_USBOH3_UH1 72
// #define MXC_INT_USBOH3_UH2 73
// #define MXC_INT_USBOH3_UH3 74
// #define MXC_INT_USBOH3_UOTG 75
// #else
// #define MXC_INT_LCDIF 71
// #define MXC_INT_USBO2H_UH1 72
// #define MXC_INT_USBO2H_UH2 73
// #define MXC_INT_USBO2H_UH3 74
// #define MXC_INT_USBO2H_UOTG 75
// #endif
// #define MXC_INT_ANATOP_UTMI0 76
// #define MXC_INT_ANATOP_UTMI1 77
// #define MXC_INT_SSI1 78
// #define MXC_INT_SSI2 79
// #define MXC_INT_SSI3 80
// #define MXC_INT_ANATOP_TEMPSNSR 81
// #define MXC_INT_ASRC 82
// #define MXC_INT_ESAI 83
// #define MXC_INT_SPDIF 84
// #define MXC_INT_MLB 85
// #define MXC_INT_ANATOP_ANA1 86
// #define MXC_INT_GPT 87
// #define MXC_INT_EPIT1 88
// #define MXC_INT_EPIT2 89
// #define MXC_INT_GPIO1_INT7_NUM 90
// #define MXC_INT_GPIO1_INT6_NUM 91
// #define MXC_INT_GPIO1_INT5_NUM 92
// #define MXC_INT_GPIO1_INT4_NUM 93
// #define MXC_INT_GPIO1_INT3_NUM 94
// #define MXC_INT_GPIO1_INT2_NUM 95
// #define MXC_INT_GPIO1_INT1_NUM 96
// #define MXC_INT_GPIO1_INT0_NUM 97
// #define MXC_INT_GPIO1_INT15_0_NUM 98
// #define MXC_INT_GPIO1_INT31_16_NUM 99
// #define MXC_INT_GPIO2_INT15_0_NUM 100
// #define MXC_INT_GPIO2_INT31_16_NUM 101
// #define MXC_INT_GPIO3_INT15_0_NUM 102
// #define MXC_INT_GPIO3_INT31_16_NUM 103
// #define MXC_INT_GPIO4_INT15_0_NUM 104
// #define MXC_INT_GPIO4_INT31_16_NUM 105
// #define MXC_INT_GPIO5_INT15_0_NUM 106
// #define MXC_INT_GPIO5_INT31_16_NUM 107
// #define MXC_INT_GPIO6_INT15_0_NUM 108
// #define MXC_INT_GPIO6_INT31_16_NUM 109
// #define MXC_INT_GPIO7_INT15_0_NUM 110
// #define MXC_INT_GPIO7_INT31_16_NUM 111
// #define MXC_INT_WDOG1 112
// #define MXC_INT_WDOG2 113
// #define MXC_INT_KPP 114
// #define MXC_INT_PWM1 115
// #define MXC_INT_PWM2 116
// #define MXC_INT_PWM3 117
// #define MXC_INT_PWM4 118
// #define MXC_INT_CCM_INT1_NUM 119
// #define MXC_INT_CCM_INT2_NUM 120
// #define MXC_INT_GPC_INT1_NUM 121
// #define MXC_INT_GPC_INT2_NUM 122
// #define MXC_INT_SRC 123
// #define MXC_INT_CHEETAH_L2 124
// #define MXC_INT_CHEETAH_PARITY 125
// #define MXC_INT_CHEETAH_PERFORM 126
// #define MXC_INT_CHEETAH_TRIGGER 127
// #define MXC_INT_SRC_CPU_WDOG 128
// #ifndef CONFIG_MX6SL
// #define MXC_INT_INTERRUPT_129_NUM 129
// #define MXC_INT_INTERRUPT_130_NUM 130
// #define MXC_INT_INTERRUPT_13 131
// #define MXC_INT_CSI_INTR1 132
// #define MXC_INT_CSI_INTR2 133
// #define MXC_INT_DSI 134
// #define MXC_INT_HSI 135
// #else
// #define MXC_INT_EPDC 129
// #define MXC_INT_PXP 130
// #define MXC_INT_DCP_GP 131
// #define MXC_INT_DCP_CH0 132
// #define MXC_INT_DCP_SEC 133
// #endif
// #define MXC_INT_SJC 136
// #ifndef CONFIG_MX6SL
// #define MXC_INT_CAAM_INT0_NUM 137
// #define MXC_INT_CAAM_INT1_NUM 138
// #define MXC_INT_INTERRUPT_139_NUM 139
// #define MXC_INT_TZASC1 140
// #define MXC_INT_TZASC2 141
// #define MXC_INT_CAN1 142
// #define MXC_INT_CAN2 143
// #define MXC_INT_PERFMON1 144
// #define MXC_INT_PERFMON2 145
// #define MXC_INT_PERFMON3 146
// #define MXC_INT_HDMI_TX 147
// #define MXC_INT_HDMI_TX_WAKEUP 148
// #define MXC_INT_MLB_AHB0 149
// #define MXC_INT_ENET1 150
// #define MXC_INT_ENET2 151
// #define MXC_INT_PCIE_0 152
// #define MXC_INT_PCIE_1 153
// #define MXC_INT_PCIE_2 154
// #define MXC_INT_PCIE_3 155
// #define MXC_INT_DCIC1 156
// #define MXC_INT_DCIC2 157
// #define MXC_INT_MLB_AHB1 158
// #else
// #define MXC_INT_TZASC1 140
// #define MXC_INT_FEC 146
// #endif
// #define MXC_INT_ANATOP_ANA2 159
// /* gpio and gpio based interrupt handling */
// #define GPIO_DR 0x00
// #define GPIO_GDIR 0x04
// #define GPIO_PSR 0x08
// #define GPIO_ICR1 0x0C
// #define GPIO_ICR2 0x10
// #define GPIO_IMR 0x14
// #define GPIO_ISR 0x18
// #define GPIO_INT_LOW_LEV 0x0
// #define GPIO_INT_HIGH_LEV 0x1
// #define GPIO_INT_RISE_EDGE 0x2
// #define GPIO_INT_FALL_EDGE 0x3
// #define GPIO_INT_NONE 0x4
#define CLKCTL_CCR 0x00
#define CLKCTL_CCDR 0x04
#define CLKCTL_CSR 0x08
#define CLKCTL_CCSR 0x0C
#define CLKCTL_CACRR 0x10
#define CLKCTL_CBCDR 0x14
#define CLKCTL_CBCMR 0x18
#define CLKCTL_CSCMR1 0x1C
#define CLKCTL_CSCMR2 0x20
#define CLKCTL_CSCDR1 0x24
#define CLKCTL_CS1CDR 0x28
#define CLKCTL_CS2CDR 0x2C
#define CLKCTL_CDCDR 0x30
#define CLKCTL_CHSCCDR 0x34
#define CLKCTL_CSCDR2 0x38
#define CLKCTL_CSCDR3 0x3C
#define CLKCTL_CSCDR4 0x40
#define CLKCTL_CWDR 0x44
#define CLKCTL_CDHIPR 0x48
#define CLKCTL_CDCR 0x4C
#define CLKCTL_CTOR 0x50
#define CLKCTL_CLPCR 0x54
#define CLKCTL_CISR 0x58
#define CLKCTL_CIMR 0x5C
#define CLKCTL_CCOSR 0x60
#define CLKCTL_CGPR 0x64
#define CLKCTL_CCGR0 0x68
#define CLKCTL_CCGR1 0x6C
#define CLKCTL_CCGR2 0x70
#define CLKCTL_CCGR3 0x74
#define CLKCTL_CCGR4 0x78
#define CLKCTL_CCGR5 0x7C
#define CLKCTL_CCGR6 0x80
#define CLKCTL_CCGR7 0x84
#define CLKCTL_CMEOR 0x88
// #define ANATOP_USB1 0x10
// #define ANATOP_USB2 0x20
// #define ANATOP_PLL_VIDEO 0xA0
// #define CHIP_TYPE_DQ 0x63000
// #define CHIP_TYPE_DL 0x61000
// #define CHIP_TYPE_SOLO 0x61000
// #define CHIP_TYPE_SOLOLITE 0x60000
// #define CHIP_REV_1_0 0x10
// #define CHIP_REV_2_0 0x20
// #define CHIP_REV_2_1 0x21
// #define CHIP_REV_UNKNOWN 0xff
// #define BOARD_REV_1 0x000
// #define BOARD_REV_2 0x100
// #define BOARD_REV_3 0x200
// #define BOARD_REV_4 0x300
// #define BOARD_REV_5 0x400
// #define PLATFORM_ICGC 0x14
// #define SRC_GPR9 0x40
// #define SRC_GPR10 0x44
// //#define SNVS_LPGPR 0x68
/* Get Board ID */
#define board_is_rev(system_rev, rev) (((system_rev & 0x0F00) == rev) ? 1 : 0)
#define chip_is_type(system_rev, rev) \
(((system_rev & 0xFF000) == rev) ? 1 : 0)
// #define mx6_board_is_unknown() board_is_rev(fsl_system_rev, BOARD_REV_1)
// #define mx6_board_is_reva() board_is_rev(fsl_system_rev, BOARD_REV_2)
// #define mx6_board_is_revb() board_is_rev(fsl_system_rev, BOARD_REV_3)
// #define mx6_board_is_revc() board_is_rev(fsl_system_rev, BOARD_REV_4)
// #define mx6_chip_is_dq() chip_is_type(fsl_system_rev, CHIP_TYPE_DQ)
// #define mx6_chip_is_dl() chip_is_type(fsl_system_rev, CHIP_TYPE_DL)
// #define mx6_chip_is_solo() chip_is_type(fsl_system_rev, CHIP_TYPE_SOLO)
// #define mx6_chip_is_sololite() chip_is_type(fsl_system_rev, CHIP_TYPE_SOLOLITE)
// #define mx6_chip_dq_name "i.MX6Q"
// #define mx6_chip_dl_solo_name "i.MX6DL/Solo"
// #define mx6_chip_sololite_name "i.MX6SoloLite"
#define mx6_chip_name() (mx6_chip_is_dq() ? mx6_chip_dq_name : \
((mx6_chip_is_dl() | mx6_chip_is_solo()) ? mx6_chip_dl_solo_name : \
(mx6_chip_is_sololite() ? mx6_chip_sololite_name : "unknown-chip")))
#define mx6_board_rev_name() (mx6_board_is_reva() ? "RevA" : \
(mx6_board_is_revb() ? "RevB" : \
(mx6_board_is_revc() ? "RevC" : "unknown-board")))
// clang-format on
#ifndef __ASSEMBLER__
enum boot_device {
WEIM_NOR_BOOT,
ONE_NAND_BOOT,
PATA_BOOT,
SATA_BOOT,
I2C_BOOT,
SPI_NOR_BOOT,
SD_BOOT,
MMC_BOOT,
NAND_BOOT,
UNKNOWN_BOOT,
BOOT_DEV_NUM = UNKNOWN_BOOT,
};
enum mxc_clock {
MXC_ARM_CLK = 0,
MXC_PER_CLK,
MXC_AHB_CLK,
MXC_IPG_CLK,
MXC_IPG_PERCLK,
MXC_UART_CLK,
MXC_CSPI_CLK,
MXC_AXI_CLK,
MXC_EMI_SLOW_CLK,
MXC_DDR_CLK,
MXC_ESDHC_CLK,
MXC_ESDHC2_CLK,
MXC_ESDHC3_CLK,
MXC_ESDHC4_CLK,
MXC_SATA_CLK,
MXC_NFC_CLK,
MXC_GPMI_CLK,
MXC_BCH_CLK,
};
enum mxc_peri_clocks {
MXC_UART1_BAUD,
MXC_UART2_BAUD,
MXC_UART3_BAUD,
MXC_SSI1_BAUD,
MXC_SSI2_BAUD,
MXC_CSI_BAUD,
MXC_MSTICK1_CLK,
MXC_MSTICK2_CLK,
MXC_SPI1_CLK,
MXC_SPI2_CLK,
};
extern unsigned int fsl_system_rev;
extern unsigned int mxc_get_clock(enum mxc_clock clk);
extern unsigned int get_board_rev(void);
extern int is_soc_rev(int rev);
extern enum boot_device get_boot_device(void);
extern void fsl_set_system_rev(void);
#endif /* __ASSEMBLER__*/
#endif /* __ASM_ARCH_MXC_MX6_H__ */
@@ -0,0 +1,102 @@
/*
* Copyright (c) 2010-2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 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 HOLDER 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.
*/
/**
* @file ivt.c
* @brief image vector table configuration for imx6q
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023.08.25
*/
/*************************************************
File name: ivt.c
Description: imx6q image vector table
Others:
History:
1. Date: 2023-08-28
Author: AIIT XUOS Lab
Modification:
1. first version
*************************************************/
#include <hab_defines.h>
extern unsigned * _start_image_addr;
extern unsigned * __start_boot_data;
extern unsigned * _image_size;
extern unsigned * __hab_data;
extern uint8_t input_dcd_hdr[];
extern void _boot_start(void);
struct hab_ivt input_ivt __attribute__((section(".ivt"))) = {
/** @ref hdr word with tag #HAB_TAG_IVT, length and HAB version fields
* (see @ref data)
*/
IVT_HDR(sizeof(struct hab_ivt), HAB_VER(4, 0)),
/** Absolute address of the first instruction to execute from the
* image
*/
(hab_image_entry_f)_boot_start,
/** Reserved in this version of HAB: should be NULL. */
NULL,
/** Absolute address of the image DCD: may be NULL. */
&input_dcd_hdr,
/** Absolute address of the Boot Data: may be NULL, but not interpreted
* any further by HAB
*/
&__start_boot_data,
/** Absolute address of the IVT.*/
(const void*)(&input_ivt),
/** Absolute address of the image CSF.*/
//(const void*) &__hab_data,
0,
/** Reserved in this version of HAB: should be zero. */
0
};
typedef struct {
uint32_t start; /**< Start address of the image */
uint32_t size; /**< Size of the image */
uint32_t plugin; /**< Plugin flag */
} boot_data_t;
boot_data_t bd __attribute__ ((section (".boot_data"))) ={
(uint32_t) &_start_image_addr,
(uint32_t) &_image_size,
0,
};
@@ -0,0 +1,194 @@
/*
* Copyright (c) 2010-2012, Freescale Semiconductor, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright notice, this list
* of conditions and the following disclaimer.
*
* o 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.
*
* o Neither the name of Freescale Semiconductor, Inc. nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* 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 HOLDER 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 OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @file nxp_imx6q_sabrelite.lds
* @brief nxp imx6q sabrelite lds function
* @version 3.0
* @author AIIT XUOS Lab
* @date 2023.08.25
*/
OUTPUT_FORMAT("elf32-littlearm") /*binary file format*/
OUTPUT_ARCH(arm) /*arch target*/
ENTRY(_vector_jumper) /*entry address pointer*/
/* mx6dq has 256kB of OCRAM
* +-------------------+ 0x0093FFFF
* | RAM Vector |
* +-------------------+ 0x0093FFB8
* | Stack |
* | 8KB |
* +-------------------+ 0x0093E000
* | MMU Table |
* | 24KB |
* +-------------------+ 0x00938000
* | |
* | Free Area |
* | 195KB |
* | |
* +-------------------+ 0x00907400
* | DCD Table |
* | 1KB |
* +-------------------+ 0x00907000
* | Reserved |
* | 28KB |
* +-------------------+ 0x00900000
*/
/*
#define OCRAM_ORG 0x00907400
#define OCRAM_FREE_SIZE 196K*/
/*
* External DDR CHIP_MX6DQ/CHIP_MX6SDL start 0x10000000, CHIP_MX6SL start 0x80000000
*/
/*
#define DDR_ORG 0x10000000
#define DDR_LEN 2048M*/
BOOT_STACK_SIZE = 0x4000;
RAM_VECTORS_SIZE = 72;
/* Specify the memory areas */
MEMORY
{
ocram (rwx) : ORIGIN = 0x00900000, LENGTH = 256K
ddr3 (rwx) : ORIGIN = 0x10000000, LENGTH = 1024M
virt_ddr3 (WRX) : ORIGIN = 0x90010000, LENGTH = 1024M
}
SECTIONS
{
. = ORIGIN(ddr3);
. = ALIGN(4);
_start_image_addr = .;
.ivt :
{
. = . + 0x400;
KEEP(*(.ivt))
} > ddr3
.boot_data :
{
__start_boot_data = .;
KEEP(*(.boot_data))
} > ddr3
/* aligned to ease the hexdump read of generated binary */
.dcd_hdr : ALIGN(16)
{
KEEP(*(.dcd_hdr))
} > ddr3
.dcd_wrt_cmd :
{
KEEP(*(.dcd_wrt_cmd))
} > ddr3
.dcd_data :
{
KEEP(*(.dcd_data))
} > ddr3
.start_sec : {
. = ALIGN(0x1000);
/* read only area. */
boot.o(.text)
imx6q_lowlevel_init.o(.text .text.*)
bootmmu.o(.text .text.*)
boot.o(.rodata .rodata.*)
imx6q_lowlevel_init.o(.rodata .rodata.*)
bootmmu.o(.rodata .rodata.*)
/* already initialized to zero. */
boot.o(.data .data.*)
imx6q_lowlevel_init.o(.data .data.*)
bootmmu.o(.data .data.*)
/* initialization start checkpoint. */
PROVIDE(boot_start_addr = .);
boot.o(.bss .bss.* COMMON)
imx6q_lowlevel_init.o(.bss .bss.* COMMON)
bootmmu.o(.bss .bss.* COMMON)
/* stack for booting code. */
. = ALIGN(0x1000);
PROVIDE(stacks_start = .);
. += BOOT_STACK_SIZE;
PROVIDE(stacks_end = .);
PROVIDE(stacks_top = .);
/* initialization end checkpoint. */
PROVIDE(boot_end_addr = .);
} > ddr3
/* Other Kernel code is placed over 0x80000000 + 128KB. */
.text : AT(0x10010000) {
*(.vectors)
. = ALIGN(0x1000);
*(.text .text.* .gnu.linkonce.t.*)
} > virt_ddr3
. = ALIGN(0x1000);
/* Other Kernel code text checkpoint. */
PROVIDE(kern_text = .);
.data : {
*(.data .data.*)
/* user app */
. = ALIGN(0x1000);
PROVIDE(_binary_fs_img_start = .);
*(.rawdata_fs_img*)
PROVIDE(_binary_fs_img_end = .);
PROVIDE(_binary_init_start = .);
*(.rawdata_init*)
PROVIDE(_binary_init_end = .);
PROVIDE(_binary_default_fs_start = .);
*(.rawdata_memfs*)
PROVIDE(_binary_default_fs_end = .);
} > virt_ddr3
PROVIDE(kernel_data_begin = .);
_image_size = . - 0x90000000;
.bss : {
PROVIDE(__bss_start__ = .);
*(.bss .bss.* COMMON)
PROVIDE(__bss_end__ = .);
} > virt_ddr3
. = ALIGN(0x1000);
PROVIDE(kernel_data_end = .);
}