blob: 603af16881328c4df9ce9a4e0d324cc62e23fe45 [file] [log] [blame]
Barnali Sarkar89331cd2017-02-16 17:22:37 +05301/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2017 Intel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 */
15
16#include <arch/io.h>
17#include <assert.h>
18#include <device/pci_def.h>
19#include <commonlib/helpers.h>
20#include <console/console.h>
21#include <fast_spi_def.h>
22#include <intelblocks/fast_spi.h>
23#include <soc/intel/common/spi_flash.h>
24#include <soc/pci_devs.h>
25#include <spi_flash.h>
26#include <spi-generic.h>
27#include <stdlib.h>
28#include <string.h>
29
30/*
31 * Get the FAST_SPIBAR.
32 */
33void *fast_spi_get_bar(void)
34{
35 device_t dev = PCH_DEV_SPI;
36 uintptr_t bar;
37
38 bar = pci_read_config32(dev, PCI_BASE_ADDRESS_0);
39 assert(bar != 0);
40 /*
41 * Bits 31-12 are the base address as per EDS for SPI,
42 * Don't care about 0-11 bit
43 */
44 return (void *)(bar & ~PCI_BASE_ADDRESS_MEM_ATTR_MASK);
45}
46
47/*
48 * Disable the BIOS write protect and Enable Prefetching and Caching.
49 */
50void fast_spi_init(void)
51{
52 device_t dev = PCH_DEV_SPI;
53 uint8_t bios_cntl;
54
55 bios_cntl = pci_read_config8(dev, SPIBAR_BIOS_CONTROL);
56
57 /* Disable the BIOS write protect so write commands are allowed. */
58 bios_cntl &= ~SPIBAR_BIOS_CONTROL_EISS;
59 bios_cntl |= SPIBAR_BIOS_CONTROL_WPD;
60 /* Enable Prefetching and caching. */
61 bios_cntl |= SPIBAR_BIOS_CONTROL_PREFETCH_ENABLE;
62 bios_cntl &= ~SPIBAR_BIOS_CONTROL_CACHE_DISABLE;
63
64 pci_write_config8(dev, SPIBAR_BIOS_CONTROL, bios_cntl);
65}
66
67/*
68 * Set FAST_SPIBAR BIOS Control BILD bit.
69 */
70static void fast_spi_set_bios_control_reg(uint8_t bios_cntl_bit)
71{
72 device_t dev = PCH_DEV_SPI;
73 uint8_t bc_cntl;
74
75 assert((bios_cntl_bit & (bios_cntl_bit - 1)) == 0);
76 bc_cntl = pci_read_config8(dev, SPIBAR_BIOS_CONTROL);
77 bc_cntl |= bios_cntl_bit;
78 pci_write_config8(dev, SPIBAR_BIOS_CONTROL, bc_cntl);
79}
80
81/*
82 * Set FAST_SPIBAR BIOS Control BILD bit.
83 */
84void fast_spi_set_bios_interface_lock_down(void)
85{
86 fast_spi_set_bios_control_reg(SPIBAR_BIOS_CONTROL_BILD);
87}
88
89/*
90 * Set FAST_SPIBAR BIOS Control LE bit.
91 */
92void fast_spi_set_lock_enable(void)
93{
94 fast_spi_set_bios_control_reg(SPIBAR_BIOS_CONTROL_LOCK_ENABLE);
95}
96
97/*
98 * Set FAST_SPIBAR BIOS Control EISS bit.
99 */
100void fast_spi_set_eiss(void)
101{
102 fast_spi_set_bios_control_reg(SPIBAR_BIOS_CONTROL_EISS);
103}
104
105/*
106 * Set FAST_SPI opcode menu.
107 */
108void fast_spi_set_opcode_menu(void)
109{
110 void *spibar = fast_spi_get_bar();
111
112 write16(spibar + SPIBAR_PREOP, SPI_OPPREFIX);
113 write16(spibar + SPIBAR_OPTYPE, SPI_OPTYPE);
114 write32(spibar + SPIBAR_OPMENU_LOWER, SPI_OPMENU_LOWER);
115 write32(spibar + SPIBAR_OPMENU_UPPER, SPI_OPMENU_UPPER);
116}
117
118/*
119 * Lock FAST_SPIBAR.
120 */
121void fast_spi_lock_bar(void)
122{
123 void *spibar = fast_spi_get_bar();
124 uint32_t hsfs;
125
126 hsfs = read32(spibar + SPIBAR_HSFSTS_CTL);
127 hsfs |= SPIBAR_HSFSTS_FLOCKDN;
128 write32(spibar + SPIBAR_HSFSTS_CTL, hsfs);
129}
130
131/*
132 * Set FAST_SPIBAR Soft Reset Data Register value.
133 */
134void fast_spi_set_strap_msg_data(uint32_t soft_reset_data)
135{
136 void *spibar = fast_spi_get_bar();
137 uint32_t ssl, ssms;
138
139 /* Set Strap Lock Disable */
140 ssl = read32(spibar + SPIBAR_RESET_LOCK);
141 ssl &= ~SPIBAR_RESET_LOCK_ENABLE;
142 write32(spibar + SPIBAR_RESET_LOCK, ssl);
143
144 /* Write Soft Reset Data register at SPIBAR0 offset 0xF8[0:15] */
145 write32(spibar + SPIBAR_RESET_DATA, soft_reset_data);
146
147 /* Set Strap Mux Select set to '1' */
148 ssms = read32(spibar + SPIBAR_RESET_CTRL);
149 ssms |= SPIBAR_RESET_CTRL_SSMC;
150 write32(spibar + SPIBAR_RESET_CTRL, ssms);
151
152 /* Set Strap Lock Enable */
153 ssl = read32(spibar + SPIBAR_RESET_LOCK);
154 ssl |= SPIBAR_RESET_LOCK_ENABLE;
155 write32(spibar + SPIBAR_RESET_LOCK, ssl);
156}
157
158/*
159 * Returns bios_start and fills in size of the BIOS region.
160 */
161size_t fast_spi_get_bios_region(size_t *bios_size)
162{
163 size_t bios_start, bios_end;
164 /*
165 * BIOS_BFPREG provides info about BIOS Flash Primary Region
166 * Base and Limit.
167 * Base and Limit fields are in units of 4KiB.
168 */
169 uint32_t val = read32(fast_spi_get_bar() + SPIBAR_BFPREG);
170
171 bios_start = (val & SPIBAR_BFPREG_PRB_MASK) * 4 * KiB;
172 bios_end = (((val & SPIBAR_BFPREG_PRL_MASK) >>
173 SPIBAR_BFPREG_PRL_SHIFT) + 1) * 4 * KiB;
174 *bios_size = bios_end - bios_start;
175 return bios_start;
176}
177
178/*
179 * Program temporary BAR for SPI in case any of the stages before ramstage need
180 * to access FAST_SPI MMIO regs. Ramstage will assign a new BAR during PCI
181 * enumeration.
182 */
183void fast_spi_early_init(uintptr_t spi_base_address)
184{
185 device_t dev = PCH_DEV_SPI;
186 uint8_t pcireg;
187
188 /* Assign Resources to SPI Controller */
189 /* Clear BIT 1-2 SPI Command Register */
190 pcireg = pci_read_config8(dev, PCI_COMMAND);
191 pcireg &= ~(PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);
192 pci_write_config8(dev, PCI_COMMAND, pcireg);
193
194 /* Program Temporary BAR for SPI */
195 pci_write_config32(dev, PCI_BASE_ADDRESS_0,
196 spi_base_address | PCI_BASE_ADDRESS_SPACE_MEMORY);
197
198 /* Enable Bus Master and MMIO Space */
199 pcireg = pci_read_config8(dev, PCI_COMMAND);
200 pcireg |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
201 pci_write_config8(dev, PCI_COMMAND, pcireg);
202
203 /* Initialize SPI to allow BIOS to write/erase on flash. */
204 fast_spi_init();
205}