1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
/* Copyright 2015 The ChromiumOS Authors
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "debug_printf.h"
#include "setup.h"
#include "rom_flash.h"
static int _flash_error(void)
{
int retval = GREG32(FLASH, FSH_ERROR);
if (!retval)
return 0;
debug_printf("Register FLASH_FSH_ERROR is not zero (found %x).\n",
retval);
debug_printf("Will read again to verify FSH_ERROR was cleared ");
debug_printf("and then continue...\n");
retval = GREG32(FLASH, FSH_ERROR);
if (retval) {
debug_printf("ERROR: Read to FLASH_FSH_ERROR (%x) "
"did not clear it\n", retval);
}
return retval;
}
/* Verify the flash controller is awake. */
static int _check_flash_is_awake(void)
{
int retval;
GREG32(FLASH, FSH_TRANS) = 0xFFFFFFFF;
retval = GREG32(FLASH, FSH_TRANS);
GREG32(FLASH, FSH_TRANS) = 0x0;
if (retval == 0) {
debug_printf("ERROR:FLASH Controller seems unresponsive. ");
debug_printf("Did you make sure to run 'reseth'?\n");
return E_FL_NOT_AWAKE;
}
return 0;
}
/* Send cmd to flash controller. */
static int _flash_cmd(uint32_t fidx, uint32_t cmd)
{
int cnt, retval;
/* Activate controller. */
GREG32(FLASH, FSH_PE_EN) = FSH_OP_ENABLE;
GREG32_ADDR(FLASH, FSH_PE_CONTROL0)[fidx] = cmd;
/* wait on FSH_PE_EN (means the operation started) */
cnt = 500; /* TODO(mschilder): pick sane value. */
do {
retval = GREG32(FLASH, FSH_PE_EN);
} while (retval && cnt--);
if (retval) {
debug_printf("ERROR: FLASH_FSH_PE_EN never went to 0, is ");
debug_printf("0x%x after timeout\n", retval);
return E_FL_TIMEOUT;
}
/*
* wait 100us before checking FSH_PE_CONTROL (means the operation
* ended)
*/
cnt = 1000000;
do {
retval = GREG32_ADDR(FLASH, FSH_PE_CONTROL0)[fidx];
} while (retval && --cnt);
if (retval) {
debug_printf
("ERROR: FLASH_FSH_PE_CONTROL%d is 0x%x after timeout\n",
fidx, retval);
GREG32_ADDR(FLASH, FSH_PE_CONTROL0)[fidx] = 0;
return E_FL_TIMEOUT;
}
return 0;
}
int flash_info_read(uint32_t offset, uint32_t *dst)
{
int retval;
/* Make sure flash controller is awake. */
retval = _check_flash_is_awake();
if (retval)
return retval;
GWRITE_FIELD(FLASH, FSH_TRANS, OFFSET, offset);
GWRITE_FIELD(FLASH, FSH_TRANS, MAINB, 1);
GWRITE_FIELD(FLASH, FSH_TRANS, SIZE, 1);
retval = _flash_cmd(1, FSH_OP_READ);
if (retval)
return retval;
if (_flash_error())
return E_FL_ERROR;
if (!retval)
*dst = GREG32(FLASH, FSH_DOUT_VAL1);
return retval;
}
|