blob: 4be2db081a5983c2b086f8600e4e4cb16b53e7ea [file] [log] [blame]
/*
* Copyright (c) 2019 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_INCLUDE_DRIVERS_PCIE_MSI_H_
#define ZEPHYR_INCLUDE_DRIVERS_PCIE_MSI_H_
#include <drivers/pcie/pcie.h>
#include <zephyr/types.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Find a PCI(e) capability in an endpoint's configuration space.
*
* @param bdf the PCI endpoint to examine
* @param cap_id the capability ID of interest
* @return the index of the configuration word, or 0 if no capability.
*
* Note: PCI(e) capabilities are only used in the MSI code, so for
* now, capabilities-related code is only included when MSI is. It
* can easily be separated out if/when its use spreads.
*/
extern u32_t pcie_get_cap(pcie_bdf_t bdf, u32_t cap_id);
/*
* Configuration word 13 contains the head of the capabilities list.
*/
#define PCIE_CONF_CAPPTR 13U /* capabilities pointer */
#define PCIE_CONF_CAPPTR_FIRST(w) (((w) >> 2) & 0x3FU)
/*
* The first word of every capability contains a capability identifier,
* and a link to the next capability (or 0) in configuration space.
*/
#define PCIE_CONF_CAP_ID(w) ((w) & 0xFFU)
#define PCIE_CONF_CAP_NEXT(w) (((w) >> 10) & 0x3FU)
/**
* @brief Compute the target address for an MSI posted write.
*
* This function is exported by the arch, board or SoC code.
*
* @param irq The IRQ we wish to trigger via MSI.
* @return A (32-bit) value for the MSI MAP register.
*/
extern u32_t pcie_msi_map(unsigned int irq);
/**
* @brief Compute the data for an MSI posted write.
*
* This function is exported by the arch, board or SoC code.
*
* @param irq The IRQ we wish to trigger via MSI.
* @return A (16-bit) value for MSI MDR register.
*/
extern u16_t pcie_msi_mdr(unsigned int irq);
/**
* @brief Configure the given PCI endpoint to generate MSIs.
*
* @param bdf the target PCI endpoint
* @param irq the IRQ which should be generated
* @return true if the endpoint supports MSI, false otherwise.
*/
extern bool pcie_set_msi(pcie_bdf_t bdf, unsigned int irq);
/*
* MSI capability ID in the PCI configuration capability list.
*/
#define PCIE_MSI_CAP_ID 05U
/*
* The first word of the MSI capability is shared with the
* capability ID and list link. The high 16 bits are the MCR.
*/
#define PCIE_MSI_MCR 0U
#define PCIE_MSI_MCR_EN 0x00010000U /* enable MSI */
#define PCIE_MSI_MCR_MME 0x00700000U /* mask of # of enabled IRQs */
#define PCIE_MSI_MCR_64 0x00800000U /* 64-bit MSI */
/*
* The MAP follows the MCR. If PCIE_MSI_MCR_64, then the MAP
* is two words long. The MDR follows immediately after the MAP.
*/
#define PCIE_MSI_MAP0 1U
#define PCIE_MSI_MAP1_64 2U
#define PCIE_MSI_MDR_32 2U
#define PCIE_MSI_MDR_64 3U
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_DRIVERS_PCIE_MSI_H_ */