forked from OERV-BSP/u-boot
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4609811251 |
@@ -47,9 +47,6 @@ config TARGET_SIPEED_MAIX
|
||||
bool "Support Sipeed Maix Board"
|
||||
select SYS_CACHE_SHIFT_6
|
||||
|
||||
config TARGET_SPACEMIT_K3
|
||||
bool "Support SpacemiT K3 based Boards"
|
||||
|
||||
config TARGET_STARFIVE_VISIONFIVE2
|
||||
bool "Support StarFive VisionFive2 Board"
|
||||
select BOARD_LATE_INIT
|
||||
@@ -119,7 +116,6 @@ source "board/sipeed/maix/Kconfig"
|
||||
source "board/sophgo/milkv_duo/Kconfig"
|
||||
source "board/sophgo/licheerv_nano/Kconfig"
|
||||
source "board/spacemit/bananapi-f3/Kconfig"
|
||||
source "board/spacemit/k3-generic/Kconfig"
|
||||
source "board/starfive/visionfive2/Kconfig"
|
||||
source "board/thead/th1520_lpi4a/Kconfig"
|
||||
source "board/xilinx/mbv/Kconfig"
|
||||
@@ -133,7 +129,6 @@ source "arch/riscv/cpu/ast2700/Kconfig"
|
||||
source "arch/riscv/cpu/generic/Kconfig"
|
||||
source "arch/riscv/cpu/jh7110/Kconfig"
|
||||
source "arch/riscv/cpu/k1/Kconfig"
|
||||
source "arch/riscv/cpu/k3/Kconfig"
|
||||
source "arch/riscv/cpu/k230/Kconfig"
|
||||
source "arch/riscv/cpu/th1520/Kconfig"
|
||||
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#
|
||||
# Copyright (c) 2026, Hangfan Li <lihangfan@iscas.ac.cn>
|
||||
|
||||
# Due to limitation of Kconfig, the following symbols cannot be selected here:
|
||||
# CONFIG_ARCH_RV64I
|
||||
# CONFIG_RISCV_SMODE
|
||||
|
||||
config SPACEMIT_K3
|
||||
bool
|
||||
select ARCH_EARLY_INIT_R
|
||||
select SUPPORT_SPL
|
||||
select SPL
|
||||
select BINMAN
|
||||
imply CPU
|
||||
imply CPU_RISCV
|
||||
imply SPL_CPU
|
||||
imply RISCV_ISA_ZICBOM
|
||||
imply FIT
|
||||
imply SPL_LOAD_FIT
|
||||
imply SPL_LOAD_FIT_FULL
|
||||
imply PINCTRL
|
||||
imply SPL_PINCTRL
|
||||
imply PINCTRL_SINGLE
|
||||
imply SYS_NS16550
|
||||
imply SPL_RISCV_ACLINT if SPL_RISCV_MMODE
|
||||
|
||||
if SPACEMIT_K3
|
||||
|
||||
config SYS_CPU
|
||||
default "k3"
|
||||
|
||||
config SPL_SMP
|
||||
default n
|
||||
|
||||
config SPL_TEXT_BASE
|
||||
hex
|
||||
default 0xc0801000
|
||||
|
||||
config SPL_MAX_SIZE
|
||||
hex
|
||||
default 0x6AF00
|
||||
|
||||
config SPL_BSS_START_ADDR
|
||||
hex
|
||||
default 0xc0874000
|
||||
|
||||
config SPL_BSS_MAX_SIZE
|
||||
hex
|
||||
default 0x3000
|
||||
|
||||
config SPL_OPENSBI_LOAD_ADDR
|
||||
hex
|
||||
default 0x100000000
|
||||
|
||||
endif
|
||||
@@ -1,8 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#
|
||||
# Copyright (c) 2026, Hangfan Li <lihangfan@iscas.ac.cn>
|
||||
|
||||
obj-$(CONFIG_XPL_BUILD) += spl.o
|
||||
obj-y += cpu.o
|
||||
obj-y += cache.o
|
||||
obj-y += dram.o
|
||||
@@ -1,31 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (c) 2026 Hangfan Li <lihangfan@iscas.ac.cn>
|
||||
*/
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <cpu_func.h>
|
||||
#include <linux/bitops.h>
|
||||
|
||||
#if CONFIG_IS_ENABLED(RISCV_MMODE)
|
||||
void icache_enable(void)
|
||||
{
|
||||
csr_set(0x7c0, 0x2);
|
||||
}
|
||||
|
||||
void dcache_enable(void)
|
||||
{
|
||||
csr_set(0x7c0, 0x1);
|
||||
csr_set(0x7f0, 0x1);
|
||||
}
|
||||
|
||||
int icache_status(void)
|
||||
{
|
||||
return (csr_read(0x7c0) & 0x2) != 0;
|
||||
}
|
||||
|
||||
int dcache_status(void)
|
||||
{
|
||||
return (csr_read(0x7c0) & 0x1) != 0;
|
||||
}
|
||||
#endif /* CONFIG_IS_ENABLED(RISCV_MMODE) */
|
||||
@@ -1,24 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (c) 2026 Hangfan Li <lihangfan@iscas.ac.cn>
|
||||
*/
|
||||
|
||||
#include <irq_func.h>
|
||||
#include <asm/cache.h>
|
||||
|
||||
|
||||
/*
|
||||
* cleanup_before_linux() is called just before we call linux
|
||||
* it prepares the processor for linux
|
||||
*
|
||||
* we disable interrupt and caches.
|
||||
*/
|
||||
int cleanup_before_linux(void)
|
||||
{
|
||||
disable_interrupts();
|
||||
|
||||
cache_flush();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (c) 2026 Hangfan Li <lihangfan@iscas.ac.cn>
|
||||
*/
|
||||
|
||||
#include <fdtdec.h>
|
||||
#include <init.h>
|
||||
#include <linux/sizes.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
__weak int dram_init(void)
|
||||
{
|
||||
return fdtdec_setup_mem_size_base();
|
||||
}
|
||||
|
||||
__weak int dram_init_banksize(void)
|
||||
{
|
||||
return fdtdec_setup_memory_banksize();
|
||||
}
|
||||
|
||||
@@ -1,32 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (c) 2026 Hangfan Li <lihangfan@iscas.ac.cn>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <linux/types.h>
|
||||
#include <asm/spl.h>
|
||||
#include <spl.h>
|
||||
#include <cpu_func.h>
|
||||
|
||||
|
||||
void harts_early_init(void)
|
||||
{
|
||||
icache_enable();
|
||||
dcache_enable();
|
||||
}
|
||||
|
||||
void board_boot_order(u32 *spl_boot_list)
|
||||
{
|
||||
/* Boot from SPI NOR with YMODEM UART fallback. */
|
||||
spl_boot_list[0] = BOOT_DEVICE_SPI;
|
||||
spl_boot_list[1] = BOOT_DEVICE_UART;
|
||||
spl_boot_list[2] = BOOT_DEVICE_NONE;
|
||||
}
|
||||
|
||||
int spl_board_init_f(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
/ {
|
||||
cpus {
|
||||
bootph-all;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
timebase-frequency = <24000000>;
|
||||
|
||||
cpu_0: cpu@0 {
|
||||
bootph-all;
|
||||
compatible = "spacemit,x100", "riscv";
|
||||
device_type = "cpu";
|
||||
reg = <0>;
|
||||
riscv,isa = "rv64imafdcvh_zicbom_zicboz_zicntr_zicond_zicsr_zifencei_zihintpause_zihpm_zfh_zfhmin_zba_zbb_zbc_zbs_zkt_zvbb_zvbc_zvfh_zvfhmin_zvkb_zvkg_zvkn_zvknc_zvkned_zvkng_zvknha_zvknhb_zvks_zvksc_zvksed_zvksh_zvksg_zvkt_ssaia_sscofpmf_sstc_svinval_svnapot_svpbmt_smstateen";
|
||||
riscv,isa-base = "rv64i";
|
||||
riscv,isa-extensions = "i", "m", "a", "f", "d", "c", "v", "h",
|
||||
"zicbom", "zicboz", "zicntr", "zicond", "zicsr",
|
||||
"zifencei", "zihintpause", "zihpm", "zfh", "zfhmin",
|
||||
"zba", "zbb", "zbc", "zbs", "zkt", "zvbb", "zvbc",
|
||||
"zvfh", "zvfhmin", "zvkb", "zvkg", "zvkn", "zvknc",
|
||||
"zvkned", "zvkng", "zvknha", "zvknhb", "zvks",
|
||||
"zvksc", "zvksed", "zvksh", "zvksg", "zvkt", "ssaia",
|
||||
"sscofpmf", "sstc", "svinval", "svnapot", "svpbmt",
|
||||
"smstateen";
|
||||
riscv,cbom-block-size = <64>;
|
||||
/*riscv,cbop-block-size = <64>;*/
|
||||
riscv,cboz-block-size = <64>;
|
||||
i-cache-block-size = <64>;
|
||||
i-cache-size = <65536>;
|
||||
i-cache-sets = <256>;
|
||||
d-cache-block-size = <64>;
|
||||
d-cache-size = <65536>;
|
||||
d-cache-sets = <256>;
|
||||
next-level-cache = <&cluster0_l2_cache>;
|
||||
mmu-type = "riscv,sv39";
|
||||
cpu0_intc: interrupt-controller {
|
||||
#interrupt-cells = <1>;
|
||||
compatible = "riscv,cpu-intc";
|
||||
interrupt-controller;
|
||||
};
|
||||
};
|
||||
|
||||
cluster0_l2_cache: l2-cache0 {
|
||||
bootph-all;
|
||||
compatible = "cache";
|
||||
cache-block-size = <64>;
|
||||
cache-level = <2>;
|
||||
cache-size = <4194304>;
|
||||
cache-sets = <4096>;
|
||||
cache-unified;
|
||||
};
|
||||
|
||||
cluster1_l2_cache: l2-cache1 {
|
||||
compatible = "cache";
|
||||
cache-block-size = <64>;
|
||||
cache-level = <2>;
|
||||
cache-size = <4194304>;
|
||||
cache-sets = <4096>;
|
||||
cache-unified;
|
||||
};
|
||||
|
||||
cluster2_l2_cache: l2-cache2 {
|
||||
compatible = "cache";
|
||||
cache-block-size = <64>;
|
||||
cache-level = <2>;
|
||||
cache-size = <1048576>;
|
||||
cache-sets = <1024>;
|
||||
cache-unified;
|
||||
};
|
||||
|
||||
cluster3_l2_cache: l2-cache3 {
|
||||
compatible = "cache";
|
||||
cache-block-size = <64>;
|
||||
cache-level = <2>;
|
||||
cache-size = <1048576>;
|
||||
cache-sets = <1024>;
|
||||
cache-unified;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -1,54 +0,0 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
|
||||
/* Copyright (c) 2025 Spacemit, Inc */
|
||||
|
||||
#include <dt-bindings/pinctrl/k3-pinctrl.h>
|
||||
|
||||
&pinctrl {
|
||||
pinctrl_uart0_0: uart0_0_grp {
|
||||
bootph-all;
|
||||
pinctrl-single,pins = <
|
||||
K3_PADCONF(149, MUX_MODE2, (PULL_UP | PAD_DS8)) /* tx */
|
||||
K3_PADCONF(150, MUX_MODE2, (PULL_UP | PAD_DS8)) /* rx */
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_uart0_1: uart0_1_grp {
|
||||
bootph-all;
|
||||
pinctrl-single,pins = <
|
||||
K3_PADCONF(132, MUX_MODE2, (PULL_UP | PAD_DS8)) /* tx */
|
||||
K3_PADCONF(133, MUX_MODE2, (PULL_UP | PAD_DS8)) /* rx */
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_uart0_2: uart0_2_grp {
|
||||
bootph-all;
|
||||
pinctrl-single,pins = <
|
||||
K3_PADCONF(145, MUX_MODE5, (PULL_UP | PAD_DS8)) /* tx */
|
||||
K3_PADCONF(146, MUX_MODE5, (PULL_UP | PAD_DS8)) /* rx */
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_uart0_3: uart0_3_grp {
|
||||
bootph-all;
|
||||
pinctrl-single,pins = <
|
||||
K3_PADCONF(42, MUX_MODE2, (PULL_UP | PAD_DS8)) /* tx */
|
||||
K3_PADCONF(43, MUX_MODE2, (PULL_UP | PAD_DS8)) /* rx */
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_uart0_4: uart0_4_grp {
|
||||
bootph-all;
|
||||
pinctrl-single,pins = <
|
||||
K3_PADCONF(93, MUX_MODE3, (PULL_UP | PAD_DS8)) /* tx */
|
||||
K3_PADCONF(94, MUX_MODE3, (PULL_UP | PAD_DS8)) /* rx */
|
||||
>;
|
||||
};
|
||||
|
||||
pinctrl_i2c2_1: i2c2_1_grp {
|
||||
bootph-all;
|
||||
pinctrl-single,pins = <
|
||||
K3_PADCONF(46, MUX_MODE5, (PULL_UP | PAD_DS0)) /* i2c2_scl */
|
||||
K3_PADCONF(47, MUX_MODE5, (PULL_UP | PAD_DS0)) /* i2c2_sda */
|
||||
>;
|
||||
};
|
||||
};
|
||||
@@ -1,56 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
|
||||
/*
|
||||
* Copyright (C) 2026 Hangfan Li <lihangfan@iscas.ac.cn>
|
||||
*/
|
||||
|
||||
#include "k3.dtsi"
|
||||
#include "k3-pinctrl.dtsi"
|
||||
#include "binman.dtsi"
|
||||
|
||||
/ {
|
||||
model = "SpacemiT K3 DEB1 Board";
|
||||
compatible = "spacemit,k3-deb1", "spacemit,k3";
|
||||
|
||||
chosen {
|
||||
stdout-path = "serial0";
|
||||
};
|
||||
|
||||
memory@0 {
|
||||
device_type = "memory";
|
||||
reg = <0x00000000 0x00000000 0x00000000 0x80000000>;
|
||||
};
|
||||
};
|
||||
|
||||
&serial0 {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_uart0_0>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
&qspi0 {
|
||||
status = "okay";
|
||||
|
||||
flash@0 {
|
||||
bootph-all;
|
||||
compatible = "jedec,spi-nor";
|
||||
reg = <0>;
|
||||
spi-max-frequency = <26500000>;
|
||||
m25p,fast-read;
|
||||
broken-flash-reset;
|
||||
};
|
||||
};
|
||||
|
||||
&i2c2 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_i2c2_1>;
|
||||
status = "okay";
|
||||
|
||||
eeprom@50{
|
||||
bootph-all;
|
||||
compatible = "atmel,24c02";
|
||||
reg = <0x50>;
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
@@ -1,26 +0,0 @@
|
||||
&binman {
|
||||
bootinfo_nor {
|
||||
filename = "bootinfo_nor.bin";
|
||||
|
||||
mkimage {
|
||||
args = "-s -T spacemit-binfo";
|
||||
};
|
||||
};
|
||||
|
||||
spl {
|
||||
filename = "spacemit-spl-unsigned.bin";
|
||||
|
||||
mkimage {
|
||||
args = "-T spacemit-spl";
|
||||
offset = <0xFE0>;
|
||||
|
||||
section {
|
||||
// Use a section to pad SPL at 32B align-size, before passing to mkimage
|
||||
blob {
|
||||
align-size = <32>;
|
||||
filename = "spl/u-boot-spl.bin";
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -1,181 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later OR MIT
|
||||
/*
|
||||
* Copyright (C) 2026 Hangfan Li <lihangfan@iscas.ac.cn>
|
||||
*/
|
||||
|
||||
/dts-v1/;
|
||||
|
||||
#include "k3-cpus.dtsi"
|
||||
#include <dt-bindings/clock/spacemit-k3-clock.h>
|
||||
#include <dt-bindings/reset/reset-spacemit-k3.h>
|
||||
|
||||
/ {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
model = "SpacemiT K3";
|
||||
compatible = "spacemit,k3";
|
||||
|
||||
aliases {
|
||||
serial0 = &serial0;
|
||||
i2c2 = &i2c2;
|
||||
};
|
||||
|
||||
clocks {
|
||||
clk0: osc {
|
||||
bootph-all;
|
||||
compatible = "fixed-clock";
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <66667000>;
|
||||
};
|
||||
vctcxo_24: vctcxo_24 {
|
||||
bootph-all;
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <24000000>;
|
||||
clock-output-names = "vctcxo_24";
|
||||
};
|
||||
vctcxo_3: vctcxo_3 {
|
||||
bootph-all;
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <3000000>;
|
||||
clock-output-names = "vctcxo_3";
|
||||
};
|
||||
vctcxo_1: vctcxo_1 {
|
||||
bootph-all;
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <1000000>;
|
||||
clock-output-names = "vctcxo_1";
|
||||
};
|
||||
pll1_vco: pll1_vco {
|
||||
bootph-all;
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <24576000>;
|
||||
clock-output-names = "pll1_vco";
|
||||
};
|
||||
osc_32k: osc_32k {
|
||||
bootph-all;
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <32000>;
|
||||
clock-output-names = "osc_32k";
|
||||
};
|
||||
clk_dummy: clk_dummy {
|
||||
bootph-all;
|
||||
#clock-cells = <0>;
|
||||
compatible = "fixed-clock";
|
||||
clock-frequency = <0>;
|
||||
clock-output-names = "clk_dummy";
|
||||
};
|
||||
};
|
||||
|
||||
soc {
|
||||
bootph-all;
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
compatible = "simple-bus";
|
||||
ranges;
|
||||
|
||||
ccu: clock-controller@d4050000 {
|
||||
bootph-all;
|
||||
compatible = "spacemit,k3-ccu";
|
||||
reg = <0x0 0xd4050000 0x0 0x209c>,
|
||||
<0x0 0xd4282800 0x0 0x400>,
|
||||
<0x0 0xd4015000 0x0 0x1000>,
|
||||
<0x0 0xd4090000 0x0 0x1000>,
|
||||
<0x0 0xd4282c00 0x0 0x400>,
|
||||
<0x0 0xd8440000 0x0 0x98>,
|
||||
<0x0 0xc0000000 0x0 0x4280>,
|
||||
<0x0 0xf0610000 0x0 0x20>,
|
||||
<0x0 0xc0880000 0x0 0xd100>;
|
||||
reg-names = "mpmu", "apmu", "apbc", "apbs", "ciu", "dciu", "ddrc", "apbc2", "rcpu";
|
||||
clocks = <&vctcxo_24>, <&vctcxo_3>, <&vctcxo_1>, <&pll1_vco>,
|
||||
<&osc_32k>, <&clk_dummy>;
|
||||
clock-names = "vctcxo_24", "vctcxo_3", "vctcxo_1", "pll1_vco",
|
||||
"osc_32k", "clk_dummy";
|
||||
#clock-cells = <1>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
pinctrl: pinctrl@d401e000 {
|
||||
bootph-all;
|
||||
compatible = "pinctrl-single";
|
||||
reg = <0x0 0xd401e000 0x0 0x400>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
#pinctrl-cells = <1>;
|
||||
#gpio-range-cells = <3>;
|
||||
pinctrl-single,register-width = <32>;
|
||||
pinctrl-single,function-mask = <0xffff>;
|
||||
|
||||
range: gpio-range {
|
||||
bootph-all;
|
||||
#pinctrl-single,gpio-range-cells = <3>;
|
||||
};
|
||||
};
|
||||
|
||||
clint: timer@e081c000 {
|
||||
compatible = "spacemit,k3-clint", "sifive,clint0";
|
||||
reg = <0x0 0xe081c000 0x0 0x4000>;
|
||||
bootph-pre-ram;
|
||||
interrupts-extended = <&cpu0_intc 3>, <&cpu0_intc 7>;
|
||||
};
|
||||
|
||||
reset: reset-controller@d4050000 {
|
||||
bootph-all;
|
||||
compatible = "spacemit,k3-reset";
|
||||
reg = <0x0 0xd4050000 0x0 0x209c>,
|
||||
<0x0 0xd4282800 0x0 0x400>,
|
||||
<0x0 0xd4015000 0x0 0x1000>,
|
||||
<0x0 0xd4090000 0x0 0x1000>,
|
||||
<0x0 0xd4282c00 0x0 0x400>,
|
||||
<0x0 0xd8440000 0x0 0x98>,
|
||||
<0x0 0xc0000000 0x0 0x4280>,
|
||||
<0x0 0xf0610000 0x0 0x20>,
|
||||
<0x0 0xc0880000 0x0 0xd100>;
|
||||
reg-names = "mpmu", "apmu", "apbc", "apbs", "ciu", "dciu", "ddrc", "apbc2","rcpu";
|
||||
#reset-cells = <1>;
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
serial0: serial@d4017000 {
|
||||
bootph-all;
|
||||
compatible = "intel,xscale-uart";
|
||||
reg = <0x00000000 0xD4017000 0x00000000 0x00000100>;
|
||||
reg-shift = <2>;
|
||||
reg-io-width = <4>;
|
||||
clock-frequency = <14745600>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
qspi0: qspi@d420c000 {
|
||||
bootph-all;
|
||||
compatible = "spacemit,k3-qspi";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0x0 0xd420c000 0x0 0x1000>,
|
||||
<0x0 0xb8000000 0x0 0xc00000>;
|
||||
reg-names = "QuadSPI", "QuadSPI-memory";
|
||||
spi-max-frequency = <26500000>;
|
||||
clock-names = "qspi_en", "qspi";
|
||||
clocks = <&ccu CLK_QSPI>, <&ccu CLK_QSPI_BUS>;
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
i2c2: twsi2@d4012000 {
|
||||
bootph-all;
|
||||
compatible = "spacemit,i2c";
|
||||
reg = <0x0 0xd4012000 0x0 0x38>;
|
||||
clocks = <&ccu CLK_TWSI2>, <&ccu CLK_TWSI2_BUS>;
|
||||
clock-names = "i2c2_en", "i2c2";
|
||||
resets = <&reset RESET_TWSI2>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
clock-frequency = <100000>;
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
@@ -1,42 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#
|
||||
# Copyright (c) 2026, Hangfan Li <lihangfan@iscas.ac.cn>
|
||||
|
||||
if TARGET_SPACEMIT_K3
|
||||
|
||||
config SYS_VENDOR
|
||||
default "spacemit"
|
||||
|
||||
config SYS_BOARD
|
||||
default "k3-generic"
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
default "spacemit-k3-generic"
|
||||
|
||||
config CUSTOM_SYS_INIT_SP_ADDR
|
||||
default 0xc0880000
|
||||
|
||||
config TEXT_BASE
|
||||
hex
|
||||
default 0x80200000 if RISCV_SMODE
|
||||
|
||||
config SYS_LOAD_ADDR
|
||||
hex
|
||||
default 0x102000000
|
||||
|
||||
config DEFAULT_DEVICE_TREE
|
||||
default "k3-spacemit-deb1"
|
||||
|
||||
config BOARD_SPECIFIC_OPTIONS
|
||||
def_bool y
|
||||
select SPACEMIT_K3
|
||||
select HAS_CUSTOM_SYS_INIT_SP_ADDR
|
||||
imply SPI
|
||||
imply SPL_SPI
|
||||
imply SPL_DM_SPI
|
||||
imply SPL_SPI_FLASH_SUPPORT
|
||||
imply SPL_DM_SPI_FLASH
|
||||
imply SPL_SPI_LOAD
|
||||
imply FSL_QSPI
|
||||
|
||||
endif
|
||||
@@ -1,5 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#
|
||||
# Copyright (c) 2026, Hangfan Li <lihangfan@iscas.ac.cn>
|
||||
|
||||
obj-y := k3-generic.o
|
||||
@@ -1,10 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (c) 2026, Hangfan Li <lihangfan@iscas.ac.cn>
|
||||
*/
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
/* Add board-specific initialization */
|
||||
return 0;
|
||||
}
|
||||
@@ -185,8 +185,6 @@ static const table_entry_t uimage_type[] = {
|
||||
{ IH_TYPE_STARFIVE_SPL, "sfspl", "StarFive SPL Image" },
|
||||
{ IH_TYPE_TFA_BL31, "tfa-bl31", "TFA BL31 Image", },
|
||||
{ IH_TYPE_STM32IMAGE_V2, "stm32imagev2", "STMicroelectronics STM32 Image V2.0" },
|
||||
{ IH_TYPE_SPACEMIT_BOOTINFO, "spacemit-binfo", "SpacemiT BootInfo Binary Header" },
|
||||
{ IH_TYPE_SPACEMIT_SPL, "spacemit-spl", "SpacemiT BootROM loadable Image" },
|
||||
{ -1, "", "", },
|
||||
};
|
||||
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
CONFIG_RISCV=y
|
||||
CONFIG_TARGET_SPACEMIT_K3=y
|
||||
CONFIG_ARCH_RV64I=y
|
||||
CONFIG_RISCV_SMODE=y
|
||||
CONFIG_SPL_CLK=y
|
||||
CONFIG_SPACEMIT_K3_CCU=y
|
||||
CONFIG_TIMER_EARLY=y
|
||||
CONFIG_RISCV_TIMER=y
|
||||
CONFIG_MISC=y
|
||||
CONFIG_SPL_MISC=y
|
||||
CONFIG_SPL_DRIVERS_MISC=y
|
||||
CONFIG_DM_RESET=y
|
||||
CONFIG_SPL_DM_RESET=y
|
||||
CONFIG_RESET_SPACEMIT_K3=y
|
||||
CONFIG_SPL_I2C=y
|
||||
CONFIG_DM_I2C=y
|
||||
CONFIG_SYS_I2C_SPACEMIT=y
|
||||
CONFIG_I2C_EEPROM=y
|
||||
CONFIG_SPL_I2C_EEPROM=y
|
||||
@@ -284,6 +284,5 @@ source "drivers/clk/tegra/Kconfig"
|
||||
source "drivers/clk/ti/Kconfig"
|
||||
source "drivers/clk/thead/Kconfig"
|
||||
source "drivers/clk/uniphier/Kconfig"
|
||||
source "drivers/clk/spacemit/Kconfig"
|
||||
|
||||
endmenu
|
||||
|
||||
@@ -61,4 +61,3 @@ obj-$(CONFIG_MACH_PIC32) += clk_pic32.o
|
||||
obj-$(CONFIG_SANDBOX_CLK_CCF) += clk_sandbox_ccf.o
|
||||
obj-$(CONFIG_SANDBOX) += clk_sandbox.o
|
||||
obj-$(CONFIG_SANDBOX) += clk_sandbox_test.o
|
||||
obj-$(CONFIG_TARGET_SPACEMIT_K3) += spacemit/
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
# common clock support for SPACEMIT SoC family.
|
||||
|
||||
config SPACEMIT_K3_CCU
|
||||
tristate "Clock support for Spacemit k3 SoCs"
|
||||
depends on TARGET_SPACEMIT_K3
|
||||
select CLK
|
||||
select CLK_CCF
|
||||
select SPL_CLK_CCF if SPL
|
||||
help
|
||||
Build the driver for Spacemit K3 Clock Driver.
|
||||
@@ -1,6 +0,0 @@
|
||||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
# Spacemit Clock specific Makefile
|
||||
#
|
||||
#SoC support
|
||||
obj-$(CONFIG_SPACEMIT_K3_CCU) += ccu-k3.o ccu_mix.o ccu_plla.o
|
||||
@@ -1,370 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Spacemit k3 clock controller driver
|
||||
*
|
||||
* Copyright (c) 2023, spacemit Corporation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <clk.h>
|
||||
#include <clk-uclass.h>
|
||||
#include <dm.h>
|
||||
#include <log.h>
|
||||
#include <asm/io.h>
|
||||
#include "common.h"
|
||||
#include "ccu_mix.h"
|
||||
#include "ccu_plla.h"
|
||||
#include "ccu-k3.h"
|
||||
|
||||
|
||||
struct spacemit_ccu_clk k3_clock_controller;
|
||||
struct clk vctcxo_24, vctcxo_3, vctcxo_1, pll1_vco, osc_32k, clk_dummy;
|
||||
|
||||
static SPACEMIT_CCU_FACTOR(pll1_2457p6_vco, "pll1_2457p6_vco", "pll1_vco",
|
||||
1, 100);
|
||||
|
||||
static const struct ccu_plla_rate_tbl pll2_rate_tbl[] = {
|
||||
PLLA_RATE(3000000000UL, 0x0b3e2000, 0x00000000, 0xa0558c8c),
|
||||
};
|
||||
|
||||
static SPACEMIT_CCU_PLLA(pll2, "pll2", &pll2_rate_tbl, ARRAY_SIZE(pll2_rate_tbl),
|
||||
BASE_TYPE_APBS, APBS_PLL2_SWCR1, APBS_PLL2_SWCR2, APBS_PLL2_SWCR3,
|
||||
MPMU_POSR, POSR_PLL2_LOCK, 1,
|
||||
0);
|
||||
static SPACEMIT_CCU_GATE_FACTOR(pll1_d4, "pll1_d4", "pll1_2457p6_vco",
|
||||
BASE_TYPE_APBS, APBS_PLL1_SWCR2,
|
||||
BIT(3), BIT(3), 0x0,
|
||||
4, 1, 0);
|
||||
static SPACEMIT_CCU_GATE_FACTOR(pll1_d5, "pll1_d5", "pll1_2457p6_vco",
|
||||
BASE_TYPE_APBS, APBS_PLL1_SWCR2,
|
||||
BIT(4), BIT(4), 0x0,
|
||||
5, 1, 0);
|
||||
static SPACEMIT_CCU_GATE_FACTOR(pll1_d6, "pll1_d6", "pll1_2457p6_vco",
|
||||
BASE_TYPE_APBS, APBS_PLL1_SWCR2,
|
||||
BIT(5), BIT(5), 0x0,
|
||||
6, 1, 0);
|
||||
static SPACEMIT_CCU_GATE_FACTOR(pll1_d8, "pll1_d8", "pll1_2457p6_vco",
|
||||
BASE_TYPE_APBS, APBS_PLL1_SWCR2,
|
||||
BIT(7), BIT(7), 0x0,
|
||||
8, 1, 0);
|
||||
|
||||
static SPACEMIT_CCU_DIV_GATE(pll1_dx, "pll1_dx", "pll1_2457p6_vco",
|
||||
BASE_TYPE_APBS, APBS_PLL1_SWCR2,
|
||||
23, 5, BIT(22), BIT(22), 0x0,
|
||||
0);
|
||||
|
||||
static SPACEMIT_CCU_GATE_FACTOR(pll2_d8, "pll2_d8", "pll2",
|
||||
BASE_TYPE_APBS, APBS_PLL2_SWCR2,
|
||||
BIT(7), BIT(7), 0x0,
|
||||
8, 1, 0);
|
||||
|
||||
static SPACEMIT_CCU_GATE(pll1_d8_307p2, "pll1_d8_307p2", "pll1_d8",
|
||||
BASE_TYPE_MPMU, MPMU_ACGR,
|
||||
BIT(13), BIT(13), 0x0,
|
||||
0);
|
||||
static SPACEMIT_CCU_GATE(pll1_d6_409p6, "pll1_d6_409p6", "pll1_d6",
|
||||
BASE_TYPE_MPMU, MPMU_ACGR,
|
||||
BIT(0), BIT(0), 0x0,
|
||||
0);
|
||||
static SPACEMIT_CCU_GATE(pll1_d5_491p52, "pll1_d5_491p52", "pll1_d5",
|
||||
BASE_TYPE_MPMU, MPMU_ACGR,
|
||||
BIT(21), BIT(21), 0x0,
|
||||
0);
|
||||
static SPACEMIT_CCU_GATE_FACTOR(pll1_d10_245p76, "pll1_d10_245p76", "pll1_d5",
|
||||
BASE_TYPE_MPMU, MPMU_ACGR,
|
||||
BIT(18), BIT(18), 0x0,
|
||||
2, 1, 0);
|
||||
|
||||
static SPACEMIT_CCU_GATE_FACTOR(pll1_d24_102p4, "pll1_d24_102p4", "pll1_d8",
|
||||
BASE_TYPE_MPMU, MPMU_ACGR,
|
||||
BIT(12), BIT(12), 0x0,
|
||||
3, 1, 0);
|
||||
static SPACEMIT_CCU_GATE_FACTOR(pll1_d96_25p6, "pll1_d96_25p6", "pll1_d8",
|
||||
BASE_TYPE_MPMU, MPMU_ACGR,
|
||||
BIT(4), BIT(4), 0x0,
|
||||
12, 1, 0);
|
||||
|
||||
|
||||
static SPACEMIT_CCU_GATE_FACTOR(pll1_d78_31p5, "pll1_d78_31p5", "pll1_d4",
|
||||
BASE_TYPE_MPMU, MPMU_ACGR,
|
||||
BIT(6), BIT(6), 0x0,
|
||||
39, 2, 0);
|
||||
static SPACEMIT_CCU_GATE_FACTOR(pll1_d48_51p2, "pll1_d48_51p2", "pll1_d8",
|
||||
BASE_TYPE_MPMU, MPMU_ACGR,
|
||||
BIT(7), BIT(7), 0x0,
|
||||
6, 1, 0);
|
||||
static SPACEMIT_CCU_FACTOR(pll1_d40_61p44, "pll1_d40_61p44", "pll1_d8_307p2",
|
||||
5, 1);
|
||||
|
||||
static const char * const qspi_parent_names[] = {
|
||||
"pll1_d6_409p6", "pll2_d8", "pll1_d8_307p2", "pll1_d10_245p76",
|
||||
"clk_dummy", "pll1_dx", "pll1_d5_491p52", "clk_dummy"
|
||||
};
|
||||
|
||||
static SPACEMIT_CCU_DIV_MFC_MUX_GATE(qspi_clk, "qspi_clk", qspi_parent_names,
|
||||
BASE_TYPE_APMU, APMU_QSPI_CLK_RES_CTRL,
|
||||
9, 3, BIT(12),
|
||||
6, 3, BIT(4), BIT(4), 0x0,
|
||||
0);
|
||||
|
||||
static SPACEMIT_CCU_GATE(qspi_bus_clk, "qspi_bus_clk", "clk_dummy",
|
||||
BASE_TYPE_APMU, APMU_QSPI_CLK_RES_CTRL,
|
||||
BIT(3), BIT(3), 0x0,
|
||||
0);
|
||||
|
||||
static const char *twsi_parent_names[] = {
|
||||
"pll1_d78_31p5", "pll1_d48_51p2", "pll1_d40_61p44"
|
||||
};
|
||||
|
||||
static SPACEMIT_CCU_MUX_GATE(twsi2_clk, "twsi2_clk", twsi_parent_names,
|
||||
BASE_TYPE_APBC, APBC_TWSI2_CLK_RST,
|
||||
4, 3, 0x3, 0x3, 0x0,
|
||||
0);
|
||||
|
||||
|
||||
static const char * const apb_parent_names[] = {
|
||||
"pll1_d96_25p6", "pll1_d48_51p2",
|
||||
"pll1_d96_25p6", "pll1_d24_102p4"
|
||||
};
|
||||
|
||||
static SPACEMIT_CCU_MUX(apb_clk, "apb_clk", apb_parent_names,
|
||||
BASE_TYPE_MPMU, MPMU_APBCSCR,
|
||||
0, 2, 0);
|
||||
|
||||
static SPACEMIT_CCU_GATE(twsi2_bus_clk, "twsi2_bus_clk", "apb_clk",
|
||||
BASE_TYPE_APBC, APBC_TWSI2_CLK_RST,
|
||||
BIT(0), BIT(0), 0x0,
|
||||
0);
|
||||
|
||||
|
||||
|
||||
|
||||
static struct spacemit_clk_table spacemit_k3_clks = {
|
||||
.clks = {
|
||||
[CLK_PLL1_2457P6] = &pll1_2457p6_vco.common.clk,
|
||||
[CLK_PLL2] = &pll2.common.clk,
|
||||
[CLK_PLL1_D4] = &pll1_d4.common.clk,
|
||||
[CLK_PLL1_D5] = &pll1_d5.common.clk,
|
||||
[CLK_PLL1_D6] = &pll1_d6.common.clk,
|
||||
[CLK_PLL1_D8] = &pll1_d8.common.clk,
|
||||
[CLK_PLL1_DX] = &pll1_dx.common.clk,
|
||||
[CLK_PLL2_D8] = &pll2_d8.common.clk,
|
||||
[CLK_PLL1_31P5] = &pll1_d78_31p5.common.clk,
|
||||
[CLK_PLL1_51P2] = &pll1_d48_51p2.common.clk,
|
||||
[CLK_PLL1_61P44] = &pll1_d40_61p44.common.clk,
|
||||
|
||||
[CLK_PLL1_102P4] = &pll1_d24_102p4.common.clk,
|
||||
[CLK_PLL1_25P6] = &pll1_d96_25p6.common.clk,
|
||||
[CLK_APB] = &apb_clk.common.clk,
|
||||
[CLK_TWSI2_BUS] = &twsi2_bus_clk.common.clk,
|
||||
|
||||
[CLK_PLL1_307P2] = &pll1_d8_307p2.common.clk,
|
||||
[CLK_PLL1_409P6] = &pll1_d6_409p6.common.clk,
|
||||
[CLK_PLL1_491] = &pll1_d5_491p52.common.clk,
|
||||
[CLK_PLL1_245P76] = &pll1_d10_245p76.common.clk,
|
||||
[CLK_QSPI] = &qspi_clk.common.clk,
|
||||
[CLK_QSPI_BUS] = &qspi_bus_clk.common.clk,
|
||||
[CLK_TWSI2] = &twsi2_clk.common.clk,
|
||||
},
|
||||
.num = CLK_MAX_NO,
|
||||
};
|
||||
|
||||
static int ccu_of_xlate(struct clk *clk,
|
||||
struct ofnode_phandle_args *args)
|
||||
{
|
||||
if (args->args_count > 1) {
|
||||
pr_debug("Invalid args_count: %d\n", args->args_count);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (args->args_count) {
|
||||
clk->id = args->args[0];
|
||||
if (clk->id >= spacemit_k3_clks.num ||
|
||||
!spacemit_k3_clks.clks[clk->id]) {
|
||||
pr_debug("Unsupported clock id: %u\n", args->args[0]);
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
clk->id = 0;
|
||||
}
|
||||
|
||||
clk->data = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ulong ccu_clk_round_rate(struct clk *clk, ulong rate)
|
||||
{
|
||||
struct clk *c;
|
||||
int err = clk_get_by_id(clk->id, &c);
|
||||
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return clk_round_rate(c, rate);
|
||||
}
|
||||
|
||||
const struct clk_ops ccu_clk_ops = {
|
||||
.get_rate = ccf_clk_get_rate,
|
||||
.round_rate = ccu_clk_round_rate,
|
||||
.set_parent = ccf_clk_set_parent,
|
||||
.disable = ccf_clk_disable,
|
||||
.set_rate = ccf_clk_set_rate,
|
||||
.enable = ccf_clk_enable,
|
||||
.of_xlate = ccu_of_xlate,
|
||||
};
|
||||
|
||||
int ccu_common_init(struct clk * clk, struct spacemit_ccu_clk *clk_info, struct spacemit_clk_table *clks)
|
||||
{
|
||||
struct ccu_common *common = clk_to_ccu_common(clk);
|
||||
int ret;
|
||||
|
||||
if (!common)
|
||||
return -1;
|
||||
|
||||
switch(common->base_type){
|
||||
case BASE_TYPE_MPMU:
|
||||
common->base = clk_info->mpmu_base;
|
||||
break;
|
||||
case BASE_TYPE_APMU:
|
||||
common->base = clk_info->apmu_base;
|
||||
break;
|
||||
case BASE_TYPE_APBC:
|
||||
common->base = clk_info->apbc_base;
|
||||
break;
|
||||
case BASE_TYPE_APBS:
|
||||
common->base = clk_info->apbs_base;
|
||||
break;
|
||||
case BASE_TYPE_CIU:
|
||||
common->base = clk_info->ciu_base;
|
||||
break;
|
||||
case BASE_TYPE_DCIU:
|
||||
common->base = clk_info->dciu_base;
|
||||
break;
|
||||
case BASE_TYPE_DDRC:
|
||||
common->base = clk_info->ddrc_base;
|
||||
break;
|
||||
case BASE_TYPE_AUDC:
|
||||
common->base = clk_info->audio_ctrl_base;
|
||||
break;
|
||||
case BASE_TYPE_APBC2:
|
||||
common->base = clk_info->apbc2_base;
|
||||
break;
|
||||
case BASE_TYPE_RCPU:
|
||||
common->base = clk_info->rcpu_base;
|
||||
break;
|
||||
default:
|
||||
common->base = clk_info->apbc_base;
|
||||
break;
|
||||
|
||||
}
|
||||
common->clk_tbl = clks;
|
||||
if (common->is_pll) {
|
||||
struct ccu_plla *pll = clk_to_ccu_plla(clk);
|
||||
|
||||
pll->pll.lock_base = clk_info->mpmu_base;
|
||||
}
|
||||
|
||||
if(common->parent_name == NULL && common->parent_names != NULL)
|
||||
common->parent_name = common->parent_names[ccu_mix_get_parent(clk)];
|
||||
|
||||
ret = clk_register(clk, common->driver_name, common->name, common->parent_name);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int spacemit_ccu_probe(struct spacemit_ccu_clk *clk_info,
|
||||
struct spacemit_clk_table *clks)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = CLK_PLL1_2457P6; i < clks->num ; i++) {
|
||||
struct clk *clk = clks->clks[i];
|
||||
int ret;
|
||||
|
||||
if (!clk)
|
||||
continue;
|
||||
|
||||
if (i >= CLK_VCTCXO_24 && i != CLK_TWSI2_BUS)
|
||||
continue;
|
||||
|
||||
clk->id = i;
|
||||
ret = ccu_common_init(clk, clk_info, clks);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void ccu_clk_dm(ulong id, struct clk *clk)
|
||||
{
|
||||
if (!IS_ERR(clk)){
|
||||
clk->id = id;
|
||||
spacemit_k3_clks.clks[id] = clk;
|
||||
}
|
||||
}
|
||||
|
||||
static int spacemit_k3_ccu_probe(struct udevice *dev)
|
||||
{
|
||||
int ret = 0;
|
||||
struct spacemit_ccu_clk *clk_info = &k3_clock_controller;
|
||||
struct spacemit_clk_table *clks = &spacemit_k3_clks;
|
||||
|
||||
pr_debug("init clock start \n");
|
||||
|
||||
clk_info->mpmu_base = (void __iomem *)dev_remap_addr_index(dev, 0);
|
||||
if (!clk_info->mpmu_base) {
|
||||
pr_err("failed to map mpmu registers\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
clk_info->apmu_base = (void __iomem *)dev_remap_addr_index(dev, 1);
|
||||
if (!clk_info->apmu_base) {
|
||||
pr_err("failed to map apmu registers\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
clk_info->apbc_base = (void __iomem *)dev_remap_addr_index(dev, 2);
|
||||
if (!clk_info->apbc_base) {
|
||||
pr_err("failed to map apbc registers\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
clk_info->apbs_base = (void __iomem *)dev_remap_addr_index(dev, 3);
|
||||
if (!clk_info->apbs_base) {
|
||||
pr_err("failed to map apbs registers\n");
|
||||
goto out;
|
||||
}
|
||||
clk_get_by_name(dev, "vctcxo_24", &vctcxo_24);
|
||||
ccu_clk_dm(CLK_VCTCXO_24, dev_get_clk_ptr(vctcxo_24.dev));
|
||||
clk_get_by_name(dev, "vctcxo_3", &vctcxo_3);
|
||||
ccu_clk_dm(CLK_VCTCXO_3, dev_get_clk_ptr(vctcxo_3.dev));
|
||||
clk_get_by_name(dev, "vctcxo_1", &vctcxo_1);
|
||||
ccu_clk_dm(CLK_VCTCXO_1, dev_get_clk_ptr(vctcxo_1.dev));
|
||||
clk_get_by_name(dev, "pll1_vco", &pll1_vco);
|
||||
ccu_clk_dm(CLK_PLL1, dev_get_clk_ptr(pll1_vco.dev));
|
||||
clk_get_by_name(dev, "osc_32k", &osc_32k);
|
||||
ccu_clk_dm(OSC_32K, dev_get_clk_ptr(osc_32k.dev));
|
||||
clk_get_by_name(dev, "clk_dummy", &clk_dummy);
|
||||
ccu_clk_dm(CLK_DUMMY, dev_get_clk_ptr(clk_dummy.dev));
|
||||
|
||||
ret = spacemit_ccu_probe(clk_info, clks);
|
||||
pr_debug("init clock finish ret=%d \n", ret);
|
||||
if (!ret)
|
||||
return 0;
|
||||
out:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const struct udevice_id ccu_clk_ids[] = {
|
||||
{ .compatible = "spacemit,k3-ccu" },
|
||||
{ },
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(spacemit_k3_ccu) = {
|
||||
.name = "k3-ccu",
|
||||
.id = UCLASS_CLK,
|
||||
.of_match = ccu_clk_ids,
|
||||
.ops = &ccu_clk_ops,
|
||||
.probe = spacemit_k3_ccu_probe,
|
||||
};
|
||||
@@ -1,25 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2025, spacemit Corporation.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _CCU_SPACEMIT_K3_H_
|
||||
#define _CCU_SPACEMIT_K3_H_
|
||||
|
||||
#define APBS_PLL1_SWCR2 0x104
|
||||
#define APBS_PLL2_SWCR1 0x118
|
||||
#define APBS_PLL2_SWCR2 0x11c
|
||||
#define APBS_PLL2_SWCR3 0x120
|
||||
|
||||
#define MPMU_FCCR 0x0008
|
||||
#define MPMU_POSR 0x0010
|
||||
#define POSR_PLL2_LOCK BIT(25)
|
||||
#define MPMU_ACGR 0x1024
|
||||
|
||||
#define MPMU_APBCSCR 0x1050
|
||||
#define APBC_TWSI2_CLK_RST 0x38
|
||||
|
||||
#define APMU_QSPI_CLK_RES_CTRL 0x060
|
||||
|
||||
#endif /* _CCU_SPACEMIT_K3_H_ */
|
||||
@@ -1,453 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Spacemit clock type mix(div/mux/gate/factor)
|
||||
*
|
||||
* Copyright (c) 2023, spacemit Corporation.
|
||||
*
|
||||
*/
|
||||
#include <asm/io.h>
|
||||
#include <malloc.h>
|
||||
#include <clk-uclass.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <clk.h>
|
||||
#include <div64.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "ccu_mix.h"
|
||||
|
||||
#define TIMEOUT_LIMIT (20000) /* max timeout 10000us */
|
||||
|
||||
static unsigned long ccu_rate_delta(unsigned long rate1, unsigned long rate2)
|
||||
{
|
||||
return rate1 > rate2 ? rate1 - rate2 : rate2 - rate1;
|
||||
}
|
||||
|
||||
static int ccu_mix_trigger_fc(struct clk *clk)
|
||||
{
|
||||
struct ccu_mix *mix = clk_to_ccu_mix(clk);
|
||||
struct ccu_common *common = &mix->common;
|
||||
unsigned long val = 0;
|
||||
|
||||
int ret = 0, timeout = 50;
|
||||
|
||||
if (common->reg_type == CLK_DIV_TYPE_1REG_FC_V2 ||
|
||||
common->reg_type == CLK_DIV_TYPE_2REG_FC_V4 ||
|
||||
common->reg_type == CLK_DIV_TYPE_1REG_FC_DIV_V5 ||
|
||||
common->reg_type == CLK_DIV_TYPE_1REG_FC_MUX_V6) {
|
||||
timeout = 50;
|
||||
val = readl(common->base + common->reg_ctrl);
|
||||
val |= common->fc;
|
||||
writel(val, common->base + common->reg_ctrl);
|
||||
|
||||
do {
|
||||
val = readl(common->base + common->reg_ctrl);
|
||||
timeout--;
|
||||
if (!(val & (common->fc)))
|
||||
break;
|
||||
} while (timeout);
|
||||
|
||||
if (timeout == 0) {
|
||||
timeout = 5000;
|
||||
do {
|
||||
val = readl(common->base + common->reg_ctrl);
|
||||
timeout--;
|
||||
if (!(val & (common->fc)))
|
||||
break;
|
||||
} while (timeout);
|
||||
if (timeout != 0) {
|
||||
ret = 0;
|
||||
|
||||
} else {
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ccu_mix_disable(struct clk *clk)
|
||||
{
|
||||
struct ccu_mix *mix = clk_to_ccu_mix(clk);
|
||||
struct ccu_common *common = &mix->common;
|
||||
struct ccu_gate_config *gate = mix->gate;
|
||||
u32 tmp;
|
||||
|
||||
if (!gate)
|
||||
return 0;
|
||||
|
||||
if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 ||
|
||||
common->reg_type == CLK_DIV_TYPE_2REG_FC_V4)
|
||||
tmp = readl(common->base + common->reg_sel);
|
||||
else
|
||||
tmp = readl(common->base + common->reg_ctrl);
|
||||
|
||||
tmp &= ~gate->gate_mask;
|
||||
tmp |= gate->val_disable;
|
||||
|
||||
if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 ||
|
||||
common->reg_type == CLK_DIV_TYPE_2REG_FC_V4)
|
||||
writel(tmp, common->base + common->reg_sel);
|
||||
else
|
||||
writel(tmp, common->base + common->reg_ctrl);
|
||||
|
||||
if (gate->flags & SPACEMIT_CLK_GATE_NEED_DELAY) {
|
||||
udelay(200);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ulong ccu_mix_round_rate(struct clk *clk, ulong rate)
|
||||
{
|
||||
return rate;
|
||||
}
|
||||
|
||||
static int ccu_mix_set_parent(struct clk *clk, struct clk *parent)
|
||||
{
|
||||
struct ccu_mix *mix = clk_to_ccu_mix(clk);
|
||||
struct ccu_common *common = &mix->common;
|
||||
struct ccu_mux_config *mux = mix->mux;
|
||||
int index = -ENOENT;
|
||||
u32 reg, i;
|
||||
int ret;
|
||||
|
||||
if (!parent)
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < common->num_parents; i++) {
|
||||
if (!strcmp(parent->dev->name, common->parent_names[i])) {
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (index < 0) {
|
||||
pr_info("Could not fetch index\n");
|
||||
return index;
|
||||
}
|
||||
|
||||
if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 ||
|
||||
common->reg_type == CLK_DIV_TYPE_2REG_FC_V4)
|
||||
reg = readl(common->base + common->reg_sel);
|
||||
else
|
||||
reg = readl(common->base + common->reg_ctrl);
|
||||
|
||||
reg &= ~GENMASK(mux->width + mux->shift - 1, mux->shift);
|
||||
|
||||
if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 ||
|
||||
common->reg_type == CLK_DIV_TYPE_2REG_FC_V4)
|
||||
writel(reg | (index << mux->shift),
|
||||
common->base + common->reg_sel);
|
||||
else
|
||||
writel(reg | (index << mux->shift),
|
||||
common->base + common->reg_ctrl);
|
||||
|
||||
if (common->reg_type == CLK_DIV_TYPE_1REG_FC_V2 ||
|
||||
common->reg_type == CLK_DIV_TYPE_2REG_FC_V4 ||
|
||||
common->reg_type == CLK_DIV_TYPE_1REG_FC_MUX_V6) {
|
||||
ret = ccu_mix_trigger_fc(clk);
|
||||
if (ret)
|
||||
pr_info("%s of %s timeout\n", __func__, clk->dev->name);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ccu_mix_enable(struct clk *clk)
|
||||
{
|
||||
struct ccu_mix *mix = clk_to_ccu_mix(clk);
|
||||
struct ccu_common *common = &mix->common;
|
||||
struct ccu_gate_config *gate = mix->gate;
|
||||
u32 tmp;
|
||||
u32 val = 0;
|
||||
int timeout_power = 1;
|
||||
|
||||
if (!gate)
|
||||
return 0;
|
||||
|
||||
if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 ||
|
||||
common->reg_type == CLK_DIV_TYPE_2REG_FC_V4)
|
||||
tmp = readl(common->base + common->reg_sel);
|
||||
else
|
||||
tmp = readl(common->base + common->reg_ctrl);
|
||||
|
||||
tmp &= ~gate->gate_mask;
|
||||
tmp |= gate->val_enable;
|
||||
|
||||
if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 ||
|
||||
common->reg_type == CLK_DIV_TYPE_2REG_FC_V4)
|
||||
writel(tmp, common->base + common->reg_sel);
|
||||
else
|
||||
writel(tmp, common->base + common->reg_ctrl);
|
||||
|
||||
if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 ||
|
||||
common->reg_type == CLK_DIV_TYPE_2REG_FC_V4)
|
||||
val = readl(common->base + common->reg_sel);
|
||||
else
|
||||
val = readl(common->base + common->reg_ctrl);
|
||||
|
||||
while ((val & gate->gate_mask) != gate->val_enable &&
|
||||
(timeout_power < TIMEOUT_LIMIT)) {
|
||||
udelay(timeout_power);
|
||||
if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 ||
|
||||
common->reg_type == CLK_DIV_TYPE_2REG_FC_V4)
|
||||
val = readl(common->base + common->reg_sel);
|
||||
else
|
||||
val = readl(common->base + common->reg_ctrl);
|
||||
timeout_power *= 10;
|
||||
}
|
||||
|
||||
if (timeout_power > 1) {
|
||||
if (val == tmp)
|
||||
pr_info("write clk_gate %s timeout occur, read pass after %d us delay\n",
|
||||
clk_hw_get_name(&common->clk), timeout_power);
|
||||
else
|
||||
pr_info("write clk_gate %s timeout after %d us!\n",
|
||||
clk_hw_get_name(&common->clk), timeout_power);
|
||||
}
|
||||
|
||||
if (gate->flags & SPACEMIT_CLK_GATE_NEED_DELAY) {
|
||||
udelay(200);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ulong ccu_mix_get_rate(struct clk *clk)
|
||||
{
|
||||
struct ccu_mix *mix = clk_to_ccu_mix(clk);
|
||||
struct ccu_common *common = &mix->common;
|
||||
struct ccu_div_config *div = mix->div;
|
||||
unsigned long parent_rate = clk_get_parent_rate(clk);
|
||||
unsigned long val;
|
||||
u32 reg;
|
||||
|
||||
if (!div) {
|
||||
if (mix->factor)
|
||||
val = parent_rate * mix->factor->mul / mix->factor->div;
|
||||
else
|
||||
val = parent_rate;
|
||||
return val;
|
||||
}
|
||||
if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 ||
|
||||
common->reg_type == CLK_DIV_TYPE_2REG_FC_V4)
|
||||
reg = readl(common->base + common->reg_sel);
|
||||
else
|
||||
reg = readl(common->base + common->reg_ctrl);
|
||||
|
||||
val = reg >> div->shift;
|
||||
val &= (1 << div->width) - 1;
|
||||
|
||||
val = divider_recalc_rate(clk, parent_rate, val, div->table, div->flags,
|
||||
div->width);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
unsigned long ccu_mix_calc_best_rate(struct clk *clk, unsigned long rate,
|
||||
u32 *mux_val, u32 *div_val, u32 *parent_id)
|
||||
{
|
||||
struct ccu_mix *mix = clk_to_ccu_mix(clk);
|
||||
struct ccu_common *common = &mix->common;
|
||||
struct ccu_div_config *div = mix->div ? mix->div : NULL;
|
||||
struct ccu_mux_config *mux = mix->mux ? mix->mux : NULL;
|
||||
struct clk *parent = NULL;
|
||||
unsigned long parent_rate = 0, best_rate = 0, best_delta = ULONG_MAX;
|
||||
u32 i, j, p_id, div_max;
|
||||
|
||||
if (mux) {
|
||||
for (i = 0; i < common->num_parents; i++) {
|
||||
parent = NULL;
|
||||
for (p_id = 0; p_id < common->clk_tbl->num; p_id++) {
|
||||
parent = common->clk_tbl->clks[p_id];
|
||||
if (!parent)
|
||||
continue;
|
||||
if (!strcmp(parent->dev->name,
|
||||
common->parent_names[i])) {
|
||||
break;
|
||||
}
|
||||
parent = NULL;
|
||||
}
|
||||
|
||||
if (!parent)
|
||||
continue;
|
||||
|
||||
parent_rate = clk_get_rate(parent);
|
||||
if (!parent_rate)
|
||||
continue;
|
||||
|
||||
if (div)
|
||||
div_max = 1 << div->width;
|
||||
else
|
||||
div_max = 1;
|
||||
for (j = 1; j <= div_max; j++) {
|
||||
unsigned long candidate_rate =
|
||||
DIV_ROUND_UP_ULL(parent_rate, j);
|
||||
unsigned long delta =
|
||||
ccu_rate_delta(candidate_rate, rate);
|
||||
|
||||
if (delta < best_delta) {
|
||||
best_rate = candidate_rate;
|
||||
best_delta = delta;
|
||||
*mux_val = i;
|
||||
*div_val = j - 1;
|
||||
*parent_id = p_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
parent_rate = clk_get_parent_rate(clk);
|
||||
if (!parent_rate)
|
||||
return 0;
|
||||
|
||||
if (div)
|
||||
div_max = 1 << div->width;
|
||||
else
|
||||
div_max = 1;
|
||||
for (j = 1; j <= div_max; j++) {
|
||||
unsigned long candidate_rate =
|
||||
DIV_ROUND_UP_ULL(parent_rate, j);
|
||||
unsigned long delta = ccu_rate_delta(candidate_rate,
|
||||
rate);
|
||||
|
||||
if (delta < best_delta) {
|
||||
best_rate = candidate_rate;
|
||||
best_delta = delta;
|
||||
*div_val = j - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return best_rate;
|
||||
}
|
||||
|
||||
static ulong ccu_mix_set_rate(struct clk *clk, unsigned long rate)
|
||||
{
|
||||
struct ccu_mix *mix = clk_to_ccu_mix(clk);
|
||||
struct ccu_common *common = &mix->common;
|
||||
struct ccu_div_config *div_config = mix->div ? mix->div : NULL;
|
||||
struct ccu_mux_config *mux_config = mix->mux ? mix->mux : NULL;
|
||||
unsigned long best_rate = 0;
|
||||
u32 cur_mux, cur_div, mux_val = 0, div_val = 0, parent_id = 0;
|
||||
struct clk *parent;
|
||||
unsigned long val;
|
||||
u32 reg;
|
||||
int ret;
|
||||
|
||||
if (!div_config && !mux_config) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
best_rate = ccu_mix_calc_best_rate(clk, rate, &mux_val, &div_val,
|
||||
&parent_id);
|
||||
if (!best_rate)
|
||||
return -EINVAL;
|
||||
|
||||
if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 ||
|
||||
common->reg_type == CLK_DIV_TYPE_2REG_FC_V4)
|
||||
reg = readl(common->base + common->reg_sel);
|
||||
else
|
||||
reg = readl(common->base + common->reg_ctrl);
|
||||
|
||||
if (mux_config) {
|
||||
cur_mux = reg >> mux_config->shift;
|
||||
cur_mux &= (1 << mux_config->width) - 1;
|
||||
if (cur_mux != mux_val) {
|
||||
parent = common->clk_tbl->clks[parent_id];
|
||||
if (!clk_valid(parent))
|
||||
return -EINVAL;
|
||||
|
||||
ret = clk_set_parent(clk, parent);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
if (div_config) {
|
||||
cur_div = reg >> div_config->shift;
|
||||
cur_div &= (1 << div_config->width) - 1;
|
||||
if (cur_div == div_val)
|
||||
return 0;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
val = div_val;
|
||||
if (val > BIT(div_config->width) - 1)
|
||||
return 0;
|
||||
|
||||
if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 ||
|
||||
common->reg_type == CLK_DIV_TYPE_2REG_FC_V4)
|
||||
reg = readl(common->base + common->reg_sel);
|
||||
else
|
||||
reg = readl(common->base + common->reg_ctrl);
|
||||
|
||||
reg &= ~GENMASK(div_config->width + div_config->shift - 1,
|
||||
div_config->shift);
|
||||
|
||||
if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 ||
|
||||
common->reg_type == CLK_DIV_TYPE_2REG_FC_V4)
|
||||
writel(reg | (val << div_config->shift),
|
||||
common->base + common->reg_sel);
|
||||
else
|
||||
writel(reg | (val << div_config->shift),
|
||||
common->base + common->reg_ctrl);
|
||||
|
||||
if (common->reg_type == CLK_DIV_TYPE_1REG_FC_V2 ||
|
||||
common->reg_type == CLK_DIV_TYPE_2REG_FC_V4 ||
|
||||
common->reg_type == CLK_DIV_TYPE_1REG_FC_DIV_V5 ||
|
||||
common->reg_type == CLK_DIV_TYPE_1REG_FC_MUX_V6) {
|
||||
ret = ccu_mix_trigger_fc(clk);
|
||||
if (ret)
|
||||
pr_info("%s of %s timeout\n", __func__, clk->dev->name);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned int ccu_mix_get_parent(struct clk *clk)
|
||||
{
|
||||
struct ccu_mix *mix = clk_to_ccu_mix(clk);
|
||||
struct ccu_common *common = &mix->common;
|
||||
struct ccu_mux_config *mux = mix->mux;
|
||||
u32 reg;
|
||||
unsigned int parent;
|
||||
|
||||
if (!mux)
|
||||
return 0;
|
||||
|
||||
if (common->reg_type == CLK_DIV_TYPE_2REG_NOFC_V3 ||
|
||||
common->reg_type == CLK_DIV_TYPE_2REG_FC_V4)
|
||||
reg = readl(common->base + common->reg_sel);
|
||||
else
|
||||
reg = readl(common->base + common->reg_ctrl);
|
||||
|
||||
parent = reg >> mux->shift;
|
||||
parent &= (1 << mux->width) - 1;
|
||||
|
||||
if (mux->table) {
|
||||
int num_parents = common->num_parents;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_parents; i++)
|
||||
if (mux->table[i] == parent)
|
||||
return i;
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
const struct clk_ops ccu_mix_ops = {
|
||||
.disable = ccu_mix_disable,
|
||||
.round_rate = ccu_mix_round_rate,
|
||||
.set_parent = ccu_mix_set_parent,
|
||||
.enable = ccu_mix_enable,
|
||||
.get_rate = ccu_mix_get_rate,
|
||||
.set_rate = ccu_mix_set_rate,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(ccu_clk_mix) = {
|
||||
.name = CCU_CLK_MIX,
|
||||
.id = UCLASS_CLK,
|
||||
.ops = &ccu_mix_ops,
|
||||
};
|
||||
@@ -1,368 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2023, spacemit Corporation.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _CCU_MIX_H_
|
||||
#define _CCU_MIX_H_
|
||||
|
||||
#include "ccu-k3.h"
|
||||
#include "common.h"
|
||||
|
||||
#define CCU_CLK_MIX "ccu_clk_mix"
|
||||
#define SPACEMIT_CLK_GATE_NEED_DELAY BIT(0)
|
||||
|
||||
struct ccu_gate_config {
|
||||
u32 gate_mask;
|
||||
u32 val_enable;
|
||||
u32 val_disable;
|
||||
u32 flags;
|
||||
};
|
||||
|
||||
struct ccu_factor_config {
|
||||
u32 div;
|
||||
u32 mul;
|
||||
};
|
||||
|
||||
struct ccu_mux_config {
|
||||
u8 shift;
|
||||
u8 width;
|
||||
const u8 *table;
|
||||
u32 flags;
|
||||
};
|
||||
|
||||
struct ccu_div_config {
|
||||
u8 shift;
|
||||
u8 width;
|
||||
u32 max;
|
||||
u32 offset;
|
||||
u32 flags;
|
||||
struct clk_div_table *table;
|
||||
};
|
||||
|
||||
struct ccu_mix {
|
||||
struct ccu_gate_config *gate;
|
||||
struct ccu_factor_config *factor;
|
||||
struct ccu_div_config *div;
|
||||
struct ccu_mux_config *mux;
|
||||
struct ccu_common common;
|
||||
};
|
||||
|
||||
#define CCU_GATE_INIT(_gate_mask, _val_enable, _val_disable, _flags) \
|
||||
(&(struct ccu_gate_config) { \
|
||||
.gate_mask = _gate_mask, \
|
||||
.val_enable = _val_enable, \
|
||||
.val_disable = _val_disable, \
|
||||
.flags = _flags, \
|
||||
})
|
||||
|
||||
#define CCU_FACTOR_INIT(_div, _mul) \
|
||||
(&(struct ccu_factor_config) { \
|
||||
.div = _div, \
|
||||
.mul = _mul, \
|
||||
})
|
||||
|
||||
|
||||
#define CCU_MUX_INIT(_shift, _width, _table, _flags) \
|
||||
(&(struct ccu_mux_config) { \
|
||||
.shift = _shift, \
|
||||
.width = _width, \
|
||||
.table = _table, \
|
||||
.flags = _flags, \
|
||||
})
|
||||
|
||||
#define CCU_DIV_INIT(_shift, _width, _table, _flags) \
|
||||
(&(struct ccu_div_config) { \
|
||||
.shift = _shift, \
|
||||
.width = _width, \
|
||||
.flags = _flags, \
|
||||
.table = _table, \
|
||||
})
|
||||
|
||||
#define SPACEMIT_CCU_GATE(_struct, _name, _parent, _base_type, _reg, \
|
||||
_gate_mask, _val_enable, _val_disable, _flags) \
|
||||
struct ccu_mix _struct = { \
|
||||
.gate = CCU_GATE_INIT(_gate_mask, _val_enable, _val_disable, 0), \
|
||||
.common = { \
|
||||
.reg_ctrl = _reg, \
|
||||
.base_type = _base_type, \
|
||||
.name = _name, \
|
||||
.parent_name = _parent, \
|
||||
.num_parents = 1, \
|
||||
.driver_name = CCU_CLK_MIX, \
|
||||
.flags = _flags, \
|
||||
} \
|
||||
}
|
||||
#define SPACEMIT_CCU_GATE_NO_PARENT(_struct, _name, _parent, _base_type, _reg, \
|
||||
_gate_mask, _val_enable, _val_disable, _flags) \
|
||||
struct ccu_mix _struct = { \
|
||||
.gate = CCU_GATE_INIT(_gate_mask, _val_enable, _val_disable, 0), \
|
||||
.common = { \
|
||||
.reg_ctrl = _reg, \
|
||||
.base_type = _base_type, \
|
||||
.name = _name, \
|
||||
.parent_name = SPACEMIT_CLK_NO_PARENT, \
|
||||
.num_parents = 0, \
|
||||
.driver_name = CCU_CLK_MIX, \
|
||||
.flags = _flags, \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SPACEMIT_CCU_FACTOR(_struct, _name, _parent, \
|
||||
_div, _mul) \
|
||||
struct ccu_mix _struct = { \
|
||||
.factor = CCU_FACTOR_INIT(_div, _mul), \
|
||||
.common = { \
|
||||
.name = _name, \
|
||||
.parent_name = _parent, \
|
||||
.num_parents = 1, \
|
||||
.driver_name = CCU_CLK_MIX, \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SPACEMIT_CCU_MUX(_struct, _name, _parents, _base_type, _reg, \
|
||||
_shift, _width, _flags) \
|
||||
struct ccu_mix _struct = { \
|
||||
.mux = CCU_MUX_INIT(_shift, _width, NULL, 0), \
|
||||
.common = { \
|
||||
.reg_ctrl = _reg, \
|
||||
.base_type = _base_type, \
|
||||
.name = _name, \
|
||||
.parent_names = _parents, \
|
||||
.num_parents = ARRAY_SIZE(_parents), \
|
||||
.driver_name = CCU_CLK_MIX, \
|
||||
.flags = _flags, \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SPACEMIT_CCU_DIV(_struct, _name, _parent, _base_type, _reg, \
|
||||
_shift, _width, _flags) \
|
||||
struct ccu_mix _struct = { \
|
||||
.div = CCU_DIV_INIT(_shift, _width, NULL, 0), \
|
||||
.common = { \
|
||||
.reg_ctrl = _reg, \
|
||||
.base_type = _base_type, \
|
||||
.name = _name, \
|
||||
.parent_name = _parent, \
|
||||
.num_parents = 1, \
|
||||
.driver_name = CCU_CLK_MIX, \
|
||||
.flags = _flags, \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SPACEMIT_CCU_GATE_FACTOR(_struct, _name, _parent, _base_type, _reg, \
|
||||
_gate_mask, _val_enable, _val_disable, \
|
||||
_div, _mul, _flags) \
|
||||
struct ccu_mix _struct = { \
|
||||
.gate = CCU_GATE_INIT(_gate_mask, _val_enable, _val_disable, 0), \
|
||||
.factor = CCU_FACTOR_INIT(_div, _mul), \
|
||||
.common = { \
|
||||
.reg_ctrl = _reg, \
|
||||
.base_type = _base_type, \
|
||||
.name = _name, \
|
||||
.parent_name = _parent, \
|
||||
.num_parents = 1, \
|
||||
.driver_name = CCU_CLK_MIX, \
|
||||
.flags = _flags, \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
#define SPACEMIT_CCU_MUX_GATE(_struct, _name, _parents, _base_type, _reg, \
|
||||
_shift, _width, _gate_mask, _val_enable, _val_disable, _flags) \
|
||||
struct ccu_mix _struct = { \
|
||||
.gate = CCU_GATE_INIT(_gate_mask, _val_enable, _val_disable, 0), \
|
||||
.mux = CCU_MUX_INIT(_shift, _width, NULL, 0), \
|
||||
.common = { \
|
||||
.reg_ctrl = _reg, \
|
||||
.base_type = _base_type, \
|
||||
.name = _name, \
|
||||
.parent_names = _parents, \
|
||||
.num_parents = ARRAY_SIZE(_parents), \
|
||||
.driver_name = CCU_CLK_MIX, \
|
||||
.flags = _flags, \
|
||||
} \
|
||||
}
|
||||
|
||||
#define SPACEMIT_CCU_DIV_GATE(_struct, _name, _parent, _base_type, _reg, \
|
||||
_shift, _width, _gate_mask, _val_enable, _val_disable, _flags) \
|
||||
struct ccu_mix _struct = { \
|
||||
.gate = CCU_GATE_INIT(_gate_mask, _val_enable, _val_disable, 0), \
|
||||
.div = CCU_DIV_INIT(_shift, _width, NULL, 0), \
|
||||
.common = { \
|
||||
.reg_ctrl = _reg, \
|
||||
.base_type = _base_type, \
|
||||
.name = _name, \
|
||||
.parent_name = _parent, \
|
||||
.num_parents = 1, \
|
||||
.driver_name = CCU_CLK_MIX, \
|
||||
.flags = _flags, \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
#define SPACEMIT_CCU_DIV_MUX_GATE(_struct, _name, _parents, \
|
||||
_base_type, _reg_ctrl, \
|
||||
_mshift, _mwidth, \
|
||||
_muxshift, _muxwidth, \
|
||||
_gate_mask, _val_enable, _val_disable, _flags) \
|
||||
struct ccu_mix _struct = { \
|
||||
.gate = CCU_GATE_INIT(_gate_mask, _val_enable, _val_disable, 0), \
|
||||
.div = CCU_DIV_INIT(_mshift, _mwidth, NULL, 0), \
|
||||
.mux = CCU_MUX_INIT(_muxshift, _muxwidth, NULL, 0), \
|
||||
.common = { \
|
||||
.reg_ctrl = _reg_ctrl, \
|
||||
.base_type = _base_type, \
|
||||
.name = _name, \
|
||||
.parent_names = _parents, \
|
||||
.num_parents = ARRAY_SIZE(_parents), \
|
||||
.driver_name = CCU_CLK_MIX, \
|
||||
.flags = _flags, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define SPACEMIT_CCU_DIV2_FC_MUX_GATE(_struct, _name, _parents, _base_type, _reg_ctrl, _reg_sel, \
|
||||
_mshift, _mwidth, _fc, _muxshift, _muxwidth, _gate_mask, _val_enable, _val_disable, \
|
||||
_flags) \
|
||||
struct ccu_mix _struct = { \
|
||||
.gate = CCU_GATE_INIT(_gate_mask, _val_enable, _val_disable, 0), \
|
||||
.div = CCU_DIV_INIT(_mshift, _mwidth, NULL, 0), \
|
||||
.mux = CCU_MUX_INIT(_muxshift, _muxwidth, NULL, 0), \
|
||||
.common = { \
|
||||
.reg_type = CLK_DIV_TYPE_2REG_FC_V4, \
|
||||
.reg_ctrl = _reg_ctrl, \
|
||||
.reg_sel = _reg_sel, \
|
||||
.fc = _fc, \
|
||||
.base_type = _base_type, \
|
||||
.name = _name, \
|
||||
.parent_names = _parents, \
|
||||
.num_parents = ARRAY_SIZE(_parents), \
|
||||
.driver_name = CCU_CLK_MIX, \
|
||||
.flags = _flags, \
|
||||
}, \
|
||||
}
|
||||
|
||||
|
||||
#define SPACEMIT_CCU_DIV_FC_MUX_GATE(_struct, _name, _parents, _base_type, _reg_ctrl, \
|
||||
_mshift, _mwidth, _fc, _muxshift, _muxwidth, _gate_mask, _val_enable, _val_disable, \
|
||||
_flags) \
|
||||
struct ccu_mix _struct = { \
|
||||
.gate = CCU_GATE_INIT(_gate_mask, _val_enable, _val_disable, 0), \
|
||||
.div = CCU_DIV_INIT(_mshift, _mwidth, NULL, 0), \
|
||||
.mux = CCU_MUX_INIT(_muxshift, _muxwidth, NULL, 0), \
|
||||
.common = { \
|
||||
.reg_type = CLK_DIV_TYPE_1REG_FC_V2, \
|
||||
.reg_ctrl = _reg_ctrl, \
|
||||
.fc = _fc, \
|
||||
.base_type = _base_type, \
|
||||
.name = _name, \
|
||||
.parent_names = _parents, \
|
||||
.num_parents = ARRAY_SIZE(_parents), \
|
||||
.driver_name = CCU_CLK_MIX, \
|
||||
.flags = _flags, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define SPACEMIT_CCU_DIV_MFC_MUX_GATE(_struct, _name, _parents, _base_type, _reg_ctrl, \
|
||||
_mshift, _mwidth, _fc, _muxshift, _muxwidth, _gate_mask, _val_enable, _val_disable, \
|
||||
_flags) \
|
||||
struct ccu_mix _struct = { \
|
||||
.gate = CCU_GATE_INIT(_gate_mask, _val_enable, _val_disable, 0), \
|
||||
.div = CCU_DIV_INIT(_mshift, _mwidth, NULL, 0), \
|
||||
.mux = CCU_MUX_INIT(_muxshift, _muxwidth, NULL, 0), \
|
||||
.common = { \
|
||||
.reg_type = CLK_DIV_TYPE_1REG_FC_MUX_V6, \
|
||||
.reg_ctrl = _reg_ctrl, \
|
||||
.fc = _fc, \
|
||||
.base_type = _base_type, \
|
||||
.name = _name, \
|
||||
.parent_names = _parents, \
|
||||
.num_parents = ARRAY_SIZE(_parents), \
|
||||
.driver_name = CCU_CLK_MIX, \
|
||||
.flags = _flags, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define SPACEMIT_CCU_DIV_FC_WITH_GATE(_struct, _name, _parent, _base_type, _reg_ctrl, \
|
||||
_mshift, _mwidth, _fc, _gate_mask, _val_enable, _val_disable, \
|
||||
_flags) \
|
||||
struct ccu_mix _struct = { \
|
||||
.gate = CCU_GATE_INIT(_gate_mask, _val_enable, _val_disable, 0), \
|
||||
.div = CCU_DIV_INIT(_mshift, _mwidth, NULL, 0), \
|
||||
.common = { \
|
||||
.reg_type = CLK_DIV_TYPE_1REG_FC_V2, \
|
||||
.reg_ctrl = _reg_ctrl, \
|
||||
.fc = _fc, \
|
||||
.base_type = _base_type, \
|
||||
.name = _name, \
|
||||
.parent_name = _parent, \
|
||||
.num_parents = 1, \
|
||||
.driver_name = CCU_CLK_MIX, \
|
||||
.flags = _flags, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define SPACEMIT_CCU_DIV_FC_MUX(_struct, _name, _parents, _base_type, _reg_ctrl, \
|
||||
_mshift, _mwidth, _fc, _muxshift, _muxwidth, _flags) \
|
||||
struct ccu_mix _struct = { \
|
||||
.div = CCU_DIV_INIT(_mshift, _mwidth, NULL, 0), \
|
||||
.mux = CCU_MUX_INIT(_muxshift, _muxwidth, NULL, 0), \
|
||||
.common = { \
|
||||
.reg_type = CLK_DIV_TYPE_1REG_FC_V2, \
|
||||
.reg_ctrl = _reg_ctrl, \
|
||||
.fc = _fc, \
|
||||
.base_type = _base_type, \
|
||||
.name = _name, \
|
||||
.parent_names = _parents, \
|
||||
.num_parents = ARRAY_SIZE(_parents), \
|
||||
.driver_name = CCU_CLK_MIX, \
|
||||
.flags = _flags, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define SPACEMIT_CCU_MUX_FC_GATE(_struct, _name, _parents, _base_type, _reg_ctrl, \
|
||||
_fc, _muxshift, _muxwidth, _gate_mask, _val_enable, _val_disable, _flags) \
|
||||
struct ccu_mix _struct = { \
|
||||
.gate = CCU_GATE_INIT(_gate_mask, _val_enable, _val_disable, 0), \
|
||||
.mux = CCU_MUX_INIT(_muxshift, _muxwidth, NULL, 0), \
|
||||
.common = { \
|
||||
.reg_type = CLK_DIV_TYPE_1REG_FC_V2, \
|
||||
.reg_ctrl = _reg_ctrl, \
|
||||
.fc = _fc, \
|
||||
.base_type = _base_type, \
|
||||
.name = _name, \
|
||||
.parent_names = _parents, \
|
||||
.num_parents = ARRAY_SIZE(_parents), \
|
||||
.driver_name = CCU_CLK_MIX, \
|
||||
.flags = _flags, \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define SPACEMIT_CCU_MUX_FC(_struct, _name, _parents, _base_type, _reg_ctrl, \
|
||||
_fc, _muxshift, _muxwidth, _flags) \
|
||||
struct ccu_mix _struct = { \
|
||||
.mux = CCU_MUX_INIT(_muxshift, _muxwidth, NULL, 0), \
|
||||
.common = { \
|
||||
.reg_type = CLK_DIV_TYPE_1REG_FC_V2, \
|
||||
.reg_ctrl = _reg_ctrl, \
|
||||
.fc = _fc, \
|
||||
.base_type = _base_type, \
|
||||
.name = _name, \
|
||||
.parent_names = _parents, \
|
||||
.num_parents = ARRAY_SIZE(_parents), \
|
||||
.driver_name = CCU_CLK_MIX, \
|
||||
.flags = _flags, \
|
||||
}, \
|
||||
}
|
||||
|
||||
static inline struct ccu_mix *clk_to_ccu_mix(struct clk *clk)
|
||||
{
|
||||
struct ccu_common *common = clk_to_ccu_common(clk);
|
||||
|
||||
return container_of(common, struct ccu_mix, common);
|
||||
}
|
||||
|
||||
unsigned int ccu_mix_get_parent(struct clk *clk);
|
||||
|
||||
#endif /* _CCU_DIV_H_ */
|
||||
@@ -1,267 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2024 SpacemiT Technology Co. Ltd
|
||||
* Copyright (c) 2024-2025 Haylen Chu <heylenay@4d2.org>
|
||||
*/
|
||||
|
||||
#include <asm/io.h>
|
||||
#include <malloc.h>
|
||||
#include <clk-uclass.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <clk.h>
|
||||
#include <div64.h>
|
||||
#include "ccu_plla.h"
|
||||
|
||||
#define PLL_MIN_FREQ 600000000
|
||||
#define PLL_MAX_FREQ 3400000000
|
||||
#define PLL_DELAYTIME 590 //(590*5)us
|
||||
|
||||
#define PLLA_SWCR2_MASK GENMASK(15, 8)
|
||||
|
||||
#define plla_readl(reg) readl(reg)
|
||||
#define plla_readl_pll_swcr1(p) plla_readl(p.base + p.reg_ctrl)
|
||||
#define plla_readl_pll_swcr2(p) plla_readl(p.base + p.reg_sel)
|
||||
#define plla_readl_pll_swcr3(p) plla_readl(p.base + p.reg_xtc)
|
||||
|
||||
#define plla_writel(val, reg) writel(val, reg)
|
||||
#define plla_writel_pll_swcr1(val, p) plla_writel(val, p.base + p.reg_ctrl)
|
||||
#define plla_writel_pll_swcr2(val, p) plla_writel(val, p.base + p.reg_sel)
|
||||
#define plla_writel_pll_swcr3(val, p) plla_writel(val, p.base + p.reg_xtc)
|
||||
|
||||
/* unified pllax_swcr1 for plla */
|
||||
union pllax_swcr1 {
|
||||
struct {
|
||||
unsigned int reg1:8;
|
||||
unsigned int reg2:8;
|
||||
unsigned int reg3:8;
|
||||
unsigned int reg4:8;
|
||||
} b;
|
||||
unsigned int v;
|
||||
};
|
||||
|
||||
/* unified pllax_swcr2 for plla */
|
||||
union pllax_swcr2 {
|
||||
struct {
|
||||
unsigned int div1_en:1;
|
||||
unsigned int div2_en:1;
|
||||
unsigned int div3_en:1;
|
||||
unsigned int div4_en:1;
|
||||
unsigned int div5_en:1;
|
||||
unsigned int div6_en:1;
|
||||
unsigned int div7_en:1;
|
||||
unsigned int div8_en:1;
|
||||
unsigned int reg0:8;
|
||||
unsigned int pll_en:1;
|
||||
unsigned int mon_cfg:4;
|
||||
unsigned int div10_en:1;
|
||||
unsigned int mmd_en:1;
|
||||
unsigned int mmd:5;
|
||||
unsigned int reserved2:3;
|
||||
unsigned int div64_en:1;
|
||||
} b;
|
||||
unsigned int v;
|
||||
};
|
||||
|
||||
/* unified pllax_swcr3 for plla */
|
||||
union pllax_swcr3{
|
||||
struct {
|
||||
unsigned int reg5:8;
|
||||
unsigned int reg6:8;
|
||||
unsigned int reg7:8;
|
||||
unsigned int reg8:8;
|
||||
} b;
|
||||
|
||||
unsigned int v;
|
||||
};
|
||||
|
||||
static int ccu_plla_is_enabled(struct clk *clk)
|
||||
{
|
||||
struct ccu_plla *p = clk_to_ccu_plla(clk);
|
||||
union pllax_swcr2 swcr2;
|
||||
unsigned int enabled;
|
||||
|
||||
swcr2.v = plla_readl_pll_swcr2(p->common);
|
||||
enabled = swcr2.b.pll_en;
|
||||
|
||||
return enabled;
|
||||
}
|
||||
|
||||
/* frequency unit Mhz, return pll vco freq */
|
||||
static ulong __get_vco_freq(struct clk *clk)
|
||||
{
|
||||
unsigned int size, i;
|
||||
struct ccu_plla_rate_tbl *freq_pll_regs_table;
|
||||
struct ccu_plla *p = clk_to_ccu_plla(clk);
|
||||
union pllax_swcr1 swcr1;
|
||||
union pllax_swcr2 swcr2;
|
||||
union pllax_swcr3 swcr3;
|
||||
|
||||
swcr1.v = plla_readl_pll_swcr1(p->common);
|
||||
swcr2.v = plla_readl_pll_swcr2(p->common);
|
||||
swcr2.v &= PLLA_SWCR2_MASK;
|
||||
swcr3.v = plla_readl_pll_swcr3(p->common);
|
||||
|
||||
freq_pll_regs_table = p->pll.rate_tbl;
|
||||
size = p->pll.tbl_size;
|
||||
|
||||
for (i = 0; i < size; i++) {
|
||||
if ((freq_pll_regs_table[i].swcr1 == swcr1.v) &&
|
||||
(freq_pll_regs_table[i].swcr2 == swcr2.v) &&
|
||||
(freq_pll_regs_table[i].swcr3 == swcr3.v))
|
||||
return freq_pll_regs_table[i].rate;
|
||||
}
|
||||
|
||||
pr_info("Unknown rate for clock\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ccu_plla_enable(struct clk *clk)
|
||||
{
|
||||
unsigned int delaytime = PLL_DELAYTIME;
|
||||
struct ccu_plla *p = clk_to_ccu_plla(clk);
|
||||
union pllax_swcr2 swcr2;
|
||||
|
||||
if (ccu_plla_is_enabled(clk))
|
||||
return 0;
|
||||
|
||||
swcr2.v = plla_readl_pll_swcr2(p->common);
|
||||
swcr2.b.pll_en = 1;
|
||||
plla_writel_pll_swcr2(swcr2.v, p->common);
|
||||
|
||||
/* check lock status */
|
||||
udelay(50);
|
||||
|
||||
while ((!(readl(p->pll.lock_base + p->pll.reg_lock) & p->pll.lock_enable_bit))
|
||||
&& delaytime) {
|
||||
udelay(5);
|
||||
delaytime--;
|
||||
}
|
||||
if (unlikely(!delaytime))
|
||||
pr_err("ccu_pll_enable enabling didn't get stable within 3000us!!!\n" );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ccu_plla_disable(struct clk *clk)
|
||||
{
|
||||
struct ccu_plla *p = clk_to_ccu_plla(clk);
|
||||
union pllax_swcr2 swcr2;
|
||||
|
||||
swcr2.v = plla_readl_pll_swcr2(p->common);
|
||||
swcr2.b.pll_en = 0;
|
||||
plla_writel_pll_swcr2(swcr2.v, p->common);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* pll rate change requires sequence:
|
||||
* clock off -> change rate setting -> clock on
|
||||
* This function doesn't really change rate, but cache the config
|
||||
*/
|
||||
static ulong ccu_plla_set_rate(struct clk *clk, ulong rate)
|
||||
{
|
||||
unsigned int i, reg0 = 0;
|
||||
struct ccu_plla *p = clk_to_ccu_plla(clk);
|
||||
struct ccu_plla_config *params = &p->pll;
|
||||
union pllax_swcr1 swcr1;
|
||||
union pllax_swcr1 swcr2;
|
||||
union pllax_swcr3 swcr3;
|
||||
bool found = false;
|
||||
bool pll_enabled = false;
|
||||
|
||||
if (ccu_plla_is_enabled(clk)) {
|
||||
pll_enabled = true;
|
||||
ccu_plla_disable(clk);
|
||||
}
|
||||
|
||||
/* setp 1: calculate fbd frcd kvco and band */
|
||||
if (params->rate_tbl) {
|
||||
for (i = 0; i < params->tbl_size; i++) {
|
||||
if (rate == params->rate_tbl[i].rate) {
|
||||
found = true;
|
||||
|
||||
swcr1.v = params->rate_tbl[i].swcr1;
|
||||
reg0 = params->rate_tbl[i].swcr2;
|
||||
swcr3.v = params->rate_tbl[i].swcr3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pr_err("don't find freq table for pll\n");
|
||||
if (pll_enabled)
|
||||
ccu_plla_enable(clk);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
pr_err("unsupported pll rate %lu\n", rate);
|
||||
if (pll_enabled)
|
||||
ccu_plla_enable(clk);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* setp 2: set pll kvco/band and fbd/frcd setting */
|
||||
plla_writel_pll_swcr1(swcr1.v, p->common);
|
||||
|
||||
swcr2.v = plla_readl_pll_swcr2(p->common);
|
||||
swcr2.v &= ~PLLA_SWCR2_MASK;
|
||||
swcr2.v |= reg0;
|
||||
plla_writel_pll_swcr2(swcr2.v, p->common);
|
||||
|
||||
plla_writel_pll_swcr3(swcr3.v, p->common);
|
||||
|
||||
if (pll_enabled)
|
||||
ccu_plla_enable(clk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ulong ccu_plla_get_rate(struct clk *clk)
|
||||
{
|
||||
ulong val;
|
||||
val = __get_vco_freq(clk);
|
||||
return val;
|
||||
}
|
||||
|
||||
static ulong ccu_plla_round_rate(struct clk *clk, ulong rate)
|
||||
{
|
||||
struct ccu_plla *p = clk_to_ccu_plla(clk);
|
||||
unsigned long max_rate = 0;
|
||||
unsigned int i;
|
||||
struct ccu_plla_config *params = &p->pll;
|
||||
|
||||
if (rate > PLL_MAX_FREQ || rate < PLL_MIN_FREQ) {
|
||||
pr_err("%lu rate out of range!\n", rate);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (params->rate_tbl) {
|
||||
for (i = 0; i < params->tbl_size; i++) {
|
||||
if (params->rate_tbl[i].rate <= rate) {
|
||||
if (max_rate < params->rate_tbl[i].rate)
|
||||
max_rate = params->rate_tbl[i].rate;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pr_info("don't find freq table for pll\n");
|
||||
}
|
||||
return max_rate;
|
||||
}
|
||||
|
||||
const struct clk_ops ccu_plla_ops = {
|
||||
.enable = ccu_plla_enable,
|
||||
.disable = ccu_plla_disable,
|
||||
.set_rate = ccu_plla_set_rate,
|
||||
.get_rate = ccu_plla_get_rate,
|
||||
.round_rate = ccu_plla_round_rate,
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(ccu_clk_plla) = {
|
||||
.name = CCU_CLK_PLLA,
|
||||
.id = UCLASS_CLK,
|
||||
.ops = &ccu_plla_ops,
|
||||
};
|
||||
@@ -1,76 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2024 SpacemiT Technology Co. Ltd
|
||||
* Copyright (c) 2024-2025 Haylen Chu <heylenay@4d2.org>
|
||||
*/
|
||||
|
||||
#ifndef _CCU_PLLA_H_
|
||||
#define _CCU_PLLA_H_
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#define CCU_CLK_PLLA "ccu_clk_plla"
|
||||
struct ccu_plla_rate_tbl {
|
||||
unsigned long long rate;
|
||||
u32 swcr1;
|
||||
u32 swcr2;
|
||||
u32 swcr3;
|
||||
};
|
||||
|
||||
struct ccu_plla_config {
|
||||
struct ccu_plla_rate_tbl *rate_tbl;
|
||||
u32 tbl_size;
|
||||
void __iomem *lock_base;
|
||||
u32 reg_lock;
|
||||
u32 lock_enable_bit;
|
||||
};
|
||||
|
||||
#define PLLA_RATE(_rate, _swcr1, _swcr2, _swcr3) \
|
||||
{ \
|
||||
.rate = _rate, \
|
||||
.swcr1 = _swcr1, \
|
||||
.swcr2 = _swcr2, \
|
||||
.swcr3 = _swcr3, \
|
||||
}
|
||||
|
||||
struct ccu_plla {
|
||||
struct ccu_plla_config pll;
|
||||
struct ccu_common common;
|
||||
};
|
||||
|
||||
#define _SPACEMIT_CCU_PLLA_CONFIG(_table, _size, _reg_lock, _lock_enable_bit) \
|
||||
{ \
|
||||
.rate_tbl = (struct ccu_plla_rate_tbl *)_table, \
|
||||
.tbl_size = _size, \
|
||||
.reg_lock = _reg_lock, \
|
||||
.lock_enable_bit = _lock_enable_bit, \
|
||||
}
|
||||
|
||||
#define SPACEMIT_CCU_PLLA(_struct, _name, _table, _size, \
|
||||
_base_type, _reg_ctrl, _reg_sel, _reg_xtc, \
|
||||
_reg_lock, _lock_enable_bit, _is_pll, \
|
||||
_flags) \
|
||||
struct ccu_plla _struct = { \
|
||||
.pll = _SPACEMIT_CCU_PLLA_CONFIG(_table, _size, _reg_lock, _lock_enable_bit), \
|
||||
.common = { \
|
||||
.reg_ctrl = _reg_ctrl, \
|
||||
.reg_sel = _reg_sel, \
|
||||
.reg_xtc = _reg_xtc, \
|
||||
.base_type = _base_type, \
|
||||
.is_pll = _is_pll, \
|
||||
.name = _name, \
|
||||
.parent_name = SPACEMIT_CLK_NO_PARENT, \
|
||||
.num_parents = 1, \
|
||||
.driver_name = CCU_CLK_PLLA, \
|
||||
} \
|
||||
}
|
||||
|
||||
|
||||
static inline struct ccu_plla *clk_to_ccu_plla(struct clk *clk)
|
||||
{
|
||||
struct ccu_common *common = clk_to_ccu_common(clk);
|
||||
|
||||
return container_of(common, struct ccu_plla, common);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,82 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2023, spacemit Corporation.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _CCU_SPACEMIT_COMMON_H_
|
||||
#define _CCU_SPACEMIT_COMMON_H_
|
||||
|
||||
#include <clk.h>
|
||||
#include <clk-uclass.h>
|
||||
|
||||
#include <dt-bindings/clock/spacemit-k3-clock.h>
|
||||
|
||||
#define SPACEMIT_CLK_NO_PARENT "clk_dummy"
|
||||
|
||||
enum ccu_base_type{
|
||||
BASE_TYPE_MPMU = 0,
|
||||
BASE_TYPE_APMU = 1,
|
||||
BASE_TYPE_APBC = 2,
|
||||
BASE_TYPE_APBS = 3,
|
||||
BASE_TYPE_CIU = 4,
|
||||
BASE_TYPE_DCIU = 5,
|
||||
BASE_TYPE_DDRC = 6,
|
||||
BASE_TYPE_AUDC = 7,
|
||||
BASE_TYPE_APBC2 = 8,
|
||||
BASE_TYPE_RCPU = 9,
|
||||
};
|
||||
|
||||
enum {
|
||||
CLK_DIV_TYPE_1REG_NOFC_V1 = 0,
|
||||
CLK_DIV_TYPE_1REG_FC_V2,
|
||||
CLK_DIV_TYPE_2REG_NOFC_V3,
|
||||
CLK_DIV_TYPE_2REG_FC_V4,
|
||||
CLK_DIV_TYPE_1REG_FC_DIV_V5,
|
||||
CLK_DIV_TYPE_1REG_FC_MUX_V6,
|
||||
};
|
||||
|
||||
struct ccu_common {
|
||||
void __iomem *base;
|
||||
enum ccu_base_type base_type;
|
||||
u32 reg_type;
|
||||
u32 reg_ctrl;
|
||||
u32 reg_sel;
|
||||
u32 reg_xtc;
|
||||
u32 fc;
|
||||
bool is_pll;
|
||||
const char *name;
|
||||
const char *driver_name;
|
||||
const char *parent_name;
|
||||
const char * const *parent_names;
|
||||
u8 num_parents;
|
||||
unsigned long flags;
|
||||
struct clk clk;
|
||||
struct spacemit_clk_table * clk_tbl;
|
||||
};
|
||||
|
||||
struct spacemit_ccu_clk {
|
||||
void __iomem *mpmu_base;
|
||||
void __iomem *apmu_base;
|
||||
void __iomem *apbc_base;
|
||||
void __iomem *apbs_base;
|
||||
void __iomem *ciu_base;
|
||||
void __iomem *dciu_base;
|
||||
void __iomem *ddrc_base;
|
||||
void __iomem *audio_ctrl_base;
|
||||
void __iomem *apbc2_base;
|
||||
void __iomem *rcpu_base;
|
||||
u32 pll2_freq;
|
||||
};
|
||||
|
||||
struct spacemit_clk_table{
|
||||
struct clk* clks[CLK_MAX_NO];
|
||||
unsigned int num;
|
||||
};
|
||||
|
||||
static inline struct ccu_common *clk_to_ccu_common(struct clk *clk)
|
||||
{
|
||||
return container_of(clk, struct ccu_common, clk);
|
||||
}
|
||||
|
||||
#endif /* _CCU_SPACEMIT_COMMON_H_ */
|
||||
@@ -817,12 +817,6 @@ config SYS_I2C_IHS
|
||||
help
|
||||
Support for gdsys IHS I2C driver on FPGA bus.
|
||||
|
||||
config SYS_I2C_SPACEMIT
|
||||
bool "SPACEMIT I2C driver"
|
||||
depends on DM_I2C || TARGET_SPACEMIT_K3
|
||||
help
|
||||
Support for SPACEMIT I2C controllers.
|
||||
|
||||
source "drivers/i2c/muxes/Kconfig"
|
||||
|
||||
endif
|
||||
|
||||
@@ -58,5 +58,5 @@ obj-$(CONFIG_SYS_I2C_UNIPHIER_F) += i2c-uniphier-f.o
|
||||
obj-$(CONFIG_SYS_I2C_VERSATILE) += i2c-versatile.o
|
||||
obj-$(CONFIG_SYS_I2C_XILINX_XIIC) += xilinx_xiic.o
|
||||
obj-$(CONFIG_TEGRA186_BPMP_I2C) += tegra186_bpmp_i2c.o
|
||||
obj-$(CONFIG_$(SPL_)SYS_I2C_SPACEMIT) += spacemit_i2c.o
|
||||
|
||||
obj-$(CONFIG_$(PHASE_)I2C_MUX) += muxes/
|
||||
|
||||
@@ -1,468 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2023 Spacemit
|
||||
*/
|
||||
|
||||
#include <dm.h>
|
||||
#include <reset.h>
|
||||
#include <clk.h>
|
||||
#include <i2c.h>
|
||||
#include <log.h>
|
||||
#include <asm/io.h>
|
||||
#include <linux/delay.h>
|
||||
#include "spacemit_i2c.h"
|
||||
|
||||
/* All transfers are described by this data structure */
|
||||
struct spacemit_i2c_msg {
|
||||
u8 condition;
|
||||
u8 acknack;
|
||||
u8 direction;
|
||||
u8 data;
|
||||
};
|
||||
|
||||
struct spacemit_i2c {
|
||||
u32 icr;
|
||||
u32 isr;
|
||||
u32 isar;
|
||||
u32 idbr;
|
||||
u32 ilcr;
|
||||
u32 iwcr;
|
||||
u32 irst_cyc;
|
||||
u32 ibmr;
|
||||
};
|
||||
|
||||
/*
|
||||
* i2c_reset: - reset the host controller
|
||||
*
|
||||
*/
|
||||
static void i2c_reset(struct spacemit_i2c *base, bool sda_glitch_nofix)
|
||||
{
|
||||
u32 icr_mode;
|
||||
|
||||
/* Save bus mode (standard or fast speed) for later use */
|
||||
icr_mode = readl(&base->icr) & ICR_MODE_MASK;
|
||||
writel(readl(&base->icr) & ~ICR_IUE, &base->icr); /* disable unit */
|
||||
writel(readl(&base->icr) | ICR_UR, &base->icr); /* reset the unit */
|
||||
udelay(100);
|
||||
writel(readl(&base->icr) & ~ICR_IUE, &base->icr); /* disable unit */
|
||||
|
||||
#ifdef CONFIG_SYS_I2C_SLAVE
|
||||
writel(CONFIG_SYS_I2C_SLAVE, &base->isar); /* set our slave address */
|
||||
#else
|
||||
writel(0x00, &base->isar); /* set our slave address */
|
||||
#endif
|
||||
/* set control reg values */
|
||||
writel(I2C_ICR_INIT | icr_mode, &base->icr);
|
||||
writel(I2C_ISR_INIT, &base->isr); /* set clear interrupt bits */
|
||||
if (sda_glitch_nofix)
|
||||
writel(readl(&base->irst_cyc) | IRCR_SDA_GLITCH_NOFIX,
|
||||
&base->irst_cyc);
|
||||
writel(readl(&base->icr) | ICR_IUE, &base->icr); /* enable unit */
|
||||
udelay(1e0);
|
||||
}
|
||||
|
||||
/*
|
||||
* i2c_isr_set_cleared: - wait until certain bits of the I2C status register
|
||||
* are set and cleared
|
||||
*
|
||||
* @return: 1 in case of success, 0 means timeout (no match within 10 ms).
|
||||
*/
|
||||
static int i2c_isr_set_cleared(struct spacemit_i2c *base, unsigned long set_mask,
|
||||
unsigned long cleared_mask)
|
||||
{
|
||||
int timeout = 1000, isr;
|
||||
|
||||
do {
|
||||
isr = readl(&base->isr);
|
||||
/* udelay(10); */
|
||||
/* this delay time can't exceed the watchog timeout period */
|
||||
__udelay(10);
|
||||
if (timeout-- < 0)
|
||||
return 0;
|
||||
} while (((isr & set_mask) != set_mask)
|
||||
|| ((isr & cleared_mask) != 0));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* i2c_transfer: - Transfer one byte over the i2c bus
|
||||
*
|
||||
* This function can tranfer a byte over the i2c bus in both directions.
|
||||
* It is used by the public API functions.
|
||||
*
|
||||
* @return: 0: transfer successful
|
||||
* -1: message is empty
|
||||
* -2: transmit timeout
|
||||
* -3: ACK missing
|
||||
* -4: receive timeout
|
||||
* -5: illegal parameters
|
||||
* -6: bus is busy and couldn't be aquired
|
||||
*/
|
||||
static int i2c_transfer(struct spacemit_i2c *base, struct spacemit_i2c_msg *msg,
|
||||
bool sda_glitch_nofix)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (!msg)
|
||||
goto transfer_error_msg_empty;
|
||||
|
||||
switch (msg->direction) {
|
||||
case I2C_WRITE:
|
||||
/* check if bus is not busy */
|
||||
if (!i2c_isr_set_cleared(base, 0, ISR_IBB))
|
||||
goto transfer_error_bus_busy;
|
||||
|
||||
/* start transmission */
|
||||
writel(readl(&base->icr) & ~ICR_START, &base->icr);
|
||||
writel(readl(&base->icr) & ~ICR_STOP, &base->icr);
|
||||
writel(msg->data, &base->idbr);
|
||||
if (msg->condition == I2C_COND_START)
|
||||
writel(readl(&base->icr) | ICR_START, &base->icr);
|
||||
if (msg->condition == I2C_COND_STOP)
|
||||
writel(readl(&base->icr) | ICR_STOP, &base->icr);
|
||||
if (msg->acknack == I2C_ACKNAK_SENDNAK)
|
||||
writel(readl(&base->icr) | ICR_ACKNAK, &base->icr);
|
||||
if (msg->acknack == I2C_ACKNAK_SENDACK)
|
||||
writel(readl(&base->icr) & ~ICR_ACKNAK, &base->icr);
|
||||
writel(readl(&base->icr) & ~ICR_ALDIE, &base->icr);
|
||||
writel(readl(&base->icr) | ICR_TB, &base->icr);
|
||||
|
||||
/* transmit register empty? */
|
||||
if (!i2c_isr_set_cleared(base, ISR_ITE, 0))
|
||||
goto transfer_error_transmit_timeout;
|
||||
|
||||
/* clear 'transmit empty' state */
|
||||
writel(readl(&base->isr) | ISR_ITE, &base->isr);
|
||||
|
||||
/* wait for ACK from slave */
|
||||
if (msg->acknack == I2C_ACKNAK_WAITACK)
|
||||
if (!i2c_isr_set_cleared(base, 0, ISR_ACKNAK))
|
||||
goto transfer_error_ack_missing;
|
||||
break;
|
||||
|
||||
case I2C_READ:
|
||||
|
||||
/* check if bus is not busy */
|
||||
if (!i2c_isr_set_cleared(base, 0, ISR_IBB))
|
||||
goto transfer_error_bus_busy;
|
||||
|
||||
/* start receive */
|
||||
writel(readl(&base->icr) & ~ICR_START, &base->icr);
|
||||
writel(readl(&base->icr) & ~ICR_STOP, &base->icr);
|
||||
if (msg->condition == I2C_COND_START)
|
||||
writel(readl(&base->icr) | ICR_START, &base->icr);
|
||||
if (msg->condition == I2C_COND_STOP)
|
||||
writel(readl(&base->icr) | ICR_STOP, &base->icr);
|
||||
if (msg->acknack == I2C_ACKNAK_SENDNAK)
|
||||
writel(readl(&base->icr) | ICR_ACKNAK, &base->icr);
|
||||
if (msg->acknack == I2C_ACKNAK_SENDACK)
|
||||
writel(readl(&base->icr) & ~ICR_ACKNAK, &base->icr);
|
||||
writel(readl(&base->icr) & ~ICR_ALDIE, &base->icr);
|
||||
writel(readl(&base->icr) | ICR_TB, &base->icr);
|
||||
|
||||
/* receive register full? */
|
||||
if (!i2c_isr_set_cleared(base, ISR_IRF, 0))
|
||||
goto transfer_error_receive_timeout;
|
||||
|
||||
msg->data = readl(&base->idbr);
|
||||
|
||||
/* clear 'receive empty' state */
|
||||
writel(readl(&base->isr) | ISR_IRF, &base->isr);
|
||||
break;
|
||||
default:
|
||||
goto transfer_error_illegal_param;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
transfer_error_msg_empty:
|
||||
debug("i2c_transfer: error: 'msg' is empty\n");
|
||||
ret = -1;
|
||||
goto i2c_transfer_finish;
|
||||
|
||||
transfer_error_transmit_timeout:
|
||||
debug("i2c_transfer: error: transmit timeout\n");
|
||||
ret = -2;
|
||||
goto i2c_transfer_finish;
|
||||
|
||||
transfer_error_ack_missing:
|
||||
debug("i2c_transfer: error: ACK missing\n");
|
||||
ret = -3;
|
||||
goto i2c_transfer_finish;
|
||||
|
||||
transfer_error_receive_timeout:
|
||||
debug("i2c_transfer: error: receive timeout\n");
|
||||
ret = -4;
|
||||
goto i2c_transfer_finish;
|
||||
|
||||
transfer_error_illegal_param:
|
||||
debug("i2c_transfer: error: illegal parameters\n");
|
||||
ret = -5;
|
||||
goto i2c_transfer_finish;
|
||||
|
||||
transfer_error_bus_busy:
|
||||
debug("i2c_transfer: error: bus is busy\n");
|
||||
ret = -6;
|
||||
goto i2c_transfer_finish;
|
||||
|
||||
i2c_transfer_finish:
|
||||
debug("i2c_transfer: ISR: 0x%04x\n", readl(&base->isr));
|
||||
i2c_reset(base, sda_glitch_nofix);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __i2c_read(struct spacemit_i2c *base, uchar chip, u8 *addr, int alen,
|
||||
uchar *buffer, int len, bool sda_glitch_nofix)
|
||||
{
|
||||
struct spacemit_i2c_msg msg;
|
||||
|
||||
debug("i2c_read(chip=0x%02x, len=0x%02x)\n", chip, len);
|
||||
|
||||
if (len == 0) {
|
||||
pr_err("reading zero byte is invalid\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
i2c_reset(base, sda_glitch_nofix);
|
||||
|
||||
/* dummy chip address write */
|
||||
debug("i2c_read: dummy chip address write\n");
|
||||
msg.condition = I2C_COND_START;
|
||||
msg.acknack = I2C_ACKNAK_WAITACK;
|
||||
msg.direction = I2C_WRITE;
|
||||
msg.data = (chip << 1);
|
||||
msg.data &= 0xFE;
|
||||
if (i2c_transfer(base, &msg, sda_glitch_nofix))
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* send memory address bytes;
|
||||
* alen defines how much bytes we have to send.
|
||||
*/
|
||||
while (--alen >= 0) {
|
||||
debug("i2c_read: send address byte %02x (alen=%d)\n",
|
||||
*addr, alen);
|
||||
msg.condition = I2C_COND_NORMAL;
|
||||
msg.acknack = I2C_ACKNAK_WAITACK;
|
||||
msg.direction = I2C_WRITE;
|
||||
msg.data = addr[alen];
|
||||
if (i2c_transfer(base, &msg, sda_glitch_nofix))
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* start read sequence */
|
||||
debug("i2c_read: start read sequence\n");
|
||||
msg.condition = I2C_COND_START;
|
||||
msg.acknack = I2C_ACKNAK_WAITACK;
|
||||
msg.direction = I2C_WRITE;
|
||||
msg.data = (chip << 1);
|
||||
msg.data |= 0x01;
|
||||
if (i2c_transfer(base, &msg, sda_glitch_nofix))
|
||||
return -1;
|
||||
|
||||
/* read bytes; send NACK at last byte */
|
||||
while (len--) {
|
||||
if (len == 0) {
|
||||
msg.condition = I2C_COND_STOP;
|
||||
msg.acknack = I2C_ACKNAK_SENDNAK;
|
||||
} else {
|
||||
msg.condition = I2C_COND_NORMAL;
|
||||
msg.acknack = I2C_ACKNAK_SENDACK;
|
||||
}
|
||||
|
||||
msg.direction = I2C_READ;
|
||||
msg.data = 0x00;
|
||||
if (i2c_transfer(base, &msg, sda_glitch_nofix))
|
||||
return -1;
|
||||
|
||||
*buffer = msg.data;
|
||||
debug("i2c_read: reading byte (%p)=0x%02x\n",
|
||||
buffer, *buffer);
|
||||
buffer++;
|
||||
}
|
||||
|
||||
i2c_reset(base, sda_glitch_nofix);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __i2c_write(struct spacemit_i2c *base, uchar chip, u8 *addr, int alen,
|
||||
uchar *buffer, int len, bool sda_glitch_nofix)
|
||||
{
|
||||
struct spacemit_i2c_msg msg;
|
||||
|
||||
debug("i2c_write(chip=0x%02x, len=0x%02x)\n", chip, len);
|
||||
|
||||
i2c_reset(base, sda_glitch_nofix);
|
||||
|
||||
/* chip address write */
|
||||
debug("i2c_write: chip address write\n");
|
||||
msg.condition = I2C_COND_START;
|
||||
msg.acknack = I2C_ACKNAK_WAITACK;
|
||||
msg.direction = I2C_WRITE;
|
||||
msg.data = (chip << 1);
|
||||
msg.data &= 0xFE;
|
||||
if (i2c_transfer(base, &msg, sda_glitch_nofix))
|
||||
return -1;
|
||||
|
||||
/*
|
||||
* send memory address bytes;
|
||||
* alen defines how much bytes we have to send.
|
||||
*/
|
||||
while (--alen >= 0) {
|
||||
debug("i2c_read: send address byte %02x (alen=%d)\n",
|
||||
*addr, alen);
|
||||
msg.condition = I2C_COND_NORMAL;
|
||||
msg.acknack = I2C_ACKNAK_WAITACK;
|
||||
msg.direction = I2C_WRITE;
|
||||
msg.data = addr[alen];
|
||||
if (i2c_transfer(base, &msg, sda_glitch_nofix))
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* write bytes; send NACK at last byte */
|
||||
while (len--) {
|
||||
debug("i2c_write: writing byte (%p)=0x%02x\n",
|
||||
buffer, *buffer);
|
||||
|
||||
if (len == 0)
|
||||
msg.condition = I2C_COND_STOP;
|
||||
else
|
||||
msg.condition = I2C_COND_NORMAL;
|
||||
|
||||
msg.acknack = I2C_ACKNAK_WAITACK;
|
||||
msg.direction = I2C_WRITE;
|
||||
msg.data = *(buffer++);
|
||||
|
||||
if (i2c_transfer(base, &msg, sda_glitch_nofix))
|
||||
return -1;
|
||||
}
|
||||
|
||||
i2c_reset(base, sda_glitch_nofix);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
struct spacemit_i2c_priv {
|
||||
struct spacemit_i2c *base;
|
||||
struct reset_ctl_bulk resets;
|
||||
#if CONFIG_IS_ENABLED(CLK)
|
||||
struct clk clk_func;
|
||||
struct clk clk_bus;
|
||||
#endif
|
||||
u32 clk_rate;
|
||||
bool sda_glitch_nofix;
|
||||
};
|
||||
|
||||
static int spacemit_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs)
|
||||
{
|
||||
struct spacemit_i2c_priv *i2c = dev_get_priv(bus);
|
||||
struct i2c_msg *dmsg, *omsg, dummy;
|
||||
|
||||
memset(&dummy, 0, sizeof(struct i2c_msg));
|
||||
|
||||
/*
|
||||
* We expect either two messages (one with an offset and one with the
|
||||
* actual data) or one message (just data or offset/data combined)
|
||||
*/
|
||||
if (nmsgs > 2 || nmsgs == 0) {
|
||||
debug("%s: Only one or two messages are supported.", __func__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
omsg = nmsgs == 1 ? &dummy : msg;
|
||||
dmsg = nmsgs == 1 ? msg : msg + 1;
|
||||
|
||||
if (dmsg->flags & I2C_M_RD)
|
||||
return __i2c_read(i2c->base, dmsg->addr, omsg->buf,
|
||||
omsg->len, dmsg->buf, dmsg->len,
|
||||
i2c->sda_glitch_nofix);
|
||||
else
|
||||
return __i2c_write(i2c->base, dmsg->addr, omsg->buf,
|
||||
omsg->len, dmsg->buf, dmsg->len,
|
||||
i2c->sda_glitch_nofix);
|
||||
}
|
||||
|
||||
static int spacemit_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
|
||||
{
|
||||
struct spacemit_i2c_priv *priv = dev_get_priv(bus);
|
||||
u32 val;
|
||||
|
||||
if (speed > 100000)
|
||||
val = ICR_FM;
|
||||
else
|
||||
val = ICR_SM;
|
||||
clrsetbits_le32(&priv->base->icr, ICR_MODE_MASK, val);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spacemit_i2c_probe(struct udevice *bus)
|
||||
{
|
||||
struct spacemit_i2c_priv *priv = dev_get_priv(bus);
|
||||
int ret;
|
||||
|
||||
ret = reset_get_bulk(bus, &priv->resets);
|
||||
ret = reset_deassert_bulk(&priv->resets);
|
||||
if (ret){
|
||||
debug("I2C probe: failed to reset \n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if CONFIG_IS_ENABLED(CLK)
|
||||
ret = clk_get_by_name(bus, "i2c2_en", &priv->clk_func);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = clk_get_by_name(bus, "i2c2", &priv->clk_bus);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = clk_enable(&priv->clk_func);
|
||||
if (ret && ret != -ENOSYS && ret != -ENOTSUPP) {
|
||||
debug("I2C probe: failed to enable func clock\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = clk_enable(&priv->clk_bus);
|
||||
if (ret && ret != -ENOSYS && ret != -ENOTSUPP) {
|
||||
debug("I2C probe: failed to enable bus clock\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif
|
||||
priv->base = (void *)devfdt_get_addr_ptr(bus);
|
||||
ret = dev_read_u32(bus, "clock-frequency", &priv->clk_rate);
|
||||
if (ret) {
|
||||
pr_info("Default to 100kHz\n");
|
||||
/* default clock rate: 100k */
|
||||
priv->clk_rate = 100000;
|
||||
}
|
||||
|
||||
ret = spacemit_i2c_set_bus_speed(bus, priv->clk_rate);
|
||||
|
||||
priv->sda_glitch_nofix = dev_read_bool(bus, "spacemit,sda-glitch-nofix");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dm_i2c_ops spacemit_i2c_ops = {
|
||||
.xfer = spacemit_i2c_xfer,
|
||||
.set_bus_speed = spacemit_i2c_set_bus_speed,
|
||||
};
|
||||
|
||||
static const struct udevice_id spacemit_i2c_ids[] = {
|
||||
{ .compatible = "spacemit,i2c" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(i2c_spacemit) = {
|
||||
.name = "i2c_spacemit",
|
||||
.id = UCLASS_I2C,
|
||||
.of_match = spacemit_i2c_ids,
|
||||
.probe = spacemit_i2c_probe,
|
||||
.priv_auto = sizeof(struct spacemit_i2c_priv),
|
||||
.ops = &spacemit_i2c_ops,
|
||||
};
|
||||
@@ -1,71 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0+ */
|
||||
/*
|
||||
* Copyright (C) 2023 Spacemit
|
||||
*/
|
||||
|
||||
#ifndef _SPACEMIT_I2C_H_
|
||||
#define _SPACEMIT_I2C_H_
|
||||
extern void i2c_clk_enable(void);
|
||||
|
||||
/* Shall the current transfer have a start/stop condition? */
|
||||
#define I2C_COND_NORMAL 0
|
||||
#define I2C_COND_START 1
|
||||
#define I2C_COND_STOP 2
|
||||
|
||||
/* Shall the current transfer be ack/nacked or being waited for it? */
|
||||
#define I2C_ACKNAK_WAITACK 1
|
||||
#define I2C_ACKNAK_SENDACK 2
|
||||
#define I2C_ACKNAK_SENDNAK 4
|
||||
|
||||
/* Specify who shall transfer the data (master or slave) */
|
||||
#define I2C_READ 0
|
||||
#define I2C_WRITE 1
|
||||
|
||||
#if (CONFIG_SYS_I2C_SPEED == 400000)
|
||||
#define I2C_ICR_INIT (ICR_FM | ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD \
|
||||
| ICR_SCLE)
|
||||
#else
|
||||
#define I2C_ICR_INIT (ICR_BEIE | ICR_IRFIE | ICR_ITEIE | ICR_GCD | ICR_SCLE)
|
||||
#endif
|
||||
|
||||
/* ----- Control register bits ---------------------------------------- */
|
||||
|
||||
#define ICR_START 0x1 /* start bit */
|
||||
#define ICR_STOP 0x2 /* stop bit */
|
||||
#define ICR_ACKNAK 0x4 /* send ACK(0) or NAK(1) */
|
||||
#define ICR_TB 0x8 /* transfer byte bit */
|
||||
#define ICR_MA BIT(12) /* master abort */
|
||||
#define ICR_SCLE BIT(13) /* master clock enable, mona SCLEA */
|
||||
#define ICR_IUE BIT(14) /* unit enable */
|
||||
#define ICR_GCD BIT(21) /* general call disable */
|
||||
#define ICR_ITEIE BIT(19) /* enable tx interrupts */
|
||||
#define ICR_IRFIE BIT(20) /* enable rx interrupts, mona: DRFIE */
|
||||
#define ICR_BEIE BIT(22) /* enable bus error ints */
|
||||
#define ICR_SSDIE BIT(24) /* slave STOP detected int enable */
|
||||
#define ICR_ALDIE BIT(18) /* enable arbitration interrupt */
|
||||
#define ICR_SADIE BIT(23) /* slave address detected int enable */
|
||||
#define ICR_UR BIT(10) /* unit reset */
|
||||
#define ICR_SM (0x0) /* Standard Mode */
|
||||
#define ICR_FM BIT(8) /* Fast Mode */
|
||||
#define ICR_MODE_MASK (0x300) /* Mode mask */
|
||||
/* ----- Status register bits ----------------------------------------- */
|
||||
|
||||
#define ISR_RWM BIT(13) /* read/write mode */
|
||||
#define ISR_ACKNAK BIT(14) /* ack/nak status */
|
||||
#define ISR_UB BIT(15) /* unit busy */
|
||||
#define ISR_IBB BIT(16) /* bus busy */
|
||||
#define ISR_SSD BIT(24) /* slave stop detected */
|
||||
#define ISR_ALD BIT(18) /* arbitration loss detected */
|
||||
#define ISR_ITE BIT(19) /* tx buffer empty */
|
||||
#define ISR_IRF BIT(20) /* rx buffer full */
|
||||
#define ISR_GCAD BIT(21) /* general call address detected */
|
||||
#define ISR_SAD BIT(23) /* slave address detected */
|
||||
#define ISR_BED BIT(22) /* bus error no ACK/NAK */
|
||||
|
||||
/* ----- Reset cycle counter register bits -------------------------------- */
|
||||
|
||||
#define IRCR_SDA_GLITCH_NOFIX BIT(7) /* bypass the SDA glitch fix */
|
||||
|
||||
#define I2C_ISR_INIT 0x1FDE000
|
||||
|
||||
#endif
|
||||
@@ -252,13 +252,5 @@ config RESET_SPACEMIT_K1
|
||||
Support for SPACEMIT's K1 Reset system. Basic Assert/Deassert
|
||||
is supported.
|
||||
|
||||
config RESET_SPACEMIT_K3
|
||||
bool "Support for SPACEMIT's K3 Reset driver"
|
||||
depends on DM_RESET
|
||||
help
|
||||
Support for SPACEMIT's K3 Reset system. Basic Assert/Deassert
|
||||
is supported.
|
||||
|
||||
|
||||
source "drivers/reset/stm32/Kconfig"
|
||||
endmenu
|
||||
|
||||
@@ -35,7 +35,6 @@ obj-$(CONFIG_RESET_AT91) += reset-at91.o
|
||||
obj-$(CONFIG_$(PHASE_)RESET_JH7110) += reset-jh7110.o
|
||||
obj-$(CONFIG_RESET_RZG2L_USBPHY_CTRL) += reset-rzg2l-usbphy-ctrl.o
|
||||
obj-$(CONFIG_RESET_SPACEMIT_K1) += reset-spacemit-k1.o
|
||||
obj-$(CONFIG_RESET_SPACEMIT_K3) += reset-spacemit-k3.o
|
||||
|
||||
obj-$(CONFIG_ARCH_STM32) += stm32/
|
||||
obj-$(CONFIG_ARCH_STM32MP) += stm32/
|
||||
|
||||
@@ -1,566 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Spacemit K3 reset controller driver
|
||||
*
|
||||
* Copyright (c) 2025, spacemit Corporation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <dm.h>
|
||||
#include <reset-uclass.h>
|
||||
#include <asm/io.h>
|
||||
#include <dm/device_compat.h>
|
||||
#include <dm/device-internal.h>
|
||||
#include <dm/lists.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <dt-bindings/reset/reset-spacemit-k3.h>
|
||||
|
||||
/* APBC register offset */
|
||||
#define APBC_UART0_CLK_RST 0x00
|
||||
#define APBC_UART2_CLK_RST 0x04
|
||||
#define APBC_GPIO_CLK_RST 0x08
|
||||
#define APBC_PWM0_CLK_RST 0x0c
|
||||
#define APBC_PWM1_CLK_RST 0x10
|
||||
#define APBC_PWM2_CLK_RST 0x14
|
||||
#define APBC_PWM3_CLK_RST 0x18
|
||||
#define APBC_TWSI8_CLK_RST 0x20
|
||||
#define APBC_UART3_CLK_RST 0x24
|
||||
#define APBC_RTC_CLK_RST 0x28
|
||||
#define APBC_TWSI0_CLK_RST 0x2c
|
||||
#define APBC_TWSI1_CLK_RST 0x30
|
||||
#define APBC_TIMERS0_CLK_RST 0x34
|
||||
#define APBC_TWSI2_CLK_RST 0x38
|
||||
#define APBC_AIB_CLK_RST 0x3c
|
||||
#define APBC_TWSI4_CLK_RST 0x40
|
||||
#define APBC_TIMERS1_CLK_RST 0x44
|
||||
#define APBC_ONEWIRE_CLK_RST 0x48
|
||||
#define APBC_TWSI5_CLK_RST 0x4c
|
||||
#define APBC_DRO_CLK_RST 0x58
|
||||
#define APBC_IR0_CLK_RST 0x5c
|
||||
#define APBC_IR1_CLK_RST 0x1c
|
||||
#define APBC_TWSI6_CLK_RST 0x60
|
||||
#define APBC_TSEN_CLK_RST 0x6c
|
||||
#define APBC_UART4_CLK_RST 0x70
|
||||
#define APBC_UART5_CLK_RST 0x74
|
||||
#define APBC_UART6_CLK_RST 0x78
|
||||
#define APBC_SSP3_CLK_RST 0x7c
|
||||
#define APBC_SSPA0_CLK_RST 0x80
|
||||
#define APBC_SSPA1_CLK_RST 0x84
|
||||
#define APBC_SSPA2_CLK_RST 0x88
|
||||
#define APBC_SSPA3_CLK_RST 0x8c
|
||||
#define APBC_IPC_AP2AUD_CLK_RST 0x90
|
||||
#define APBC_UART7_CLK_RST 0x94
|
||||
#define APBC_UART8_CLK_RST 0x98
|
||||
#define APBC_UART9_CLK_RST 0x9c
|
||||
#define APBC_CAN0_CLK_RST 0xa0
|
||||
#define APBC_CAN1_CLK_RST 0xa4
|
||||
#define APBC_PWM4_CLK_RST 0xa8
|
||||
#define APBC_PWM5_CLK_RST 0xac
|
||||
#define APBC_PWM6_CLK_RST 0xb0
|
||||
#define APBC_PWM7_CLK_RST 0xb4
|
||||
#define APBC_PWM8_CLK_RST 0xb8
|
||||
#define APBC_PWM9_CLK_RST 0xbc
|
||||
#define APBC_PWM10_CLK_RST 0xc0
|
||||
#define APBC_PWM11_CLK_RST 0xc4
|
||||
#define APBC_PWM12_CLK_RST 0xc8
|
||||
#define APBC_PWM13_CLK_RST 0xcc
|
||||
#define APBC_PWM14_CLK_RST 0xd0
|
||||
#define APBC_PWM15_CLK_RST 0xd4
|
||||
#define APBC_PWM16_CLK_RST 0xd8
|
||||
#define APBC_PWM17_CLK_RST 0xdc
|
||||
#define APBC_PWM18_CLK_RST 0xe0
|
||||
#define APBC_PWM19_CLK_RST 0xe4
|
||||
#define APBC_TIMERS2_CLK_RST 0x11c
|
||||
#define APBC_TIMERS3_CLK_RST 0x120
|
||||
#define APBC_TIMERS4_CLK_RST 0x124
|
||||
#define APBC_TIMERS5_CLK_RST 0x128
|
||||
#define APBC_TIMERS6_CLK_RST 0x12c
|
||||
#define APBC_TIMERS7_CLK_RST 0x130
|
||||
#define APBC_CAN2_CLK_RST 0x148
|
||||
#define APBC_CAN3_CLK_RST 0x14c
|
||||
#define APBC_CAN4_CLK_RST 0x150
|
||||
#define APBC_UART10_CLK_RST 0x154
|
||||
#define APBC_SSP0_CLK_RST 0x158
|
||||
#define APBC_SSP1_CLK_RST 0x15c
|
||||
#define APBC_SSPA4_CLK_RST 0x160
|
||||
#define APBC_SSPA5_CLK_RST 0x164
|
||||
/* end of APBC register offset */
|
||||
|
||||
/* MPMU register offset */
|
||||
#define MPMU_WDTPCR 0x200
|
||||
#define MPMU_RIPCCR 0x210
|
||||
/* end of MPMU register offset */
|
||||
|
||||
/* APMU register offset */
|
||||
#define APMU_CSI_CCIC2_CLK_RES_CTRL 0x24
|
||||
#define APMU_ISP_CLK_RES_CTRL 0x38
|
||||
#define APMU_LCD_CLK_RES_CTRL1 0x44
|
||||
#define APMU_LCD_CLK_RES_CTRL2 0x4c
|
||||
#define APMU_CCIC_CLK_RES_CTRL 0x50
|
||||
#define APMU_SDH0_CLK_RES_CTRL 0x54
|
||||
#define APMU_SDH1_CLK_RES_CTRL 0x58
|
||||
#define APMU_USB_CLK_RES_CTRL 0x5c
|
||||
#define APMU_QSPI_CLK_RES_CTRL 0x60
|
||||
#define APMU_DMA_CLK_RES_CTRL 0x64
|
||||
#define APMU_AES_CLK_RES_CTRL 0x68
|
||||
#define APMU_MCB_CLK_RES_CTRL 0x6c
|
||||
#define APMU_VPU_CLK_RES_CTRL 0xa4
|
||||
#define APMU_DTC_CLK_RES_CTRL 0xac
|
||||
#define APMU_GPU_CLK_RES_CTRL 0xcc
|
||||
#define APMU_SDH2_CLK_RES_CTRL 0xe0
|
||||
#define APMU_PMUA_MC_CTRL 0xe8
|
||||
#define APMU_PMU_CC2_AP 0x100
|
||||
#define APMU_UCIE_CTRL 0x11c
|
||||
#define APMU_AUDIO_CLK_RES_CTRL 0x14c
|
||||
#define APMU_LCD_CLK_RES_CTRL3 0x26C
|
||||
#define APMU_UFS_CLK_RES_CTRL 0x268
|
||||
#define APMU_LCD_CLK_RES_CTRL4 0x270
|
||||
#define APMU_LCD_CLK_RES_CTRL5 0x274
|
||||
#define APMU_LCD_EDP_CTRL 0x23c
|
||||
#define APMU_PCIE_CLK_RES_CTRL_PORTA 0x1F0
|
||||
#define APMU_PCIE_CLK_RES_CTRL_PORTB 0x1D0
|
||||
#define APMU_PCIE_CLK_RES_CTRL_PORTC 0x1C8
|
||||
#define APMU_PCIE_CLK_RES_CTRL_PORTD 0x1E0
|
||||
#define APMU_PCIE_CLK_RES_CTRL_PORTE 0x1E8
|
||||
#define APMU_EMAC0_CLK_RES_CTRL 0x3e4
|
||||
#define APMU_EMAC1_CLK_RES_CTRL 0x3ec
|
||||
#define APMU_EMAC2_CLK_RES_CTRL 0x248
|
||||
#define APMU_ESPI_CLK_RES_CTRL 0x240
|
||||
/* end of APMU register offset */
|
||||
|
||||
/* CIUDRAGON register offset */
|
||||
#define DCIU_DMASYS_S0_RSTN 0x204
|
||||
#define DCIU_DMASYS_S1_RSTN 0x208
|
||||
#define DCIU_DMASYS_A0_RSTN 0x20C
|
||||
#define DCIU_DMASYS_A1_RSTN 0x210
|
||||
#define DCIU_DMASYS_A2_RSTN 0x214
|
||||
#define DCIU_DMASYS_A3_RSTN 0x218
|
||||
#define DCIU_DMASYS_A4_RSTN 0x21C
|
||||
#define DCIU_DMASYS_A5_RSTN 0x220
|
||||
#define DCIU_DMASYS_A6_RSTN 0x224
|
||||
#define DCIU_DMASYS_A7_RSTN 0x228
|
||||
#define DCIU_DMASYS_RSTN 0x22C
|
||||
#define DCIU_DMASYS_SDMA_RSTN 0x230
|
||||
/* end of CIUDRAGON register offset */
|
||||
|
||||
/* APBC2 register offset */
|
||||
#define APBC2_UART1_CLK_RST 0x00
|
||||
#define APBC2_SSP2_CLK_RST 0x04
|
||||
#define APBC2_TWSI3_CLK_RST 0x08
|
||||
#define APBC2_RTC_CLK_RST 0x0c
|
||||
#define APBC2_TIMERS_CLK_RST 0x10
|
||||
#define APBC2_JTAG_SW_CLK_RST 0x18
|
||||
#define APBC2_GPIO_CLK_RST 0x1c
|
||||
/* end of APBC2 register offset */
|
||||
|
||||
/* RCPU register offset */
|
||||
//0xc088c000
|
||||
#define RCPU5_CLK_RST_OFFSET 0xC000
|
||||
#define RCPU5_RT24_CORE0_SW_RESET (0xCC + RCPU5_CLK_RST_OFFSET)
|
||||
#define RCPU5_RT24_CORE1_SW_RESET (0xD0 + RCPU5_CLK_RST_OFFSET)
|
||||
/* end of RCPU register offset */
|
||||
|
||||
enum spacemit_reset_base_type {
|
||||
RST_BASE_TYPE_MPMU = 0,
|
||||
RST_BASE_TYPE_APMU = 1,
|
||||
RST_BASE_TYPE_APBC = 2,
|
||||
RST_BASE_TYPE_APBS = 3,
|
||||
RST_BASE_TYPE_CIU = 4,
|
||||
RST_BASE_TYPE_DCIU = 5,
|
||||
RST_BASE_TYPE_DDRC = 6,
|
||||
RST_BASE_TYPE_APBC2 = 7,
|
||||
RST_BASE_TYPE_RCPU = 8,
|
||||
};
|
||||
|
||||
struct spacemit_reset_signal {
|
||||
u32 offset;
|
||||
u32 mask;
|
||||
u32 deassert_val;
|
||||
u32 assert_val;
|
||||
enum spacemit_reset_base_type type;
|
||||
};
|
||||
|
||||
struct spacemit_reset {
|
||||
void __iomem *mpmu_base;
|
||||
void __iomem *apmu_base;
|
||||
void __iomem *apbc_base;
|
||||
void __iomem *apbs_base;
|
||||
void __iomem *ciu_base;
|
||||
void __iomem *dciu_base;
|
||||
void __iomem *ddrc_base;
|
||||
void __iomem *apbc2_base;
|
||||
void __iomem *rcpu_base;
|
||||
const struct spacemit_reset_signal *signals;
|
||||
};
|
||||
|
||||
struct spacemit_reset k3_reset_controller;
|
||||
|
||||
static const struct spacemit_reset_signal
|
||||
k3_reset_signals[RESET_NUMBER] = {
|
||||
//APBC
|
||||
[RESET_UART0] = { APBC_UART0_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_UART2] = { APBC_UART2_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_UART3] = { APBC_UART3_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_UART4] = { APBC_UART4_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_UART5] = { APBC_UART5_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_UART6] = { APBC_UART6_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_UART7] = { APBC_UART7_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_UART8] = { APBC_UART8_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_UART9] = { APBC_UART9_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_UART10] = { APBC_UART10_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_GPIO] = { APBC_GPIO_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_PWM0] = { APBC_PWM0_CLK_RST, BIT(2)|BIT(0), BIT(0), BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_PWM1] = { APBC_PWM1_CLK_RST, BIT(2)|BIT(0), BIT(0), BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_PWM2] = { APBC_PWM2_CLK_RST, BIT(2)|BIT(0), BIT(0), BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_PWM3] = { APBC_PWM3_CLK_RST, BIT(2)|BIT(0), BIT(0), BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_PWM4] = { APBC_PWM4_CLK_RST, BIT(2)|BIT(0), BIT(0), BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_PWM5] = { APBC_PWM5_CLK_RST, BIT(2)|BIT(0), BIT(0), BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_PWM6] = { APBC_PWM6_CLK_RST, BIT(2)|BIT(0), BIT(0), BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_PWM7] = { APBC_PWM7_CLK_RST, BIT(2)|BIT(0), BIT(0), BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_PWM8] = { APBC_PWM8_CLK_RST, BIT(2)|BIT(0), BIT(0), BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_PWM9] = { APBC_PWM9_CLK_RST, BIT(2)|BIT(0), BIT(0), BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_PWM10] = { APBC_PWM10_CLK_RST, BIT(2)|BIT(0), BIT(0), BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_PWM11] = { APBC_PWM11_CLK_RST, BIT(2)|BIT(0), BIT(0), BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_PWM12] = { APBC_PWM12_CLK_RST, BIT(2)|BIT(0), BIT(0), BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_PWM13] = { APBC_PWM13_CLK_RST, BIT(2)|BIT(0), BIT(0), BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_PWM14] = { APBC_PWM14_CLK_RST, BIT(2)|BIT(0), BIT(0), BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_PWM15] = { APBC_PWM15_CLK_RST, BIT(2)|BIT(0), BIT(0), BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_PWM16] = { APBC_PWM16_CLK_RST, BIT(2)|BIT(0), BIT(0), BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_PWM17] = { APBC_PWM17_CLK_RST, BIT(2)|BIT(0), BIT(0), BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_PWM18] = { APBC_PWM18_CLK_RST, BIT(2)|BIT(0), BIT(0), BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_PWM19] = { APBC_PWM19_CLK_RST, BIT(2)|BIT(0), BIT(0), BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_SPI0] = { APBC_SSP0_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_SPI1] = { APBC_SSP1_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_SPI3] = { APBC_SSP3_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_RTC] = { APBC_RTC_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_TWSI0] = { APBC_TWSI0_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_TWSI1] = { APBC_TWSI1_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_TWSI2] = { APBC_TWSI2_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_TWSI4] = { APBC_TWSI4_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_TWSI5] = { APBC_TWSI5_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_TWSI6] = { APBC_TWSI6_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_TWSI8] = { APBC_TWSI8_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_TIMERS0] = { APBC_TIMERS0_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_TIMERS1] = { APBC_TIMERS1_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_TIMERS2] = { APBC_TIMERS2_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_TIMERS3] = { APBC_TIMERS3_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_TIMERS4] = { APBC_TIMERS4_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_TIMERS5] = { APBC_TIMERS5_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_TIMERS6] = { APBC_TIMERS6_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_TIMERS7] = { APBC_TIMERS7_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_AIB] = { APBC_AIB_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_ONEWIRE] = { APBC_ONEWIRE_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_I2S0] = { APBC_SSPA0_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_I2S1] = { APBC_SSPA1_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_I2S2] = { APBC_SSPA2_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_I2S3] = { APBC_SSPA3_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_I2S4] = { APBC_SSPA4_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_I2S5] = { APBC_SSPA5_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_DRO] = { APBC_DRO_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_IR0] = { APBC_IR0_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_IR1] = { APBC_IR1_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_TSEN] = { APBC_TSEN_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_IPC_AP2AUD] = { APBC_IPC_AP2AUD_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_CAN0] = { APBC_CAN0_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_CAN1] = { APBC_CAN1_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_CAN2] = { APBC_CAN2_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_CAN3] = { APBC_CAN3_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
[RESET_CAN4] = { APBC_CAN4_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC },
|
||||
//MPMU
|
||||
[RESET_WDT] = { MPMU_WDTPCR, BIT(2), 0, BIT(2), RST_BASE_TYPE_MPMU },
|
||||
[RESET_RIPC] = { MPMU_RIPCCR, BIT(2), 0, BIT(2), RST_BASE_TYPE_MPMU },
|
||||
//APMU
|
||||
[RESET_CSI] = { APMU_CSI_CCIC2_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_CCIC2_PHY] = { APMU_CSI_CCIC2_CLK_RES_CTRL, BIT(2), BIT(2), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_CCIC3_PHY] = { APMU_CSI_CCIC2_CLK_RES_CTRL, BIT(29), BIT(29), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_ISP_CIBUS] = { APMU_ISP_CLK_RES_CTRL, BIT(16), BIT(16), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_DSI_ESC] = { APMU_LCD_CLK_RES_CTRL1, BIT(3), BIT(3), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_LCD] = { APMU_LCD_CLK_RES_CTRL1, BIT(4), BIT(4), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_V2D] = { APMU_LCD_CLK_RES_CTRL1, BIT(27), BIT(27), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_LCD_MCLK] = { APMU_LCD_CLK_RES_CTRL2, BIT(9), BIT(9), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_LCD_DSCCLK] = { APMU_LCD_CLK_RES_CTRL2, BIT(15), BIT(15), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_SC2_HCLK] = { APMU_CCIC_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_CCIC_4X] = { APMU_CCIC_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_CCIC1_PHY] = { APMU_CCIC_CLK_RES_CTRL, BIT(2), BIT(2), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_SDH_AXI] = { APMU_SDH0_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_SDH0] = { APMU_SDH0_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_SDH1] = { APMU_SDH1_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_SDH2] = { APMU_SDH2_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_USB2] = { APMU_USB_CLK_RES_CTRL, BIT(0)|BIT(2)|BIT(3), BIT(0)|BIT(2)|BIT(3), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_USB3_PORTA] = { APMU_USB_CLK_RES_CTRL, BIT(5)|BIT(6)|BIT(7), BIT(5)|BIT(6)|BIT(7), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_USB3_PORTB] = { APMU_USB_CLK_RES_CTRL, BIT(9)|BIT(10)|BIT(11), BIT(9)|BIT(10)|BIT(11), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_USB3_PORTC] = { APMU_USB_CLK_RES_CTRL, BIT(13)|BIT(14)|BIT(15), BIT(13)|BIT(14)|BIT(15), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_USB3_PORTD] = { APMU_USB_CLK_RES_CTRL, BIT(17)|BIT(18)|BIT(19), BIT(17)|BIT(18)|BIT(19), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_QSPI] = { APMU_QSPI_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_QSPI_BUS] = { APMU_QSPI_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_DMA] = { APMU_DMA_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_AES_WTM] = { APMU_AES_CLK_RES_CTRL, BIT(4), BIT(4), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_MCB_DCLK] = { APMU_MCB_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_MCB_ACLK] = { APMU_MCB_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_VPU] = { APMU_VPU_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_DTC] = { APMU_DTC_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_GPU] = { APMU_GPU_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_MC] = { APMU_PMUA_MC_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_CPU0_POP] = { APMU_PMU_CC2_AP, BIT(0), 0, BIT(0), RST_BASE_TYPE_APMU },
|
||||
[RESET_CPU0_SW] = { APMU_PMU_CC2_AP, BIT(1), 0, BIT(1), RST_BASE_TYPE_APMU },
|
||||
[RESET_CPU1_POP] = { APMU_PMU_CC2_AP, BIT(3), 0, BIT(3), RST_BASE_TYPE_APMU },
|
||||
[RESET_CPU1_SW] = { APMU_PMU_CC2_AP, BIT(4), 0, BIT(4), RST_BASE_TYPE_APMU },
|
||||
[RESET_CPU2_POP] = { APMU_PMU_CC2_AP, BIT(6), 0, BIT(6), RST_BASE_TYPE_APMU },
|
||||
[RESET_CPU2_SW] = { APMU_PMU_CC2_AP, BIT(7), 0, BIT(7), RST_BASE_TYPE_APMU },
|
||||
[RESET_CPU3_POP] = { APMU_PMU_CC2_AP, BIT(9), 0, BIT(9), RST_BASE_TYPE_APMU },
|
||||
[RESET_CPU3_SW] = { APMU_PMU_CC2_AP, BIT(10), 0, BIT(10), RST_BASE_TYPE_APMU },
|
||||
[RESET_C0_MPSUB_SW] = { APMU_PMU_CC2_AP, BIT(12), 0, BIT(12), RST_BASE_TYPE_APMU },
|
||||
[RESET_CPU4_POP] = { APMU_PMU_CC2_AP, BIT(16), 0, BIT(16), RST_BASE_TYPE_APMU },
|
||||
[RESET_CPU4_SW] = { APMU_PMU_CC2_AP, BIT(17), 0, BIT(17), RST_BASE_TYPE_APMU },
|
||||
[RESET_CPU5_POP] = { APMU_PMU_CC2_AP, BIT(19), 0, BIT(19), RST_BASE_TYPE_APMU },
|
||||
[RESET_CPU5_SW] = { APMU_PMU_CC2_AP, BIT(20), 0, BIT(20), RST_BASE_TYPE_APMU },
|
||||
[RESET_CPU6_POP] = { APMU_PMU_CC2_AP, BIT(22), 0, BIT(22), RST_BASE_TYPE_APMU },
|
||||
[RESET_CPU6_SW] = { APMU_PMU_CC2_AP, BIT(23), 0, BIT(23), RST_BASE_TYPE_APMU },
|
||||
[RESET_CPU7_POP] = { APMU_PMU_CC2_AP, BIT(25), 0, BIT(25), RST_BASE_TYPE_APMU },
|
||||
[RESET_CPU7_SW] = { APMU_PMU_CC2_AP, BIT(26), 0, BIT(26), RST_BASE_TYPE_APMU },
|
||||
[RESET_C1_MPSUB_SW] = { APMU_PMU_CC2_AP, BIT(28), 0, BIT(28), RST_BASE_TYPE_APMU },
|
||||
[RESET_MPSUB_DBG] = { APMU_PMU_CC2_AP, BIT(29), 0, BIT(29), RST_BASE_TYPE_APMU },
|
||||
[RESET_UCIE] = { APMU_UCIE_CTRL, BIT(1)|BIT(2)|BIT(3), BIT(1)|BIT(2)|BIT(3), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_RCPU] = { APMU_AUDIO_CLK_RES_CTRL, BIT(0)|BIT(2)|BIT(3), BIT(0)|BIT(2)|BIT(3), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_DSI4LN2_ESCCLK] = { APMU_LCD_CLK_RES_CTRL3, BIT(3), BIT(3), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_DSI4LN2_LCD_SW] = { APMU_LCD_CLK_RES_CTRL3, BIT(4), BIT(4), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_DSI4LN2_LCD_MCLK] = { APMU_LCD_CLK_RES_CTRL4, BIT(9), BIT(9), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_DSI4LN2_LCD_DSCCLK] = { APMU_LCD_CLK_RES_CTRL4, BIT(15), BIT(15), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_DSI4LN2_DPU_ACLK] = { APMU_LCD_CLK_RES_CTRL5, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_DPU_ACLK] = { APMU_LCD_CLK_RES_CTRL5, BIT(15), BIT(15), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_UFS_ACLK] = { APMU_UFS_CLK_RES_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_EDP0] = { APMU_LCD_EDP_CTRL, BIT(0), BIT(0), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_EDP1] = { APMU_LCD_EDP_CTRL, BIT(16), BIT(16), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_PCIE_PORTA] = { APMU_PCIE_CLK_RES_CTRL_PORTA, BIT(3)|BIT(4)|BIT(5), BIT(3)|BIT(4)|BIT(5), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_PCIE_PORTB] = { APMU_PCIE_CLK_RES_CTRL_PORTB, BIT(3)|BIT(4)|BIT(5), BIT(3)|BIT(4)|BIT(5), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_PCIE_PORTC] = { APMU_PCIE_CLK_RES_CTRL_PORTC, BIT(3)|BIT(4)|BIT(5), BIT(3)|BIT(4)|BIT(5), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_PCIE_PORTD] = { APMU_PCIE_CLK_RES_CTRL_PORTD, BIT(3)|BIT(4)|BIT(5), BIT(3)|BIT(4)|BIT(5), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_PCIE_PORTE] = { APMU_PCIE_CLK_RES_CTRL_PORTE, BIT(3)|BIT(4)|BIT(5), BIT(3)|BIT(4)|BIT(5), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_EMAC0] = { APMU_EMAC0_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_EMAC1] = { APMU_EMAC1_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_EMAC2] = { APMU_EMAC2_CLK_RES_CTRL, BIT(1), BIT(1), 0, RST_BASE_TYPE_APMU },
|
||||
[RESET_ESPI] = { APMU_ESPI_CLK_RES_CTRL, BIT(0)|BIT(2), BIT(0)|BIT(2), 0, RST_BASE_TYPE_APMU },
|
||||
//DCIU
|
||||
[RESET_HDMA] = { DCIU_DMASYS_RSTN, BIT(0), BIT(0), 0, RST_BASE_TYPE_DCIU },
|
||||
[RESET_DMA350] = { DCIU_DMASYS_SDMA_RSTN, BIT(0), BIT(0), 0, RST_BASE_TYPE_DCIU },
|
||||
[RESET_DMA350_0] = { DCIU_DMASYS_S0_RSTN, BIT(0), BIT(0), 0, RST_BASE_TYPE_DCIU },
|
||||
[RESET_DMA350_1] = { DCIU_DMASYS_S1_RSTN, BIT(0), BIT(0), 0, RST_BASE_TYPE_DCIU },
|
||||
[RESET_AXIDMA0] = { DCIU_DMASYS_A0_RSTN, BIT(0), BIT(0), 0, RST_BASE_TYPE_DCIU },
|
||||
[RESET_AXIDMA1] = { DCIU_DMASYS_A1_RSTN, BIT(0), BIT(0), 0, RST_BASE_TYPE_DCIU },
|
||||
[RESET_AXIDMA2] = { DCIU_DMASYS_A2_RSTN, BIT(0), BIT(0), 0, RST_BASE_TYPE_DCIU },
|
||||
[RESET_AXIDMA3] = { DCIU_DMASYS_A3_RSTN, BIT(0), BIT(0), 0, RST_BASE_TYPE_DCIU },
|
||||
[RESET_AXIDMA4] = { DCIU_DMASYS_A4_RSTN, BIT(0), BIT(0), 0, RST_BASE_TYPE_DCIU },
|
||||
[RESET_AXIDMA5] = { DCIU_DMASYS_A5_RSTN, BIT(0), BIT(0), 0, RST_BASE_TYPE_DCIU },
|
||||
[RESET_AXIDMA6] = { DCIU_DMASYS_A6_RSTN, BIT(0), BIT(0), 0, RST_BASE_TYPE_DCIU },
|
||||
[RESET_AXIDMA7] = { DCIU_DMASYS_A7_RSTN, BIT(0), BIT(0), 0, RST_BASE_TYPE_DCIU },
|
||||
//APBC2
|
||||
[RESET_SEC_UART1] = { APBC2_UART1_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC2 },
|
||||
[RESET_SEC_SSP2] = { APBC2_SSP2_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC2 },
|
||||
[RESET_SEC_TWSI3] = { APBC2_TWSI3_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC2 },
|
||||
[RESET_SEC_RTC] = { APBC2_RTC_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC2 },
|
||||
[RESET_SEC_TIMERS] = { APBC2_TIMERS_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC2 },
|
||||
[RESET_SEC_JTAG] = { APBC2_JTAG_SW_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC2 },
|
||||
[RESET_SEC_GPIO] = { APBC2_GPIO_CLK_RST, BIT(2), 0, BIT(2), RST_BASE_TYPE_APBC2 },
|
||||
//RCPU
|
||||
//0xc088c000
|
||||
[RESET_RCPU5_RT24_CORE0] = { RCPU5_RT24_CORE0_SW_RESET, BIT(0), 0, BIT(0), RST_BASE_TYPE_RCPU },
|
||||
[RESET_RCPU5_RT24_CORE1] = { RCPU5_RT24_CORE1_SW_RESET, BIT(0), 0, BIT(0), RST_BASE_TYPE_RCPU },
|
||||
};
|
||||
|
||||
static u32 spacemit_reset_read(struct spacemit_reset *reset, u32 id)
|
||||
{
|
||||
void __iomem *base;
|
||||
|
||||
switch (reset->signals[id].type) {
|
||||
case RST_BASE_TYPE_APMU:
|
||||
base = reset->apmu_base;
|
||||
break;
|
||||
case RST_BASE_TYPE_APBC:
|
||||
base = reset->apbc_base;
|
||||
break;
|
||||
case RST_BASE_TYPE_MPMU:
|
||||
base = reset->mpmu_base;
|
||||
break;
|
||||
case RST_BASE_TYPE_APBS:
|
||||
base = reset->apbs_base;
|
||||
break;
|
||||
case RST_BASE_TYPE_CIU:
|
||||
base = reset->ciu_base;
|
||||
break;
|
||||
case RST_BASE_TYPE_DCIU:
|
||||
base = reset->dciu_base;
|
||||
break;
|
||||
case RST_BASE_TYPE_DDRC:
|
||||
base = reset->ddrc_base;
|
||||
break;
|
||||
case RST_BASE_TYPE_APBC2:
|
||||
base = reset->apbc2_base;
|
||||
break;
|
||||
case RST_BASE_TYPE_RCPU:
|
||||
base = reset->rcpu_base;
|
||||
break;
|
||||
default:
|
||||
base = reset->apbc_base;
|
||||
break;
|
||||
}
|
||||
return readl(base + reset->signals[id].offset);
|
||||
}
|
||||
|
||||
static void spacemit_reset_write(struct spacemit_reset *reset, u32 value, u32 id)
|
||||
{
|
||||
void __iomem *base;
|
||||
|
||||
switch (reset->signals[id].type) {
|
||||
case RST_BASE_TYPE_APMU:
|
||||
base = reset->apmu_base;
|
||||
break;
|
||||
case RST_BASE_TYPE_APBC:
|
||||
base = reset->apbc_base;
|
||||
break;
|
||||
case RST_BASE_TYPE_MPMU:
|
||||
base = reset->mpmu_base;
|
||||
break;
|
||||
case RST_BASE_TYPE_APBS:
|
||||
base = reset->apbs_base;
|
||||
break;
|
||||
case RST_BASE_TYPE_CIU:
|
||||
base = reset->ciu_base;
|
||||
break;
|
||||
case RST_BASE_TYPE_DCIU:
|
||||
base = reset->dciu_base;
|
||||
break;
|
||||
case RST_BASE_TYPE_DDRC:
|
||||
base = reset->ddrc_base;
|
||||
break;
|
||||
case RST_BASE_TYPE_APBC2:
|
||||
base = reset->apbc2_base;
|
||||
break;
|
||||
case RST_BASE_TYPE_RCPU:
|
||||
base = reset->rcpu_base;
|
||||
break;
|
||||
default:
|
||||
base = reset->apbc_base;
|
||||
break;
|
||||
}
|
||||
|
||||
writel(value, base + reset->signals[id].offset);
|
||||
}
|
||||
|
||||
static void spacemit_reset_set(struct reset_ctl *rst, u32 id, bool assert)
|
||||
{
|
||||
u32 value;
|
||||
struct spacemit_reset *reset = dev_get_priv(rst->dev);
|
||||
|
||||
value = spacemit_reset_read(reset, id);
|
||||
if (assert == 1) {
|
||||
value &= ~reset->signals[id].mask;
|
||||
value |= reset->signals[id].assert_val;
|
||||
} else {
|
||||
value &= ~reset->signals[id].mask;
|
||||
value |= reset->signals[id].deassert_val;
|
||||
}
|
||||
|
||||
spacemit_reset_write(reset, value, id);
|
||||
}
|
||||
static int spacemit_reset_update(struct reset_ctl *rst, bool assert)
|
||||
{
|
||||
if (rst->id < RESET_UART0 || rst->id >= RESET_NUMBER)
|
||||
return 0;
|
||||
|
||||
spacemit_reset_set(rst, rst->id, assert);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int spacemit_reset_assert(struct reset_ctl *rst)
|
||||
{
|
||||
return spacemit_reset_update(rst, true);
|
||||
}
|
||||
|
||||
static int spacemit_reset_deassert(struct reset_ctl *rst)
|
||||
{
|
||||
return spacemit_reset_update(rst, false);
|
||||
}
|
||||
|
||||
static int spacemit_k3_reset_probe(struct udevice *dev)
|
||||
{
|
||||
struct spacemit_reset *reset = dev_get_priv(dev);
|
||||
|
||||
reset->mpmu_base = (void __iomem *)dev_remap_addr_index(dev, 0);
|
||||
if (!reset->mpmu_base) {
|
||||
pr_err("failed to map mpmu registers\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
reset->apmu_base = (void __iomem *)dev_remap_addr_index(dev, 1);
|
||||
if (!reset->apmu_base) {
|
||||
pr_err("failed to map apmu registers\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
reset->apbc_base = (void __iomem *)dev_remap_addr_index(dev, 2);
|
||||
if (!reset->apbc_base) {
|
||||
pr_err("failed to map apbc registers\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
reset->apbs_base = (void __iomem *)dev_remap_addr_index(dev, 3);
|
||||
if (!reset->apbs_base) {
|
||||
pr_err("failed to map apbs registers\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
reset->ciu_base = (void __iomem *)dev_remap_addr_index(dev, 4);
|
||||
if (!reset->ciu_base) {
|
||||
pr_err("failed to map ciu registers\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
reset->dciu_base = (void __iomem *)dev_remap_addr_index(dev, 5);
|
||||
if (!reset->dciu_base) {
|
||||
pr_err("failed to map dragon ciu registers\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
reset->ddrc_base = (void __iomem *)dev_remap_addr_index(dev, 6);
|
||||
if (!reset->ddrc_base) {
|
||||
pr_err("failed to map ddrc registers\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
reset->apbc2_base = (void __iomem *)dev_remap_addr_index(dev, 7);
|
||||
if (!reset->apbc2_base) {
|
||||
pr_err("failed to map apbc2 registers\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
reset->rcpu_base = (void __iomem *)dev_remap_addr_index(dev, 8);
|
||||
if (!reset->rcpu_base) {
|
||||
pr_err("failed to map rcpu registers\n");
|
||||
goto out;
|
||||
}
|
||||
|
||||
reset->signals = k3_reset_signals;
|
||||
pr_info("reset driver probe finish\n");
|
||||
|
||||
out:
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct reset_ops k3_reset_ops = {
|
||||
.rst_assert = spacemit_reset_assert,
|
||||
.rst_deassert = spacemit_reset_deassert,
|
||||
};
|
||||
|
||||
static const struct udevice_id k3_reset_ids[] = {
|
||||
{ .compatible = "spacemit,k3-reset", },
|
||||
{},
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(k3_reset) = {
|
||||
.name = "spacemit,k3-reset",
|
||||
.id = UCLASS_RESET,
|
||||
.ops = &k3_reset_ops,
|
||||
.of_match = k3_reset_ids,
|
||||
.probe = spacemit_k3_reset_probe,
|
||||
.priv_auto = sizeof(struct spacemit_reset),
|
||||
};
|
||||
@@ -268,13 +268,6 @@ static const struct fsl_qspi_devtype_data ls2080a_data = {
|
||||
.little_endian = true,
|
||||
};
|
||||
|
||||
static const struct fsl_qspi_devtype_data spacemit_k3_data = {
|
||||
.rxfifo = SZ_128,
|
||||
.txfifo = SZ_256,
|
||||
.ahb_buf_size = SZ_512,
|
||||
.quirks = 0,
|
||||
.little_endian = true,
|
||||
};
|
||||
struct fsl_qspi {
|
||||
struct udevice *dev;
|
||||
void __iomem *iobase;
|
||||
@@ -896,7 +889,6 @@ static const struct udevice_id fsl_qspi_ids[] = {
|
||||
{ .compatible = "fsl,ls1021a-qspi", .data = (ulong)&ls1021a_data, },
|
||||
{ .compatible = "fsl,ls1088a-qspi", .data = (ulong)&ls2080a_data, },
|
||||
{ .compatible = "fsl,ls2080a-qspi", .data = (ulong)&ls2080a_data, },
|
||||
{ .compatible = "spacemit,k3-qspi", .data = (ulong)&spacemit_k3_data, },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
* Copyright (c) 2026, Hangfan Li <lihangfan@iscas.ac.cn>
|
||||
*/
|
||||
|
||||
#ifndef __CONFIG_H
|
||||
#define __CONFIG_H
|
||||
|
||||
#define CFG_SYS_NS16550_IER 0x40
|
||||
#define RISCV_SMODE_TIMER_FREQ 24000000
|
||||
#define RISCV_MMODE_TIMER_FREQ 24000000
|
||||
#define RISCV_MMODE_TIMERBASE 0xe081c000
|
||||
#define RISCV_MMODE_TIMEROFF 0xbff8
|
||||
#endif /* __CONFIG_H */
|
||||
@@ -1,303 +0,0 @@
|
||||
// SPDX-License-Identifier: (GPL-2.0+ or MIT)
|
||||
|
||||
#ifndef _DT_BINDINGS_CLK_SPACEMIT_K3_H_
|
||||
#define _DT_BINDINGS_CLK_SPACEMIT_K3_H_
|
||||
|
||||
#define CLK_PLL1_2457P6 0
|
||||
#define CLK_PLL2 1
|
||||
#define CLK_PLL3 2
|
||||
#define CLK_PLL4 3
|
||||
#define CLK_PLL5 4
|
||||
#define CLK_PLL6 5
|
||||
#define CLK_PLL7 6
|
||||
#define CLK_PLL8 7
|
||||
#define CLK_PLL1_D2 8
|
||||
#define CLK_PLL1_D3 9
|
||||
#define CLK_PLL1_D4 10
|
||||
#define CLK_PLL1_D5 11
|
||||
#define CLK_PLL1_D6 12
|
||||
#define CLK_PLL1_D7 13
|
||||
#define CLK_PLL1_D8 14
|
||||
#define CLK_PLL1_DX 15
|
||||
#define CLK_PLL1_D64 16
|
||||
#define CLK_PLL1_D10_AUD 17
|
||||
#define CLK_PLL1_D100_AUD 18
|
||||
#define CLK_PLL2_D1 19
|
||||
#define CLK_PLL2_D2 20
|
||||
#define CLK_PLL2_D3 21
|
||||
#define CLK_PLL2_D4 22
|
||||
#define CLK_PLL2_D5 23
|
||||
#define CLK_PLL2_D6 24
|
||||
#define CLK_PLL2_D7 25
|
||||
#define CLK_PLL2_D8 26
|
||||
#define CLK_PLL2_66 27
|
||||
#define CLK_PLL2_33 28
|
||||
#define CLK_PLL2_50 29
|
||||
#define CLK_PLL2_25 30
|
||||
#define CLK_PLL2_20 31
|
||||
#define CLK_PLL2_D24_125 32
|
||||
#define CLK_PLL2_D120_25 33
|
||||
#define CLK_PLL3_D1 34
|
||||
#define CLK_PLL3_D2 35
|
||||
#define CLK_PLL3_D3 36
|
||||
#define CLK_PLL3_D4 37
|
||||
#define CLK_PLL3_D5 38
|
||||
#define CLK_PLL3_D6 39
|
||||
#define CLK_PLL3_D7 40
|
||||
#define CLK_PLL3_D8 41
|
||||
#define CLK_PLL4_D1 42
|
||||
#define CLK_PLL4_D2 43
|
||||
#define CLK_PLL4_D3 44
|
||||
#define CLK_PLL4_D4 45
|
||||
#define CLK_PLL4_D5 46
|
||||
#define CLK_PLL4_D6 47
|
||||
#define CLK_PLL4_D7 48
|
||||
#define CLK_PLL4_D8 49
|
||||
#define CLK_PLL5_D1 50
|
||||
#define CLK_PLL5_D2 51
|
||||
#define CLK_PLL5_D3 52
|
||||
#define CLK_PLL5_D4 53
|
||||
#define CLK_PLL5_D5 54
|
||||
#define CLK_PLL5_D6 55
|
||||
#define CLK_PLL5_D7 56
|
||||
#define CLK_PLL5_D8 57
|
||||
#define CLK_PLL6_D1 58
|
||||
#define CLK_PLL6_D2 59
|
||||
#define CLK_PLL6_D3 60
|
||||
#define CLK_PLL6_D4 61
|
||||
#define CLK_PLL6_D5 62
|
||||
#define CLK_PLL6_D6 63
|
||||
#define CLK_PLL6_D7 64
|
||||
#define CLK_PLL6_D8 65
|
||||
#define CLK_PLL6_80 66
|
||||
#define CLK_PLL6_40 67
|
||||
#define CLK_PLL6_20 68
|
||||
#define CLK_PLL7_D1 69
|
||||
#define CLK_PLL7_D2 70
|
||||
#define CLK_PLL7_D3 71
|
||||
#define CLK_PLL7_D4 72
|
||||
#define CLK_PLL7_D5 73
|
||||
#define CLK_PLL7_D6 74
|
||||
#define CLK_PLL7_D7 75
|
||||
#define CLK_PLL7_D8 76
|
||||
#define CLK_PLL8_D1 77
|
||||
#define CLK_PLL8_D2 78
|
||||
#define CLK_PLL8_D3 79
|
||||
#define CLK_PLL8_D4 80
|
||||
#define CLK_PLL8_D5 81
|
||||
#define CLK_PLL8_D6 82
|
||||
#define CLK_PLL8_D7 83
|
||||
#define CLK_PLL8_D8 84
|
||||
#define CLK_PLL1_307P2 85
|
||||
#define CLK_PLL1_76P8 86
|
||||
#define CLK_PLL1_61P44 87
|
||||
#define CLK_PLL1_153P6 88
|
||||
#define CLK_PLL1_102P4 89
|
||||
#define CLK_PLL1_51P2 90
|
||||
#define CLK_PLL1_51P2_AP 91
|
||||
#define CLK_PLL1_57P6 92
|
||||
#define CLK_PLL1_25P6 93
|
||||
#define CLK_PLL1_12P8 94
|
||||
#define CLK_PLL1_12P8_WDT 95
|
||||
#define CLK_PLL1_6P4 96
|
||||
#define CLK_PLL1_3P2 97
|
||||
#define CLK_PLL1_1P6 98
|
||||
#define CLK_PLL1_0P8 99
|
||||
#define CLK_PLL1_351 100
|
||||
#define CLK_PLL1_409P6 101
|
||||
#define CLK_PLL1_204P8 102
|
||||
#define CLK_PLL1_491 103
|
||||
#define CLK_PLL1_245P76 104
|
||||
#define CLK_PLL1_614 105
|
||||
#define CLK_PLL1_47P26 106
|
||||
#define CLK_PLL1_31P5 107
|
||||
#define CLK_PLL1_819 108
|
||||
#define CLK_PLL1_1228 109
|
||||
#define CLK_APB 110
|
||||
#define CLK_SLOW_UART1 111
|
||||
#define CLK_SLOW_UART2 112
|
||||
#define CLK_WDT 113
|
||||
#define CLK_RIPC 114
|
||||
#define CLK_UART1 115
|
||||
#define CLK_UART2 116
|
||||
#define CLK_UART3 117
|
||||
#define CLK_UART4 118
|
||||
#define CLK_UART5 119
|
||||
#define CLK_UART6 120
|
||||
#define CLK_UART7 121
|
||||
#define CLK_UART8 122
|
||||
#define CLK_UART9 123
|
||||
#define CLK_UART10 124
|
||||
#define CLK_GPIO 125
|
||||
#define CLK_PWM0 126
|
||||
#define CLK_PWM1 127
|
||||
#define CLK_PWM2 128
|
||||
#define CLK_PWM3 129
|
||||
#define CLK_PWM4 130
|
||||
#define CLK_PWM5 131
|
||||
#define CLK_PWM6 132
|
||||
#define CLK_PWM7 133
|
||||
#define CLK_PWM8 134
|
||||
#define CLK_PWM9 135
|
||||
#define CLK_PWM10 136
|
||||
#define CLK_PWM11 137
|
||||
#define CLK_PWM12 138
|
||||
#define CLK_PWM13 139
|
||||
#define CLK_PWM14 140
|
||||
#define CLK_PWM15 141
|
||||
#define CLK_PWM16 142
|
||||
#define CLK_PWM17 143
|
||||
#define CLK_PWM18 144
|
||||
#define CLK_PWM19 145
|
||||
#define CLK_SPI0 146
|
||||
#define CLK_SPI1 147
|
||||
#define CLK_SPI3 148
|
||||
#define CLK_RTC 149
|
||||
#define CLK_TWSI0 150
|
||||
#define CLK_TWSI1 151
|
||||
#define CLK_TWSI2 152
|
||||
#define CLK_TWSI4 153
|
||||
#define CLK_TWSI5 154
|
||||
#define CLK_TWSI6 155
|
||||
#define CLK_TWSI8 156
|
||||
#define CLK_TIMERS0 157
|
||||
#define CLK_TIMERS1 158
|
||||
#define CLK_TIMERS2 159
|
||||
#define CLK_TIMERS3 160
|
||||
#define CLK_TIMERS4 161
|
||||
#define CLK_TIMERS5 162
|
||||
#define CLK_TIMERS6 163
|
||||
#define CLK_TIMERS7 164
|
||||
#define CLK_AIB 165
|
||||
#define CLK_ONEWIRE 166
|
||||
#define CLK_I2S0 167
|
||||
#define CLK_I2S1 168
|
||||
#define CLK_I2S2 169
|
||||
#define CLK_I2S3 170
|
||||
#define CLK_I2S4 171
|
||||
#define CLK_I2S5 172
|
||||
#define CLK_DRO 173
|
||||
#define CLK_IR0 174
|
||||
#define CLK_IR1 175
|
||||
#define CLK_TSEN 176
|
||||
#define CLK_IPC_AP2RCPU 177
|
||||
#define CLK_CAN0 178
|
||||
#define CLK_CAN1 179
|
||||
#define CLK_CAN2 180
|
||||
#define CLK_CAN3 181
|
||||
#define CLK_CAN4 182
|
||||
#define CLK_CAN0_BUS 183
|
||||
#define CLK_CAN1_BUS 184
|
||||
#define CLK_CAN2_BUS 185
|
||||
#define CLK_CAN3_BUS 186
|
||||
#define CLK_CAN4_BUS 187
|
||||
#define CLK_AXICLK 188
|
||||
#define CLK_CCI550 189
|
||||
#define CLK_CPU_C1_PLL_SRC 190
|
||||
#define CLK_CPU_C3_PLL_SRC 191
|
||||
#define CLK_CPU_C0_CORE 192
|
||||
#define CLK_CPU_C1_CORE 193
|
||||
#define CLK_CPU_C2_CORE 194
|
||||
#define CLK_CPU_C3_CORE 195
|
||||
#define CLK_CCIC2PHY 196
|
||||
#define CLK_CCIC3PHY 197
|
||||
#define CLK_CSI 198
|
||||
#define CLK_ISP_BUS 199
|
||||
#define CLK_D1P_1228P8 200
|
||||
#define CLK_D1P_819P2 201
|
||||
#define CLK_D1P_614P4 202
|
||||
#define CLK_D1P_491P52 203
|
||||
#define CLK_D1P_409P6 204
|
||||
#define CLK_D1P_307P2 205
|
||||
#define CLK_D1P_245P76 206
|
||||
#define CLK_V2D 207
|
||||
#define CLK_DSI_ESC 208
|
||||
#define CLK_LCD_HCLK 209
|
||||
#define CLK_LCD_DSC 210
|
||||
#define CLK_LCD_PXCLK 211
|
||||
#define CLK_LCD_MCLK 212
|
||||
#define CLK_CCIC_4X 213
|
||||
#define CLK_CCIC1PHY 214
|
||||
#define CLK_SC2_HCLK 215
|
||||
#define CLK_SDH_AXI 216
|
||||
#define CLK_SDH0 217
|
||||
#define CLK_SDH1 218
|
||||
#define CLK_SDH2 219
|
||||
#define CLK_USB2_BUS 220
|
||||
#define CLK_USB3_PORTA_BUS 221
|
||||
#define CLK_USB3_PORTB_BUS 222
|
||||
#define CLK_USB3_PORTC_BUS 223
|
||||
#define CLK_USB3_PORTD_BUS 224
|
||||
#define CLK_QSPI 225
|
||||
#define CLK_QSPI_BUS 226
|
||||
#define CLK_DMA 227
|
||||
#define CLK_AES_WTM 228
|
||||
#define CLK_VPU 229
|
||||
#define CLK_DTC 230
|
||||
#define CLK_GPU 231
|
||||
#define CLK_MC_AHB 232
|
||||
#define CLK_TOP_DCLK 233
|
||||
#define CLK_UCIE 234
|
||||
#define CLK_UCIE_SBCLK 235
|
||||
#define CLK_RCPU 236
|
||||
#define CLK_DSI4LN2_DSI_ESC 237
|
||||
#define CLK_DSI4LN2_LCD_DSC 238
|
||||
#define CLK_DSI4LN2_LCD_PXCLK 239
|
||||
#define CLK_DSI4LN2_LCD_MCLK 240
|
||||
#define CLK_DSI4LN2_DPU_ACLK 241
|
||||
#define CLK_DPU_ACLK 242
|
||||
#define CLK_UFS_ACLK 243
|
||||
#define CLK_EDP0_PXCLK 244
|
||||
#define CLK_EDP1_PXCLK 245
|
||||
#define CLK_PCIEA 246
|
||||
#define CLK_PCIEB 247
|
||||
#define CLK_PCIEC 248
|
||||
#define CLK_PCIED 249
|
||||
#define CLK_PCIEE 250
|
||||
#define CLK_EMAC0_BUS 251
|
||||
#define CLK_EMAC0_REF 252
|
||||
#define CLK_EMAC0_1588 253
|
||||
#define CLK_EMAC0_RGMII_TX 254
|
||||
#define CLK_EMAC1_BUS 255
|
||||
#define CLK_EMAC1_REF 256
|
||||
#define CLK_EMAC1_1588 257
|
||||
#define CLK_EMAC1_RGMII_TX 258
|
||||
#define CLK_EMAC2_BUS 259
|
||||
#define CLK_EMAC2_REF 260
|
||||
#define CLK_EMAC2_1588 261
|
||||
#define CLK_EMAC2_RGMII_TX 262
|
||||
#define CLK_ESPI_SCLK_SRC 263
|
||||
#define CLK_ESPI_SCLK 264
|
||||
#define CLK_ESPI_MCLK 265
|
||||
#define CLK_CAM_SRC1 266
|
||||
#define CLK_CAM_SRC2 267
|
||||
#define CLK_CAM_SRC3 268
|
||||
#define CLK_CAM_SRC4 269
|
||||
#define CLK_ISIM_VCLK0 270
|
||||
#define CLK_ISIM_VCLK1 271
|
||||
#define CLK_ISIM_VCLK2 272
|
||||
#define CLK_ISIM_VCLK3 273
|
||||
#define CLK_HDMA 274
|
||||
#define CLK_DMA350 275
|
||||
#define CLK_C2_TCM_PIPE 276
|
||||
#define CLK_C3_TCM_PIPE 277
|
||||
#define CLK_RCPU_RT24_CORE0 278
|
||||
#define CLK_RCPU_RT24_CORE1 279
|
||||
#define CLK_SEC_UART1 280
|
||||
#define CLK_SEC_SSP2 281
|
||||
#define CLK_SEC_TWSI3 282
|
||||
#define CLK_SEC_RTC 283
|
||||
#define CLK_SEC_TIMERS0 284
|
||||
#define CLK_SEC_GPIO 285
|
||||
|
||||
#define CLK_VCTCXO_24 286
|
||||
#define CLK_VCTCXO_3 287
|
||||
#define CLK_VCTCXO_1 288
|
||||
#define CLK_PLL1 289
|
||||
#define OSC_32K 290
|
||||
#define CLK_DUMMY 291
|
||||
|
||||
#define CLK_TWSI2_BUS 292
|
||||
#define CLK_MAX_NO 293
|
||||
|
||||
#endif /* _DT_BINDINGS_CLK_SPACEMIT_K3_H_ */
|
||||
@@ -1,229 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#ifndef __DT_BINDINGS_K3_PINCTRL_H
|
||||
#define __DT_BINDINGS_K3_PINCTRL_H
|
||||
|
||||
/*
|
||||
* For K3:
|
||||
* +---------+----------+-----------+--------+--------+----------+--------+
|
||||
* | pull | drive | schmitter | slew | edge | strong | mux |
|
||||
* | up/down | strength | trigger | rate | detect | pull | mode |
|
||||
* +---------+----------+-----------+--------+--------+----------+--------+
|
||||
* 3 bits 4 bits 1 bits 1 bit 3 bits 1 bit 3 bits
|
||||
*/
|
||||
|
||||
/* pinnum list */
|
||||
#define GPIO_00 (0)
|
||||
#define GPIO_01 (1)
|
||||
#define GPIO_02 (2)
|
||||
#define GPIO_03 (3)
|
||||
#define GPIO_04 (4)
|
||||
#define GPIO_05 (5)
|
||||
#define GPIO_06 (6)
|
||||
#define GPIO_07 (7)
|
||||
#define GPIO_08 (8)
|
||||
#define GPIO_09 (9)
|
||||
#define GPIO_10 (10)
|
||||
#define GPIO_11 (11)
|
||||
#define GPIO_12 (12)
|
||||
#define GPIO_13 (13)
|
||||
#define GPIO_14 (14)
|
||||
#define GPIO_15 (15)
|
||||
#define GPIO_16 (16)
|
||||
#define GPIO_17 (17)
|
||||
#define GPIO_18 (18)
|
||||
#define GPIO_19 (19)
|
||||
#define GPIO_20 (20)
|
||||
#define GPIO_21 (21)
|
||||
#define GPIO_22 (22)
|
||||
#define GPIO_23 (23)
|
||||
#define GPIO_24 (24)
|
||||
#define GPIO_25 (25)
|
||||
#define GPIO_26 (26)
|
||||
#define GPIO_27 (27)
|
||||
#define GPIO_28 (28)
|
||||
#define GPIO_29 (29)
|
||||
#define GPIO_30 (30)
|
||||
#define GPIO_31 (31)
|
||||
#define GPIO_32 (32)
|
||||
#define GPIO_33 (33)
|
||||
#define GPIO_34 (34)
|
||||
#define GPIO_35 (35)
|
||||
#define GPIO_36 (36)
|
||||
#define GPIO_37 (37)
|
||||
#define GPIO_38 (38)
|
||||
#define GPIO_39 (39)
|
||||
#define GPIO_40 (40)
|
||||
#define GPIO_41 (41)
|
||||
#define GPIO_42 (42)
|
||||
#define GPIO_43 (43)
|
||||
#define GPIO_44 (44)
|
||||
#define GPIO_45 (45)
|
||||
#define GPIO_46 (46)
|
||||
#define GPIO_47 (47)
|
||||
#define GPIO_48 (48)
|
||||
#define GPIO_49 (49)
|
||||
#define GPIO_50 (50)
|
||||
#define GPIO_51 (51)
|
||||
#define GPIO_52 (52)
|
||||
#define GPIO_53 (53)
|
||||
#define GPIO_54 (54)
|
||||
#define GPIO_55 (55)
|
||||
#define GPIO_56 (56)
|
||||
#define GPIO_57 (57)
|
||||
#define GPIO_58 (58)
|
||||
#define GPIO_59 (59)
|
||||
#define GPIO_60 (60)
|
||||
#define GPIO_61 (61)
|
||||
#define GPIO_62 (62)
|
||||
#define GPIO_63 (63)
|
||||
#define GPIO_64 (64)
|
||||
#define GPIO_65 (65)
|
||||
#define GPIO_66 (66)
|
||||
#define GPIO_67 (67)
|
||||
#define GPIO_68 (68)
|
||||
#define GPIO_69 (69)
|
||||
#define GPIO_70 (70)
|
||||
#define GPIO_71 (71)
|
||||
#define GPIO_72 (72)
|
||||
#define GPIO_73 (73)
|
||||
#define GPIO_74 (74)
|
||||
#define GPIO_75 (75)
|
||||
#define GPIO_76 (76)
|
||||
#define GPIO_77 (77)
|
||||
#define GPIO_78 (78)
|
||||
#define GPIO_79 (79)
|
||||
#define GPIO_80 (80)
|
||||
#define GPIO_81 (81)
|
||||
#define GPIO_82 (82)
|
||||
#define GPIO_83 (83)
|
||||
#define GPIO_84 (84)
|
||||
#define GPIO_85 (85)
|
||||
#define GPIO_86 (86)
|
||||
#define GPIO_87 (87)
|
||||
#define GPIO_88 (88)
|
||||
#define GPIO_89 (89)
|
||||
#define GPIO_90 (90)
|
||||
#define GPIO_91 (91)
|
||||
#define GPIO_92 (92)
|
||||
#define GPIO_93 (93)
|
||||
#define GPIO_94 (94)
|
||||
#define GPIO_95 (95)
|
||||
#define GPIO_96 (96)
|
||||
#define GPIO_97 (97)
|
||||
#define GPIO_98 (98)
|
||||
#define GPIO_99 (99)
|
||||
#define GPIO_100 (100)
|
||||
#define GPIO_101 (101)
|
||||
#define GPIO_102 (102)
|
||||
#define GPIO_103 (103)
|
||||
#define GPIO_104 (104)
|
||||
#define GPIO_105 (105)
|
||||
#define GPIO_106 (106)
|
||||
#define GPIO_107 (107)
|
||||
#define GPIO_108 (108)
|
||||
#define GPIO_109 (109)
|
||||
#define GPIO_110 (110)
|
||||
#define GPIO_111 (111)
|
||||
#define GPIO_112 (112)
|
||||
#define GPIO_113 (113)
|
||||
#define GPIO_114 (114)
|
||||
#define GPIO_115 (115)
|
||||
#define GPIO_116 (116)
|
||||
#define GPIO_117 (117)
|
||||
#define GPIO_118 (118)
|
||||
#define GPIO_119 (119)
|
||||
#define GPIO_120 (120)
|
||||
#define GPIO_121 (121)
|
||||
#define GPIO_122 (122)
|
||||
#define GPIO_123 (123)
|
||||
#define GPIO_124 (124)
|
||||
#define GPIO_125 (125)
|
||||
#define GPIO_126 (126)
|
||||
#define GPIO_127 (127)
|
||||
#define PWR_SCL (128)
|
||||
#define PWR_SDA (129)
|
||||
#define VCXO_EN (130)
|
||||
#define PMIC_INT_N (131)
|
||||
#define MMC1_DAT3 (132)
|
||||
#define MMC1_DAT2 (133)
|
||||
#define MMC1_DAT1 (134)
|
||||
#define MMC1_DAT0 (135)
|
||||
#define MMC1_CMD (136)
|
||||
#define MMC1_CLK (137)
|
||||
#define QSPI_DAT0 (138)
|
||||
#define QSPI_DAT1 (139)
|
||||
#define QSPI_DAT2 (140)
|
||||
#define QSPI_DAT3 (141)
|
||||
#define QSPI_CS0 (142)
|
||||
#define QSPI_CS1 (143)
|
||||
#define QSPI_CLK (144)
|
||||
#define PRI_TDI (145)
|
||||
#define PRI_TMS (146)
|
||||
#define PRI_TCK (147)
|
||||
#define PRI_TDO (148)
|
||||
#define PWR_SSP_SCLK (149)
|
||||
#define PWR_SSP_FRM (150)
|
||||
#define PWR_SSP_TXD (151)
|
||||
#define PWR_SSP_RXD (152)
|
||||
|
||||
/* pin mux */
|
||||
#define PAD_MUX GENMASK(2, 0)
|
||||
#define MUX_MODE0 0
|
||||
#define MUX_MODE1 1
|
||||
#define MUX_MODE2 2
|
||||
#define MUX_MODE3 3
|
||||
#define MUX_MODE4 4
|
||||
#define MUX_MODE5 5
|
||||
#define MUX_MODE6 6
|
||||
#define MUX_MODE7 7
|
||||
|
||||
#define PAD_STRONG_PULL BIT(3)
|
||||
|
||||
#define PAD_EDGE GENMASK(6, 4)
|
||||
#define PAD_EDGE_RISE BIT(4)
|
||||
#define PAD_EDGE_FALL BIT(5)
|
||||
#define PAD_EDGE_CLEAR BIT(6)
|
||||
|
||||
#define PAD_SLEW_RATE_EN BIT(7)
|
||||
|
||||
#define PAD_SCHMITT BIT(8)
|
||||
|
||||
#define PAD_PULLDOWN BIT(13)
|
||||
#define PAD_PULLUP BIT(14)
|
||||
#define PAD_PULL_EN BIT(15)
|
||||
|
||||
/*
|
||||
* drive strength
|
||||
* DRIVE[3:0] -> bits[12:9]
|
||||
*/
|
||||
#define PAD_DRIVE GENMASK(12, 9)
|
||||
#define PAD_DS0 (0 << 9) /* bit[12:9] 0000 */
|
||||
#define PAD_DS1 (1 << 9) /* bit[12:9] 0001 */
|
||||
#define PAD_DS2 (2 << 9) /* bit[12:9] 0010 */
|
||||
#define PAD_DS3 (3 << 9) /* bit[12:9] 0011 */
|
||||
#define PAD_DS4 (4 << 9) /* bit[12:9] 0100 */
|
||||
#define PAD_DS5 (5 << 9) /* bit[12:9] 0101 */
|
||||
#define PAD_DS6 (6 << 9) /* bit[12:9] 0110 */
|
||||
#define PAD_DS7 (7 << 9) /* bit[12:9] 0111 */
|
||||
#define PAD_DS8 (8 << 9) /* bit[12:9] 1000 */
|
||||
#define PAD_DS9 (9 << 9) /* bit[12:9] 1001 */
|
||||
#define PAD_DS10 (10 << 9) /* bit[12:9] 1010 */
|
||||
#define PAD_DS11 (11 << 9) /* bit[12:9] 1011 */
|
||||
#define PAD_DS12 (12 << 9) /* bit[12:9] 1100 */
|
||||
#define PAD_DS13 (13 << 9) /* bit[12:9] 1101 */
|
||||
#define PAD_DS14 (14 << 9) /* bit[12:9] 1110 */
|
||||
#define PAD_DS15 (15 << 9) /* bit[12:9] 1111 */
|
||||
|
||||
/* pull up/down */
|
||||
#define PULL_DIS (0 << 13) /* bit[15:13] 000 */
|
||||
#define PULL_UP (6 << 13) /* bit[15:13] 110 */
|
||||
#define PULL_DOWN (5 << 13) /* bit[15:13] 101 */
|
||||
|
||||
// pin reg offset
|
||||
#define PIN_ID(x) ((x) > 130? (x) + 2: (x))
|
||||
|
||||
// pinctrl-single,pins
|
||||
#define K3_PADCONF(pinid, mux, conf) ((PIN_ID(pinid)) << 2) ((conf) | (mux))
|
||||
|
||||
#endif /* __DT_BINDINGS_K3_PINCTRL_H */
|
||||
@@ -1,183 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only OR */
|
||||
/*
|
||||
* Spacemit K3 reset controller driver
|
||||
* Copyright (c) 2025, spacemit Corporation.
|
||||
*/
|
||||
|
||||
#ifndef __DT_BINDINGS_RESET_SAPCEMIT_K3_H__
|
||||
#define __DT_BINDINGS_RESET_SAPCEMIT_K3_H__
|
||||
//APBC
|
||||
#define RESET_UART0 0
|
||||
#define RESET_UART2 1
|
||||
#define RESET_UART3 2
|
||||
#define RESET_UART4 3
|
||||
#define RESET_UART5 4
|
||||
#define RESET_UART6 5
|
||||
#define RESET_UART7 6
|
||||
#define RESET_UART8 7
|
||||
#define RESET_UART9 8
|
||||
#define RESET_UART10 9
|
||||
#define RESET_GPIO 10
|
||||
#define RESET_PWM0 11
|
||||
#define RESET_PWM1 12
|
||||
#define RESET_PWM2 13
|
||||
#define RESET_PWM3 14
|
||||
#define RESET_PWM4 15
|
||||
#define RESET_PWM5 16
|
||||
#define RESET_PWM6 17
|
||||
#define RESET_PWM7 18
|
||||
#define RESET_PWM8 19
|
||||
#define RESET_PWM9 20
|
||||
#define RESET_PWM10 21
|
||||
#define RESET_PWM11 22
|
||||
#define RESET_PWM12 23
|
||||
#define RESET_PWM13 24
|
||||
#define RESET_PWM14 25
|
||||
#define RESET_PWM15 26
|
||||
#define RESET_PWM16 27
|
||||
#define RESET_PWM17 28
|
||||
#define RESET_PWM18 29
|
||||
#define RESET_PWM19 30
|
||||
#define RESET_SPI0 31
|
||||
#define RESET_SPI1 32
|
||||
#define RESET_SPI3 33
|
||||
#define RESET_RTC 34
|
||||
#define RESET_TWSI0 35
|
||||
#define RESET_TWSI1 36
|
||||
#define RESET_TWSI2 37
|
||||
#define RESET_TWSI4 38
|
||||
#define RESET_TWSI5 39
|
||||
#define RESET_TWSI6 40
|
||||
#define RESET_TWSI8 41
|
||||
#define RESET_TIMERS0 42
|
||||
#define RESET_TIMERS1 43
|
||||
#define RESET_TIMERS2 44
|
||||
#define RESET_TIMERS3 45
|
||||
#define RESET_TIMERS4 46
|
||||
#define RESET_TIMERS5 47
|
||||
#define RESET_TIMERS6 48
|
||||
#define RESET_TIMERS7 49
|
||||
#define RESET_AIB 50
|
||||
#define RESET_ONEWIRE 51
|
||||
#define RESET_I2S0 52
|
||||
#define RESET_I2S1 53
|
||||
#define RESET_I2S2 54
|
||||
#define RESET_I2S3 55
|
||||
#define RESET_I2S4 56
|
||||
#define RESET_I2S5 57
|
||||
#define RESET_DRO 58
|
||||
#define RESET_IR0 59
|
||||
#define RESET_IR1 60
|
||||
#define RESET_TSEN 61
|
||||
#define RESET_IPC_AP2AUD 62
|
||||
#define RESET_CAN0 63
|
||||
#define RESET_CAN1 64
|
||||
#define RESET_CAN2 65
|
||||
#define RESET_CAN3 66
|
||||
#define RESET_CAN4 67
|
||||
//MPMU
|
||||
#define RESET_WDT 68
|
||||
#define RESET_RIPC 69
|
||||
//APMU
|
||||
#define RESET_CSI 70
|
||||
#define RESET_CCIC2_PHY 71
|
||||
#define RESET_CCIC3_PHY 72
|
||||
#define RESET_ISP 73
|
||||
#define RESET_ISP_AHB 74
|
||||
#define RESET_ISP_CIBUS 75
|
||||
#define RESET_DSI_ESC 76
|
||||
#define RESET_LCD 77
|
||||
#define RESET_V2D 78
|
||||
#define RESET_LCD_SPI_HBUS 79
|
||||
#define RESET_LCD_SPI_BUS 80
|
||||
#define RESET_LCD_MCLK 81
|
||||
#define RESET_LCD_DSCCLK 82
|
||||
#define RESET_SC2_HCLK 83
|
||||
#define RESET_CCIC_4X 84
|
||||
#define RESET_CCIC1_PHY 85
|
||||
#define RESET_SDH_AXI 86
|
||||
#define RESET_SDH0 87
|
||||
#define RESET_SDH1 88
|
||||
#define RESET_SDH2 89
|
||||
#define RESET_USB2 90
|
||||
#define RESET_USB3_PORTA 91
|
||||
#define RESET_USB3_PORTB 92
|
||||
#define RESET_USB3_PORTC 93
|
||||
#define RESET_USB3_PORTD 94
|
||||
#define RESET_QSPI 95
|
||||
#define RESET_QSPI_BUS 96
|
||||
#define RESET_DMA 97
|
||||
#define RESET_AES_WTM 98
|
||||
#define RESET_MCB_DCLK 99
|
||||
#define RESET_MCB_ACLK 100
|
||||
#define RESET_VPU 101
|
||||
#define RESET_DTC 102
|
||||
#define RESET_GPU 103
|
||||
#define RESET_MC 104
|
||||
#define RESET_CPU0_POP 105
|
||||
#define RESET_CPU0_SW 106
|
||||
#define RESET_CPU1_POP 107
|
||||
#define RESET_CPU1_SW 108
|
||||
#define RESET_CPU2_POP 109
|
||||
#define RESET_CPU2_SW 110
|
||||
#define RESET_CPU3_POP 111
|
||||
#define RESET_CPU3_SW 112
|
||||
#define RESET_C0_MPSUB_SW 113
|
||||
#define RESET_CPU4_POP 114
|
||||
#define RESET_CPU4_SW 115
|
||||
#define RESET_CPU5_POP 116
|
||||
#define RESET_CPU5_SW 117
|
||||
#define RESET_CPU6_POP 118
|
||||
#define RESET_CPU6_SW 119
|
||||
#define RESET_CPU7_POP 120
|
||||
#define RESET_CPU7_SW 121
|
||||
#define RESET_C1_MPSUB_SW 122
|
||||
#define RESET_MPSUB_DBG 123
|
||||
#define RESET_UCIE 124
|
||||
#define RESET_RCPU 125
|
||||
#define RESET_DSI4LN2_ESCCLK 126
|
||||
#define RESET_DSI4LN2_LCD_SW 127
|
||||
#define RESET_DSI4LN2_LCD_MCLK 128
|
||||
#define RESET_DSI4LN2_LCD_DSCCLK 129
|
||||
#define RESET_DSI4LN2_DPU_ACLK 130
|
||||
#define RESET_DPU_ACLK 131
|
||||
#define RESET_UFS_ACLK 132
|
||||
#define RESET_EDP0 133
|
||||
#define RESET_EDP1 134
|
||||
#define RESET_PCIE_PORTA 135
|
||||
#define RESET_PCIE_PORTB 136
|
||||
#define RESET_PCIE_PORTC 137
|
||||
#define RESET_PCIE_PORTD 138
|
||||
#define RESET_PCIE_PORTE 139
|
||||
#define RESET_EMAC0 140
|
||||
#define RESET_EMAC1 141
|
||||
#define RESET_EMAC2 142
|
||||
#define RESET_ESPI 143
|
||||
//DCIU
|
||||
#define RESET_HDMA 144
|
||||
#define RESET_DMA350 145
|
||||
#define RESET_DMA350_0 146
|
||||
#define RESET_DMA350_1 147
|
||||
#define RESET_AXIDMA0 148
|
||||
#define RESET_AXIDMA1 149
|
||||
#define RESET_AXIDMA2 150
|
||||
#define RESET_AXIDMA3 151
|
||||
#define RESET_AXIDMA4 152
|
||||
#define RESET_AXIDMA5 153
|
||||
#define RESET_AXIDMA6 154
|
||||
#define RESET_AXIDMA7 155
|
||||
//APBC2
|
||||
#define RESET_SEC_UART1 156
|
||||
#define RESET_SEC_SSP2 157
|
||||
#define RESET_SEC_TWSI3 158
|
||||
#define RESET_SEC_RTC 159
|
||||
#define RESET_SEC_TIMERS 160
|
||||
#define RESET_SEC_JTAG 161
|
||||
#define RESET_SEC_GPIO 162
|
||||
//RCPU
|
||||
#define RESET_RCPU5_RT24_CORE0 163
|
||||
#define RESET_RCPU5_RT24_CORE1 164
|
||||
|
||||
#define RESET_NUMBER 165
|
||||
|
||||
#endif /* __DT_BINDINGS_RESET_SAPCEMIT_K3_H__ */
|
||||
@@ -234,8 +234,6 @@ enum image_type_t {
|
||||
IH_TYPE_STARFIVE_SPL, /* StarFive SPL image */
|
||||
IH_TYPE_TFA_BL31, /* TFA BL31 image */
|
||||
IH_TYPE_STM32IMAGE_V2, /* STMicroelectronics STM32 Image V2.0 */
|
||||
IH_TYPE_SPACEMIT_BOOTINFO, /* SpacemiT BootInfo Binary Header */
|
||||
IH_TYPE_SPACEMIT_SPL, /* SpacemiT BootROM loadable Image */
|
||||
|
||||
IH_TYPE_COUNT, /* Number of image types */
|
||||
};
|
||||
|
||||
@@ -108,8 +108,6 @@ KWB_IMAGE_OBJS-$(CONFIG_TOOLS_LIBCRYPTO) := kwbimage.o
|
||||
|
||||
ROCKCHIP_OBS = generated/lib/rc4.o rkcommon.o rkimage.o rksd.o rkspi.o
|
||||
|
||||
SPACEMIT_OBJS = spacemit-boot.o spacemit-spl.o
|
||||
|
||||
# common objs for dumpimage and mkimage
|
||||
dumpimage-mkimage-objs := aisimage.o \
|
||||
atmelimage.o \
|
||||
@@ -142,7 +140,6 @@ dumpimage-mkimage-objs := aisimage.o \
|
||||
stm32image.o \
|
||||
$(ROCKCHIP_OBS) \
|
||||
socfpgaimage.o \
|
||||
$(SPACEMIT_OBJS) \
|
||||
sunxi_egon.o \
|
||||
generated/lib/crc16-ccitt.o \
|
||||
generated/lib/hash-checksum.o \
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2026 Hangfan Li <lihangfan@iscas.ac.cn>
|
||||
*/
|
||||
|
||||
|
||||
#include "imagetool.h"
|
||||
|
||||
struct bootinfo_hdr {
|
||||
struct {
|
||||
/** @magic: MAGIC value, always 0xB00714F0 */
|
||||
uint32_t magic;
|
||||
/** @version: ???*/
|
||||
uint32_t version;
|
||||
/** @flash_type: oneof "NORF", "BLCK" */
|
||||
uint32_t flash_type;
|
||||
/** @mid: ???*/
|
||||
uint8_t mid;
|
||||
uint8_t _reserved_0[1];
|
||||
/** @did: ???*/
|
||||
uint16_t did;
|
||||
/** @page_size: ???*/
|
||||
uint32_t page_size;
|
||||
/** @block_size: ???*/
|
||||
uint32_t block_size;
|
||||
/** @total_size: ???*/
|
||||
uint32_t total_size;
|
||||
/** @multi_plane: ???*/
|
||||
uint8_t multi_plane;
|
||||
uint8_t _reserved_1[3];
|
||||
/** @spl0_offset: Offset to primary SPL image */
|
||||
uint32_t spl0_offset;
|
||||
/** @spl1_offset: Offset to backup SPL image */
|
||||
uint32_t spl1_offset;
|
||||
/** @spl_size_limit: Max size of SPL image */
|
||||
uint32_t spl_size_limit;
|
||||
/** @partitiontable0_offset: ??? */
|
||||
uint32_t partitiontable0_offset;
|
||||
/** @partitiontable1_offset: ??? */
|
||||
uint32_t partitiontable1_offset;
|
||||
uint8_t _reserved_2[12];
|
||||
} data;
|
||||
struct {
|
||||
/** @crc32: crc32 of data */
|
||||
uint32_t crc32;
|
||||
uint8_t _reserved_0[12];
|
||||
} checksum;
|
||||
};
|
||||
|
||||
static int spacemit_bootinfo_check_params(struct image_tool_params *params)
|
||||
{
|
||||
/* Only the RISC-V architecture is supported */
|
||||
if (params->Aflag && params->arch != IH_ARCH_RISCV)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
static int spacemit_bootinfo_verify_header(unsigned char *buf, int size,
|
||||
struct image_tool_params *params)
|
||||
{
|
||||
printf("spacemit_bootinfo_verify_header\n");
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
static void spacemit_bootinfo_print_header(const void *buf,
|
||||
struct image_tool_params *params)
|
||||
{
|
||||
printf("spacemit_bootinfo_print_header\n");
|
||||
}
|
||||
|
||||
static void spacemit_bootinfo_set_header(void *buf, struct stat *sbuf, int infd,
|
||||
struct image_tool_params *params)
|
||||
{
|
||||
printf("spacemit_bootinfo_set_header\n");
|
||||
}
|
||||
|
||||
static int spacemit_bootinfo_check_image_type(uint8_t type)
|
||||
{
|
||||
if (type == IH_TYPE_SPACEMIT_BOOTINFO)
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
static struct bootinfo_hdr spacemit_bootinfo_hdr;
|
||||
|
||||
U_BOOT_IMAGE_TYPE(
|
||||
spacemit_bootinfo, /* id */
|
||||
"SpacemiT BootInfo Header", /* name */
|
||||
sizeof(struct bootinfo_hdr), /* header_size */
|
||||
&spacemit_bootinfo_hdr, /* header */
|
||||
spacemit_bootinfo_check_params, /* check_params */
|
||||
spacemit_bootinfo_verify_header, /* verify header */
|
||||
spacemit_bootinfo_print_header, /* print header */
|
||||
spacemit_bootinfo_set_header, /* set header */
|
||||
NULL, /* extract_subimage */
|
||||
spacemit_bootinfo_check_image_type, /* check_image_type */
|
||||
NULL, /* fflag_handle */
|
||||
NULL /* vrec_header */
|
||||
);
|
||||
@@ -1,129 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
|
||||
/*
|
||||
* Copyright (C) 2026 Hangfan Li <lihangfan@iscas.ac.cn>
|
||||
*/
|
||||
|
||||
|
||||
#include "imagetool.h"
|
||||
#include <u-boot/crc.h>
|
||||
#include <openssl/engine.h>
|
||||
|
||||
#define SPACEMIT_SPL_HDR_MAGIC_LE32 0x44484941
|
||||
|
||||
struct spl_hdr {
|
||||
struct {
|
||||
/** @magic: MAGIC value, always 0x44484941 */
|
||||
uint32_t magic;
|
||||
/** @version: ??? */
|
||||
uint8_t version;
|
||||
/** @secure: ??? */
|
||||
uint8_t secure;
|
||||
uint8_t _reserved_0[2];
|
||||
/** @payload_size: Size of payload only */
|
||||
uint64_t payload_size;
|
||||
/** @loadaddr: Target load address */
|
||||
uint64_t loadaddr;
|
||||
} header;
|
||||
struct {
|
||||
/** @header: crc32 of header data */
|
||||
uint32_t header;
|
||||
/** @payload: crc32 of payload image */
|
||||
uint32_t payload;
|
||||
} checksum;
|
||||
// Useful for mmap-ed output file
|
||||
uint8_t payload[0];
|
||||
};
|
||||
|
||||
static int spacemit_spl_check_params(struct image_tool_params *params)
|
||||
{
|
||||
/* Only the RISC-V architecture is supported */
|
||||
if (params->Aflag && params->arch != IH_ARCH_RISCV)
|
||||
return EXIT_FAILURE;
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
static int spacemit_spl_verify_header(unsigned char *buf, int size,
|
||||
struct image_tool_params *params)
|
||||
{
|
||||
const struct spl_hdr *hdr = (void *)buf;
|
||||
if (le32_to_cpu(hdr->header.magic) != SPACEMIT_SPL_HDR_MAGIC_LE32) {
|
||||
printf("Unmatched header MAGIC value: %08x\n", le32_to_cpu(hdr->header.magic));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (le32_to_cpu(hdr->checksum.header) != crc32(0, (void *)&hdr->header, sizeof(hdr->header))) {
|
||||
printf("Unmatched header checksum\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (le32_to_cpu(hdr->header.payload_size) + sizeof(struct spl_hdr) > params->file_size) {
|
||||
printf("Payload size (%lu) exceeds file size (%u) - header size (%lu)\n",
|
||||
le32_to_cpu(hdr->header.payload_size), params->file_size, sizeof(struct spl_hdr));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
if (le32_to_cpu(hdr->checksum.payload) != crc32(0, (void *)&hdr->payload, le32_to_cpu(hdr->header.payload_size))) {
|
||||
printf("Unmatched payload checksum\n");
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
static void spacemit_spl_print_header(const void *buf,
|
||||
struct image_tool_params *params)
|
||||
{
|
||||
const struct spl_hdr *hdr = buf;
|
||||
printf("SpacemiT BootROM Loadable Image\n");
|
||||
printf("-> Header Version: 0x%02x\n", hdr->header.version);
|
||||
printf("-> Secure Mode: ");
|
||||
if (hdr->header.secure == 0) {
|
||||
printf("Disabled\n");
|
||||
} else {
|
||||
printf("Enabled (0x%02x)\n", hdr->header.secure);
|
||||
}
|
||||
printf("-> Payload Size: %lu\n", le64_to_cpu(hdr->header.payload_size));
|
||||
printf("-> Payload Load Addr: %lu\n", le64_to_cpu(hdr->header.loadaddr));
|
||||
}
|
||||
|
||||
static void spacemit_spl_set_header(void *buf, struct stat *sbuf, int infd,
|
||||
struct image_tool_params *params)
|
||||
{
|
||||
// Filling header info
|
||||
struct spl_hdr *hdr = buf;
|
||||
memset((void *)hdr, 0, sizeof(struct spl_hdr));
|
||||
hdr->header.magic = cpu_to_le32(SPACEMIT_SPL_HDR_MAGIC_LE32);
|
||||
hdr->header.version = 0x01;
|
||||
hdr->header.secure = 0;
|
||||
hdr->header.payload_size = cpu_to_le64(params->file_size - sizeof(struct spl_hdr));
|
||||
hdr->header.loadaddr = cpu_to_le64(0x0);
|
||||
hdr->checksum.header = cpu_to_le32(crc32(0, (void *)&hdr->header, sizeof(hdr->header)));
|
||||
hdr->checksum.payload = cpu_to_le32(crc32(0, (void *)hdr->payload, le64_to_cpu(hdr->header.payload_size)));
|
||||
|
||||
// Payload is already copied by mkimage
|
||||
|
||||
// Generate signature
|
||||
// Here we directly call into OpenSSL to avoid U-Boot overheads
|
||||
}
|
||||
|
||||
static int spacemit_spl_check_image_type(uint8_t type)
|
||||
{
|
||||
if (type == IH_TYPE_SPACEMIT_SPL)
|
||||
return EXIT_SUCCESS;
|
||||
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
static struct spl_hdr spacemit_spl_hdr;
|
||||
|
||||
U_BOOT_IMAGE_TYPE(
|
||||
spacemit_spl, /* id */
|
||||
"SpacemiT BROM loadable Image", /* name */
|
||||
sizeof(struct spl_hdr), /* header_size */
|
||||
&spacemit_spl_hdr, /* header */
|
||||
spacemit_spl_check_params, /* check_params */
|
||||
spacemit_spl_verify_header, /* verify header */
|
||||
spacemit_spl_print_header, /* print header */
|
||||
spacemit_spl_set_header, /* set header */
|
||||
NULL, /* extract_subimage */
|
||||
spacemit_spl_check_image_type, /* check_image_type */
|
||||
NULL, /* fflag_handle */
|
||||
NULL /* vrec_header */
|
||||
);
|
||||
Reference in New Issue
Block a user