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