Merge tag 'mtd/for-5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux
Pull MTD updates from Miquel Raynal: "This contains the following changes for MTD: MTD core changes: - New Hyperbus framework - New _is_locked (concat) implementation - Various cleanups NAND core changes: - use longest matching pattern in ->exec_op() default parser - export NAND operation tracer - add flag to indicate panic_write in MTD - use kzalloc() instead of kmalloc() and memset() Raw NAND controller drivers changes: - brcmnand: - fix BCH ECC layout for large page NAND parts - fallback to detected ecc-strength, ecc-step-size - when oops in progress use pio and interrupt polling - code refactor code to introduce helper functions - add support for v7.3 controller - FSMC: - use nand_op_trace for operation tracing - GPMI: - move all driver code into single file - various cleanups (including dmaengine changes) - use runtime PM to manage clocks - implement exec_op - MTK: - correct low level time calculation of r/w cycle - improve data sampling timing for read cycle - add validity check for CE# pin setting - fix wrongly assigned OOB buffer pointer issue - re-license MTK NAND driver as Dual MIT/GPL - STM32: - manage the get_irq error case - increase DMA completion timeouts Raw NAND chips drivers changes: - Macronix: add read-retry support Onenand driver changes: - add support for 8Gb datasize chips - avoid fall-through warnings SPI-NAND changes: - define macros for page-read ops with three-byte addresses - add support for two-byte device IDs and then for GigaDevice GD5F1GQ4UFxxG - add initial support for Paragon PN26G0xA - handle the case where the last page read has bitflips SPI-NOR core changes: - add support for the mt25ql02g and w25q16jv flashes - print error in case of jedec read id fails - is25lp256: add post BFPT fix to correct the addr_width SPI NOR controller drivers changes: - intel-spi: Add support for Intel Elkhart Lake SPI serial flash - smt32: remove the driver as the driver was replaced by spi-stm32-qspi.c - cadence-quadspi: add reset control" * tag 'mtd/for-5.3' of git://git.kernel.org/pub/scm/linux/kernel/git/mtd/linux: (60 commits) mtd: concat: implement _is_locked mtd operation mtd: concat: refactor concat_lock/concat_unlock mtd: abi: do not use C++ style comments in uapi header mtd: afs: remove unneeded NULL check mtd: rawnand: stm32_fmc2: increase DMA completion timeouts mtd: rawnand: Use kzalloc() instead of kmalloc() and memset() mtd: hyperbus: Add driver for TI's HyperBus memory controller mtd: spinand: read returns badly if the last page has bitflips mtd: spinand: Add initial support for Paragon PN26G0xA mtd: rawnand: mtk: Re-license MTK NAND driver as Dual MIT/GPL mtd: rawnand: gpmi: remove double assignment to block_size dt-bindings: mtd: brcmnand: Add brcmnand, brcmnand-v7.3 support mtd: rawnand: brcmnand: Add support for v7.3 controller mtd: rawnand: brcmnand: Refactored code to introduce helper functions mtd: rawnand: brcmnand: When oops in progress use pio and interrupt polling mtd: Add flag to indicate panic_write mtd: rawnand: Add Macronix NAND read retry support mtd: onenand: Avoid fall-through warnings mtd: spinand: Add support for GigaDevice GD5F1GQ4UFxxG mtd: spinand: Add support for two-byte device IDs ...
This commit is contained in:
24
include/linux/dma/mxs-dma.h
Normal file
24
include/linux/dma/mxs-dma.h
Normal file
@@ -0,0 +1,24 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _MXS_DMA_H_
|
||||
#define _MXS_DMA_H_
|
||||
|
||||
#include <linux/dmaengine.h>
|
||||
|
||||
#define MXS_DMA_CTRL_WAIT4END BIT(31)
|
||||
#define MXS_DMA_CTRL_WAIT4RDY BIT(30)
|
||||
|
||||
/*
|
||||
* The mxs dmaengine can do PIO transfers. We pass a pointer to the PIO words
|
||||
* in the second argument to dmaengine_prep_slave_sg when the direction is
|
||||
* set to DMA_TRANS_NONE. To make this clear and to prevent users from doing
|
||||
* the error prone casting we have this wrapper function
|
||||
*/
|
||||
static inline struct dma_async_tx_descriptor *mxs_dmaengine_prep_pio(
|
||||
struct dma_chan *chan, u32 *pio, unsigned int npio,
|
||||
enum dma_transfer_direction dir, unsigned long flags)
|
||||
{
|
||||
return dmaengine_prep_slave_sg(chan, (struct scatterlist *)pio, npio,
|
||||
dir, flags);
|
||||
}
|
||||
|
||||
#endif /* _MXS_DMA_H_ */
|
@@ -219,6 +219,13 @@ struct cfi_pri_amdstd {
|
||||
uint8_t VppMin;
|
||||
uint8_t VppMax;
|
||||
uint8_t TopBottom;
|
||||
/* Below field are added from version 1.5 */
|
||||
uint8_t ProgramSuspend;
|
||||
uint8_t UnlockBypass;
|
||||
uint8_t SecureSiliconSector;
|
||||
uint8_t SoftwareFeatures;
|
||||
#define CFI_POLL_STATUS_REG BIT(0)
|
||||
#define CFI_POLL_DQ BIT(1)
|
||||
} __packed;
|
||||
|
||||
/* Vendor-Specific PRI for Atmel chips (command set 0x0002) */
|
||||
|
84
include/linux/mtd/hyperbus.h
Normal file
84
include/linux/mtd/hyperbus.h
Normal file
@@ -0,0 +1,84 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0
|
||||
*
|
||||
* Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com/
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_MTD_HYPERBUS_H__
|
||||
#define __LINUX_MTD_HYPERBUS_H__
|
||||
|
||||
#include <linux/mtd/map.h>
|
||||
|
||||
enum hyperbus_memtype {
|
||||
HYPERFLASH,
|
||||
HYPERRAM,
|
||||
};
|
||||
|
||||
/**
|
||||
* struct hyperbus_device - struct representing HyperBus slave device
|
||||
* @map: map_info struct for accessing MMIO HyperBus flash memory
|
||||
* @np: pointer to HyperBus slave device node
|
||||
* @mtd: pointer to MTD struct
|
||||
* @ctlr: pointer to HyperBus controller struct
|
||||
* @memtype: type of memory device: HyperFlash or HyperRAM
|
||||
*/
|
||||
|
||||
struct hyperbus_device {
|
||||
struct map_info map;
|
||||
struct device_node *np;
|
||||
struct mtd_info *mtd;
|
||||
struct hyperbus_ctlr *ctlr;
|
||||
enum hyperbus_memtype memtype;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct hyperbus_ops - struct representing custom HyperBus operations
|
||||
* @read16: read 16 bit of data from flash in a single burst. Used to read
|
||||
* from non default address space, such as ID/CFI space
|
||||
* @write16: write 16 bit of data to flash in a single burst. Used to
|
||||
* send cmd to flash or write single 16 bit word at a time.
|
||||
* @copy_from: copy data from flash memory
|
||||
* @copy_to: copy data to flash memory
|
||||
* @calibrate: calibrate HyperBus controller
|
||||
*/
|
||||
|
||||
struct hyperbus_ops {
|
||||
u16 (*read16)(struct hyperbus_device *hbdev, unsigned long addr);
|
||||
void (*write16)(struct hyperbus_device *hbdev,
|
||||
unsigned long addr, u16 val);
|
||||
void (*copy_from)(struct hyperbus_device *hbdev, void *to,
|
||||
unsigned long from, ssize_t len);
|
||||
void (*copy_to)(struct hyperbus_device *dev, unsigned long to,
|
||||
const void *from, ssize_t len);
|
||||
int (*calibrate)(struct hyperbus_device *dev);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct hyperbus_ctlr - struct representing HyperBus controller
|
||||
* @dev: pointer to HyperBus controller device
|
||||
* @calibrated: flag to indicate ctlr calibration sequence is complete
|
||||
* @ops: HyperBus controller ops
|
||||
*/
|
||||
struct hyperbus_ctlr {
|
||||
struct device *dev;
|
||||
bool calibrated;
|
||||
|
||||
const struct hyperbus_ops *ops;
|
||||
};
|
||||
|
||||
/**
|
||||
* hyperbus_register_device - probe and register a HyperBus slave memory device
|
||||
* @hbdev: hyperbus_device struct with dev, np and ctlr field populated
|
||||
*
|
||||
* Return: 0 for success, others for failure.
|
||||
*/
|
||||
int hyperbus_register_device(struct hyperbus_device *hbdev);
|
||||
|
||||
/**
|
||||
* hyperbus_unregister_device - deregister HyperBus slave memory device
|
||||
* @hbdev: hyperbus_device to be unregistered
|
||||
*
|
||||
* Return: 0 for success, others for failure.
|
||||
*/
|
||||
int hyperbus_unregister_device(struct hyperbus_device *hbdev);
|
||||
|
||||
#endif /* __LINUX_MTD_HYPERBUS_H__ */
|
@@ -316,6 +316,12 @@ struct mtd_info {
|
||||
int (*_get_device) (struct mtd_info *mtd);
|
||||
void (*_put_device) (struct mtd_info *mtd);
|
||||
|
||||
/*
|
||||
* flag indicates a panic write, low level drivers can take appropriate
|
||||
* action if required to ensure writes go through
|
||||
*/
|
||||
bool oops_panic_write;
|
||||
|
||||
struct notifier_block reboot_notifier; /* default mode before reboot */
|
||||
|
||||
/* ECC status information */
|
||||
|
@@ -77,6 +77,7 @@
|
||||
#define ONENAND_DEVICE_DENSITY_1Gb (0x003)
|
||||
#define ONENAND_DEVICE_DENSITY_2Gb (0x004)
|
||||
#define ONENAND_DEVICE_DENSITY_4Gb (0x005)
|
||||
#define ONENAND_DEVICE_DENSITY_8Gb (0x006)
|
||||
|
||||
/*
|
||||
* Version ID Register F002h (R)
|
||||
|
@@ -874,6 +874,42 @@ int nand_op_parser_exec_op(struct nand_chip *chip,
|
||||
const struct nand_op_parser *parser,
|
||||
const struct nand_operation *op, bool check_only);
|
||||
|
||||
static inline void nand_op_trace(const char *prefix,
|
||||
const struct nand_op_instr *instr)
|
||||
{
|
||||
#if IS_ENABLED(CONFIG_DYNAMIC_DEBUG) || defined(DEBUG)
|
||||
switch (instr->type) {
|
||||
case NAND_OP_CMD_INSTR:
|
||||
pr_debug("%sCMD [0x%02x]\n", prefix,
|
||||
instr->ctx.cmd.opcode);
|
||||
break;
|
||||
case NAND_OP_ADDR_INSTR:
|
||||
pr_debug("%sADDR [%d cyc: %*ph]\n", prefix,
|
||||
instr->ctx.addr.naddrs,
|
||||
instr->ctx.addr.naddrs < 64 ?
|
||||
instr->ctx.addr.naddrs : 64,
|
||||
instr->ctx.addr.addrs);
|
||||
break;
|
||||
case NAND_OP_DATA_IN_INSTR:
|
||||
pr_debug("%sDATA_IN [%d B%s]\n", prefix,
|
||||
instr->ctx.data.len,
|
||||
instr->ctx.data.force_8bit ?
|
||||
", force 8-bit" : "");
|
||||
break;
|
||||
case NAND_OP_DATA_OUT_INSTR:
|
||||
pr_debug("%sDATA_OUT [%d B%s]\n", prefix,
|
||||
instr->ctx.data.len,
|
||||
instr->ctx.data.force_8bit ?
|
||||
", force 8-bit" : "");
|
||||
break;
|
||||
case NAND_OP_WAITRDY_INSTR:
|
||||
pr_debug("%sWAITRDY [max %d ms]\n", prefix,
|
||||
instr->ctx.waitrdy.timeout_ms);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* struct nand_controller_ops - Controller operations
|
||||
*
|
||||
|
@@ -68,30 +68,60 @@
|
||||
SPI_MEM_OP_DUMMY(ndummy, 1), \
|
||||
SPI_MEM_OP_DATA_IN(len, buf, 1))
|
||||
|
||||
#define SPINAND_PAGE_READ_FROM_CACHE_OP_3A(fast, addr, ndummy, buf, len) \
|
||||
SPI_MEM_OP(SPI_MEM_OP_CMD(fast ? 0x0b : 0x03, 1), \
|
||||
SPI_MEM_OP_ADDR(3, addr, 1), \
|
||||
SPI_MEM_OP_DUMMY(ndummy, 1), \
|
||||
SPI_MEM_OP_DATA_IN(len, buf, 1))
|
||||
|
||||
#define SPINAND_PAGE_READ_FROM_CACHE_X2_OP(addr, ndummy, buf, len) \
|
||||
SPI_MEM_OP(SPI_MEM_OP_CMD(0x3b, 1), \
|
||||
SPI_MEM_OP_ADDR(2, addr, 1), \
|
||||
SPI_MEM_OP_DUMMY(ndummy, 1), \
|
||||
SPI_MEM_OP_DATA_IN(len, buf, 2))
|
||||
|
||||
#define SPINAND_PAGE_READ_FROM_CACHE_X2_OP_3A(addr, ndummy, buf, len) \
|
||||
SPI_MEM_OP(SPI_MEM_OP_CMD(0x3b, 1), \
|
||||
SPI_MEM_OP_ADDR(3, addr, 1), \
|
||||
SPI_MEM_OP_DUMMY(ndummy, 1), \
|
||||
SPI_MEM_OP_DATA_IN(len, buf, 2))
|
||||
|
||||
#define SPINAND_PAGE_READ_FROM_CACHE_X4_OP(addr, ndummy, buf, len) \
|
||||
SPI_MEM_OP(SPI_MEM_OP_CMD(0x6b, 1), \
|
||||
SPI_MEM_OP_ADDR(2, addr, 1), \
|
||||
SPI_MEM_OP_DUMMY(ndummy, 1), \
|
||||
SPI_MEM_OP_DATA_IN(len, buf, 4))
|
||||
|
||||
#define SPINAND_PAGE_READ_FROM_CACHE_X4_OP_3A(addr, ndummy, buf, len) \
|
||||
SPI_MEM_OP(SPI_MEM_OP_CMD(0x6b, 1), \
|
||||
SPI_MEM_OP_ADDR(3, addr, 1), \
|
||||
SPI_MEM_OP_DUMMY(ndummy, 1), \
|
||||
SPI_MEM_OP_DATA_IN(len, buf, 4))
|
||||
|
||||
#define SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP(addr, ndummy, buf, len) \
|
||||
SPI_MEM_OP(SPI_MEM_OP_CMD(0xbb, 1), \
|
||||
SPI_MEM_OP_ADDR(2, addr, 2), \
|
||||
SPI_MEM_OP_DUMMY(ndummy, 2), \
|
||||
SPI_MEM_OP_DATA_IN(len, buf, 2))
|
||||
|
||||
#define SPINAND_PAGE_READ_FROM_CACHE_DUALIO_OP_3A(addr, ndummy, buf, len) \
|
||||
SPI_MEM_OP(SPI_MEM_OP_CMD(0xbb, 1), \
|
||||
SPI_MEM_OP_ADDR(3, addr, 2), \
|
||||
SPI_MEM_OP_DUMMY(ndummy, 2), \
|
||||
SPI_MEM_OP_DATA_IN(len, buf, 2))
|
||||
|
||||
#define SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP(addr, ndummy, buf, len) \
|
||||
SPI_MEM_OP(SPI_MEM_OP_CMD(0xeb, 1), \
|
||||
SPI_MEM_OP_ADDR(2, addr, 4), \
|
||||
SPI_MEM_OP_DUMMY(ndummy, 4), \
|
||||
SPI_MEM_OP_DATA_IN(len, buf, 4))
|
||||
|
||||
#define SPINAND_PAGE_READ_FROM_CACHE_QUADIO_OP_3A(addr, ndummy, buf, len) \
|
||||
SPI_MEM_OP(SPI_MEM_OP_CMD(0xeb, 1), \
|
||||
SPI_MEM_OP_ADDR(3, addr, 4), \
|
||||
SPI_MEM_OP_DUMMY(ndummy, 4), \
|
||||
SPI_MEM_OP_DATA_IN(len, buf, 4))
|
||||
|
||||
#define SPINAND_PROG_EXEC_OP(addr) \
|
||||
SPI_MEM_OP(SPI_MEM_OP_CMD(0x10, 1), \
|
||||
SPI_MEM_OP_ADDR(3, addr, 1), \
|
||||
@@ -197,6 +227,7 @@ struct spinand_manufacturer {
|
||||
extern const struct spinand_manufacturer gigadevice_spinand_manufacturer;
|
||||
extern const struct spinand_manufacturer macronix_spinand_manufacturer;
|
||||
extern const struct spinand_manufacturer micron_spinand_manufacturer;
|
||||
extern const struct spinand_manufacturer paragon_spinand_manufacturer;
|
||||
extern const struct spinand_manufacturer toshiba_spinand_manufacturer;
|
||||
extern const struct spinand_manufacturer winbond_spinand_manufacturer;
|
||||
|
||||
@@ -260,7 +291,7 @@ struct spinand_ecc_info {
|
||||
*/
|
||||
struct spinand_info {
|
||||
const char *model;
|
||||
u8 devid;
|
||||
u16 devid;
|
||||
u32 flags;
|
||||
struct nand_memory_organization memorg;
|
||||
struct nand_ecc_req eccreq;
|
||||
@@ -422,7 +453,7 @@ static inline void spinand_set_of_node(struct spinand_device *spinand,
|
||||
|
||||
int spinand_match_and_init(struct spinand_device *dev,
|
||||
const struct spinand_info *table,
|
||||
unsigned int table_size, u8 devid);
|
||||
unsigned int table_size, u16 devid);
|
||||
|
||||
int spinand_upd_cfg(struct spinand_device *spinand, u8 mask, u8 val);
|
||||
int spinand_select_target(struct spinand_device *spinand, unsigned int target);
|
||||
|
Reference in New Issue
Block a user