blob: 334404dee953160a4f31342c5dc2415413e5c119 [file] [log] [blame]
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -07001/*
Martin Rotheffaf8f2019-10-20 20:29:22 -06002 * This file is part of the coreboot project.
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -07003 *
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -07004 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of
7 * the License, or (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Paul Menzela8ae1c62013-02-20 13:21:20 +010011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -070012 * GNU General Public License for more details.
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -070013 */
14
Furquan Shaikhc28984d2016-11-20 21:04:00 -080015#include <console/console.h>
Elyes HAOUAS361a9352019-12-18 21:26:33 +010016#include <commonlib/helpers.h>
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -070017#include <spi_flash.h>
Furquan Shaikhc28984d2016-11-20 21:04:00 -080018#include <spi-generic.h>
Furquan Shaikh810e2cd2016-12-05 20:32:24 -080019#include <string.h>
Edward O'Callaghanc4561e22014-06-26 15:02:40 +100020
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -070021#include "spi_flash_internal.h"
22
23/* MX25xx-specific commands */
24#define CMD_MX25XX_WREN 0x06 /* Write Enable */
25#define CMD_MX25XX_WRDI 0x04 /* Write Disable */
26#define CMD_MX25XX_RDSR 0x05 /* Read Status Register */
27#define CMD_MX25XX_WRSR 0x01 /* Write Status Register */
28#define CMD_MX25XX_READ 0x03 /* Read Data Bytes */
29#define CMD_MX25XX_FAST_READ 0x0b /* Read Data Bytes at Higher Speed */
30#define CMD_MX25XX_PP 0x02 /* Page Program */
31#define CMD_MX25XX_SE 0x20 /* Sector Erase */
32#define CMD_MX25XX_BE 0xD8 /* Block Erase */
33#define CMD_MX25XX_CE 0xc7 /* Chip Erase */
34#define CMD_MX25XX_DP 0xb9 /* Deep Power-down */
35#define CMD_MX25XX_RES 0xab /* Release from DP, and Read Signature */
36
37#define MACRONIX_SR_WIP (1 << 0) /* Write-in-Progress */
38
39struct macronix_spi_flash_params {
40 u16 idcode;
41 u16 page_size;
42 u16 pages_per_sector;
43 u16 sectors_per_block;
44 u16 nr_blocks;
45 const char *name;
46};
47
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -070048static const struct macronix_spi_flash_params macronix_spi_flash_table[] = {
49 {
Arthur Heymanse73a85c2018-06-13 00:20:31 +020050 .idcode = 0x2014,
51 .page_size = 256,
52 .pages_per_sector = 16,
53 .sectors_per_block = 16,
54 .nr_blocks = 16,
55 .name = "MX25L8005",
56 },
57 {
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -070058 .idcode = 0x2015,
59 .page_size = 256,
60 .pages_per_sector = 16,
61 .sectors_per_block = 16,
62 .nr_blocks = 32,
63 .name = "MX25L1605D",
64 },
65 {
66 .idcode = 0x2016,
67 .page_size = 256,
68 .pages_per_sector = 16,
69 .sectors_per_block = 16,
70 .nr_blocks = 64,
71 .name = "MX25L3205D",
72 },
73 {
74 .idcode = 0x2017,
75 .page_size = 256,
76 .pages_per_sector = 16,
77 .sectors_per_block = 16,
78 .nr_blocks = 128,
79 .name = "MX25L6405D",
80 },
81 {
82 .idcode = 0x2018,
83 .page_size = 256,
84 .pages_per_sector = 16,
85 .sectors_per_block = 16,
86 .nr_blocks = 256,
87 .name = "MX25L12805D",
88 },
89 {
Mike Banon4902a802019-01-12 13:55:09 +030090 .idcode = 0x2019,
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -070091 .page_size = 256,
92 .pages_per_sector = 16,
93 .sectors_per_block = 16,
Mike Banon4902a802019-01-12 13:55:09 +030094 .nr_blocks = 512,
95 .name = "MX25L25635F",
96 },
97 {
98 .idcode = 0x201a,
99 .page_size = 256,
100 .pages_per_sector = 16,
101 .sectors_per_block = 16,
102 .nr_blocks = 1024,
103 .name = "MX66L51235F",
104 },
105 {
106 .idcode = 0x2415,
107 .page_size = 256,
108 .pages_per_sector = 16,
109 .sectors_per_block = 16,
110 .nr_blocks = 32,
111 .name = "MX25L1635D",
112 },
113 {
114 .idcode = 0x2515,
115 .page_size = 256,
116 .pages_per_sector = 16,
117 .sectors_per_block = 16,
118 .nr_blocks = 32,
119 .name = "MX25L1635E",
120 },
121 {
122 .idcode = 0x2534,
123 .page_size = 256,
124 .pages_per_sector = 16,
125 .sectors_per_block = 16,
126 .nr_blocks = 16,
127 .name = "MX25U8032E",
128 },
129 {
130 .idcode = 0x2535,
131 .page_size = 256,
132 .pages_per_sector = 16,
133 .sectors_per_block = 16,
134 .nr_blocks = 32,
135 .name = "MX25U1635E",
136 },
137 {
138 .idcode = 0x2536,
139 .page_size = 256,
140 .pages_per_sector = 16,
141 .sectors_per_block = 16,
142 .nr_blocks = 64,
143 .name = "MX25U3235E",
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700144 },
Idwer Vollering06413ff2014-10-26 01:20:20 +0200145 {
146 .idcode = 0x2537,
147 .page_size = 256,
148 .pages_per_sector = 16,
149 .sectors_per_block = 16,
150 .nr_blocks = 128,
151 .name = "MX25U6435F",
152 },
153 {
Kyösti Mälkki3f382c72014-11-11 15:01:31 +0200154 .idcode = 0x2538,
155 .page_size = 256,
156 .pages_per_sector = 16,
157 .sectors_per_block = 16,
158 .nr_blocks = 256,
159 .name = "MX25U12835F",
160 },
161 {
Mike Banon4902a802019-01-12 13:55:09 +0300162 .idcode = 0x2539,
163 .page_size = 256,
164 .pages_per_sector = 16,
165 .sectors_per_block = 16,
166 .nr_blocks = 512,
167 .name = "MX25U25635F",
168 },
169 {
170 .idcode = 0x253a,
171 .page_size = 256,
172 .pages_per_sector = 16,
173 .sectors_per_block = 16,
174 .nr_blocks = 1024,
175 .name = "MX25U51245G",
176 },
177 {
178 .idcode = 0x2618,
179 .page_size = 256,
180 .pages_per_sector = 16,
181 .sectors_per_block = 16,
182 .nr_blocks = 256,
183 .name = "MX25L12855E",
184 },
185 {
186 .idcode = 0x5e16,
187 .page_size = 256,
188 .pages_per_sector = 16,
189 .sectors_per_block = 16,
190 .nr_blocks = 64,
191 .name = "MX25L3235D", /* MX25L3225D/MX25L3236D/MX25L3237D */
192 },
193 {
Idwer Vollering06413ff2014-10-26 01:20:20 +0200194 .idcode = 0x9517,
195 .page_size = 256,
196 .pages_per_sector = 16,
197 .sectors_per_block = 16,
198 .nr_blocks = 128,
199 .name = "MX25L6495F",
200 },
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700201};
202
Furquan Shaikhe2fc5e22017-05-17 17:26:01 -0700203static const struct spi_flash_ops spi_flash_ops = {
Aaron Durbincb01aa52020-01-11 11:44:47 -0700204 .read = spi_flash_cmd_read,
Aaron Durbind701ef72019-12-27 15:16:17 -0700205 .write = spi_flash_cmd_write_page_program,
Furquan Shaikhe2fc5e22017-05-17 17:26:01 -0700206 .erase = spi_flash_cmd_erase,
207 .status = spi_flash_cmd_status,
Furquan Shaikhe2fc5e22017-05-17 17:26:01 -0700208};
209
Furquan Shaikhbd9e32e2017-05-15 23:28:41 -0700210int spi_flash_probe_macronix(const struct spi_slave *spi, u8 *idcode,
Furquan Shaikh30221b42017-05-15 14:35:15 -0700211 struct spi_flash *flash)
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700212{
213 const struct macronix_spi_flash_params *params;
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700214 unsigned int i;
215 u16 id = idcode[2] | idcode[1] << 8;
216
217 for (i = 0; i < ARRAY_SIZE(macronix_spi_flash_table); i++) {
218 params = &macronix_spi_flash_table[i];
219 if (params->idcode == id)
220 break;
221 }
222
223 if (i == ARRAY_SIZE(macronix_spi_flash_table)) {
224 printk(BIOS_WARNING, "SF: Unsupported Macronix ID %04x\n", id);
Furquan Shaikh30221b42017-05-15 14:35:15 -0700225 return -1;
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700226 }
227
Furquan Shaikh30221b42017-05-15 14:35:15 -0700228 memcpy(&flash->spi, spi, sizeof(*spi));
229 flash->name = params->name;
230 flash->page_size = params->page_size;
231 flash->sector_size = params->page_size * params->pages_per_sector;
232 flash->size = flash->sector_size * params->sectors_per_block *
Furquan Shaikhfc1a1232017-05-12 00:19:56 -0700233 params->nr_blocks;
Furquan Shaikh30221b42017-05-15 14:35:15 -0700234 flash->erase_cmd = CMD_MX25XX_SE;
235 flash->status_cmd = CMD_MX25XX_RDSR;
Aaron Durbind701ef72019-12-27 15:16:17 -0700236 flash->pp_cmd = CMD_MX25XX_PP;
237 flash->wren_cmd = CMD_MX25XX_WREN;
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700238
Furquan Shaikhe2fc5e22017-05-17 17:26:01 -0700239 flash->ops = &spi_flash_ops;
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700240
Furquan Shaikh30221b42017-05-15 14:35:15 -0700241 return 0;
Stefan Reinauer1c56d9b2012-05-10 11:27:32 -0700242}