1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 3 * Common LiteX header providing 4 * helper functions for accessing CSRs. 5 * 6 * Copyright (C) 2019-2020 Antmicro <www.antmicro.com> 7 */ 8 9 #ifndef _LINUX_LITEX_H 10 #define _LINUX_LITEX_H 11 12 #include <linux/io.h> 13 #include <linux/types.h> 14 #include <linux/compiler_types.h> 15 16 /* 17 * The parameters below are true for LiteX SoCs configured for 8-bit CSR Bus, 18 * 32-bit aligned. 19 * 20 * Supporting other configurations will require extending the logic in this 21 * header and in the LiteX SoC controller driver. 22 */ 23 #define LITEX_SUBREG_SIZE 0x1 24 #define LITEX_SUBREG_SIZE_BIT (LITEX_SUBREG_SIZE * 8) 25 26 /* LiteX subregisters of any width are always aligned on a 4-byte boundary */ 27 #define LITEX_SUBREG_ALIGN 0x4 28 29 static inline void _write_litex_subregister(u32 val, void __iomem *addr) 30 { 31 writel((u32 __force)cpu_to_le32(val), addr); 32 } 33 34 static inline u32 _read_litex_subregister(void __iomem *addr) 35 { 36 return le32_to_cpu((__le32 __force)readl(addr)); 37 } 38 39 #define WRITE_LITEX_SUBREGISTER(val, base_offset, subreg_id) \ 40 _write_litex_subregister(val, (base_offset) + \ 41 LITEX_SUBREG_ALIGN * (subreg_id)) 42 43 #define READ_LITEX_SUBREGISTER(base_offset, subreg_id) \ 44 _read_litex_subregister((base_offset) + \ 45 LITEX_SUBREG_ALIGN * (subreg_id)) 46 47 /* 48 * LiteX SoC Generator, depending on the configuration, can split a single 49 * logical CSR (Control&Status Register) into a series of consecutive physical 50 * registers. 51 * 52 * For example, in the configuration with 8-bit CSR Bus, 32-bit aligned (the 53 * default one for 32-bit CPUs) a 32-bit logical CSR will be generated as four 54 * 32-bit physical registers, each one containing one byte of meaningful data. 55 * 56 * For details see: https://github.com/enjoy-digital/litex/wiki/CSR-Bus 57 * 58 * The purpose of `litex_set_reg`/`litex_get_reg` is to implement the logic 59 * of writing to/reading from the LiteX CSR in a single place that can be 60 * then reused by all LiteX drivers. 61 */ 62 63 /** 64 * litex_set_reg() - Writes the value to the LiteX CSR (Control&Status Register) 65 * @reg: Address of the CSR 66 * @reg_size: The width of the CSR expressed in the number of bytes 67 * @val: Value to be written to the CSR 68 * 69 * In the currently supported LiteX configuration (8-bit CSR Bus, 32-bit aligned), 70 * a 32-bit LiteX CSR is generated as 4 consecutive 32-bit physical registers, 71 * each one containing one byte of meaningful data. 72 * 73 * This function splits a single possibly multi-byte write into a series of 74 * single-byte writes with a proper offset. 75 */ 76 static inline void litex_set_reg(void __iomem *reg, ulong reg_size, ulong val) 77 { 78 ulong shifted_data, shift, i; 79 80 for (i = 0; i < reg_size; ++i) { 81 shift = ((reg_size - i - 1) * LITEX_SUBREG_SIZE_BIT); 82 shifted_data = val >> shift; 83 84 WRITE_LITEX_SUBREGISTER(shifted_data, reg, i); 85 } 86 } 87 88 /** 89 * litex_get_reg() - Reads the value of the LiteX CSR (Control&Status Register) 90 * @reg: Address of the CSR 91 * @reg_size: The width of the CSR expressed in the number of bytes 92 * 93 * Return: Value read from the CSR 94 * 95 * In the currently supported LiteX configuration (8-bit CSR Bus, 32-bit aligned), 96 * a 32-bit LiteX CSR is generated as 4 consecutive 32-bit physical registers, 97 * each one containing one byte of meaningful data. 98 * 99 * This function generates a series of single-byte reads with a proper offset 100 * and joins their results into a single multi-byte value. 101 */ 102 static inline ulong litex_get_reg(void __iomem *reg, ulong reg_size) 103 { 104 ulong shifted_data, shift, i; 105 ulong result = 0; 106 107 for (i = 0; i < reg_size; ++i) { 108 shifted_data = READ_LITEX_SUBREGISTER(reg, i); 109 110 shift = ((reg_size - i - 1) * LITEX_SUBREG_SIZE_BIT); 111 result |= (shifted_data << shift); 112 } 113 114 return result; 115 } 116 117 118 static inline void litex_write8(void __iomem *reg, u8 val) 119 { 120 WRITE_LITEX_SUBREGISTER(val, reg, 0); 121 } 122 123 static inline void litex_write16(void __iomem *reg, u16 val) 124 { 125 WRITE_LITEX_SUBREGISTER(val >> 8, reg, 0); 126 WRITE_LITEX_SUBREGISTER(val, reg, 1); 127 } 128 129 static inline void litex_write32(void __iomem *reg, u32 val) 130 { 131 WRITE_LITEX_SUBREGISTER(val >> 24, reg, 0); 132 WRITE_LITEX_SUBREGISTER(val >> 16, reg, 1); 133 WRITE_LITEX_SUBREGISTER(val >> 8, reg, 2); 134 WRITE_LITEX_SUBREGISTER(val, reg, 3); 135 } 136 137 static inline void litex_write64(void __iomem *reg, u64 val) 138 { 139 WRITE_LITEX_SUBREGISTER(val >> 56, reg, 0); 140 WRITE_LITEX_SUBREGISTER(val >> 48, reg, 1); 141 WRITE_LITEX_SUBREGISTER(val >> 40, reg, 2); 142 WRITE_LITEX_SUBREGISTER(val >> 32, reg, 3); 143 WRITE_LITEX_SUBREGISTER(val >> 24, reg, 4); 144 WRITE_LITEX_SUBREGISTER(val >> 16, reg, 5); 145 WRITE_LITEX_SUBREGISTER(val >> 8, reg, 6); 146 WRITE_LITEX_SUBREGISTER(val, reg, 7); 147 } 148 149 static inline u8 litex_read8(void __iomem *reg) 150 { 151 return READ_LITEX_SUBREGISTER(reg, 0); 152 } 153 154 static inline u16 litex_read16(void __iomem *reg) 155 { 156 return (READ_LITEX_SUBREGISTER(reg, 0) << 8) 157 | (READ_LITEX_SUBREGISTER(reg, 1)); 158 } 159 160 static inline u32 litex_read32(void __iomem *reg) 161 { 162 return (READ_LITEX_SUBREGISTER(reg, 0) << 24) 163 | (READ_LITEX_SUBREGISTER(reg, 1) << 16) 164 | (READ_LITEX_SUBREGISTER(reg, 2) << 8) 165 | (READ_LITEX_SUBREGISTER(reg, 3)); 166 } 167 168 static inline u64 litex_read64(void __iomem *reg) 169 { 170 return ((u64)READ_LITEX_SUBREGISTER(reg, 0) << 56) 171 | ((u64)READ_LITEX_SUBREGISTER(reg, 1) << 48) 172 | ((u64)READ_LITEX_SUBREGISTER(reg, 2) << 40) 173 | ((u64)READ_LITEX_SUBREGISTER(reg, 3) << 32) 174 | ((u64)READ_LITEX_SUBREGISTER(reg, 4) << 24) 175 | ((u64)READ_LITEX_SUBREGISTER(reg, 5) << 16) 176 | ((u64)READ_LITEX_SUBREGISTER(reg, 6) << 8) 177 | ((u64)READ_LITEX_SUBREGISTER(reg, 7)); 178 } 179 180 #endif /* _LINUX_LITEX_H */ 181