blob: 94db33d2fe8ce074210daccc3011dec4a138aa05 [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{
21 /* Enable PCR Base address in PCH */
Nico Hubere5495032020-02-17 18:26:51 +010022 pci_write_config32(PCH_DEV_P2SB, PCI_BASE_ADDRESS_0, P2SB_BAR);
23 pci_write_config32(PCH_DEV_P2SB, PCI_BASE_ADDRESS_1, 0);
Subrata Banik7837c202018-05-07 17:13:40 +053024
25 /* Enable P2SB MSE */
Elyes HAOUAS2ec1c132020-04-29 09:57:05 +020026 pci_write_config16(PCH_DEV_P2SB, PCI_COMMAND,
Subrata Banik7837c202018-05-07 17:13:40 +053027 PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
28}
29
30/*
31 * Enable decoding for HPET range.
32 * This is needed for FspMemoryInit to store and retrieve a global data
33 * pointer.
34 */
35void p2sb_configure_hpet(void)
36{
37 /*
38 * Enable decoding for HPET memory address range.
39 * HPTC_OFFSET(0x60) bit 7, when set the P2SB will decode
40 * the High Performance Timer memory address range
41 * selected by bits 1:0
42 */
Nico Hubere5495032020-02-17 18:26:51 +010043 pci_write_config8(PCH_DEV_P2SB, HPTC_OFFSET, HPTC_ADDR_ENABLE_BIT);
Subrata Banik7837c202018-05-07 17:13:40 +053044}
45
Arthur Heymansf629f7b2020-11-12 21:00:03 +010046union p2sb_bdf p2sb_get_hpet_bdf(void)
47{
John Zhao41aa8d62022-01-20 11:29:18 -080048 const bool was_hidden = p2sb_dev_is_hidden(PCH_DEV_P2SB);
Arthur Heymansf629f7b2020-11-12 21:00:03 +010049 if (was_hidden)
50 p2sb_unhide();
51
52 union p2sb_bdf bdf = { .raw = pci_read_config16(PCH_DEV_P2SB, PCH_P2SB_HBDF) };
53
54 if (was_hidden)
55 p2sb_hide();
56
57 return bdf;
58}
59
60void p2sb_set_hpet_bdf(union p2sb_bdf bdf)
61{
62 pci_write_config16(PCH_DEV_P2SB, PCH_P2SB_HBDF, bdf.raw);
63}
64
Arthur Heymansa1f65be2020-11-12 21:07:13 +010065union p2sb_bdf p2sb_get_ioapic_bdf(void)
66{
John Zhao41aa8d62022-01-20 11:29:18 -080067 const bool was_hidden = p2sb_dev_is_hidden(PCH_DEV_P2SB);
Arthur Heymansa1f65be2020-11-12 21:07:13 +010068 if (was_hidden)
69 p2sb_unhide();
70
71 union p2sb_bdf bdf = { .raw = pci_read_config16(PCH_DEV_P2SB, PCH_P2SB_IBDF) };
72
73 if (was_hidden)
74 p2sb_hide();
75
76 return bdf;
77}
78
79void p2sb_set_ioapic_bdf(union p2sb_bdf bdf)
80{
81 pci_write_config16(PCH_DEV_P2SB, PCH_P2SB_IBDF, bdf.raw);
82}
83
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -070084void p2sb_unhide(void)
85{
John Zhao41aa8d62022-01-20 11:29:18 -080086 p2sb_dev_unhide(PCH_DEV_P2SB);
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -070087}
88
89void p2sb_hide(void)
90{
John Zhao41aa8d62022-01-20 11:29:18 -080091 p2sb_dev_hide(PCH_DEV_P2SB);
Subrata Banik7837c202018-05-07 17:13:40 +053092}
93
94static void p2sb_configure_endpoints(int epmask_id, uint32_t mask)
95{
96 uint32_t reg32;
97
Nico Hubere5495032020-02-17 18:26:51 +010098 reg32 = pci_read_config32(PCH_DEV_P2SB, PCH_P2SB_EPMASK(epmask_id));
99 pci_write_config32(PCH_DEV_P2SB, PCH_P2SB_EPMASK(epmask_id),
Subrata Banik7837c202018-05-07 17:13:40 +0530100 reg32 | mask);
101}
102
103static void p2sb_lock_endpoints(void)
104{
105 uint8_t reg8;
106
107 /* Set the "Endpoint Mask Lock!", P2SB PCI offset E2h bit[1] to 1. */
Nico Hubere5495032020-02-17 18:26:51 +0100108 reg8 = pci_read_config8(PCH_DEV_P2SB, PCH_P2SB_E0 + 2);
109 pci_write_config8(PCH_DEV_P2SB, PCH_P2SB_E0 + 2,
Subrata Banik7837c202018-05-07 17:13:40 +0530110 reg8 | P2SB_E0_MASKLOCK);
111}
112
113void p2sb_disable_sideband_access(void)
114{
115 uint32_t ep_mask[P2SB_EP_MASK_MAX_REG];
116 int i;
117
118 memset(ep_mask, 0, sizeof(ep_mask));
119
120 p2sb_soc_get_sb_mask(ep_mask, ARRAY_SIZE(ep_mask));
121
122 /* Remove the host accessing right to PSF register range. */
123 for (i = 0; i < P2SB_EP_MASK_MAX_REG; i++)
124 p2sb_configure_endpoints(i, ep_mask[i]);
125
126 p2sb_lock_endpoints();
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -0700127}
128
129static void read_resources(struct device *dev)
130{
131 /*
132 * There's only one resource on the P2SB device. It's also already
133 * manually set to a fixed address in earlier boot stages.
Patrick Rudolph8d7a89b2019-10-04 09:22:27 +0200134 * The following code makes sure that it doesn't change if the device
135 * is visible and the resource allocator is being run.
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -0700136 */
137 mmio_resource(dev, PCI_BASE_ADDRESS_0, P2SB_BAR / KiB, P2SB_SIZE / KiB);
138}
139
140static const struct device_operations device_ops = {
141 .read_resources = read_resources,
Nico Huber2f8ba692020-04-05 14:05:24 +0200142 .set_resources = noop_set_resources,
Subrata Banik6bbc91a2017-12-07 14:55:51 +0530143 .ops_pci = &pci_dev_ops_pci,
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -0700144};
145
146static const unsigned short pci_device_ids[] = {
Wonkyu Kim9f401072020-11-13 15:16:32 -0800147 PCI_DID_INTEL_MTL_SOC_P2SB,
148 PCI_DID_INTEL_MTL_IOE_M_P2SB,
149 PCI_DID_INTEL_MTL_IOE_P_P2SB,
Felix Singer43b7f412022-03-07 04:34:52 +0100150 PCI_DID_INTEL_APL_P2SB,
151 PCI_DID_INTEL_GLK_P2SB,
152 PCI_DID_INTEL_LWB_P2SB,
153 PCI_DID_INTEL_LWB_P2SB_SUPER,
154 PCI_DID_INTEL_SKL_LP_P2SB,
155 PCI_DID_INTEL_SKL_P2SB,
156 PCI_DID_INTEL_KBL_P2SB,
157 PCI_DID_INTEL_CNL_P2SB,
158 PCI_DID_INTEL_CNP_H_P2SB,
159 PCI_DID_INTEL_ICL_P2SB,
160 PCI_DID_INTEL_CMP_P2SB,
161 PCI_DID_INTEL_CMP_H_P2SB,
162 PCI_DID_INTEL_TGL_P2SB,
163 PCI_DID_INTEL_TGL_H_P2SB,
164 PCI_DID_INTEL_EHL_P2SB,
165 PCI_DID_INTEL_JSP_P2SB,
166 PCI_DID_INTEL_ADP_P_P2SB,
167 PCI_DID_INTEL_ADP_S_P2SB,
168 PCI_DID_INTEL_ADP_M_P2SB,
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -0700169 0,
170};
171
172static const struct pci_driver pmc __pci_driver = {
173 .ops = &device_ops,
Felix Singer43b7f412022-03-07 04:34:52 +0100174 .vendor = PCI_VID_INTEL,
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -0700175 .devices = pci_device_ids,
176};