blob: 70fbcaa147cd3d8d85e1bb49343a91a54cb82d6c [file] [log] [blame]
John Zhao41aa8d62022-01-20 11:29:18 -08001/* SPDX-License-Identifier: GPL-2.0-only */
2
3#define __SIMPLE_DEVICE__
4
5#include <console/console.h>
6#include <device/pci.h>
7#include <device/pci_ids.h>
8#include <intelblocks/p2sb.h>
9#include <intelblocks/p2sblib.h>
10#include <intelblocks/pcr.h>
11#include <soc/pci_devs.h>
12
Subrata Banik7c477a92022-03-14 12:47:31 +053013void p2sb_dev_enable_bar(pci_devfn_t dev, uint64_t bar)
14{
15 /* Enable PCR Base addresses */
16 pci_write_config32(dev, PCI_BASE_ADDRESS_0, (uint32_t)bar);
17 pci_write_config32(dev, PCI_BASE_ADDRESS_1, (uint32_t)(bar >> 32));
18
19 /* Enable P2SB MSE */
20 pci_write_config16(dev, PCI_COMMAND, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
21}
22
John Zhao41aa8d62022-01-20 11:29:18 -080023bool p2sb_dev_is_hidden(pci_devfn_t dev)
24{
25 const uint16_t pci_vid = pci_read_config16(dev, PCI_VENDOR_ID);
26
27 if (pci_vid == 0xffff)
28 return true;
Felix Singer43b7f412022-03-07 04:34:52 +010029 if (pci_vid == PCI_VID_INTEL)
John Zhao41aa8d62022-01-20 11:29:18 -080030 return false;
31 printk(BIOS_ERR, "P2SB PCI_VENDOR_ID is invalid, unknown if hidden\n");
32 return true;
33}
34
35static void p2sb_dev_set_hide_bit(pci_devfn_t dev, int hide)
36{
37 const uint16_t reg = P2SBC + 1;
38 const uint8_t mask = P2SBC_HIDE_BIT;
39 uint8_t val;
40
41 val = pci_read_config8(dev, reg);
42 val &= ~mask;
43 if (hide)
44 val |= mask;
45 pci_write_config8(dev, reg, val);
46}
47
48void p2sb_dev_unhide(pci_devfn_t dev)
49{
50 p2sb_dev_set_hide_bit(dev, 0);
51
52 if (p2sb_dev_is_hidden(dev))
lilacious40cb3fe2023-06-21 23:24:14 +020053 die_with_post_code(POSTCODE_HW_INIT_FAILURE,
John Zhao41aa8d62022-01-20 11:29:18 -080054 "Unable to unhide the P2SB device!\n");
55}
56
57void p2sb_dev_hide(pci_devfn_t dev)
58{
59 p2sb_dev_set_hide_bit(dev, 1);
60
61 if (!p2sb_dev_is_hidden(dev))
lilacious40cb3fe2023-06-21 23:24:14 +020062 die_with_post_code(POSTCODE_HW_INIT_FAILURE,
John Zhao41aa8d62022-01-20 11:29:18 -080063 "Unable to hide the P2SB device!\n");
64}
65
Subrata Banik6f7875f2022-08-23 02:27:58 +053066static void p2sb_send_sideband_msg(pci_devfn_t dev, uint8_t cmd, uint8_t pid,
John Zhao41aa8d62022-01-20 11:29:18 -080067 uint16_t reg, uint32_t *data)
68{
69 struct pcr_sbi_msg msg = {
70 .pid = pid,
71 .offset = reg,
72 .opcode = cmd,
73 .is_posted = false,
74 .fast_byte_enable = 0xF,
75 .bar = 0,
76 .fid = 0
77 };
78 uint8_t response;
79 int status;
80
John Zhao41aa8d62022-01-20 11:29:18 -080081 status = pcr_execute_sideband_msg(dev, &msg, data, &response);
82 if (status || response)
83 printk(BIOS_ERR, "Fail to execute p2sb sideband access\n");
Subrata Banik6f7875f2022-08-23 02:27:58 +053084}
85
86static void p2sb_execute_sbi_in_smm(pci_devfn_t dev, uint8_t cmd, uint8_t pid,
87 uint16_t reg, uint32_t *data)
88{
89 /* Unhide the P2SB device */
90 p2sb_dev_unhide(dev);
91
92 p2sb_send_sideband_msg(dev, cmd, pid, reg, data);
John Zhao41aa8d62022-01-20 11:29:18 -080093
94 /* Hide the P2SB device */
95 p2sb_dev_hide(dev);
96}
97
Subrata Banik6f7875f2022-08-23 02:27:58 +053098static void p2sb_execute_sideband_access(pci_devfn_t dev, uint8_t cmd, uint8_t pid,
99 uint16_t reg, uint32_t *data)
100{
101 if (ENV_SMM)
102 /*
103 * FSP-S will hide the P2SB device. With the device hidden, we will not be
104 * able to send the sideband interface message. Therefore, we need to unhide
105 * the P2SB device which can only be done in SMM requiring that this
106 * function is called from SMM.
107 */
108 p2sb_execute_sbi_in_smm(dev, cmd, pid, reg, data);
109 else if (!p2sb_dev_is_hidden(dev))
110 p2sb_send_sideband_msg(dev, cmd, pid, reg, data);
111 else
112 printk(BIOS_WARNING, "Error: P2SB must be hidden, try calling from SMM!\n");
113}
114
John Zhao41aa8d62022-01-20 11:29:18 -0800115uint32_t p2sb_dev_sbi_read(pci_devfn_t dev, uint8_t pid, uint16_t reg)
116{
117 uint32_t val = 0;
118 p2sb_execute_sideband_access(dev, PCR_READ, pid, reg, &val);
119 return val;
120}
121
122void p2sb_dev_sbi_write(pci_devfn_t dev, uint8_t pid, uint16_t reg, uint32_t val)
123{
124 p2sb_execute_sideband_access(dev, PCR_WRITE, pid, reg, &val);
125}