From: Raymond Mao <[email protected]> And support for required components including clock, I2C controller, and I2C EEPROM.
Signed-off-by: Raymond Mao <[email protected]> --- 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 <[email protected]> + * 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

