* [PATCH 00/17] Add board support for Spacemit K1 SoC in SPL
@ 2026-01-17 19:01 Raymond Mao
2026-01-17 19:01 ` [PATCH 01/17] spacemit: k1: support multi-board infrastructure Raymond Mao
` (18 more replies)
0 siblings, 19 replies; 37+ messages in thread
From: Raymond Mao @ 2026-01-17 19:01 UTC (permalink / raw)
To: u-boot
Cc: uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski,
Heiko Schocher, Jaehoon Chung, Peng Fan, Yao Zi,
Heinrich Schuchardt, Conor Dooley, Yu-Chien Peter Lin,
Jamie Gibbons, Michal Simek, Eric Schikschneit, Yixun Lan,
Junhui Liu, Sam Protsenko, Patrick Delaunay, Patrice Chotard,
Ilias Apalodimas, Neil Armstrong, Casey Connolly,
Christian Marangi, Angelo Dureghello, Aniket Limaye,
Utsav Agarwal, Justin Swartz, Nathan Barrett-Morrison,
Ian Roberts, Arturs Artamonovs, Oliver Gaskell, Greg Malysa,
Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Kory Maincent,
Anshul Dalal, Justin Klaassen, Paul Barker, Samuel Holland,
Jernej Skrabec, Marek Vasut, Rui Miguel Silva, Gabriel Fernandez,
Jonas Karlman, Kever Yang, Heiko Stuebner, Elaine Zhang,
Joseph Chen
From: Raymond Mao <raymond.mao@riscstar.com>
This patch series introduces full support for the k1 SoC in SPL for
multiple boards.
The series enables the board by:
1. Adding the base board definition with device tree.
2. Bringing up essential clock sources and tree.
3. Initializing I2C buses for peripheral communication.
4. Integrating the PMIC driver for power management.
5. Adding regulator drivers for voltage domain control.
Junhui Liu (1):
clk: spacemit: Add support for K1 SoC
Raymond Mao (16):
spacemit: k1: support multi-board infrastructure
spacemit: k1: enable SPL with debug UART
configs: k1: enable early timer support
reset: k1: add SPL support and enable TWSI8 reset
dt-bindings: clock: import k1-syscon from upstream
dts: k1: import dts file from upstream folder
dts: k1: enable clocks in SPL
board: k1: initialize clock and serial devices in SPL
configs: k1: add default option for clock driver in SPL
i2c: k1: add I2C driver support
dt-bindings: pinctrl: add k1 support
spacemit: k1: add TLV EEPROM support in SPL
spacemit: k1: Add DDR firmware support to SPL
power: pmic: add support for Spacemit P1 PMIC
power: regulator: add support for Spacemit P1 SoC
board: k1: enable pmic in spl
arch/riscv/Kconfig | 10 +-
arch/riscv/cpu/k1/Kconfig | 6 +
arch/riscv/dts/Makefile | 1 +
arch/riscv/dts/k1-spl.dts | 239 +++
arch/riscv/dts/k1.dtsi | 667 +++++-
board/spacemit/bananapi-f3/Kconfig | 25 -
board/spacemit/bananapi-f3/Makefile | 5 -
board/spacemit/k1/Kconfig | 38 +
.../spacemit/{bananapi-f3 => k1}/MAINTAINERS | 4 +-
board/spacemit/k1/Makefile | 26 +
board/spacemit/{bananapi-f3 => k1}/board.c | 0
board/spacemit/k1/spl.c | 252 +++
board/spacemit/k1/tlv_codes.h | 22 +
configs/bananapi-f3_defconfig | 24 -
configs/k1_defconfig | 77 +
drivers/clk/Kconfig | 5 +-
drivers/clk/Makefile | 1 +
drivers/clk/spacemit/Kconfig | 31 +
drivers/clk/spacemit/Makefile | 7 +
drivers/clk/spacemit/clk-k1.c | 1793 +++++++++++++++++
drivers/clk/spacemit/clk_common.h | 79 +
drivers/clk/spacemit/clk_ddn.c | 93 +
drivers/clk/spacemit/clk_ddn.h | 53 +
drivers/clk/spacemit/clk_mix.c | 403 ++++
drivers/clk/spacemit/clk_mix.h | 224 ++
drivers/clk/spacemit/clk_pll.c | 157 ++
drivers/clk/spacemit/clk_pll.h | 81 +
drivers/i2c/Kconfig | 7 +
drivers/i2c/Makefile | 1 +
drivers/i2c/k1_i2c.c | 521 +++++
drivers/i2c/k1_i2c.h | 69 +
drivers/power/pmic/Kconfig | 17 +
drivers/power/pmic/Makefile | 1 +
drivers/power/pmic/pmic_spacemit_p1.c | 94 +
drivers/power/regulator/Kconfig | 15 +
drivers/power/regulator/Makefile | 1 +
.../power/regulator/spacemit_p1_regulator.c | 460 +++++
drivers/reset/Kconfig | 7 +
drivers/reset/Makefile | 2 +-
drivers/reset/reset-spacemit-k1.c | 4 -
include/configs/{bananapi-f3.h => k1.h} | 9 +
.../dt-bindings/clock/spacemit,k1-syscon.h | 253 +++
include/dt-bindings/pinctrl/k1-pinctrl.h | 59 +
include/power/spacemit_p1.h | 163 ++
include/soc/spacemit/k1-syscon.h | 149 ++
lib/vendor/spacemit/ddr_fw.bin | Bin 0 -> 19416 bytes
46 files changed, 5985 insertions(+), 170 deletions(-)
create mode 100644 arch/riscv/dts/k1-spl.dts
delete mode 100644 board/spacemit/bananapi-f3/Kconfig
delete mode 100644 board/spacemit/bananapi-f3/Makefile
create mode 100644 board/spacemit/k1/Kconfig
rename board/spacemit/{bananapi-f3 => k1}/MAINTAINERS (61%)
create mode 100644 board/spacemit/k1/Makefile
rename board/spacemit/{bananapi-f3 => k1}/board.c (100%)
create mode 100644 board/spacemit/k1/spl.c
create mode 100644 board/spacemit/k1/tlv_codes.h
delete mode 100644 configs/bananapi-f3_defconfig
create mode 100644 configs/k1_defconfig
create mode 100644 drivers/clk/spacemit/Kconfig
create mode 100644 drivers/clk/spacemit/Makefile
create mode 100644 drivers/clk/spacemit/clk-k1.c
create mode 100644 drivers/clk/spacemit/clk_common.h
create mode 100644 drivers/clk/spacemit/clk_ddn.c
create mode 100644 drivers/clk/spacemit/clk_ddn.h
create mode 100644 drivers/clk/spacemit/clk_mix.c
create mode 100644 drivers/clk/spacemit/clk_mix.h
create mode 100644 drivers/clk/spacemit/clk_pll.c
create mode 100644 drivers/clk/spacemit/clk_pll.h
create mode 100644 drivers/i2c/k1_i2c.c
create mode 100644 drivers/i2c/k1_i2c.h
create mode 100644 drivers/power/pmic/pmic_spacemit_p1.c
create mode 100644 drivers/power/regulator/spacemit_p1_regulator.c
rename include/configs/{bananapi-f3.h => k1.h} (52%)
create mode 100644 include/dt-bindings/clock/spacemit,k1-syscon.h
create mode 100644 include/dt-bindings/pinctrl/k1-pinctrl.h
create mode 100644 include/power/spacemit_p1.h
create mode 100644 include/soc/spacemit/k1-syscon.h
create mode 100644 lib/vendor/spacemit/ddr_fw.bin
--
2.25.1
^ permalink raw reply [flat|nested] 37+ messages in thread* [PATCH 01/17] spacemit: k1: support multi-board infrastructure 2026-01-17 19:01 [PATCH 00/17] Add board support for Spacemit K1 SoC in SPL Raymond Mao @ 2026-01-17 19:01 ` Raymond Mao 2026-01-23 10:27 ` Heinrich Schuchardt 2026-01-17 19:01 ` [PATCH 02/17] spacemit: k1: enable SPL with debug UART Raymond Mao ` (17 subsequent siblings) 18 siblings, 1 reply; 37+ messages in thread From: Raymond Mao @ 2026-01-17 19:01 UTC (permalink / raw) To: u-boot Cc: uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Yao Zi, Jamie Gibbons, Heinrich Schuchardt, Yu-Chien Peter Lin, Conor Dooley, Eric Schikschneit, Randolph Sheng-Kai Lin, Michal Simek, Junhui Liu, Yixun Lan, Sam Protsenko, Patrick Delaunay, Patrice Chotard, Neil Armstrong, Casey Connolly, Christian Marangi, Ian Roberts, Arturs Artamonovs, Utsav Agarwal, Nathan Barrett-Morrison, Aniket Limaye, Justin Swartz, Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Anshul Dalal, Kory Maincent, Samuel Holland, Rui Miguel Silva, Justin Klaassen, Paul Barker, Marek Vasut, Gabriel Fernandez, Jonas Karlman, Kever Yang, Joseph Chen, Heiko Stuebner, Elaine Zhang From: Raymond Mao <raymond.mao@riscstar.com> Restructure K1 SoC support to handle multiple boards through a single configuration: 1. Rename bananapi-f3_defconfig to k1_defconfig. 2. Move all K1 board files to k1 directory. Eliminates the need for board-specific defconfigs while maintaining hardware compatibility. Signed-off-by: Raymond Mao <raymond.mao@riscstar.com> --- arch/riscv/Kconfig | 10 ++++++---- arch/riscv/cpu/k1/Kconfig | 4 ++++ board/spacemit/{bananapi-f3 => k1}/Kconfig | 11 ++++++++--- board/spacemit/{bananapi-f3 => k1}/MAINTAINERS | 4 ++-- board/spacemit/{bananapi-f3 => k1}/Makefile | 0 board/spacemit/{bananapi-f3 => k1}/board.c | 0 configs/{bananapi-f3_defconfig => k1_defconfig} | 3 ++- include/configs/{bananapi-f3.h => k1.h} | 0 8 files changed, 22 insertions(+), 10 deletions(-) rename board/spacemit/{bananapi-f3 => k1}/Kconfig (63%) rename board/spacemit/{bananapi-f3 => k1}/MAINTAINERS (61%) rename board/spacemit/{bananapi-f3 => k1}/Makefile (100%) rename board/spacemit/{bananapi-f3 => k1}/board.c (100%) rename configs/{bananapi-f3_defconfig => k1_defconfig} (97%) rename include/configs/{bananapi-f3.h => k1.h} (100%) diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 79867656b15..ac50c1d7234 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -8,15 +8,17 @@ choice prompt "Target select" optional +config ARCH_K1 + bool "Spacemit K1 Architecture" + help + This enables support for Spacemit K1 SoC family. + config TARGET_ANDES_AE350 bool "Support Andes ae350" config TARGET_ANDES_VOYAGER bool "Support Andes Voyager Board" -config TARGET_BANANAPI_F3 - bool "Support BananaPi F3 Board" - config TARGET_K230_CANMV bool "Support K230 CanMV Board" @@ -115,7 +117,7 @@ source "board/sifive/unmatched/Kconfig" 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/k1/Kconfig" source "board/starfive/visionfive2/Kconfig" source "board/thead/th1520_lpi4a/Kconfig" source "board/xilinx/mbv/Kconfig" diff --git a/arch/riscv/cpu/k1/Kconfig b/arch/riscv/cpu/k1/Kconfig index 14201df80f2..4b621158334 100644 --- a/arch/riscv/cpu/k1/Kconfig +++ b/arch/riscv/cpu/k1/Kconfig @@ -2,6 +2,8 @@ # # Copyright (C) 2024, Kongyang Liu <seashell11234455@gmail.com> +if ARCH_K1 + config SPACEMIT_K1 bool select BINMAN @@ -17,3 +19,5 @@ config SPACEMIT_K1 imply SPL_CPU imply SPL_OPENSBI imply SPL_LOAD_FIT + +endif diff --git a/board/spacemit/bananapi-f3/Kconfig b/board/spacemit/k1/Kconfig similarity index 63% rename from board/spacemit/bananapi-f3/Kconfig rename to board/spacemit/k1/Kconfig index f89fa9af2c7..9f9c806d00d 100644 --- a/board/spacemit/bananapi-f3/Kconfig +++ b/board/spacemit/k1/Kconfig @@ -1,7 +1,7 @@ -if TARGET_BANANAPI_F3 +if ARCH_K1 config SYS_BOARD - default "bananapi-f3" + default "k1" config SYS_VENDOR default "spacemit" @@ -10,7 +10,7 @@ config SYS_CPU default "k1" config SYS_CONFIG_NAME - default "bananapi-f3" + default "k1" config TEXT_BASE default 0x00200000 @@ -22,4 +22,9 @@ config BOARD_SPECIFIC_OPTIONS def_bool y select SPACEMIT_K1 +config TARGET_BANANAPI_F3 + bool "Support BananaPi F3 Board" + help + BananaPi F3 board contains Spacemit K1 SoC. + endif diff --git a/board/spacemit/bananapi-f3/MAINTAINERS b/board/spacemit/k1/MAINTAINERS similarity index 61% rename from board/spacemit/bananapi-f3/MAINTAINERS rename to board/spacemit/k1/MAINTAINERS index 131bad03181..bd476c32719 100644 --- a/board/spacemit/bananapi-f3/MAINTAINERS +++ b/board/spacemit/k1/MAINTAINERS @@ -1,6 +1,6 @@ BananaPi F3 M: Huan Zhou <pericycle.cc@@gmail.com> S: Maintained -F: board/spacemit/bananapi-f3/ -F: configs/bananapi-f3_defconfig +F: board/spacemit/k1/ +F: configs/k1_defconfig F: doc/board/spacemit/bananapi-f3.rst diff --git a/board/spacemit/bananapi-f3/Makefile b/board/spacemit/k1/Makefile similarity index 100% rename from board/spacemit/bananapi-f3/Makefile rename to board/spacemit/k1/Makefile diff --git a/board/spacemit/bananapi-f3/board.c b/board/spacemit/k1/board.c similarity index 100% rename from board/spacemit/bananapi-f3/board.c rename to board/spacemit/k1/board.c diff --git a/configs/bananapi-f3_defconfig b/configs/k1_defconfig similarity index 97% rename from configs/bananapi-f3_defconfig rename to configs/k1_defconfig index a726ce84775..0bdc3c800f0 100644 --- a/configs/bananapi-f3_defconfig +++ b/configs/k1_defconfig @@ -6,9 +6,10 @@ CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x1000000 CONFIG_DEFAULT_DEVICE_TREE="k1-bananapi-f3" CONFIG_SYS_BOOTM_LEN=0xa000000 CONFIG_SYS_LOAD_ADDR=0x200000 -CONFIG_TARGET_BANANAPI_F3=y CONFIG_ARCH_RV64I=y CONFIG_RISCV_SMODE=y +CONFIG_ARCH_K1=y +CONFIG_TARGET_BANANAPI_F3=y CONFIG_FIT=y CONFIG_SUPPORT_RAW_INITRD=y CONFIG_OF_BOARD_SETUP=y diff --git a/include/configs/bananapi-f3.h b/include/configs/k1.h similarity index 100% rename from include/configs/bananapi-f3.h rename to include/configs/k1.h -- 2.25.1 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [PATCH 01/17] spacemit: k1: support multi-board infrastructure 2026-01-17 19:01 ` [PATCH 01/17] spacemit: k1: support multi-board infrastructure Raymond Mao @ 2026-01-23 10:27 ` Heinrich Schuchardt 2026-01-23 10:46 ` Heinrich Schuchardt 0 siblings, 1 reply; 37+ messages in thread From: Heinrich Schuchardt @ 2026-01-23 10:27 UTC (permalink / raw) To: Raymond Mao Cc: uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Yao Zi, Jamie Gibbons, Yu-Chien Peter Lin, Conor Dooley, Eric Schikschneit, Randolph Sheng-Kai Lin, Michal Simek, Junhui Liu, Yixun Lan, Sam Protsenko, Patrick Delaunay, Patrice Chotard, Neil Armstrong, Casey Connolly, Christian Marangi, Ian Roberts, Arturs Artamonovs, Utsav Agarwal, Nathan Barrett-Morrison, Aniket Limaye, Justin Swartz, Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Anshul Dalal, Kory Maincent, Samuel Holland, Rui Miguel Silva, Justin Klaassen, Paul Barker, Marek Vasut, Gabriel Fernandez, Jonas Karlman, Kever Yang, Joseph Chen, Heiko Stuebner, Elaine Zhang, u-boot On 1/17/26 20:01, Raymond Mao wrote: > From: Raymond Mao <raymond.mao@riscstar.com> > > Restructure K1 SoC support to handle multiple boards through a single > configuration: > > 1. Rename bananapi-f3_defconfig to k1_defconfig. > 2. Move all K1 board files to k1 directory. > > Eliminates the need for board-specific defconfigs while maintaining > hardware compatibility. > > Signed-off-by: Raymond Mao <raymond.mao@riscstar.com> > --- > arch/riscv/Kconfig | 10 ++++++---- > arch/riscv/cpu/k1/Kconfig | 4 ++++ > board/spacemit/{bananapi-f3 => k1}/Kconfig | 11 ++++++++--- > board/spacemit/{bananapi-f3 => k1}/MAINTAINERS | 4 ++-- > board/spacemit/{bananapi-f3 => k1}/Makefile | 0 > board/spacemit/{bananapi-f3 => k1}/board.c | 0 > configs/{bananapi-f3_defconfig => k1_defconfig} | 3 ++- > include/configs/{bananapi-f3.h => k1.h} | 0 > 8 files changed, 22 insertions(+), 10 deletions(-) > rename board/spacemit/{bananapi-f3 => k1}/Kconfig (63%) > rename board/spacemit/{bananapi-f3 => k1}/MAINTAINERS (61%) > rename board/spacemit/{bananapi-f3 => k1}/Makefile (100%) > rename board/spacemit/{bananapi-f3 => k1}/board.c (100%) > rename configs/{bananapi-f3_defconfig => k1_defconfig} (97%) > rename include/configs/{bananapi-f3.h => k1.h} (100%) This changes in this patch look ok. But please, update doc/board/spacemit/bananapi-f3.rst to point to the new defconfig. Best regards Heinrich > > diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig > index 79867656b15..ac50c1d7234 100644 > --- a/arch/riscv/Kconfig > +++ b/arch/riscv/Kconfig > @@ -8,15 +8,17 @@ choice > prompt "Target select" > optional > > +config ARCH_K1 > + bool "Spacemit K1 Architecture" > + help > + This enables support for Spacemit K1 SoC family. > + > config TARGET_ANDES_AE350 > bool "Support Andes ae350" > > config TARGET_ANDES_VOYAGER > bool "Support Andes Voyager Board" > > -config TARGET_BANANAPI_F3 > - bool "Support BananaPi F3 Board" > - > config TARGET_K230_CANMV > bool "Support K230 CanMV Board" > > @@ -115,7 +117,7 @@ source "board/sifive/unmatched/Kconfig" > 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/k1/Kconfig" > source "board/starfive/visionfive2/Kconfig" > source "board/thead/th1520_lpi4a/Kconfig" > source "board/xilinx/mbv/Kconfig" > diff --git a/arch/riscv/cpu/k1/Kconfig b/arch/riscv/cpu/k1/Kconfig > index 14201df80f2..4b621158334 100644 > --- a/arch/riscv/cpu/k1/Kconfig > +++ b/arch/riscv/cpu/k1/Kconfig > @@ -2,6 +2,8 @@ > # > # Copyright (C) 2024, Kongyang Liu <seashell11234455@gmail.com> > > +if ARCH_K1 > + > config SPACEMIT_K1 > bool > select BINMAN > @@ -17,3 +19,5 @@ config SPACEMIT_K1 > imply SPL_CPU > imply SPL_OPENSBI > imply SPL_LOAD_FIT > + > +endif > diff --git a/board/spacemit/bananapi-f3/Kconfig b/board/spacemit/k1/Kconfig > similarity index 63% > rename from board/spacemit/bananapi-f3/Kconfig > rename to board/spacemit/k1/Kconfig > index f89fa9af2c7..9f9c806d00d 100644 > --- a/board/spacemit/bananapi-f3/Kconfig > +++ b/board/spacemit/k1/Kconfig > @@ -1,7 +1,7 @@ > -if TARGET_BANANAPI_F3 > +if ARCH_K1 > > config SYS_BOARD > - default "bananapi-f3" > + default "k1" > > config SYS_VENDOR > default "spacemit" > @@ -10,7 +10,7 @@ config SYS_CPU > default "k1" > > config SYS_CONFIG_NAME > - default "bananapi-f3" > + default "k1" > > config TEXT_BASE > default 0x00200000 > @@ -22,4 +22,9 @@ config BOARD_SPECIFIC_OPTIONS > def_bool y > select SPACEMIT_K1 > > +config TARGET_BANANAPI_F3 > + bool "Support BananaPi F3 Board" > + help > + BananaPi F3 board contains Spacemit K1 SoC. > + > endif > diff --git a/board/spacemit/bananapi-f3/MAINTAINERS b/board/spacemit/k1/MAINTAINERS > similarity index 61% > rename from board/spacemit/bananapi-f3/MAINTAINERS > rename to board/spacemit/k1/MAINTAINERS > index 131bad03181..bd476c32719 100644 > --- a/board/spacemit/bananapi-f3/MAINTAINERS > +++ b/board/spacemit/k1/MAINTAINERS > @@ -1,6 +1,6 @@ > BananaPi F3 > M: Huan Zhou <pericycle.cc@@gmail.com> > S: Maintained > -F: board/spacemit/bananapi-f3/ > -F: configs/bananapi-f3_defconfig > +F: board/spacemit/k1/ > +F: configs/k1_defconfig > F: doc/board/spacemit/bananapi-f3.rst > diff --git a/board/spacemit/bananapi-f3/Makefile b/board/spacemit/k1/Makefile > similarity index 100% > rename from board/spacemit/bananapi-f3/Makefile > rename to board/spacemit/k1/Makefile > diff --git a/board/spacemit/bananapi-f3/board.c b/board/spacemit/k1/board.c > similarity index 100% > rename from board/spacemit/bananapi-f3/board.c > rename to board/spacemit/k1/board.c > diff --git a/configs/bananapi-f3_defconfig b/configs/k1_defconfig > similarity index 97% > rename from configs/bananapi-f3_defconfig > rename to configs/k1_defconfig > index a726ce84775..0bdc3c800f0 100644 > --- a/configs/bananapi-f3_defconfig > +++ b/configs/k1_defconfig > @@ -6,9 +6,10 @@ CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x1000000 > CONFIG_DEFAULT_DEVICE_TREE="k1-bananapi-f3" > CONFIG_SYS_BOOTM_LEN=0xa000000 > CONFIG_SYS_LOAD_ADDR=0x200000 > -CONFIG_TARGET_BANANAPI_F3=y > CONFIG_ARCH_RV64I=y > CONFIG_RISCV_SMODE=y > +CONFIG_ARCH_K1=y > +CONFIG_TARGET_BANANAPI_F3=y > CONFIG_FIT=y > CONFIG_SUPPORT_RAW_INITRD=y > CONFIG_OF_BOARD_SETUP=y > diff --git a/include/configs/bananapi-f3.h b/include/configs/k1.h > similarity index 100% > rename from include/configs/bananapi-f3.h > rename to include/configs/k1.h ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH 01/17] spacemit: k1: support multi-board infrastructure 2026-01-23 10:27 ` Heinrich Schuchardt @ 2026-01-23 10:46 ` Heinrich Schuchardt 0 siblings, 0 replies; 37+ messages in thread From: Heinrich Schuchardt @ 2026-01-23 10:46 UTC (permalink / raw) To: Raymond Mao Cc: uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Yao Zi, Jamie Gibbons, Yu-Chien Peter Lin, Conor Dooley, Eric Schikschneit, Randolph Sheng-Kai Lin, Michal Simek, Junhui Liu, Yixun Lan, Sam Protsenko, Patrick Delaunay, Patrice Chotard, Neil Armstrong, Casey Connolly, Christian Marangi, Ian Roberts, Arturs Artamonovs, Utsav Agarwal, Nathan Barrett-Morrison, Aniket Limaye, Justin Swartz, Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Anshul Dalal, Kory Maincent, Samuel Holland, Rui Miguel Silva, Justin Klaassen, Paul Barker, Marek Vasut, Gabriel Fernandez, Jonas Karlman, Kever Yang, Joseph Chen, Heiko Stuebner, Elaine Zhang, u-boot On 1/23/26 11:27, Heinrich Schuchardt wrote: > On 1/17/26 20:01, Raymond Mao wrote: >> From: Raymond Mao <raymond.mao@riscstar.com> >> >> Restructure K1 SoC support to handle multiple boards through a single >> configuration: >> >> 1. Rename bananapi-f3_defconfig to k1_defconfig. >> 2. Move all K1 board files to k1 directory. >> >> Eliminates the need for board-specific defconfigs while maintaining >> hardware compatibility. >> >> Signed-off-by: Raymond Mao <raymond.mao@riscstar.com> >> --- >> arch/riscv/Kconfig | 10 ++++++---- >> arch/riscv/cpu/k1/Kconfig | 4 ++++ >> board/spacemit/{bananapi-f3 => k1}/Kconfig | 11 ++++++++--- >> board/spacemit/{bananapi-f3 => k1}/MAINTAINERS | 4 ++-- >> board/spacemit/{bananapi-f3 => k1}/Makefile | 0 >> board/spacemit/{bananapi-f3 => k1}/board.c | 0 >> configs/{bananapi-f3_defconfig => k1_defconfig} | 3 ++- I would suggest add the vendor name and call this spacemit_k1_defconfig to avoid ambiguity. Best regards Heinrich >> include/configs/{bananapi-f3.h => k1.h} | 0 >> 8 files changed, 22 insertions(+), 10 deletions(-) >> rename board/spacemit/{bananapi-f3 => k1}/Kconfig (63%) >> rename board/spacemit/{bananapi-f3 => k1}/MAINTAINERS (61%) >> rename board/spacemit/{bananapi-f3 => k1}/Makefile (100%) >> rename board/spacemit/{bananapi-f3 => k1}/board.c (100%) >> rename configs/{bananapi-f3_defconfig => k1_defconfig} (97%) >> rename include/configs/{bananapi-f3.h => k1.h} (100%) > > This changes in this patch look ok. > > But please, update doc/board/spacemit/bananapi-f3.rst to point to the > new defconfig. > > Best regards > > Heinrich > >> >> diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig >> index 79867656b15..ac50c1d7234 100644 >> --- a/arch/riscv/Kconfig >> +++ b/arch/riscv/Kconfig >> @@ -8,15 +8,17 @@ choice >> prompt "Target select" >> optional >> +config ARCH_K1 >> + bool "Spacemit K1 Architecture" >> + help >> + This enables support for Spacemit K1 SoC family. >> + >> config TARGET_ANDES_AE350 >> bool "Support Andes ae350" >> config TARGET_ANDES_VOYAGER >> bool "Support Andes Voyager Board" >> -config TARGET_BANANAPI_F3 >> - bool "Support BananaPi F3 Board" >> - >> config TARGET_K230_CANMV >> bool "Support K230 CanMV Board" >> @@ -115,7 +117,7 @@ source "board/sifive/unmatched/Kconfig" >> 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/k1/Kconfig" >> source "board/starfive/visionfive2/Kconfig" >> source "board/thead/th1520_lpi4a/Kconfig" >> source "board/xilinx/mbv/Kconfig" >> diff --git a/arch/riscv/cpu/k1/Kconfig b/arch/riscv/cpu/k1/Kconfig >> index 14201df80f2..4b621158334 100644 >> --- a/arch/riscv/cpu/k1/Kconfig >> +++ b/arch/riscv/cpu/k1/Kconfig >> @@ -2,6 +2,8 @@ >> # >> # Copyright (C) 2024, Kongyang Liu <seashell11234455@gmail.com> >> +if ARCH_K1 >> + >> config SPACEMIT_K1 >> bool >> select BINMAN >> @@ -17,3 +19,5 @@ config SPACEMIT_K1 >> imply SPL_CPU >> imply SPL_OPENSBI >> imply SPL_LOAD_FIT >> + >> +endif >> diff --git a/board/spacemit/bananapi-f3/Kconfig b/board/spacemit/k1/ >> Kconfig >> similarity index 63% >> rename from board/spacemit/bananapi-f3/Kconfig >> rename to board/spacemit/k1/Kconfig >> index f89fa9af2c7..9f9c806d00d 100644 >> --- a/board/spacemit/bananapi-f3/Kconfig >> +++ b/board/spacemit/k1/Kconfig >> @@ -1,7 +1,7 @@ >> -if TARGET_BANANAPI_F3 >> +if ARCH_K1 >> config SYS_BOARD >> - default "bananapi-f3" >> + default "k1" >> config SYS_VENDOR >> default "spacemit" >> @@ -10,7 +10,7 @@ config SYS_CPU >> default "k1" >> config SYS_CONFIG_NAME >> - default "bananapi-f3" >> + default "k1" >> config TEXT_BASE >> default 0x00200000 >> @@ -22,4 +22,9 @@ config BOARD_SPECIFIC_OPTIONS >> def_bool y >> select SPACEMIT_K1 >> +config TARGET_BANANAPI_F3 >> + bool "Support BananaPi F3 Board" >> + help >> + BananaPi F3 board contains Spacemit K1 SoC. >> + >> endif >> diff --git a/board/spacemit/bananapi-f3/MAINTAINERS b/board/spacemit/ >> k1/MAINTAINERS >> similarity index 61% >> rename from board/spacemit/bananapi-f3/MAINTAINERS >> rename to board/spacemit/k1/MAINTAINERS >> index 131bad03181..bd476c32719 100644 >> --- a/board/spacemit/bananapi-f3/MAINTAINERS >> +++ b/board/spacemit/k1/MAINTAINERS >> @@ -1,6 +1,6 @@ >> BananaPi F3 >> M: Huan Zhou <pericycle.cc@@gmail.com> >> S: Maintained >> -F: board/spacemit/bananapi-f3/ >> -F: configs/bananapi-f3_defconfig >> +F: board/spacemit/k1/ >> +F: configs/k1_defconfig >> F: doc/board/spacemit/bananapi-f3.rst >> diff --git a/board/spacemit/bananapi-f3/Makefile b/board/spacemit/k1/ >> Makefile >> similarity index 100% >> rename from board/spacemit/bananapi-f3/Makefile >> rename to board/spacemit/k1/Makefile >> diff --git a/board/spacemit/bananapi-f3/board.c b/board/spacemit/k1/ >> board.c >> similarity index 100% >> rename from board/spacemit/bananapi-f3/board.c >> rename to board/spacemit/k1/board.c >> diff --git a/configs/bananapi-f3_defconfig b/configs/k1_defconfig >> similarity index 97% >> rename from configs/bananapi-f3_defconfig >> rename to configs/k1_defconfig >> index a726ce84775..0bdc3c800f0 100644 >> --- a/configs/bananapi-f3_defconfig >> +++ b/configs/k1_defconfig >> @@ -6,9 +6,10 @@ CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x1000000 >> CONFIG_DEFAULT_DEVICE_TREE="k1-bananapi-f3" >> CONFIG_SYS_BOOTM_LEN=0xa000000 >> CONFIG_SYS_LOAD_ADDR=0x200000 >> -CONFIG_TARGET_BANANAPI_F3=y >> CONFIG_ARCH_RV64I=y >> CONFIG_RISCV_SMODE=y >> +CONFIG_ARCH_K1=y >> +CONFIG_TARGET_BANANAPI_F3=y >> CONFIG_FIT=y >> CONFIG_SUPPORT_RAW_INITRD=y >> CONFIG_OF_BOARD_SETUP=y >> diff --git a/include/configs/bananapi-f3.h b/include/configs/k1.h >> similarity index 100% >> rename from include/configs/bananapi-f3.h >> rename to include/configs/k1.h > ^ permalink raw reply [flat|nested] 37+ messages in thread
* [PATCH 02/17] spacemit: k1: enable SPL with debug UART 2026-01-17 19:01 [PATCH 00/17] Add board support for Spacemit K1 SoC in SPL Raymond Mao 2026-01-17 19:01 ` [PATCH 01/17] spacemit: k1: support multi-board infrastructure Raymond Mao @ 2026-01-17 19:01 ` Raymond Mao 2026-01-18 8:50 ` Yao Zi 2026-01-23 14:51 ` Heinrich Schuchardt 2026-01-17 19:01 ` [PATCH 03/17] configs: k1: enable early timer support Raymond Mao ` (16 subsequent siblings) 18 siblings, 2 replies; 37+ messages in thread From: Raymond Mao @ 2026-01-17 19:01 UTC (permalink / raw) To: u-boot Cc: uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Yao Zi, Randolph Sheng-Kai Lin, Heinrich Schuchardt, Conor Dooley, Yu-Chien Peter Lin, Jamie Gibbons, Eric Schikschneit, Michal Simek, Junhui Liu, Yixun Lan, Sam Protsenko, Patrice Chotard, Patrick Delaunay, Casey Connolly, Neil Armstrong, Christian Marangi, Aniket Limaye, Angelo Dureghello, Vasileios Bimpikas, Nathan Barrett-Morrison, Justin Swartz, Oliver Gaskell, Ian Roberts, Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Anshul Dalal, Kory Maincent, Samuel Holland, Justin Klaassen, Paul Barker, Rui Miguel Silva, Marek Vasut, Gabriel Fernandez, Kever Yang, Jonas Karlman, Heiko Stuebner, Joseph Chen, Elaine Zhang From: Raymond Mao <raymond.mao@riscstar.com> Add SPL support featuring debug UART output for early boot diagnostics on K1 SoC. Signed-off-by: Raymond Mao <raymond.mao@riscstar.com> --- arch/riscv/cpu/k1/Kconfig | 2 ++ arch/riscv/dts/Makefile | 1 + arch/riscv/dts/k1-spl.dts | 26 ++++++++++++++++++++++++++ arch/riscv/dts/k1.dtsi | 2 +- board/spacemit/k1/Makefile | 2 ++ board/spacemit/k1/spl.c | 24 ++++++++++++++++++++++++ configs/k1_defconfig | 21 ++++++++++++++++++++- include/configs/k1.h | 2 ++ 8 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 arch/riscv/dts/k1-spl.dts create mode 100644 board/spacemit/k1/spl.c diff --git a/arch/riscv/cpu/k1/Kconfig b/arch/riscv/cpu/k1/Kconfig index 4b621158334..4f7a07fd8ee 100644 --- a/arch/riscv/cpu/k1/Kconfig +++ b/arch/riscv/cpu/k1/Kconfig @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-or-later # # Copyright (C) 2024, Kongyang Liu <seashell11234455@gmail.com> +# Copyright (C) 2025-2026, RISCStar Ltd. if ARCH_K1 @@ -9,6 +10,7 @@ config SPACEMIT_K1 select BINMAN select ARCH_EARLY_INIT_R select SYS_CACHE_SHIFT_6 + select SUPPORT_SPL imply CPU imply CPU_RISCV imply RISCV_TIMER if (RISCV_SMODE || SPL_RISCV_SMODE) diff --git a/arch/riscv/dts/Makefile b/arch/riscv/dts/Makefile index 9b347fc3b50..e942ef95142 100644 --- a/arch/riscv/dts/Makefile +++ b/arch/riscv/dts/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0+ +dtb-$(CONFIG_ARCH_K1) += k1-spl.dtb dtb-$(CONFIG_TARGET_ANDES_AE350) += ae350_32.dtb ae350_64.dtb dtb-$(CONFIG_TARGET_ANDES_VOYAGER) += qilai-voyager.dtb dtb-$(CONFIG_TARGET_BANANAPI_F3) += k1-bananapi-f3.dtb diff --git a/arch/riscv/dts/k1-spl.dts b/arch/riscv/dts/k1-spl.dts new file mode 100644 index 00000000000..6018ea1e452 --- /dev/null +++ b/arch/riscv/dts/k1-spl.dts @@ -0,0 +1,26 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Copyright (C) 2023-2026 Spacemit, Inc + * Copyright (C) 2025-2026 RISCStar Ltd. + */ + +/dts-v1/; +#include "k1.dtsi" +#include "binman.dtsi" + +/ { + model = "spacemit k1 spl"; + + chosen { + stdout-path = "serial0:115200n8"; + bootph-all; + }; +}; + +&soc { + bootph-all; + serial@d4017000 { + status = "okay"; + bootph-all; + }; +}; diff --git a/arch/riscv/dts/k1.dtsi b/arch/riscv/dts/k1.dtsi index a633e43da32..9c203eb4b79 100644 --- a/arch/riscv/dts/k1.dtsi +++ b/arch/riscv/dts/k1.dtsi @@ -318,7 +318,7 @@ }; }; - soc { + soc: soc { compatible = "simple-bus"; interrupt-parent = <&plic>; #address-cells = <2>; diff --git a/board/spacemit/k1/Makefile b/board/spacemit/k1/Makefile index 2168698402b..7bce47bac8c 100644 --- a/board/spacemit/k1/Makefile +++ b/board/spacemit/k1/Makefile @@ -1,5 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-or-later # # Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com> +# Copyright (c) 2025-2026, RISCStar Ltd. obj-y := board.o +obj-$(CONFIG_SPL_BUILD) += spl.o diff --git a/board/spacemit/k1/spl.c b/board/spacemit/k1/spl.c new file mode 100644 index 00000000000..11a097389f1 --- /dev/null +++ b/board/spacemit/k1/spl.c @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2025-2026, RISCStar Ltd. + */ + +#include <spl.h> + +void board_init_f(ulong dummy) +{ + int ret; + + ret = spl_early_init(); + if (ret) + panic("spl_early_init() failed:%d\n", ret); + + riscv_cpu_setup(); + + preloader_console_init(); +} + +u32 spl_boot_device(void) +{ + return BOOT_DEVICE_NONE; +} diff --git a/configs/k1_defconfig b/configs/k1_defconfig index 0bdc3c800f0..f1a16735943 100644 --- a/configs/k1_defconfig +++ b/configs/k1_defconfig @@ -3,7 +3,19 @@ CONFIG_SYS_MALLOC_LEN=0x1000000 CONFIG_NR_DRAM_BANKS=2 CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x1000000 -CONFIG_DEFAULT_DEVICE_TREE="k1-bananapi-f3" +CONFIG_DEFAULT_DEVICE_TREE="k1-spl" +CONFIG_SPL=y +CONFIG_SPL_TEXT_BASE=0xC0801000 +CONFIG_SPL_MAX_SIZE=0x33000 +CONFIG_SPL_BSS_START_ADDR=0xC0837000 +CONFIG_SPL_BSS_MAX_SIZE=0x2000 +# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set +CONFIG_SPL_HAVE_INIT_STACK=y +CONFIG_SPL_STACK=0xC0840000 +CONFIG_SPL_SIZE_LIMIT=0x31000 +CONFIG_SPL_FIT_SIGNATURE=y +CONFIG_SPL_LOAD_FIT_ADDRESS=0x08000000 +CONFIG_STACK_SIZE=0x100000 CONFIG_SYS_BOOTM_LEN=0xa000000 CONFIG_SYS_LOAD_ADDR=0x200000 CONFIG_ARCH_RV64I=y @@ -23,3 +35,10 @@ CONFIG_PINCTRL_SINGLE=y CONFIG_RESET_SPACEMIT_K1=y CONFIG_SYS_NS16550=y CONFIG_SYS_NS16550_MEM32=y +CONFIG_DEBUG_UART=y +CONFIG_DEBUG_UART_BASE=0xD4017000 +CONFIG_DEBUG_UART_CLOCK=14700000 +CONFIG_DEBUG_UART_SHIFT=2 +CONFIG_DEBUG_UART_NS16550=y +CONFIG_DEBUG_UART_ANNOUNCE=y +# CONFIG_DEBUG_SBI_CONSOLE is not set diff --git a/include/configs/k1.h b/include/configs/k1.h index 97cf4d72df0..6a26fdfcebe 100644 --- a/include/configs/k1.h +++ b/include/configs/k1.h @@ -7,6 +7,8 @@ #ifndef __CONFIG_H #define __CONFIG_H +#define CFG_SYS_NS16550_CLK 14700000 + #define CFG_SYS_SDRAM_BASE 0x0 #define CFG_SYS_NS16550_IER 0x40 /* UART Unit Enable */ -- 2.25.1 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [PATCH 02/17] spacemit: k1: enable SPL with debug UART 2026-01-17 19:01 ` [PATCH 02/17] spacemit: k1: enable SPL with debug UART Raymond Mao @ 2026-01-18 8:50 ` Yao Zi 2026-01-23 14:51 ` Heinrich Schuchardt 1 sibling, 0 replies; 37+ messages in thread From: Yao Zi @ 2026-01-18 8:50 UTC (permalink / raw) To: Raymond Mao, u-boot Cc: uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Randolph Sheng-Kai Lin, Heinrich Schuchardt, Conor Dooley, Yu-Chien Peter Lin, Jamie Gibbons, Eric Schikschneit, Michal Simek, Junhui Liu, Yixun Lan, Sam Protsenko, Patrice Chotard, Patrick Delaunay, Casey Connolly, Neil Armstrong, Christian Marangi, Aniket Limaye, Angelo Dureghello, Vasileios Bimpikas, Nathan Barrett-Morrison, Justin Swartz, Oliver Gaskell, Ian Roberts, Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Anshul Dalal, Kory Maincent, Samuel Holland, Justin Klaassen, Paul Barker, Rui Miguel Silva, Marek Vasut, Gabriel Fernandez, Kever Yang, Jonas Karlman, Heiko Stuebner, Joseph Chen, Elaine Zhang On Sat, Jan 17, 2026 at 02:01:36PM -0500, Raymond Mao wrote: > From: Raymond Mao <raymond.mao@riscstar.com> > > Add SPL support featuring debug UART output for early boot > diagnostics on K1 SoC. > > Signed-off-by: Raymond Mao <raymond.mao@riscstar.com> > --- > arch/riscv/cpu/k1/Kconfig | 2 ++ > arch/riscv/dts/Makefile | 1 + > arch/riscv/dts/k1-spl.dts | 26 ++++++++++++++++++++++++++ > arch/riscv/dts/k1.dtsi | 2 +- > board/spacemit/k1/Makefile | 2 ++ > board/spacemit/k1/spl.c | 24 ++++++++++++++++++++++++ > configs/k1_defconfig | 21 ++++++++++++++++++++- > include/configs/k1.h | 2 ++ > 8 files changed, 78 insertions(+), 2 deletions(-) > create mode 100644 arch/riscv/dts/k1-spl.dts > create mode 100644 board/spacemit/k1/spl.c ... > diff --git a/configs/k1_defconfig b/configs/k1_defconfig > index 0bdc3c800f0..f1a16735943 100644 > --- a/configs/k1_defconfig > +++ b/configs/k1_defconfig > @@ -3,7 +3,19 @@ CONFIG_SYS_MALLOC_LEN=0x1000000 > CONFIG_NR_DRAM_BANKS=2 > CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y > CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x1000000 > -CONFIG_DEFAULT_DEVICE_TREE="k1-bananapi-f3" > +CONFIG_DEFAULT_DEVICE_TREE="k1-spl" > +CONFIG_SPL=y > +CONFIG_SPL_TEXT_BASE=0xC0801000 Please be consistent about cases in hex. Rest of the file uses lowercases, and I think it's better to align. > +CONFIG_SPL_MAX_SIZE=0x33000 > +CONFIG_SPL_BSS_START_ADDR=0xC0837000 > +CONFIG_SPL_BSS_MAX_SIZE=0x2000 > +# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set > +CONFIG_SPL_HAVE_INIT_STACK=y > +CONFIG_SPL_STACK=0xC0840000 > +CONFIG_SPL_SIZE_LIMIT=0x31000 > +CONFIG_SPL_FIT_SIGNATURE=y > +CONFIG_SPL_LOAD_FIT_ADDRESS=0x08000000 > +CONFIG_STACK_SIZE=0x100000 > CONFIG_SYS_BOOTM_LEN=0xa000000 > CONFIG_SYS_LOAD_ADDR=0x200000 > CONFIG_ARCH_RV64I=y > @@ -23,3 +35,10 @@ CONFIG_PINCTRL_SINGLE=y > CONFIG_RESET_SPACEMIT_K1=y > CONFIG_SYS_NS16550=y > CONFIG_SYS_NS16550_MEM32=y > +CONFIG_DEBUG_UART=y > +CONFIG_DEBUG_UART_BASE=0xD4017000 > +CONFIG_DEBUG_UART_CLOCK=14700000 > +CONFIG_DEBUG_UART_SHIFT=2 > +CONFIG_DEBUG_UART_NS16550=y > +CONFIG_DEBUG_UART_ANNOUNCE=y Regards, Yao Zi ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH 02/17] spacemit: k1: enable SPL with debug UART 2026-01-17 19:01 ` [PATCH 02/17] spacemit: k1: enable SPL with debug UART Raymond Mao 2026-01-18 8:50 ` Yao Zi @ 2026-01-23 14:51 ` Heinrich Schuchardt 2026-02-03 14:24 ` Raymond Mao 1 sibling, 1 reply; 37+ messages in thread From: Heinrich Schuchardt @ 2026-01-23 14:51 UTC (permalink / raw) To: Raymond Mao Cc: uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Yao Zi, Randolph Sheng-Kai Lin, Conor Dooley, Yu-Chien Peter Lin, Jamie Gibbons, Eric Schikschneit, Michal Simek, Junhui Liu, Yixun Lan, Sam Protsenko, Patrice Chotard, Patrick Delaunay, Casey Connolly, Neil Armstrong, Christian Marangi, Aniket Limaye, Angelo Dureghello, Vasileios Bimpikas, Nathan Barrett-Morrison, Justin Swartz, Oliver Gaskell, Ian Roberts, Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Anshul Dalal, Kory Maincent, Samuel Holland, Justin Klaassen, Paul Barker, Rui Miguel Silva, Marek Vasut, Gabriel Fernandez, Kever Yang, Jonas Karlman, Heiko Stuebner, Joseph Chen, Elaine Zhang, u-boot On 1/17/26 20:01, Raymond Mao wrote: > From: Raymond Mao <raymond.mao@riscstar.com> > > Add SPL support featuring debug UART output for early boot > diagnostics on K1 SoC. Please, describe how to install the SPL binary to make this patch testable. > > Signed-off-by: Raymond Mao <raymond.mao@riscstar.com> > --- > arch/riscv/cpu/k1/Kconfig | 2 ++ > arch/riscv/dts/Makefile | 1 + > arch/riscv/dts/k1-spl.dts | 26 ++++++++++++++++++++++++++ > arch/riscv/dts/k1.dtsi | 2 +- > board/spacemit/k1/Makefile | 2 ++ > board/spacemit/k1/spl.c | 24 ++++++++++++++++++++++++ > configs/k1_defconfig | 21 ++++++++++++++++++++- > include/configs/k1.h | 2 ++ > 8 files changed, 78 insertions(+), 2 deletions(-) > create mode 100644 arch/riscv/dts/k1-spl.dts > create mode 100644 board/spacemit/k1/spl.c > > diff --git a/arch/riscv/cpu/k1/Kconfig b/arch/riscv/cpu/k1/Kconfig > index 4b621158334..4f7a07fd8ee 100644 > --- a/arch/riscv/cpu/k1/Kconfig > +++ b/arch/riscv/cpu/k1/Kconfig > @@ -1,6 +1,7 @@ > # SPDX-License-Identifier: GPL-2.0-or-later > # > # Copyright (C) 2024, Kongyang Liu <seashell11234455@gmail.com> > +# Copyright (C) 2025-2026, RISCStar Ltd. > > if ARCH_K1 > > @@ -9,6 +10,7 @@ config SPACEMIT_K1 > select BINMAN > select ARCH_EARLY_INIT_R > select SYS_CACHE_SHIFT_6 > + select SUPPORT_SPL > imply CPU > imply CPU_RISCV > imply RISCV_TIMER if (RISCV_SMODE || SPL_RISCV_SMODE) > diff --git a/arch/riscv/dts/Makefile b/arch/riscv/dts/Makefile > index 9b347fc3b50..e942ef95142 100644 > --- a/arch/riscv/dts/Makefile > +++ b/arch/riscv/dts/Makefile > @@ -1,5 +1,6 @@ > # SPDX-License-Identifier: GPL-2.0+ > > +dtb-$(CONFIG_ARCH_K1) += k1-spl.dtb > dtb-$(CONFIG_TARGET_ANDES_AE350) += ae350_32.dtb ae350_64.dtb > dtb-$(CONFIG_TARGET_ANDES_VOYAGER) += qilai-voyager.dtb > dtb-$(CONFIG_TARGET_BANANAPI_F3) += k1-bananapi-f3.dtb > diff --git a/arch/riscv/dts/k1-spl.dts b/arch/riscv/dts/k1-spl.dts > new file mode 100644 > index 00000000000..6018ea1e452 > --- /dev/null > +++ b/arch/riscv/dts/k1-spl.dts Why do you introduce this file? Can't we use dts/upstream/src/riscv/spacemit/k1-bananapi-f3.dts > @@ -0,0 +1,26 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT > +/* > + * Copyright (C) 2023-2026 Spacemit, Inc > + * Copyright (C) 2025-2026 RISCStar Ltd. > + */ > + > +/dts-v1/; > +#include "k1.dtsi" > +#include "binman.dtsi" > + > +/ { > + model = "spacemit k1 spl"; > + > + chosen { > + stdout-path = "serial0:115200n8"; > + bootph-all; The target should be to inherit bootph-all from the Linux kernel tree. Until you you have this upstream you could add the bootph-all properties to arch/riscv/dts/k1-bananapi-f3-u-boot.dtsi Best regards Heinrich > + }; > +}; > + > +&soc { > + bootph-all; > + serial@d4017000 { > + status = "okay"; > + bootph-all; > + }; > +}; > diff --git a/arch/riscv/dts/k1.dtsi b/arch/riscv/dts/k1.dtsi > index a633e43da32..9c203eb4b79 100644 > --- a/arch/riscv/dts/k1.dtsi > +++ b/arch/riscv/dts/k1.dtsi > @@ -318,7 +318,7 @@ > }; > }; > > - soc { > + soc: soc { > compatible = "simple-bus"; > interrupt-parent = <&plic>; > #address-cells = <2>; > diff --git a/board/spacemit/k1/Makefile b/board/spacemit/k1/Makefile > index 2168698402b..7bce47bac8c 100644 > --- a/board/spacemit/k1/Makefile > +++ b/board/spacemit/k1/Makefile > @@ -1,5 +1,7 @@ > # SPDX-License-Identifier: GPL-2.0-or-later > # > # Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com> > +# Copyright (c) 2025-2026, RISCStar Ltd. > > obj-y := board.o > +obj-$(CONFIG_SPL_BUILD) += spl.o > diff --git a/board/spacemit/k1/spl.c b/board/spacemit/k1/spl.c > new file mode 100644 > index 00000000000..11a097389f1 > --- /dev/null > +++ b/board/spacemit/k1/spl.c > @@ -0,0 +1,24 @@ > +// SPDX-License-Identifier: GPL-2.0-or-later > +/* > + * Copyright (c) 2025-2026, RISCStar Ltd. > + */ > + > +#include <spl.h> > + > +void board_init_f(ulong dummy) > +{ > + int ret; > + > + ret = spl_early_init(); > + if (ret) > + panic("spl_early_init() failed:%d\n", ret); > + > + riscv_cpu_setup(); > + > + preloader_console_init(); > +} > + > +u32 spl_boot_device(void) > +{ > + return BOOT_DEVICE_NONE; > +} > diff --git a/configs/k1_defconfig b/configs/k1_defconfig > index 0bdc3c800f0..f1a16735943 100644 > --- a/configs/k1_defconfig > +++ b/configs/k1_defconfig > @@ -3,7 +3,19 @@ CONFIG_SYS_MALLOC_LEN=0x1000000 > CONFIG_NR_DRAM_BANKS=2 > CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y > CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x1000000 > -CONFIG_DEFAULT_DEVICE_TREE="k1-bananapi-f3" > +CONFIG_DEFAULT_DEVICE_TREE="k1-spl" > +CONFIG_SPL=y > +CONFIG_SPL_TEXT_BASE=0xC0801000 > +CONFIG_SPL_MAX_SIZE=0x33000 > +CONFIG_SPL_BSS_START_ADDR=0xC0837000 > +CONFIG_SPL_BSS_MAX_SIZE=0x2000 > +# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set > +CONFIG_SPL_HAVE_INIT_STACK=y > +CONFIG_SPL_STACK=0xC0840000 > +CONFIG_SPL_SIZE_LIMIT=0x31000 > +CONFIG_SPL_FIT_SIGNATURE=y > +CONFIG_SPL_LOAD_FIT_ADDRESS=0x08000000 > +CONFIG_STACK_SIZE=0x100000 > CONFIG_SYS_BOOTM_LEN=0xa000000 > CONFIG_SYS_LOAD_ADDR=0x200000 > CONFIG_ARCH_RV64I=y > @@ -23,3 +35,10 @@ CONFIG_PINCTRL_SINGLE=y > CONFIG_RESET_SPACEMIT_K1=y > CONFIG_SYS_NS16550=y > CONFIG_SYS_NS16550_MEM32=y > +CONFIG_DEBUG_UART=y > +CONFIG_DEBUG_UART_BASE=0xD4017000 > +CONFIG_DEBUG_UART_CLOCK=14700000 > +CONFIG_DEBUG_UART_SHIFT=2 > +CONFIG_DEBUG_UART_NS16550=y > +CONFIG_DEBUG_UART_ANNOUNCE=y > +# CONFIG_DEBUG_SBI_CONSOLE is not set > diff --git a/include/configs/k1.h b/include/configs/k1.h > index 97cf4d72df0..6a26fdfcebe 100644 > --- a/include/configs/k1.h > +++ b/include/configs/k1.h > @@ -7,6 +7,8 @@ > #ifndef __CONFIG_H > #define __CONFIG_H > > +#define CFG_SYS_NS16550_CLK 14700000 > + > #define CFG_SYS_SDRAM_BASE 0x0 > #define CFG_SYS_NS16550_IER 0x40 /* UART Unit Enable */ > ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH 02/17] spacemit: k1: enable SPL with debug UART 2026-01-23 14:51 ` Heinrich Schuchardt @ 2026-02-03 14:24 ` Raymond Mao 0 siblings, 0 replies; 37+ messages in thread From: Raymond Mao @ 2026-02-03 14:24 UTC (permalink / raw) To: Heinrich Schuchardt Cc: uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Yao Zi, Randolph Sheng-Kai Lin, Conor Dooley, Yu-Chien Peter Lin, Jamie Gibbons, Eric Schikschneit, Michal Simek, Junhui Liu, Yixun Lan, Sam Protsenko, Patrice Chotard, Patrick Delaunay, Casey Connolly, Neil Armstrong, Christian Marangi, Aniket Limaye, Angelo Dureghello, Vasileios Bimpikas, Nathan Barrett-Morrison, Justin Swartz, Oliver Gaskell, Ian Roberts, Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Anshul Dalal, Kory Maincent, Samuel Holland, Justin Klaassen, Paul Barker, Rui Miguel Silva, Marek Vasut, Gabriel Fernandez, Kever Yang, Jonas Karlman, Heiko Stuebner, Joseph Chen, Elaine Zhang, u-boot Hi Heinrich, On Fri, Jan 23, 2026 at 9:52 AM Heinrich Schuchardt <xypron.glpk@gmx.de> wrote: > > On 1/17/26 20:01, Raymond Mao wrote: > > From: Raymond Mao <raymond.mao@riscstar.com> > > > > Add SPL support featuring debug UART output for early boot > > diagnostics on K1 SoC. > > Please, describe how to install the SPL binary to make this patch testable. > Currently it only supports testing via USB download through fastboot, not an installable image in flash. Regards, Raymond > > > > Signed-off-by: Raymond Mao <raymond.mao@riscstar.com> > > --- > > arch/riscv/cpu/k1/Kconfig | 2 ++ > > arch/riscv/dts/Makefile | 1 + > > arch/riscv/dts/k1-spl.dts | 26 ++++++++++++++++++++++++++ > > arch/riscv/dts/k1.dtsi | 2 +- > > board/spacemit/k1/Makefile | 2 ++ > > board/spacemit/k1/spl.c | 24 ++++++++++++++++++++++++ > > configs/k1_defconfig | 21 ++++++++++++++++++++- > > include/configs/k1.h | 2 ++ > > 8 files changed, 78 insertions(+), 2 deletions(-) > > create mode 100644 arch/riscv/dts/k1-spl.dts > > create mode 100644 board/spacemit/k1/spl.c > > > > diff --git a/arch/riscv/cpu/k1/Kconfig b/arch/riscv/cpu/k1/Kconfig > > index 4b621158334..4f7a07fd8ee 100644 > > --- a/arch/riscv/cpu/k1/Kconfig > > +++ b/arch/riscv/cpu/k1/Kconfig > > @@ -1,6 +1,7 @@ > > # SPDX-License-Identifier: GPL-2.0-or-later > > # > > # Copyright (C) 2024, Kongyang Liu <seashell11234455@gmail.com> > > +# Copyright (C) 2025-2026, RISCStar Ltd. > > > > if ARCH_K1 > > > > @@ -9,6 +10,7 @@ config SPACEMIT_K1 > > select BINMAN > > select ARCH_EARLY_INIT_R > > select SYS_CACHE_SHIFT_6 > > + select SUPPORT_SPL > > imply CPU > > imply CPU_RISCV > > imply RISCV_TIMER if (RISCV_SMODE || SPL_RISCV_SMODE) > > diff --git a/arch/riscv/dts/Makefile b/arch/riscv/dts/Makefile > > index 9b347fc3b50..e942ef95142 100644 > > --- a/arch/riscv/dts/Makefile > > +++ b/arch/riscv/dts/Makefile > > @@ -1,5 +1,6 @@ > > # SPDX-License-Identifier: GPL-2.0+ > > > > +dtb-$(CONFIG_ARCH_K1) += k1-spl.dtb > > dtb-$(CONFIG_TARGET_ANDES_AE350) += ae350_32.dtb ae350_64.dtb > > dtb-$(CONFIG_TARGET_ANDES_VOYAGER) += qilai-voyager.dtb > > dtb-$(CONFIG_TARGET_BANANAPI_F3) += k1-bananapi-f3.dtb > > diff --git a/arch/riscv/dts/k1-spl.dts b/arch/riscv/dts/k1-spl.dts > > new file mode 100644 > > index 00000000000..6018ea1e452 > > --- /dev/null > > +++ b/arch/riscv/dts/k1-spl.dts > > Why do you introduce this file? > Can't we use dts/upstream/src/riscv/spacemit/k1-bananapi-f3.dts > > > @@ -0,0 +1,26 @@ > > +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT > > +/* > > + * Copyright (C) 2023-2026 Spacemit, Inc > > + * Copyright (C) 2025-2026 RISCStar Ltd. > > + */ > > + > > +/dts-v1/; > > +#include "k1.dtsi" > > +#include "binman.dtsi" > > + > > +/ { > > + model = "spacemit k1 spl"; > > + > > + chosen { > > + stdout-path = "serial0:115200n8"; > > + bootph-all; > > The target should be to inherit bootph-all from the Linux kernel tree. > > Until you you have this upstream you could add the bootph-all properties > to arch/riscv/dts/k1-bananapi-f3-u-boot.dtsi > > Best regards > > Heinrich > > > + }; > > +}; > > + > > +&soc { > > + bootph-all; > > + serial@d4017000 { > > + status = "okay"; > > + bootph-all; > > + }; > > +}; > > diff --git a/arch/riscv/dts/k1.dtsi b/arch/riscv/dts/k1.dtsi > > index a633e43da32..9c203eb4b79 100644 > > --- a/arch/riscv/dts/k1.dtsi > > +++ b/arch/riscv/dts/k1.dtsi > > @@ -318,7 +318,7 @@ > > }; > > }; > > > > - soc { > > + soc: soc { > > compatible = "simple-bus"; > > interrupt-parent = <&plic>; > > #address-cells = <2>; > > diff --git a/board/spacemit/k1/Makefile b/board/spacemit/k1/Makefile > > index 2168698402b..7bce47bac8c 100644 > > --- a/board/spacemit/k1/Makefile > > +++ b/board/spacemit/k1/Makefile > > @@ -1,5 +1,7 @@ > > # SPDX-License-Identifier: GPL-2.0-or-later > > # > > # Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com> > > +# Copyright (c) 2025-2026, RISCStar Ltd. > > > > obj-y := board.o > > +obj-$(CONFIG_SPL_BUILD) += spl.o > > diff --git a/board/spacemit/k1/spl.c b/board/spacemit/k1/spl.c > > new file mode 100644 > > index 00000000000..11a097389f1 > > --- /dev/null > > +++ b/board/spacemit/k1/spl.c > > @@ -0,0 +1,24 @@ > > +// SPDX-License-Identifier: GPL-2.0-or-later > > +/* > > + * Copyright (c) 2025-2026, RISCStar Ltd. > > + */ > > + > > +#include <spl.h> > > + > > +void board_init_f(ulong dummy) > > +{ > > + int ret; > > + > > + ret = spl_early_init(); > > + if (ret) > > + panic("spl_early_init() failed:%d\n", ret); > > + > > + riscv_cpu_setup(); > > + > > + preloader_console_init(); > > +} > > + > > +u32 spl_boot_device(void) > > +{ > > + return BOOT_DEVICE_NONE; > > +} > > diff --git a/configs/k1_defconfig b/configs/k1_defconfig > > index 0bdc3c800f0..f1a16735943 100644 > > --- a/configs/k1_defconfig > > +++ b/configs/k1_defconfig > > @@ -3,7 +3,19 @@ CONFIG_SYS_MALLOC_LEN=0x1000000 > > CONFIG_NR_DRAM_BANKS=2 > > CONFIG_HAS_CUSTOM_SYS_INIT_SP_ADDR=y > > CONFIG_CUSTOM_SYS_INIT_SP_ADDR=0x1000000 > > -CONFIG_DEFAULT_DEVICE_TREE="k1-bananapi-f3" > > +CONFIG_DEFAULT_DEVICE_TREE="k1-spl" > > +CONFIG_SPL=y > > +CONFIG_SPL_TEXT_BASE=0xC0801000 > > +CONFIG_SPL_MAX_SIZE=0x33000 > > +CONFIG_SPL_BSS_START_ADDR=0xC0837000 > > +CONFIG_SPL_BSS_MAX_SIZE=0x2000 > > +# CONFIG_SPL_SHARES_INIT_SP_ADDR is not set > > +CONFIG_SPL_HAVE_INIT_STACK=y > > +CONFIG_SPL_STACK=0xC0840000 > > +CONFIG_SPL_SIZE_LIMIT=0x31000 > > +CONFIG_SPL_FIT_SIGNATURE=y > > +CONFIG_SPL_LOAD_FIT_ADDRESS=0x08000000 > > +CONFIG_STACK_SIZE=0x100000 > > CONFIG_SYS_BOOTM_LEN=0xa000000 > > CONFIG_SYS_LOAD_ADDR=0x200000 > > CONFIG_ARCH_RV64I=y > > @@ -23,3 +35,10 @@ CONFIG_PINCTRL_SINGLE=y > > CONFIG_RESET_SPACEMIT_K1=y > > CONFIG_SYS_NS16550=y > > CONFIG_SYS_NS16550_MEM32=y > > +CONFIG_DEBUG_UART=y > > +CONFIG_DEBUG_UART_BASE=0xD4017000 > > +CONFIG_DEBUG_UART_CLOCK=14700000 > > +CONFIG_DEBUG_UART_SHIFT=2 > > +CONFIG_DEBUG_UART_NS16550=y > > +CONFIG_DEBUG_UART_ANNOUNCE=y > > +# CONFIG_DEBUG_SBI_CONSOLE is not set > > diff --git a/include/configs/k1.h b/include/configs/k1.h > > index 97cf4d72df0..6a26fdfcebe 100644 > > --- a/include/configs/k1.h > > +++ b/include/configs/k1.h > > @@ -7,6 +7,8 @@ > > #ifndef __CONFIG_H > > #define __CONFIG_H > > > > +#define CFG_SYS_NS16550_CLK 14700000 > > + > > #define CFG_SYS_SDRAM_BASE 0x0 > > #define CFG_SYS_NS16550_IER 0x40 /* UART Unit Enable */ > > > ^ permalink raw reply [flat|nested] 37+ messages in thread
* [PATCH 03/17] configs: k1: enable early timer support 2026-01-17 19:01 [PATCH 00/17] Add board support for Spacemit K1 SoC in SPL Raymond Mao 2026-01-17 19:01 ` [PATCH 01/17] spacemit: k1: support multi-board infrastructure Raymond Mao 2026-01-17 19:01 ` [PATCH 02/17] spacemit: k1: enable SPL with debug UART Raymond Mao @ 2026-01-17 19:01 ` Raymond Mao 2026-01-17 19:01 ` [PATCH 04/17] reset: k1: add SPL support and enable TWSI8 reset Raymond Mao ` (15 subsequent siblings) 18 siblings, 0 replies; 37+ messages in thread From: Raymond Mao @ 2026-01-17 19:01 UTC (permalink / raw) To: u-boot Cc: uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Yao Zi, Yu-Chien Peter Lin, Randolph Sheng-Kai Lin, Conor Dooley, Jamie Gibbons, Michal Simek, Eric Schikschneit, Junhui Liu, Yixun Lan, Sam Protsenko, Patrick Delaunay, Patrice Chotard, Casey Connolly, Ilias Apalodimas, Christian Marangi, Angelo Dureghello, Arturs Artamonovs, Utsav Agarwal, Aniket Limaye, Nathan Barrett-Morrison, Justin Swartz, Greg Malysa, Vasileios Bimpikas, Oliver Gaskell, Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Kory Maincent, Anshul Dalal, Justin Klaassen, Samuel Holland, Paul Barker, Rui Miguel Silva, Marek Vasut, Andre Przywara, Gabriel Fernandez, Kever Yang, Jonas Karlman, Elaine Zhang, Joseph Chen From: Raymond Mao <raymond.mao@riscstar.com> Enable CONFIG_TIMER_EARLY to allow udelay() calls during early initialization phases. This is required for proper timing operations before the full timer driver is available. Signed-off-by: Raymond Mao <raymond.mao@riscstar.com> --- configs/k1_defconfig | 2 ++ include/configs/k1.h | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/configs/k1_defconfig b/configs/k1_defconfig index f1a16735943..ca9c1d0bd8d 100644 --- a/configs/k1_defconfig +++ b/configs/k1_defconfig @@ -20,6 +20,7 @@ CONFIG_SYS_BOOTM_LEN=0xa000000 CONFIG_SYS_LOAD_ADDR=0x200000 CONFIG_ARCH_RV64I=y CONFIG_RISCV_SMODE=y +CONFIG_SPL_RISCV_SMODE=y CONFIG_ARCH_K1=y CONFIG_TARGET_BANANAPI_F3=y CONFIG_FIT=y @@ -42,3 +43,4 @@ CONFIG_DEBUG_UART_SHIFT=2 CONFIG_DEBUG_UART_NS16550=y CONFIG_DEBUG_UART_ANNOUNCE=y # CONFIG_DEBUG_SBI_CONSOLE is not set +CONFIG_TIMER_EARLY=y diff --git a/include/configs/k1.h b/include/configs/k1.h index 6a26fdfcebe..d46fec8b251 100644 --- a/include/configs/k1.h +++ b/include/configs/k1.h @@ -1,6 +1,7 @@ /* SPDX-License-Identifier: GPL-2.0-or-later */ /* * Copyright (c) 2024, Kongyang Liu <seashell11234455@gmail.com> + * Copyright (c) 2025-2026, RISCStar Ltd. * */ @@ -12,4 +13,7 @@ #define CFG_SYS_SDRAM_BASE 0x0 #define CFG_SYS_NS16550_IER 0x40 /* UART Unit Enable */ +#define RISCV_MMODE_TIMER_FREQ 24000000 +#define RISCV_SMODE_TIMER_FREQ 24000000 + #endif /* __CONFIG_H */ -- 2.25.1 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 04/17] reset: k1: add SPL support and enable TWSI8 reset 2026-01-17 19:01 [PATCH 00/17] Add board support for Spacemit K1 SoC in SPL Raymond Mao ` (2 preceding siblings ...) 2026-01-17 19:01 ` [PATCH 03/17] configs: k1: enable early timer support Raymond Mao @ 2026-01-17 19:01 ` Raymond Mao 2026-01-18 9:10 ` Yao Zi 2026-01-17 19:01 ` [PATCH 05/17] dt-bindings: clock: import k1-syscon from upstream Raymond Mao ` (14 subsequent siblings) 18 siblings, 1 reply; 37+ messages in thread From: Raymond Mao @ 2026-01-17 19:01 UTC (permalink / raw) To: u-boot Cc: uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Yao Zi, Randolph Sheng-Kai Lin, Yu-Chien Peter Lin, Heinrich Schuchardt, Conor Dooley, Jamie Gibbons, Michal Simek, Eric Schikschneit, Yixun Lan, Junhui Liu, Sam Protsenko, Patrick Delaunay, Patrice Chotard, Neil Armstrong, Casey Connolly, Ilias Apalodimas, Christian Marangi, Aniket Limaye, Utsav Agarwal, Greg Malysa, Justin Swartz, Nathan Barrett-Morrison, Vasileios Bimpikas, Arturs Artamonovs, Ian Roberts, Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Kory Maincent, Paul Barker, Justin Klaassen, Rui Miguel Silva, Marek Vasut, Samuel Holland, Gabriel Fernandez, Kever Yang, Jonas Karlman, Elaine Zhang, Joseph Chen From: Raymond Mao <raymond.mao@riscstar.com> This commit enhances the K1 reset controller driver: 1. Enable SPL support - Select CONFIG_SPL_RESET_SPACEMIT_K1 for SPL builds - Reset controller is required during early boot for proper hardware initialization sequence 2. Remove TWSI8 (I2C8) reset restriction - TWSI8 is now fully controllable by reset controller Signed-off-by: Raymond Mao <raymond.mao@riscstar.com> --- drivers/reset/Kconfig | 7 +++++++ drivers/reset/Makefile | 2 +- drivers/reset/reset-spacemit-k1.c | 4 ---- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/drivers/reset/Kconfig b/drivers/reset/Kconfig index 74c267dfc4e..1e69024ce74 100644 --- a/drivers/reset/Kconfig +++ b/drivers/reset/Kconfig @@ -252,5 +252,12 @@ config RESET_SPACEMIT_K1 Support for SPACEMIT's K1 Reset system. Basic Assert/Deassert is supported. +config SPL_RESET_SPACEMIT_K1 + bool "SPL Reset driver for Spacemit K1 SoC" + depends on SPL && RESET_SPACEMIT_K1 + default y + help + Support for reset controller on Spacemit K1 SoCs in SPL. + source "drivers/reset/stm32/Kconfig" endmenu diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index ee5b009d134..ec6893b1c45 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile @@ -33,8 +33,8 @@ obj-$(CONFIG_RESET_ZYNQMP) += reset-zynqmp.o obj-$(CONFIG_RESET_DRA7) += reset-dra7.o obj-$(CONFIG_RESET_AT91) += reset-at91.o obj-$(CONFIG_$(PHASE_)RESET_JH7110) += reset-jh7110.o +obj-$(CONFIG_$(PHASE_)RESET_SPACEMIT_K1) += reset-spacemit-k1.o obj-$(CONFIG_RESET_RZG2L_USBPHY_CTRL) += reset-rzg2l-usbphy-ctrl.o -obj-$(CONFIG_RESET_SPACEMIT_K1) += reset-spacemit-k1.o obj-$(CONFIG_ARCH_STM32) += stm32/ obj-$(CONFIG_ARCH_STM32MP) += stm32/ diff --git a/drivers/reset/reset-spacemit-k1.c b/drivers/reset/reset-spacemit-k1.c index 613e002fc4f..99dce90b4c4 100644 --- a/drivers/reset/reset-spacemit-k1.c +++ b/drivers/reset/reset-spacemit-k1.c @@ -452,10 +452,6 @@ static int spacemit_reset_update(struct reset_ctl *rst, bool assert) if (rst->id < RESET_UART1 || rst->id >= RESET_NUMBER) return 0; - /* can not write to twsi8 */ - if (rst->id == RESET_TWSI8) - return 0; - spacemit_reset_set(rst, rst->id, assert); return 0; } -- 2.25.1 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [PATCH 04/17] reset: k1: add SPL support and enable TWSI8 reset 2026-01-17 19:01 ` [PATCH 04/17] reset: k1: add SPL support and enable TWSI8 reset Raymond Mao @ 2026-01-18 9:10 ` Yao Zi 2026-01-21 23:17 ` Raymond Mao 0 siblings, 1 reply; 37+ messages in thread From: Yao Zi @ 2026-01-18 9:10 UTC (permalink / raw) To: Raymond Mao, u-boot Cc: uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Randolph Sheng-Kai Lin, Yu-Chien Peter Lin, Heinrich Schuchardt, Conor Dooley, Jamie Gibbons, Michal Simek, Eric Schikschneit, Yixun Lan, Junhui Liu, Sam Protsenko, Patrick Delaunay, Patrice Chotard, Neil Armstrong, Casey Connolly, Ilias Apalodimas, Christian Marangi, Aniket Limaye, Utsav Agarwal, Greg Malysa, Justin Swartz, Nathan Barrett-Morrison, Vasileios Bimpikas, Arturs Artamonovs, Ian Roberts, Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Kory Maincent, Paul Barker, Justin Klaassen, Rui Miguel Silva, Marek Vasut, Samuel Holland, Gabriel Fernandez, Kever Yang, Jonas Karlman, Elaine Zhang, Joseph Chen On Sat, Jan 17, 2026 at 02:01:38PM -0500, Raymond Mao wrote: > From: Raymond Mao <raymond.mao@riscstar.com> > > This commit enhances the K1 reset controller driver: > > 1. Enable SPL support > - Select CONFIG_SPL_RESET_SPACEMIT_K1 for SPL builds > - Reset controller is required during early boot for > proper hardware initialization sequence > > 2. Remove TWSI8 (I2C8) reset restriction > - TWSI8 is now fully controllable by reset controller I don't think you change any real logics in the driver, so what fixes the function of TWSI8 reset? This deserves more explanation. > Signed-off-by: Raymond Mao <raymond.mao@riscstar.com> > --- > drivers/reset/Kconfig | 7 +++++++ > drivers/reset/Makefile | 2 +- > drivers/reset/reset-spacemit-k1.c | 4 ---- > 3 files changed, 8 insertions(+), 5 deletions(-) Regards, Yao Zi ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH 04/17] reset: k1: add SPL support and enable TWSI8 reset 2026-01-18 9:10 ` Yao Zi @ 2026-01-21 23:17 ` Raymond Mao 0 siblings, 0 replies; 37+ messages in thread From: Raymond Mao @ 2026-01-21 23:17 UTC (permalink / raw) To: Yao Zi Cc: u-boot, uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Randolph Sheng-Kai Lin, Yu-Chien Peter Lin, Heinrich Schuchardt, Conor Dooley, Jamie Gibbons, Michal Simek, Eric Schikschneit, Yixun Lan, Junhui Liu, Sam Protsenko, Patrick Delaunay, Patrice Chotard, Neil Armstrong, Casey Connolly, Ilias Apalodimas, Christian Marangi, Aniket Limaye, Utsav Agarwal, Greg Malysa, Justin Swartz, Nathan Barrett-Morrison, Vasileios Bimpikas, Arturs Artamonovs, Ian Roberts, Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Kory Maincent, Paul Barker, Justin Klaassen, Rui Miguel Silva, Marek Vasut, Samuel Holland, Gabriel Fernandez, Kever Yang, Jonas Karlman, Elaine Zhang, Joseph Chen Hi Yao Zi On Sun, Jan 18, 2026 at 4:12 AM Yao Zi <me@ziyao.cc> wrote: > On Sat, Jan 17, 2026 at 02:01:38PM -0500, Raymond Mao wrote: > > From: Raymond Mao <raymond.mao@riscstar.com> > > > > This commit enhances the K1 reset controller driver: > > > > 1. Enable SPL support > > - Select CONFIG_SPL_RESET_SPACEMIT_K1 for SPL builds > > - Reset controller is required during early boot for > > proper hardware initialization sequence > > > > 2. Remove TWSI8 (I2C8) reset restriction > > - TWSI8 is now fully controllable by reset controller > > I don't think you change any real logics in the driver, so what fixes > the function of TWSI8 reset? This deserves more explanation. > > The TWSI8 reset could be accessed. But it's only writable. So I remove the restriction. Regards, Raymond > > Signed-off-by: Raymond Mao <raymond.mao@riscstar.com> > > --- > > drivers/reset/Kconfig | 7 +++++++ > > drivers/reset/Makefile | 2 +- > > drivers/reset/reset-spacemit-k1.c | 4 ---- > > 3 files changed, 8 insertions(+), 5 deletions(-) > > Regards, > Yao Zi > ^ permalink raw reply [flat|nested] 37+ messages in thread
* [PATCH 05/17] dt-bindings: clock: import k1-syscon from upstream 2026-01-17 19:01 [PATCH 00/17] Add board support for Spacemit K1 SoC in SPL Raymond Mao ` (3 preceding siblings ...) 2026-01-17 19:01 ` [PATCH 04/17] reset: k1: add SPL support and enable TWSI8 reset Raymond Mao @ 2026-01-17 19:01 ` Raymond Mao 2026-01-17 19:01 ` [PATCH 06/17] dts: k1: import dts file from upstream folder Raymond Mao ` (13 subsequent siblings) 18 siblings, 0 replies; 37+ messages in thread From: Raymond Mao @ 2026-01-17 19:01 UTC (permalink / raw) To: u-boot Cc: uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Yao Zi, Jamie Gibbons, Heinrich Schuchardt, Conor Dooley, Yu-Chien Peter Lin, Michal Simek, Eric Schikschneit, Yixun Lan, Junhui Liu, Sam Protsenko, Patrick Delaunay, Patrice Chotard, Neil Armstrong, Casey Connolly, Ilias Apalodimas, Christian Marangi, Angelo Dureghello, Ian Roberts, Justin Swartz, Nathan Barrett-Morrison, Aniket Limaye, Oliver Gaskell, Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Kory Maincent, Paul Barker, Rui Miguel Silva, Justin Klaassen, Samuel Holland, Marek Vasut, Gabriel Fernandez, Jonas Karlman, Kever Yang, Joseph Chen, Elaine Zhang From: Raymond Mao <raymond.mao@riscstar.com> Import spacemit,k1-syscon.h from upstream folder. And remove duplicated reset IDs in it. Signed-off-by: Raymond Mao <raymond.mao@riscstar.com> --- .../dt-bindings/clock/spacemit,k1-syscon.h | 253 ++++++++++++++++++ 1 file changed, 253 insertions(+) create mode 100644 include/dt-bindings/clock/spacemit,k1-syscon.h diff --git a/include/dt-bindings/clock/spacemit,k1-syscon.h b/include/dt-bindings/clock/spacemit,k1-syscon.h new file mode 100644 index 00000000000..c33da4ce73b --- /dev/null +++ b/include/dt-bindings/clock/spacemit,k1-syscon.h @@ -0,0 +1,253 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (C) 2024-2025 Haylen Chu <heylenay@outlook.com> + */ + +#ifndef _DT_BINDINGS_SPACEMIT_CCU_H_ +#define _DT_BINDINGS_SPACEMIT_CCU_H_ + +/* APBS (PLL) clocks */ +#define CLK_PLL1 0 +#define CLK_PLL2 1 +#define CLK_PLL3 2 +#define CLK_PLL1_D2 3 +#define CLK_PLL1_D3 4 +#define CLK_PLL1_D4 5 +#define CLK_PLL1_D5 6 +#define CLK_PLL1_D6 7 +#define CLK_PLL1_D7 8 +#define CLK_PLL1_D8 9 +#define CLK_PLL1_D11 10 +#define CLK_PLL1_D13 11 +#define CLK_PLL1_D23 12 +#define CLK_PLL1_D64 13 +#define CLK_PLL1_D10_AUD 14 +#define CLK_PLL1_D100_AUD 15 +#define CLK_PLL2_D1 16 +#define CLK_PLL2_D2 17 +#define CLK_PLL2_D3 18 +#define CLK_PLL2_D4 19 +#define CLK_PLL2_D5 20 +#define CLK_PLL2_D6 21 +#define CLK_PLL2_D7 22 +#define CLK_PLL2_D8 23 +#define CLK_PLL3_D1 24 +#define CLK_PLL3_D2 25 +#define CLK_PLL3_D3 26 +#define CLK_PLL3_D4 27 +#define CLK_PLL3_D5 28 +#define CLK_PLL3_D6 29 +#define CLK_PLL3_D7 30 +#define CLK_PLL3_D8 31 +#define CLK_PLL3_80 32 +#define CLK_PLL3_40 33 +#define CLK_PLL3_20 34 + +/* MPMU clocks */ +#define CLK_PLL1_307P2 0 +#define CLK_PLL1_76P8 1 +#define CLK_PLL1_61P44 2 +#define CLK_PLL1_153P6 3 +#define CLK_PLL1_102P4 4 +#define CLK_PLL1_51P2 5 +#define CLK_PLL1_51P2_AP 6 +#define CLK_PLL1_57P6 7 +#define CLK_PLL1_25P6 8 +#define CLK_PLL1_12P8 9 +#define CLK_PLL1_12P8_WDT 10 +#define CLK_PLL1_6P4 11 +#define CLK_PLL1_3P2 12 +#define CLK_PLL1_1P6 13 +#define CLK_PLL1_0P8 14 +#define CLK_PLL1_409P6 15 +#define CLK_PLL1_204P8 16 +#define CLK_PLL1_491 17 +#define CLK_PLL1_245P76 18 +#define CLK_PLL1_614 19 +#define CLK_PLL1_47P26 20 +#define CLK_PLL1_31P5 21 +#define CLK_PLL1_819 22 +#define CLK_PLL1_1228 23 +#define CLK_SLOW_UART 24 +#define CLK_SLOW_UART1 25 +#define CLK_SLOW_UART2 26 +#define CLK_WDT 27 +#define CLK_RIPC 28 +#define CLK_I2S_SYSCLK 29 +#define CLK_I2S_BCLK 30 +#define CLK_APB 31 +#define CLK_WDT_BUS 32 +#define CLK_I2S_153P6 33 +#define CLK_I2S_153P6_BASE 34 +#define CLK_I2S_SYSCLK_SRC 35 +#define CLK_I2S_BCLK_FACTOR 36 + +/* APBC clocks */ +#define CLK_UART0 0 +#define CLK_UART2 1 +#define CLK_UART3 2 +#define CLK_UART4 3 +#define CLK_UART5 4 +#define CLK_UART6 5 +#define CLK_UART7 6 +#define CLK_UART8 7 +#define CLK_UART9 8 +#define CLK_GPIO 9 +#define CLK_PWM0 10 +#define CLK_PWM1 11 +#define CLK_PWM2 12 +#define CLK_PWM3 13 +#define CLK_PWM4 14 +#define CLK_PWM5 15 +#define CLK_PWM6 16 +#define CLK_PWM7 17 +#define CLK_PWM8 18 +#define CLK_PWM9 19 +#define CLK_PWM10 20 +#define CLK_PWM11 21 +#define CLK_PWM12 22 +#define CLK_PWM13 23 +#define CLK_PWM14 24 +#define CLK_PWM15 25 +#define CLK_PWM16 26 +#define CLK_PWM17 27 +#define CLK_PWM18 28 +#define CLK_PWM19 29 +#define CLK_SSP3 30 +#define CLK_RTC 31 +#define CLK_TWSI0 32 +#define CLK_TWSI1 33 +#define CLK_TWSI2 34 +#define CLK_TWSI4 35 +#define CLK_TWSI5 36 +#define CLK_TWSI6 37 +#define CLK_TWSI7 38 +#define CLK_TWSI8 39 +#define CLK_TIMERS1 40 +#define CLK_TIMERS2 41 +#define CLK_AIB 42 +#define CLK_ONEWIRE 43 +#define CLK_SSPA0 44 +#define CLK_SSPA1 45 +#define CLK_DRO 46 +#define CLK_IR 47 +#define CLK_TSEN 48 +#define CLK_IPC_AP2AUD 49 +#define CLK_CAN0 50 +#define CLK_CAN0_BUS 51 +#define CLK_UART0_BUS 52 +#define CLK_UART2_BUS 53 +#define CLK_UART3_BUS 54 +#define CLK_UART4_BUS 55 +#define CLK_UART5_BUS 56 +#define CLK_UART6_BUS 57 +#define CLK_UART7_BUS 58 +#define CLK_UART8_BUS 59 +#define CLK_UART9_BUS 60 +#define CLK_GPIO_BUS 61 +#define CLK_PWM0_BUS 62 +#define CLK_PWM1_BUS 63 +#define CLK_PWM2_BUS 64 +#define CLK_PWM3_BUS 65 +#define CLK_PWM4_BUS 66 +#define CLK_PWM5_BUS 67 +#define CLK_PWM6_BUS 68 +#define CLK_PWM7_BUS 69 +#define CLK_PWM8_BUS 70 +#define CLK_PWM9_BUS 71 +#define CLK_PWM10_BUS 72 +#define CLK_PWM11_BUS 73 +#define CLK_PWM12_BUS 74 +#define CLK_PWM13_BUS 75 +#define CLK_PWM14_BUS 76 +#define CLK_PWM15_BUS 77 +#define CLK_PWM16_BUS 78 +#define CLK_PWM17_BUS 79 +#define CLK_PWM18_BUS 80 +#define CLK_PWM19_BUS 81 +#define CLK_SSP3_BUS 82 +#define CLK_RTC_BUS 83 +#define CLK_TWSI0_BUS 84 +#define CLK_TWSI1_BUS 85 +#define CLK_TWSI2_BUS 86 +#define CLK_TWSI4_BUS 87 +#define CLK_TWSI5_BUS 88 +#define CLK_TWSI6_BUS 89 +#define CLK_TWSI7_BUS 90 +#define CLK_TWSI8_BUS 91 +#define CLK_TIMERS1_BUS 92 +#define CLK_TIMERS2_BUS 93 +#define CLK_AIB_BUS 94 +#define CLK_ONEWIRE_BUS 95 +#define CLK_SSPA0_BUS 96 +#define CLK_SSPA1_BUS 97 +#define CLK_TSEN_BUS 98 +#define CLK_IPC_AP2AUD_BUS 99 +#define CLK_SSPA0_I2S_BCLK 100 +#define CLK_SSPA1_I2S_BCLK 101 + +/* APMU clocks */ +#define CLK_CCI550 0 +#define CLK_CPU_C0_HI 1 +#define CLK_CPU_C0_CORE 2 +#define CLK_CPU_C0_ACE 3 +#define CLK_CPU_C0_TCM 4 +#define CLK_CPU_C1_HI 5 +#define CLK_CPU_C1_CORE 6 +#define CLK_CPU_C1_ACE 7 +#define CLK_CCIC_4X 8 +#define CLK_CCIC1PHY 9 +#define CLK_SDH_AXI 10 +#define CLK_SDH0 11 +#define CLK_SDH1 12 +#define CLK_SDH2 13 +#define CLK_USB_P1 14 +#define CLK_USB_AXI 15 +#define CLK_USB30 16 +#define CLK_QSPI 17 +#define CLK_QSPI_BUS 18 +#define CLK_DMA 19 +#define CLK_AES 20 +#define CLK_VPU 21 +#define CLK_GPU 22 +#define CLK_EMMC 23 +#define CLK_EMMC_X 24 +#define CLK_AUDIO 25 +#define CLK_HDMI 26 +#define CLK_PMUA_ACLK 27 +#define CLK_PCIE0_MASTER 28 +#define CLK_PCIE0_SLAVE 29 +#define CLK_PCIE0_DBI 30 +#define CLK_PCIE1_MASTER 31 +#define CLK_PCIE1_SLAVE 32 +#define CLK_PCIE1_DBI 33 +#define CLK_PCIE2_MASTER 34 +#define CLK_PCIE2_SLAVE 35 +#define CLK_PCIE2_DBI 36 +#define CLK_EMAC0_BUS 37 +#define CLK_EMAC0_PTP 38 +#define CLK_EMAC1_BUS 39 +#define CLK_EMAC1_PTP 40 +#define CLK_JPG 41 +#define CLK_CCIC2PHY 42 +#define CLK_CCIC3PHY 43 +#define CLK_CSI 44 +#define CLK_CAMM0 45 +#define CLK_CAMM1 46 +#define CLK_CAMM2 47 +#define CLK_ISP_CPP 48 +#define CLK_ISP_BUS 49 +#define CLK_ISP 50 +#define CLK_DPU_MCLK 51 +#define CLK_DPU_ESC 52 +#define CLK_DPU_BIT 53 +#define CLK_DPU_PXCLK 54 +#define CLK_DPU_HCLK 55 +#define CLK_DPU_SPI 56 +#define CLK_DPU_SPI_HBUS 57 +#define CLK_DPU_SPIBUS 58 +#define CLK_DPU_SPI_ACLK 59 +#define CLK_V2D 60 +#define CLK_EMMC_BUS 61 + +#endif /* _DT_BINDINGS_SPACEMIT_CCU_H_ */ -- 2.25.1 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 06/17] dts: k1: import dts file from upstream folder 2026-01-17 19:01 [PATCH 00/17] Add board support for Spacemit K1 SoC in SPL Raymond Mao ` (4 preceding siblings ...) 2026-01-17 19:01 ` [PATCH 05/17] dt-bindings: clock: import k1-syscon from upstream Raymond Mao @ 2026-01-17 19:01 ` Raymond Mao 2026-01-17 23:03 ` Yixun Lan 2026-01-17 19:01 ` [PATCH 07/17] clk: spacemit: Add support for K1 SoC Raymond Mao ` (12 subsequent siblings) 18 siblings, 1 reply; 37+ messages in thread From: Raymond Mao @ 2026-01-17 19:01 UTC (permalink / raw) To: u-boot Cc: uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Yao Zi, Yu-Chien Peter Lin, Heinrich Schuchardt, Conor Dooley, Jamie Gibbons, Eric Schikschneit, Randolph Sheng-Kai Lin, Michal Simek, Yixun Lan, Junhui Liu, Sam Protsenko, Patrice Chotard, Patrick Delaunay, Neil Armstrong, Casey Connolly, Christian Marangi, Nathan Barrett-Morrison, Greg Malysa, Vasileios Bimpikas, Justin Swartz, Aniket Limaye, Oliver Gaskell, Utsav Agarwal, Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Anshul Dalal, Samuel Holland, Justin Klaassen, Paul Barker, Marek Vasut, Rui Miguel Silva, Gabriel Fernandez, Kever Yang, Jonas Karlman, Elaine Zhang, Joseph Chen From: Raymond Mao <raymond.mao@riscstar.com> Import K1.dtsi from upstream folder. Signed-off-by: Raymond Mao <raymond.mao@riscstar.com> --- arch/riscv/dts/k1.dtsi | 562 +++++++++++++++++++++++++++++++++-------- 1 file changed, 460 insertions(+), 102 deletions(-) diff --git a/arch/riscv/dts/k1.dtsi b/arch/riscv/dts/k1.dtsi index 9c203eb4b79..20f1cb57462 100644 --- a/arch/riscv/dts/k1.dtsi +++ b/arch/riscv/dts/k1.dtsi @@ -1,8 +1,11 @@ -// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +// SPDX-License-Identifier: GPL-2.0 OR MIT /* * Copyright (C) 2024 Yangyu Chen <cyy@cyyself.name> */ +#include <dt-bindings/clock/spacemit,k1-syscon.h> +#include <dt-bindings/reset/spacemit-k1-reset.h> + /dts-v1/; / { #address-cells = <2>; @@ -10,18 +13,6 @@ model = "SpacemiT K1"; compatible = "spacemit,k1"; - aliases { - serial0 = &uart0; - serial1 = &uart2; - serial2 = &uart3; - serial3 = &uart4; - serial4 = &uart5; - serial5 = &uart6; - serial6 = &uart7; - serial7 = &uart8; - serial8 = &uart9; - }; - cpus { #address-cells = <1>; #size-cells = <0>; @@ -318,6 +309,36 @@ }; }; + clocks { + vctcxo_1m: clock-1m { + compatible = "fixed-clock"; + clock-frequency = <1000000>; + clock-output-names = "vctcxo_1m"; + #clock-cells = <0>; + }; + + vctcxo_24m: clock-24m { + compatible = "fixed-clock"; + clock-frequency = <24000000>; + clock-output-names = "vctcxo_24m"; + #clock-cells = <0>; + }; + + vctcxo_3m: clock-3m { + compatible = "fixed-clock"; + clock-frequency = <3000000>; + clock-output-names = "vctcxo_3m"; + #clock-cells = <0>; + }; + + osc_32k: clock-32k { + compatible = "fixed-clock"; + clock-frequency = <32000>; + clock-output-names = "osc_32k"; + #clock-cells = <0>; + }; + }; + soc: soc { compatible = "simple-bus"; interrupt-parent = <&plic>; @@ -326,96 +347,267 @@ dma-noncoherent; ranges; - uart0: serial@d4017000 { - compatible = "spacemit,k1-uart", "intel,xscale-uart"; - reg = <0x0 0xd4017000 0x0 0x100>; - interrupts = <42>; - clock-frequency = <14857000>; - reg-shift = <2>; - reg-io-width = <4>; + syscon_rcpu: system-controller@c0880000 { + compatible = "spacemit,k1-syscon-rcpu"; + reg = <0x0 0xc0880000 0x0 0x2048>; + #reset-cells = <1>; + }; + + syscon_rcpu2: system-controller@c0888000 { + compatible = "spacemit,k1-syscon-rcpu2"; + reg = <0x0 0xc0888000 0x0 0x28>; + #reset-cells = <1>; + }; + + syscon_apbc: system-controller@d4015000 { + compatible = "spacemit,k1-syscon-apbc"; + reg = <0x0 0xd4015000 0x0 0x1000>; + clocks = <&osc_32k>, <&vctcxo_1m>, <&vctcxo_3m>, + <&vctcxo_24m>; + clock-names = "osc", "vctcxo_1m", "vctcxo_3m", + "vctcxo_24m"; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + gpio: gpio@d4019000 { + compatible = "spacemit,k1-gpio"; + reg = <0x0 0xd4019000 0x0 0x100>; + clocks = <&syscon_apbc CLK_GPIO>, + <&syscon_apbc CLK_GPIO_BUS>; + clock-names = "core", "bus"; + gpio-controller; + #gpio-cells = <3>; + interrupts = <58>; + interrupt-parent = <&plic>; + interrupt-controller; + #interrupt-cells = <3>; + gpio-ranges = <&pinctrl 0 0 0 32>, + <&pinctrl 1 0 32 32>, + <&pinctrl 2 0 64 32>, + <&pinctrl 3 0 96 32>; + }; + + pwm0: pwm@d401a000 { + compatible = "spacemit,k1-pwm", "marvell,pxa910-pwm"; + reg = <0x0 0xd401a000 0x0 0x10>; + #pwm-cells = <3>; + clocks = <&syscon_apbc CLK_PWM0>; + resets = <&syscon_apbc RESET_PWM0>; + status = "disabled"; + }; + + pwm1: pwm@d401a400 { + compatible = "spacemit,k1-pwm", "marvell,pxa910-pwm"; + reg = <0x0 0xd401a400 0x0 0x10>; + #pwm-cells = <3>; + clocks = <&syscon_apbc CLK_PWM1>; + resets = <&syscon_apbc RESET_PWM1>; + status = "disabled"; + }; + + pwm2: pwm@d401a800 { + compatible = "spacemit,k1-pwm", "marvell,pxa910-pwm"; + reg = <0x0 0xd401a800 0x0 0x10>; + #pwm-cells = <3>; + clocks = <&syscon_apbc CLK_PWM2>; + resets = <&syscon_apbc RESET_PWM2>; + status = "disabled"; + }; + + pwm3: pwm@d401ac00 { + compatible = "spacemit,k1-pwm", "marvell,pxa910-pwm"; + reg = <0x0 0xd401ac00 0x0 0x10>; + #pwm-cells = <3>; + clocks = <&syscon_apbc CLK_PWM3>; + resets = <&syscon_apbc RESET_PWM3>; + status = "disabled"; + }; + + pwm4: pwm@d401b000 { + compatible = "spacemit,k1-pwm", "marvell,pxa910-pwm"; + reg = <0x0 0xd401b000 0x0 0x10>; + #pwm-cells = <3>; + clocks = <&syscon_apbc CLK_PWM4>; + resets = <&syscon_apbc RESET_PWM4>; + status = "disabled"; + }; + + pwm5: pwm@d401b400 { + compatible = "spacemit,k1-pwm", "marvell,pxa910-pwm"; + reg = <0x0 0xd401b400 0x0 0x10>; + #pwm-cells = <3>; + clocks = <&syscon_apbc CLK_PWM5>; + resets = <&syscon_apbc RESET_PWM5>; + status = "disabled"; + }; + + pwm6: pwm@d401b800 { + compatible = "spacemit,k1-pwm", "marvell,pxa910-pwm"; + reg = <0x0 0xd401b800 0x0 0x10>; + #pwm-cells = <3>; + clocks = <&syscon_apbc CLK_PWM6>; + resets = <&syscon_apbc RESET_PWM6>; + status = "disabled"; + }; + + pwm7: pwm@d401bc00 { + compatible = "spacemit,k1-pwm", "marvell,pxa910-pwm"; + reg = <0x0 0xd401bc00 0x0 0x10>; + #pwm-cells = <3>; + clocks = <&syscon_apbc CLK_PWM7>; + resets = <&syscon_apbc RESET_PWM7>; + status = "disabled"; + }; + + pinctrl: pinctrl@d401e000 { + compatible = "spacemit,k1-pinctrl"; + reg = <0x0 0xd401e000 0x0 0x400>; + clocks = <&syscon_apbc CLK_AIB>, + <&syscon_apbc CLK_AIB_BUS>; + clock-names = "func", "bus"; + }; + + pwm8: pwm@d4020000 { + compatible = "spacemit,k1-pwm", "marvell,pxa910-pwm"; + reg = <0x0 0xd4020000 0x0 0x10>; + #pwm-cells = <3>; + clocks = <&syscon_apbc CLK_PWM8>; + resets = <&syscon_apbc RESET_PWM8>; + status = "disabled"; + }; + + pwm9: pwm@d4020400 { + compatible = "spacemit,k1-pwm", "marvell,pxa910-pwm"; + reg = <0x0 0xd4020400 0x0 0x10>; + #pwm-cells = <3>; + clocks = <&syscon_apbc CLK_PWM9>; + resets = <&syscon_apbc RESET_PWM9>; + status = "disabled"; + }; + + pwm10: pwm@d4020800 { + compatible = "spacemit,k1-pwm", "marvell,pxa910-pwm"; + reg = <0x0 0xd4020800 0x0 0x10>; + #pwm-cells = <3>; + clocks = <&syscon_apbc CLK_PWM10>; + resets = <&syscon_apbc RESET_PWM10>; status = "disabled"; }; - uart2: serial@d4017100 { - compatible = "spacemit,k1-uart", "intel,xscale-uart"; - reg = <0x0 0xd4017100 0x0 0x100>; - interrupts = <44>; - clock-frequency = <14857000>; - reg-shift = <2>; - reg-io-width = <4>; + pwm11: pwm@d4020c00 { + compatible = "spacemit,k1-pwm", "marvell,pxa910-pwm"; + reg = <0x0 0xd4020c00 0x0 0x10>; + #pwm-cells = <3>; + clocks = <&syscon_apbc CLK_PWM11>; + resets = <&syscon_apbc RESET_PWM11>; status = "disabled"; }; - uart3: serial@d4017200 { - compatible = "spacemit,k1-uart", "intel,xscale-uart"; - reg = <0x0 0xd4017200 0x0 0x100>; - interrupts = <45>; - clock-frequency = <14857000>; - reg-shift = <2>; - reg-io-width = <4>; + pwm12: pwm@d4021000 { + compatible = "spacemit,k1-pwm", "marvell,pxa910-pwm"; + reg = <0x0 0xd4021000 0x0 0x10>; + #pwm-cells = <3>; + clocks = <&syscon_apbc CLK_PWM12>; + resets = <&syscon_apbc RESET_PWM12>; status = "disabled"; }; - uart4: serial@d4017300 { - compatible = "spacemit,k1-uart", "intel,xscale-uart"; - reg = <0x0 0xd4017300 0x0 0x100>; - interrupts = <46>; - clock-frequency = <14857000>; - reg-shift = <2>; - reg-io-width = <4>; + pwm13: pwm@d4021400 { + compatible = "spacemit,k1-pwm", "marvell,pxa910-pwm"; + reg = <0x0 0xd4021400 0x0 0x10>; + #pwm-cells = <3>; + clocks = <&syscon_apbc CLK_PWM13>; + resets = <&syscon_apbc RESET_PWM13>; status = "disabled"; }; - uart5: serial@d4017400 { - compatible = "spacemit,k1-uart", "intel,xscale-uart"; - reg = <0x0 0xd4017400 0x0 0x100>; - interrupts = <47>; - clock-frequency = <14857000>; - reg-shift = <2>; - reg-io-width = <4>; + pwm14: pwm@d4021800 { + compatible = "spacemit,k1-pwm", "marvell,pxa910-pwm"; + reg = <0x0 0xd4021800 0x0 0x10>; + #pwm-cells = <3>; + clocks = <&syscon_apbc CLK_PWM14>; + resets = <&syscon_apbc RESET_PWM14>; status = "disabled"; }; - uart6: serial@d4017500 { - compatible = "spacemit,k1-uart", "intel,xscale-uart"; - reg = <0x0 0xd4017500 0x0 0x100>; - interrupts = <48>; - clock-frequency = <14857000>; - reg-shift = <2>; - reg-io-width = <4>; + pwm15: pwm@d4021c00 { + compatible = "spacemit,k1-pwm", "marvell,pxa910-pwm"; + reg = <0x0 0xd4021c00 0x0 0x10>; + #pwm-cells = <3>; + clocks = <&syscon_apbc CLK_PWM15>; + resets = <&syscon_apbc RESET_PWM15>; status = "disabled"; }; - uart7: serial@d4017600 { - compatible = "spacemit,k1-uart", "intel,xscale-uart"; - reg = <0x0 0xd4017600 0x0 0x100>; - interrupts = <49>; - clock-frequency = <14857000>; - reg-shift = <2>; - reg-io-width = <4>; + pwm16: pwm@d4022000 { + compatible = "spacemit,k1-pwm", "marvell,pxa910-pwm"; + reg = <0x0 0xd4022000 0x0 0x10>; + #pwm-cells = <3>; + clocks = <&syscon_apbc CLK_PWM16>; + resets = <&syscon_apbc RESET_PWM16>; status = "disabled"; }; - uart8: serial@d4017700 { - compatible = "spacemit,k1-uart", "intel,xscale-uart"; - reg = <0x0 0xd4017700 0x0 0x100>; - interrupts = <50>; - clock-frequency = <14857000>; - reg-shift = <2>; - reg-io-width = <4>; + pwm17: pwm@d4022400 { + compatible = "spacemit,k1-pwm", "marvell,pxa910-pwm"; + reg = <0x0 0xd4022400 0x0 0x10>; + #pwm-cells = <3>; + clocks = <&syscon_apbc CLK_PWM17>; + resets = <&syscon_apbc RESET_PWM17>; status = "disabled"; }; - uart9: serial@d4017800 { - compatible = "spacemit,k1-uart", "intel,xscale-uart"; - reg = <0x0 0xd4017800 0x0 0x100>; - interrupts = <51>; - clock-frequency = <14857000>; - reg-shift = <2>; - reg-io-width = <4>; + pwm18: pwm@d4022800 { + compatible = "spacemit,k1-pwm", "marvell,pxa910-pwm"; + reg = <0x0 0xd4022800 0x0 0x10>; + #pwm-cells = <3>; + clocks = <&syscon_apbc CLK_PWM18>; + resets = <&syscon_apbc RESET_PWM18>; status = "disabled"; }; + pwm19: pwm@d4022c00 { + compatible = "spacemit,k1-pwm", "marvell,pxa910-pwm"; + reg = <0x0 0xd4022c00 0x0 0x10>; + #pwm-cells = <3>; + clocks = <&syscon_apbc CLK_PWM19>; + resets = <&syscon_apbc RESET_PWM19>; + status = "disabled"; + }; + + syscon_mpmu: system-controller@d4050000 { + compatible = "spacemit,k1-syscon-mpmu"; + reg = <0x0 0xd4050000 0x0 0x209c>; + clocks = <&osc_32k>, <&vctcxo_1m>, <&vctcxo_3m>, + <&vctcxo_24m>; + clock-names = "osc", "vctcxo_1m", "vctcxo_3m", + "vctcxo_24m"; + #clock-cells = <1>; + #power-domain-cells = <1>; + #reset-cells = <1>; + }; + + pll: clock-controller@d4090000 { + compatible = "spacemit,k1-pll"; + reg = <0x0 0xd4090000 0x0 0x1000>; + clocks = <&vctcxo_24m>; + spacemit,mpmu = <&syscon_mpmu>; + #clock-cells = <1>; + }; + + syscon_apmu: system-controller@d4282800 { + compatible = "spacemit,k1-syscon-apmu"; + reg = <0x0 0xd4282800 0x0 0x400>; + clocks = <&osc_32k>, <&vctcxo_1m>, <&vctcxo_3m>, + <&vctcxo_24m>; + clock-names = "osc", "vctcxo_1m", "vctcxo_3m", + "vctcxo_24m"; + #clock-cells = <1>; + #power-domain-cells = <1>; + #reset-cells = <1>; + }; + plic: interrupt-controller@e0000000 { compatible = "spacemit,k1-plic", "sifive,plic-1.0.0"; reg = <0x0 0xe0000000 0x0 0x4000000>; @@ -446,35 +638,201 @@ <&cpu7_intc 3>, <&cpu7_intc 7>; }; - sec_uart1: serial@f0612000 { - compatible = "spacemit,k1-uart", "intel,xscale-uart"; - reg = <0x0 0xf0612000 0x0 0x100>; - interrupts = <43>; - clock-frequency = <14857000>; - reg-shift = <2>; - reg-io-width = <4>; - status = "reserved"; /* for TEE usage */ - }; - - reset: reset-controller@d4050000 { - compatible = "spacemit,k1-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>; - reg-names = "mpmu", "apmu", "apbc", "apbs", "ciu", "dciu", "ddrc", "apbc2"; + syscon_apbc2: system-controller@f0610000 { + compatible = "spacemit,k1-syscon-apbc2"; + reg = <0x0 0xf0610000 0x0 0x20>; #reset-cells = <1>; - status = "disabled"; }; - pinctrl: pinctrl@d401e000 { - compatible = "spacemit,k1-pinctrl", "pinctrl-single"; - reg = <0x0 0xd401e000 0x0 0x400>; - pinctrl-single,register-width = <32>; + camera-bus { + compatible = "simple-bus"; + ranges; + #address-cells = <2>; + #size-cells = <2>; + dma-ranges = <0x0 0x00000000 0x0 0x00000000 0x0 0x80000000>, + <0x0 0x80000000 0x1 0x00000000 0x1 0x80000000>; + }; + + dma-bus { + compatible = "simple-bus"; + ranges; + #address-cells = <2>; + #size-cells = <2>; + dma-ranges = <0x0 0x00000000 0x0 0x00000000 0x0 0x80000000>, + <0x1 0x00000000 0x1 0x80000000 0x3 0x00000000>; + + uart0: serial@d4017000 { + compatible = "spacemit,k1-uart", + "intel,xscale-uart"; + reg = <0x0 0xd4017000 0x0 0x100>; + clocks = <&syscon_apbc CLK_UART0>, + <&syscon_apbc CLK_UART0_BUS>; + clock-names = "core", "bus"; + interrupts = <42>; + reg-shift = <2>; + reg-io-width = <4>; + status = "disabled"; + }; + + uart2: serial@d4017100 { + compatible = "spacemit,k1-uart", + "intel,xscale-uart"; + reg = <0x0 0xd4017100 0x0 0x100>; + clocks = <&syscon_apbc CLK_UART2>, + <&syscon_apbc CLK_UART2_BUS>; + clock-names = "core", "bus"; + interrupts = <44>; + reg-shift = <2>; + reg-io-width = <4>; + status = "disabled"; + }; + + uart3: serial@d4017200 { + compatible = "spacemit,k1-uart", + "intel,xscale-uart"; + reg = <0x0 0xd4017200 0x0 0x100>; + clocks = <&syscon_apbc CLK_UART3>, + <&syscon_apbc CLK_UART3_BUS>; + clock-names = "core", "bus"; + interrupts = <45>; + reg-shift = <2>; + reg-io-width = <4>; + status = "disabled"; + }; + + uart4: serial@d4017300 { + compatible = "spacemit,k1-uart", + "intel,xscale-uart"; + reg = <0x0 0xd4017300 0x0 0x100>; + clocks = <&syscon_apbc CLK_UART4>, + <&syscon_apbc CLK_UART4_BUS>; + clock-names = "core", "bus"; + interrupts = <46>; + reg-shift = <2>; + reg-io-width = <4>; + status = "disabled"; + }; + + uart5: serial@d4017400 { + compatible = "spacemit,k1-uart", + "intel,xscale-uart"; + reg = <0x0 0xd4017400 0x0 0x100>; + clocks = <&syscon_apbc CLK_UART5>, + <&syscon_apbc CLK_UART5_BUS>; + clock-names = "core", "bus"; + interrupts = <47>; + reg-shift = <2>; + reg-io-width = <4>; + status = "disabled"; + }; + + uart6: serial@d4017500 { + compatible = "spacemit,k1-uart", + "intel,xscale-uart"; + reg = <0x0 0xd4017500 0x0 0x100>; + clocks = <&syscon_apbc CLK_UART6>, + <&syscon_apbc CLK_UART6_BUS>; + clock-names = "core", "bus"; + interrupts = <48>; + reg-shift = <2>; + reg-io-width = <4>; + status = "disabled"; + }; + + uart7: serial@d4017600 { + compatible = "spacemit,k1-uart", + "intel,xscale-uart"; + reg = <0x0 0xd4017600 0x0 0x100>; + clocks = <&syscon_apbc CLK_UART7>, + <&syscon_apbc CLK_UART7_BUS>; + clock-names = "core", "bus"; + interrupts = <49>; + reg-shift = <2>; + reg-io-width = <4>; + status = "disabled"; + }; + + uart8: serial@d4017700 { + compatible = "spacemit,k1-uart", + "intel,xscale-uart"; + reg = <0x0 0xd4017700 0x0 0x100>; + clocks = <&syscon_apbc CLK_UART8>, + <&syscon_apbc CLK_UART8_BUS>; + clock-names = "core", "bus"; + interrupts = <50>; + reg-shift = <2>; + reg-io-width = <4>; + status = "disabled"; + }; + + uart9: serial@d4017800 { + compatible = "spacemit,k1-uart", + "intel,xscale-uart"; + reg = <0x0 0xd4017800 0x0 0x100>; + clocks = <&syscon_apbc CLK_UART9>, + <&syscon_apbc CLK_UART9_BUS>; + clock-names = "core", "bus"; + interrupts = <51>; + reg-shift = <2>; + reg-io-width = <4>; + status = "disabled"; + }; + + sec_uart1: serial@f0612000 { + compatible = "spacemit,k1-uart", + "intel,xscale-uart"; + reg = <0x0 0xf0612000 0x0 0x100>; + interrupts = <43>; + clock-frequency = <14857000>; + reg-shift = <2>; + reg-io-width = <4>; + status = "reserved"; /* for TEE usage */ + }; + }; + + multimedia-bus { + compatible = "simple-bus"; + ranges; + #address-cells = <2>; + #size-cells = <2>; + dma-ranges = <0x0 0x00000000 0x0 0x00000000 0x0 0x80000000>, + <0x0 0x80000000 0x1 0x00000000 0x3 0x80000000>; + }; + + network-bus { + compatible = "simple-bus"; + ranges; + #address-cells = <2>; + #size-cells = <2>; + dma-ranges = <0x0 0x00000000 0x0 0x00000000 0x0 0x80000000>, + <0x0 0x80000000 0x1 0x00000000 0x0 0x80000000>; + }; + + pcie-bus { + compatible = "simple-bus"; + ranges; + #address-cells = <2>; + #size-cells = <2>; + dma-ranges = <0x0 0x00000000 0x0 0x00000000 0x0 0x80000000>, + <0x0 0xb8000000 0x1 0x38000000 0x3 0x48000000>; + }; + + storage-bus { + compatible = "simple-bus"; + ranges; + #address-cells = <2>; + #size-cells = <2>; + dma-ranges = <0x0 0x00000000 0x0 0x00000000 0x0 0x80000000>; + + emmc: mmc@d4281000 { + compatible = "spacemit,k1-sdhci"; + reg = <0x0 0xd4281000 0x0 0x200>; + clocks = <&syscon_apmu CLK_SDH_AXI>, + <&syscon_apmu CLK_SDH2>; + clock-names = "core", "io"; + interrupts = <101>; + status = "disabled"; + }; }; }; }; -- 2.25.1 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [PATCH 06/17] dts: k1: import dts file from upstream folder 2026-01-17 19:01 ` [PATCH 06/17] dts: k1: import dts file from upstream folder Raymond Mao @ 2026-01-17 23:03 ` Yixun Lan 2026-01-18 8:56 ` Yao Zi 0 siblings, 1 reply; 37+ messages in thread From: Yixun Lan @ 2026-01-17 23:03 UTC (permalink / raw) To: Raymond Mao Cc: u-boot, uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Yao Zi, Yu-Chien Peter Lin, Heinrich Schuchardt, Conor Dooley, Jamie Gibbons, Eric Schikschneit, Randolph Sheng-Kai Lin, Michal Simek, Junhui Liu, Sam Protsenko, Patrice Chotard, Patrick Delaunay, Neil Armstrong, Casey Connolly, Christian Marangi, Nathan Barrett-Morrison, Greg Malysa, Vasileios Bimpikas, Justin Swartz, Aniket Limaye, Oliver Gaskell, Utsav Agarwal, Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Anshul Dalal, Samuel Holland, Justin Klaassen, Paul Barker, Marek Vasut, Rui Miguel Silva, Gabriel Fernandez, Kever Yang, Jonas Karlman, Elaine Zhang, Joseph Chen Hi Raymond, On 14:01 Sat 17 Jan , Raymond Mao wrote: > From: Raymond Mao <raymond.mao@riscstar.com> > > Import K1.dtsi from upstream folder. > Can you explore the possibility of using OF_UPSTREAM? which should get rid of this copy & paste > Signed-off-by: Raymond Mao <raymond.mao@riscstar.com> > --- -- Yixun Lan (dlan) ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH 06/17] dts: k1: import dts file from upstream folder 2026-01-17 23:03 ` Yixun Lan @ 2026-01-18 8:56 ` Yao Zi 0 siblings, 0 replies; 37+ messages in thread From: Yao Zi @ 2026-01-18 8:56 UTC (permalink / raw) To: Yixun Lan, Raymond Mao Cc: u-boot, uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Yu-Chien Peter Lin, Heinrich Schuchardt, Conor Dooley, Jamie Gibbons, Eric Schikschneit, Randolph Sheng-Kai Lin, Michal Simek, Junhui Liu, Sam Protsenko, Patrice Chotard, Patrick Delaunay, Neil Armstrong, Casey Connolly, Christian Marangi, Nathan Barrett-Morrison, Greg Malysa, Vasileios Bimpikas, Justin Swartz, Aniket Limaye, Oliver Gaskell, Utsav Agarwal, Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Anshul Dalal, Samuel Holland, Justin Klaassen, Paul Barker, Marek Vasut, Rui Miguel Silva, Gabriel Fernandez, Kever Yang, Jonas Karlman, Elaine Zhang, Joseph Chen On Sun, Jan 18, 2026 at 07:03:57AM +0800, Yixun Lan wrote: > Hi Raymond, > > On 14:01 Sat 17 Jan , Raymond Mao wrote: > > From: Raymond Mao <raymond.mao@riscstar.com> > > > > Import K1.dtsi from upstream folder. > > > Can you explore the possibility of using OF_UPSTREAM? > which should get rid of this copy & paste This is probably impossible with the current in-tree reset driver, since it follows a different devicetree ABI. > > Signed-off-by: Raymond Mao <raymond.mao@riscstar.com> > > --- > > -- > Yixun Lan (dlan) Regards, Yao Zi ^ permalink raw reply [flat|nested] 37+ messages in thread
* [PATCH 07/17] clk: spacemit: Add support for K1 SoC 2026-01-17 19:01 [PATCH 00/17] Add board support for Spacemit K1 SoC in SPL Raymond Mao ` (5 preceding siblings ...) 2026-01-17 19:01 ` [PATCH 06/17] dts: k1: import dts file from upstream folder Raymond Mao @ 2026-01-17 19:01 ` Raymond Mao 2026-01-17 19:01 ` [PATCH 08/17] dts: k1: enable clocks in SPL Raymond Mao ` (11 subsequent siblings) 18 siblings, 0 replies; 37+ messages in thread From: Raymond Mao @ 2026-01-17 19:01 UTC (permalink / raw) To: u-boot Cc: uboot, Junhui Liu, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Yao Zi, Raymond Mao, Heinrich Schuchardt, Yu-Chien Peter Lin, Jamie Gibbons, Conor Dooley, Randolph Sheng-Kai Lin, Eric Schikschneit, Michal Simek, Yixun Lan, Sam Protsenko, Patrice Chotard, Patrick Delaunay, Neil Armstrong, Casey Connolly, Ilias Apalodimas, Christian Marangi, Utsav Agarwal, Oliver Gaskell, Vasileios Bimpikas, Nathan Barrett-Morrison, Justin Swartz, Aniket Limaye, Arturs Artamonovs, Ian Roberts, Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Anshul Dalal, Kory Maincent, Rui Miguel Silva, Justin Klaassen, Paul Barker, Andre Przywara, Samuel Holland, Marek Vasut, Gabriel Fernandez, Jonas Karlman, Kever Yang, Finley Xiao, Elaine Zhang, Joseph Chen From: Junhui Liu <junhui.liu@pigmoral.tech> Add clock support for Spacemit K1 SoC. Signed-off-by: Junhui Liu <junhui.liu@pigmoral.tech> Signed-off-by: Raymond Mao <raymond.mao@riststar.com> --- drivers/clk/Kconfig | 5 +- drivers/clk/Makefile | 1 + drivers/clk/spacemit/Kconfig | 31 + drivers/clk/spacemit/Makefile | 7 + drivers/clk/spacemit/clk-k1.c | 1793 +++++++++++++++++++++++++++++ drivers/clk/spacemit/clk_common.h | 79 ++ drivers/clk/spacemit/clk_ddn.c | 93 ++ drivers/clk/spacemit/clk_ddn.h | 53 + drivers/clk/spacemit/clk_mix.c | 403 +++++++ drivers/clk/spacemit/clk_mix.h | 224 ++++ drivers/clk/spacemit/clk_pll.c | 157 +++ drivers/clk/spacemit/clk_pll.h | 81 ++ include/soc/spacemit/k1-syscon.h | 149 +++ 13 files changed, 3074 insertions(+), 2 deletions(-) create mode 100644 drivers/clk/spacemit/Kconfig create mode 100644 drivers/clk/spacemit/Makefile create mode 100644 drivers/clk/spacemit/clk-k1.c create mode 100644 drivers/clk/spacemit/clk_common.h create mode 100644 drivers/clk/spacemit/clk_ddn.c create mode 100644 drivers/clk/spacemit/clk_ddn.h create mode 100644 drivers/clk/spacemit/clk_mix.c create mode 100644 drivers/clk/spacemit/clk_mix.h create mode 100644 drivers/clk/spacemit/clk_pll.c create mode 100644 drivers/clk/spacemit/clk_pll.h create mode 100644 include/soc/spacemit/k1-syscon.h diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 85cc472b4cb..85da15bcaad 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -275,11 +275,12 @@ source "drivers/clk/mvebu/Kconfig" source "drivers/clk/owl/Kconfig" source "drivers/clk/qcom/Kconfig" source "drivers/clk/renesas/Kconfig" -source "drivers/clk/sophgo/Kconfig" -source "drivers/clk/sunxi/Kconfig" source "drivers/clk/sifive/Kconfig" +source "drivers/clk/sophgo/Kconfig" +source "drivers/clk/spacemit/Kconfig" source "drivers/clk/starfive/Kconfig" source "drivers/clk/stm32/Kconfig" +source "drivers/clk/sunxi/Kconfig" source "drivers/clk/tegra/Kconfig" source "drivers/clk/ti/Kconfig" source "drivers/clk/thead/Kconfig" diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 5f0c0d8a5c2..dabbb3af4b6 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -48,6 +48,7 @@ obj-$(CONFIG_CLK_RENESAS) += renesas/ obj-$(CONFIG_$(PHASE_)CLK_SCMI) += clk_scmi.o obj-$(CONFIG_CLK_SIFIVE) += sifive/ obj-$(CONFIG_CLK_SOPHGO) += sophgo/ +obj-$(CONFIG_CLK_SPACEMIT) += spacemit/ obj-$(CONFIG_CLK_SUNXI) += sunxi/ obj-$(CONFIG_CLK_UNIPHIER) += uniphier/ obj-$(CONFIG_CLK_VERSACLOCK) += clk_versaclock.o diff --git a/drivers/clk/spacemit/Kconfig b/drivers/clk/spacemit/Kconfig new file mode 100644 index 00000000000..fd96ec8fd2e --- /dev/null +++ b/drivers/clk/spacemit/Kconfig @@ -0,0 +1,31 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (c) 2025, Junhui Liu <junhui.liu@pigmoral.tech> + +config CLK_SPACEMIT + bool "Clock support for SpacemiT SoCs" + depends on CLK + select REGMAP + help + This enables support clock driver for Spacemit SoC + family. + +if CLK_SPACEMIT + +config CLK_SPACEMIT_K1 + bool "SpacemiT K1 clock support" + select CLK_CCF + default SPACEMIT_K1 + help + This enables support clock driver for Spacemit K1 SoC. + It's based on Common Clock Framework. + +config SPL_CLK_SPACEMIT_K1 + bool "Enable Spacemit K1 SoC clock support in SPL" + select SPL_CLK_CCF + default SPACEMIT_K1 + help + It allows to use the Spacemit K1 SoC clock driver in + SPL. + +endif diff --git a/drivers/clk/spacemit/Makefile b/drivers/clk/spacemit/Makefile new file mode 100644 index 00000000000..824e94d1f74 --- /dev/null +++ b/drivers/clk/spacemit/Makefile @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Copyright (C) 2025 Junhui Liu <junhui.liu@pigmoral.tech> + +obj-$(CONFIG_CLK_SPACEMIT) += clk_ddn.o clk_mix.o clk_pll.o + +obj-$(CONFIG_CLK_SPACEMIT_K1) += clk-k1.o diff --git a/drivers/clk/spacemit/clk-k1.c b/drivers/clk/spacemit/clk-k1.c new file mode 100644 index 00000000000..9401703b125 --- /dev/null +++ b/drivers/clk/spacemit/clk-k1.c @@ -0,0 +1,1793 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024 SpacemiT Technology Co. Ltd + * Copyright (c) 2024-2025 Haylen Chu <heylenay@4d2.org> + * Copyright (c) 2025 Junhui Liu <junhui.liu@pigmoral.tech> + * Authors: Haylen Chu <heylenay@4d2.org> + */ + +#include <dm.h> +#include <dm/device_compat.h> +#include <dm/lists.h> +#include <regmap.h> +#include <linux/clk-provider.h> +#include <soc/spacemit/k1-syscon.h> + +#include "clk_common.h" +#include "clk_ddn.h" +#include "clk_mix.h" +#include "clk_pll.h" + +#include <dt-bindings/clock/spacemit,k1-syscon.h> + +#define K1_PLL_ID 100 +#define K1_MPMU_ID 200 +#define K1_APBC_ID 300 +#define K1_APMU_ID 400 + +struct spacemit_ccu_data { + struct clk **clks; + size_t num; + unsigned long offset; +}; + +/* APBS clocks start, APBS region contains and only contains all PLL clocks */ + +/* + * PLL{1,2} must run at fixed frequencies to provide clocks in correct rates for + * peripherals. + */ +static const struct ccu_pll_rate_tbl pll1_rate_tbl[] = { + CCU_PLL_RATE(2457600000UL, 0x0050dd64, 0x330ccccd), +}; + +static const struct ccu_pll_rate_tbl pll2_rate_tbl[] = { + CCU_PLL_RATE(3000000000UL, 0x0050dd66, 0x3fe00000), +}; + +static const struct ccu_pll_rate_tbl pll3_rate_tbl[] = { + CCU_PLL_RATE(1600000000UL, 0x0050cd61, 0x43eaaaab), + CCU_PLL_RATE(1800000000UL, 0x0050cd61, 0x4b000000), + CCU_PLL_RATE(2000000000UL, 0x0050dd62, 0x2aeaaaab), + CCU_PLL_RATE(2457600000UL, 0x0050dd64, 0x330ccccd), + CCU_PLL_RATE(3000000000UL, 0x0050dd66, 0x3fe00000), + CCU_PLL_RATE(3200000000UL, 0x0050dd67, 0x43eaaaab), +}; + +CCU_PLL_DEFINE(CLK_PLL1, pll1, pll1, "clock-24m", pll1_rate_tbl, + APBS_PLL1_SWCR1, APBS_PLL1_SWCR3, MPMU_POSR, POSR_PLL1_LOCK, + CLK_SET_RATE_GATE); +CCU_PLL_DEFINE(CLK_PLL2, pll2, pll2, "clock-24m", pll2_rate_tbl, + APBS_PLL2_SWCR1, APBS_PLL2_SWCR3, MPMU_POSR, POSR_PLL2_LOCK, + CLK_SET_RATE_GATE); +CCU_PLL_DEFINE(CLK_PLL3, pll3, pll3, "clock-24m", pll3_rate_tbl, + APBS_PLL3_SWCR1, APBS_PLL3_SWCR3, MPMU_POSR, POSR_PLL3_LOCK, + CLK_SET_RATE_GATE); + +CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D2, pll1_d2, pll1_d2, "pll1", APBS_PLL1_SWCR2, + BIT(1), 2, 1); +CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D3, pll1_d3, pll1_d3, "pll1", APBS_PLL1_SWCR2, + BIT(2), 3, 1); +CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D4, pll1_d4, pll1_d4, "pll1", APBS_PLL1_SWCR2, + BIT(3), 4, 1); +CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D5, pll1_d5, pll1_d5, "pll1", APBS_PLL1_SWCR2, + BIT(4), 5, 1); +CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D6, pll1_d6, pll1_d6, "pll1", APBS_PLL1_SWCR2, + BIT(5), 6, 1); +CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D7, pll1_d7, pll1_d7, "pll1", APBS_PLL1_SWCR2, + BIT(6), 7, 1); +CCU_FACTOR_GATE_FLAGS_DEFINE(CLK_PLL1_D8, pll1_d8, pll1_d8, "pll1", + APBS_PLL1_SWCR2, BIT(7), 8, 1, CLK_IS_CRITICAL); +CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D11, pll1_d11_223p4, pll1_d11_223p4, "pll1", + APBS_PLL1_SWCR2, BIT(15), 11, 1); +CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D13, pll1_d13_189, pll1_d13_189, "pll1", + APBS_PLL1_SWCR2, BIT(16), 13, 1); +CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D23, pll1_d23_106p8, pll1_d23_106p8, "pll1", + APBS_PLL1_SWCR2, BIT(20), 23, 1); +CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D64, pll1_d64_38p4, pll1_d64_38p4, "pll1", + APBS_PLL1_SWCR2, BIT(0), 64, 1); +CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D10_AUD, pll1_aud_245p7, pll1_aud_245p7, "pll1", + APBS_PLL1_SWCR2, BIT(10), 10, 1); +CCU_FACTOR_GATE_DEFINE(CLK_PLL1_D100_AUD, pll1_aud_24p5, pll1_aud_24p5, "pll1", + APBS_PLL1_SWCR2, BIT(11), 100, 1); + +CCU_FACTOR_GATE_DEFINE(CLK_PLL2_D1, pll2_d1, pll2_d1, "pll2", APBS_PLL2_SWCR2, + BIT(0), 1, 1); +CCU_FACTOR_GATE_DEFINE(CLK_PLL2_D2, pll2_d2, pll2_d2, "pll2", APBS_PLL2_SWCR2, + BIT(1), 2, 1); +CCU_FACTOR_GATE_DEFINE(CLK_PLL2_D3, pll2_d3, pll2_d3, "pll2", APBS_PLL2_SWCR2, + BIT(2), 3, 1); +CCU_FACTOR_GATE_DEFINE(CLK_PLL2_D4, pll2_d4, pll2_d4, "pll2", APBS_PLL2_SWCR2, + BIT(3), 4, 1); +CCU_FACTOR_GATE_DEFINE(CLK_PLL2_D5, pll2_d5, pll2_d5, "pll2", APBS_PLL2_SWCR2, + BIT(4), 5, 1); +CCU_FACTOR_GATE_DEFINE(CLK_PLL2_D6, pll2_d6, pll2_d6, "pll2", APBS_PLL2_SWCR2, + BIT(5), 6, 1); +CCU_FACTOR_GATE_DEFINE(CLK_PLL2_D7, pll2_d7, pll2_d7, "pll2", APBS_PLL2_SWCR2, + BIT(6), 7, 1); +CCU_FACTOR_GATE_DEFINE(CLK_PLL2_D8, pll2_d8, pll2_d8, "pll2", APBS_PLL2_SWCR2, + BIT(7), 8, 1); + +CCU_FACTOR_GATE_DEFINE(CLK_PLL3_D1, pll3_d1, pll3_d1, "pll3", APBS_PLL3_SWCR2, + BIT(0), 1, 1); +CCU_FACTOR_GATE_DEFINE(CLK_PLL3_D2, pll3_d2, pll3_d2, "pll3", APBS_PLL3_SWCR2, + BIT(1), 2, 1); +CCU_FACTOR_GATE_DEFINE(CLK_PLL3_D3, pll3_d3, pll3_d3, "pll3", APBS_PLL3_SWCR2, + BIT(2), 3, 1); +CCU_FACTOR_GATE_DEFINE(CLK_PLL3_D4, pll3_d4, pll3_d4, "pll3", APBS_PLL3_SWCR2, + BIT(3), 4, 1); +CCU_FACTOR_GATE_DEFINE(CLK_PLL3_D5, pll3_d5, pll3_d5, "pll3", APBS_PLL3_SWCR2, + BIT(4), 5, 1); +CCU_FACTOR_GATE_DEFINE(CLK_PLL3_D6, pll3_d6, pll3_d6, "pll3", APBS_PLL3_SWCR2, + BIT(5), 6, 1); +CCU_FACTOR_GATE_DEFINE(CLK_PLL3_D7, pll3_d7, pll3_d7, "pll3", APBS_PLL3_SWCR2, + BIT(6), 7, 1); +CCU_FACTOR_GATE_DEFINE(CLK_PLL3_D8, pll3_d8, pll3_d8, "pll3", APBS_PLL3_SWCR2, + BIT(7), 8, 1); + +CCU_FACTOR_DEFINE(CLK_PLL3_20, pll3_20, pll3_20, "pll3_d8", 20, 1); +CCU_FACTOR_DEFINE(CLK_PLL3_40, pll3_40, pll3_40, "pll3_d8", 10, 1); +CCU_FACTOR_DEFINE(CLK_PLL3_80, pll3_80, pll3_80, "pll3_d8", 5, 1); +/* APBS clocks end */ + +/* MPMU clocks start */ +CCU_GATE_DEFINE(CLK_PLL1_307P2, pll1_d8_307p2, pll1_d8_307p2, "pll1_d8", + MPMU_ACGR, BIT(13), 0); + +CCU_FACTOR_DEFINE(CLK_PLL1_76P8, pll1_d32_76p8, pll1_d32_76p8, "pll1_d8_307p2", + 4, 1); + +CCU_FACTOR_DEFINE(CLK_PLL1_61P44, pll1_d40_61p44, pll1_d40_61p44, + "pll1_d8_307p2", 5, 1); + +CCU_FACTOR_DEFINE(CLK_PLL1_153P6, pll1_d16_153p6, pll1_d16_153p6, + "pll1_d8", 2, 1); +CCU_FACTOR_GATE_DEFINE(CLK_PLL1_102P4, pll1_d24_102p4, pll1_d24_102p4, + "pll1_d8", MPMU_ACGR, BIT(12), 3, 1); +CCU_FACTOR_GATE_DEFINE(CLK_PLL1_51P2, pll1_d48_51p2, pll1_d48_51p2, + "pll1_d8", MPMU_ACGR, BIT(7), 6, 1); +CCU_FACTOR_GATE_DEFINE(CLK_PLL1_51P2_AP, pll1_d48_51p2_ap, pll1_d48_51p2_ap, + "pll1_d8", MPMU_ACGR, BIT(11), 6, 1); +CCU_FACTOR_GATE_DEFINE(CLK_PLL1_57P6, pll1_m3d128_57p6, pll1_m3d128_57p6, + "pll1_d8", MPMU_ACGR, BIT(8), 16, 3); +CCU_FACTOR_GATE_DEFINE(CLK_PLL1_25P6, pll1_d96_25p6, pll1_d96_25p6, + "pll1_d8", MPMU_ACGR, BIT(4), 12, 1); +CCU_FACTOR_GATE_DEFINE(CLK_PLL1_12P8, pll1_d192_12p8, pll1_d192_12p8, + "pll1_d8", MPMU_ACGR, BIT(3), 24, 1); +CCU_FACTOR_GATE_DEFINE(CLK_PLL1_12P8_WDT, pll1_d192_12p8_wdt, pll1_d192_12p8_wdt, + "pll1_d8", MPMU_ACGR, BIT(19), 24, 1); +CCU_FACTOR_GATE_DEFINE(CLK_PLL1_6P4, pll1_d384_6p4, pll1_d384_6p4, + "pll1_d8", MPMU_ACGR, BIT(2), 48, 1); + +CCU_FACTOR_DEFINE(CLK_PLL1_3P2, pll1_d768_3p2, pll1_d768_3p2, + "pll1_d384_6p4", 2, 1); +CCU_FACTOR_DEFINE(CLK_PLL1_1P6, pll1_d1536_1p6, pll1_d1536_1p6, + "pll1_d384_6p4", 4, 1); +CCU_FACTOR_DEFINE(CLK_PLL1_0P8, pll1_d3072_0p8, pll1_d3072_0p8, + "pll1_d384_6p4", 8, 1); + +CCU_GATE_DEFINE(CLK_PLL1_409P6, pll1_d6_409p6, pll1_d6_409p6, "pll1_d6", + MPMU_ACGR, BIT(0), 0); +CCU_FACTOR_GATE_DEFINE(CLK_PLL1_204P8, pll1_d12_204p8, pll1_d12_204p8, + "pll1_d6", MPMU_ACGR, BIT(5), 2, 1); + +CCU_GATE_DEFINE(CLK_PLL1_491, pll1_d5_491p52, pll1_d5_491p52, "pll1_d5", + MPMU_ACGR, BIT(21), 0); +CCU_FACTOR_GATE_DEFINE(CLK_PLL1_245P76, pll1_d10_245p76, pll1_d10_245p76, + "pll1_d5", MPMU_ACGR, BIT(18), 2, 1); + +CCU_GATE_DEFINE(CLK_PLL1_614, pll1_d4_614p4, pll1_d4_614p4, "pll1_d4", + MPMU_ACGR, BIT(15), 0); +CCU_FACTOR_GATE_DEFINE(CLK_PLL1_47P26, pll1_d52_47p26, pll1_d52_47p26, + "pll1_d4", MPMU_ACGR, BIT(10), 13, 1); +CCU_FACTOR_GATE_DEFINE(CLK_PLL1_31P5, pll1_d78_31p5, pll1_d78_31p5, + "pll1_d4", MPMU_ACGR, BIT(6), 39, 2); + +CCU_GATE_DEFINE(CLK_PLL1_819, pll1_d3_819p2, pll1_d3_819p2, "pll1_d3", + MPMU_ACGR, BIT(14), 0); + +CCU_GATE_DEFINE(CLK_PLL1_1228, pll1_d2_1228p8, pll1_d2_1228p8, "pll1_d2", + MPMU_ACGR, BIT(16), 0); + +CCU_GATE_DEFINE(CLK_SLOW_UART, slow_uart, slow_uart, "clock-32k", MPMU_ACGR, + BIT(1), CLK_IGNORE_UNUSED); +CCU_DDN_DEFINE(CLK_SLOW_UART1, slow_uart1_14p74, slow_uart1_14p74, + "pll1_d16_153p6", MPMU_SUCCR, + CCU_DDN_MASK(16, 13), 16, CCU_DDN_MASK(0, 13), 0, 2, 0); +CCU_DDN_DEFINE(CLK_SLOW_UART2, slow_uart2_48, slow_uart2_48, + "pll1_d4_614p4", MPMU_SUCCR_1, + CCU_DDN_MASK(16, 13), 16, CCU_DDN_MASK(0, 13), 0, 2, 0); + +#if !IS_ENABLED(CONFIG_SPL_BUILD) +CCU_GATE_DEFINE(CLK_WDT, wdt_clk, wdt_clk, "pll1_d96_25p6", MPMU_WDTPCR, + BIT(1), 0); + +CCU_FACTOR_DEFINE(CLK_I2S_153P6, i2s_153p6, i2s_153p6, "pll1_d8_307p2", 2, 1); + +static const char * const i2s_153p6_base_parents[] = { + "i2s_153p6", + "pll1_d8_307p2", +}; + +CCU_MUX_DEFINE(CLK_I2S_153P6_BASE, i2s_153p6_base, i2s_153p6_base, + i2s_153p6_base_parents, ARRAY_SIZE(i2s_153p6_base_parents), + MPMU_FCCR, 29, 1, 0); + +static const char * const i2s_sysclk_src_parents[] = { + "pll1_d96_25p6", + "i2s_153p6_base" +}; + +CCU_MUX_GATE_DEFINE(CLK_I2S_SYSCLK_SRC, i2s_sysclk_src, i2s_sysclk_src, + i2s_sysclk_src_parents, ARRAY_SIZE(i2s_sysclk_src_parents), + MPMU_ISCCR, 30, 1, BIT(31), 0); + +CCU_DDN_DEFINE(CLK_I2S_SYSCLK, i2s_sysclk, i2s_sysclk, "i2s_sysclk_src", + MPMU_ISCCR, CCU_DDN_MASK(0, 15), 0, CCU_DDN_MASK(15, 12), + 15, 1, 0); + +CCU_FACTOR_DEFINE(CLK_I2S_BCLK_FACTOR, i2s_bclk_factor, i2s_bclk_factor, + "i2s_sysclk", 2, 1); +/* + * Divider of i2s_bclk always implies a 1/2 factor, which is + * described by i2s_bclk_factor. + */ +CCU_DIV_GATE_DEFINE(CLK_I2S_BCLK, i2s_bclk, i2s_bclk, "i2s_bclk_factor", + MPMU_ISCCR, 27, 2, BIT(29), 0); + +static const char * const apb_parents[] = { + "pll1_d96_25p6", + "pll1_d48_51p2", + "pll1_d96_25p6", + "pll1_d24_102p4", +}; + +CCU_MUX_DEFINE(CLK_APB, apb_clk, apb_clk, apb_parents, ARRAY_SIZE(apb_parents), + MPMU_APBCSCR, 0, 2, 0); + +CCU_GATE_DEFINE(CLK_WDT_BUS, wdt_bus_clk, wdt_bus_clk, "apb_clk", MPMU_WDTPCR, + BIT(0), 0); + +CCU_GATE_DEFINE(CLK_RIPC, ripc_clk, ripc_clk, "apb_clk", MPMU_RIPCCR, 0x1, 0); +#endif +/* MPMU clocks end */ + +/* APBC clocks start */ +static const char * const uart_clk_parents[] = { + "pll1_m3d128_57p6", + "slow_uart1_14p74", + "slow_uart2_48", +}; + +CCU_MUX_GATE_DEFINE(CLK_UART0, uart0_clk, uart0_clk, uart_clk_parents, + ARRAY_SIZE(uart_clk_parents), APBC_UART1_CLK_RST, + 4, 3, BIT(1) | BIT(0), 0); + +static const char * const twsi_parents[] = { + "pll1_d78_31p5", + "pll1_d48_51p2", + "pll1_d40_61p44", +}; + +CCU_MUX_GATE_DEFINE(CLK_TWSI2, twsi2_clk, twsi2_clk, twsi_parents, + ARRAY_SIZE(twsi_parents), APBC_TWSI2_CLK_RST, + 4, 3, BIT(1) | BIT(0), 0); +/* + * APBC_TWSI8_CLK_RST has a quirk that reading always results in zero. + * Combine functional and bus bits together as a gate to avoid sharing the + * write-only register between different clock hardwares. + */ +CCU_GATE_DEFINE(CLK_TWSI8, twsi8_clk, twsi8_clk, "pll1_d78_31p5", + APBC_TWSI8_CLK_RST, BIT(1) | BIT(0), 0); + +#if !IS_ENABLED(CONFIG_SPL_BUILD) +CCU_MUX_GATE_DEFINE(CLK_UART2, uart2_clk, uart2_clk, uart_clk_parents, + ARRAY_SIZE(uart_clk_parents), APBC_UART2_CLK_RST, + 4, 3, BIT(1) | BIT(0), 0); +CCU_MUX_GATE_DEFINE(CLK_UART3, uart3_clk, uart3_clk, uart_clk_parents, + ARRAY_SIZE(uart_clk_parents), APBC_UART3_CLK_RST, + 4, 3, BIT(1) | BIT(0), 0); +CCU_MUX_GATE_DEFINE(CLK_UART4, uart4_clk, uart4_clk, uart_clk_parents, + ARRAY_SIZE(uart_clk_parents), APBC_UART4_CLK_RST, + 4, 3, BIT(1) | BIT(0), 0); +CCU_MUX_GATE_DEFINE(CLK_UART5, uart5_clk, uart5_clk, uart_clk_parents, + ARRAY_SIZE(uart_clk_parents), APBC_UART5_CLK_RST, + 4, 3, BIT(1) | BIT(0), 0); +CCU_MUX_GATE_DEFINE(CLK_UART6, uart6_clk, uart6_clk, uart_clk_parents, + ARRAY_SIZE(uart_clk_parents), APBC_UART6_CLK_RST, + 4, 3, BIT(1) | BIT(0), 0); +CCU_MUX_GATE_DEFINE(CLK_UART7, uart7_clk, uart7_clk, uart_clk_parents, + ARRAY_SIZE(uart_clk_parents), APBC_UART7_CLK_RST, + 4, 3, BIT(1) | BIT(0), 0); +CCU_MUX_GATE_DEFINE(CLK_UART8, uart8_clk, uart8_clk, uart_clk_parents, + ARRAY_SIZE(uart_clk_parents), APBC_UART8_CLK_RST, + 4, 3, BIT(1) | BIT(0), 0); +CCU_MUX_GATE_DEFINE(CLK_UART9, uart9_clk, uart9_clk, uart_clk_parents, + ARRAY_SIZE(uart_clk_parents), APBC_UART9_CLK_RST, + 4, 3, BIT(1) | BIT(0), 0); + +CCU_GATE_DEFINE(CLK_GPIO, gpio_clk, gpio_clk, "clock-24m", APBC_GPIO_CLK_RST, + BIT(1) | BIT(0), 0); + +static const char * const pwm_parents[] = { + "pll1_d192_12p8", + "clock-32k", +}; + +CCU_MUX_GATE_DEFINE(CLK_PWM0, pwm0_clk, pwm0_clk, pwm_parents, + ARRAY_SIZE(pwm_parents), APBC_PWM0_CLK_RST, 4, 3, + BIT(1) | BIT(0), 0); +CCU_MUX_GATE_DEFINE(CLK_PWM1, pwm1_clk, pwm1_clk, pwm_parents, + ARRAY_SIZE(pwm_parents), APBC_PWM1_CLK_RST, 4, 3, + BIT(1) | BIT(0), 0); +CCU_MUX_GATE_DEFINE(CLK_PWM2, pwm2_clk, pwm2_clk, pwm_parents, + ARRAY_SIZE(pwm_parents), APBC_PWM2_CLK_RST, 4, 3, + BIT(1) | BIT(0), 0); +CCU_MUX_GATE_DEFINE(CLK_PWM3, pwm3_clk, pwm3_clk, pwm_parents, + ARRAY_SIZE(pwm_parents), APBC_PWM3_CLK_RST, 4, 3, + BIT(1) | BIT(0), 0); +CCU_MUX_GATE_DEFINE(CLK_PWM4, pwm4_clk, pwm4_clk, pwm_parents, + ARRAY_SIZE(pwm_parents), APBC_PWM4_CLK_RST, 4, 3, + BIT(1) | BIT(0), 0); +CCU_MUX_GATE_DEFINE(CLK_PWM5, pwm5_clk, pwm5_clk, pwm_parents, + ARRAY_SIZE(pwm_parents), APBC_PWM5_CLK_RST, 4, 3, + BIT(1) | BIT(0), 0); +CCU_MUX_GATE_DEFINE(CLK_PWM6, pwm6_clk, pwm6_clk, pwm_parents, + ARRAY_SIZE(pwm_parents), APBC_PWM6_CLK_RST, 4, 3, + BIT(1) | BIT(0), 0); +CCU_MUX_GATE_DEFINE(CLK_PWM7, pwm7_clk, pwm7_clk, pwm_parents, + ARRAY_SIZE(pwm_parents), APBC_PWM7_CLK_RST, 4, 3, + BIT(1) | BIT(0), 0); +CCU_MUX_GATE_DEFINE(CLK_PWM8, pwm8_clk, pwm8_clk, pwm_parents, + ARRAY_SIZE(pwm_parents), APBC_PWM8_CLK_RST, 4, 3, + BIT(1) | BIT(0), 0); +CCU_MUX_GATE_DEFINE(CLK_PWM9, pwm9_clk, pwm9_clk, pwm_parents, + ARRAY_SIZE(pwm_parents), APBC_PWM9_CLK_RST, 4, 3, + BIT(1) | BIT(0), 0); +CCU_MUX_GATE_DEFINE(CLK_PWM10, pwm10_clk, pwm10_clk, pwm_parents, + ARRAY_SIZE(pwm_parents), APBC_PWM10_CLK_RST, 4, 3, + BIT(1) | BIT(0), 0); +CCU_MUX_GATE_DEFINE(CLK_PWM11, pwm11_clk, pwm11_clk, pwm_parents, + ARRAY_SIZE(pwm_parents), APBC_PWM11_CLK_RST, 4, 3, + BIT(1) | BIT(0), 0); +CCU_MUX_GATE_DEFINE(CLK_PWM12, pwm12_clk, pwm12_clk, pwm_parents, + ARRAY_SIZE(pwm_parents), APBC_PWM12_CLK_RST, 4, 3, + BIT(1) | BIT(0), 0); +CCU_MUX_GATE_DEFINE(CLK_PWM13, pwm13_clk, pwm13_clk, pwm_parents, + ARRAY_SIZE(pwm_parents), APBC_PWM13_CLK_RST, 4, 3, + BIT(1) | BIT(0), 0); +CCU_MUX_GATE_DEFINE(CLK_PWM14, pwm14_clk, pwm14_clk, pwm_parents, + ARRAY_SIZE(pwm_parents), APBC_PWM14_CLK_RST, 4, 3, + BIT(1) | BIT(0), 0); +CCU_MUX_GATE_DEFINE(CLK_PWM15, pwm15_clk, pwm15_clk, pwm_parents, + ARRAY_SIZE(pwm_parents), APBC_PWM15_CLK_RST, 4, 3, + BIT(1) | BIT(0), 0); +CCU_MUX_GATE_DEFINE(CLK_PWM16, pwm16_clk, pwm16_clk, pwm_parents, + ARRAY_SIZE(pwm_parents), APBC_PWM16_CLK_RST, 4, 3, + BIT(1) | BIT(0), 0); +CCU_MUX_GATE_DEFINE(CLK_PWM17, pwm17_clk, pwm17_clk, pwm_parents, + ARRAY_SIZE(pwm_parents), APBC_PWM17_CLK_RST, 4, 3, + BIT(1) | BIT(0), 0); +CCU_MUX_GATE_DEFINE(CLK_PWM18, pwm18_clk, pwm18_clk, pwm_parents, + ARRAY_SIZE(pwm_parents), APBC_PWM18_CLK_RST, 4, 3, + BIT(1) | BIT(0), 0); +CCU_MUX_GATE_DEFINE(CLK_PWM19, pwm19_clk, pwm19_clk, pwm_parents, + ARRAY_SIZE(pwm_parents), APBC_PWM19_CLK_RST, 4, 3, + BIT(1) | BIT(0), 0); + +static const char * const ssp_parents[] = { + "pll1_d384_6p4", + "pll1_d192_12p8", + "pll1_d96_25p6", + "pll1_d48_51p2", + "pll1_d768_3p2", + "pll1_d1536_1p6", + "pll1_d3072_0p8", +}; + +CCU_MUX_GATE_DEFINE(CLK_SSP3, ssp3_clk, ssp3_clk, ssp_parents, + ARRAY_SIZE(ssp_parents), APBC_SSP3_CLK_RST, 4, 3, + BIT(1), 0); + +CCU_GATE_DEFINE(CLK_RTC, rtc_clk, rtc_clk, "clock-32k", APBC_RTC_CLK_RST, + BIT(7) | BIT(1) | BIT(0), 0); + +CCU_MUX_GATE_DEFINE(CLK_TWSI0, twsi0_clk, twsi0_clk, twsi_parents, + ARRAY_SIZE(twsi_parents), APBC_TWSI0_CLK_RST, + 4, 3, BIT(1) | BIT(0), 0); +CCU_MUX_GATE_DEFINE(CLK_TWSI1, twsi1_clk, twsi1_clk, twsi_parents, + ARRAY_SIZE(twsi_parents), APBC_TWSI1_CLK_RST, + 4, 3, BIT(1) | BIT(0), 0); +CCU_MUX_GATE_DEFINE(CLK_TWSI4, twsi4_clk, twsi4_clk, twsi_parents, + ARRAY_SIZE(twsi_parents), APBC_TWSI4_CLK_RST, + 4, 3, BIT(1) | BIT(0), 0); +CCU_MUX_GATE_DEFINE(CLK_TWSI5, twsi5_clk, twsi5_clk, twsi_parents, + ARRAY_SIZE(twsi_parents), APBC_TWSI5_CLK_RST, + 4, 3, BIT(1) | BIT(0), 0); +CCU_MUX_GATE_DEFINE(CLK_TWSI6, twsi6_clk, twsi6_clk, twsi_parents, + ARRAY_SIZE(twsi_parents), APBC_TWSI6_CLK_RST, + 4, 3, BIT(1) | BIT(0), 0); +CCU_MUX_GATE_DEFINE(CLK_TWSI7, twsi7_clk, twsi7_clk, twsi_parents, + ARRAY_SIZE(twsi_parents), APBC_TWSI7_CLK_RST, + 4, 3, BIT(1) | BIT(0), 0); + +static const char * const timer_parents[] = { + "pll1_d192_12p8", + "clock-32k", + "pll1_d384_6p4", + "clock-3m", + "clock-1m", +}; + +CCU_MUX_GATE_DEFINE(CLK_TIMERS1, timers1_clk, timers1_clk, timer_parents, + ARRAY_SIZE(timer_parents), APBC_TIMERS1_CLK_RST, 4, 3, + BIT(1) | BIT(0), 0); +CCU_MUX_GATE_DEFINE(CLK_TIMERS2, timers2_clk, timers2_clk, timer_parents, + ARRAY_SIZE(timer_parents), APBC_TIMERS2_CLK_RST, 4, 3, + BIT(1) | BIT(0), 0); + +CCU_GATE_DEFINE(CLK_AIB, aib_clk, aib_clk, "clock-24m", APBC_AIB_CLK_RST, + BIT(1) | BIT(0), 0); + +CCU_GATE_DEFINE(CLK_ONEWIRE, onewire_clk, onewire_clk, "clock-24m", + APBC_ONEWIRE_CLK_RST, BIT(1) | BIT(0), 0); + +/* + * When i2s_bclk is selected as the parent clock of sspa, + * the hardware requires bit3 to be set + */ +CCU_GATE_DEFINE(CLK_SSPA0_I2S_BCLK, sspa0_i2s_bclk, sspa0_i2s_bclk, "i2s_bclk", + APBC_SSPA0_CLK_RST, BIT(3), 0); +CCU_GATE_DEFINE(CLK_SSPA1_I2S_BCLK, sspa1_i2s_bclk, sspa1_i2s_bclk, "i2s_bclk", + APBC_SSPA1_CLK_RST, BIT(3), 0); + +static const char * const sspa0_parents[] = { + "pll1_d384_6p4", + "pll1_d192_12p8", + "pll1_d96_25p6", + "pll1_d48_51p2", + "pll1_d768_3p2", + "pll1_d1536_1p6", + "pll1_d3072_0p8", + "sspa0_i2s_bclk", +}; + +CCU_MUX_GATE_DEFINE(CLK_SSPA0, sspa0_clk, sspa0_clk, sspa0_parents, + ARRAY_SIZE(sspa0_parents), APBC_SSPA0_CLK_RST, 4, 3, + BIT(1), 0); + +static const char * const sspa1_parents[] = { + "pll1_d384_6p4", + "pll1_d192_12p8", + "pll1_d96_25p6", + "pll1_d48_51p2", + "pll1_d768_3p2", + "pll1_d1536_1p6", + "pll1_d3072_0p8", + "sspa1_i2s_bclk", +}; + +CCU_MUX_GATE_DEFINE(CLK_SSPA1, sspa1_clk, sspa1_clk, sspa1_parents, + ARRAY_SIZE(sspa1_parents), APBC_SSPA1_CLK_RST, 4, 3, + BIT(1), 0); + +CCU_GATE_DEFINE(CLK_DRO, dro_clk, dro_clk, "apb_clk", APBC_DRO_CLK_RST, + BIT(1) | BIT(0), 0); +CCU_GATE_DEFINE(CLK_IR, ir_clk, ir_clk, "apb_clk", APBC_IR_CLK_RST, + BIT(1) | BIT(0), 0); +CCU_GATE_DEFINE(CLK_TSEN, tsen_clk, tsen_clk, "apb_clk", APBC_TSEN_CLK_RST, + BIT(1) | BIT(0), 0); +CCU_GATE_DEFINE(CLK_IPC_AP2AUD, ipc_ap2aud_clk, ipc_ap2aud_clk, "apb_clk", + APBC_IPC_AP2AUD_CLK_RST, BIT(1) | BIT(0), 0); + +static const char * const can_parents[] = { + "pll3_20", + "pll3_40", + "pll3_80", +}; + +CCU_MUX_GATE_DEFINE(CLK_CAN0, can0_clk, can0_clk, can_parents, + ARRAY_SIZE(can_parents), APBC_CAN0_CLK_RST, 4, 3, + BIT(1), 0); +CCU_GATE_DEFINE(CLK_CAN0_BUS, can0_bus_clk, can0_bus_clk, "clock-24m", + APBC_CAN0_CLK_RST, BIT(0), 0); + +CCU_GATE_DEFINE(CLK_UART0_BUS, uart0_bus_clk, uart0_bus_clk, "apb_clk", + APBC_UART1_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_UART2_BUS, uart2_bus_clk, uart2_bus_clk, "apb_clk", + APBC_UART2_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_UART3_BUS, uart3_bus_clk, uart3_bus_clk, "apb_clk", + APBC_UART3_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_UART4_BUS, uart4_bus_clk, uart4_bus_clk, "apb_clk", + APBC_UART4_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_UART5_BUS, uart5_bus_clk, uart5_bus_clk, "apb_clk", + APBC_UART5_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_UART6_BUS, uart6_bus_clk, uart6_bus_clk, "apb_clk", + APBC_UART6_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_UART7_BUS, uart7_bus_clk, uart7_bus_clk, "apb_clk", + APBC_UART7_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_UART8_BUS, uart8_bus_clk, uart8_bus_clk, "apb_clk", + APBC_UART8_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_UART9_BUS, uart9_bus_clk, uart9_bus_clk, "apb_clk", + APBC_UART9_CLK_RST, BIT(0), 0); + +CCU_GATE_DEFINE(CLK_GPIO_BUS, gpio_bus_clk, gpio_bus_clk, "apb_clk", + APBC_GPIO_CLK_RST, BIT(0), 0); + +CCU_GATE_DEFINE(CLK_PWM0_BUS, pwm0_bus_clk, pwm0_bus_clk, "apb_clk", + APBC_PWM0_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_PWM1_BUS, pwm1_bus_clk, pwm1_bus_clk, "apb_clk", + APBC_PWM1_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_PWM2_BUS, pwm2_bus_clk, pwm2_bus_clk, "apb_clk", + APBC_PWM2_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_PWM3_BUS, pwm3_bus_clk, pwm3_bus_clk, "apb_clk", + APBC_PWM3_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_PWM4_BUS, pwm4_bus_clk, pwm4_bus_clk, "apb_clk", + APBC_PWM4_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_PWM5_BUS, pwm5_bus_clk, pwm5_bus_clk, "apb_clk", + APBC_PWM5_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_PWM6_BUS, pwm6_bus_clk, pwm6_bus_clk, "apb_clk", + APBC_PWM6_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_PWM7_BUS, pwm7_bus_clk, pwm7_bus_clk, "apb_clk", + APBC_PWM7_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_PWM8_BUS, pwm8_bus_clk, pwm8_bus_clk, "apb_clk", + APBC_PWM8_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_PWM9_BUS, pwm9_bus_clk, pwm9_bus_clk, "apb_clk", + APBC_PWM9_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_PWM10_BUS, pwm10_bus_clk, pwm10_bus_clk, "apb_clk", + APBC_PWM10_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_PWM11_BUS, pwm11_bus_clk, pwm11_bus_clk, "apb_clk", + APBC_PWM11_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_PWM12_BUS, pwm12_bus_clk, pwm12_bus_clk, "apb_clk", + APBC_PWM12_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_PWM13_BUS, pwm13_bus_clk, pwm13_bus_clk, "apb_clk", + APBC_PWM13_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_PWM14_BUS, pwm14_bus_clk, pwm14_bus_clk, "apb_clk", + APBC_PWM14_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_PWM15_BUS, pwm15_bus_clk, pwm15_bus_clk, "apb_clk", + APBC_PWM15_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_PWM16_BUS, pwm16_bus_clk, pwm16_bus_clk, "apb_clk", + APBC_PWM16_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_PWM17_BUS, pwm17_bus_clk, pwm17_bus_clk, "apb_clk", + APBC_PWM17_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_PWM18_BUS, pwm18_bus_clk, pwm18_bus_clk, "apb_clk", + APBC_PWM18_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_PWM19_BUS, pwm19_bus_clk, pwm19_bus_clk, "apb_clk", + APBC_PWM19_CLK_RST, BIT(0), 0); + +CCU_GATE_DEFINE(CLK_SSP3_BUS, ssp3_bus_clk, ssp3_bus_clk, "apb_clk", + APBC_SSP3_CLK_RST, BIT(0), 0); + +CCU_GATE_DEFINE(CLK_RTC_BUS, rtc_bus_clk, rtc_bus_clk, "apb_clk", + APBC_RTC_CLK_RST, BIT(0), 0); + +CCU_GATE_DEFINE(CLK_TWSI0_BUS, twsi0_bus_clk, twsi0_bus_clk, "apb_clk", + APBC_TWSI0_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_TWSI1_BUS, twsi1_bus_clk, twsi1_bus_clk, "apb_clk", + APBC_TWSI1_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_TWSI2_BUS, twsi2_bus_clk, twsi2_bus_clk, "apb_clk", + APBC_TWSI2_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_TWSI4_BUS, twsi4_bus_clk, twsi4_bus_clk, "apb_clk", + APBC_TWSI4_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_TWSI5_BUS, twsi5_bus_clk, twsi5_bus_clk, "apb_clk", + APBC_TWSI5_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_TWSI6_BUS, twsi6_bus_clk, twsi6_bus_clk, "apb_clk", + APBC_TWSI6_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_TWSI7_BUS, twsi7_bus_clk, twsi7_bus_clk, "apb_clk", + APBC_TWSI7_CLK_RST, BIT(0), 0); +CCU_FACTOR_DEFINE(CLK_TWSI8_BUS, twsi8_bus_clk, twsi8_bus_clk, "apb_clk", 1, 1); + +CCU_GATE_DEFINE(CLK_TIMERS1_BUS, timers1_bus_clk, timers1_bus_clk, "apb_clk", + APBC_TIMERS1_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_TIMERS2_BUS, timers2_bus_clk, timers2_bus_clk, "apb_clk", + APBC_TIMERS2_CLK_RST, BIT(0), 0); + +CCU_GATE_DEFINE(CLK_AIB_BUS, aib_bus_clk, aib_bus_clk, "apb_clk", + APBC_AIB_CLK_RST, BIT(0), 0); + +CCU_GATE_DEFINE(CLK_ONEWIRE_BUS, onewire_bus_clk, onewire_bus_clk, "apb_clk", + APBC_ONEWIRE_CLK_RST, BIT(0), 0); + +CCU_GATE_DEFINE(CLK_SSPA0_BUS, sspa0_bus_clk, sspa0_bus_clk, "apb_clk", + APBC_SSPA0_CLK_RST, BIT(0), 0); +CCU_GATE_DEFINE(CLK_SSPA1_BUS, sspa1_bus_clk, sspa1_bus_clk, "apb_clk", + APBC_SSPA1_CLK_RST, BIT(0), 0); + +CCU_GATE_DEFINE(CLK_TSEN_BUS, tsen_bus_clk, tsen_bus_clk, "apb_clk", + APBC_TSEN_CLK_RST, BIT(0), 0); + +CCU_GATE_DEFINE(CLK_IPC_AP2AUD_BUS, ipc_ap2aud_bus_clk, ipc_ap2aud_bus_clk, + "apb_clk", APBC_IPC_AP2AUD_CLK_RST, BIT(0), 0); +#endif +/* APBC clocks end */ + +/* APMU clocks start */ +static const char * const pmua_aclk_parents[] = { + "pll1_d10_245p76", + "pll1_d8_307p2", +}; + +CCU_MUX_DIV_FC_DEFINE(CLK_PMUA_ACLK, pmua_aclk, pmua_aclk, pmua_aclk_parents, + ARRAY_SIZE(pmua_aclk_parents), + APMU_ACLK_CLK_CTRL, APMU_ACLK_CLK_CTRL, 1, 2, BIT(4), + 0, 1, 0); + +static const char * const emmc_parents[] = { + "pll1_d6_409p6", + "pll1_d4_614p4", + "pll1_d52_47p26", + "pll1_d3_819p2", +}; + +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_EMMC, emmc_clk, emmc_clk, emmc_parents, + ARRAY_SIZE(emmc_parents), + APMU_PMUA_EM_CLK_RES_CTRL, + APMU_PMUA_EM_CLK_RES_CTRL, 8, 3, BIT(11), + 6, 2, BIT(4), 0); +CCU_DIV_GATE_DEFINE(CLK_EMMC_X, emmc_x_clk, emmc_x_clk, "pll1_d2_1228p8", + APMU_PMUA_EM_CLK_RES_CTRL, 12, + 3, BIT(15), 0); + +CCU_GATE_DEFINE(CLK_EMMC_BUS, emmc_bus_clk, emmc_bus_clk, "pmua_aclk", + APMU_PMUA_EM_CLK_RES_CTRL, BIT(3), 0); + +#if !IS_ENABLED(CONFIG_SPL_BUILD) +static const char * const cci550_clk_parents[] = { + "pll1_d5_491p52", + "pll1_d4_614p4", + "pll1_d3_819p2", + "pll2_d3", +}; + +CCU_MUX_DIV_FC_DEFINE(CLK_CCI550, cci550_clk, cci550_clk, cci550_clk_parents, + ARRAY_SIZE(cci550_clk_parents), + APMU_CCI550_CLK_CTRL, APMU_CCI550_CLK_CTRL, 8, 3, + BIT(12), 0, 2, CLK_IS_CRITICAL); + +static const char * const cpu_c0_hi_clk_parents[] = { + "pll3_d2", + "pll3_d1", +}; + +CCU_MUX_DEFINE(CLK_CPU_C0_HI, cpu_c0_hi_clk, cpu_c0_hi_clk, + cpu_c0_hi_clk_parents, ARRAY_SIZE(cpu_c0_hi_clk_parents), + APMU_CPU_C0_CLK_CTRL, 13, 1, 0); +static const char * const cpu_c0_clk_parents[] = { + "pll1_d4_614p4", + "pll1_d3_819p2", + "pll1_d6_409p6", + "pll1_d5_491p52", + "pll1_d2_1228p8", + "pll3_d3", + "pll2_d3", + "cpu_c0_hi_clk", +}; + +CCU_MUX_FC_DEFINE(CLK_CPU_C0_CORE, cpu_c0_core_clk, cpu_c0_core_clk, + cpu_c0_clk_parents, ARRAY_SIZE(cpu_c0_clk_parents), + APMU_CPU_C0_CLK_CTRL, APMU_CPU_C0_CLK_CTRL, + BIT(12), 0, 3, CLK_IS_CRITICAL); +CCU_DIV_DEFINE(CLK_CPU_C0_ACE, cpu_c0_ace_clk, cpu_c0_ace_clk, + "cpu_c0_core_clk", APMU_CPU_C0_CLK_CTRL, 6, 3, CLK_IS_CRITICAL); +CCU_DIV_DEFINE(CLK_CPU_C0_TCM, cpu_c0_tcm_clk, cpu_c0_tcm_clk, + "cpu_c0_core_clk", APMU_CPU_C0_CLK_CTRL, 9, 3, CLK_IS_CRITICAL); + +static const char * const cpu_c1_hi_clk_parents[] = { + "pll3_d2", + "pll3_d1", +}; + +CCU_MUX_DEFINE(CLK_CPU_C1_HI, cpu_c1_hi_clk, cpu_c1_hi_clk, + cpu_c1_hi_clk_parents, ARRAY_SIZE(cpu_c1_hi_clk_parents), + APMU_CPU_C1_CLK_CTRL, 13, 1, 0); +static const char * const cpu_c1_clk_parents[] = { + "pll1_d4_614p4", + "pll1_d3_819p2", + "pll1_d6_409p6", + "pll1_d5_491p52", + "pll1_d2_1228p8", + "pll3_d3", + "pll2_d3", + "cpu_c1_hi_clk", +}; + +CCU_MUX_FC_DEFINE(CLK_CPU_C1_CORE, cpu_c1_core_clk, cpu_c1_core_clk, + cpu_c1_clk_parents, ARRAY_SIZE(cpu_c1_clk_parents), + APMU_CPU_C1_CLK_CTRL, APMU_CPU_C1_CLK_CTRL, + BIT(12), 0, 3, CLK_IS_CRITICAL); +CCU_DIV_DEFINE(CLK_CPU_C1_ACE, cpu_c1_ace_clk, cpu_c1_ace_clk, + "cpu_c1_core_clk", APMU_CPU_C1_CLK_CTRL, 6, 3, CLK_IS_CRITICAL); + +static const char * const jpg_parents[] = { + "pll1_d4_614p4", + "pll1_d6_409p6", + "pll1_d5_491p52", + "pll1_d3_819p2", + "pll1_d2_1228p8", + "pll2_d4", + "pll2_d3", +}; + +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_JPG, jpg_clk, jpg_clk, jpg_parents, + ARRAY_SIZE(jpg_parents), + APMU_JPG_CLK_RES_CTRL, + APMU_JPG_CLK_RES_CTRL, + 5, 3, BIT(15), 2, 3, BIT(1), 0); + +static const char * const ccic2phy_parents[] = { + "pll1_d24_102p4", + "pll1_d48_51p2_ap", +}; + +CCU_MUX_GATE_DEFINE(CLK_CCIC2PHY, ccic2phy_clk, ccic2phy_clk, ccic2phy_parents, + ARRAY_SIZE(ccic2phy_parents), APMU_CSI_CCIC2_CLK_RES_CTRL, + 7, 1, BIT(5), 0); + +static const char * const ccic3phy_parents[] = { + "pll1_d24_102p4", + "pll1_d48_51p2_ap", +}; + +CCU_MUX_GATE_DEFINE(CLK_CCIC3PHY, ccic3phy_clk, ccic3phy_clk, ccic3phy_parents, + ARRAY_SIZE(ccic3phy_parents), APMU_CSI_CCIC2_CLK_RES_CTRL, + 31, 1, BIT(30), 0); + +static const char * const csi_parents[] = { + "pll1_d5_491p52", + "pll1_d6_409p6", + "pll1_d4_614p4", + "pll1_d3_819p2", + "pll2_d2", + "pll2_d3", + "pll2_d4", + "pll1_d2_1228p8", +}; + +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_CSI, csi_clk, csi_clk, csi_parents, + ARRAY_SIZE(csi_parents), + APMU_CSI_CCIC2_CLK_RES_CTRL, + APMU_CSI_CCIC2_CLK_RES_CTRL, 20, 3, BIT(15), + 16, 3, BIT(4), 0); + +static const char * const camm_parents[] = { + "pll1_d8_307p2", + "pll2_d5", + "pll1_d6_409p6", + "clock-24m", +}; + +CCU_MUX_DIV_GATE_DEFINE(CLK_CAMM0, camm0_clk, camm0_clk, camm_parents, + ARRAY_SIZE(camm_parents), + APMU_CSI_CCIC2_CLK_RES_CTRL, 23, 4, 8, 2, + BIT(28), 0); +CCU_MUX_DIV_GATE_DEFINE(CLK_CAMM1, camm1_clk, camm1_clk, camm_parents, + ARRAY_SIZE(camm_parents), + APMU_CSI_CCIC2_CLK_RES_CTRL, 23, 4, 8, 2, + BIT(6), 0); +CCU_MUX_DIV_GATE_DEFINE(CLK_CAMM2, camm2_clk, camm2_clk, camm_parents, + ARRAY_SIZE(camm_parents), + APMU_CSI_CCIC2_CLK_RES_CTRL, 23, 4, 8, 2, + BIT(3), 0); + +static const char * const isp_cpp_parents[] = { + "pll1_d8_307p2", + "pll1_d6_409p6", +}; + +CCU_MUX_DIV_GATE_DEFINE(CLK_ISP_CPP, isp_cpp_clk, isp_cpp_clk, isp_cpp_parents, + ARRAY_SIZE(isp_cpp_parents), + APMU_ISP_CLK_RES_CTRL, 24, 2, 26, 1, + BIT(28), 0); +static const char * const isp_bus_parents[] = { + "pll1_d6_409p6", + "pll1_d5_491p52", + "pll1_d8_307p2", + "pll1_d10_245p76", +}; + +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_ISP_BUS, isp_bus_clk, isp_bus_clk, + isp_bus_parents, ARRAY_SIZE(isp_cpp_parents), + APMU_ISP_CLK_RES_CTRL, + APMU_ISP_CLK_RES_CTRL, 18, 3, BIT(23), + 21, 2, BIT(17), 0); +static const char * const isp_parents[] = { + "pll1_d6_409p6", + "pll1_d5_491p52", + "pll1_d4_614p4", + "pll1_d8_307p2", +}; + +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_ISP, isp_clk, isp_clk, isp_parents, + ARRAY_SIZE(isp_parents), + APMU_ISP_CLK_RES_CTRL, + APMU_ISP_CLK_RES_CTRL, + 4, 3, BIT(7), 8, 2, BIT(1), 0); + +static const char * const dpumclk_parents[] = { + "pll1_d6_409p6", + "pll1_d5_491p52", + "pll1_d4_614p4", + "pll1_d8_307p2", +}; + +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_DPU_MCLK, dpu_mclk, dpu_mclk, + dpumclk_parents, ARRAY_SIZE(dpumclk_parents), + APMU_LCD_CLK_RES_CTRL2, APMU_LCD_CLK_RES_CTRL1, + 1, 4, BIT(29), 5, 3, BIT(0), 0); + +static const char * const dpuesc_parents[] = { + "pll1_d48_51p2_ap", + "pll1_d52_47p26", + "pll1_d96_25p6", + "pll1_d32_76p8", +}; + +CCU_MUX_GATE_DEFINE(CLK_DPU_ESC, dpu_esc_clk, dpu_esc_clk, dpuesc_parents, + ARRAY_SIZE(dpuesc_parents), APMU_LCD_CLK_RES_CTRL1, 0, 2, + BIT(2), 0); + +static const char * const dpubit_parents[] = { + "pll1_d3_819p2", + "pll2_d2", + "pll2_d3", + "pll1_d2_1228p8", + "pll2_d4", + "pll2_d5", + "pll2_d7", + "pll2_d8", +}; + +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_DPU_BIT, dpu_bit_clk, dpu_bit_clk, + dpubit_parents, ARRAY_SIZE(dpubit_parents), + APMU_LCD_CLK_RES_CTRL1, + APMU_LCD_CLK_RES_CTRL1, 17, 3, BIT(31), + 20, 3, BIT(16), 0); + +static const char * const dpupx_parents[] = { + "pll1_d6_409p6", + "pll1_d5_491p52", + "pll1_d4_614p4", + "pll1_d8_307p2", + "pll2_d7", + "pll2_d8", +}; + +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_DPU_PXCLK, dpu_pxclk, dpu_pxclk, + dpupx_parents, ARRAY_SIZE(dpupx_parents), + APMU_LCD_CLK_RES_CTRL2, APMU_LCD_CLK_RES_CTRL1, + 17, 4, BIT(30), 21, 3, BIT(16), 0); + +CCU_GATE_DEFINE(CLK_DPU_HCLK, dpu_hclk, dpu_hclk, "pmua_aclk", + APMU_LCD_CLK_RES_CTRL1, BIT(5), 0); + +static const char * const dpu_spi_parents[] = { + "pll1_d8_307p2", + "pll1_d6_409p6", + "pll1_d10_245p76", + "pll1_d11_223p4", + "pll1_d13_189", + "pll1_d23_106p8", + "pll2_d3", + "pll2_d5", +}; + +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_DPU_SPI, dpu_spi_clk, dpu_spi_clk, + dpu_spi_parents, ARRAY_SIZE(dpu_spi_parents), + APMU_LCD_SPI_CLK_RES_CTRL, + APMU_LCD_SPI_CLK_RES_CTRL, 8, 3, + BIT(7), 12, 3, BIT(1), 0); +CCU_GATE_DEFINE(CLK_DPU_SPI_HBUS, dpu_spi_hbus_clk, dpu_spi_hbus_clk, + "pmua_aclk", APMU_LCD_SPI_CLK_RES_CTRL, BIT(3), 0); +CCU_GATE_DEFINE(CLK_DPU_SPIBUS, dpu_spi_bus_clk, dpu_spi_bus_clk, + "pmua_aclk", APMU_LCD_SPI_CLK_RES_CTRL, BIT(5), 0); +CCU_GATE_DEFINE(CLK_DPU_SPI_ACLK, dpu_spi_aclk, dpu_spi_aclk, + "pmua_aclk", APMU_LCD_SPI_CLK_RES_CTRL, BIT(6), 0); + +static const char * const v2d_parents[] = { + "pll1_d5_491p52", + "pll1_d6_409p6", + "pll1_d8_307p2", + "pll1_d4_614p4", +}; + +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_V2D, v2d_clk, v2d_clk, v2d_parents, + ARRAY_SIZE(v2d_parents), + APMU_LCD_CLK_RES_CTRL1, + APMU_LCD_CLK_RES_CTRL1, 9, 3, BIT(28), 12, 2, + BIT(8), 0); + +static const char * const ccic_4x_parents[] = { + "pll1_d5_491p52", + "pll1_d6_409p6", + "pll1_d4_614p4", + "pll1_d3_819p2", + "pll2_d2", + "pll2_d3", + "pll2_d4", + "pll1_d2_1228p8", +}; + +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_CCIC_4X, ccic_4x_clk, ccic_4x_clk, + ccic_4x_parents, ARRAY_SIZE(ccic_4x_parents), + APMU_CCIC_CLK_RES_CTRL, + APMU_CCIC_CLK_RES_CTRL, 18, 3, + BIT(15), 23, 2, BIT(4), 0); + +static const char * const ccic1phy_parents[] = { + "pll1_d24_102p4", + "pll1_d48_51p2_ap", +}; + +CCU_MUX_GATE_DEFINE(CLK_CCIC1PHY, ccic1phy_clk, ccic1phy_clk, ccic1phy_parents, + ARRAY_SIZE(ccic1phy_parents), APMU_CCIC_CLK_RES_CTRL, 7, 1, + BIT(5), 0); + +CCU_GATE_DEFINE(CLK_SDH_AXI, sdh_axi_aclk, sdh_axi_aclk, "pmua_aclk", + APMU_SDH0_CLK_RES_CTRL, BIT(3), 0); +static const char * const sdh01_parents[] = { + "pll1_d6_409p6", + "pll1_d4_614p4", + "pll2_d8", + "pll2_d5", + "pll1_d11_223p4", + "pll1_d13_189", + "pll1_d23_106p8", +}; + +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_SDH0, sdh0_clk, sdh0_clk, sdh01_parents, + ARRAY_SIZE(sdh01_parents), + APMU_SDH0_CLK_RES_CTRL, + APMU_SDH0_CLK_RES_CTRL, 8, 3, BIT(11), 5, 3, + BIT(4), 0); +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_SDH1, sdh1_clk, sdh1_clk, sdh01_parents, + ARRAY_SIZE(sdh01_parents), + APMU_SDH1_CLK_RES_CTRL, + APMU_SDH1_CLK_RES_CTRL, 8, 3, BIT(11), 5, 3, + BIT(4), 0); +static const char * const sdh2_parents[] = { + "pll1_d6_409p6", + "pll1_d4_614p4", + "pll2_d8", + "pll1_d3_819p2", + "pll1_d11_223p4", + "pll1_d13_189", + "pll1_d23_106p8", +}; + +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_SDH2, sdh2_clk, sdh2_clk, sdh2_parents, + ARRAY_SIZE(sdh2_parents), + APMU_SDH2_CLK_RES_CTRL, + APMU_SDH2_CLK_RES_CTRL, 8, 3, BIT(11), 5, 3, + BIT(4), 0); + +CCU_GATE_DEFINE(CLK_USB_AXI, usb_axi_clk, usb_axi_clk, "pmua_aclk", + APMU_USB_CLK_RES_CTRL, BIT(1), 0); +CCU_GATE_DEFINE(CLK_USB_P1, usb_p1_aclk, usb_p1_aclk, "pmua_aclk", + APMU_USB_CLK_RES_CTRL, BIT(5), 0); +CCU_GATE_DEFINE(CLK_USB30, usb30_clk, usb30_clk, "pmua_aclk", + APMU_USB_CLK_RES_CTRL, BIT(8), 0); + +static const char * const qspi_parents[] = { + "pll1_d6_409p6", + "pll2_d8", + "pll1_d8_307p2", + "pll1_d10_245p76", + "pll1_d11_223p4", + "pll1_d23_106p8", + "pll1_d5_491p52", + "pll1_d13_189", +}; + +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_QSPI, qspi_clk, qspi_clk, qspi_parents, + ARRAY_SIZE(qspi_parents), + APMU_QSPI_CLK_RES_CTRL, + APMU_QSPI_CLK_RES_CTRL, 9, 3, BIT(12), 6, 3, + BIT(4), 0); +CCU_GATE_DEFINE(CLK_QSPI_BUS, qspi_bus_clk, qspi_bus_clk, "pmua_aclk", + APMU_QSPI_CLK_RES_CTRL, BIT(3), 0); +CCU_GATE_DEFINE(CLK_DMA, dma_clk, dma_clk, "pmua_aclk", APMU_DMA_CLK_RES_CTRL, + BIT(3), 0); + +static const char * const aes_parents[] = { + "pll1_d12_204p8", + "pll1_d24_102p4", +}; + +CCU_MUX_GATE_DEFINE(CLK_AES, aes_clk, aes_clk, aes_parents, + ARRAY_SIZE(aes_parents), APMU_AES_CLK_RES_CTRL, 6, 1, + BIT(5), 0); + +static const char * const vpu_parents[] = { + "pll1_d4_614p4", + "pll1_d5_491p52", + "pll1_d3_819p2", + "pll1_d6_409p6", + "pll3_d6", + "pll2_d3", + "pll2_d4", + "pll2_d5", +}; + +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_VPU, vpu_clk, vpu_clk, vpu_parents, + ARRAY_SIZE(vpu_parents), APMU_VPU_CLK_RES_CTRL, + APMU_VPU_CLK_RES_CTRL, 13, 3, BIT(21), 10, 3, + BIT(3), 0); + +static const char * const gpu_parents[] = { + "pll1_d4_614p4", + "pll1_d5_491p52", + "pll1_d3_819p2", + "pll1_d6_409p6", + "pll3_d6", + "pll2_d3", + "pll2_d4", + "pll2_d5", +}; + +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_GPU, gpu_clk, gpu_clk, gpu_parents, + ARRAY_SIZE(gpu_parents), APMU_GPU_CLK_RES_CTRL, + APMU_GPU_CLK_RES_CTRL, 12, 3, BIT(15), 18, 3, + BIT(4), 0); + +static const char * const audio_parents[] = { + "pll1_aud_245p7", + "pll1_d8_307p2", + "pll1_d6_409p6", +}; + +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_AUDIO, audio_clk, audio_clk, audio_parents, + ARRAY_SIZE(audio_parents), + APMU_AUDIO_CLK_RES_CTRL, + APMU_AUDIO_CLK_RES_CTRL, 4, 3, BIT(15), + 7, 3, BIT(12), 0); + +static const char * const hdmi_parents[] = { + "pll1_d6_409p6", + "pll1_d5_491p52", + "pll1_d4_614p4", + "pll1_d8_307p2", +}; + +CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(CLK_HDMI, hdmi_mclk, hdmi_mclk, hdmi_parents, + ARRAY_SIZE(hdmi_parents), + APMU_HDMI_CLK_RES_CTRL, + APMU_HDMI_CLK_RES_CTRL, 1, 4, BIT(29), 5, + 3, BIT(0), 0); + +CCU_GATE_DEFINE(CLK_PCIE0_MASTER, pcie0_master_clk, pcie0_master_clk, + "pmua_aclk", APMU_PCIE_CLK_RES_CTRL_0, BIT(2), 0); +CCU_GATE_DEFINE(CLK_PCIE0_SLAVE, pcie0_slave_clk, pcie0_slave_clk, "pmua_aclk", + APMU_PCIE_CLK_RES_CTRL_0, BIT(1), 0); +CCU_GATE_DEFINE(CLK_PCIE0_DBI, pcie0_dbi_clk, pcie0_dbi_clk, "pmua_aclk", + APMU_PCIE_CLK_RES_CTRL_0, BIT(0), 0); + +CCU_GATE_DEFINE(CLK_PCIE1_MASTER, pcie1_master_clk, pcie1_master_clk, + "pmua_aclk", APMU_PCIE_CLK_RES_CTRL_1, BIT(2), 0); +CCU_GATE_DEFINE(CLK_PCIE1_SLAVE, pcie1_slave_clk, pcie1_slave_clk, "pmua_aclk", + APMU_PCIE_CLK_RES_CTRL_1, BIT(1), 0); +CCU_GATE_DEFINE(CLK_PCIE1_DBI, pcie1_dbi_clk, pcie1_dbi_clk, "pmua_aclk", + APMU_PCIE_CLK_RES_CTRL_1, BIT(0), 0); + +CCU_GATE_DEFINE(CLK_PCIE2_MASTER, pcie2_master_clk, pcie2_master_clk, + "pmua_aclk", APMU_PCIE_CLK_RES_CTRL_2, BIT(2), 0); +CCU_GATE_DEFINE(CLK_PCIE2_SLAVE, pcie2_slave_clk, pcie2_slave_clk, "pmua_aclk", + APMU_PCIE_CLK_RES_CTRL_2, BIT(1), 0); +CCU_GATE_DEFINE(CLK_PCIE2_DBI, pcie2_dbi_clk, pcie2_dbi_clk, "pmua_aclk", + APMU_PCIE_CLK_RES_CTRL_2, BIT(0), 0); + +CCU_GATE_DEFINE(CLK_EMAC0_BUS, emac0_bus_clk, emac0_bus_clk, "pmua_aclk", + APMU_EMAC0_CLK_RES_CTRL, BIT(0), 0); +CCU_GATE_DEFINE(CLK_EMAC0_PTP, emac0_ptp_clk, emac0_ptp_clk, "pll2_d6", + APMU_EMAC0_CLK_RES_CTRL, BIT(15), 0); +CCU_GATE_DEFINE(CLK_EMAC1_BUS, emac1_bus_clk, emac1_bus_clk, "pmua_aclk", + APMU_EMAC1_CLK_RES_CTRL, BIT(0), 0); +CCU_GATE_DEFINE(CLK_EMAC1_PTP, emac1_ptp_clk, emac1_ptp_clk, "pll2_d6", + APMU_EMAC1_CLK_RES_CTRL, BIT(15), 0); + +#endif +/* APMU clocks end */ + +static struct clk *k1_ccu_pll_clks[] = { + &pll1.common.clk, + &pll2.common.clk, + &pll3.common.clk, + &pll1_d2.common.clk, + &pll1_d3.common.clk, + &pll1_d4.common.clk, + &pll1_d5.common.clk, + &pll1_d6.common.clk, + &pll1_d7.common.clk, + &pll1_d8.common.clk, + &pll1_d11_223p4.common.clk, + &pll1_d13_189.common.clk, + &pll1_d23_106p8.common.clk, + &pll1_d64_38p4.common.clk, + &pll1_aud_245p7.common.clk, + &pll1_aud_24p5.common.clk, + &pll2_d1.common.clk, + &pll2_d2.common.clk, + &pll2_d3.common.clk, + &pll2_d4.common.clk, + &pll2_d5.common.clk, + &pll2_d6.common.clk, + &pll2_d7.common.clk, + &pll2_d8.common.clk, + &pll3_d1.common.clk, + &pll3_d2.common.clk, + &pll3_d3.common.clk, + &pll3_d4.common.clk, + &pll3_d5.common.clk, + &pll3_d6.common.clk, + &pll3_d7.common.clk, + &pll3_d8.common.clk, + &pll3_80.common.clk, + &pll3_40.common.clk, + &pll3_20.common.clk, +}; + +static const struct spacemit_ccu_data k1_ccu_pll_data = { + .clks = k1_ccu_pll_clks, + .num = ARRAY_SIZE(k1_ccu_pll_clks), + .offset = K1_PLL_ID, +}; + +#if IS_ENABLED(CONFIG_SPL_BUILD) +static struct clk *k1_ccu_mpmu_clks[] = { + &pll1_d8_307p2.common.clk, + &pll1_d32_76p8.common.clk, + &pll1_d40_61p44.common.clk, + &pll1_d16_153p6.common.clk, + &pll1_d24_102p4.common.clk, + &pll1_d48_51p2.common.clk, + &pll1_d48_51p2_ap.common.clk, + &pll1_m3d128_57p6.common.clk, + &pll1_d96_25p6.common.clk, + &pll1_d192_12p8.common.clk, + &pll1_d192_12p8_wdt.common.clk, + &pll1_d384_6p4.common.clk, + &pll1_d768_3p2.common.clk, + &pll1_d1536_1p6.common.clk, + &pll1_d3072_0p8.common.clk, + &pll1_d6_409p6.common.clk, + &pll1_d12_204p8.common.clk, + &pll1_d5_491p52.common.clk, + &pll1_d10_245p76.common.clk, + &pll1_d4_614p4.common.clk, + &pll1_d52_47p26.common.clk, + &pll1_d78_31p5.common.clk, + &pll1_d3_819p2.common.clk, + &pll1_d2_1228p8.common.clk, + &slow_uart.common.clk, + &slow_uart1_14p74.common.clk, + &slow_uart2_48.common.clk, +}; +#else +static struct clk *k1_ccu_mpmu_clks[] = { + &pll1_d8_307p2.common.clk, + &pll1_d32_76p8.common.clk, + &pll1_d40_61p44.common.clk, + &pll1_d16_153p6.common.clk, + &pll1_d24_102p4.common.clk, + &pll1_d48_51p2.common.clk, + &pll1_d48_51p2_ap.common.clk, + &pll1_m3d128_57p6.common.clk, + &pll1_d96_25p6.common.clk, + &pll1_d192_12p8.common.clk, + &pll1_d192_12p8_wdt.common.clk, + &pll1_d384_6p4.common.clk, + &pll1_d768_3p2.common.clk, + &pll1_d1536_1p6.common.clk, + &pll1_d3072_0p8.common.clk, + &pll1_d6_409p6.common.clk, + &pll1_d12_204p8.common.clk, + &pll1_d5_491p52.common.clk, + &pll1_d10_245p76.common.clk, + &pll1_d4_614p4.common.clk, + &pll1_d52_47p26.common.clk, + &pll1_d78_31p5.common.clk, + &pll1_d3_819p2.common.clk, + &pll1_d2_1228p8.common.clk, + &slow_uart.common.clk, + &slow_uart1_14p74.common.clk, + &slow_uart2_48.common.clk, + &wdt_clk.common.clk, + &apb_clk.common.clk, + &ripc_clk.common.clk, + &i2s_153p6.common.clk, + &i2s_153p6_base.common.clk, + &i2s_sysclk_src.common.clk, + &i2s_sysclk.common.clk, + &i2s_bclk_factor.common.clk, + &i2s_bclk.common.clk, + &wdt_bus_clk.common.clk, +}; +#endif + +static const struct spacemit_ccu_data k1_ccu_mpmu_data = { + .clks = k1_ccu_mpmu_clks, + .num = ARRAY_SIZE(k1_ccu_mpmu_clks), + .offset = K1_MPMU_ID, +}; + +#if IS_ENABLED(CONFIG_SPL_BUILD) +static struct clk *k1_ccu_apbc_clks[] = { + &uart0_clk.common.clk, + &twsi2_clk.common.clk, + &twsi8_clk.common.clk, +}; +#else +static struct clk *k1_ccu_apbc_clks[] = { + &uart0_clk.common.clk, + &uart2_clk.common.clk, + &uart3_clk.common.clk, + &uart4_clk.common.clk, + &uart5_clk.common.clk, + &uart6_clk.common.clk, + &uart7_clk.common.clk, + &uart8_clk.common.clk, + &uart9_clk.common.clk, + &gpio_clk.common.clk, + &pwm0_clk.common.clk, + &pwm1_clk.common.clk, + &pwm2_clk.common.clk, + &pwm3_clk.common.clk, + &pwm4_clk.common.clk, + &pwm5_clk.common.clk, + &pwm6_clk.common.clk, + &pwm7_clk.common.clk, + &pwm8_clk.common.clk, + &pwm9_clk.common.clk, + &pwm10_clk.common.clk, + &pwm11_clk.common.clk, + &pwm12_clk.common.clk, + &pwm13_clk.common.clk, + &pwm14_clk.common.clk, + &pwm15_clk.common.clk, + &pwm16_clk.common.clk, + &pwm17_clk.common.clk, + &pwm18_clk.common.clk, + &pwm19_clk.common.clk, + &ssp3_clk.common.clk, + &rtc_clk.common.clk, + &twsi0_clk.common.clk, + &twsi1_clk.common.clk, + &twsi2_clk.common.clk, + &twsi4_clk.common.clk, + &twsi5_clk.common.clk, + &twsi6_clk.common.clk, + &twsi7_clk.common.clk, + &twsi8_clk.common.clk, + &timers1_clk.common.clk, + &timers2_clk.common.clk, + &aib_clk.common.clk, + &onewire_clk.common.clk, + &sspa0_clk.common.clk, + &sspa1_clk.common.clk, + &dro_clk.common.clk, + &ir_clk.common.clk, + &tsen_clk.common.clk, + &ipc_ap2aud_clk.common.clk, + &can0_clk.common.clk, + &can0_bus_clk.common.clk, + &uart0_bus_clk.common.clk, + &uart2_bus_clk.common.clk, + &uart3_bus_clk.common.clk, + &uart4_bus_clk.common.clk, + &uart5_bus_clk.common.clk, + &uart6_bus_clk.common.clk, + &uart7_bus_clk.common.clk, + &uart8_bus_clk.common.clk, + &uart9_bus_clk.common.clk, + &gpio_bus_clk.common.clk, + &pwm0_bus_clk.common.clk, + &pwm1_bus_clk.common.clk, + &pwm2_bus_clk.common.clk, + &pwm3_bus_clk.common.clk, + &pwm4_bus_clk.common.clk, + &pwm5_bus_clk.common.clk, + &pwm6_bus_clk.common.clk, + &pwm7_bus_clk.common.clk, + &pwm8_bus_clk.common.clk, + &pwm9_bus_clk.common.clk, + &pwm10_bus_clk.common.clk, + &pwm11_bus_clk.common.clk, + &pwm12_bus_clk.common.clk, + &pwm13_bus_clk.common.clk, + &pwm14_bus_clk.common.clk, + &pwm15_bus_clk.common.clk, + &pwm16_bus_clk.common.clk, + &pwm17_bus_clk.common.clk, + &pwm18_bus_clk.common.clk, + &pwm19_bus_clk.common.clk, + &ssp3_bus_clk.common.clk, + &rtc_bus_clk.common.clk, + &twsi0_bus_clk.common.clk, + &twsi1_bus_clk.common.clk, + &twsi2_bus_clk.common.clk, + &twsi4_bus_clk.common.clk, + &twsi5_bus_clk.common.clk, + &twsi6_bus_clk.common.clk, + &twsi7_bus_clk.common.clk, + &twsi8_bus_clk.common.clk, + &timers1_bus_clk.common.clk, + &timers2_bus_clk.common.clk, + &aib_bus_clk.common.clk, + &onewire_bus_clk.common.clk, + &sspa0_bus_clk.common.clk, + &sspa1_bus_clk.common.clk, + &tsen_bus_clk.common.clk, + &ipc_ap2aud_bus_clk.common.clk, + &sspa0_i2s_bclk.common.clk, + &sspa1_i2s_bclk.common.clk, +}; +#endif + +static const struct spacemit_ccu_data k1_ccu_apbc_data = { + .clks = k1_ccu_apbc_clks, + .num = ARRAY_SIZE(k1_ccu_apbc_clks), + .offset = K1_APBC_ID, +}; + +#if IS_ENABLED(CONFIG_SPL_BUILD) +static struct clk *k1_ccu_apmu_clks[] = { + &emmc_clk.common.clk, + &emmc_x_clk.common.clk, + &pmua_aclk.common.clk, + &emmc_bus_clk.common.clk, +}; +#else +static struct clk *k1_ccu_apmu_clks[] = { + &cci550_clk.common.clk, + &cpu_c0_hi_clk.common.clk, + &cpu_c0_core_clk.common.clk, + &cpu_c0_ace_clk.common.clk, + &cpu_c0_tcm_clk.common.clk, + &cpu_c1_hi_clk.common.clk, + &cpu_c1_core_clk.common.clk, + &cpu_c1_ace_clk.common.clk, + &ccic_4x_clk.common.clk, + &ccic1phy_clk.common.clk, + &sdh_axi_aclk.common.clk, + &sdh0_clk.common.clk, + &sdh1_clk.common.clk, + &sdh2_clk.common.clk, + &usb_p1_aclk.common.clk, + &usb_axi_clk.common.clk, + &usb30_clk.common.clk, + &qspi_clk.common.clk, + &qspi_bus_clk.common.clk, + &dma_clk.common.clk, + &aes_clk.common.clk, + &vpu_clk.common.clk, + &gpu_clk.common.clk, + &emmc_clk.common.clk, + &emmc_x_clk.common.clk, + &audio_clk.common.clk, + &hdmi_mclk.common.clk, + &pmua_aclk.common.clk, + &pcie0_master_clk.common.clk, + &pcie0_slave_clk.common.clk, + &pcie0_dbi_clk.common.clk, + &pcie1_master_clk.common.clk, + &pcie1_slave_clk.common.clk, + &pcie1_dbi_clk.common.clk, + &pcie2_master_clk.common.clk, + &pcie2_slave_clk.common.clk, + &pcie2_dbi_clk.common.clk, + &emac0_bus_clk.common.clk, + &emac0_ptp_clk.common.clk, + &emac1_bus_clk.common.clk, + &emac1_ptp_clk.common.clk, + &jpg_clk.common.clk, + &ccic2phy_clk.common.clk, + &ccic3phy_clk.common.clk, + &csi_clk.common.clk, + &camm0_clk.common.clk, + &camm1_clk.common.clk, + &camm2_clk.common.clk, + &isp_cpp_clk.common.clk, + &isp_bus_clk.common.clk, + &isp_clk.common.clk, + &dpu_mclk.common.clk, + &dpu_esc_clk.common.clk, + &dpu_bit_clk.common.clk, + &dpu_pxclk.common.clk, + &dpu_hclk.common.clk, + &dpu_spi_clk.common.clk, + &dpu_spi_hbus_clk.common.clk, + &dpu_spi_bus_clk.common.clk, + &dpu_spi_aclk.common.clk, + &v2d_clk.common.clk, + &emmc_bus_clk.common.clk, +}; +#endif + +static int clk_k1_enable(struct clk *clk) +{ + const struct spacemit_ccu_data *data; + struct clk *c; + struct clk *pclk; + int ret, i; + + data = (struct spacemit_ccu_data *)dev_get_driver_data(clk->dev); + for (i = 0; i < data->num; i++) { + if (clk->id == data->clks[i]->id) { + c = data->clks[i]; + break; + } + } + if (i == data->num) + c = clk; + + pclk = clk_get_parent(c); + if (!IS_ERR_OR_NULL(pclk)) { + ret = ccf_clk_enable(pclk); + if (ret) + return ret; + } + ret = ccu_gate_enable(c); + return ret; +} + +static int clk_k1_disable(struct clk *clk) +{ + const struct spacemit_ccu_data *data; + struct clk *c; + struct clk *pclk; + int ret, i; + + data = (struct spacemit_ccu_data *)dev_get_driver_data(clk->dev); + for (i = 0; i < data->num; i++) { + if (clk->id == data->clks[i]->id) { + c = data->clks[i]; + break; + } + } + if (i == data->num) + c = clk; + + pclk = clk_get_parent(c); + if (!IS_ERR_OR_NULL(pclk)) { + ret = ccf_clk_disable(pclk); + if (ret) + return ret; + } + ret = ccu_gate_disable(c); + return ret; +} + +#define K1_CLK_OPS(name) \ +static const struct clk_ops k1_##name##_clk_ops = { \ + .set_rate = ccf_clk_set_rate, \ + .get_rate = ccf_clk_get_rate, \ + .enable = clk_k1_enable, \ + .disable = clk_k1_disable, \ + .set_parent = ccf_clk_set_parent, \ + .of_xlate = k1_##name##_clk_of_xlate, \ +} + +static const struct spacemit_ccu_data k1_ccu_apmu_data = { + .clks = k1_ccu_apmu_clks, + .num = ARRAY_SIZE(k1_ccu_apmu_clks), + .offset = K1_APMU_ID, +}; + +struct clk_retry_item { + struct ccu_common *common; + struct list_head link; +}; + +static LIST_HEAD(retry_list); + +static int k1_clk_retry_register(void) +{ + struct clk_retry_item *item, *tmp; + int retries = 5; + int ret; + + while (!list_empty(&retry_list) && retries) { + list_for_each_entry_safe(item, tmp, &retry_list, link) { + struct ccu_common *common = item->common; + + ret = common->init(common); + if (ret) + return ret; + + list_del(&item->link); + kfree(item); + } + retries--; + } + + return 0; +} + +static int k1_clk_register(struct udevice *dev, struct regmap *regmap, + struct regmap *lock_regmap, + const struct spacemit_ccu_data *data) +{ + int i, ret; + + for (i = 0; i < data->num; i++) { + struct clk *clk = data->clks[i]; + struct ccu_common *common; + + if (!clk) + continue; + + common = clk_to_ccu_common(clk); + common->regmap = regmap; + common->lock_regmap = lock_regmap; + + clk->id = common->clk.id + data->offset; + + ret = common->init(common); + if (ret) + return ret; + } + + return 0; +} + +static int k1_clk_probe(struct udevice *dev) +{ + struct regmap *base_regmap, *lock_regmap = NULL; + const struct spacemit_ccu_data *data; + int ret; + + clk_register_fixed_rate(NULL, "clock-1m", 1000000); + clk_register_fixed_rate(NULL, "clock-24m", 24000000); + clk_register_fixed_rate(NULL, "clock-3m", 3000000); + clk_register_fixed_rate(NULL, "clock-32k", 32000); + + ret = regmap_init_mem(dev_ofnode(dev), &base_regmap); + if (ret) + return ret; + + /* + * The lock status of PLLs locate in MPMU region, while PLLs themselves + * are in APBS region. Reference to MPMU syscon is required to check PLL + * status. + */ + if (device_is_compatible(dev, "spacemit,k1-pll")) { + struct ofnode_phandle_args mpmu_args; + + ret = dev_read_phandle_with_args(dev, "spacemit,mpmu", NULL, 0, 0, + &mpmu_args); + if (ret) + return ret; + + ret = regmap_init_mem(mpmu_args.node, &lock_regmap); + if (ret) + return ret; + } + + data = (struct spacemit_ccu_data *)dev_get_driver_data(dev); + + ret = k1_clk_register(dev, base_regmap, lock_regmap, data); + if (ret) + return -EPROBE_DEFER; + + return k1_clk_retry_register(); +} + +static int k1_apbc_clk_probe(struct udevice *dev) +{ + struct regmap *base_regmap, *lock_regmap = NULL; + const struct spacemit_ccu_data *data; + int ret; + struct clk clk; + + ret = regmap_init_mem(dev_ofnode(dev), &base_regmap); + if (ret) + return ret; + + clk_register_fixed_rate(NULL, "clock-1m", 1000000); + clk_register_fixed_rate(NULL, "clock-24m", 24000000); + clk_register_fixed_rate(NULL, "clock-3m", 3000000); + clk_register_fixed_rate(NULL, "clock-32k", 32000); + + /* probe PLL controller */ + ret = clk_get_by_index(dev, 5, &clk); + if (ret) + return -EPROBE_DEFER; + + /* probe MPMU controller */ + ret = clk_get_by_index(dev, 4, &clk); + if (ret) + return -EPROBE_DEFER; + + ret = regmap_init_mem(dev_ofnode(dev), &base_regmap); + if (ret) + return ret; + + /* + * The lock status of PLLs locate in MPMU region, while PLLs themselves + * are in APBS region. Reference to MPMU syscon is required to check PLL + * status. + */ + if (device_is_compatible(dev, "spacemit,k1-pll")) { + struct ofnode_phandle_args mpmu_args; + + ret = dev_read_phandle_with_args(dev, "spacemit,mpmu", NULL, 0, 0, + &mpmu_args); + if (ret) + return ret; + + ret = regmap_init_mem(mpmu_args.node, &lock_regmap); + if (ret) + return ret; + } + + data = (struct spacemit_ccu_data *)dev_get_driver_data(dev); + + ret = k1_clk_register(dev, base_regmap, lock_regmap, data); + if (ret) + return -EPROBE_DEFER; + + return k1_clk_retry_register(); +} + +static int k1_pll_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args) +{ + if (args->args_count > 1) { + debug("Invalid args_count: %d\n", args->args_count); + return -EINVAL; + } + + if (args->args_count) + clk->id = K1_PLL_ID + args->args[0]; + else + clk->id = K1_PLL_ID; + + return 0; +} + +static int k1_mpmu_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args) +{ + if (args->args_count > 1) { + debug("Invalid args_count: %d\n", args->args_count); + return -EINVAL; + } + + if (args->args_count) + clk->id = K1_MPMU_ID + args->args[0]; + else + clk->id = K1_MPMU_ID; + + return 0; +} + +static int k1_apbc_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args) +{ + if (args->args_count > 1) { + debug("Invalid args_count: %d\n", args->args_count); + return -EINVAL; + } + + if (args->args_count) + clk->id = K1_APBC_ID + args->args[0]; + else + clk->id = K1_APBC_ID; + + return 0; +} + +static int k1_apmu_clk_of_xlate(struct clk *clk, struct ofnode_phandle_args *args) +{ + if (args->args_count > 1) { + debug("Invalid args_count: %d\n", args->args_count); + return -EINVAL; + } + + if (args->args_count) + clk->id = K1_APMU_ID + args->args[0]; + else + clk->id = K1_APMU_ID; + + return 0; +} + +static const struct udevice_id k1_pll_clk_match[] = { + { .compatible = "spacemit,k1-pll", + .data = (ulong)&k1_ccu_pll_data }, + { /* sentinel */ }, +}; + +K1_CLK_OPS(pll); + +U_BOOT_DRIVER(k1_pll_clk) = { + .name = "k1_pll_clk", + .id = UCLASS_CLK, + .of_match = k1_pll_clk_match, + .probe = k1_clk_probe, + .ops = &k1_pll_clk_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +static const struct udevice_id k1_mpmu_clk_match[] = { + { .compatible = "spacemit,k1-syscon-mpmu", + .data = (ulong)&k1_ccu_mpmu_data }, + { /* sentinel */ }, +}; + +K1_CLK_OPS(mpmu); + +U_BOOT_DRIVER(k1_mpmu_clk) = { + .name = "k1_mpmu_clk", + .id = UCLASS_CLK, + .of_match = k1_mpmu_clk_match, + .probe = k1_clk_probe, + .ops = &k1_mpmu_clk_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +static const struct udevice_id k1_apbc_clk_match[] = { + { .compatible = "spacemit,k1-syscon-apbc", + .data = (ulong)&k1_ccu_apbc_data }, + { /* sentinel */ }, +}; + +K1_CLK_OPS(apbc); + +U_BOOT_DRIVER(k1_apbc_clk) = { + .name = "k1_apbc_clk", + .id = UCLASS_CLK, + .of_match = k1_apbc_clk_match, + .probe = k1_apbc_clk_probe, + .ops = &k1_apbc_clk_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +static const struct udevice_id k1_apmu_clk_match[] = { + { .compatible = "spacemit,k1-syscon-apmu", + .data = (ulong)&k1_ccu_apmu_data }, + { /* sentinel */ }, +}; + +K1_CLK_OPS(apmu); + +U_BOOT_DRIVER(k1_apmu_clk) = { + .name = "k1_apmu_clk", + .id = UCLASS_CLK, + .of_match = k1_apmu_clk_match, + .probe = k1_clk_probe, + .ops = &k1_apmu_clk_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +static const struct udevice_id k1_rcpu_clk_match[] = { + { .compatible = "spacemit,k1-syscon-rcpu" }, + { /* sentinel */ }, +}; + +U_BOOT_DRIVER(k1_rcpu_clk) = { + .name = "k1_rcpu_clk", + .id = UCLASS_CLK, + .of_match = k1_rcpu_clk_match, + .flags = DM_FLAG_PRE_RELOC, +}; + +static const struct udevice_id k1_rcpu2_clk_match[] = { + { .compatible = "spacemit,k1-syscon-rcpu2" }, + { /* sentinel */ }, +}; + +U_BOOT_DRIVER(k1_rcpu2_clk) = { + .name = "k1_rcpu2_clk", + .id = UCLASS_CLK, + .of_match = k1_rcpu2_clk_match, + .flags = DM_FLAG_PRE_RELOC, +}; + +static const struct udevice_id k1_apbc2_clk_match[] = { + { .compatible = "spacemit,k1-syscon-apbc2" }, + { /* sentinel */ }, +}; + +U_BOOT_DRIVER(k1_apbc2_clk) = { + .name = "k1_apbc2_clk", + .id = UCLASS_CLK, + .of_match = k1_apbc2_clk_match, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/clk/spacemit/clk_common.h b/drivers/clk/spacemit/clk_common.h new file mode 100644 index 00000000000..dda9264caf3 --- /dev/null +++ b/drivers/clk/spacemit/clk_common.h @@ -0,0 +1,79 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2024 SpacemiT Technology Co. Ltd + * Copyright (c) 2024-2025 Haylen Chu <heylenay@4d2.org> + * Copyright (c) 2025 Junhui Liu <junhui.liu@pigmoral.tech> + * Copyright (c) 2025-2026 RISCStar Ltd. + * + * Authors: Haylen Chu <heylenay@4d2.org> + */ + +#ifndef _CLK_COMMON_H_ +#define _CLK_COMMON_H_ + +#include <linux/clk-provider.h> + +struct ccu_common; + +typedef int (*ccu_init_fn)(struct ccu_common *common); + +struct ccu_common { + struct regmap *regmap; + struct regmap *lock_regmap; + const char *name; + const char * const *parents; + size_t num_parents; + ccu_init_fn init; + + union { + /* For DDN and MIX */ + struct { + u32 reg_ctrl; + u32 reg_fc; + u32 mask_fc; + }; + + /* For PLL */ + struct { + u32 reg_swcr1; + u32 reg_swcr3; + }; + }; + + struct clk clk; +}; + +#define CCU_COMMON(_id, _name, _parent, _init, _flags) \ + .name = #_name, \ + .parents = (const char *[]) { _parent }, \ + .num_parents = 1, \ + .init = _init, \ + .clk = { .flags = _flags, .id = _id, } \ + +#define CCU_COMMON_PARENTS(_id, _name, _parents, _num_p, _init, _flags) \ + .name = #_name, \ + .parents = _parents, \ + .num_parents = _num_p, \ + .init = _init, \ + .clk = { .flags = _flags, .id = _id, } \ + +static inline struct ccu_common *clk_to_ccu_common(struct clk *clk) +{ + return container_of(clk, struct ccu_common, clk); +} + +#define ccu_read(c, reg) \ + ({ \ + struct ccu_common * const __ccu = (c); \ + u32 tmp; \ + regmap_read(__ccu->regmap, __ccu->reg_##reg, &tmp); \ + tmp; \ + }) +#define ccu_update(c, reg, mask, val) \ + ({ \ + struct ccu_common * const __ccu = (c); \ + regmap_update_bits(__ccu->regmap, __ccu->reg_##reg, \ + mask, val); \ + }) + +#endif /* _CLK_COMMON_H_ */ diff --git a/drivers/clk/spacemit/clk_ddn.c b/drivers/clk/spacemit/clk_ddn.c new file mode 100644 index 00000000000..7b93f30d5c3 --- /dev/null +++ b/drivers/clk/spacemit/clk_ddn.c @@ -0,0 +1,93 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024 SpacemiT Technology Co. Ltd + * Copyright (c) 2024-2025 Haylen Chu <heylenay@4d2.org> + * Copyright (c) 2025 Junhui Liu <junhui.liu@pigmoral.tech> + * Authors: Haylen Chu <heylenay@4d2.org> + * + * DDN stands for "Divider Denominator Numerator", it's M/N clock with a + * constant x2 factor. This clock hardware follows the equation below, + * + * numerator Fin + * 2 * ------------- = ------- + * denominator Fout + * + * Thus, Fout could be calculated with, + * + * Fin denominator + * Fout = ----- * ------------- + * 2 numerator + */ + +#include <dm/device.h> +#include <regmap.h> +#include <linux/clk-provider.h> +#include <linux/rational.h> + +#include "clk_ddn.h" + +#define UBOOT_DM_SPACEMIT_CLK_DDN "spacemit_clk_ddn" + +static unsigned long ccu_ddn_calc_rate(unsigned long prate, unsigned long num, + unsigned long den, unsigned int pre_div) +{ + return prate * den / pre_div / num; +} + +static unsigned long ccu_ddn_calc_best_rate(struct ccu_ddn *ddn, + unsigned long rate, unsigned long prate, + unsigned long *num, unsigned long *den) +{ + rational_best_approximation(rate, prate / ddn->pre_div, + ddn->den_mask >> ddn->den_shift, + ddn->num_mask >> ddn->num_shift, + den, num); + return ccu_ddn_calc_rate(prate, *num, *den, ddn->pre_div); +} + +static unsigned long ccu_ddn_recalc_rate(struct clk *clk) +{ + struct ccu_ddn *ddn = clk_to_ccu_ddn(clk); + unsigned int val, num, den; + + val = ccu_read(&ddn->common, ctrl); + + num = (val & ddn->num_mask) >> ddn->num_shift; + den = (val & ddn->den_mask) >> ddn->den_shift; + + return ccu_ddn_calc_rate(clk_get_parent_rate(clk), num, den, ddn->pre_div); +} + +static unsigned long ccu_ddn_set_rate(struct clk *clk, unsigned long rate) +{ + struct ccu_ddn *ddn = clk_to_ccu_ddn(clk); + unsigned long num, den; + + ccu_ddn_calc_best_rate(ddn, rate, clk_get_parent_rate(clk), &num, &den); + + ccu_update(&ddn->common, ctrl, + ddn->num_mask | ddn->den_mask, + (num << ddn->num_shift) | (den << ddn->den_shift)); + + return 0; +} + +static const struct clk_ops spacemit_clk_ddn_ops = { + .get_rate = ccu_ddn_recalc_rate, + .set_rate = ccu_ddn_set_rate, +}; + +int spacemit_ddn_init(struct ccu_common *common) +{ + struct clk *clk = &common->clk; + + return clk_register(clk, UBOOT_DM_SPACEMIT_CLK_DDN, + common->name, common->parents[0]); +} + +U_BOOT_DRIVER(spacemit_clk_ddn) = { + .name = UBOOT_DM_SPACEMIT_CLK_DDN, + .id = UCLASS_CLK, + .ops = &spacemit_clk_ddn_ops, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/clk/spacemit/clk_ddn.h b/drivers/clk/spacemit/clk_ddn.h new file mode 100644 index 00000000000..cde761bdc43 --- /dev/null +++ b/drivers/clk/spacemit/clk_ddn.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2024 SpacemiT Technology Co. Ltd + * Copyright (c) 2024-2025 Haylen Chu <heylenay@4d2.org> + * Copyright (c) 2025 Junhui Liu <junhui.liu@pigmoral.tech> + * Copyright (c) 2025-2026 RISCStar Ltd. + * + * Authors: Haylen Chu <heylenay@4d2.org> + */ + +#ifndef _CLK_DDN_H_ +#define _CLK_DDN_H_ + +#include <linux/clk-provider.h> + +#include "clk_common.h" + +struct ccu_ddn { + struct ccu_common common; + unsigned int num_mask; + unsigned int num_shift; + unsigned int den_mask; + unsigned int den_shift; + unsigned int pre_div; +}; + +#define CCU_DDN_MASK(_num_shift, _num_width) \ + GENMASK((_num_shift) + (_num_width) - 1, _num_shift) + +#define CCU_DDN_DEFINE(_id, _var, _name, _parent, _reg_ctrl, _num_mask, \ + _num_shift, _den_mask, _den_shift, _pre_div, _flags) \ +static struct ccu_ddn _var = { \ + .common = { \ + .reg_ctrl = _reg_ctrl, \ + CCU_COMMON(_id, _name, _parent, spacemit_ddn_init, _flags) \ + }, \ + .num_mask = _num_mask, \ + .num_shift = _num_shift, \ + .den_mask = _den_mask, \ + .den_shift = _den_shift, \ + .pre_div = _pre_div, \ +} + +static inline struct ccu_ddn *clk_to_ccu_ddn(struct clk *clk) +{ + struct ccu_common *common = clk_to_ccu_common(clk); + + return container_of(common, struct ccu_ddn, common); +} + +int spacemit_ddn_init(struct ccu_common *common); + +#endif /* _CLK_DDN_H_ */ diff --git a/drivers/clk/spacemit/clk_mix.c b/drivers/clk/spacemit/clk_mix.c new file mode 100644 index 00000000000..a1158512a92 --- /dev/null +++ b/drivers/clk/spacemit/clk_mix.c @@ -0,0 +1,403 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024 SpacemiT Technology Co. Ltd + * Copyright (c) 2024-2025 Haylen Chu <heylenay@4d2.org> + * Copyright (c) 2025 Junhui Liu <junhui.liu@pigmoral.tech> + * Authors: Haylen Chu <heylenay@4d2.org> + * + * MIX clock type is the combination of mux, factor or divider, and gate + */ + +#include <dm/device.h> +#include <dm/uclass.h> +#include <div64.h> +#include <regmap.h> +#include <linux/clk-provider.h> +#include <linux/kernel.h> + +#include "clk_mix.h" + +#define UBOOT_DM_SPACEMIT_CLK_GATE "spacemit_clk_gate" +#define UBOOT_DM_SPACEMIT_CLK_FACTOR "spacemit_clk_factor" +#define UBOOT_DM_SPACEMIT_CLK_MUX "spacemit_clk_mux" +#define UBOOT_DM_SPACEMIT_CLK_DIV "spacemit_clk_div" +#define UBOOT_DM_SPACEMIT_CLK_FACTOR_GATE "spacemit_clk_factor_gate" +#define UBOOT_DM_SPACEMIT_CLK_MUX_GATE "spacemit_clk_mux_gate" +#define UBOOT_DM_SPACEMIT_CLK_DIV_GATE "spacemit_clk_div_gate" +#define UBOOT_DM_SPACEMIT_CLK_MUX_DIV "spacemit_clk_mux_div" +#define UBOOT_DM_SPACEMIT_CLK_MUX_DIV_GATE "spacemit_clk_mux_div_gate" + +#define MIX_FC_TIMEOUT_US 10000 +#define MIX_FC_DELAY_US 5 + +int ccu_gate_disable(struct clk *clk) +{ + struct ccu_mix *mix = clk_to_ccu_mix(clk); + + ccu_update(&mix->common, ctrl, mix->gate.mask, 0); + + return 0; +} + +int ccu_gate_enable(struct clk *clk) +{ + struct ccu_mix *mix = clk_to_ccu_mix(clk); + struct ccu_gate_config *gate = &mix->gate; + + ccu_update(&mix->common, ctrl, gate->mask, gate->mask); + + return 0; +} + +static unsigned long ccu_factor_recalc_rate(struct clk *clk) +{ + struct ccu_mix *mix = clk_to_ccu_mix(clk); + + return clk_get_parent_rate(clk) * mix->factor.mul / mix->factor.div; +} + +static unsigned long ccu_div_recalc_rate(struct clk *clk) +{ + struct ccu_mix *mix = clk_to_ccu_mix(clk); + struct ccu_div_config *div = &mix->div; + unsigned long val; + + val = ccu_read(&mix->common, ctrl) >> div->shift; + val &= (1 << div->width) - 1; + + return divider_recalc_rate(clk, clk_get_parent_rate(clk), val, NULL, 0, div->width); +} + +/* + * Some clocks require a "FC" (frequency change) bit to be set after changing + * their rates or reparenting. This bit will be automatically cleared by + * hardware in MIX_FC_TIMEOUT_US, which indicates the operation is completed. + */ +static int ccu_mix_trigger_fc(struct clk *clk) +{ + struct ccu_common *common = clk_to_ccu_common(clk); + unsigned int val; + + if (common->reg_fc) + return 0; + + ccu_update(common, fc, common->mask_fc, common->mask_fc); + + return regmap_read_poll_timeout(common->regmap, common->reg_fc, + val, !(val & common->mask_fc), + MIX_FC_DELAY_US, + MIX_FC_TIMEOUT_US); +} + +static unsigned long +ccu_mix_calc_best_rate(struct clk *clk, unsigned long rate, + struct clk **best_parent, + unsigned long *best_parent_rate, + u32 *div_val) +{ + struct ccu_common *common = clk_to_ccu_common(clk); + struct ccu_mix *mix = clk_to_ccu_mix(clk); + unsigned int parent_num = common->num_parents; + struct ccu_div_config *div = &mix->div; + u32 div_max = 1 << div->width; + unsigned long best_rate = 0; + + for (int i = 0; i < parent_num; i++) { + struct udevice *parent_dev; + unsigned long parent_rate; + struct clk *parent; + + if (uclass_get_device_by_name(UCLASS_CLK, common->parents[i], + &parent_dev)) + continue; + parent = dev_get_clk_ptr(parent_dev); + if (!parent) + continue; + + parent_rate = clk_get_rate(parent); + + for (int j = 1; j <= div_max; j++) { + unsigned long tmp = DIV_ROUND_CLOSEST_ULL(parent_rate, j); + + if (abs(tmp - rate) < abs(best_rate - rate)) { + best_rate = tmp; + + if (div_val) + *div_val = j - 1; + + if (best_parent) { + *best_parent = parent; + *best_parent_rate = parent_rate; + } + } + } + } + + return best_rate; +} + +static unsigned long 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 = &mix->div; + u32 current_div, target_div, mask; + + ccu_mix_calc_best_rate(clk, rate, NULL, NULL, &target_div); + + current_div = ccu_read(common, ctrl) >> div->shift; + current_div &= (1 << div->width) - 1; + + if (current_div == target_div) + return 0; + + mask = GENMASK(div->width + div->shift - 1, div->shift); + + ccu_update(common, ctrl, mask, target_div << div->shift); + + return ccu_mix_trigger_fc(clk); +} + +static u8 ccu_mux_get_parent(struct clk *clk) +{ + struct ccu_mix *mix = clk_to_ccu_mix(clk); + struct ccu_mux_config *mux = &mix->mux; + u8 parent; + + parent = ccu_read(&mix->common, ctrl) >> mux->shift; + parent &= (1 << mux->width) - 1; + + return parent; +} + +static int ccu_mux_set_parent(struct clk *clk, struct clk *parent) +{ + struct ccu_common *common = clk_to_ccu_common(clk); + struct ccu_mix *mix = clk_to_ccu_mix(clk); + struct ccu_mux_config *mux = &mix->mux; + u32 mask; + int i = 0; + + mask = GENMASK(mux->width + mux->shift - 1, mux->shift); + + for (i = 0; i < common->num_parents; i++) { + if (!strcmp(parent->dev->name, common->parents[i])) + break; + } + + if (i == common->num_parents) + return -EINVAL; + + ccu_update(&mix->common, ctrl, mask, i << mux->shift); + + return ccu_mix_trigger_fc(clk); +} + +int spacemit_gate_init(struct ccu_common *common) +{ + struct clk *clk = &common->clk; + + return clk_register(clk, UBOOT_DM_SPACEMIT_CLK_GATE, + common->name, common->parents[0]); +} + +static const struct clk_ops spacemit_clk_gate_ops = { + .disable = ccu_gate_disable, + .enable = ccu_gate_enable, + .get_rate = clk_generic_get_rate, +}; + +U_BOOT_DRIVER(spacemit_clk_gate) = { + .name = UBOOT_DM_SPACEMIT_CLK_GATE, + .id = UCLASS_CLK, + .ops = &spacemit_clk_gate_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +int spacemit_factor_init(struct ccu_common *common) +{ + struct clk *clk = &common->clk; + + return clk_register(clk, UBOOT_DM_SPACEMIT_CLK_FACTOR, + common->name, common->parents[0]); +} + +static const struct clk_ops spacemit_clk_factor_ops = { + .get_rate = ccu_factor_recalc_rate, +}; + +U_BOOT_DRIVER(spacemit_clk_factor) = { + .name = UBOOT_DM_SPACEMIT_CLK_FACTOR, + .id = UCLASS_CLK, + .ops = &spacemit_clk_factor_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +int spacemit_mux_init(struct ccu_common *common) +{ + struct clk *clk = &common->clk; + u8 index; + + index = ccu_mux_get_parent(clk); + if (index >= common->num_parents) + index = 0; + + return clk_register(clk, UBOOT_DM_SPACEMIT_CLK_MUX, + common->name, common->parents[index]); +} + +static const struct clk_ops spacemit_clk_mux_ops = { + .set_parent = ccu_mux_set_parent, + .get_rate = clk_generic_get_rate, +}; + +U_BOOT_DRIVER(spacemit_clk_mux) = { + .name = UBOOT_DM_SPACEMIT_CLK_MUX, + .id = UCLASS_CLK, + .ops = &spacemit_clk_mux_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +int spacemit_div_init(struct ccu_common *common) +{ + struct clk *clk = &common->clk; + + return clk_register(clk, UBOOT_DM_SPACEMIT_CLK_DIV, + common->name, common->parents[0]); +} + +static const struct clk_ops spacemit_clk_div_ops = { + .get_rate = ccu_div_recalc_rate, + .set_rate = ccu_mix_set_rate, +}; + +U_BOOT_DRIVER(spacemit_clk_div) = { + .name = UBOOT_DM_SPACEMIT_CLK_DIV, + .id = UCLASS_CLK, + .ops = &spacemit_clk_div_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +int spacemit_factor_gate_init(struct ccu_common *common) +{ + struct clk *clk = &common->clk; + + return clk_register(clk, UBOOT_DM_SPACEMIT_CLK_FACTOR_GATE, + common->name, common->parents[0]); +} + +static const struct clk_ops spacemit_clk_factor_gate_ops = { + .disable = ccu_gate_disable, + .enable = ccu_gate_enable, + .get_rate = ccu_factor_recalc_rate, +}; + +U_BOOT_DRIVER(spacemit_clk_factor_gate) = { + .name = UBOOT_DM_SPACEMIT_CLK_FACTOR_GATE, + .id = UCLASS_CLK, + .ops = &spacemit_clk_factor_gate_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +int spacemit_mux_gate_init(struct ccu_common *common) +{ + struct clk *clk = &common->clk; + u8 index; + + index = ccu_mux_get_parent(clk); + if (index >= common->num_parents) + index = 0; + + return clk_register(clk, UBOOT_DM_SPACEMIT_CLK_MUX_GATE, + common->name, common->parents[index]); +} + +static const struct clk_ops spacemit_clk_mux_gate_ops = { + .disable = ccu_gate_disable, + .enable = ccu_gate_enable, + .set_parent = ccu_mux_set_parent, + .get_rate = clk_generic_get_rate, +}; + +U_BOOT_DRIVER(spacemit_clk_mux_gate) = { + .name = UBOOT_DM_SPACEMIT_CLK_MUX_GATE, + .id = UCLASS_CLK, + .ops = &spacemit_clk_mux_gate_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +int spacemit_div_gate_init(struct ccu_common *common) +{ + struct clk *clk = &common->clk; + + return clk_register(clk, UBOOT_DM_SPACEMIT_CLK_DIV_GATE, + common->name, common->parents[0]); +} + +static const struct clk_ops spacemit_clk_div_gate_ops = { + .disable = ccu_gate_disable, + .enable = ccu_gate_enable, + .get_rate = ccu_div_recalc_rate, + .set_rate = ccu_mix_set_rate, +}; + +U_BOOT_DRIVER(spacemit_clk_div_gate) = { + .name = UBOOT_DM_SPACEMIT_CLK_DIV_GATE, + .id = UCLASS_CLK, + .ops = &spacemit_clk_div_gate_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +int spacemit_mux_div_init(struct ccu_common *common) +{ + struct clk *clk = &common->clk; + u8 index; + + index = ccu_mux_get_parent(clk); + if (index >= common->num_parents) + index = 0; + + return clk_register(clk, UBOOT_DM_SPACEMIT_CLK_MUX_DIV, + common->name, common->parents[index]); +} + +static const struct clk_ops spacemit_clk_mux_div_ops = { + .set_parent = ccu_mux_set_parent, + .get_rate = ccu_div_recalc_rate, + .set_rate = ccu_mix_set_rate, +}; + +U_BOOT_DRIVER(spacemit_clk_mux_div) = { + .name = UBOOT_DM_SPACEMIT_CLK_MUX_DIV, + .id = UCLASS_CLK, + .ops = &spacemit_clk_mux_div_ops, + .flags = DM_FLAG_PRE_RELOC, +}; + +int spacemit_mux_div_gate_init(struct ccu_common *common) +{ + struct clk *clk = &common->clk; + u8 index; + + index = ccu_mux_get_parent(clk); + if (index >= common->num_parents) + index = 0; + + return clk_register(clk, UBOOT_DM_SPACEMIT_CLK_MUX_DIV_GATE, + common->name, common->parents[index]); +} + +static const struct clk_ops spacemit_clk_mux_div_gate_ops = { + .disable = ccu_gate_disable, + .enable = ccu_gate_enable, + .set_parent = ccu_mux_set_parent, + .get_rate = ccu_div_recalc_rate, + .set_rate = ccu_mix_set_rate, +}; + +U_BOOT_DRIVER(spacemit_clk_mux_div_gate) = { + .name = UBOOT_DM_SPACEMIT_CLK_MUX_DIV_GATE, + .id = UCLASS_CLK, + .ops = &spacemit_clk_mux_div_gate_ops, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/clk/spacemit/clk_mix.h b/drivers/clk/spacemit/clk_mix.h new file mode 100644 index 00000000000..bd733a93f6c --- /dev/null +++ b/drivers/clk/spacemit/clk_mix.h @@ -0,0 +1,224 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2024 SpacemiT Technology Co. Ltd + * Copyright (c) 2024-2025 Haylen Chu <heylenay@4d2.org> + * Copyright (c) 2025 Junhui Liu <junhui.liu@pigmoral.tech> + * Copyright (c) 2025-2026 RISCStar Ltd. + * + * Authors: Haylen Chu <heylenay@4d2.org> + */ + +#ifndef _CLK_MIX_H_ +#define _CLK_MIX_H_ + +#include <linux/clk-provider.h> + +#include "clk_common.h" + +/** + * struct ccu_gate_config - Gate configuration + * + * @mask: Mask to enable the gate. Some clocks may have more than one bit + * set in this field. + */ +struct ccu_gate_config { + u32 mask; +}; + +struct ccu_factor_config { + u32 div; + u32 mul; +}; + +struct ccu_mux_config { + u8 shift; + u8 width; +}; + +struct ccu_div_config { + u8 shift; + u8 width; +}; + +struct ccu_mix { + struct ccu_factor_config factor; + struct ccu_gate_config gate; + struct ccu_div_config div; + struct ccu_mux_config mux; + struct ccu_common common; +}; + +#define CCU_GATE_INIT(_mask) { .mask = _mask } +#define CCU_FACTOR_INIT(_div, _mul) { .div = _div, .mul = _mul } +#define CCU_MUX_INIT(_shift, _width) { .shift = _shift, .width = _width } +#define CCU_DIV_INIT(_shift, _width) { .shift = _shift, .width = _width } + +#define CCU_GATE_DEFINE(_id, _var, _name, _parent, _reg_ctrl, \ + _mask_gate, _flags) \ +static struct ccu_mix _var = { \ + .gate = CCU_GATE_INIT(_mask_gate), \ + .common = { \ + .reg_ctrl = _reg_ctrl, \ + CCU_COMMON(_id, _name, _parent, spacemit_gate_init, \ + _flags) \ + } \ +} + +#define CCU_FACTOR_DEFINE(_id, _var, _name, _parent, _div, _mul) \ +static struct ccu_mix _var = { \ + .factor = CCU_FACTOR_INIT(_div, _mul), \ + .common = { \ + CCU_COMMON(_id, _name, _parent, spacemit_factor_init, \ + 0) \ + } \ +} + +#define CCU_MUX_DEFINE(_id, _var, _name, _parents, _num_p, _reg_ctrl, \ + _shift, _width, _flags) \ +static struct ccu_mix _var = { \ + .mux = CCU_MUX_INIT(_shift, _width), \ + .common = { \ + .reg_ctrl = _reg_ctrl, \ + CCU_COMMON_PARENTS(_id, _name, _parents, _num_p, \ + spacemit_mux_init, _flags) \ + } \ +} + +#define CCU_DIV_DEFINE(_id, _var, _name, _parent, _reg_ctrl, _shift, \ + _width, _flags) \ +static struct ccu_mix _var = { \ + .div = CCU_DIV_INIT(_shift, _width), \ + .common = { \ + .reg_ctrl = _reg_ctrl, \ + CCU_COMMON(_id, _name, _parent, spacemit_div_init, \ + _flags) \ + } \ +} + +#define CCU_FACTOR_GATE_FLAGS_DEFINE(_id, _var, _name, _parent, \ + _reg_ctrl, _mask_gate, _div, _mul, \ + _flags) \ +static struct ccu_mix _var = { \ + .gate = CCU_GATE_INIT(_mask_gate), \ + .factor = CCU_FACTOR_INIT(_div, _mul), \ + .common = { \ + .reg_ctrl = _reg_ctrl, \ + CCU_COMMON(_id, _name, _parent, \ + spacemit_factor_gate_init, _flags) \ + } \ +} + +#define CCU_FACTOR_GATE_DEFINE(_id, _var, _name, _parent, _reg_ctrl, \ + _mask_gate, _div, _mul) \ + CCU_FACTOR_GATE_FLAGS_DEFINE(_id, _var, _name, _parent, \ + _reg_ctrl, _mask_gate, _div, _mul, \ + 0) + +#define CCU_MUX_GATE_DEFINE(_id, _var, _name, _parents, _num_p, \ + _reg_ctrl, _shift, _width, _mask_gate, \ + _flags) \ +static struct ccu_mix _var = { \ + .gate = CCU_GATE_INIT(_mask_gate), \ + .mux = CCU_MUX_INIT(_shift, _width), \ + .common = { \ + .reg_ctrl = _reg_ctrl, \ + CCU_COMMON_PARENTS(_id, _name, _parents, _num_p, \ + spacemit_mux_gate_init, _flags) \ + } \ +} + +#define CCU_DIV_GATE_DEFINE(_id, _var, _name, _parent, _reg_ctrl, \ + _shift, _width, _mask_gate, _flags) \ +static struct ccu_mix _var = { \ + .gate = CCU_GATE_INIT(_mask_gate), \ + .div = CCU_DIV_INIT(_shift, _width), \ + .common = { \ + .reg_ctrl = _reg_ctrl, \ + CCU_COMMON(_id, _name, _parent, \ + spacemit_div_gate_init, _flags) \ + } \ +} + +#define CCU_MUX_DIV_GATE_DEFINE(_id, _var, _name, _parents, _num_p, \ + _reg_ctrl, _mshift, _mwidth, _muxshift, \ + _muxwidth, _mask_gate, _flags) \ +static struct ccu_mix _var = { \ + .gate = CCU_GATE_INIT(_mask_gate), \ + .div = CCU_DIV_INIT(_mshift, _mwidth), \ + .mux = CCU_MUX_INIT(_muxshift, _muxwidth), \ + .common = { \ + .reg_ctrl = _reg_ctrl, \ + CCU_COMMON_PARENTS(_id, _name, _parents, _num_p, \ + spacemit_mux_div_gate_init, _flags) \ + }, \ +} + +#define CCU_MUX_DIV_GATE_SPLIT_FC_DEFINE(_id, _var, _name, _parents, \ + _num_p, _reg_ctrl, _reg_fc, \ + _mshift, _mwidth, _mask_fc, \ + _muxshift, _muxwidth, \ + _mask_gate, _flags) \ +static struct ccu_mix _var = { \ + .gate = CCU_GATE_INIT(_mask_gate), \ + .div = CCU_DIV_INIT(_mshift, _mwidth), \ + .mux = CCU_MUX_INIT(_muxshift, _muxwidth), \ + .common = { \ + .reg_ctrl = _reg_ctrl, \ + .reg_fc = _reg_fc, \ + .mask_fc = _mask_fc, \ + CCU_COMMON_PARENTS(_id, _name, _parents, _num_p, \ + spacemit_mux_div_gate_init, _flags) \ + }, \ +} + +#define CCU_MUX_DIV_FC_DEFINE(_id, _var, _name, _parents, _num_p, \ + _reg_ctrl, _reg_fc, _mshift, _mwidth, \ + _mask_fc, _muxshift, _muxwidth, _flags) \ +static struct ccu_mix _var = { \ + .div = CCU_DIV_INIT(_mshift, _mwidth), \ + .mux = CCU_MUX_INIT(_muxshift, _muxwidth), \ + .common = { \ + .reg_ctrl = _reg_ctrl, \ + .reg_fc = _reg_fc, \ + .mask_fc = _mask_fc, \ + CCU_COMMON_PARENTS(_id, _name, _parents, _num_p, \ + spacemit_mux_div_init, _flags) \ + }, \ +} + +#define CCU_MUX_FC_DEFINE(_id, _var, _name, _parents, _num_p, \ + _reg_ctrl, _reg_fc, _mask_fc, _muxshift, \ + _muxwidth, _flags) \ +static struct ccu_mix _var = { \ + .mux = CCU_MUX_INIT(_muxshift, _muxwidth), \ + .common = { \ + .reg_ctrl = _reg_ctrl, \ + .reg_fc = _reg_fc, \ + .mask_fc = _mask_fc, \ + CCU_COMMON_PARENTS(_id, _name, _parents, _num_p, \ + spacemit_mux_init, \ + _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); +} + +int ccu_gate_enable(struct clk *clk); +int ccu_gate_disable(struct clk *clk); + +int spacemit_gate_init(struct ccu_common *common); +int spacemit_factor_init(struct ccu_common *common); +int spacemit_mux_init(struct ccu_common *common); +int spacemit_div_init(struct ccu_common *common); +int spacemit_factor_gate_init(struct ccu_common *common); +int spacemit_div_gate_init(struct ccu_common *common); +int spacemit_mux_gate_init(struct ccu_common *common); +int spacemit_mux_div_init(struct ccu_common *common); +int spacemit_mux_div_gate_init(struct ccu_common *common); + +#endif /* _CLK_MIX_H_ */ diff --git a/drivers/clk/spacemit/clk_pll.c b/drivers/clk/spacemit/clk_pll.c new file mode 100644 index 00000000000..56da70af58a --- /dev/null +++ b/drivers/clk/spacemit/clk_pll.c @@ -0,0 +1,157 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2024 SpacemiT Technology Co. Ltd + * Copyright (c) 2024-2025 Haylen Chu <heylenay@4d2.org> + * Copyright (c) 2025 Junhui Liu <junhui.liu@pigmoral.tech> + * Authors: Haylen Chu <heylenay@4d2.org> + */ + +#include <dm/device.h> +#include <regmap.h> +#include <linux/bug.h> +#include <linux/clk-provider.h> + +#include "clk_pll.h" + +#define UBOOT_DM_SPACEMIT_CLK_PLL "spacemit_clk_pll" + +#define PLL_TIMEOUT_US 3000 +#define PLL_DELAY_US 5 + +#define PLL_SWCR3_EN ((u32)BIT(31)) +#define PLL_SWCR3_MASK GENMASK(30, 0) + +static const struct ccu_pll_rate_tbl *ccu_pll_lookup_best_rate(struct ccu_pll *pll, + unsigned long rate) +{ + struct ccu_pll_config *config = &pll->config; + const struct ccu_pll_rate_tbl *best_entry; + unsigned long best_delta = ULONG_MAX; + int i; + + for (i = 0; i < config->tbl_num; i++) { + const struct ccu_pll_rate_tbl *entry = &config->rate_tbl[i]; + unsigned long delta = abs(entry->rate - rate); + + if (delta < best_delta) { + best_delta = delta; + best_entry = entry; + } + } + + return best_entry; +} + +static const struct ccu_pll_rate_tbl *ccu_pll_lookup_matched_entry(struct ccu_pll *pll) +{ + struct ccu_pll_config *config = &pll->config; + u32 swcr1, swcr3; + int i; + + swcr1 = ccu_read(&pll->common, swcr1); + swcr3 = ccu_read(&pll->common, swcr3); + swcr3 &= PLL_SWCR3_MASK; + + for (i = 0; i < config->tbl_num; i++) { + const struct ccu_pll_rate_tbl *entry = &config->rate_tbl[i]; + + if (swcr1 == entry->swcr1 && swcr3 == entry->swcr3) + return entry; + } + + return NULL; +} + +static void ccu_pll_update_param(struct ccu_pll *pll, const struct ccu_pll_rate_tbl *entry) +{ + struct ccu_common *common = &pll->common; + + regmap_write(common->regmap, common->reg_swcr1, entry->swcr1); + ccu_update(common, swcr3, PLL_SWCR3_MASK, entry->swcr3); +} + +static int ccu_pll_enable(struct clk *clk) +{ + struct ccu_pll *pll = clk_to_ccu_pll(clk); + struct ccu_common *common = &pll->common; + unsigned int tmp; + + ccu_update(common, swcr3, PLL_SWCR3_EN, PLL_SWCR3_EN); + + /* check lock status */ + return regmap_read_poll_timeout(common->lock_regmap, + pll->config.reg_lock, + tmp, + tmp & pll->config.mask_lock, + PLL_DELAY_US, PLL_TIMEOUT_US); +} + +static int ccu_pll_disable(struct clk *clk) +{ + struct ccu_common *common = clk_to_ccu_common(clk); + + ccu_update(common, swcr3, PLL_SWCR3_EN, 0); + + return 0; +} + +/* + * PLLs must be gated before changing rate, which is ensured by + * flag CLK_SET_RATE_GATE. + */ +static unsigned long ccu_pll_set_rate(struct clk *clk, unsigned long rate) +{ + struct ccu_pll *pll = clk_to_ccu_pll(clk); + const struct ccu_pll_rate_tbl *entry; + + entry = ccu_pll_lookup_best_rate(pll, rate); + ccu_pll_update_param(pll, entry); + + return 0; +} + +static unsigned long ccu_pll_recalc_rate(struct clk *clk) +{ + struct ccu_pll *pll = clk_to_ccu_pll(clk); + const struct ccu_pll_rate_tbl *entry; + + entry = ccu_pll_lookup_matched_entry(pll); + + WARN_ON_ONCE(!entry); + + return entry ? entry->rate : 0; +} + +static const struct clk_ops spacemit_clk_pll_ops = { + .enable = ccu_pll_enable, + .disable = ccu_pll_disable, + .set_rate = ccu_pll_set_rate, + .get_rate = ccu_pll_recalc_rate, +}; + +int spacemit_pll_init(struct ccu_common *common) +{ + struct clk *clk = &common->clk; + struct ccu_pll *pll = clk_to_ccu_pll(clk); + int ret; + + ret = clk_register(clk, UBOOT_DM_SPACEMIT_CLK_PLL, + common->name, common->parents[0]); + if (ret) + return ret; + + if (ccu_pll_lookup_matched_entry(pll)) + return 0; + + ccu_pll_disable(clk); + ccu_pll_update_param(pll, &pll->config.rate_tbl[0]); + + return 0; +} + +U_BOOT_DRIVER(spacemit_clk_pll) = { + .name = UBOOT_DM_SPACEMIT_CLK_PLL, + .id = UCLASS_CLK, + .ops = &spacemit_clk_pll_ops, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/clk/spacemit/clk_pll.h b/drivers/clk/spacemit/clk_pll.h new file mode 100644 index 00000000000..6c684cf56b9 --- /dev/null +++ b/drivers/clk/spacemit/clk_pll.h @@ -0,0 +1,81 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2024 SpacemiT Technology Co. Ltd + * Copyright (c) 2024-2025 Haylen Chu <heylenay@4d2.org> + * Copyright (c) 2025 Junhui Liu <junhui.liu@pigmoral.tech> + * Copyright (c) 2025-2026 RISCStar Ltd. + * + * Authors: Haylen Chu <heylenay@4d2.org> + */ + +#ifndef _CLK_PLL_H_ +#define _CLK_PLL_H_ + +#include <linux/clk-provider.h> + +#include "clk_common.h" + +/** + * struct ccu_pll_rate_tbl - Structure mapping between PLL rate and register + * configuration. + * + * @rate: PLL rate + * @swcr1: Register value of PLLX_SW1_CTRL (PLLx_SWCR1). + * @swcr3: Register value of the PLLx_SW3_CTRL's lowest 31 bits of + * PLLx_SW3_CTRL (PLLx_SWCR3). This highest bit is for enabling + * the PLL and not contained in this field. + */ +struct ccu_pll_rate_tbl { + unsigned long rate; + u32 swcr1; + u32 swcr3; +}; + +#define CCU_PLL_RATE(_rate, _swcr1, _swcr3) \ + { \ + .rate = _rate, \ + .swcr1 = _swcr1, \ + .swcr3 = _swcr3, \ + } + +struct ccu_pll_config { + const struct ccu_pll_rate_tbl *rate_tbl; + u32 tbl_num; + u32 reg_lock; + u32 mask_lock; +}; + +struct ccu_pll { + struct ccu_common common; + struct ccu_pll_config config; +}; + +#define CCU_PLL_CONFIG(_table, _reg_lock, _mask_lock) \ + { \ + .rate_tbl = (_table), \ + .tbl_num = sizeof(_table) / sizeof((_table)[0]), \ + .reg_lock = (_reg_lock), \ + .mask_lock = (_mask_lock), \ + } + +#define CCU_PLL_DEFINE(_id, _var, _name, _parent, _table, _reg_swcr1, \ + _reg_swcr3, _reg_lock, _mask_lock, _flags) \ +static struct ccu_pll _var = { \ + .config = CCU_PLL_CONFIG(_table, _reg_lock, _mask_lock), \ + .common = { \ + .reg_swcr1 = _reg_swcr1, \ + .reg_swcr3 = _reg_swcr3, \ + CCU_COMMON(_id, _name, _parent, spacemit_pll_init, _flags) \ + } \ +} + +static inline struct ccu_pll *clk_to_ccu_pll(struct clk *clk) +{ + struct ccu_common *common = clk_to_ccu_common(clk); + + return container_of(common, struct ccu_pll, common); +} + +int spacemit_pll_init(struct ccu_common *common); + +#endif /* _CLK_PLL_H_ */ diff --git a/include/soc/spacemit/k1-syscon.h b/include/soc/spacemit/k1-syscon.h new file mode 100644 index 00000000000..331cc1d35bb --- /dev/null +++ b/include/soc/spacemit/k1-syscon.h @@ -0,0 +1,149 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ + +/* SpacemiT clock and reset driver definitions for the K1 SoC */ + +#ifndef __SOC_K1_SYSCON_H__ +#define __SOC_K1_SYSCON_H__ + +/* APBS register offset */ +#define APBS_PLL1_SWCR1 0x100 +#define APBS_PLL1_SWCR2 0x104 +#define APBS_PLL1_SWCR3 0x108 +#define APBS_PLL2_SWCR1 0x118 +#define APBS_PLL2_SWCR2 0x11c +#define APBS_PLL2_SWCR3 0x120 +#define APBS_PLL3_SWCR1 0x124 +#define APBS_PLL3_SWCR2 0x128 +#define APBS_PLL3_SWCR3 0x12c + +/* MPMU register offset */ +#define MPMU_POSR 0x0010 +#define MPMU_FCCR 0x0008 +#define POSR_PLL1_LOCK BIT(27) +#define POSR_PLL2_LOCK BIT(28) +#define POSR_PLL3_LOCK BIT(29) +#define MPMU_SUCCR 0x0014 +#define MPMU_ISCCR 0x0044 +#define MPMU_WDTPCR 0x0200 +#define MPMU_RIPCCR 0x0210 +#define MPMU_ACGR 0x1024 +#define MPMU_APBCSCR 0x1050 +#define MPMU_SUCCR_1 0x10b0 + +/* APBC register offset */ +#define APBC_UART1_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_TIMERS1_CLK_RST 0x34 +#define APBC_TWSI2_CLK_RST 0x38 +#define APBC_AIB_CLK_RST 0x3c +#define APBC_TWSI4_CLK_RST 0x40 +#define APBC_TIMERS2_CLK_RST 0x44 +#define APBC_ONEWIRE_CLK_RST 0x48 +#define APBC_TWSI5_CLK_RST 0x4c +#define APBC_DRO_CLK_RST 0x58 +#define APBC_IR_CLK_RST 0x5c +#define APBC_TWSI6_CLK_RST 0x60 +#define APBC_COUNTER_CLK_SEL 0x64 +#define APBC_TWSI7_CLK_RST 0x68 +#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_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_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 + +/* APMU register offset */ +#define APMU_JPG_CLK_RES_CTRL 0x020 +#define APMU_CSI_CCIC2_CLK_RES_CTRL 0x024 +#define APMU_ISP_CLK_RES_CTRL 0x038 +#define APMU_LCD_CLK_RES_CTRL1 0x044 +#define APMU_LCD_SPI_CLK_RES_CTRL 0x048 +#define APMU_LCD_CLK_RES_CTRL2 0x04c +#define APMU_CCIC_CLK_RES_CTRL 0x050 +#define APMU_SDH0_CLK_RES_CTRL 0x054 +#define APMU_SDH1_CLK_RES_CTRL 0x058 +#define APMU_USB_CLK_RES_CTRL 0x05c +#define APMU_QSPI_CLK_RES_CTRL 0x060 +#define APMU_DMA_CLK_RES_CTRL 0x064 +#define APMU_AES_CLK_RES_CTRL 0x068 +#define APMU_VPU_CLK_RES_CTRL 0x0a4 +#define APMU_GPU_CLK_RES_CTRL 0x0cc +#define APMU_SDH2_CLK_RES_CTRL 0x0e0 +#define APMU_PMUA_MC_CTRL 0x0e8 +#define APMU_PMU_CC2_AP 0x100 +#define APMU_PMUA_EM_CLK_RES_CTRL 0x104 +#define APMU_AUDIO_CLK_RES_CTRL 0x14c +#define APMU_HDMI_CLK_RES_CTRL 0x1b8 +#define APMU_CCI550_CLK_CTRL 0x300 +#define APMU_ACLK_CLK_CTRL 0x388 +#define APMU_CPU_C0_CLK_CTRL 0x38C +#define APMU_CPU_C1_CLK_CTRL 0x390 +#define APMU_PCIE_CLK_RES_CTRL_0 0x3cc +#define APMU_PCIE_CLK_RES_CTRL_1 0x3d4 +#define APMU_PCIE_CLK_RES_CTRL_2 0x3dc +#define APMU_EMAC0_CLK_RES_CTRL 0x3e4 +#define APMU_EMAC1_CLK_RES_CTRL 0x3ec + +/* RCPU register offsets */ +#define RCPU_SSP0_CLK_RST 0x0028 +#define RCPU_I2C0_CLK_RST 0x0030 +#define RCPU_UART1_CLK_RST 0x003c +#define RCPU_CAN_CLK_RST 0x0048 +#define RCPU_IR_CLK_RST 0x004c +#define RCPU_UART0_CLK_RST 0x00d8 +#define AUDIO_HDMI_CLK_CTRL 0x2044 + +/* RCPU2 register offsets */ +#define RCPU2_PWM0_CLK_RST 0x0000 +#define RCPU2_PWM1_CLK_RST 0x0004 +#define RCPU2_PWM2_CLK_RST 0x0008 +#define RCPU2_PWM3_CLK_RST 0x000c +#define RCPU2_PWM4_CLK_RST 0x0010 +#define RCPU2_PWM5_CLK_RST 0x0014 +#define RCPU2_PWM6_CLK_RST 0x0018 +#define RCPU2_PWM7_CLK_RST 0x001c +#define RCPU2_PWM8_CLK_RST 0x0020 +#define RCPU2_PWM9_CLK_RST 0x0024 + +/* APBC2 register offsets */ +#define APBC2_UART1_CLK_RST 0x0000 +#define APBC2_SSP2_CLK_RST 0x0004 +#define APBC2_TWSI3_CLK_RST 0x0008 +#define APBC2_RTC_CLK_RST 0x000c +#define APBC2_TIMERS0_CLK_RST 0x0010 +#define APBC2_KPC_CLK_RST 0x0014 +#define APBC2_GPIO_CLK_RST 0x001c + +#endif /* __SOC_K1_SYSCON_H__ */ -- 2.25.1 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 08/17] dts: k1: enable clocks in SPL 2026-01-17 19:01 [PATCH 00/17] Add board support for Spacemit K1 SoC in SPL Raymond Mao ` (6 preceding siblings ...) 2026-01-17 19:01 ` [PATCH 07/17] clk: spacemit: Add support for K1 SoC Raymond Mao @ 2026-01-17 19:01 ` Raymond Mao 2026-01-17 19:01 ` [PATCH 09/17] board: k1: initialize clock and serial devices " Raymond Mao ` (10 subsequent siblings) 18 siblings, 0 replies; 37+ messages in thread From: Raymond Mao @ 2026-01-17 19:01 UTC (permalink / raw) To: u-boot Cc: uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Yao Zi, Yu-Chien Peter Lin, Randolph Sheng-Kai Lin, Conor Dooley, Heinrich Schuchardt, Jamie Gibbons, Michal Simek, Eric Schikschneit, Junhui Liu, Yixun Lan, Sam Protsenko, Patrice Chotard, Patrick Delaunay, Casey Connolly, Christian Marangi, Ian Roberts, Vasileios Bimpikas, Oliver Gaskell, Nathan Barrett-Morrison, Aniket Limaye, Justin Swartz, Arturs Artamonovs, Greg Malysa, Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Kory Maincent, Anshul Dalal, Samuel Holland, Paul Barker, Justin Klaassen, Marek Vasut, Rui Miguel Silva, Gabriel Fernandez, Jonas Karlman, Kever Yang, Finley Xiao, Joseph Chen, Elaine Zhang From: Raymond Mao <raymond.mao@riscstar.com> Enable clock nodes for K1 SoC in SPL. Signed-off-by: Raymond Mao <raymond.mao@riscstar.com> --- arch/riscv/dts/k1-spl.dts | 51 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 49 insertions(+), 2 deletions(-) diff --git a/arch/riscv/dts/k1-spl.dts b/arch/riscv/dts/k1-spl.dts index 6018ea1e452..1f6db740747 100644 --- a/arch/riscv/dts/k1-spl.dts +++ b/arch/riscv/dts/k1-spl.dts @@ -11,16 +11,63 @@ / { model = "spacemit k1 spl"; + aliases { + console = &uart0; + serial0 = &uart0; + }; + chosen { stdout-path = "serial0:115200n8"; bootph-all; }; }; +&vctcxo_1m { + status = "okay"; + bootph-pre-ram; +}; + +&vctcxo_24m { + status = "okay"; + bootph-pre-ram; +}; + +&vctcxo_3m { + status = "okay"; + bootph-pre-ram; +}; + +&osc_32k { + status = "okay"; + bootph-pre-ram; +}; + &soc { bootph-all; - serial@d4017000 { + system-controller@d4050000 { status = "okay"; - bootph-all; + bootph-pre-ram; + }; + clock-controller@d4090000 { + status = "okay"; + bootph-pre-ram; + }; + system-controller@d4282800 { + status = "okay"; + bootph-pre-ram; }; + system-controller@d4015000 { + clocks = <&osc_32k>, <&vctcxo_1m>, <&vctcxo_3m>, + <&vctcxo_24m>, <&syscon_mpmu CLK_PLL1_31P5>, + <&pll CLK_PLL1_D4>; + clock-names = "osc", "vctcxo_1m", "vctcxo_3m", + "vctcxo_24m", "pll1_d78_31p5", "pll1_d4"; + status = "okay"; + bootph-pre-ram; + }; +}; + +&uart0 { + status = "okay"; + bootph-pre-ram; }; -- 2.25.1 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 09/17] board: k1: initialize clock and serial devices in SPL 2026-01-17 19:01 [PATCH 00/17] Add board support for Spacemit K1 SoC in SPL Raymond Mao ` (7 preceding siblings ...) 2026-01-17 19:01 ` [PATCH 08/17] dts: k1: enable clocks in SPL Raymond Mao @ 2026-01-17 19:01 ` Raymond Mao 2026-01-17 19:01 ` [PATCH 10/17] configs: k1: add default option for clock driver " Raymond Mao ` (9 subsequent siblings) 18 siblings, 0 replies; 37+ messages in thread From: Raymond Mao @ 2026-01-17 19:01 UTC (permalink / raw) To: u-boot Cc: uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Yao Zi, Yu-Chien Peter Lin, Heinrich Schuchardt, Randolph Sheng-Kai Lin, Conor Dooley, Jamie Gibbons, Michal Simek, Eric Schikschneit, Junhui Liu, Yixun Lan, Sam Protsenko, Patrice Chotard, Patrick Delaunay, Casey Connolly, Ilias Apalodimas, Christian Marangi, Oliver Gaskell, Greg Malysa, Arturs Artamonovs, Justin Swartz, Aniket Limaye, Nathan Barrett-Morrison, Ian Roberts, Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Kory Maincent, Paul Barker, Rui Miguel Silva, Justin Klaassen, Samuel Holland, Marek Vasut, Gabriel Fernandez, Kever Yang, Jonas Karlman, Heiko Stuebner, Finley Xiao, Joseph Chen, Elaine Zhang From: Raymond Mao <raymond.mao@riscstar.com> Initialize clock and serial devices in SPL. Otherwise, the device driver won't be loaded in SPL. Signed-off-by: Raymond Mao <raymond.mao@riscstar.com> --- board/spacemit/k1/spl.c | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/board/spacemit/k1/spl.c b/board/spacemit/k1/spl.c index 11a097389f1..1c299810d39 100644 --- a/board/spacemit/k1/spl.c +++ b/board/spacemit/k1/spl.c @@ -3,8 +3,44 @@ * Copyright (c) 2025-2026, RISCStar Ltd. */ +#include <dm/device.h> +#include <dm/uclass.h> #include <spl.h> +static void clk_early_init(void) +{ + struct udevice *dev; + int ret; + + ret = uclass_get_device_by_name(UCLASS_CLK, "clock-controller@d4090000", &dev); + if (ret) + panic("Fail to detect clock-controller@d4090000\n"); + ret = uclass_get_device_by_name(UCLASS_CLK, "system-controller@d4050000", &dev); + if (ret) + panic("Fail to detect system-controller@d4050000\n"); + ret = uclass_get_device_by_name(UCLASS_CLK, "system-controller@d4282800", &dev); + if (ret) + panic("Fail to detect system-controller@d4282800\n"); + ret = uclass_get_device_by_name(UCLASS_CLK, "system-controller@d4015000", &dev); + if (ret) + panic("Fail to detect system-controller@d4015000\n"); + + if (device_active(dev)) + debug("clk: device is active\n"); + else + debug("clk: device not active, probing...\n"); +} + +void serial_early_init(void) +{ + struct udevice *dev; + int ret; + + ret = uclass_get_device(UCLASS_SERIAL, 0, &dev); + if (ret) + panic("Serial uclass init failed: %d\n", ret); +} + void board_init_f(ulong dummy) { int ret; @@ -15,6 +51,8 @@ void board_init_f(ulong dummy) riscv_cpu_setup(); + clk_early_init(); + serial_early_init(); preloader_console_init(); } -- 2.25.1 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 10/17] configs: k1: add default option for clock driver in SPL 2026-01-17 19:01 [PATCH 00/17] Add board support for Spacemit K1 SoC in SPL Raymond Mao ` (8 preceding siblings ...) 2026-01-17 19:01 ` [PATCH 09/17] board: k1: initialize clock and serial devices " Raymond Mao @ 2026-01-17 19:01 ` Raymond Mao 2026-01-17 19:01 ` [PATCH 11/17] i2c: k1: add I2C driver support Raymond Mao ` (8 subsequent siblings) 18 siblings, 0 replies; 37+ messages in thread From: Raymond Mao @ 2026-01-17 19:01 UTC (permalink / raw) To: u-boot Cc: uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Yao Zi, Jamie Gibbons, Yu-Chien Peter Lin, Randolph Sheng-Kai Lin, Conor Dooley, Heinrich Schuchardt, Michal Simek, Eric Schikschneit, Junhui Liu, Yixun Lan, Sam Protsenko, Patrice Chotard, Patrick Delaunay, Casey Connolly, Neil Armstrong, Christian Marangi, Ian Roberts, Nathan Barrett-Morrison, Oliver Gaskell, Justin Swartz, Aniket Limaye, Arturs Artamonovs, Angelo Dureghello, Greg Malysa, Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Kory Maincent, Justin Klaassen, Paul Barker, Samuel Holland, Rui Miguel Silva, Marek Vasut, Gabriel Fernandez, Jonas Karlman, Kever Yang, Elaine Zhang, Finley Xiao, Joseph Chen From: Raymond Mao <raymond.mao@riscstar.com> Add default option for enabling clock driver in SPL. Signed-off-by: Raymond Mao <raymond.mao@riscstar.com> --- configs/k1_defconfig | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/configs/k1_defconfig b/configs/k1_defconfig index ca9c1d0bd8d..9c4612bcd84 100644 --- a/configs/k1_defconfig +++ b/configs/k1_defconfig @@ -44,3 +44,11 @@ CONFIG_DEBUG_UART_NS16550=y CONFIG_DEBUG_UART_ANNOUNCE=y # CONFIG_DEBUG_SBI_CONSOLE is not set CONFIG_TIMER_EARLY=y +CONFIG_REGMAP=y +CONFIG_SPL_REGMAP=y +CONFIG_LIB_RATIONAL=y +CONFIG_SPL_LIB_RATIONAL=y +CONFIG_CLK=y +CONFIG_CLK_SPACEMIT=y +CONFIG_SPL_CLK=y +CONFIG_SYS_MALLOC_F_LEN=0x5000 -- 2.25.1 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 11/17] i2c: k1: add I2C driver support 2026-01-17 19:01 [PATCH 00/17] Add board support for Spacemit K1 SoC in SPL Raymond Mao ` (9 preceding siblings ...) 2026-01-17 19:01 ` [PATCH 10/17] configs: k1: add default option for clock driver " Raymond Mao @ 2026-01-17 19:01 ` Raymond Mao 2026-01-19 5:24 ` Heiko Schocher 2026-01-17 19:01 ` [PATCH 12/17] dt-bindings: pinctrl: add k1 support Raymond Mao ` (7 subsequent siblings) 18 siblings, 1 reply; 37+ messages in thread From: Raymond Mao @ 2026-01-17 19:01 UTC (permalink / raw) To: u-boot Cc: uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Yao Zi, Randolph Sheng-Kai Lin, Yu-Chien Peter Lin, Conor Dooley, Heinrich Schuchardt, Jamie Gibbons, Michal Simek, Eric Schikschneit, Yixun Lan, Junhui Liu, Sam Protsenko, Patrice Chotard, Patrick Delaunay, Ilias Apalodimas, Casey Connolly, Christian Marangi, Neil Armstrong, Nathan Barrett-Morrison, Justin Swartz, Greg Malysa, Aniket Limaye, Ian Roberts, Oliver Gaskell, Utsav Agarwal, Arturs Artamonovs, Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Anshul Dalal, Samuel Holland, Paul Barker, Rui Miguel Silva, Justin Klaassen, Andre Przywara, Marek Vasut, Gabriel Fernandez, Jonas Karlman, Kever Yang, Joseph Chen, Elaine Zhang From: Raymond Mao <raymond.mao@riscstar.com> Add I2C driver support on Spacemit K1 SoC using driver model. Signed-off-by: Raymond Mao <raymond.mao@riscstar.com> --- drivers/i2c/Kconfig | 7 + drivers/i2c/Makefile | 1 + drivers/i2c/k1_i2c.c | 521 +++++++++++++++++++++++++++++++++++++++++++ drivers/i2c/k1_i2c.h | 69 ++++++ 4 files changed, 598 insertions(+) create mode 100644 drivers/i2c/k1_i2c.c create mode 100644 drivers/i2c/k1_i2c.h diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 55465dc1d46..eb7219f15a6 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -817,6 +817,13 @@ config SYS_I2C_IHS help Support for gdsys IHS I2C driver on FPGA bus. +config SYS_I2C_SPACEMIT_K1 + bool "Spacemit K1 I2C driver" + depends on DM_I2C + help + Support for Spacemit I2C controller. It's based on + Driver Model. + source "drivers/i2c/muxes/Kconfig" endif diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index 5fe30d0df4f..f25c56a37c7 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -57,6 +57,7 @@ obj-$(CONFIG_SYS_I2C_UNIPHIER) += i2c-uniphier.o 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_SYS_I2C_SPACEMIT_K1) += k1_i2c.o obj-$(CONFIG_TEGRA186_BPMP_I2C) += tegra186_bpmp_i2c.o obj-$(CONFIG_$(PHASE_)I2C_MUX) += muxes/ diff --git a/drivers/i2c/k1_i2c.c b/drivers/i2c/k1_i2c.c new file mode 100644 index 00000000000..2de24ac779b --- /dev/null +++ b/drivers/i2c/k1_i2c.c @@ -0,0 +1,521 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2023-2026 Spacemit, Inc + * Copyright (C) 2025-2026 RISCStar Ltd. + */ + +#include <asm/io.h> +#include <clk.h> +#include <dm.h> +#include <dm/device_compat.h> +#include <i2c.h> +#include <linux/delay.h> +#include <reset.h> +#include "k1_i2c.h" + +#define ICR_OFFSET 0x00 +#define ISR_OFFSET 0x04 +#define ISAR_OFFSET 0x08 +#define IDBR_OFFSET 0x0c +#define ILCR_OFFSET 0x10 +#define IWCR_OFFSET 0x14 +#define IRCR_OFFSET 0x18 +#define IBMR_OFFSET 0x1c +#define WFIFO_OFFSET 0x20 +#define WFIFO_WPTR_OFFSET 0x24 +#define WFIFO_RPTR_OFFSET 0x28 +#define RFIFO_OFFSET 0x2c +#define RFIFO_WPTR_OFFSET 0x30 +#define RFIFO_RPTR_OFFSET 0x34 + +/* All transfers are described by this data structure */ +struct k1_i2c_msg { + u8 condition; + u8 acknack; + u8 direction; + u8 data; +}; + +struct k1_i2c { + u32 icr; + u32 isr; + u32 isar; + u32 idbr; + u32 ilcr; + u32 iwcr; + u32 irst_cyc; + u32 ibmr; +}; + +struct k1_i2c_priv { + int id; + void __iomem *base; + struct reset_ctl_bulk resets; + struct clk clk; + u32 clk_rate; +}; + +/* + * i2c_reset: - reset the host controller + * + */ +static void i2c_reset(void __iomem *base) +{ + u32 icr_mode; + u32 val; + + /* Save bus mode (standard or fast speed) for later use */ + icr_mode = readl(base + ICR_OFFSET) & ICR_MODE_MASK; + /* disable unit */ + val = readl(base + ICR_OFFSET); + writel(val & ~ICR_IUE, base + ICR_OFFSET); + udelay(10); + /* reset the unit */ + val = readl(base + ICR_OFFSET); + val |= ICR_UR; + writel(val, base + ICR_OFFSET); + udelay(100); + /* disable unit */ + val = readl(base + ICR_OFFSET); + writel(val & ~ICR_IUE, base + ICR_OFFSET); + + /* set slave address */ + writel(0x00, base + ISR_OFFSET); + /* set control reg values */ + writel(I2C_ICR_INIT | icr_mode, base + ICR_OFFSET); + writel(I2C_ISR_INIT, base + ISR_OFFSET); /* set clear interrupt bits */ + val = readl(base + ICR_OFFSET); + val |= ICR_IUE; + writel(val, base + ICR_OFFSET); /* enable unit */ + udelay(100); +} + +/* + * 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(void __iomem *base, unsigned long set_mask, + unsigned long cleared_mask) +{ + int timeout = 1000, isr; + + do { + isr = readl(base + ISR_OFFSET); + 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 transfer a byte over the i2c bus in both directions. + * It is used by the public API functions. + * + * @return: 0: transfer successful or error code + */ +static int i2c_transfer(void __iomem *base, struct k1_i2c_msg *msg) +{ + int ret; + u32 val; + + 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 */ + val = readl(base + ICR_OFFSET); + val &= ~ICR_START; + writel(val, base + ICR_OFFSET); + val = readl(base + ICR_OFFSET); + val &= ~ICR_STOP; + writel(val, base + ICR_OFFSET); + writel(msg->data, base + IDBR_OFFSET); + if (msg->condition == I2C_COND_START) { + val = readl(base + ICR_OFFSET); + val |= ICR_START; + writel(val, base + ICR_OFFSET); + } + if (msg->condition == I2C_COND_STOP) { + val = readl(base + ICR_OFFSET); + val |= ICR_STOP; + writel(val, base + ICR_OFFSET); + } + if (msg->acknack == I2C_ACKNAK_SENDNAK) { + val = readl(base + ICR_OFFSET); + val |= ICR_ACKNAK; + writel(val, base + ICR_OFFSET); + } + if (msg->acknack == I2C_ACKNAK_SENDACK) { + val = readl(base + ICR_OFFSET); + val &= ~ICR_ACKNAK; + writel(val, base + ICR_OFFSET); + } + val = readl(base + ICR_OFFSET); + val &= ~ICR_ALDIE; + writel(val, base + ICR_OFFSET); + val = readl(base + ICR_OFFSET); + val |= ICR_TB; + writel(val, base + ICR_OFFSET); + + /* transmit register empty? */ + if (!i2c_isr_set_cleared(base, ISR_ITE, 0)) + goto transfer_error_transmit_timeout; + + /* clear 'transmit empty' state */ + val = readl(base + ISR_OFFSET); + val |= ISR_ITE; + writel(val, base + ISR_OFFSET); + + /* 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 */ + val = readl(base + ICR_OFFSET); + val &= ~ICR_START; + writel(val, base + ICR_OFFSET); + val = readl(base + ICR_OFFSET); + val &= ~ICR_STOP; + writel(val, base + ICR_OFFSET); + if (msg->condition == I2C_COND_START) { + val = readl(base + ICR_OFFSET); + val |= ICR_START; + writel(val, base + ICR_OFFSET); + } + if (msg->condition == I2C_COND_STOP) { + val = readl(base + ICR_OFFSET); + val |= ICR_STOP; + writel(val, base + ICR_OFFSET); + } + if (msg->acknack == I2C_ACKNAK_SENDNAK) { + val = readl(base + ICR_OFFSET); + val |= ICR_ACKNAK; + writel(val, base + ICR_OFFSET); + } + if (msg->acknack == I2C_ACKNAK_SENDACK) { + val = readl(base + ICR_OFFSET); + val &= ~ICR_ACKNAK; + writel(val, base + ICR_OFFSET); + } + val = readl(base + ICR_OFFSET); + val &= ~ICR_ALDIE; + writel(val, base + ICR_OFFSET); + val = readl(base + ICR_OFFSET); + val |= ICR_TB; + writel(val, base + ICR_OFFSET); + + /* receive register full? */ + if (!i2c_isr_set_cleared(base, ISR_IRF, 0)) + goto transfer_error_receive_timeout; + + msg->data = readl(base + IDBR_OFFSET); + + /* clear 'receive empty' state */ + val = readl(base + ISR_OFFSET); + val |= ISR_IRF; + writel(val, base + ISR_OFFSET); + break; + default: + goto transfer_error_illegal_param; + } + + return 0; + +transfer_error_msg_empty: + debug("%s: error: 'msg' is empty\n", __func__); + ret = -EINVAL; + goto i2c_transfer_finish; + +transfer_error_transmit_timeout: + debug("%s: error: transmit timeout\n", __func__); + ret = -ETIMEDOUT; + goto i2c_transfer_finish; + +transfer_error_ack_missing: + debug("%s: error: ACK missing\n", __func__); + ret = -EREMOTEIO; + goto i2c_transfer_finish; + +transfer_error_receive_timeout: + debug("%s: error: receive timeout\n", __func__); + ret = -ETIMEDOUT; + goto i2c_transfer_finish; + +transfer_error_illegal_param: + debug("%s: error: illegal parameters\n", __func__); + ret = -EINVAL; + goto i2c_transfer_finish; + +transfer_error_bus_busy: + debug("%s: error: bus is busy\n", __func__); + ret = -EIO; + goto i2c_transfer_finish; + +i2c_transfer_finish: + debug("%s: ISR: 0x%04x\n", __func__, readl(base + ISR_OFFSET)); + i2c_reset(base); + return ret; +} + +static int __i2c_read(void __iomem *base, uchar chip, u8 *addr, int alen, + uchar *buffer, int len) +{ + struct k1_i2c_msg msg; + int ret; + + debug("%s(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n", + __func__, chip, *addr, alen, len); + + if (len == 0) { + pr_err("reading zero byte is invalid\n"); + return -EINVAL; + } + + i2c_reset(base); + + /* dummy chip address write */ + debug("%s: dummy chip address write\n", __func__); + msg.condition = I2C_COND_START; + msg.acknack = I2C_ACKNAK_WAITACK; + msg.direction = I2C_WRITE; + msg.data = (chip << 1); + msg.data &= 0xFE; + ret = i2c_transfer(base, &msg); + if (ret) + return ret; + + /* + * send memory address bytes; + * alen defines how much bytes we have to send. + */ + while (--alen >= 0) { + debug("%s: send address byte %02x (alen=%d)\n", + __func__, *addr, alen); + msg.condition = I2C_COND_NORMAL; + msg.acknack = I2C_ACKNAK_WAITACK; + msg.direction = I2C_WRITE; + msg.data = addr[alen]; + ret = i2c_transfer(base, &msg); + if (ret) + return ret; + } + + /* start read sequence */ + debug("%s: start read sequence\n", __func__); + msg.condition = I2C_COND_START; + msg.acknack = I2C_ACKNAK_WAITACK; + msg.direction = I2C_WRITE; + msg.data = (chip << 1); + msg.data |= 0x01; + ret = i2c_transfer(base, &msg); + if (ret) + return ret; + + /* 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; + ret = i2c_transfer(base, &msg); + if (ret) + return ret; + + *buffer = msg.data; + debug("%s: reading byte (%p)=0x%02x\n", + __func__, buffer, *buffer); + buffer++; + } + + i2c_reset(base); + + return 0; +} + +static int __i2c_write(struct k1_i2c *base, uchar chip, u8 *addr, int alen, + uchar *buffer, int len) +{ + struct k1_i2c_msg msg; + int ret; + + debug("%s(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n", + __func__, chip, *addr, alen, len); + + i2c_reset(base); + + /* chip address write */ + debug("%s: chip address write\n", __func__); + msg.condition = I2C_COND_START; + msg.acknack = I2C_ACKNAK_WAITACK; + msg.direction = I2C_WRITE; + msg.data = (chip << 1); + msg.data &= 0xFE; + ret = i2c_transfer(base, &msg); + if (ret) + return ret; + + /* + * send memory address bytes; + * alen defines how much bytes we have to send. + */ + while (--alen >= 0) { + debug("%s: send address byte %02x (alen=%d)\n", + __func__, *addr, alen); + msg.condition = I2C_COND_NORMAL; + msg.acknack = I2C_ACKNAK_WAITACK; + msg.direction = I2C_WRITE; + msg.data = addr[alen]; + ret = i2c_transfer(base, &msg); + if (ret) + return ret; + } + + /* write bytes; send NACK at last byte */ + while (len--) { + debug("%s: writing byte (%p)=0x%02x\n", + __func__, 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++); + + ret = i2c_transfer(base, &msg); + if (ret) + return ret; + } + + i2c_reset(base); + + return 0; +} + +static int k1_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs) +{ + struct k1_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 -EINVAL; + } + + 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); + else + return __i2c_write(i2c->base, dmsg->addr, omsg->buf, + omsg->len, dmsg->buf, dmsg->len); +} + +static int k1_i2c_set_bus_speed(struct udevice *bus, unsigned int speed) +{ + struct k1_i2c_priv *priv = dev_get_priv(bus); + void __iomem *base = priv->base; + u32 val; + + if (speed > 100000) + val = ICR_FM; + else + val = ICR_SM; + clrsetbits_le32(base + ICR_OFFSET, ICR_MODE_MASK, val); + + return 0; +} + +static int k1_i2c_bind(struct udevice *bus) +{ + return 0; +} + +static int k1_i2c_probe(struct udevice *bus) +{ + struct k1_i2c_priv *priv = dev_get_priv(bus); + struct reset_ctl reset; + int ret; + + priv->id = dev_seq(bus); + ret = reset_get_by_index(bus, 0, &reset); + if (ret) { + dev_err(bus, "%s: can not get reset\n", __func__); + return ret; + } + reset_assert(&reset); + udelay(10); + reset_deassert(&reset); + udelay(10); + + ret = clk_get_by_index(bus, 0, &priv->clk); + if (ret) + return ret; + + ret = clk_enable(&priv->clk); + if (ret && ret != -ENOSYS && ret != -EOPNOTSUPP) { + debug("%s: failed to enable clock\n", __func__); + return ret; + } + priv->clk_rate = clk_get_rate(&priv->clk); + + priv->base = (void *)devfdt_get_addr_ptr(bus); + k1_i2c_set_bus_speed(bus, priv->clk_rate); + return 0; +} + +static const struct dm_i2c_ops k1_i2c_ops = { + .xfer = k1_i2c_xfer, + .set_bus_speed = k1_i2c_set_bus_speed, +}; + +static const struct udevice_id k1_i2c_ids[] = { + { .compatible = "spacemit,k1-i2c" }, + { } +}; + +U_BOOT_DRIVER(i2c_spacemit) = { + .name = "i2c_spacemit", + .id = UCLASS_I2C, + .of_match = k1_i2c_ids, + .bind = k1_i2c_bind, + .probe = k1_i2c_probe, + .priv_auto = sizeof(struct k1_i2c_priv), + .ops = &k1_i2c_ops, +}; diff --git a/drivers/i2c/k1_i2c.h b/drivers/i2c/k1_i2c.h new file mode 100644 index 00000000000..a755abf054d --- /dev/null +++ b/drivers/i2c/k1_i2c.h @@ -0,0 +1,69 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2023-2026 Spacemit Ltd. + * Copyright (C) 2025-2026 RISCStar Ltd. + */ + +#ifndef __SPACEMIT_I2C_H +#define __SPACEMIT_I2C_H + +/* 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 */ + +#define I2C_ISR_INIT 0x1FDE000 + +#endif -- 2.25.1 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [PATCH 11/17] i2c: k1: add I2C driver support 2026-01-17 19:01 ` [PATCH 11/17] i2c: k1: add I2C driver support Raymond Mao @ 2026-01-19 5:24 ` Heiko Schocher 0 siblings, 0 replies; 37+ messages in thread From: Heiko Schocher @ 2026-01-19 5:24 UTC (permalink / raw) To: Raymond Mao, u-boot Cc: uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Jaehoon Chung, Peng Fan, Yao Zi, Randolph Sheng-Kai Lin, Yu-Chien Peter Lin, Conor Dooley, Heinrich Schuchardt, Jamie Gibbons, Michal Simek, Eric Schikschneit, Yixun Lan, Junhui Liu, Sam Protsenko, Patrice Chotard, Patrick Delaunay, Ilias Apalodimas, Casey Connolly, Christian Marangi, Neil Armstrong, Nathan Barrett-Morrison, Justin Swartz, Greg Malysa, Aniket Limaye, Ian Roberts, Oliver Gaskell, Utsav Agarwal, Arturs Artamonovs, Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Anshul Dalal, Samuel Holland, Paul Barker, Rui Miguel Silva, Justin Klaassen, Andre Przywara, Marek Vasut, Gabriel Fernandez, Jonas Karlman, Kever Yang, Joseph Chen, Elaine Zhang Hello Raymond, On 17.01.26 20:01, Raymond Mao wrote: > From: Raymond Mao <raymond.mao@riscstar.com> > > Add I2C driver support on Spacemit K1 SoC using driver model. > > Signed-off-by: Raymond Mao <raymond.mao@riscstar.com> > --- > drivers/i2c/Kconfig | 7 + > drivers/i2c/Makefile | 1 + > drivers/i2c/k1_i2c.c | 521 +++++++++++++++++++++++++++++++++++++++++++ > drivers/i2c/k1_i2c.h | 69 ++++++ > 4 files changed, 598 insertions(+) > create mode 100644 drivers/i2c/k1_i2c.c > create mode 100644 drivers/i2c/k1_i2c.h > > diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig > index 55465dc1d46..eb7219f15a6 100644 > --- a/drivers/i2c/Kconfig > +++ b/drivers/i2c/Kconfig > @@ -817,6 +817,13 @@ config SYS_I2C_IHS > help > Support for gdsys IHS I2C driver on FPGA bus. > > +config SYS_I2C_SPACEMIT_K1 > + bool "Spacemit K1 I2C driver" > + depends on DM_I2C > + help > + Support for Spacemit I2C controller. It's based on > + Driver Model. > + > source "drivers/i2c/muxes/Kconfig" > > endif > diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile > index 5fe30d0df4f..f25c56a37c7 100644 > --- a/drivers/i2c/Makefile > +++ b/drivers/i2c/Makefile > @@ -57,6 +57,7 @@ obj-$(CONFIG_SYS_I2C_UNIPHIER) += i2c-uniphier.o > 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_SYS_I2C_SPACEMIT_K1) += k1_i2c.o Nitpick, please sort alphabetical. > obj-$(CONFIG_TEGRA186_BPMP_I2C) += tegra186_bpmp_i2c.o > > obj-$(CONFIG_$(PHASE_)I2C_MUX) += muxes/ > diff --git a/drivers/i2c/k1_i2c.c b/drivers/i2c/k1_i2c.c > new file mode 100644 > index 00000000000..2de24ac779b > --- /dev/null > +++ b/drivers/i2c/k1_i2c.c > @@ -0,0 +1,521 @@ > +// SPDX-License-Identifier: GPL-2.0+ > +/* > + * Copyright (C) 2023-2026 Spacemit, Inc > + * Copyright (C) 2025-2026 RISCStar Ltd. > + */ > + > +#include <asm/io.h> > +#include <clk.h> > +#include <dm.h> > +#include <dm/device_compat.h> > +#include <i2c.h> > +#include <linux/delay.h> > +#include <reset.h> > +#include "k1_i2c.h" > + > +#define ICR_OFFSET 0x00 > +#define ISR_OFFSET 0x04 > +#define ISAR_OFFSET 0x08 > +#define IDBR_OFFSET 0x0c > +#define ILCR_OFFSET 0x10 > +#define IWCR_OFFSET 0x14 > +#define IRCR_OFFSET 0x18 > +#define IBMR_OFFSET 0x1c > +#define WFIFO_OFFSET 0x20 > +#define WFIFO_WPTR_OFFSET 0x24 > +#define WFIFO_RPTR_OFFSET 0x28 > +#define RFIFO_OFFSET 0x2c > +#define RFIFO_WPTR_OFFSET 0x30 > +#define RFIFO_RPTR_OFFSET 0x34 > + > +/* All transfers are described by this data structure */ > +struct k1_i2c_msg { > + u8 condition; > + u8 acknack; > + u8 direction; > + u8 data; > +}; > + > +struct k1_i2c { > + u32 icr; > + u32 isr; > + u32 isar; > + u32 idbr; > + u32 ilcr; > + u32 iwcr; > + u32 irst_cyc; > + u32 ibmr; > +}; > + > +struct k1_i2c_priv { > + int id; > + void __iomem *base; > + struct reset_ctl_bulk resets; > + struct clk clk; > + u32 clk_rate; > +}; > + > +/* > + * i2c_reset: - reset the host controller > + * > + */ > +static void i2c_reset(void __iomem *base) > +{ > + u32 icr_mode; > + u32 val; > + > + /* Save bus mode (standard or fast speed) for later use */ > + icr_mode = readl(base + ICR_OFFSET) & ICR_MODE_MASK; > + /* disable unit */ > + val = readl(base + ICR_OFFSET); > + writel(val & ~ICR_IUE, base + ICR_OFFSET); > + udelay(10); > + /* reset the unit */ > + val = readl(base + ICR_OFFSET); > + val |= ICR_UR; > + writel(val, base + ICR_OFFSET); > + udelay(100); > + /* disable unit */ > + val = readl(base + ICR_OFFSET); > + writel(val & ~ICR_IUE, base + ICR_OFFSET); > + > + /* set slave address */ > + writel(0x00, base + ISR_OFFSET); > + /* set control reg values */ > + writel(I2C_ICR_INIT | icr_mode, base + ICR_OFFSET); > + writel(I2C_ISR_INIT, base + ISR_OFFSET); /* set clear interrupt bits */ > + val = readl(base + ICR_OFFSET); > + val |= ICR_IUE; > + writel(val, base + ICR_OFFSET); /* enable unit */ > + udelay(100); > +} > + > +/* > + * 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). may you can rework this to return 0 on success and on error -ETIMEDOUT ? > + */ > +static int /(void __iomem *base, unsigned long set_mask, > + unsigned long cleared_mask) > +{ > + int timeout = 1000, isr; > + > + do { > + isr = readl(base + ISR_OFFSET); > + udelay(10); > + if (timeout-- < 0) > + return 0; > + } while (((isr & set_mask) != set_mask) || > + ((isr & cleared_mask) != 0)); may you can use readl_poll_timeout ? > + > + return 1; > +} > + > +/* > + * i2c_transfer: - Transfer one byte over the i2c bus > + * > + * This function can transfer a byte over the i2c bus in both directions. > + * It is used by the public API functions. > + * > + * @return: 0: transfer successful or error code > + */ > +static int i2c_transfer(void __iomem *base, struct k1_i2c_msg *msg) > +{ > + int ret; > + u32 val; > + > + 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 */ > + val = readl(base + ICR_OFFSET); > + val &= ~ICR_START; > + writel(val, base + ICR_OFFSET); > + val = readl(base + ICR_OFFSET); > + val &= ~ICR_STOP; > + writel(val, base + ICR_OFFSET); > + writel(msg->data, base + IDBR_OFFSET); > + if (msg->condition == I2C_COND_START) { > + val = readl(base + ICR_OFFSET); > + val |= ICR_START; > + writel(val, base + ICR_OFFSET); > + } > + if (msg->condition == I2C_COND_STOP) { > + val = readl(base + ICR_OFFSET); > + val |= ICR_STOP; > + writel(val, base + ICR_OFFSET); > + } > + if (msg->acknack == I2C_ACKNAK_SENDNAK) { > + val = readl(base + ICR_OFFSET); > + val |= ICR_ACKNAK; > + writel(val, base + ICR_OFFSET); > + } > + if (msg->acknack == I2C_ACKNAK_SENDACK) { > + val = readl(base + ICR_OFFSET); > + val &= ~ICR_ACKNAK; > + writel(val, base + ICR_OFFSET); > + } > + val = readl(base + ICR_OFFSET); > + val &= ~ICR_ALDIE; > + writel(val, base + ICR_OFFSET); > + val = readl(base + ICR_OFFSET); > + val |= ICR_TB; > + writel(val, base + ICR_OFFSET); > + > + /* transmit register empty? */ > + if (!i2c_isr_set_cleared(base, ISR_ITE, 0)) > + goto transfer_error_transmit_timeout; > + > + /* clear 'transmit empty' state */ > + val = readl(base + ISR_OFFSET); > + val |= ISR_ITE; > + writel(val, base + ISR_OFFSET); > + > + /* 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: > + please remove empty line > + /* check if bus is not busy */ > + if (!i2c_isr_set_cleared(base, 0, ISR_IBB)) > + goto transfer_error_bus_busy; > + > + /* start receive */ > + val = readl(base + ICR_OFFSET); > + val &= ~ICR_START; > + writel(val, base + ICR_OFFSET); > + val = readl(base + ICR_OFFSET); > + val &= ~ICR_STOP; > + writel(val, base + ICR_OFFSET); > + if (msg->condition == I2C_COND_START) { > + val = readl(base + ICR_OFFSET); > + val |= ICR_START; > + writel(val, base + ICR_OFFSET); > + } > + if (msg->condition == I2C_COND_STOP) { > + val = readl(base + ICR_OFFSET); > + val |= ICR_STOP; > + writel(val, base + ICR_OFFSET); > + } > + if (msg->acknack == I2C_ACKNAK_SENDNAK) { > + val = readl(base + ICR_OFFSET); > + val |= ICR_ACKNAK; > + writel(val, base + ICR_OFFSET); > + } > + if (msg->acknack == I2C_ACKNAK_SENDACK) { > + val = readl(base + ICR_OFFSET); > + val &= ~ICR_ACKNAK; > + writel(val, base + ICR_OFFSET); > + } > + val = readl(base + ICR_OFFSET); > + val &= ~ICR_ALDIE; > + writel(val, base + ICR_OFFSET); > + val = readl(base + ICR_OFFSET); > + val |= ICR_TB; > + writel(val, base + ICR_OFFSET); > + > + /* receive register full? */ > + if (!i2c_isr_set_cleared(base, ISR_IRF, 0)) > + goto transfer_error_receive_timeout; > + > + msg->data = readl(base + IDBR_OFFSET); > + > + /* clear 'receive empty' state */ > + val = readl(base + ISR_OFFSET); > + val |= ISR_IRF; > + writel(val, base + ISR_OFFSET); > + break; > + default: > + goto transfer_error_illegal_param; > + } > + > + return 0; > + > +transfer_error_msg_empty: > + debug("%s: error: 'msg' is empty\n", __func__); > + ret = -EINVAL; > + goto i2c_transfer_finish; > + > +transfer_error_transmit_timeout: > + debug("%s: error: transmit timeout\n", __func__); > + ret = -ETIMEDOUT; > + goto i2c_transfer_finish; > + > +transfer_error_ack_missing: > + debug("%s: error: ACK missing\n", __func__); > + ret = -EREMOTEIO; > + goto i2c_transfer_finish; > + > +transfer_error_receive_timeout: > + debug("%s: error: receive timeout\n", __func__); > + ret = -ETIMEDOUT; > + goto i2c_transfer_finish; > + > +transfer_error_illegal_param: > + debug("%s: error: illegal parameters\n", __func__); > + ret = -EINVAL; > + goto i2c_transfer_finish; > + > +transfer_error_bus_busy: > + debug("%s: error: bus is busy\n", __func__); > + ret = -EIO; > + goto i2c_transfer_finish; > + > +i2c_transfer_finish: > + debug("%s: ISR: 0x%04x\n", __func__, readl(base + ISR_OFFSET)); > + i2c_reset(base); > + return ret; > +} > + > +static int __i2c_read(void __iomem *base, uchar chip, u8 *addr, int alen, > + uchar *buffer, int len) > +{ > + struct k1_i2c_msg msg; > + int ret; > + > + debug("%s(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n", > + __func__, chip, *addr, alen, len); > + > + if (len == 0) { > + pr_err("reading zero byte is invalid\n"); > + return -EINVAL; > + } > + > + i2c_reset(base); > + > + /* dummy chip address write */ > + debug("%s: dummy chip address write\n", __func__); > + msg.condition = I2C_COND_START; > + msg.acknack = I2C_ACKNAK_WAITACK; > + msg.direction = I2C_WRITE; > + msg.data = (chip << 1); > + msg.data &= 0xFE; > + ret = i2c_transfer(base, &msg); > + if (ret) > + return ret; > + > + /* > + * send memory address bytes; > + * alen defines how much bytes we have to send. > + */ > + while (--alen >= 0) { > + debug("%s: send address byte %02x (alen=%d)\n", > + __func__, *addr, alen); > + msg.condition = I2C_COND_NORMAL; > + msg.acknack = I2C_ACKNAK_WAITACK; > + msg.direction = I2C_WRITE; > + msg.data = addr[alen]; > + ret = i2c_transfer(base, &msg); > + if (ret) > + return ret; > + } > + > + /* start read sequence */ > + debug("%s: start read sequence\n", __func__); > + msg.condition = I2C_COND_START; > + msg.acknack = I2C_ACKNAK_WAITACK; > + msg.direction = I2C_WRITE; > + msg.data = (chip << 1); > + msg.data |= 0x01; > + ret = i2c_transfer(base, &msg); > + if (ret) > + return ret; > + > + /* 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; > + ret = i2c_transfer(base, &msg); > + if (ret) > + return ret; > + > + *buffer = msg.data; > + debug("%s: reading byte (%p)=0x%02x\n", > + __func__, buffer, *buffer); > + buffer++; > + } > + > + i2c_reset(base); > + > + return 0; > +} > + > +static int __i2c_write(struct k1_i2c *base, uchar chip, u8 *addr, int alen, > + uchar *buffer, int len) > +{ > + struct k1_i2c_msg msg; > + int ret; > + > + debug("%s(chip=0x%02x, addr=0x%02x, alen=0x%02x, len=0x%02x)\n", > + __func__, chip, *addr, alen, len); > + > + i2c_reset(base); > + > + /* chip address write */ > + debug("%s: chip address write\n", __func__); > + msg.condition = I2C_COND_START; > + msg.acknack = I2C_ACKNAK_WAITACK; > + msg.direction = I2C_WRITE; > + msg.data = (chip << 1); > + msg.data &= 0xFE; > + ret = i2c_transfer(base, &msg); > + if (ret) > + return ret; > + > + /* > + * send memory address bytes; > + * alen defines how much bytes we have to send. > + */ > + while (--alen >= 0) { > + debug("%s: send address byte %02x (alen=%d)\n", > + __func__, *addr, alen); > + msg.condition = I2C_COND_NORMAL; > + msg.acknack = I2C_ACKNAK_WAITACK; > + msg.direction = I2C_WRITE; > + msg.data = addr[alen]; > + ret = i2c_transfer(base, &msg); > + if (ret) > + return ret; > + } > + > + /* write bytes; send NACK at last byte */ > + while (len--) { > + debug("%s: writing byte (%p)=0x%02x\n", > + __func__, 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++); > + > + ret = i2c_transfer(base, &msg); > + if (ret) > + return ret; > + } > + > + i2c_reset(base); > + > + return 0; > +} > + > +static int k1_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, int nmsgs) > +{ > + struct k1_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 -EINVAL; > + } > + > + 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); > + else > + return __i2c_write(i2c->base, dmsg->addr, omsg->buf, > + omsg->len, dmsg->buf, dmsg->len); > +} > + > +static int k1_i2c_set_bus_speed(struct udevice *bus, unsigned int speed) > +{ > + struct k1_i2c_priv *priv = dev_get_priv(bus); > + void __iomem *base = priv->base; > + u32 val; > + > + if (speed > 100000) please use I2C_SPEED_STANDARD_RATE > + val = ICR_FM; > + else > + val = ICR_SM; > + clrsetbits_le32(base + ICR_OFFSET, ICR_MODE_MASK, val); > + > + return 0; > +} > + > +static int k1_i2c_bind(struct udevice *bus) > +{ > + return 0; > +} I think you can remove this function complete (and so in U_BOOT_DRIVER(i2c_spacemit)) > + > +static int k1_i2c_probe(struct udevice *bus) > +{ > + struct k1_i2c_priv *priv = dev_get_priv(bus); > + struct reset_ctl reset; > + int ret; > + > + priv->id = dev_seq(bus); > + ret = reset_get_by_index(bus, 0, &reset); > + if (ret) { > + dev_err(bus, "%s: can not get reset\n", __func__); > + return ret; > + } > + reset_assert(&reset); > + udelay(10); > + reset_deassert(&reset); > + udelay(10); > + > + ret = clk_get_by_index(bus, 0, &priv->clk); > + if (ret) > + return ret; > + > + ret = clk_enable(&priv->clk); > + if (ret && ret != -ENOSYS && ret != -EOPNOTSUPP) { > + debug("%s: failed to enable clock\n", __func__); > + return ret; > + } > + priv->clk_rate = clk_get_rate(&priv->clk); > + > + priv->base = (void *)devfdt_get_addr_ptr(bus); > + k1_i2c_set_bus_speed(bus, priv->clk_rate); > + return 0; > +} > + > +static const struct dm_i2c_ops k1_i2c_ops = { > + .xfer = k1_i2c_xfer, > + .set_bus_speed = k1_i2c_set_bus_speed, > +}; > + > +static const struct udevice_id k1_i2c_ids[] = { > + { .compatible = "spacemit,k1-i2c" }, > + { } > +}; > + > +U_BOOT_DRIVER(i2c_spacemit) = { > + .name = "i2c_spacemit", > + .id = UCLASS_I2C, > + .of_match = k1_i2c_ids, > + .bind = k1_i2c_bind, > + .probe = k1_i2c_probe, > + .priv_auto = sizeof(struct k1_i2c_priv), > + .ops = &k1_i2c_ops, > +}; > diff --git a/drivers/i2c/k1_i2c.h b/drivers/i2c/k1_i2c.h > new file mode 100644 > index 00000000000..a755abf054d > --- /dev/null > +++ b/drivers/i2c/k1_i2c.h > @@ -0,0 +1,69 @@ > +/* SPDX-License-Identifier: GPL-2.0+ */ > +/* > + * Copyright (C) 2023-2026 Spacemit Ltd. > + * Copyright (C) 2025-2026 RISCStar Ltd. > + */ > + > +#ifndef __SPACEMIT_I2C_H > +#define __SPACEMIT_I2C_H > + > +/* 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 */ > + > +#define I2C_ISR_INIT 0x1FDE000 > + > +#endif > Thanks! bye, Heiko -- Nabla Software Engineering HRB 40522 Augsburg Phone: +49 821 45592596 E-Mail: office@nabladev.com Geschäftsführer : Stefano Babic ^ permalink raw reply [flat|nested] 37+ messages in thread
* [PATCH 12/17] dt-bindings: pinctrl: add k1 support 2026-01-17 19:01 [PATCH 00/17] Add board support for Spacemit K1 SoC in SPL Raymond Mao ` (10 preceding siblings ...) 2026-01-17 19:01 ` [PATCH 11/17] i2c: k1: add I2C driver support Raymond Mao @ 2026-01-17 19:01 ` Raymond Mao 2026-01-18 9:26 ` Yao Zi 2026-01-17 19:01 ` [PATCH 13/17] spacemit: k1: add TLV EEPROM support in SPL Raymond Mao ` (6 subsequent siblings) 18 siblings, 1 reply; 37+ messages in thread From: Raymond Mao @ 2026-01-17 19:01 UTC (permalink / raw) To: u-boot Cc: uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Yao Zi, Jamie Gibbons, Randolph Sheng-Kai Lin, Heinrich Schuchardt, Conor Dooley, Yu-Chien Peter Lin, Eric Schikschneit, Michal Simek, Junhui Liu, Yixun Lan, Sam Protsenko, Patrice Chotard, Patrick Delaunay, Casey Connolly, Christian Marangi, Ilias Apalodimas, Arturs Artamonovs, Nathan Barrett-Morrison, Vasileios Bimpikas, Justin Swartz, Aniket Limaye, Ian Roberts, Angelo Dureghello, Oliver Gaskell, Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Anshul Dalal, Paul Barker, Justin Klaassen, Samuel Holland, Rui Miguel Silva, Jernej Skrabec, Marek Vasut, Gabriel Fernandez, Kever Yang, Jonas Karlman, Finley Xiao, Elaine Zhang, Joseph Chen From: Raymond Mao <raymond.mao@riscstar.com> Add dt-binding file of pinctrl driver for Spacemit K1 SoC. Signed-off-by: Raymond Mao <raymond.mao@riscstar.com> --- include/dt-bindings/pinctrl/k1-pinctrl.h | 59 ++++++++++++++++++++++++ 1 file changed, 59 insertions(+) create mode 100644 include/dt-bindings/pinctrl/k1-pinctrl.h diff --git a/include/dt-bindings/pinctrl/k1-pinctrl.h b/include/dt-bindings/pinctrl/k1-pinctrl.h new file mode 100644 index 00000000000..6c6b223c969 --- /dev/null +++ b/include/dt-bindings/pinctrl/k1-pinctrl.h @@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ +/* + * Copyright (C) 2025-2026 RISCStar Ltd. + */ + +#ifndef __DT_BINDINGS_K1_PINCTRL_H +#define __DT_BINDINGS_K1_PINCTRL_H + +/* pin mux */ +#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 + +/* strong pull resistor */ +#define SPU_EN BIT(3) + +/* edge detect */ +#define EDGE_NONE BIT(6) +#define EDGE_RISE BIT(4) +#define EDGE_FALL BIT(5) +#define EDGE_BOTH (EDGE_RISE | EDGE_FALL) + +/* slew rate output control */ +#define SLE_EN BIT(7) + +/* schmitter trigger input threshold */ +#define ST00 (0 << 8) +#define ST01 BIT(8) +#define ST02 BIT(9) +#define ST03 (BIT(8) | BIT(9)) + +/* driver strength*/ +#define PAD_DS_3V BIT(10) +#define PAD_DS_SLOW0 (0 << 11) +#define PAD_DS_SLOW1 BIT(11) +#define PAD_DS_MEDIUM BIT(12) +#define PAD_DS_FAST (BIT(11) | BIT(12)) + +#define PAD_1V8_DS0 PAD_DS_SLOW0 +#define PAD_1V8_DS1 PAD_DS_SLOW1 +#define PAD_1V8_DS2 PAD_DS_MEDIUM +#define PAD_1V8_DS3 PAD_DS_FAST + +#define PAD_3V_DS0 (PAD_DS_SLOW0 | PAD_DS_3V) +#define PAD_3V_DS1 (PAD_DS_SLOW1 | PAD_DS_3V) +#define PAD_3V_DS2 (PAD_DS_MEDIUM | PAD_DS_3V) +#define PAD_3V_DS3 (PAD_DS_FAST | PAD_DS_3V) + +/* 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 */ + +#endif /* __DT_BINDINGS_K1_PINCTRL_H */ -- 2.25.1 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [PATCH 12/17] dt-bindings: pinctrl: add k1 support 2026-01-17 19:01 ` [PATCH 12/17] dt-bindings: pinctrl: add k1 support Raymond Mao @ 2026-01-18 9:26 ` Yao Zi 2026-01-21 23:20 ` Raymond Mao 0 siblings, 1 reply; 37+ messages in thread From: Yao Zi @ 2026-01-18 9:26 UTC (permalink / raw) To: Raymond Mao, u-boot Cc: uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Jamie Gibbons, Randolph Sheng-Kai Lin, Heinrich Schuchardt, Conor Dooley, Yu-Chien Peter Lin, Eric Schikschneit, Michal Simek, Junhui Liu, Yixun Lan, Sam Protsenko, Patrice Chotard, Patrick Delaunay, Casey Connolly, Christian Marangi, Ilias Apalodimas, Arturs Artamonovs, Nathan Barrett-Morrison, Vasileios Bimpikas, Justin Swartz, Aniket Limaye, Ian Roberts, Angelo Dureghello, Oliver Gaskell, Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Anshul Dalal, Paul Barker, Justin Klaassen, Samuel Holland, Rui Miguel Silva, Jernej Skrabec, Marek Vasut, Gabriel Fernandez, Kever Yang, Jonas Karlman, Finley Xiao, Elaine Zhang, Joseph Chen On Sat, Jan 17, 2026 at 02:01:46PM -0500, Raymond Mao wrote: > From: Raymond Mao <raymond.mao@riscstar.com> > > Add dt-binding file of pinctrl driver for Spacemit K1 SoC. > > Signed-off-by: Raymond Mao <raymond.mao@riscstar.com> > --- > include/dt-bindings/pinctrl/k1-pinctrl.h | 59 ++++++++++++++++++++++++ > 1 file changed, 59 insertions(+) > create mode 100644 include/dt-bindings/pinctrl/k1-pinctrl.h > > diff --git a/include/dt-bindings/pinctrl/k1-pinctrl.h b/include/dt-bindings/pinctrl/k1-pinctrl.h > new file mode 100644 > index 00000000000..6c6b223c969 > --- /dev/null > +++ b/include/dt-bindings/pinctrl/k1-pinctrl.h > @@ -0,0 +1,59 @@ > +/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ > +/* > + * Copyright (C) 2025-2026 RISCStar Ltd. > + */ > + > +#ifndef __DT_BINDINGS_K1_PINCTRL_H > +#define __DT_BINDINGS_K1_PINCTRL_H > + > +/* pin mux */ > +#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 > + > +/* strong pull resistor */ > +#define SPU_EN BIT(3) > + > +/* edge detect */ > +#define EDGE_NONE BIT(6) > +#define EDGE_RISE BIT(4) > +#define EDGE_FALL BIT(5) > +#define EDGE_BOTH (EDGE_RISE | EDGE_FALL) > + > +/* slew rate output control */ > +#define SLE_EN BIT(7) > + > +/* schmitter trigger input threshold */ > +#define ST00 (0 << 8) > +#define ST01 BIT(8) > +#define ST02 BIT(9) > +#define ST03 (BIT(8) | BIT(9)) > + > +/* driver strength*/ > +#define PAD_DS_3V BIT(10) > +#define PAD_DS_SLOW0 (0 << 11) > +#define PAD_DS_SLOW1 BIT(11) > +#define PAD_DS_MEDIUM BIT(12) > +#define PAD_DS_FAST (BIT(11) | BIT(12)) > + > +#define PAD_1V8_DS0 PAD_DS_SLOW0 > +#define PAD_1V8_DS1 PAD_DS_SLOW1 > +#define PAD_1V8_DS2 PAD_DS_MEDIUM > +#define PAD_1V8_DS3 PAD_DS_FAST > + > +#define PAD_3V_DS0 (PAD_DS_SLOW0 | PAD_DS_3V) > +#define PAD_3V_DS1 (PAD_DS_SLOW1 | PAD_DS_3V) > +#define PAD_3V_DS2 (PAD_DS_MEDIUM | PAD_DS_3V) > +#define PAD_3V_DS3 (PAD_DS_FAST | PAD_DS_3V) > + > +/* 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 */ > + > +#endif /* __DT_BINDINGS_K1_PINCTRL_H */ These definitions look like hardware bits instead of dt-bindings, and I don't see a binding file for the pinctrl driver of SpacemiT K1 in Linux upstream. If it's the case, please keep the definitions inside your driver, correct the commit description, and probably squash it into the driver patch. Thanks, Yao Zi ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH 12/17] dt-bindings: pinctrl: add k1 support 2026-01-18 9:26 ` Yao Zi @ 2026-01-21 23:20 ` Raymond Mao 2026-01-22 14:55 ` Yao Zi 0 siblings, 1 reply; 37+ messages in thread From: Raymond Mao @ 2026-01-21 23:20 UTC (permalink / raw) To: Yao Zi Cc: u-boot, uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Jamie Gibbons, Randolph Sheng-Kai Lin, Heinrich Schuchardt, Conor Dooley, Yu-Chien Peter Lin, Eric Schikschneit, Michal Simek, Junhui Liu, Yixun Lan, Sam Protsenko, Patrice Chotard, Patrick Delaunay, Casey Connolly, Christian Marangi, Ilias Apalodimas, Arturs Artamonovs, Nathan Barrett-Morrison, Vasileios Bimpikas, Justin Swartz, Aniket Limaye, Ian Roberts, Angelo Dureghello, Oliver Gaskell, Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Anshul Dalal, Paul Barker, Justin Klaassen, Samuel Holland, Rui Miguel Silva, Jernej Skrabec, Marek Vasut, Gabriel Fernandez, Kever Yang, Jonas Karlman, Finley Xiao, Elaine Zhang, Joseph Chen Hi Yao Zi, On Sun, Jan 18, 2026 at 4:28 AM Yao Zi <me@ziyao.cc> wrote: > On Sat, Jan 17, 2026 at 02:01:46PM -0500, Raymond Mao wrote: > > From: Raymond Mao <raymond.mao@riscstar.com> > > > > Add dt-binding file of pinctrl driver for Spacemit K1 SoC. > > > > Signed-off-by: Raymond Mao <raymond.mao@riscstar.com> > > --- > > include/dt-bindings/pinctrl/k1-pinctrl.h | 59 ++++++++++++++++++++++++ > > 1 file changed, 59 insertions(+) > > create mode 100644 include/dt-bindings/pinctrl/k1-pinctrl.h > > > > diff --git a/include/dt-bindings/pinctrl/k1-pinctrl.h > b/include/dt-bindings/pinctrl/k1-pinctrl.h > > new file mode 100644 > > index 00000000000..6c6b223c969 > > --- /dev/null > > +++ b/include/dt-bindings/pinctrl/k1-pinctrl.h > > @@ -0,0 +1,59 @@ > > +/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ > > +/* > > + * Copyright (C) 2025-2026 RISCStar Ltd. > > + */ > > + > > +#ifndef __DT_BINDINGS_K1_PINCTRL_H > > +#define __DT_BINDINGS_K1_PINCTRL_H > > + > > +/* pin mux */ > > +#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 > > + > > +/* strong pull resistor */ > > +#define SPU_EN BIT(3) > > + > > +/* edge detect */ > > +#define EDGE_NONE BIT(6) > > +#define EDGE_RISE BIT(4) > > +#define EDGE_FALL BIT(5) > > +#define EDGE_BOTH (EDGE_RISE | EDGE_FALL) > > + > > +/* slew rate output control */ > > +#define SLE_EN BIT(7) > > + > > +/* schmitter trigger input threshold */ > > +#define ST00 (0 << 8) > > +#define ST01 BIT(8) > > +#define ST02 BIT(9) > > +#define ST03 (BIT(8) | BIT(9)) > > + > > +/* driver strength*/ > > +#define PAD_DS_3V BIT(10) > > +#define PAD_DS_SLOW0 (0 << 11) > > +#define PAD_DS_SLOW1 BIT(11) > > +#define PAD_DS_MEDIUM BIT(12) > > +#define PAD_DS_FAST (BIT(11) | BIT(12)) > > + > > +#define PAD_1V8_DS0 PAD_DS_SLOW0 > > +#define PAD_1V8_DS1 PAD_DS_SLOW1 > > +#define PAD_1V8_DS2 PAD_DS_MEDIUM > > +#define PAD_1V8_DS3 PAD_DS_FAST > > + > > +#define PAD_3V_DS0 (PAD_DS_SLOW0 | PAD_DS_3V) > > +#define PAD_3V_DS1 (PAD_DS_SLOW1 | PAD_DS_3V) > > +#define PAD_3V_DS2 (PAD_DS_MEDIUM | PAD_DS_3V) > > +#define PAD_3V_DS3 (PAD_DS_FAST | PAD_DS_3V) > > + > > +/* 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 */ > > + > > +#endif /* __DT_BINDINGS_K1_PINCTRL_H */ > > These definitions look like hardware bits instead of dt-bindings, and I > don't see a binding file for the pinctrl driver of SpacemiT K1 in Linux > upstream. If it's the case, please keep the definitions inside your > driver, correct the commit description, and probably squash it into the > driver patch. > > We'll use the pinctrl-single driver. So all pin configurations could be filled in the DTS file, not in the dt-binding file. But the pinmux configurations should be included in the dt-binding file. Regards, Raymond > Thanks, > Yao Zi > ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH 12/17] dt-bindings: pinctrl: add k1 support 2026-01-21 23:20 ` Raymond Mao @ 2026-01-22 14:55 ` Yao Zi 0 siblings, 0 replies; 37+ messages in thread From: Yao Zi @ 2026-01-22 14:55 UTC (permalink / raw) To: Raymond Mao Cc: u-boot, uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Jamie Gibbons, Randolph Sheng-Kai Lin, Heinrich Schuchardt, Conor Dooley, Yu-Chien Peter Lin, Eric Schikschneit, Michal Simek, Junhui Liu, Yixun Lan, Sam Protsenko, Patrice Chotard, Patrick Delaunay, Casey Connolly, Christian Marangi, Ilias Apalodimas, Arturs Artamonovs, Nathan Barrett-Morrison, Vasileios Bimpikas, Justin Swartz, Aniket Limaye, Ian Roberts, Angelo Dureghello, Oliver Gaskell, Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Anshul Dalal, Paul Barker, Justin Klaassen, Samuel Holland, Rui Miguel Silva, Jernej Skrabec, Marek Vasut, Gabriel Fernandez, Kever Yang, Jonas Karlman, Finley Xiao, Elaine Zhang, Joseph Chen On Wed, Jan 21, 2026 at 06:20:15PM -0500, Raymond Mao wrote: > Hi Yao Zi, > > On Sun, Jan 18, 2026 at 4:28 AM Yao Zi <me@ziyao.cc> wrote: > > > On Sat, Jan 17, 2026 at 02:01:46PM -0500, Raymond Mao wrote: > > > From: Raymond Mao <raymond.mao@riscstar.com> > > > > > > Add dt-binding file of pinctrl driver for Spacemit K1 SoC. > > > > > > Signed-off-by: Raymond Mao <raymond.mao@riscstar.com> > > > --- > > > include/dt-bindings/pinctrl/k1-pinctrl.h | 59 ++++++++++++++++++++++++ > > > 1 file changed, 59 insertions(+) > > > create mode 100644 include/dt-bindings/pinctrl/k1-pinctrl.h > > > > > > diff --git a/include/dt-bindings/pinctrl/k1-pinctrl.h > > b/include/dt-bindings/pinctrl/k1-pinctrl.h > > > new file mode 100644 > > > index 00000000000..6c6b223c969 > > > --- /dev/null > > > +++ b/include/dt-bindings/pinctrl/k1-pinctrl.h > > > @@ -0,0 +1,59 @@ > > > +/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */ > > > +/* > > > + * Copyright (C) 2025-2026 RISCStar Ltd. > > > + */ > > > + > > > +#ifndef __DT_BINDINGS_K1_PINCTRL_H > > > +#define __DT_BINDINGS_K1_PINCTRL_H > > > + > > > +/* pin mux */ > > > +#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 > > > + > > > +/* strong pull resistor */ > > > +#define SPU_EN BIT(3) > > > + > > > +/* edge detect */ > > > +#define EDGE_NONE BIT(6) > > > +#define EDGE_RISE BIT(4) > > > +#define EDGE_FALL BIT(5) > > > +#define EDGE_BOTH (EDGE_RISE | EDGE_FALL) > > > + > > > +/* slew rate output control */ > > > +#define SLE_EN BIT(7) > > > + > > > +/* schmitter trigger input threshold */ > > > +#define ST00 (0 << 8) > > > +#define ST01 BIT(8) > > > +#define ST02 BIT(9) > > > +#define ST03 (BIT(8) | BIT(9)) > > > + > > > +/* driver strength*/ > > > +#define PAD_DS_3V BIT(10) > > > +#define PAD_DS_SLOW0 (0 << 11) > > > +#define PAD_DS_SLOW1 BIT(11) > > > +#define PAD_DS_MEDIUM BIT(12) > > > +#define PAD_DS_FAST (BIT(11) | BIT(12)) > > > + > > > +#define PAD_1V8_DS0 PAD_DS_SLOW0 > > > +#define PAD_1V8_DS1 PAD_DS_SLOW1 > > > +#define PAD_1V8_DS2 PAD_DS_MEDIUM > > > +#define PAD_1V8_DS3 PAD_DS_FAST > > > + > > > +#define PAD_3V_DS0 (PAD_DS_SLOW0 | PAD_DS_3V) > > > +#define PAD_3V_DS1 (PAD_DS_SLOW1 | PAD_DS_3V) > > > +#define PAD_3V_DS2 (PAD_DS_MEDIUM | PAD_DS_3V) > > > +#define PAD_3V_DS3 (PAD_DS_FAST | PAD_DS_3V) > > > + > > > +/* 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 */ > > > + > > > +#endif /* __DT_BINDINGS_K1_PINCTRL_H */ > > > > These definitions look like hardware bits instead of dt-bindings, and I > > don't see a binding file for the pinctrl driver of SpacemiT K1 in Linux > > upstream. If it's the case, please keep the definitions inside your > > driver, correct the commit description, and probably squash it into the > > driver patch. > > > > We'll use the pinctrl-single driver. So all pin configurations could be But you removed the pinctrl-single node in PATCH 6, didn't you? And I don't think this "binding" file gets used in any devicetree after applying the series. And I suggest aligning with the upstream pinctrl binding. It eases migration to upstream device-tree, and makes it possible to share a single dtb between Linux and U-Boot, which is a nice feature. > filled in the DTS file, not in the dt-binding file. > But the pinmux configurations should be included in the dt-binding file. > Regards, > Raymond > > > > Thanks, > > Yao Zi > > Best regards, Yao Zi ^ permalink raw reply [flat|nested] 37+ messages in thread
* [PATCH 13/17] spacemit: k1: add TLV EEPROM support in SPL 2026-01-17 19:01 [PATCH 00/17] Add board support for Spacemit K1 SoC in SPL Raymond Mao ` (11 preceding siblings ...) 2026-01-17 19:01 ` [PATCH 12/17] dt-bindings: pinctrl: add k1 support Raymond Mao @ 2026-01-17 19:01 ` Raymond Mao 2026-01-17 19:01 ` [PATCH 14/17] spacemit: k1: Add DDR firmware support to SPL Raymond Mao ` (5 subsequent siblings) 18 siblings, 0 replies; 37+ messages in thread From: Raymond Mao @ 2026-01-17 19:01 UTC (permalink / raw) To: u-boot Cc: uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Yao Zi, Conor Dooley, Heinrich Schuchardt, Jamie Gibbons, Yu-Chien Peter Lin, Eric Schikschneit, Randolph Sheng-Kai Lin, Michal Simek, Yixun Lan, Junhui Liu, Sam Protsenko, Patrice Chotard, Patrick Delaunay, Casey Connolly, Neil Armstrong, Ilias Apalodimas, Christian Marangi, Ian Roberts, Vasileios Bimpikas, Angelo Dureghello, Justin Swartz, Aniket Limaye, Nathan Barrett-Morrison, Arturs Artamonovs, Utsav Agarwal, Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Kory Maincent, Paul Barker, Justin Klaassen, Rui Miguel Silva, Marek Vasut, Samuel Holland, Gabriel Fernandez, Kever Yang, Jonas Karlman, Elaine Zhang, Joseph Chen From: Raymond Mao <raymond.mao@riscstar.com> And support for required components including clock, I2C controller, and I2C EEPROM. Signed-off-by: Raymond Mao <raymond.mao@riscstar.com> --- arch/riscv/dts/k1-spl.dts | 28 +++++++++ arch/riscv/dts/k1.dtsi | 105 +++++++++++++++++++++++++++++++++- board/spacemit/k1/spl.c | 101 +++++++++++++++++++++++++++++++- board/spacemit/k1/tlv_codes.h | 22 +++++++ configs/k1_defconfig | 14 +++++ 5 files changed, 268 insertions(+), 2 deletions(-) create mode 100644 board/spacemit/k1/tlv_codes.h diff --git a/arch/riscv/dts/k1-spl.dts b/arch/riscv/dts/k1-spl.dts index 1f6db740747..cd7875f3e35 100644 --- a/arch/riscv/dts/k1-spl.dts +++ b/arch/riscv/dts/k1-spl.dts @@ -5,6 +5,7 @@ */ /dts-v1/; + #include "k1.dtsi" #include "binman.dtsi" @@ -65,6 +66,33 @@ status = "okay"; bootph-pre-ram; }; + + i2c@d4012000 { /* i2c2 */ + status = "okay"; + bootph-pre-ram; + eeprom: eeprom { + compatible = "atmel,24c02"; + reg = <0x50>; + status = "okay"; + bootph-pre-ram; + }; + }; + + i2c@d401d800 { /* i2c8 */ + status = "okay"; + bootph-pre-ram; + pmic@41 { + compatible = "pmic"; + reg = <0x41>; + status = "okay"; + bootph-pre-ram; + }; + }; + + reset-controller@d4050000 { + status = "okay"; + bootph-pre-ram; + }; }; &uart0 { diff --git a/arch/riscv/dts/k1.dtsi b/arch/riscv/dts/k1.dtsi index 20f1cb57462..59f901f233a 100644 --- a/arch/riscv/dts/k1.dtsi +++ b/arch/riscv/dts/k1.dtsi @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 OR MIT /* - * Copyright (C) 2024 Yangyu Chen <cyy@cyyself.name> + * Copyright (C) 2025-2026 RISCStar Ltd. */ #include <dt-bindings/clock/spacemit,k1-syscon.h> @@ -576,6 +576,21 @@ status = "disabled"; }; + reset: reset-controller@d4050000 { + compatible = "spacemit,k1-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>; + reg-names = "mpmu", "apmu", "apbc", "apbs", "ciu", "dciu", "ddrc", "apbc2"; + #reset-cells = <1>; + status = "disabled"; + }; + syscon_mpmu: system-controller@d4050000 { compatible = "spacemit,k1-syscon-mpmu"; reg = <0x0 0xd4050000 0x0 0x209c>; @@ -608,6 +623,94 @@ #reset-cells = <1>; }; + i2c0: i2c@d4010800 { + compatible = "spacemit,k1-i2c"; + reg = <0x0 0xd4010800 0x0 0x38>; + clocks = <&syscon_apbc CLK_TWSI0>; + resets = <&reset RESET_TWSI0>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c1: i2c@d4011000 { + compatible = "spacemit,k1-i2c"; + reg = <0x0 0xd4011000 0x0 0x38>; + clocks = <&syscon_apbc CLK_TWSI1>; + resets = <&reset RESET_TWSI1>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c2: i2c@d4012000 { + compatible = "spacemit,k1-i2c"; + reg = <0x0 0xd4012000 0x0 0x38>; + clocks = <&syscon_apbc CLK_TWSI2>; + resets = <&reset RESET_TWSI2>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c3: i2c@d4014000 { + compatible = "spacemit,k1-i2c"; + reg = <0x0 0xd4014000 0x0 0x38>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c4: i2c@d4012800 { + compatible = "spacemit,k1-i2c"; + reg = <0x0 0xd4012800 0x0 0x38>; + clocks = <&syscon_apbc CLK_TWSI4>; + resets = <&reset RESET_TWSI4>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c5: i2c@d4013800 { + compatible = "spacemit,k1-i2c"; + reg = <0x0 0xd4013800 0x0 0x38>; + clocks = <&syscon_apbc CLK_TWSI5>; + resets = <&reset RESET_TWSI5>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c6: i2c@d4018800 { + compatible = "spacemit,k1-i2c"; + reg = <0x0 0xd4018800 0x0 0x38>; + clocks = <&syscon_apbc CLK_TWSI6>; + resets = <&reset RESET_TWSI6>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c7: i2c@d401d000 { + compatible = "spacemit,k1-i2c"; + reg = <0x0 0xd401d000 0x0 0x38>; + clocks = <&syscon_apbc CLK_TWSI7>; + resets = <&reset RESET_TWSI7>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c8: i2c@d401d800 { + compatible = "spacemit,k1-i2c"; + reg = <0x0 0xd401d800 0x0 0x38>; + clocks = <&syscon_apbc CLK_TWSI8>; + resets = <&reset RESET_TWSI8>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + plic: interrupt-controller@e0000000 { compatible = "spacemit,k1-plic", "sifive,plic-1.0.0"; reg = <0x0 0xe0000000 0x0 0x4000000>; diff --git a/board/spacemit/k1/spl.c b/board/spacemit/k1/spl.c index 1c299810d39..6fe064bd430 100644 --- a/board/spacemit/k1/spl.c +++ b/board/spacemit/k1/spl.c @@ -3,9 +3,83 @@ * Copyright (c) 2025-2026, RISCStar Ltd. */ +#include <asm/io.h> +#include <clk.h> +#include <clk-uclass.h> +#include <configs/k1.h> #include <dm/device.h> #include <dm/uclass.h> +#include <dt-bindings/pinctrl/k1-pinctrl.h> +#include <i2c.h> +#include <linux/delay.h> +#include <log.h> #include <spl.h> +#include <tlv_eeprom.h> + +#define I2C_PIN_CONFIG(x) ((x) | EDGE_NONE | PULL_UP | PAD_1V8_DS2) +#define I2C_BUF_SIZE 64 + +#define MFP_GPIO_84 0xd401e154 +#define MFP_GPIO_85 0xd401e158 + +static void reset_early_init(void) +{ + struct udevice *dev; + int ret; + + ret = uclass_get_device(UCLASS_RESET, 0, &dev); + if (ret) + panic("Fail to detect reset controller.\n"); +} + +static void i2c_early_init(void) +{ + struct udevice *bus; + + // eeprom: I2C2, pin group(GPIO_84, GPIO_85) + writel(I2C_PIN_CONFIG(MUX_MODE4), (void __iomem *)MFP_GPIO_84); + writel(I2C_PIN_CONFIG(MUX_MODE4), (void __iomem *)MFP_GPIO_85); + udelay(100); + uclass_first_device(UCLASS_I2C, &bus); + while (bus) { + uclass_next_device(&bus); + if (!bus) + break; + } +} + +int read_product_name(char *name, int size) +{ + u8 eeprom_data[TLV_TOTAL_LEN_MAX], *p; + struct tlvinfo_header *tlv_hdr; + struct tlvinfo_tlv *tlv_entry; + int ret, i = 0; + u32 entry_size; + + if (!name || size <= 0) + return -EINVAL; + ret = read_tlvinfo_tlv_eeprom(eeprom_data, &tlv_hdr, + &tlv_entry, i); + if (ret) + return ret; + p = (u8 *)tlv_entry; + for (i = 0; i < tlv_hdr->totallen; ) { + if (tlv_entry->type == TLV_CODE_PRODUCT_NAME) { + if (tlv_entry->length < size) + size = tlv_entry->length; + memset(name, 0, size); + memcpy(name, &tlv_entry->value[0], size); + return 0; + } + if (tlv_entry->type == TLV_CODE_CRC_32) + return -ENOENT; + entry_size = tlv_entry->length + sizeof(struct tlvinfo_tlv); + i += entry_size; + p += entry_size; + tlv_entry = (struct tlvinfo_tlv *)p; + } + return -ENOENT; +} static void clk_early_init(void) { @@ -43,6 +117,7 @@ void serial_early_init(void) void board_init_f(ulong dummy) { + u8 i2c_buf[I2C_BUF_SIZE]; int ret; ret = spl_early_init(); @@ -51,12 +126,36 @@ void board_init_f(ulong dummy) riscv_cpu_setup(); + reset_early_init(); clk_early_init(); serial_early_init(); + preloader_console_init(); + + i2c_early_init(); + ret = read_product_name(i2c_buf, I2C_BUF_SIZE); + if (ret) + log_info("Fail to detect board:%d\n", ret); + else + log_info("Get board name:%s\n", (char *)i2c_buf); } u32 spl_boot_device(void) { - return BOOT_DEVICE_NONE; + return BOOT_DEVICE_NOR; +} + +void pmic_init(void) +{ + struct udevice *pmic_dev = NULL; + int ret; + + ret = uclass_get_device(UCLASS_PMIC, 0, &pmic_dev); + if (ret) + panic("Fail to detect PMIC:%d\n", ret); +} + +void spl_board_init(void) +{ + pmic_init(); } diff --git a/board/spacemit/k1/tlv_codes.h b/board/spacemit/k1/tlv_codes.h new file mode 100644 index 00000000000..7d1808e1acf --- /dev/null +++ b/board/spacemit/k1/tlv_codes.h @@ -0,0 +1,22 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2025-2026 RISCStar Ltd. + */ + +#ifndef __TLV_CODES_H +#define __TLV_CODES_H + +#define TLV_CODE_SDK_VERSION 0x40 +#define TLV_CODE_DDR_CSNUM 0x41 +#define TLV_CODE_DDR_TYPE 0x42 +#define TLV_CODE_DDR_DATARATE 0x43 +#define TLV_CODE_DDR_TX_ODT 0x44 + +#define TLV_CODE_WIFI_MAC_ADDR 0x60 +#define TLV_CODE_BLUETOOTH_ADDR 0x61 + +#define TLV_CODE_PMIC_TYPE 0x80 +#define TLV_CODE_EEPROM_I2C_INDEX 0x81 +#define TLV_CODE_EEPROM_PIN_GROUP 0x82 + +#endif /* __TLV_CODES_H */ diff --git a/configs/k1_defconfig b/configs/k1_defconfig index 9c4612bcd84..0d5c3932797 100644 --- a/configs/k1_defconfig +++ b/configs/k1_defconfig @@ -34,6 +34,7 @@ CONFIG_ENV_OVERWRITE=y CONFIG_PINCTRL=y CONFIG_PINCTRL_SINGLE=y CONFIG_RESET_SPACEMIT_K1=y +CONFIG_SPL_RESET_SPACEMIT_K1=y CONFIG_SYS_NS16550=y CONFIG_SYS_NS16550_MEM32=y CONFIG_DEBUG_UART=y @@ -52,3 +53,16 @@ CONFIG_CLK=y CONFIG_CLK_SPACEMIT=y CONFIG_SPL_CLK=y CONFIG_SYS_MALLOC_F_LEN=0x5000 +CONFIG_SPL_LOG_LEVEL=7 +CONFIG_SPL_DM_RESET=y +CONFIG_DM_I2C=y +CONFIG_SPL_I2C=y +CONFIG_SYS_I2C_SPACEMIT_K1=y +CONFIG_MISC=y +CONFIG_SPL_MISC=y +CONFIG_SPL_DRIVERS_MISC=y +CONFIG_I2C_EEPROM=y +CONFIG_SPL_I2C_EEPROM=y +CONFIG_CMD_TLV_EEPROM=y +CONFIG_SPL_CMD_TLV_EEPROM=y +CONFIG_LOG=y -- 2.25.1 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 14/17] spacemit: k1: Add DDR firmware support to SPL 2026-01-17 19:01 [PATCH 00/17] Add board support for Spacemit K1 SoC in SPL Raymond Mao ` (12 preceding siblings ...) 2026-01-17 19:01 ` [PATCH 13/17] spacemit: k1: add TLV EEPROM support in SPL Raymond Mao @ 2026-01-17 19:01 ` Raymond Mao 2026-01-19 9:40 ` Yao Zi 2026-01-17 19:01 ` [PATCH 15/17] power: pmic: add support for Spacemit P1 PMIC Raymond Mao ` (4 subsequent siblings) 18 siblings, 1 reply; 37+ messages in thread From: Raymond Mao @ 2026-01-17 19:01 UTC (permalink / raw) To: u-boot Cc: uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Yao Zi, Heinrich Schuchardt, Jamie Gibbons, Randolph Sheng-Kai Lin, Yu-Chien Peter Lin, Michal Simek, Eric Schikschneit, Yixun Lan, Junhui Liu, Sam Protsenko, Patrice Chotard, Patrick Delaunay, Casey Connolly, Neil Armstrong, Christian Marangi, Oliver Gaskell, Arturs Artamonovs, Greg Malysa, Justin Swartz, Nathan Barrett-Morrison, Aniket Limaye, Utsav Agarwal, Ian Roberts, Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Kory Maincent, Justin Klaassen, Samuel Holland, Paul Barker, Rui Miguel Silva, Marek Vasut, Gabriel Fernandez, Jonas Karlman, Kever Yang, Joseph Chen, Elaine Zhang From: Raymond Mao <raymond.mao@riscstar.com> Include DDR initialization firmware in the SPL image. The firmware path can be specified via the DDR_FW_FILE environment variable. If the firmware is not found, an empty placeholder file is created to allow the build to proceed without DDR initialization support. Signed-off-by: Raymond Mao <raymond.mao@riscstar.com> --- arch/riscv/dts/k1-spl.dts | 34 ++++++++++++++++++++++++++++++++- board/spacemit/k1/Kconfig | 8 ++++++++ board/spacemit/k1/Makefile | 19 ++++++++++++++++++ board/spacemit/k1/spl.c | 30 +++++++++++++++++++++++++++++ include/configs/k1.h | 3 +++ lib/vendor/spacemit/ddr_fw.bin | Bin 0 -> 19416 bytes 6 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 lib/vendor/spacemit/ddr_fw.bin diff --git a/arch/riscv/dts/k1-spl.dts b/arch/riscv/dts/k1-spl.dts index cd7875f3e35..f8b280fa96f 100644 --- a/arch/riscv/dts/k1-spl.dts +++ b/arch/riscv/dts/k1-spl.dts @@ -7,7 +7,6 @@ /dts-v1/; #include "k1.dtsi" -#include "binman.dtsi" / { model = "spacemit k1 spl"; @@ -21,6 +20,39 @@ stdout-path = "serial0:115200n8"; bootph-all; }; + + binman { + section { + filename = "u-boot-spl-ddr.bin"; + pad-byte = <0xff>; + align-size = <4>; + align = <4>; + + spl_section: section { + type = "section"; + size = <CONFIG_SPL_DDR_FIRMWARE_OFFSET>; + + u-boot-spl-nodtb { + type = "blob"; + filename = "spl/u-boot-spl.bin"; + align-end = <4>; + }; + + u-boot-spl-dtb { + type = "blob"; + filename = "spl/u-boot-spl.dtb"; + align-end = <4>; + }; + }; + + ddr_fw: ddr-firmware { + type = "blob"; + offset = <CONFIG_SPL_DDR_FIRMWARE_OFFSET>; + filename = "lib/vendor/spacemit/ddr_fw.bin"; + align-end = <4>; + }; + }; + }; }; &vctcxo_1m { diff --git a/board/spacemit/k1/Kconfig b/board/spacemit/k1/Kconfig index 9f9c806d00d..a5fa788f660 100644 --- a/board/spacemit/k1/Kconfig +++ b/board/spacemit/k1/Kconfig @@ -15,6 +15,14 @@ config SYS_CONFIG_NAME config TEXT_BASE default 0x00200000 +config SPL_DDR_FIRMWARE_OFFSET + hex "DDR firmware offset in SPL image" + depends on SPL + default 0x20000 + help + Offset where DDR firmware should be placed in the SPL + image. + config SPL_OPENSBI_LOAD_ADDR default 0x00000000 diff --git a/board/spacemit/k1/Makefile b/board/spacemit/k1/Makefile index 7bce47bac8c..ebe6e55867c 100644 --- a/board/spacemit/k1/Makefile +++ b/board/spacemit/k1/Makefile @@ -5,3 +5,22 @@ obj-y := board.o obj-$(CONFIG_SPL_BUILD) += spl.o + +DDR_FW_SRC ?= $(DDR_FW_FILE) +FW_TARGET = $(srctree)/lib/vendor/spacemit/ddr_fw.bin + +DDR_FW_HEADER = $(objtree)/include/generated/ddr_fw_info.h + +$(obj)/spl.o: $(DDR_FW_HEADER) + +$(DDR_FW_HEADER): $(FW_TARGET) + @echo "/* DDR firmware info - $$(date) */" > $@ + @if [ -f "$(FW_TARGET)" ]; then \ + SIZE=$$(stat -c%s "$(FW_TARGET)" 2>/dev/null || echo 0); \ + else \ + SIZE=0; \ + fi; \ + echo "#define DDR_FW_FILE_SIZE $$SIZE" >> $@ + @echo "/* Note: Update ADDR if binman layout changes */" >> $@ + +clean-files += $(FW_TARGET) $(DDR_FW_HEADER) diff --git a/board/spacemit/k1/spl.c b/board/spacemit/k1/spl.c index 6fe064bd430..54bad9000fe 100644 --- a/board/spacemit/k1/spl.c +++ b/board/spacemit/k1/spl.c @@ -6,10 +6,12 @@ #include <asm/io.h> #include <clk.h> #include <clk-uclass.h> +#include <cpu_func.h> #include <configs/k1.h> #include <dm/device.h> #include <dm/uclass.h> #include <dt-bindings/pinctrl/k1-pinctrl.h> +#include <generated/ddr_fw_info.h> #include <i2c.h> #include <linux/delay.h> #include <log.h> @@ -115,6 +117,33 @@ void serial_early_init(void) panic("Serial uclass init failed: %d\n", ret); } +/* Load DDR training firmware */ +int init_ddr_firmware(void) +{ + void __iomem *src, *dst; + unsigned long size; + + src = (void __iomem *)(CONFIG_SPL_TEXT_BASE + + CONFIG_SPL_DDR_FIRMWARE_OFFSET); + dst = (void __iomem *)(DDR_TRAINING_DATA_BASE); + memcpy(dst, src, DDR_FW_FILE_SIZE); + size = round_up(DDR_FW_FILE_SIZE, 64); + flush_dcache_range((u32)(u64)dst, (u32)(u64)dst + size); + return 0; +} + +void ddr_early_init(void) +{ + void __iomem *addr; + + init_ddr_firmware(); + addr = (void __iomem *)(CONFIG_SPL_TEXT_BASE + + CONFIG_SPL_DDR_FIRMWARE_OFFSET); + // verify DDR firmware header + log_info("[0x%x]:0x%x, firmware size:%d\n", + (uint)(u64)addr, readl(addr), DDR_FW_FILE_SIZE); +} + void board_init_f(ulong dummy) { u8 i2c_buf[I2C_BUF_SIZE]; @@ -138,6 +167,7 @@ void board_init_f(ulong dummy) log_info("Fail to detect board:%d\n", ret); else log_info("Get board name:%s\n", (char *)i2c_buf); + ddr_early_init(); } u32 spl_boot_device(void) diff --git a/include/configs/k1.h b/include/configs/k1.h index d46fec8b251..4cefdf7c725 100644 --- a/include/configs/k1.h +++ b/include/configs/k1.h @@ -16,4 +16,7 @@ #define RISCV_MMODE_TIMER_FREQ 24000000 #define RISCV_SMODE_TIMER_FREQ 24000000 +#define DDR_TRAINING_DATA_BASE 0xC0832000 +#define DDR_TRAINING_INFO_BUFF 0xC0800000 + #endif /* __CONFIG_H */ diff --git a/lib/vendor/spacemit/ddr_fw.bin b/lib/vendor/spacemit/ddr_fw.bin new file mode 100644 index 0000000000000000000000000000000000000000..cefecae24977ee76c74e6f3b658adc6a81984640 GIT binary patch literal 19416 zcmc&*3vgT2nZAl7U!cPh)(Zj>rozHjU?_DGa3Hfu9b!i?Q<mkmz;swJvMkaDCw80{ zTc~YWzBrx0B&H~--Hl_%*ks!*gfyPGlR$`#x(}8T*mXnOO@d=C?Nai<_$kTz{pZ|s z@72?CfL+fdx;p1S|Lgp(^WURQRXM|XXQiuLf4w^rSkw@0^|}g%WAwC3#`E?3`3ODd z@#j-`UaEv1lB8xuerx++pr9mXbvMKU?!H)2V{dS2@J#W^>n&3InpriaW%ae2s`7@V ztM({+8y6_9n};I@6xU6|kzU1h<8Z{~v|(LCbdDlRO&;$xqtX_S%Q+ltmWypf@AkGJ z`@Yq~sJly|b?&Ax#=zrsZB6Vm;I_qDLW+fO5DzUOzf|Ww{z9GG>h6oqk>yzy_bi8{ z`EX;8EY1E;jL$t9V3=ORXJ2%eyUtzjsB3OrPSRf9oje8(V@nmRiH*O&sg%U(+=H!Z zBtHf8bQtQ~L!VouJWV%-_B&)->{L6~tMc<!uhlagv$%VMj#5d=wfpAOhg^VoraRy{ z4eDFNOO>F<`xm3qk~Y4^^Gd6i!*<TC4_(*IN7XJdT6%4L$Rc&**kT8@74Da}djp`- z5`^X$*1(DnVs!=9qK0UreQ)R`d0*&2C|GeI6bScht8*XLc<H=mRw&^4AQp6Y<iIBI zlsh_lS=2N5g*u_}-zKQ~uBr#@X~4Q<f<4V(gPy^tdVU&tS_O{IzcR`5Q!!e4MUp%_ zvX^JzeUm(wPAgBdpz8ZZdU;5f&<T@sn8|s_GdQMxWRc9?5WnN+v>o?v5j!4$_KQMR zk1QFxAH0a~{!?jp-`^xS?3WE~$<K*VA29IUe?{0!V>a3fgym(1rtFhxG&L%AUab`r z`^VB~YKrfCN?AM<Rl0sCaM-7qENs;C4`Q?vqq;0?PT7>DEEYqS($6x;!mzq)1V#I& z>19c|>m%w%<j?Qz332{bXWHG)KV|T3zWxV-lc95lM%>>QqxSPcBk*mu!vADujchjg zwqvuQm7(9K(#jU@+YEE~2|=~<!!%mS<l9`HzZW=$RFgc9iqYUFN%DMe2J+OK<au{m zc^(v0JKsq!Ps&|BpWe6kviwFi@Mrk!Fe0`U|F`7Gk`=l2r*dz|?(Yp*5mzbK@+jL8 zRF6?iT-QcXdQ+RW4)Yv3(BE^6#^yANcx^@OwYVu_<mBu_ygm@pAc6O0#d}V*5xf!K zHTV_aCoamT<0eg%ABm6XT24f69xNXnCW=W>a7z7*<PLI~j}gZ~|AA1)7WEkEXiJ-z z4ZPj+ev;hbo?}Id_vz7Di8Ih&94>*y3Lad~t4v!-yiBTN+(+C+V&{WL>qEpxez)eY zx5WEvu!16T&oLt+`}UBnq>%Ki8sRuRg#vr$oAn_+CV#utOS0SjgfIMliyb?ufA4wU z;$GaybNJ99@&KcTGO~tYSy5pjw8tjPvLa?1R^@t5ttG2^kXh9uVvWhF<T{chvsF<Z zfJIHIY!9-rsAMiuTGP0i-kP3FV@+SEXZ4*9gL}=IT(xRF$qmX(tIWb0)NKOR6_mHp zE+6U^BZ0T&`b3+8q;;^ijibzW;J3P_fH#hoz{0F8sBSZ3O5}m&k}NT*j%fCFsjwAa zd%Pv8-$-SNa-Cs`{dLn>ViziQZdLZ}!V>*CW=jlhi?>9%-mt{dR<kAEUX>TAmG&q% zE2zP#iobq1f{HnUYSiDN$V(6I<dwQUvIHZj=na_gcQAr;0IKQ;MUJf=?-iqx>v~)4 zhBg{wXAWR&Q9OluWnREApbAF~|C^{|`~`MOL0#Sw3L~dmQTHF$#>^|JYVV7o-uIWp zP~U4<-f1ybyKz=9tp=R2#>VO8HpzscFUm2@Z!?|=JLAbYj&sG(09ATV)Ldse^>9i1 zqMCk48+4|^xr2`|ZP3ZePiG8Bm%Eiw6Z{f2@vKuTHmJp)BlfTp7Gc*k`$x5ixXlf@ zC2nc%oxP#f<ut2(|Hs}?y`nu2>2?B}>Tz6hYqK)2ce8xCKUem=y8UR6a>u33O3%D) z@*?^1;#^sN9Aga1(Y6_5l5P7@&7M!TdKY0PS031ViG0;^vZh6g=6%p?_x#FnD?86T zBP=oe2fzYzuG};4FXLe4A9L8wrv<G1JAv2HmVmdG!wzi_u%6#S8b+&gqmYL9<hyur zx52q#8Egk^q}@M%&LvUb7g+k&*N5_duE}>yj1s+gP07DZp{e3@no{2pnEKZVOf%<F z`4@p@Xl;Gyu007HrP{j`93^UGdL8ArCs5j-o$NEG^o*97)m|ZKzhCG}*r+>8Ir$!X z4hT%0K7ncGnpa;FSW3%{N>+JQj1B>Js`H<@AJTCti=_BJ;MpB*##wq-I6gv{<KTSO zb1<TZc}_%#T8V7<)QNy+KZ^u}jdf<uerLCc4u~~Y@71F?`R_;NhOW)o6TiA0)q(gn z)ysIm_>W#UDiO=&d7nzNwfG-n@t<{m5Upo%PAGmh#HiacE0=d$5EIMoh>2HMHAdRU zBnzU{ZTrWHC{~T_qi)a`@DvP>HF-L0!?E{RucukAwen67K9Mb4H`yZS`=DpkEWc`X z&BI6m8$td#L@Ou@jcZYsGK|wa;^8@Gg2VL4HVF_n4dZ*m<Wl97f2$kcZ=~-!4vN(C z%p)vP7x0m^xvAKco5ov0YGQ60H&*I-1~gj~Mb}=BY{{h#Rp0n8OKDfW`A2#VvggM> zq30&{yi=v;E$sQk$MpOQ4$q!n<M2Z?evreTrsv}vevmp~Euk*0Yu1405O_VV^|z>_ zw#f9o5Ay@8t45iFI$`LzvG2&9ep{qj9lebA)odoLB@qF|S2f`K1``%!YNJ=@@0)B^ ziHEsIgPsoiaO@}T0bovu&9im=diLW?m6ZLlLg>|Hx5X^&@TeG3?+Hm3^edI)@C&QI zWRh{K;o!Z)9=UclpSAH>cf&aKwMc9B72JCs>r27Yn9h@^1}@TS5fe8Y%T}iSsW&bd zi@$HeRE22Iz#TjFWB9Og$}@PyD7tLBsow@2(i8OIc`=r|Ve~SJEQ3#ueg+?>T9nQ2 zXW9XVF`VAURAygs)~HBv*7%(_;WN5kESg?U?6XK8uUS!ZF}(cRs`gK7XW#g|t8jm0 zL7*rI%{9K&xI#J4D#o9(ijmbR6FAAh2N40_dFTqm+gKbRFVyNuWk&U6-(*W@R9G~g z6_W**;Ja-4ZlihKf=gn7g1!kJt+@5QLXnVJn6QpwVI3IFR1XHR6VZWW9nUR>hDX#1 z$_5qX`OwtuRXLHoF{-9nZyfbBw19X9E%0~-EoiZdDnwl?a@v}j^L{Tn4)MIt&XV^g z&O7XB2eYRg9`CiIQfLu%<vhzpPRozfhpt7fE}+o4pDUo$Vgc1ZN#~MeOKXTg4`*@m zVOZ5AIN!KSB6A!n`knMH;ntlNH@fyRJJIShR?N)TW_UlJSCt2XTHQB-x{qND-<AfW zBP~WpDvbT;v~i4G3zIPtF1w%jymcp?of2g*&zrGxZmFNB$^WekxE<5r#(XmF(vPX) z_-M@?>>P4!RpY1apVZFY^Bi*S#Dd^~;Nr%^jdv(-Q}&&JAHoCShsbO2!|RzJ<}p8X z4o|r9=<Q4&GNfjO{2Yhx?5syt$j)&DK_e_f;@u8k!$!z|={?Up8%9ee$Om~Y=)<$g z|Du6{2F?HQJ|{|N$U~i!osmP~rB*lITI{5iTUf3()jUKEesaXGMPZ_Y>?G*Wv&ZE3 zEORA%53}#=92jAd8#ppkW;rH8SvnOQa=i24PNN#?10?s%L;sZMnNH0!`%r^XRKXiK zc21>ppLjMrZ3m0*l-cfPnT;}_8~R}xPO-n)qR2XBobp(okRm~J5u`&dfM+?}64~Yg zg))M*$Tk`9mBixT_H?jb#%>n<(qjkh0Yyqj!{WBPzdAbD%`~!D+!ud^bP(&)(z!Hi zI!5lL`r&7u!AbRWPmgrf^D-)sJbwD-c0l_=`w+lBSSw0m)WvO9!YekTliSg#O6FCX zzN!9V(LL2#T1W5eTra5CB(BvwV%oJGDb_+S+0m_4=aO|+Y1xx_<bKZ9>)t}%VfZvv zDZ-NLP>JJNk*&hVp&@9|kU6jd&;`%@ID`GN&ab%!()M9Q9U<->(ek6gT^u(iF1gh4 z+|d||e^%k+t;<vMxU1j-`8>z@T=u2-WLk7(*5Z*1<#6~b)ud}WO`f_?KA}mnoWyF^ zHh~&sQhk|n1-zA2S0$_x#v9u&)a`VqfX;;mUo8|D5=NIQ2b4dzu(<8EO&ktdZ?#RH zIr;7hp4mO<0gzvdUO(&D=2P!0zY>*^Ze@laOrP7Vi)@qh4kZu{<NdXs<v@jc-D1>~ z?-FJdBl9K9h#dHTkp=6L>eCC!f@$~lJg>1oetZS1vU$e>-GUhXLtaJQiapnQ!Q{=m z{DT#vG0~-Xw5suR`^nmi==`!Th#M`9OBK{fsLoL*p*lyMgvyECVxjX2?;6awQs-3* z#Sw*i6Rc{YTEb7&4l+N^Ba{3*LJ@2Hp9vlnR?3d}ktzKI$|5POBtkYK0~bH_SRu2y zKQ8cyvognSba1G5b5Isl%hoO)ed$C+`s$G{%JMwXJSykVxwKi9at3opV;weLxxA>y zdxno!E`^4-@hrSsdvj@2FfXR6U?N8Kf_GiTblN4k6Dk)IcFgLPOL`hf70d<ELDppz zMJ75470d<E!Ol!eC!vB#K?iXX9XQr6NUmHKh{^>WmAEQNt6(C$dQtLN^-^o9Ua(Tr zIjo1Wefsr!1yiSP)+-ooJ#?A%`i>Oqx%FmAzh2!;)>@XXl0olEg@2LFT9HNg>BMY% ze2(8N6ZJu&6$DnmRtum%t5(g#?+JAEBIU05JsDF+h%<4@kFR2MPVgp8aLBc0cm;7r zV?k4X%giBFGBf1zJm>PRlr>DYT*7K_qDib_QfrZFnHlo<Ip?wLOYz7xNqiddE3-DK znwcS|=$G&qZ0t7CMHQj%vamy@Gp(C!RHi9>j@cY46ydi{;kSvD1m;AFy5zG`NuK26 zar8`njyLck!t=92I(kg9yku+0juIk5)|7O~^1g&*^_*T}?Mc07bXqr49Ev|FqV|lc zwWvuaSuGhk^P4wLB8{Q<rr;I;?G&#iL)(m6a_HZwmdvI$psIk^jv?IT{7UMAq&n_G z>jJWXlzKYLYq^&n&nYiM$5h-UMlUO}fW7NR1%}#*Zgrp|i8~gs9sK{GI920jm8(`o z933Y7GUYb?X6Cqx8_zb}7V+S=h>hPzVz));xi@sV$AvzKaZ{JyV#d7(^t?D#=pAqI zwceP1L*WS3bh<~d+Q&KfsKCSTPta{^RFk*#MW{O#zzq}EEyJ-Z+VB+1RUDG*meVn0 zl_+He#{Z&*NYnusf{pxfidHNQ@|y;^7R!L^mdoe43hU-cmqx3v+<M~+d!JwMd{JO= z@Nn>s#<v@z8;&^ILr*KNm(>sX^LoX#TRc}Qu6FT!jRG&xU~W`g`t!|7N39r#-u34q z1>J(*QeDmQ2D-u@>KeIzIL58F>jZkj?Bo;dtPe#uz@C41#IaCOkb!a=2V8Zfi}9Xo z=Vu%`{CfeNznh?mcWalTaYYpPyO?jP8vJnq--)|38Xqqcyg|p{PP?IgcIWT3vGAe~ z>AlFVFvq5TAh7kf8Q44;b!%F@jHi>A?Gsqt4C}#v<5-n<1=b<lrr|JVT(1WeNgM49 z>ymmtTzazkqGH>oJ8>UA=LS#RiZdtg`P0?i9H-}B1<w2(0%suX;L;rBF!HYjjL(2! zGH|U5xk#&;W=_64A}F}~#Oh$kpdd2}UPYeGX@rjms7?b4`z1QJ4JkXfEvO(hT}=Z^ zr|d)Ql&xu~OK_cDgNvW5^W@5s+?*rX&zzikAv;Q~%V)+_vnt~}J@=@tFS-lB?ff}I zU!%v#z77ie+ACm6br@?F67?#OC+EnDGiSg3l1^`rz-14zjzU7ug3h>_{oz*tR=kz( zZ7lQSok9-1uV{!Z#y5JWLcfmC-==W>>seNb(fgnsnhkq81hxDCpWSMj_3sk1rP}N+ z)2y;n%=)z1Bbcpwmvh(kGcg;)EWIBKK5^yN0OFbT7Rx-uw;L$(^Ba)ndlMA-*$JHP z0>tPB8GXKn6F$AqW+!PxXkP2~$Ztw5id;<jT%Utw(l<IOQk_nx;gTqO_fDDF)FD6* z7jNzo@zPp!z)^=G2T<?b6!kf#Y57_9HSy!PFn-)$uYUAuN@#jI{kXqg{Uq}P8?v`K z91?D6hrdsE@;1x8Ay*r#w8<ur(_jUxQyBFOMsU{`u*fr2>@6Pd*f_4B4xjxI+~^0c zS2SF5g}{Z1{9V4rQwghQ(D@J7hv3r;le$WbmOjLNI*BU%)`G#Z`~RHYN9H@4mdkTK z&HF@}Jzm{hKWhW(0lZ%xXL%GAz<T~vL>0jL=tI=|#Q%7+NBk~p!+W?Ghd|ENV38fx zi@f<pnD(qrlS_FRw+oq$UR+MA7B(tUz}FD7VzgIjgzmP<dqebF16TLJv#6I6{EF$2 z{3=1W&GOk<=+BN2t#xh0*}*o#|2ptnE8_9*1Ag>AyW}4Q2jO*mZyxeqiJMKp%X_={ zWbZCh(itYtE}?r8=<kw0&KVfB9NgJ5;3(#A)&ylPD=NzFc+I7hYeXI9yA-}h>}Y2g zZ+*GF{7tKO(}rb^ypYu$UN5Ys^EOxwB)(R&1^0KidlP9x&JFk-7Pp(XW>M{*tkZMC zF6BD~?V&d~?oOu1cIZo4&*PxMNA{8OFtaDB;KcqDU#)K?bA!k^rjC&m>1bw(qGDZm z<J_a9nV-<zx7aQ>o%qDuG;(B&Ach>xj+|L_&E)MFBsrh8BuVjCa2tNwEXk1>NRl}= ze{GWR%w~#|x+Fg|OLA%^lKg+}Nh(R6rSn<S6Nr{gS8o02@jKXU#hFzcbVE+7I7Bay zRUu*27Q(MAg|D%GVfGaV+5AD&GudIs`vEO~XI0VQ*P1iNf6)vorVGJ;=M3?i^Ys~# zW3$NDBk}n<i2NCsum4BjGUe;fMJ&z#gDGF16QiZSpEh5g0j!<X2e`Xz+^Maq%K0Mi zoOCriyCYZg(+YC+2!CR^dW3G{(C?**&tG&?o)+gJMT0}09uax^u@7i(zt!zPzOgQn z|69cA?aOHu<x!H*TG1D~5_b+LgCeWZZJ*?9GQ}$2gba<$J;n3$UERb{Qybys83Dfq z2i})*4gfEUr&CR5D8u5n+v@Z=8JH&%Gcs~9tFsN>sp?=n>v~DaJ372P<N61L?o00x zS=jwwt=?xu79J5<xc_K;77o9^-J3`kIbsx9nC)f%UDIXZE;{`)*q}#bVZulmF+7qO zH^hvBnat7SFte0|EIgV%3!5=htTJThUKe+kvC|ko6^V7>F&^=MX3E0)+zjMMj#Gvt zad|kMEa%iQL6@|YK^C5eQ^_)6mWAhGfpaE%0$CDb;@2h%&&2sD_67IL$lLk8@JxJx zvLwXcuT2)dFR5g~ueJF3f6tmrYVKw|-|0^N+`~OPL?q5{sz+Uocj(BQ+Rg1(PYiG< z^(6t-kNyiE>-q`0>jn7TU_nXLiZvn<FgzF!<YPR)FB-hlerM2QXMMO6-GYL42l~}F z-ZLV)B;B{sxxU(0u_V9T>0Mo2?OVHMb!GX=O26~&vTFazN@rPRxpS?rriO;f);cRz zuUfTw!(!(plJ>X!{z7NTy@k(~+`DkT^S%;o*<z<LKR@F<=rT}&FcDwLs!h)OIemt7 z`Tg<u66gO8!ptkV_l6{aG@j$|KXhMaepAky<i&g<{W$(o&SU-E(AV7yoo4iGUCQw| z_(XD2!n&k+Uzztw=Y0=5NiPXI{1mqLDZa}~^!;*P!XH<!sag5d%BOu!7zkTiR{s5U zYimfYH^m#u6TY=I8XlU}Hj>eOAbYwxy$3Fg-r5b$ifUigI$x!ClhgZTS*73StXb`x zUsPCl9sUGc(z240`@UDWF~9J(jgKzjpH4GC20YHSHD%Q`8gM4K^3|0-fioT4f&{)c zl&!3BW&xZ5#F+(M-^LoJchwIBcaoHeZW1s&H4S|YG>!#8OH$=(h_!Cbn$^`c$s44x z@j!TL>c+RHrpkXkH8p|f|G?*czOwSi{AD%1$7-s}R#sB@`P*gp-+!Ih$rSSs+;w;9 zJr6#>L8`IdN$X+s<-WunzeHN*2UgH`>gaU~T(Po}nLWit?744^bBR+o?CI9Qd{eG_ zKuE!i=w|$JN72V2V~sH^m9Kkhjqpx$48FrxvAWvl6wCA#%a_HCY1k#{q3V^;!FPS@ zeXF2D0_Ril<4)Qp-$tKzU5(Fx!S+d{XQzksXeOznPcfew7sHbRMcjCbrJT>?h4JGl z783LL6D!GiYu2shhVZcF`VZ@2Awf@0Uv>5BYO^L7pF)kv)7tuydv!G>z$EK29-wBU zvwYPi3ZPG{tSNjJ|1F%)=yNfo`A+^&sC|0Z0(9X5z&ZKS#eBYc8a$?T98_E9tE}-= yBh#;{aKh|S2RzBcol{dn+Ib2(0thVRZ@kIL|A~yw`TFggz?<|mrTy_yN%~*8DwD$i literal 0 HcmV?d00001 -- 2.25.1 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [PATCH 14/17] spacemit: k1: Add DDR firmware support to SPL 2026-01-17 19:01 ` [PATCH 14/17] spacemit: k1: Add DDR firmware support to SPL Raymond Mao @ 2026-01-19 9:40 ` Yao Zi 2026-01-21 23:24 ` Raymond Mao 0 siblings, 1 reply; 37+ messages in thread From: Yao Zi @ 2026-01-19 9:40 UTC (permalink / raw) To: Raymond Mao, u-boot Cc: uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Heinrich Schuchardt, Randolph Sheng-Kai Lin, Yixun Lan, Junhui Liu, Neil Armstrong, Quentin Schulz, Samuel Holland (My mail provider complains about the huge list of recipients, so I reduced it a little.) On Sat, Jan 17, 2026 at 02:01:48PM -0500, Raymond Mao wrote: > From: Raymond Mao <raymond.mao@riscstar.com> > > Include DDR initialization firmware in the SPL image. The firmware > path can be specified via the DDR_FW_FILE environment variable. If > the firmware is not found, an empty placeholder file is created to > allow the build to proceed without DDR initialization support. > > Signed-off-by: Raymond Mao <raymond.mao@riscstar.com> > --- > arch/riscv/dts/k1-spl.dts | 34 ++++++++++++++++++++++++++++++++- > board/spacemit/k1/Kconfig | 8 ++++++++ > board/spacemit/k1/Makefile | 19 ++++++++++++++++++ > board/spacemit/k1/spl.c | 30 +++++++++++++++++++++++++++++ > include/configs/k1.h | 3 +++ > lib/vendor/spacemit/ddr_fw.bin | Bin 0 -> 19416 bytes It's unusual to ship binary firmware in U-Boot repository. Please place the firmware somewhere else, and give a clear instruction in the board/architecture documentation explaining how to obtain/build it. > 6 files changed, 93 insertions(+), 1 deletion(-) > create mode 100644 lib/vendor/spacemit/ddr_fw.bin ... > diff --git a/board/spacemit/k1/Kconfig b/board/spacemit/k1/Kconfig > index 9f9c806d00d..a5fa788f660 100644 > --- a/board/spacemit/k1/Kconfig > +++ b/board/spacemit/k1/Kconfig > @@ -15,6 +15,14 @@ config SYS_CONFIG_NAME > config TEXT_BASE > default 0x00200000 > > +config SPL_DDR_FIRMWARE_OFFSET > + hex "DDR firmware offset in SPL image" > + depends on SPL > + default 0x20000 > + help > + Offset where DDR firmware should be placed in the SPL > + image. > + > config SPL_OPENSBI_LOAD_ADDR > default 0x00000000 > > diff --git a/board/spacemit/k1/Makefile b/board/spacemit/k1/Makefile > index 7bce47bac8c..ebe6e55867c 100644 > --- a/board/spacemit/k1/Makefile > +++ b/board/spacemit/k1/Makefile > @@ -5,3 +5,22 @@ > > obj-y := board.o > obj-$(CONFIG_SPL_BUILD) += spl.o > + > +DDR_FW_SRC ?= $(DDR_FW_FILE) > +FW_TARGET = $(srctree)/lib/vendor/spacemit/ddr_fw.bin > + > +DDR_FW_HEADER = $(objtree)/include/generated/ddr_fw_info.h > + > +$(obj)/spl.o: $(DDR_FW_HEADER) > + > +$(DDR_FW_HEADER): $(FW_TARGET) > + @echo "/* DDR firmware info - $$(date) */" > $@ > + @if [ -f "$(FW_TARGET)" ]; then \ > + SIZE=$$(stat -c%s "$(FW_TARGET)" 2>/dev/null || echo 0); \ > + else \ > + SIZE=0; \ > + fi; \ > + echo "#define DDR_FW_FILE_SIZE $$SIZE" >> $@ > + @echo "/* Note: Update ADDR if binman layout changes */" >> $@ > + > +clean-files += $(FW_TARGET) $(DDR_FW_HEADER) Please make use of existing binman[1] facibilities to avoid the extra Kconfig and Makefile pieces. binman_sym() could be used for obtaining both size and offset of a binman entry. > diff --git a/board/spacemit/k1/spl.c b/board/spacemit/k1/spl.c > index 6fe064bd430..54bad9000fe 100644 > --- a/board/spacemit/k1/spl.c > +++ b/board/spacemit/k1/spl.c > @@ -6,10 +6,12 @@ > #include <asm/io.h> > #include <clk.h> > #include <clk-uclass.h> > +#include <cpu_func.h> > #include <configs/k1.h> > #include <dm/device.h> > #include <dm/uclass.h> > #include <dt-bindings/pinctrl/k1-pinctrl.h> > +#include <generated/ddr_fw_info.h> > #include <i2c.h> > #include <linux/delay.h> > #include <log.h> > @@ -115,6 +117,33 @@ void serial_early_init(void) > panic("Serial uclass init failed: %d\n", ret); > } > > +/* Load DDR training firmware */ > +int init_ddr_firmware(void) > +{ > + void __iomem *src, *dst; > + unsigned long size; > + > + src = (void __iomem *)(CONFIG_SPL_TEXT_BASE + > + CONFIG_SPL_DDR_FIRMWARE_OFFSET); > + dst = (void __iomem *)(DDR_TRAINING_DATA_BASE); > + memcpy(dst, src, DDR_FW_FILE_SIZE); > + size = round_up(DDR_FW_FILE_SIZE, 64); > + flush_dcache_range((u32)(u64)dst, (u32)(u64)dst + size); > + return 0; > +} > + > +void ddr_early_init(void) > +{ > + void __iomem *addr; > + > + init_ddr_firmware(); > + addr = (void __iomem *)(CONFIG_SPL_TEXT_BASE + > + CONFIG_SPL_DDR_FIRMWARE_OFFSET); > + // verify DDR firmware header However, you don't verify it, but only print some of the information. The comment seems misleading and extra. > + log_info("[0x%x]:0x%x, firmware size:%d\n", > + (uint)(u64)addr, readl(addr), DDR_FW_FILE_SIZE); Regards, Yao Zi ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH 14/17] spacemit: k1: Add DDR firmware support to SPL 2026-01-19 9:40 ` Yao Zi @ 2026-01-21 23:24 ` Raymond Mao 2026-01-22 14:43 ` Yao Zi 0 siblings, 1 reply; 37+ messages in thread From: Raymond Mao @ 2026-01-21 23:24 UTC (permalink / raw) To: Yao Zi Cc: u-boot, uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Heinrich Schuchardt, Randolph Sheng-Kai Lin, Yixun Lan, Junhui Liu, Neil Armstrong, Quentin Schulz, Samuel Holland Hi Yao Zi, On Mon, Jan 19, 2026 at 4:41 AM Yao Zi <me@ziyao.cc> wrote: > (My mail provider complains about the huge list of recipients, so I > reduced it a little.) > > On Sat, Jan 17, 2026 at 02:01:48PM -0500, Raymond Mao wrote: > > From: Raymond Mao <raymond.mao@riscstar.com> > > > > Include DDR initialization firmware in the SPL image. The firmware > > path can be specified via the DDR_FW_FILE environment variable. If > > the firmware is not found, an empty placeholder file is created to > > allow the build to proceed without DDR initialization support. > > > > Signed-off-by: Raymond Mao <raymond.mao@riscstar.com> > > --- > > arch/riscv/dts/k1-spl.dts | 34 ++++++++++++++++++++++++++++++++- > > board/spacemit/k1/Kconfig | 8 ++++++++ > > board/spacemit/k1/Makefile | 19 ++++++++++++++++++ > > board/spacemit/k1/spl.c | 30 +++++++++++++++++++++++++++++ > > include/configs/k1.h | 3 +++ > > lib/vendor/spacemit/ddr_fw.bin | Bin 0 -> 19416 bytes > > It's unusual to ship binary firmware in U-Boot repository. Please place > the firmware somewhere else, and give a clear instruction in the > board/architecture documentation explaining how to obtain/build it. > > > 6 files changed, 93 insertions(+), 1 deletion(-) > > create mode 100644 lib/vendor/spacemit/ddr_fw.bin > > ... > > > diff --git a/board/spacemit/k1/Kconfig b/board/spacemit/k1/Kconfig > > index 9f9c806d00d..a5fa788f660 100644 > > --- a/board/spacemit/k1/Kconfig > > +++ b/board/spacemit/k1/Kconfig > > @@ -15,6 +15,14 @@ config SYS_CONFIG_NAME > > config TEXT_BASE > > default 0x00200000 > > > > +config SPL_DDR_FIRMWARE_OFFSET > > + hex "DDR firmware offset in SPL image" > > + depends on SPL > > + default 0x20000 > > + help > > + Offset where DDR firmware should be placed in the SPL > > + image. > > + > > config SPL_OPENSBI_LOAD_ADDR > > default 0x00000000 > > > > diff --git a/board/spacemit/k1/Makefile b/board/spacemit/k1/Makefile > > index 7bce47bac8c..ebe6e55867c 100644 > > --- a/board/spacemit/k1/Makefile > > +++ b/board/spacemit/k1/Makefile > > @@ -5,3 +5,22 @@ > > > > obj-y := board.o > > obj-$(CONFIG_SPL_BUILD) += spl.o > > + > > +DDR_FW_SRC ?= $(DDR_FW_FILE) > > +FW_TARGET = $(srctree)/lib/vendor/spacemit/ddr_fw.bin > > + > > +DDR_FW_HEADER = $(objtree)/include/generated/ddr_fw_info.h > > + > > +$(obj)/spl.o: $(DDR_FW_HEADER) > > + > > +$(DDR_FW_HEADER): $(FW_TARGET) > > + @echo "/* DDR firmware info - $$(date) */" > $@ > > + @if [ -f "$(FW_TARGET)" ]; then \ > > + SIZE=$$(stat -c%s "$(FW_TARGET)" 2>/dev/null || echo 0); \ > > + else \ > > + SIZE=0; \ > > + fi; \ > > + echo "#define DDR_FW_FILE_SIZE $$SIZE" >> $@ > > + @echo "/* Note: Update ADDR if binman layout changes */" >> $@ > > + > > +clean-files += $(FW_TARGET) $(DDR_FW_HEADER) > > Please make use of existing binman[1] facibilities to avoid the extra > Kconfig and Makefile pieces. binman_sym() could be used for obtaining > both size and offset of a binman entry. > > It doesn't work at all in SPL. I checked the binman symbol table that was totally empty. > > diff --git a/board/spacemit/k1/spl.c b/board/spacemit/k1/spl.c > > index 6fe064bd430..54bad9000fe 100644 > > --- a/board/spacemit/k1/spl.c > > +++ b/board/spacemit/k1/spl.c > > @@ -6,10 +6,12 @@ > > #include <asm/io.h> > > #include <clk.h> > > #include <clk-uclass.h> > > +#include <cpu_func.h> > > #include <configs/k1.h> > > #include <dm/device.h> > > #include <dm/uclass.h> > > #include <dt-bindings/pinctrl/k1-pinctrl.h> > > +#include <generated/ddr_fw_info.h> > > #include <i2c.h> > > #include <linux/delay.h> > > #include <log.h> > > @@ -115,6 +117,33 @@ void serial_early_init(void) > > panic("Serial uclass init failed: %d\n", ret); > > } > > > > +/* Load DDR training firmware */ > > +int init_ddr_firmware(void) > > +{ > > + void __iomem *src, *dst; > > + unsigned long size; > > + > > + src = (void __iomem *)(CONFIG_SPL_TEXT_BASE + > > + CONFIG_SPL_DDR_FIRMWARE_OFFSET); > > + dst = (void __iomem *)(DDR_TRAINING_DATA_BASE); > > + memcpy(dst, src, DDR_FW_FILE_SIZE); > > + size = round_up(DDR_FW_FILE_SIZE, 64); > > + flush_dcache_range((u32)(u64)dst, (u32)(u64)dst + size); > > + return 0; > > +} > > + > > +void ddr_early_init(void) > > +{ > > + void __iomem *addr; > > + > > + init_ddr_firmware(); > > + addr = (void __iomem *)(CONFIG_SPL_TEXT_BASE + > > + CONFIG_SPL_DDR_FIRMWARE_OFFSET); > > + // verify DDR firmware header > > However, you don't verify it, but only print some of the information. > The comment seems misleading and extra. > > OK. I could remove the print and use checking instead. Raymond > > + log_info("[0x%x]:0x%x, firmware size:%d\n", > > + (uint)(u64)addr, readl(addr), DDR_FW_FILE_SIZE); > > Regards, > Yao Zi > ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH 14/17] spacemit: k1: Add DDR firmware support to SPL 2026-01-21 23:24 ` Raymond Mao @ 2026-01-22 14:43 ` Yao Zi 0 siblings, 0 replies; 37+ messages in thread From: Yao Zi @ 2026-01-22 14:43 UTC (permalink / raw) To: Raymond Mao Cc: u-boot, uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Heinrich Schuchardt, Randolph Sheng-Kai Lin, Yixun Lan, Junhui Liu, Neil Armstrong, Quentin Schulz, Samuel Holland On Wed, Jan 21, 2026 at 06:24:01PM -0500, Raymond Mao wrote: > Hi Yao Zi, > > On Mon, Jan 19, 2026 at 4:41 AM Yao Zi <me@ziyao.cc> wrote: > > > (My mail provider complains about the huge list of recipients, so I > > reduced it a little.) > > > > On Sat, Jan 17, 2026 at 02:01:48PM -0500, Raymond Mao wrote: > > > From: Raymond Mao <raymond.mao@riscstar.com> > > > > > > Include DDR initialization firmware in the SPL image. The firmware > > > path can be specified via the DDR_FW_FILE environment variable. If > > > the firmware is not found, an empty placeholder file is created to > > > allow the build to proceed without DDR initialization support. > > > > > > Signed-off-by: Raymond Mao <raymond.mao@riscstar.com> > > > --- > > > arch/riscv/dts/k1-spl.dts | 34 ++++++++++++++++++++++++++++++++- > > > board/spacemit/k1/Kconfig | 8 ++++++++ > > > board/spacemit/k1/Makefile | 19 ++++++++++++++++++ > > > board/spacemit/k1/spl.c | 30 +++++++++++++++++++++++++++++ > > > include/configs/k1.h | 3 +++ > > > lib/vendor/spacemit/ddr_fw.bin | Bin 0 -> 19416 bytes > > > > It's unusual to ship binary firmware in U-Boot repository. Please place > > the firmware somewhere else, and give a clear instruction in the > > board/architecture documentation explaining how to obtain/build it. > > > > > 6 files changed, 93 insertions(+), 1 deletion(-) > > > create mode 100644 lib/vendor/spacemit/ddr_fw.bin > > > > ... > > > > > diff --git a/board/spacemit/k1/Kconfig b/board/spacemit/k1/Kconfig > > > index 9f9c806d00d..a5fa788f660 100644 > > > --- a/board/spacemit/k1/Kconfig > > > +++ b/board/spacemit/k1/Kconfig > > > @@ -15,6 +15,14 @@ config SYS_CONFIG_NAME > > > config TEXT_BASE > > > default 0x00200000 > > > > > > +config SPL_DDR_FIRMWARE_OFFSET > > > + hex "DDR firmware offset in SPL image" > > > + depends on SPL > > > + default 0x20000 > > > + help > > > + Offset where DDR firmware should be placed in the SPL > > > + image. > > > + > > > config SPL_OPENSBI_LOAD_ADDR > > > default 0x00000000 > > > > > > diff --git a/board/spacemit/k1/Makefile b/board/spacemit/k1/Makefile > > > index 7bce47bac8c..ebe6e55867c 100644 > > > --- a/board/spacemit/k1/Makefile > > > +++ b/board/spacemit/k1/Makefile > > > @@ -5,3 +5,22 @@ > > > > > > obj-y := board.o > > > obj-$(CONFIG_SPL_BUILD) += spl.o > > > + > > > +DDR_FW_SRC ?= $(DDR_FW_FILE) > > > +FW_TARGET = $(srctree)/lib/vendor/spacemit/ddr_fw.bin > > > + > > > +DDR_FW_HEADER = $(objtree)/include/generated/ddr_fw_info.h > > > + > > > +$(obj)/spl.o: $(DDR_FW_HEADER) > > > + > > > +$(DDR_FW_HEADER): $(FW_TARGET) > > > + @echo "/* DDR firmware info - $$(date) */" > $@ > > > + @if [ -f "$(FW_TARGET)" ]; then \ > > > + SIZE=$$(stat -c%s "$(FW_TARGET)" 2>/dev/null || echo 0); \ > > > + else \ > > > + SIZE=0; \ > > > + fi; \ > > > + echo "#define DDR_FW_FILE_SIZE $$SIZE" >> $@ > > > + @echo "/* Note: Update ADDR if binman layout changes */" >> $@ > > > + > > > +clean-files += $(FW_TARGET) $(DDR_FW_HEADER) > > > > Please make use of existing binman[1] facibilities to avoid the extra > > Kconfig and Makefile pieces. binman_sym() could be used for obtaining > > both size and offset of a binman entry. > > > > It doesn't work at all in SPL. I checked the binman symbol table > that was totally empty. I've tried commit fd871fc6bb49 ("pinctrl: mediatek: mt8365: add PUPD registers") with th1520_lpi4a_defconfig, and drivers/ram/thead/th1520_ddr.c, which makes use of binman_sym(), does work. This suggests binman facilities do work on RISC-V, at least after the last time when I fixed it[1]. Are you testing on a U-Boot version earlier than v2025.07? Otherwise there's likely something (configuration or code) wrong on your side. btw, every first line of your replied paragraphs has the wrong level of quotes, which is a little confusing. Best regards, Yao Zi [1]: https://lore.kernel.org/u-boot/20250416162533.1396-1-ziyao@disroot.org/ ^ permalink raw reply [flat|nested] 37+ messages in thread
* [PATCH 15/17] power: pmic: add support for Spacemit P1 PMIC 2026-01-17 19:01 [PATCH 00/17] Add board support for Spacemit K1 SoC in SPL Raymond Mao ` (13 preceding siblings ...) 2026-01-17 19:01 ` [PATCH 14/17] spacemit: k1: Add DDR firmware support to SPL Raymond Mao @ 2026-01-17 19:01 ` Raymond Mao 2026-01-17 19:01 ` [PATCH 16/17] power: regulator: add support for Spacemit P1 SoC Raymond Mao ` (3 subsequent siblings) 18 siblings, 0 replies; 37+ messages in thread From: Raymond Mao @ 2026-01-17 19:01 UTC (permalink / raw) To: u-boot Cc: uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Yao Zi, Randolph Sheng-Kai Lin, Conor Dooley, Yu-Chien Peter Lin, Jamie Gibbons, Eric Schikschneit, Michal Simek, Yixun Lan, Junhui Liu, Sam Protsenko, Patrick Delaunay, Patrice Chotard, Casey Connolly, Ilias Apalodimas, Christian Marangi, Neil Armstrong, Angelo Dureghello, Utsav Agarwal, Greg Malysa, Justin Swartz, Aniket Limaye, Nathan Barrett-Morrison, Ian Roberts, Oliver Gaskell, Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Anshul Dalal, Kory Maincent, Rui Miguel Silva, Justin Klaassen, Paul Barker, Samuel Holland, Marek Vasut, Gabriel Fernandez, Kever Yang, Jonas Karlman, Elaine Zhang, Joseph Chen From: Raymond Mao <raymond.mao@riscstar.com> Spacemit's PMIC is used by Spacemit K1 SoC. It contains voltage regulators, GPIOs and Watchdog. Signed-off-by: Raymond Mao <raymond.mao@riscstar.com> --- drivers/power/pmic/Kconfig | 17 +++ drivers/power/pmic/Makefile | 1 + drivers/power/pmic/pmic_spacemit_p1.c | 95 +++++++++++++++ include/power/spacemit_p1.h | 162 ++++++++++++++++++++++++++ 4 files changed, 275 insertions(+) create mode 100644 drivers/power/pmic/pmic_spacemit_p1.c create mode 100644 include/power/spacemit_p1.h diff --git a/drivers/power/pmic/Kconfig b/drivers/power/pmic/Kconfig index b1a5b1c2a1f..19a0c4a77dd 100644 --- a/drivers/power/pmic/Kconfig +++ b/drivers/power/pmic/Kconfig @@ -433,6 +433,23 @@ config PMIC_RAA215300 support and several voltage regulators. For now, this driver simply allows register access and will bind the sysreset driver (CONFIG_SYSRESET_RAA215300) if it is enabled. + +config PMIC_SPACEMIT_P1 + bool "Enable driver for Spacemit P1 power management chip" + depends on DM_PMIC + help + The P1 PMIC integrates multiple functions including + voltage regulators, a watchdog timer, GPIO interfaces, and a + real-time clock. + +config SPL_PMIC_SPACEMIT_P1 + bool "Enable driver for Spacemit P1 power management chip in SPL" + depends on SPL_DM_PMIC + help + The P1 PMIC integrates multiple functions including + voltage regulators, a watchdog timer, GPIO interfaces, and a + real-time clock. + endif config PMIC_TPS65217 diff --git a/drivers/power/pmic/Makefile b/drivers/power/pmic/Makefile index 6bebffb05a6..dfe60223f00 100644 --- a/drivers/power/pmic/Makefile +++ b/drivers/power/pmic/Makefile @@ -39,6 +39,7 @@ obj-$(CONFIG_PMIC_TPS65941) += tps65941.o obj-$(CONFIG_PMIC_RAA215300) += raa215300.o obj-$(CONFIG_POWER_TPS65218) += pmic_tps65218.o obj-$(CONFIG_$(PHASE_)DM_PMIC_CPCAP) += cpcap.o +obj-$(CONFIG_$(PHASE_)PMIC_SPACEMIT_P1) += pmic_spacemit_p1.o ifeq ($(CONFIG_$(PHASE_)POWER_LEGACY),y) obj-$(CONFIG_POWER_LTC3676) += pmic_ltc3676.o diff --git a/drivers/power/pmic/pmic_spacemit_p1.c b/drivers/power/pmic/pmic_spacemit_p1.c new file mode 100644 index 00000000000..88c8a375de1 --- /dev/null +++ b/drivers/power/pmic/pmic_spacemit_p1.c @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2025-2026 RISCStar Ltd. + */ + +#include <dm.h> +#include <power/pmic.h> +#include <power/spacemit_p1.h> + +static int pmic_p1_reg_count(struct udevice *dev) +{ + return P1_MAX_REGS; +} + +static int pmic_p1_write(struct udevice *dev, uint reg, const u8 *buffer, + int len) +{ + int ret; + + ret = dm_i2c_write(dev, reg, buffer, len); + if (ret) + pr_err("%s write error on register %02x\n", dev->name, reg); + + return ret; +} + +static int pmic_p1_read(struct udevice *dev, uint reg, u8 *buffer, + int len) +{ + int ret; + + ret = dm_i2c_read(dev, reg, buffer, len); + if (ret) + pr_err("%s read error on register %02x\n", dev->name, reg); + + return ret; +} + +static const struct pmic_child_info p1_children_info[] = { + { .prefix = "buck", .driver = P1_BUCK_DRIVER }, + { .prefix = "aldo", .driver = P1_LDO_DRIVER }, + { .prefix = "dldo", .driver = P1_LDO_DRIVER }, + { }, +}; + +static int pmic_p1_bind(struct udevice *dev) +{ + const struct pmic_child_info *p1_children_info = + (struct pmic_child_info *)dev_get_driver_data(dev); + ofnode regulators_node; + int children; + + regulators_node = dev_read_subnode(dev, "regulators"); + if (!ofnode_valid(regulators_node)) { + debug("%s regulators subnode not found\n", dev->name); + return -EINVAL; + } + + children = pmic_bind_children(dev, regulators_node, + p1_children_info); + if (!children) + debug("%s has no children (regulators)\n", dev->name); + + return 0; +} + +static int pmic_p1_probe(struct udevice *dev) +{ + return 0; +} + +static struct dm_pmic_ops pmic_p1_ops = { + .reg_count = pmic_p1_reg_count, + .read = pmic_p1_read, + .write = pmic_p1_write, +}; + +static const struct udevice_id pmic_p1_match[] = { + { + .compatible = "spacemit,p1", + .data = (ulong)&p1_children_info, + }, { + /* sentinel */ + } +}; + +U_BOOT_DRIVER(pmic_p1) = { + .name = "pmic_p1", + .id = UCLASS_PMIC, + .of_match = pmic_p1_match, + .bind = pmic_p1_bind, + .probe = pmic_p1_probe, + .ops = &pmic_p1_ops, + //.priv_auto = sizeof(struct p1_pdata), +}; diff --git a/include/power/spacemit_p1.h b/include/power/spacemit_p1.h new file mode 100644 index 00000000000..848bb469305 --- /dev/null +++ b/include/power/spacemit_p1.h @@ -0,0 +1,162 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2025-2026 RISCStar Ltd. + */ + +#ifndef __SPACEMIT_P1_H_ +#define __SPACEMIT_P1_H_ + +#define P1_MAX_REGS 0xA8 + +#define P1_REG_ID 0x0 + +#define P1_ID 0x2 + +#define P1_REG_BUCK1_CTRL 0x47 +#define P1_REG_BUCK2_CTRL 0x4a +#define P1_REG_BUCK3_CTRL 0x4d +#define P1_REG_BUCK4_CTRL 0x50 +#define P1_REG_BUCK5_CTRL 0x53 +#define P1_REG_BUCK6_CTRL 0x56 + +#define P1_REG_BUCK1_VSEL 0x48 +#define P1_REG_BUCK2_VSEL 0x4b +#define P1_REG_BUCK3_VSEL 0x4e +#define P1_REG_BUCK4_VSEL 0x51 +#define P1_REG_BUCK5_VSEL 0x54 +#define P1_REG_BUCK6_VSEL 0x57 + +#define P1_REG_BUCK1_SVSEL 0x49 +#define P1_REG_BUCK2_SVSEL 0x4c +#define P1_REG_BUCK3_SVSEL 0x4f +#define P1_REG_BUCK4_SVSEL 0x52 +#define P1_REG_BUCK5_SVSEL 0x55 +#define P1_REG_BUCK6_SVSEL 0x58 + +#define P1_BUCK_CTRL(x) (0x47 + ((x) - 1) * 3) +#define P1_BUCK_VSEL(x) (0x48 + ((x) - 1) * 3) +#define P1_BUCK_SVSEL(x) (0x49 + ((x) - 1) * 3) + +#define BUCK_VSEL_MASK 0xff +#define BUCK_EN_MASK 0x1 +#define BUCK_SVSEL_MASK 0xff + +#define P1_REG_ALDO1_CTRL 0x5b +#define P1_REG_ALDO2_CTRL 0x5e +#define P1_REG_ALDO3_CTRL 0x61 +#define P1_REG_ALDO4_CTRL 0x64 + +#define P1_REG_ALDO1_VOLT 0x5c +#define P1_REG_ALDO2_VOLT 0x5f +#define P1_REG_ALDO3_VOLT 0x62 +#define P1_REG_ALDO4_VOLT 0x65 + +#define P1_REG_ALDO1_SVOLT 0x5d +#define P1_REG_ALDO2_SVOLT 0x60 +#define P1_REG_ALDO3_SVOLT 0x63 +#define P1_REG_ALDO4_SVOLT 0x66 + +#define P1_ALDO_CTRL(x) (0x5b + ((x) - 1) * 3) +#define P1_ALDO_VOLT(x) (0x5c + ((x) - 1) * 3) +#define P1_ALDO_SVOLT(x) (0x5d + ((x) - 1) * 3) + +#define ALDO_SVSEL_MASK 0x7f +#define ALDO_EN_MASK 0x1 +#define ALDO_VSEL_MASK 0x7f + +#define P1_REG_DLDO1_CTRL 0x67 +#define P1_REG_DLDO2_CTRL 0x6a +#define P1_REG_DLDO3_CTRL 0x6d +#define P1_REG_DLDO4_CTRL 0x70 +#define P1_REG_DLDO5_CTRL 0x73 +#define P1_REG_DLDO6_CTRL 0x76 +#define P1_REG_DLDO7_CTRL 0x79 + +#define P1_REG_DLDO1_VOLT 0x68 +#define P1_REG_DLDO2_VOLT 0x6b +#define P1_REG_DLDO3_VOLT 0x6e +#define P1_REG_DLDO4_VOLT 0x71 +#define P1_REG_DLDO5_VOLT 0x74 +#define P1_REG_DLDO6_VOLT 0x77 +#define P1_REG_DLDO7_VOLT 0x7a + +#define P1_REG_DLDO1_SVOLT 0x69 +#define P1_REG_DLDO2_SVOLT 0x6c +#define P1_REG_DLDO3_SVOLT 0x6f +#define P1_REG_DLDO4_SVOLT 0x72 +#define P1_REG_DLDO5_SVOLT 0x75 +#define P1_REG_DLDO6_SVOLT 0x78 +#define P1_REG_DLDO7_SVOLT 0x7b + +#define P1_DLDO_CTRL(x) (0x67 + ((x) - 1) * 3) +#define P1_DLDO_VOLT(x) (0x68 + ((x) - 1) * 3) +#define P1_DLDO_SVOLT(x) (0x69 + ((x) - 1) * 3) + +#define DLDO_SVSEL_MASK 0x7f +#define DLDO_EN_MASK 0x1 +#define DLDO_VSEL_MASK 0x7f + +#define P1_REG_SWITCH_CTRL 0x59 +#define P1_SWTICH_EN_MASK 0x1 + +#define P1_REG_SWITCH_PWRKEY_EVENT_CTRL 0x97 +#define P1_SWITCH_PWRKEY_EVENT_EN_MSK 0xf + +#define P1_REG_SWITCH_PWRKEY_INIT_CTRL 0x9e +#define P1_SWITCH_PWRKEY_INT_EN_MSK 0xf + +/* Watchdog Timer Registers */ +#define P1_WDT_CTRL 0x44 +#define P1_PWR_CTRL0 0x7C +#define P1_PWR_CTRL2 0x7E +#define P1_PWR_CTRL2_MSK 0xff + +/* Watchdog Timer Control Bits */ +#define P1_WDT_CLEAR_STATUS 0x1 +#define P1_SW_RST 0x2 +#define P1_WDT_RESET_ENABLE 0x80 +#define P1_WDT_ENABLE 0x8 +#define P1_WDT_TIMEOUT_1S 0x0 +#define P1_WDT_TIMEOUT_4S 0x1 +#define P1_WDT_TIMEOUT_8S 0x2 +#define P1_WDT_TIMEOUT_16S 0x3 + +#define P1_RTC_TICK_CTRL 0x1d +#define P1_RTC_TICK_CTRL_MSK 0x7f + +#define P1_RTC_TICK_EVENT 0x92 +#define P1_RTC_TICK_EVENT_MSK 0x3f + +#define P1_RTC_TICK_IRQ 0x99 +#define P1_RTC_TICK_IRQ_MSK 0x3f + +#define P1_REG_ALIVE 0xab +#define P1_ALIVE_MSK 0x7 +#define SYS_REBOOT_FLAG_BIT 0x2 + +/* SWITCH ID */ +enum { + P1_ID_SWITCH1, + P1_ID_SWITCH1_PWRKEY_EVENT, + P1_ID_SWITCH1_PWRKEY_INT, + P1_ID_SWITCH_RTC_TICK_CTRL, + P1_ID_SWITCH_RTC_TICK_EVENT, + P1_ID_SWITCH_RTC_TCK_IRQ, + P1_ID_SWITCH_POWER_DOWN, + P1_ID_SWITCH_CHARGING_FLAG, +}; + +/* POWERKEY events */ +enum { + PWRKEY_RISING_EVENT = 1, + PWRKEY_FAILING_EVENT = 2, + PWRKEY_SHORT_PRESS_EVENT = 4, + PWRKEY_LONG_PRESS_EVENT = 8, +}; + +#define P1_BUCK_DRIVER "p1_buck" +#define P1_LDO_DRIVER "p1_ldo" +#define P1_SWITCH_DRIVER "p1_switch" +#define P1_WDT_DRIVER "p1_wdt" + +#endif /* __SPACEMIT_P1_H_ */ -- 2.25.1 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 16/17] power: regulator: add support for Spacemit P1 SoC 2026-01-17 19:01 [PATCH 00/17] Add board support for Spacemit K1 SoC in SPL Raymond Mao ` (14 preceding siblings ...) 2026-01-17 19:01 ` [PATCH 15/17] power: pmic: add support for Spacemit P1 PMIC Raymond Mao @ 2026-01-17 19:01 ` Raymond Mao 2026-01-17 19:01 ` [PATCH 17/17] board: k1: enable pmic in spl Raymond Mao ` (2 subsequent siblings) 18 siblings, 0 replies; 37+ messages in thread From: Raymond Mao @ 2026-01-17 19:01 UTC (permalink / raw) To: u-boot Cc: uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Yao Zi, Yu-Chien Peter Lin, Heinrich Schuchardt, Randolph Sheng-Kai Lin, Jamie Gibbons, Michal Simek, Eric Schikschneit, Yixun Lan, Junhui Liu, Sam Protsenko, Patrick Delaunay, Patrice Chotard, Ilias Apalodimas, Casey Connolly, Neil Armstrong, Christian Marangi, Vasileios Bimpikas, Greg Malysa, Aniket Limaye, Nathan Barrett-Morrison, Justin Swartz, Angelo Dureghello, Utsav Agarwal, Ian Roberts, Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Anshul Dalal, Kory Maincent, Paul Barker, Samuel Holland, Justin Klaassen, Rui Miguel Silva, Andre Przywara, Marek Vasut, Gabriel Fernandez, Jonas Karlman, Kever Yang, Heiko Stuebner, Joseph Chen, Elaine Zhang From: Raymond Mao <raymond.mao@riscstar.com> Support voltage regulator for Spacemit P1 SoC. It contains 6 BUCKs and 11 LDOs. Signed-off-by: Raymond Mao <raymond.mao@riscstar.com> --- drivers/power/pmic/pmic_spacemit_p1.c | 5 +- drivers/power/regulator/Kconfig | 15 + drivers/power/regulator/Makefile | 1 + .../power/regulator/spacemit_p1_regulator.c | 460 ++++++++++++++++++ include/power/spacemit_p1.h | 3 +- 5 files changed, 480 insertions(+), 4 deletions(-) create mode 100644 drivers/power/regulator/spacemit_p1_regulator.c diff --git a/drivers/power/pmic/pmic_spacemit_p1.c b/drivers/power/pmic/pmic_spacemit_p1.c index 88c8a375de1..d09240ee469 100644 --- a/drivers/power/pmic/pmic_spacemit_p1.c +++ b/drivers/power/pmic/pmic_spacemit_p1.c @@ -38,8 +38,8 @@ static int pmic_p1_read(struct udevice *dev, uint reg, u8 *buffer, static const struct pmic_child_info p1_children_info[] = { { .prefix = "buck", .driver = P1_BUCK_DRIVER }, - { .prefix = "aldo", .driver = P1_LDO_DRIVER }, - { .prefix = "dldo", .driver = P1_LDO_DRIVER }, + { .prefix = "aldo", .driver = P1_ALDO_DRIVER }, + { .prefix = "dldo", .driver = P1_DLDO_DRIVER }, { }, }; @@ -91,5 +91,4 @@ U_BOOT_DRIVER(pmic_p1) = { .bind = pmic_p1_bind, .probe = pmic_p1_probe, .ops = &pmic_p1_ops, - //.priv_auto = sizeof(struct p1_pdata), }; diff --git a/drivers/power/regulator/Kconfig b/drivers/power/regulator/Kconfig index c6da459a212..182510581c0 100644 --- a/drivers/power/regulator/Kconfig +++ b/drivers/power/regulator/Kconfig @@ -520,3 +520,18 @@ config DM_REGULATOR_CPCAP REGULATOR CPCAP. The driver supports both DC-to-DC Step-Down Switching (SW) Regulators and Low-Dropout Linear (LDO) Regulators found in CPCAP PMIC and implements get/set api for voltage and state. + +config DM_REGULATOR_SPACEMIT_P1 + bool "Enable driver for Spacemit P1 PMIC regulators" + depends on DM_REGULATOR && PMIC_SPACEMIT_P1 + help + Enable implementation of driver-model regulator uclass features + for regulator P1. The driver supports BUCKs, LDOs and SWITCHes. + +config SPL_DM_REGULATOR_SPACEMIT_P1 + bool "Enable driver for Spacemit P1 PMIC regulators in SPL" + depends on SPL_DM_REGULATOR && SPL_PMIC_SPACEMIT_P1 + help + Enable implementation of driver-model regulator uclass features + for regulator P1 in SPL. The driver supports BUCKs, LDOs and + SWITCHes. diff --git a/drivers/power/regulator/Makefile b/drivers/power/regulator/Makefile index ee8f56ea3b9..2a586e42f5c 100644 --- a/drivers/power/regulator/Makefile +++ b/drivers/power/regulator/Makefile @@ -47,3 +47,4 @@ obj-$(CONFIG_$(PHASE_)DM_REGULATOR_ANATOP) += anatop_regulator.o obj-$(CONFIG_DM_REGULATOR_TPS65219) += tps65219_regulator.o obj-$(CONFIG_REGULATOR_RZG2L_USBPHY) += rzg2l-usbphy-regulator.o obj-$(CONFIG_$(PHASE_)DM_REGULATOR_CPCAP) += cpcap_regulator.o +obj-$(CONFIG_$(PHASE_)DM_REGULATOR_SPACEMIT_P1) += spacemit_p1_regulator.o diff --git a/drivers/power/regulator/spacemit_p1_regulator.c b/drivers/power/regulator/spacemit_p1_regulator.c new file mode 100644 index 00000000000..9d7cfc43e1a --- /dev/null +++ b/drivers/power/regulator/spacemit_p1_regulator.c @@ -0,0 +1,460 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2025-2026 RISCStar Ltd. + */ + +#include <dm.h> +#include <dm/lists.h> +#include <errno.h> +#include <log.h> +#include <power/pmic.h> +#include <power/regulator.h> +#include <power/spacemit_p1.h> + +struct p1_reg_info { + uint min_uv; + uint step_uv; + u8 vsel_reg; + u8 vsel_sleep_reg; + u8 config_reg; + u8 vsel_mask; + u8 min_sel; + u8 max_sel; +}; + +static const struct p1_reg_info p1_bucks[] = { + /* BUCK 1 */ + { 500000, 5000, P1_BUCK_VSEL(1), P1_BUCK_SVSEL(1), P1_BUCK_CTRL(1), + BUCK_VSEL_MASK, 0x00, 0xaa }, + { 1375000, 25000, P1_BUCK_VSEL(1), P1_BUCK_SVSEL(1), P1_BUCK_CTRL(1), + BUCK_VSEL_MASK, 0xab, 0xfe }, + /* BUCK 2 */ + { 500000, 5000, P1_BUCK_VSEL(2), P1_BUCK_SVSEL(2), P1_BUCK_CTRL(2), + BUCK_VSEL_MASK, 0x00, 0xaa }, + { 1375000, 25000, P1_BUCK_VSEL(2), P1_BUCK_SVSEL(2), P1_BUCK_CTRL(2), + BUCK_VSEL_MASK, 0xab, 0xfe }, + /* BUCK 3 */ + { 500000, 5000, P1_BUCK_VSEL(3), P1_BUCK_SVSEL(3), P1_BUCK_CTRL(3), + BUCK_VSEL_MASK, 0x00, 0xaa }, + { 1375000, 25000, P1_BUCK_VSEL(3), P1_BUCK_SVSEL(3), P1_BUCK_CTRL(3), + BUCK_VSEL_MASK, 0xab, 0xfe }, + /* BUCK 4 */ + { 500000, 5000, P1_BUCK_VSEL(4), P1_BUCK_SVSEL(4), P1_BUCK_CTRL(4), + BUCK_VSEL_MASK, 0x00, 0xaa }, + { 1375000, 25000, P1_BUCK_VSEL(4), P1_BUCK_SVSEL(4), P1_BUCK_CTRL(4), + BUCK_VSEL_MASK, 0xab, 0xfe }, + /* BUCK 5 */ + { 500000, 5000, P1_BUCK_VSEL(5), P1_BUCK_SVSEL(5), P1_BUCK_CTRL(5), + BUCK_VSEL_MASK, 0x00, 0xaa }, + { 1375000, 25000, P1_BUCK_VSEL(5), P1_BUCK_SVSEL(5), P1_BUCK_CTRL(5), + BUCK_VSEL_MASK, 0xab, 0xfe }, + /* BUCK 6 */ + { 500000, 5000, P1_BUCK_VSEL(6), P1_BUCK_SVSEL(6), P1_BUCK_CTRL(6), + BUCK_VSEL_MASK, 0x00, 0xaa }, + { 1375000, 25000, P1_BUCK_VSEL(6), P1_BUCK_SVSEL(6), P1_BUCK_CTRL(6), + BUCK_VSEL_MASK, 0xab, 0xfe }, +}; + +static const struct p1_reg_info p1_aldos[] = { + /* ALDO 1 */ + { 500000, 25000, P1_ALDO_VOLT(1), P1_ALDO_SVOLT(1), P1_ALDO_CTRL(1), + ALDO_VSEL_MASK, 0x0b, 0x7f }, + /* ALDO 2 */ + { 500000, 25000, P1_ALDO_VOLT(2), P1_ALDO_SVOLT(2), P1_ALDO_CTRL(2), + ALDO_VSEL_MASK, 0x0b, 0x7f }, + /* ALDO 3 */ + { 500000, 25000, P1_ALDO_VOLT(3), P1_ALDO_SVOLT(3), P1_ALDO_CTRL(3), + ALDO_VSEL_MASK, 0x0b, 0x7f }, + /* ALDO 4 */ + { 500000, 25000, P1_ALDO_VOLT(4), P1_ALDO_SVOLT(4), P1_ALDO_CTRL(4), + ALDO_VSEL_MASK, 0x0b, 0x7f }, +}; + +static const struct p1_reg_info p1_dldos[] = { + /* DLDO 1 */ + { 500000, 25000, P1_DLDO_VOLT(1), P1_DLDO_SVOLT(1), P1_DLDO_CTRL(1), + ALDO_VSEL_MASK, 0x0b, 0x7f }, + /* DLDO 2 */ + { 500000, 25000, P1_DLDO_VOLT(2), P1_DLDO_SVOLT(2), P1_DLDO_CTRL(2), + ALDO_VSEL_MASK, 0x0b, 0x7f }, + /* DLDO 3 */ + { 500000, 25000, P1_DLDO_VOLT(3), P1_DLDO_SVOLT(3), P1_DLDO_CTRL(3), + ALDO_VSEL_MASK, 0x0b, 0x7f }, + /* DLDO 4 */ + { 500000, 25000, P1_DLDO_VOLT(4), P1_DLDO_SVOLT(4), P1_DLDO_CTRL(4), + ALDO_VSEL_MASK, 0x0b, 0x7f }, + /* DLDO 5 */ + { 500000, 25000, P1_DLDO_VOLT(5), P1_DLDO_SVOLT(5), P1_DLDO_CTRL(5), + ALDO_VSEL_MASK, 0x0b, 0x7f }, + /* DLDO 6 */ + { 500000, 25000, P1_DLDO_VOLT(6), P1_DLDO_SVOLT(6), P1_DLDO_CTRL(6), + ALDO_VSEL_MASK, 0x0b, 0x7f }, + /* DLDO 7 */ + { 500000, 25000, P1_DLDO_VOLT(7), P1_DLDO_SVOLT(7), P1_DLDO_CTRL(7), + ALDO_VSEL_MASK, 0x0b, 0x7f }, +}; + +static const struct p1_reg_info *get_buck_reg(struct udevice *pmic, + int idx, int uvolt) +{ + if (idx < 0) + return NULL; + if (uvolt < 1375000) + return &p1_bucks[(idx - 1) * 2 + 0]; + return &p1_bucks[(idx - 1) * 2 + 1]; +} + +static const struct p1_reg_info *get_aldo_reg(struct udevice *pmic, + int idx, int uvolt) +{ + return &p1_aldos[idx]; +} + +static const struct p1_reg_info *get_dldo_reg(struct udevice *pmic, + int idx, int uvolt) +{ + return &p1_dldos[idx]; +} + +static int buck_get_value(struct udevice *dev) +{ + const struct dm_pmic_ops *ops = device_get_ops(dev->parent); + const struct p1_reg_info *info; + uint val; + int ret; + + if (!ops || !ops->read) + return -ENOSYS; + + info = get_buck_reg(dev->parent, dev->driver_data, 0); + if (!info) + return -ENOENT; + ret = pmic_reg_read(dev->parent, info->vsel_reg); + if (ret < 0) + return ret; + val = ret & info->vsel_mask; + while (val > info->max_sel) + info++; + + return info->min_uv + (val - info->min_sel) * info->step_uv; +} + +static int buck_set_value(struct udevice *dev, int uvolt) +{ + const struct dm_pmic_ops *ops = device_get_ops(dev->parent); + const struct p1_reg_info *info; + uint val; + int ret; + + if (!ops || !ops->write) + return -ENOSYS; + + info = get_buck_reg(dev->parent, dev->driver_data, uvolt); + if (!info) + return -ENOENT; + val = (uvolt - info->min_uv); + val = val / info->step_uv; + val += info->min_sel; + ret = pmic_reg_write(dev->parent, info->vsel_reg, val); + if (ret < 0) + return ret; + return 0; +} + +static int buck_get_enable(struct udevice *dev) +{ + const struct p1_reg_info *info; + int ret; + + info = get_buck_reg(dev->parent, dev->driver_data, 0); + if (!info) + return -ENOENT; + + ret = pmic_reg_read(dev->parent, info->config_reg); + if (ret < 0) + return ret; + return ret & BUCK_EN_MASK; +} + +static int buck_set_enable(struct udevice *dev, bool enable) +{ + const struct p1_reg_info *info; + uint val; + int ret; + + info = get_buck_reg(dev->parent, dev->driver_data, 0); + if (!info) + return -ENOENT; + + ret = pmic_reg_read(dev->parent, info->config_reg); + if (ret < 0) + return ret; + val = (unsigned int)ret; + val &= BUCK_EN_MASK; + + if (enable == val) + return 0; + + val = enable; + ret = pmic_clrsetbits(dev->parent, info->config_reg, BUCK_EN_MASK, val); + if (ret < 0) + return ret; + + return 0; +} + +static const struct dm_regulator_ops p1_buck_ops = { + .get_value = buck_get_value, + .set_value = buck_set_value, + .get_enable = buck_get_enable, + .set_enable = buck_set_enable, +}; + +static int p1_buck_probe(struct udevice *dev) +{ + struct dm_regulator_uclass_plat *uc_pdata; + + uc_pdata = dev_get_uclass_plat(dev); + + uc_pdata->type = REGULATOR_TYPE_BUCK; + uc_pdata->mode_count = 0; + + return 0; +} + +U_BOOT_DRIVER(p1_buck) = { + .name = P1_BUCK_DRIVER, + .id = UCLASS_REGULATOR, + .ops = &p1_buck_ops, + .probe = p1_buck_probe, +}; + +static int aldo_get_value(struct udevice *dev) +{ + const struct dm_pmic_ops *ops = device_get_ops(dev->parent); + const struct p1_reg_info *info; + uint val; + int ret; + + if (!ops || !ops->read) + return -ENOSYS; + + info = get_aldo_reg(dev->parent, dev->driver_data, 0); + if (!info) + return -ENOENT; + + ret = pmic_reg_read(dev->parent, info->vsel_reg); + if (ret < 0) + return ret; + + val = ret & info->vsel_mask; + while (val > info->max_sel) + info++; + + return info->min_uv + (val - info->min_sel) * info->step_uv; +} + +static int aldo_set_value(struct udevice *dev, int uvolt) +{ + const struct dm_pmic_ops *ops = device_get_ops(dev->parent); + const struct p1_reg_info *info; + uint val; + int ret; + + if (!ops || !ops->write) + return -ENOSYS; + + info = get_aldo_reg(dev->parent, dev->driver_data, uvolt); + if (!info) + return -ENOENT; + val = (uvolt - info->min_uv); + val = val / info->step_uv; + val += info->min_sel; + ret = pmic_reg_write(dev->parent, info->vsel_reg, val); + if (ret < 0) + return ret; + return 0; +} + +static int aldo_get_enable(struct udevice *dev) +{ + const struct p1_reg_info *info; + int ret; + + info = get_aldo_reg(dev->parent, dev->driver_data, 0); + if (!info) + return -ENOENT; + + ret = pmic_reg_read(dev->parent, info->config_reg); + if (ret < 0) + return ret; + return ret & ALDO_EN_MASK; +} + +static int aldo_set_enable(struct udevice *dev, bool enable) +{ + const struct p1_reg_info *info; + uint val; + int ret; + + info = get_aldo_reg(dev->parent, dev->driver_data, 0); + if (!info) + return -ENOENT; + + ret = pmic_reg_read(dev->parent, info->config_reg); + if (ret < 0) + return ret; + val = (unsigned int)ret; + val &= ALDO_EN_MASK; + + if (enable == val) + return 0; + + val = enable; + ret = pmic_clrsetbits(dev->parent, info->config_reg, ALDO_EN_MASK, val); + if (ret < 0) + return ret; + + return 0; +} + +static const struct dm_regulator_ops p1_aldo_ops = { + .get_value = aldo_get_value, + .set_value = aldo_set_value, + .get_enable = aldo_get_enable, + .set_enable = aldo_set_enable, +}; + +static int p1_aldo_probe(struct udevice *dev) +{ + struct dm_regulator_uclass_plat *uc_pdata; + + uc_pdata = dev_get_uclass_plat(dev); + + uc_pdata->type = REGULATOR_TYPE_LDO; + uc_pdata->mode_count = 0; + + return 0; +} + +U_BOOT_DRIVER(p1_aldo) = { + .name = P1_ALDO_DRIVER, + .id = UCLASS_REGULATOR, + .ops = &p1_aldo_ops, + .probe = p1_aldo_probe, +}; + +static int dldo_get_value(struct udevice *dev) +{ + const struct dm_pmic_ops *ops = device_get_ops(dev->parent); + const struct p1_reg_info *info; + uint val; + int ret; + + if (!ops || !ops->read) + return -ENOSYS; + + info = get_dldo_reg(dev->parent, dev->driver_data, 0); + if (!info) + return -ENOENT; + + ret = pmic_reg_read(dev->parent, info->vsel_reg); + if (ret < 0) + return ret; + + val = ret & info->vsel_mask; + while (val > info->max_sel) + info++; + + return info->min_uv + (val - info->min_sel) * info->step_uv; +} + +static int dldo_set_value(struct udevice *dev, int uvolt) +{ + const struct dm_pmic_ops *ops = device_get_ops(dev->parent); + const struct p1_reg_info *info; + uint val; + int ret; + + if (!ops || !ops->write) + return -ENOSYS; + + info = get_dldo_reg(dev->parent, dev->driver_data, uvolt); + if (!info) + return -ENOENT; + val = (uvolt - info->min_uv); + val = val / info->step_uv; + val += info->min_sel; + ret = pmic_reg_write(dev->parent, info->vsel_reg, val); + if (ret < 0) + return ret; + return 0; +} + +static int dldo_get_enable(struct udevice *dev) +{ + const struct p1_reg_info *info; + int ret; + + info = get_dldo_reg(dev->parent, dev->driver_data, 0); + if (!info) + return -ENOENT; + + ret = pmic_reg_read(dev->parent, info->config_reg); + if (ret < 0) + return ret; + return ret & DLDO_EN_MASK; +} + +static int dldo_set_enable(struct udevice *dev, bool enable) +{ + const struct p1_reg_info *info; + uint val; + int ret; + + info = get_dldo_reg(dev->parent, dev->driver_data, 0); + if (!info) + return -ENOENT; + + ret = pmic_reg_read(dev->parent, info->config_reg); + if (ret < 0) + return ret; + val = (unsigned int)ret; + val &= DLDO_EN_MASK; + + if (enable == val) + return 0; + + val = enable; + ret = pmic_clrsetbits(dev->parent, info->config_reg, DLDO_EN_MASK, val); + if (ret < 0) + return ret; + + return 0; +} + +static const struct dm_regulator_ops p1_dldo_ops = { + .get_value = dldo_get_value, + .set_value = dldo_set_value, + .get_enable = dldo_get_enable, + .set_enable = dldo_set_enable, +}; + +static int p1_dldo_probe(struct udevice *dev) +{ + struct dm_regulator_uclass_plat *uc_pdata; + + uc_pdata = dev_get_uclass_plat(dev); + + uc_pdata->type = REGULATOR_TYPE_LDO; + uc_pdata->mode_count = 0; + + return 0; +} + +U_BOOT_DRIVER(p1_dldo) = { + .name = P1_DLDO_DRIVER, + .id = UCLASS_REGULATOR, + .ops = &p1_dldo_ops, + .probe = p1_dldo_probe, +}; diff --git a/include/power/spacemit_p1.h b/include/power/spacemit_p1.h index 848bb469305..2e3a006282c 100644 --- a/include/power/spacemit_p1.h +++ b/include/power/spacemit_p1.h @@ -155,7 +155,8 @@ enum { }; #define P1_BUCK_DRIVER "p1_buck" -#define P1_LDO_DRIVER "p1_ldo" +#define P1_ALDO_DRIVER "p1_aldo" +#define P1_DLDO_DRIVER "p1_dldo" #define P1_SWITCH_DRIVER "p1_switch" #define P1_WDT_DRIVER "p1_wdt" -- 2.25.1 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* [PATCH 17/17] board: k1: enable pmic in spl 2026-01-17 19:01 [PATCH 00/17] Add board support for Spacemit K1 SoC in SPL Raymond Mao ` (15 preceding siblings ...) 2026-01-17 19:01 ` [PATCH 16/17] power: regulator: add support for Spacemit P1 SoC Raymond Mao @ 2026-01-17 19:01 ` Raymond Mao 2026-01-17 23:13 ` [PATCH 00/17] Add board support for Spacemit K1 SoC in SPL Yixun Lan 2026-01-22 8:29 ` Heinrich Schuchardt 18 siblings, 0 replies; 37+ messages in thread From: Raymond Mao @ 2026-01-17 19:01 UTC (permalink / raw) To: u-boot Cc: uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Yao Zi, Heinrich Schuchardt, Conor Dooley, Yu-Chien Peter Lin, Jamie Gibbons, Michal Simek, Eric Schikschneit, Randolph Sheng-Kai Lin, Yixun Lan, Junhui Liu, Sam Protsenko, Patrice Chotard, Patrick Delaunay, Casey Connolly, Christian Marangi, Neil Armstrong, Ilias Apalodimas, Arturs Artamonovs, Greg Malysa, Vasileios Bimpikas, Nathan Barrett-Morrison, Aniket Limaye, Justin Swartz, Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Kory Maincent, Anshul Dalal, Paul Barker, Justin Klaassen, Samuel Holland, Rui Miguel Silva, Marek Vasut, Gabriel Fernandez, Jonas Karlman, Kever Yang, Elaine Zhang, Joseph Chen From: Raymond Mao <raymond.mao@riscstar.com> Add Spacemit P1 SoC support in SPL. And set the default voltage for BUCKs and LDOs. Signed-off-by: Raymond Mao <raymond.mao@riscstar.com> --- arch/riscv/dts/k1-spl.dts | 128 ++++++++++++++++++++++++++++++++++---- board/spacemit/k1/spl.c | 83 ++++++++++++++++++++---- configs/k1_defconfig | 9 +++ 3 files changed, 198 insertions(+), 22 deletions(-) diff --git a/arch/riscv/dts/k1-spl.dts b/arch/riscv/dts/k1-spl.dts index f8b280fa96f..6dedca20f51 100644 --- a/arch/riscv/dts/k1-spl.dts +++ b/arch/riscv/dts/k1-spl.dts @@ -110,17 +110,6 @@ }; }; - i2c@d401d800 { /* i2c8 */ - status = "okay"; - bootph-pre-ram; - pmic@41 { - compatible = "pmic"; - reg = <0x41>; - status = "okay"; - bootph-pre-ram; - }; - }; - reset-controller@d4050000 { status = "okay"; bootph-pre-ram; @@ -131,3 +120,120 @@ status = "okay"; bootph-pre-ram; }; + +&i2c8 { + status = "okay"; + bootph-pre-ram; + pmic@41 { + compatible = "spacemit,p1"; + reg = <0x41>; + status = "okay"; + bootph-pre-ram; + + regulators { + buck1 { + regulator-name = "vdd_core"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3450000>; + regulator-ramp-delay = <5000>; + regulator-always-on; + bootph-pre-ram; + }; + + buck2 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3450000>; + regulator-ramp-delay = <5000>; + regulator-always-on; + }; + + buck3_1v8: buck3 { + regulator-name = "vdd_1v8"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1800000>; + regulator-ramp-delay = <5000>; + regulator-always-on; + bootph-pre-ram; + }; + + buck4 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3300000>; + regulator-ramp-delay = <5000>; + regulator-always-on; + }; + + buck5 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3450000>; + regulator-ramp-delay = <5000>; + regulator-always-on; + }; + + buck6 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3450000>; + regulator-ramp-delay = <5000>; + regulator-always-on; + }; + + aldo1 { + regulator-name = "vdd_1v8_mmc"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + regulator-boot-on; + bootph-pre-ram; + }; + + aldo2 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + }; + + aldo3 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + }; + + aldo4 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + }; + + dldo1 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + }; + + dldo2 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + }; + + dldo3 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + }; + + dldo4 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + }; + + dldo5 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + }; + + dldo6 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + }; + + dldo7 { + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <3400000>; + }; + }; + }; +}; diff --git a/board/spacemit/k1/spl.c b/board/spacemit/k1/spl.c index 54bad9000fe..c08d168fd52 100644 --- a/board/spacemit/k1/spl.c +++ b/board/spacemit/k1/spl.c @@ -8,6 +8,7 @@ #include <clk-uclass.h> #include <cpu_func.h> #include <configs/k1.h> +#include <cpu_func.h> #include <dm/device.h> #include <dm/uclass.h> #include <dt-bindings/pinctrl/k1-pinctrl.h> @@ -15,8 +16,10 @@ #include <i2c.h> #include <linux/delay.h> #include <log.h> +#include <power/regulator.h> #include <spl.h> #include <tlv_eeprom.h> +#include "tlv_codes.h" #define I2C_PIN_CONFIG(x) ((x) | EDGE_NONE | PULL_UP | PAD_1V8_DS2) #define I2C_BUF_SIZE 64 @@ -117,6 +120,73 @@ void serial_early_init(void) panic("Serial uclass init failed: %d\n", ret); } +static void set_vdd_core(void) +{ + struct udevice *dev; + int ret; + + ret = regulator_get_by_platname("vdd_core", &dev); + if (ret) + panic("Fail to detect vdd_core (%d)\n", ret); + ret = regulator_set_enable(dev, true); + if (ret) + log_warning("Fail to enable vdd_core (%d)\n", ret); + ret = regulator_get_value(dev); + if (ret < 0) + log_warning("Fail to read vdd_core (%d)\n", ret); + log_info("vdd_core, value:%d\n", ret); +} + +static void set_vdd_1v8(void) +{ + struct udevice *dev; + int ret; + + ret = regulator_get_by_platname("vdd_1v8", &dev); + if (ret) + panic("Fail to detect vdd_1v8 (%d)\n", ret); + ret = regulator_set_value(dev, 1800000); + if (ret) + log_warning("Fail to set vdd_1v8 as 1800000 (%d)\n", ret); + ret = regulator_set_enable(dev, true); + if (ret) + log_warning("Fail to enable vdd_1v8 (%d)\n", ret); + ret = regulator_get_value(dev); + if (ret < 0) + log_warning("Fail to read vdd_1v8 (%d)\n", ret); + log_info("vdd_1v8, value:%d\n", ret); +} + +static void set_vdd_mmc(void) +{ + struct udevice *dev; + int ret; + + ret = regulator_get_by_platname("vdd_1v8_mmc", &dev); + if (ret) + panic("Fail to detect vdd_1v8_mmc (%d)\n", ret); + ret = regulator_set_enable(dev, true); + if (ret) + log_warning("Fail to enable vdd_1v8_mmc (%d)\n", ret); + ret = regulator_get_value(dev); + if (ret < 0) + log_warning("Fail to read vdd_1v8_mmc (%d)\n", ret); + log_info("vdd_1v8_mmc, value:%d\n", ret); +} + +void pmic_init(void) +{ + struct udevice *pmic_dev; + int ret; + + ret = uclass_get_device(UCLASS_PMIC, 0, &pmic_dev); + if (ret) + panic("Fail to detect PMIC (%d)\n", ret); + set_vdd_core(); + set_vdd_1v8(); + set_vdd_mmc(); +} + /* Load DDR training firmware */ int init_ddr_firmware(void) { @@ -167,6 +237,8 @@ void board_init_f(ulong dummy) log_info("Fail to detect board:%d\n", ret); else log_info("Get board name:%s\n", (char *)i2c_buf); + pmic_init(); + ddr_early_init(); } @@ -175,17 +247,6 @@ u32 spl_boot_device(void) return BOOT_DEVICE_NOR; } -void pmic_init(void) -{ - struct udevice *pmic_dev = NULL; - int ret; - - ret = uclass_get_device(UCLASS_PMIC, 0, &pmic_dev); - if (ret) - panic("Fail to detect PMIC:%d\n", ret); -} - void spl_board_init(void) { - pmic_init(); } diff --git a/configs/k1_defconfig b/configs/k1_defconfig index 0d5c3932797..49a2dbca4f0 100644 --- a/configs/k1_defconfig +++ b/configs/k1_defconfig @@ -66,3 +66,12 @@ CONFIG_SPL_I2C_EEPROM=y CONFIG_CMD_TLV_EEPROM=y CONFIG_SPL_CMD_TLV_EEPROM=y CONFIG_LOG=y +CONFIG_SPL_POWER=y +CONFIG_DM_PMIC=y +CONFIG_SPL_DM_PMIC=y +CONFIG_PMIC_SPACEMIT_P1=y +CONFIG_SPL_PMIC_SPACEMIT_P1=y +CONFIG_DM_REGULATOR=y +CONFIG_SPL_DM_REGULATOR=y +CONFIG_DM_REGULATOR_SPACEMIT_P1=y +CONFIG_SPL_DM_REGULATOR_SPACEMIT_P1=y -- 2.25.1 ^ permalink raw reply related [flat|nested] 37+ messages in thread
* Re: [PATCH 00/17] Add board support for Spacemit K1 SoC in SPL 2026-01-17 19:01 [PATCH 00/17] Add board support for Spacemit K1 SoC in SPL Raymond Mao ` (16 preceding siblings ...) 2026-01-17 19:01 ` [PATCH 17/17] board: k1: enable pmic in spl Raymond Mao @ 2026-01-17 23:13 ` Yixun Lan 2026-01-22 8:29 ` Heinrich Schuchardt 18 siblings, 0 replies; 37+ messages in thread From: Yixun Lan @ 2026-01-17 23:13 UTC (permalink / raw) To: Raymond Mao Cc: u-boot, uboot, Raymond Mao, Rick Chen, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Yao Zi, Heinrich Schuchardt, Conor Dooley, Yu-Chien Peter Lin, Jamie Gibbons, Michal Simek, Eric Schikschneit, Junhui Liu, Sam Protsenko, Patrick Delaunay, Patrice Chotard, Ilias Apalodimas, Neil Armstrong, Casey Connolly, Christian Marangi, Angelo Dureghello, Aniket Limaye, Utsav Agarwal, Justin Swartz, Nathan Barrett-Morrison, Ian Roberts, Arturs Artamonovs, Oliver Gaskell, Greg Malysa, Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Kory Maincent, Anshul Dalal, Justin Klaassen, Paul Barker, Samuel Holland, Jernej Skrabec, Marek Vasut, Rui Miguel Silva, Gabriel Fernandez, Jonas Karlman, Kever Yang, Heiko Stuebner Hi Raymond, please Cc to spacemit@lists.linux.dev for more wide audience On 14:01 Sat 17 Jan , Raymond Mao wrote: > From: Raymond Mao <raymond.mao@riscstar.com> > > This patch series introduces full support for the k1 SoC in SPL for > multiple boards. > > The series enables the board by: > 1. Adding the base board definition with device tree. this is rather huge patchset.. please order and list index of patches for people easy to review.. some patches touch dts and driver code, please submit in separate patch > 2. Bringing up essential clock sources and tree. > 3. Initializing I2C buses for peripheral communication. > 4. Integrating the PMIC driver for power management. > 5. Adding regulator drivers for voltage domain control. > > Junhui Liu (1): > clk: spacemit: Add support for K1 SoC > > Raymond Mao (16): > spacemit: k1: support multi-board infrastructure > spacemit: k1: enable SPL with debug UART > configs: k1: enable early timer support > reset: k1: add SPL support and enable TWSI8 reset > dt-bindings: clock: import k1-syscon from upstream > dts: k1: import dts file from upstream folder > dts: k1: enable clocks in SPL > board: k1: initialize clock and serial devices in SPL > configs: k1: add default option for clock driver in SPL > i2c: k1: add I2C driver support > dt-bindings: pinctrl: add k1 support > spacemit: k1: add TLV EEPROM support in SPL > spacemit: k1: Add DDR firmware support to SPL > power: pmic: add support for Spacemit P1 PMIC > power: regulator: add support for Spacemit P1 SoC > board: k1: enable pmic in spl > > arch/riscv/Kconfig | 10 +- > arch/riscv/cpu/k1/Kconfig | 6 + > arch/riscv/dts/Makefile | 1 + > arch/riscv/dts/k1-spl.dts | 239 +++ > arch/riscv/dts/k1.dtsi | 667 +++++- > board/spacemit/bananapi-f3/Kconfig | 25 - > board/spacemit/bananapi-f3/Makefile | 5 - > board/spacemit/k1/Kconfig | 38 + > .../spacemit/{bananapi-f3 => k1}/MAINTAINERS | 4 +- > board/spacemit/k1/Makefile | 26 + > board/spacemit/{bananapi-f3 => k1}/board.c | 0 > board/spacemit/k1/spl.c | 252 +++ > board/spacemit/k1/tlv_codes.h | 22 + > configs/bananapi-f3_defconfig | 24 - > configs/k1_defconfig | 77 + > drivers/clk/Kconfig | 5 +- > drivers/clk/Makefile | 1 + > drivers/clk/spacemit/Kconfig | 31 + > drivers/clk/spacemit/Makefile | 7 + > drivers/clk/spacemit/clk-k1.c | 1793 +++++++++++++++++ > drivers/clk/spacemit/clk_common.h | 79 + > drivers/clk/spacemit/clk_ddn.c | 93 + > drivers/clk/spacemit/clk_ddn.h | 53 + > drivers/clk/spacemit/clk_mix.c | 403 ++++ > drivers/clk/spacemit/clk_mix.h | 224 ++ > drivers/clk/spacemit/clk_pll.c | 157 ++ > drivers/clk/spacemit/clk_pll.h | 81 + > drivers/i2c/Kconfig | 7 + > drivers/i2c/Makefile | 1 + > drivers/i2c/k1_i2c.c | 521 +++++ > drivers/i2c/k1_i2c.h | 69 + > drivers/power/pmic/Kconfig | 17 + > drivers/power/pmic/Makefile | 1 + > drivers/power/pmic/pmic_spacemit_p1.c | 94 + > drivers/power/regulator/Kconfig | 15 + > drivers/power/regulator/Makefile | 1 + > .../power/regulator/spacemit_p1_regulator.c | 460 +++++ > drivers/reset/Kconfig | 7 + > drivers/reset/Makefile | 2 +- > drivers/reset/reset-spacemit-k1.c | 4 - > include/configs/{bananapi-f3.h => k1.h} | 9 + > .../dt-bindings/clock/spacemit,k1-syscon.h | 253 +++ > include/dt-bindings/pinctrl/k1-pinctrl.h | 59 + > include/power/spacemit_p1.h | 163 ++ > include/soc/spacemit/k1-syscon.h | 149 ++ > lib/vendor/spacemit/ddr_fw.bin | Bin 0 -> 19416 bytes > 46 files changed, 5985 insertions(+), 170 deletions(-) > create mode 100644 arch/riscv/dts/k1-spl.dts > delete mode 100644 board/spacemit/bananapi-f3/Kconfig > delete mode 100644 board/spacemit/bananapi-f3/Makefile > create mode 100644 board/spacemit/k1/Kconfig > rename board/spacemit/{bananapi-f3 => k1}/MAINTAINERS (61%) > create mode 100644 board/spacemit/k1/Makefile > rename board/spacemit/{bananapi-f3 => k1}/board.c (100%) > create mode 100644 board/spacemit/k1/spl.c > create mode 100644 board/spacemit/k1/tlv_codes.h > delete mode 100644 configs/bananapi-f3_defconfig > create mode 100644 configs/k1_defconfig > create mode 100644 drivers/clk/spacemit/Kconfig > create mode 100644 drivers/clk/spacemit/Makefile > create mode 100644 drivers/clk/spacemit/clk-k1.c > create mode 100644 drivers/clk/spacemit/clk_common.h > create mode 100644 drivers/clk/spacemit/clk_ddn.c > create mode 100644 drivers/clk/spacemit/clk_ddn.h > create mode 100644 drivers/clk/spacemit/clk_mix.c > create mode 100644 drivers/clk/spacemit/clk_mix.h > create mode 100644 drivers/clk/spacemit/clk_pll.c > create mode 100644 drivers/clk/spacemit/clk_pll.h > create mode 100644 drivers/i2c/k1_i2c.c > create mode 100644 drivers/i2c/k1_i2c.h > create mode 100644 drivers/power/pmic/pmic_spacemit_p1.c > create mode 100644 drivers/power/regulator/spacemit_p1_regulator.c > rename include/configs/{bananapi-f3.h => k1.h} (52%) > create mode 100644 include/dt-bindings/clock/spacemit,k1-syscon.h > create mode 100644 include/dt-bindings/pinctrl/k1-pinctrl.h > create mode 100644 include/power/spacemit_p1.h > create mode 100644 include/soc/spacemit/k1-syscon.h > create mode 100644 lib/vendor/spacemit/ddr_fw.bin > > -- > 2.25.1 > -- Yixun Lan (dlan) ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH 00/17] Add board support for Spacemit K1 SoC in SPL 2026-01-17 19:01 [PATCH 00/17] Add board support for Spacemit K1 SoC in SPL Raymond Mao ` (17 preceding siblings ...) 2026-01-17 23:13 ` [PATCH 00/17] Add board support for Spacemit K1 SoC in SPL Yixun Lan @ 2026-01-22 8:29 ` Heinrich Schuchardt 2026-01-23 14:58 ` Raymond Mao 18 siblings, 1 reply; 37+ messages in thread From: Heinrich Schuchardt @ 2026-01-22 8:29 UTC (permalink / raw) To: Raymond Mao, u-boot Cc: uboot, Raymond Mao, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Yao Zi, Conor Dooley, Yu-Chien Peter Lin, Jamie Gibbons, Michal Simek, Eric Schikschneit, Yixun Lan, Junhui Liu, Sam Protsenko, Patrick Delaunay, Patrice Chotard, Ilias Apalodimas, Neil Armstrong, Casey Connolly, Christian Marangi, Angelo Dureghello, Aniket Limaye, Utsav Agarwal, Justin Swartz, Nathan Barrett-Morrison, Ian Roberts, Arturs Artamonovs, Oliver Gaskell, Greg Malysa, Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Kory Maincent, Anshul Dalal, Justin Klaassen, Paul Barker, Samuel Holland, Jernej Skrabec, Marek Vasut, Rui Miguel Silva, Gabriel Fernandez, Jonas Karlman, Kever Yang, Heiko Stuebner, Elaine Zhang, Joseph Chen On 1/17/26 20:01, Raymond Mao wrote: > From: Raymond Mao<raymond.mao@riscstar.com> > > This patch series introduces full support for the k1 SoC in SPL for > multiple boards. > > The series enables the board by: > 1. Adding the base board definition with device tree. > 2. Bringing up essential clock sources and tree. > 3. Initializing I2C buses for peripheral communication. > 4. Integrating the PMIC driver for power management. > 5. Adding regulator drivers for voltage domain control. > > Junhui Liu (1): > clk: spacemit: Add support for K1 SoC Hello Raymond, Is a downstream OpenSBI still needed for testing this? The documentation in doc/board/spacemit/bananapi-f3.rst refers to git clone https://github.com/cyyself/opensbi -b k1-opensbi which is based on OpenSBI v1.6-32-g02c7a9bb. Or is the necessary code already upstream? Upstream OpenSBI seems to have some support in platform/generic/spacemit/k1.c. Should doc/board/spacemit/bananapi-f3.rst be renamed or do you plan on different docs for different boards? Best regards Heinrich ^ permalink raw reply [flat|nested] 37+ messages in thread
* Re: [PATCH 00/17] Add board support for Spacemit K1 SoC in SPL 2026-01-22 8:29 ` Heinrich Schuchardt @ 2026-01-23 14:58 ` Raymond Mao 0 siblings, 0 replies; 37+ messages in thread From: Raymond Mao @ 2026-01-23 14:58 UTC (permalink / raw) To: Heinrich Schuchardt Cc: u-boot, uboot, Raymond Mao, Leo, Tom Rini, Lukasz Majewski, Heiko Schocher, Jaehoon Chung, Peng Fan, Yao Zi, Conor Dooley, Yu-Chien Peter Lin, Jamie Gibbons, Michal Simek, Eric Schikschneit, Yixun Lan, Junhui Liu, Sam Protsenko, Patrick Delaunay, Patrice Chotard, Ilias Apalodimas, Neil Armstrong, Casey Connolly, Christian Marangi, Angelo Dureghello, Aniket Limaye, Utsav Agarwal, Justin Swartz, Nathan Barrett-Morrison, Ian Roberts, Arturs Artamonovs, Oliver Gaskell, Greg Malysa, Svyatoslav Ryhel, Henrik Grimler, Quentin Schulz, Kory Maincent, Anshul Dalal, Justin Klaassen, Paul Barker, Samuel Holland, Jernej Skrabec, Marek Vasut, Rui Miguel Silva, Gabriel Fernandez, Jonas Karlman, Kever Yang, Heiko Stuebner, Elaine Zhang, Joseph Chen Hi Heinrich, On Thu, Jan 22, 2026 at 3:30 AM Heinrich Schuchardt <xypron.glpk@gmx.de> wrote: > On 1/17/26 20:01, Raymond Mao wrote: > > From: Raymond Mao<raymond.mao@riscstar.com> > > > > This patch series introduces full support for the k1 SoC in SPL for > > multiple boards. > > > > The series enables the board by: > > 1. Adding the base board definition with device tree. > > 2. Bringing up essential clock sources and tree. > > 3. Initializing I2C buses for peripheral communication. > > 4. Integrating the PMIC driver for power management. > > 5. Adding regulator drivers for voltage domain control. > > > > Junhui Liu (1): > > clk: spacemit: Add support for K1 SoC > > > Hello Raymond, > > Is a downstream OpenSBI still needed for testing this? The documentation > in doc/board/spacemit/bananapi-f3.rst refers to > > git clone https://github.com/cyyself/opensbi -b k1-opensbi > > which is based on OpenSBI v1.6-32-g02c7a9bb. > > Or is the necessary code already upstream? Upstream OpenSBI seems to > have some support in platform/generic/spacemit/k1.c. > > Should doc/board/spacemit/bananapi-f3.rst be renamed or do you plan on > different docs for different boards? > > This series is for SPL, but there is a plan to update the document later when I prepare next patches for the u-boot proper. Raymond > Best regards > > Heinrich > ^ permalink raw reply [flat|nested] 37+ messages in thread
end of thread, other threads:[~2026-02-03 15:03 UTC | newest] Thread overview: 37+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-01-17 19:01 [PATCH 00/17] Add board support for Spacemit K1 SoC in SPL Raymond Mao 2026-01-17 19:01 ` [PATCH 01/17] spacemit: k1: support multi-board infrastructure Raymond Mao 2026-01-23 10:27 ` Heinrich Schuchardt 2026-01-23 10:46 ` Heinrich Schuchardt 2026-01-17 19:01 ` [PATCH 02/17] spacemit: k1: enable SPL with debug UART Raymond Mao 2026-01-18 8:50 ` Yao Zi 2026-01-23 14:51 ` Heinrich Schuchardt 2026-02-03 14:24 ` Raymond Mao 2026-01-17 19:01 ` [PATCH 03/17] configs: k1: enable early timer support Raymond Mao 2026-01-17 19:01 ` [PATCH 04/17] reset: k1: add SPL support and enable TWSI8 reset Raymond Mao 2026-01-18 9:10 ` Yao Zi 2026-01-21 23:17 ` Raymond Mao 2026-01-17 19:01 ` [PATCH 05/17] dt-bindings: clock: import k1-syscon from upstream Raymond Mao 2026-01-17 19:01 ` [PATCH 06/17] dts: k1: import dts file from upstream folder Raymond Mao 2026-01-17 23:03 ` Yixun Lan 2026-01-18 8:56 ` Yao Zi 2026-01-17 19:01 ` [PATCH 07/17] clk: spacemit: Add support for K1 SoC Raymond Mao 2026-01-17 19:01 ` [PATCH 08/17] dts: k1: enable clocks in SPL Raymond Mao 2026-01-17 19:01 ` [PATCH 09/17] board: k1: initialize clock and serial devices " Raymond Mao 2026-01-17 19:01 ` [PATCH 10/17] configs: k1: add default option for clock driver " Raymond Mao 2026-01-17 19:01 ` [PATCH 11/17] i2c: k1: add I2C driver support Raymond Mao 2026-01-19 5:24 ` Heiko Schocher 2026-01-17 19:01 ` [PATCH 12/17] dt-bindings: pinctrl: add k1 support Raymond Mao 2026-01-18 9:26 ` Yao Zi 2026-01-21 23:20 ` Raymond Mao 2026-01-22 14:55 ` Yao Zi 2026-01-17 19:01 ` [PATCH 13/17] spacemit: k1: add TLV EEPROM support in SPL Raymond Mao 2026-01-17 19:01 ` [PATCH 14/17] spacemit: k1: Add DDR firmware support to SPL Raymond Mao 2026-01-19 9:40 ` Yao Zi 2026-01-21 23:24 ` Raymond Mao 2026-01-22 14:43 ` Yao Zi 2026-01-17 19:01 ` [PATCH 15/17] power: pmic: add support for Spacemit P1 PMIC Raymond Mao 2026-01-17 19:01 ` [PATCH 16/17] power: regulator: add support for Spacemit P1 SoC Raymond Mao 2026-01-17 19:01 ` [PATCH 17/17] board: k1: enable pmic in spl Raymond Mao 2026-01-17 23:13 ` [PATCH 00/17] Add board support for Spacemit K1 SoC in SPL Yixun Lan 2026-01-22 8:29 ` Heinrich Schuchardt 2026-01-23 14:58 ` Raymond Mao
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox