1 /* SPDX-License-Identifier: GPL-2.0 */ 1 /* SPDX-License-Identifier: GPL-2.0 */ 2 /* 2 /* 3 * Common LiteX header providing 3 * Common LiteX header providing 4 * helper functions for accessing CSRs. 4 * helper functions for accessing CSRs. 5 * 5 * 6 * Copyright (C) 2019-2020 Antmicro <www.antmi 6 * Copyright (C) 2019-2020 Antmicro <www.antmicro.com> 7 */ 7 */ 8 8 9 #ifndef _LINUX_LITEX_H 9 #ifndef _LINUX_LITEX_H 10 #define _LINUX_LITEX_H 10 #define _LINUX_LITEX_H 11 11 12 #include <linux/io.h> 12 #include <linux/io.h> 13 13 >> 14 /* LiteX SoCs support 8- or 32-bit CSR Bus data width (i.e., subreg. size) */ >> 15 #if defined(CONFIG_LITEX_SUBREG_SIZE) && \ >> 16 (CONFIG_LITEX_SUBREG_SIZE == 1 || CONFIG_LITEX_SUBREG_SIZE == 4) >> 17 #define LITEX_SUBREG_SIZE CONFIG_LITEX_SUBREG_SIZE >> 18 #else >> 19 #error LiteX subregister size (LITEX_SUBREG_SIZE) must be 4 or 1! >> 20 #endif >> 21 #define LITEX_SUBREG_SIZE_BIT (LITEX_SUBREG_SIZE * 8) >> 22 >> 23 /* LiteX subregisters of any width are always aligned on a 4-byte boundary */ >> 24 #define LITEX_SUBREG_ALIGN 0x4 >> 25 14 static inline void _write_litex_subregister(u3 26 static inline void _write_litex_subregister(u32 val, void __iomem *addr) 15 { 27 { 16 writel((u32 __force)cpu_to_le32(val), 28 writel((u32 __force)cpu_to_le32(val), addr); 17 } 29 } 18 30 19 static inline u32 _read_litex_subregister(void 31 static inline u32 _read_litex_subregister(void __iomem *addr) 20 { 32 { 21 return le32_to_cpu((__le32 __force)rea 33 return le32_to_cpu((__le32 __force)readl(addr)); 22 } 34 } 23 35 24 /* 36 /* 25 * LiteX SoC Generator, depending on the confi 37 * LiteX SoC Generator, depending on the configuration, can split a single 26 * logical CSR (Control&Status Register) into 38 * logical CSR (Control&Status Register) into a series of consecutive physical 27 * registers. 39 * registers. 28 * 40 * 29 * For example, in the configuration with 8-bi 41 * For example, in the configuration with 8-bit CSR Bus, a 32-bit aligned, 30 * 32-bit wide logical CSR will be laid out as 42 * 32-bit wide logical CSR will be laid out as four 32-bit physical 31 * subregisters, each one containing one byte 43 * subregisters, each one containing one byte of meaningful data. 32 * 44 * 33 * For Linux support, upstream LiteX enforces << 34 * means that only larger-than-32-bit CSRs wil << 35 * subregisters (e.g., a 64-bit CSR will be sp << 36 * 32-bit subregisters). << 37 * << 38 * For details see: https://github.com/enjoy-d 45 * For details see: https://github.com/enjoy-digital/litex/wiki/CSR-Bus 39 */ 46 */ 40 47 >> 48 /* number of LiteX subregisters needed to store a register of given reg_size */ >> 49 #define _litex_num_subregs(reg_size) \ >> 50 (((reg_size) - 1) / LITEX_SUBREG_SIZE + 1) >> 51 >> 52 /* >> 53 * since the number of 4-byte aligned subregisters required to store a single >> 54 * LiteX CSR (MMIO) register varies with LITEX_SUBREG_SIZE, the offset of the >> 55 * next adjacent LiteX CSR register w.r.t. the offset of the current one also >> 56 * depends on how many subregisters the latter is spread across >> 57 */ >> 58 #define _next_reg_off(off, size) \ >> 59 ((off) + _litex_num_subregs(size) * LITEX_SUBREG_ALIGN) >> 60 >> 61 /* >> 62 * The purpose of `_litex_[set|get]_reg()` is to implement the logic of >> 63 * writing to/reading from the LiteX CSR in a single place that can be then >> 64 * reused by all LiteX drivers via the `litex_[write|read][8|16|32|64]()` >> 65 * accessors for the appropriate data width. >> 66 * NOTE: direct use of `_litex_[set|get]_reg()` by LiteX drivers is strongly >> 67 * discouraged, as they perform no error checking on the requested data width! >> 68 */ >> 69 >> 70 /** >> 71 * _litex_set_reg() - Writes a value to the LiteX CSR (Control&Status Register) >> 72 * @reg: Address of the CSR >> 73 * @reg_size: The width of the CSR expressed in the number of bytes >> 74 * @val: Value to be written to the CSR >> 75 * >> 76 * This function splits a single (possibly multi-byte) LiteX CSR write into >> 77 * a series of subregister writes with a proper offset. >> 78 * NOTE: caller is responsible for ensuring (0 < reg_size <= sizeof(u64)). >> 79 */ >> 80 static inline void _litex_set_reg(void __iomem *reg, size_t reg_size, u64 val) >> 81 { >> 82 u8 shift = _litex_num_subregs(reg_size) * LITEX_SUBREG_SIZE_BIT; >> 83 >> 84 while (shift > 0) { >> 85 shift -= LITEX_SUBREG_SIZE_BIT; >> 86 _write_litex_subregister(val >> shift, reg); >> 87 reg += LITEX_SUBREG_ALIGN; >> 88 } >> 89 } >> 90 >> 91 /** >> 92 * _litex_get_reg() - Reads a value of the LiteX CSR (Control&Status Register) >> 93 * @reg: Address of the CSR >> 94 * @reg_size: The width of the CSR expressed in the number of bytes >> 95 * >> 96 * Return: Value read from the CSR >> 97 * >> 98 * This function generates a series of subregister reads with a proper offset >> 99 * and joins their results into a single (possibly multi-byte) LiteX CSR value. >> 100 * NOTE: caller is responsible for ensuring (0 < reg_size <= sizeof(u64)). >> 101 */ >> 102 static inline u64 _litex_get_reg(void __iomem *reg, size_t reg_size) >> 103 { >> 104 u64 r; >> 105 u8 i; >> 106 >> 107 r = _read_litex_subregister(reg); >> 108 for (i = 1; i < _litex_num_subregs(reg_size); i++) { >> 109 r <<= LITEX_SUBREG_SIZE_BIT; >> 110 reg += LITEX_SUBREG_ALIGN; >> 111 r |= _read_litex_subregister(reg); >> 112 } >> 113 return r; >> 114 } >> 115 41 static inline void litex_write8(void __iomem * 116 static inline void litex_write8(void __iomem *reg, u8 val) 42 { 117 { 43 _write_litex_subregister(val, reg); !! 118 _litex_set_reg(reg, sizeof(u8), val); 44 } 119 } 45 120 46 static inline void litex_write16(void __iomem 121 static inline void litex_write16(void __iomem *reg, u16 val) 47 { 122 { 48 _write_litex_subregister(val, reg); !! 123 _litex_set_reg(reg, sizeof(u16), val); 49 } 124 } 50 125 51 static inline void litex_write32(void __iomem 126 static inline void litex_write32(void __iomem *reg, u32 val) 52 { 127 { 53 _write_litex_subregister(val, reg); !! 128 _litex_set_reg(reg, sizeof(u32), val); 54 } 129 } 55 130 56 static inline void litex_write64(void __iomem 131 static inline void litex_write64(void __iomem *reg, u64 val) 57 { 132 { 58 _write_litex_subregister(val >> 32, re !! 133 _litex_set_reg(reg, sizeof(u64), val); 59 _write_litex_subregister(val, reg + 4) << 60 } 134 } 61 135 62 static inline u8 litex_read8(void __iomem *reg 136 static inline u8 litex_read8(void __iomem *reg) 63 { 137 { 64 return _read_litex_subregister(reg); !! 138 return _litex_get_reg(reg, sizeof(u8)); 65 } 139 } 66 140 67 static inline u16 litex_read16(void __iomem *r 141 static inline u16 litex_read16(void __iomem *reg) 68 { 142 { 69 return _read_litex_subregister(reg); !! 143 return _litex_get_reg(reg, sizeof(u16)); 70 } 144 } 71 145 72 static inline u32 litex_read32(void __iomem *r 146 static inline u32 litex_read32(void __iomem *reg) 73 { 147 { 74 return _read_litex_subregister(reg); !! 148 return _litex_get_reg(reg, sizeof(u32)); 75 } 149 } 76 150 77 static inline u64 litex_read64(void __iomem *r 151 static inline u64 litex_read64(void __iomem *reg) 78 { 152 { 79 return ((u64)_read_litex_subregister(r !! 153 return _litex_get_reg(reg, sizeof(u64)); 80 _read_litex_subregister(reg + << 81 } 154 } 82 155 83 #endif /* _LINUX_LITEX_H */ 156 #endif /* _LINUX_LITEX_H */ 84 157
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.