Merge pull request #4 from brain-hackers/x1

x1
This commit is contained in:
Takumi Sueda 2021-12-14 01:44:12 +09:00 committed by GitHub
commit 4b50ef496b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
23 changed files with 109 additions and 3342 deletions

2
.gitignore vendored
View File

@ -254,3 +254,5 @@ dmypy.json
# End of https://www.toptal.com/developers/gitignore/api/python,go,jetbrains+all # End of https://www.toptal.com/developers/gitignore/api/python,go,jetbrains+all
*.bin *.bin
*.elf
/*/tmp

1
x1/.gitignore vendored
View File

@ -1 +0,0 @@
c/uboot_bin.h

View File

@ -15,20 +15,10 @@ clean:
@./extract.py a.out $@ @./extract.py a.out $@
@rm -f a.out @rm -f a.out
c/main.elf: c/main.bin:
@$(CC) -nostdlib -static -fPIC -marm -O0 c/start.S c/main.c c/scg.c c/divmod.c c/divmod.S -o c/main.elf @$(CC) -nostdlib -static -fPIC -mcpu=cortex-a7 c/start.S c/main.c
@./extract.py a.out $@
c/main.bin: c/main.elf @rm -f a.out
@./extract.py c/main.elf $@
c/uboot_loader.bin:
@if [ "$(UBOOT)" = "" ]; then \
echo "Please specify UBOOT."; \
exit 1; \
fi
@c/generate.py $(UBOOT) c/uboot_bin.h.tpl c/uboot_bin.h
@$(CC) -nostdlib -static -fPIC -marm -O0 c/start.S c/main_uboot.c -o c/uboot_loader.elf
@./extract.py c/uboot_loader.elf $@
spray/main.bin: spray/main.bin:
@$(AS) spray/top.S @$(AS) spray/top.S
@ -37,16 +27,22 @@ spray/main.bin:
@./extract.py -p a.out spray/bottom.bin @./extract.py -p a.out spray/bottom.bin
@$(AS) spray/bottom_reset.S @$(AS) spray/bottom_reset.S
@./extract.py -p a.out spray/bottom_reset.bin @./extract.py -p a.out spray/bottom_reset.bin
@./append_nop.py spray/top.bin spray/bottom.bin spray/bottom_reset.bin spray/main.bin 112 113 @./spray/append_nop.py spray/top.bin spray/bottom.bin spray/bottom_reset.bin spray/main.bin 112 113
@rm -f a.out @rm -f a.out
injector/AppMain.bin: injector/AppMain.bin:
@if [ "$(ELF)" = "" ]; then \ @if [ "$(INJECTED_S)" = "" ]; then \
echo "Please specify ELF."; \ echo "Please specify INJECTED_S."; \
exit 1; \ exit 1; \
fi fi
@$(STRIP) $(ELF) @$(AS) $(INJECTED_S) -o injector/injected.elf
@./extract.py $(ELF) injector/injected.bin @./extract.py -p injector/injected.elf injector/injected.bin
@$(AS) injector/disable_mmu.S -o injector/disable_mmu.elf @$(AS) injector/disable_mmu.S -o injector/disable_mmu.elf
@./extract.py -p injector/disable_mmu.elf injector/disable_mmu.bin @./extract.py -p injector/disable_mmu.elf injector/disable_mmu.bin
@./injector/inject.py 0xf00000 0x700000 injector/disable_mmu.bin injector/injected.bin injector/AppMain.bin @./injector/inject.py 0xf00000 0x700000 injector/disable_mmu.bin injector/injected.bin injector/AppMain.bin
injector/uboot.bin:
@$(AS) injector/disable_mmu.S -o injector/disable_mmu.elf
@./extract.py -p injector/disable_mmu.elf injector/disable_mmu.bin
@./extract.py -p injector/disable_mmu.elf injector/disable_mmu.bin
@./injector/inject.py 0xed0000 0x700000 injector/disable_mmu.bin u-boot.bin injector/uboot.bin

View File

@ -2,6 +2,7 @@
- `mrc.S` Read SCTLR (MMU etc.) and return - `mrc.S` Read SCTLR (MMU etc.) and return
- `return.S` Return immediately - `return.S` Return immediately
- `extract.py` Extract .text - `extract.py` Extract .text
- `memmap.c` Analyze page table
#### Build #### Build
@ -16,37 +17,3 @@ make all
- Create index.din `touch /path/to/sd/APP/foo/index.din` - Create index.din `touch /path/to/sd/APP/foo/index.din`
- Copy and rename the raw executable `cp foo.bin /path/to/sd/APP/foo/AppMain.bin` - Copy and rename the raw executable `cp foo.bin /path/to/sd/APP/foo/AppMain.bin`
#### License
See each directory and SPDX license identifier for further information.
// Portions from OP-TEE projects \
// https://github.com/OP-TEE/optee_os
Unless it has its own copyright/license embedded in its body, each file
is subject to the following license terms:
Copyright (c) 2015, Linaro Limited
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE 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.

View File

@ -1,56 +0,0 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Copyright (c) 2014, STMicroelectronics International N.V.
* Copyright (c) 2020, Linaro Limited
*/
#if defined(CFG_UNWIND) && defined(__arm__)
#define UNWIND(...) __VA_ARGS__
#else
#define UNWIND(...)
#endif
.macro FUNC name colon section=default align=4
.ifc \section\(),default
.section .text.\name
.else
.section \section , "ax" , %progbits
.endif
.global \name
.type \name , %function
.balign \align
\name \colon
UNWIND( .fnstart)
.endm
.macro DATA name colon
.global \name
.type \name , %object
\name \colon
.endm
.macro LOCAL_FUNC name colon section=default align=4
.ifc \section\(),default
.section .text.\name
.else
.section \section , "ax" , %progbits
.endif
.type \name , %function
.balign \align
\name \colon
UNWIND( .fnstart)
.endm
.macro LOCAL_DATA name colon
.type \name , %object
\name \colon
.endm
.macro END_DATA name
.size \name , .-\name
.endm
.macro END_FUNC name
UNWIND( .fnend)
.size \name , .-\name
.endm

View File

@ -1,24 +0,0 @@
#pragma pack(1)
#define readl(a) (*(volatile unsigned int *)(a))
#define writel(v, a) (*(volatile unsigned int *)(a) = (v))
#define writeb(v, a) (*(volatile unsigned char *)(a) = (v))
typedef unsigned int u32;
typedef unsigned short u16;
typedef unsigned char u8;
typedef struct _pixel_t {
u8 r;
u8 g;
u8 b;
} pixel_t;
#define pack_pixel(p) (((u16)(p.r & 0x1f) << 11) | ((u16)(p.g & 0x3f) << 5) | ((u16)(p.b & 0x1f)))
#define WNATIVE 10
#define HNATIVE 854
void rot(u16* x, u16* y);
void prepare_fb(u16** fb);
void bitblt(u16** fb, pixel_t px, u16 x, u16 y);

View File

@ -1,33 +0,0 @@
#include "common.h"
void rot(u16* x, u16* y) {
u16 nx, ny;
nx = WNATIVE - ny;
ny = nx;
*x = nx;
*y = ny;
}
void prepare_fb(u16** fb) {
int x, y;
u16 px = 0b1111100000000000;
fb[0][0] = 0x2a;
fb[0][1] = 0x00;
fb[0][2] = 0x00;
fb[0][3] = 0x2b;
fb[0][4] = 0x00;
fb[0][5] = 0x00;
fb[0][6] = 0x2c;
for (y=0; y<HNATIVE; y++) {
for (x=7; x<WNATIVE; x++) {
*(volatile unsigned int *)(&fb[y][x]) = px;
}
}
}
void bitblt(u16** fb, pixel_t px, u16 x, u16 y) {
rot(&x, &y);
fb[y][x] = pack_pixel(px);
}

View File

@ -1,22 +0,0 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Copyright (c) 2014, STMicroelectronics International N.V.
*/
#include "asm.S"
/*
* signed ret_idivmod_values(signed quot, signed rem);
* return quotient and remaining the EABI way (regs r0,r1)
*/
FUNC ret_idivmod_values , :
bx lr
END_FUNC ret_idivmod_values
/*
* unsigned ret_uidivmod_values(unsigned quot, unsigned rem);
* return quotient and remaining the EABI way (regs r0,r1)
*/
FUNC ret_uidivmod_values , :
bx lr
END_FUNC ret_uidivmod_values

View File

@ -1,151 +0,0 @@
// SPDX-License-Identifier: BSD-2-Clause
/*
* Copyright (c) 2014, STMicroelectronics International N.V.
*/
/*
* Form ABI specifications:
* int __aeabi_idiv(int numerator, int denominator);
* unsigned __aeabi_uidiv(unsigned numerator, unsigned denominator);
*
* typedef struct { int quot; int rem; } idiv_return;
* typedef struct { unsigned quot; unsigned rem; } uidiv_return;
*
* __value_in_regs idiv_return __aeabi_idivmod(int numerator,
* int *denominator);
* __value_in_regs uidiv_return __aeabi_uidivmod(unsigned *numerator,
* unsigned denominator);
*/
/* struct qr - stores qutient/remainder to handle divmod EABI interfaces. */
struct qr {
unsigned q; /* computed quotient */
unsigned r; /* computed remainder */
unsigned q_n; /* specficies if quotient shall be negative */
unsigned r_n; /* specficies if remainder shall be negative */
};
static void uint_div_qr(unsigned numerator, unsigned denominator,
struct qr *qr);
/* returns in R0 and R1 by tail calling an asm function */
unsigned __aeabi_uidivmod(unsigned numerator, unsigned denominator);
unsigned __aeabi_uidiv(unsigned numerator, unsigned denominator);
/* returns in R0 and R1 by tail calling an asm function */
signed __aeabi_idivmod(signed numerator, signed denominator);
signed __aeabi_idiv(signed numerator, signed denominator);
/*
* __ste_idivmod_ret_t __aeabi_idivmod(signed numerator, signed denominator)
* Numerator and Denominator are received in R0 and R1.
* Where __ste_idivmod_ret_t is returned in R0 and R1.
*
* __ste_uidivmod_ret_t __aeabi_uidivmod(unsigned numerator,
* unsigned denominator)
* Numerator and Denominator are received in R0 and R1.
* Where __ste_uidivmod_ret_t is returned in R0 and R1.
*/
#ifdef __GNUC__
signed ret_idivmod_values(signed quotient, signed remainder);
unsigned ret_uidivmod_values(unsigned quotient, unsigned remainder);
#else
#error "Compiler not supported"
#endif
static void division_qr(unsigned n, unsigned p, struct qr *qr)
{
unsigned i = 1, q = 0;
if (p == 0) {
qr->r = 0xFFFFFFFF; /* division by 0 */
return;
}
while ((p >> 31) == 0) {
i = i << 1; /* count the max division steps */
p = p << 1; /* increase p until it has maximum size*/
}
while (i > 0) {
q = q << 1; /* write bit in q at index (size-1) */
if (n >= p)
{
n -= p;
q++;
}
p = p >> 1; /* decrease p */
i = i >> 1; /* decrease remaining size in q */
}
qr->r = n;
qr->q = q;
}
static void uint_div_qr(unsigned numerator, unsigned denominator, struct qr *qr)
{
division_qr(numerator, denominator, qr);
/* negate quotient and/or remainder according to requester */
if (qr->q_n)
qr->q = -qr->q;
if (qr->r_n)
qr->r = -qr->r;
}
unsigned __aeabi_uidiv(unsigned numerator, unsigned denominator)
{
struct qr qr = { .q_n = 0, .r_n = 0 };
uint_div_qr(numerator, denominator, &qr);
return qr.q;
}
unsigned __aeabi_uidivmod(unsigned numerator, unsigned denominator)
{
struct qr qr = { .q_n = 0, .r_n = 0 };
uint_div_qr(numerator, denominator, &qr);
return ret_uidivmod_values(qr.q, qr.r);
}
signed __aeabi_idiv(signed numerator, signed denominator)
{
struct qr qr = { .q_n = 0, .r_n = 0 };
if (((numerator < 0) && (denominator > 0)) ||
((numerator > 0) && (denominator < 0)))
qr.q_n = 1; /* quotient shall be negate */
if (numerator < 0) {
numerator = -numerator;
qr.r_n = 1; /* remainder shall be negate */
}
if (denominator < 0)
denominator = -denominator;
uint_div_qr(numerator, denominator, &qr);
return qr.q;
}
signed __aeabi_idivmod(signed numerator, signed denominator)
{
struct qr qr = { .q_n = 0, .r_n = 0 };
if (((numerator < 0) && (denominator > 0)) ||
((numerator > 0) && (denominator < 0)))
qr.q_n = 1; /* quotient shall be negate */
if (numerator < 0) {
numerator = -numerator;
qr.r_n = 1; /* remainder shall be negate */
}
if (denominator < 0)
denominator = -denominator;
uint_div_qr(numerator, denominator, &qr);
return ret_idivmod_values(qr.q, qr.r);
}

View File

@ -1,58 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2016 Freescale Semiconductor, Inc.
*
*/
struct lpuart_fsl_reg32 {
u32 verid;
u32 param;
u32 global;
u32 pincfg;
u32 baud;
u32 stat;
u32 ctrl;
u32 data;
u32 match;
u32 modir;
u32 fifo;
u32 water;
};
struct lpuart_fsl {
u8 ubdh;
u8 ubdl;
u8 uc1;
u8 uc2;
u8 us1;
u8 us2;
u8 uc3;
u8 ud;
u8 uma1;
u8 uma2;
u8 uc4;
u8 uc5;
u8 ued;
u8 umodem;
u8 uir;
u8 reserved;
u8 upfifo;
u8 ucfifo;
u8 usfifo;
u8 utwfifo;
u8 utcfifo;
u8 urwfifo;
u8 urcfifo;
u8 rsvd[28];
};
/* Used on i.MX7ULP */
#define LPUART_BAUD_BOTHEDGE_MASK (0x20000)
#define LPUART_BAUD_OSR_MASK (0x1F000000)
#define LPUART_BAUD_OSR_SHIFT (24)
#define LPUART_BAUD_OSR(x) ((((u32)(x)) << 24) & 0x1F000000)
#define LPUART_BAUD_SBR_MASK (0x1FFF)
#define LPUART_BAUD_SBR_SHIFT (0U)
#define LPUART_BAUD_SBR(x) (((u32)(x)) & 0x1FFF)
#define LPUART_BAUD_M10_MASK (0x20000000U)
#define LPUART_BAUD_SBNS_MASK (0x2000U)

View File

@ -1,27 +0,0 @@
#!/usr/bin/env python3
import sys
import textwrap
def main():
if len(sys.argv) < 3:
print(f'Usage: {sys.argv[0]} u-boot.bin uboot_bin.h.tpl uboot_bin.h')
with open(sys.argv[2]) as f:
tpl = f.read()
with open(sys.argv[1], 'rb') as ui, open(sys.argv[3], 'w') as header:
uboot = ui.read()
out = ''
for i, b in enumerate(uboot):
out += f'{b:#04x}, '
if (i+1) % 16 == 0:
out = out.rstrip()
out += '\n'
formatted = tpl.format(uboot_size=len(uboot), uboot_bin=textwrap.indent(out, ' '))
header.write(formatted)
main()

File diff suppressed because it is too large Load Diff

View File

@ -1,332 +1,14 @@
#include "common.h"
#include "pcc.h"
#include "imx-regs.h"
#include "fsl_lpuart.h"
#define US1_TDRE (1 << 7)
#define US1_RDRF (1 << 5)
#define US1_OR (1 << 3)
#define UC2_TE (1 << 3)
#define UC2_RE (1 << 2)
#define CFIFO_TXFLUSH (1 << 7)
#define CFIFO_RXFLUSH (1 << 6)
#define SFIFO_RXOF (1 << 2)
#define SFIFO_RXUF (1 << 0)
#define STAT_LBKDIF (1 << 31)
#define STAT_RXEDGIF (1 << 30)
#define STAT_TDRE (1 << 23)
#define STAT_RDRF (1 << 21)
#define STAT_IDLE (1 << 20)
#define STAT_OR (1 << 19)
#define STAT_NF (1 << 18)
#define STAT_FE (1 << 17)
#define STAT_PF (1 << 16)
#define STAT_MA1F (1 << 15)
#define STAT_MA2F (1 << 14)
#define STAT_FLAGS (STAT_LBKDIF | STAT_RXEDGIF | STAT_IDLE | STAT_OR | \
STAT_NF | STAT_FE | STAT_PF | STAT_MA1F | STAT_MA2F)
#define CTRL_ORIE (1 << 27)
#define CTRL_NEIE (1 << 26)
#define CTRL_FEIE (1 << 25)
#define CTRL_PEIE (1 << 24)
#define CTRL_TIE (1 << 23)
#define CTRL_TCIE (1 << 22)
#define CTRL_RIE (1 << 21)
#define CTRL_ILIE (1 << 20)
#define CTRL_TE (1 << 19)
#define CTRL_RE (1 << 18)
#define CTRL_MA1IE (1 << 15)
#define CTRL_MA2IE (1 << 14)
#define FIFO_TXOFE (1 << 9)
#define FIFO_RXUFE (1 << 8)
#define FIFO_TXFE (1 << 7)
#define FIFO_RXFE (1 << 3)
static struct lpuart_fsl_reg32* regs[] = {
(struct lpuart_fsl_reg32*)0x4103A000,
(struct lpuart_fsl_reg32*)0x4103B000,
(struct lpuart_fsl_reg32*)0x410AB000,
(struct lpuart_fsl_reg32*)0x410AC000,
(struct lpuart_fsl_reg32*)0x402D0000,
(struct lpuart_fsl_reg32*)0x402E0000,
(struct lpuart_fsl_reg32*)0x40A60000,
(struct lpuart_fsl_reg32*)0x40A70000,
};
static void lpuart_read32(u32 *addr, u32 *val) {
*(u32 *)val = readl(addr);
}
static void lpuart_write32(u32 *addr, u32 val) {
writel(val, addr);
}
// clk
static enum scg_clk pcc_clksrc[2][7] = {
{
SCG_NIC1_BUS_CLK,
SCG_NIC1_CLK,
SCG_DDR_CLK,
SCG_APLL_PFD2_CLK,
SCG_APLL_PFD1_CLK,
SCG_APLL_PFD0_CLK,
USB_PLL_OUT,
},
{
SCG_SOSC_DIV2_CLK,
MIPI_PLL_OUT,
SCG_FIRC_DIV2_CLK,
SCG_ROSC_CLK,
SCG_NIC1_BUS_CLK,
SCG_NIC1_CLK,
SCG_APLL_PFD3_CLK,
},
};
static struct pcc_entry pcc_arrays[] = {
{PCC2_RBASE, DMA1_PCC2_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV},
{PCC2_RBASE, RGPIO1_PCC2_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV},
{PCC2_RBASE, FLEXBUS0_PCC2_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV},
{PCC2_RBASE, SEMA42_1_PCC2_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV},
{PCC2_RBASE, DMA1_CH_MUX0_PCC2_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV},
{PCC2_RBASE, SNVS_PCC2_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV},
{PCC2_RBASE, CAAM_PCC2_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV},
{PCC2_RBASE, LPTPM4_PCC2_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV},
{PCC2_RBASE, LPTPM5_PCC2_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV},
{PCC2_RBASE, LPIT1_PCC2_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV},
{PCC2_RBASE, LPSPI2_PCC2_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV},
{PCC2_RBASE, LPSPI3_PCC2_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV},
{PCC2_RBASE, LPI2C4_PCC2_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV},
{PCC2_RBASE, LPI2C5_PCC2_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV},
{PCC2_RBASE, LPUART4_PCC2_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV},
{PCC2_RBASE, LPUART5_PCC2_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV},
{PCC2_RBASE, FLEXIO1_PCC2_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV},
{PCC2_RBASE, USBOTG0_PCC2_SLOT, CLKSRC_PER_PLAT, PCC_HAS_DIV},
{PCC2_RBASE, USBOTG1_PCC2_SLOT, CLKSRC_PER_PLAT, PCC_HAS_DIV},
{PCC2_RBASE, USBPHY_PCC2_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV},
{PCC2_RBASE, USB_PL301_PCC2_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV},
{PCC2_RBASE, USDHC0_PCC2_SLOT, CLKSRC_PER_PLAT, PCC_HAS_DIV},
{PCC2_RBASE, USDHC1_PCC2_SLOT, CLKSRC_PER_PLAT, PCC_HAS_DIV},
{PCC2_RBASE, WDG1_PCC2_SLOT, CLKSRC_PER_BUS, PCC_HAS_DIV},
{PCC2_RBASE, WDG2_PCC2_SLOT, CLKSRC_PER_BUS, PCC_HAS_DIV},
{PCC3_RBASE, LPTPM6_PCC3_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV},
{PCC3_RBASE, LPTPM7_PCC3_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV},
{PCC3_RBASE, LPI2C6_PCC3_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV},
{PCC3_RBASE, LPI2C7_PCC3_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV},
{PCC3_RBASE, LPUART6_PCC3_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV},
{PCC3_RBASE, LPUART7_PCC3_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV},
{PCC3_RBASE, VIU0_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV},
{PCC3_RBASE, DSI0_PCC3_SLOT, CLKSRC_PER_BUS, PCC_HAS_DIV},
{PCC3_RBASE, LCDIF0_PCC3_SLOT, CLKSRC_PER_PLAT, PCC_HAS_DIV},
{PCC3_RBASE, MMDC0_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV},
{PCC3_RBASE, PORTC_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV},
{PCC3_RBASE, PORTD_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV},
{PCC3_RBASE, PORTE_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV},
{PCC3_RBASE, PORTF_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV},
{PCC3_RBASE, GPU3D_PCC3_SLOT, CLKSRC_PER_PLAT, PCC_NO_DIV},
{PCC3_RBASE, GPU2D_PCC3_SLOT, CLKSRC_PER_PLAT, PCC_NO_DIV},
};
int pcc_clock_get_clksrc(enum pcc_clk clk, enum scg_clk *src)
{
u32 reg, val, clksrc_type;
clksrc_type = pcc_arrays[clk].clksrc;
if (clksrc_type >= CLKSRC_NO_PCS) {
return 1;
}
reg = pcc_arrays[clk].pcc_base + pcc_arrays[clk].pcc_slot * 4;
val = readl(reg);
if (!(val & PCC_PR_MASK)) {
return 2;
}
val &= PCC_PCS_MASK;
val = (val >> PCC_PCS_OFFSET);
if (!val) {
return 3;
}
*src = pcc_clksrc[clksrc_type][val - 1];
return 0;
}
u32 pcc_clock_get_rate(enum pcc_clk clk)
{
u32 reg, val, rate, frac, div;
enum scg_clk parent;
int ret;
ret = pcc_clock_get_clksrc(clk, &parent);
if (ret)
return 0;
rate = scg_clk_get_rate(parent);
if (pcc_arrays[clk].div == PCC_HAS_DIV) {
reg = pcc_arrays[clk].pcc_base + pcc_arrays[clk].pcc_slot * 4;
val = readl(reg);
frac = (val & PCC_FRAC_MASK) >> PCC_FRAC_OFFSET;
div = (val & PCC_PCD_MASK) >> PCC_PCD_OFFSET;
rate = rate * (frac + 1) / (div + 1);
}
return rate;
}
static void setbrg(struct lpuart_fsl_reg32* reg, int baudrate)
{
u32 sbr, osr, baud_diff, tmp_osr, tmp_sbr, tmp_diff, tmp;
u32 clk = pcc_clock_get_rate(PER_CLK_LPUART4);
baud_diff = baudrate;
osr = 0;
sbr = 0;
for (tmp_osr = 4; tmp_osr <= 32; tmp_osr++) {
tmp_sbr = (clk / (baudrate * tmp_osr));
if (tmp_sbr == 0)
tmp_sbr = 1;
/*calculate difference in actual buad w/ current values */
tmp_diff = (clk / (tmp_osr * tmp_sbr));
tmp_diff = tmp_diff - baudrate;
/* select best values between sbr and sbr+1 */
if (tmp_diff > (baudrate - (clk / (tmp_osr * (tmp_sbr + 1))))) {
tmp_diff = baudrate - (clk / (tmp_osr * (tmp_sbr + 1)));
tmp_sbr++;
}
if (tmp_diff <= baud_diff) {
baud_diff = tmp_diff;
osr = tmp_osr;
sbr = tmp_sbr;
}
}
tmp = readl(&reg->baud);
if ((osr > 3) && (osr < 8))
tmp |= LPUART_BAUD_BOTHEDGE_MASK;
tmp &= ~LPUART_BAUD_OSR_MASK;
tmp |= LPUART_BAUD_OSR(osr-1);
tmp &= ~LPUART_BAUD_SBR_MASK;
tmp |= LPUART_BAUD_SBR(sbr);
/* explicitly disable 10 bit mode & set 1 stop bit */
tmp &= ~(LPUART_BAUD_M10_MASK | LPUART_BAUD_SBNS_MASK);
writel(tmp, &reg->baud);
}
static void serial_putc(struct lpuart_fsl_reg32* reg, const char c) {
u32 stat;
while (1) {
lpuart_read32(&reg->stat, &stat);
if (stat & STAT_TDRE) {
break;
}
}
lpuart_write32(&reg->data, c);
}
struct iomux {
u16 buf;
u8 mode;
u8 pull;
};
void iomux() {
u32 pcc_u4;
struct iomux imu4;
pcc_u4 = readl(0x403f00b4);
pcc_u4 |= (1 << 30);
writel(pcc_u4, 0x403f00b4);
imu4.buf = 0b0011; // PTC2 U4 TX
imu4.mode = 0b0100; // PTC2 U4 TX
imu4.pull = 0b11; // PTC2 U4 TX
writel(*((u32 *)&imu4), (u32 *)0x40ac0008);
//writel(0x0000000a, 0x400f0004);
//writel(0x000fffff, 0x400f0004);
//writel(0x00000fff, 0x400f0044);
//writel(0x0000ffff, 0x400f0084);
//writel(0x000fffff, 0x400f00c4);
}
void main() { void main() {
u32 ctrl, baud, i; char *str = "Hello World";
int aa = 1234;
writel(0x00000004, 0x400f0004); int i;
for (i=0; i<999; i++) {
iomux();
lpuart_write32(&regs[4]->global, 0); // De-assert reset:w
lpuart_read32(&regs[4]->baud, &baud);
baud &= ~(1 << 15); // LBKDIE
baud &= ~(1 << 14); // RXEDGIE
lpuart_write32(&regs[4]->baud, baud);
lpuart_read32(&regs[4]->ctrl, &ctrl);
ctrl &= ~CTRL_ORIE;
ctrl &= ~CTRL_NEIE;
ctrl &= ~CTRL_FEIE;
ctrl &= ~CTRL_PEIE;
ctrl &= ~CTRL_TIE;
ctrl &= ~CTRL_TCIE;
ctrl &= ~CTRL_RIE;
ctrl &= ~CTRL_ILIE;
ctrl &= ~CTRL_MA1IE;
ctrl &= ~CTRL_MA2IE;
ctrl &= ~CTRL_RE;
ctrl &= ~CTRL_TE;
lpuart_write32(&regs[4]->ctrl, ctrl);
lpuart_write32(&regs[4]->modir, 0);
lpuart_write32(&regs[4]->fifo, ~(FIFO_TXFE | FIFO_RXFE));
lpuart_write32(&regs[4]->match, 0);
setbrg(regs[4], 115200);
ctrl |= CTRL_RE;
ctrl |= CTRL_TE;
lpuart_write32(&regs[4]->ctrl, ctrl);
// putc
while (1) {
for (i=0; i<8; i++) {
serial_putc(regs[4], 'Y');
serial_putc(regs[4], '\n');
}
}
asm volatile( asm volatile(
"mov pc, lr\n" "mrc p15, 0, r10, c1, c0, 0\n"
"bic r10, #1\n"
"mcr p15, 0, r10, c1, c0, 0\n"
: "=r" (aa)
); );
aa += 1;
}
} }

View File

@ -1,24 +0,0 @@
#include "common.h"
void main() {
u16** fb = (u16 **)0x62000000;
pixel_t px = {
.r = 255,
.g = 0,
.b = 0
};
prepare_fb(fb);
writel(0x00000001, 0x40aa0008); // Clear RUN
writel(0x62000000, 0x40aa0040); // Set current FB
writel(0x62000000, 0x40aa0050); // Set next FB
writel(0x00000001, 0x40aa0004); // Set RUN
//bitblt(fb, px, 100, 100);
asm volatile(
"foo:\n"
"b foo\n"
"mov pc, lr\n"
);
}

View File

@ -1,34 +0,0 @@
#include "common.h"
#include "uboot_bin.h"
#define VIRT_START (unsigned char *)0x8c000000
void main() {
int i;
u8* ptr = VIRT_START;
// Turn off interrupts
asm volatile (
"cpsid if \n"
);
for (i=0; i<UBOOT_SIZE; i++) {
writeb(uboot_bin[i], ptr);
ptr++;
}
asm volatile (
"mrc p15, 0, r8, c14, c2, 1 \n"
"bic r8, r8, #1 \n"
"mcr p15, 0, r8, c14, c2, 1 \n"
"mrc p15, 0, r8, c14, c3, 1 \n"
"bic r8, r8, #1 \n"
"mcr p15, 0, r8, c14, c3, 1 \n"
"mrc p15, 0, r10, c1, c0, 0 \n"
"bic r10, r10, #1 \n"
"mcr p15, 0, r10, c1, c0, 0 \n"
"ldr r0, =0x60200000 \n"
"mov pc, r0"
);
}

View File

@ -1,371 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2016 Freescale Semiconductor, Inc.
*/
#ifndef _ASM_ARCH_PCC_H
#define _ASM_ARCH_PCC_H
#include "scg.h"
/* PCC2 */
enum pcc2_entry {
/* On-Platform (32 entries) */
RSVD0_PCC2_SLOT = 0,
RSVD1_PCC2_SLOT = 1,
CA7_GIC_PCC2_SLOT = 2,
RSVD3_PCC2_SLOT = 3,
RSVD4_PCC2_SLOT = 4,
RSVD5_PCC2_SLOT = 5,
RSVD6_PCC2_SLOT = 6,
RSVD7_PCC2_SLOT = 7,
DMA1_PCC2_SLOT = 8,
RSVD9_PCC2_SLOT = 9,
RSVD10_PCC2_SLOT = 10,
RSVD11_PCC2_SLOT = 11,
RSVD12_PCC2_SLOT = 12,
RSVD13_PCC2_SLOT = 13,
RSVD14_PCC2_SLOT = 14,
RGPIO1_PCC2_SLOT = 15,
FLEXBUS0_PCC2_SLOT = 16,
RSVD17_PCC2_SLOT = 17,
RSVD18_PCC2_SLOT = 18,
RSVD19_PCC2_SLOT = 19,
RSVD20_PCC2_SLOT = 20,
RSVD21_PCC2_SLOT = 21,
RSVD22_PCC2_SLOT = 22,
RSVD23_PCC2_SLOT = 23,
RSVD24_PCC2_SLOT = 24,
RSVD25_PCC2_SLOT = 25,
RSVD26_PCC2_SLOT = 26,
SEMA42_1_PCC2_SLOT = 27,
RSVD28_PCC2_SLOT = 28,
RSVD29_PCC2_SLOT = 29,
RSVD30_PCC2_SLOT = 30,
RSVD31_PCC2_SLOT = 31,
/* Off-Platform (96 entries) */
RSVD32_PCC2_SLOT = 32,
DMA1_CH_MUX0_PCC2_SLOT = 33,
MU_B_PCC2_SLOT = 34,
SNVS_PCC2_SLOT = 35,
CAAM_PCC2_SLOT = 36,
LPTPM4_PCC2_SLOT = 37,
LPTPM5_PCC2_SLOT = 38,
LPIT1_PCC2_SLOT = 39,
RSVD40_PCC2_SLOT = 40,
LPSPI2_PCC2_SLOT = 41,
LPSPI3_PCC2_SLOT = 42,
LPI2C4_PCC2_SLOT = 43,
LPI2C5_PCC2_SLOT = 44,
LPUART4_PCC2_SLOT = 45,
LPUART5_PCC2_SLOT = 46,
RSVD47_PCC2_SLOT = 47,
RSVD48_PCC2_SLOT = 48,
FLEXIO1_PCC2_SLOT = 49,
RSVD50_PCC2_SLOT = 50,
USBOTG0_PCC2_SLOT = 51,
USBOTG1_PCC2_SLOT = 52,
USBPHY_PCC2_SLOT = 53,
USB_PL301_PCC2_SLOT = 54,
USDHC0_PCC2_SLOT = 55,
USDHC1_PCC2_SLOT = 56,
RSVD57_PCC2_SLOT = 57,
TRGMUX1_PCC2_SLOT = 58,
RSVD59_PCC2_SLOT = 59,
RSVD60_PCC2_SLOT = 60,
WDG1_PCC2_SLOT = 61,
SCG1_PCC2_SLOT = 62,
PCC2_PCC2_SLOT = 63,
PMC1_PCC2_SLOT = 64,
SMC1_PCC2_SLOT = 65,
RCM1_PCC2_SLOT = 66,
WDG2_PCC2_SLOT = 67,
RSVD68_PCC2_SLOT = 68,
TEST_SPACE1_PCC2_SLOT = 69,
TEST_SPACE2_PCC2_SLOT = 70,
TEST_SPACE3_PCC2_SLOT = 71,
RSVD72_PCC2_SLOT = 72,
RSVD73_PCC2_SLOT = 73,
RSVD74_PCC2_SLOT = 74,
RSVD75_PCC2_SLOT = 75,
RSVD76_PCC2_SLOT = 76,
RSVD77_PCC2_SLOT = 77,
RSVD78_PCC2_SLOT = 78,
RSVD79_PCC2_SLOT = 79,
RSVD80_PCC2_SLOT = 80,
RSVD81_PCC2_SLOT = 81,
RSVD82_PCC2_SLOT = 82,
RSVD83_PCC2_SLOT = 83,
RSVD84_PCC2_SLOT = 84,
RSVD85_PCC2_SLOT = 85,
RSVD86_PCC2_SLOT = 86,
RSVD87_PCC2_SLOT = 87,
RSVD88_PCC2_SLOT = 88,
RSVD89_PCC2_SLOT = 89,
RSVD90_PCC2_SLOT = 90,
RSVD91_PCC2_SLOT = 91,
RSVD92_PCC2_SLOT = 92,
RSVD93_PCC2_SLOT = 93,
RSVD94_PCC2_SLOT = 94,
RSVD95_PCC2_SLOT = 95,
RSVD96_PCC2_SLOT = 96,
RSVD97_PCC2_SLOT = 97,
RSVD98_PCC2_SLOT = 98,
RSVD99_PCC2_SLOT = 99,
RSVD100_PCC2_SLOT = 100,
RSVD101_PCC2_SLOT = 101,
RSVD102_PCC2_SLOT = 102,
RSVD103_PCC2_SLOT = 103,
RSVD104_PCC2_SLOT = 104,
RSVD105_PCC2_SLOT = 105,
RSVD106_PCC2_SLOT = 106,
RSVD107_PCC2_SLOT = 107,
RSVD108_PCC2_SLOT = 108,
RSVD109_PCC2_SLOT = 109,
RSVD110_PCC2_SLOT = 110,
RSVD111_PCC2_SLOT = 111,
RSVD112_PCC2_SLOT = 112,
RSVD113_PCC2_SLOT = 113,
RSVD114_PCC2_SLOT = 114,
RSVD115_PCC2_SLOT = 115,
RSVD116_PCC2_SLOT = 116,
RSVD117_PCC2_SLOT = 117,
RSVD118_PCC2_SLOT = 118,
RSVD119_PCC2_SLOT = 119,
RSVD120_PCC2_SLOT = 120,
RSVD121_PCC2_SLOT = 121,
RSVD122_PCC2_SLOT = 122,
RSVD123_PCC2_SLOT = 123,
RSVD124_PCC2_SLOT = 124,
RSVD125_PCC2_SLOT = 125,
RSVD126_PCC2_SLOT = 126,
RSVD127_PCC2_SLOT = 127,
};
enum pcc3_entry {
/* On-Platform (32 entries) */
RSVD0_PCC3_SLOT = 0,
RSVD1_PCC3_SLOT = 1,
RSVD2_PCC3_SLOT = 2,
RSVD3_PCC3_SLOT = 3,
RSVD4_PCC3_SLOT = 4,
RSVD5_PCC3_SLOT = 5,
RSVD6_PCC3_SLOT = 6,
RSVD7_PCC3_SLOT = 7,
RSVD8_PCC3_SLOT = 8,
RSVD9_PCC3_SLOT = 9,
RSVD10_PCC3_SLOT = 10,
RSVD11_PCC3_SLOT = 11,
RSVD12_PCC3_SLOT = 12,
RSVD13_PCC3_SLOT = 13,
RSVD14_PCC3_SLOT = 14,
RSVD15_PCC3_SLOT = 15,
ROMCP1_PCC3_SLOT = 16,
RSVD17_PCC3_SLOT = 17,
RSVD18_PCC3_SLOT = 18,
RSVD19_PCC3_SLOT = 19,
RSVD20_PCC3_SLOT = 20,
RSVD21_PCC3_SLOT = 21,
RSVD22_PCC3_SLOT = 22,
RSVD23_PCC3_SLOT = 23,
RSVD24_PCC3_SLOT = 24,
RSVD25_PCC3_SLOT = 25,
RSVD26_PCC3_SLOT = 26,
RSVD27_PCC3_SLOT = 27,
RSVD28_PCC3_SLOT = 28,
RSVD29_PCC3_SLOT = 29,
RSVD30_PCC3_SLOT = 30,
RSVD31_PCC3_SLOT = 31,
/* Off-Platform (96 entries) */
RSVD32_PCC3_SLOT = 32,
LPTPM6_PCC3_SLOT = 33,
LPTPM7_PCC3_SLOT = 34,
RSVD35_PCC3_SLOT = 35,
LPI2C6_PCC3_SLOT = 36,
LPI2C7_PCC3_SLOT = 37,
LPUART6_PCC3_SLOT = 38,
LPUART7_PCC3_SLOT = 39,
VIU0_PCC3_SLOT = 40,
DSI0_PCC3_SLOT = 41,
LCDIF0_PCC3_SLOT = 42,
MMDC0_PCC3_SLOT = 43,
IOMUXC1_PCC3_SLOT = 44,
IOMUXC_DDR_PCC3_SLOT = 45,
PORTC_PCC3_SLOT = 46,
PORTD_PCC3_SLOT = 47,
PORTE_PCC3_SLOT = 48,
PORTF_PCC3_SLOT = 49,
RSVD50_PCC3_SLOT = 50,
PCC3_PCC3_SLOT = 51,
RSVD52_PCC3_SLOT = 52,
WKPU_PCC3_SLOT = 53,
RSVD54_PCC3_SLOT = 54,
RSVD55_PCC3_SLOT = 55,
RSVD56_PCC3_SLOT = 56,
RSVD57_PCC3_SLOT = 57,
RSVD58_PCC3_SLOT = 58,
RSVD59_PCC3_SLOT = 59,
RSVD60_PCC3_SLOT = 60,
RSVD61_PCC3_SLOT = 61,
RSVD62_PCC3_SLOT = 62,
RSVD63_PCC3_SLOT = 63,
RSVD64_PCC3_SLOT = 64,
RSVD65_PCC3_SLOT = 65,
RSVD66_PCC3_SLOT = 66,
RSVD67_PCC3_SLOT = 67,
RSVD68_PCC3_SLOT = 68,
RSVD69_PCC3_SLOT = 69,
RSVD70_PCC3_SLOT = 70,
RSVD71_PCC3_SLOT = 71,
RSVD72_PCC3_SLOT = 72,
RSVD73_PCC3_SLOT = 73,
RSVD74_PCC3_SLOT = 74,
RSVD75_PCC3_SLOT = 75,
RSVD76_PCC3_SLOT = 76,
RSVD77_PCC3_SLOT = 77,
RSVD78_PCC3_SLOT = 78,
RSVD79_PCC3_SLOT = 79,
RSVD80_PCC3_SLOT = 80,
GPU3D_PCC3_SLOT = 81,
GPU2D_PCC3_SLOT = 82,
RSVD83_PCC3_SLOT = 83,
RSVD84_PCC3_SLOT = 84,
RSVD85_PCC3_SLOT = 85,
RSVD86_PCC3_SLOT = 86,
RSVD87_PCC3_SLOT = 87,
RSVD88_PCC3_SLOT = 88,
RSVD89_PCC3_SLOT = 89,
RSVD90_PCC3_SLOT = 90,
RSVD91_PCC3_SLOT = 91,
RSVD92_PCC3_SLOT = 92,
RSVD93_PCC3_SLOT = 93,
RSVD94_PCC3_SLOT = 94,
RSVD95_PCC3_SLOT = 95,
RSVD96_PCC3_SLOT = 96,
RSVD97_PCC3_SLOT = 97,
RSVD98_PCC3_SLOT = 98,
RSVD99_PCC3_SLOT = 99,
RSVD100_PCC3_SLOT = 100,
RSVD101_PCC3_SLOT = 101,
RSVD102_PCC3_SLOT = 102,
RSVD103_PCC3_SLOT = 103,
RSVD104_PCC3_SLOT = 104,
RSVD105_PCC3_SLOT = 105,
RSVD106_PCC3_SLOT = 106,
RSVD107_PCC3_SLOT = 107,
RSVD108_PCC3_SLOT = 108,
RSVD109_PCC3_SLOT = 109,
RSVD110_PCC3_SLOT = 110,
RSVD111_PCC3_SLOT = 111,
RSVD112_PCC3_SLOT = 112,
RSVD113_PCC3_SLOT = 113,
RSVD114_PCC3_SLOT = 114,
RSVD115_PCC3_SLOT = 115,
RSVD116_PCC3_SLOT = 116,
RSVD117_PCC3_SLOT = 117,
RSVD118_PCC3_SLOT = 118,
RSVD119_PCC3_SLOT = 119,
RSVD120_PCC3_SLOT = 120,
RSVD121_PCC3_SLOT = 121,
RSVD122_PCC3_SLOT = 122,
RSVD123_PCC3_SLOT = 123,
RSVD124_PCC3_SLOT = 124,
RSVD125_PCC3_SLOT = 125,
RSVD126_PCC3_SLOT = 126,
RSVD127_PCC3_SLOT = 127,
};
/* PCC registers */
#define PCC_PR_OFFSET 31
#define PCC_PR_MASK (0x1 << PCC_PR_OFFSET)
#define PCC_CGC_OFFSET 30
#define PCC_CGC_MASK (0x1 << PCC_CGC_OFFSET)
#define PCC_INUSE_OFFSET 29
#define PCC_INUSE_MASK (0x1 << PCC_INUSE_OFFSET)
#define PCC_PCS_OFFSET 24
#define PCC_PCS_MASK (0x7 << PCC_PCS_OFFSET)
#define PCC_FRAC_OFFSET 4
#define PCC_FRAC_MASK (0x1 << PCC_FRAC_OFFSET)
#define PCC_PCD_OFFSET 0
#define PCC_PCD_MASK (0xf << PCC_PCD_OFFSET)
enum pcc_clksrc_type {
CLKSRC_PER_PLAT = 0,
CLKSRC_PER_BUS = 1,
CLKSRC_NO_PCS = 2,
};
enum pcc_div_type {
PCC_HAS_DIV,
PCC_NO_DIV,
};
/* All peripheral clocks on A7 PCCs */
enum pcc_clk {
/*PCC2 clocks*/
PER_CLK_DMA1 = 0,
PER_CLK_RGPIO2P1,
PER_CLK_FLEXBUS,
PER_CLK_SEMA42_1,
PER_CLK_DMA_MUX1,
PER_CLK_SNVS,
PER_CLK_CAAM,
PER_CLK_LPTPM4,
PER_CLK_LPTPM5,
PER_CLK_LPIT1,
PER_CLK_LPSPI2,
PER_CLK_LPSPI3,
PER_CLK_LPI2C4,
PER_CLK_LPI2C5,
PER_CLK_LPUART4,
PER_CLK_LPUART5,
PER_CLK_FLEXIO1,
PER_CLK_USB0,
PER_CLK_USB1,
PER_CLK_USB_PHY,
PER_CLK_USB_PL301,
PER_CLK_USDHC0,
PER_CLK_USDHC1,
PER_CLK_WDG1,
PER_CLK_WDG2,
/*PCC3 clocks*/
PER_CLK_LPTPM6,
PER_CLK_LPTPM7,
PER_CLK_LPI2C6,
PER_CLK_LPI2C7,
PER_CLK_LPUART6,
PER_CLK_LPUART7,
PER_CLK_VIU,
PER_CLK_DSI,
PER_CLK_LCDIF,
PER_CLK_MMDC,
PER_CLK_PCTLC,
PER_CLK_PCTLD,
PER_CLK_PCTLE,
PER_CLK_PCTLF,
PER_CLK_GPU3D,
PER_CLK_GPU2D,
};
/* This structure keeps info for each pcc slot */
struct pcc_entry {
u32 pcc_base;
u32 pcc_slot;
enum pcc_clksrc_type clksrc;
enum pcc_div_type div;
};
int pcc_clock_enable(enum pcc_clk clk, int enable);
int pcc_clock_sel(enum pcc_clk clk, enum scg_clk src);
int pcc_clock_div_config(enum pcc_clk clk, int frac, u8 div);
int pcc_clock_is_enable(enum pcc_clk clk);
int pcc_clock_get_clksrc(enum pcc_clk clk, enum scg_clk *src);
u32 pcc_clock_get_rate(enum pcc_clk clk);
#endif

View File

@ -1,640 +0,0 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2016 Freescale Semiconductor, Inc.
*/
#include "common.h"
//#include <div64.h>
//#include <asm/io.h>
//#include <errno.h>
#include "imx-regs.h"
#include "pcc.h"
//#include <asm/arch/sys_proto.h>
scg_p scg1_regs = (scg_p)SCG1_RBASE;
////////////////////////////////////////////////////////////////
static u32 scg_src_get_rate(enum scg_clk clksrc)
{
u32 reg;
switch (clksrc) {
case SCG_SOSC_CLK:
reg = readl(&scg1_regs->sosccsr);
if (!(reg & SCG_SOSC_CSR_SOSCVLD_MASK))
return 0;
return 24000000;
case SCG_FIRC_CLK:
reg = readl(&scg1_regs->firccsr);
if (!(reg & SCG_FIRC_CSR_FIRCVLD_MASK))
return 0;
return 48000000;
case SCG_SIRC_CLK:
reg = readl(&scg1_regs->sirccsr);
if (!(reg & SCG_SIRC_CSR_SIRCVLD_MASK))
return 0;
return 16000000;
case SCG_ROSC_CLK:
reg = readl(&scg1_regs->rtccsr);
if (!(reg & SCG_ROSC_CSR_ROSCVLD_MASK))
return 0;
return 32768;
default:
break;
}
return 0;
}
//////////////////////////////////////////////////////////////////////
static u32 scg_sircdiv_get_rate(enum scg_clk clk)
{
u32 reg, val, rate;
u32 shift, mask;
switch (clk) {
case SCG_SIRC_DIV1_CLK:
mask = SCG_SIRCDIV_DIV1_MASK;
shift = SCG_SIRCDIV_DIV1_SHIFT;
break;
case SCG_SIRC_DIV2_CLK:
mask = SCG_SIRCDIV_DIV2_MASK;
shift = SCG_SIRCDIV_DIV2_SHIFT;
break;
case SCG_SIRC_DIV3_CLK:
mask = SCG_SIRCDIV_DIV3_MASK;
shift = SCG_SIRCDIV_DIV3_SHIFT;
break;
default:
return 0;
}
reg = readl(&scg1_regs->sirccsr);
if (!(reg & SCG_SIRC_CSR_SIRCVLD_MASK))
return 0;
reg = readl(&scg1_regs->sircdiv);
val = (reg & mask) >> shift;
if (!val) /*clock disabled*/
return 0;
rate = scg_src_get_rate(SCG_SIRC_CLK);
rate = rate / (1 << (val - 1));
return rate;
}
////////////////////////////////////////////////////////////////
static u32 scg_fircdiv_get_rate(enum scg_clk clk)
{
u32 reg, val, rate;
u32 shift, mask;
switch (clk) {
case SCG_FIRC_DIV1_CLK:
mask = SCG_FIRCDIV_DIV1_MASK;
shift = SCG_FIRCDIV_DIV1_SHIFT;
break;
case SCG_FIRC_DIV2_CLK:
mask = SCG_FIRCDIV_DIV2_MASK;
shift = SCG_FIRCDIV_DIV2_SHIFT;
break;
case SCG_FIRC_DIV3_CLK:
mask = SCG_FIRCDIV_DIV3_MASK;
shift = SCG_FIRCDIV_DIV3_SHIFT;
break;
default:
return 0;
}
reg = readl(&scg1_regs->firccsr);
if (!(reg & SCG_FIRC_CSR_FIRCVLD_MASK))
return 0;
reg = readl(&scg1_regs->fircdiv);
val = (reg & mask) >> shift;
if (!val) /*clock disabled*/
return 0;
rate = scg_src_get_rate(SCG_FIRC_CLK);
rate = rate / (1 << (val - 1));
return rate;
}
///////////////////////////////////////////////////////////////////////
static u32 scg_soscdiv_get_rate(enum scg_clk clk)
{
u32 reg, val, rate;
u32 shift, mask;
switch (clk) {
case SCG_SOSC_DIV1_CLK:
mask = SCG_SOSCDIV_DIV1_MASK;
shift = SCG_SOSCDIV_DIV1_SHIFT;
break;
case SCG_SOSC_DIV2_CLK:
mask = SCG_SOSCDIV_DIV2_MASK;
shift = SCG_SOSCDIV_DIV2_SHIFT;
break;
case SCG_SOSC_DIV3_CLK:
mask = SCG_SOSCDIV_DIV3_MASK;
shift = SCG_SOSCDIV_DIV3_SHIFT;
break;
default:
return 0;
}
reg = readl(&scg1_regs->sosccsr);
if (!(reg & SCG_SOSC_CSR_SOSCVLD_MASK))
return 0;
reg = readl(&scg1_regs->soscdiv);
val = (reg & mask) >> shift;
if (!val) /*clock disabled*/
return 0;
rate = scg_src_get_rate(SCG_SOSC_CLK);
rate = rate / (1 << (val - 1));
return rate;
}
///////////////////////////////////////////////////////////////
static u32 scg_apll_pfd_get_rate(enum scg_clk clk)
{
u32 reg, val, rate;
u32 shift, mask, gate, valid;
switch (clk) {
case SCG_APLL_PFD0_CLK:
gate = SCG_PLL_PFD0_GATE_MASK;
valid = SCG_PLL_PFD0_VALID_MASK;
mask = SCG_PLL_PFD0_FRAC_MASK;
shift = SCG_PLL_PFD0_FRAC_SHIFT;
break;
case SCG_APLL_PFD1_CLK:
gate = SCG_PLL_PFD1_GATE_MASK;
valid = SCG_PLL_PFD1_VALID_MASK;
mask = SCG_PLL_PFD1_FRAC_MASK;
shift = SCG_PLL_PFD1_FRAC_SHIFT;
break;
case SCG_APLL_PFD2_CLK:
gate = SCG_PLL_PFD2_GATE_MASK;
valid = SCG_PLL_PFD2_VALID_MASK;
mask = SCG_PLL_PFD2_FRAC_MASK;
shift = SCG_PLL_PFD2_FRAC_SHIFT;
break;
case SCG_APLL_PFD3_CLK:
gate = SCG_PLL_PFD3_GATE_MASK;
valid = SCG_PLL_PFD3_VALID_MASK;
mask = SCG_PLL_PFD3_FRAC_MASK;
shift = SCG_PLL_PFD3_FRAC_SHIFT;
break;
default:
return 0;
}
reg = readl(&scg1_regs->apllpfd);
if (reg & gate || !(reg & valid))
return 0;
clk_debug("scg_apll_pfd_get_rate reg 0x%x\n", reg);
val = (reg & mask) >> shift;
rate = decode_pll(PLL_A7_APLL);
rate = rate / val * 18;
clk_debug("scg_apll_pfd_get_rate rate %u\n", rate);
return rate;
}
///////////////////////////////////////////////////////////////////nn
static u32 scg_spll_pfd_get_rate(enum scg_clk clk)
{
u32 reg, val, rate;
u32 shift, mask, gate, valid;
switch (clk) {
case SCG_SPLL_PFD0_CLK:
gate = SCG_PLL_PFD0_GATE_MASK;
valid = SCG_PLL_PFD0_VALID_MASK;
mask = SCG_PLL_PFD0_FRAC_MASK;
shift = SCG_PLL_PFD0_FRAC_SHIFT;
break;
case SCG_SPLL_PFD1_CLK:
gate = SCG_PLL_PFD1_GATE_MASK;
valid = SCG_PLL_PFD1_VALID_MASK;
mask = SCG_PLL_PFD1_FRAC_MASK;
shift = SCG_PLL_PFD1_FRAC_SHIFT;
break;
case SCG_SPLL_PFD2_CLK:
gate = SCG_PLL_PFD2_GATE_MASK;
valid = SCG_PLL_PFD2_VALID_MASK;
mask = SCG_PLL_PFD2_FRAC_MASK;
shift = SCG_PLL_PFD2_FRAC_SHIFT;
break;
case SCG_SPLL_PFD3_CLK:
gate = SCG_PLL_PFD3_GATE_MASK;
valid = SCG_PLL_PFD3_VALID_MASK;
mask = SCG_PLL_PFD3_FRAC_MASK;
shift = SCG_PLL_PFD3_FRAC_SHIFT;
break;
default:
return 0;
}
reg = readl(&scg1_regs->spllpfd);
if (reg & gate || !(reg & valid))
return 0;
clk_debug("scg_spll_pfd_get_rate reg 0x%x\n", reg);
val = (reg & mask) >> shift;
rate = decode_pll(PLL_A7_SPLL);
rate = rate / val * 18;
clk_debug("scg_spll_pfd_get_rate rate %u\n", rate);
return rate;
}
static u32 scg_apll_get_rate(void)
{
u32 reg, val, rate;
reg = readl(&scg1_regs->apllcfg);
val = (reg & SCG_PLL_CFG_PLLSEL_MASK) >> SCG_PLL_CFG_PLLSEL_SHIFT;
if (!val) {
/* APLL clock after two dividers */
rate = decode_pll(PLL_A7_APLL);
val = (reg & SCG_PLL_CFG_POSTDIV1_MASK) >>
SCG_PLL_CFG_POSTDIV1_SHIFT;
rate = rate / (val + 1);
val = (reg & SCG_PLL_CFG_POSTDIV2_MASK) >>
SCG_PLL_CFG_POSTDIV2_SHIFT;
rate = rate / (val + 1);
} else {
/* APLL PFD clock */
val = (reg & SCG_PLL_CFG_PFDSEL_MASK) >>
SCG_PLL_CFG_PFDSEL_SHIFT;
rate = scg_apll_pfd_get_rate(SCG_APLL_PFD0_CLK + val);
}
return rate;
}
static u32 scg_spll_get_rate(void)
{
u32 reg, val, rate;
reg = readl(&scg1_regs->spllcfg);
val = (reg & SCG_PLL_CFG_PLLSEL_MASK) >> SCG_PLL_CFG_PLLSEL_SHIFT;
clk_debug("scg_spll_get_rate reg 0x%x\n", reg);
if (!val) {
/* APLL clock after two dividers */
rate = decode_pll(PLL_A7_SPLL);
val = (reg & SCG_PLL_CFG_POSTDIV1_MASK) >>
SCG_PLL_CFG_POSTDIV1_SHIFT;
rate = rate / (val + 1);
val = (reg & SCG_PLL_CFG_POSTDIV2_MASK) >>
SCG_PLL_CFG_POSTDIV2_SHIFT;
rate = rate / (val + 1);
clk_debug("scg_spll_get_rate SPLL %u\n", rate);
} else {
/* APLL PFD clock */
val = (reg & SCG_PLL_CFG_PFDSEL_MASK) >>
SCG_PLL_CFG_PFDSEL_SHIFT;
rate = scg_spll_pfd_get_rate(SCG_SPLL_PFD0_CLK + val);
clk_debug("scg_spll_get_rate PFD %u\n", rate);
}
return rate;
}
static enum scg_clk scg_scs_array[4] = {
SCG_SOSC_CLK, SCG_SIRC_CLK, SCG_FIRC_CLK, SCG_ROSC_CLK,
};
/////////////////////////////////////////////////////////////////////
static u32 scg_sys_get_rate(enum scg_clk clk)
{
u32 reg, val, rate;
if (clk != SCG_CORE_CLK && clk != SCG_BUS_CLK)
return 0;
reg = readl(&scg1_regs->csr);
val = (reg & SCG_CCR_SCS_MASK) >> SCG_CCR_SCS_SHIFT;
clk_debug("scg_sys_get_rate reg 0x%x\n", reg);
switch (val) {
case SCG_SCS_SYS_OSC:
case SCG_SCS_SLOW_IRC:
case SCG_SCS_FAST_IRC:
case SCG_SCS_RTC_OSC:
rate = scg_src_get_rate(scg_scs_array[val]);
break;
case 5:
rate = scg_apll_get_rate();
break;
case 6:
rate = scg_spll_get_rate();
break;
default:
return 0;
}
clk_debug("scg_sys_get_rate parent rate %u\n", rate);
val = (reg & SCG_CCR_DIVCORE_MASK) >> SCG_CCR_DIVCORE_SHIFT;
rate = rate / (val + 1);
if (clk == SCG_BUS_CLK) {
val = (reg & SCG_CCR_DIVBUS_MASK) >> SCG_CCR_DIVBUS_SHIFT;
rate = rate / (val + 1);
}
return rate;
}
///////////////////////////////////////////////////////////////
u32 decode_pll(enum pll_clocks pll)
{
u32 reg, pre_div, infreq, mult;
u32 num, denom;
/*
* Alought there are four choices for the bypass src,
* we choose OSC_24M which is the default set in ROM.
*/
switch (pll) {
case PLL_A7_SPLL:
reg = readl(&scg1_regs->spllcsr);
if (!(reg & SCG_SPLL_CSR_SPLLVLD_MASK))
return 0;
reg = readl(&scg1_regs->spllcfg);
pre_div = (reg & SCG_PLL_CFG_PREDIV_MASK) >>
SCG_PLL_CFG_PREDIV_SHIFT;
pre_div += 1;
mult = (reg & SCG1_SPLL_CFG_MULT_MASK) >>
SCG_PLL_CFG_MULT_SHIFT;
infreq = (reg & SCG_PLL_CFG_CLKSRC_MASK) >>
SCG_PLL_CFG_CLKSRC_SHIFT;
if (!infreq)
infreq = scg_src_get_rate(SCG_SOSC_CLK);
else
infreq = scg_src_get_rate(SCG_FIRC_CLK);
num = readl(&scg1_regs->spllnum);
denom = readl(&scg1_regs->splldenom);
infreq = infreq / pre_div;
return infreq * mult + infreq * num / denom;
case PLL_A7_APLL:
reg = readl(&scg1_regs->apllcsr);
if (!(reg & SCG_APLL_CSR_APLLVLD_MASK))
return 0;
reg = readl(&scg1_regs->apllcfg);
pre_div = (reg & SCG_PLL_CFG_PREDIV_MASK) >>
SCG_PLL_CFG_PREDIV_SHIFT;
pre_div += 1;
mult = (reg & SCG_APLL_CFG_MULT_MASK) >>
SCG_PLL_CFG_MULT_SHIFT;
infreq = (reg & SCG_PLL_CFG_CLKSRC_MASK) >>
SCG_PLL_CFG_CLKSRC_SHIFT;
if (!infreq)
infreq = scg_src_get_rate(SCG_SOSC_CLK);
else
infreq = scg_src_get_rate(SCG_FIRC_CLK);
num = readl(&scg1_regs->apllnum);
denom = readl(&scg1_regs->aplldenom);
infreq = infreq / pre_div;
return infreq * mult + infreq * num / denom;
case PLL_USB:
reg = readl(&scg1_regs->upllcsr);
if (!(reg & SCG_UPLL_CSR_UPLLVLD_MASK))
return 0;
return 480000000u;
case PLL_MIPI:
return 480000000u;
default:
break;
}
return 0;
}
// //////////////////////////////////////////////////////////////////////////
u32 scg_clk_get_rate(enum scg_clk clk)
{
switch (clk) {
case SCG_SIRC_DIV1_CLK:
case SCG_SIRC_DIV2_CLK:
case SCG_SIRC_DIV3_CLK:
return scg_sircdiv_get_rate(clk);
case SCG_FIRC_DIV1_CLK:
case SCG_FIRC_DIV2_CLK:
case SCG_FIRC_DIV3_CLK:
return scg_fircdiv_get_rate(clk);
case SCG_SOSC_DIV1_CLK:
case SCG_SOSC_DIV2_CLK:
case SCG_SOSC_DIV3_CLK:
return scg_soscdiv_get_rate(clk);
case SCG_CORE_CLK:
case SCG_BUS_CLK:
return scg_sys_get_rate(clk);
case SCG_SPLL_PFD0_CLK:
case SCG_SPLL_PFD1_CLK:
case SCG_SPLL_PFD2_CLK:
case SCG_SPLL_PFD3_CLK:
return scg_spll_pfd_get_rate(clk);
case SCG_APLL_PFD0_CLK:
case SCG_APLL_PFD1_CLK:
case SCG_APLL_PFD2_CLK:
case SCG_APLL_PFD3_CLK:
return scg_apll_pfd_get_rate(clk);
case USB_PLL_OUT:
return decode_pll(PLL_USB);
case MIPI_PLL_OUT:
return decode_pll(PLL_MIPI);
case SCG_SOSC_CLK:
case SCG_FIRC_CLK:
case SCG_SIRC_CLK:
case SCG_ROSC_CLK:
return scg_src_get_rate(clk);
default:
return 0;
}
}
/* A7 domain system clock source is SPLL */
#define SCG1_RCCR_SCS_NUM ((SCG_SCS_SYS_PLL) << SCG_CCR_SCS_SHIFT)
/* A7 Core clck = SPLL PFD0 / 1 = 500MHz / 1 = 500MHz */
#define SCG1_RCCR_DIVCORE_NUM ((0x0) << SCG_CCR_DIVCORE_SHIFT)
#define SCG1_RCCR_CFG_MASK (SCG_CCR_SCS_MASK | SCG_CCR_DIVBUS_MASK)
/* A7 Plat clck = A7 Core Clock / 2 = 250MHz / 1 = 250MHz */
#define SCG1_RCCR_DIVBUS_NUM ((0x1) << SCG_CCR_DIVBUS_SHIFT)
#define SCG1_RCCR_CFG_NUM (SCG1_RCCR_SCS_NUM | SCG1_RCCR_DIVBUS_NUM)
/* POSTDIV2 = 1 */
#define SCG1_SPLL_CFG_POSTDIV2_NUM ((0x0) << SCG_PLL_CFG_POSTDIV2_SHIFT)
/* POSTDIV1 = 1 */
#define SCG1_SPLL_CFG_POSTDIV1_NUM ((0x0) << SCG_PLL_CFG_POSTDIV1_SHIFT)
/* MULT = 22 */
#define SCG1_SPLL_CFG_MULT_NUM ((22) << SCG_PLL_CFG_MULT_SHIFT)
/* PFD0 output clock selected */
#define SCG1_SPLL_CFG_PFDSEL_NUM ((0) << SCG_PLL_CFG_PFDSEL_SHIFT)
/* PREDIV = 1 */
#define SCG1_SPLL_CFG_PREDIV_NUM ((0x0) << SCG_PLL_CFG_PREDIV_SHIFT)
/* SPLL output clocks (including PFD outputs) selected */
#define SCG1_SPLL_CFG_BYPASS_NUM ((0x0) << SCG_PLL_CFG_BYPASS_SHIFT)
/* SPLL PFD output clock selected */
#define SCG1_SPLL_CFG_PLLSEL_NUM ((0x1) << SCG_PLL_CFG_PLLSEL_SHIFT)
/* Clock source is System OSC */
#define SCG1_SPLL_CFG_CLKSRC_NUM ((0x0) << SCG_PLL_CFG_CLKSRC_SHIFT)
#define SCG1_SPLL_CFG_NUM_24M_OSC (SCG1_SPLL_CFG_POSTDIV2_NUM | \
SCG1_SPLL_CFG_POSTDIV1_NUM | \
(22 << SCG_PLL_CFG_MULT_SHIFT) | \
SCG1_SPLL_CFG_PFDSEL_NUM | \
SCG1_SPLL_CFG_PREDIV_NUM | \
SCG1_SPLL_CFG_BYPASS_NUM | \
SCG1_SPLL_CFG_PLLSEL_NUM | \
SCG1_SPLL_CFG_CLKSRC_NUM)
/*413Mhz = A7 SPLL(528MHz) * 18/23 */
#define SCG1_SPLL_PFD0_FRAC_NUM ((23) << SCG_PLL_PFD0_FRAC_SHIFT)
/* DDR clock source is APLL PFD0 (396MHz) */
#define SCG1_DDRCCR_DDRCS_NUM ((0x0) << SCG_DDRCCR_DDRCS_SHIFT)
/* DDR clock = APLL PFD0 / 1 = 396MHz / 1 = 396MHz */
#define SCG1_DDRCCR_DDRDIV_NUM ((0x1) << SCG_DDRCCR_DDRDIV_SHIFT)
/* DDR clock = APLL PFD0 / 2 = 396MHz / 2 = 198MHz */
#define SCG1_DDRCCR_DDRDIV_LF_NUM ((0x2) << SCG_DDRCCR_DDRDIV_SHIFT)
#define SCG1_DDRCCR_CFG_NUM (SCG1_DDRCCR_DDRCS_NUM | \
SCG1_DDRCCR_DDRDIV_NUM)
#define SCG1_DDRCCR_CFG_LF_NUM (SCG1_DDRCCR_DDRCS_NUM | \
SCG1_DDRCCR_DDRDIV_LF_NUM)
/* SCG1(A7) APLLCFG configurations */
/* divide by 1 <<28 */
#define SCG1_APLL_CFG_POSTDIV2_NUM ((0x0) << SCG_PLL_CFG_POSTDIV2_SHIFT)
/* divide by 1 <<24 */
#define SCG1_APLL_CFG_POSTDIV1_NUM ((0x0) << SCG_PLL_CFG_POSTDIV1_SHIFT)
/* MULT is 22 <<16 */
#define SCG1_APLL_CFG_MULT_NUM ((22) << SCG_PLL_CFG_MULT_SHIFT)
/* PFD0 output clock selected <<14 */
#define SCG1_APLL_CFG_PFDSEL_NUM ((0) << SCG_PLL_CFG_PFDSEL_SHIFT)
/* PREDIV = 1 <<8 */
#define SCG1_APLL_CFG_PREDIV_NUM ((0x0) << SCG_PLL_CFG_PREDIV_SHIFT)
/* APLL output clocks (including PFD outputs) selected <<2 */
#define SCG1_APLL_CFG_BYPASS_NUM ((0x0) << SCG_PLL_CFG_BYPASS_SHIFT)
/* APLL PFD output clock selected <<1 */
#define SCG1_APLL_CFG_PLLSEL_NUM ((0x0) << SCG_PLL_CFG_PLLSEL_SHIFT)
/* Clock source is System OSC <<0 */
#define SCG1_APLL_CFG_CLKSRC_NUM ((0x0) << SCG_PLL_CFG_CLKSRC_SHIFT)
/*
* A7 APLL = 24MHz / 1 * 22 / 1 / 1 = 528MHz,
* system PLL is sourced from APLL,
* APLL clock source is system OSC (24MHz)
*/
#define SCG1_APLL_CFG_NUM_24M_OSC (SCG1_APLL_CFG_POSTDIV2_NUM | \
SCG1_APLL_CFG_POSTDIV1_NUM | \
(22 << SCG_PLL_CFG_MULT_SHIFT) | \
SCG1_APLL_CFG_PFDSEL_NUM | \
SCG1_APLL_CFG_PREDIV_NUM | \
SCG1_APLL_CFG_BYPASS_NUM | \
SCG1_APLL_CFG_PLLSEL_NUM | \
SCG1_APLL_CFG_CLKSRC_NUM)
/* PFD0 Freq = A7 APLL(528MHz) * 18 / 27 = 352MHz */
#define SCG1_APLL_PFD0_FRAC_NUM (27)
/* SCG1(A7) FIRC DIV configurations */
/* Disable FIRC DIV3 */
#define SCG1_FIRCDIV_DIV3_NUM ((0x0) << SCG_FIRCDIV_DIV3_SHIFT)
/* FIRC DIV2 = 48MHz / 1 = 48MHz */
#define SCG1_FIRCDIV_DIV2_NUM ((0x1) << SCG_FIRCDIV_DIV2_SHIFT)
/* Disable FIRC DIV1 */
#define SCG1_FIRCDIV_DIV1_NUM ((0x0) << SCG_FIRCDIV_DIV1_SHIFT)
/* SCG1(A7) NICCCR configurations */
/* NIC clock source is DDR clock (396/198MHz) */
#define SCG1_NICCCR_NICCS_NUM ((0x1) << SCG_NICCCR_NICCS_SHIFT)
/* NIC0 clock = DDR Clock / 2 = 396MHz / 2 = 198MHz */
#define SCG1_NICCCR_NIC0_DIV_NUM ((0x1) << SCG_NICCCR_NIC0_DIV_SHIFT)
/* NIC0 clock = DDR Clock / 1 = 198MHz / 1 = 198MHz */
#define SCG1_NICCCR_NIC0_DIV_LF_NUM ((0x0) << SCG_NICCCR_NIC0_DIV_SHIFT)
/* NIC1 clock = NIC0 Clock / 1 = 198MHz / 2 = 198MHz */
#define SCG1_NICCCR_NIC1_DIV_NUM ((0x0) << SCG_NICCCR_NIC1_DIV_SHIFT)
/* NIC1 bus clock = NIC1 Clock / 3 = 198MHz / 3 = 66MHz */
#define SCG1_NICCCR_NIC1_DIVBUS_NUM ((0x2) << SCG_NICCCR_NIC1_DIVBUS_SHIFT)
#define SCG1_NICCCR_CFG_NUM (SCG1_NICCCR_NICCS_NUM | \
SCG1_NICCCR_NIC0_DIV_NUM | \
SCG1_NICCCR_NIC1_DIV_NUM | \
SCG1_NICCCR_NIC1_DIVBUS_NUM)
/* SCG1(A7) FIRC DIV configurations */
/* Enable FIRC DIV3 */
#define SCG1_SOSCDIV_DIV3_NUM ((0x1) << SCG_SOSCDIV_DIV3_SHIFT)
/* FIRC DIV2 = 48MHz / 1 = 48MHz */
#define SCG1_SOSCDIV_DIV2_NUM ((0x1) << SCG_SOSCDIV_DIV2_SHIFT)
/* Enable FIRC DIV1 */
#define SCG1_SOSCDIV_DIV1_NUM ((0x1) << SCG_SOSCDIV_DIV1_SHIFT)

View File

@ -1,339 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2016 Freescale Semiconductor, Inc.
*/
#ifndef _ASM_ARCH_SCG_H
#define _ASM_ARCH_SCG_H
#ifdef CONFIG_CLK_DEBUG
#define clk_debug(fmt, args...) printf(fmt, ##args)
#else
#define clk_debug(fmt, args...)
#endif
#define SCG_CCR_SCS_SHIFT (24)
#define SCG_CCR_SCS_MASK ((0xFUL) << SCG_CCR_SCS_SHIFT)
#define SCG_CCR_DIVCORE_SHIFT (16)
#define SCG_CCR_DIVCORE_MASK ((0xFUL) << SCG_CCR_DIVCORE_SHIFT)
#define SCG_CCR_DIVPLAT_SHIFT (12)
#define SCG_CCR_DIVPLAT_MASK ((0xFUL) << SCG_CCR_DIVPLAT_SHIFT)
#define SCG_CCR_DIVEXT_SHIFT (8)
#define SCG_CCR_DIVEXT_MASK ((0xFUL) << SCG_CCR_DIVEXT_SHIFT)
#define SCG_CCR_DIVBUS_SHIFT (4)
#define SCG_CCR_DIVBUS_MASK ((0xFUL) << SCG_CCR_DIVBUS_SHIFT)
#define SCG_CCR_DIVSLOW_SHIFT (0)
#define SCG_CCR_DIVSLOW_MASK ((0xFUL) << SCG_CCR_DIVSLOW_SHIFT)
/* SCG DDR Clock Control Register */
#define SCG_DDRCCR_DDRCS_SHIFT (24)
#define SCG_DDRCCR_DDRCS_MASK ((0x1UL) << SCG_DDRCCR_DDRCS_SHIFT)
#define SCG_DDRCCR_DDRDIV_SHIFT (0)
#define SCG_DDRCCR_DDRDIV_MASK ((0x7UL) << SCG_DDRCCR_DDRDIV_SHIFT)
/* SCG NIC Clock Control Register */
#define SCG_NICCCR_NICCS_SHIFT (28)
#define SCG_NICCCR_NICCS_MASK ((0x1UL) << SCG_NICCCR_NICCS_SHIFT)
#define SCG_NICCCR_NIC0_DIV_SHIFT (24)
#define SCG_NICCCR_NIC0_DIV_MASK ((0xFUL) << SCG_NICCCR_NIC0_DIV_SHIFT)
#define SCG_NICCCR_GPU_DIV_SHIFT (20)
#define SCG_NICCCR_GPU_DIV_MASK ((0xFUL) << SCG_NICCCR_GPU_DIV_SHIFT)
#define SCG_NICCCR_NIC1_DIV_SHIFT (16)
#define SCG_NICCCR_NIC1_DIV_MASK ((0xFUL) << SCG_NICCCR_NIC1_DIV_SHIFT)
#define SCG_NICCCR_NIC1_DIVEXT_SHIFT (8)
#define SCG_NICCCR_NIC1_DIVEXT_MASK ((0xFUL) << SCG_NICCCR_NIC1_DIVEXT_SHIFT)
#define SCG_NICCCR_NIC1_DIVBUS_SHIFT (4)
#define SCG_NICCCR_NIC1_DIVBUS_MASK ((0xFUL) << SCG_NICCCR_NIC1_DIVBUS_SHIFT)
/* SCG NIC clock status register */
#define SCG_NICCSR_NICCS_SHIFT (28)
#define SCG_NICCSR_NICCS_MASK ((0x1UL) << SCG_NICCSR_NICCS_SHIFT)
#define SCG_NICCSR_NIC0DIV_SHIFT (24)
#define SCG_NICCSR_NIC0DIV_MASK ((0xFUL) << SCG_NICCSR_NIC0DIV_SHIFT)
#define SCG_NICCSR_GPUDIV_SHIFT (20)
#define SCG_NICCSR_GPUDIV_MASK ((0xFUL) << SCG_NICCSR_GPUDIV_SHIFT)
#define SCG_NICCSR_NIC1DIV_SHIFT (16)
#define SCG_NICCSR_NIC1DIV_MASK ((0xFUL) << SCG_NICCSR_NIC1DIV_SHIFT)
#define SCG_NICCSR_NIC1EXTDIV_SHIFT (8)
#define SCG_NICCSR_NIC1EXTDIV_MASK ((0xFUL) << SCG_NICCSR_NIC1EXTDIV_SHIFT)
#define SCG_NICCSR_NIC1BUSDIV_SHIFT (4)
#define SCG_NICCSR_NIC1BUSDIV_MASK ((0xFUL) << SCG_NICCSR_NIC1BUSDIV_SHIFT)
/* SCG Slow IRC Control Status Register */
#define SCG_SIRC_CSR_SIRCVLD_SHIFT (24)
#define SCG_SIRC_CSR_SIRCVLD_MASK ((0x1UL) << SCG_SIRC_CSR_SIRCVLD_SHIFT)
#define SCG_SIRC_CSR_SIRCEN_SHIFT (0)
#define SCG_SIRC_CSR_SIRCEN_MASK ((0x1UL) << SCG_SIRC_CSR_SIRCEN_SHIFT)
/* SCG Slow IRC Configuration Register */
#define SCG_SIRCCFG_RANGE_SHIFT (0)
#define SCG_SIRCCFG_RANGE_MASK ((0x1UL) << SCG_SIRCCFG_RANGE_SHIFT)
#define SCG_SIRCCFG_RANGE_4M ((0x0UL) << SCG_SIRCCFG_RANGE_SHIFT)
#define SCG_SIRCCFG_RANGE_16M ((0x1UL) << SCG_SIRCCFG_RANGE_SHIFT)
/* SCG Slow IRC Divide Register */
#define SCG_SIRCDIV_DIV3_SHIFT (16)
#define SCG_SIRCDIV_DIV3_MASK ((0x7UL) << SCG_SIRCDIV_DIV3_SHIFT)
#define SCG_SIRCDIV_DIV2_SHIFT (8)
#define SCG_SIRCDIV_DIV2_MASK ((0x7UL) << SCG_SIRCDIV_DIV2_SHIFT)
#define SCG_SIRCDIV_DIV1_SHIFT (0)
#define SCG_SIRCDIV_DIV1_MASK ((0x7UL) << SCG_SIRCDIV_DIV1_SHIFT)
/*
* FIRC/SIRC DIV1 ==> xIRC_PLAT_CLK
* FIRC/SIRC DIV2 ==> xIRC_BUS_CLK
* FIRC/SIRC DIV3 ==> xIRC_SLOW_CLK
*/
/* SCG Fast IRC Control Status Register */
#define SCG_FIRC_CSR_FIRCVLD_SHIFT (24)
#define SCG_FIRC_CSR_FIRCVLD_MASK ((0x1UL) << SCG_FIRC_CSR_FIRCVLD_SHIFT)
#define SCG_FIRC_CSR_FIRCEN_SHIFT (0)
#define SCG_FIRC_CSR_FIRCEN_MASK ((0x1UL) << SCG_FIRC_CSR_FIRCEN_SHIFT)
/* SCG Fast IRC Divide Register */
#define SCG_FIRCDIV_DIV3_SHIFT (16)
#define SCG_FIRCDIV_DIV3_MASK ((0x7UL) << SCG_FIRCDIV_DIV3_SHIFT)
#define SCG_FIRCDIV_DIV2_SHIFT (8)
#define SCG_FIRCDIV_DIV2_MASK ((0x7UL) << SCG_FIRCDIV_DIV2_SHIFT)
#define SCG_FIRCDIV_DIV1_SHIFT (0)
#define SCG_FIRCDIV_DIV1_MASK ((0x7UL) << SCG_FIRCDIV_DIV1_SHIFT)
#define SCG_FIRCCFG_RANGE_SHIFT (0)
#define SCG_FIRCCFG_RANGE_MASK ((0x3UL) << SCG_FIRCCFG_RANGE_SHIFT)
#define SCG_FIRCCFG_RANGE_SHIFT (0)
#define SCG_FIRCCFG_RANGE_48M ((0x0UL) << SCG_FIRCCFG_RANGE_SHIFT)
/* SCG System OSC Control Status Register */
#define SCG_SOSC_CSR_SOSCVLD_SHIFT (24)
#define SCG_SOSC_CSR_SOSCVLD_MASK ((0x1UL) << SCG_SOSC_CSR_SOSCVLD_SHIFT)
/* SCG Fast IRC Divide Register */
#define SCG_SOSCDIV_DIV3_SHIFT (16)
#define SCG_SOSCDIV_DIV3_MASK ((0x7UL) << SCG_SOSCDIV_DIV3_SHIFT)
#define SCG_SOSCDIV_DIV2_SHIFT (8)
#define SCG_SOSCDIV_DIV2_MASK ((0x7UL) << SCG_SOSCDIV_DIV2_SHIFT)
#define SCG_SOSCDIV_DIV1_SHIFT (0)
#define SCG_SOSCDIV_DIV1_MASK ((0x7UL) << SCG_SOSCDIV_DIV1_SHIFT)
/* SCG RTC OSC Control Status Register */
#define SCG_ROSC_CSR_ROSCVLD_SHIFT (24)
#define SCG_ROSC_CSR_ROSCVLD_MASK ((0x1UL) << SCG_ROSC_CSR_ROSCVLD_SHIFT)
#define SCG_SPLL_CSR_SPLLVLD_SHIFT (24)
#define SCG_SPLL_CSR_SPLLVLD_MASK ((0x1UL) << SCG_SPLL_CSR_SPLLVLD_SHIFT)
#define SCG_SPLL_CSR_SPLLEN_SHIFT (0)
#define SCG_SPLL_CSR_SPLLEN_MASK ((0x1UL) << SCG_SPLL_CSR_SPLLEN_SHIFT)
#define SCG_APLL_CSR_APLLEN_SHIFT (0)
#define SCG_APLL_CSR_APLLEN_MASK (0x1UL)
#define SCG_APLL_CSR_APLLVLD_MASK (0x01000000)
#define SCG_UPLL_CSR_UPLLVLD_MASK (0x01000000)
#define SCG_PLL_PFD3_GATE_MASK (0x80000000)
#define SCG_PLL_PFD2_GATE_MASK (0x00800000)
#define SCG_PLL_PFD1_GATE_MASK (0x00008000)
#define SCG_PLL_PFD0_GATE_MASK (0x00000080)
#define SCG_PLL_PFD3_VALID_MASK (0x40000000)
#define SCG_PLL_PFD2_VALID_MASK (0x00400000)
#define SCG_PLL_PFD1_VALID_MASK (0x00004000)
#define SCG_PLL_PFD0_VALID_MASK (0x00000040)
#define SCG_PLL_PFD0_FRAC_SHIFT (0)
#define SCG_PLL_PFD0_FRAC_MASK ((0x3F) << SCG_PLL_PFD0_FRAC_SHIFT)
#define SCG_PLL_PFD1_FRAC_SHIFT (8)
#define SCG_PLL_PFD1_FRAC_MASK ((0x3F) << SCG_PLL_PFD1_FRAC_SHIFT)
#define SCG_PLL_PFD2_FRAC_SHIFT (16)
#define SCG_PLL_PFD2_FRAC_MASK ((0x3F) << SCG_PLL_PFD2_FRAC_SHIFT)
#define SCG_PLL_PFD3_FRAC_SHIFT (24)
#define SCG_PLL_PFD3_FRAC_MASK ((0x3F) << SCG_PLL_PFD3_FRAC_SHIFT)
#define SCG_PLL_CFG_POSTDIV2_SHIFT (28)
#define SCG_PLL_CFG_POSTDIV2_MASK ((0xFUL) << SCG_PLL_CFG_POSTDIV2_SHIFT)
#define SCG_PLL_CFG_POSTDIV1_SHIFT (24)
#define SCG_PLL_CFG_POSTDIV1_MASK ((0xFUL) << SCG_PLL_CFG_POSTDIV1_SHIFT)
#define SCG_PLL_CFG_MULT_SHIFT (16)
#define SCG1_SPLL_CFG_MULT_MASK ((0x7FUL) << SCG_PLL_CFG_MULT_SHIFT)
#define SCG_APLL_CFG_MULT_MASK ((0x7FUL) << SCG_PLL_CFG_MULT_SHIFT)
#define SCG_PLL_CFG_PFDSEL_SHIFT (14)
#define SCG_PLL_CFG_PFDSEL_MASK ((0x3UL) << SCG_PLL_CFG_PFDSEL_SHIFT)
#define SCG_PLL_CFG_PREDIV_SHIFT (8)
#define SCG_PLL_CFG_PREDIV_MASK ((0x7UL) << SCG_PLL_CFG_PREDIV_SHIFT)
#define SCG_PLL_CFG_BYPASS_SHIFT (2)
/* 0: SPLL, 1: bypass */
#define SCG_PLL_CFG_BYPASS_MASK ((0x1UL) << SCG_PLL_CFG_BYPASS_SHIFT)
#define SCG_PLL_CFG_PLLSEL_SHIFT (1)
/* 0: pll, 1: pfd */
#define SCG_PLL_CFG_PLLSEL_MASK ((0x1UL) << SCG_PLL_CFG_PLLSEL_SHIFT)
#define SCG_PLL_CFG_CLKSRC_SHIFT (0)
/* 0: Sys-OSC, 1: FIRC */
#define SCG_PLL_CFG_CLKSRC_MASK ((0x1UL) << SCG_PLL_CFG_CLKSRC_SHIFT)
#define SCG0_SPLL_CFG_MULT_SHIFT (17)
/* 0: Multiplier = 20, 1: Multiplier = 22 */
#define SCG0_SPLL_CFG_MULT_MASK ((0x1UL) << SCG0_SPLL_CFG_MULT_SHIFT)
#define PLL_USB_EN_USB_CLKS_MASK (0x01 << 6)
#define PLL_USB_PWR_MASK (0x01 << 12)
#define PLL_USB_ENABLE_MASK (0x01 << 13)
#define PLL_USB_BYPASS_MASK (0x01 << 16)
#define PLL_USB_REG_ENABLE_MASK (0x01 << 21)
#define PLL_USB_DIV_SEL_MASK (0x07 << 22)
#define PLL_USB_LOCK_MASK (0x01 << 31)
enum scg_clk {
SCG_SOSC_CLK,
SCG_FIRC_CLK,
SCG_SIRC_CLK,
SCG_ROSC_CLK,
SCG_SIRC_DIV1_CLK,
SCG_SIRC_DIV2_CLK,
SCG_SIRC_DIV3_CLK,
SCG_FIRC_DIV1_CLK,
SCG_FIRC_DIV2_CLK,
SCG_FIRC_DIV3_CLK,
SCG_SOSC_DIV1_CLK,
SCG_SOSC_DIV2_CLK,
SCG_SOSC_DIV3_CLK,
SCG_CORE_CLK,
SCG_BUS_CLK,
SCG_SPLL_PFD0_CLK,
SCG_SPLL_PFD1_CLK,
SCG_SPLL_PFD2_CLK,
SCG_SPLL_PFD3_CLK,
SCG_DDR_CLK,
SCG_NIC0_CLK,
SCG_GPU_CLK,
SCG_NIC1_CLK,
SCG_NIC1_BUS_CLK,
SCG_NIC1_EXT_CLK,
SCG_APLL_PFD0_CLK,
SCG_APLL_PFD1_CLK,
SCG_APLL_PFD2_CLK,
SCG_APLL_PFD3_CLK,
USB_PLL_OUT,
MIPI_PLL_OUT
};
enum scg_sys_src {
SCG_SCS_SYS_OSC = 1,
SCG_SCS_SLOW_IRC,
SCG_SCS_FAST_IRC,
SCG_SCS_RTC_OSC,
SCG_SCS_AUX_PLL,
SCG_SCS_SYS_PLL,
SCG_SCS_USBPHY_PLL,
};
/* PLL supported by i.mx7ulp */
enum pll_clocks {
PLL_M4_SPLL, /* M4 SPLL */
PLL_M4_APLL, /* M4 APLL*/
PLL_A7_SPLL, /* A7 SPLL */
PLL_A7_APLL, /* A7 APLL */
PLL_USB, /* USB PLL*/
PLL_MIPI, /* MIPI PLL */
};
typedef struct scg_regs {
u32 verid; /* VERSION_ID */
u32 param; /* PARAMETER */
u32 rsvd11[2];
u32 csr; /* Clock Status Register */
u32 rccr; /* Run Clock Control Register */
u32 vccr; /* VLPR Clock Control Register */
u32 hccr; /* HSRUN Clock Control Register */
u32 clkoutcnfg; /* SCG CLKOUT Configuration Register */
u32 rsvd12[3];
u32 ddrccr; /* SCG DDR Clock Control Register */
u32 rsvd13[3];
u32 nicccr; /* NIC Clock Control Register */
u32 niccsr; /* NIC Clock Status Register */
u32 rsvd10[46];
u32 sosccsr; /* System OSC Control Status Register, offset 0x100 */
u32 soscdiv; /* System OSC Divide Register */
u32 sosccfg; /* System Oscillator Configuration Register */
u32 sosctest; /* System Oscillator Test Register */
u32 rsvd20[60];
u32 sirccsr; /* Slow IRC Control Status Register, offset 0x200 */
u32 sircdiv; /* Slow IRC Divide Register */
u32 sirccfg; /* Slow IRC Configuration Register */
u32 sirctrim; /* Slow IRC Trim Register */
u32 loptrim; /* Low Power Oscillator Trim Register */
u32 sirctest; /* Slow IRC Test Register */
u32 rsvd30[58];
u32 firccsr; /* Fast IRC Control Status Register, offset 0x300 */
u32 fircdiv;
u32 firccfg;
u32 firctcfg; /* Fast IRC Trim Configuration Register */
u32 firctriml; /* Fast IRC Trim Low Register */
u32 firctrimh;
u32 fircstat; /* Fast IRC Status Register */
u32 firctest; /* Fast IRC Test Register */
u32 rsvd40[56];
u32 rtccsr; /* RTC OSC Control Status Register, offset 0x400 */
u32 rsvd50[63];
u32 apllcsr; /* Auxiliary PLL Control Status Register, offset 0x500 */
u32 aplldiv; /* Auxiliary PLL Divider Register */
u32 apllcfg; /* Auxiliary PLL Configuration Register */
u32 apllpfd; /* Auxiliary PLL PFD Register */
u32 apllnum; /* Auxiliary PLL Numerator Register */
u32 aplldenom; /* Auxiliary PLL Denominator Register */
u32 apllss; /* Auxiliary PLL Spread Spectrum Register */
u32 rsvd60[55];
u32 apllock_cnfg; /* Auxiliary PLL LOCK Configuration Register */
u32 rsvd61[1];
u32 spllcsr; /* System PLL Control Status Register, offset 0x600 */
u32 splldiv; /* System PLL Divide Register */
u32 spllcfg; /* System PLL Configuration Register */
u32 spllpfd; /* System PLL Test Register */
u32 spllnum; /* System PLL Numerator Register */
u32 splldenom; /* System PLL Denominator Register */
u32 spllss; /* System PLL Spread Spectrum Register */
u32 rsvd70[55];
u32 spllock_cnfg; /* System PLL LOCK Configuration Register */
u32 rsvd71[1];
u32 upllcsr; /* USB PLL Control Status Register, offset 0x700 */
u32 uplldiv; /* USB PLL Divide Register */
u32 upllcfg; /* USB PLL Configuration Register */
} scg_t, *scg_p;
u32 scg_clk_get_rate(enum scg_clk clk);
int scg_enable_pll_pfd(enum scg_clk clk, u32 frac);
//int scg_enable_usb_pll(bool usb_control);
u32 decode_pll(enum pll_clocks pll);
void scg_a7_rccr_init(void);
void scg_a7_spll_init(void);
void scg_a7_ddrclk_init(void);
void scg_a7_apll_init(void);
void scg_a7_firc_init(void);
void scg_a7_nicclk_init(void);
void scg_a7_sys_clk_sel(enum scg_sys_src clk);
void scg_a7_info(void);
void scg_a7_soscdiv_init(void);
#endif

View File

@ -1,47 +0,0 @@
/*
* include/linux/sizes.h
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef __LINUX_SIZES_H__
#define __LINUX_SIZES_H__
#define SZ_1 0x00000001
#define SZ_2 0x00000002
#define SZ_4 0x00000004
#define SZ_8 0x00000008
#define SZ_16 0x00000010
#define SZ_32 0x00000020
#define SZ_64 0x00000040
#define SZ_128 0x00000080
#define SZ_256 0x00000100
#define SZ_512 0x00000200
#define SZ_1K 0x00000400
#define SZ_2K 0x00000800
#define SZ_4K 0x00001000
#define SZ_8K 0x00002000
#define SZ_16K 0x00004000
#define SZ_32K 0x00008000
#define SZ_64K 0x00010000
#define SZ_128K 0x00020000
#define SZ_256K 0x00040000
#define SZ_512K 0x00080000
#define SZ_1M 0x00100000
#define SZ_2M 0x00200000
#define SZ_4M 0x00400000
#define SZ_8M 0x00800000
#define SZ_16M 0x01000000
#define SZ_32M 0x02000000
#define SZ_64M 0x04000000
#define SZ_128M 0x08000000
#define SZ_256M 0x10000000
#define SZ_512M 0x20000000
#define SZ_1G 0x40000000
#define SZ_2G 0x80000000
#endif /* __LINUX_SIZES_H__ */

View File

@ -1,5 +0,0 @@
#define UBOOT_SIZE {uboot_size}
unsigned char uboot_bin[] = {{
{uboot_bin}
}};

View File

@ -3,10 +3,42 @@
.global _start .global _start
_start: _start:
ldr r0, =0x67800000 //preload U-Boot from sd
ldr r4, .L3
adr r1, [.LC0]
adr r0, [.LC1]
mov r3, r4
blx r3
add r5, r4, #0xc
mov r3, r0
ldr r0, .L3+4
mov r1, #1
mov r2, r0
blx r5
cpsid if cpsid if
//copy U-Boot to head of RAM
ldr r3, =0x37500000
ldr r1, =0x37540000
.L2:
mov r2, r3
sub r3, r3, #0x7500000
ldr r0, [r2], #4
cmp r2, r1
str r0, [r3]
mov r3, r2
bne .L2
ldr r0, =0x60000000
//MUB Interrupt Disable
ldr r2,=0x40220064
ldr r3,[r2]
ldr r1,=0x0000ffff
and r3,r3,r1
str r3,[r2]
mrc p15, 0, r8, c14, c2, 1 mrc p15, 0, r8, c14, c2, 1
bic r8, r8, #1 bic r8, r8, #1
mcr p15, 0, r8, c14, c2, 1 mcr p15, 0, r8, c14, c2, 1
@ -15,12 +47,51 @@ _start:
mcr p15, 0, r8, c14, c3, 1 mcr p15, 0, r8, c14, c3, 1
mov r9, #0 mov r9, #0
mrc p15, 0, r10, c1, c0, 0 mrc p15, 0, r6, c1, c0, 0
@bic r10, r10, #5 @ disable MMU and dcache bic r6, r6, #4 @ disable dcache
bic r10, r10, #1 @ disable MMU bic r6, r6, #4096 @ disable icache
@bic r10, r10, #4096 @ disable icache mcr p15, 0, r6, c1, c0, 0 // write ctrl regs
mcr p15, 0, r10, c1, c0, 0 // write ctrl regs
#mcr p15, 0, r9, c7, c7, 0 // invalidate cache
#mcr p15, 0, r9, c8, c7, 0 // invalidate TLB
mov pc, r0
mcr p15, 0, r9, c7, c5, 0 // invalidate icache
// from: https://www.aps-web.jp/academy/ca/229/#i-2
mov r10,#0 //
mcr p15,2,r10,c0,c0,0 // CSSELR
//
isb //
mrc p15,1,r1,c0,c0,0 // CCSIDR
and r2,r1,#7 // b001=8ワード/
add r2,r2,#4 // DCISW
ldr r4,=0x3FF //
ands r4,r4,r1,LSR #3 // r4
clz r5,r4 // DCISW
ldr r7,=0x7FFF //
ands r7,r7,r1,LSR #13 // r7
// 0x7F=12Kbyte/0xFF=32Kbyte/0x1FF=64Kbyte
loop2:
mov r9,r4 // r9
loop3:
orr r11,r10,r9,LSL r5 //
orr r11,r11,r7,LSL r2 //
mcr p15,0,r11,c7,c6,2 // DCISW/
//
subs r9,r9,#1 // -1
bge loop3 //
subs r7,r7,#1 // -1
bge loop2 //
mcr p15, 0, r9, c8, c7, 0 // invalidate TLB
mcr p15, 0, r9, c7, c5, 6 // invalidate branch predictor array
bic r6, r6, #1 @ disable MMU
mcr p15, 0, r6, c1, c0, 0 // write ctrl regs
bx r0
.L3:
.word 0x60006400
.word 0x37500000
.LC0:
.ascii "r\000"
.LC1:
.ascii "SD0:\\u-boot.bin\000"

Binary file not shown.