Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/dpll/zl3073x/flash.c
29267 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
3
#include <linux/array_size.h>
4
#include <linux/bitfield.h>
5
#include <linux/bits.h>
6
#include <linux/delay.h>
7
#include <linux/dev_printk.h>
8
#include <linux/errno.h>
9
#include <linux/jiffies.h>
10
#include <linux/minmax.h>
11
#include <linux/netlink.h>
12
#include <linux/sched/signal.h>
13
#include <linux/sizes.h>
14
#include <linux/sprintf.h>
15
#include <linux/string.h>
16
#include <linux/types.h>
17
#include <linux/unaligned.h>
18
#include <net/devlink.h>
19
20
#include "core.h"
21
#include "devlink.h"
22
#include "flash.h"
23
24
#define ZL_FLASH_ERR_PFX "FW update failed: "
25
#define ZL_FLASH_ERR_MSG(_extack, _msg, ...) \
26
NL_SET_ERR_MSG_FMT_MOD((_extack), ZL_FLASH_ERR_PFX _msg, \
27
## __VA_ARGS__)
28
29
/**
30
* zl3073x_flash_download - Download image block to device memory
31
* @zldev: zl3073x device structure
32
* @component: name of the component to be downloaded
33
* @addr: device memory target address
34
* @data: pointer to data to download
35
* @size: size of data to download
36
* @extack: netlink extack pointer to report errors
37
*
38
* Return: 0 on success, <0 on error
39
*/
40
static int
41
zl3073x_flash_download(struct zl3073x_dev *zldev, const char *component,
42
u32 addr, const void *data, size_t size,
43
struct netlink_ext_ack *extack)
44
{
45
#define ZL_CHECK_DELAY 5000 /* Check for interrupt each 5 seconds */
46
unsigned long check_time;
47
const void *ptr, *end;
48
int rc = 0;
49
50
dev_dbg(zldev->dev, "Downloading %zu bytes to device memory at 0x%0x\n",
51
size, addr);
52
53
check_time = jiffies + msecs_to_jiffies(ZL_CHECK_DELAY);
54
55
for (ptr = data, end = data + size; ptr < end; ptr += 4, addr += 4) {
56
/* Write current word to HW memory */
57
rc = zl3073x_write_hwreg(zldev, addr,
58
get_unaligned((u32 *)ptr));
59
if (rc) {
60
ZL_FLASH_ERR_MSG(extack,
61
"failed to write to memory at 0x%0x",
62
addr);
63
return rc;
64
}
65
66
if (time_is_before_jiffies(check_time)) {
67
if (signal_pending(current)) {
68
ZL_FLASH_ERR_MSG(extack,
69
"Flashing interrupted");
70
return -EINTR;
71
}
72
73
check_time = jiffies + msecs_to_jiffies(ZL_CHECK_DELAY);
74
}
75
76
/* Report status each 1 kB block */
77
if ((ptr - data) % 1024 == 0)
78
zl3073x_devlink_flash_notify(zldev, "Downloading image",
79
component, ptr - data,
80
size);
81
}
82
83
zl3073x_devlink_flash_notify(zldev, "Downloading image", component,
84
ptr - data, size);
85
86
dev_dbg(zldev->dev, "%zu bytes downloaded to device memory\n", size);
87
88
return rc;
89
}
90
91
/**
92
* zl3073x_flash_error_check - Check for flash utility errors
93
* @zldev: zl3073x device structure
94
* @extack: netlink extack pointer to report errors
95
*
96
* The function checks for errors detected by the flash utility and
97
* reports them if any were found.
98
*
99
* Return: 0 on success, -EIO when errors are detected
100
*/
101
static int
102
zl3073x_flash_error_check(struct zl3073x_dev *zldev,
103
struct netlink_ext_ack *extack)
104
{
105
u32 count, cause;
106
int rc;
107
108
rc = zl3073x_read_u32(zldev, ZL_REG_ERROR_COUNT, &count);
109
if (rc)
110
return rc;
111
else if (!count)
112
return 0; /* No error */
113
114
rc = zl3073x_read_u32(zldev, ZL_REG_ERROR_CAUSE, &cause);
115
if (rc)
116
return rc;
117
118
/* Report errors */
119
ZL_FLASH_ERR_MSG(extack,
120
"utility error occurred: count=%u cause=0x%x", count,
121
cause);
122
123
return -EIO;
124
}
125
126
/**
127
* zl3073x_flash_wait_ready - Check or wait for utility to be ready to flash
128
* @zldev: zl3073x device structure
129
* @timeout_ms: timeout for the waiting
130
*
131
* Return: 0 on success, <0 on error
132
*/
133
static int
134
zl3073x_flash_wait_ready(struct zl3073x_dev *zldev, unsigned int timeout_ms)
135
{
136
#define ZL_FLASH_POLL_DELAY_MS 100
137
unsigned long timeout;
138
int rc, i;
139
140
dev_dbg(zldev->dev, "Waiting for flashing to be ready\n");
141
142
timeout = jiffies + msecs_to_jiffies(timeout_ms);
143
144
for (i = 0; time_is_after_jiffies(timeout); i++) {
145
u8 value;
146
147
/* Check for interrupt each 1s */
148
if (i > 9) {
149
if (signal_pending(current))
150
return -EINTR;
151
i = 0;
152
}
153
154
rc = zl3073x_read_u8(zldev, ZL_REG_WRITE_FLASH, &value);
155
if (rc)
156
return rc;
157
158
value = FIELD_GET(ZL_WRITE_FLASH_OP, value);
159
160
if (value == ZL_WRITE_FLASH_OP_DONE)
161
return 0; /* Successfully done */
162
163
msleep(ZL_FLASH_POLL_DELAY_MS);
164
}
165
166
return -ETIMEDOUT;
167
}
168
169
/**
170
* zl3073x_flash_cmd_wait - Perform flash operation and wait for finish
171
* @zldev: zl3073x device structure
172
* @operation: operation to perform
173
* @extack: netlink extack pointer to report errors
174
*
175
* Return: 0 on success, <0 on error
176
*/
177
static int
178
zl3073x_flash_cmd_wait(struct zl3073x_dev *zldev, u32 operation,
179
struct netlink_ext_ack *extack)
180
{
181
#define ZL_FLASH_PHASE1_TIMEOUT_MS 60000 /* up to 1 minute */
182
#define ZL_FLASH_PHASE2_TIMEOUT_MS 120000 /* up to 2 minutes */
183
u8 value;
184
int rc;
185
186
dev_dbg(zldev->dev, "Sending flash command: 0x%x\n", operation);
187
188
rc = zl3073x_flash_wait_ready(zldev, ZL_FLASH_PHASE1_TIMEOUT_MS);
189
if (rc)
190
return rc;
191
192
/* Issue the requested operation */
193
rc = zl3073x_read_u8(zldev, ZL_REG_WRITE_FLASH, &value);
194
if (rc)
195
return rc;
196
197
value &= ~ZL_WRITE_FLASH_OP;
198
value |= FIELD_PREP(ZL_WRITE_FLASH_OP, operation);
199
200
rc = zl3073x_write_u8(zldev, ZL_REG_WRITE_FLASH, value);
201
if (rc)
202
return rc;
203
204
/* Wait for command completion */
205
rc = zl3073x_flash_wait_ready(zldev, ZL_FLASH_PHASE2_TIMEOUT_MS);
206
if (rc)
207
return rc;
208
209
return zl3073x_flash_error_check(zldev, extack);
210
}
211
212
/**
213
* zl3073x_flash_get_sector_size - Get flash sector size
214
* @zldev: zl3073x device structure
215
* @sector_size: sector size returned by the function
216
*
217
* The function reads the flash sector size detected by flash utility and
218
* stores it into @sector_size.
219
*
220
* Return: 0 on success, <0 on error
221
*/
222
static int
223
zl3073x_flash_get_sector_size(struct zl3073x_dev *zldev, size_t *sector_size)
224
{
225
u8 flash_info;
226
int rc;
227
228
rc = zl3073x_read_u8(zldev, ZL_REG_FLASH_INFO, &flash_info);
229
if (rc)
230
return rc;
231
232
switch (FIELD_GET(ZL_FLASH_INFO_SECTOR_SIZE, flash_info)) {
233
case ZL_FLASH_INFO_SECTOR_4K:
234
*sector_size = SZ_4K;
235
break;
236
case ZL_FLASH_INFO_SECTOR_64K:
237
*sector_size = SZ_64K;
238
break;
239
default:
240
rc = -EINVAL;
241
break;
242
}
243
244
return rc;
245
}
246
247
/**
248
* zl3073x_flash_block - Download and flash memory block
249
* @zldev: zl3073x device structure
250
* @component: component name
251
* @operation: flash operation to perform
252
* @page: destination flash page
253
* @addr: device memory address to load data
254
* @data: pointer to data to be flashed
255
* @size: size of data
256
* @extack: netlink extack pointer to report errors
257
*
258
* The function downloads the memory block given by the @data pointer and
259
* the size @size and flashes it into internal memory on flash page @page.
260
* The internal flash operation performed by the firmware is specified by
261
* the @operation parameter.
262
*
263
* Return: 0 on success, <0 on error
264
*/
265
static int
266
zl3073x_flash_block(struct zl3073x_dev *zldev, const char *component,
267
u32 operation, u32 page, u32 addr, const void *data,
268
size_t size, struct netlink_ext_ack *extack)
269
{
270
int rc;
271
272
/* Download block to device memory */
273
rc = zl3073x_flash_download(zldev, component, addr, data, size, extack);
274
if (rc)
275
return rc;
276
277
/* Set address to flash from */
278
rc = zl3073x_write_u32(zldev, ZL_REG_IMAGE_START_ADDR, addr);
279
if (rc)
280
return rc;
281
282
/* Set size of block to flash */
283
rc = zl3073x_write_u32(zldev, ZL_REG_IMAGE_SIZE, size);
284
if (rc)
285
return rc;
286
287
/* Set destination page to flash */
288
rc = zl3073x_write_u32(zldev, ZL_REG_FLASH_INDEX_WRITE, page);
289
if (rc)
290
return rc;
291
292
/* Set filling pattern */
293
rc = zl3073x_write_u32(zldev, ZL_REG_FILL_PATTERN, U32_MAX);
294
if (rc)
295
return rc;
296
297
zl3073x_devlink_flash_notify(zldev, "Flashing image", component, 0,
298
size);
299
300
dev_dbg(zldev->dev, "Flashing %zu bytes to page %u\n", size, page);
301
302
/* Execute sectors flash operation */
303
rc = zl3073x_flash_cmd_wait(zldev, operation, extack);
304
if (rc)
305
return rc;
306
307
zl3073x_devlink_flash_notify(zldev, "Flashing image", component, size,
308
size);
309
310
return 0;
311
}
312
313
/**
314
* zl3073x_flash_sectors - Flash sectors
315
* @zldev: zl3073x device structure
316
* @component: component name
317
* @page: destination flash page
318
* @addr: device memory address to load data
319
* @data: pointer to data to be flashed
320
* @size: size of data
321
* @extack: netlink extack pointer to report errors
322
*
323
* The function flashes given @data with size of @size to the internal flash
324
* memory block starting from page @page. The function uses sector flash
325
* method and has to take into account the flash sector size reported by
326
* flashing utility. Input data are spliced into blocks according this
327
* sector size and each block is flashed separately.
328
*
329
* Return: 0 on success, <0 on error
330
*/
331
int zl3073x_flash_sectors(struct zl3073x_dev *zldev, const char *component,
332
u32 page, u32 addr, const void *data, size_t size,
333
struct netlink_ext_ack *extack)
334
{
335
#define ZL_FLASH_MAX_BLOCK_SIZE 0x0001E000
336
#define ZL_FLASH_PAGE_SIZE 256
337
size_t max_block_size, block_size, sector_size;
338
const void *ptr, *end;
339
int rc;
340
341
/* Get flash sector size */
342
rc = zl3073x_flash_get_sector_size(zldev, &sector_size);
343
if (rc) {
344
ZL_FLASH_ERR_MSG(extack, "Failed to get flash sector size");
345
return rc;
346
}
347
348
/* Determine max block size depending on sector size */
349
max_block_size = ALIGN_DOWN(ZL_FLASH_MAX_BLOCK_SIZE, sector_size);
350
351
for (ptr = data, end = data + size; ptr < end; ptr += block_size) {
352
char comp_str[32];
353
354
block_size = min_t(size_t, max_block_size, end - ptr);
355
356
/* Add suffix '-partN' if the requested component size is
357
* greater than max_block_size.
358
*/
359
if (max_block_size < size)
360
snprintf(comp_str, sizeof(comp_str), "%s-part%zu",
361
component, (ptr - data) / max_block_size + 1);
362
else
363
strscpy(comp_str, component);
364
365
/* Flash the memory block */
366
rc = zl3073x_flash_block(zldev, comp_str,
367
ZL_WRITE_FLASH_OP_SECTORS, page, addr,
368
ptr, block_size, extack);
369
if (rc)
370
goto finish;
371
372
/* Move to next page */
373
page += block_size / ZL_FLASH_PAGE_SIZE;
374
}
375
376
finish:
377
zl3073x_devlink_flash_notify(zldev,
378
rc ? "Flashing failed" : "Flashing done",
379
component, 0, 0);
380
381
return rc;
382
}
383
384
/**
385
* zl3073x_flash_page - Flash page
386
* @zldev: zl3073x device structure
387
* @component: component name
388
* @page: destination flash page
389
* @addr: device memory address to load data
390
* @data: pointer to data to be flashed
391
* @size: size of data
392
* @extack: netlink extack pointer to report errors
393
*
394
* The function flashes given @data with size of @size to the internal flash
395
* memory block starting with page @page.
396
*
397
* Return: 0 on success, <0 on error
398
*/
399
int zl3073x_flash_page(struct zl3073x_dev *zldev, const char *component,
400
u32 page, u32 addr, const void *data, size_t size,
401
struct netlink_ext_ack *extack)
402
{
403
int rc;
404
405
/* Flash the memory block */
406
rc = zl3073x_flash_block(zldev, component, ZL_WRITE_FLASH_OP_PAGE, page,
407
addr, data, size, extack);
408
409
zl3073x_devlink_flash_notify(zldev,
410
rc ? "Flashing failed" : "Flashing done",
411
component, 0, 0);
412
413
return rc;
414
}
415
416
/**
417
* zl3073x_flash_page_copy - Copy flash page
418
* @zldev: zl3073x device structure
419
* @component: component name
420
* @src_page: source page to copy
421
* @dst_page: destination page
422
* @extack: netlink extack pointer to report errors
423
*
424
* The function copies one flash page specified by @src_page into the flash
425
* page specified by @dst_page.
426
*
427
* Return: 0 on success, <0 on error
428
*/
429
int zl3073x_flash_page_copy(struct zl3073x_dev *zldev, const char *component,
430
u32 src_page, u32 dst_page,
431
struct netlink_ext_ack *extack)
432
{
433
int rc;
434
435
/* Set source page to be copied */
436
rc = zl3073x_write_u32(zldev, ZL_REG_FLASH_INDEX_READ, src_page);
437
if (rc)
438
return rc;
439
440
/* Set destination page for the copy */
441
rc = zl3073x_write_u32(zldev, ZL_REG_FLASH_INDEX_WRITE, dst_page);
442
if (rc)
443
return rc;
444
445
/* Perform copy operation */
446
rc = zl3073x_flash_cmd_wait(zldev, ZL_WRITE_FLASH_OP_COPY_PAGE, extack);
447
if (rc)
448
ZL_FLASH_ERR_MSG(extack, "Failed to copy page %u to page %u",
449
src_page, dst_page);
450
451
return rc;
452
}
453
454
/**
455
* zl3073x_flash_mode_verify - Check flash utility
456
* @zldev: zl3073x device structure
457
*
458
* Return: 0 if the flash utility is ready, <0 on error
459
*/
460
static int
461
zl3073x_flash_mode_verify(struct zl3073x_dev *zldev)
462
{
463
u8 family, release;
464
u32 hash;
465
int rc;
466
467
rc = zl3073x_read_u32(zldev, ZL_REG_FLASH_HASH, &hash);
468
if (rc)
469
return rc;
470
471
rc = zl3073x_read_u8(zldev, ZL_REG_FLASH_FAMILY, &family);
472
if (rc)
473
return rc;
474
475
rc = zl3073x_read_u8(zldev, ZL_REG_FLASH_RELEASE, &release);
476
if (rc)
477
return rc;
478
479
dev_dbg(zldev->dev,
480
"Flash utility check: hash 0x%08x, fam 0x%02x, rel 0x%02x\n",
481
hash, family, release);
482
483
/* Return success for correct family */
484
return (family == 0x21) ? 0 : -ENODEV;
485
}
486
487
static int
488
zl3073x_flash_host_ctrl_enable(struct zl3073x_dev *zldev)
489
{
490
u8 host_ctrl;
491
int rc;
492
493
/* Enable host control */
494
rc = zl3073x_read_u8(zldev, ZL_REG_HOST_CONTROL, &host_ctrl);
495
if (rc)
496
return rc;
497
498
host_ctrl |= ZL_HOST_CONTROL_ENABLE;
499
500
return zl3073x_write_u8(zldev, ZL_REG_HOST_CONTROL, host_ctrl);
501
}
502
503
/**
504
* zl3073x_flash_mode_enter - Switch the device to flash mode
505
* @zldev: zl3073x device structure
506
* @util_ptr: buffer with flash utility
507
* @util_size: size of buffer with flash utility
508
* @extack: netlink extack pointer to report errors
509
*
510
* The function prepares and switches the device into flash mode.
511
*
512
* The procedure:
513
* 1) Stop device CPU by specific HW register sequence
514
* 2) Download flash utility to device memory
515
* 3) Resume device CPU by specific HW register sequence
516
* 4) Check communication with flash utility
517
* 5) Enable host control necessary to access flash API
518
* 6) Check for potential error detected by the utility
519
*
520
* The API provided by normal firmware is not available in flash mode
521
* so the caller has to ensure that this API is not used in this mode.
522
*
523
* After performing flash operation the caller should call
524
* @zl3073x_flash_mode_leave to return back to normal operation.
525
*
526
* Return: 0 on success, <0 on error.
527
*/
528
int zl3073x_flash_mode_enter(struct zl3073x_dev *zldev, const void *util_ptr,
529
size_t util_size, struct netlink_ext_ack *extack)
530
{
531
/* Sequence to be written prior utility download */
532
static const struct zl3073x_hwreg_seq_item pre_seq[] = {
533
HWREG_SEQ_ITEM(0x80000400, 1, BIT(0), 0),
534
HWREG_SEQ_ITEM(0x80206340, 1, BIT(4), 0),
535
HWREG_SEQ_ITEM(0x10000000, 1, BIT(2), 0),
536
HWREG_SEQ_ITEM(0x10000024, 0x00000001, U32_MAX, 0),
537
HWREG_SEQ_ITEM(0x10000020, 0x00000001, U32_MAX, 0),
538
HWREG_SEQ_ITEM(0x10000000, 1, BIT(10), 1000),
539
};
540
/* Sequence to be written after utility download */
541
static const struct zl3073x_hwreg_seq_item post_seq[] = {
542
HWREG_SEQ_ITEM(0x10400004, 0x000000C0, U32_MAX, 0),
543
HWREG_SEQ_ITEM(0x10400008, 0x00000000, U32_MAX, 0),
544
HWREG_SEQ_ITEM(0x10400010, 0x20000000, U32_MAX, 0),
545
HWREG_SEQ_ITEM(0x10400014, 0x20000004, U32_MAX, 0),
546
HWREG_SEQ_ITEM(0x10000000, 1, GENMASK(10, 9), 0),
547
HWREG_SEQ_ITEM(0x10000020, 0x00000000, U32_MAX, 0),
548
HWREG_SEQ_ITEM(0x10000000, 0, BIT(0), 1000),
549
};
550
int rc;
551
552
zl3073x_devlink_flash_notify(zldev, "Prepare flash mode", "utility",
553
0, 0);
554
555
/* Execure pre-load sequence */
556
rc = zl3073x_write_hwreg_seq(zldev, pre_seq, ARRAY_SIZE(pre_seq));
557
if (rc) {
558
ZL_FLASH_ERR_MSG(extack, "cannot execute pre-load sequence");
559
goto error;
560
}
561
562
/* Download utility image to device memory */
563
rc = zl3073x_flash_download(zldev, "utility", 0x20000000, util_ptr,
564
util_size, extack);
565
if (rc) {
566
ZL_FLASH_ERR_MSG(extack, "cannot download flash utility");
567
goto error;
568
}
569
570
/* Execute post-load sequence */
571
rc = zl3073x_write_hwreg_seq(zldev, post_seq, ARRAY_SIZE(post_seq));
572
if (rc) {
573
ZL_FLASH_ERR_MSG(extack, "cannot execute post-load sequence");
574
goto error;
575
}
576
577
/* Check that utility identifies itself correctly */
578
rc = zl3073x_flash_mode_verify(zldev);
579
if (rc) {
580
ZL_FLASH_ERR_MSG(extack, "flash utility check failed");
581
goto error;
582
}
583
584
/* Enable host control */
585
rc = zl3073x_flash_host_ctrl_enable(zldev);
586
if (rc) {
587
ZL_FLASH_ERR_MSG(extack, "cannot enable host control");
588
goto error;
589
}
590
591
zl3073x_devlink_flash_notify(zldev, "Flash mode enabled", "utility",
592
0, 0);
593
594
return 0;
595
596
error:
597
zl3073x_flash_mode_leave(zldev, extack);
598
599
return rc;
600
}
601
602
/**
603
* zl3073x_flash_mode_leave - Leave flash mode
604
* @zldev: zl3073x device structure
605
* @extack: netlink extack pointer to report errors
606
*
607
* The function instructs the device to leave the flash mode and
608
* to return back to normal operation.
609
*
610
* The procedure:
611
* 1) Set reset flag
612
* 2) Reset the device CPU by specific HW register sequence
613
* 3) Wait for the device to be ready
614
* 4) Check the reset flag was cleared
615
*
616
* Return: 0 on success, <0 on error
617
*/
618
int zl3073x_flash_mode_leave(struct zl3073x_dev *zldev,
619
struct netlink_ext_ack *extack)
620
{
621
/* Sequence to be written after flash */
622
static const struct zl3073x_hwreg_seq_item fw_reset_seq[] = {
623
HWREG_SEQ_ITEM(0x80000404, 1, BIT(0), 0),
624
HWREG_SEQ_ITEM(0x80000410, 1, BIT(0), 0),
625
};
626
u8 reset_status;
627
int rc;
628
629
zl3073x_devlink_flash_notify(zldev, "Leaving flash mode", "utility",
630
0, 0);
631
632
/* Read reset status register */
633
rc = zl3073x_read_u8(zldev, ZL_REG_RESET_STATUS, &reset_status);
634
if (rc)
635
return rc;
636
637
/* Set reset bit */
638
reset_status |= ZL_REG_RESET_STATUS_RESET;
639
640
/* Update reset status register */
641
rc = zl3073x_write_u8(zldev, ZL_REG_RESET_STATUS, reset_status);
642
if (rc)
643
return rc;
644
645
/* We do not check the return value here as the sequence resets
646
* the device CPU and the last write always return an error.
647
*/
648
zl3073x_write_hwreg_seq(zldev, fw_reset_seq, ARRAY_SIZE(fw_reset_seq));
649
650
/* Wait for the device to be ready */
651
msleep(500);
652
653
/* Read again the reset status register */
654
rc = zl3073x_read_u8(zldev, ZL_REG_RESET_STATUS, &reset_status);
655
if (rc)
656
return rc;
657
658
/* Check the reset bit was cleared */
659
if (reset_status & ZL_REG_RESET_STATUS_RESET) {
660
dev_err(zldev->dev,
661
"Reset not confirmed after switch to normal mode\n");
662
return -EINVAL;
663
}
664
665
return 0;
666
}
667
668