From: Ray Jui <rjui@xxxxxxxxxxxx> Signed-off-by: Ray Jui <rjui@xxxxxxxxxxxx> Signed-off-by: Brian Norris <computersforpeace@xxxxxxxxx> --- drivers/mtd/nand/brcmstb_nand_soc.c | 110 ++++++++++++++++++++++++++++++++++++ 1 file changed, 110 insertions(+) diff --git a/drivers/mtd/nand/brcmstb_nand_soc.c b/drivers/mtd/nand/brcmstb_nand_soc.c index c878334edb1a..5fb851c655f2 100644 --- a/drivers/mtd/nand/brcmstb_nand_soc.c +++ b/drivers/mtd/nand/brcmstb_nand_soc.c @@ -93,11 +93,121 @@ static const struct brcmnand_soc_ofdata bcm63138_nand_soc = { .ctlrdy_set_enabled = bcm63138_nand_intc_set, }; +struct iproc_nand_soc_priv { + void __iomem *idm_base; + void __iomem *ext_base; + spinlock_t idm_lock; +}; + +#define IPROC_NAND_CTLR_READY_OFFSET 0x10 +#define IPROC_NAND_CTLR_READY BIT(0) + +#define IPROC_NAND_IO_CTRL_OFFSET 0x00 +#define IPROC_NAND_APB_LE_MODE BIT(24) +#define IPROC_NAND_INT_CTRL_READ_ENABLE BIT(6) + +static bool iproc_nand_intc_ack(struct brcmnand_soc *soc) +{ + struct iproc_nand_soc_priv *priv = soc->priv; + void __iomem *mmio = priv->ext_base + IPROC_NAND_CTLR_READY_OFFSET; + u32 val = __raw_readl(mmio); + + if (val & IPROC_NAND_CTLR_READY) { + __raw_writel(IPROC_NAND_CTLR_READY, mmio); + return true; + } + + return false; +} + +static void iproc_nand_intc_set(struct brcmnand_soc *soc, bool en) +{ + struct iproc_nand_soc_priv *priv = soc->priv; + void __iomem *mmio = priv->idm_base + IPROC_NAND_IO_CTRL_OFFSET; + u32 val; + unsigned long flags; + + spin_lock_irqsave(&priv->idm_lock, flags); + + val = __raw_readl(mmio); + + if (en) + val |= IPROC_NAND_INT_CTRL_READ_ENABLE; + else + val &= ~IPROC_NAND_INT_CTRL_READ_ENABLE; + + __raw_writel(val, mmio); + + spin_unlock_irqrestore(&priv->idm_lock, flags); +} + +static int iproc_nand_soc_init(struct brcmnand_soc *soc) +{ + struct iproc_nand_soc_priv *priv; + + priv = devm_kzalloc(soc->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + spin_lock_init(&priv->idm_lock); + + priv->idm_base = of_io_request_and_map(soc->dn, 0, DRV_NAME); + if (IS_ERR(priv->idm_base)) + return PTR_ERR(priv->idm_base); + + priv->ext_base = of_io_request_and_map(soc->dn, 1, DRV_NAME); + if (IS_ERR(priv->ext_base)) { + struct resource res; + + of_address_to_resource(soc->dn, 0, &res); + release_mem_region(res.start, resource_size(&res)); + iounmap(priv->idm_base); + return PTR_ERR(priv->ext_base); + } + + soc->priv = priv; + iproc_nand_intc_ack(soc); + + return 0; +} + +static void iproc_nand_apb_access(struct brcmnand_soc *soc, bool prepare) +{ + struct iproc_nand_soc_priv *priv = soc->priv; + void __iomem *mmio = priv->idm_base + IPROC_NAND_IO_CTRL_OFFSET; + u32 val; + unsigned long flags; + + spin_lock_irqsave(&priv->idm_lock, flags); + + val = __raw_readl(mmio); + + if (prepare) + val |= IPROC_NAND_APB_LE_MODE; + else + val &= ~IPROC_NAND_APB_LE_MODE; + + __raw_writel(val, mmio); + + spin_unlock_irqrestore(&priv->idm_lock, flags); +} + +static const struct brcmnand_soc_ofdata iproc_nand_soc = { + .init = iproc_nand_soc_init, + .ctlrdy_ack = iproc_nand_intc_ack, + .ctlrdy_set_enabled = iproc_nand_intc_set, + .prepare_data_bus = iproc_nand_apb_access, +}; + static const struct of_device_id brcmnand_soc_ofmatch[] = { { .compatible = "brcm,nand-soc-bcm63138", .data = &bcm63138_nand_soc, }, + { + .compatible = "brcm,nand-soc-iproc", + .data = &iproc_nand_soc, + }, {}, }; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html