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