blob: 7514feebf82cc68adf271cc1f961be336be078c4 [file] [log] [blame]
Patrick Georgiac959032020-05-05 22:49:26 +02001/* SPDX-License-Identifier: GPL-2.0-or-later */
Mariusz Szafranskia4041332017-08-02 17:28:17 +02002
Kyösti Mälkki13f66502019-03-03 08:01:05 +02003#include <device/mmio.h>
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +02004#include <device/pci_ops.h>
Mariusz Szafranskia4041332017-08-02 17:28:17 +02005#include <device/pci_def.h>
6#include <fsp/soc_binding.h>
7#include <commonlib/helpers.h>
8
9#include <soc/bootblock.h>
10#include <soc/gpio_defs.h>
11#include <soc/uart.h>
12
13static uint16_t legacy_uart_ioadr_tab[] = {0x3F8, 0x2F8, 0x3E8, 0x2E8};
14
15#define ELEM_OF_UART_TAB ARRAY_SIZE(legacy_uart_ioadr_tab)
16
17static void pci_early_hsuart_device_probe(u8 bus, u8 dev, u8 func,
18 u32 mmio_base)
19{
20 register uint16_t reg16;
Elyes HAOUAS68c851b2018-06-12 22:06:09 +020021 pci_devfn_t uart_dev = PCI_DEV(bus, dev, func);
Mariusz Szafranskia4041332017-08-02 17:28:17 +020022
23 /* We're using MMIO for HSUARTs. This section is needed for logging
24 * from FSP only
25 */
26 /* Decode IOBASE at IOBA (BAR0). */
27 reg16 = pci_read_config16(uart_dev, PCI_BASE_ADDRESS_0) | mmio_base;
28 pci_write_config16(uart_dev, PCI_BASE_ADDRESS_0, reg16);
29
Julius Wernercd49cce2019-03-05 16:53:33 -080030#if (CONFIG(NON_LEGACY_UART_MODE))
Mariusz Szafranskia4041332017-08-02 17:28:17 +020031 /* Decode MMIO at MEMBA (BAR1) */
32 pci_write_config32(uart_dev, PCI_BASE_ADDRESS_1,
33 CONFIG_CONSOLE_UART_BASE_ADDRESS +
34 SIZE_OF_HSUART_RES * func);
35#endif
36
37 /* Enable memory/io space and allow to initiate
38 * a transaction as a master
39 */
40 pci_write_config16(uart_dev, PCI_COMMAND,
41 pci_read_config16(uart_dev, PCI_COMMAND) |
Julius Wernercd49cce2019-03-05 16:53:33 -080042#if (CONFIG(NON_LEGACY_UART_MODE))
Mariusz Szafranskia4041332017-08-02 17:28:17 +020043 PCI_COMMAND_MEMORY |
44#endif
45 PCI_COMMAND_MASTER | PCI_COMMAND_IO);
46
Julius Wernercd49cce2019-03-05 16:53:33 -080047#if (CONFIG(CONSOLE_SERIAL_230400))
Mariusz Szafranskia4041332017-08-02 17:28:17 +020048 /* Change the highest speed to 230400 */
49 uint32_t *psr_reg =
50 (uint32_t *)(CONFIG_CONSOLE_UART_BASE_ADDRESS +
51 SIZE_OF_HSUART_RES * func + PSR_OFFSET);
52 *psr_reg >>= 1;
53#endif
Mariusz Szafranskia4041332017-08-02 17:28:17 +020054}
55
56static void early_config_gpio(void)
57{
58 uint32_t reg32;
59
60 // HSUART0:
61 // UART0_RXD
62 reg32 = read32(
63 (void *)PCH_PCR_ADDRESS(PID_GPIOCOM1, R_PAD_CFG_DW0_UART0_RXD));
64 if (((reg32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE) !=
65 V_PCH_GPIO_PAD_MODE_NAT_1) {
66 reg32 &= ~B_PCH_GPIO_PAD_MODE;
67 reg32 |= (UINT32)(V_PCH_GPIO_PAD_MODE_NAT_1
68 << N_PCH_GPIO_PAD_MODE);
69 write32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
70 R_PAD_CFG_DW0_UART0_RXD),
71 reg32);
72 }
73 // UART0_TXD
74 reg32 = read32(
75 (void *)PCH_PCR_ADDRESS(PID_GPIOCOM1, R_PAD_CFG_DW0_UART0_TXD));
76 if (((reg32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE) !=
77 V_PCH_GPIO_PAD_MODE_NAT_1) {
78 reg32 &= ~B_PCH_GPIO_PAD_MODE;
79 reg32 |= (UINT32)(V_PCH_GPIO_PAD_MODE_NAT_1
80 << N_PCH_GPIO_PAD_MODE);
81 write32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
82 R_PAD_CFG_DW0_UART0_TXD),
83 reg32);
84 }
85 // UART0_CTS
86 reg32 = read32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
87 R_PAD_CFG_DW0_SMB3_CLTT_CLK));
88 if (((reg32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE) !=
89 V_PCH_GPIO_PAD_MODE_NAT_2) {
90 reg32 &= ~B_PCH_GPIO_PAD_MODE;
91 reg32 |= (UINT32)(V_PCH_GPIO_PAD_MODE_NAT_2
92 << N_PCH_GPIO_PAD_MODE);
93 write32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
94 R_PAD_CFG_DW0_SMB3_CLTT_CLK),
95 reg32);
96 }
97 // UART0_RTS
98 reg32 = read32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
99 R_PAD_CFG_DW0_PCIE_CLKREQ5_N));
100 if (((reg32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE) !=
101 V_PCH_GPIO_PAD_MODE_NAT_3) {
102 reg32 &= ~B_PCH_GPIO_PAD_MODE;
103 reg32 |= (UINT32)(V_PCH_GPIO_PAD_MODE_NAT_3
104 << N_PCH_GPIO_PAD_MODE);
105 write32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
106 R_PAD_CFG_DW0_PCIE_CLKREQ5_N),
107 reg32);
108 }
109
110 // HSUART1:
111 // UART1_RXD
112 reg32 = read32(
113 (void *)PCH_PCR_ADDRESS(PID_GPIOCOM1, R_PAD_CFG_DW0_UART1_RXD));
114 if (((reg32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE) !=
115 V_PCH_GPIO_PAD_MODE_NAT_1) {
116 reg32 &= ~B_PCH_GPIO_PAD_MODE;
117 reg32 |= (UINT32)(V_PCH_GPIO_PAD_MODE_NAT_1
118 << N_PCH_GPIO_PAD_MODE);
119 write32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
120 R_PAD_CFG_DW0_UART1_RXD),
121 reg32);
122 }
123 // UART1_TXD
124 reg32 = read32(
125 (void *)PCH_PCR_ADDRESS(PID_GPIOCOM1, R_PAD_CFG_DW0_UART1_TXD));
126 if (((reg32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE) !=
127 V_PCH_GPIO_PAD_MODE_NAT_1) {
128 reg32 &= ~B_PCH_GPIO_PAD_MODE;
129 reg32 |= (UINT32)(V_PCH_GPIO_PAD_MODE_NAT_1
130 << N_PCH_GPIO_PAD_MODE);
131 write32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
132 R_PAD_CFG_DW0_UART1_TXD),
133 reg32);
134 }
135 // UART1_CTS
136 reg32 = read32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
137 R_PAD_CFG_DW0_SATA1_SDOUT));
138 if (((reg32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE) !=
139 V_PCH_GPIO_PAD_MODE_NAT_1) {
140 reg32 &= ~B_PCH_GPIO_PAD_MODE;
141 reg32 |= (UINT32)(V_PCH_GPIO_PAD_MODE_NAT_1
142 << N_PCH_GPIO_PAD_MODE);
143 write32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
144 R_PAD_CFG_DW0_SATA1_SDOUT),
145 reg32);
146 }
147 // UART1_RTS
148 reg32 = read32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
149 R_PAD_CFG_DW0_SATA0_SDOUT));
150 if (((reg32 & B_PCH_GPIO_PAD_MODE) >> N_PCH_GPIO_PAD_MODE) !=
151 V_PCH_GPIO_PAD_MODE_NAT_1) {
152 reg32 &= ~B_PCH_GPIO_PAD_MODE;
153 reg32 |= (UINT32)(V_PCH_GPIO_PAD_MODE_NAT_1
154 << N_PCH_GPIO_PAD_MODE);
155 write32((void *)PCH_PCR_ADDRESS(PID_GPIOCOM1,
156 R_PAD_CFG_DW0_SATA0_SDOUT),
157 reg32);
158 }
159}
160
161void early_uart_init(void)
162{
163 register int i;
164
Jonathan Neuschäfer5268b762018-02-12 12:24:25 +0100165 /* Check: do we have enough elements to init. ? */
Julien Viard de Galbert26436fb2018-01-25 10:29:42 +0100166 BUILD_BUG_ON(DENVERTON_UARTS_TO_INI > ELEM_OF_UART_TAB);
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200167
168 /* HSUART(B0:D26:0-1) GPIO init. */
169 early_config_gpio();
170
Julien Viard de Galbert26436fb2018-01-25 10:29:42 +0100171 for (i = DENVERTON_UARTS_TO_INI - 1; i >= 0; --i) {
Mariusz Szafranskia4041332017-08-02 17:28:17 +0200172 pci_early_hsuart_device_probe(0, CONFIG_HSUART_DEV, i,
173 legacy_uart_ioadr_tab[i]);
174 }
175}