xref: /linux-6.15/include/linux/cb710.h (revision 6b5679d2)
1d2912cb1SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
25f5bac82SMichał Mirosław /*
35f5bac82SMichał Mirosław  *  cb710/cb710.h
45f5bac82SMichał Mirosław  *
55f5bac82SMichał Mirosław  *  Copyright by Michał Mirosław, 2008-2009
65f5bac82SMichał Mirosław  */
75f5bac82SMichał Mirosław #ifndef LINUX_CB710_DRIVER_H
85f5bac82SMichał Mirosław #define LINUX_CB710_DRIVER_H
95f5bac82SMichał Mirosław 
105f5bac82SMichał Mirosław #include <linux/io.h>
115f5bac82SMichał Mirosław #include <linux/interrupt.h>
125f5bac82SMichał Mirosław #include <linux/spinlock.h>
135f5bac82SMichał Mirosław #include <linux/pci.h>
145f5bac82SMichał Mirosław #include <linux/platform_device.h>
155f5bac82SMichał Mirosław #include <linux/mmc/host.h>
165f5bac82SMichał Mirosław 
175f5bac82SMichał Mirosław struct cb710_slot;
185f5bac82SMichał Mirosław 
195f5bac82SMichał Mirosław typedef int (*cb710_irq_handler_t)(struct cb710_slot *);
205f5bac82SMichał Mirosław 
215f5bac82SMichał Mirosław /* per-virtual-slot structure */
225f5bac82SMichał Mirosław struct cb710_slot {
235f5bac82SMichał Mirosław 	struct platform_device	pdev;
245f5bac82SMichał Mirosław 	void __iomem		*iobase;
255f5bac82SMichał Mirosław 	cb710_irq_handler_t	irq_handler;
265f5bac82SMichał Mirosław };
275f5bac82SMichał Mirosław 
285f5bac82SMichał Mirosław /* per-device structure */
295f5bac82SMichał Mirosław struct cb710_chip {
305f5bac82SMichał Mirosław 	struct pci_dev		*pdev;
315f5bac82SMichał Mirosław 	void __iomem		*iobase;
325f5bac82SMichał Mirosław 	unsigned		platform_id;
335f5bac82SMichał Mirosław #ifdef CONFIG_CB710_DEBUG_ASSUMPTIONS
345f5bac82SMichał Mirosław 	atomic_t		slot_refs_count;
355f5bac82SMichał Mirosław #endif
365f5bac82SMichał Mirosław 	unsigned		slot_mask;
375f5bac82SMichał Mirosław 	unsigned		slots;
385f5bac82SMichał Mirosław 	spinlock_t		irq_lock;
39*6b5679d2SGustavo A. R. Silva 	struct cb710_slot	slot[];
405f5bac82SMichał Mirosław };
415f5bac82SMichał Mirosław 
425f5bac82SMichał Mirosław /* NOTE: cb710_chip.slots is modified only during device init/exit and
435f5bac82SMichał Mirosław  * they are all serialized wrt themselves */
445f5bac82SMichał Mirosław 
455f5bac82SMichał Mirosław /* cb710_chip.slot_mask values */
465f5bac82SMichał Mirosław #define CB710_SLOT_MMC		1
475f5bac82SMichał Mirosław #define CB710_SLOT_MS		2
485f5bac82SMichał Mirosław #define CB710_SLOT_SM		4
495f5bac82SMichał Mirosław 
505f5bac82SMichał Mirosław /* slot port accessors - so the logic is more clear in the code */
515f5bac82SMichał Mirosław #define CB710_PORT_ACCESSORS(t) \
525f5bac82SMichał Mirosław static inline void cb710_write_port_##t(struct cb710_slot *slot,	\
535f5bac82SMichał Mirosław 	unsigned port, u##t value)					\
545f5bac82SMichał Mirosław {									\
555f5bac82SMichał Mirosław 	iowrite##t(value, slot->iobase + port);				\
565f5bac82SMichał Mirosław }									\
575f5bac82SMichał Mirosław 									\
585f5bac82SMichał Mirosław static inline u##t cb710_read_port_##t(struct cb710_slot *slot,		\
595f5bac82SMichał Mirosław 	unsigned port)							\
605f5bac82SMichał Mirosław {									\
615f5bac82SMichał Mirosław 	return ioread##t(slot->iobase + port);				\
625f5bac82SMichał Mirosław }									\
635f5bac82SMichał Mirosław 									\
645f5bac82SMichał Mirosław static inline void cb710_modify_port_##t(struct cb710_slot *slot,	\
655f5bac82SMichał Mirosław 	unsigned port, u##t set, u##t clear)				\
665f5bac82SMichał Mirosław {									\
675f5bac82SMichał Mirosław 	iowrite##t(							\
685f5bac82SMichał Mirosław 		(ioread##t(slot->iobase + port) & ~clear)|set,		\
695f5bac82SMichał Mirosław 		slot->iobase + port);					\
705f5bac82SMichał Mirosław }
715f5bac82SMichał Mirosław 
725f5bac82SMichał Mirosław CB710_PORT_ACCESSORS(8)
735f5bac82SMichał Mirosław CB710_PORT_ACCESSORS(16)
745f5bac82SMichał Mirosław CB710_PORT_ACCESSORS(32)
755f5bac82SMichał Mirosław 
765f5bac82SMichał Mirosław void cb710_pci_update_config_reg(struct pci_dev *pdev,
775f5bac82SMichał Mirosław 	int reg, uint32_t and, uint32_t xor);
785f5bac82SMichał Mirosław void cb710_set_irq_handler(struct cb710_slot *slot,
795f5bac82SMichał Mirosław 	cb710_irq_handler_t handler);
805f5bac82SMichał Mirosław 
815f5bac82SMichał Mirosław /* some device struct walking */
825f5bac82SMichał Mirosław 
cb710_pdev_to_slot(struct platform_device * pdev)835f5bac82SMichał Mirosław static inline struct cb710_slot *cb710_pdev_to_slot(
845f5bac82SMichał Mirosław 	struct platform_device *pdev)
855f5bac82SMichał Mirosław {
865f5bac82SMichał Mirosław 	return container_of(pdev, struct cb710_slot, pdev);
875f5bac82SMichał Mirosław }
885f5bac82SMichał Mirosław 
cb710_slot_to_chip(struct cb710_slot * slot)895f5bac82SMichał Mirosław static inline struct cb710_chip *cb710_slot_to_chip(struct cb710_slot *slot)
905f5bac82SMichał Mirosław {
915f5bac82SMichał Mirosław 	return dev_get_drvdata(slot->pdev.dev.parent);
925f5bac82SMichał Mirosław }
935f5bac82SMichał Mirosław 
cb710_slot_dev(struct cb710_slot * slot)945f5bac82SMichał Mirosław static inline struct device *cb710_slot_dev(struct cb710_slot *slot)
955f5bac82SMichał Mirosław {
965f5bac82SMichał Mirosław 	return &slot->pdev.dev;
975f5bac82SMichał Mirosław }
985f5bac82SMichał Mirosław 
cb710_chip_dev(struct cb710_chip * chip)995f5bac82SMichał Mirosław static inline struct device *cb710_chip_dev(struct cb710_chip *chip)
1005f5bac82SMichał Mirosław {
1015f5bac82SMichał Mirosław 	return &chip->pdev->dev;
1025f5bac82SMichał Mirosław }
1035f5bac82SMichał Mirosław 
1045f5bac82SMichał Mirosław /* debugging aids */
1055f5bac82SMichał Mirosław 
1065f5bac82SMichał Mirosław #ifdef CONFIG_CB710_DEBUG
1075f5bac82SMichał Mirosław void cb710_dump_regs(struct cb710_chip *chip, unsigned dump);
1085f5bac82SMichał Mirosław #else
1095f5bac82SMichał Mirosław #define cb710_dump_regs(c, d) do {} while (0)
1105f5bac82SMichał Mirosław #endif
1115f5bac82SMichał Mirosław 
1125f5bac82SMichał Mirosław #define CB710_DUMP_REGS_MMC	0x0F
1135f5bac82SMichał Mirosław #define CB710_DUMP_REGS_MS	0x30
1145f5bac82SMichał Mirosław #define CB710_DUMP_REGS_SM	0xC0
1155f5bac82SMichał Mirosław #define CB710_DUMP_REGS_ALL	0xFF
1165f5bac82SMichał Mirosław #define CB710_DUMP_REGS_MASK	0xFF
1175f5bac82SMichał Mirosław 
1185f5bac82SMichał Mirosław #define CB710_DUMP_ACCESS_8	0x100
1195f5bac82SMichał Mirosław #define CB710_DUMP_ACCESS_16	0x200
1205f5bac82SMichał Mirosław #define CB710_DUMP_ACCESS_32	0x400
1215f5bac82SMichał Mirosław #define CB710_DUMP_ACCESS_ALL	0x700
1225f5bac82SMichał Mirosław #define CB710_DUMP_ACCESS_MASK	0x700
1235f5bac82SMichał Mirosław 
1245f5bac82SMichał Mirosław #endif /* LINUX_CB710_DRIVER_H */
1255f5bac82SMichał Mirosław /*
1265f5bac82SMichał Mirosław  *  cb710/sgbuf2.h
1275f5bac82SMichał Mirosław  *
1285f5bac82SMichał Mirosław  *  Copyright by Michał Mirosław, 2008-2009
1295f5bac82SMichał Mirosław  */
1305f5bac82SMichał Mirosław #ifndef LINUX_CB710_SG_H
1315f5bac82SMichał Mirosław #define LINUX_CB710_SG_H
1325f5bac82SMichał Mirosław 
1335f5bac82SMichał Mirosław #include <linux/highmem.h>
1345f5bac82SMichał Mirosław #include <linux/scatterlist.h>
1355f5bac82SMichał Mirosław 
1365f5bac82SMichał Mirosław /*
1375f5bac82SMichał Mirosław  * 32-bit PIO mapping sg iterator
1385f5bac82SMichał Mirosław  *
1395f5bac82SMichał Mirosław  * Hides scatterlist access issues - fragment boundaries, alignment, page
1405f5bac82SMichał Mirosław  * mapping - for drivers using 32-bit-word-at-a-time-PIO (ie. PCI devices
1415f5bac82SMichał Mirosław  * without DMA support).
1425f5bac82SMichał Mirosław  *
1435f5bac82SMichał Mirosław  * Best-case reading (transfer from device):
1444b2a108cSSebastian Andrzej Siewior  *   sg_miter_start(, SG_MITER_TO_SG);
1455f5bac82SMichał Mirosław  *   cb710_sg_dwiter_write_from_io();
1464b2a108cSSebastian Andrzej Siewior  *   sg_miter_stop();
1475f5bac82SMichał Mirosław  *
1485f5bac82SMichał Mirosław  * Best-case writing (transfer to device):
1494b2a108cSSebastian Andrzej Siewior  *   sg_miter_start(, SG_MITER_FROM_SG);
1505f5bac82SMichał Mirosław  *   cb710_sg_dwiter_read_to_io();
1515f5bac82SMichał Mirosław  *   sg_miter_stop();
1525f5bac82SMichał Mirosław  */
1535f5bac82SMichał Mirosław 
1545f5bac82SMichał Mirosław uint32_t cb710_sg_dwiter_read_next_block(struct sg_mapping_iter *miter);
1555f5bac82SMichał Mirosław void cb710_sg_dwiter_write_next_block(struct sg_mapping_iter *miter, uint32_t data);
1565f5bac82SMichał Mirosław 
1575f5bac82SMichał Mirosław /**
1585f5bac82SMichał Mirosław  * cb710_sg_dwiter_write_from_io - transfer data to mapped buffer from 32-bit IO port
1595f5bac82SMichał Mirosław  * @miter: sg mapping iter
1605f5bac82SMichał Mirosław  * @port: PIO port - IO or MMIO address
1615f5bac82SMichał Mirosław  * @count: number of 32-bit words to transfer
1625f5bac82SMichał Mirosław  *
1635f5bac82SMichał Mirosław  * Description:
1645f5bac82SMichał Mirosław  *   Reads @count 32-bit words from register @port and stores it in
1655f5bac82SMichał Mirosław  *   buffer iterated by @miter.  Data that would overflow the buffer
1665f5bac82SMichał Mirosław  *   is silently ignored.  Iterator is advanced by 4*@count bytes
1675f5bac82SMichał Mirosław  *   or to the buffer's end whichever is closer.
1685f5bac82SMichał Mirosław  *
1695f5bac82SMichał Mirosław  * Context:
1705f5bac82SMichał Mirosław  *   IRQ disabled if the SG_MITER_ATOMIC is set.  Don't care otherwise.
1715f5bac82SMichał Mirosław  */
cb710_sg_dwiter_write_from_io(struct sg_mapping_iter * miter,void __iomem * port,size_t count)1725f5bac82SMichał Mirosław static inline void cb710_sg_dwiter_write_from_io(struct sg_mapping_iter *miter,
1735f5bac82SMichał Mirosław 	void __iomem *port, size_t count)
1745f5bac82SMichał Mirosław {
1755f5bac82SMichał Mirosław 	while (count-- > 0)
1765f5bac82SMichał Mirosław 		cb710_sg_dwiter_write_next_block(miter, ioread32(port));
1775f5bac82SMichał Mirosław }
1785f5bac82SMichał Mirosław 
1795f5bac82SMichał Mirosław /**
1805f5bac82SMichał Mirosław  * cb710_sg_dwiter_read_to_io - transfer data to 32-bit IO port from mapped buffer
1815f5bac82SMichał Mirosław  * @miter: sg mapping iter
1825f5bac82SMichał Mirosław  * @port: PIO port - IO or MMIO address
1835f5bac82SMichał Mirosław  * @count: number of 32-bit words to transfer
1845f5bac82SMichał Mirosław  *
1855f5bac82SMichał Mirosław  * Description:
1865f5bac82SMichał Mirosław  *   Writes @count 32-bit words to register @port from buffer iterated
1875f5bac82SMichał Mirosław  *   through @miter.  If buffer ends before @count words are written
1885f5bac82SMichał Mirosław  *   missing data is replaced by zeroes. @miter is advanced by 4*@count
1895f5bac82SMichał Mirosław  *   bytes or to the buffer's end whichever is closer.
1905f5bac82SMichał Mirosław  *
1915f5bac82SMichał Mirosław  * Context:
1925f5bac82SMichał Mirosław  *   IRQ disabled if the SG_MITER_ATOMIC is set.  Don't care otherwise.
1935f5bac82SMichał Mirosław  */
cb710_sg_dwiter_read_to_io(struct sg_mapping_iter * miter,void __iomem * port,size_t count)1945f5bac82SMichał Mirosław static inline void cb710_sg_dwiter_read_to_io(struct sg_mapping_iter *miter,
1955f5bac82SMichał Mirosław 	void __iomem *port, size_t count)
1965f5bac82SMichał Mirosław {
1975f5bac82SMichał Mirosław 	while (count-- > 0)
1985f5bac82SMichał Mirosław 		iowrite32(cb710_sg_dwiter_read_next_block(miter), port);
1995f5bac82SMichał Mirosław }
2005f5bac82SMichał Mirosław 
2015f5bac82SMichał Mirosław #endif /* LINUX_CB710_SG_H */
202