blob: 5048e5d5455f5107e6f88834c1b8f65106ec2b58 [file] [log] [blame]
/* SPDX-License-Identifier: GPL-2.0-only */
#include <arch/io.h>
#include <assert.h>
#include <console/uart.h>
#include <device/mmio.h>
#include <device/pci_def.h>
#include <device/pci_ops.h>
#include <southbridge/intel/lynxpoint/iobp.h>
#include <southbridge/intel/lynxpoint/lp_gpio.h>
#include <southbridge/intel/lynxpoint/pch.h>
#include <types.h>
static pci_devfn_t get_uart_pci_device(void)
{
switch (CONFIG_UART_FOR_CONSOLE) {
case 0: return PCI_DEV(0, 0x15, 5);
case 1: return PCI_DEV(0, 0x15, 6);
default: return dead_code_t(pci_devfn_t);
}
}
/* TODO: Figure out if all steps are actually necessary */
void uart_bootblock_init(void)
{
const pci_devfn_t dev = get_uart_pci_device();
/* Program IOBP GPIODF */
pch_iobp_update(SIO_IOBP_GPIODF, ~0x131f, 0x131f);
/* Program IOBP CB000180h[5:0] = 111111b (undefined register) */
pch_iobp_update(0xcb000180, ~0x0000003f, 0x0000003f);
/* Set and enable MMIO BAR */
pci_write_config32(dev, PCI_BASE_ADDRESS_0, CONFIG_CONSOLE_UART_BASE_ADDRESS);
pci_or_config16(dev, PCI_COMMAND, PCI_COMMAND_MEMORY);
void *const bar = (void *)(uintptr_t)CONFIG_CONSOLE_UART_BASE_ADDRESS;
/* Initialize LTR */
clrbits32(bar + SIO_REG_PPR_GEN, SIO_REG_PPR_GEN_LTR_MODE_MASK);
clrbits32(bar + SIO_REG_PPR_RST, SIO_REG_PPR_RST_ASSERT);
/* Take UART out of reset */
setbits32(bar + SIO_REG_PPR_RST, SIO_REG_PPR_RST_ASSERT);
/* Set M and N divisor inputs and enable clock */
uint32_t ppr_clock = 0;
ppr_clock |= SIO_REG_PPR_CLOCK_EN;
ppr_clock |= SIO_REG_PPR_CLOCK_UPDATE;
ppr_clock |= SIO_REG_PPR_CLOCK_N_DIV << 16;
ppr_clock |= SIO_REG_PPR_CLOCK_M_DIV << 1;
write32(bar + SIO_REG_PPR_CLOCK, ppr_clock);
}