mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
234 lines
4.8 KiB
234 lines
4.8 KiB
// SPDX-License-Identifier: GPL-2.0+ |
|
// Copyright 2019 IBM Corp. |
|
#include <linux/sched/mm.h> |
|
#include "trace.h" |
|
#include "ocxl_internal.h" |
|
|
|
int ocxl_global_mmio_read32(struct ocxl_afu *afu, size_t offset, |
|
enum ocxl_endian endian, u32 *val) |
|
{ |
|
if (offset > afu->config.global_mmio_size - 4) |
|
return -EINVAL; |
|
|
|
#ifdef __BIG_ENDIAN__ |
|
if (endian == OCXL_HOST_ENDIAN) |
|
endian = OCXL_BIG_ENDIAN; |
|
#endif |
|
|
|
switch (endian) { |
|
case OCXL_BIG_ENDIAN: |
|
*val = readl_be((char *)afu->global_mmio_ptr + offset); |
|
break; |
|
|
|
default: |
|
*val = readl((char *)afu->global_mmio_ptr + offset); |
|
break; |
|
} |
|
|
|
return 0; |
|
} |
|
EXPORT_SYMBOL_GPL(ocxl_global_mmio_read32); |
|
|
|
int ocxl_global_mmio_read64(struct ocxl_afu *afu, size_t offset, |
|
enum ocxl_endian endian, u64 *val) |
|
{ |
|
if (offset > afu->config.global_mmio_size - 8) |
|
return -EINVAL; |
|
|
|
#ifdef __BIG_ENDIAN__ |
|
if (endian == OCXL_HOST_ENDIAN) |
|
endian = OCXL_BIG_ENDIAN; |
|
#endif |
|
|
|
switch (endian) { |
|
case OCXL_BIG_ENDIAN: |
|
*val = readq_be((char *)afu->global_mmio_ptr + offset); |
|
break; |
|
|
|
default: |
|
*val = readq((char *)afu->global_mmio_ptr + offset); |
|
break; |
|
} |
|
|
|
return 0; |
|
} |
|
EXPORT_SYMBOL_GPL(ocxl_global_mmio_read64); |
|
|
|
int ocxl_global_mmio_write32(struct ocxl_afu *afu, size_t offset, |
|
enum ocxl_endian endian, u32 val) |
|
{ |
|
if (offset > afu->config.global_mmio_size - 4) |
|
return -EINVAL; |
|
|
|
#ifdef __BIG_ENDIAN__ |
|
if (endian == OCXL_HOST_ENDIAN) |
|
endian = OCXL_BIG_ENDIAN; |
|
#endif |
|
|
|
switch (endian) { |
|
case OCXL_BIG_ENDIAN: |
|
writel_be(val, (char *)afu->global_mmio_ptr + offset); |
|
break; |
|
|
|
default: |
|
writel(val, (char *)afu->global_mmio_ptr + offset); |
|
break; |
|
} |
|
|
|
|
|
return 0; |
|
} |
|
EXPORT_SYMBOL_GPL(ocxl_global_mmio_write32); |
|
|
|
int ocxl_global_mmio_write64(struct ocxl_afu *afu, size_t offset, |
|
enum ocxl_endian endian, u64 val) |
|
{ |
|
if (offset > afu->config.global_mmio_size - 8) |
|
return -EINVAL; |
|
|
|
#ifdef __BIG_ENDIAN__ |
|
if (endian == OCXL_HOST_ENDIAN) |
|
endian = OCXL_BIG_ENDIAN; |
|
#endif |
|
|
|
switch (endian) { |
|
case OCXL_BIG_ENDIAN: |
|
writeq_be(val, (char *)afu->global_mmio_ptr + offset); |
|
break; |
|
|
|
default: |
|
writeq(val, (char *)afu->global_mmio_ptr + offset); |
|
break; |
|
} |
|
|
|
|
|
return 0; |
|
} |
|
EXPORT_SYMBOL_GPL(ocxl_global_mmio_write64); |
|
|
|
int ocxl_global_mmio_set32(struct ocxl_afu *afu, size_t offset, |
|
enum ocxl_endian endian, u32 mask) |
|
{ |
|
u32 tmp; |
|
|
|
if (offset > afu->config.global_mmio_size - 4) |
|
return -EINVAL; |
|
|
|
#ifdef __BIG_ENDIAN__ |
|
if (endian == OCXL_HOST_ENDIAN) |
|
endian = OCXL_BIG_ENDIAN; |
|
#endif |
|
|
|
switch (endian) { |
|
case OCXL_BIG_ENDIAN: |
|
tmp = readl_be((char *)afu->global_mmio_ptr + offset); |
|
tmp |= mask; |
|
writel_be(tmp, (char *)afu->global_mmio_ptr + offset); |
|
break; |
|
|
|
default: |
|
tmp = readl((char *)afu->global_mmio_ptr + offset); |
|
tmp |= mask; |
|
writel(tmp, (char *)afu->global_mmio_ptr + offset); |
|
break; |
|
} |
|
|
|
return 0; |
|
} |
|
EXPORT_SYMBOL_GPL(ocxl_global_mmio_set32); |
|
|
|
int ocxl_global_mmio_set64(struct ocxl_afu *afu, size_t offset, |
|
enum ocxl_endian endian, u64 mask) |
|
{ |
|
u64 tmp; |
|
|
|
if (offset > afu->config.global_mmio_size - 8) |
|
return -EINVAL; |
|
|
|
#ifdef __BIG_ENDIAN__ |
|
if (endian == OCXL_HOST_ENDIAN) |
|
endian = OCXL_BIG_ENDIAN; |
|
#endif |
|
|
|
switch (endian) { |
|
case OCXL_BIG_ENDIAN: |
|
tmp = readq_be((char *)afu->global_mmio_ptr + offset); |
|
tmp |= mask; |
|
writeq_be(tmp, (char *)afu->global_mmio_ptr + offset); |
|
break; |
|
|
|
default: |
|
tmp = readq((char *)afu->global_mmio_ptr + offset); |
|
tmp |= mask; |
|
writeq(tmp, (char *)afu->global_mmio_ptr + offset); |
|
break; |
|
} |
|
|
|
return 0; |
|
} |
|
EXPORT_SYMBOL_GPL(ocxl_global_mmio_set64); |
|
|
|
int ocxl_global_mmio_clear32(struct ocxl_afu *afu, size_t offset, |
|
enum ocxl_endian endian, u32 mask) |
|
{ |
|
u32 tmp; |
|
|
|
if (offset > afu->config.global_mmio_size - 4) |
|
return -EINVAL; |
|
|
|
#ifdef __BIG_ENDIAN__ |
|
if (endian == OCXL_HOST_ENDIAN) |
|
endian = OCXL_BIG_ENDIAN; |
|
#endif |
|
|
|
switch (endian) { |
|
case OCXL_BIG_ENDIAN: |
|
tmp = readl_be((char *)afu->global_mmio_ptr + offset); |
|
tmp &= ~mask; |
|
writel_be(tmp, (char *)afu->global_mmio_ptr + offset); |
|
break; |
|
|
|
default: |
|
tmp = readl((char *)afu->global_mmio_ptr + offset); |
|
tmp &= ~mask; |
|
writel(tmp, (char *)afu->global_mmio_ptr + offset); |
|
break; |
|
} |
|
|
|
|
|
return 0; |
|
} |
|
EXPORT_SYMBOL_GPL(ocxl_global_mmio_clear32); |
|
|
|
int ocxl_global_mmio_clear64(struct ocxl_afu *afu, size_t offset, |
|
enum ocxl_endian endian, u64 mask) |
|
{ |
|
u64 tmp; |
|
|
|
if (offset > afu->config.global_mmio_size - 8) |
|
return -EINVAL; |
|
|
|
#ifdef __BIG_ENDIAN__ |
|
if (endian == OCXL_HOST_ENDIAN) |
|
endian = OCXL_BIG_ENDIAN; |
|
#endif |
|
|
|
switch (endian) { |
|
case OCXL_BIG_ENDIAN: |
|
tmp = readq_be((char *)afu->global_mmio_ptr + offset); |
|
tmp &= ~mask; |
|
writeq_be(tmp, (char *)afu->global_mmio_ptr + offset); |
|
break; |
|
|
|
default: |
|
tmp = readq((char *)afu->global_mmio_ptr + offset); |
|
tmp &= ~mask; |
|
writeq(tmp, (char *)afu->global_mmio_ptr + offset); |
|
break; |
|
} |
|
|
|
writeq(tmp, (char *)afu->global_mmio_ptr + offset); |
|
|
|
return 0; |
|
} |
|
EXPORT_SYMBOL_GPL(ocxl_global_mmio_clear64);
|
|
|