zephyr/soc/x86/apollo_lake/soc.c
Daniel Leung ae989e0539 x86: apollo_lake: add mmu regions for UARTs and I2Cs
UARTs and I2C controllers are accessed through MMIO and
these regions need to be added to MMU for proper access.

This also enable MMU for Apollo Lake by default since
serial console is now usable.

Signed-off-by: Daniel Leung <daniel.leung@intel.com>
2020-05-19 19:19:51 +02:00

226 lines
7.1 KiB
C

/*
* Copyright (c) 2018, Intel Corporation
* Copyright (c) 2011-2015, Wind River Systems, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
/**
* @file
* @brief System/hardware module for the Apollo Lake SoC
*
* This module provides routines to initialize and support soc-level hardware
* for the Apollo Lake SoC.
*/
#include <kernel.h>
#include "soc.h"
#include <drivers/uart.h>
#include <device.h>
#include <init.h>
#ifdef CONFIG_PCIE
#include <drivers/pcie/pcie.h>
#endif
#ifdef CONFIG_X86_MMU
/* loapic */
MMU_BOOT_REGION(CONFIG_LOAPIC_BASE_ADDRESS, 4 * 1024, MMU_ENTRY_WRITE);
/* ioapic */
MMU_BOOT_REGION(DT_REG_ADDR(DT_INST(0, intel_ioapic)), 1024 * 1024, MMU_ENTRY_WRITE);
#ifdef CONFIG_HPET_TIMER
MMU_BOOT_REGION(DT_REG_ADDR(DT_INST(0, intel_hpet)), KB(4), MMU_ENTRY_WRITE);
#endif /* CONFIG_HPET_TIMER */
/* for UARTs */
#if DT_NODE_HAS_STATUS(DT_INST(0, ns16550), okay) && \
!DT_PROP(DT_INST(0, ns16550), pcie)
MMU_BOOT_REGION(DT_REG_ADDR(DT_INST(0, ns16550)), 0x1000,
(MMU_ENTRY_READ | MMU_ENTRY_WRITE));
#endif
#if DT_NODE_HAS_STATUS(DT_INST(1, ns16550), okay) && \
!DT_PROP(DT_INST(1, ns16550), pcie)
MMU_BOOT_REGION(DT_REG_ADDR(DT_INST(1, ns16550)), 0x1000,
(MMU_ENTRY_READ | MMU_ENTRY_WRITE));
#endif
#if DT_NODE_HAS_STATUS(DT_INST(2, ns16550), okay) && \
!DT_PROP(DT_INST(2, ns16550), pcie)
MMU_BOOT_REGION(DT_REG_ADDR(DT_INST(2, ns16550)), 0x1000,
(MMU_ENTRY_READ | MMU_ENTRY_WRITE));
#endif
#if DT_NODE_HAS_STATUS(DT_INST(3, ns16550), okay) && \
!DT_PROP(DT_INST(3, ns16550), pcie)
MMU_BOOT_REGION(DT_REG_ADDR(DT_INST(3, ns16550)), 0x1000,
(MMU_ENTRY_READ | MMU_ENTRY_WRITE));
#endif
/* for I2C controllers */
#ifdef CONFIG_I2C
#if DT_NODE_HAS_STATUS(DT_INST(0, snps_designware_i2c), okay) && \
!DT_PROP(DT_INST(0, snps_designware_i2c), pcie)
MMU_BOOT_REGION(DT_REG_ADDR(DT_INST(0, snps_designware_i2c)), 0x1000,
(MMU_ENTRY_READ | MMU_ENTRY_WRITE));
#endif
#if DT_NODE_HAS_STATUS(DT_INST(1, snps_designware_i2c), okay) && \
!DT_PROP(DT_INST(1, snps_designware_i2c), pcie)
MMU_BOOT_REGION(DT_REG_ADDR(DT_INST(1, snps_designware_i2c)), 0x1000,
(MMU_ENTRY_READ | MMU_ENTRY_WRITE));
#endif
#if DT_NODE_HAS_STATUS(DT_INST(2, snps_designware_i2c), okay) && \
!DT_PROP(DT_INST(2, snps_designware_i2c), pcie)
MMU_BOOT_REGION(DT_REG_ADDR(DT_INST(2, snps_designware_i2c)), 0x1000,
(MMU_ENTRY_READ | MMU_ENTRY_WRITE));
#endif
#if DT_NODE_HAS_STATUS(DT_INST(3, snps_designware_i2c), okay) && \
!DT_PROP(DT_INST(3, snps_designware_i2c), pcie)
MMU_BOOT_REGION(DT_REG_ADDR(DT_INST(3, snps_designware_i2c)), 0x1000,
(MMU_ENTRY_READ | MMU_ENTRY_WRITE));
#endif
#if DT_NODE_HAS_STATUS(DT_INST(4, snps_designware_i2c), okay) && \
!DT_PROP(DT_INST(4, snps_designware_i2c), pcie)
MMU_BOOT_REGION(DT_REG_ADDR(DT_INST(4, snps_designware_i2c)), 0x1000,
(MMU_ENTRY_READ | MMU_ENTRY_WRITE));
#endif
#if DT_NODE_HAS_STATUS(DT_INST(5, snps_designware_i2c), okay) && \
!DT_PROP(DT_INST(5, snps_designware_i2c), pcie)
MMU_BOOT_REGION(DT_REG_ADDR(DT_INST(5, snps_designware_i2c)), 0x1000,
(MMU_ENTRY_READ | MMU_ENTRY_WRITE));
#endif
#if DT_NODE_HAS_STATUS(DT_INST(6, snps_designware_i2c), okay) && \
!DT_PROP(DT_INST(6, snps_designware_i2c), pcie)
MMU_BOOT_REGION(DT_REG_ADDR(DT_INST(6, snps_designware_i2c)), 0x1000,
(MMU_ENTRY_READ | MMU_ENTRY_WRITE));
#endif
#if DT_NODE_HAS_STATUS(DT_INST(7, snps_designware_i2c), okay) && \
!DT_PROP(DT_INST(7, snps_designware_i2c), pcie)
MMU_BOOT_REGION(DT_REG_ADDR(DT_INST(7, snps_designware_i2c)), 0x1000,
(MMU_ENTRY_READ | MMU_ENTRY_WRITE));
#endif
#endif /* CONFIG_I2C */
/* for GPIO controller */
#ifdef CONFIG_GPIO_INTEL_APL
MMU_BOOT_REGION(DT_REG_ADDR(DT_NODELABEL(gpio_n_000_031)),
DT_REG_SIZE(DT_NODELABEL(gpio_n_000_031)),
(MMU_ENTRY_READ | MMU_ENTRY_WRITE));
MMU_BOOT_REGION(DT_REG_ADDR(DT_NODELABEL(gpio_nw_000_031)),
DT_REG_SIZE(DT_NODELABEL(gpio_nw_000_031)),
(MMU_ENTRY_READ | MMU_ENTRY_WRITE));
MMU_BOOT_REGION(DT_REG_ADDR(DT_NODELABEL(gpio_w_000_031)),
DT_REG_SIZE(DT_NODELABEL(gpio_w_000_031)),
(MMU_ENTRY_READ | MMU_ENTRY_WRITE));
MMU_BOOT_REGION(DT_REG_ADDR(DT_NODELABEL(gpio_sw_000_031)),
DT_REG_SIZE(DT_NODELABEL(gpio_sw_000_031)),
(MMU_ENTRY_READ | MMU_ENTRY_WRITE));
#endif
static void device_mmu_region(pcie_bdf_t bdf, pcie_id_t id)
{
mm_reg_t base;
if (pcie_probe(bdf, id)) {
base = pcie_get_mbar(bdf, 0);
if (base != PCIE_CONF_BAR_NONE) {
z_x86_add_mmu_region(
base, 0x1000,
MMU_ENTRY_READ | MMU_ENTRY_WRITE);
}
}
}
void z_x86_soc_add_mmu_regions(void)
{
#ifdef CONFIG_PCIE
#if DT_NODE_HAS_STATUS(DT_INST(0, ns16550), okay) && \
DT_PROP(DT_INST(0, ns16550), pcie)
device_mmu_region(DT_REG_ADDR(DT_INST(0, ns16550)),
DT_REG_SIZE(DT_INST(0, ns16550)));
#endif
#if DT_NODE_HAS_STATUS(DT_INST(1, ns16550), okay) && \
DT_PROP(DT_INST(1, ns16550), pcie)
device_mmu_region(DT_REG_ADDR(DT_INST(1, ns16550)),
DT_REG_SIZE(DT_INST(1, ns16550)));
#endif
#if DT_NODE_HAS_STATUS(DT_INST(2, ns16550), okay) && \
DT_PROP(DT_INST(2, ns16550), pcie)
device_mmu_region(DT_REG_ADDR(DT_INST(2, ns16550)),
DT_REG_SIZE(DT_INST(2, ns16550)));
#endif
#if DT_NODE_HAS_STATUS(DT_INST(3, ns16550), okay) && \
DT_PROP(DT_INST(3, ns16550), pcie)
device_mmu_region(DT_REG_ADDR(DT_INST(3, ns16550)),
DT_REG_SIZE(DT_INST(3, ns16550)));
#endif
#if DT_NODE_HAS_STATUS(DT_INST(0, snps_designware_i2c), okay) && \
DT_PROP(DT_INST(0, snps_designware_i2c), pcie)
device_mmu_region(DT_REG_ADDR(DT_INST(0, snps_designware_i2c)),
DT_REG_SIZE(DT_INST(0, snps_designware_i2c)));
#endif
#if DT_NODE_HAS_STATUS(DT_INST(1, snps_designware_i2c), okay) && \
DT_PROP(DT_INST(1, snps_designware_i2c), pcie)
device_mmu_region(DT_REG_ADDR(DT_INST(1, snps_designware_i2c)),
DT_REG_SIZE(DT_INST(1, snps_designware_i2c)));
#endif
#if DT_NODE_HAS_STATUS(DT_INST(2, snps_designware_i2c), okay) && \
DT_PROP(DT_INST(2, snps_designware_i2c), pcie)
device_mmu_region(DT_REG_ADDR(DT_INST(2, snps_designware_i2c)),
DT_REG_SIZE(DT_INST(2, snps_designware_i2c)));
#endif
#if DT_NODE_HAS_STATUS(DT_INST(3, snps_designware_i2c), okay) && \
DT_PROP(DT_INST(3, snps_designware_i2c), pcie)
device_mmu_region(DT_REG_ADDR(DT_INST(3, snps_designware_i2c)),
DT_REG_SIZE(DT_INST(3, snps_designware_i2c)));
#endif
#if DT_NODE_HAS_STATUS(DT_INST(4, snps_designware_i2c), okay) && \
DT_PROP(DT_INST(4, snps_designware_i2c), pcie)
device_mmu_region(DT_REG_ADDR(DT_INST(4, snps_designware_i2c)),
DT_REG_SIZE(DT_INST(4, snps_designware_i2c)));
#endif
#if DT_NODE_HAS_STATUS(DT_INST(5, snps_designware_i2c), okay) && \
DT_PROP(DT_INST(5, snps_designware_i2c), pcie)
device_mmu_region(DT_REG_ADDR(DT_INST(5, snps_designware_i2c)),
DT_REG_SIZE(DT_INST(5, snps_designware_i2c)));
#endif
#if DT_NODE_HAS_STATUS(DT_INST(6, snps_designware_i2c), okay) && \
DT_PROP(DT_INST(6, snps_designware_i2c), pcie)
device_mmu_region(DT_REG_ADDR(DT_INST(6, snps_designware_i2c)),
DT_REG_SIZE(DT_INST(6, snps_designware_i2c)));
#endif
#if DT_NODE_HAS_STATUS(DT_INST(7, snps_designware_i2c), okay) && \
DT_PROP(DT_INST(7, snps_designware_i2c), pcie)
device_mmu_region(DT_REG_ADDR(DT_INST(7, snps_designware_i2c)),
DT_REG_SIZE(DT_INST(7, snps_designware_i2c)));
#endif
#endif /* CONFIG_PCIE */
}
#endif /* CONFIG_X86_MMU */