diff --git a/arch/riscv/include/asm/arch-fu740/eeprom.h b/arch/riscv/include/asm/arch-fu740/eeprom.h new file mode 100644 index 00000000000..aaa02c6d2bb --- /dev/null +++ b/arch/riscv/include/asm/arch-fu740/eeprom.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) 2024 SiFive, Inc. + * + * Zong Li + */ + +#ifndef _ASM_RISCV_EEPROM_H +#define _ASM_RISCV_EEPROM_H + +#define PCB_REVISION_REV3 0x3 + +u8 get_pcb_revision_from_eeprom(void); + +#endif /* _ASM_RISCV_EEPROM_H */ diff --git a/board/sifive/unmatched/spl.c b/board/sifive/unmatched/spl.c index 7c0beedc083..e69bed9d99d 100644 --- a/board/sifive/unmatched/spl.c +++ b/board/sifive/unmatched/spl.c @@ -15,6 +15,29 @@ #include #include #include +#include +#include + +struct pwm_sifive_regs { + unsigned int cfg; /* PWM configuration register */ + unsigned int pad0; /* Reserved */ + unsigned int cnt; /* PWM count register */ + unsigned int pad1; /* Reserved */ + unsigned int pwms; /* Scaled PWM count register */ + unsigned int pad2; /* Reserved */ + unsigned int pad3; /* Reserved */ + unsigned int pad4; /* Reserved */ + unsigned int cmp0; /* PWM 0 compare register */ + unsigned int cmp1; /* PWM 1 compare register */ + unsigned int cmp2; /* PWM 2 compare register */ + unsigned int cmp3; /* PWM 3 compare register */ +}; + +#define PWM0_BASE 0x10020000 +#define PWM1_BASE 0x10021000 +#define PWM_CFG_INIT 0x1000 +#define PWM_CMP_ENABLE_VAL 0x0 +#define PWM_CMP_DISABLE_VAL 0xffff #define UBRDG_RESET SIFIVE_GENERIC_GPIO_NR(0, 7) #define ULPI_RESET SIFIVE_GENERIC_GPIO_NR(0, 9) @@ -26,6 +49,33 @@ #define MODE_SELECT_SD 0xb #define MODE_SELECT_MASK GENMASK(3, 0) +void spl_pwm_device_init(void) +{ + struct pwm_sifive_regs *pwm0, *pwm1; + + pwm0 = (struct pwm_sifive_regs *)PWM0_BASE; + pwm1 = (struct pwm_sifive_regs *)PWM1_BASE; + writel(PWM_CMP_DISABLE_VAL, (void *)&pwm0->cmp0); + + /* Set the 3-color PWM LEDs to yellow in SPL */ + writel(PWM_CMP_ENABLE_VAL, (void *)&pwm0->cmp1); + writel(PWM_CMP_ENABLE_VAL, (void *)&pwm0->cmp2); + writel(PWM_CMP_DISABLE_VAL, (void *)&pwm0->cmp3); + writel(PWM_CFG_INIT, (void *)&pwm0->cfg); + + /* Turn on all the fans, (J21), (J23) and (J24), on the unmatched board */ + /* The SoC fan(J21) on the rev3 board cannot be controlled by PWM_COMP0, + * so here sets the initial value of PWM_COMP0 as DISABLE */ + if (get_pcb_revision_from_eeprom() == PCB_REVISION_REV3) + writel(PWM_CMP_DISABLE_VAL, (void *)&pwm1->cmp1); + else + writel(PWM_CMP_ENABLE_VAL, (void *)&pwm1->cmp1); + + writel(PWM_CMP_ENABLE_VAL, (void *)&pwm1->cmp2); + writel(PWM_CMP_ENABLE_VAL, (void *)&pwm1->cmp3); + writel(PWM_CFG_INIT, (void *)&pwm1->cfg); +} + static inline int spl_reset_device_by_gpio(const char *label, int pin, int low_width) { int ret; @@ -90,6 +140,8 @@ int spl_board_init_f(void) goto end; } + spl_pwm_device_init(); + ret = spl_gemgxl_init(); if (ret) { debug("Gigabit ethernet PHY (VSC8541) init failed: %d\n", ret);