nand: move in driver.h the nand_flash_controller's declaration
[openocd.git] / src / pld / ecp5.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /***************************************************************************
4 * Copyright (C) 2022 by Daniel Anselmi *
5 * danselmi@gmx.ch *
6 ***************************************************************************/
7
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
11
12 #include "lattice.h"
13 #include "lattice_cmd.h"
14
15 #define ISC_PROGRAM_USERCODE 0xC2
16
17 #define STATUS_DONE_BIT 0x00000100
18 #define STATUS_ERROR_BITS 0x00020040
19 #define STATUS_FEA_OTP 0x00004000
20 #define STATUS_FAIL_FLAG 0x00002000
21 #define STATUS_BUSY_FLAG 0x00001000
22 #define REGISTER_ALL_BITS_1 0xffffffff
23
24 int lattice_ecp5_read_status(struct jtag_tap *tap, uint32_t *status, uint32_t out, bool do_idle)
25 {
26 return lattice_read_u32_register(tap, LSC_READ_STATUS, status, out, do_idle);
27 }
28
29 int lattice_ecp5_read_usercode(struct jtag_tap *tap, uint32_t *usercode, uint32_t out)
30 {
31 return lattice_read_u32_register(tap, READ_USERCODE, usercode, out, true);
32 }
33
34 int lattice_ecp5_write_usercode(struct lattice_pld_device *lattice_device, uint32_t usercode)
35 {
36 struct jtag_tap *tap = lattice_device->tap;
37 if (!tap)
38 return ERROR_FAIL;
39
40 int retval = lattice_set_instr(tap, ISC_ENABLE, TAP_IDLE);
41 if (retval != ERROR_OK)
42 return retval;
43 jtag_add_runtest(5, TAP_IDLE);
44 jtag_add_sleep(20000);
45
46 retval = lattice_set_instr(tap, ISC_PROGRAM_USERCODE, TAP_IDLE);
47 if (retval != ERROR_OK)
48 return retval;
49
50 uint8_t buffer[4];
51 struct scan_field field;
52 h_u32_to_le(buffer, usercode);
53 field.num_bits = 32;
54 field.out_value = buffer;
55 field.in_value = NULL;
56 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
57 jtag_add_runtest(5, TAP_IDLE);
58 jtag_add_sleep(2000);
59
60 retval = lattice_set_instr(tap, ISC_DISABLE, TAP_IDLE);
61 if (retval != ERROR_OK)
62 return retval;
63 jtag_add_runtest(5, TAP_IDLE);
64 jtag_add_sleep(200000);
65
66 retval = jtag_execute_queue();
67 if (retval != ERROR_OK)
68 return retval;
69 return lattice_verify_usercode(lattice_device, 0x0, usercode, REGISTER_ALL_BITS_1);
70 }
71
72 static int lattice_ecp5_enable_sram_programming(struct jtag_tap *tap)
73 {
74 int retval = lattice_set_instr(tap, ISC_ENABLE, TAP_IDLE);
75 if (retval != ERROR_OK)
76 return retval;
77
78 struct scan_field field;
79 uint8_t buffer = 0x0;
80 field.num_bits = 8;
81 field.out_value = &buffer;
82 field.in_value = NULL;
83 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
84 jtag_add_runtest(2, TAP_IDLE);
85 jtag_add_sleep(10000);
86
87 return jtag_execute_queue();
88 }
89
90 static int lattice_ecp5_erase_sram(struct jtag_tap *tap)
91 {
92 int retval = lattice_set_instr(tap, ISC_ERASE, TAP_IRPAUSE);
93 if (retval != ERROR_OK)
94 return retval;
95
96 struct scan_field field;
97 uint8_t buffer = 1;
98 field.num_bits = 8;
99 field.out_value = &buffer;
100 field.in_value = NULL;
101 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
102 jtag_add_runtest(2, TAP_IDLE);
103 jtag_add_sleep(200000);
104 return jtag_execute_queue();
105 }
106
107 static int lattice_ecp5_init_address(struct jtag_tap *tap)
108 {
109 int retval = lattice_set_instr(tap, LSC_INIT_ADDRESS, TAP_IDLE);
110 if (retval != ERROR_OK)
111 return retval;
112
113 struct scan_field field;
114 uint8_t buffer = 1;
115 field.num_bits = 8;
116 field.out_value = &buffer;
117 field.in_value = NULL;
118 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
119 jtag_add_runtest(2, TAP_IDLE);
120 jtag_add_sleep(10000);
121 return jtag_execute_queue();
122 }
123
124 static int lattice_ecp5_program_config_map(struct jtag_tap *tap, struct lattice_bit_file *bit_file)
125 {
126 int retval = lattice_set_instr(tap, LSC_BITSTREAM_BURST, TAP_IDLE);
127 if (retval != ERROR_OK)
128 return retval;
129 jtag_add_runtest(2, TAP_IDLE);
130 jtag_add_sleep(10000);
131
132 struct scan_field field;
133 field.num_bits = (bit_file->raw_bit.length - bit_file->offset) * 8;
134 field.out_value = bit_file->raw_bit.data + bit_file->offset;
135 field.in_value = NULL;
136 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
137 retval = lattice_set_instr(tap, BYPASS, TAP_IDLE);
138 if (retval != ERROR_OK)
139 return retval;
140 jtag_add_runtest(100, TAP_IDLE);
141 jtag_add_sleep(10000);
142
143 return jtag_execute_queue();
144 }
145
146 static int lattice_ecp5_exit_programming_mode(struct jtag_tap *tap)
147 {
148 int retval = lattice_set_instr(tap, ISC_DISABLE, TAP_IDLE);
149 if (retval != ERROR_OK)
150 return retval;
151 jtag_add_runtest(2, TAP_IDLE);
152 jtag_add_sleep(200000);
153 retval = lattice_set_instr(tap, BYPASS, TAP_IDLE);
154 if (retval != ERROR_OK)
155 return retval;
156 jtag_add_runtest(2, TAP_IDLE);
157 jtag_add_sleep(1000);
158 return jtag_execute_queue();
159 }
160
161 int lattice_ecp5_load(struct lattice_pld_device *lattice_device, struct lattice_bit_file *bit_file)
162 {
163 struct jtag_tap *tap = lattice_device->tap;
164 if (!tap)
165 return ERROR_FAIL;
166
167 int retval = lattice_preload(lattice_device);
168 if (retval != ERROR_OK)
169 return retval;
170
171 retval = lattice_ecp5_enable_sram_programming(tap);
172 if (retval != ERROR_OK)
173 return retval;
174
175 const uint32_t out = 0x0;
176 const uint32_t expected1 = 0x0;
177 const uint32_t mask1 = STATUS_ERROR_BITS | STATUS_FEA_OTP;
178 retval = lattice_verify_status_register_u32(lattice_device, out, expected1, mask1, true);
179 if (retval != ERROR_OK)
180 return retval;
181
182 retval = lattice_ecp5_erase_sram(tap);
183 if (retval != ERROR_OK)
184 return retval;
185
186 const uint32_t mask2 = STATUS_FAIL_FLAG | STATUS_BUSY_FLAG;
187 retval = lattice_verify_status_register_u32(lattice_device, out, expected1, mask2, false);
188 if (retval != ERROR_OK)
189 return retval;
190
191 retval = lattice_ecp5_init_address(tap);
192 if (retval != ERROR_OK)
193 return retval;
194
195 retval = lattice_ecp5_program_config_map(tap, bit_file);
196 if (retval != ERROR_OK)
197 return retval;
198
199 retval = lattice_ecp5_exit_programming_mode(tap);
200 if (retval != ERROR_OK)
201 return retval;
202
203 const uint32_t expected2 = STATUS_DONE_BIT;
204 const uint32_t mask3 = STATUS_DONE_BIT | STATUS_FAIL_FLAG;
205 return lattice_verify_status_register_u32(lattice_device, out, expected2, mask3, false);
206 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)