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