blob: eab48ea6d1ea4c0571147afedbe5614695aed908 [file] [log] [blame]
Norman James6a58a272015-10-07 14:34:16 -05001#include <stdint.h>
2#include <stdbool.h>
3#include <stdlib.h>
4#include <errno.h>
5#include <stdio.h>
6#include <string.h>
7
8#include <libflash/libflash.h>
9#include <libflash/libflash-priv.h>
10
11#include "ast.h"
12
13#ifndef __unused
14#define __unused __attribute__((unused))
15#endif
16
17#define CALIBRATE_BUF_SIZE 16384
18
19struct ast_sf_ctrl {
20 /* We have 2 controllers, one for the BMC flash, one for the PNOR */
21 uint8_t type;
22
23 /* Address and previous value of the ctrl register */
24 uint32_t ctl_reg;
25
26 /* Control register value for normal commands */
27 uint32_t ctl_val;
28
29 /* Control register value for (fast) reads */
30 uint32_t ctl_read_val;
31
32 /* Flash read timing register */
33 uint32_t fread_timing_reg;
34 uint32_t fread_timing_val;
35
36 /* Address of the flash mapping */
37 uint32_t flash;
38
39 /* Current 4b mode */
40 bool mode_4b;
41
42 /* Callbacks */
43 struct spi_flash_ctrl ops;
44};
45
46static uint32_t ast_ahb_freq;
47
48static const uint32_t ast_ct_hclk_divs[] = {
49 0xf, /* HCLK */
50 0x7, /* HCLK/2 */
51 0xe, /* HCLK/3 */
52 0x6, /* HCLK/4 */
53 0xd, /* HCLK/5 */
54};
55
56static int ast_sf_start_cmd(struct ast_sf_ctrl *ct, uint8_t cmd)
57{
58 /* Switch to user mode, CE# dropped */
59 ast_ahb_writel(ct->ctl_val | 7, ct->ctl_reg);
60
61 /* user mode, CE# active */
62 ast_ahb_writel(ct->ctl_val | 3, ct->ctl_reg);
63
64 /* write cmd */
65 return ast_copy_to_ahb(ct->flash, &cmd, 1);
66}
67
68static void ast_sf_end_cmd(struct ast_sf_ctrl *ct)
69{
70 /* clear CE# */
71 ast_ahb_writel(ct->ctl_val | 7, ct->ctl_reg);
72
73 /* Switch back to read mode */
74 ast_ahb_writel(ct->ctl_read_val, ct->ctl_reg);
75}
76
77static int ast_sf_send_addr(struct ast_sf_ctrl *ct, uint32_t addr)
78{
79 const void *ap;
80
81 /* Layout address MSB first in memory */
82 addr = cpu_to_be32(addr);
83
84 /* Send the right amount of bytes */
85 ap = (char *)&addr;
86
87 if (ct->mode_4b)
88 return ast_copy_to_ahb(ct->flash, ap, 4);
89 else
90 return ast_copy_to_ahb(ct->flash, ap + 1, 3);
91}
92
93static int ast_sf_cmd_rd(struct spi_flash_ctrl *ctrl, uint8_t cmd,
94 bool has_addr, uint32_t addr, void *buffer,
95 uint32_t size)
96{
97 struct ast_sf_ctrl *ct = container_of(ctrl, struct ast_sf_ctrl, ops);
98 int rc;
99
100 rc = ast_sf_start_cmd(ct, cmd);
101 if (rc)
102 goto bail;
103 if (has_addr) {
104 rc = ast_sf_send_addr(ct, addr);
105 if (rc)
106 goto bail;
107 }
108 if (buffer && size)
109 rc = ast_copy_from_ahb(buffer, ct->flash, size);
110 bail:
111 ast_sf_end_cmd(ct);
112 return rc;
113}
114
115static int ast_sf_cmd_wr(struct spi_flash_ctrl *ctrl, uint8_t cmd,
116 bool has_addr, uint32_t addr, const void *buffer,
117 uint32_t size)
118{
119 struct ast_sf_ctrl *ct = container_of(ctrl, struct ast_sf_ctrl, ops);
120 int rc;
121
122 rc = ast_sf_start_cmd(ct, cmd);
123 if (rc)
124 goto bail;
125 if (has_addr) {
126 rc = ast_sf_send_addr(ct, addr);
127 if (rc)
128 goto bail;
129 }
130 if (buffer && size)
131 rc = ast_copy_to_ahb(ct->flash, buffer, size);
132 bail:
133 ast_sf_end_cmd(ct);
134 return rc;
135}
136
137static int ast_sf_set_4b(struct spi_flash_ctrl *ctrl, bool enable)
138{
139 struct ast_sf_ctrl *ct = container_of(ctrl, struct ast_sf_ctrl, ops);
140
141 if (ct->type != AST_SF_TYPE_PNOR)
142 return enable ? FLASH_ERR_4B_NOT_SUPPORTED : 0;
143
144 /*
145 * We update the "old" value as well since when quitting
146 * we don't restore the mode of the flash itself so we need
147 * to leave the controller in a compatible setup
148 */
149 if (enable) {
150 ct->ctl_val |= 0x2000;
151 ct->ctl_read_val |= 0x2000;
152 } else {
153 ct->ctl_val &= ~0x2000;
154 ct->ctl_read_val &= ~0x2000;
155 }
156 ct->mode_4b = enable;
157
158 /* Update read mode */
159 ast_ahb_writel(ct->ctl_read_val, ct->ctl_reg);
160
161 return 0;
162}
163
164static int ast_sf_read(struct spi_flash_ctrl *ctrl, uint32_t pos,
165 void *buf, uint32_t len)
166{
167 struct ast_sf_ctrl *ct = container_of(ctrl, struct ast_sf_ctrl, ops);
168
169 /*
170 * We are in read mode by default. We don't yet support fancy
171 * things like fast read or X2 mode
172 */
173 return ast_copy_from_ahb(buf, ct->flash + pos, len);
174}
175
176static void ast_get_ahb_freq(void)
177{
178 static const uint32_t cpu_freqs_24_48[] = {
179 384000000,
180 360000000,
181 336000000,
182 408000000
183 };
184 static const uint32_t cpu_freqs_25[] = {
185 400000000,
186 375000000,
187 350000000,
188 425000000
189 };
190 static const uint32_t ahb_div[] = { 1, 2, 4, 3 };
191 uint32_t strap, cpu_clk, div;
192
193 if (ast_ahb_freq)
194 return;
195
196 /* HW strapping gives us the CPU freq and AHB divisor */
197 strap = ast_ahb_readl(SCU_HW_STRAPPING);
198 if (strap & 0x00800000) {
199 FL_DBG("AST: CLKIN 25Mhz\n");
200 cpu_clk = cpu_freqs_25[(strap >> 8) & 3];
201 } else {
202 FL_DBG("AST: CLKIN 24/48Mhz\n");
203 cpu_clk = cpu_freqs_24_48[(strap >> 8) & 3];
204 }
205 FL_DBG("AST: CPU frequency: %d Mhz\n", cpu_clk / 1000000);
206 div = ahb_div[(strap >> 10) & 3];
207 ast_ahb_freq = cpu_clk / div;
208 FL_DBG("AST: AHB frequency: %d Mhz\n", ast_ahb_freq / 1000000);
209}
210
211static int ast_sf_check_reads(struct ast_sf_ctrl *ct,
212 const uint8_t *golden_buf, uint8_t *test_buf)
213{
214 int i, rc;
215
216 for (i = 0; i < 10; i++) {
217 rc = ast_copy_from_ahb(test_buf, ct->flash, CALIBRATE_BUF_SIZE);
218 if (rc)
219 return rc;
220 if (memcmp(test_buf, golden_buf, CALIBRATE_BUF_SIZE) != 0)
221 return FLASH_ERR_VERIFY_FAILURE;
222 }
223 return 0;
224}
225
226static int ast_sf_calibrate_reads(struct ast_sf_ctrl *ct, uint32_t hdiv,
227 const uint8_t *golden_buf, uint8_t *test_buf)
228{
229 int i, rc;
230 int good_pass = -1, pass_count = 0;
231 uint32_t shift = (hdiv - 1) << 2;
232 uint32_t mask = ~(0xfu << shift);
233
234#define FREAD_TPASS(i) (((i) / 2) | (((i) & 1) ? 0 : 8))
235
236 /* Try HCLK delay 0..5, each one with/without delay and look for a
237 * good pair.
238 */
239 for (i = 0; i < 12; i++) {
240 bool pass;
241
242 ct->fread_timing_val &= mask;
243 ct->fread_timing_val |= FREAD_TPASS(i) << shift;
244 ast_ahb_writel(ct->fread_timing_val, ct->fread_timing_reg);
245 rc = ast_sf_check_reads(ct, golden_buf, test_buf);
246 if (rc && rc != FLASH_ERR_VERIFY_FAILURE)
247 return rc;
248 pass = (rc == 0);
249 FL_DBG(" * [%08x] %d HCLK delay, %dns DI delay : %s\n",
250 ct->fread_timing_val, i/2, (i & 1) ? 0 : 4, pass ? "PASS" : "FAIL");
251 if (pass) {
252 pass_count++;
253 if (pass_count == 3) {
254 good_pass = i - 1;
255 break;
256 }
257 } else
258 pass_count = 0;
259 }
260
261 /* No good setting for this frequency */
262 if (good_pass < 0)
263 return FLASH_ERR_VERIFY_FAILURE;
264
265 /* We have at least one pass of margin, let's use first pass */
266 ct->fread_timing_val &= mask;
267 ct->fread_timing_val |= FREAD_TPASS(good_pass) << shift;
268 ast_ahb_writel(ct->fread_timing_val, ct->fread_timing_reg);
269 FL_DBG("AST: * -> good is pass %d [0x%08x]\n",
270 good_pass, ct->fread_timing_val);
271 return 0;
272}
273
274static bool ast_calib_data_usable(const uint8_t *test_buf, uint32_t size)
275{
276 const uint32_t *tb32 = (const uint32_t *)test_buf;
277 uint32_t i, cnt = 0;
278
279 /* We check if we have enough words that are neither all 0
280 * nor all 1's so the calibration can be considered valid.
281 *
282 * I use an arbitrary threshold for now of 64
283 */
284 size >>= 2;
285 for (i = 0; i < size; i++) {
286 if (tb32[i] != 0 && tb32[i] != 0xffffffff)
287 cnt++;
288 }
289 return cnt >= 64;
290}
291
292static int ast_sf_optimize_reads(struct ast_sf_ctrl *ct, struct flash_info *info,
293 uint32_t max_freq)
294{
295 uint8_t *golden_buf, *test_buf;
296 int i, rc, best_div = -1;
297 uint32_t save_read_val = ct->ctl_read_val;
298
299 test_buf = malloc(CALIBRATE_BUF_SIZE * 2);
300 golden_buf = test_buf + CALIBRATE_BUF_SIZE;
301
302 /* We start with the dumbest setting and read some data */
303 ct->ctl_read_val = (ct->ctl_read_val & 0x2000) |
304 (0x00 << 28) | /* Single bit */
305 (0x00 << 24) | /* CE# max */
306 (0x03 << 16) | /* use normal reads */
307 (0x00 << 8) | /* HCLK/16 */
308 (0x00 << 6) | /* no dummy cycle */
309 (0x00); /* normal read */
310 ast_ahb_writel(ct->ctl_read_val, ct->ctl_reg);
311
312 rc = ast_copy_from_ahb(golden_buf, ct->flash, CALIBRATE_BUF_SIZE);
313 if (rc) {
314 free(test_buf);
315 return rc;
316 }
317
318 /* Establish our read mode with freq field set to 0 */
319 ct->ctl_read_val = save_read_val & 0xfffff0ff;
320
321 /* Check if calibration data is suitable */
Norman James61aad542015-11-01 20:12:19 -0600322/*
Norman James6a58a272015-10-07 14:34:16 -0500323 if (!ast_calib_data_usable(golden_buf, CALIBRATE_BUF_SIZE)) {
324 FL_INF("AST: Calibration area too uniform, "
325 "using low speed\n");
326 ast_ahb_writel(ct->ctl_read_val, ct->ctl_reg);
327 free(test_buf);
328 return 0;
329 }
Norman James61aad542015-11-01 20:12:19 -0600330*/
Norman James6a58a272015-10-07 14:34:16 -0500331 /* Now we iterate the HCLK dividers until we find our breaking point */
332 for (i = 5; i > 0; i--) {
333 uint32_t tv, freq;
334
335 /* Compare timing to max */
336 freq = ast_ahb_freq / i;
337 if (freq >= max_freq)
338 continue;
339
340 /* Set the timing */
341 tv = ct->ctl_read_val | (ast_ct_hclk_divs[i - 1] << 8);
342 ast_ahb_writel(tv, ct->ctl_reg);
343 FL_DBG("AST: Trying HCLK/%d...\n", i);
344 rc = ast_sf_calibrate_reads(ct, i, golden_buf, test_buf);
345
346 /* Some other error occurred, bail out */
347 if (rc && rc != FLASH_ERR_VERIFY_FAILURE) {
348 free(test_buf);
349 return rc;
350 }
351 if (rc == 0)
352 best_div = i;
353 }
354 free(test_buf);
355
356 /* Nothing found ? */
357 if (best_div < 0)
358 FL_ERR("AST: No good frequency, using dumb slow\n");
359 else {
360 FL_DBG("AST: Found good read timings at HCLK/%d\n", best_div);
361 ct->ctl_read_val |= (ast_ct_hclk_divs[best_div - 1] << 8);
362 }
363 ast_ahb_writel(ct->ctl_read_val, ct->ctl_reg);
364
365 return 0;
366}
367
368static int ast_sf_get_hclk(uint32_t *ctl_val, uint32_t max_freq)
369{
370 int i;
371
372 /* It appears that running commands at HCLK/2 on some micron
373 * chips results in occasionally reads of bogus status (that
374 * or unrelated chip hangs).
375 *
376 * Since we cannot calibrate properly the reads for commands,
377 * instead, let's limit our SPI frequency to HCLK/4 to stay
378 * on the safe side of things
379 */
380#define MIN_CMD_FREQ 4
381 for (i = MIN_CMD_FREQ; i <= 5; i++) {
382 uint32_t freq = ast_ahb_freq / i;
383 if (freq >= max_freq)
384 continue;
385 *ctl_val |= (ast_ct_hclk_divs[i - 1] << 8);
386 return i;
387 }
388 return 0;
389}
390
391static int ast_sf_setup_macronix(struct ast_sf_ctrl *ct, struct flash_info *info)
392{
393 int rc, div;
394 uint8_t srcr[2];
395
396 /*
397 * Those Macronix chips support dual reads at 104Mhz
398 * and dual IO at 84Mhz with 4 dummies.
399 *
400 * Our calibration algo should give us something along
401 * the lines of HCLK/3 (HCLK/2 seems to work sometimes
402 * but appears to be fairly unreliable) which is 64Mhz
403 *
404 * So we chose dual IO mode.
405 *
406 * The CE# inactive width for reads must be 7ns, we set it
407 * to 3T which is about 15ns at the fastest speed we support
408 * HCLK/2) as I've had issue with smaller values.
409 *
410 * For write and program it's 30ns so let's set the value
411 * for normal ops to 6T.
412 *
413 * Preserve the current 4b mode.
414 */
415 FL_DBG("AST: Setting up Macronix...\n");
416
417 /*
418 * Read the status and config registers
419 */
420 rc = ast_sf_cmd_rd(&ct->ops, CMD_RDSR, false, 0, &srcr[0], 1);
421 if (rc != 0) {
422 FL_ERR("AST: Failed to read status\n");
423 return rc;
424 }
425 rc = ast_sf_cmd_rd(&ct->ops, CMD_RDCR, false, 0, &srcr[1], 1);
426 if (rc != 0) {
427 FL_ERR("AST: Failed to read configuration\n");
428 return rc;
429 }
430
431 FL_DBG("AST: Macronix SR:CR: 0x%02x:%02x\n", srcr[0], srcr[1]);
432
433 /* Switch to 8 dummy cycles to enable 104Mhz operations */
434 srcr[1] = (srcr[1] & 0x3f) | 0x80;
435
436 rc = fl_wren(&ct->ops);
437 if (rc) {
438 FL_ERR("AST: Failed to WREN for Macronix config\n");
439 return rc;
440 }
441
442 rc = ast_sf_cmd_wr(&ct->ops, CMD_WRSR, false, 0, srcr, 2);
443 if (rc != 0) {
444 FL_ERR("AST: Failed to write Macronix config\n");
445 return rc;
446 }
447 rc = fl_sync_wait_idle(&ct->ops);;
448 if (rc != 0) {
449 FL_ERR("AST: Failed waiting for config write\n");
450 return rc;
451 }
452
453 FL_DBG("AST: Macronix SR:CR: 0x%02x:%02x\n", srcr[0], srcr[1]);
454
455 /* Use 2READ */
456 ct->ctl_read_val = (ct->ctl_read_val & 0x2000) |
457 (0x03 << 28) | /* Dual IO */
458 (0x0d << 24) | /* CE# width 3T */
459 (0xbb << 16) | /* 2READ command */
460 (0x00 << 8) | /* HCLK/16 (optimize later) */
461 (0x02 << 6) | /* 2 bytes dummy cycle (8 clocks) */
462 (0x01); /* fast read */
463
464 /* Configure SPI flash read timing */
465 rc = ast_sf_optimize_reads(ct, info, 104000000);
466 if (rc) {
467 FL_ERR("AST: Failed to setup proper read timings, rc=%d\n", rc);
468 return rc;
469 }
470
471 /*
472 * For other commands and writes also increase the SPI clock
473 * to HCLK/2 since the chip supports up to 133Mhz and set
474 * CE# inactive to 6T. We request a timing that is 20% below
475 * the limit of the chip, so about 106Mhz which should fit.
476 */
477 ct->ctl_val = (ct->ctl_val & 0x2000) |
478 (0x00 << 28) | /* Single bit */
479 (0x0a << 24) | /* CE# width 6T (b1010) */
480 (0x00 << 16) | /* no command */
481 (0x00 << 8) | /* HCLK/16 (done later) */
482 (0x00 << 6) | /* no dummy cycle */
483 (0x00); /* normal read */
484
485 div = ast_sf_get_hclk(&ct->ctl_val, 106000000);
486 FL_DBG("AST: Command timing set to HCLK/%d\n", div);
487
488 /* Update chip with current read config */
489 ast_ahb_writel(ct->ctl_read_val, ct->ctl_reg);
490 return 0;
491}
492
493static int ast_sf_setup_winbond(struct ast_sf_ctrl *ct, struct flash_info *info)
494{
495 int rc, div;
496
497 FL_DBG("AST: Setting up Windbond...\n");
498
499 /*
500 * This Windbond chip support dual reads at 104Mhz
501 * with 8 dummy cycles.
502 *
503 * The CE# inactive width for reads must be 10ns, we set it
504 * to 3T which is about 15.6ns.
505 */
506 ct->ctl_read_val = (ct->ctl_read_val & 0x2000) |
507 (0x02 << 28) | /* Dual bit data only */
508 (0x0e << 24) | /* CE# width 2T (b1110) */
509 (0x3b << 16) | /* DREAD command */
510 (0x00 << 8) | /* HCLK/16 */
511 (0x01 << 6) | /* 1-byte dummy cycle */
512 (0x01); /* fast read */
513
514 /* Configure SPI flash read timing */
515 rc = ast_sf_optimize_reads(ct, info, 104000000);
516 if (rc) {
517 FL_ERR("AST: Failed to setup proper read timings, rc=%d\n", rc);
518 return rc;
519 }
520
521 /*
522 * For other commands and writes also increase the SPI clock
523 * to HCLK/2 since the chip supports up to 133Mhz. CE# inactive
524 * for write and erase is 50ns so let's set it to 10T.
525 */
526 ct->ctl_val = (ct->ctl_read_val & 0x2000) |
527 (0x00 << 28) | /* Single bit */
528 (0x06 << 24) | /* CE# width 10T (b0110) */
529 (0x00 << 16) | /* no command */
530 (0x00 << 8) | /* HCLK/16 */
531 (0x00 << 6) | /* no dummy cycle */
532 (0x01); /* fast read */
533
534 div = ast_sf_get_hclk(&ct->ctl_val, 106000000);
535 FL_DBG("AST: Command timing set to HCLK/%d\n", div);
536
537 /* Update chip with current read config */
538 ast_ahb_writel(ct->ctl_read_val, ct->ctl_reg);
539 return 0;
540}
541
542static int ast_sf_setup_micron(struct ast_sf_ctrl *ct, struct flash_info *info)
543{
544 uint8_t vconf, ext_id[6];
545 int rc, div;
546
547 FL_DBG("AST: Setting up Micron...\n");
548
549 /*
550 * Read the extended chip ID to try to detect old vs. new
551 * flashes since old Micron flashes have a lot of issues
552 */
553 rc = ast_sf_cmd_rd(&ct->ops, CMD_RDID, false, 0, ext_id, 6);
554 if (rc != 0) {
555 FL_ERR("AST: Failed to read Micron ext ID, sticking to dumb speed\n");
556 return 0;
557 }
558 /* Check ID matches expectations */
559 if (ext_id[0] != ((info->id >> 16) & 0xff) ||
560 ext_id[1] != ((info->id >> 8) & 0xff) ||
561 ext_id[2] != ((info->id ) & 0xff)) {
562 FL_ERR("AST: Micron ext ID mismatch, sticking to dumb speed\n");
563 return 0;
564 }
565 FL_DBG("AST: Micron ext ID byte: 0x%02x\n", ext_id[4]);
566
567 /* Check for old (<45nm) chips, don't try to be fancy on those */
568 if (!(ext_id[4] & 0x40)) {
569 FL_DBG("AST: Old chip, using dumb timings\n");
570 goto dumb;
571 }
572
573 /*
574 * Read the micron specific volatile configuration reg
575 */
576 rc = ast_sf_cmd_rd(&ct->ops, CMD_MIC_RDVCONF, false, 0, &vconf, 1);
577 if (rc != 0) {
578 FL_ERR("AST: Failed to read Micron vconf, sticking to dumb speed\n");
579 goto dumb;
580 }
581 FL_DBG("AST: Micron VCONF: 0x%02x\n", vconf);
582
583 /* Switch to 8 dummy cycles (we might be able to operate with 4
584 * but let's keep some margin
585 */
586 vconf = (vconf & 0x0f) | 0x80;
587
588 rc = ast_sf_cmd_wr(&ct->ops, CMD_MIC_WRVCONF, false, 0, &vconf, 1);
589 if (rc != 0) {
590 FL_ERR("AST: Failed to write Micron vconf, "
591 " sticking to dumb speed\n");
592 goto dumb;
593 }
594 rc = fl_sync_wait_idle(&ct->ops);;
595 if (rc != 0) {
596 FL_ERR("AST: Failed waiting for config write\n");
597 return rc;
598 }
599 FL_DBG("AST: Updated to : 0x%02x\n", vconf);
600
601 /*
602 * Try to do full dual IO, with 8 dummy cycles it supports 133Mhz
603 *
604 * The CE# inactive width for reads must be 20ns, we set it
605 * to 4T which is about 20.8ns.
606 */
607 ct->ctl_read_val = (ct->ctl_read_val & 0x2000) |
608 (0x03 << 28) | /* Single bit */
609 (0x0c << 24) | /* CE# 4T */
610 (0xbb << 16) | /* 2READ command */
611 (0x00 << 8) | /* HCLK/16 (optimize later) */
612 (0x02 << 6) | /* 8 dummy cycles (2 bytes) */
613 (0x01); /* fast read */
614
615 /* Configure SPI flash read timing */
616 rc = ast_sf_optimize_reads(ct, info, 133000000);
617 if (rc) {
618 FL_ERR("AST: Failed to setup proper read timings, rc=%d\n", rc);
619 return rc;
620 }
621
622 /*
623 * For other commands and writes also increase the SPI clock
624 * to HCLK/2 since the chip supports up to 133Mhz. CE# inactive
625 * for write and erase is 50ns so let's set it to 10T.
626 */
627 ct->ctl_val = (ct->ctl_read_val & 0x2000) |
628 (0x00 << 28) | /* Single bit */
629 (0x06 << 24) | /* CE# width 10T (b0110) */
630 (0x00 << 16) | /* no command */
631 (0x00 << 8) | /* HCLK/16 */
632 (0x00 << 6) | /* no dummy cycle */
633 (0x00); /* norm read */
634
635 div = ast_sf_get_hclk(&ct->ctl_val, 133000000);
636 FL_DBG("AST: Command timing set to HCLK/%d\n", div);
637
638 /* Update chip with current read config */
639 ast_ahb_writel(ct->ctl_read_val, ct->ctl_reg);
640
641 return 0;
642
643 dumb:
644 ct->ctl_val = ct->ctl_read_val = (ct->ctl_read_val & 0x2000) |
645 (0x00 << 28) | /* Single bit */
646 (0x00 << 24) | /* CE# max */
647 (0x03 << 16) | /* use normal reads */
648 (0x06 << 8) | /* HCLK/4 */
649 (0x00 << 6) | /* no dummy cycle */
650 (0x00); /* normal read */
651
652 /* Update chip with current read config */
653 ast_ahb_writel(ct->ctl_read_val, ct->ctl_reg);
654
655 return 0;
656}
657
658static int ast_sf_setup(struct spi_flash_ctrl *ctrl, uint32_t *tsize)
659{
660 struct ast_sf_ctrl *ct = container_of(ctrl, struct ast_sf_ctrl, ops);
661 struct flash_info *info = ctrl->finfo;
662
663 (void)tsize;
664
665 /*
666 * Configure better timings and read mode for known
667 * flash chips
668 */
669 switch(info->id) {
670 case 0xc22019: /* MX25L25635F */
671 case 0xc2201a: /* MX66L51235F */
672 return ast_sf_setup_macronix(ct, info);
673 case 0xef4018: /* W25Q128BV */
674 return ast_sf_setup_winbond(ct, info);
675 case 0x20ba20: /* MT25Qx512xx */
676 return ast_sf_setup_micron(ct, info);
677 }
678 /* No special tuning */
679 return 0;
680}
681
682static bool ast_sf_init_pnor(struct ast_sf_ctrl *ct)
683{
684 uint32_t reg;
685
686 ct->ctl_reg = PNOR_SPI_FCTL_CTRL;
687 ct->fread_timing_reg = PNOR_SPI_FREAD_TIMING;
688 ct->flash = PNOR_FLASH_BASE;
689
690 /* Enable writing to the controller */
691 reg = ast_ahb_readl(PNOR_SPI_FCTL_CONF);
692 if (reg == 0xffffffff) {
693 FL_ERR("AST_SF: Failed read from controller config\n");
694 return false;
695 }
696 ast_ahb_writel(reg | 1, PNOR_SPI_FCTL_CONF);
697
698 /*
699 * Snapshot control reg and sanitize it for our
700 * use, switching to 1-bit mode, clearing user
701 * mode if set, etc...
702 *
703 * Also configure SPI clock to something safe
704 * like HCLK/8 (24Mhz)
705 */
706 ct->ctl_val = ast_ahb_readl(ct->ctl_reg);
707 if (ct->ctl_val == 0xffffffff) {
708 FL_ERR("AST_SF: Failed read from controller control\n");
709 return false;
710 }
711
712 ct->ctl_val = (ct->ctl_val & 0x2000) |
713 (0x00 << 28) | /* Single bit */
714 (0x00 << 24) | /* CE# width 16T */
715 (0x00 << 16) | /* no command */
716 (0x04 << 8) | /* HCLK/8 */
717 (0x00 << 6) | /* no dummy cycle */
718 (0x00); /* normal read */
719
720 /* Initial read mode is default */
721 ct->ctl_read_val = ct->ctl_val;
722
723 /* Initial read timings all 0 */
724 ct->fread_timing_val = 0;
725
726 /* Configure for read */
727 ast_ahb_writel(ct->ctl_read_val, ct->ctl_reg);
728 ast_ahb_writel(ct->fread_timing_val, ct->fread_timing_reg);
729
730 if (ct->ctl_val & 0x2000)
731 ct->mode_4b = true;
732 else
733 ct->mode_4b = false;
734
735 return true;
736}
737
738static bool ast_sf_init_bmc(struct ast_sf_ctrl *ct)
739{
740 ct->ctl_reg = BMC_SPI_FCTL_CTRL;
741 ct->fread_timing_reg = BMC_SPI_FREAD_TIMING;
742 ct->flash = BMC_FLASH_BASE;
743
744 /*
745 * Snapshot control reg and sanitize it for our
746 * use, switching to 1-bit mode, clearing user
747 * mode if set, etc...
748 *
749 * Also configure SPI clock to something safe
750 * like HCLK/8 (24Mhz)
751 */
752 ct->ctl_val =
753 (0x00 << 28) | /* Single bit */
754 (0x00 << 24) | /* CE# width 16T */
755 (0x00 << 16) | /* no command */
756 (0x04 << 8) | /* HCLK/8 */
757 (0x00 << 6) | /* no dummy cycle */
758 (0x00); /* normal read */
759
760 /* Initial read mode is default */
761 ct->ctl_read_val = ct->ctl_val;
762
763 /* Initial read timings all 0 */
764 ct->fread_timing_val = 0;
765
766 /* Configure for read */
767 ast_ahb_writel(ct->ctl_read_val, ct->ctl_reg);
768 ast_ahb_writel(ct->fread_timing_val, ct->fread_timing_reg);
769
770 ct->mode_4b = false;
771
772 return true;
773}
774
775int ast_sf_open(uint8_t type, struct spi_flash_ctrl **ctrl)
776{
777 struct ast_sf_ctrl *ct;
778
779 if (type != AST_SF_TYPE_PNOR && type != AST_SF_TYPE_BMC)
780 return -EINVAL;
781
782 *ctrl = NULL;
783 ct = malloc(sizeof(*ct));
784 if (!ct) {
785 FL_ERR("AST_SF: Failed to allocate\n");
786 return -ENOMEM;
787 }
788 memset(ct, 0, sizeof(*ct));
789 ct->type = type;
790 ct->ops.cmd_wr = ast_sf_cmd_wr;
791 ct->ops.cmd_rd = ast_sf_cmd_rd;
792 ct->ops.set_4b = ast_sf_set_4b;
793 ct->ops.read = ast_sf_read;
794 ct->ops.setup = ast_sf_setup;
795
796 ast_get_ahb_freq();
797
798 if (type == AST_SF_TYPE_PNOR) {
799 if (!ast_sf_init_pnor(ct))
800 goto fail;
801 } else {
802 if (!ast_sf_init_bmc(ct))
803 goto fail;
804 }
805
806 *ctrl = &ct->ops;
807
808 return 0;
809 fail:
810 free(ct);
811 return -EIO;
812}
813
814void ast_sf_close(struct spi_flash_ctrl *ctrl)
815{
816 struct ast_sf_ctrl *ct = container_of(ctrl, struct ast_sf_ctrl, ops);
817
818 /* Restore control reg to read */
819 ast_ahb_writel(ct->ctl_read_val, ct->ctl_reg);
820
821 /* Additional cleanup */
822 if (ct->type == AST_SF_TYPE_PNOR) {
823 uint32_t reg = ast_ahb_readl(PNOR_SPI_FCTL_CONF);
824 if (reg != 0xffffffff)
825 ast_ahb_writel(reg & ~1, PNOR_SPI_FCTL_CONF);
826 }
827
828 /* Free the whole lot */
829 free(ct);
830}
831