11802d0beSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
293db446aSBoris Brezillon /*
393db446aSBoris Brezillon * Copyright © 2015 Broadcom Corporation
493db446aSBoris Brezillon */
593db446aSBoris Brezillon
693db446aSBoris Brezillon #ifndef __BRCMNAND_H__
793db446aSBoris Brezillon #define __BRCMNAND_H__
893db446aSBoris Brezillon
993db446aSBoris Brezillon #include <linux/types.h>
1093db446aSBoris Brezillon #include <linux/io.h>
1193db446aSBoris Brezillon
1293db446aSBoris Brezillon struct platform_device;
1393db446aSBoris Brezillon struct dev_pm_ops;
14*25f97138SFlorian Fainelli struct brcmnand_io_ops;
15*25f97138SFlorian Fainelli
16*25f97138SFlorian Fainelli /* Special register offset constant to intercept a non-MMIO access
17*25f97138SFlorian Fainelli * to the flash cache register space. This is intentionally large
18*25f97138SFlorian Fainelli * not to overlap with an existing offset.
19*25f97138SFlorian Fainelli */
20*25f97138SFlorian Fainelli #define BRCMNAND_NON_MMIO_FC_ADDR 0xffffffff
2193db446aSBoris Brezillon
2293db446aSBoris Brezillon struct brcmnand_soc {
2393db446aSBoris Brezillon bool (*ctlrdy_ack)(struct brcmnand_soc *soc);
2493db446aSBoris Brezillon void (*ctlrdy_set_enabled)(struct brcmnand_soc *soc, bool en);
2593db446aSBoris Brezillon void (*prepare_data_bus)(struct brcmnand_soc *soc, bool prepare,
2693db446aSBoris Brezillon bool is_param);
27*25f97138SFlorian Fainelli const struct brcmnand_io_ops *ops;
28*25f97138SFlorian Fainelli };
29*25f97138SFlorian Fainelli
30*25f97138SFlorian Fainelli struct brcmnand_io_ops {
31*25f97138SFlorian Fainelli u32 (*read_reg)(struct brcmnand_soc *soc, u32 offset);
32*25f97138SFlorian Fainelli void (*write_reg)(struct brcmnand_soc *soc, u32 val, u32 offset);
3393db446aSBoris Brezillon };
3493db446aSBoris Brezillon
brcmnand_soc_data_bus_prepare(struct brcmnand_soc * soc,bool is_param)3593db446aSBoris Brezillon static inline void brcmnand_soc_data_bus_prepare(struct brcmnand_soc *soc,
3693db446aSBoris Brezillon bool is_param)
3793db446aSBoris Brezillon {
3893db446aSBoris Brezillon if (soc && soc->prepare_data_bus)
3993db446aSBoris Brezillon soc->prepare_data_bus(soc, true, is_param);
4093db446aSBoris Brezillon }
4193db446aSBoris Brezillon
brcmnand_soc_data_bus_unprepare(struct brcmnand_soc * soc,bool is_param)4293db446aSBoris Brezillon static inline void brcmnand_soc_data_bus_unprepare(struct brcmnand_soc *soc,
4393db446aSBoris Brezillon bool is_param)
4493db446aSBoris Brezillon {
4593db446aSBoris Brezillon if (soc && soc->prepare_data_bus)
4693db446aSBoris Brezillon soc->prepare_data_bus(soc, false, is_param);
4793db446aSBoris Brezillon }
4893db446aSBoris Brezillon
brcmnand_readl(void __iomem * addr)4993db446aSBoris Brezillon static inline u32 brcmnand_readl(void __iomem *addr)
5093db446aSBoris Brezillon {
5193db446aSBoris Brezillon /*
5293db446aSBoris Brezillon * MIPS endianness is configured by boot strap, which also reverses all
5393db446aSBoris Brezillon * bus endianness (i.e., big-endian CPU + big endian bus ==> native
5493db446aSBoris Brezillon * endian I/O).
5593db446aSBoris Brezillon *
5693db446aSBoris Brezillon * Other architectures (e.g., ARM) either do not support big endian, or
5793db446aSBoris Brezillon * else leave I/O in little endian mode.
5893db446aSBoris Brezillon */
5993db446aSBoris Brezillon if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
6093db446aSBoris Brezillon return __raw_readl(addr);
6193db446aSBoris Brezillon else
6293db446aSBoris Brezillon return readl_relaxed(addr);
6393db446aSBoris Brezillon }
6493db446aSBoris Brezillon
brcmnand_writel(u32 val,void __iomem * addr)6593db446aSBoris Brezillon static inline void brcmnand_writel(u32 val, void __iomem *addr)
6693db446aSBoris Brezillon {
6793db446aSBoris Brezillon /* See brcmnand_readl() comments */
6893db446aSBoris Brezillon if (IS_ENABLED(CONFIG_MIPS) && IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
6993db446aSBoris Brezillon __raw_writel(val, addr);
7093db446aSBoris Brezillon else
7193db446aSBoris Brezillon writel_relaxed(val, addr);
7293db446aSBoris Brezillon }
7393db446aSBoris Brezillon
brcmnand_soc_has_ops(struct brcmnand_soc * soc)74*25f97138SFlorian Fainelli static inline bool brcmnand_soc_has_ops(struct brcmnand_soc *soc)
75*25f97138SFlorian Fainelli {
76*25f97138SFlorian Fainelli return soc && soc->ops && soc->ops->read_reg && soc->ops->write_reg;
77*25f97138SFlorian Fainelli }
78*25f97138SFlorian Fainelli
brcmnand_soc_read(struct brcmnand_soc * soc,u32 offset)79*25f97138SFlorian Fainelli static inline u32 brcmnand_soc_read(struct brcmnand_soc *soc, u32 offset)
80*25f97138SFlorian Fainelli {
81*25f97138SFlorian Fainelli return soc->ops->read_reg(soc, offset);
82*25f97138SFlorian Fainelli }
83*25f97138SFlorian Fainelli
brcmnand_soc_write(struct brcmnand_soc * soc,u32 val,u32 offset)84*25f97138SFlorian Fainelli static inline void brcmnand_soc_write(struct brcmnand_soc *soc, u32 val,
85*25f97138SFlorian Fainelli u32 offset)
86*25f97138SFlorian Fainelli {
87*25f97138SFlorian Fainelli soc->ops->write_reg(soc, val, offset);
88*25f97138SFlorian Fainelli }
89*25f97138SFlorian Fainelli
9093db446aSBoris Brezillon int brcmnand_probe(struct platform_device *pdev, struct brcmnand_soc *soc);
9193db446aSBoris Brezillon int brcmnand_remove(struct platform_device *pdev);
9293db446aSBoris Brezillon
9393db446aSBoris Brezillon extern const struct dev_pm_ops brcmnand_pm_ops;
9493db446aSBoris Brezillon
9593db446aSBoris Brezillon #endif /* __BRCMNAND_H__ */
96