1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <console/uart.h>
5 #include <device/mmio.h>
6 #include <device/pci_def.h>
7 #include <device/pci_ops.h>
8 #include <southbridge/intel/lynxpoint/iobp.h>
9 #include <southbridge/intel/lynxpoint/lp_gpio.h>
10 #include <southbridge/intel/lynxpoint/pch.h>
13 static pci_devfn_t
get_uart_pci_device(void)
15 switch (CONFIG_UART_FOR_CONSOLE
) {
16 case 0: return PCI_DEV(0, 0x15, 5);
17 case 1: return PCI_DEV(0, 0x15, 6);
18 default: return dead_code_t(pci_devfn_t
);
22 /* TODO: Figure out if all steps are actually necessary */
23 void uart_bootblock_init(void)
25 const pci_devfn_t dev
= get_uart_pci_device();
27 /* Program IOBP GPIODF */
28 pch_iobp_update(SIO_IOBP_GPIODF
, ~0x131f, 0x131f);
30 /* Program IOBP CB000180h[5:0] = 111111b (undefined register) */
31 pch_iobp_update(0xcb000180, ~0x0000003f, 0x0000003f);
33 /* Set and enable MMIO BAR */
34 pci_write_config32(dev
, PCI_BASE_ADDRESS_0
, CONFIG_CONSOLE_UART_BASE_ADDRESS
);
35 pci_or_config16(dev
, PCI_COMMAND
, PCI_COMMAND_MEMORY
);
37 void *const bar
= (void *)(uintptr_t)CONFIG_CONSOLE_UART_BASE_ADDRESS
;
40 clrbits32(bar
+ SIO_REG_PPR_GEN
, SIO_REG_PPR_GEN_LTR_MODE_MASK
);
41 clrbits32(bar
+ SIO_REG_PPR_RST
, SIO_REG_PPR_RST_ASSERT
);
43 /* Take UART out of reset */
44 setbits32(bar
+ SIO_REG_PPR_RST
, SIO_REG_PPR_RST_ASSERT
);
46 /* Set M and N divisor inputs and enable clock */
47 uint32_t ppr_clock
= 0;
48 ppr_clock
|= SIO_REG_PPR_CLOCK_EN
;
49 ppr_clock
|= SIO_REG_PPR_CLOCK_UPDATE
;
50 ppr_clock
|= SIO_REG_PPR_CLOCK_N_DIV
<< 16;
51 ppr_clock
|= SIO_REG_PPR_CLOCK_M_DIV
<< 1;
52 write32(bar
+ SIO_REG_PPR_CLOCK
, ppr_clock
);