TimJTi commented on code in PR #15523: URL: https://github.com/apache/nuttx/pull/15523#discussion_r1916386520
########## drivers/mtd/gd55.c: ########## @@ -0,0 +1,2082 @@ +/**************************************************************************** + * drivers/mtd/gd55.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> +#include <assert.h> +#include <errno.h> +#include <debug.h> +#include <inttypes.h> +#include <stdbool.h> +#include <stdint.h> + +#ifdef CONFIG_MTD_GD55_SECTOR512 +# include <stdlib.h> +# include <string.h> +#endif + +#include <nuttx/kmalloc.h> +#include <nuttx/signal.h> +#include <nuttx/fs/ioctl.h> +#include <nuttx/spi/qspi.h> +#include <nuttx/mtd/mtd.h> + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* 4 byte addressing is needed for addresses needing more than a 3 byte + * address, i.e. 16Mbyte + */ + +#define MODE_3BYTE_LIMIT ((16 * 1024 * 1024)) + +/* GD55 Commands */ + +#define GD55_QREAD 0x6b /* Quad output fast read */ +#define GD55_QREAD_DUMMIES 8 +#define GD55_QC_READ 0xeb /* Quad output continuous fast read */ +#define GD55_QC_READ_DUMMIES 6 +#define GD55_EQPP 0xc2 /* Extended quad page program */ +#define GD55_EQPP_DUMMIES 0 /* No dummy clocks */ +#define GD55_SE 0x20 /* 4Kb Sector erase */ +#define GD55_BE32 0x52 /* 32Kbit block Erase */ +#define GD55_BE64 0xd8 /* 64Kbit block Erase */ +#define GD55_CE 0x60 /* Chip erase (alternate) */ +#define GD55_WREN 0x06 /* Write Enable */ +#define GD55_WRDI 0x04 /* Write Disable */ +#define GD55_RDSR1 0x05 /* Read status register 1 */ +#define GD55_EN4B 0xb7 /* Enable 4 byte Addressing Mode */ +#define GD55_DIS4B 0xe9 /* Disable 4 byte Addressing Mode */ +#define GD55_IBSL 0x36 /* Individual block/sector lock */ +#define GD55_IBSUL 0x39 /* Individual block/sector unlock */ +#define GD55_RIBSL 0x3d /* Read individual block/sector lock */ +#define GD55_RDNVCR 0xb5 /* Read Non-Volatile config register */ +#define GD55_RD_NVCR_DUMMIES 8 +#define GD55_RDSR2 0x35 /* Read status register 2 */ +#define GD55_WRSR1 0x01 /* Write status register 1 */ +#define GD55_SE_ALT 0x21 /* Alternate 4Kb Sector erase */ +#define GD55_QC_READ_ALT 0xec /* Quad output continuous fast read */ +#define GD55_4B_QDTR_READ 0xed /* Quad I/O DTR read */ +#define GD55_4B_QDTR_READ_ALT 0xee /* Alternate quad I/O DTR read */ +#define GD55_PP 0x02 /* Page program (SPI, not used) */ +#define GD55_PP_ALT 0x12 /* Aternate page program (SPI) */ +#define GD55_BE32_ALT 0x5c /* Alternate 32Kbit block Erase */ +#define GD55_BE64_ALT 0xd8 /* ALternate 64Kbit block Erase */ +#define GD55_CE_ALT 0xc7 /* Alternate chip erase */ +#define GD55_QPP 0x32 /* Quad page program */ +#define GD55_QPP_ALT 0x34 /* ALternate quad page program */ +#define GD55_QPP_DUMMIES 0 /* No dummy clocks */ +#define GD55_QPIEN 0x38 /* Enable QPI Operation */ +#define GD55_QPIDIS 0xff /* Disable QPI Operation */ +#define GD55_DP 0xb9 /* Deep power down */ +#define GD55_RDP 0xab /* Release deep power down */ +#define GD55_RUID 0x4b /* Read Unique ID */ +#define GD55_RDID 0x9e /* Read identification */ +#define GD55_RDID_ALT 0x9f /* Read identification (alternate) */ +#define GD55_PE_SUSPEND 0x75 /* Suspends program/erase */ +#define GD55_PE_RESUME 0x7a /* Resume program */ +#define GD55_RDVCR 0x85 /* Read Volatile config register */ +#define GD55_RD_VCR_DUMMIES 1 +#define GD55_WRSR2 0x31 /* Write status register 2 */ +#define GD55_WRNVCR 0xb1 /* Write Non-Volatile config register */ +#define GD55_WRENVSC 0x50 /* Write en. Volatile config register */ +#define GD55_WRVCR 0x91 /* Write Volatile config register */ +#define GD55_WREAR 0xc5 /* Write Extended address register */ +#define GD55_EARR 0xc8 /* Read extended address register */ +#define GD55_RSFDP 0x5a /* Read SFDP */ +#define GD55_RDSCUR 0x48 /* Read security register */ +#define GD55_WRSCUR 0x42 /* Write security register */ +#define GD55_ERSCUR 0x44 /* Erase security register */ +#define GD55_RSTEN 0x66 /* Reset Enable */ +#define GD55_RST 0x99 /* Reset Memory */ +#define GD55_GBSL 0x7e /* Global block/sector lock */ +#define GD55_GBSUL 0x98 /* Global block/sector unlock */ + +/* Read ID (RDID) register values */ + +#define GD55_MANUFACTURER 0xc8 /* GigaSevice manufacturer ID */ + +/* JEDEC Read ID register values */ + +#define GD55_JEDEC_MANUFACTURER 0xc8 /* GigaDevice manufacturer ID */ + +#define GD55B_JEDEC_MEMORY_TYPE 0x47 /* GD55B memory type, 3V */ +#define GD55L_JEDEC_MEMORY_TYPE 0x67 /* GD55L memory type, 1.8V */ +#define GD55_JEDEC_1G_CAPACITY 0x1b /* 1Gbit memory capacity */ +#define GD55_JEDEC_2G_CAPACITY 0x1c /* 2Gbit memory capacity */ + +/* GD55 devices all have identical sector sizes: + * block protection size: 64KiB + * sector size: 4KiB + * page size: 256B + */ + +#define GD55_SECTOR_SHIFT (12) +#define GD55_SECTOR_SIZE (1 << GD55_SECTOR_SHIFT) /* 4KiB */ +#define GD55_PAGE_SHIFT (8) /* 256B */ +#define GD55_PAGE_SIZE (1 << GD55_PAGE_SHIFT) +#define GD55_BP_SHIFT (16) +#define GD55_BP_SIZE (1 << GD55_BP_SHIFT) /* 64KiB */ +#define GD55_MIN_BP_BLKS (GD55_BP_SIZE >> GD55_PAGE_SHIFT) +#define GD55_SECTORS_PER_BP_BLK (GD55_BP_SIZE / GD55_SECTOR_SIZE) + +/* GD55B01xx (128 MiB) memory capacity */ + +#define GD55_NSECTORS_1GBIT (32768) + +/* GD55B02xx (256 MiB) memory capacity */ + +#define GD55_NSECTORS_2GBIT (65536) + +/* 512 byte sector support **************************************************/ + +#define GD55_SECTOR512_SHIFT (9) +#define GD55_SECTOR512_SIZE (1 << GD55_SECTOR512_SHIFT) + +/* Status register 1 bit definitions */ + +#define GD55_SR_WIP (1 << 0) /* Bit 0: Write in progress */ +#define GD55_SR_WEL (1 << 1) /* Bit 1: Write enable latch */ +#define GD55_SR_BP_SHIFT (2) /* Bits 2-6: Block protect bits */ +#define GD55_SR_BP_MASK (31 << GD55_SR_BP_SHIFT) +#define GD55_STATUS_BP_NONE (0 << GD55_SR_BP_SHIFT) +#define GD55_STATUS_BP_ALL (7 << GD55_SR_BP_SHIFT) +#define GD55_STATUS_TB_MASK (1 << 6) /* BP4 Top/Bottom Protect */ +#define GD55_STATUS_TB_TOP (0 << 6) /* = 0, BP3..0 protect Top down */ +#define GD55_STATUS_TB_BOTTOM (1 << 6) /* = 1, BP3..0 " Bottom up */ +#define GD55_SR_BP_TOP(b) (((b + 1) << GD55_SR_BP_SHIFT) | \ + GD55_STATUS_TB_TOP) +#define GD55_SR_BP_BOTTOM(b) (((b + 1) << GD55_SR_BP_SHIFT) | \ + GD55_STATUS_TB_BOTTOM) +#define GD55_BP_ALL (14 << GD55_SR_BP_SHIFT) + /* GD55B01 needs BP bits = 0xx11xx + * GD55B02 needs BP bits = 0xx111x + */ +#define GD55_SR_SRP0 (1 << 7) /* Bit 7: SR protect bit 0 */ + +/* Status register 2 bit definitions */ + +#define GD55_SR_ADS (1 << 0) /* Bit 0: Current Address Mode */ + /* Bit 1 - reserved */ +#define GD55_SR_SUS2 (1 << 2) /* Bit 2: Program suspend bit 2 */ +#define GD55_SR_LB (1 << 3) /* Bit 3: Security Register Lock */ +#define GD55_SR_PE (1 << 4) /* Bit 4: Program Error Bit */ +#define GD55_SR_EE (1 << 5) /* Bit 5: Erase Error Bit */ +#define GD55_SR_SRP1 (1 << 6) /* Bit 6: SR protection bit 1 */ +#define GD55_SR_SUS1 (1 << 7) /* Bit 7: Program suspend bit 1 */ + +/* Non-volatile and volatile config register addresses and bits */ + +#define GD55_DUMMY_CYCLES_REG 1 /* Dummy Cycle Configuration */ +#define GD55_ODT_DS_REG 3 /* On-die termination and driver + * strength configuration + */ +#define GD55_DLP_PROT_REG 4 /* Data Learning and protect mode */ +#define GD55_PROT_MODE_MASK (1 << 2) /* Bit 2, BP or WPS mode */ +#define GD55_PROT_MODE_WPS (0 << 2) /* 0 = Sector Protect mode */ +#define GD55_PROT_MODE_BP (1 << 2) /* 1 = Block Protect mode (def.) */ +#define GD55_4BYTE_MODE_REG 5 /* 3 pr 4-byte address mode */ +#define GD55_XIP_MODE_REG 6 /* XIP (continuous read) mode */ +#define GD55_WRAP_CONFIG_REG 7 /* Wrap mode (none/64/32/16 byte) */ + +/* Block protection bit */ + +#define GD55_BLK_PROTECTED (1 << 0) /* lsb set means block is locked */ + +/* Cache flags **************************************************************/ + +#define GD55_CACHE_VALID (1 << 0) /* 1=Cache has valid data */ +#define GD55_CACHE_DIRTY (1 << 1) /* 1=Cache is dirty */ +#define GD55_CACHE_ERASED (1 << 2) /* 1=Backing FLASH is erased */ + +#define IS_VALID(p) ((((p)->flags) & GD55_CACHE_VALID) != 0) +#define IS_DIRTY(p) ((((p)->flags) & GD55_CACHE_DIRTY) != 0) +#define IS_ERASED(p) ((((p)->flags) & GD55_CACHE_ERASED) != 0) + +#define SET_VALID(p) do { (p)->flags |= GD55_CACHE_VALID; } while (0) Review Comment: You're as style-pedantic as I am and I hate when I miss this sort of thing - thanks for spotting this :-) -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: commits-unsubscr...@nuttx.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org