uboot/arch/x86/cpu/apollolake/cpu_common.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Copyright 2019 Google LLC
   4 */
   5
   6#include <common.h>
   7#include <dm.h>
   8#include <log.h>
   9#include <asm/cpu_common.h>
  10#include <asm/io.h>
  11#include <asm/msr.h>
  12#include <asm/pci.h>
  13#include <asm/arch/cpu.h>
  14#include <asm/arch/iomap.h>
  15#include <asm/arch/uart.h>
  16#include <power/acpi_pmc.h>
  17
  18/* Define this here to avoid referencing any drivers for the debug UART 1 */
  19#define PCH_DEV_P2SB    PCI_BDF(0, 0x0d, 0)
  20
  21void cpu_flush_l1d_to_l2(void)
  22{
  23        struct msr_t msr;
  24
  25        msr = msr_read(MSR_POWER_MISC);
  26        msr.lo |= FLUSH_DL1_L2;
  27        msr_write(MSR_POWER_MISC, msr);
  28}
  29
  30void enable_pm_timer_emulation(const struct udevice *pmc)
  31{
  32        struct acpi_pmc_upriv *upriv = dev_get_uclass_priv(pmc);
  33        msr_t msr;
  34
  35        /*
  36         * The derived frequency is calculated as follows:
  37         *    (CTC_FREQ * msr[63:32]) >> 32 = target frequency.
  38         *
  39         * Back-solve the multiplier so the 3.579545MHz ACPI timer frequency is
  40         * used.
  41         */
  42        msr.hi = (3579545ULL << 32) / CTC_FREQ;
  43
  44        /* Set PM1 timer IO port and enable */
  45        msr.lo = EMULATE_PM_TMR_EN | (upriv->acpi_base + R_ACPI_PM1_TMR);
  46        debug("PM timer %x %x\n", msr.hi, msr.lo);
  47        msr_write(MSR_EMULATE_PM_TIMER, msr);
  48}
  49
  50static void pch_uart_init(void)
  51{
  52        /*
  53         * Set up the pinmux so that the UART rx/tx signals are connected
  54         * outside the SoC.
  55         *
  56         * There are about 500 lines of code required to program the GPIO
  57         * configuration for the UARTs. But it boils down to four writes, and
  58         * for the debug UART we want the minimum possible amount of code before
  59         * the UART is running. So just add the magic writes here. See
  60         * apl_hostbridge_early_init_pinctrl() for the full horror.
  61         */
  62        if (PCI_FUNC(PCH_DEV_UART) == 1) {
  63                writel(0x40000402, 0xd0c50650);
  64                writel(0x3c47, 0xd0c50654);
  65                writel(0x40000400, 0xd0c50658);
  66                writel(0x3c48, 0xd0c5065c);
  67        } else { /* UART2 */
  68                writel(0x40000402, 0xd0c50670);
  69                writel(0x3c4b, 0xd0c50674);
  70                writel(0x40000400, 0xd0c50678);
  71                writel(0x3c4c, 0xd0c5067c);
  72        }
  73
  74#ifdef CONFIG_DEBUG_UART
  75        apl_uart_init(PCH_DEV_UART, CONFIG_VAL(DEBUG_UART_BASE));
  76#endif
  77}
  78
  79static void p2sb_enable_bar(ulong bar)
  80{
  81        /* Enable PCR Base address in PCH */
  82        pci_x86_write_config(PCH_DEV_P2SB, PCI_BASE_ADDRESS_0, bar,
  83                             PCI_SIZE_32);
  84        pci_x86_write_config(PCH_DEV_P2SB, PCI_BASE_ADDRESS_1, 0, PCI_SIZE_32);
  85
  86        /* Enable P2SB MSE */
  87        pci_x86_write_config(PCH_DEV_P2SB, PCI_COMMAND,
  88                             PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY,
  89                             PCI_SIZE_8);
  90}
  91
  92/*
  93 * board_debug_uart_init() - Init the debug UART ready for use
  94 *
  95 * This is the minimum init needed to get the UART running. It avoids any
  96 * drivers or complex code, so that the UART is running as soon as possible.
  97 */
  98void board_debug_uart_init(void)
  99{
 100        p2sb_enable_bar(IOMAP_P2SB_BAR);
 101        pch_uart_init();
 102}
 103