pro3_control_panel/base/flash_utils.py
2025-12-15 09:23:52 +08:00

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))