blob: 955bf4b936b239fa11189c6cc5a06415f8a00bfc [file] [log] [blame]
Mariusz Szafranskia4041332017-08-02 17:28:17 +02001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2016 - 2017 Intel Corp.
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; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
Kyösti Mälkki13f66502019-03-03 08:01:05 +020017#include <device/mmio.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +020018#include <device/pci_ops.h>
Mariusz Szafranskia4041332017-08-02 17:28:17 +020019#include <device/pci_def.h>
20#include <fsp/soc_binding.h>
21#include <commonlib/helpers.h>
22
23#include <soc/bootblock.h>
24#include <soc/gpio_defs.h>
25#include <soc/uart.h>
26
27static uint16_t legacy_uart_ioadr_tab[] = {0x3F8, 0x2F8, 0x3E8, 0x2E8};
28
29#define ELEM_OF_UART_TAB ARRAY_SIZE(legacy_uart_ioadr_tab)
30
31static void pci_early_hsuart_device_probe(u8 bus, u8 dev, u8 func,
32 u32 mmio_base)
33{
34 register uint16_t reg16;
Elyes HAOUAS68c851b2018-06-12 22:06:09 +020035 pci_devfn_t uart_dev = PCI_DEV(bus, dev, func);
Mariusz Szafranskia4041332017-08-02 17:28:17 +020036
37 /* We're using MMIO for HSUARTs. This section is needed for logging
38 * from FSP only
39 */
40 /* Decode IOBASE at IOBA (BAR0). */
41 reg16 = pci_read_config16(uart_dev, PCI_BASE_ADDRESS_0) | mmio_base;
42 pci_write_config16(uart_dev, PCI_BASE_ADDRESS_0, reg16);
43
44#if (IS_ENABLED(CONFIG_NON_LEGACY_UART_MODE))
45 /* Decode MMIO at MEMBA (BAR1) */
46 pci_write_config32(uart_dev, PCI_BASE_ADDRESS_1,
47 CONFIG_CONSOLE_UART_BASE_ADDRESS +
48 SIZE_OF_HSUART_RES * func);
49#endif
50
51 /* Enable memory/io space and allow to initiate
52 * a transaction as a master
53 */
54 pci_write_config16(uart_dev, PCI_COMMAND,
55 pci_read_config16(uart_dev, PCI_COMMAND) |
56#if (IS_ENABLED(CONFIG_NON_LEGACY_UART_MODE))
57 PCI_COMMAND_MEMORY |
58#endif
59 PCI_COMMAND_MASTER | PCI_COMMAND_IO);
60
61#if (IS_ENABLED(CONFIG_CONSOLE_SERIAL_230400))
62 /* Change the highest speed to 230400 */
63 uint32_t *psr_reg =
64 (uint32_t *)(CONFIG_CONSOLE_UART_BASE_ADDRESS +
65 SIZE_OF_HSUART_RES * func + PSR_OFFSET);
66 *psr_reg >>= 1;
67#endif
Mariusz Szafranskia4041332017-08-02 17:28:17 +020068}
69
70static void early_config_gpio(void)
71{
72 uint32_t reg32;
73
74 // HSUART0:
75 // UART0_RXD
76 reg32 = read32(
77 (void *)PCH_PCR_ADDRESS(PID_GPIOCOM1, R_PAD_CFG_DW0_UART0_RXD));
78 if (((reg32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE) !=
79 V_PCH_GPIO_PAD_MODE_NAT_1) {
80 reg32 &= ~B_PCH_GPIO_PAD_MODE;
81 reg32 |= (UINT32)(V_PCH_GPIO_PAD_MODE_NAT_1
82 << N_PCH_GPIO_PAD_MODE);
83 write32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
84 R_PAD_CFG_DW0_UART0_RXD),
85 reg32);
86 }
87 // UART0_TXD
88 reg32 = read32(
89 (void *)PCH_PCR_ADDRESS(PID_GPIOCOM1, R_PAD_CFG_DW0_UART0_TXD));
90 if (((reg32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE) !=
91 V_PCH_GPIO_PAD_MODE_NAT_1) {
92 reg32 &= ~B_PCH_GPIO_PAD_MODE;
93 reg32 |= (UINT32)(V_PCH_GPIO_PAD_MODE_NAT_1
94 << N_PCH_GPIO_PAD_MODE);
95 write32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
96 R_PAD_CFG_DW0_UART0_TXD),
97 reg32);
98 }
99 // UART0_CTS
100 reg32 = read32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
101 R_PAD_CFG_DW0_SMB3_CLTT_CLK));
102 if (((reg32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE) !=
103 V_PCH_GPIO_PAD_MODE_NAT_2) {
104 reg32 &= ~B_PCH_GPIO_PAD_MODE;
105 reg32 |= (UINT32)(V_PCH_GPIO_PAD_MODE_NAT_2
106 << N_PCH_GPIO_PAD_MODE);
107 write32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
108 R_PAD_CFG_DW0_SMB3_CLTT_CLK),
109 reg32);
110 }
111 // UART0_RTS
112 reg32 = read32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
113 R_PAD_CFG_DW0_PCIE_CLKREQ5_N));
114 if (((reg32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE) !=
115 V_PCH_GPIO_PAD_MODE_NAT_3) {
116 reg32 &= ~B_PCH_GPIO_PAD_MODE;
117 reg32 |= (UINT32)(V_PCH_GPIO_PAD_MODE_NAT_3
118 << N_PCH_GPIO_PAD_MODE);
119 write32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
120 R_PAD_CFG_DW0_PCIE_CLKREQ5_N),
121 reg32);
122 }
123
124 // HSUART1:
125 // UART1_RXD
126 reg32 = read32(
127 (void *)PCH_PCR_ADDRESS(PID_GPIOCOM1, R_PAD_CFG_DW0_UART1_RXD));
128 if (((reg32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE) !=
129 V_PCH_GPIO_PAD_MODE_NAT_1) {
130 reg32 &= ~B_PCH_GPIO_PAD_MODE;
131 reg32 |= (UINT32)(V_PCH_GPIO_PAD_MODE_NAT_1
132 << N_PCH_GPIO_PAD_MODE);
133 write32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
134 R_PAD_CFG_DW0_UART1_RXD),
135 reg32);
136 }
137 // UART1_TXD
138 reg32 = read32(
139 (void *)PCH_PCR_ADDRESS(PID_GPIOCOM1, R_PAD_CFG_DW0_UART1_TXD));
140 if (((reg32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE) !=
141 V_PCH_GPIO_PAD_MODE_NAT_1) {
142 reg32 &= ~B_PCH_GPIO_PAD_MODE;
143 reg32 |= (UINT32)(V_PCH_GPIO_PAD_MODE_NAT_1
144 << N_PCH_GPIO_PAD_MODE);
145 write32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
146 R_PAD_CFG_DW0_UART1_TXD),
147 reg32);
148 }
149 // UART1_CTS
150 reg32 = read32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
151 R_PAD_CFG_DW0_SATA1_SDOUT));
152 if (((reg32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE) !=
153 V_PCH_GPIO_PAD_MODE_NAT_1) {
154 reg32 &= ~B_PCH_GPIO_PAD_MODE;
155 reg32 |= (UINT32)(V_PCH_GPIO_PAD_MODE_NAT_1
156 << N_PCH_GPIO_PAD_MODE);
157 write32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
158 R_PAD_CFG_DW0_SATA1_SDOUT),
159 reg32);
160 }
161 // UART1_RTS
162 reg32 = read32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
163 R_PAD_CFG_DW0_SATA0_SDOUT));
164 if (((reg32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE) !=
165 V_PCH_GPIO_PAD_MODE_NAT_1) {
166 reg32 &= ~B_PCH_GPIO_PAD_MODE;
167 reg32 |= (UINT32)(V_PCH_GPIO_PAD_MODE_NAT_1
168 << N_PCH_GPIO_PAD_MODE);
169 write32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
170 R_PAD_CFG_DW0_SATA0_SDOUT),
171 reg32);
172 }
173}
174
175void early_uart_init(void)
176{
177 register int i;
178
Jonathan Neuschäfer5268b762018-02-12 12:24:25 +0100179 /* Check: do we have enough elements to init. ? */
Julien Viard de Galbert26436fb2018-01-25 10:29:42 +0100180 BUILD_BUG_ON(DENVERTON_UARTS_TO_INI > ELEM_OF_UART_TAB);
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200181
182 /* HSUART(B0:D26:0-1) GPIO init. */
183 early_config_gpio();
184
Julien Viard de Galbert26436fb2018-01-25 10:29:42 +0100185 for (i = DENVERTON_UARTS_TO_INI - 1; i >= 0; --i) {
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200186 pci_early_hsuart_device_probe(0, CONFIG_HSUART_DEV, i,
187 legacy_uart_ioadr_tab[i]);
188 }
189}