zephyr/drivers/pcie/host/ptm.c
Tomasz Bursztyka 23a0ce4ff3 drivers/pcie: Add PTM root device driver as well as implement PTM API
Any exposed PTM root device will by default see their root capability
enabled so they will become PTM responder.

Signed-off-by: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
2021-11-04 11:06:02 -04:00

95 lines
2.1 KiB
C

/*
* Copyright (c) 2021 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#define LOG_LEVEL CONFIG_PCIE_LOG_LEVEL
#include <logging/log.h>
LOG_MODULE_REGISTER(pcie);
#include <errno.h>
#include <kernel.h>
#include <soc.h>
#include <device.h>
#include <init.h>
#include <drivers/pcie/pcie.h>
#include "ptm.h"
static int pcie_ptm_root_setup(const struct device *dev, uint32_t base)
{
const struct pcie_ptm_root_config *config = dev->config;
union ptm_cap_reg cap;
union ptm_ctrl_reg ctrl;
cap.raw = pcie_conf_read(config->bdf, base + PTM_CAP_REG_OFFSET);
if ((cap.root == 0) || ((cap.root == 1) && (cap.responder == 0))) {
LOG_ERR("PTM root not supported on 0x%x", config->bdf);
return -ENOTSUP;
}
ctrl.ptm_enable = 1;
ctrl.root_select = 1;
pcie_conf_write(config->bdf, base + PTM_CTRL_REG_OFFSET, ctrl.raw);
LOG_DBG("PTM root 0x%x enabled", config->bdf);
return 0;
}
static int pcie_ptm_root_init(const struct device *dev)
{
const struct pcie_ptm_root_config *config = dev->config;
uint32_t reg;
reg = pcie_get_ext_cap(config->bdf, PCIE_EXT_CAP_ID_PTM);
if (reg == 0) {
LOG_ERR("PTM capability not exposed on 0x%x", config->bdf);
return -ENODEV;
}
return pcie_ptm_root_setup(dev, reg);
}
#define PCIE_PTM_ROOT_INIT(index) \
static const struct pcie_ptm_root_config ptm_config_##index = { \
.bdf = DT_INST_REG_ADDR(index), \
}; \
DEVICE_DT_INST_DEFINE(index, &pcie_ptm_root_init, NULL, NULL, \
&ptm_config_##index, PRE_KERNEL_1, \
CONFIG_KERNEL_INIT_PRIORITY_DEVICE, NULL);
DT_INST_FOREACH_STATUS_OKAY(PCIE_PTM_ROOT_INIT)
bool pcie_ptm_enable(pcie_bdf_t bdf)
{
uint32_t base;
union ptm_cap_reg cap;
union ptm_ctrl_reg ctrl;
base = pcie_get_ext_cap(bdf, PCIE_EXT_CAP_ID_PTM);
if (base == 0) {
LOG_ERR("PTM capability not exposed on 0x%x", bdf);
return false;
}
cap.raw = pcie_conf_read(bdf, base + PTM_CAP_REG_OFFSET);
if (cap.requester == 0) {
LOG_ERR("PTM requester not supported on 0x%x", bdf);
return false;
}
ctrl.ptm_enable = 1;
pcie_conf_write(bdf, base + PTM_CTRL_REG_OFFSET, ctrl.raw);
LOG_DBG("PTM requester 0x%x enabled", bdf);
return true;
}