xref: /openbmc/linux/include/linux/logic_pio.h (revision b8104fda)
1031e3601SZhichang Yuan // SPDX-License-Identifier: GPL-2.0+
2031e3601SZhichang Yuan /*
3031e3601SZhichang Yuan  * Copyright (C) 2017 HiSilicon Limited, All Rights Reserved.
4031e3601SZhichang Yuan  * Author: Gabriele Paoloni <gabriele.paoloni@huawei.com>
5031e3601SZhichang Yuan  * Author: Zhichang Yuan <yuanzhichang@hisilicon.com>
6031e3601SZhichang Yuan  */
7031e3601SZhichang Yuan 
8031e3601SZhichang Yuan #ifndef __LINUX_LOGIC_PIO_H
9031e3601SZhichang Yuan #define __LINUX_LOGIC_PIO_H
10031e3601SZhichang Yuan 
11031e3601SZhichang Yuan #include <linux/fwnode.h>
12031e3601SZhichang Yuan 
13031e3601SZhichang Yuan enum {
14031e3601SZhichang Yuan 	LOGIC_PIO_INDIRECT,		/* Indirect IO flag */
15031e3601SZhichang Yuan 	LOGIC_PIO_CPU_MMIO,		/* Memory-mapped IO flag */
16031e3601SZhichang Yuan };
17031e3601SZhichang Yuan 
18031e3601SZhichang Yuan struct logic_pio_hwaddr {
19031e3601SZhichang Yuan 	struct list_head list;
20031e3601SZhichang Yuan 	struct fwnode_handle *fwnode;
21031e3601SZhichang Yuan 	resource_size_t hw_start;
22031e3601SZhichang Yuan 	resource_size_t io_start;
23031e3601SZhichang Yuan 	resource_size_t size; /* range size populated */
24031e3601SZhichang Yuan 	unsigned long flags;
25031e3601SZhichang Yuan 
26031e3601SZhichang Yuan 	void *hostdata;
27031e3601SZhichang Yuan 	const struct logic_pio_host_ops *ops;
28031e3601SZhichang Yuan };
29031e3601SZhichang Yuan 
30031e3601SZhichang Yuan struct logic_pio_host_ops {
31031e3601SZhichang Yuan 	u32 (*in)(void *hostdata, unsigned long addr, size_t dwidth);
32031e3601SZhichang Yuan 	void (*out)(void *hostdata, unsigned long addr, u32 val,
33031e3601SZhichang Yuan 		    size_t dwidth);
34031e3601SZhichang Yuan 	u32 (*ins)(void *hostdata, unsigned long addr, void *buffer,
35031e3601SZhichang Yuan 		   size_t dwidth, unsigned int count);
36031e3601SZhichang Yuan 	void (*outs)(void *hostdata, unsigned long addr, const void *buffer,
37031e3601SZhichang Yuan 		     size_t dwidth, unsigned int count);
38031e3601SZhichang Yuan };
39031e3601SZhichang Yuan 
40031e3601SZhichang Yuan #ifdef CONFIG_INDIRECT_PIO
41031e3601SZhichang Yuan u8 logic_inb(unsigned long addr);
42031e3601SZhichang Yuan void logic_outb(u8 value, unsigned long addr);
43031e3601SZhichang Yuan void logic_outw(u16 value, unsigned long addr);
44031e3601SZhichang Yuan void logic_outl(u32 value, unsigned long addr);
45031e3601SZhichang Yuan u16 logic_inw(unsigned long addr);
46031e3601SZhichang Yuan u32 logic_inl(unsigned long addr);
47031e3601SZhichang Yuan void logic_outb(u8 value, unsigned long addr);
48031e3601SZhichang Yuan void logic_outw(u16 value, unsigned long addr);
49031e3601SZhichang Yuan void logic_outl(u32 value, unsigned long addr);
50031e3601SZhichang Yuan void logic_insb(unsigned long addr, void *buffer, unsigned int count);
51031e3601SZhichang Yuan void logic_insl(unsigned long addr, void *buffer, unsigned int count);
52031e3601SZhichang Yuan void logic_insw(unsigned long addr, void *buffer, unsigned int count);
53031e3601SZhichang Yuan void logic_outsb(unsigned long addr, const void *buffer, unsigned int count);
54031e3601SZhichang Yuan void logic_outsw(unsigned long addr, const void *buffer, unsigned int count);
55031e3601SZhichang Yuan void logic_outsl(unsigned long addr, const void *buffer, unsigned int count);
56031e3601SZhichang Yuan 
57031e3601SZhichang Yuan #ifndef inb
58031e3601SZhichang Yuan #define inb logic_inb
59031e3601SZhichang Yuan #endif
60031e3601SZhichang Yuan 
61031e3601SZhichang Yuan #ifndef inw
62031e3601SZhichang Yuan #define inw logic_inw
63031e3601SZhichang Yuan #endif
64031e3601SZhichang Yuan 
65031e3601SZhichang Yuan #ifndef inl
66031e3601SZhichang Yuan #define inl logic_inl
67031e3601SZhichang Yuan #endif
68031e3601SZhichang Yuan 
69031e3601SZhichang Yuan #ifndef outb
70031e3601SZhichang Yuan #define outb logic_outb
71031e3601SZhichang Yuan #endif
72031e3601SZhichang Yuan 
73031e3601SZhichang Yuan #ifndef outw
74031e3601SZhichang Yuan #define outw logic_outw
75031e3601SZhichang Yuan #endif
76031e3601SZhichang Yuan 
77031e3601SZhichang Yuan #ifndef outl
78031e3601SZhichang Yuan #define outl logic_outl
79031e3601SZhichang Yuan #endif
80031e3601SZhichang Yuan 
81031e3601SZhichang Yuan #ifndef insb
82031e3601SZhichang Yuan #define insb logic_insb
83031e3601SZhichang Yuan #endif
84031e3601SZhichang Yuan 
85031e3601SZhichang Yuan #ifndef insw
86031e3601SZhichang Yuan #define insw logic_insw
87031e3601SZhichang Yuan #endif
88031e3601SZhichang Yuan 
89031e3601SZhichang Yuan #ifndef insl
90031e3601SZhichang Yuan #define insl logic_insl
91031e3601SZhichang Yuan #endif
92031e3601SZhichang Yuan 
93031e3601SZhichang Yuan #ifndef outsb
94031e3601SZhichang Yuan #define outsb logic_outsb
95031e3601SZhichang Yuan #endif
96031e3601SZhichang Yuan 
97031e3601SZhichang Yuan #ifndef outsw
98031e3601SZhichang Yuan #define outsw logic_outsw
99031e3601SZhichang Yuan #endif
100031e3601SZhichang Yuan 
101031e3601SZhichang Yuan #ifndef outsl
102031e3601SZhichang Yuan #define outsl logic_outsl
103031e3601SZhichang Yuan #endif
104031e3601SZhichang Yuan 
105031e3601SZhichang Yuan /*
106031e3601SZhichang Yuan  * We reserve 0x4000 bytes for Indirect IO as so far this library is only
107031e3601SZhichang Yuan  * used by the HiSilicon LPC Host. If needed, we can reserve a wider IO
108031e3601SZhichang Yuan  * area by redefining the macro below.
109031e3601SZhichang Yuan  */
110031e3601SZhichang Yuan #define PIO_INDIRECT_SIZE 0x4000
111031e3601SZhichang Yuan #else
112b8104fdaSJohn Garry #define PIO_INDIRECT_SIZE 0
113031e3601SZhichang Yuan #endif /* CONFIG_INDIRECT_PIO */
114b8104fdaSJohn Garry #define MMIO_UPPER_LIMIT (IO_SPACE_LIMIT - PIO_INDIRECT_SIZE)
115031e3601SZhichang Yuan 
116031e3601SZhichang Yuan struct logic_pio_hwaddr *find_io_range_by_fwnode(struct fwnode_handle *fwnode);
117031e3601SZhichang Yuan unsigned long logic_pio_trans_hwaddr(struct fwnode_handle *fwnode,
118031e3601SZhichang Yuan 			resource_size_t hw_addr, resource_size_t size);
119031e3601SZhichang Yuan int logic_pio_register_range(struct logic_pio_hwaddr *newrange);
120b884e2deSJohn Garry void logic_pio_unregister_range(struct logic_pio_hwaddr *range);
121031e3601SZhichang Yuan resource_size_t logic_pio_to_hwaddr(unsigned long pio);
122031e3601SZhichang Yuan unsigned long logic_pio_trans_cpuaddr(resource_size_t hw_addr);
123031e3601SZhichang Yuan 
124031e3601SZhichang Yuan #endif /* __LINUX_LOGIC_PIO_H */
125