blob: 981ad078720bb8964566064038f054d490d66a84 [file] [log] [blame]
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -07001/*
2 * This file is part of the coreboot project.
3 *
Subrata Banik7837c202018-05-07 17:13:40 +05304 * Copyright (C) 2016 Google Inc.
5 * Copyright (C) 2018 Intel Corporation.
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -07006 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
Kyösti Mälkkif1b58b72019-03-01 13:43:02 +020017#include <device/pci_ops.h>
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -070018#include <console/console.h>
19#include <device/device.h>
20#include <device/pci.h>
21#include <device/pci_ids.h>
Subrata Banik7837c202018-05-07 17:13:40 +053022#include <intelblocks/p2sb.h>
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -070023#include <soc/iomap.h>
Subrata Banik7837c202018-05-07 17:13:40 +053024#include <soc/p2sb.h>
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -070025#include <soc/pci_devs.h>
Subrata Banik7837c202018-05-07 17:13:40 +053026#include <string.h>
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -070027
Subrata Banik7837c202018-05-07 17:13:40 +053028#define PCH_P2SB_EPMASK(mask_number) (PCH_P2SB_EPMASK0 + ((mask_number) * 4))
29
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -070030#define HIDE_BIT (1 << 0)
31
Subrata Banik7837c202018-05-07 17:13:40 +053032#if defined(__SIMPLE_DEVICE__)
33static pci_devfn_t p2sb_get_device(void)
34{
35 int devfn = PCH_DEVFN_P2SB;
36 pci_devfn_t dev = PCI_DEV(0, PCI_SLOT(devfn), PCI_FUNC(devfn));
37
38 if (dev == PCI_DEV_INVALID)
Keith Short15588b02019-05-09 11:40:34 -060039 die_with_post_code(POST_HW_INIT_FAILURE,
40 "PCH_DEV_P2SB not found!\n");
Subrata Banik7837c202018-05-07 17:13:40 +053041
42 return dev;
43}
44#else
45static struct device *p2sb_get_device(void)
46{
47 struct device *dev = PCH_DEV_P2SB;
48 if (!dev)
Keith Short15588b02019-05-09 11:40:34 -060049 die_with_post_code(POST_HW_INIT_FAILURE,
50 "PCH_DEV_P2SB not found!\n");
Subrata Banik7837c202018-05-07 17:13:40 +053051
52 return dev;
53}
54#endif
55
56#define P2SB_GET_DEV p2sb_get_device()
57
58void p2sb_enable_bar(void)
59{
60 /* Enable PCR Base address in PCH */
61 pci_write_config32(P2SB_GET_DEV, PCI_BASE_ADDRESS_0, P2SB_BAR);
62 pci_write_config32(P2SB_GET_DEV, PCI_BASE_ADDRESS_1, 0);
63
64 /* Enable P2SB MSE */
65 pci_write_config8(P2SB_GET_DEV, PCI_COMMAND,
66 PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
67}
68
69/*
70 * Enable decoding for HPET range.
71 * This is needed for FspMemoryInit to store and retrieve a global data
72 * pointer.
73 */
74void p2sb_configure_hpet(void)
75{
76 /*
77 * Enable decoding for HPET memory address range.
78 * HPTC_OFFSET(0x60) bit 7, when set the P2SB will decode
79 * the High Performance Timer memory address range
80 * selected by bits 1:0
81 */
82 pci_write_config8(P2SB_GET_DEV, HPTC_OFFSET, HPTC_ADDR_ENABLE_BIT);
83}
84
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -070085static void p2sb_set_hide_bit(int hide)
86{
Subrata Banik7837c202018-05-07 17:13:40 +053087 const uint16_t reg = PCH_P2SB_E0 + 1;
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -070088 const uint8_t mask = HIDE_BIT;
89 uint8_t val;
90
Subrata Banik7837c202018-05-07 17:13:40 +053091 val = pci_read_config8(P2SB_GET_DEV, reg);
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -070092 val &= ~mask;
93 if (hide)
94 val |= mask;
Subrata Banik7837c202018-05-07 17:13:40 +053095 pci_write_config8(P2SB_GET_DEV, reg, val);
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -070096}
97
98void p2sb_unhide(void)
99{
100 p2sb_set_hide_bit(0);
Subrata Banik7837c202018-05-07 17:13:40 +0530101
102 if (pci_read_config16(P2SB_GET_DEV, PCI_VENDOR_ID) !=
103 PCI_VENDOR_ID_INTEL)
Keith Short15588b02019-05-09 11:40:34 -0600104 die_with_post_code(POST_HW_INIT_FAILURE,
105 "Unable to unhide PCH_DEV_P2SB device !\n");
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -0700106}
107
108void p2sb_hide(void)
109{
110 p2sb_set_hide_bit(1);
Subrata Banik7837c202018-05-07 17:13:40 +0530111
112 if (pci_read_config16(P2SB_GET_DEV, PCI_VENDOR_ID) !=
113 0xFFFF)
Keith Short15588b02019-05-09 11:40:34 -0600114 die_with_post_code(POST_HW_INIT_FAILURE,
115 "Unable to hide PCH_DEV_P2SB device !\n");
Subrata Banik7837c202018-05-07 17:13:40 +0530116}
117
118static void p2sb_configure_endpoints(int epmask_id, uint32_t mask)
119{
120 uint32_t reg32;
121
122 reg32 = pci_read_config32(P2SB_GET_DEV, PCH_P2SB_EPMASK(epmask_id));
123 pci_write_config32(P2SB_GET_DEV, PCH_P2SB_EPMASK(epmask_id),
124 reg32 | mask);
125}
126
127static void p2sb_lock_endpoints(void)
128{
129 uint8_t reg8;
130
131 /* Set the "Endpoint Mask Lock!", P2SB PCI offset E2h bit[1] to 1. */
132 reg8 = pci_read_config8(P2SB_GET_DEV, PCH_P2SB_E0 + 2);
133 pci_write_config8(P2SB_GET_DEV, PCH_P2SB_E0 + 2,
134 reg8 | P2SB_E0_MASKLOCK);
135}
136
137void p2sb_disable_sideband_access(void)
138{
139 uint32_t ep_mask[P2SB_EP_MASK_MAX_REG];
140 int i;
141
142 memset(ep_mask, 0, sizeof(ep_mask));
143
144 p2sb_soc_get_sb_mask(ep_mask, ARRAY_SIZE(ep_mask));
145
146 /* Remove the host accessing right to PSF register range. */
147 for (i = 0; i < P2SB_EP_MASK_MAX_REG; i++)
148 p2sb_configure_endpoints(i, ep_mask[i]);
149
150 p2sb_lock_endpoints();
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -0700151}
152
153static void read_resources(struct device *dev)
154{
155 /*
156 * There's only one resource on the P2SB device. It's also already
157 * manually set to a fixed address in earlier boot stages.
Patrick Rudolph8d7a89b2019-10-04 09:22:27 +0200158 * The following code makes sure that it doesn't change if the device
159 * is visible and the resource allocator is being run.
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -0700160 */
161 mmio_resource(dev, PCI_BASE_ADDRESS_0, P2SB_BAR / KiB, P2SB_SIZE / KiB);
162}
163
164static const struct device_operations device_ops = {
165 .read_resources = read_resources,
166 .set_resources = DEVICE_NOOP,
Subrata Banik6bbc91a2017-12-07 14:55:51 +0530167 .ops_pci = &pci_dev_ops_pci,
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -0700168};
169
170static const unsigned short pci_device_ids[] = {
171 PCI_DEVICE_ID_INTEL_APL_P2SB,
172 PCI_DEVICE_ID_INTEL_GLK_P2SB,
Maxim Polyakov571d07d2019-08-22 13:11:32 +0300173 PCI_DEVICE_ID_INTEL_LWB_P2SB,
174 PCI_DEVICE_ID_INTEL_LWB_P2SB_SUPER,
Patrick Rudolph8d7a89b2019-10-04 09:22:27 +0200175 PCI_DEVICE_ID_INTEL_SKL_LP_P2SB,
176 PCI_DEVICE_ID_INTEL_SKL_P2SB,
177 PCI_DEVICE_ID_INTEL_KBL_P2SB,
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -0700178 PCI_DEVICE_ID_INTEL_CNL_P2SB,
praveen hodagatta praneshe26c4a42018-09-20 03:49:45 +0800179 PCI_DEVICE_ID_INTEL_CNP_H_P2SB,
Aamir Bohra9eac0392018-06-30 12:07:04 +0530180 PCI_DEVICE_ID_INTEL_ICL_P2SB,
Ronak Kanabarda7ffb482019-02-05 01:51:13 +0530181 PCI_DEVICE_ID_INTEL_CMP_P2SB,
Ravi Sarawadi6b5bf402019-10-21 22:25:04 -0700182 PCI_DEVICE_ID_INTEL_TGL_P2SB,
Lijian Zhaoa3cbbf72017-10-26 11:59:14 -0700183 0,
184};
185
186static const struct pci_driver pmc __pci_driver = {
187 .ops = &device_ops,
188 .vendor = PCI_VENDOR_ID_INTEL,
189 .devices = pci_device_ids,
190};