1 /* all about xtx factory */
2
3 #include <string.h>
4 #include <stdlib.h>
5 #include <time.h>
6 #include <pthread.h>
7 #include <errno.h>
8 #include <unistd.h>
9 #include <hal_timer.h>
10
11 #include "inter.h"
12
13 #define NOR_XTX_QE_BIT BIT(1)
14 #define NOR_XTX_WPS_BIT BIT(4)
15 #define NOR_XTX_CMD_READ_SR1 (0x35)
16 #define NOR_XTX_CMD_BLK_LOCK_STATUS (0x3D)
17 #define NOR_XTX_CMD_BLK_LOCK (0x36)
18 #define NOR_XTX_CMD_BLK_UNLOCK (0x39)
19
20 static struct nor_info idt_xtx[] =
21 {
22 {
23 .model = "xt25f128",
24 .id = {0x0b, 0x40, 0x18},
25 .total_size = SZ_16M,
26 .flag = SUPPORT_GENERAL | SUPPORT_INDIVIDUAL_PROTECT,
27 },
28 };
29
nor_xtx_read_status1(unsigned char * sr1)30 static int nor_xtx_read_status1(unsigned char *sr1)
31 {
32 int ret;
33 char cmd[1] = {NOR_XTX_CMD_READ_SR1};
34 char reg[2] = {0};
35
36 ret = nor_transfer(1, cmd, 1, reg, 2);
37 if (ret) {
38 SPINOR_ERR("read xtx status1 register fail\n");
39 return ret;
40 }
41
42 *sr1 = reg[1];
43 return 0;
44 }
45
nor_xtx_quad_mode(struct nor_flash * unused)46 static int nor_xtx_quad_mode(struct nor_flash *unused)
47 {
48 int ret;
49 unsigned char sr[2];
50
51 ret = nor_xtx_read_status1(&sr[1]);
52 if (ret)
53 return ret;
54
55 if (sr[1] & NOR_XTX_QE_BIT)
56 return 0;
57
58 sr[1] |= NOR_XTX_QE_BIT;
59
60 ret = nor_read_status(&sr[0]);
61 if (ret)
62 return ret;
63
64 ret = nor_write_status(sr, 2);
65 if (ret)
66 return ret;
67
68 ret = nor_xtx_read_status1(&sr[1]);
69 if (ret)
70 return ret;
71 if (!(sr[1] & NOR_XTX_QE_BIT)) {
72 SPINOR_ERR("set xtx QE failed (0x%x)\n", sr[1]);
73 return -EINVAL;
74 }
75 return 0;
76 }
77
nor_xtx_set_wps(int wps)78 static int nor_xtx_set_wps(int wps)
79 {
80 int ret;
81 unsigned char sr[2];
82 unsigned char sr1;
83
84 ret = nor_xtx_read_status1(&sr1);
85 if (ret)
86 return ret;
87
88 if (wps)
89 sr[1] = sr1 | NOR_XTX_WPS_BIT;
90 else
91 sr[1] = sr1 & ~NOR_XTX_WPS_BIT;
92
93 if (sr1 == sr[1])
94 return 0;
95
96 ret = nor_read_status(&sr[0]);
97 if (ret)
98 return ret;
99
100 ret = nor_write_status(sr, 2);
101 if (ret)
102 return ret;
103
104 ret = nor_xtx_read_status1(&sr1);
105 if (ret)
106 return ret;
107
108 if ((sr1 & NOR_XTX_WPS_BIT) != (sr[1] & NOR_XTX_WPS_BIT)) {
109 SPINOR_ERR("set xtx wps %d failed (0x%x)\n", wps, sr1);
110 return -EINVAL;
111 }
112 return 0;
113 }
114
nor_xtx_init_lock(struct nor_flash * nor)115 static int nor_xtx_init_lock(struct nor_flash *nor)
116 {
117 return nor_xtx_set_wps(true);
118 }
119
nor_xtx_deinit_lock(struct nor_flash * nor)120 static void nor_xtx_deinit_lock(struct nor_flash *nor)
121 {
122 nor_xtx_set_wps(false);
123 }
124
nor_xtx_blk_islock(unsigned int addr)125 static bool nor_xtx_blk_islock(unsigned int addr)
126 {
127 int ret;
128 unsigned char tbuf[4], st;
129
130 tbuf[0] = NOR_XTX_CMD_BLK_LOCK_STATUS;
131 tbuf[1] = addr >> 16;
132 tbuf[2] = addr >> 8;
133 tbuf[3] = addr & 0xFF;
134 ret = nor_transfer(4, tbuf, 4, &st, 1);
135 if (ret)
136 return ret;
137 return st & 0x1 ? true : false;
138 }
139
nor_xtx_blk_unlock(unsigned int addr)140 static int nor_xtx_blk_unlock(unsigned int addr)
141 {
142 int ret;
143 unsigned char tbuf[4];
144
145 ret = nor_write_enable();
146 if (ret)
147 return ret;
148
149 tbuf[0] = NOR_XTX_CMD_BLK_UNLOCK;
150 tbuf[1] = addr >> 16;
151 tbuf[2] = addr >> 8;
152 tbuf[3] = addr & 0xFF;
153 ret = nor_transfer(4, tbuf, 4, NULL, 0);
154 if (ret)
155 return ret;
156 if (nor_xtx_blk_islock(addr) == true)
157 return -EBUSY;
158 return 0;
159 }
160
nor_xtx_blk_lock(unsigned int addr)161 static int nor_xtx_blk_lock(unsigned int addr)
162 {
163 int ret;
164 unsigned char tbuf[4];
165
166 ret = nor_write_enable();
167 if (ret)
168 return ret;
169
170 tbuf[0] = NOR_XTX_CMD_BLK_LOCK;
171 tbuf[1] = addr >> 16;
172 tbuf[2] = addr >> 8;
173 tbuf[3] = addr & 0xFF;
174 ret = nor_transfer(4, tbuf, 4, NULL, 0);
175 if (ret)
176 return ret;
177 if (nor_xtx_blk_islock(addr) == true)
178 return 0;
179 return -EBUSY;
180 }
181
nor_xtx_lock(struct nor_flash * nor,unsigned int addr,unsigned int len)182 static int nor_xtx_lock(struct nor_flash *nor, unsigned int addr,
183 unsigned int len)
184 {
185 return nor_xtx_blk_lock(addr);
186 }
187
nor_xtx_unlock(struct nor_flash * nor,unsigned int addr,unsigned int len)188 static int nor_xtx_unlock(struct nor_flash *nor, unsigned int addr,
189 unsigned int len)
190 {
191 return nor_xtx_blk_unlock(addr);
192 }
193
nor_xtx_islock(struct nor_flash * nor,unsigned int addr,unsigned int len)194 static bool nor_xtx_islock(struct nor_flash *nor, unsigned int addr,
195 unsigned int len)
196 {
197 return nor_xtx_blk_islock(addr);
198 }
199
200 static struct nor_factory nor_xtx = {
201 .factory = FACTORY_XTX,
202 .idt = idt_xtx,
203 .idt_cnt = sizeof(idt_xtx),
204
205 .init = NULL,
206 .deinit = NULL,
207 .init_lock = nor_xtx_init_lock,
208 .deinit_lock = nor_xtx_deinit_lock,
209 .lock = nor_xtx_lock,
210 .unlock = nor_xtx_unlock,
211 .islock = nor_xtx_islock,
212 .set_quad_mode = nor_xtx_quad_mode,
213 .set_4bytes_addr = NULL,
214 };
215
nor_register_factory_xtx(void)216 int nor_register_factory_xtx(void)
217 {
218 return nor_register_factory(&nor_xtx);
219 }
220