blob: f6a211ba757d6f562cb816f1b63e80ebd3bf655f [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
Elyes Haouas8ed58352022-10-22 22:17:28 +02005#include <assert.h>
6#include <commonlib/bsd/helpers.h>
Subrata Banik6c4b5912017-11-07 16:10:05 +05307#include <device/device.h>
Sridhar Siricillab017a432022-03-23 00:19:01 +05308#include <device/mmio.h>
Subrata Banik6c4b5912017-11-07 16:10:05 +05309#include <device/pci.h>
Elyes Haouas8ed58352022-10-22 22:17:28 +020010#include <device/pci_def.h>
Subrata Banik6c4b5912017-11-07 16:10:05 +053011#include <device/pci_ids.h>
Sridhar Siricillab017a432022-03-23 00:19:01 +053012#include <device/pci_ops.h>
Elyes Haouas8ed58352022-10-22 22:17:28 +020013#include <device/pci_type.h>
Subrata Banik6c4b5912017-11-07 16:10:05 +053014#include <device/spi.h>
15#include <intelblocks/fast_spi.h>
16#include <intelblocks/gspi.h>
17#include <intelblocks/spi.h>
18#include <soc/pci_devs.h>
19#include <spi-generic.h>
Elyes Haouas8ed58352022-10-22 22:17:28 +020020#include <types.h>
Subrata Banik6c4b5912017-11-07 16:10:05 +053021
22const struct spi_ctrlr_buses spi_ctrlr_bus_map[] = {
23 { .ctrlr = &fast_spi_flash_ctrlr, .bus_start = 0, .bus_end = 0 },
Julius Wernercd49cce2019-03-05 16:53:33 -080024#if !ENV_SMM && CONFIG(SOC_INTEL_COMMON_BLOCK_GSPI)
Subrata Banik6c4b5912017-11-07 16:10:05 +053025 { .ctrlr = &gspi_ctrlr, .bus_start = 1,
26 .bus_end = 1 + (CONFIG_SOC_INTEL_COMMON_BLOCK_GSPI_MAX - 1)},
27#endif
28};
29
30const size_t spi_ctrlr_bus_map_count = ARRAY_SIZE(spi_ctrlr_bus_map);
31
Sridhar Siricillab017a432022-03-23 00:19:01 +053032#define MMIO_BIOS_GPR0 0x98
33
34union spi_bios_gpr0 {
35 struct {
36 /* Specified write protection is enabled */
37 /*
38 * This field corresponds to flash address bits 26:12
39 * and specifies the lower limit of protected range.
40 */
41 uint32_t protect_range_base:15;
42
43 /* Specifies read protection is enabled */
44 uint32_t read_protect_en:1;
45
46 /*
47 * This field corresponds to flash address bits 26:12
48 * and specifies the upper limit of the protected range
49 */
50 uint32_t protect_range_limit:15;
51
52 uint32_t write_protect_en:1;
53 } __packed fields;
54
55 uint32_t data;
56};
57
58/* Read SPI BAR 0 from PCI configuration space */
59static uintptr_t get_spi_bar(pci_devfn_t dev)
60{
61 uintptr_t bar;
62
63 bar = pci_read_config32(dev, PCI_BASE_ADDRESS_0);
64 assert(bar != 0);
65 /*
66 * Bits 31-12 are the base address as per EDS for SPI,
67 * Don't care about 0-11 bit
68 */
69 return bar & ~PCI_BASE_ADDRESS_MEM_ATTR_MASK;
70}
71
72static uint32_t spi_read_bar(pci_devfn_t dev, uint32_t offset)
73{
74 return read32p(get_spi_bar(dev) + offset);
75}
76
77static uint32_t spi_read_bios_gpr0(void)
78{
79 return spi_read_bar(PCH_DEV_SPI, MMIO_BIOS_GPR0);
80}
81
82static uint32_t spi_get_wp_cse_ro_start_offset(union spi_bios_gpr0 bios_gpr0)
83{
84 return bios_gpr0.fields.protect_range_base << 12;
85}
86
87static uint32_t spi_get_wp_cse_ro_limit(union spi_bios_gpr0 bios_gpr0)
88{
89 return bios_gpr0.fields.protect_range_limit << 12 | 0xfff;
90}
91
92bool is_spi_wp_cse_ro_en(void)
93{
94 union spi_bios_gpr0 bios_gpr0;
95
96 bios_gpr0.data = spi_read_bios_gpr0();
97 return !!bios_gpr0.fields.write_protect_en;
98}
99
100void spi_get_wp_cse_ro_range(uint32_t *base, uint32_t *limit)
101{
102 union spi_bios_gpr0 bios_gpr0;
103
104 bios_gpr0.data = spi_read_bios_gpr0();
105 *base = spi_get_wp_cse_ro_start_offset(bios_gpr0);
106 *limit = spi_get_wp_cse_ro_limit(bios_gpr0);
107}
108
Subrata Banik6c4b5912017-11-07 16:10:05 +0530109static int spi_dev_to_bus(struct device *dev)
110{
111 return spi_soc_devfn_to_bus(dev->path.pci.devfn);
112}
113
114static struct spi_bus_operations spi_bus_ops = {
115 .dev_to_bus = &spi_dev_to_bus,
116};
117
Nico Huber57686192022-08-06 19:11:55 +0200118struct device_operations spi_dev_ops = {
Elyes HAOUAS1d191272018-11-27 12:23:48 +0100119 .read_resources = pci_dev_read_resources,
120 .set_resources = pci_dev_set_resources,
121 .enable_resources = pci_dev_enable_resources,
122 .scan_bus = scan_generic_bus,
Subrata Banik6c4b5912017-11-07 16:10:05 +0530123 .ops_spi_bus = &spi_bus_ops,
Subrata Banik6bbc91a2017-12-07 14:55:51 +0530124 .ops_pci = &pci_dev_ops_pci,
Subrata Banik6c4b5912017-11-07 16:10:05 +0530125};
126
127static const unsigned short pci_device_ids[] = {
Wonkyu Kim9f401072020-11-13 15:16:32 -0800128 PCI_DID_INTEL_MTL_GSPI0,
129 PCI_DID_INTEL_MTL_GSPI1,
130 PCI_DID_INTEL_MTL_GSPI2,
Felix Singer43b7f412022-03-07 04:34:52 +0100131 PCI_DID_INTEL_APL_SPI0,
132 PCI_DID_INTEL_APL_SPI1,
133 PCI_DID_INTEL_APL_SPI2,
Felix Singer43b7f412022-03-07 04:34:52 +0100134 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,
Felix Singer43b7f412022-03-07 04:34:52 +0100140 PCI_DID_INTEL_CNP_H_SPI0,
141 PCI_DID_INTEL_CNP_H_SPI1,
142 PCI_DID_INTEL_CNP_H_SPI2,
Felix Singer43b7f412022-03-07 04:34:52 +0100143 PCI_DID_INTEL_ICP_SPI0,
144 PCI_DID_INTEL_ICP_SPI1,
145 PCI_DID_INTEL_ICP_SPI2,
Felix Singer43b7f412022-03-07 04:34:52 +0100146 PCI_DID_INTEL_CMP_SPI0,
147 PCI_DID_INTEL_CMP_SPI1,
148 PCI_DID_INTEL_CMP_SPI2,
Felix Singer43b7f412022-03-07 04:34:52 +0100149 PCI_DID_INTEL_CMP_H_SPI0,
150 PCI_DID_INTEL_CMP_H_SPI1,
151 PCI_DID_INTEL_CMP_H_SPI2,
Felix Singer43b7f412022-03-07 04:34:52 +0100152 PCI_DID_INTEL_TGP_GSPI0,
153 PCI_DID_INTEL_TGP_GSPI1,
154 PCI_DID_INTEL_TGP_GSPI2,
155 PCI_DID_INTEL_TGP_GSPI3,
156 PCI_DID_INTEL_TGP_GSPI4,
157 PCI_DID_INTEL_TGP_GSPI5,
158 PCI_DID_INTEL_TGP_GSPI6,
159 PCI_DID_INTEL_TGP_H_SPI0,
160 PCI_DID_INTEL_TGP_H_GSPI0,
161 PCI_DID_INTEL_TGP_H_GSPI1,
162 PCI_DID_INTEL_TGP_H_GSPI2,
163 PCI_DID_INTEL_TGP_H_GSPI3,
Felix Singer43b7f412022-03-07 04:34:52 +0100164 PCI_DID_INTEL_MCC_GSPI0,
165 PCI_DID_INTEL_MCC_GSPI1,
166 PCI_DID_INTEL_MCC_GSPI2,
167 PCI_DID_INTEL_JSP_SPI0,
168 PCI_DID_INTEL_JSP_SPI1,
169 PCI_DID_INTEL_JSP_SPI2,
Felix Singer43b7f412022-03-07 04:34:52 +0100170 PCI_DID_INTEL_ADP_P_SPI0,
171 PCI_DID_INTEL_ADP_P_SPI1,
172 PCI_DID_INTEL_ADP_P_SPI2,
173 PCI_DID_INTEL_ADP_P_SPI3,
174 PCI_DID_INTEL_ADP_P_SPI4,
175 PCI_DID_INTEL_ADP_P_SPI5,
176 PCI_DID_INTEL_ADP_P_SPI6,
177 PCI_DID_INTEL_ADP_S_SPI0,
178 PCI_DID_INTEL_ADP_S_SPI1,
179 PCI_DID_INTEL_ADP_S_SPI2,
180 PCI_DID_INTEL_ADP_S_SPI3,
181 PCI_DID_INTEL_ADP_S_SPI4,
182 PCI_DID_INTEL_ADP_S_SPI5,
183 PCI_DID_INTEL_ADP_S_SPI6,
184 PCI_DID_INTEL_ADP_M_N_SPI0,
185 PCI_DID_INTEL_ADP_M_N_SPI1,
186 PCI_DID_INTEL_ADP_M_SPI2,
Jeff Dalye5ac3002022-01-10 23:47:35 -0500187 PCI_DID_INTEL_DNV_SPI,
Subrata Banik6c4b5912017-11-07 16:10:05 +0530188 0
189};
190
191static const struct pci_driver pch_spi __pci_driver = {
192 .ops = &spi_dev_ops,
Felix Singer43b7f412022-03-07 04:34:52 +0100193 .vendor = PCI_VID_INTEL,
Subrata Banik6c4b5912017-11-07 16:10:05 +0530194 .devices = pci_device_ids,
195};