1 /*
2 * Copyright (c) 2023 HPMicro
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 */
7
8 #include "hpm_nor_flash.h"
9 #include "hpm_l1c_drv.h"
10 #include "board.h"
11
nor_flash_init(nor_flash_config_t * cfg)12 hpm_stat_t nor_flash_init(nor_flash_config_t *cfg)
13 {
14 xpi_nor_config_option_t option;
15
16 option.header.U = cfg->opt_header;
17 option.option0.U = cfg->opt0;
18 option.option1.U = cfg->opt1;
19 hpm_stat_t status = rom_xpi_nor_auto_config(cfg->xpi_base, &cfg->nor_config, &option);
20 if (status != status_success) {
21 return status;
22 }
23
24 rom_xpi_nor_get_property(cfg->xpi_base, &cfg->nor_config, xpi_nor_property_sector_size, &cfg->sector_size);
25
26 return status_success;
27 }
28
nor_flash_read(nor_flash_config_t * cfg,uint8_t * buf,uint32_t addr,uint32_t size)29 hpm_stat_t nor_flash_read(nor_flash_config_t *cfg, uint8_t *buf, uint32_t addr, uint32_t size)
30 {
31 uint32_t aligned_start = HPM_L1C_CACHELINE_ALIGN_DOWN(addr);
32 uint32_t aligned_end = HPM_L1C_CACHELINE_ALIGN_UP(addr + size);
33 uint32_t aligned_size = aligned_end - aligned_start;
34
35 (void)cfg;
36 l1c_dc_invalidate(aligned_start, aligned_size);
37
38 memcpy(buf, (void *)addr, size);
39 return status_success;
40 }
41
nor_flash_write(nor_flash_config_t * cfg,uint8_t * buf,uint32_t addr,uint32_t size)42 hpm_stat_t nor_flash_write(nor_flash_config_t *cfg, uint8_t *buf, uint32_t addr, uint32_t size)
43 {
44 addr > cfg->base_addr ? (addr -= cfg->base_addr) : addr;
45 hpm_stat_t status = rom_xpi_nor_program(cfg->xpi_base, xpi_xfer_channel_auto, \
46 &cfg->nor_config, (const uint32_t *)buf, addr, size);
47
48 return status;
49 }
50
nor_flash_erase_sector(nor_flash_config_t * cfg,uint32_t start_addr)51 static hpm_stat_t nor_flash_erase_sector(nor_flash_config_t *cfg, uint32_t start_addr)
52 {
53 start_addr > cfg->base_addr ? (start_addr -= cfg->base_addr) : start_addr;
54 hpm_stat_t status = rom_xpi_nor_erase_sector(cfg->xpi_base, xpi_xfer_channel_auto, &cfg->nor_config, start_addr);
55
56 return status;
57 }
58
nor_flash_erase(nor_flash_config_t * cfg,uint32_t start_addr,uint32_t size)59 void nor_flash_erase(nor_flash_config_t *cfg, uint32_t start_addr, uint32_t size)
60 {
61 uint32_t sector_size = cfg->sector_size;
62 for (uint32_t i = 0; i < size / sector_size; i++) {
63 nor_flash_erase_sector(cfg, start_addr + i * sector_size);
64 }
65 }
66