blob: 06b2a2fc92593b1a17f85e738388e4b85bad9d78 [file] [log] [blame]
Mario Scheithauer5716b4c2018-11-14 13:27:05 +01001/*
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>
Mario Scheithauera94a1532018-11-28 09:13:28 +010018#include <device/pci_def.h>
Mario Scheithauer5716b4c2018-11-14 13:27:05 +010019#include <device/pci_ids.h>
20#include <device/pci_ops.h>
21#include <gpio.h>
22#include <hwilib.h>
23#include <intelblocks/lpc_lib.h>
24#include <intelblocks/pcr.h>
25#include <soc/pcr_ids.h>
26#include <timer.h>
27#include <timestamp.h>
28#include <baseboard/variants.h>
29#include <variant/ptn3460.h>
30
31#define TX_DWORD3 0xa8c
32
33void variant_mainboard_final(void)
34{
35 int status;
36 struct device *dev = NULL;
Mario Scheithauera94a1532018-11-28 09:13:28 +010037 uint16_t cmd;
Mario Scheithauer5716b4c2018-11-14 13:27:05 +010038
39 /*
40 * Set up the DP2LVDS converter.
41 * ptn3460_init() may only be executed after i2c bus init.
42 */
43 status = ptn3460_init("hwinfo.hex");
44 if (status)
45 printk(BIOS_ERR, "LCD: Set up PTN with status 0x%x\n", status);
46 else
47 printk(BIOS_INFO, "LCD: Set up PTN was successful.\n");
48
49 /*
50 * PIR6 register mapping for PCIe root ports
51 * INTA#->PIRQB#, INTB#->PIRQC#, INTC#->PIRQD#, INTD#-> PIRQA#
52 */
53 pcr_write16(PID_ITSS, 0x314c, 0x0321);
54
55 /* Disable clock outputs 1-5 (CLKOUT) for XIO2001 PCIe to PCI Bridge. */
56 dev = dev_find_device(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_XIO2001, 0);
57 if (dev)
58 pci_write_config8(dev, 0xd8, 0x3e);
59
60 /* Enable CLKRUN_EN for power gating LPC */
61 lpc_enable_pci_clk_cntl();
62
63 /*
64 * Enable LPC PCE (Power Control Enable) by setting IOSF-SB port 0xD2
65 * offset 0x341D bit3 and bit0.
66 * Enable LPC CCE (Clock Control Enable) by setting IOSF-SB port 0xD2
67 * offset 0x341C bit [3:0].
68 */
69 pcr_or32(PID_LPC, PCR_LPC_PRC, (PCR_LPC_CCE_EN | PCR_LPC_PCE_EN));
70
71 /*
72 * Correct the SATA transmit signal via the High Speed I/O Transmit
73 * Control Register 3.
74 * Bit [23:16] set the output voltage swing for TX line.
75 * The value 0x4a sets the swing level to 0.58 V.
76 */
77 pcr_rmw32(PID_MODPHY, TX_DWORD3, (0x00 << 16), (0x4a << 16));
Mario Scheithauera94a1532018-11-28 09:13:28 +010078
79 /* Set Master Enable for on-board PCI device. */
80 dev = dev_find_device(PCI_VENDOR_ID_SIEMENS, 0x403e, 0);
81 if (dev) {
82 cmd = pci_read_config16(dev, PCI_COMMAND);
83 cmd |= PCI_COMMAND_MASTER;
84 pci_write_config16(dev, PCI_COMMAND, cmd);
85 }
Mario Scheithauer5716b4c2018-11-14 13:27:05 +010086}
87
88static void wait_for_legacy_dev(void *unused)
89{
90 uint32_t legacy_delay, us_since_boot;
91 struct stopwatch sw;
92
93 /* Open main hwinfo block. */
94 if (hwilib_find_blocks("hwinfo.hex") != CB_SUCCESS)
95 return;
96
97 /* Get legacy delay parameter from hwinfo. */
98 if (hwilib_get_field(LegacyDelay, (uint8_t *) &legacy_delay,
99 sizeof(legacy_delay)) != sizeof(legacy_delay))
100 return;
101
102 us_since_boot = get_us_since_boot();
103 /* No need to wait if the time since boot is already long enough.*/
104 if (us_since_boot > legacy_delay)
105 return;
106 stopwatch_init_msecs_expire(&sw, (legacy_delay - us_since_boot) / 1000);
107 printk(BIOS_NOTICE, "Wait remaining %d of %d us for legacy devices...",
108 legacy_delay - us_since_boot, legacy_delay);
109 stopwatch_wait_until_expired(&sw);
110 printk(BIOS_NOTICE, "done!\n");
111}
112
113static void finalize_boot(void *unused)
114{
115 /* Set coreboot ready LED. */
116 gpio_output(CNV_RGI_DT, 1);
117}
118
119BOOT_STATE_INIT_ENTRY(BS_DEV_ENUMERATE, BS_ON_ENTRY, wait_for_legacy_dev, NULL);
120BOOT_STATE_INIT_ENTRY(BS_PAYLOAD_BOOT, BS_ON_ENTRY, finalize_boot, NULL);