1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #define __SIMPLE_DEVICE__
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>
13 void p2sb_dev_enable_bar(pci_devfn_t dev
, uint64_t bar
)
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));
20 pci_write_config16(dev
, PCI_COMMAND
, PCI_COMMAND_MASTER
| PCI_COMMAND_MEMORY
);
23 bool p2sb_dev_is_hidden(pci_devfn_t dev
)
25 const uint16_t pci_vid
= pci_read_config16(dev
, PCI_VENDOR_ID
);
27 if (pci_vid
== 0xffff)
29 if (pci_vid
== PCI_VID_INTEL
)
31 printk(BIOS_ERR
, "P2SB PCI_VENDOR_ID is invalid, unknown if hidden\n");
35 static void p2sb_dev_set_hide_bit(pci_devfn_t dev
, int hide
)
37 const uint16_t reg
= P2SBC
+ 1;
38 const uint8_t mask
= P2SBC_HIDE_BIT
;
41 val
= pci_read_config8(dev
, reg
);
45 pci_write_config8(dev
, reg
, val
);
48 void p2sb_dev_unhide(pci_devfn_t dev
)
50 p2sb_dev_set_hide_bit(dev
, 0);
52 if (p2sb_dev_is_hidden(dev
))
53 die_with_post_code(POSTCODE_HW_INIT_FAILURE
,
54 "Unable to unhide the P2SB device!\n");
57 void p2sb_dev_hide(pci_devfn_t dev
)
59 p2sb_dev_set_hide_bit(dev
, 1);
61 if (!p2sb_dev_is_hidden(dev
))
62 die_with_post_code(POSTCODE_HW_INIT_FAILURE
,
63 "Unable to hide the P2SB device!\n");
66 static void p2sb_send_sideband_msg(pci_devfn_t dev
, uint8_t cmd
, uint8_t pid
,
67 uint16_t reg
, uint32_t *data
)
69 struct pcr_sbi_msg msg
= {
74 .fast_byte_enable
= 0xF,
81 status
= pcr_execute_sideband_msg(dev
, &msg
, data
, &response
);
82 if (status
|| response
)
83 printk(BIOS_ERR
, "Fail to execute p2sb sideband access\n");
86 static void p2sb_execute_sbi_in_smm(pci_devfn_t dev
, uint8_t cmd
, uint8_t pid
,
87 uint16_t reg
, uint32_t *data
)
89 /* Unhide the P2SB device */
92 p2sb_send_sideband_msg(dev
, cmd
, pid
, reg
, data
);
94 /* Hide the P2SB device */
98 static void p2sb_execute_sideband_access(pci_devfn_t dev
, uint8_t cmd
, uint8_t pid
,
99 uint16_t reg
, uint32_t *data
)
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.
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
);
112 printk(BIOS_WARNING
, "Error: P2SB must be hidden, try calling from SMM!\n");
115 uint32_t p2sb_dev_sbi_read(pci_devfn_t dev
, uint8_t pid
, uint16_t reg
)
118 p2sb_execute_sideband_access(dev
, PCR_READ
, pid
, reg
, &val
);
122 void p2sb_dev_sbi_write(pci_devfn_t dev
, uint8_t pid
, uint16_t reg
, uint32_t val
)
124 p2sb_execute_sideband_access(dev
, PCR_WRITE
, pid
, reg
, &val
);