1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #define __SIMPLE_DEVICE__
5 #include <device/pci_ops.h>
6 #include <device/device.h>
7 #include <device/pci.h>
8 #include <device/pci_ids.h>
9 #include <intelblocks/p2sb.h>
10 #include <intelblocks/p2sblib.h>
11 #include <soc/iomap.h>
13 #include <soc/pci_devs.h>
16 #define PCH_P2SB_EPMASK(mask_number) (PCH_P2SB_EPMASK0 + ((mask_number) * 4))
18 void p2sb_enable_bar(void)
20 p2sb_dev_enable_bar(PCH_DEV_P2SB
, P2SB_BAR
);
24 * Enable decoding for HPET range.
25 * This is needed for FspMemoryInit to store and retrieve a global data
28 void p2sb_configure_hpet(void)
31 * Enable decoding for HPET memory address range.
32 * HPTC_OFFSET(0x60) bit 7, when set the P2SB will decode
33 * the High Performance Timer memory address range
34 * selected by bits 1:0
36 pci_write_config8(PCH_DEV_P2SB
, HPTC_OFFSET
, HPTC_ADDR_ENABLE_BIT
);
39 union p2sb_bdf
p2sb_get_hpet_bdf(void)
41 const bool was_hidden
= p2sb_dev_is_hidden(PCH_DEV_P2SB
);
45 union p2sb_bdf bdf
= { .raw
= pci_read_config16(PCH_DEV_P2SB
, PCH_P2SB_HBDF
) };
53 void p2sb_set_hpet_bdf(union p2sb_bdf bdf
)
55 pci_write_config16(PCH_DEV_P2SB
, PCH_P2SB_HBDF
, bdf
.raw
);
58 union p2sb_bdf
p2sb_get_ioapic_bdf(void)
60 const bool was_hidden
= p2sb_dev_is_hidden(PCH_DEV_P2SB
);
64 union p2sb_bdf bdf
= { .raw
= pci_read_config16(PCH_DEV_P2SB
, PCH_P2SB_IBDF
) };
72 void p2sb_set_ioapic_bdf(union p2sb_bdf bdf
)
74 pci_write_config16(PCH_DEV_P2SB
, PCH_P2SB_IBDF
, bdf
.raw
);
77 void p2sb_unhide(void)
79 p2sb_dev_unhide(PCH_DEV_P2SB
);
84 p2sb_dev_hide(PCH_DEV_P2SB
);
87 static void p2sb_configure_endpoints(int epmask_id
, uint32_t mask
)
91 reg32
= pci_read_config32(PCH_DEV_P2SB
, PCH_P2SB_EPMASK(epmask_id
));
92 pci_write_config32(PCH_DEV_P2SB
, PCH_P2SB_EPMASK(epmask_id
),
96 static void p2sb_lock_endpoints(void)
100 /* Set the "Endpoint Mask Lock!", P2SB PCI offset E2h bit[1] to 1. */
101 reg8
= pci_read_config8(PCH_DEV_P2SB
, PCH_P2SB_E0
+ 2);
102 pci_write_config8(PCH_DEV_P2SB
, PCH_P2SB_E0
+ 2,
103 reg8
| P2SB_E0_MASKLOCK
);
106 void p2sb_disable_sideband_access(void)
108 uint32_t ep_mask
[P2SB_EP_MASK_MAX_REG
];
111 memset(ep_mask
, 0, sizeof(ep_mask
));
113 p2sb_soc_get_sb_mask(ep_mask
, ARRAY_SIZE(ep_mask
));
115 /* Remove the host accessing right to PSF register range. */
116 for (i
= 0; i
< P2SB_EP_MASK_MAX_REG
; i
++)
117 p2sb_configure_endpoints(i
, ep_mask
[i
]);
119 p2sb_lock_endpoints();
122 static void read_resources(struct device
*dev
)
125 * There's only one resource on the P2SB device. It's also already
126 * manually set to a fixed address in earlier boot stages.
127 * The following code makes sure that it doesn't change if the device
128 * is visible and the resource allocator is being run.
130 mmio_range(dev
, PCI_BASE_ADDRESS_0
, P2SB_BAR
, P2SB_SIZE
);
133 const struct device_operations p2sb_ops
= {
134 .read_resources
= read_resources
,
135 .set_resources
= noop_set_resources
,
136 .ops_pci
= &pci_dev_ops_pci
,
139 static const unsigned short pci_device_ids
[] = {
140 PCI_DID_INTEL_PTL_H_P2SB
,
141 PCI_DID_INTEL_PTL_U_H_P2SB
,
142 PCI_DID_INTEL_LNL_P2SB
,
143 PCI_DID_INTEL_MTL_SOC_P2SB
,
144 PCI_DID_INTEL_RPP_P_P2SB
,
145 PCI_DID_INTEL_APL_P2SB
,
146 PCI_DID_INTEL_GLK_P2SB
,
147 PCI_DID_INTEL_LWB_P2SB
,
148 PCI_DID_INTEL_LWB_P2SB_SUPER
,
149 PCI_DID_INTEL_CNL_P2SB
,
150 PCI_DID_INTEL_CNP_H_P2SB
,
151 PCI_DID_INTEL_CMP_P2SB
,
152 PCI_DID_INTEL_CMP_H_P2SB
,
153 PCI_DID_INTEL_TGL_P2SB
,
154 PCI_DID_INTEL_TGL_H_P2SB
,
155 PCI_DID_INTEL_EHL_P2SB
,
156 PCI_DID_INTEL_JSP_P2SB
,
157 PCI_DID_INTEL_ADP_P_P2SB
,
158 PCI_DID_INTEL_ADP_S_P2SB
,
159 PCI_DID_INTEL_ADP_M_P2SB
,
160 PCI_DID_INTEL_SPR_SP_P2SB
,
161 PCI_DID_INTEL_RPP_S_P2SB
,
162 PCI_DID_INTEL_SNR_P2SB
,
166 static const struct pci_driver pmc __pci_driver
= {
168 .vendor
= PCI_VID_INTEL
,
169 .devices
= pci_device_ids
,