1 /*
2 * Copyright (c) 2021 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define LOG_LEVEL CONFIG_PCIE_LOG_LEVEL
8 #include <zephyr/logging/log.h>
9 LOG_MODULE_REGISTER(pcie);
10
11 #include <errno.h>
12
13 #include <zephyr/kernel.h>
14
15 #include <soc.h>
16 #include <zephyr/device.h>
17 #include <zephyr/init.h>
18
19 #define DT_DRV_COMPAT ptm_root
20
21 #include <zephyr/drivers/pcie/pcie.h>
22 #include "ptm.h"
23
pcie_ptm_root_setup(const struct device * dev,uint32_t base)24 static int pcie_ptm_root_setup(const struct device *dev, uint32_t base)
25 {
26 const struct pcie_ptm_root_config *config = dev->config;
27 union ptm_cap_reg cap;
28 union ptm_ctrl_reg ctrl;
29
30 cap.raw = pcie_conf_read(config->pcie->bdf, base + PTM_CAP_REG_OFFSET);
31 if ((cap.root == 0) || ((cap.root == 1) && (cap.responder == 0))) {
32 LOG_ERR("PTM root not supported on 0x%x", config->pcie->bdf);
33 return -ENOTSUP;
34 }
35
36 ctrl.ptm_enable = 1;
37 ctrl.root_select = 1;
38
39 pcie_conf_write(config->pcie->bdf, base + PTM_CTRL_REG_OFFSET, ctrl.raw);
40
41 LOG_DBG("PTM root 0x%x enabled", config->pcie->bdf);
42
43 return 0;
44 }
45
pcie_ptm_root_init(const struct device * dev)46 static int pcie_ptm_root_init(const struct device *dev)
47 {
48 const struct pcie_ptm_root_config *config = dev->config;
49 uint32_t reg;
50
51 reg = pcie_get_ext_cap(config->pcie->bdf, PCIE_EXT_CAP_ID_PTM);
52 if (reg == 0) {
53 LOG_ERR("PTM capability not exposed on 0x%x", config->pcie->bdf);
54 return -ENODEV;
55 }
56
57 return pcie_ptm_root_setup(dev, reg);
58 }
59
60 #define PCIE_PTM_ROOT_INIT(index) \
61 DEVICE_PCIE_INST_DECLARE(index); \
62 static const struct pcie_ptm_root_config ptm_config_##index = { \
63 DEVICE_PCIE_INST_INIT(index, pcie), \
64 }; \
65 DEVICE_DT_INST_DEFINE(index, &pcie_ptm_root_init, NULL, NULL, \
66 &ptm_config_##index, PRE_KERNEL_1, \
67 CONFIG_KERNEL_INIT_PRIORITY_DEVICE, NULL);
68
DT_INST_FOREACH_STATUS_OKAY(PCIE_PTM_ROOT_INIT)69 DT_INST_FOREACH_STATUS_OKAY(PCIE_PTM_ROOT_INIT)
70
71
72 bool pcie_ptm_enable(pcie_bdf_t bdf)
73 {
74 uint32_t base;
75 union ptm_cap_reg cap;
76 union ptm_ctrl_reg ctrl;
77
78 base = pcie_get_ext_cap(bdf, PCIE_EXT_CAP_ID_PTM);
79 if (base == 0) {
80 LOG_ERR("PTM capability not exposed on 0x%x", bdf);
81 return false;
82 }
83
84 cap.raw = pcie_conf_read(bdf, base + PTM_CAP_REG_OFFSET);
85 if (cap.requester == 0) {
86 LOG_ERR("PTM requester not supported on 0x%x", bdf);
87 return false;
88 }
89
90 ctrl.ptm_enable = 1;
91
92 pcie_conf_write(bdf, base + PTM_CTRL_REG_OFFSET, ctrl.raw);
93
94 LOG_DBG("PTM requester 0x%x enabled", bdf);
95
96 return true;
97 }
98