mtd: nand: support GPMI NAND driver for i.MX8

enable the GPMI NAND driver for i.MX8, i.MX8 use similar controller as
i.MX8M

- register definition for i.mx8
- DMA structure must be 32bit address

Signed-off-by: Peng Fan <peng.fan@nxp.com>
This commit is contained in:
Peng Fan 2020-05-04 22:09:00 +08:00 committed by Stefano Babic
parent f290fe0a42
commit 39320e7256
8 changed files with 43 additions and 30 deletions

View File

@ -7,6 +7,7 @@
* *
* Based on code from LTIB: * Based on code from LTIB:
* Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved. * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
* Copyright 2020 NXP
*/ */
#ifndef __DMA_H__ #ifndef __DMA_H__
@ -53,7 +54,7 @@ enum {
MXS_DMA_CHANNEL_AHB_APBH_RESERVED1, MXS_DMA_CHANNEL_AHB_APBH_RESERVED1,
MXS_MAX_DMA_CHANNELS, MXS_MAX_DMA_CHANNELS,
}; };
#elif (defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8M)) #else
enum { enum {
MXS_DMA_CHANNEL_AHB_APBH_GPMI0 = 0, MXS_DMA_CHANNEL_AHB_APBH_GPMI0 = 0,
MXS_DMA_CHANNEL_AHB_APBH_GPMI1, MXS_DMA_CHANNEL_AHB_APBH_GPMI1,
@ -95,13 +96,13 @@ enum {
#define MXS_DMA_DESC_BYTES_OFFSET 16 #define MXS_DMA_DESC_BYTES_OFFSET 16
struct mxs_dma_cmd { struct mxs_dma_cmd {
unsigned long next; u32 next;
unsigned long data; u32 data;
union { union {
dma_addr_t address; u32 address;
unsigned long alternate; u32 alternate;
}; };
unsigned long pio_words[DMA_PIO_WORDS]; u32 pio_words[DMA_PIO_WORDS];
}; };
/* /*
@ -117,7 +118,7 @@ struct mxs_dma_cmd {
struct mxs_dma_desc { struct mxs_dma_desc {
struct mxs_dma_cmd cmd; struct mxs_dma_cmd cmd;
unsigned int flags; unsigned int flags;
dma_addr_t address; u32 address;
void *buffer; void *buffer;
struct list_head node; struct list_head node;
} __aligned(MXS_DMA_ALIGNMENT); } __aligned(MXS_DMA_ALIGNMENT);

View File

@ -7,6 +7,7 @@
* *
* Based on code from LTIB: * Based on code from LTIB:
* Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved. * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved.
* Copyright 2020 NXP
*/ */
#ifndef __REGS_APBH_H__ #ifndef __REGS_APBH_H__
@ -95,7 +96,7 @@ struct mxs_apbh_regs {
mxs_reg_32(hw_apbh_version) mxs_reg_32(hw_apbh_version)
}; };
#elif (defined(CONFIG_MX28) || defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8M)) #else
struct mxs_apbh_regs { struct mxs_apbh_regs {
mxs_reg_32(hw_apbh_ctrl0) mxs_reg_32(hw_apbh_ctrl0)
mxs_reg_32(hw_apbh_ctrl1) mxs_reg_32(hw_apbh_ctrl1)
@ -274,7 +275,7 @@ struct mxs_apbh_regs {
#define APBH_CTRL0_CLKGATE_CHANNEL_NAND7 0x0800 #define APBH_CTRL0_CLKGATE_CHANNEL_NAND7 0x0800
#define APBH_CTRL0_CLKGATE_CHANNEL_HSADC 0x1000 #define APBH_CTRL0_CLKGATE_CHANNEL_HSADC 0x1000
#define APBH_CTRL0_CLKGATE_CHANNEL_LCDIF 0x2000 #define APBH_CTRL0_CLKGATE_CHANNEL_LCDIF 0x2000
#elif (defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8M)) #elif (defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8) || defined(CONFIG_IMX8M))
#define APBH_CTRL0_CLKGATE_CHANNEL_OFFSET 0 #define APBH_CTRL0_CLKGATE_CHANNEL_OFFSET 0
#define APBH_CTRL0_CLKGATE_CHANNEL_NAND0 0x0001 #define APBH_CTRL0_CLKGATE_CHANNEL_NAND0 0x0001
#define APBH_CTRL0_CLKGATE_CHANNEL_NAND1 0x0002 #define APBH_CTRL0_CLKGATE_CHANNEL_NAND1 0x0002
@ -357,7 +358,6 @@ struct mxs_apbh_regs {
#if defined(CONFIG_MX28) #if defined(CONFIG_MX28)
#define APBH_CHANNEL_CTRL_RESET_CHANNEL_MASK (0xffff << 16) #define APBH_CHANNEL_CTRL_RESET_CHANNEL_MASK (0xffff << 16)
#define APBH_CHANNEL_CTRL_RESET_CHANNEL_OFFSET 16
#define APBH_CHANNEL_CTRL_RESET_CHANNEL_SSP0 (0x0001 << 16) #define APBH_CHANNEL_CTRL_RESET_CHANNEL_SSP0 (0x0001 << 16)
#define APBH_CHANNEL_CTRL_RESET_CHANNEL_SSP1 (0x0002 << 16) #define APBH_CHANNEL_CTRL_RESET_CHANNEL_SSP1 (0x0002 << 16)
#define APBH_CHANNEL_CTRL_RESET_CHANNEL_SSP2 (0x0004 << 16) #define APBH_CHANNEL_CTRL_RESET_CHANNEL_SSP2 (0x0004 << 16)
@ -390,9 +390,8 @@ struct mxs_apbh_regs {
#define APBH_CHANNEL_CTRL_FREEZE_CHANNEL_LCDIF 0x2000 #define APBH_CHANNEL_CTRL_FREEZE_CHANNEL_LCDIF 0x2000
#endif #endif
#if (defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8M)) /* Not on i.MX23 */
#define APBH_CHANNEL_CTRL_RESET_CHANNEL_OFFSET 16 #define APBH_CHANNEL_CTRL_RESET_CHANNEL_OFFSET 16
#endif
#if defined(CONFIG_MX23) #if defined(CONFIG_MX23)
#define APBH_DEVSEL_CH7_MASK (0xf << 28) #define APBH_DEVSEL_CH7_MASK (0xf << 28)

View File

@ -7,6 +7,7 @@
* *
* Based on code from LTIB: * Based on code from LTIB:
* Copyright 2008-2010, 2016 Freescale Semiconductor, Inc. All Rights Reserved. * Copyright 2008-2010, 2016 Freescale Semiconductor, Inc. All Rights Reserved.
* Copyright 2020 NXP
* *
*/ */
@ -127,7 +128,7 @@ struct mxs_bch_regs {
#define BCH_FLASHLAYOUT0_NBLOCKS_OFFSET 24 #define BCH_FLASHLAYOUT0_NBLOCKS_OFFSET 24
#define BCH_FLASHLAYOUT0_META_SIZE_MASK (0xff << 16) #define BCH_FLASHLAYOUT0_META_SIZE_MASK (0xff << 16)
#define BCH_FLASHLAYOUT0_META_SIZE_OFFSET 16 #define BCH_FLASHLAYOUT0_META_SIZE_OFFSET 16
#if (defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8M)) #if (defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8) || defined(CONFIG_IMX8M))
#define BCH_FLASHLAYOUT0_ECC0_MASK (0x1f << 11) #define BCH_FLASHLAYOUT0_ECC0_MASK (0x1f << 11)
#define BCH_FLASHLAYOUT0_ECC0_OFFSET 11 #define BCH_FLASHLAYOUT0_ECC0_OFFSET 11
#else #else
@ -158,7 +159,7 @@ struct mxs_bch_regs {
#define BCH_FLASHLAYOUT1_PAGE_SIZE_MASK (0xffff << 16) #define BCH_FLASHLAYOUT1_PAGE_SIZE_MASK (0xffff << 16)
#define BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET 16 #define BCH_FLASHLAYOUT1_PAGE_SIZE_OFFSET 16
#if (defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8M)) #if (defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8) || defined(CONFIG_IMX8M))
#define BCH_FLASHLAYOUT1_ECCN_MASK (0x1f << 11) #define BCH_FLASHLAYOUT1_ECCN_MASK (0x1f << 11)
#define BCH_FLASHLAYOUT1_ECCN_OFFSET 11 #define BCH_FLASHLAYOUT1_ECCN_OFFSET 11
#else #else

View File

@ -44,7 +44,7 @@ config TI_EDMA3
config APBH_DMA config APBH_DMA
bool "Support APBH DMA" bool "Support APBH DMA"
depends on MX23 || MX28 || MX6 || MX7 || IMX8M depends on MX23 || MX28 || MX6 || MX7 || IMX8 || IMX8M
help help
Enable APBH DMA driver. Enable APBH DMA driver.

View File

@ -7,6 +7,8 @@
* *
* Based on code from LTIB: * Based on code from LTIB:
* Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved.
* Copyright 2017 NXP
*
*/ */
#include <cpu_func.h> #include <cpu_func.h>
@ -88,7 +90,7 @@ void mxs_dma_flush_desc(struct mxs_dma_desc *desc)
uint32_t addr; uint32_t addr;
uint32_t size; uint32_t size;
addr = (uint32_t)desc; addr = (uintptr_t)desc;
size = roundup(sizeof(struct mxs_dma_desc), MXS_DMA_ALIGNMENT); size = roundup(sizeof(struct mxs_dma_desc), MXS_DMA_ALIGNMENT);
flush_dcache_range(addr, addr + size); flush_dcache_range(addr, addr + size);
@ -215,16 +217,17 @@ static int mxs_dma_reset(int channel)
#if defined(CONFIG_MX23) #if defined(CONFIG_MX23)
uint32_t setreg = (uint32_t)(&apbh_regs->hw_apbh_ctrl0_set); uint32_t setreg = (uint32_t)(&apbh_regs->hw_apbh_ctrl0_set);
uint32_t offset = APBH_CTRL0_RESET_CHANNEL_OFFSET; uint32_t offset = APBH_CTRL0_RESET_CHANNEL_OFFSET;
#elif (defined(CONFIG_MX28) || defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8M)) #elif defined(CONFIG_MX28) || defined(CONFIG_MX6) || defined(CONFIG_MX7) || \
uint32_t setreg = (uint32_t)(&apbh_regs->hw_apbh_channel_ctrl_set); defined(CONFIG_IMX8) || defined(CONFIG_IMX8M)
uint32_t offset = APBH_CHANNEL_CTRL_RESET_CHANNEL_OFFSET; u32 setreg = (uintptr_t)(&apbh_regs->hw_apbh_channel_ctrl_set);
u32 offset = APBH_CHANNEL_CTRL_RESET_CHANNEL_OFFSET;
#endif #endif
ret = mxs_dma_validate_chan(channel); ret = mxs_dma_validate_chan(channel);
if (ret) if (ret)
return ret; return ret;
writel(1 << (channel + offset), setreg); writel(1 << (channel + offset), (uintptr_t)setreg);
return 0; return 0;
} }

View File

@ -259,12 +259,12 @@ config NAND_MXC
config NAND_MXS config NAND_MXS
bool "MXS NAND support" bool "MXS NAND support"
depends on MX23 || MX28 || MX6 || MX7 || IMX8M depends on MX23 || MX28 || MX6 || MX7 || IMX8 || IMX8M
select SYS_NAND_SELF_INIT select SYS_NAND_SELF_INIT
imply CMD_NAND imply CMD_NAND
select APBH_DMA select APBH_DMA
select APBH_DMA_BURST if ARCH_MX6 || ARCH_MX7 || ARCH_IMX8M select APBH_DMA_BURST if ARCH_MX6 || ARCH_MX7 || ARCH_IMX8 || ARCH_IMX8M
select APBH_DMA_BURST8 if ARCH_MX6 || ARCH_MX7 || ARCH_IMX8M select APBH_DMA_BURST8 if ARCH_MX6 || ARCH_MX7 || ARCH_IMX8 || ARCH_IMX8M
help help
This enables NAND driver for the NAND flash controller on the This enables NAND driver for the NAND flash controller on the
MXS processors. MXS processors.

View File

@ -31,7 +31,8 @@
#define MXS_NAND_DMA_DESCRIPTOR_COUNT 4 #define MXS_NAND_DMA_DESCRIPTOR_COUNT 4
#if (defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8M)) #if defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8) || \
defined(CONFIG_IMX8M)
#define MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT 2 #define MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT 2
#else #else
#define MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT 0 #define MXS_NAND_CHUNK_DATA_CHUNK_SIZE_SHIFT 0
@ -55,21 +56,21 @@ struct nand_ecclayout fake_ecc_layout;
#if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF) #if !CONFIG_IS_ENABLED(SYS_DCACHE_OFF)
static void mxs_nand_flush_data_buf(struct mxs_nand_info *info) static void mxs_nand_flush_data_buf(struct mxs_nand_info *info)
{ {
uint32_t addr = (uint32_t)info->data_buf; uint32_t addr = (uintptr_t)info->data_buf;
flush_dcache_range(addr, addr + info->data_buf_size); flush_dcache_range(addr, addr + info->data_buf_size);
} }
static void mxs_nand_inval_data_buf(struct mxs_nand_info *info) static void mxs_nand_inval_data_buf(struct mxs_nand_info *info)
{ {
uint32_t addr = (uint32_t)info->data_buf; uint32_t addr = (uintptr_t)info->data_buf;
invalidate_dcache_range(addr, addr + info->data_buf_size); invalidate_dcache_range(addr, addr + info->data_buf_size);
} }
static void mxs_nand_flush_cmd_buf(struct mxs_nand_info *info) static void mxs_nand_flush_cmd_buf(struct mxs_nand_info *info)
{ {
uint32_t addr = (uint32_t)info->cmd_buf; uint32_t addr = (uintptr_t)info->cmd_buf;
flush_dcache_range(addr, addr + MXS_NAND_COMMAND_BUFFER_SIZE); flush_dcache_range(addr, addr + MXS_NAND_COMMAND_BUFFER_SIZE);
} }
@ -773,7 +774,7 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand,
if (status[i] == 0xff) { if (status[i] == 0xff) {
if (is_mx6dqp() || is_mx7() || if (is_mx6dqp() || is_mx7() ||
is_mx6ul() || is_imx8m()) is_mx6ul() || is_imx8() || is_imx8m())
if (readl(&bch_regs->hw_bch_debug1)) if (readl(&bch_regs->hw_bch_debug1))
flag = 1; flag = 1;
continue; continue;
@ -1172,7 +1173,7 @@ int mxs_nand_setup_ecc(struct mtd_info *mtd)
/* Set erase threshold to ecc strength for mx6ul, mx6qp and mx7 */ /* Set erase threshold to ecc strength for mx6ul, mx6qp and mx7 */
if (is_mx6dqp() || is_mx7() || if (is_mx6dqp() || is_mx7() ||
is_mx6ul() || is_imx8m()) is_mx6ul() || is_imx8() || is_imx8m())
writel(BCH_MODE_ERASE_THRESHOLD(geo->ecc_strength), writel(BCH_MODE_ERASE_THRESHOLD(geo->ecc_strength),
&bch_regs->hw_bch_mode); &bch_regs->hw_bch_mode);
@ -1311,7 +1312,7 @@ int mxs_nand_init_spl(struct nand_chip *nand)
nand_info->gpmi_regs = (struct mxs_gpmi_regs *)MXS_GPMI_BASE; nand_info->gpmi_regs = (struct mxs_gpmi_regs *)MXS_GPMI_BASE;
nand_info->bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE; nand_info->bch_regs = (struct mxs_bch_regs *)MXS_BCH_BASE;
if (is_mx6sx() || is_mx7() || is_imx8m()) if (is_mx6sx() || is_mx7() || is_imx8() || is_imx8m())
nand_info->max_ecc_strength_supported = 62; nand_info->max_ecc_strength_supported = 62;
else else
nand_info->max_ecc_strength_supported = 40; nand_info->max_ecc_strength_supported = 40;

View File

@ -33,6 +33,10 @@ static const struct mxs_nand_dt_data mxs_nand_imx7d_data = {
.max_ecc_strength_supported = 62, .max_ecc_strength_supported = 62,
}; };
static const struct mxs_nand_dt_data mxs_nand_imx8qxp_data = {
.max_ecc_strength_supported = 62,
};
static const struct udevice_id mxs_nand_dt_ids[] = { static const struct udevice_id mxs_nand_dt_ids[] = {
{ {
.compatible = "fsl,imx6q-gpmi-nand", .compatible = "fsl,imx6q-gpmi-nand",
@ -50,6 +54,10 @@ static const struct udevice_id mxs_nand_dt_ids[] = {
.compatible = "fsl,imx7d-gpmi-nand", .compatible = "fsl,imx7d-gpmi-nand",
.data = (unsigned long)&mxs_nand_imx7d_data, .data = (unsigned long)&mxs_nand_imx7d_data,
}, },
{
.compatible = "fsl,imx8qxp-gpmi-nand",
.data = (unsigned long)&mxs_nand_imx8qxp_data,
},
{ /* sentinel */ } { /* sentinel */ }
}; };