blob: f52091bced5001f6f1a1e4e64252f7e639645e7e [file] [log] [blame]
Mario Scheithauer66038c82018-09-25 17:26:32 +02001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2018 Siemens AG
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <bootstate.h>
17#include <console/console.h>
18#include <device/pci_def.h>
19#include <device/pci_ids.h>
20#include <device/pci_ops.h>
21#include <hwilib.h>
22#include <intelblocks/lpc_lib.h>
23#include <timer.h>
24#include <timestamp.h>
25#include <baseboard/variants.h>
Werner Zeh42065f82019-05-02 12:45:21 +020026#include <soc/pci_devs.h>
27
28#define SD_CAP_BYP 0x810
29#define SD_CAP_BYP_EN 0x5A
30#define SD_CAP_BYP_REG1 0x814
Mario Scheithauer66038c82018-09-25 17:26:32 +020031
32void variant_mainboard_final(void)
33{
34 struct device *dev;
35 uint16_t cmd = 0;
36
37 /* Set Master Enable for on-board PCI device. */
38 dev = dev_find_device(PCI_VENDOR_ID_SIEMENS, 0x403e, 0);
39 if (dev) {
40 cmd = pci_read_config16(dev, PCI_COMMAND);
41 cmd |= PCI_COMMAND_MASTER;
42 pci_write_config16(dev, PCI_COMMAND, cmd);
43 }
Werner Zeh42065f82019-05-02 12:45:21 +020044
45 /* Reduce SD-Card speed to DDR50 because of PCB constraints. */
46 dev = pcidev_path_on_root(PCH_DEVFN_SDCARD);
47 if (dev) {
48 uint32_t reg;
49 struct resource *res = find_resource(dev, PCI_BASE_ADDRESS_0);
50 if (!res)
51 return;
52
53 write32(res2mmio(res, SD_CAP_BYP, 0), SD_CAP_BYP_EN);
54 reg = read32(res2mmio(res, SD_CAP_BYP_REG1, 0));
55 /* Disable HS400 and SDR104, keep SDR50 and DDR50 modes. */
56 reg &= ~0x20005800;
57 write32(res2mmio(res, SD_CAP_BYP_REG1, 0), reg);
58 }
Mario Scheithauer66038c82018-09-25 17:26:32 +020059}
60
61static void wait_for_legacy_dev(void *unused)
62{
63 uint32_t legacy_delay, us_since_boot;
64 struct stopwatch sw;
65
66 /* Open main hwinfo block. */
67 if (hwilib_find_blocks("hwinfo.hex") != CB_SUCCESS)
68 return;
69
70 /* Get legacy delay parameter from hwinfo. */
71 if (hwilib_get_field(LegacyDelay, (uint8_t *) &legacy_delay,
72 sizeof(legacy_delay)) != sizeof(legacy_delay))
73 return;
74
75 us_since_boot = get_us_since_boot();
76 /* No need to wait if the time since boot is already long enough.*/
77 if (us_since_boot > legacy_delay)
78 return;
79 stopwatch_init_msecs_expire(&sw, (legacy_delay - us_since_boot) / 1000);
80 printk(BIOS_NOTICE, "Wait remaining %d of %d us for legacy devices...",
81 legacy_delay - us_since_boot, legacy_delay);
82 stopwatch_wait_until_expired(&sw);
83 printk(BIOS_NOTICE, "done!\n");
84}
85
86BOOT_STATE_INIT_ENTRY(BS_DEV_ENUMERATE, BS_ON_ENTRY, wait_for_legacy_dev, NULL);