mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-09-27 23:20:26 +09:00
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:
parent
f290fe0a42
commit
39320e7256
@ -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);
|
||||||
|
@ -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)
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
|
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
|
@ -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;
|
||||||
|
@ -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 */ }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user