diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/asm-generic/global_data.h | 4 | ||||
| -rw-r--r-- | include/bloblist.h | 2 | ||||
| -rw-r--r-- | include/btrfs.h | 6 | ||||
| -rw-r--r-- | include/configs/bananapi-f3.h | 13 | ||||
| -rw-r--r-- | include/configs/k1.h | 20 | ||||
| -rw-r--r-- | include/dt-bindings/reset/spacemit-k1-reset.h | 118 | ||||
| -rw-r--r-- | include/image.h | 9 | ||||
| -rw-r--r-- | include/linux/string.h | 13 | ||||
| -rw-r--r-- | include/pmbus.h | 667 | ||||
| -rw-r--r-- | include/power/regulator.h | 24 | ||||
| -rw-r--r-- | include/power/sandbox_pmic.h | 15 | ||||
| -rw-r--r-- | include/power/spacemit_p1.h | 163 | ||||
| -rw-r--r-- | include/soc/spacemit/k1-reset.h | 23 | ||||
| -rw-r--r-- | include/soc/spacemit/k1-syscon.h | 149 | ||||
| -rw-r--r-- | include/spi.h | 1 |
15 files changed, 1077 insertions, 150 deletions
diff --git a/include/asm-generic/global_data.h b/include/asm-generic/global_data.h index ad7ebb1bbc9..fd116b0cebf 100644 --- a/include/asm-generic/global_data.h +++ b/include/asm-generic/global_data.h @@ -697,9 +697,9 @@ enum gd_flags { */ GD_FLG_DM_DEAD = 0x400000, /** - * @GD_FLG_BLOBLIST_READY: bloblist is ready for use + * @GD_FLG_BLOBLIST_HANDOFF: bloblist has been found. */ - GD_FLG_BLOBLIST_READY = 0x800000, + GD_FLG_BLOBLIST_HANDOFF = 0x800000, /** * @GD_FLG_HUSH_OLD_PARSER: Use hush old parser. */ diff --git a/include/bloblist.h b/include/bloblist.h index 4c578772965..fcd290eeb16 100644 --- a/include/bloblist.h +++ b/include/bloblist.h @@ -516,7 +516,7 @@ bool bloblist_exists(void); * If CONFIG_BLOBLIST_PASSAGE_MANDATORY is selected, bloblist in the incoming * standard passage is mandatorily required. * - * Sets GD_FLG_BLOBLIST_READY in global_data flags on success + * Sets GD_FLG_BLOBLIST_HANDOFF in global_data flags on success * * Return: 0 if OK, -ve on error */ diff --git a/include/btrfs.h b/include/btrfs.h index 2d73add18e0..3878b7817ea 100644 --- a/include/btrfs.h +++ b/include/btrfs.h @@ -10,15 +10,19 @@ struct blk_desc; struct disk_partition; +struct fs_dir_stream; +struct fs_dirent; int btrfs_probe(struct blk_desc *fs_dev_desc, struct disk_partition *fs_partition); -int btrfs_ls(const char *); int btrfs_exists(const char *); int btrfs_size(const char *, loff_t *); int btrfs_read(const char *, void *, loff_t, loff_t, loff_t *); void btrfs_close(void); int btrfs_uuid(char *); void btrfs_list_subvols(void); +int btrfs_opendir(const char *filename, struct fs_dir_stream **dirsp); +int btrfs_readdir(struct fs_dir_stream *dirs, struct fs_dirent **dentp); +void btrfs_closedir(struct fs_dir_stream *dirs); #endif /* __U_BOOT_BTRFS_H__ */ diff --git a/include/configs/bananapi-f3.h b/include/configs/bananapi-f3.h deleted file mode 100644 index 97cf4d72df0..00000000000 --- a/include/configs/bananapi-f3.h +++ /dev/null @@ -1,13 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Copyright (c) 2024, Kongyang Liu <[email protected]> - * - */ - -#ifndef __CONFIG_H -#define __CONFIG_H - -#define CFG_SYS_SDRAM_BASE 0x0 -#define CFG_SYS_NS16550_IER 0x40 /* UART Unit Enable */ - -#endif /* __CONFIG_H */ diff --git a/include/configs/k1.h b/include/configs/k1.h new file mode 100644 index 00000000000..e09c3594905 --- /dev/null +++ b/include/configs/k1.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (c) 2024, Kongyang Liu <[email protected]> + * Copyright (C) 2025-2026, RISCstar Ltd. + * + */ + +#ifndef __CONFIG_H +#define __CONFIG_H + +#define CFG_SYS_NS16550_CLK 14700000 +#define CFG_SYS_NS16550_IER 0x40 /* UART Unit Enable */ +#define CFG_SYS_SDRAM_BASE 0x0 + +#define RISCV_MMODE_TIMERBASE 0xe4000000 +#define RISCV_MMODE_TIMEROFF 0xbff8 +#define RISCV_MMODE_TIMER_FREQ 24000000 +#define RISCV_SMODE_TIMER_FREQ 24000000 + +#endif /* __CONFIG_H */ diff --git a/include/dt-bindings/reset/spacemit-k1-reset.h b/include/dt-bindings/reset/spacemit-k1-reset.h deleted file mode 100644 index 74db58b27ef..00000000000 --- a/include/dt-bindings/reset/spacemit-k1-reset.h +++ /dev/null @@ -1,118 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (C) 2022 Spacemit Inc. - * Copyright (C) 2025 Huan Zhou <[email protected]> - */ - -#ifndef __DT_BINDINGS_RESET_SAPCEMIT_K1_H__ -#define __DT_BINDINGS_RESET_SAPCEMIT_K1_H__ -/* APBC */ -#define RESET_UART1 1 -#define RESET_UART2 2 -#define RESET_GPIO 3 -#define RESET_PWM0 4 -#define RESET_PWM1 5 -#define RESET_PWM2 6 -#define RESET_PWM3 7 -#define RESET_PWM4 8 -#define RESET_PWM5 9 -#define RESET_PWM6 10 -#define RESET_PWM7 11 -#define RESET_PWM8 12 -#define RESET_PWM9 13 -#define RESET_PWM10 14 -#define RESET_PWM11 15 -#define RESET_PWM12 16 -#define RESET_PWM13 17 -#define RESET_PWM14 18 -#define RESET_PWM15 19 -#define RESET_PWM16 20 -#define RESET_PWM17 21 -#define RESET_PWM18 22 -#define RESET_PWM19 23 -#define RESET_SSP3 24 -#define RESET_UART3 25 -#define RESET_RTC 26 -#define RESET_TWSI0 27 -#define RESET_TIMERS1 28 -#define RESET_AIB 29 -#define RESET_TIMERS2 30 -#define RESET_ONEWIRE 31 -#define RESET_SSPA0 32 -#define RESET_SSPA1 33 -#define RESET_DRO 34 -#define RESET_IR 35 -#define RESET_TWSI1 36 -#define RESET_TSEN 37 -#define RESET_TWSI2 38 -#define RESET_TWSI4 39 -#define RESET_TWSI5 40 -#define RESET_TWSI6 41 -#define RESET_TWSI7 42 -#define RESET_TWSI8 43 -#define RESET_IPC_AP2AUD 44 -#define RESET_UART4 45 -#define RESET_UART5 46 -#define RESET_UART6 47 -#define RESET_UART7 48 -#define RESET_UART8 49 -#define RESET_UART9 50 -#define RESET_CAN0 51 - -/* MPMU */ -#define RESET_WDT 52 - -/* APMU */ -#define RESET_JPG 53 -#define RESET_CSI 54 -#define RESET_CCIC2_PHY 55 -#define RESET_CCIC3_PHY 56 -#define RESET_ISP 57 -#define RESET_ISP_AHB 58 -#define RESET_ISP_CI 59 -#define RESET_ISP_CPP 60 -#define RESET_LCD 61 -#define RESET_DSI_ESC 62 -#define RESET_V2D 63 -#define RESET_MIPI 64 -#define RESET_LCD_SPI 65 -#define RESET_LCD_SPI_BUS 66 -#define RESET_LCD_SPI_HBUS 67 -#define RESET_LCD_MCLK 68 -#define RESET_CCIC_4X 69 -#define RESET_CCIC1_PHY 70 -#define RESET_SDH_AXI 71 -#define RESET_SDH0 72 -#define RESET_SDH1 73 -#define RESET_USB_AXI 74 -#define RESET_USBP1_AXI 75 -#define RESET_USB3_0 76 -#define RESET_QSPI 77 -#define RESET_QSPI_BUS 78 -#define RESET_DMA 79 -#define RESET_AES 80 -#define RESET_VPU 81 -#define RESET_GPU 82 -#define RESET_SDH2 83 -#define RESET_MC 84 -#define RESET_EM_AXI 85 -#define RESET_EM 86 -#define RESET_AUDIO_SYS 87 -#define RESET_HDMI 88 -#define RESET_PCIE0 89 -#define RESET_PCIE1 90 -#define RESET_PCIE2 91 -#define RESET_EMAC0 92 -#define RESET_EMAC1 93 - -/* APBC2 */ -#define RESET_SEC_UART1 94 -#define RESET_SEC_SSP2 95 -#define RESET_SEC_TWSI3 96 -#define RESET_SEC_RTC 97 -#define RESET_SEC_TIMERS0 98 -#define RESET_SEC_KPC 99 -#define RESET_SEC_GPIO 100 -#define RESET_NUMBER 101 - -#endif diff --git a/include/image.h b/include/image.h index 9c8a746d576..4b3c9c87bf5 100644 --- a/include/image.h +++ b/include/image.h @@ -1461,11 +1461,20 @@ int fit_image_verify_with_data(const void *fit, int image_noffset, int fit_image_verify(const void *fit, int noffset); #if CONFIG_IS_ENABLED(FIT_SIGNATURE) int fit_config_verify(const void *fit, int conf_noffset); +int fit_config_verify_with_key_blob(const void *fit, int conf_noffset, + const void *key_blob); #else static inline int fit_config_verify(const void *fit, int conf_noffset) { return 0; } + +static inline int fit_config_verify_with_key_blob(const void *fit, + int conf_noffset, + const void *key_blob) +{ + return 0; +} #endif int fit_all_image_verify(const void *fit); int fit_config_decrypt(const void *fit, int conf_noffset); diff --git a/include/linux/string.h b/include/linux/string.h index 850356d7c3f..986499dfc70 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -43,12 +43,8 @@ extern int strcmp(const char *,const char *); #ifndef __HAVE_ARCH_STRNCMP extern int strncmp(const char *,const char *,__kernel_size_t); #endif -#ifndef __HAVE_ARCH_STRCASECMP int strcasecmp(const char *s1, const char *s2); -#endif -#ifndef __HAVE_ARCH_STRNCASECMP -extern int strncasecmp(const char *s1, const char *s2, __kernel_size_t len); -#endif +int strncasecmp(const char *s1, const char *s2, __kernel_size_t len); #ifndef __HAVE_ARCH_STRCHR extern char * strchr(const char *,int); #endif @@ -63,7 +59,7 @@ extern char * strchr(const char *,int); * @c: character to search for * Return: position of @c in @s, or end of @s if not found */ -const char *strchrnul(const char *s, int c); +char *strchrnul(const char *s, int c); #ifndef __HAVE_ARCH_STRRCHR extern char * strrchr(const char *,int); @@ -75,6 +71,7 @@ extern char * strstr(const char *,const char *); #ifndef __HAVE_ARCH_STRNSTR extern char *strnstr(const char *, const char *, size_t); #endif +char *strcasestr(const char *, const char *); #ifndef __HAVE_ARCH_STRLEN extern __kernel_size_t strlen(const char *); #endif @@ -107,10 +104,6 @@ extern char * strndup(const char *, size_t); extern const char *strdup_const(const char *s); extern void kfree_const(const void *x); -#ifndef __HAVE_ARCH_STRSWAB -extern char * strswab(const char *); -#endif - #ifndef __HAVE_ARCH_MEMSET extern void * memset(void *,int,__kernel_size_t); #endif diff --git a/include/pmbus.h b/include/pmbus.h new file mode 100644 index 00000000000..0e121fa6637 --- /dev/null +++ b/include/pmbus.h @@ -0,0 +1,667 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright 2026 Free Mobile, Vincent Jardin + * + * PMBus 1.x command codes, numeric format decoders, and driver_info + * scaffolding for U-Boot. + * + * Intents + * + * U-Boot's PMBus support is not a hwmon clone. It shall be used to: + * 1. identify PMBus regulators a board carries at boot, + * 2. print telemetry so an operator can confirm rail voltages and + * fault status before handing off to the kernel, + * 3. decode chip alerts when a rail trips an over/under voltage, + * over current, or thermal threshold, + * 4. optionally trim a critical rail before kernel boot, to better + * protect the board. + * + * No periodic polling, no /sys, no userspace surface, no fan control + * loops. Linux owns those. See doc/develop/pmbus.rst for the full + * porting guide and policy notes. + * + * Linux relationship + * + * Constants (command codes, status bit names, sensor class enum, + * format enum) are mirrored verbatim from + * linux/drivers/hwmon/pmbus/pmbus.h + * with attribution; this is standardised data and copying it avoids + * accidental drift. Decoders (LINEAR11/16, DIRECT, VID, IEEE754) are + * reimplemented from the PMBus 1.x spec rather than copied. The + * surrounding kernel context (struct pmbus_data, hwmon caching, + * sysfs publication) does not apply to U-Boot. + * + * Tree level files (this header, lib/pmbus.c, future per chip drivers + * under drivers/power/regulator/) must stay platform agnostic. They + * may reference only the PMBus 1.x specification and chip datasheets, + * never a specific board, SoC, or product. Board specific quirks + * live under board/<vendor>/<board>/. + */ + +#ifndef _PMBUS_H_ +#define _PMBUS_H_ + +#include <linux/types.h> + +struct udevice; +struct pmbus_driver_info; +struct pmbus_status_override; + +/* + * PMBus 1.3 standard command codes (Part II). + * + * Subset relevant to U-Boot's needs: + * - configuration (PAGE, OPERATION, VOUT_*), + * - telemetry (READ_VIN, READ_IOUT, READ_TEMPERATURE_1, ...), + * - status (STATUS_WORD, STATUS_VOUT, ...), + * - identification (MFR_ID, MFR_MODEL, MFR_REVISION). + * Chip specific extensions (for example MPS PROTECTION_LAST 0xFB) shall be in + * the per chip driver file. + */ +#define PMBUS_PAGE 0x00 +#define PMBUS_OPERATION 0x01 +#define PMBUS_ON_OFF_CONFIG 0x02 +#define PMBUS_CLEAR_FAULTS 0x03 +#define PMBUS_PHASE 0x04 + +#define PMBUS_WRITE_PROTECT 0x10 + +#define PMBUS_CAPABILITY 0x19 +#define PMBUS_QUERY 0x1a +#define PMBUS_SMBALERT_MASK 0x1b +#define PMBUS_VOUT_MODE 0x20 +#define PMBUS_VOUT_COMMAND 0x21 +#define PMBUS_VOUT_TRIM 0x22 +#define PMBUS_VOUT_CAL_OFFSET 0x23 +#define PMBUS_VOUT_MAX 0x24 +#define PMBUS_VOUT_MARGIN_HIGH 0x25 +#define PMBUS_VOUT_MARGIN_LOW 0x26 +#define PMBUS_VOUT_TRANSITION_RATE 0x27 +#define PMBUS_VOUT_DROOP 0x28 +#define PMBUS_VOUT_SCALE_LOOP 0x29 +#define PMBUS_VOUT_SCALE_MONITOR 0x2a + +#define PMBUS_COEFFICIENTS 0x30 +#define PMBUS_POUT_MAX 0x31 + +#define PMBUS_STATUS_BYTE 0x78 +#define PMBUS_STATUS_WORD 0x79 +#define PMBUS_STATUS_VOUT 0x7a +#define PMBUS_STATUS_IOUT 0x7b +#define PMBUS_STATUS_INPUT 0x7c +#define PMBUS_STATUS_TEMPERATURE 0x7d +#define PMBUS_STATUS_CML 0x7e +#define PMBUS_STATUS_OTHER 0x7f +#define PMBUS_STATUS_MFR_SPECIFIC 0x80 + +#define PMBUS_READ_VIN 0x88 +#define PMBUS_READ_IIN 0x89 +#define PMBUS_READ_VCAP 0x8a +#define PMBUS_READ_VOUT 0x8b +#define PMBUS_READ_IOUT 0x8c +#define PMBUS_READ_TEMPERATURE_1 0x8d +#define PMBUS_READ_TEMPERATURE_2 0x8e +#define PMBUS_READ_TEMPERATURE_3 0x8f +#define PMBUS_READ_DUTY_CYCLE 0x94 +#define PMBUS_READ_FREQUENCY 0x95 +#define PMBUS_READ_POUT 0x96 +#define PMBUS_READ_PIN 0x97 + +#define PMBUS_REVISION 0x98 +#define PMBUS_MFR_ID 0x99 +#define PMBUS_MFR_MODEL 0x9a +#define PMBUS_MFR_REVISION 0x9b +#define PMBUS_MFR_LOCATION 0x9c +#define PMBUS_MFR_DATE 0x9d +#define PMBUS_MFR_SERIAL 0x9e + +#define PMBUS_IC_DEVICE_ID 0xad +#define PMBUS_IC_DEVICE_REV 0xae + +/* VOUT_MODE upper bits: numeric format selector (Part II sec 8.3). */ +#define PB_VOUT_MODE_MODE_MASK 0xe0 +#define PB_VOUT_MODE_PARAM_MASK 0x1f +#define PB_VOUT_MODE_LINEAR 0x00 +#define PB_VOUT_MODE_VID 0x20 +#define PB_VOUT_MODE_DIRECT 0x40 +#define PB_VOUT_MODE_IEEE754 0x60 + +/* STATUS_WORD lower byte (= STATUS_BYTE), Part II sec 10.1.1. */ +#define PB_STATUS_NONE_ABOVE BIT(0) +#define PB_STATUS_CML BIT(1) +#define PB_STATUS_TEMPERATURE BIT(2) +#define PB_STATUS_VIN_UV BIT(3) +#define PB_STATUS_IOUT_OC BIT(4) +#define PB_STATUS_VOUT_OV BIT(5) +#define PB_STATUS_OFF BIT(6) +#define PB_STATUS_BUSY BIT(7) + +/* STATUS_WORD upper byte. */ +#define PB_STATUS_UNKNOWN BIT(8) +#define PB_STATUS_OTHER BIT(9) +#define PB_STATUS_FANS BIT(10) +#define PB_STATUS_POWER_GOOD_N BIT(11) +#define PB_STATUS_WORD_MFR BIT(12) +#define PB_STATUS_INPUT BIT(13) +#define PB_STATUS_IOUT_POUT BIT(14) +#define PB_STATUS_VOUT BIT(15) + +/* STATUS_VOUT (PMBus 1.3.1 Part II sec 17.3, Table 17). */ +#define PB_VOLTAGE_VOUT_MAX_MIN_WARN BIT(3) +#define PB_VOLTAGE_UV_FAULT BIT(4) +#define PB_VOLTAGE_UV_WARNING BIT(5) +#define PB_VOLTAGE_OV_WARNING BIT(6) +#define PB_VOLTAGE_OV_FAULT BIT(7) + +/* STATUS_IOUT (Part II sec 10.6). */ +#define PB_POUT_OP_WARNING BIT(0) +#define PB_POUT_OP_FAULT BIT(1) +#define PB_POWER_LIMITING BIT(2) +#define PB_CURRENT_SHARE_FAULT BIT(3) +#define PB_IOUT_UC_FAULT BIT(4) +#define PB_IOUT_OC_WARNING BIT(5) +#define PB_IOUT_OC_LV_FAULT BIT(6) +#define PB_IOUT_OC_FAULT BIT(7) + +/* STATUS_INPUT (Part II sec 10.7). */ +#define PB_PIN_OP_WARNING BIT(0) +#define PB_IIN_OC_WARNING BIT(1) +#define PB_IIN_OC_FAULT BIT(2) + +/* STATUS_TEMPERATURE (Part II sec 10.8). */ +#define PB_TEMP_UT_FAULT BIT(4) +#define PB_TEMP_UT_WARNING BIT(5) +#define PB_TEMP_OT_WARNING BIT(6) +#define PB_TEMP_OT_FAULT BIT(7) + +/* STATUS_CML (Part II sec 10.9). */ +#define PB_CML_FAULT_OTHER_MEM_LOGIC BIT(0) +#define PB_CML_FAULT_OTHER_COMM BIT(1) +#define PB_CML_FAULT_PROCESSOR BIT(3) +#define PB_CML_FAULT_MEMORY BIT(4) +#define PB_CML_FAULT_PACKET_ERROR BIT(5) +#define PB_CML_FAULT_INVALID_DATA BIT(6) +#define PB_CML_FAULT_INVALID_COMMAND BIT(7) + +/* + * OPERATION (01h) command bits per PMBus 1.3 Part II sec 9.1. Bit[7] + * is the master rail enable; the lower bits select margin high/low + * and turn off behaviour (subset surfaced for the regulator helper). + */ +#define PB_OPERATION_ON BIT(7) + +/* + * LINEAR11 numeric format (PMBus 1.3 Part II sec 7): 16 bit register + * with a signed 11 bit mantissa in bits[10:0] and a signed 5 bit + * exponent in bits[15:11]. Engineering value = mantissa * 2^exponent. + */ +#define PB_LINEAR11_MANT_MASK 0x07ff +#define PB_LINEAR11_MANT_BITS 11 +#define PB_LINEAR11_EXP_SHIFT 11 +#define PB_LINEAR11_EXP_MASK 0x1f +#define PB_LINEAR11_EXP_BITS 5 + +/* + * Cache buffer sizes for the active device singleton + MFR_* block + * reads. PMBus block reads return up to 32 bytes per the SMBus spec; + * 16 covers every MFR string seen in practice on regulator class + * chips and keeps the singleton compact. + */ +#define PMBUS_MFR_STRING_MAX 16 +#define PMBUS_VENDOR_NAME_MAX 8 +#define PMBUS_REGULATOR_NAME_MAX 24 + +/* PMBus revision identifiers reported by PMBUS_REVISION (98h). */ +#define PMBUS_REV_10 0x00 /* PMBus 1.0 */ +#define PMBUS_REV_11 0x11 /* PMBus 1.1 */ +#define PMBUS_REV_12 0x22 /* PMBus 1.2 */ +#define PMBUS_REV_13 0x33 /* PMBus 1.3 */ + +/* + * Numeric formats and sensor classes. + * + * Mirrors linux/drivers/hwmon/pmbus/pmbus.h enum pmbus_data_format + * and enum pmbus_sensor_classes. A chip's pmbus_driver_info wires + * each sensor class to one format and (for DIRECT) to its m/b/R + * coefficients. + */ +enum pmbus_data_format { + pmbus_fmt_linear = 0, + pmbus_fmt_ieee754, + pmbus_fmt_direct, + pmbus_fmt_vid, +}; + +enum pmbus_sensor_classes { + PSC_VOLTAGE_IN = 0, + PSC_VOLTAGE_OUT, + PSC_CURRENT_IN, + PSC_CURRENT_OUT, + PSC_POWER, + PSC_TEMPERATURE, + PSC_NUM_CLASSES +}; + +/* + * Per chip identification record. Each per chip driver declares one + * of these and points the framework at it. Subset of the kernel + * struct pmbus_driver_info: U-Boot has no per page caches, no fan + * accessors, no virtual registers, no async sysfs publication. + * + * pages number of PAGE distinct rails the chip exposes + * (1 for single rail parts). + * format[] numeric format per sensor class. + * m/b/R[] DIRECT format coefficients per sensor class. See + * pmbus_reg2data_direct() below for the formula. + * Unused for non DIRECT classes. + * read_byte_data, read_word_data + * optional per chip register translators. Return the + * standard register value on success, ENODATA to fall + * through to the generic transport, any other negative + * errno on bus error. + * identify optional probe time hook to discover format and + * page count from the chip itself (for example, the + * MPQ8785 VOUT_MODE switch between LINEAR and DIRECT). + */ +struct pmbus_driver_info { + int pages; + enum pmbus_data_format format[PSC_NUM_CLASSES]; + int m[PSC_NUM_CLASSES]; + int b[PSC_NUM_CLASSES]; + int R[PSC_NUM_CLASSES]; + + int (*read_byte_data)(struct udevice *dev, int page, int reg); + int (*read_word_data)(struct udevice *dev, int page, int reg); + int (*identify)(struct udevice *dev, struct pmbus_driver_info *info); + + /* + * Optional sparse table of chip specific STATUS_* bit name + * substitutions. Terminated by an entry with .name = NULL + * (matching the convention used by struct udevice_id and + * other U-Boot driver tables). NULL pointer means the chip + * uses only PMBus 1.x standard names. See struct + * pmbus_status_override and pmbus_print_status_bits(). + */ + const struct pmbus_status_override *status_overrides; + + /* + * Bitmask (BIT(enum pmbus_sensor_classes)) of the sensor classes + * this chip actually implements. When non-zero, pmbus_print_telemetry + * prints exactly these classes -- mirroring the kernel's per chip + * sensor set -- and skips the rest. This is how an MPS buck that + * ACKs READ_POUT / READ_IIN with an uncalibrated value still hides + * POWER / CURRENT_IN (the kernel's mpq8646 driver exposes neither). + * Zero means "not declared": the telemetry printer falls back to a + * live pmbus_word_command_supported() probe per class, which is what + * the generic driver (compatible = "pmbus") relies on. + */ + u8 classes_present; +}; + +/* + * Decoder helpers (raw register, returns engineering value in micro + * units). + * + * All return signed micro units (uV, uA, udegC), 64 bit to avoid + * overflow on large mantissa times exponent products. The caller + * divides by 1000 for milli units, or by 1_000_000 for the integer + * engineering value. + */ + +/* + * LINEAR11. Bits[15:11] = signed 5 bit exponent Y, bits[10:0] = + * signed 11 bit mantissa N. Engineering value = N * 2^Y. + * + * Used by most PMBus chips for VIN, IIN, IOUT, TEMP. Some MPS + * parts deviate (they report DIRECT format with chip specific m/b/R + * coefficients); check the chip datasheet against PMBUS_VOUT_MODE + * and the Linux per chip driver if porting. + */ +s64 pmbus_reg2data_linear11(u16 raw); + +/* + * LINEAR16. 16 bit unsigned mantissa multiplied by 2^Y, where Y is + * the signed 5 bit exponent supplied via VOUT_MODE bits[4:0]. The + * caller must read VOUT_MODE (cmd 0x20) and pass it in vout_mode. + * Only the mode_mask bits[7:5] = 0 selector is the LINEAR16 path. + * + * Used for READ_VOUT (8Bh) on chips whose VOUT_MODE selects Linear. + * Returns 0 if VOUT_MODE indicates a non Linear mode; the caller + * is then expected to dispatch to pmbus_reg2data_direct() with the + * appropriate per chip m/b/R, or to pmbus_reg2data_vid() / _ieee754() + * if the chip uses those formats. + */ +s64 pmbus_reg2data_linear16(u16 raw, u8 vout_mode); + +/* + * DIRECT. PMBus 1.3 Part II sec 8.4. The chip stores a signed 16 bit + * value X; the engineering value Y is one over m, multiplied by the + * quantity (X scaled by ten to the power minus R, then offset by + * minus b), with chip specific (m, b, R) coefficients. + * + * In symbolic form: Y = (1/m) * (X * 10**(-R) - b). The negative + * exponent and trailing subtraction are math operators in the + * formula, not punctuation in the prose. + * + * Returns micro units. Implementation order matches the Linux + * reference (multiply before subtract, scale R then divide by m) to + * minimise quantisation drift. m == 0 returns 0. + */ +s64 pmbus_reg2data_direct(s16 raw, int m, int b, int R); + +/* + * Encoder: engineering value (micro units) to LINEAR16 raw register + * value. Used by pre kernel rail trim code (see board/nxp/common/vid.c) + * to write VOUT_COMMAND from a target voltage. The exponent is + * recovered from VOUT_MODE. + * + * Returns 0 if VOUT_MODE indicates a non Linear format; the caller + * must then dispatch to pmbus_data2reg_direct() (DIRECT format) or + * the VID / IEEE754 encoders (when those land) per the chip's actual + * VOUT_MODE selector. + */ +u16 pmbus_data2reg_linear16(s64 micro, u8 vout_mode); + +/* + * Encoder: engineering value (micro units) to DIRECT raw register + * value. Inverse of pmbus_reg2data_direct(): + * + * X = (m * Y + b) * 10^R + * + * with chip specific (m, b, R) coefficients (typically taken from + * the chip's pmbus_driver_info[PSC_VOLTAGE_OUT]). m == 0 returns 0. + * + * The result is saturated to the s16 range mandated by the PMBus + * 1.3 Part II sec 8.4 DIRECT encoding; out of range targets return + * 0x7fff or 0x8000 rather than wrapping. + */ +u16 pmbus_data2reg_direct(s64 micro, int m, int b, int R); + +/* + * Dispatcher: pick the right reg2data_* helper based on the chip's + * pmbus_driver_info[class]. vout_mode is consulted only for + * VOLTAGE_OUT in linear format. For DIRECT, m/b/R are taken from + * info. For VID and IEEE754 the dispatcher returns 0 (formats + * not yet wired up; add when a consumer lands). + */ +s64 pmbus_reg2data(const struct pmbus_driver_info *info, + enum pmbus_sensor_classes class, + u16 raw, u8 vout_mode); + +/* + * Transport helpers. + * + * Thin wrappers over the U-Boot DM I2C primitives that handle PMBus + * framing details (little endian word layout, two stage block read, + * CLEAR_FAULTS pseudo command without payload). + */ + +/* Read a byte register. */ +int pmbus_read_byte(struct udevice *dev, u8 cmd, u8 *val); + +/* Read a 16 bit register, little endian on the wire. */ +int pmbus_read_word(struct udevice *dev, u8 cmd, u16 *val); + +/* Write a byte register. */ +int pmbus_write_byte(struct udevice *dev, u8 cmd, u8 val); + +/* Write a 16 bit register, little endian on the wire. */ +int pmbus_write_word(struct udevice *dev, u8 cmd, u16 val); + +/* + * Block read of a vendor string register (MFR_ID, MFR_MODEL, + * MFR_REVISION). The first wire byte is the payload length; the + * helper does the second read for the payload itself, so even strict + * I2C controllers (which forbid over read on block transactions) + * work. Output is null terminated and printable only (non printable + * bytes are substituted with '.'). + * + * reverse_bytes: some MPS NVM personalities store ASCII strings + * LSB first (chip returns "SPM" for the human string "MPS"); pass + * true to reverse on copy. Spec compliant chips pass false. + * + * Returns string length on success or a negative errno on bus error + * or invalid length byte. outsz must be at least 2. + */ +int pmbus_read_string(struct udevice *dev, u8 cmd, char *out, int outsz, + bool reverse_bytes); + +/* Issue a CLEAR_FAULTS (03h) write. Clears RAM sticky STATUS_*. */ +int pmbus_clear_faults(struct udevice *dev); + +/* + * Capability probe: is a word sized command implemented by the chip? + * + * Primary signal is the bus NAK -- compliant parts do not ACK a + * command they do not implement, so the word read fails. Secondary + * signal is a clean -> dirty transition of STATUS_CML[INVALID_COMMAND] + * across the read (a chip that ACKs but does not implement the + * register raises it). Non destructive: never issues CLEAR_FAULTS, so + * sticky fault history survives for a subsequent pmbus status; a + * pre existing CML fault disables the secondary signal so it cannot + * produce a false "unsupported". + * + * Returns true if the command appears supported, false otherwise. + */ +bool pmbus_word_command_supported(struct udevice *dev, u8 reg); + +/* + * High level snapshot printers shared by the pmbus CLI and board + * boot time diagnostics. Both operate on the current pmbus_active() + * device (select it first via pmbus_set_active()); chip is the I2C + * handle from pmbus_active_get_i2c() / the CLI's require_active(). + * + * pmbus_print_telemetry: decodes VIN / VOUT / IIN / IOUT / POUT / TEMP + * through the active device's pmbus_driver_info (LINEAR / DIRECT / VID + * per VOUT_MODE and per class format), skipping commands the chip does + * not implement (pmbus_word_command_supported). Falls back to + * LINEAR16 / LINEAR11 when no driver_info is cached. Caller prints the + * header line. + * + * pmbus_print_status_word: reads + decodes STATUS_WORD with the active + * device's chip specific status_overrides, if any. + */ +void pmbus_print_telemetry(struct udevice *chip); +void pmbus_print_status_word(struct udevice *chip); + +/* + * Regulator -> thermal bridge. + * + * Read READ_TEMPERATURE_1 (8Dh) from a UCLASS_REGULATOR device that + * was bound by a pmbus_helper based chip driver, decode it through + * the chip's pmbus_driver_info (so the MPS DIRECT 1 degC/LSB quirk + * and the standard LINEAR11 encoding are both handled), select the + * regulator's PAGE first on multi rail parts, and return the result + * in millidegrees Celsius. + * + * This is what the generic drivers/thermal/pmbus_thermal.c companion + * calls on its parent; keeping the decode here avoids exposing the + * regulator-private pmbus_regulator_priv layout to other subsystems. + * + * Returns 0 on success, or a negative errno (-ENODEV if reg is not a + * probed pmbus regulator, -EIO on bus error). + */ +int pmbus_regulator_read_temp(struct udevice *reg_dev, int *temp_mc); + +/* + * Look up the pmbus_driver_info of a probed UCLASS_REGULATOR device at + * (bus_seq, addr) that is driven by a pmbus_helper based chip driver + * (mpq8785, pmbus_generic, ...). Probes the device so its identify + * hook has run and format[] is populated, then returns its + * driver_info. Returns NULL if no such regulator is bound at that + * address, if the device is not a pmbus regulator, or if + * CONFIG_DM_REGULATOR_PMBUS_HELPER is disabled. + * + * Lets pmbus_set_active() -- and thus the pmbus CLI and the board + * boot snapshots -- reuse the rich, VOUT_MODE detected driver_info of + * a DT bound generic / chip regulator when the device is selected by + * raw <bus>:<addr> (which has no chip-match registry entry and would + * otherwise fall back to blanket LINEAR16 / LINEAR11 decoding). + */ +const struct pmbus_driver_info *pmbus_regulator_info_by_addr(int bus_seq, + u8 addr); + +/* + * Status bit name decoding. + * + * Sparse mask to name table. pmbus_print_bits() emits only the bits + * that are SET in v, joined by |; if no bit is set, prints + * clean. Bits not in the table are silently ignored (RESERVED bits + * or chip specific bits handled by a separate per chip table). + */ +struct pmbus_bit { + u16 mask; + const char *name; +}; + +void pmbus_print_bits(u16 v, const struct pmbus_bit *tab); + +/* + * Per chip override entry. When a chip reuses a PMBus standard + * STATUS bit for a documented chip specific signal (for example MPS + * uses STATUS_WORD bit[12] = MFR_SPECIFIC as NVM_SUMMARY, bit[8] = + * UNKNOWN as WATCH_DOG, bit[0] = NONE_ABOVE as DRMOS_FAULT), the + * per chip driver supplies a sparse table of (reg, mask, name) + * triples and pmbus_print_status_bits() substitutes the chip name + * for the standard one when the bit is set. + * + * reg is one of PMBUS_STATUS_WORD / VOUT / IOUT / INPUT / + * TEMPERATURE / CML, so the same table can carry overrides for + * every status register on the chip in one place. Tables that omit + * a (reg, mask) leave the standard name in place. + * + * Override entries whose mask is NOT in the standard table are + * still printed (the chip can extend coverage beyond PMBus 1.x for + * vendor specific bits in standard registers). + * + * Tables are NULL terminated: the last entry has .name = NULL. + * Following the same convention U-Boot uses for struct udevice_id + * and other driver tables avoids the explicit-count foot-gun. + */ +struct pmbus_status_override { + u8 reg; + u16 mask; + const char *name; +}; + +/* + * Print the bit names of a STATUS_* register value. For each bit + * set in v, prefer a chip override matching (reg, mask) over the + * standard std table entry; if neither matches, the bit is + * silently skipped (RESERVED). If no bit is set at all, prints + * clean. Pass ovr = NULL to disable the override path. + */ +void pmbus_print_status_bits(u8 reg, u16 v, + const struct pmbus_bit *std, + const struct pmbus_status_override *ovr); + +/* + * Built in PMBus 1.3 standard bit tables (use these from per chip + * drivers and board diagnostics; vendor extensions go in chip local + * tables that the per chip driver passes alongside these). + */ +/* + * All tables below are NULL terminated (last entry has .name = NULL), + * so callers walk with for (t = tab; t && t->name; t++) and the + * helpers above need no count argument. + */ +extern const struct pmbus_bit pmbus_status_word_bits[]; +extern const struct pmbus_bit pmbus_status_vout_bits[]; +extern const struct pmbus_bit pmbus_status_iout_bits[]; +extern const struct pmbus_bit pmbus_status_input_bits[]; +extern const struct pmbus_bit pmbus_status_temp_bits[]; +extern const struct pmbus_bit pmbus_status_cml_bits[]; + +/* + * Active device tracking for the pmbus U-Boot CLI. + * + * The framework keeps one active PMBus device. It is selected by + * pmbus dev <bus>:<addr> (raw I2C tuple) and remembered across + * subcommands so subsequent invocations of pmbus telemetry, + * pmbus status, pmbus dump, etc. operate on the same chip + * without re-typing the address. + * + * pmbus_set_active() probes the chip's MFR_ID at the given address, + * looks the result up in the chip-match registry (populated by + * per chip drivers via pmbus_register_chip()), and caches the + * resulting struct pmbus_driver_info. Subcommands consult + * pmbus_active() to find the cached metadata. + */ +struct pmbus_active_dev { + bool valid; + int bus_seq; + u8 addr; + char vendor[PMBUS_VENDOR_NAME_MAX]; + char name[PMBUS_REGULATOR_NAME_MAX]; /* DT regulator-name when bound; "" otherwise */ + char mfr_id[PMBUS_MFR_STRING_MAX]; + char mfr_model[PMBUS_MFR_STRING_MAX]; + char mfr_revision[PMBUS_MFR_STRING_MAX]; + bool mfr_reverse; /* chip stores MFR strings LSB first */ + const struct pmbus_driver_info *info; +}; + +const struct pmbus_active_dev *pmbus_active(void); +int pmbus_active_get_i2c(struct udevice **i2c_dev); +int pmbus_set_active(int bus_seq, u8 addr); +void pmbus_clear_active(void); + +/* + * Per chip driver / board file registers a chip match so the + * framework can associate an MFR_ID prefix (read at probe time) + * with a vendor namespace ("mps", "lltc", "renesas", ...) and a + * pmbus_driver_info pointer. The first matching entry wins. + * + * mfr_id_reverse flags MPS style chips that store the MFR_ID + * string LSB first (chip returns "SPM" for the human string + * "MPS"); the framework reads the string in both orderings and + * matches against the prefix in the natural reading. + */ +struct pmbus_chip_match { + const char *mfr_id; + bool mfr_id_reverse; + const char *vendor; + const struct pmbus_driver_info *info; +}; + +int pmbus_register_chip(const struct pmbus_chip_match *match); + +/* + * Resolve a regulator-name (DT regulator-name property) to its + * (bus, addr) tuple by walking UCLASS_REGULATOR. Used by the + * pmbus dev <name> CLI alias so a chip bound through DT can be + * selected by its human readable rail name (e.g. "+0V8_VDD") + * instead of the i2c bus / address pair. Returns 0 on success + * (out parameters populated and the regulator probed), or a + * negative errno if no match is found or the bus / address cannot + * be derived. Available only when CONFIG_DM_REGULATOR is set. + */ +int pmbus_resolve_by_name(const char *name, int *bus_seq, u8 *addr); + +/* + * Vendor extension dispatcher. + * + * When the user types pmbus <vendor> <args...>, the framework + * looks up the registered handler for <vendor> and calls it with + * the argv tail (argv[0] = "<vendor>"). The handler operates on + * pmbus_active(), or returns CMD_RET_USAGE if the active device is + * not from this vendor. + * + * Per chip drivers register their vendor handler at init time. The + * MPS extension publishes pmbus mps last, pmbus mps clear last, + * and pmbus mps clear force. + */ +typedef int (*pmbus_vendor_handler_t)(struct cmd_tbl *cmdtp, int flag, + int argc, char *const argv[]); + +struct pmbus_vendor_op { + const char *vendor; + pmbus_vendor_handler_t handler; + const char *help; +}; + +int pmbus_register_vendor_handler(const struct pmbus_vendor_op *op); +const struct pmbus_vendor_op *pmbus_lookup_vendor(const char *vendor); +unsigned int pmbus_vendor_count(void); +const struct pmbus_vendor_op *pmbus_vendor_at(unsigned int i); + +#endif /* _PMBUS_H_ */ diff --git a/include/power/regulator.h b/include/power/regulator.h index 4011fb1d254..8d4d1450b90 100644 --- a/include/power/regulator.h +++ b/include/power/regulator.h @@ -316,6 +316,18 @@ int regulator_set_suspend_value(struct udevice *dev, int uV); int regulator_get_suspend_value(struct udevice *dev); /** + * regulator_set_value_clamp: set clamped microvoltage value of a given regulator + * + * @dev - pointer to the regulator device + * @min_uV - the minimum output value to set [micro Volts] + * @target_uV - the target output value to set [micro Volts] + * @max_uV - the maximum output value to set [micro Volts] + * Return: - 0 on success or -errno val if fails + */ +int regulator_set_value_clamp(struct udevice *dev, + int min_uV, int target_uV, int max_uV); + +/** * regulator_set_value_force: set the microvoltage value of a given regulator * without any min-,max condition check * @@ -359,9 +371,6 @@ int regulator_get_enable(struct udevice *dev); */ int regulator_set_enable(struct udevice *dev, bool enable); -#define regulator_enable(dev) regulator_set_enable(dev, true) -#define regulator_disable(dev) regulator_set_enable(dev, false) - /** * regulator_set_enable_if_allowed: set regulator enable state if allowed by * regulator @@ -550,6 +559,12 @@ static inline int regulator_get_suspend_value(struct udevice *dev) return -ENOSYS; } +static inline int regulator_set_value_clamp(struct udevice *dev, + int min_uV, int target_uV, int max_uV) +{ + return -ENOSYS; +} + static inline int regulator_set_value_force(struct udevice *dev, int uV) { return -ENOSYS; @@ -633,4 +648,7 @@ static inline int device_get_supply_regulator(struct udevice *dev, const char *s } #endif +#define regulator_enable(dev) regulator_set_enable_if_allowed(dev, true) +#define regulator_disable(dev) regulator_set_enable_if_allowed(dev, false) + #endif /* _INCLUDE_REGULATOR_H_ */ diff --git a/include/power/sandbox_pmic.h b/include/power/sandbox_pmic.h index 1dbd15b5235..50ef39b45e9 100644 --- a/include/power/sandbox_pmic.h +++ b/include/power/sandbox_pmic.h @@ -13,10 +13,10 @@ #define SANDBOX_OF_BUCK_PREFIX "buck" #define SANDBOX_BUCK_COUNT 3 -#define SANDBOX_LDO_COUNT 2 +#define SANDBOX_LDO_COUNT 3 /* * Sandbox PMIC registers: - * We have only 12 significant registers, but we alloc 16 for padding. + * We have only 15 significant registers, but we alloc 16 for padding. */ enum { SANDBOX_PMIC_REG_BUCK1_UV = 0, @@ -36,6 +36,10 @@ enum { SANDBOX_PMIC_REG_LDO2_UA, SANDBOX_PMIC_REG_LDO2_OM, + SANDBOX_PMIC_REG_LDO3_UV, + SANDBOX_PMIC_REG_LDO3_UA, + SANDBOX_PMIC_REG_LDO3_OM, + SANDBOX_PMIC_REG_COUNT = 16, }; @@ -94,6 +98,11 @@ enum { #define OUT_LDO2_UV_MAX 3950000 #define OUT_LDO2_UV_STEP 50000 +/* LDO3 Voltage: min: 0.75V, step: 50mV, max 3.95V */ +#define OUT_LDO3_UV_MIN 750000 +#define OUT_LDO3_UV_MAX 3950000 +#define OUT_LDO3_UV_STEP 50000 + /* register <-> value conversion */ #define REG2VAL(min, step, reg) ((min) + ((step) * (reg))) #define VAL2REG(min, step, val) (((val) - (min)) / (step)) @@ -116,6 +125,8 @@ enum { #define SANDBOX_LDO1_PLATNAME "VDD_EMMC_1.8V" #define SANDBOX_LDO2_DEVNAME "ldo2" #define SANDBOX_LDO2_PLATNAME "VDD_LCD_3.3V" +#define SANDBOX_LDO3_DEVNAME "ldo3" +#define SANDBOX_LDO3_PLATNAME "SUPPLY_1.8_3.3V" /* * Expected regulators setup after call of: diff --git a/include/power/spacemit_p1.h b/include/power/spacemit_p1.h new file mode 100644 index 00000000000..ef5a45e8cec --- /dev/null +++ b/include/power/spacemit_p1.h @@ -0,0 +1,163 @@ +/* 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_ALDO_DRIVER "p1_aldo" +#define P1_DLDO_DRIVER "p1_dldo" +#define P1_SWITCH_DRIVER "p1_switch" +#define P1_WDT_DRIVER "p1_wdt" + +#endif /* __SPACEMIT_P1_H_ */ diff --git a/include/soc/spacemit/k1-reset.h b/include/soc/spacemit/k1-reset.h new file mode 100644 index 00000000000..1dbfd6b1cb0 --- /dev/null +++ b/include/soc/spacemit/k1-reset.h @@ -0,0 +1,23 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * SpacemiT K1 reset driver — header interface. + * + * Copyright (C) 2026 RISCstar Ltd. + */ + +#ifndef _SOC_SPACEMIT_K1_RESET_H +#define _SOC_SPACEMIT_K1_RESET_H + +struct udevice; + +enum spacemit_k1_reset_syscon { + SPACEMIT_K1_RESET_MPMU, + SPACEMIT_K1_RESET_APMU, + SPACEMIT_K1_RESET_APBC, + SPACEMIT_K1_RESET_APBC2, +}; + +int spacemit_k1_reset_bind(struct udevice *parent, + enum spacemit_k1_reset_syscon syscon); + +#endif /* _SOC_SPACEMIT_K1_RESET_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__ */ diff --git a/include/spi.h b/include/spi.h index 7eaf0aa69b8..97096a77526 100644 --- a/include/spi.h +++ b/include/spi.h @@ -161,6 +161,7 @@ struct spi_slave { unsigned int max_write_size; void *memory_map; + u8 bits_per_word; u8 flags; #define SPI_XFER_BEGIN BIT(0) /* Assert CS before transfer */ #define SPI_XFER_END BIT(1) /* Deassert CS after transfer */ |
