Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0 */
0002 #ifndef _ASM_S390_PCI_IO_H
0003 #define _ASM_S390_PCI_IO_H
0004 
0005 #ifdef CONFIG_PCI
0006 
0007 #include <linux/kernel.h>
0008 #include <linux/slab.h>
0009 #include <asm/pci_insn.h>
0010 
0011 /* I/O size constraints */
0012 #define ZPCI_MAX_READ_SIZE  8
0013 #define ZPCI_MAX_WRITE_SIZE 128
0014 
0015 /* I/O Map */
0016 #define ZPCI_IOMAP_SHIFT        48
0017 #define ZPCI_IOMAP_ADDR_SHIFT       62
0018 #define ZPCI_IOMAP_ADDR_BASE        (1UL << ZPCI_IOMAP_ADDR_SHIFT)
0019 #define ZPCI_IOMAP_ADDR_OFF_MASK    ((1UL << ZPCI_IOMAP_SHIFT) - 1)
0020 #define ZPCI_IOMAP_MAX_ENTRIES                          \
0021     (1UL << (ZPCI_IOMAP_ADDR_SHIFT - ZPCI_IOMAP_SHIFT))
0022 #define ZPCI_IOMAP_ADDR_IDX_MASK                        \
0023     ((ZPCI_IOMAP_ADDR_BASE - 1) & ~ZPCI_IOMAP_ADDR_OFF_MASK)
0024 
0025 struct zpci_iomap_entry {
0026     u32 fh;
0027     u8 bar;
0028     u16 count;
0029 };
0030 
0031 extern struct zpci_iomap_entry *zpci_iomap_start;
0032 
0033 #define ZPCI_ADDR(idx) (ZPCI_IOMAP_ADDR_BASE | ((u64) idx << ZPCI_IOMAP_SHIFT))
0034 #define ZPCI_IDX(addr)                              \
0035     (((__force u64) addr & ZPCI_IOMAP_ADDR_IDX_MASK) >> ZPCI_IOMAP_SHIFT)
0036 #define ZPCI_OFFSET(addr)                           \
0037     ((__force u64) addr & ZPCI_IOMAP_ADDR_OFF_MASK)
0038 
0039 #define ZPCI_CREATE_REQ(handle, space, len)                 \
0040     ((u64) handle << 32 | space << 16 | len)
0041 
0042 #define zpci_read(LENGTH, RETTYPE)                      \
0043 static inline RETTYPE zpci_read_##RETTYPE(const volatile void __iomem *addr)    \
0044 {                                       \
0045     u64 data;                               \
0046     int rc;                                 \
0047                                         \
0048     rc = zpci_load(&data, addr, LENGTH);                    \
0049     if (rc)                                 \
0050         data = -1ULL;                           \
0051     return (RETTYPE) data;                          \
0052 }
0053 
0054 #define zpci_write(LENGTH, VALTYPE)                     \
0055 static inline void zpci_write_##VALTYPE(VALTYPE val,                \
0056                     const volatile void __iomem *addr)  \
0057 {                                       \
0058     u64 data = (VALTYPE) val;                       \
0059                                         \
0060     zpci_store(addr, data, LENGTH);                     \
0061 }
0062 
0063 zpci_read(8, u64)
0064 zpci_read(4, u32)
0065 zpci_read(2, u16)
0066 zpci_read(1, u8)
0067 zpci_write(8, u64)
0068 zpci_write(4, u32)
0069 zpci_write(2, u16)
0070 zpci_write(1, u8)
0071 
0072 static inline int zpci_write_single(volatile void __iomem *dst, const void *src,
0073                     unsigned long len)
0074 {
0075     u64 val;
0076 
0077     switch (len) {
0078     case 1:
0079         val = (u64) *((u8 *) src);
0080         break;
0081     case 2:
0082         val = (u64) *((u16 *) src);
0083         break;
0084     case 4:
0085         val = (u64) *((u32 *) src);
0086         break;
0087     case 8:
0088         val = (u64) *((u64 *) src);
0089         break;
0090     default:
0091         val = 0;        /* let FW report error */
0092         break;
0093     }
0094     return zpci_store(dst, val, len);
0095 }
0096 
0097 static inline int zpci_read_single(void *dst, const volatile void __iomem *src,
0098                    unsigned long len)
0099 {
0100     u64 data;
0101     int cc;
0102 
0103     cc = zpci_load(&data, src, len);
0104     if (cc)
0105         goto out;
0106 
0107     switch (len) {
0108     case 1:
0109         *((u8 *) dst) = (u8) data;
0110         break;
0111     case 2:
0112         *((u16 *) dst) = (u16) data;
0113         break;
0114     case 4:
0115         *((u32 *) dst) = (u32) data;
0116         break;
0117     case 8:
0118         *((u64 *) dst) = (u64) data;
0119         break;
0120     }
0121 out:
0122     return cc;
0123 }
0124 
0125 int zpci_write_block(volatile void __iomem *dst, const void *src,
0126              unsigned long len);
0127 
0128 static inline u8 zpci_get_max_write_size(u64 src, u64 dst, int len, int max)
0129 {
0130     int count = len > max ? max : len, size = 1;
0131 
0132     while (!(src & 0x1) && !(dst & 0x1) && ((size << 1) <= count)) {
0133         dst = dst >> 1;
0134         src = src >> 1;
0135         size = size << 1;
0136     }
0137     return size;
0138 }
0139 
0140 static inline int zpci_memcpy_fromio(void *dst,
0141                      const volatile void __iomem *src,
0142                      unsigned long n)
0143 {
0144     int size, rc = 0;
0145 
0146     while (n > 0) {
0147         size = zpci_get_max_write_size((u64 __force) src,
0148                            (u64) dst, n,
0149                            ZPCI_MAX_READ_SIZE);
0150         rc = zpci_read_single(dst, src, size);
0151         if (rc)
0152             break;
0153         src += size;
0154         dst += size;
0155         n -= size;
0156     }
0157     return rc;
0158 }
0159 
0160 static inline int zpci_memcpy_toio(volatile void __iomem *dst,
0161                    const void *src, unsigned long n)
0162 {
0163     int size, rc = 0;
0164 
0165     if (!src)
0166         return -EINVAL;
0167 
0168     while (n > 0) {
0169         size = zpci_get_max_write_size((u64 __force) dst,
0170                            (u64) src, n,
0171                            ZPCI_MAX_WRITE_SIZE);
0172         if (size > 8) /* main path */
0173             rc = zpci_write_block(dst, src, size);
0174         else
0175             rc = zpci_write_single(dst, src, size);
0176         if (rc)
0177             break;
0178         src += size;
0179         dst += size;
0180         n -= size;
0181     }
0182     return rc;
0183 }
0184 
0185 static inline int zpci_memset_io(volatile void __iomem *dst,
0186                  unsigned char val, size_t count)
0187 {
0188     u8 *src = kmalloc(count, GFP_KERNEL);
0189     int rc;
0190 
0191     if (src == NULL)
0192         return -ENOMEM;
0193     memset(src, val, count);
0194 
0195     rc = zpci_memcpy_toio(dst, src, count);
0196     kfree(src);
0197     return rc;
0198 }
0199 
0200 #endif /* CONFIG_PCI */
0201 
0202 #endif /* _ASM_S390_PCI_IO_H */