1 /* 2 * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved. 3 * 4 * SPDX-License-Identifier: GPL-2.0+ 5 */ 6 7 #include <common.h> 8 #include <malloc.h> 9 #include <errno.h> 10 #include <div64.h> 11 #include <dfu.h> 12 #include <spi.h> 13 #include <spi_flash.h> 14 15 static long dfu_get_medium_size_sf(struct dfu_entity *dfu) 16 { 17 return dfu->data.sf.size; 18 } 19 20 static int dfu_read_medium_sf(struct dfu_entity *dfu, u64 offset, void *buf, 21 long *len) 22 { 23 return spi_flash_read(dfu->data.sf.dev, offset, *len, buf); 24 } 25 26 static int dfu_write_medium_sf(struct dfu_entity *dfu, 27 u64 offset, void *buf, long *len) 28 { 29 int ret; 30 31 ret = spi_flash_erase(dfu->data.sf.dev, offset, *len); 32 if (ret) 33 return ret; 34 35 ret = spi_flash_write(dfu->data.sf.dev, offset, *len, buf); 36 if (ret) 37 return ret; 38 39 return 0; 40 } 41 42 static int dfu_flush_medium_sf(struct dfu_entity *dfu) 43 { 44 return 0; 45 } 46 47 static unsigned int dfu_polltimeout_sf(struct dfu_entity *dfu) 48 { 49 return DFU_DEFAULT_POLL_TIMEOUT; 50 } 51 52 static void dfu_free_entity_sf(struct dfu_entity *dfu) 53 { 54 spi_flash_free(dfu->data.sf.dev); 55 } 56 57 static struct spi_flash *parse_dev(char *devstr) 58 { 59 unsigned int bus; 60 unsigned int cs; 61 unsigned int speed = CONFIG_SF_DEFAULT_SPEED; 62 unsigned int mode = CONFIG_SF_DEFAULT_MODE; 63 char *s, *endp; 64 struct spi_flash *dev; 65 66 s = strsep(&devstr, ":"); 67 if (!s || !*s || (bus = simple_strtoul(s, &endp, 0), *endp)) { 68 printf("Invalid SPI bus %s\n", s); 69 return NULL; 70 } 71 72 s = strsep(&devstr, ":"); 73 if (!s || !*s || (cs = simple_strtoul(s, &endp, 0), *endp)) { 74 printf("Invalid SPI chip-select %s\n", s); 75 return NULL; 76 } 77 78 s = strsep(&devstr, ":"); 79 if (s && *s) { 80 speed = simple_strtoul(s, &endp, 0); 81 if (*endp || !speed) { 82 printf("Invalid SPI speed %s\n", s); 83 return NULL; 84 } 85 } 86 87 s = strsep(&devstr, ":"); 88 if (s && *s) { 89 mode = simple_strtoul(s, &endp, 0); 90 if (*endp || mode > 3) { 91 printf("Invalid SPI mode %s\n", s); 92 return NULL; 93 } 94 } 95 96 dev = spi_flash_probe(bus, cs, speed, mode); 97 if (!dev) { 98 printf("Failed to create SPI flash at %d:%d:%d:%d\n", 99 bus, cs, speed, mode); 100 return NULL; 101 } 102 103 return dev; 104 } 105 106 int dfu_fill_entity_sf(struct dfu_entity *dfu, char *devstr, char *s) 107 { 108 char *st; 109 110 dfu->data.sf.dev = parse_dev(devstr); 111 if (!dfu->data.sf.dev) 112 return -ENODEV; 113 114 dfu->dev_type = DFU_DEV_SF; 115 dfu->max_buf_size = dfu->data.sf.dev->sector_size; 116 117 st = strsep(&s, " "); 118 if (!strcmp(st, "raw")) { 119 dfu->layout = DFU_RAW_ADDR; 120 dfu->data.sf.start = simple_strtoul(s, &s, 16); 121 s++; 122 dfu->data.sf.size = simple_strtoul(s, &s, 16); 123 } else { 124 printf("%s: Memory layout (%s) not supported!\n", __func__, st); 125 spi_flash_free(dfu->data.sf.dev); 126 return -1; 127 } 128 129 dfu->get_medium_size = dfu_get_medium_size_sf; 130 dfu->read_medium = dfu_read_medium_sf; 131 dfu->write_medium = dfu_write_medium_sf; 132 dfu->flush_medium = dfu_flush_medium_sf; 133 dfu->poll_timeout = dfu_polltimeout_sf; 134 dfu->free_entity = dfu_free_entity_sf; 135 136 /* initial state */ 137 dfu->inited = 0; 138 139 return 0; 140 } 141