mb/system76/cml-u/dt: Make use of chipset devicetree
[coreboot.git] / src / soc / intel / apollolake / xdci.c
blob086bbfd458858ca484cb629b9e27f70b6db27311
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <device/mmio.h>
4 #include <console/console.h>
5 #include <device/device.h>
6 #include <device/pci.h>
7 #include <intelblocks/xdci.h>
8 #include <soc/pci_devs.h>
9 #include <timer.h>
11 #define DUAL_ROLE_CFG0 0x80d8
12 # define DRD_CONFIG_MASK (0x3 << 0)
13 # define DRD_CONFIG_DYNAMIC (0x0 << 0)
14 # define DRD_CONFIG_HOST (0x1 << 0)
15 # define DRD_CONFIG_DEVICE (0x2 << 0)
16 # define SW_VBUS_VALID_MASK (1 << 24)
17 # define SW_VBUS_DEASSERT_VALID (0 << 24)
18 # define SW_VBUS_ASSERT_VALID (1 << 24)
19 # define SW_IDPIN_EN_MASK (1 << 21)
20 # define SW_IDPIN_DIS (0 << 21)
21 # define SW_IDPIN_EN (1 << 21)
22 # define SW_IDPIN_MASK (1 << 20)
23 # define SW_IDPIN_HOST (0 << 20)
24 # define SW_IDPIN_DEVICE (1 << 20)
25 #define DUAL_ROLE_CFG1 0x80dc
26 # define DRD_MODE_MASK (1 << 29)
27 # define DRD_MODE_DEVICE (0 << 29)
28 # define DRD_MODE_HOST (1 << 29)
30 static void configure_host_mode_port0(struct device *dev)
32 uint32_t *cfg0;
33 uint32_t *cfg1;
34 const struct resource *res;
35 uint32_t reg;
36 struct stopwatch sw;
39 * Only default to host mode if the xdci device is present and
40 * enabled. If it's disabled assume the switch was already done
41 * in FSP.
43 if (!dev->enabled)
44 return;
46 printk(BIOS_INFO, "Putting port 0 into host mode.\n");
48 res = find_resource(dev, PCI_BASE_ADDRESS_0);
50 cfg0 = (void *)(uintptr_t)(res->base + DUAL_ROLE_CFG0);
51 cfg1 = (void *)(uintptr_t)(res->base + DUAL_ROLE_CFG1);
53 reg = read32(cfg0);
54 reg &= ~(DRD_CONFIG_MASK | SW_IDPIN_EN_MASK | SW_IDPIN_MASK);
55 reg &= ~(SW_VBUS_VALID_MASK);
56 reg |= DRD_CONFIG_DYNAMIC | SW_IDPIN_EN | SW_IDPIN_HOST;
57 reg |= SW_VBUS_DEASSERT_VALID;
58 write32(cfg0, reg);
60 stopwatch_init_msecs_expire(&sw, 10);
62 /* Wait for the host mode status bit. */
63 while ((read32(cfg1) & DRD_MODE_MASK) != DRD_MODE_HOST) {
64 if (stopwatch_expired(&sw)) {
65 printk(BIOS_INFO, "Timed out waiting for host mode.\n");
66 break;
70 printk(BIOS_INFO, "XDCI port 0 host switch over took %lld ms\n",
71 stopwatch_duration_msecs(&sw));
74 void soc_xdci_init(struct device *dev)
76 configure_host_mode_port0(dev);