blob: 5f9290a536b52e675abdefed710f531c7c943c3e [file] [log] [blame]
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +00001/*
2 * This file is part of the flashrom project.
3 *
4 * Copyright (C) 2007 Carl-Daniel Hailfinger
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 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20/*
21 * Contains the generic SPI framework
22 */
23
24#include <stdio.h>
25#include <pci/pci.h>
26#include <stdint.h>
27#include <string.h>
28#include "flash.h"
29
30#define ITE_SUPERIO_PORT1 0x2e
31#define ITE_SUPERIO_PORT2 0x4e
32
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +000033/* Read Electronic ID */
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +000034#define JEDEC_RDID {0x9f}
35#define JEDEC_RDID_OUTSIZE 0x01
36#define JEDEC_RDID_INSIZE 0x03
37
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +000038/* Write Enable */
39#define JEDEC_WREN {0x06}
40#define JEDEC_WREN_OUTSIZE 0x01
41#define JEDEC_WREN_INSIZE 0x00
42
43/* Write Disable */
44#define JEDEC_WRDI {0x04}
45#define JEDEC_WRDI_OUTSIZE 0x01
46#define JEDEC_WRDI_INSIZE 0x00
47
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +000048/* Chip Erase 0x60 is supported by Macronix/SST chips. */
Carl-Daniel Hailfinger21c78902007-12-17 14:33:32 +000049#define JEDEC_CE_60 {0x60};
50#define JEDEC_CE_60_OUTSIZE 0x01
51#define JEDEC_CE_60_INSIZE 0x00
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +000052
Carl-Daniel Hailfinger21c78902007-12-17 14:33:32 +000053/* Chip Erase 0xc7 is supported by ST/EON/Macronix chips. */
54#define JEDEC_CE_C7 {0xc7};
55#define JEDEC_CE_C7_OUTSIZE 0x01
56#define JEDEC_CE_C7_INSIZE 0x00
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +000057
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +000058/* Block Erase 0x52 is supported by SST chips. */
Carl-Daniel Hailfinger21c78902007-12-17 14:33:32 +000059#define JEDEC_BE_52 {0x52};
60#define JEDEC_BE_52_OUTSIZE 0x04
61#define JEDEC_BE_52_INSIZE 0x00
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +000062
63/* Block Erase 0xd8 is supported by EON/Macronix chips. */
Carl-Daniel Hailfinger21c78902007-12-17 14:33:32 +000064#define JEDEC_BE_D8 {0xd8};
65#define JEDEC_BE_D8_OUTSIZE 0x04
66#define JEDEC_BE_D8_INSIZE 0x00
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +000067
68/* Sector Erase 0x20 is supported by Macronix/SST chips. */
69#define JEDEC_SE {0x20};
70#define JEDEC_SE_OUTSIZE 0x04
71#define JEDEC_SE_INSIZE 0x00
72
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +000073/* Read Status Register */
74#define JEDEC_RDSR {0x05};
75#define JEDEC_RDSR_OUTSIZE 0x01
76#define JEDEC_RDSR_INSIZE 0x01
77#define JEDEC_RDSR_BIT_WIP (0x01 << 0)
78
79uint16_t it8716f_flashport = 0;
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +000080
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +000081void generic_spi_prettyprint_status_register(struct flashchip *flash);
82
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +000083/* Generic Super I/O helper functions */
84uint8_t regval(uint16_t port, uint8_t reg)
85{
86 outb(reg, port);
87 return inb(port + 1);
88}
89
90void regwrite(uint16_t port, uint8_t reg, uint8_t val)
91{
92 outb(reg, port);
93 outb(val, port + 1);
94}
95
96/* Helper functions for most recent ITE IT87xx Super I/O chips */
97#define CHIP_ID_BYTE1_REG 0x20
98#define CHIP_ID_BYTE2_REG 0x21
99static void enter_conf_mode_ite(uint16_t port)
100{
101 outb(0x87, port);
102 outb(0x01, port);
103 outb(0x55, port);
104 if (port == ITE_SUPERIO_PORT1)
105 outb(0x55, port);
106 else
107 outb(0xaa, port);
108}
109
110static void exit_conf_mode_ite(uint16_t port)
111{
112 regwrite(port, 0x02, 0x02);
113}
114
Carl-Daniel Hailfinger3d94a0e2007-10-16 21:09:06 +0000115static uint16_t find_ite_spi_flash_port(uint16_t port)
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +0000116{
117 uint8_t tmp = 0;
118 uint16_t id, flashport = 0;
119
120 enter_conf_mode_ite(port);
121
122 id = regval(port, CHIP_ID_BYTE1_REG) << 8;
123 id |= regval(port, CHIP_ID_BYTE2_REG);
124
125 /* TODO: Handle more IT87xx if they support flash translation */
126 if (id == 0x8716) {
127 /* NOLDN, reg 0x24, mask out lowest bit (suspend) */
128 tmp = regval(port, 0x24) & 0xFE;
129 printf("Serial flash segment 0x%08x-0x%08x %sabled\n",
130 0xFFFE0000, 0xFFFFFFFF, (tmp & 1 << 1) ? "en" : "dis");
131 printf("Serial flash segment 0x%08x-0x%08x %sabled\n",
132 0x000E0000, 0x000FFFFF, (tmp & 1 << 1) ? "en" : "dis");
133 printf("Serial flash segment 0x%08x-0x%08x %sabled\n",
134 0xFFEE0000, 0xFFEFFFFF, (tmp & 1 << 2) ? "en" : "dis");
135 printf("Serial flash segment 0x%08x-0x%08x %sabled\n",
136 0xFFF80000, 0xFFFEFFFF, (tmp & 1 << 3) ? "en" : "dis");
137 printf("LPC write to serial flash %sabled\n",
138 (tmp & 1 << 4) ? "en" : "dis");
139 printf("serial flash pin %i\n", (tmp & 1 << 5) ? 87 : 29);
140 /* LDN 0x7, reg 0x64/0x65 */
141 regwrite(port, 0x07, 0x7);
142 flashport = regval(port, 0x64) << 8;
143 flashport |= regval(port, 0x65);
144 }
145 exit_conf_mode_ite(port);
146 return flashport;
147}
148
Carl-Daniel Hailfinger3d94a0e2007-10-16 21:09:06 +0000149int it87xx_probe_spi_flash(const char *name)
150{
151 it8716f_flashport = find_ite_spi_flash_port(ITE_SUPERIO_PORT1);
152 if (!it8716f_flashport)
153 it8716f_flashport = find_ite_spi_flash_port(ITE_SUPERIO_PORT2);
154 return (!it8716f_flashport);
155}
156
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +0000157/* The IT8716F only supports commands with length 1,2,4,5 bytes including
158 command byte and can not read more than 3 bytes from the device.
159 This function expects writearr[0] to be the first byte sent to the device,
160 whereas the IT8716F splits commands internally into address and non-address
161 commands with the address in inverse wire order. That's why the register
162 ordering in case 4 and 5 may seem strange. */
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000163static int it8716f_spi_command(uint16_t port, unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr)
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +0000164{
165 uint8_t busy, writeenc;
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000166 int i;
167
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +0000168 do {
169 busy = inb(port) & 0x80;
170 } while (busy);
171 if (readcnt > 3) {
Uwe Hermanna502dce2007-10-17 23:55:15 +0000172 printf("%s called with unsupported readcnt %i.\n",
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +0000173 __FUNCTION__, readcnt);
174 return 1;
175 }
176 switch (writecnt) {
177 case 1:
178 outb(writearr[0], port + 1);
179 writeenc = 0x0;
180 break;
181 case 2:
182 outb(writearr[0], port + 1);
183 outb(writearr[1], port + 7);
184 writeenc = 0x1;
185 break;
186 case 4:
187 outb(writearr[0], port + 1);
188 outb(writearr[1], port + 4);
189 outb(writearr[2], port + 3);
190 outb(writearr[3], port + 2);
191 writeenc = 0x2;
192 break;
193 case 5:
194 outb(writearr[0], port + 1);
195 outb(writearr[1], port + 4);
196 outb(writearr[2], port + 3);
197 outb(writearr[3], port + 2);
198 outb(writearr[4], port + 7);
199 writeenc = 0x3;
200 break;
201 default:
Uwe Hermanna502dce2007-10-17 23:55:15 +0000202 printf("%s called with unsupported writecnt %i.\n",
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +0000203 __FUNCTION__, writecnt);
204 return 1;
205 }
206 /* Start IO, 33MHz, readcnt input bytes, writecnt output bytes. Note:
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000207 * We can't use writecnt directly, but have to use a strange encoding.
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +0000208 */
209 outb((0x5 << 4) | ((readcnt & 0x3) << 2) | (writeenc), port);
210 do {
211 busy = inb(port) & 0x80;
212 } while (busy);
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000213
214 for (i = 0; i < readcnt; i++) {
215 readarr[i] = inb(port + 5 + i);
216 }
217
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +0000218 return 0;
219}
220
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000221int generic_spi_command(unsigned int writecnt, unsigned int readcnt, const unsigned char *writearr, unsigned char *readarr)
Carl-Daniel Hailfinger3d94a0e2007-10-16 21:09:06 +0000222{
223 if (it8716f_flashport)
224 return it8716f_spi_command(it8716f_flashport, writecnt, readcnt, writearr, readarr);
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000225 printf_debug("%s called, but no SPI chipset detected\n", __FUNCTION__);
Carl-Daniel Hailfinger3d94a0e2007-10-16 21:09:06 +0000226 return 1;
227}
228
229static int generic_spi_rdid(unsigned char *readarr)
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +0000230{
231 const unsigned char cmd[] = JEDEC_RDID;
232
Carl-Daniel Hailfinger3d94a0e2007-10-16 21:09:06 +0000233 if (generic_spi_command(JEDEC_RDID_OUTSIZE, JEDEC_RDID_INSIZE, cmd, readarr))
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +0000234 return 1;
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000235 printf_debug("RDID returned %02x %02x %02x.\n", readarr[0], readarr[1], readarr[2]);
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +0000236 return 0;
237}
238
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000239void generic_spi_write_enable()
240{
241 const unsigned char cmd[] = JEDEC_WREN;
242
243 /* Send WREN (Write Enable) */
244 generic_spi_command(JEDEC_WREN_OUTSIZE, JEDEC_WREN_INSIZE, cmd, NULL);
245
246}
247
248void generic_spi_write_disable()
249{
250 const unsigned char cmd[] = JEDEC_WRDI;
251
252 /* Send WRDI (Write Disable) */
253 generic_spi_command(JEDEC_WRDI_OUTSIZE, JEDEC_WRDI_INSIZE, cmd, NULL);
254}
255
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +0000256int probe_spi(struct flashchip *flash)
257{
258 unsigned char readarr[3];
259 uint8_t manuf_id;
260 uint16_t model_id;
Carl-Daniel Hailfinger3d94a0e2007-10-16 21:09:06 +0000261 if (!generic_spi_rdid(readarr)) {
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +0000262 manuf_id = readarr[0];
263 model_id = (readarr[1] << 8) | readarr[2];
264 printf_debug("%s: id1 0x%x, id2 0x%x\n", __FUNCTION__, manuf_id, model_id);
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000265 if (manuf_id == flash->manufacture_id && model_id == flash->model_id) {
266 /* Print the status register before erase to tell the
267 * user about possible write protection.
268 */
269 generic_spi_prettyprint_status_register(flash);
270
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +0000271 return 1;
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000272 }
Carl-Daniel Hailfinger70539262007-10-15 21:45:29 +0000273 }
274
275 return 0;
276}
277
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000278uint8_t generic_spi_read_status_register()
279{
280 const unsigned char cmd[] = JEDEC_RDSR;
281 unsigned char readarr[1];
282
283 /* Read Status Register */
284 generic_spi_command(JEDEC_RDSR_OUTSIZE, JEDEC_RDSR_INSIZE, cmd, readarr);
285 return readarr[0];
286}
287
Carl-Daniel Hailfinger9a3ec822007-12-29 10:15:58 +0000288/* Prettyprint the status register. Works for
289 * ST M25P series
290 * MX MX25L series
291 */
292void generic_spi_prettyprint_status_register_st_m25p(uint8_t status)
293{
294 printf_debug("Chip status register: Status Register Write Disable "
295 "(SRWD) is %sset\n", (status & (1 << 7)) ? "" : "not ");
296 printf_debug("Chip status register: Bit 6 is "
297 "%sset\n", (status & (1 << 6)) ? "" : "not ");
298 printf_debug("Chip status register: Bit 5 is "
299 "%sset\n", (status & (1 << 5)) ? "" : "not ");
300 printf_debug("Chip status register: Block Protect 2 (BP2) is "
301 "%sset\n", (status & (1 << 4)) ? "" : "not ");
302 printf_debug("Chip status register: Block Protect 1 (BP1) is "
303 "%sset\n", (status & (1 << 3)) ? "" : "not ");
304 printf_debug("Chip status register: Block Protect 0 (BP0) is "
305 "%sset\n", (status & (1 << 2)) ? "" : "not ");
306 printf_debug("Chip status register: Write Enable Latch (WEL) is "
307 "%sset\n", (status & (1 << 1)) ? "" : "not ");
308 printf_debug("Chip status register: Write In Progress (WIP) is "
309 "%sset\n", (status & (1 << 0)) ? "" : "not ");
310}
311
312void generic_spi_prettyprint_status_register(struct flashchip *flash)
313{
314 uint8_t status;
315
316 status = generic_spi_read_status_register();
317 printf_debug("Chip status register is %02x\n", status);
318 switch (flash->manufacture_id) {
319 case ST_ID:
320 case MX_ID:
321 if ((flash->model_id & 0xff00) == 0x2000)
322 generic_spi_prettyprint_status_register_st_m25p(status);
323 break;
324 }
325}
326
Carl-Daniel Hailfinger21c78902007-12-17 14:33:32 +0000327int generic_spi_chip_erase_c7(struct flashchip *flash)
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000328{
Carl-Daniel Hailfinger21c78902007-12-17 14:33:32 +0000329 const unsigned char cmd[] = JEDEC_CE_C7;
Carl-Daniel Hailfingerf5df46f2007-12-16 21:15:27 +0000330
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000331 generic_spi_write_enable();
332 /* Send CE (Chip Erase) */
Carl-Daniel Hailfinger21c78902007-12-17 14:33:32 +0000333 generic_spi_command(JEDEC_CE_C7_OUTSIZE, JEDEC_CE_C7_INSIZE, cmd, NULL);
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000334 /* Wait until the Write-In-Progress bit is cleared.
335 * This usually takes 1-85 s, so wait in 1 s steps.
336 */
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000337 while (generic_spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
338 sleep(1);
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000339 return 0;
340}
341
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000342/* Block size is usually
343 * 64k for Macronix
344 * 32k for SST
345 * 4-32k non-uniform for EON
346 */
Carl-Daniel Hailfinger21c78902007-12-17 14:33:32 +0000347int generic_spi_block_erase_d8(const struct flashchip *flash, unsigned long addr)
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000348{
Carl-Daniel Hailfinger21c78902007-12-17 14:33:32 +0000349 unsigned char cmd[JEDEC_BE_D8_OUTSIZE] = JEDEC_BE_D8;
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000350
351 cmd[1] = (addr & 0x00ff0000) >> 16;
352 cmd[2] = (addr & 0x0000ff00) >> 8;
353 cmd[3] = (addr & 0x000000ff);
354 generic_spi_write_enable();
355 /* Send BE (Block Erase) */
Carl-Daniel Hailfinger21c78902007-12-17 14:33:32 +0000356 generic_spi_command(JEDEC_BE_D8_OUTSIZE, JEDEC_BE_D8_INSIZE, cmd, NULL);
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000357 /* Wait until the Write-In-Progress bit is cleared.
358 * This usually takes 100-4000 ms, so wait in 100 ms steps.
359 */
360 while (generic_spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
361 usleep(100 * 1000);
362 return 0;
363}
364
365/* Sector size is usually 4k, though Macronix eliteflash has 64k */
366int generic_spi_sector_erase(const struct flashchip *flash, unsigned long addr)
367{
368 unsigned char cmd[JEDEC_SE_OUTSIZE] = JEDEC_SE;
369 cmd[1] = (addr & 0x00ff0000) >> 16;
370 cmd[2] = (addr & 0x0000ff00) >> 8;
371 cmd[3] = (addr & 0x000000ff);
372
373 generic_spi_write_enable();
374 /* Send SE (Sector Erase) */
375 generic_spi_command(JEDEC_SE_OUTSIZE, JEDEC_SE_INSIZE, cmd, NULL);
376 /* Wait until the Write-In-Progress bit is cleared.
377 * This usually takes 15-800 ms, so wait in 10 ms steps.
378 */
379 while (generic_spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
380 usleep(10 * 1000);
381 return 0;
382}
383
384/* Page size is usually 256 bytes */
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000385void it8716f_spi_page_program(int block, uint8_t *buf, uint8_t *bios) {
386 int i;
387
388 generic_spi_write_enable();
389 outb(0x06 , it8716f_flashport + 1);
390 outb((3 << 4), it8716f_flashport);
391 for (i = 0; i < 256; i++) {
392 bios[256 * block + i] = buf[256 * block + i];
393 }
394 outb(0, it8716f_flashport);
Carl-Daniel Hailfinger5b1c6ed2007-10-22 16:15:28 +0000395 /* Wait until the Write-In-Progress bit is cleared.
396 * This usually takes 1-10 ms, so wait in 1 ms steps.
397 */
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000398 while (generic_spi_read_status_register() & JEDEC_RDSR_BIT_WIP)
399 usleep(1000);
Carl-Daniel Hailfinger6b444962007-10-18 00:24:07 +0000400}
401
402void generic_spi_page_program(int block, uint8_t *buf, uint8_t *bios)
403{
404 if (it8716f_flashport)
405 it8716f_spi_page_program(block, buf, bios);
406}
407
408int generic_spi_chip_write(struct flashchip *flash, uint8_t *buf) {
409 int total_size = 1024 * flash->total_size;
410 int i;
411 for (i = 0; i < total_size / 256; i++) {
412 generic_spi_page_program(i, buf, (uint8_t *)flash->virtual_memory);
413 }
414 return 0;
415}
416