blob: 7890ee02113e37e898bff7b2cf628586c2c1f57c [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>
Elyes HAOUASe39db682019-05-15 21:12:31 +020027#include <types.h>
Werner Zeh42065f82019-05-02 12:45:21 +020028
29#define SD_CAP_BYP 0x810
30#define SD_CAP_BYP_EN 0x5A
31#define SD_CAP_BYP_REG1 0x814
Mario Scheithauer66038c82018-09-25 17:26:32 +020032
33void variant_mainboard_final(void)
34{
35 struct device *dev;
36 uint16_t cmd = 0;
37
38 /* Set Master Enable for on-board PCI device. */
39 dev = dev_find_device(PCI_VENDOR_ID_SIEMENS, 0x403e, 0);
40 if (dev) {
41 cmd = pci_read_config16(dev, PCI_COMMAND);
42 cmd |= PCI_COMMAND_MASTER;
43 pci_write_config16(dev, PCI_COMMAND, cmd);
44 }
Werner Zeh42065f82019-05-02 12:45:21 +020045
46 /* Reduce SD-Card speed to DDR50 because of PCB constraints. */
47 dev = pcidev_path_on_root(PCH_DEVFN_SDCARD);
48 if (dev) {
49 uint32_t reg;
50 struct resource *res = find_resource(dev, PCI_BASE_ADDRESS_0);
51 if (!res)
52 return;
53
54 write32(res2mmio(res, SD_CAP_BYP, 0), SD_CAP_BYP_EN);
55 reg = read32(res2mmio(res, SD_CAP_BYP_REG1, 0));
56 /* Disable HS400 and SDR104, keep SDR50 and DDR50 modes. */
57 reg &= ~0x20005800;
58 write32(res2mmio(res, SD_CAP_BYP_REG1, 0), reg);
59 }
Mario Scheithauer66038c82018-09-25 17:26:32 +020060}
61
62static void wait_for_legacy_dev(void *unused)
63{
64 uint32_t legacy_delay, us_since_boot;
65 struct stopwatch sw;
66
67 /* Open main hwinfo block. */
68 if (hwilib_find_blocks("hwinfo.hex") != CB_SUCCESS)
69 return;
70
71 /* Get legacy delay parameter from hwinfo. */
72 if (hwilib_get_field(LegacyDelay, (uint8_t *) &legacy_delay,
73 sizeof(legacy_delay)) != sizeof(legacy_delay))
74 return;
75
76 us_since_boot = get_us_since_boot();
77 /* No need to wait if the time since boot is already long enough.*/
78 if (us_since_boot > legacy_delay)
79 return;
80 stopwatch_init_msecs_expire(&sw, (legacy_delay - us_since_boot) / 1000);
81 printk(BIOS_NOTICE, "Wait remaining %d of %d us for legacy devices...",
82 legacy_delay - us_since_boot, legacy_delay);
83 stopwatch_wait_until_expired(&sw);
84 printk(BIOS_NOTICE, "done!\n");
85}
86
87BOOT_STATE_INIT_ENTRY(BS_DEV_ENUMERATE, BS_ON_ENTRY, wait_for_legacy_dev, NULL);