nand: brcm: add BCM6368 support
This adds support for BCM6368, BCM6328, BCM6362 and BCM63268 SoCs. Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com> Reviewed-by: Daniel Schwierzeck <daniel.schwierzeck@gmail.com>
This commit is contained in:
		
							parent
							
								
									22247c63ac
								
							
						
					
					
						commit
						a9f80cf9ad
					
				|  | @ -72,6 +72,12 @@ config NAND_BRCMNAND | ||||||
| 	  Enable the driver for NAND flash on platforms using a Broadcom NAND | 	  Enable the driver for NAND flash on platforms using a Broadcom NAND | ||||||
| 	  controller. | 	  controller. | ||||||
| 
 | 
 | ||||||
|  | config NAND_BRCMNAND_6368 | ||||||
|  | 	bool "Support Broadcom NAND controller on bcm6368" | ||||||
|  | 	depends on NAND_BRCMNAND && ARCH_BMIPS | ||||||
|  | 	help | ||||||
|  | 	  Enable support for broadcom nand driver on bcm6368. | ||||||
|  | 
 | ||||||
| config NAND_BRCMNAND_6838 | config NAND_BRCMNAND_6838 | ||||||
|        bool "Support Broadcom NAND controller on bcm6838" |        bool "Support Broadcom NAND controller on bcm6838" | ||||||
|        depends on NAND_BRCMNAND && ARCH_BMIPS && SOC_BMIPS_BCM6838 |        depends on NAND_BRCMNAND && ARCH_BMIPS && SOC_BMIPS_BCM6838 | ||||||
|  |  | ||||||
|  | @ -1,5 +1,6 @@ | ||||||
| # SPDX-License-Identifier: GPL-2.0+
 | # SPDX-License-Identifier: GPL-2.0+
 | ||||||
| 
 | 
 | ||||||
|  | obj-$(CONFIG_NAND_BRCMNAND_6368) += bcm6368_nand.o | ||||||
| obj-$(CONFIG_NAND_BRCMNAND_63158) += bcm63158_nand.o | obj-$(CONFIG_NAND_BRCMNAND_63158) += bcm63158_nand.o | ||||||
| obj-$(CONFIG_NAND_BRCMNAND_6838) += bcm6838_nand.o | obj-$(CONFIG_NAND_BRCMNAND_6838) += bcm6838_nand.o | ||||||
| obj-$(CONFIG_NAND_BRCMNAND_6858) += bcm6858_nand.o | obj-$(CONFIG_NAND_BRCMNAND_6858) += bcm6858_nand.o | ||||||
|  |  | ||||||
|  | @ -0,0 +1,117 @@ | ||||||
|  | // SPDX-License-Identifier: GPL-2.0+
 | ||||||
|  | 
 | ||||||
|  | #include <common.h> | ||||||
|  | #include <asm/io.h> | ||||||
|  | #include <memalign.h> | ||||||
|  | #include <nand.h> | ||||||
|  | #include <linux/errno.h> | ||||||
|  | #include <linux/io.h> | ||||||
|  | #include <linux/ioport.h> | ||||||
|  | #include <dm.h> | ||||||
|  | 
 | ||||||
|  | #include "brcmnand.h" | ||||||
|  | 
 | ||||||
|  | struct bcm6368_nand_soc { | ||||||
|  | 	struct brcmnand_soc soc; | ||||||
|  | 	void __iomem *base; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | #define soc_to_priv(_soc) container_of(_soc, struct bcm6368_nand_soc, soc) | ||||||
|  | 
 | ||||||
|  | #define BCM6368_NAND_INT		0x00 | ||||||
|  | #define  BCM6368_NAND_STATUS_SHIFT	0 | ||||||
|  | #define  BCM6368_NAND_STATUS_MASK	(0xfff << BCM6368_NAND_STATUS_SHIFT) | ||||||
|  | #define  BCM6368_NAND_ENABLE_SHIFT	16 | ||||||
|  | #define  BCM6368_NAND_ENABLE_MASK	(0xffff << BCM6368_NAND_ENABLE_SHIFT) | ||||||
|  | 
 | ||||||
|  | enum { | ||||||
|  | 	BCM6368_NP_READ		= BIT(0), | ||||||
|  | 	BCM6368_BLOCK_ERASE	= BIT(1), | ||||||
|  | 	BCM6368_COPY_BACK	= BIT(2), | ||||||
|  | 	BCM6368_PAGE_PGM	= BIT(3), | ||||||
|  | 	BCM6368_CTRL_READY	= BIT(4), | ||||||
|  | 	BCM6368_DEV_RBPIN	= BIT(5), | ||||||
|  | 	BCM6368_ECC_ERR_UNC	= BIT(6), | ||||||
|  | 	BCM6368_ECC_ERR_CORR	= BIT(7), | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | static bool bcm6368_nand_intc_ack(struct brcmnand_soc *soc) | ||||||
|  | { | ||||||
|  | 	struct bcm6368_nand_soc *priv = soc_to_priv(soc); | ||||||
|  | 	void __iomem *mmio = priv->base + BCM6368_NAND_INT; | ||||||
|  | 	u32 val = brcmnand_readl(mmio); | ||||||
|  | 
 | ||||||
|  | 	if (val & (BCM6368_CTRL_READY << BCM6368_NAND_STATUS_SHIFT)) { | ||||||
|  | 		/* Ack interrupt */ | ||||||
|  | 		val &= ~BCM6368_NAND_STATUS_MASK; | ||||||
|  | 		val |= BCM6368_CTRL_READY << BCM6368_NAND_STATUS_SHIFT; | ||||||
|  | 		brcmnand_writel(val, mmio); | ||||||
|  | 		return true; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return false; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static void bcm6368_nand_intc_set(struct brcmnand_soc *soc, bool en) | ||||||
|  | { | ||||||
|  | 	struct bcm6368_nand_soc *priv = soc_to_priv(soc); | ||||||
|  | 	void __iomem *mmio = priv->base + BCM6368_NAND_INT; | ||||||
|  | 	u32 val = brcmnand_readl(mmio); | ||||||
|  | 
 | ||||||
|  | 	/* Don't ack any interrupts */ | ||||||
|  | 	val &= ~BCM6368_NAND_STATUS_MASK; | ||||||
|  | 
 | ||||||
|  | 	if (en) | ||||||
|  | 		val |= BCM6368_CTRL_READY << BCM6368_NAND_ENABLE_SHIFT; | ||||||
|  | 	else | ||||||
|  | 		val &= ~(BCM6368_CTRL_READY << BCM6368_NAND_ENABLE_SHIFT); | ||||||
|  | 
 | ||||||
|  | 	brcmnand_writel(val, mmio); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static int bcm6368_nand_probe(struct udevice *dev) | ||||||
|  | { | ||||||
|  | 	struct bcm6368_nand_soc *priv = dev_get_priv(dev); | ||||||
|  | 	struct brcmnand_soc *soc = &priv->soc; | ||||||
|  | 
 | ||||||
|  | 	priv->base = dev_remap_addr_name(dev, "nand-int-base"); | ||||||
|  | 	if (!priv->base) | ||||||
|  | 		return -EINVAL; | ||||||
|  | 
 | ||||||
|  | 	soc->ctlrdy_ack = bcm6368_nand_intc_ack; | ||||||
|  | 	soc->ctlrdy_set_enabled = bcm6368_nand_intc_set; | ||||||
|  | 
 | ||||||
|  | 	/* Disable and ack all interrupts  */ | ||||||
|  | 	brcmnand_writel(0, priv->base + BCM6368_NAND_INT); | ||||||
|  | 	brcmnand_writel(BCM6368_NAND_STATUS_MASK, | ||||||
|  | 			priv->base + BCM6368_NAND_INT); | ||||||
|  | 
 | ||||||
|  | 	return brcmnand_probe(dev, soc); | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | static const struct udevice_id bcm6368_nand_dt_ids[] = { | ||||||
|  | 	{ | ||||||
|  | 		.compatible = "brcm,nand-bcm6368", | ||||||
|  | 	}, | ||||||
|  | 	{ /* sentinel */ } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | U_BOOT_DRIVER(bcm6368_nand) = { | ||||||
|  | 	.name = "bcm6368-nand", | ||||||
|  | 	.id = UCLASS_MTD, | ||||||
|  | 	.of_match = bcm6368_nand_dt_ids, | ||||||
|  | 	.probe = bcm6368_nand_probe, | ||||||
|  | 	.priv_auto_alloc_size = sizeof(struct bcm6368_nand_soc), | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | void board_nand_init(void) | ||||||
|  | { | ||||||
|  | 	struct udevice *dev; | ||||||
|  | 	int ret; | ||||||
|  | 
 | ||||||
|  | 	ret = uclass_get_device_by_driver(UCLASS_MTD, | ||||||
|  | 					  DM_GET_DRIVER(bcm6368_nand), &dev); | ||||||
|  | 	if (ret && ret != -ENODEV) | ||||||
|  | 		pr_err("Failed to initialize %s. (error %d)\n", dev->name, | ||||||
|  | 		       ret); | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue