blob: 0716e1ae90a65ab684f8a305ac2feef8bdf10dc8 [file] [log] [blame]
Patrick Georgiac959032020-05-05 22:49:26 +02001/* SPDX-License-Identifier: GPL-2.0-or-later */
Subrata Banik6c4b5912017-11-07 16:10:05 +05302
Sridhar Siricillab017a432022-03-23 00:19:01 +05303#define __SIMPLE_DEVICE__
4
Subrata Banik6c4b5912017-11-07 16:10:05 +05305#include <device/device.h>
Sridhar Siricillab017a432022-03-23 00:19:01 +05306#include <device/mmio.h>
Subrata Banik6c4b5912017-11-07 16:10:05 +05307#include <device/pci.h>
8#include <device/pci_ids.h>
Sridhar Siricillab017a432022-03-23 00:19:01 +05309#include <device/pci_ops.h>
Subrata Banik6c4b5912017-11-07 16:10:05 +053010#include <device/spi.h>
11#include <intelblocks/fast_spi.h>
12#include <intelblocks/gspi.h>
13#include <intelblocks/spi.h>
14#include <soc/pci_devs.h>
15#include <spi-generic.h>
16
17const struct spi_ctrlr_buses spi_ctrlr_bus_map[] = {
18 { .ctrlr = &fast_spi_flash_ctrlr, .bus_start = 0, .bus_end = 0 },
Julius Wernercd49cce2019-03-05 16:53:33 -080019#if !ENV_SMM && CONFIG(SOC_INTEL_COMMON_BLOCK_GSPI)
Subrata Banik6c4b5912017-11-07 16:10:05 +053020 { .ctrlr = &gspi_ctrlr, .bus_start = 1,
21 .bus_end = 1 + (CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX - 1)},
22#endif
23};
24
25const size_t spi_ctrlr_bus_map_count = ARRAY_SIZE(spi_ctrlr_bus_map);
26
Sridhar Siricillab017a432022-03-23 00:19:01 +053027#define MMIO_BIOS_GPR0 0x98
28
29union spi_bios_gpr0 {
30 struct {
31 /* Specified write protection is enabled */
32 /*
33 * This field corresponds to flash address bits 26:12
34 * and specifies the lower limit of protected range.
35 */
36 uint32_t protect_range_base:15;
37
38 /* Specifies read protection is enabled */
39 uint32_t read_protect_en:1;
40
41 /*
42 * This field corresponds to flash address bits 26:12
43 * and specifies the upper limit of the protected range
44 */
45 uint32_t protect_range_limit:15;
46
47 uint32_t write_protect_en:1;
48 } __packed fields;
49
50 uint32_t data;
51};
52
53/* Read SPI BAR 0 from PCI configuration space */
54static uintptr_t get_spi_bar(pci_devfn_t dev)
55{
56 uintptr_t bar;
57
58 bar = pci_read_config32(dev, PCI_BASE_ADDRESS_0);
59 assert(bar != 0);
60 /*
61 * Bits 31-12 are the base address as per EDS for SPI,
62 * Don't care about 0-11 bit
63 */
64 return bar & ~PCI_BASE_ADDRESS_MEM_ATTR_MASK;
65}
66
67static uint32_t spi_read_bar(pci_devfn_t dev, uint32_t offset)
68{
69 return read32p(get_spi_bar(dev) + offset);
70}
71
72static uint32_t spi_read_bios_gpr0(void)
73{
74 return spi_read_bar(PCH_DEV_SPI, MMIO_BIOS_GPR0);
75}
76
77static uint32_t spi_get_wp_cse_ro_start_offset(union spi_bios_gpr0 bios_gpr0)
78{
79 return bios_gpr0.fields.protect_range_base << 12;
80}
81
82static uint32_t spi_get_wp_cse_ro_limit(union spi_bios_gpr0 bios_gpr0)
83{
84 return bios_gpr0.fields.protect_range_limit << 12 | 0xfff;
85}
86
87bool is_spi_wp_cse_ro_en(void)
88{
89 union spi_bios_gpr0 bios_gpr0;
90
91 bios_gpr0.data = spi_read_bios_gpr0();
92 return !!bios_gpr0.fields.write_protect_en;
93}
94
95void spi_get_wp_cse_ro_range(uint32_t *base, uint32_t *limit)
96{
97 union spi_bios_gpr0 bios_gpr0;
98
99 bios_gpr0.data = spi_read_bios_gpr0();
100 *base = spi_get_wp_cse_ro_start_offset(bios_gpr0);
101 *limit = spi_get_wp_cse_ro_limit(bios_gpr0);
102}
103
Subrata Banik6c4b5912017-11-07 16:10:05 +0530104static int spi_dev_to_bus(struct device *dev)
105{
106 return spi_soc_devfn_to_bus(dev->path.pci.devfn);
107}
108
109static struct spi_bus_operations spi_bus_ops = {
110 .dev_to_bus = &spi_dev_to_bus,
111};
112
113static struct device_operations spi_dev_ops = {
Elyes HAOUAS1d191272018-11-27 12:23:48 +0100114 .read_resources = pci_dev_read_resources,
115 .set_resources = pci_dev_set_resources,
116 .enable_resources = pci_dev_enable_resources,
117 .scan_bus = scan_generic_bus,
Subrata Banik6c4b5912017-11-07 16:10:05 +0530118 .ops_spi_bus = &spi_bus_ops,
Subrata Banik6bbc91a2017-12-07 14:55:51 +0530119 .ops_pci = &pci_dev_ops_pci,
Subrata Banik6c4b5912017-11-07 16:10:05 +0530120};
121
122static const unsigned short pci_device_ids[] = {
Wonkyu Kim9f401072020-11-13 15:16:32 -0800123 PCI_DID_INTEL_MTL_HWSEQ_SPI,
124 PCI_DID_INTEL_MTL_GSPI0,
125 PCI_DID_INTEL_MTL_GSPI1,
126 PCI_DID_INTEL_MTL_GSPI2,
Felix Singer43b7f412022-03-07 04:34:52 +0100127 PCI_DID_INTEL_SPT_SPI1,
128 PCI_DID_INTEL_SPT_SPI2,
129 PCI_DID_INTEL_SPT_SPI3,
130 PCI_DID_INTEL_APL_SPI0,
131 PCI_DID_INTEL_APL_SPI1,
132 PCI_DID_INTEL_APL_SPI2,
133 PCI_DID_INTEL_APL_HWSEQ_SPI,
134 PCI_DID_INTEL_GLK_SPI0,
135 PCI_DID_INTEL_GLK_SPI1,
136 PCI_DID_INTEL_GLK_SPI2,
137 PCI_DID_INTEL_CNL_SPI0,
138 PCI_DID_INTEL_CNL_SPI1,
139 PCI_DID_INTEL_CNL_SPI2,
140 PCI_DID_INTEL_CNL_HWSEQ_SPI,
141 PCI_DID_INTEL_CNP_H_SPI0,
142 PCI_DID_INTEL_CNP_H_SPI1,
143 PCI_DID_INTEL_CNP_H_SPI2,
144 PCI_DID_INTEL_CNP_H_HWSEQ_SPI,
145 PCI_DID_INTEL_LWB_SPI,
146 PCI_DID_INTEL_LWB_SPI_SUPER,
147 PCI_DID_INTEL_ICP_SPI0,
148 PCI_DID_INTEL_ICP_SPI1,
149 PCI_DID_INTEL_ICP_SPI2,
150 PCI_DID_INTEL_ICP_HWSEQ_SPI,
151 PCI_DID_INTEL_CMP_SPI0,
152 PCI_DID_INTEL_CMP_SPI1,
153 PCI_DID_INTEL_CMP_SPI2,
154 PCI_DID_INTEL_CMP_HWSEQ_SPI,
155 PCI_DID_INTEL_CMP_H_SPI0,
156 PCI_DID_INTEL_CMP_H_SPI1,
157 PCI_DID_INTEL_CMP_H_SPI2,
158 PCI_DID_INTEL_CMP_H_HWSEQ_SPI,
159 PCI_DID_INTEL_TGP_SPI0,
160 PCI_DID_INTEL_TGP_GSPI0,
161 PCI_DID_INTEL_TGP_GSPI1,
162 PCI_DID_INTEL_TGP_GSPI2,
163 PCI_DID_INTEL_TGP_GSPI3,
164 PCI_DID_INTEL_TGP_GSPI4,
165 PCI_DID_INTEL_TGP_GSPI5,
166 PCI_DID_INTEL_TGP_GSPI6,
167 PCI_DID_INTEL_TGP_H_SPI0,
168 PCI_DID_INTEL_TGP_H_GSPI0,
169 PCI_DID_INTEL_TGP_H_GSPI1,
170 PCI_DID_INTEL_TGP_H_GSPI2,
171 PCI_DID_INTEL_TGP_H_GSPI3,
172 PCI_DID_INTEL_MCC_SPI0,
173 PCI_DID_INTEL_MCC_GSPI0,
174 PCI_DID_INTEL_MCC_GSPI1,
175 PCI_DID_INTEL_MCC_GSPI2,
176 PCI_DID_INTEL_JSP_SPI0,
177 PCI_DID_INTEL_JSP_SPI1,
178 PCI_DID_INTEL_JSP_SPI2,
179 PCI_DID_INTEL_JSP_HWSEQ_SPI,
180 PCI_DID_INTEL_ADP_P_HWSEQ_SPI,
181 PCI_DID_INTEL_ADP_S_HWSEQ_SPI,
182 PCI_DID_INTEL_ADP_M_N_HWSEQ_SPI,
183 PCI_DID_INTEL_ADP_P_SPI0,
184 PCI_DID_INTEL_ADP_P_SPI1,
185 PCI_DID_INTEL_ADP_P_SPI2,
186 PCI_DID_INTEL_ADP_P_SPI3,
187 PCI_DID_INTEL_ADP_P_SPI4,
188 PCI_DID_INTEL_ADP_P_SPI5,
189 PCI_DID_INTEL_ADP_P_SPI6,
190 PCI_DID_INTEL_ADP_S_SPI0,
191 PCI_DID_INTEL_ADP_S_SPI1,
192 PCI_DID_INTEL_ADP_S_SPI2,
193 PCI_DID_INTEL_ADP_S_SPI3,
194 PCI_DID_INTEL_ADP_S_SPI4,
195 PCI_DID_INTEL_ADP_S_SPI5,
196 PCI_DID_INTEL_ADP_S_SPI6,
197 PCI_DID_INTEL_ADP_M_N_SPI0,
198 PCI_DID_INTEL_ADP_M_N_SPI1,
199 PCI_DID_INTEL_ADP_M_SPI2,
200 PCI_DID_INTEL_SPR_HWSEQ_SPI,
Subrata Banik6c4b5912017-11-07 16:10:05 +0530201 0
202};
203
204static const struct pci_driver pch_spi __pci_driver = {
205 .ops = &spi_dev_ops,
Felix Singer43b7f412022-03-07 04:34:52 +0100206 .vendor = PCI_VID_INTEL,
Subrata Banik6c4b5912017-11-07 16:10:05 +0530207 .devices = pci_device_ids,
208};