summaryrefslogtreecommitdiffstats
path: root/sys/dev/fdt/amlpciephy.c
diff options
context:
space:
mode:
authorkettenis <kettenis@openbsd.org>2020-12-27 19:32:29 +0000
committerkettenis <kettenis@openbsd.org>2020-12-27 19:32:29 +0000
commita2199a24dedfcb4f088134cb58bb72823fa20754 (patch)
treeff259d72bc204044217a7e42eb84ef549f62d675 /sys/dev/fdt/amlpciephy.c
parentAdd PCIe power domain. (diff)
downloadwireguard-openbsd-a2199a24dedfcb4f088134cb58bb72823fa20754.tar.xz
wireguard-openbsd-a2199a24dedfcb4f088134cb58bb72823fa20754.zip
Add PCIe support.
Diffstat (limited to 'sys/dev/fdt/amlpciephy.c')
-rw-r--r--sys/dev/fdt/amlpciephy.c116
1 files changed, 68 insertions, 48 deletions
diff --git a/sys/dev/fdt/amlpciephy.c b/sys/dev/fdt/amlpciephy.c
index b8db93599e9..51686d2f7a7 100644
--- a/sys/dev/fdt/amlpciephy.c
+++ b/sys/dev/fdt/amlpciephy.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: amlpciephy.c,v 1.2 2020/03/26 12:58:18 kettenis Exp $ */
+/* $OpenBSD: amlpciephy.c,v 1.3 2020/12/27 19:32:29 kettenis Exp $ */
/*
* Copyright (c) 2019 Mark Kettenis <kettenis@openbsd.org>
*
@@ -29,6 +29,9 @@
#include <dev/ofw/fdt.h>
#define PHY_R0 0x00
+#define PHY_R0_PCIE_POWER_MASK (0x1f << 0)
+#define PHY_R0_PCIE_POWER_ON (0x1c << 0)
+#define PHY_R0_PCIE_POWER_OFF (0x1d << 0)
#define PHY_R0_MODE_MASK (0x3 << 5)
#define PHY_R0_MODE_USB3 (0x3 << 5)
#define PHY_R4 0x10
@@ -113,57 +116,74 @@ amlpciephy_enable(void *cookie, uint32_t *cells)
uint32_t type = cells[0];
uint32_t reg;
- /*
- * Hardware can be switched between PCIe 2.0 and USB 3.0 mode,
- * but we only support USB for now.
- */
- if (type != PHY_TYPE_USB3)
+ /* Hardware can be switched between PCIe 2.0 and USB 3.0 mode. */
+ if (type != PHY_TYPE_PCIE && type != PHY_TYPE_USB3)
return -1;
clock_set_assigned(node);
clock_enable_all(node);
- reset_assert_all(node);
- delay(10);
- reset_deassert_all(node);
-
- /* Switch to USB 3.0 mode. */
- reg = HREAD4(sc, PHY_R0);
- reg &= ~PHY_R0_MODE_MASK;
- reg |= PHY_R0_MODE_USB3;
- HWRITE4(sc, PHY_R0, reg);
-
- /* Workaround for SuperSpeed PHY suspend bug. */
- reg = amlpciephy_read(sc, 0x102d);
- reg |= (1 << 7);
- amlpciephy_write(sc, 0x102d, reg);
-
- reg = amlpciephy_read(sc, 0x1010);
- reg &= ~0xff0;
- reg |= 0x10;
- amlpciephy_write(sc, 0x1010, reg);
-
- /* Rx equalization magic. */
- reg = amlpciephy_read(sc, 0x1006);
- reg &= (1 << 6);
- reg |= (1 << 7);
- reg &= ~(0x7 << 8);
- reg |= (0x3 << 8);
- reg |= (1 << 11);
- amlpciephy_write(sc, 0x1006, reg);
-
- /* Tx equalization magic. */
- reg = amlpciephy_read(sc, 0x1002);
- reg &= ~0x3f80;
- reg |= (0x16 << 7);
- reg &= ~0x7f;
- reg |= (0x7f | (1 << 14));
- amlpciephy_write(sc, 0x1002, reg);
-
- /* MPLL loop magic. */
- reg = amlpciephy_read(sc, 0x30);
- reg &= ~(0xf << 4);
- reg |= (8 << 4);
- amlpciephy_write(sc, 0x30, reg);
+
+ switch (type) {
+ case PHY_TYPE_PCIE:
+ /* Power on. */
+ reg = HREAD4(sc, PHY_R0);
+ printf("R0: 0x%x\n", reg);
+ reg &= ~PHY_R0_PCIE_POWER_MASK;
+ reg |= PHY_R0_PCIE_POWER_ON;
+ HWRITE4(sc, PHY_R0, reg);
+
+ reset_assert_all(node);
+ delay(500);
+ reset_deassert_all(node);
+ delay(500);
+
+ break;
+ case PHY_TYPE_USB3:
+ reset_assert_all(node);
+ delay(10);
+ reset_deassert_all(node);
+
+ /* Switch to USB 3.0 mode. */
+ reg = HREAD4(sc, PHY_R0);
+ reg &= ~PHY_R0_MODE_MASK;
+ reg |= PHY_R0_MODE_USB3;
+ HWRITE4(sc, PHY_R0, reg);
+
+ /* Workaround for SuperSpeed PHY suspend bug. */
+ reg = amlpciephy_read(sc, 0x102d);
+ reg |= (1 << 7);
+ amlpciephy_write(sc, 0x102d, reg);
+
+ reg = amlpciephy_read(sc, 0x1010);
+ reg &= ~0xff0;
+ reg |= 0x10;
+ amlpciephy_write(sc, 0x1010, reg);
+
+ /* Rx equalization magic. */
+ reg = amlpciephy_read(sc, 0x1006);
+ reg &= (1 << 6);
+ reg |= (1 << 7);
+ reg &= ~(0x7 << 8);
+ reg |= (0x3 << 8);
+ reg |= (1 << 11);
+ amlpciephy_write(sc, 0x1006, reg);
+
+ /* Tx equalization magic. */
+ reg = amlpciephy_read(sc, 0x1002);
+ reg &= ~0x3f80;
+ reg |= (0x16 << 7);
+ reg &= ~0x7f;
+ reg |= (0x7f | (1 << 14));
+ amlpciephy_write(sc, 0x1002, reg);
+
+ /* MPLL loop magic. */
+ reg = amlpciephy_read(sc, 0x30);
+ reg &= ~(0xf << 4);
+ reg |= (8 << 4);
+ amlpciephy_write(sc, 0x30, reg);
+
+ break;
+ }
return 0;
}