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>
This commit is contained in:
Tomasz Bursztyka 2021-08-18 11:18:44 +02:00 committed by Christopher Friedt
parent e854950219
commit 23a0ce4ff3
4 changed files with 145 additions and 0 deletions

View file

@ -3,3 +3,4 @@ zephyr_library()
zephyr_library_sources(pcie.c)
zephyr_library_sources_ifdef(CONFIG_PCIE_MSI msi.c)
zephyr_library_sources_ifdef(CONFIG_PCIE_SHELL shell.c)
zephyr_library_sources_ifdef(CONFIG_PCIE_PTM ptm.c)

View file

@ -44,6 +44,12 @@ config PCIE_MSI_X
endif # PCIE_MSI
config PCIE_PTM
bool "Enable support for PCI(e) Precision Time Management (PTM)"
help
This will enable support both PTM root and PTM requester features.
Up to the PCIe device driver to enable its PTM requester capability.
config PCIE_SHELL
bool "Enable PCIe/new PCI Shell"
default y

94
drivers/pcie/host/ptm.c Normal file
View file

@ -0,0 +1,94 @@
/*
* 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;
}

44
drivers/pcie/host/ptm.h Normal file
View file

@ -0,0 +1,44 @@
/*
* Copyright (c) 2021 Intel Corporation.
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef ZEPHYR_DRIVERS_PCIE_HOST_PTM_H_
#define ZEPHYR_DRIVERS_PCIE_HOST_PTM_H_
#include <drivers/pcie/pcie.h>
#include <drivers/pcie/cap.h>
#define PTM_CAP_REG_OFFSET 0x04U
union ptm_cap_reg {
struct {
uint32_t requester : 1;
uint32_t responder : 1;
uint32_t root : 1;
uint32_t _reserved1 : 5;
uint32_t local_clock_granularity : 8;
uint32_t _reserved2 : 16;
};
uint32_t raw;
};
#define PTM_CTRL_REG_OFFSET 0x08U
union ptm_ctrl_reg {
struct {
uint32_t ptm_enable : 1;
uint32_t root_select : 1;
uint32_t _reserved1 : 6;
uint32_t effective_granularity : 8;
uint32_t _reserved2 : 16;
};
uint32_t raw;
};
struct pcie_ptm_root_config {
pcie_bdf_t bdf;
};
#endif /* ZEPHYR_DRIVERS_PCIE_HOST_PTM_H_ */