Mention branches and keyring.
[releases.git] / include / asm / pci_io.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _ASM_S390_PCI_IO_H
3 #define _ASM_S390_PCI_IO_H
4
5 #ifdef CONFIG_PCI
6
7 #include <linux/kernel.h>
8 #include <linux/slab.h>
9 #include <asm/pci_insn.h>
10
11 /* I/O size constraints */
12 #define ZPCI_MAX_READ_SIZE      8
13 #define ZPCI_MAX_WRITE_SIZE     128
14 #define ZPCI_BOUNDARY_SIZE      (1 << 12)
15 #define ZPCI_BOUNDARY_MASK      (ZPCI_BOUNDARY_SIZE - 1)
16
17 /* I/O Map */
18 #define ZPCI_IOMAP_SHIFT                48
19 #define ZPCI_IOMAP_ADDR_SHIFT           62
20 #define ZPCI_IOMAP_ADDR_BASE            (1UL << ZPCI_IOMAP_ADDR_SHIFT)
21 #define ZPCI_IOMAP_ADDR_OFF_MASK        ((1UL << ZPCI_IOMAP_SHIFT) - 1)
22 #define ZPCI_IOMAP_MAX_ENTRIES                                                  \
23         (1UL << (ZPCI_IOMAP_ADDR_SHIFT - ZPCI_IOMAP_SHIFT))
24 #define ZPCI_IOMAP_ADDR_IDX_MASK                                                \
25         ((ZPCI_IOMAP_ADDR_BASE - 1) & ~ZPCI_IOMAP_ADDR_OFF_MASK)
26
27 struct zpci_iomap_entry {
28         u32 fh;
29         u8 bar;
30         u16 count;
31 };
32
33 extern struct zpci_iomap_entry *zpci_iomap_start;
34
35 #define ZPCI_ADDR(idx) (ZPCI_IOMAP_ADDR_BASE | ((u64) idx << ZPCI_IOMAP_SHIFT))
36 #define ZPCI_IDX(addr)                                                          \
37         (((__force u64) addr & ZPCI_IOMAP_ADDR_IDX_MASK) >> ZPCI_IOMAP_SHIFT)
38 #define ZPCI_OFFSET(addr)                                                       \
39         ((__force u64) addr & ZPCI_IOMAP_ADDR_OFF_MASK)
40
41 #define ZPCI_CREATE_REQ(handle, space, len)                                     \
42         ((u64) handle << 32 | space << 16 | len)
43
44 #define zpci_read(LENGTH, RETTYPE)                                              \
45 static inline RETTYPE zpci_read_##RETTYPE(const volatile void __iomem *addr)    \
46 {                                                                               \
47         u64 data;                                                               \
48         int rc;                                                                 \
49                                                                                 \
50         rc = zpci_load(&data, addr, LENGTH);                                    \
51         if (rc)                                                                 \
52                 data = -1ULL;                                                   \
53         return (RETTYPE) data;                                                  \
54 }
55
56 #define zpci_write(LENGTH, VALTYPE)                                             \
57 static inline void zpci_write_##VALTYPE(VALTYPE val,                            \
58                                         const volatile void __iomem *addr)      \
59 {                                                                               \
60         u64 data = (VALTYPE) val;                                               \
61                                                                                 \
62         zpci_store(addr, data, LENGTH);                                         \
63 }
64
65 zpci_read(8, u64)
66 zpci_read(4, u32)
67 zpci_read(2, u16)
68 zpci_read(1, u8)
69 zpci_write(8, u64)
70 zpci_write(4, u32)
71 zpci_write(2, u16)
72 zpci_write(1, u8)
73
74 static inline int zpci_write_single(volatile void __iomem *dst, const void *src,
75                                     unsigned long len)
76 {
77         u64 val;
78
79         switch (len) {
80         case 1:
81                 val = (u64) *((u8 *) src);
82                 break;
83         case 2:
84                 val = (u64) *((u16 *) src);
85                 break;
86         case 4:
87                 val = (u64) *((u32 *) src);
88                 break;
89         case 8:
90                 val = (u64) *((u64 *) src);
91                 break;
92         default:
93                 val = 0;                /* let FW report error */
94                 break;
95         }
96         return zpci_store(dst, val, len);
97 }
98
99 static inline int zpci_read_single(void *dst, const volatile void __iomem *src,
100                                    unsigned long len)
101 {
102         u64 data;
103         int cc;
104
105         cc = zpci_load(&data, src, len);
106         if (cc)
107                 goto out;
108
109         switch (len) {
110         case 1:
111                 *((u8 *) dst) = (u8) data;
112                 break;
113         case 2:
114                 *((u16 *) dst) = (u16) data;
115                 break;
116         case 4:
117                 *((u32 *) dst) = (u32) data;
118                 break;
119         case 8:
120                 *((u64 *) dst) = (u64) data;
121                 break;
122         }
123 out:
124         return cc;
125 }
126
127 int zpci_write_block(volatile void __iomem *dst, const void *src,
128                      unsigned long len);
129
130 static inline int zpci_get_max_io_size(u64 src, u64 dst, int len, int max)
131 {
132         int offset = dst & ZPCI_BOUNDARY_MASK;
133         int size;
134
135         size = min3(len, ZPCI_BOUNDARY_SIZE - offset, max);
136         if (IS_ALIGNED(src, 8) && IS_ALIGNED(dst, 8) && IS_ALIGNED(size, 8))
137                 return size;
138
139         if (size >= 8)
140                 return 8;
141         return rounddown_pow_of_two(size);
142 }
143
144 static inline int zpci_memcpy_fromio(void *dst,
145                                      const volatile void __iomem *src,
146                                      unsigned long n)
147 {
148         int size, rc = 0;
149
150         while (n > 0) {
151                 size = zpci_get_max_io_size((u64 __force) src,
152                                             (u64) dst, n,
153                                             ZPCI_MAX_READ_SIZE);
154                 rc = zpci_read_single(dst, src, size);
155                 if (rc)
156                         break;
157                 src += size;
158                 dst += size;
159                 n -= size;
160         }
161         return rc;
162 }
163
164 static inline int zpci_memcpy_toio(volatile void __iomem *dst,
165                                    const void *src, unsigned long n)
166 {
167         int size, rc = 0;
168
169         if (!src)
170                 return -EINVAL;
171
172         while (n > 0) {
173                 size = zpci_get_max_io_size((u64 __force) dst,
174                                             (u64) src, n,
175                                             ZPCI_MAX_WRITE_SIZE);
176                 if (size > 8) /* main path */
177                         rc = zpci_write_block(dst, src, size);
178                 else
179                         rc = zpci_write_single(dst, src, size);
180                 if (rc)
181                         break;
182                 src += size;
183                 dst += size;
184                 n -= size;
185         }
186         return rc;
187 }
188
189 static inline int zpci_memset_io(volatile void __iomem *dst,
190                                  unsigned char val, size_t count)
191 {
192         u8 *src = kmalloc(count, GFP_KERNEL);
193         int rc;
194
195         if (src == NULL)
196                 return -ENOMEM;
197         memset(src, val, count);
198
199         rc = zpci_memcpy_toio(dst, src, count);
200         kfree(src);
201         return rc;
202 }
203
204 #endif /* CONFIG_PCI */
205
206 #endif /* _ASM_S390_PCI_IO_H */