blob: 86a7c88ef50b09bc7a1f0906ed28645b9c175ea0 [file] [log] [blame]
Jorge Ramirez-Ortiz29a8e022017-01-29 18:01:38 +01001/*
2 * Copyright (c) 2017 Linaro Limited
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7#include <kernel.h>
8#include <device.h>
9#include <string.h>
Anas Nashiffe051a92019-06-25 15:53:50 -040010#include <drivers/flash.h>
Jorge Ramirez-Ortiz29a8e022017-01-29 18:01:38 +010011#include <init.h>
12#include <soc.h>
13
Sebastian Bøeb7eaeb92017-10-27 16:11:54 +020014#include "flash_stm32.h"
Jorge Ramirez-Ortiz29a8e022017-01-29 18:01:38 +010015
Marti Bolivar32482e92017-08-30 16:39:26 -040016#define STM32F4X_SECTOR_MASK ((u32_t) 0xFFFFFF07)
17
Marti Bolivar4fea6df2017-08-30 14:02:10 -040018bool flash_stm32_valid_range(struct device *dev, off_t offset, u32_t len,
19 bool write)
Jorge Ramirez-Ortiz29a8e022017-01-29 18:01:38 +010020{
Michel Jaouene9153972017-06-14 12:49:33 +020021 ARG_UNUSED(write);
Marti Bolivar32482e92017-08-30 16:39:26 -040022
23 return flash_stm32_range_exists(dev, offset, len);
Jorge Ramirez-Ortiz29a8e022017-01-29 18:01:38 +010024}
25
Marti Bolivar4fea6df2017-08-30 14:02:10 -040026static int write_byte(struct device *dev, off_t offset, u8_t val)
Jorge Ramirez-Ortiz29a8e022017-01-29 18:01:38 +010027{
Marti Bolivar4fea6df2017-08-30 14:02:10 -040028 struct stm32f4x_flash *regs = FLASH_STM32_REGS(dev);
Kumar Galaccad5bf2017-04-21 10:03:20 -050029 u32_t tmp;
Jorge Ramirez-Ortiz29a8e022017-01-29 18:01:38 +010030 int rc;
31
32 /* if the control register is locked, do not fail silently */
Neil Armstronga9183cd2017-05-02 14:55:08 +000033 if (regs->cr & FLASH_CR_LOCK) {
Jorge Ramirez-Ortiz29a8e022017-01-29 18:01:38 +010034 return -EIO;
35 }
36
Marti Bolivar4fea6df2017-08-30 14:02:10 -040037 rc = flash_stm32_wait_flash_idle(dev);
Jorge Ramirez-Ortiz29a8e022017-01-29 18:01:38 +010038 if (rc < 0) {
39 return rc;
40 }
41
Neil Armstronga9183cd2017-05-02 14:55:08 +000042 regs->cr &= ~CR_PSIZE_MASK;
43 regs->cr |= FLASH_PSIZE_BYTE;
44 regs->cr |= FLASH_CR_PG;
Jorge Ramirez-Ortiz29a8e022017-01-29 18:01:38 +010045
46 /* flush the register write */
Neil Armstronga9183cd2017-05-02 14:55:08 +000047 tmp = regs->cr;
Jorge Ramirez-Ortiz29a8e022017-01-29 18:01:38 +010048
Kumar Galaccad5bf2017-04-21 10:03:20 -050049 *((u8_t *) offset + CONFIG_FLASH_BASE_ADDRESS) = val;
Jorge Ramirez-Ortiz29a8e022017-01-29 18:01:38 +010050
Marti Bolivar4fea6df2017-08-30 14:02:10 -040051 rc = flash_stm32_wait_flash_idle(dev);
Neil Armstronga9183cd2017-05-02 14:55:08 +000052 regs->cr &= (~FLASH_CR_PG);
Jorge Ramirez-Ortiz29a8e022017-01-29 18:01:38 +010053
54 return rc;
55}
56
Marti Bolivar32482e92017-08-30 16:39:26 -040057static int erase_sector(struct device *dev, u32_t sector)
Jorge Ramirez-Ortiz29a8e022017-01-29 18:01:38 +010058{
Marti Bolivar4fea6df2017-08-30 14:02:10 -040059 struct stm32f4x_flash *regs = FLASH_STM32_REGS(dev);
Kumar Galaccad5bf2017-04-21 10:03:20 -050060 u32_t tmp;
Jorge Ramirez-Ortiz29a8e022017-01-29 18:01:38 +010061 int rc;
62
63 /* if the control register is locked, do not fail silently */
Neil Armstronga9183cd2017-05-02 14:55:08 +000064 if (regs->cr & FLASH_CR_LOCK) {
Jorge Ramirez-Ortiz29a8e022017-01-29 18:01:38 +010065 return -EIO;
66 }
67
Marti Bolivar4fea6df2017-08-30 14:02:10 -040068 rc = flash_stm32_wait_flash_idle(dev);
Jorge Ramirez-Ortiz29a8e022017-01-29 18:01:38 +010069 if (rc < 0) {
70 return rc;
71 }
72
Neil Armstronga9183cd2017-05-02 14:55:08 +000073 regs->cr &= STM32F4X_SECTOR_MASK;
74 regs->cr |= FLASH_CR_SER | (sector << 3);
75 regs->cr |= FLASH_CR_STRT;
Jorge Ramirez-Ortiz29a8e022017-01-29 18:01:38 +010076
77 /* flush the register write */
Neil Armstronga9183cd2017-05-02 14:55:08 +000078 tmp = regs->cr;
Jorge Ramirez-Ortiz29a8e022017-01-29 18:01:38 +010079
Marti Bolivar4fea6df2017-08-30 14:02:10 -040080 rc = flash_stm32_wait_flash_idle(dev);
Neil Armstronga9183cd2017-05-02 14:55:08 +000081 regs->cr &= ~(FLASH_CR_SER | FLASH_CR_SNB);
Jorge Ramirez-Ortiz29a8e022017-01-29 18:01:38 +010082
83 return rc;
84}
85
Marti Bolivar4fea6df2017-08-30 14:02:10 -040086int flash_stm32_block_erase_loop(struct device *dev, unsigned int offset,
87 unsigned int len)
Jorge Ramirez-Ortiz29a8e022017-01-29 18:01:38 +010088{
Marti Bolivar32482e92017-08-30 16:39:26 -040089 struct flash_pages_info info;
90 u32_t start_sector, end_sector;
Leandro Pereira5e2303d2017-10-23 13:12:44 -070091 u32_t i;
92 int rc = 0;
Jorge Ramirez-Ortiz29a8e022017-01-29 18:01:38 +010093
Marti Bolivar32482e92017-08-30 16:39:26 -040094 rc = flash_get_page_info_by_offs(dev, offset, &info);
95 if (rc) {
96 return rc;
97 }
98 start_sector = info.index;
99 rc = flash_get_page_info_by_offs(dev, offset + len - 1, &info);
100 if (rc) {
101 return rc;
102 }
103 end_sector = info.index;
104
105 for (i = start_sector; i <= end_sector; i++) {
Marti Bolivar4fea6df2017-08-30 14:02:10 -0400106 rc = erase_sector(dev, i);
Jorge Ramirez-Ortiz29a8e022017-01-29 18:01:38 +0100107 if (rc < 0) {
108 break;
109 }
110 }
Jorge Ramirez-Ortiz29a8e022017-01-29 18:01:38 +0100111
112 return rc;
113}
114
Marti Bolivar4fea6df2017-08-30 14:02:10 -0400115int flash_stm32_write_range(struct device *dev, unsigned int offset,
116 const void *data, unsigned int len)
Jorge Ramirez-Ortiz29a8e022017-01-29 18:01:38 +0100117{
Neil Armstronga9183cd2017-05-02 14:55:08 +0000118 int i, rc = 0;
Jorge Ramirez-Ortiz29a8e022017-01-29 18:01:38 +0100119
120 for (i = 0; i < len; i++, offset++) {
Marti Bolivar4fea6df2017-08-30 14:02:10 -0400121 rc = write_byte(dev, offset, ((const u8_t *) data)[i]);
Jorge Ramirez-Ortiz29a8e022017-01-29 18:01:38 +0100122 if (rc < 0) {
Jorge Ramirez-Ortiz29a8e022017-01-29 18:01:38 +0100123 return rc;
124 }
125 }
126
Jorge Ramirez-Ortiz29a8e022017-01-29 18:01:38 +0100127 return rc;
128}
Marti Bolivar32482e92017-08-30 16:39:26 -0400129
130/*
131 * Different SoC flash layouts are specified in across various
132 * reference manuals, but the flash layout for a given number of
133 * sectors is consistent across these manuals, with one "gotcha". The
134 * number of sectors is given by the HAL as FLASH_SECTOR_TOTAL.
135 *
136 * The only "gotcha" is that when there are 24 sectors, they are split
137 * across 2 "banks" of 12 sectors each, with another set of small
138 * sectors (16 KB) in the second bank occurring after the large ones
139 * (128 KB) in the first. We could consider supporting this as two
140 * devices to make the layout cleaner, but this will do for now.
141 */
142#ifndef FLASH_SECTOR_TOTAL
143#error "Unknown flash layout"
144#else /* defined(FLASH_SECTOR_TOTAL) */
145#if FLASH_SECTOR_TOTAL == 5
146static const struct flash_pages_layout stm32f4_flash_layout[] = {
147 /* RM0401, table 5: STM32F410Tx, STM32F410Cx, STM32F410Rx */
148 {.pages_count = 4, .pages_size = KB(16)},
149 {.pages_count = 1, .pages_size = KB(64)},
150};
151#elif FLASH_SECTOR_TOTAL == 6
152static const struct flash_pages_layout stm32f4_flash_layout[] = {
153 /* RM0368, table 5: STM32F401xC */
154 {.pages_count = 4, .pages_size = KB(16)},
155 {.pages_count = 1, .pages_size = KB(64)},
156 {.pages_count = 1, .pages_size = KB(128)},
157};
158#elif FLASH_SECTOR_TOTAL == 8
159static const struct flash_pages_layout stm32f4_flash_layout[] = {
160 /*
161 * RM0368, table 5: STM32F401xE
162 * RM0383, table 4: STM32F411xE
163 * RM0390, table 4: STM32F446xx
164 */
165 {.pages_count = 4, .pages_size = KB(16)},
166 {.pages_count = 1, .pages_size = KB(64)},
167 {.pages_count = 3, .pages_size = KB(128)},
168};
169#elif FLASH_SECTOR_TOTAL == 12
170static const struct flash_pages_layout stm32f4_flash_layout[] = {
171 /*
172 * RM0090, table 5: STM32F405xx, STM32F415xx, STM32F407xx, STM32F417xx
173 * RM0402, table 5: STM32F412Zx, STM32F412Vx, STM32F412Rx, STM32F412Cx
174 */
175 {.pages_count = 4, .pages_size = KB(16)},
176 {.pages_count = 1, .pages_size = KB(64)},
177 {.pages_count = 7, .pages_size = KB(128)},
178};
179#elif FLASH_SECTOR_TOTAL == 16
180static const struct flash_pages_layout stm32f4_flash_layout[] = {
181 /* RM0430, table 5.: STM32F413xx, STM32F423xx */
182 {.pages_count = 4, .pages_size = KB(16)},
183 {.pages_count = 1, .pages_size = KB(64)},
184 {.pages_count = 11, .pages_size = KB(128)},
185};
186#elif FLASH_SECTOR_TOTAL == 24
187static const struct flash_pages_layout stm32f4_flash_layout[] = {
188 /*
189 * RM0090, table 6: STM32F427xx, STM32F437xx, STM32F429xx, STM32F439xx
190 * RM0386, table 4: STM32F469xx, STM32F479xx
191 */
192 {.pages_count = 4, .pages_size = KB(16)},
193 {.pages_count = 1, .pages_size = KB(64)},
194 {.pages_count = 7, .pages_size = KB(128)},
195 {.pages_count = 4, .pages_size = KB(16)},
196 {.pages_count = 1, .pages_size = KB(64)},
197 {.pages_count = 7, .pages_size = KB(128)},
198};
199#else
200#error "Unknown flash layout"
201#endif /* FLASH_SECTOR_TOTAL == 5 */
202#endif/* !defined(FLASH_SECTOR_TOTAL) */
203
204void flash_stm32_page_layout(struct device *dev,
205 const struct flash_pages_layout **layout,
206 size_t *layout_size)
207{
208 ARG_UNUSED(dev);
209
210 *layout = stm32f4_flash_layout;
211 *layout_size = ARRAY_SIZE(stm32f4_flash_layout);
212}