blob: e7590c7b0063d86183c04305fc1f79dbcffad811 [file] [log] [blame]
Rong Changaaa1acf2012-06-21 19:21:18 +08001/*
2 * This file is part of the flashrom project.
3 *
4 * Copyright (C) 2012 Google Inc.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 *
17 * Neither the name of Google or the names of contributors or
18 * licensors may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * This software is provided "AS IS," without a warranty of any kind.
22 * ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
23 * INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
24 * PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED.
25 * GOOGLE INC AND ITS LICENSORS SHALL NOT BE LIABLE
26 * FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
27 * OR DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL
28 * GOOGLE OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA,
29 * OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
30 * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
31 * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE,
32 * EVEN IF GOOGLE HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
33 */
34
35#if defined(__i386__) || defined(__x86_64__)
36#include <inttypes.h>
37#include <string.h>
38#include <unistd.h>
39
40#include "chipdrivers.h"
41#include "flash.h"
42#include "programmer.h"
43#include "spi.h"
44
45#define REG_EC_HWVER 0xff00
46#define REG_EC_FWVER 0xff01
47#define REG_EC_EDIID 0xff24
48#define REG_8051_CTRL 0xff14
49
50#define HWVER 0xa2
51#define EDIID 0x02
52#define CPU_RESET 1
53
54/* Hwardware registers */
55#define REG_SPI_DATA 0xfeab
56#define REG_SPI_COMMAND 0xfeac
57#define REG_SPI_CONFIG 0xfead
58#define CFG_CSn_FORCE_LOW (1 << 4)
59#define CFG_COMMAND_WRITE_ENABLE (1 << 3)
60#define CFG_STATUS (1 << 1)
61#define CFG_ENABLE_BUSY_STATUS_CHECK (1 << 0)
62
63/* Timeout */
64#define EC_COMMAND_TIMEOUT 4
65#define EC_RESTART_TIMEOUT 10
66#define ENE_SPI_DELAY_CYCLE 4
67
68/* Configurable ec command/status */
69static unsigned int port_ec_command = 0x6c;
70static unsigned int port_ec_data = 0x68;
71
72static uint8_t ec_reset_cmd = 0x59;
73static uint8_t ec_reset_data = 0xf2;
74
75static uint8_t ec_restart_cmd = 0x59;
76static uint8_t ec_restart_data = 0xf9;
77
78static uint8_t ec_reboot_cmd = 0x59;
79static uint8_t ec_reboot_data = 0xf6;
80
81static const uint16_t ec_status_buf = 0xf554;
82static const uint8_t ec_is_stopping = 0xa5;
83static const uint8_t ec_is_running = 0;
84
85static const uint8_t mask_input_buffer_full = 2;
86static const uint8_t mask_output_buffer_full = 1;
87
88static unsigned int port_io_base = 0xfd60;
89const int port_ene_bank = 1;
90const int port_ene_offset = 2;
91const int port_ene_data = 3;
92
93static void ec_command(uint8_t cmd, uint8_t data)
94{
95 struct timeval begin, now;
96
97 /* Spin wait for EC input buffer empty */
98 gettimeofday(&begin, NULL);
99 while (INB(port_ec_command) & mask_input_buffer_full) {
100 gettimeofday(&now, NULL);
101 if ((now.tv_sec - begin.tv_sec) >= EC_COMMAND_TIMEOUT) {
102 msg_pdbg("%s: buf not empty\n", __func__);
103 return;
104 }
105 }
106 /* Write command */
107 OUTB(cmd, port_ec_command);
108
109 /* Spin wait for EC input buffer empty */
110 gettimeofday(&begin, NULL);
111 while (INB(port_ec_command) & mask_input_buffer_full) {
112 gettimeofday(&now, NULL);
113 if ((now.tv_sec - begin.tv_sec) >= EC_COMMAND_TIMEOUT) {
114 msg_pdbg("%s: buf not empty\n", __func__);
115 return;
116 }
117 }
118 /* Write data */
119 OUTB(data, port_ec_data);
120}
121
122static uint8_t ene_read(uint16_t addr)
123{
124 uint8_t bank;
125 uint8_t offset;
126 uint8_t data;
127
128 bank = addr >> 8;
129 offset = addr & 0xff;
130
131 OUTB(bank, port_io_base + port_ene_bank);
132 OUTB(offset, port_io_base + port_ene_offset);
133 data = INB(port_io_base + port_ene_data);
134
135 return data;
136}
137
138static void ene_write(uint16_t addr, uint8_t data)
139{
140 uint8_t bank;
141 uint8_t offset;
142
143 bank = addr >> 8;
144 offset = addr & 0xff;
145
146 OUTB(bank, port_io_base + port_ene_bank);
147 OUTB(offset, port_io_base + port_ene_offset);
148
149 OUTB(data, port_io_base + port_ene_data);
150}
151
152/**
153 * wait_cycles, wait for n LPC bus clock cycles
154 *
155 * @param n: number of LPC cycles to wait
156 * @return void
157 */
158void wait_cycles(int n)
159{
160 while (n--)
161 INB(port_io_base + port_ene_bank);
162}
163
164static void ene_spi_start(void)
165{
166 int cfg;
167
168 cfg = ene_read(REG_SPI_CONFIG);
169 cfg |= CFG_CSn_FORCE_LOW;
170 cfg |= CFG_COMMAND_WRITE_ENABLE;
171 ene_write(REG_SPI_CONFIG, cfg);
172
173 wait_cycles(ENE_SPI_DELAY_CYCLE);
174}
175
176static void ene_spi_end(void)
177{
178 int cfg;
179
180 cfg = ene_read(REG_SPI_CONFIG);
181 cfg &= ~CFG_CSn_FORCE_LOW;
182 cfg |= CFG_COMMAND_WRITE_ENABLE;
183 ene_write(REG_SPI_CONFIG, cfg);
184
185 wait_cycles(ENE_SPI_DELAY_CYCLE);
186}
187
188static int ene_spi_wait(void)
189{
190 struct timeval begin, now;
191
192 gettimeofday(&begin, NULL);
193 while(ene_read(REG_SPI_CONFIG) & CFG_STATUS) {
194 gettimeofday(&now, NULL);
195 if ((now.tv_sec - begin.tv_sec) >= EC_COMMAND_TIMEOUT) {
196 msg_pdbg("%s: spi busy\n", __func__);
197 return 1;
198 }
199 }
200 return 0;
201}
202
203static int ene_spi_send_command(unsigned int writecnt,
204 unsigned int readcnt,
205 const unsigned char *writearr,
206 unsigned char *readarr)
207{
208 int spicfg;
209 int i;
210
211 ene_spi_start();
212
213 for (i = 0; i < writecnt; i++) {
214 ene_write(REG_SPI_COMMAND, writearr[i]);
215 if (ene_spi_wait()) {
216 msg_pdbg("%s: write count %d\n", __func__, i);
217 return 1;
218 }
219 }
220
221 for (i = 0; i < readcnt; i++) {
222 /* Push data by clock the serial bus */
223 ene_write(REG_SPI_COMMAND, 0);
224 if (ene_spi_wait()) {
225 msg_pdbg("%s: read count %d\n", __func__, i);
226 return 1;
227 }
228 readarr[i] = ene_read(REG_SPI_DATA);
229 if (ene_spi_wait()) {
230 msg_pdbg("%s: read count %d\n", __func__, i);
231 return 1;
232 }
233 }
234
235 ene_spi_end();
236 return 0;
237}
238
239static int ene_enter_flash_mode(void)
240{
241 uint8_t reg, spicfg;
242
243 struct timeval begin, now;
244 gettimeofday(&begin, NULL);
245
246 /* EC prepare reset */
247 ec_command(ec_reset_cmd, ec_reset_data);
248
249 /* Spin wait for EC ready */
250 while (ene_read(ec_status_buf) != ec_is_running) {
251 gettimeofday(&now, NULL);
252 if ((now.tv_sec - begin.tv_sec) >= EC_COMMAND_TIMEOUT) {
253 msg_pdbg("%s: ec reset busy\n", __func__);
254 return -1;
255 }
256 }
257
258 /* Wait 1 second */
259 sleep(1);
260
261 /* Reset 8051 */
262 reg = ene_read(REG_8051_CTRL);
263 reg |= CPU_RESET;
264 ene_write(REG_8051_CTRL, reg);
265
266 return 0;
267}
268
269static int ene_leave_flash_mode(void *data)
270{
271 uint8_t reg, spicfg;
272 struct timeval begin, now;
273
274 reg = ene_read(REG_8051_CTRL);
275 reg &= ~CPU_RESET;
276 ene_write(REG_8051_CTRL, reg);
277
278 gettimeofday(&begin, NULL);
279 /* EC restart */
280 while (ene_read(ec_status_buf) != ec_is_running) {
281 gettimeofday(&now, NULL);
282 if ((now.tv_sec - begin.tv_sec) >= EC_RESTART_TIMEOUT) {
283 msg_pdbg("%s: ec restart busy\n", __func__);
284 return 1;
285 }
286 }
287
288 msg_pdbg("%s: send ec restart\n", __func__);
289 ec_command(ec_restart_cmd, ec_restart_data);
290
291 return 0;
292}
293
294static const struct spi_programmer spi_programmer_ene = {
295 .type = SPI_CONTROLLER_ENE,
296 .max_data_read = 256,
297 .max_data_write = 256,
298 .command = ene_spi_send_command,
299 .multicommand = default_spi_send_multicommand,
300 .read = default_spi_read,
301 .write_256 = default_spi_write_256,
302};
303
304int ene_probe_spi_flash(const char *name)
305{
306 uint8_t hwver, ediid;
307
308 msg_pdbg("%s\n", __func__);
309 hwver = ene_read(REG_EC_HWVER);
310 ediid = ene_read(REG_EC_EDIID);
311
312 if (hwver != HWVER || ediid != EDIID) {
313 msg_pdbg("ENE EC not found (probe failed) : hwver %02x ediid %02x\n",
314 hwver, ediid);
315 return 0;
316 }
317
318 /* TODO: probe the EC stop protocol
319 *
320 * Compal - ec_command(0x41, 0xa1) returns 43 4f 4d 50 41 4c 9c
321 */
322
323
324 if (register_shutdown(ene_leave_flash_mode, NULL))
325 return 1;
326
327 ene_enter_flash_mode();
328
329 buses_supported |= BUS_LPC;
330 register_spi_programmer(&spi_programmer_ene);
331 msg_pdbg("%s: successfully initialized ene\n", __func__);
332 return 0;
333}
334
335#endif /* __i386__ || __x86_64__ */
336