blob: e1a5bc2ef839a2daa229f4196185b16f529d9005 [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))
53 die_with_post_code(POST_HW_INIT_FAILURE,
54 "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))
62 die_with_post_code(POST_HW_INIT_FAILURE,
63 "Unable to hide the P2SB device!\n");
64}
65
66static void p2sb_execute_sideband_access(pci_devfn_t dev, uint8_t cmd, uint8_t pid,
67 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
81 /* Unhide the P2SB device */
82 p2sb_dev_unhide(dev);
83
84 status = pcr_execute_sideband_msg(dev, &msg, data, &response);
85 if (status || response)
86 printk(BIOS_ERR, "Fail to execute p2sb sideband access\n");
87
88 /* Hide the P2SB device */
89 p2sb_dev_hide(dev);
90}
91
92uint32_t p2sb_dev_sbi_read(pci_devfn_t dev, uint8_t pid, uint16_t reg)
93{
94 uint32_t val = 0;
95 p2sb_execute_sideband_access(dev, PCR_READ, pid, reg, &val);
96 return val;
97}
98
99void p2sb_dev_sbi_write(pci_devfn_t dev, uint8_t pid, uint16_t reg, uint32_t val)
100{
101 p2sb_execute_sideband_access(dev, PCR_WRITE, pid, reg, &val);
102}