linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 0/9] BCMA support for brcmnand
@ 2022-01-07  0:13 Florian Fainelli
  2022-01-07  0:13 ` [PATCH v2 1/9] mtd: rawnand: brcmnand: Assign soc as early as possible Florian Fainelli
                   ` (8 more replies)
  0 siblings, 9 replies; 12+ messages in thread
From: Florian Fainelli @ 2022-01-07  0:13 UTC (permalink / raw)
  To: linux-mtd
  Cc: Florian Fainelli, Rafał Miłecki, Miquel Raynal,
	Richard Weinberger, Vignesh Raghavendra, Brian Norris,
	Kamal Dasu, Arnd Bergmann, Cai Huoqing, Colin Ian King,
	open list, open list:BROADCOM SPECIFIC AMBA DRIVER (BCMA),
	open list:BROADCOM STB NAND FLASH DRIVER

Hi all,

This patch series adds support for the BRCMNAND controller revision 3.4
embedded in MIPS-based SoCs such as 5357, typically found in the Netgear
WNR3500L v2 and other kinds of Wi-Fi routers. The upstream platform that
uses this controller is under arch/mips/bcm47xx/ and does not use Device
Tree (and probably never will by now). BCMA (Broadcom AMBA) is a special
kind of discoverable memory mapped interface which requires the use of
special accessors to read from/write to the hardware block.

The integration of brcmnand into that SoC is a bit quirky in that every
register offering byte level data about the flash (OOB, device ID, etc.)
requires byte swapping. The command shift should also have been 24, but
is in fact 0, took me a while to understand why no reads were actually
working because of that.

This has been tested with Linux 5.10.82 and Linus' master with OpenWrt
and confirmed that the squashfs + jffs2 overlay that OpenWrt creates is
entirely functional and that written data is made persistent.

Changes in v2:

- re-ordered the patch such that the soc variable is initialized as
  early as possible
- corrected bug in the conversion of brcmnand_init_cs() which
  incorrectly used the wrong device_node variable (parent instead of
  child)
- took Andy's feedback to make the test for a valid interrupt to be > 0
  while calling platform_get_irq_optional()
- utilized static branch (disabled by default) and conditional
  compilation and confirm with disassembly that the generated code is
  as efficient as before if not enabling the BCMA shim and as efficient
  as possible if enabling BCMA shim
- updated BCMA shim driver descriptor, author and added helper function
  to encapsulate the container_of usage
- added comment to explain why a slightly different platform device name
  is used for the 5357-style NAND controller

Florian Fainelli (9):
  mtd: rawnand: brcmnand: Assign soc as early as possible
  mtd: rawnand: brcmnand: Allow SoC to provide I/O operations
  mtd: rawnand: brcmnand: Avoid pdev in brcmnand_init_cs()
  mtd: rawnand: brcmnand: Move OF operations out of brcmnand_init_cs()
  mtd: rawnand: brcmnand: Allow working without interrupts
  mtd: rawnand: brcmnand: Add platform data structure for BCMA
  mtd: rawnand: brcmnand: Allow platform data instantation
  mtd: rawnand: brcmnand: BCMA controller uses command shift of 0
  mtd: rawnand: brcmnand: Add BCMA shim

 MAINTAINERS                                 |   1 +
 drivers/bcma/driver_chipcommon_nflash.c     |  20 ++-
 drivers/mtd/nand/raw/Kconfig                |  13 ++
 drivers/mtd/nand/raw/brcmnand/Makefile      |   2 +
 drivers/mtd/nand/raw/brcmnand/bcma_nand.c   | 132 ++++++++++++++++
 drivers/mtd/nand/raw/brcmnand/brcmnand.c    | 160 +++++++++++++-------
 drivers/mtd/nand/raw/brcmnand/brcmnand.h    |  29 ++++
 include/linux/bcma/bcma_driver_chipcommon.h |   5 +
 include/linux/platform_data/brcmnand.h      |  12 ++
 9 files changed, 321 insertions(+), 53 deletions(-)
 create mode 100644 drivers/mtd/nand/raw/brcmnand/bcma_nand.c
 create mode 100644 include/linux/platform_data/brcmnand.h

-- 
2.25.1


^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v2 1/9] mtd: rawnand: brcmnand: Assign soc as early as possible
  2022-01-07  0:13 [PATCH v2 0/9] BCMA support for brcmnand Florian Fainelli
@ 2022-01-07  0:13 ` Florian Fainelli
  2022-01-07  0:13 ` [PATCH v2 2/9] mtd: rawnand: brcmnand: Allow SoC to provide I/O operations Florian Fainelli
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Florian Fainelli @ 2022-01-07  0:13 UTC (permalink / raw)
  To: linux-mtd
  Cc: Florian Fainelli, Rafał Miłecki, Miquel Raynal,
	Richard Weinberger, Vignesh Raghavendra, Brian Norris,
	Kamal Dasu, Arnd Bergmann, Cai Huoqing, Colin Ian King,
	open list, open list:BROADCOM SPECIFIC AMBA DRIVER (BCMA),
	open list:BROADCOM STB NAND FLASH DRIVER

In order to key off the brcmnand_probe() code in subsequent changes
depending upon ctlr->soc, assign that variable as early as possible,
instead of much later when we have checked that it is non-NULL.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/mtd/nand/raw/brcmnand/brcmnand.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index f75929783b94..63080ae3aef1 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -2998,6 +2998,7 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc)
 
 	dev_set_drvdata(dev, ctrl);
 	ctrl->dev = dev;
+	ctrl->soc = soc;
 
 	init_completion(&ctrl->done);
 	init_completion(&ctrl->dma_done);
@@ -3138,8 +3139,6 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc)
 	 * interesting ways
 	 */
 	if (soc) {
-		ctrl->soc = soc;
-
 		ret = devm_request_irq(dev, ctrl->irq, brcmnand_irq, 0,
 				       DRV_NAME, ctrl);
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 2/9] mtd: rawnand: brcmnand: Allow SoC to provide I/O operations
  2022-01-07  0:13 [PATCH v2 0/9] BCMA support for brcmnand Florian Fainelli
  2022-01-07  0:13 ` [PATCH v2 1/9] mtd: rawnand: brcmnand: Assign soc as early as possible Florian Fainelli
@ 2022-01-07  0:13 ` Florian Fainelli
  2022-01-07  3:10   ` Florian Fainelli
  2022-01-07  0:13 ` [PATCH v2 3/9] mtd: rawnand: brcmnand: Avoid pdev in brcmnand_init_cs() Florian Fainelli
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 12+ messages in thread
From: Florian Fainelli @ 2022-01-07  0:13 UTC (permalink / raw)
  To: linux-mtd
  Cc: Florian Fainelli, Rafał Miłecki, Miquel Raynal,
	Richard Weinberger, Vignesh Raghavendra, Brian Norris,
	Kamal Dasu, Arnd Bergmann, Cai Huoqing, Colin Ian King,
	open list, open list:BROADCOM SPECIFIC AMBA DRIVER (BCMA),
	open list:BROADCOM STB NAND FLASH DRIVER

Allow a brcmnand_soc instance to provide a custom set of I/O operations
which we will require when using this driver on a BCMA bus which is not
directly memory mapped I/O. Update the nand_{read,write}_reg accordingly
to use the SoC operations if provided.

To minimize the penalty on other SoCs which do support standard MMIO
accesses, we use a static key which is disabled by default and gets
enabled if a soc implementation does provide I/O operations.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/mtd/nand/raw/brcmnand/brcmnand.c | 30 ++++++++++++++++++++++--
 drivers/mtd/nand/raw/brcmnand/brcmnand.h | 29 +++++++++++++++++++++++
 2 files changed, 57 insertions(+), 2 deletions(-)

diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index 63080ae3aef1..9c3909c34dc2 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -25,6 +25,7 @@
 #include <linux/of.h>
 #include <linux/of_platform.h>
 #include <linux/slab.h>
+#include <linux/static_key.h>
 #include <linux/list.h>
 #include <linux/log2.h>
 
@@ -207,6 +208,8 @@ enum {
 
 struct brcmnand_host;
 
+static DEFINE_STATIC_KEY_FALSE(brcmnand_soc_has_ops_key);
+
 struct brcmnand_controller {
 	struct device		*dev;
 	struct nand_controller	controller;
@@ -592,15 +595,25 @@ enum {
 	INTFC_CTLR_READY		= BIT(31),
 };
 
+static inline bool brcmnand_non_mmio_ops(struct brcmnand_controller *ctrl)
+{
+	return static_branch_unlikely(&brcmnand_soc_has_ops_key);
+}
+
 static inline u32 nand_readreg(struct brcmnand_controller *ctrl, u32 offs)
 {
+	if (brcmnand_non_mmio_ops(ctrl))
+		return brcmnand_soc_read(ctrl->soc, offs);
 	return brcmnand_readl(ctrl->nand_base + offs);
 }
 
 static inline void nand_writereg(struct brcmnand_controller *ctrl, u32 offs,
 				 u32 val)
 {
-	brcmnand_writel(val, ctrl->nand_base + offs);
+	if (brcmnand_non_mmio_ops(ctrl))
+		brcmnand_soc_write(ctrl->soc, val, offs);
+	else
+		brcmnand_writel(val, ctrl->nand_base + offs);
 }
 
 static int brcmnand_revision_init(struct brcmnand_controller *ctrl)
@@ -766,13 +779,18 @@ static inline void brcmnand_rmw_reg(struct brcmnand_controller *ctrl,
 
 static inline u32 brcmnand_read_fc(struct brcmnand_controller *ctrl, int word)
 {
+	if (brcmnand_non_mmio_ops(ctrl))
+		return brcmnand_soc_read(ctrl->soc, BRCMNAND_NON_MMIO_FC_ADDR);
 	return __raw_readl(ctrl->nand_fc + word * 4);
 }
 
 static inline void brcmnand_write_fc(struct brcmnand_controller *ctrl,
 				     int word, u32 val)
 {
-	__raw_writel(val, ctrl->nand_fc + word * 4);
+	if (brcmnand_non_mmio_ops(ctrl))
+		brcmnand_soc_write(ctrl->soc, val, BRCMNAND_NON_MMIO_FC_ADDR);
+	else
+		__raw_writel(val, ctrl->nand_fc + word * 4);
 }
 
 static inline void edu_writel(struct brcmnand_controller *ctrl,
@@ -3000,6 +3018,12 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc)
 	ctrl->dev = dev;
 	ctrl->soc = soc;
 
+	/* Enable the static key if the soc provides I/O operations indicating
+	 * that a non-memory mapped IO access path must be used
+	 */
+	if (brcmnand_soc_has_ops(ctrl->soc))
+		static_branch_enable(&brcmnand_soc_has_ops_key);
+
 	init_completion(&ctrl->done);
 	init_completion(&ctrl->dma_done);
 	init_completion(&ctrl->edu_done);
@@ -3145,6 +3169,8 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc)
 		/* Enable interrupt */
 		ctrl->soc->ctlrdy_ack(ctrl->soc);
 		ctrl->soc->ctlrdy_set_enabled(ctrl->soc, true);
+		if (brcmnand_soc_has_ops(soc))
+			static_branch_enable(&brcmnand_soc_has_ops_key);
 	} else {
 		/* Use standard interrupt infrastructure */
 		ret = devm_request_irq(dev, ctrl->irq, brcmnand_ctlrdy_irq, 0,
diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.h b/drivers/mtd/nand/raw/brcmnand/brcmnand.h
index eb498fbe505e..f1f93d85f50d 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.h
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.h
@@ -11,12 +11,25 @@
 
 struct platform_device;
 struct dev_pm_ops;
+struct brcmnand_io_ops;
+
+/* Special register offset constant to intercept a non-MMIO access
+ * to the flash cache register space. This is intentionally large
+ * not to overlap with an existing offset.
+ */
+#define BRCMNAND_NON_MMIO_FC_ADDR	0xffffffff
 
 struct brcmnand_soc {
 	bool (*ctlrdy_ack)(struct brcmnand_soc *soc);
 	void (*ctlrdy_set_enabled)(struct brcmnand_soc *soc, bool en);
 	void (*prepare_data_bus)(struct brcmnand_soc *soc, bool prepare,
 				 bool is_param);
+	const struct brcmnand_io_ops *ops;
+};
+
+struct brcmnand_io_ops {
+	u32 (*read_reg)(struct brcmnand_soc *soc, u32 offset);
+	void (*write_reg)(struct brcmnand_soc *soc, u32 val, u32 offset);
 };
 
 static inline void brcmnand_soc_data_bus_prepare(struct brcmnand_soc *soc,
@@ -58,6 +71,22 @@ static inline void brcmnand_writel(u32 val, void __iomem *addr)
 		writel_relaxed(val, addr);
 }
 
+static inline bool brcmnand_soc_has_ops(struct brcmnand_soc *soc)
+{
+	return soc && soc->ops && soc->ops->read_reg && soc->ops->write_reg;
+}
+
+static inline u32 brcmnand_soc_read(struct brcmnand_soc *soc, u32 offset)
+{
+	return soc->ops->read_reg(soc, offset);
+}
+
+static inline void brcmnand_soc_write(struct brcmnand_soc *soc, u32 val,
+				      u32 offset)
+{
+	soc->ops->write_reg(soc, val, offset);
+}
+
 int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc);
 int brcmnand_remove(struct platform_device *pdev);
 
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 3/9] mtd: rawnand: brcmnand: Avoid pdev in brcmnand_init_cs()
  2022-01-07  0:13 [PATCH v2 0/9] BCMA support for brcmnand Florian Fainelli
  2022-01-07  0:13 ` [PATCH v2 1/9] mtd: rawnand: brcmnand: Assign soc as early as possible Florian Fainelli
  2022-01-07  0:13 ` [PATCH v2 2/9] mtd: rawnand: brcmnand: Allow SoC to provide I/O operations Florian Fainelli
@ 2022-01-07  0:13 ` Florian Fainelli
  2022-01-07  0:13 ` [PATCH v2 4/9] mtd: rawnand: brcmnand: Move OF operations out of brcmnand_init_cs() Florian Fainelli
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Florian Fainelli @ 2022-01-07  0:13 UTC (permalink / raw)
  To: linux-mtd
  Cc: Florian Fainelli, Rafał Miłecki, Miquel Raynal,
	Richard Weinberger, Vignesh Raghavendra, Brian Norris,
	Kamal Dasu, Arnd Bergmann, Cai Huoqing, Colin Ian King,
	open list, open list:BROADCOM SPECIFIC AMBA DRIVER (BCMA),
	open list:BROADCOM STB NAND FLASH DRIVER

In preparation for encapsulation more of what the loop calling
brcmnand_init_cs() does, avoid using platform_device when it is the
device behind platform_device that we are using for printing errors.

No functional change.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/mtd/nand/raw/brcmnand/brcmnand.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index 9c3909c34dc2..fc14765f7d23 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -2771,7 +2771,7 @@ static const struct nand_controller_ops brcmnand_controller_ops = {
 static int brcmnand_init_cs(struct brcmnand_host *host, struct device_node *dn)
 {
 	struct brcmnand_controller *ctrl = host->ctrl;
-	struct platform_device *pdev = host->pdev;
+	struct device *dev = ctrl->dev;
 	struct mtd_info *mtd;
 	struct nand_chip *chip;
 	int ret;
@@ -2779,7 +2779,7 @@ static int brcmnand_init_cs(struct brcmnand_host *host, struct device_node *dn)
 
 	ret = of_property_read_u32(dn, "reg", &host->cs);
 	if (ret) {
-		dev_err(&pdev->dev, "can't get chip-select\n");
+		dev_err(dev, "can't get chip-select\n");
 		return -ENXIO;
 	}
 
@@ -2788,13 +2788,13 @@ static int brcmnand_init_cs(struct brcmnand_host *host, struct device_node *dn)
 
 	nand_set_flash_node(chip, dn);
 	nand_set_controller_data(chip, host);
-	mtd->name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "brcmnand.%d",
+	mtd->name = devm_kasprintf(dev, GFP_KERNEL, "brcmnand.%d",
 				   host->cs);
 	if (!mtd->name)
 		return -ENOMEM;
 
 	mtd->owner = THIS_MODULE;
-	mtd->dev.parent = &pdev->dev;
+	mtd->dev.parent = dev;
 
 	chip->legacy.cmd_ctrl = brcmnand_cmd_ctrl;
 	chip->legacy.cmdfunc = brcmnand_cmdfunc;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 4/9] mtd: rawnand: brcmnand: Move OF operations out of brcmnand_init_cs()
  2022-01-07  0:13 [PATCH v2 0/9] BCMA support for brcmnand Florian Fainelli
                   ` (2 preceding siblings ...)
  2022-01-07  0:13 ` [PATCH v2 3/9] mtd: rawnand: brcmnand: Avoid pdev in brcmnand_init_cs() Florian Fainelli
@ 2022-01-07  0:13 ` Florian Fainelli
  2022-01-07  0:13 ` [PATCH v2 5/9] mtd: rawnand: brcmnand: Allow working without interrupts Florian Fainelli
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Florian Fainelli @ 2022-01-07  0:13 UTC (permalink / raw)
  To: linux-mtd
  Cc: Florian Fainelli, Rafał Miłecki, Miquel Raynal,
	Richard Weinberger, Vignesh Raghavendra, Brian Norris,
	Kamal Dasu, Arnd Bergmann, Cai Huoqing, Colin Ian King,
	open list, open list:BROADCOM SPECIFIC AMBA DRIVER (BCMA),
	open list:BROADCOM STB NAND FLASH DRIVER

In order to initialize a given chip select object for use by the
brcmnand driver, move all of the Device Tree specific routines outside
of brcmnand_init_cs() in order to make it usable in a platform data
configuration which will be necessary for supporting BCMA chips.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/mtd/nand/raw/brcmnand/brcmnand.c | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index fc14765f7d23..eb3f96489f83 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -2768,7 +2768,7 @@ static const struct nand_controller_ops brcmnand_controller_ops = {
 	.attach_chip = brcmnand_attach_chip,
 };
 
-static int brcmnand_init_cs(struct brcmnand_host *host, struct device_node *dn)
+static int brcmnand_init_cs(struct brcmnand_host *host)
 {
 	struct brcmnand_controller *ctrl = host->ctrl;
 	struct device *dev = ctrl->dev;
@@ -2777,16 +2777,9 @@ static int brcmnand_init_cs(struct brcmnand_host *host, struct device_node *dn)
 	int ret;
 	u16 cfg_offs;
 
-	ret = of_property_read_u32(dn, "reg", &host->cs);
-	if (ret) {
-		dev_err(dev, "can't get chip-select\n");
-		return -ENXIO;
-	}
-
 	mtd = nand_to_mtd(&host->chip);
 	chip = &host->chip;
 
-	nand_set_flash_node(chip, dn);
 	nand_set_controller_data(chip, host);
 	mtd->name = devm_kasprintf(dev, GFP_KERNEL, "brcmnand.%d",
 				   host->cs);
@@ -3195,7 +3188,16 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc)
 			host->pdev = pdev;
 			host->ctrl = ctrl;
 
-			ret = brcmnand_init_cs(host, child);
+			ret = of_property_read_u32(child, "reg", &host->cs);
+			if (ret) {
+				dev_err(dev, "can't get chip-select\n");
+				devm_kfree(dev, host);
+				continue;
+			}
+
+			nand_set_flash_node(&host->chip, child);
+
+			ret = brcmnand_init_cs(host);
 			if (ret) {
 				devm_kfree(dev, host);
 				continue; /* Try all chip-selects */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 5/9] mtd: rawnand: brcmnand: Allow working without interrupts
  2022-01-07  0:13 [PATCH v2 0/9] BCMA support for brcmnand Florian Fainelli
                   ` (3 preceding siblings ...)
  2022-01-07  0:13 ` [PATCH v2 4/9] mtd: rawnand: brcmnand: Move OF operations out of brcmnand_init_cs() Florian Fainelli
@ 2022-01-07  0:13 ` Florian Fainelli
  2022-01-07  0:13 ` [PATCH v2 6/9] mtd: rawnand: brcmnand: Add platform data structure for BCMA Florian Fainelli
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Florian Fainelli @ 2022-01-07  0:13 UTC (permalink / raw)
  To: linux-mtd
  Cc: Florian Fainelli, Rafał Miłecki, Miquel Raynal,
	Richard Weinberger, Vignesh Raghavendra, Brian Norris,
	Kamal Dasu, Arnd Bergmann, Cai Huoqing, Colin Ian King,
	open list, open list:BROADCOM SPECIFIC AMBA DRIVER (BCMA),
	open list:BROADCOM STB NAND FLASH DRIVER

The BCMA devices include the brcmnand controller but they do not wire up
any interrupt line, allow the main interrupt to be optional and update
the completion path to also check for the lack of an interrupt line.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/mtd/nand/raw/brcmnand/brcmnand.c | 54 +++++++++++-------------
 1 file changed, 24 insertions(+), 30 deletions(-)

diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index eb3f96489f83..08e2acde5133 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -216,7 +216,7 @@ struct brcmnand_controller {
 	void __iomem		*nand_base;
 	void __iomem		*nand_fc; /* flash cache */
 	void __iomem		*flash_dma_base;
-	unsigned int		irq;
+	int			irq;
 	unsigned int		dma_irq;
 	int			nand_version;
 
@@ -1610,7 +1610,7 @@ static bool brcmstb_nand_wait_for_completion(struct nand_chip *chip)
 	bool err = false;
 	int sts;
 
-	if (mtd->oops_panic_write) {
+	if (mtd->oops_panic_write || ctrl->irq < 0) {
 		/* switch to interrupt polling and PIO mode */
 		disable_ctrl_irqs(ctrl);
 		sts = bcmnand_ctrl_poll_status(ctrl, NAND_CTRL_RDY,
@@ -3144,35 +3144,29 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc)
 	}
 
 	/* IRQ */
-	ctrl->irq = platform_get_irq(pdev, 0);
-	if ((int)ctrl->irq < 0) {
-		dev_err(dev, "no IRQ defined\n");
-		ret = -ENODEV;
-		goto err;
-	}
-
-	/*
-	 * Some SoCs integrate this controller (e.g., its interrupt bits) in
-	 * interesting ways
-	 */
-	if (soc) {
-		ret = devm_request_irq(dev, ctrl->irq, brcmnand_irq, 0,
-				       DRV_NAME, ctrl);
+	ctrl->irq = platform_get_irq_optional(pdev, 0);
+	if (ctrl->irq > 0) {
+		/*
+		 * Some SoCs integrate this controller (e.g., its interrupt bits) in
+		 * interesting ways
+		 */
+		if (soc) {
+			ret = devm_request_irq(dev, ctrl->irq, brcmnand_irq, 0,
+					       DRV_NAME, ctrl);
 
-		/* Enable interrupt */
-		ctrl->soc->ctlrdy_ack(ctrl->soc);
-		ctrl->soc->ctlrdy_set_enabled(ctrl->soc, true);
-		if (brcmnand_soc_has_ops(soc))
-			static_branch_enable(&brcmnand_soc_has_ops_key);
-	} else {
-		/* Use standard interrupt infrastructure */
-		ret = devm_request_irq(dev, ctrl->irq, brcmnand_ctlrdy_irq, 0,
-				       DRV_NAME, ctrl);
-	}
-	if (ret < 0) {
-		dev_err(dev, "can't allocate IRQ %d: error %d\n",
-			ctrl->irq, ret);
-		goto err;
+			/* Enable interrupt */
+			ctrl->soc->ctlrdy_ack(ctrl->soc);
+			ctrl->soc->ctlrdy_set_enabled(ctrl->soc, true);
+		} else {
+			/* Use standard interrupt infrastructure */
+			ret = devm_request_irq(dev, ctrl->irq, brcmnand_ctlrdy_irq, 0,
+					       DRV_NAME, ctrl);
+		}
+		if (ret < 0) {
+			dev_err(dev, "can't allocate IRQ %d: error %d\n",
+				ctrl->irq, ret);
+			goto err;
+		}
 	}
 
 	for_each_available_child_of_node(dn, child) {
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 6/9] mtd: rawnand: brcmnand: Add platform data structure for BCMA
  2022-01-07  0:13 [PATCH v2 0/9] BCMA support for brcmnand Florian Fainelli
                   ` (4 preceding siblings ...)
  2022-01-07  0:13 ` [PATCH v2 5/9] mtd: rawnand: brcmnand: Allow working without interrupts Florian Fainelli
@ 2022-01-07  0:13 ` Florian Fainelli
  2022-01-07  0:13 ` [PATCH v2 7/9] mtd: rawnand: brcmnand: Allow platform data instantation Florian Fainelli
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Florian Fainelli @ 2022-01-07  0:13 UTC (permalink / raw)
  To: linux-mtd
  Cc: Florian Fainelli, Rafał Miłecki, Miquel Raynal,
	Richard Weinberger, Vignesh Raghavendra, Brian Norris,
	Kamal Dasu, Arnd Bergmann, Cai Huoqing, Colin Ian King,
	open list, open list:BROADCOM SPECIFIC AMBA DRIVER (BCMA),
	open list:BROADCOM STB NAND FLASH DRIVER

Update the BCMA's chipcommon nand flash driver to detect which
chip-select is used and pass that information via platform data to the
brcmnand driver. Make sure that the brcmnand platform data structure is
always at the beginning of the platform data of the "nflash" device
created by BCMA to allow brcmnand to safely de-reference it.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 MAINTAINERS                                 |  1 +
 drivers/bcma/driver_chipcommon_nflash.c     | 20 +++++++++++++++++++-
 include/linux/bcma/bcma_driver_chipcommon.h |  5 +++++
 include/linux/platform_data/brcmnand.h      | 12 ++++++++++++
 4 files changed, 37 insertions(+), 1 deletion(-)
 create mode 100644 include/linux/platform_data/brcmnand.h

diff --git a/MAINTAINERS b/MAINTAINERS
index dd36acc87ce6..404f3eb8ff18 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3966,6 +3966,7 @@ L:	linux-mtd@lists.infradead.org
 L:	bcm-kernel-feedback-list@broadcom.com
 S:	Maintained
 F:	drivers/mtd/nand/raw/brcmnand/
+F:	include/linux/platform_data/brcmnand.h
 
 BROADCOM STB PCIE DRIVER
 M:	Jim Quinlan <jim2101024@gmail.com>
diff --git a/drivers/bcma/driver_chipcommon_nflash.c b/drivers/bcma/driver_chipcommon_nflash.c
index d4f699aef8c4..a1a814750b4a 100644
--- a/drivers/bcma/driver_chipcommon_nflash.c
+++ b/drivers/bcma/driver_chipcommon_nflash.c
@@ -7,18 +7,28 @@
 
 #include "bcma_private.h"
 
+#include <linux/bitops.h>
 #include <linux/platform_device.h>
+#include <linux/platform_data/brcmnand.h>
 #include <linux/bcma/bcma.h>
 
+/* Alternate NAND controller driver name in order to allow both bcm47xxnflash
+ * and bcma_brcmnand to be built into the same kernel image.
+ */
+static const char *bcma_nflash_alt_name = "bcma_brcmnand";
+
 struct platform_device bcma_nflash_dev = {
 	.name		= "bcma_nflash",
 	.num_resources	= 0,
 };
 
+static const char *probes[] = { "bcm47xxpart", NULL };
+
 /* Initialize NAND flash access */
 int bcma_nflash_init(struct bcma_drv_cc *cc)
 {
 	struct bcma_bus *bus = cc->core->bus;
+	u32 reg;
 
 	if (bus->chipinfo.id != BCMA_CHIP_ID_BCM4706 &&
 	    cc->core->id.rev != 38) {
@@ -33,8 +43,16 @@ int bcma_nflash_init(struct bcma_drv_cc *cc)
 
 	cc->nflash.present = true;
 	if (cc->core->id.rev == 38 &&
-	    (cc->status & BCMA_CC_CHIPST_5357_NAND_BOOT))
+	    (cc->status & BCMA_CC_CHIPST_5357_NAND_BOOT)) {
 		cc->nflash.boot = true;
+		/* Determine the chip select that is being used */
+		reg = bcma_cc_read32(cc, BCMA_CC_NAND_CS_NAND_SELECT) & 0xff;
+		cc->nflash.brcmnand_info.chip_select = ffs(reg) - 1;
+		cc->nflash.brcmnand_info.part_probe_types = probes;
+		cc->nflash.brcmnand_info.ecc_stepsize = 512;
+		cc->nflash.brcmnand_info.ecc_strength = 1;
+		bcma_nflash_dev.name = bcma_nflash_alt_name;
+	}
 
 	/* Prepare platform device, but don't register it yet. It's too early,
 	 * malloc (required by device_private_init) is not available yet. */
diff --git a/include/linux/bcma/bcma_driver_chipcommon.h b/include/linux/bcma/bcma_driver_chipcommon.h
index d35b9206096d..e3314f746bfa 100644
--- a/include/linux/bcma/bcma_driver_chipcommon.h
+++ b/include/linux/bcma/bcma_driver_chipcommon.h
@@ -3,6 +3,7 @@
 #define LINUX_BCMA_DRIVER_CC_H_
 
 #include <linux/platform_device.h>
+#include <linux/platform_data/brcmnand.h>
 #include <linux/gpio.h>
 
 /** ChipCommon core registers. **/
@@ -599,6 +600,10 @@ struct bcma_sflash {
 
 #ifdef CONFIG_BCMA_NFLASH
 struct bcma_nflash {
+	/* Must be the fist member for the brcmnand driver to
+	 * de-reference that structure.
+	 */
+	struct brcmnand_platform_data brcmnand_info;
 	bool present;
 	bool boot;		/* This is the flash the SoC boots from */
 };
diff --git a/include/linux/platform_data/brcmnand.h b/include/linux/platform_data/brcmnand.h
new file mode 100644
index 000000000000..8b8777985dce
--- /dev/null
+++ b/include/linux/platform_data/brcmnand.h
@@ -0,0 +1,12 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef BRCMNAND_PLAT_DATA_H
+#define BRCMNAND_PLAT_DATA_H
+
+struct brcmnand_platform_data {
+	int	chip_select;
+	const char * const *part_probe_types;
+	unsigned int ecc_stepsize;
+	unsigned int ecc_strength;
+};
+
+#endif /* BRCMNAND_PLAT_DATA_H */
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 7/9] mtd: rawnand: brcmnand: Allow platform data instantation
  2022-01-07  0:13 [PATCH v2 0/9] BCMA support for brcmnand Florian Fainelli
                   ` (5 preceding siblings ...)
  2022-01-07  0:13 ` [PATCH v2 6/9] mtd: rawnand: brcmnand: Add platform data structure for BCMA Florian Fainelli
@ 2022-01-07  0:13 ` Florian Fainelli
  2022-01-07  0:13 ` [PATCH v2 8/9] mtd: rawnand: brcmnand: BCMA controller uses command shift of 0 Florian Fainelli
  2022-01-07  0:13 ` [PATCH v2 9/9] mtd: rawnand: brcmnand: Add BCMA shim Florian Fainelli
  8 siblings, 0 replies; 12+ messages in thread
From: Florian Fainelli @ 2022-01-07  0:13 UTC (permalink / raw)
  To: linux-mtd
  Cc: Florian Fainelli, Rafał Miłecki, Miquel Raynal,
	Richard Weinberger, Vignesh Raghavendra, Brian Norris,
	Kamal Dasu, Arnd Bergmann, Cai Huoqing, Colin Ian King,
	open list, open list:BROADCOM SPECIFIC AMBA DRIVER (BCMA),
	open list:BROADCOM STB NAND FLASH DRIVER

Make use of the recently refactored code in brcmnand_init_cs() and
derive the chip-select from the platform data that is supplied. Update
the various code paths to avoid relying on possibly non-existent
resources, too.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/mtd/nand/raw/brcmnand/brcmnand.c | 45 ++++++++++++++++++------
 1 file changed, 35 insertions(+), 10 deletions(-)

diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index 08e2acde5133..eab19df152f3 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -9,6 +9,7 @@
 #include <linux/delay.h>
 #include <linux/device.h>
 #include <linux/platform_device.h>
+#include <linux/platform_data/brcmnand.h>
 #include <linux/err.h>
 #include <linux/completion.h>
 #include <linux/interrupt.h>
@@ -2768,7 +2769,8 @@ static const struct nand_controller_ops brcmnand_controller_ops = {
 	.attach_chip = brcmnand_attach_chip,
 };
 
-static int brcmnand_init_cs(struct brcmnand_host *host)
+static int brcmnand_init_cs(struct brcmnand_host *host,
+			    const char * const *part_probe_types)
 {
 	struct brcmnand_controller *ctrl = host->ctrl;
 	struct device *dev = ctrl->dev;
@@ -2821,7 +2823,7 @@ static int brcmnand_init_cs(struct brcmnand_host *host)
 	if (ret)
 		return ret;
 
-	ret = mtd_device_register(mtd, NULL, 0);
+	ret = mtd_device_parse_register(mtd, part_probe_types, NULL, NULL, 0);
 	if (ret)
 		nand_cleanup(chip);
 
@@ -2990,17 +2992,15 @@ static int brcmnand_edu_setup(struct platform_device *pdev)
 
 int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc)
 {
+	struct brcmnand_platform_data *pd = dev_get_platdata(&pdev->dev);
 	struct device *dev = &pdev->dev;
 	struct device_node *dn = dev->of_node, *child;
 	struct brcmnand_controller *ctrl;
+	struct brcmnand_host *host;
 	struct resource *res;
 	int ret;
 
-	/* We only support device-tree instantiation */
-	if (!dn)
-		return -ENODEV;
-
-	if (!of_match_node(brcmnand_of_match, dn))
+	if (dn && !of_match_node(brcmnand_of_match, dn))
 		return -ENODEV;
 
 	ctrl = devm_kzalloc(dev, sizeof(*ctrl), GFP_KERNEL);
@@ -3027,7 +3027,7 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc)
 	/* NAND register range */
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	ctrl->nand_base = devm_ioremap_resource(dev, res);
-	if (IS_ERR(ctrl->nand_base))
+	if (IS_ERR(ctrl->nand_base) && !brcmnand_soc_has_ops(soc))
 		return PTR_ERR(ctrl->nand_base);
 
 	/* Enable clock before using NAND registers */
@@ -3171,7 +3171,6 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc)
 
 	for_each_available_child_of_node(dn, child) {
 		if (of_device_is_compatible(child, "brcm,nandcs")) {
-			struct brcmnand_host *host;
 
 			host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL);
 			if (!host) {
@@ -3191,7 +3190,7 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc)
 
 			nand_set_flash_node(&host->chip, child);
 
-			ret = brcmnand_init_cs(host);
+			ret = brcmnand_init_cs(host, NULL);
 			if (ret) {
 				devm_kfree(dev, host);
 				continue; /* Try all chip-selects */
@@ -3201,6 +3200,32 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc)
 		}
 	}
 
+	if (!list_empty(&ctrl->host_list))
+		return 0;
+
+	if (!pd) {
+		ret = -ENODEV;
+		goto err;
+	}
+
+	/* If we got there we must have been probing via platform data */
+	host = devm_kzalloc(dev, sizeof(*host), GFP_KERNEL);
+	if (!host) {
+		ret = -ENOMEM;
+		goto err;
+	}
+	host->pdev = pdev;
+	host->ctrl = ctrl;
+	host->cs = pd->chip_select;
+	host->chip.ecc.size = pd->ecc_stepsize;
+	host->chip.ecc.strength = pd->ecc_strength;
+
+	ret = brcmnand_init_cs(host, pd->part_probe_types);
+	if (ret)
+		goto err;
+
+	list_add_tail(&host->node, &ctrl->host_list);
+
 	/* No chip-selects could initialize properly */
 	if (list_empty(&ctrl->host_list)) {
 		ret = -ENODEV;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 8/9] mtd: rawnand: brcmnand: BCMA controller uses command shift of 0
  2022-01-07  0:13 [PATCH v2 0/9] BCMA support for brcmnand Florian Fainelli
                   ` (6 preceding siblings ...)
  2022-01-07  0:13 ` [PATCH v2 7/9] mtd: rawnand: brcmnand: Allow platform data instantation Florian Fainelli
@ 2022-01-07  0:13 ` Florian Fainelli
  2022-01-07  0:13 ` [PATCH v2 9/9] mtd: rawnand: brcmnand: Add BCMA shim Florian Fainelli
  8 siblings, 0 replies; 12+ messages in thread
From: Florian Fainelli @ 2022-01-07  0:13 UTC (permalink / raw)
  To: linux-mtd
  Cc: Florian Fainelli, Rafał Miłecki, Miquel Raynal,
	Richard Weinberger, Vignesh Raghavendra, Brian Norris,
	Kamal Dasu, Arnd Bergmann, Cai Huoqing, Colin Ian King,
	open list, open list:BROADCOM SPECIFIC AMBA DRIVER (BCMA),
	open list:BROADCOM STB NAND FLASH DRIVER

For some odd and unexplained reason the BCMA NAND controller, albeit
revision 3.4 uses a command shift of 0 instead of 24 as it should be,
quirk that.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/mtd/nand/raw/brcmnand/brcmnand.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index eab19df152f3..4759303ece7c 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -916,6 +916,12 @@ static void brcmnand_wr_corr_thresh(struct brcmnand_host *host, u8 val)
 
 static inline int brcmnand_cmd_shift(struct brcmnand_controller *ctrl)
 {
+	/* Kludge for the BCMA-based NAND controller which does not actually
+	 * shift the command
+	 */
+	if (ctrl->nand_version == 0x0304 && brcmnand_non_mmio_ops(ctrl))
+		return 0;
+
 	if (ctrl->nand_version < 0x0602)
 		return 24;
 	return 0;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH v2 9/9] mtd: rawnand: brcmnand: Add BCMA shim
  2022-01-07  0:13 [PATCH v2 0/9] BCMA support for brcmnand Florian Fainelli
                   ` (7 preceding siblings ...)
  2022-01-07  0:13 ` [PATCH v2 8/9] mtd: rawnand: brcmnand: BCMA controller uses command shift of 0 Florian Fainelli
@ 2022-01-07  0:13 ` Florian Fainelli
  8 siblings, 0 replies; 12+ messages in thread
From: Florian Fainelli @ 2022-01-07  0:13 UTC (permalink / raw)
  To: linux-mtd
  Cc: Florian Fainelli, Rafał Miłecki, Miquel Raynal,
	Richard Weinberger, Vignesh Raghavendra, Brian Norris,
	Kamal Dasu, Arnd Bergmann, Cai Huoqing, Colin Ian King,
	open list, open list:BROADCOM SPECIFIC AMBA DRIVER (BCMA),
	open list:BROADCOM STB NAND FLASH DRIVER

Add a BCMA shim to allow us to register the brcmnand driver using the
BCMA bus which provides indirect memory mapped access to SoC registers.

There are a number of registers that need to be byte swapped because
they are natively big endian, coming directly from the NAND chip, and
there is no bus interface unlike the iProc or STB platforms that
performs the byte swapping for us.

Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
---
 drivers/mtd/nand/raw/Kconfig              |  13 +++
 drivers/mtd/nand/raw/brcmnand/Makefile    |   2 +
 drivers/mtd/nand/raw/brcmnand/bcma_nand.c | 132 ++++++++++++++++++++++
 drivers/mtd/nand/raw/brcmnand/brcmnand.c  |   4 +
 4 files changed, 151 insertions(+)
 create mode 100644 drivers/mtd/nand/raw/brcmnand/bcma_nand.c

diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig
index 0a45d3c6c15b..7f385ac6e443 100644
--- a/drivers/mtd/nand/raw/Kconfig
+++ b/drivers/mtd/nand/raw/Kconfig
@@ -208,6 +208,19 @@ config MTD_NAND_BRCMNAND
 	  originally designed for Set-Top Box but is used on various BCM7xxx,
 	  BCM3xxx, BCM63xxx, iProc/Cygnus and more.
 
+if MTD_NAND_BRCMNAND
+
+config MTD_NAND_BRCMNAND_BCMA
+	tristate "Broadcom BCMA NAND controller"
+	depends on BCMA_NFLASH
+	depends on BCMA
+	help
+	  Enables the BRCMNAND controller over BCMA on BCM47186/BCM5358 SoCs.
+	  The glue driver will take care of performing the low-level I/O
+	  operations to interface the BRCMNAND controller over the BCMA bus.
+
+endif # MTD_NAND_BRCMNAND
+
 config MTD_NAND_BCM47XXNFLASH
 	tristate "BCM4706 BCMA NAND controller"
 	depends on BCMA_NFLASH
diff --git a/drivers/mtd/nand/raw/brcmnand/Makefile b/drivers/mtd/nand/raw/brcmnand/Makefile
index 195b845e48b8..16dc7254200e 100644
--- a/drivers/mtd/nand/raw/brcmnand/Makefile
+++ b/drivers/mtd/nand/raw/brcmnand/Makefile
@@ -6,3 +6,5 @@ obj-$(CONFIG_MTD_NAND_BRCMNAND)		+= bcm63138_nand.o
 obj-$(CONFIG_MTD_NAND_BRCMNAND)		+= bcm6368_nand.o
 obj-$(CONFIG_MTD_NAND_BRCMNAND)		+= brcmstb_nand.o
 obj-$(CONFIG_MTD_NAND_BRCMNAND)		+= brcmnand.o
+
+obj-$(CONFIG_MTD_NAND_BRCMNAND_BCMA)	+= bcma_nand.o
diff --git a/drivers/mtd/nand/raw/brcmnand/bcma_nand.c b/drivers/mtd/nand/raw/brcmnand/bcma_nand.c
new file mode 100644
index 000000000000..d7c62988c452
--- /dev/null
+++ b/drivers/mtd/nand/raw/brcmnand/bcma_nand.c
@@ -0,0 +1,132 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright © 2021 Broadcom
+ */
+#include <linux/bcma/bcma.h>
+#include <linux/bcma/bcma_driver_chipcommon.h>
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+
+#include "brcmnand.h"
+
+struct brcmnand_bcma_soc {
+	struct brcmnand_soc soc;
+	struct bcma_drv_cc *cc;
+};
+
+static inline bool brcmnand_bcma_needs_swapping(u32 offset)
+{
+	switch (offset) {
+	case BCMA_CC_NAND_SPARE_RD0:
+	case BCMA_CC_NAND_SPARE_RD4:
+	case BCMA_CC_NAND_SPARE_RD8:
+	case BCMA_CC_NAND_SPARE_RD12:
+	case BCMA_CC_NAND_SPARE_WR0:
+	case BCMA_CC_NAND_SPARE_WR4:
+	case BCMA_CC_NAND_SPARE_WR8:
+	case BCMA_CC_NAND_SPARE_WR12:
+	case BCMA_CC_NAND_DEVID:
+	case BCMA_CC_NAND_DEVID_X:
+	case BCMA_CC_NAND_SPARE_RD16:
+	case BCMA_CC_NAND_SPARE_RD20:
+	case BCMA_CC_NAND_SPARE_RD24:
+	case BCMA_CC_NAND_SPARE_RD28:
+		return true;
+	}
+
+	return false;
+}
+
+static inline struct brcmnand_bcma_soc *to_bcma_soc(struct brcmnand_soc *soc)
+{
+	return container_of(soc, struct brcmnand_bcma_soc, soc);
+}
+
+static u32 brcmnand_bcma_read_reg(struct brcmnand_soc *soc, u32 offset)
+{
+	struct brcmnand_bcma_soc *sc = to_bcma_soc(soc);
+	u32 val;
+
+	/* Offset into the NAND block and deal with the flash cache separately */
+	if (offset == BRCMNAND_NON_MMIO_FC_ADDR)
+		offset = BCMA_CC_NAND_CACHE_DATA;
+	else
+		offset += BCMA_CC_NAND_REVISION;
+
+	val = bcma_cc_read32(sc->cc, offset);
+
+	/* Swap if necessary */
+	if (brcmnand_bcma_needs_swapping(offset))
+		val = be32_to_cpu(val);
+	return val;
+}
+
+static void brcmnand_bcma_write_reg(struct brcmnand_soc *soc, u32 val,
+				    u32 offset)
+{
+	struct brcmnand_bcma_soc *sc = to_bcma_soc(soc);
+
+	/* Offset into the NAND block */
+	if (offset == BRCMNAND_NON_MMIO_FC_ADDR)
+		offset = BCMA_CC_NAND_CACHE_DATA;
+	else
+		offset += BCMA_CC_NAND_REVISION;
+
+	/* Swap if necessary */
+	if (brcmnand_bcma_needs_swapping(offset))
+		val = cpu_to_be32(val);
+
+	bcma_cc_write32(sc->cc, offset, val);
+}
+
+static struct brcmnand_io_ops brcmnand_bcma_io_ops = {
+	.read_reg	= brcmnand_bcma_read_reg,
+	.write_reg	= brcmnand_bcma_write_reg,
+};
+
+static void brcmnand_bcma_prepare_data_bus(struct brcmnand_soc *soc, bool prepare,
+					   bool is_param)
+{
+	struct brcmnand_bcma_soc *sc = to_bcma_soc(soc);
+
+	/* Reset the cache address to ensure we are already accessing the
+	 * beginning of a sub-page.
+	 */
+	bcma_cc_write32(sc->cc, BCMA_CC_NAND_CACHE_ADDR, 0);
+}
+
+static int brcmnand_bcma_nand_probe(struct platform_device *pdev)
+{
+	struct bcma_nflash *nflash = dev_get_platdata(&pdev->dev);
+	struct brcmnand_bcma_soc *soc;
+
+	soc = devm_kzalloc(&pdev->dev, sizeof(*soc), GFP_KERNEL);
+	if (!soc)
+		return -ENOMEM;
+
+	soc->cc = container_of(nflash, struct bcma_drv_cc, nflash);
+	soc->soc.prepare_data_bus = brcmnand_bcma_prepare_data_bus;
+	soc->soc.ops = &brcmnand_bcma_io_ops;
+
+	if (soc->cc->core->bus->chipinfo.id == BCMA_CHIP_ID_BCM4706) {
+		dev_err(&pdev->dev, "Use bcm47xxnflash for 4706!\n");
+		return -ENODEV;
+	}
+
+	return brcmnand_probe(pdev, &soc->soc);
+}
+
+static struct platform_driver brcmnand_bcma_nand_driver = {
+	.probe			= brcmnand_bcma_nand_probe,
+	.remove			= brcmnand_remove,
+	.driver = {
+		.name		= "bcma_brcmnand",
+		.pm		= &brcmnand_pm_ops,
+	}
+};
+module_platform_driver(brcmnand_bcma_nand_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Broadcom");
+MODULE_DESCRIPTION("NAND controller driver glue for BCMA chips");
diff --git a/drivers/mtd/nand/raw/brcmnand/brcmnand.c b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
index 4759303ece7c..c412f79b81db 100644
--- a/drivers/mtd/nand/raw/brcmnand/brcmnand.c
+++ b/drivers/mtd/nand/raw/brcmnand/brcmnand.c
@@ -598,7 +598,11 @@ enum {
 
 static inline bool brcmnand_non_mmio_ops(struct brcmnand_controller *ctrl)
 {
+#if IS_ENABLED(CONFIG_MTD_NAND_BRCMNAND_BCMA)
 	return static_branch_unlikely(&brcmnand_soc_has_ops_key);
+#else
+	return false;
+#endif
 }
 
 static inline u32 nand_readreg(struct brcmnand_controller *ctrl, u32 offs)
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 2/9] mtd: rawnand: brcmnand: Allow SoC to provide I/O operations
  2022-01-07  0:13 ` [PATCH v2 2/9] mtd: rawnand: brcmnand: Allow SoC to provide I/O operations Florian Fainelli
@ 2022-01-07  3:10   ` Florian Fainelli
  2022-01-07  7:22     ` Miquel Raynal
  0 siblings, 1 reply; 12+ messages in thread
From: Florian Fainelli @ 2022-01-07  3:10 UTC (permalink / raw)
  To: linux-mtd
  Cc: Rafał Miłecki, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Brian Norris, Kamal Dasu, Arnd Bergmann,
	Cai Huoqing, Colin Ian King, open list,
	open list:BROADCOM SPECIFIC AMBA DRIVER (BCMA),
	open list:BROADCOM STB NAND FLASH DRIVER



On 1/6/2022 4:13 PM, Florian Fainelli wrote:
> Allow a brcmnand_soc instance to provide a custom set of I/O operations
> which we will require when using this driver on a BCMA bus which is not
> directly memory mapped I/O. Update the nand_{read,write}_reg accordingly
> to use the SoC operations if provided.
> 
> To minimize the penalty on other SoCs which do support standard MMIO
> accesses, we use a static key which is disabled by default and gets
> enabled if a soc implementation does provide I/O operations.
> 
> Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> ---

[snip]

>   	init_completion(&ctrl->done);
>   	init_completion(&ctrl->dma_done);
>   	init_completion(&ctrl->edu_done);
> @@ -3145,6 +3169,8 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc)
>   		/* Enable interrupt */
>   		ctrl->soc->ctlrdy_ack(ctrl->soc);
>   		ctrl->soc->ctlrdy_set_enabled(ctrl->soc, true);
> +		if (brcmnand_soc_has_ops(soc))
> +			static_branch_enable(&brcmnand_soc_has_ops_key);

This hunk got mistakenly added with a rebase, I will wait for additional 
comments before spinning a new version.
-- 
Florian

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 2/9] mtd: rawnand: brcmnand: Allow SoC to provide I/O operations
  2022-01-07  3:10   ` Florian Fainelli
@ 2022-01-07  7:22     ` Miquel Raynal
  0 siblings, 0 replies; 12+ messages in thread
From: Miquel Raynal @ 2022-01-07  7:22 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: linux-mtd, Rafał Miłecki, Richard Weinberger,
	Vignesh Raghavendra, Brian Norris, Kamal Dasu, Arnd Bergmann,
	Cai Huoqing, Colin Ian King, open list,
	open list:BROADCOM SPECIFIC AMBA DRIVER (BCMA),
	open list:BROADCOM STB NAND FLASH DRIVER

Hi Florian,

f.fainelli@gmail.com wrote on Thu, 6 Jan 2022 19:10:12 -0800:

> On 1/6/2022 4:13 PM, Florian Fainelli wrote:
> > Allow a brcmnand_soc instance to provide a custom set of I/O operations
> > which we will require when using this driver on a BCMA bus which is not
> > directly memory mapped I/O. Update the nand_{read,write}_reg accordingly
> > to use the SoC operations if provided.
> > 
> > To minimize the penalty on other SoCs which do support standard MMIO
> > accesses, we use a static key which is disabled by default and gets
> > enabled if a soc implementation does provide I/O operations.
> > 
> > Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
> > ---  
> 
> [snip]
> 
> >   	init_completion(&ctrl->done);
> >   	init_completion(&ctrl->dma_done);
> >   	init_completion(&ctrl->edu_done);
> > @@ -3145,6 +3169,8 @@ int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc)
> >   		/* Enable interrupt */
> >   		ctrl->soc->ctlrdy_ack(ctrl->soc);
> >   		ctrl->soc->ctlrdy_set_enabled(ctrl->soc, true);
> > +		if (brcmnand_soc_has_ops(soc))
> > +			static_branch_enable(&brcmnand_soc_has_ops_key);  
> 
> This hunk got mistakenly added with a rebase, I will wait for additional comments before spinning a new version.

FYI the series LGTM otherwise.

Thanks,
Miquèl

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2022-01-07  7:22 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-01-07  0:13 [PATCH v2 0/9] BCMA support for brcmnand Florian Fainelli
2022-01-07  0:13 ` [PATCH v2 1/9] mtd: rawnand: brcmnand: Assign soc as early as possible Florian Fainelli
2022-01-07  0:13 ` [PATCH v2 2/9] mtd: rawnand: brcmnand: Allow SoC to provide I/O operations Florian Fainelli
2022-01-07  3:10   ` Florian Fainelli
2022-01-07  7:22     ` Miquel Raynal
2022-01-07  0:13 ` [PATCH v2 3/9] mtd: rawnand: brcmnand: Avoid pdev in brcmnand_init_cs() Florian Fainelli
2022-01-07  0:13 ` [PATCH v2 4/9] mtd: rawnand: brcmnand: Move OF operations out of brcmnand_init_cs() Florian Fainelli
2022-01-07  0:13 ` [PATCH v2 5/9] mtd: rawnand: brcmnand: Allow working without interrupts Florian Fainelli
2022-01-07  0:13 ` [PATCH v2 6/9] mtd: rawnand: brcmnand: Add platform data structure for BCMA Florian Fainelli
2022-01-07  0:13 ` [PATCH v2 7/9] mtd: rawnand: brcmnand: Allow platform data instantation Florian Fainelli
2022-01-07  0:13 ` [PATCH v2 8/9] mtd: rawnand: brcmnand: BCMA controller uses command shift of 0 Florian Fainelli
2022-01-07  0:13 ` [PATCH v2 9/9] mtd: rawnand: brcmnand: Add BCMA shim Florian Fainelli

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).