From: Peng Fan Date: Mon, 4 May 2020 14:09:00 +0000 (+0800) Subject: mtd: nand: support GPMI NAND driver for i.MX8 X-Git-Url: http://git.dujemihanovic.xyz/?a=commitdiff_plain;h=39320e7256412ed4b6eee9fc09f7d30f0e4ddee4;p=u-boot.git 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 --- diff --git a/arch/arm/include/asm/mach-imx/dma.h b/arch/arm/include/asm/mach-imx/dma.h index cb73aaeeb5..247a91afb0 100644 --- a/arch/arm/include/asm/mach-imx/dma.h +++ b/arch/arm/include/asm/mach-imx/dma.h @@ -7,6 +7,7 @@ * * Based on code from LTIB: * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2020 NXP */ #ifndef __DMA_H__ @@ -53,7 +54,7 @@ enum { MXS_DMA_CHANNEL_AHB_APBH_RESERVED1, MXS_MAX_DMA_CHANNELS, }; -#elif (defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8M)) +#else enum { MXS_DMA_CHANNEL_AHB_APBH_GPMI0 = 0, MXS_DMA_CHANNEL_AHB_APBH_GPMI1, @@ -95,13 +96,13 @@ enum { #define MXS_DMA_DESC_BYTES_OFFSET 16 struct mxs_dma_cmd { - unsigned long next; - unsigned long data; + u32 next; + u32 data; union { - dma_addr_t address; - unsigned long alternate; + u32 address; + 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_cmd cmd; unsigned int flags; - dma_addr_t address; + u32 address; void *buffer; struct list_head node; } __aligned(MXS_DMA_ALIGNMENT); diff --git a/arch/arm/include/asm/mach-imx/regs-apbh.h b/arch/arm/include/asm/mach-imx/regs-apbh.h index d68953efd2..94c330c7f9 100644 --- a/arch/arm/include/asm/mach-imx/regs-apbh.h +++ b/arch/arm/include/asm/mach-imx/regs-apbh.h @@ -7,6 +7,7 @@ * * Based on code from LTIB: * Copyright 2008-2010 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2020 NXP */ #ifndef __REGS_APBH_H__ @@ -95,7 +96,7 @@ struct mxs_apbh_regs { mxs_reg_32(hw_apbh_version) }; -#elif (defined(CONFIG_MX28) || defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8M)) +#else struct mxs_apbh_regs { mxs_reg_32(hw_apbh_ctrl0) 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_HSADC 0x1000 #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_NAND0 0x0001 #define APBH_CTRL0_CLKGATE_CHANNEL_NAND1 0x0002 @@ -357,7 +358,6 @@ struct mxs_apbh_regs { #if defined(CONFIG_MX28) #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_SSP1 (0x0002 << 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 #endif -#if (defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8M)) +/* Not on i.MX23 */ #define APBH_CHANNEL_CTRL_RESET_CHANNEL_OFFSET 16 -#endif #if defined(CONFIG_MX23) #define APBH_DEVSEL_CH7_MASK (0xf << 28) diff --git a/arch/arm/include/asm/mach-imx/regs-bch.h b/arch/arm/include/asm/mach-imx/regs-bch.h index 664fb9fd4d..5a149002e2 100644 --- a/arch/arm/include/asm/mach-imx/regs-bch.h +++ b/arch/arm/include/asm/mach-imx/regs-bch.h @@ -7,6 +7,7 @@ * * Based on code from LTIB: * 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_META_SIZE_MASK (0xff << 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_OFFSET 11 #else @@ -158,7 +159,7 @@ struct mxs_bch_regs { #define BCH_FLASHLAYOUT1_PAGE_SIZE_MASK (0xffff << 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_OFFSET 11 #else diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 655e79fbaf..1993c1d31d 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -44,7 +44,7 @@ config TI_EDMA3 config APBH_DMA bool "Support APBH DMA" - depends on MX23 || MX28 || MX6 || MX7 || IMX8M + depends on MX23 || MX28 || MX6 || MX7 || IMX8 || IMX8M help Enable APBH DMA driver. diff --git a/drivers/dma/apbh_dma.c b/drivers/dma/apbh_dma.c index 8d17f8f01d..69eb040d32 100644 --- a/drivers/dma/apbh_dma.c +++ b/drivers/dma/apbh_dma.c @@ -7,6 +7,8 @@ * * Based on code from LTIB: * Copyright (C) 2010 Freescale Semiconductor, Inc. All Rights Reserved. + * Copyright 2017 NXP + * */ #include @@ -88,7 +90,7 @@ void mxs_dma_flush_desc(struct mxs_dma_desc *desc) uint32_t addr; uint32_t size; - addr = (uint32_t)desc; + addr = (uintptr_t)desc; size = roundup(sizeof(struct mxs_dma_desc), MXS_DMA_ALIGNMENT); flush_dcache_range(addr, addr + size); @@ -215,16 +217,17 @@ static int mxs_dma_reset(int channel) #if defined(CONFIG_MX23) uint32_t setreg = (uint32_t)(&apbh_regs->hw_apbh_ctrl0_set); uint32_t offset = APBH_CTRL0_RESET_CHANNEL_OFFSET; -#elif (defined(CONFIG_MX28) || defined(CONFIG_MX6) || defined(CONFIG_MX7) || defined(CONFIG_IMX8M)) - uint32_t setreg = (uint32_t)(&apbh_regs->hw_apbh_channel_ctrl_set); - uint32_t offset = APBH_CHANNEL_CTRL_RESET_CHANNEL_OFFSET; +#elif defined(CONFIG_MX28) || defined(CONFIG_MX6) || defined(CONFIG_MX7) || \ + defined(CONFIG_IMX8) || defined(CONFIG_IMX8M) + u32 setreg = (uintptr_t)(&apbh_regs->hw_apbh_channel_ctrl_set); + u32 offset = APBH_CHANNEL_CTRL_RESET_CHANNEL_OFFSET; #endif ret = mxs_dma_validate_chan(channel); if (ret) return ret; - writel(1 << (channel + offset), setreg); + writel(1 << (channel + offset), (uintptr_t)setreg); return 0; } diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig index c46fec3d32..c4d9d31388 100644 --- a/drivers/mtd/nand/raw/Kconfig +++ b/drivers/mtd/nand/raw/Kconfig @@ -259,12 +259,12 @@ config NAND_MXC config NAND_MXS bool "MXS NAND support" - depends on MX23 || MX28 || MX6 || MX7 || IMX8M + depends on MX23 || MX28 || MX6 || MX7 || IMX8 || IMX8M select SYS_NAND_SELF_INIT imply CMD_NAND select APBH_DMA - select APBH_DMA_BURST if ARCH_MX6 || ARCH_MX7 || ARCH_IMX8M - select APBH_DMA_BURST8 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_IMX8 || ARCH_IMX8M help This enables NAND driver for the NAND flash controller on the MXS processors. diff --git a/drivers/mtd/nand/raw/mxs_nand.c b/drivers/mtd/nand/raw/mxs_nand.c index 3bf5ab2d8c..b6e65c616d 100644 --- a/drivers/mtd/nand/raw/mxs_nand.c +++ b/drivers/mtd/nand/raw/mxs_nand.c @@ -31,7 +31,8 @@ #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 #else #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) 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); } 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); } 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); } @@ -773,7 +774,7 @@ static int mxs_nand_ecc_read_page(struct mtd_info *mtd, struct nand_chip *nand, if (status[i] == 0xff) { if (is_mx6dqp() || is_mx7() || - is_mx6ul() || is_imx8m()) + is_mx6ul() || is_imx8() || is_imx8m()) if (readl(&bch_regs->hw_bch_debug1)) flag = 1; 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 */ if (is_mx6dqp() || is_mx7() || - is_mx6ul() || is_imx8m()) + is_mx6ul() || is_imx8() || is_imx8m()) writel(BCH_MODE_ERASE_THRESHOLD(geo->ecc_strength), &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->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; else nand_info->max_ecc_strength_supported = 40; diff --git a/drivers/mtd/nand/raw/mxs_nand_dt.c b/drivers/mtd/nand/raw/mxs_nand_dt.c index bd429e0d62..c4dc0bb1dd 100644 --- a/drivers/mtd/nand/raw/mxs_nand_dt.c +++ b/drivers/mtd/nand/raw/mxs_nand_dt.c @@ -33,6 +33,10 @@ static const struct mxs_nand_dt_data mxs_nand_imx7d_data = { .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[] = { { .compatible = "fsl,imx6q-gpmi-nand", @@ -50,6 +54,10 @@ static const struct udevice_id mxs_nand_dt_ids[] = { .compatible = "fsl,imx7d-gpmi-nand", .data = (unsigned long)&mxs_nand_imx7d_data, }, + { + .compatible = "fsl,imx8qxp-gpmi-nand", + .data = (unsigned long)&mxs_nand_imx8qxp_data, + }, { /* sentinel */ } };