1/*
2 * Spansion FM4 flash write algorithm
3 *
4 * Copyright (c) 2015 Andreas Färber
5 *
6 * Based on S6E2CC_MN709-00007 for S6E2CC/C5/C4/C3/C2/C1 series
7 */
8
9#include "fm4.h"
10
11#define RESULT_OKAY	0
12#define RESULT_NONE	1
13#define RESULT_TIMEOUT	2
14
15	.macro busy_wait, res, addr, data, tmp1, tmp2, tmp3
16
17	ldrb	\tmp1, [\addr] /* ignore */
18	and	\tmp2, \data, #FLASH_DPOL
191001:
20	ldrb	\tmp1, [\addr]
21	and	\tmp3, \tmp1, #FLASH_DPOL
22	cmp	\tmp3, \tmp2
23	beq	1010f
24
25	and	\tmp3, \tmp1, #FLASH_TLOV
26	cmp	\tmp3, #0
27	beq	1001b
28
29	ldrb	\tmp1, [\addr]
30	and	\tmp3, \tmp1, #FLASH_DPOL
31	cmp	\tmp3, \tmp2
32	beq	1010f
33
34	mov	\res, #RESULT_TIMEOUT
35	bkpt	#0
361010:
37	.endm
38
39
40	.macro write_one, res, cmdseqaddr1, cmdseqaddr2, pa, pd, tmp1, tmp2, tmp3
41
42	mov	\tmp1, #0xAA
43	strh	\tmp1, [\cmdseqaddr1]
44	mov	\tmp1, #0x55
45	strh	\tmp1, [\cmdseqaddr2]
46	mov	\tmp1, #0xA0
47	strh	\tmp1, [\cmdseqaddr1]
48	strh	\pd, [\pa]
49
50	busy_wait \res, \pa, \pd, \tmp1, \tmp2, \tmp3
51
52	.endm
53
54
55	.macro write, cmdseqaddr1, cmdseqaddr2, dest, src, cnt, res, tmp1, tmp2, tmp3, tmp4
56
57	mov	\res, #RESULT_NONE
582001:
59	cbz	\cnt, 2010f
60
61	ldrh	\tmp1, [\src]
62	write_one \res, \cmdseqaddr1, \cmdseqaddr2, \dest, \tmp1, \tmp2, \tmp3, \tmp4
63
64	sub	\cnt, \cnt, #1
65	add	\dest, \dest, #2
66	add	\src, \src, #2
67	b	2001b
682010:
69	mov	\res, #RESULT_OKAY
70	.endm
71
72
73	/* r0 = 0xAA8
74	 * r1 = 0x554
75	 * r2 = dest
76	 * r3 = src
77	 * r4 = cnt
78	 * r5 = result
79	 */
80write:
81	write r0, r1, r2, r3, r4, r5, r6, r7, r8, r9
82
83	bkpt	#0
84
85data:
86