Lines Matching +full:address +full:- +full:address +full:- +full:data
1 // SPDX-License-Identifier: GPL-2.0-only
3 * datasheet: https://www.nxp.com/docs/en/data-sheet/K20P144M120SF3.pdf
5 * Copyright (C) 2018-2021 Collabora
6 * Copyright (C) 2018-2021 GE Healthcare
36 #define EZPORT_CMD_FAST_READ 0x0b /* flash read data at high speed */
42 #define EZPORT_SECTOR_MASK (EZPORT_SECTOR_SIZE - 1)
68 spi_bus_lock(spi->controller); in ezport_start_programming()
88 spi_bus_unlock(spi->controller); in ezport_start_programming()
95 spi_bus_lock(spi->controller); in ezport_stop_programming()
97 spi_bus_unlock(spi->controller); in ezport_stop_programming()
108 dev_err(&spi->dev, "Invalid EzPort status, EzPort is not functional!\n"); in ezport_get_status_register()
109 return -EINVAL; in ezport_get_status_register()
166 dev_err(&spi->dev, "EzPort write enable timed out\n"); in ezport_write_enable()
167 return -ETIMEDOUT; in ezport_write_enable()
177 dev_dbg(&spi->dev, "EzPort bulk erase...\n"); in ezport_bulk_erase()
194 static int ezport_section_erase(struct spi_device *spi, u32 address) in ezport_section_erase() argument
196 u8 query[] = {EZPORT_CMD_SE, (address >> 16) & 0xff, (address >> 8) & 0xff, address & 0xff}; in ezport_section_erase()
199 dev_dbg(&spi->dev, "Ezport section erase @ 0x%06x...\n", address); in ezport_section_erase()
201 if (address & EZPORT_SECTOR_MASK) in ezport_section_erase()
202 return -EINVAL; in ezport_section_erase()
215 static int ezport_flash_transfer(struct spi_device *spi, u32 address, in ezport_flash_transfer() argument
222 dev_dbg(&spi->dev, "EzPort write %zu bytes @ 0x%06x...\n", payload_size, address); in ezport_flash_transfer()
230 return -ENOMEM; in ezport_flash_transfer()
233 command[1] = address >> 16; in ezport_flash_transfer()
234 command[2] = address >> 8; in ezport_flash_transfer()
235 command[3] = address >> 0; in ezport_flash_transfer()
251 static int ezport_flash_compare(struct spi_device *spi, u32 address, in ezport_flash_compare() argument
260 return -ENOMEM; in ezport_flash_compare()
263 buffer[1] = address >> 16; in ezport_flash_compare()
264 buffer[2] = address >> 8; in ezport_flash_compare()
265 buffer[3] = address >> 0; in ezport_flash_compare()
279 /* FAST_READ receives one dummy byte before the real data */ in ezport_flash_compare()
282 ret = -EBADMSG; in ezport_flash_compare()
283 dev_dbg(&spi->dev, "Verification failure @ %06x", address); in ezport_flash_compare()
294 const u8 *data, size_t size) in ezport_firmware_compare_data() argument
297 size_t address = 0; in ezport_firmware_compare_data() local
300 dev_dbg(&spi->dev, "EzPort compare data with %zu bytes...\n", size); in ezport_firmware_compare_data()
307 dev_info(&spi->dev, "Device is in secure mode (status=0x%02x)!\n", ret); in ezport_firmware_compare_data()
308 dev_info(&spi->dev, "FW verification is not possible\n"); in ezport_firmware_compare_data()
309 return -EACCES; in ezport_firmware_compare_data()
312 while (size - address > 0) { in ezport_firmware_compare_data()
313 transfer_size = min((size_t) EZPORT_TRANSFER_SIZE, size - address); in ezport_firmware_compare_data()
315 ret = ezport_flash_compare(spi, address, data+address, transfer_size); in ezport_firmware_compare_data()
319 address += transfer_size; in ezport_firmware_compare_data()
326 const u8 *data, size_t size) in ezport_firmware_flash_data() argument
329 size_t address = 0; in ezport_firmware_flash_data() local
332 dev_dbg(&spi->dev, "EzPort flash data with %zu bytes...\n", size); in ezport_firmware_flash_data()
343 return -EINVAL; in ezport_firmware_flash_data()
346 while (size - address > 0) { in ezport_firmware_flash_data()
347 if (!(address & EZPORT_SECTOR_MASK)) { in ezport_firmware_flash_data()
348 ret = ezport_section_erase(spi, address); in ezport_firmware_flash_data()
352 return -EIO; in ezport_firmware_flash_data()
355 transfer_size = min((size_t) EZPORT_TRANSFER_SIZE, size - address); in ezport_firmware_flash_data()
357 ret = ezport_flash_transfer(spi, address, in ezport_firmware_flash_data()
358 data+address, transfer_size); in ezport_firmware_flash_data()
362 return -ETIMEDOUT; in ezport_firmware_flash_data()
364 return -EIO; in ezport_firmware_flash_data()
366 address += transfer_size; in ezport_firmware_flash_data()
369 dev_dbg(&spi->dev, "EzPort verify flashed data...\n"); in ezport_firmware_flash_data()
370 ret = ezport_firmware_compare_data(spi, data, size); in ezport_firmware_flash_data()
373 if (ret == -EACCES) in ezport_firmware_flash_data()
377 dev_err(&spi->dev, "Failed to verify flashed data: %d\n", ret); in ezport_firmware_flash_data()
381 dev_warn(&spi->dev, "EzPort reset failed!\n"); in ezport_firmware_flash_data()
391 ret = request_firmware(&fw, fwname, &spi->dev); in ezport_firmware_load()
393 dev_err(&spi->dev, "Could not get firmware: %d\n", ret); in ezport_firmware_load()
397 ret = ezport_firmware_flash_data(spi, fw->data, fw->size); in ezport_firmware_load()
405 * ezport_flash - flash device firmware
427 dev_err(&spi->dev, "Failed to flash firmware: %d\n", ret); in ezport_flash()
429 dev_dbg(&spi->dev, "Finished FW flashing!\n"); in ezport_flash()
443 return -EINVAL; in update_firmware_store()
445 mutex_lock(&achc->device_lock); in update_firmware_store()
446 ret = ezport_flash(achc->ezport, achc->reset, "achc.bin"); in update_firmware_store()
447 mutex_unlock(&achc->device_lock); in update_firmware_store()
461 mutex_lock(&achc->device_lock); in reset_show()
462 ret = gpiod_get_value(achc->reset); in reset_show()
463 mutex_unlock(&achc->device_lock); in reset_show()
480 return -EINVAL; in reset_store()
482 mutex_lock(&achc->device_lock); in reset_store()
483 gpiod_set_value(achc->reset, value); in reset_store()
484 mutex_unlock(&achc->device_lock); in reset_store()
497 static void unregister_ezport(void *data) in unregister_ezport() argument
499 struct spi_device *ezport = data; in unregister_ezport()
509 spi->max_speed_hz = ACHC_MAX_FREQ_HZ; in gehc_achc_probe()
510 spi->bits_per_word = 8; in gehc_achc_probe()
511 spi->mode = SPI_MODE_0; in gehc_achc_probe()
513 achc = devm_kzalloc(&spi->dev, sizeof(*achc), GFP_KERNEL); in gehc_achc_probe()
515 return -ENOMEM; in gehc_achc_probe()
517 achc->main = spi; in gehc_achc_probe()
519 mutex_init(&achc->device_lock); in gehc_achc_probe()
521 ret = of_property_read_u32_index(spi->dev.of_node, "reg", 1, &ezport_reg); in gehc_achc_probe()
523 return dev_err_probe(&spi->dev, ret, "missing second reg entry!\n"); in gehc_achc_probe()
525 achc->ezport = spi_new_ancillary_device(spi, ezport_reg); in gehc_achc_probe()
526 if (IS_ERR(achc->ezport)) in gehc_achc_probe()
527 return PTR_ERR(achc->ezport); in gehc_achc_probe()
529 ret = devm_add_action_or_reset(&spi->dev, unregister_ezport, achc->ezport); in gehc_achc_probe()
533 achc->reset = devm_gpiod_get(&spi->dev, "reset", GPIOD_OUT_LOW); in gehc_achc_probe()
534 if (IS_ERR(achc->reset)) in gehc_achc_probe()
535 return dev_err_probe(&spi->dev, PTR_ERR(achc->reset), "Could not get reset gpio\n"); in gehc_achc_probe()
555 .name = "gehc-achc",