xref: /rk3399_rockchip-uboot/drivers/mtd/stm32_flash.c (revision 9ecb0c416c68d3105bc9b6607bc8601cab2ecf35)
1*9ecb0c41SVikas Manocha /*
2*9ecb0c41SVikas Manocha  * (C) Copyright 2015
3*9ecb0c41SVikas Manocha  * Kamil Lulko, <kamil.lulko@gmail.com>
4*9ecb0c41SVikas Manocha  *
5*9ecb0c41SVikas Manocha  * SPDX-License-Identifier:	GPL-2.0+
6*9ecb0c41SVikas Manocha  */
7*9ecb0c41SVikas Manocha 
8*9ecb0c41SVikas Manocha #include <common.h>
9*9ecb0c41SVikas Manocha #include <asm/io.h>
10*9ecb0c41SVikas Manocha #include <asm/arch/stm32.h>
11*9ecb0c41SVikas Manocha #include "stm32_flash.h"
12*9ecb0c41SVikas Manocha 
13*9ecb0c41SVikas Manocha flash_info_t flash_info[CONFIG_SYS_MAX_FLASH_BANKS];
14*9ecb0c41SVikas Manocha 
15*9ecb0c41SVikas Manocha #define STM32_FLASH		((struct stm32_flash_regs *)FLASH_CNTL_BASE)
16*9ecb0c41SVikas Manocha 
17*9ecb0c41SVikas Manocha void stm32_flash_latency_cfg(int latency)
18*9ecb0c41SVikas Manocha {
19*9ecb0c41SVikas Manocha 	/* 5 wait states, Prefetch enabled, D-Cache enabled, I-Cache enabled */
20*9ecb0c41SVikas Manocha 	writel(FLASH_ACR_WS(5) | FLASH_ACR_PRFTEN | FLASH_ACR_ICEN
21*9ecb0c41SVikas Manocha 		| FLASH_ACR_DCEN, &STM32_FLASH->acr);
22*9ecb0c41SVikas Manocha }
23*9ecb0c41SVikas Manocha 
24*9ecb0c41SVikas Manocha static void stm32_flash_lock(u8 lock)
25*9ecb0c41SVikas Manocha {
26*9ecb0c41SVikas Manocha 	if (lock) {
27*9ecb0c41SVikas Manocha 		setbits_le32(&STM32_FLASH->cr, STM32_FLASH_CR_LOCK);
28*9ecb0c41SVikas Manocha 	} else {
29*9ecb0c41SVikas Manocha 		writel(STM32_FLASH_KEY1, &STM32_FLASH->key);
30*9ecb0c41SVikas Manocha 		writel(STM32_FLASH_KEY2, &STM32_FLASH->key);
31*9ecb0c41SVikas Manocha 	}
32*9ecb0c41SVikas Manocha }
33*9ecb0c41SVikas Manocha 
34*9ecb0c41SVikas Manocha unsigned long flash_init(void)
35*9ecb0c41SVikas Manocha {
36*9ecb0c41SVikas Manocha 	unsigned long total_size = 0;
37*9ecb0c41SVikas Manocha 	u8 i, j;
38*9ecb0c41SVikas Manocha 
39*9ecb0c41SVikas Manocha 	for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
40*9ecb0c41SVikas Manocha 		flash_info[i].flash_id = FLASH_STM32;
41*9ecb0c41SVikas Manocha 		flash_info[i].sector_count = CONFIG_SYS_MAX_FLASH_SECT;
42*9ecb0c41SVikas Manocha 		flash_info[i].start[0] = CONFIG_SYS_FLASH_BASE + (i << 20);
43*9ecb0c41SVikas Manocha 		flash_info[i].size = sect_sz_kb[0];
44*9ecb0c41SVikas Manocha 		for (j = 1; j < CONFIG_SYS_MAX_FLASH_SECT; j++) {
45*9ecb0c41SVikas Manocha 			flash_info[i].start[j] = flash_info[i].start[j - 1]
46*9ecb0c41SVikas Manocha 				+ (sect_sz_kb[j - 1]);
47*9ecb0c41SVikas Manocha 			flash_info[i].size += sect_sz_kb[j];
48*9ecb0c41SVikas Manocha 		}
49*9ecb0c41SVikas Manocha 		total_size += flash_info[i].size;
50*9ecb0c41SVikas Manocha 	}
51*9ecb0c41SVikas Manocha 
52*9ecb0c41SVikas Manocha 	return total_size;
53*9ecb0c41SVikas Manocha }
54*9ecb0c41SVikas Manocha 
55*9ecb0c41SVikas Manocha void flash_print_info(flash_info_t *info)
56*9ecb0c41SVikas Manocha {
57*9ecb0c41SVikas Manocha 	int i;
58*9ecb0c41SVikas Manocha 
59*9ecb0c41SVikas Manocha 	if (info->flash_id == FLASH_UNKNOWN) {
60*9ecb0c41SVikas Manocha 		printf("missing or unknown FLASH type\n");
61*9ecb0c41SVikas Manocha 		return;
62*9ecb0c41SVikas Manocha 	} else if (info->flash_id == FLASH_STM32) {
63*9ecb0c41SVikas Manocha 		printf("stm32 Embedded Flash\n");
64*9ecb0c41SVikas Manocha 	}
65*9ecb0c41SVikas Manocha 
66*9ecb0c41SVikas Manocha 	printf("  Size: %ld MB in %d Sectors\n",
67*9ecb0c41SVikas Manocha 	       info->size >> 20, info->sector_count);
68*9ecb0c41SVikas Manocha 
69*9ecb0c41SVikas Manocha 	printf("  Sector Start Addresses:");
70*9ecb0c41SVikas Manocha 	for (i = 0; i < info->sector_count; ++i) {
71*9ecb0c41SVikas Manocha 		if ((i % 5) == 0)
72*9ecb0c41SVikas Manocha 			printf("\n   ");
73*9ecb0c41SVikas Manocha 		printf(" %08lX%s",
74*9ecb0c41SVikas Manocha 		       info->start[i],
75*9ecb0c41SVikas Manocha 			info->protect[i] ? " (RO)" : "     ");
76*9ecb0c41SVikas Manocha 	}
77*9ecb0c41SVikas Manocha 	printf("\n");
78*9ecb0c41SVikas Manocha 	return;
79*9ecb0c41SVikas Manocha }
80*9ecb0c41SVikas Manocha 
81*9ecb0c41SVikas Manocha int flash_erase(flash_info_t *info, int first, int last)
82*9ecb0c41SVikas Manocha {
83*9ecb0c41SVikas Manocha 	u8 bank = 0xFF;
84*9ecb0c41SVikas Manocha 	int i;
85*9ecb0c41SVikas Manocha 
86*9ecb0c41SVikas Manocha 	for (i = 0; i < CONFIG_SYS_MAX_FLASH_BANKS; i++) {
87*9ecb0c41SVikas Manocha 		if (info == &flash_info[i]) {
88*9ecb0c41SVikas Manocha 			bank = i;
89*9ecb0c41SVikas Manocha 			break;
90*9ecb0c41SVikas Manocha 		}
91*9ecb0c41SVikas Manocha 	}
92*9ecb0c41SVikas Manocha 	if (bank == 0xFF)
93*9ecb0c41SVikas Manocha 		return -1;
94*9ecb0c41SVikas Manocha 
95*9ecb0c41SVikas Manocha 	stm32_flash_lock(0);
96*9ecb0c41SVikas Manocha 
97*9ecb0c41SVikas Manocha 	for (i = first; i <= last; i++) {
98*9ecb0c41SVikas Manocha 		while (readl(&STM32_FLASH->sr) & STM32_FLASH_SR_BSY)
99*9ecb0c41SVikas Manocha 			;
100*9ecb0c41SVikas Manocha 
101*9ecb0c41SVikas Manocha 		/* clear old sector number before writing a new one */
102*9ecb0c41SVikas Manocha 		clrbits_le32(&STM32_FLASH->cr, STM32_FLASH_CR_SNB_MASK);
103*9ecb0c41SVikas Manocha 
104*9ecb0c41SVikas Manocha 		if (bank == 0) {
105*9ecb0c41SVikas Manocha 			setbits_le32(&STM32_FLASH->cr,
106*9ecb0c41SVikas Manocha 				     (i << STM32_FLASH_CR_SNB_OFFSET));
107*9ecb0c41SVikas Manocha 		} else if (bank == 1) {
108*9ecb0c41SVikas Manocha 			setbits_le32(&STM32_FLASH->cr,
109*9ecb0c41SVikas Manocha 				     ((0x10 | i) << STM32_FLASH_CR_SNB_OFFSET));
110*9ecb0c41SVikas Manocha 		} else {
111*9ecb0c41SVikas Manocha 			stm32_flash_lock(1);
112*9ecb0c41SVikas Manocha 			return -1;
113*9ecb0c41SVikas Manocha 		}
114*9ecb0c41SVikas Manocha 		setbits_le32(&STM32_FLASH->cr, STM32_FLASH_CR_SER);
115*9ecb0c41SVikas Manocha 		setbits_le32(&STM32_FLASH->cr, STM32_FLASH_CR_STRT);
116*9ecb0c41SVikas Manocha 
117*9ecb0c41SVikas Manocha 		while (readl(&STM32_FLASH->sr) & STM32_FLASH_SR_BSY)
118*9ecb0c41SVikas Manocha 			;
119*9ecb0c41SVikas Manocha 
120*9ecb0c41SVikas Manocha 		clrbits_le32(&STM32_FLASH->cr, STM32_FLASH_CR_SER);
121*9ecb0c41SVikas Manocha 	}
122*9ecb0c41SVikas Manocha 
123*9ecb0c41SVikas Manocha 	stm32_flash_lock(1);
124*9ecb0c41SVikas Manocha 	return 0;
125*9ecb0c41SVikas Manocha }
126*9ecb0c41SVikas Manocha 
127*9ecb0c41SVikas Manocha int write_buff(flash_info_t *info, uchar *src, ulong addr, ulong cnt)
128*9ecb0c41SVikas Manocha {
129*9ecb0c41SVikas Manocha 	ulong i;
130*9ecb0c41SVikas Manocha 
131*9ecb0c41SVikas Manocha 	while (readl(&STM32_FLASH->sr) & STM32_FLASH_SR_BSY)
132*9ecb0c41SVikas Manocha 		;
133*9ecb0c41SVikas Manocha 
134*9ecb0c41SVikas Manocha 	stm32_flash_lock(0);
135*9ecb0c41SVikas Manocha 
136*9ecb0c41SVikas Manocha 	setbits_le32(&STM32_FLASH->cr, STM32_FLASH_CR_PG);
137*9ecb0c41SVikas Manocha 	/* To make things simple use byte writes only */
138*9ecb0c41SVikas Manocha 	for (i = 0; i < cnt; i++) {
139*9ecb0c41SVikas Manocha 		*(uchar *)(addr + i) = src[i];
140*9ecb0c41SVikas Manocha 		while (readl(&STM32_FLASH->sr) & STM32_FLASH_SR_BSY)
141*9ecb0c41SVikas Manocha 			;
142*9ecb0c41SVikas Manocha 	}
143*9ecb0c41SVikas Manocha 	clrbits_le32(&STM32_FLASH->cr, STM32_FLASH_CR_PG);
144*9ecb0c41SVikas Manocha 	stm32_flash_lock(1);
145*9ecb0c41SVikas Manocha 
146*9ecb0c41SVikas Manocha 	return 0;
147*9ecb0c41SVikas Manocha }
148