Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 // Copyright 2019 IBM Corp.
0003 #include <linux/sched/mm.h>
0004 #include "trace.h"
0005 #include "ocxl_internal.h"
0006 
0007 int ocxl_global_mmio_read32(struct ocxl_afu *afu, size_t offset,
0008                 enum ocxl_endian endian, u32 *val)
0009 {
0010     if (offset > afu->config.global_mmio_size - 4)
0011         return -EINVAL;
0012 
0013 #ifdef __BIG_ENDIAN__
0014     if (endian == OCXL_HOST_ENDIAN)
0015         endian = OCXL_BIG_ENDIAN;
0016 #endif
0017 
0018     switch (endian) {
0019     case OCXL_BIG_ENDIAN:
0020         *val = readl_be((char *)afu->global_mmio_ptr + offset);
0021         break;
0022 
0023     default:
0024         *val = readl((char *)afu->global_mmio_ptr + offset);
0025         break;
0026     }
0027 
0028     return 0;
0029 }
0030 EXPORT_SYMBOL_GPL(ocxl_global_mmio_read32);
0031 
0032 int ocxl_global_mmio_read64(struct ocxl_afu *afu, size_t offset,
0033                 enum ocxl_endian endian, u64 *val)
0034 {
0035     if (offset > afu->config.global_mmio_size - 8)
0036         return -EINVAL;
0037 
0038 #ifdef __BIG_ENDIAN__
0039     if (endian == OCXL_HOST_ENDIAN)
0040         endian = OCXL_BIG_ENDIAN;
0041 #endif
0042 
0043     switch (endian) {
0044     case OCXL_BIG_ENDIAN:
0045         *val = readq_be((char *)afu->global_mmio_ptr + offset);
0046         break;
0047 
0048     default:
0049         *val = readq((char *)afu->global_mmio_ptr + offset);
0050         break;
0051     }
0052 
0053     return 0;
0054 }
0055 EXPORT_SYMBOL_GPL(ocxl_global_mmio_read64);
0056 
0057 int ocxl_global_mmio_write32(struct ocxl_afu *afu, size_t offset,
0058                 enum ocxl_endian endian, u32 val)
0059 {
0060     if (offset > afu->config.global_mmio_size - 4)
0061         return -EINVAL;
0062 
0063 #ifdef __BIG_ENDIAN__
0064     if (endian == OCXL_HOST_ENDIAN)
0065         endian = OCXL_BIG_ENDIAN;
0066 #endif
0067 
0068     switch (endian) {
0069     case OCXL_BIG_ENDIAN:
0070         writel_be(val, (char *)afu->global_mmio_ptr + offset);
0071         break;
0072 
0073     default:
0074         writel(val, (char *)afu->global_mmio_ptr + offset);
0075         break;
0076     }
0077 
0078 
0079     return 0;
0080 }
0081 EXPORT_SYMBOL_GPL(ocxl_global_mmio_write32);
0082 
0083 int ocxl_global_mmio_write64(struct ocxl_afu *afu, size_t offset,
0084                 enum ocxl_endian endian, u64 val)
0085 {
0086     if (offset > afu->config.global_mmio_size - 8)
0087         return -EINVAL;
0088 
0089 #ifdef __BIG_ENDIAN__
0090     if (endian == OCXL_HOST_ENDIAN)
0091         endian = OCXL_BIG_ENDIAN;
0092 #endif
0093 
0094     switch (endian) {
0095     case OCXL_BIG_ENDIAN:
0096         writeq_be(val, (char *)afu->global_mmio_ptr + offset);
0097         break;
0098 
0099     default:
0100         writeq(val, (char *)afu->global_mmio_ptr + offset);
0101         break;
0102     }
0103 
0104 
0105     return 0;
0106 }
0107 EXPORT_SYMBOL_GPL(ocxl_global_mmio_write64);
0108 
0109 int ocxl_global_mmio_set32(struct ocxl_afu *afu, size_t offset,
0110                 enum ocxl_endian endian, u32 mask)
0111 {
0112     u32 tmp;
0113 
0114     if (offset > afu->config.global_mmio_size - 4)
0115         return -EINVAL;
0116 
0117 #ifdef __BIG_ENDIAN__
0118     if (endian == OCXL_HOST_ENDIAN)
0119         endian = OCXL_BIG_ENDIAN;
0120 #endif
0121 
0122     switch (endian) {
0123     case OCXL_BIG_ENDIAN:
0124         tmp = readl_be((char *)afu->global_mmio_ptr + offset);
0125         tmp |= mask;
0126         writel_be(tmp, (char *)afu->global_mmio_ptr + offset);
0127         break;
0128 
0129     default:
0130         tmp = readl((char *)afu->global_mmio_ptr + offset);
0131         tmp |= mask;
0132         writel(tmp, (char *)afu->global_mmio_ptr + offset);
0133         break;
0134     }
0135 
0136     return 0;
0137 }
0138 EXPORT_SYMBOL_GPL(ocxl_global_mmio_set32);
0139 
0140 int ocxl_global_mmio_set64(struct ocxl_afu *afu, size_t offset,
0141                 enum ocxl_endian endian, u64 mask)
0142 {
0143     u64 tmp;
0144 
0145     if (offset > afu->config.global_mmio_size - 8)
0146         return -EINVAL;
0147 
0148 #ifdef __BIG_ENDIAN__
0149     if (endian == OCXL_HOST_ENDIAN)
0150         endian = OCXL_BIG_ENDIAN;
0151 #endif
0152 
0153     switch (endian) {
0154     case OCXL_BIG_ENDIAN:
0155         tmp = readq_be((char *)afu->global_mmio_ptr + offset);
0156         tmp |= mask;
0157         writeq_be(tmp, (char *)afu->global_mmio_ptr + offset);
0158         break;
0159 
0160     default:
0161         tmp = readq((char *)afu->global_mmio_ptr + offset);
0162         tmp |= mask;
0163         writeq(tmp, (char *)afu->global_mmio_ptr + offset);
0164         break;
0165     }
0166 
0167     return 0;
0168 }
0169 EXPORT_SYMBOL_GPL(ocxl_global_mmio_set64);
0170 
0171 int ocxl_global_mmio_clear32(struct ocxl_afu *afu, size_t offset,
0172                 enum ocxl_endian endian, u32 mask)
0173 {
0174     u32 tmp;
0175 
0176     if (offset > afu->config.global_mmio_size - 4)
0177         return -EINVAL;
0178 
0179 #ifdef __BIG_ENDIAN__
0180     if (endian == OCXL_HOST_ENDIAN)
0181         endian = OCXL_BIG_ENDIAN;
0182 #endif
0183 
0184     switch (endian) {
0185     case OCXL_BIG_ENDIAN:
0186         tmp = readl_be((char *)afu->global_mmio_ptr + offset);
0187         tmp &= ~mask;
0188         writel_be(tmp, (char *)afu->global_mmio_ptr + offset);
0189         break;
0190 
0191     default:
0192         tmp = readl((char *)afu->global_mmio_ptr + offset);
0193         tmp &= ~mask;
0194         writel(tmp, (char *)afu->global_mmio_ptr + offset);
0195         break;
0196     }
0197 
0198 
0199     return 0;
0200 }
0201 EXPORT_SYMBOL_GPL(ocxl_global_mmio_clear32);
0202 
0203 int ocxl_global_mmio_clear64(struct ocxl_afu *afu, size_t offset,
0204                 enum ocxl_endian endian, u64 mask)
0205 {
0206     u64 tmp;
0207 
0208     if (offset > afu->config.global_mmio_size - 8)
0209         return -EINVAL;
0210 
0211 #ifdef __BIG_ENDIAN__
0212     if (endian == OCXL_HOST_ENDIAN)
0213         endian = OCXL_BIG_ENDIAN;
0214 #endif
0215 
0216     switch (endian) {
0217     case OCXL_BIG_ENDIAN:
0218         tmp = readq_be((char *)afu->global_mmio_ptr + offset);
0219         tmp &= ~mask;
0220         writeq_be(tmp, (char *)afu->global_mmio_ptr + offset);
0221         break;
0222 
0223     default:
0224         tmp = readq((char *)afu->global_mmio_ptr + offset);
0225         tmp &= ~mask;
0226         writeq(tmp, (char *)afu->global_mmio_ptr + offset);
0227         break;
0228     }
0229 
0230     writeq(tmp, (char *)afu->global_mmio_ptr + offset);
0231 
0232     return 0;
0233 }
0234 EXPORT_SYMBOL_GPL(ocxl_global_mmio_clear64);