146 lines
5.6 KiB
Python
146 lines
5.6 KiB
Python
#! /usr/bin/env python
|
|
# -*- coding: utf-8 -*-
|
|
|
|
# Copyright (c) 2024 Realtek Semiconductor Corp.
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
|
|
from enum import Enum
|
|
from .sys_utils import *
|
|
|
|
|
|
class FlashBPS:
|
|
def __init__(self):
|
|
self.need_unlock = False
|
|
self.protection = 0
|
|
self.is_locked = False
|
|
|
|
|
|
class FlashUtils(Enum):
|
|
# NAND Flash MID
|
|
NandMfgDosilicon = 0xE5
|
|
NandMfgGigadevice = 0xC8
|
|
NandMfgMacronix = 0xC2
|
|
NandMfgMicron = 0x2C
|
|
NandMfgWinbond = 0xEF
|
|
|
|
# NAND Flash commands
|
|
NandCmdGetFeatures = 0x0F
|
|
NandCmdSetFeatures = 0x1F
|
|
|
|
# NAND Flash registers
|
|
NandRegProtection = 0xA0
|
|
NandRegFeature = 0xB0
|
|
NandRegStatus = 0xC0
|
|
NandRegProtectionBpMask = 0x38
|
|
NandRegProtectionBpMaskWinbondMicron = 0x78
|
|
|
|
# NOR Flash command & registers
|
|
NorCmdReadStatusReg1 = 0x05
|
|
NorCmdWriteStatusReg1 = 0x01
|
|
NorStatusReg1BpMask = 0x3C
|
|
|
|
# NOR Flash default page/block size
|
|
NorDefaultPageSize = 1024
|
|
NorDefaultPagePerBlock = 4
|
|
NorDefaultBlockSize = (NorDefaultPageSize * NorDefaultPagePerBlock)
|
|
|
|
# NAND Flash default page/block size
|
|
NandDefaultPageSize = 2048
|
|
NandDefaultPagePerBlock = 64
|
|
NandDefaultBlockSize = (NandDefaultPageSize * NandDefaultPagePerBlock)
|
|
|
|
# Flash write padding data
|
|
FlashWritePaddingData = 0xFF
|
|
|
|
MinFlashProcessTimeoutInSecond = 1
|
|
|
|
# NOR Flash program / read / erase timeout
|
|
# Max page program time: typical 0.5ms for GD25Q128E, max 3ms for W25Q256JV
|
|
# Take 0.5ms * 10 = 5ms
|
|
NorPageProgramTimeoutInSeconds = 0.005
|
|
# Max 4KB sector erase time: typical 70ms for GD25Q256D, max 400ms for GD25Q256D
|
|
# Take(400ms * 2) > (70ms * 10 = 700ms)
|
|
Nor4kSectorEraseTimeoutInSenonds = 0.8
|
|
# Max 32KB block erase time: typical 0.16s for GD25Q128E, max 1.6s for W25Q256JV
|
|
# Take 2s > 0.16s * 10 = 1.6s
|
|
Nor32kBlockEraseTimeoutInSeconds = 2 # larger than max
|
|
# Max 64KB block erase time: typical 0.25s for GD25Q128E, max 1.6s for GD25Q128E
|
|
# Take 0.25s * 10 = 2.5s
|
|
Nor64kBlockEraseTimeoutInSeconds = 2.5
|
|
# Max chip erase time: typical 150s for W25Q256JV, max 400s for W25Q256JV
|
|
# Take 1000s > 400s * 2 = 800s
|
|
NorChipEraseTimeoutInSeconds = 1000
|
|
# Read flash with 1IO @ 10MHz(10Mbps)
|
|
NorRead1KiBTimeoutInSecond = 0.001
|
|
# NOR calculate checksum with 1.5MB / s, test data(15.8MB / 8s)
|
|
NorCalculate1KiBChecksumTimeoutInSeconds = 0.001
|
|
|
|
# NAND Flash 4KB page size read / program / block erase timeout
|
|
# Page size read from Array with ECC(900us) + page size(4KB) read from cache with 1IO @ 10MHz(4KB / 10Mbps=3.2ms)
|
|
# Max read from array with ECC: 90us for MT29F4G01ABBF, max 170us for MT29F4G01ABBF
|
|
# Take 90us * 10 = 900us + 3.2ms
|
|
NandPageReadTimeoutInSeconds = 0.004
|
|
# page program with ECC(4ms) + page size(4KB) load with 1IO @ 10MHz(4KB / 10Mbps=3.2ms)
|
|
# Max page program with ECC: 400us for MX35LF4GE4AD, max 800us for MX35LF4GE4AD
|
|
# Take 400us * 10 = 4ms + 3.2ms
|
|
NandPageProgramTimeoutInSeconds = 0.007
|
|
# Max block erase time: typical 4ms for MX35LFxG24AD, max 10ms for MT29F2G01ABAG
|
|
# Take 4ms * 10 = 40ms
|
|
NandBlockEraseTimeoutInSeconds = 0.04
|
|
# NAND calculate checksum with 1.5MB / s, test data(2KB / 4KB:47MB / 23s)
|
|
NandCalculate1KiBChecksumTimeoutInSeconds = 0.001
|
|
|
|
|
|
def nor_read_timeout_in_second(size_in_byte):
|
|
return int(max(divide_then_round_up(size_in_byte, 1024) * FlashUtils.NorRead1KiBTimeoutInSecond.value,
|
|
FlashUtils.MinFlashProcessTimeoutInSecond.value))
|
|
|
|
|
|
def nor_erase_timeout_in_second(size_in_kbyte):
|
|
if size_in_kbyte == 0xFFFFFFFF:
|
|
return int(max(FlashUtils.NorChipEraseTimeoutInSeconds.value,
|
|
FlashUtils.MinFlashProcessTimeoutInSecond.value))
|
|
elif size_in_kbyte == 4:
|
|
return int(max(FlashUtils.Nor4kSectorEraseTimeoutInSenonds.value,
|
|
FlashUtils.MinFlashProcessTimeoutInSecond.value))
|
|
elif size_in_kbyte == 32:
|
|
return int(max(FlashUtils.Nor32kBlockEraseTimeoutInSeconds.value,
|
|
FlashUtils.MinFlashProcessTimeoutInSecond.value))
|
|
elif size_in_kbyte == 64:
|
|
return int(max(FlashUtils.Nor64kBlockEraseTimeoutInSeconds.value,
|
|
FlashUtils.MinFlashProcessTimeoutInSecond.value))
|
|
else:
|
|
return int(
|
|
max(divide_then_round_up(size_in_kbyte, 4) * FlashUtils.Nor4kSectorEraseTimeoutInSenonds.value,
|
|
FlashUtils.MinFlashProcessTimeoutInSecond.value))
|
|
|
|
|
|
def nor_checksum_timeout_in_second(size_in_byte):
|
|
return int(max(divide_then_round_up(size_in_byte,
|
|
1024) * FlashUtils.NorCalculate1KiBChecksumTimeoutInSeconds.value,
|
|
FlashUtils.MinFlashProcessTimeoutInSecond.value))
|
|
|
|
|
|
def nand_read_timeout_in_second(size_in_byte, page_size):
|
|
return int(max(
|
|
divide_then_round_up(size_in_byte, page_size) * FlashUtils.NandPageReadTimeoutInSeconds.value,
|
|
FlashUtils.MinFlashProcessTimeoutInSecond.value))
|
|
|
|
|
|
def nand_program_timeout_in_second(size_in_byte, page_size):
|
|
return int(max(
|
|
divide_then_round_up(size_in_byte, page_size) * FlashUtils.NandPageProgramTimeoutInSeconds.value,
|
|
FlashUtils.MinFlashProcessTimeoutInSecond.value))
|
|
|
|
|
|
def nand_erase_timeout_in_second(size_in_byte, block_size):
|
|
return int(max(
|
|
divide_then_round_up(size_in_byte, block_size) * FlashUtils.NandBlockEraseTimeoutInSeconds.value,
|
|
FlashUtils.MinFlashProcessTimeoutInSecond.value))
|
|
|
|
|
|
def nand_checksum_timeout_in_second(size_in_byte, page_size):
|
|
return int(max(
|
|
divide_then_round_up(size_in_byte, 1024) * FlashUtils.NandCalculate1KiBChecksumTimeoutInSeconds.value,
|
|
FlashUtils.MinFlashProcessTimeoutInSecond.value))
|