blob: 910f01d01cfeb4a669b7f3de61df742afd8a8dc6 [file] [log] [blame]
Angel Pons0612b272020-04-05 15:46:56 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -07002
John Zhao41aa8d62022-01-20 11:29:18 -08003#define __SIMPLE_DEVICE__
4
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +02005#include <device/pci_ops.h>
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -07006#include <console/console.h>
7#include <device/device.h>
8#include <device/pci.h>
9#include <device/pci_ids.h>
Subrata Banik7837c202018-05-07 17:13:40 +053010#include <intelblocks/p2sb.h>
John Zhao41aa8d62022-01-20 11:29:18 -080011#include <intelblocks/p2sblib.h>
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -070012#include <soc/iomap.h>
Subrata Banik7837c202018-05-07 17:13:40 +053013#include <soc/p2sb.h>
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -070014#include <soc/pci_devs.h>
Subrata Banik7837c202018-05-07 17:13:40 +053015#include <string.h>
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -070016
Subrata Banik7837c202018-05-07 17:13:40 +053017#define PCH_P2SB_EPMASK(mask_number) (PCH_P2SB_EPMASK0 + ((mask_number) * 4))
18
Subrata Banik7837c202018-05-07 17:13:40 +053019void p2sb_enable_bar(void)
20{
Subrata Banik7c477a92022-03-14 12:47:31 +053021 p2sb_dev_enable_bar(PCH_DEV_P2SB, P2SB_BAR);
Subrata Banik7837c202018-05-07 17:13:40 +053022}
23
24/*
25 * Enable decoding for HPET range.
26 * This is needed for FspMemoryInit to store and retrieve a global data
27 * pointer.
28 */
29void p2sb_configure_hpet(void)
30{
31 /*
32 * Enable decoding for HPET memory address range.
33 * HPTC_OFFSET(0x60) bit 7, when set the P2SB will decode
34 * the High Performance Timer memory address range
35 * selected by bits 1:0
36 */
Nico Hubere5495032020-02-17 18:26:51 +010037 pci_write_config8(PCH_DEV_P2SB, HPTC_OFFSET, HPTC_ADDR_ENABLE_BIT);
Subrata Banik7837c202018-05-07 17:13:40 +053038}
39
Arthur Heymansf629f7b2020-11-12 21:00:03 +010040union p2sb_bdf p2sb_get_hpet_bdf(void)
41{
John Zhao41aa8d62022-01-20 11:29:18 -080042 const bool was_hidden = p2sb_dev_is_hidden(PCH_DEV_P2SB);
Arthur Heymansf629f7b2020-11-12 21:00:03 +010043 if (was_hidden)
44 p2sb_unhide();
45
46 union p2sb_bdf bdf = { .raw = pci_read_config16(PCH_DEV_P2SB, PCH_P2SB_HBDF) };
47
48 if (was_hidden)
49 p2sb_hide();
50
51 return bdf;
52}
53
54void p2sb_set_hpet_bdf(union p2sb_bdf bdf)
55{
56 pci_write_config16(PCH_DEV_P2SB, PCH_P2SB_HBDF, bdf.raw);
57}
58
Arthur Heymansa1f65be2020-11-12 21:07:13 +010059union p2sb_bdf p2sb_get_ioapic_bdf(void)
60{
John Zhao41aa8d62022-01-20 11:29:18 -080061 const bool was_hidden = p2sb_dev_is_hidden(PCH_DEV_P2SB);
Arthur Heymansa1f65be2020-11-12 21:07:13 +010062 if (was_hidden)
63 p2sb_unhide();
64
65 union p2sb_bdf bdf = { .raw = pci_read_config16(PCH_DEV_P2SB, PCH_P2SB_IBDF) };
66
67 if (was_hidden)
68 p2sb_hide();
69
70 return bdf;
71}
72
73void p2sb_set_ioapic_bdf(union p2sb_bdf bdf)
74{
75 pci_write_config16(PCH_DEV_P2SB, PCH_P2SB_IBDF, bdf.raw);
76}
77
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -070078void p2sb_unhide(void)
79{
John Zhao41aa8d62022-01-20 11:29:18 -080080 p2sb_dev_unhide(PCH_DEV_P2SB);
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -070081}
82
83void p2sb_hide(void)
84{
John Zhao41aa8d62022-01-20 11:29:18 -080085 p2sb_dev_hide(PCH_DEV_P2SB);
Subrata Banik7837c202018-05-07 17:13:40 +053086}
87
88static void p2sb_configure_endpoints(int epmask_id, uint32_t mask)
89{
90 uint32_t reg32;
91
Nico Hubere5495032020-02-17 18:26:51 +010092 reg32 = pci_read_config32(PCH_DEV_P2SB, PCH_P2SB_EPMASK(epmask_id));
93 pci_write_config32(PCH_DEV_P2SB, PCH_P2SB_EPMASK(epmask_id),
Subrata Banik7837c202018-05-07 17:13:40 +053094 reg32 | mask);
95}
96
97static void p2sb_lock_endpoints(void)
98{
99 uint8_t reg8;
100
101 /* Set the "Endpoint Mask Lock!", P2SB PCI offset E2h bit[1] to 1. */
Nico Hubere5495032020-02-17 18:26:51 +0100102 reg8 = pci_read_config8(PCH_DEV_P2SB, PCH_P2SB_E0 + 2);
103 pci_write_config8(PCH_DEV_P2SB, PCH_P2SB_E0 + 2,
Subrata Banik7837c202018-05-07 17:13:40 +0530104 reg8 | P2SB_E0_MASKLOCK);
105}
106
107void p2sb_disable_sideband_access(void)
108{
109 uint32_t ep_mask[P2SB_EP_MASK_MAX_REG];
110 int i;
111
112 memset(ep_mask, 0, sizeof(ep_mask));
113
114 p2sb_soc_get_sb_mask(ep_mask, ARRAY_SIZE(ep_mask));
115
116 /* Remove the host accessing right to PSF register range. */
117 for (i = 0; i < P2SB_EP_MASK_MAX_REG; i++)
118 p2sb_configure_endpoints(i, ep_mask[i]);
119
120 p2sb_lock_endpoints();
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -0700121}
122
123static void read_resources(struct device *dev)
124{
125 /*
126 * There's only one resource on the P2SB device. It's also already
127 * manually set to a fixed address in earlier boot stages.
Patrick Rudolph8d7a89b2019-10-04 09:22:27 +0200128 * The following code makes sure that it doesn't change if the device
129 * is visible and the resource allocator is being run.
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -0700130 */
Kyösti Mälkki27d62992022-05-24 20:25:58 +0300131 mmio_resource_kb(dev, PCI_BASE_ADDRESS_0, P2SB_BAR / KiB, P2SB_SIZE / KiB);
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -0700132}
133
134static const struct device_operations device_ops = {
135 .read_resources = read_resources,
Nico Huber2f8ba692020-04-05 14:05:24 +0200136 .set_resources = noop_set_resources,
Subrata Banik6bbc91a2017-12-07 14:55:51 +0530137 .ops_pci = &pci_dev_ops_pci,
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -0700138};
139
140static const unsigned short pci_device_ids[] = {
Wonkyu Kim9f401072020-11-13 15:16:32 -0800141 PCI_DID_INTEL_MTL_SOC_P2SB,
Bora Guvendika15b25f2022-02-28 14:43:49 -0800142 PCI_DID_INTEL_RPP_P_P2SB,
Felix Singer43b7f412022-03-07 04:34:52 +0100143 PCI_DID_INTEL_APL_P2SB,
144 PCI_DID_INTEL_GLK_P2SB,
145 PCI_DID_INTEL_LWB_P2SB,
146 PCI_DID_INTEL_LWB_P2SB_SUPER,
147 PCI_DID_INTEL_SKL_LP_P2SB,
148 PCI_DID_INTEL_SKL_P2SB,
149 PCI_DID_INTEL_KBL_P2SB,
150 PCI_DID_INTEL_CNL_P2SB,
151 PCI_DID_INTEL_CNP_H_P2SB,
152 PCI_DID_INTEL_ICL_P2SB,
153 PCI_DID_INTEL_CMP_P2SB,
154 PCI_DID_INTEL_CMP_H_P2SB,
155 PCI_DID_INTEL_TGL_P2SB,
156 PCI_DID_INTEL_TGL_H_P2SB,
157 PCI_DID_INTEL_EHL_P2SB,
158 PCI_DID_INTEL_JSP_P2SB,
159 PCI_DID_INTEL_ADP_P_P2SB,
160 PCI_DID_INTEL_ADP_S_P2SB,
161 PCI_DID_INTEL_ADP_M_P2SB,
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -0700162 0,
163};
164
165static const struct pci_driver pmc __pci_driver = {
166 .ops = &device_ops,
Felix Singer43b7f412022-03-07 04:34:52 +0100167 .vendor = PCI_VID_INTEL,
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -0700168 .devices = pci_device_ids,
169};