Xiang Wang has uploaded this change for review.

View Change

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 */


To view, visit change 31059. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: coreboot
Gerrit-Branch: master
Gerrit-Change-Id: I172dc518c9b48c122289bba5a65beece925410d4
Gerrit-Change-Number: 31059
Gerrit-PatchSet: 1
Gerrit-Owner: Xiang Wang <wxjstz@126.com>
Gerrit-MessageType: newchange