2020-10-13 14:45:52 +00:00
|
|
|
/* SPDX-License-Identifier: GPL-2.0 */
|
|
|
|
/*
|
|
|
|
* Common LiteX header providing
|
|
|
|
* helper functions for accessing CSRs.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2019-2020 Antmicro <www.antmicro.com>
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _LINUX_LITEX_H
|
|
|
|
#define _LINUX_LITEX_H
|
|
|
|
|
|
|
|
#include <linux/io.h>
|
|
|
|
|
drivers/soc/litex: support 32-bit subregisters, 64-bit CPUs
Upstream LiteX now defaults to using 32-bit CSR subregisters
(see https://github.com/enjoy-digital/litex/commit/a2b71fde).
This patch expands on commit 22447a99c97e ("drivers/soc/litex: add
LiteX SoC Controller driver"), adding support for handling both 8-
and 32-bit LiteX CSR (MMIO) subregisters, as determined by the
LITEX_SUBREG_SIZE Kconfig option.
NOTE that while LITEX_SUBREG_SIZE could theoretically be a device
tree property, defining it as a compile-time constant allows for
much better optimization of the resulting code. This is further
supported by the low expected usefulness of deploying the same
kernel across LiteX SoCs built with different CSR-Bus data widths.
Finally, the litex_[read|write][8|16|32|64]() accessors are
redefined in terms of litex_[get|set]_reg(), which, after compiler
optimization, will result in code as efficient as hardcoded shifts,
but with the added benefit of automatically matching the appropriate
LITEX_SUBREG_SIZE.
NOTE that litex_[get|set]_reg() nominally operate on 64-bit data,
but that will also be optimized by the compiler in situations where
narrower data is used from a call site.
Signed-off-by: Gabriel Somlo <gsomlo@gmail.com>
Signed-off-by: Stafford Horne <shorne@gmail.com>
2021-01-12 17:31:43 +00:00
|
|
|
/* LiteX SoCs support 8- or 32-bit CSR Bus data width (i.e., subreg. size) */
|
|
|
|
#if defined(CONFIG_LITEX_SUBREG_SIZE) && \
|
|
|
|
(CONFIG_LITEX_SUBREG_SIZE == 1 || CONFIG_LITEX_SUBREG_SIZE == 4)
|
|
|
|
#define LITEX_SUBREG_SIZE CONFIG_LITEX_SUBREG_SIZE
|
|
|
|
#else
|
|
|
|
#error LiteX subregister size (LITEX_SUBREG_SIZE) must be 4 or 1!
|
|
|
|
#endif
|
2020-10-13 14:45:52 +00:00
|
|
|
#define LITEX_SUBREG_SIZE_BIT (LITEX_SUBREG_SIZE * 8)
|
|
|
|
|
2021-01-12 17:31:42 +00:00
|
|
|
/* LiteX subregisters of any width are always aligned on a 4-byte boundary */
|
|
|
|
#define LITEX_SUBREG_ALIGN 0x4
|
|
|
|
|
2021-01-12 17:31:41 +00:00
|
|
|
static inline void _write_litex_subregister(u32 val, void __iomem *addr)
|
|
|
|
{
|
|
|
|
writel((u32 __force)cpu_to_le32(val), addr);
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline u32 _read_litex_subregister(void __iomem *addr)
|
|
|
|
{
|
|
|
|
return le32_to_cpu((__le32 __force)readl(addr));
|
|
|
|
}
|
|
|
|
|
2021-01-12 17:31:40 +00:00
|
|
|
/*
|
|
|
|
* LiteX SoC Generator, depending on the configuration, can split a single
|
|
|
|
* logical CSR (Control&Status Register) into a series of consecutive physical
|
|
|
|
* registers.
|
|
|
|
*
|
drivers/soc/litex: support 32-bit subregisters, 64-bit CPUs
Upstream LiteX now defaults to using 32-bit CSR subregisters
(see https://github.com/enjoy-digital/litex/commit/a2b71fde).
This patch expands on commit 22447a99c97e ("drivers/soc/litex: add
LiteX SoC Controller driver"), adding support for handling both 8-
and 32-bit LiteX CSR (MMIO) subregisters, as determined by the
LITEX_SUBREG_SIZE Kconfig option.
NOTE that while LITEX_SUBREG_SIZE could theoretically be a device
tree property, defining it as a compile-time constant allows for
much better optimization of the resulting code. This is further
supported by the low expected usefulness of deploying the same
kernel across LiteX SoCs built with different CSR-Bus data widths.
Finally, the litex_[read|write][8|16|32|64]() accessors are
redefined in terms of litex_[get|set]_reg(), which, after compiler
optimization, will result in code as efficient as hardcoded shifts,
but with the added benefit of automatically matching the appropriate
LITEX_SUBREG_SIZE.
NOTE that litex_[get|set]_reg() nominally operate on 64-bit data,
but that will also be optimized by the compiler in situations where
narrower data is used from a call site.
Signed-off-by: Gabriel Somlo <gsomlo@gmail.com>
Signed-off-by: Stafford Horne <shorne@gmail.com>
2021-01-12 17:31:43 +00:00
|
|
|
* For example, in the configuration with 8-bit CSR Bus, a 32-bit aligned,
|
|
|
|
* 32-bit wide logical CSR will be laid out as four 32-bit physical
|
|
|
|
* subregisters, each one containing one byte of meaningful data.
|
2021-01-12 17:31:40 +00:00
|
|
|
*
|
|
|
|
* For details see: https://github.com/enjoy-digital/litex/wiki/CSR-Bus
|
drivers/soc/litex: support 32-bit subregisters, 64-bit CPUs
Upstream LiteX now defaults to using 32-bit CSR subregisters
(see https://github.com/enjoy-digital/litex/commit/a2b71fde).
This patch expands on commit 22447a99c97e ("drivers/soc/litex: add
LiteX SoC Controller driver"), adding support for handling both 8-
and 32-bit LiteX CSR (MMIO) subregisters, as determined by the
LITEX_SUBREG_SIZE Kconfig option.
NOTE that while LITEX_SUBREG_SIZE could theoretically be a device
tree property, defining it as a compile-time constant allows for
much better optimization of the resulting code. This is further
supported by the low expected usefulness of deploying the same
kernel across LiteX SoCs built with different CSR-Bus data widths.
Finally, the litex_[read|write][8|16|32|64]() accessors are
redefined in terms of litex_[get|set]_reg(), which, after compiler
optimization, will result in code as efficient as hardcoded shifts,
but with the added benefit of automatically matching the appropriate
LITEX_SUBREG_SIZE.
NOTE that litex_[get|set]_reg() nominally operate on 64-bit data,
but that will also be optimized by the compiler in situations where
narrower data is used from a call site.
Signed-off-by: Gabriel Somlo <gsomlo@gmail.com>
Signed-off-by: Stafford Horne <shorne@gmail.com>
2021-01-12 17:31:43 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/* number of LiteX subregisters needed to store a register of given reg_size */
|
|
|
|
#define _litex_num_subregs(reg_size) \
|
|
|
|
(((reg_size) - 1) / LITEX_SUBREG_SIZE + 1)
|
|
|
|
|
|
|
|
/*
|
|
|
|
* since the number of 4-byte aligned subregisters required to store a single
|
|
|
|
* LiteX CSR (MMIO) register varies with LITEX_SUBREG_SIZE, the offset of the
|
|
|
|
* next adjacent LiteX CSR register w.r.t. the offset of the current one also
|
|
|
|
* depends on how many subregisters the latter is spread across
|
|
|
|
*/
|
|
|
|
#define _next_reg_off(off, size) \
|
|
|
|
((off) + _litex_num_subregs(size) * LITEX_SUBREG_ALIGN)
|
|
|
|
|
|
|
|
/*
|
2021-01-12 17:31:44 +00:00
|
|
|
* The purpose of `_litex_[set|get]_reg()` is to implement the logic of
|
|
|
|
* writing to/reading from the LiteX CSR in a single place that can be then
|
|
|
|
* reused by all LiteX drivers via the `litex_[write|read][8|16|32|64]()`
|
|
|
|
* accessors for the appropriate data width.
|
|
|
|
* NOTE: direct use of `_litex_[set|get]_reg()` by LiteX drivers is strongly
|
|
|
|
* discouraged, as they perform no error checking on the requested data width!
|
2021-01-12 17:31:40 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
/**
|
2021-01-12 17:31:44 +00:00
|
|
|
* _litex_set_reg() - Writes a value to the LiteX CSR (Control&Status Register)
|
2021-01-12 17:31:40 +00:00
|
|
|
* @reg: Address of the CSR
|
|
|
|
* @reg_size: The width of the CSR expressed in the number of bytes
|
|
|
|
* @val: Value to be written to the CSR
|
|
|
|
*
|
drivers/soc/litex: support 32-bit subregisters, 64-bit CPUs
Upstream LiteX now defaults to using 32-bit CSR subregisters
(see https://github.com/enjoy-digital/litex/commit/a2b71fde).
This patch expands on commit 22447a99c97e ("drivers/soc/litex: add
LiteX SoC Controller driver"), adding support for handling both 8-
and 32-bit LiteX CSR (MMIO) subregisters, as determined by the
LITEX_SUBREG_SIZE Kconfig option.
NOTE that while LITEX_SUBREG_SIZE could theoretically be a device
tree property, defining it as a compile-time constant allows for
much better optimization of the resulting code. This is further
supported by the low expected usefulness of deploying the same
kernel across LiteX SoCs built with different CSR-Bus data widths.
Finally, the litex_[read|write][8|16|32|64]() accessors are
redefined in terms of litex_[get|set]_reg(), which, after compiler
optimization, will result in code as efficient as hardcoded shifts,
but with the added benefit of automatically matching the appropriate
LITEX_SUBREG_SIZE.
NOTE that litex_[get|set]_reg() nominally operate on 64-bit data,
but that will also be optimized by the compiler in situations where
narrower data is used from a call site.
Signed-off-by: Gabriel Somlo <gsomlo@gmail.com>
Signed-off-by: Stafford Horne <shorne@gmail.com>
2021-01-12 17:31:43 +00:00
|
|
|
* This function splits a single (possibly multi-byte) LiteX CSR write into
|
|
|
|
* a series of subregister writes with a proper offset.
|
2021-01-12 17:31:44 +00:00
|
|
|
* NOTE: caller is responsible for ensuring (0 < reg_size <= sizeof(u64)).
|
2021-01-12 17:31:40 +00:00
|
|
|
*/
|
2021-01-12 17:31:44 +00:00
|
|
|
static inline void _litex_set_reg(void __iomem *reg, size_t reg_size, u64 val)
|
2021-01-12 17:31:40 +00:00
|
|
|
{
|
drivers/soc/litex: support 32-bit subregisters, 64-bit CPUs
Upstream LiteX now defaults to using 32-bit CSR subregisters
(see https://github.com/enjoy-digital/litex/commit/a2b71fde).
This patch expands on commit 22447a99c97e ("drivers/soc/litex: add
LiteX SoC Controller driver"), adding support for handling both 8-
and 32-bit LiteX CSR (MMIO) subregisters, as determined by the
LITEX_SUBREG_SIZE Kconfig option.
NOTE that while LITEX_SUBREG_SIZE could theoretically be a device
tree property, defining it as a compile-time constant allows for
much better optimization of the resulting code. This is further
supported by the low expected usefulness of deploying the same
kernel across LiteX SoCs built with different CSR-Bus data widths.
Finally, the litex_[read|write][8|16|32|64]() accessors are
redefined in terms of litex_[get|set]_reg(), which, after compiler
optimization, will result in code as efficient as hardcoded shifts,
but with the added benefit of automatically matching the appropriate
LITEX_SUBREG_SIZE.
NOTE that litex_[get|set]_reg() nominally operate on 64-bit data,
but that will also be optimized by the compiler in situations where
narrower data is used from a call site.
Signed-off-by: Gabriel Somlo <gsomlo@gmail.com>
Signed-off-by: Stafford Horne <shorne@gmail.com>
2021-01-12 17:31:43 +00:00
|
|
|
u8 shift = _litex_num_subregs(reg_size) * LITEX_SUBREG_SIZE_BIT;
|
2021-01-12 17:31:40 +00:00
|
|
|
|
drivers/soc/litex: support 32-bit subregisters, 64-bit CPUs
Upstream LiteX now defaults to using 32-bit CSR subregisters
(see https://github.com/enjoy-digital/litex/commit/a2b71fde).
This patch expands on commit 22447a99c97e ("drivers/soc/litex: add
LiteX SoC Controller driver"), adding support for handling both 8-
and 32-bit LiteX CSR (MMIO) subregisters, as determined by the
LITEX_SUBREG_SIZE Kconfig option.
NOTE that while LITEX_SUBREG_SIZE could theoretically be a device
tree property, defining it as a compile-time constant allows for
much better optimization of the resulting code. This is further
supported by the low expected usefulness of deploying the same
kernel across LiteX SoCs built with different CSR-Bus data widths.
Finally, the litex_[read|write][8|16|32|64]() accessors are
redefined in terms of litex_[get|set]_reg(), which, after compiler
optimization, will result in code as efficient as hardcoded shifts,
but with the added benefit of automatically matching the appropriate
LITEX_SUBREG_SIZE.
NOTE that litex_[get|set]_reg() nominally operate on 64-bit data,
but that will also be optimized by the compiler in situations where
narrower data is used from a call site.
Signed-off-by: Gabriel Somlo <gsomlo@gmail.com>
Signed-off-by: Stafford Horne <shorne@gmail.com>
2021-01-12 17:31:43 +00:00
|
|
|
while (shift > 0) {
|
|
|
|
shift -= LITEX_SUBREG_SIZE_BIT;
|
|
|
|
_write_litex_subregister(val >> shift, reg);
|
|
|
|
reg += LITEX_SUBREG_ALIGN;
|
2021-01-12 17:31:40 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2021-01-12 17:31:44 +00:00
|
|
|
* _litex_get_reg() - Reads a value of the LiteX CSR (Control&Status Register)
|
2021-01-12 17:31:40 +00:00
|
|
|
* @reg: Address of the CSR
|
|
|
|
* @reg_size: The width of the CSR expressed in the number of bytes
|
|
|
|
*
|
|
|
|
* Return: Value read from the CSR
|
|
|
|
*
|
drivers/soc/litex: support 32-bit subregisters, 64-bit CPUs
Upstream LiteX now defaults to using 32-bit CSR subregisters
(see https://github.com/enjoy-digital/litex/commit/a2b71fde).
This patch expands on commit 22447a99c97e ("drivers/soc/litex: add
LiteX SoC Controller driver"), adding support for handling both 8-
and 32-bit LiteX CSR (MMIO) subregisters, as determined by the
LITEX_SUBREG_SIZE Kconfig option.
NOTE that while LITEX_SUBREG_SIZE could theoretically be a device
tree property, defining it as a compile-time constant allows for
much better optimization of the resulting code. This is further
supported by the low expected usefulness of deploying the same
kernel across LiteX SoCs built with different CSR-Bus data widths.
Finally, the litex_[read|write][8|16|32|64]() accessors are
redefined in terms of litex_[get|set]_reg(), which, after compiler
optimization, will result in code as efficient as hardcoded shifts,
but with the added benefit of automatically matching the appropriate
LITEX_SUBREG_SIZE.
NOTE that litex_[get|set]_reg() nominally operate on 64-bit data,
but that will also be optimized by the compiler in situations where
narrower data is used from a call site.
Signed-off-by: Gabriel Somlo <gsomlo@gmail.com>
Signed-off-by: Stafford Horne <shorne@gmail.com>
2021-01-12 17:31:43 +00:00
|
|
|
* This function generates a series of subregister reads with a proper offset
|
|
|
|
* and joins their results into a single (possibly multi-byte) LiteX CSR value.
|
2021-01-12 17:31:44 +00:00
|
|
|
* NOTE: caller is responsible for ensuring (0 < reg_size <= sizeof(u64)).
|
2021-01-12 17:31:40 +00:00
|
|
|
*/
|
2021-01-12 17:31:44 +00:00
|
|
|
static inline u64 _litex_get_reg(void __iomem *reg, size_t reg_size)
|
2021-01-12 17:31:40 +00:00
|
|
|
{
|
drivers/soc/litex: support 32-bit subregisters, 64-bit CPUs
Upstream LiteX now defaults to using 32-bit CSR subregisters
(see https://github.com/enjoy-digital/litex/commit/a2b71fde).
This patch expands on commit 22447a99c97e ("drivers/soc/litex: add
LiteX SoC Controller driver"), adding support for handling both 8-
and 32-bit LiteX CSR (MMIO) subregisters, as determined by the
LITEX_SUBREG_SIZE Kconfig option.
NOTE that while LITEX_SUBREG_SIZE could theoretically be a device
tree property, defining it as a compile-time constant allows for
much better optimization of the resulting code. This is further
supported by the low expected usefulness of deploying the same
kernel across LiteX SoCs built with different CSR-Bus data widths.
Finally, the litex_[read|write][8|16|32|64]() accessors are
redefined in terms of litex_[get|set]_reg(), which, after compiler
optimization, will result in code as efficient as hardcoded shifts,
but with the added benefit of automatically matching the appropriate
LITEX_SUBREG_SIZE.
NOTE that litex_[get|set]_reg() nominally operate on 64-bit data,
but that will also be optimized by the compiler in situations where
narrower data is used from a call site.
Signed-off-by: Gabriel Somlo <gsomlo@gmail.com>
Signed-off-by: Stafford Horne <shorne@gmail.com>
2021-01-12 17:31:43 +00:00
|
|
|
u64 r;
|
|
|
|
u8 i;
|
|
|
|
|
|
|
|
r = _read_litex_subregister(reg);
|
|
|
|
for (i = 1; i < _litex_num_subregs(reg_size); i++) {
|
|
|
|
r <<= LITEX_SUBREG_SIZE_BIT;
|
|
|
|
reg += LITEX_SUBREG_ALIGN;
|
|
|
|
r |= _read_litex_subregister(reg);
|
2021-01-12 17:31:40 +00:00
|
|
|
}
|
drivers/soc/litex: support 32-bit subregisters, 64-bit CPUs
Upstream LiteX now defaults to using 32-bit CSR subregisters
(see https://github.com/enjoy-digital/litex/commit/a2b71fde).
This patch expands on commit 22447a99c97e ("drivers/soc/litex: add
LiteX SoC Controller driver"), adding support for handling both 8-
and 32-bit LiteX CSR (MMIO) subregisters, as determined by the
LITEX_SUBREG_SIZE Kconfig option.
NOTE that while LITEX_SUBREG_SIZE could theoretically be a device
tree property, defining it as a compile-time constant allows for
much better optimization of the resulting code. This is further
supported by the low expected usefulness of deploying the same
kernel across LiteX SoCs built with different CSR-Bus data widths.
Finally, the litex_[read|write][8|16|32|64]() accessors are
redefined in terms of litex_[get|set]_reg(), which, after compiler
optimization, will result in code as efficient as hardcoded shifts,
but with the added benefit of automatically matching the appropriate
LITEX_SUBREG_SIZE.
NOTE that litex_[get|set]_reg() nominally operate on 64-bit data,
but that will also be optimized by the compiler in situations where
narrower data is used from a call site.
Signed-off-by: Gabriel Somlo <gsomlo@gmail.com>
Signed-off-by: Stafford Horne <shorne@gmail.com>
2021-01-12 17:31:43 +00:00
|
|
|
return r;
|
2021-01-12 17:31:40 +00:00
|
|
|
}
|
2020-10-13 14:45:52 +00:00
|
|
|
|
|
|
|
static inline void litex_write8(void __iomem *reg, u8 val)
|
|
|
|
{
|
2021-01-12 17:31:44 +00:00
|
|
|
_litex_set_reg(reg, sizeof(u8), val);
|
2020-10-13 14:45:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline void litex_write16(void __iomem *reg, u16 val)
|
|
|
|
{
|
2021-01-12 17:31:44 +00:00
|
|
|
_litex_set_reg(reg, sizeof(u16), val);
|
2020-10-13 14:45:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline void litex_write32(void __iomem *reg, u32 val)
|
|
|
|
{
|
2021-01-12 17:31:44 +00:00
|
|
|
_litex_set_reg(reg, sizeof(u32), val);
|
2020-10-13 14:45:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline void litex_write64(void __iomem *reg, u64 val)
|
|
|
|
{
|
2021-01-12 17:31:44 +00:00
|
|
|
_litex_set_reg(reg, sizeof(u64), val);
|
2020-10-13 14:45:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline u8 litex_read8(void __iomem *reg)
|
|
|
|
{
|
2021-01-12 17:31:44 +00:00
|
|
|
return _litex_get_reg(reg, sizeof(u8));
|
2020-10-13 14:45:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline u16 litex_read16(void __iomem *reg)
|
|
|
|
{
|
2021-01-12 17:31:44 +00:00
|
|
|
return _litex_get_reg(reg, sizeof(u16));
|
2020-10-13 14:45:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline u32 litex_read32(void __iomem *reg)
|
|
|
|
{
|
2021-01-12 17:31:44 +00:00
|
|
|
return _litex_get_reg(reg, sizeof(u32));
|
2020-10-13 14:45:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline u64 litex_read64(void __iomem *reg)
|
|
|
|
{
|
2021-01-12 17:31:44 +00:00
|
|
|
return _litex_get_reg(reg, sizeof(u64));
|
2020-10-13 14:45:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#endif /* _LINUX_LITEX_H */
|