1 /* SPDX-License-Identifier: GPL-2.0-or-later */
3 /***************************************************************************
4 * Copyright (C) 2015 by Tobias Diedrich *
5 * <ranma+openwrt@tdiedrich.de> *
7 * based on the stmsmi code written by Antonio Borneo *
8 * <borneo.antonio@gmail.com> *
10 ***************************************************************************/
12 * Driver for the Atheros AR7xxx/AR9xxx SPI flash interface.
14 * Since no SPI mode register is present, presumably only
15 * SPI "mode 3" (CPOL=1 and CPHA=1) is supported.
17 * The SPI interface supports up to 3 chip selects, however the SPI flash
18 * used for booting the system must be connected to CS0.
20 * On boot, the first 4MiB of flash space are memory-mapped into the
21 * area bf000000 - bfffffff (4 copies), so the MIPS bootstrap
22 * vector bfc00000 is mapped to the beginning of the flash.
24 * By writing a 1 to the REMAP_DISABLE bit in the SPI_CONTROL register,
25 * the full area of 16MiB is mapped.
27 * By writing a 0 to the SPI_FUNCTION_SELECT register (write-only dword
28 * register @bf000000), memory mapping is disabled and the SPI registers
29 * are exposed to the CPU instead:
30 * bf000000 SPI_FUNCTION_SELECT
31 * bf000004 SPI_CONTROL
32 * bf000008 SPI_IO_CONTROL
33 * bf00000c SPI_READ_DATA
35 * When not memory-mapped, the SPI interface is essentially bitbanged
36 * using SPI_CONTROL and SPI_IO_CONTROL with the only hardware-assistance
37 * being the 32bit read-only shift-register SPI_READ_DATA.
46 #include <jtag/jtag.h>
47 #include <helper/time_support.h>
48 #include <helper/types.h>
49 #include <target/mips32.h>
50 #include <target/mips32_pracc.h>
51 #include <target/target.h>
53 #define BITS_PER_BYTE 8
55 #define ATH79_REG_FS 0
56 #define ATH79_REG_CLOCK 4
57 #define ATH79_REG_WRITE 8
58 #define ATH79_REG_DATA 12
60 #define ATH79_SPI_CS_ALLHI 0x70000
61 #define ATH79_SPI_CS0_HI 0x10000
62 #define ATH79_SPI_CS1_HI 0x20000
63 #define ATH79_SPI_CS2_HI 0x40000
64 #define ATH79_SPI_CE_HI 0x00100
65 #define ATH79_SPI_DO_HI 0x00001
67 #define ATH79_XFER_FINAL 0x00000001
68 #define ATH79_XFER_PARTIAL 0x00000000
71 #define ATH79_MAX_TIMEOUT (3000)
73 struct ath79_spi_ctx
{
79 struct ath79_flash_bank
{
83 const struct flash_device
*dev
;
84 struct ath79_spi_ctx spi
;
93 static const struct ath79_target target_devices
[] = {
94 /* name, tap_idcode, io_base */
95 { "ATH79", 0x00000001, 0xbf000000 },
99 static const uint32_t ath79_chipselects
[] = {
100 (~ATH79_SPI_CS0_HI
& ATH79_SPI_CS_ALLHI
),
101 (~ATH79_SPI_CS1_HI
& ATH79_SPI_CS_ALLHI
),
102 (~ATH79_SPI_CS2_HI
& ATH79_SPI_CS_ALLHI
),
105 static void ath79_pracc_addn(struct pracc_queue_info
*ctx
,
106 const uint32_t *instr
,
109 for (int i
= 0; i
< n
; i
++)
110 pracc_add(ctx
, 0, instr
[i
]);
113 static int ath79_spi_bitbang_codegen(struct ath79_flash_bank
*ath79_info
,
114 struct pracc_queue_info
*ctx
,
115 uint8_t *data
, int len
,
118 uint32_t cs_high
= ATH79_SPI_CS_ALLHI
;
119 uint32_t cs_low
= ath79_chipselects
[ath79_info
->chipselect
];
120 uint32_t clock_high
= cs_low
| ATH79_SPI_CE_HI
;
121 uint32_t clock_low
= cs_low
;
122 uint32_t pracc_out
= 0;
123 uint32_t io_base
= ath79_info
->io_base
;
125 const uint32_t preamble1
[] = {
126 /* $15 = MIPS32_PRACC_BASE_ADDR */
127 MIPS32_LUI(0, 15, PRACC_UPPER_BASE_ADDR
),
129 MIPS32_LUI(0, 1, UPPER16(io_base
)),
131 ath79_pracc_addn(ctx
, preamble1
, ARRAY_SIZE(preamble1
));
132 if (ath79_info
->spi
.pre_deselect
) {
133 /* Clear deselect flag so we don't deselect again if
134 * this is a partial xfer.
136 ath79_info
->spi
.pre_deselect
= 0;
137 const uint32_t pre_deselect
[] = {
138 /* [$1 + FS] = 1 (enable flash io register access) */
139 MIPS32_LUI(0, 2, UPPER16(1)),
140 MIPS32_ORI(0, 2, 2, LOWER16(1)),
141 MIPS32_SW(0, 2, ATH79_REG_FS
, 1),
142 /* deselect flash just in case */
143 /* $2 = SPI_CS_DIS */
144 MIPS32_LUI(0, 2, UPPER16(cs_high
)),
145 MIPS32_ORI(0, 2, 2, LOWER16(cs_high
)),
146 /* [$1 + WRITE] = $2 */
147 MIPS32_SW(0, 2, ATH79_REG_WRITE
, 1),
149 ath79_pracc_addn(ctx
, pre_deselect
, ARRAY_SIZE(pre_deselect
));
151 const uint32_t preamble2
[] = {
152 /* t0 = CLOCK_LOW + 0-bit */
153 MIPS32_LUI(0, 8, UPPER16((clock_low
+ 0))),
154 MIPS32_ORI(0, 8, 8, LOWER16((clock_low
+ 0))),
155 /* t1 = CLOCK_LOW + 1-bit */
156 MIPS32_LUI(0, 9, UPPER16((clock_low
+ 1))),
157 MIPS32_ORI(0, 9, 9, LOWER16((clock_low
+ 1))),
158 /* t2 = CLOCK_HIGH + 0-bit */
159 MIPS32_LUI(0, 10, UPPER16((clock_high
+ 0))),
160 MIPS32_ORI(0, 10, 10, LOWER16((clock_high
+ 0))),
161 /* t3 = CLOCK_HIGH + 1-bit */
162 MIPS32_LUI(0, 11, UPPER16((clock_high
+ 1))),
163 MIPS32_ORI(0, 11, 11, LOWER16((clock_high
+ 1))),
165 ath79_pracc_addn(ctx
, preamble2
, ARRAY_SIZE(preamble2
));
167 for (int i
= 0; i
< len
; i
++) {
170 /* Generate bitbang code for one byte, highest bit first .*/
171 for (int j
= BITS_PER_BYTE
- 1; j
>= 0; j
--) {
172 int bit
= ((x
>> j
) & 1);
175 /* [$1 + WRITE] = t1 */
177 MIPS32_SW(0, 9, ATH79_REG_WRITE
, 1));
178 /* [$1 + WRITE] = t3 */
180 MIPS32_SW(0, 11, ATH79_REG_WRITE
, 1));
182 /* [$1 + WRITE] = t0 */
184 MIPS32_SW(0, 8, ATH79_REG_WRITE
, 1));
185 /* [$1 + WRITE] = t2 */
187 MIPS32_SW(0, 10, ATH79_REG_WRITE
, 1));
191 /* $3 = [$1 + DATA] */
192 pracc_add(ctx
, 0, MIPS32_LW(0, 3, ATH79_REG_DATA
, 1));
194 pracc_add(ctx
, MIPS32_PRACC_PARAM_OUT
+ pracc_out
,
195 MIPS32_SW(0, 3, PRACC_OUT_OFFSET
+
200 if (len
& 3) { /* not a multiple of 4 bytes */
201 /* $3 = [$1 + DATA] */
202 pracc_add(ctx
, 0, MIPS32_LW(0, 3, ATH79_REG_DATA
, 1));
204 pracc_add(ctx
, MIPS32_PRACC_PARAM_OUT
+ pracc_out
,
205 MIPS32_SW(0, 3, PRACC_OUT_OFFSET
+ pracc_out
, 15));
209 if (ath79_info
->spi
.post_deselect
&& !partial_xfer
) {
210 const uint32_t post_deselect
[] = {
211 /* $2 = SPI_CS_DIS */
212 MIPS32_LUI(0, 2, UPPER16(cs_high
)),
213 MIPS32_ORI(0, 2, 2, LOWER16(cs_high
)),
214 /* [$1 + WRITE] = $2 */
215 MIPS32_SW(0, 2, ATH79_REG_WRITE
, 1),
217 /* [$1 + FS] = 0 (disable flash io register access) */
218 MIPS32_XORI(0, 2, 2, 0),
219 MIPS32_SW(0, 2, ATH79_REG_FS
, 1),
221 ath79_pracc_addn(ctx
, post_deselect
, ARRAY_SIZE(post_deselect
));
224 /* common pracc epilogue */
226 pracc_add(ctx
, 0, MIPS32_B(0, NEG16(ctx
->code_count
+ 1)));
227 /* restore $15 from DeSave */
228 pracc_add(ctx
, 0, MIPS32_MFC0(0, 15, 31, 0));
230 return pracc_out
/ 4;
233 static int ath79_spi_bitbang_chunk(struct flash_bank
*bank
,
234 uint8_t *data
, int len
, int *transferred
)
236 struct target
*target
= bank
->target
;
237 struct ath79_flash_bank
*ath79_info
= bank
->driver_priv
;
238 struct mips32_common
*mips32
= target_to_mips32(target
);
239 struct mips_ejtag
*ejtag_info
= &mips32
->ejtag_info
;
243 * These constants must match the worst case in the above code
244 * generator function ath79_spi_bitbang_codegen.
246 const int pracc_pre_post
= 26;
247 const int pracc_loop_byte
= 8 * 2 + 2;
249 struct pracc_queue_info ctx
= {
250 .ejtag_info
= ejtag_info
252 int max_len
= (PRACC_MAX_INSTRUCTIONS
- pracc_pre_post
) / pracc_loop_byte
;
253 int to_xfer
= len
> max_len
? max_len
: len
;
254 int partial_xfer
= len
!= to_xfer
;
255 int padded_len
= (to_xfer
+ 3) & ~3;
256 uint32_t *out
= malloc(padded_len
);
259 LOG_ERROR("not enough memory");
264 pracc_queue_init(&ctx
);
266 LOG_DEBUG("ath79_spi_bitbang_bytes(%p, %08" PRIx32
", %p, %d)",
267 target
, ath79_info
->io_base
, data
, len
);
269 LOG_DEBUG("max code %d => max len %d. to_xfer %d",
270 PRACC_MAX_INSTRUCTIONS
, max_len
, to_xfer
);
272 pracc_words
= ath79_spi_bitbang_codegen(
273 ath79_info
, &ctx
, data
, to_xfer
, partial_xfer
);
275 LOG_DEBUG("Assembled %d instructions, %d stores",
276 ctx
.code_count
, ctx
.store_count
);
278 ctx
.retval
= mips32_pracc_queue_exec(ejtag_info
, &ctx
, out
, 1);
279 if (ctx
.retval
!= ERROR_OK
)
282 if (to_xfer
& 3) { /* Not a multiple of 4 bytes. */
284 * Need to realign last word since we didn't shift the
287 int missed_bytes
= 4 - (to_xfer
& 3);
289 out
[pracc_words
- 1] <<= BITS_PER_BYTE
* missed_bytes
;
293 * pracc reads return uint32_t in host endianness, convert to
295 * Since we know the ATH79 target is big endian and the SPI
296 * shift register has the bytes in highest to lowest bit order,
297 * this will ensure correct memory byte order regardless of host
300 target_buffer_set_u32_array(target
, (uint8_t *)out
, pracc_words
, out
);
302 if (LOG_LEVEL_IS(LOG_LVL_DEBUG
)) {
303 for (int i
= 0; i
< to_xfer
; i
++) {
304 LOG_DEBUG("bitbang %02x => %02x",
305 data
[i
], ((uint8_t *)out
)[i
]);
308 memcpy(data
, out
, to_xfer
);
309 *transferred
= to_xfer
;
312 pracc_queue_free(&ctx
);
317 static void ath79_spi_bitbang_prepare(struct flash_bank
*bank
)
319 struct ath79_flash_bank
*ath79_info
= bank
->driver_priv
;
321 ath79_info
->spi
.pre_deselect
= 1;
324 static int ath79_spi_bitbang_bytes(struct flash_bank
*bank
,
325 uint8_t *data
, int len
, uint32_t flags
)
327 struct ath79_flash_bank
*ath79_info
= bank
->driver_priv
;
331 ath79_info
->spi
.post_deselect
= !!(flags
& ATH79_XFER_FINAL
);
335 retval
= ath79_spi_bitbang_chunk(
336 bank
, data
, len
, &transferred
);
337 if (retval
!= ERROR_OK
)
347 FLASH_BANK_COMMAND_HANDLER(ath79_flash_bank_command
)
349 struct ath79_flash_bank
*ath79_info
;
352 LOG_DEBUG("%s", __func__
);
354 if (CMD_ARGC
< 6 || CMD_ARGC
> 7)
355 return ERROR_COMMAND_SYNTAX_ERROR
;
358 if (strcmp(CMD_ARGV
[6], "cs0") == 0)
359 chipselect
= 0; /* default */
360 else if (strcmp(CMD_ARGV
[6], "cs1") == 0)
362 else if (strcmp(CMD_ARGV
[6], "cs2") == 0)
365 LOG_ERROR("Unknown arg: %s", CMD_ARGV
[6]);
366 return ERROR_COMMAND_SYNTAX_ERROR
;
370 ath79_info
= calloc(1, sizeof(struct ath79_flash_bank
));
372 LOG_ERROR("not enough memory");
376 ath79_info
->chipselect
= chipselect
;
377 bank
->driver_priv
= ath79_info
;
382 /* Read the status register of the external SPI flash chip. */
383 static int read_status_reg(struct flash_bank
*bank
, uint32_t *status
)
385 uint8_t spi_bytes
[] = {SPIFLASH_READ_STATUS
, 0};
388 /* Send SPI command "read STATUS" */
389 ath79_spi_bitbang_prepare(bank
);
390 retval
= ath79_spi_bitbang_bytes(
391 bank
, spi_bytes
, sizeof(spi_bytes
),
394 *status
= spi_bytes
[1];
399 /* check for WIP (write in progress) bit in status register */
401 static int wait_till_ready(struct flash_bank
*bank
, int timeout
)
407 endtime
= timeval_ms() + timeout
;
409 /* read flash status register */
410 retval
= read_status_reg(bank
, &status
);
411 if (retval
!= ERROR_OK
)
414 if ((status
& SPIFLASH_BSY_BIT
) == 0)
417 } while (timeval_ms() < endtime
);
419 LOG_ERROR("timeout");
423 /* Send "write enable" command to SPI flash chip. */
424 static int ath79_write_enable(struct flash_bank
*bank
)
429 uint8_t spi_bytes
[] = {SPIFLASH_WRITE_ENABLE
};
431 /* Send SPI command "write enable" */
432 ath79_spi_bitbang_prepare(bank
);
433 retval
= ath79_spi_bitbang_bytes(
434 bank
, spi_bytes
, sizeof(spi_bytes
),
436 if (retval
!= ERROR_OK
)
439 /* read flash status register */
440 retval
= read_status_reg(bank
, &status
);
441 if (retval
!= ERROR_OK
)
444 /* Check write enabled */
445 if ((status
& SPIFLASH_WE_BIT
) == 0) {
446 LOG_ERROR("Cannot enable write to flash. Status=0x%08" PRIx32
,
454 static int erase_command(struct flash_bank
*bank
, int sector
)
456 struct ath79_flash_bank
*ath79_info
= bank
->driver_priv
;
457 uint32_t offset
= bank
->sectors
[sector
].offset
;
459 uint8_t spi_bytes
[] = {
460 ath79_info
->dev
->erase_cmd
,
466 /* bitbang command */
467 ath79_spi_bitbang_prepare(bank
);
468 return ath79_spi_bitbang_bytes(
469 bank
, spi_bytes
, sizeof(spi_bytes
),
473 static int ath79_erase_sector(struct flash_bank
*bank
, int sector
)
475 int retval
= ath79_write_enable(bank
);
477 if (retval
!= ERROR_OK
)
480 /* send SPI command "block erase" */
481 retval
= erase_command(bank
, sector
);
482 if (retval
!= ERROR_OK
)
485 /* poll WIP for end of self timed Sector Erase cycle */
486 return wait_till_ready(bank
, ATH79_MAX_TIMEOUT
);
489 static int ath79_erase(struct flash_bank
*bank
, unsigned int first
,
492 struct target
*target
= bank
->target
;
493 struct ath79_flash_bank
*ath79_info
= bank
->driver_priv
;
494 int retval
= ERROR_OK
;
496 LOG_DEBUG("%s: from sector %u to sector %u", __func__
, first
, last
);
498 if (target
->state
!= TARGET_HALTED
) {
499 LOG_ERROR("Target not halted");
500 return ERROR_TARGET_NOT_HALTED
;
503 if ((last
< first
) || (last
>= bank
->num_sectors
)) {
504 LOG_ERROR("Flash sector invalid");
505 return ERROR_FLASH_SECTOR_INVALID
;
508 if (!ath79_info
->probed
) {
509 LOG_ERROR("Flash bank not probed");
510 return ERROR_FLASH_BANK_NOT_PROBED
;
513 if (ath79_info
->dev
->erase_cmd
== 0x00)
514 return ERROR_FLASH_OPER_UNSUPPORTED
;
516 for (unsigned sector
= first
; sector
<= last
; sector
++) {
517 if (bank
->sectors
[sector
].is_protected
) {
518 LOG_ERROR("Flash sector %u protected", sector
);
523 for (unsigned int sector
= first
; sector
<= last
; sector
++) {
524 retval
= ath79_erase_sector(bank
, sector
);
525 if (retval
!= ERROR_OK
)
533 static int ath79_protect(struct flash_bank
*bank
, int set
, unsigned int first
,
536 for (unsigned int sector
= first
; sector
<= last
; sector
++)
537 bank
->sectors
[sector
].is_protected
= set
;
541 static int ath79_write_page(struct flash_bank
*bank
, const uint8_t *buffer
,
542 uint32_t address
, uint32_t len
)
544 struct ath79_flash_bank
*ath79_info
= bank
->driver_priv
;
545 uint8_t spi_bytes
[] = {
546 SPIFLASH_PAGE_PROGRAM
,
552 uint32_t i
, pagesize
;
554 /* if no write pagesize, use reasonable default */
555 pagesize
= ath79_info
->dev
->pagesize
?
556 ath79_info
->dev
->pagesize
: SPIFLASH_DEF_PAGESIZE
;
558 if (address
& 0xff) {
559 LOG_ERROR("ath79_write_page: unaligned write address: %08" PRIx32
,
563 if (!ath79_info
->spi
.page_buf
) {
564 LOG_ERROR("ath79_write_page: page buffer not initialized");
567 if (len
> ath79_info
->dev
->pagesize
) {
568 LOG_ERROR("ath79_write_page: len bigger than page size %" PRIu32
": %" PRIu32
,
573 for (i
= 0; i
< len
; i
++) {
574 if (buffer
[i
] != 0xff)
577 if (i
== len
) /* all 0xff, no need to program. */
580 LOG_INFO("writing %" PRIu32
" bytes to flash page @0x%08" PRIx32
, len
, address
);
582 memcpy(ath79_info
->spi
.page_buf
, buffer
, len
);
585 retval
= ath79_write_enable(bank
);
586 if (retval
!= ERROR_OK
)
589 /* bitbang command */
590 ath79_spi_bitbang_prepare(bank
);
591 retval
= ath79_spi_bitbang_bytes(
592 bank
, spi_bytes
, sizeof(spi_bytes
),
594 if (retval
!= ERROR_OK
)
598 return ath79_spi_bitbang_bytes(
599 bank
, ath79_info
->spi
.page_buf
, len
,
603 static int ath79_write_buffer(struct flash_bank
*bank
, const uint8_t *buffer
,
604 uint32_t address
, uint32_t len
)
606 struct ath79_flash_bank
*ath79_info
= bank
->driver_priv
;
610 LOG_DEBUG("%s: address=0x%08" PRIx32
" len=0x%08" PRIx32
,
611 __func__
, address
, len
);
613 /* if no valid page_size, use reasonable default */
614 page_size
= ath79_info
->dev
->pagesize
?
615 ath79_info
->dev
->pagesize
: SPIFLASH_DEF_PAGESIZE
;
618 int page_len
= len
> page_size
? page_size
: len
;
620 retval
= ath79_write_page(
621 bank
, buffer
, address
, page_len
);
622 if (retval
!= ERROR_OK
)
626 address
+= page_size
;
633 static int ath79_write(struct flash_bank
*bank
, const uint8_t *buffer
,
634 uint32_t offset
, uint32_t count
)
636 struct target
*target
= bank
->target
;
638 LOG_DEBUG("%s: offset=0x%08" PRIx32
" count=0x%08" PRIx32
,
639 __func__
, offset
, count
);
641 if (target
->state
!= TARGET_HALTED
) {
642 LOG_ERROR("Target not halted");
643 return ERROR_TARGET_NOT_HALTED
;
646 if (offset
+ count
> bank
->size
) {
647 LOG_WARNING("Write pasts end of flash. Extra data discarded.");
648 count
= bank
->size
- offset
;
651 /* Check sector protection */
652 for (unsigned int sector
= 0; sector
< bank
->num_sectors
; sector
++) {
653 /* Start offset in or before this sector? */
654 /* End offset in or behind this sector? */
655 struct flash_sector
*bs
= &bank
->sectors
[sector
];
657 if ((offset
< (bs
->offset
+ bs
->size
)) &&
658 ((offset
+ count
- 1) >= bs
->offset
) &&
660 LOG_ERROR("Flash sector %u protected", sector
);
665 return ath79_write_buffer(bank
, buffer
, offset
, count
);
668 static int ath79_read_buffer(struct flash_bank
*bank
, uint8_t *buffer
,
669 uint32_t address
, uint32_t len
)
671 uint8_t spi_bytes
[] = {
679 LOG_DEBUG("%s: address=0x%08" PRIx32
" len=0x%08" PRIx32
,
680 __func__
, address
, len
);
682 if (address
& 0xff) {
683 LOG_ERROR("ath79_read_buffer: unaligned read address: %08" PRIx32
,
688 LOG_INFO("reading %" PRIu32
" bytes from flash @0x%08" PRIx32
, len
, address
);
690 /* bitbang command */
691 ath79_spi_bitbang_prepare(bank
);
692 retval
= ath79_spi_bitbang_bytes(
693 bank
, spi_bytes
, sizeof(spi_bytes
), ATH79_XFER_PARTIAL
);
694 if (retval
!= ERROR_OK
)
698 return ath79_spi_bitbang_bytes(
699 bank
, buffer
, len
, ATH79_XFER_FINAL
);
702 static int ath79_read(struct flash_bank
*bank
, uint8_t *buffer
,
703 uint32_t offset
, uint32_t count
)
705 struct target
*target
= bank
->target
;
707 LOG_DEBUG("%s: offset=0x%08" PRIx32
" count=0x%08" PRIx32
,
708 __func__
, offset
, count
);
710 if (target
->state
!= TARGET_HALTED
) {
711 LOG_ERROR("Target not halted");
712 return ERROR_TARGET_NOT_HALTED
;
715 if (offset
+ count
> bank
->size
) {
716 LOG_WARNING("Reads past end of flash. Extra data discarded.");
717 count
= bank
->size
- offset
;
720 return ath79_read_buffer(bank
, buffer
, offset
, count
);
723 /* Return ID of flash device */
724 static int read_flash_id(struct flash_bank
*bank
, uint32_t *id
)
726 struct target
*target
= bank
->target
;
728 uint8_t spi_bytes
[] = {SPIFLASH_READ_ID
, 0, 0, 0};
730 if (target
->state
!= TARGET_HALTED
) {
731 LOG_ERROR("Target not halted");
732 return ERROR_TARGET_NOT_HALTED
;
735 /* Send SPI command "read ID" */
736 ath79_spi_bitbang_prepare(bank
);
737 retval
= ath79_spi_bitbang_bytes(
738 bank
, spi_bytes
, sizeof(spi_bytes
), ATH79_XFER_FINAL
);
739 if (retval
!= ERROR_OK
)
742 *id
= (spi_bytes
[1] << 0)
743 | (spi_bytes
[2] << 8)
744 | (spi_bytes
[3] << 16);
746 if (*id
== 0xffffff) {
747 LOG_ERROR("No SPI flash found");
754 static int ath79_probe(struct flash_bank
*bank
)
756 struct target
*target
= bank
->target
;
757 struct ath79_flash_bank
*ath79_info
= bank
->driver_priv
;
758 struct flash_sector
*sectors
;
759 uint32_t id
= 0; /* silence uninitialized warning */
760 uint32_t pagesize
, sectorsize
;
761 const struct ath79_target
*target_device
;
764 if (ath79_info
->probed
) {
766 free(ath79_info
->spi
.page_buf
);
768 ath79_info
->probed
= false;
770 for (target_device
= target_devices
; target_device
->name
;
772 if (target_device
->tap_idcode
== target
->tap
->idcode
)
774 if (!target_device
->name
) {
775 LOG_ERROR("Device ID 0x%" PRIx32
" is not known",
776 target
->tap
->idcode
);
780 ath79_info
->io_base
= target_device
->io_base
;
782 LOG_DEBUG("Found device %s at address " TARGET_ADDR_FMT
,
783 target_device
->name
, bank
->base
);
785 retval
= read_flash_id(bank
, &id
);
786 if (retval
!= ERROR_OK
)
789 ath79_info
->dev
= NULL
;
790 for (const struct flash_device
*p
= flash_devices
; p
->name
; p
++)
791 if (p
->device_id
== id
) {
796 if (!ath79_info
->dev
) {
797 LOG_ERROR("Unknown flash device (ID 0x%08" PRIx32
")", id
);
801 LOG_INFO("Found flash device \'%s\' (ID 0x%08" PRIx32
")",
802 ath79_info
->dev
->name
, ath79_info
->dev
->device_id
);
804 /* Set correct size value */
805 bank
->size
= ath79_info
->dev
->size_in_bytes
;
806 if (bank
->size
<= (1UL << 16))
807 LOG_WARNING("device needs 2-byte addresses - not implemented");
808 if (bank
->size
> (1UL << 24))
809 LOG_WARNING("device needs paging or 4-byte addresses - not implemented");
811 /* if no sectors, treat whole bank as single sector */
812 sectorsize
= ath79_info
->dev
->sectorsize
?
813 ath79_info
->dev
->sectorsize
: ath79_info
->dev
->size_in_bytes
;
815 /* create and fill sectors array */
816 bank
->num_sectors
= ath79_info
->dev
->size_in_bytes
/ sectorsize
;
817 sectors
= calloc(1, sizeof(struct flash_sector
) * bank
->num_sectors
);
819 LOG_ERROR("not enough memory");
823 /* if no write pagesize, use reasonable default */
824 pagesize
= ath79_info
->dev
->pagesize
? ath79_info
->dev
->pagesize
: SPIFLASH_DEF_PAGESIZE
;
826 ath79_info
->spi
.page_buf
= malloc(pagesize
);
827 if (!ath79_info
->spi
.page_buf
) {
828 LOG_ERROR("not enough memory");
833 for (unsigned int sector
= 0; sector
< bank
->num_sectors
; sector
++) {
834 sectors
[sector
].offset
= sector
* sectorsize
;
835 sectors
[sector
].size
= sectorsize
;
836 sectors
[sector
].is_erased
= 0;
837 sectors
[sector
].is_protected
= 1;
840 bank
->sectors
= sectors
;
841 ath79_info
->probed
= true;
845 static int ath79_auto_probe(struct flash_bank
*bank
)
847 struct ath79_flash_bank
*ath79_info
= bank
->driver_priv
;
849 if (ath79_info
->probed
)
851 return ath79_probe(bank
);
854 static int ath79_flash_blank_check(struct flash_bank
*bank
)
856 /* Not implemented */
860 static int ath79_protect_check(struct flash_bank
*bank
)
862 /* Not implemented */
866 static int get_ath79_info(struct flash_bank
*bank
, struct command_invocation
*cmd
)
868 struct ath79_flash_bank
*ath79_info
= bank
->driver_priv
;
870 if (!ath79_info
->probed
) {
871 command_print_sameline(cmd
, "\nATH79 flash bank not probed yet\n");
875 command_print_sameline(cmd
, "\nATH79 flash information:\n"
876 " Device \'%s\' (ID 0x%08" PRIx32
")\n",
877 ath79_info
->dev
->name
, ath79_info
->dev
->device_id
);
882 const struct flash_driver ath79_flash
= {
884 .flash_bank_command
= ath79_flash_bank_command
,
885 .erase
= ath79_erase
,
886 .protect
= ath79_protect
,
887 .write
= ath79_write
,
889 .probe
= ath79_probe
,
890 .auto_probe
= ath79_auto_probe
,
891 .erase_check
= ath79_flash_blank_check
,
892 .protect_check
= ath79_protect_check
,
893 .info
= get_ath79_info
,
894 .free_driver_priv
= default_flash_free_driver_priv
,
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)