Xiang Wang has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/31059
Change subject: src/mb/sifive/hifive-unleashed: initialize Gigabit Ethernet Controller ......................................................................
src/mb/sifive/hifive-unleashed: initialize Gigabit Ethernet Controller
Initialize the clock of Gigabit Ethernet Controller and reset the PHY.
Change-Id: I172dc518c9b48c122289bba5a65beece925410d4 Signed-off-by: Xiang Wang wxjstz@126.com --- M src/mainboard/sifive/hifive-unleashed/romstage.c M src/soc/sifive/fu540/clock.c 2 files changed, 61 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/59/31059/1
diff --git a/src/mainboard/sifive/hifive-unleashed/romstage.c b/src/mainboard/sifive/hifive-unleashed/romstage.c index 17d1aef..4eb7d55 100644 --- a/src/mainboard/sifive/hifive-unleashed/romstage.c +++ b/src/mainboard/sifive/hifive-unleashed/romstage.c @@ -27,6 +27,7 @@ #include <symbols.h> #include <cbfs.h> #include <soc/otp.h> +#include <soc/addressmap.h>
static void update_dtb(void) { @@ -52,6 +53,30 @@ OTHER_HLS(i)->fdt = (void *)dtb_target; }
+static void nsleep(long nsec) +{ + long setp = 600; + while(*(volatile long*)&nsec > 0) + *(volatile long*)&nsec -= setp; +} + +#define GPIO_REG(n) (*(uint32_t*)(FU540_GPIO + (n))) +#define GPIO_OUTPUT_EN 0x08 +#define GPIO_OUTPUT_VAL 0x0c + +static void phy_init(void) +{ +#define PHY_NRESET 0x1000 + nsleep(2000000); + __sync_fetch_and_or(&GPIO_REG(GPIO_OUTPUT_VAL), PHY_NRESET); + __sync_fetch_and_or(&GPIO_REG(GPIO_OUTPUT_EN), PHY_NRESET); + nsleep(100); + __sync_fetch_and_and(&GPIO_REG(GPIO_OUTPUT_VAL), ~PHY_NRESET); + nsleep(100); + __sync_fetch_and_or(&GPIO_REG(GPIO_OUTPUT_VAL), PHY_NRESET); + nsleep(15000000); +} + void main(void) { console_init(); @@ -71,6 +96,7 @@ uart_init(CONFIG_UART_FOR_CONSOLE);
sdram_init(); + phy_init();
cbmem_initialize_empty();
diff --git a/src/soc/sifive/fu540/clock.c b/src/soc/sifive/fu540/clock.c index 597b206..7194c3c 100644 --- a/src/soc/sifive/fu540/clock.c +++ b/src/soc/sifive/fu540/clock.c @@ -59,6 +59,8 @@
#define PRCI_DDRPLLCFG1_MASK (1u << 31)
+#define PRCI_GEMGXLPPLCFG1_MASK (1u << 31) + #define PRCI_CORECLKSEL_CORECLKSEL 1
#define PRCI_DEVICESRESET_DDR_CTRL_RST_N(x) (((x) & 0x1) << 0) @@ -141,6 +143,15 @@ .fse = 1, };
+static const struct pll_settings gemgxlpll_settings = { + .divr = 0, + .divf = 59, + .divq = 5, + .range = 4, + .bypass = 0, + .fse = 1, +}; + static void init_coreclk(void) { // switch coreclk to input reference frequency before modifying PLL @@ -168,6 +179,19 @@ write32(&prci->ddrpllcfg1, cfg1); }
+static void init_gemgxlclk(void) +{ + u32 cfg1 = read32(&prci->gemgxlpllcfg1); + clrbits_le32(&cfg1, PRCI_GEMGXLPPLCFG1_MASK); + write32(&prci->gemgxlpllcfg1,cfg1); + + configure_pll(&prci->gemgxlpllcfg0, &gemgxlpll_settings); + + setbits_le32(&cfg1, PRCI_GEMGXLPPLCFG1_MASK); + write32(&prci->gemgxlpllcfg1,cfg1); +} + + #define FU540_UART_DEVICES 2 #define FU540_UART_REG_DIV 0x18 #define FU540_UART_DIV_VAL 4 @@ -227,6 +251,17 @@ // device? for (int i = 0; i < 256; i++) asm volatile ("nop"); + + init_gemgxlclk(); + + write32(&prci->devicesresetreg, + PRCI_DEVICESRESET_DDR_CTRL_RST_N(1) | + PRCI_DEVICESRESET_DDR_AXI_RST_N(1) | + PRCI_DEVICESRESET_DDR_AHB_RST_N(1) | + PRCI_DEVICESRESET_DDR_PHY_RST_N(1) | + PRCI_DEVICESRESET_GEMGXL_RST_N(1)); + + asm volatile ("fence"); } #endif /* ENV_ROMSTAGE */