blob: faef79adfd151325d222e83e91fd5143df185a9a [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
13bool p2sb_dev_is_hidden(pci_devfn_t dev)
14{
15 const uint16_t pci_vid = pci_read_config16(dev, PCI_VENDOR_ID);
16
17 if (pci_vid == 0xffff)
18 return true;
Felix Singer43b7f412022-03-07 04:34:52 +010019 if (pci_vid == PCI_VID_INTEL)
John Zhao41aa8d62022-01-20 11:29:18 -080020 return false;
21 printk(BIOS_ERR, "P2SB PCI_VENDOR_ID is invalid, unknown if hidden\n");
22 return true;
23}
24
25static void p2sb_dev_set_hide_bit(pci_devfn_t dev, int hide)
26{
27 const uint16_t reg = P2SBC + 1;
28 const uint8_t mask = P2SBC_HIDE_BIT;
29 uint8_t val;
30
31 val = pci_read_config8(dev, reg);
32 val &= ~mask;
33 if (hide)
34 val |= mask;
35 pci_write_config8(dev, reg, val);
36}
37
38void p2sb_dev_unhide(pci_devfn_t dev)
39{
40 p2sb_dev_set_hide_bit(dev, 0);
41
42 if (p2sb_dev_is_hidden(dev))
43 die_with_post_code(POST_HW_INIT_FAILURE,
44 "Unable to unhide the P2SB device!\n");
45}
46
47void p2sb_dev_hide(pci_devfn_t dev)
48{
49 p2sb_dev_set_hide_bit(dev, 1);
50
51 if (!p2sb_dev_is_hidden(dev))
52 die_with_post_code(POST_HW_INIT_FAILURE,
53 "Unable to hide the P2SB device!\n");
54}
55
56static void p2sb_execute_sideband_access(pci_devfn_t dev, uint8_t cmd, uint8_t pid,
57 uint16_t reg, uint32_t *data)
58{
59 struct pcr_sbi_msg msg = {
60 .pid = pid,
61 .offset = reg,
62 .opcode = cmd,
63 .is_posted = false,
64 .fast_byte_enable = 0xF,
65 .bar = 0,
66 .fid = 0
67 };
68 uint8_t response;
69 int status;
70
71 /* Unhide the P2SB device */
72 p2sb_dev_unhide(dev);
73
74 status = pcr_execute_sideband_msg(dev, &msg, data, &response);
75 if (status || response)
76 printk(BIOS_ERR, "Fail to execute p2sb sideband access\n");
77
78 /* Hide the P2SB device */
79 p2sb_dev_hide(dev);
80}
81
82uint32_t p2sb_dev_sbi_read(pci_devfn_t dev, uint8_t pid, uint16_t reg)
83{
84 uint32_t val = 0;
85 p2sb_execute_sideband_access(dev, PCR_READ, pid, reg, &val);
86 return val;
87}
88
89void p2sb_dev_sbi_write(pci_devfn_t dev, uint8_t pid, uint16_t reg, uint32_t val)
90{
91 p2sb_execute_sideband_access(dev, PCR_WRITE, pid, reg, &val);
92}