OpenRISC updates for 5.12
Include: - Update for Litex SoC controller to support wider width registers as well as reset. - Refactor SMP code to use device tree to define possible cpus. - Updates build including generating vmlinux.bin -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE2cRzVK74bBA6Je/xw7McLV5mJ+QFAmA5bOcACgkQw7McLV5m J+QzlBAAl3kfYayGs286Ol5XDHQynFLkfUkGIrD8T+aHjjZS2DRJOAwoGbE+htv6 Nt6rXciHi9FNSgTf+nuTm/aQ8qSgFlsYB0AQBjLA193Og/3+G0ifQHcMoDKKRwj/ u/gqD9geGrsgVRAxqNQ18wBqX+rBPajq8+Mtjg3/ikJfkFc0GqugqevpIRNC7gN4 PmttAlOhecxFrJ1H4O4qqwctooPAIZJgRXYK8FiOBvyQXOkBmPmuodh1FhdR+jEZ /My5PQ6vYgCaXh9FuckX2xf0B3iV5+T6FFoGMPTERjz0ntglHhFLA7P18o8gsaXT vUQfT9gtoR9OckmUUxXyXlF3oZft4KouMwp04+WWaiOX52nWLXJ4Jh3GV9UbprJl TwlnOkUtQOttRIuIkKnbzDITY91RLPjH5hlO2Suc2nKG6ExNeHNqt+btn7KoFRy9 BDqRZKppBcz2PUSfHo+kC9MDM6/D4ZYlTlprW9b/U7Aa2xfVWa5KkxamiCT6gVec 8/y+8VnOU4JGl+KcAr61FoBCHgWqAOVe3XLO3oyvdpVDChNtcFl7d2zYiqoS+9fc HDR2Xivr+qClAUpFo+JeLKfISl0j/5lu1+4t7bA6fMunv3ObFHIJUKKCFBIugLu6 j9nM2F2fqDmvh6xGSFp6bP9PIa6Rmk79EA75R0F4HINU1rnnPKI= =IW6A -----END PGP SIGNATURE----- Merge tag 'for-linus' of git://github.com/openrisc/linux Pull OpenRISC updates from Stafford Horne: - Update for Litex SoC controller to support wider width registers as well as reset. - Refactor SMP code to use device tree to define possible cpus. - Update build including generating vmlinux.bin * tag 'for-linus' of git://github.com/openrisc/linux: openrisc: Use devicetree to determine present cpus drivers/soc/litex: Add restart handler openrisc: add arch/openrisc/Kbuild drivers/soc/litex: make 'litex_[set|get]_reg()' methods private drivers/soc/litex: support 32-bit subregisters, 64-bit CPUs drivers/soc/litex: s/LITEX_REG_SIZE/LITEX_SUBREG_ALIGN/g drivers/soc/litex: separate MMIO from subregister offset calculation drivers/soc/litex: move generic accessors to litex.h openrisc: restart: Call common handlers before hanging openrisc: Add vmlinux.bin target
This commit is contained in:
commit
a3905af5be
|
@ -0,0 +1,3 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
obj-y += lib/ kernel/ mm/
|
||||
obj-y += boot/dts/
|
|
@ -24,6 +24,10 @@ LIBGCC := $(shell $(CC) $(KBUILD_CFLAGS) -print-libgcc-file-name)
|
|||
|
||||
KBUILD_CFLAGS += -pipe -ffixed-r10 -D__linux__
|
||||
|
||||
all: vmlinux.bin
|
||||
|
||||
boot := arch/$(ARCH)/boot
|
||||
|
||||
ifeq ($(CONFIG_OPENRISC_HAVE_INST_MUL),y)
|
||||
KBUILD_CFLAGS += $(call cc-option,-mhard-mul)
|
||||
else
|
||||
|
@ -38,14 +42,13 @@ endif
|
|||
|
||||
head-y := arch/openrisc/kernel/head.o
|
||||
|
||||
core-y += arch/openrisc/lib/ \
|
||||
arch/openrisc/kernel/ \
|
||||
arch/openrisc/mm/
|
||||
core-y += arch/openrisc/
|
||||
libs-y += $(LIBGCC)
|
||||
|
||||
ifneq '$(CONFIG_OPENRISC_BUILTIN_DTB)' '""'
|
||||
BUILTIN_DTB := y
|
||||
else
|
||||
BUILTIN_DTB := n
|
||||
endif
|
||||
core-$(BUILTIN_DTB) += arch/openrisc/boot/dts/
|
||||
PHONY += vmlinux.bin
|
||||
|
||||
vmlinux.bin: vmlinux
|
||||
$(Q)$(MAKE) $(build)=$(boot) $(boot)/$@
|
||||
|
||||
archclean:
|
||||
$(Q)$(MAKE) $(clean)=$(boot)
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
vmlinux.bin
|
|
@ -0,0 +1,10 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
#
|
||||
# Makefile for bootable kernel images
|
||||
#
|
||||
|
||||
targets += vmlinux.bin
|
||||
|
||||
OBJCOPYFLAGS_vmlinux.bin := -O binary
|
||||
$(obj)/vmlinux.bin: vmlinux FORCE
|
||||
$(call if_changed,objcopy)
|
|
@ -34,6 +34,7 @@
|
|||
#include <linux/init_task.h>
|
||||
#include <linux/mqueue.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/reboot.h>
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/io.h>
|
||||
|
@ -49,10 +50,16 @@
|
|||
*/
|
||||
struct thread_info *current_thread_info_set[NR_CPUS] = { &init_thread_info, };
|
||||
|
||||
void machine_restart(void)
|
||||
void machine_restart(char *cmd)
|
||||
{
|
||||
printk(KERN_INFO "*** MACHINE RESTART ***\n");
|
||||
__asm__("l.nop 1");
|
||||
do_kernel_restart(cmd);
|
||||
|
||||
/* Give a grace period for failure to restart of 1s */
|
||||
mdelay(1000);
|
||||
|
||||
/* Whoops - the platform was unable to reboot. Tell the user! */
|
||||
pr_emerg("Reboot failed -- System halted\n");
|
||||
while (1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include <linux/sched.h>
|
||||
#include <linux/sched/mm.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/of.h>
|
||||
#include <asm/cpuinfo.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <asm/tlbflush.h>
|
||||
|
@ -60,22 +61,32 @@ void __init smp_prepare_boot_cpu(void)
|
|||
|
||||
void __init smp_init_cpus(void)
|
||||
{
|
||||
int i;
|
||||
struct device_node *cpu;
|
||||
u32 cpu_id;
|
||||
|
||||
for (i = 0; i < NR_CPUS; i++)
|
||||
set_cpu_possible(i, true);
|
||||
for_each_of_cpu_node(cpu) {
|
||||
if (of_property_read_u32(cpu, "reg", &cpu_id)) {
|
||||
pr_warn("%s missing reg property", cpu->full_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (cpu_id < NR_CPUS)
|
||||
set_cpu_possible(cpu_id, true);
|
||||
}
|
||||
}
|
||||
|
||||
void __init smp_prepare_cpus(unsigned int max_cpus)
|
||||
{
|
||||
int i;
|
||||
unsigned int cpu;
|
||||
|
||||
/*
|
||||
* Initialise the present map, which describes the set of CPUs
|
||||
* actually populated at the present time.
|
||||
*/
|
||||
for (i = 0; i < max_cpus; i++)
|
||||
set_cpu_present(i, true);
|
||||
for_each_possible_cpu(cpu) {
|
||||
if (cpu < max_cpus)
|
||||
set_cpu_present(cpu, true);
|
||||
}
|
||||
}
|
||||
|
||||
void __init smp_cpus_done(unsigned int max_cpus)
|
||||
|
|
|
@ -12,9 +12,21 @@ config LITEX_SOC_CONTROLLER
|
|||
select LITEX
|
||||
help
|
||||
This option enables the SoC Controller Driver which verifies
|
||||
LiteX CSR access and provides common litex_get_reg/litex_set_reg
|
||||
LiteX CSR access and provides common litex_[read|write]*
|
||||
accessors.
|
||||
All drivers that use functions from litex.h must depend on
|
||||
LITEX.
|
||||
|
||||
config LITEX_SUBREG_SIZE
|
||||
int "Size of a LiteX CSR subregister, in bytes"
|
||||
depends on LITEX
|
||||
range 1 4
|
||||
default 4
|
||||
help
|
||||
LiteX MMIO registers (referred to as Configuration and Status
|
||||
registers, or CSRs) are spread across adjacent 8- or 32-bit
|
||||
subregisters, located at 32-bit aligned MMIO addresses. Use
|
||||
this to select the appropriate size (1 or 4 bytes) matching
|
||||
your particular LiteX build.
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -15,79 +15,11 @@
|
|||
#include <linux/module.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/reboot.h>
|
||||
|
||||
/*
|
||||
* LiteX SoC Generator, depending on the configuration, can split a single
|
||||
* logical CSR (Control&Status Register) into a series of consecutive physical
|
||||
* registers.
|
||||
*
|
||||
* For example, in the configuration with 8-bit CSR Bus, 32-bit aligned (the
|
||||
* default one for 32-bit CPUs) a 32-bit logical CSR will be generated as four
|
||||
* 32-bit physical registers, each one containing one byte of meaningful data.
|
||||
*
|
||||
* For details see: https://github.com/enjoy-digital/litex/wiki/CSR-Bus
|
||||
*
|
||||
* The purpose of `litex_set_reg`/`litex_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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* litex_set_reg() - Writes the value to the LiteX CSR (Control&Status Register)
|
||||
* @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
|
||||
*
|
||||
* In the currently supported LiteX configuration (8-bit CSR Bus, 32-bit aligned),
|
||||
* a 32-bit LiteX CSR is generated as 4 consecutive 32-bit physical registers,
|
||||
* each one containing one byte of meaningful data.
|
||||
*
|
||||
* This function splits a single possibly multi-byte write into a series of
|
||||
* single-byte writes with a proper offset.
|
||||
*/
|
||||
void litex_set_reg(void __iomem *reg, unsigned long reg_size,
|
||||
unsigned long val)
|
||||
{
|
||||
unsigned long shifted_data, shift, i;
|
||||
|
||||
for (i = 0; i < reg_size; ++i) {
|
||||
shift = ((reg_size - i - 1) * LITEX_SUBREG_SIZE_BIT);
|
||||
shifted_data = val >> shift;
|
||||
|
||||
WRITE_LITEX_SUBREGISTER(shifted_data, reg, i);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(litex_set_reg);
|
||||
|
||||
/**
|
||||
* litex_get_reg() - Reads the value of the LiteX CSR (Control&Status Register)
|
||||
* @reg: Address of the CSR
|
||||
* @reg_size: The width of the CSR expressed in the number of bytes
|
||||
*
|
||||
* Return: Value read from the CSR
|
||||
*
|
||||
* In the currently supported LiteX configuration (8-bit CSR Bus, 32-bit aligned),
|
||||
* a 32-bit LiteX CSR is generated as 4 consecutive 32-bit physical registers,
|
||||
* each one containing one byte of meaningful data.
|
||||
*
|
||||
* This function generates a series of single-byte reads with a proper offset
|
||||
* and joins their results into a single multi-byte value.
|
||||
*/
|
||||
unsigned long litex_get_reg(void __iomem *reg, unsigned long reg_size)
|
||||
{
|
||||
unsigned long shifted_data, shift, i;
|
||||
unsigned long result = 0;
|
||||
|
||||
for (i = 0; i < reg_size; ++i) {
|
||||
shifted_data = READ_LITEX_SUBREGISTER(reg, i);
|
||||
|
||||
shift = ((reg_size - i - 1) * LITEX_SUBREG_SIZE_BIT);
|
||||
result |= (shifted_data << shift);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(litex_get_reg);
|
||||
/* reset register located at the base address */
|
||||
#define RESET_REG_OFF 0x00
|
||||
#define RESET_REG_VALUE 0x00000001
|
||||
|
||||
#define SCRATCH_REG_OFF 0x04
|
||||
#define SCRATCH_REG_VALUE 0x12345678
|
||||
|
@ -131,15 +63,27 @@ static int litex_check_csr_access(void __iomem *reg_addr)
|
|||
/* restore original value of the SCRATCH register */
|
||||
litex_write32(reg_addr + SCRATCH_REG_OFF, SCRATCH_REG_VALUE);
|
||||
|
||||
pr_info("LiteX SoC Controller driver initialized");
|
||||
pr_info("LiteX SoC Controller driver initialized: subreg:%d, align:%d",
|
||||
LITEX_SUBREG_SIZE, LITEX_SUBREG_ALIGN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct litex_soc_ctrl_device {
|
||||
void __iomem *base;
|
||||
struct notifier_block reset_nb;
|
||||
};
|
||||
|
||||
static int litex_reset_handler(struct notifier_block *this, unsigned long mode,
|
||||
void *cmd)
|
||||
{
|
||||
struct litex_soc_ctrl_device *soc_ctrl_dev =
|
||||
container_of(this, struct litex_soc_ctrl_device, reset_nb);
|
||||
|
||||
litex_write32(soc_ctrl_dev->base + RESET_REG_OFF, RESET_REG_VALUE);
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static const struct of_device_id litex_soc_ctrl_of_match[] = {
|
||||
{.compatible = "litex,soc-controller"},
|
||||
|
@ -151,6 +95,7 @@ MODULE_DEVICE_TABLE(of, litex_soc_ctrl_of_match);
|
|||
static int litex_soc_ctrl_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct litex_soc_ctrl_device *soc_ctrl_dev;
|
||||
int error;
|
||||
|
||||
soc_ctrl_dev = devm_kzalloc(&pdev->dev, sizeof(*soc_ctrl_dev), GFP_KERNEL);
|
||||
if (!soc_ctrl_dev)
|
||||
|
@ -160,7 +105,29 @@ static int litex_soc_ctrl_probe(struct platform_device *pdev)
|
|||
if (IS_ERR(soc_ctrl_dev->base))
|
||||
return PTR_ERR(soc_ctrl_dev->base);
|
||||
|
||||
return litex_check_csr_access(soc_ctrl_dev->base);
|
||||
error = litex_check_csr_access(soc_ctrl_dev->base);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
platform_set_drvdata(pdev, soc_ctrl_dev);
|
||||
|
||||
soc_ctrl_dev->reset_nb.notifier_call = litex_reset_handler;
|
||||
soc_ctrl_dev->reset_nb.priority = 128;
|
||||
error = register_restart_handler(&soc_ctrl_dev->reset_nb);
|
||||
if (error) {
|
||||
dev_warn(&pdev->dev, "cannot register restart handler: %d\n",
|
||||
error);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int litex_soc_ctrl_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct litex_soc_ctrl_device *soc_ctrl_dev = platform_get_drvdata(pdev);
|
||||
|
||||
unregister_restart_handler(&soc_ctrl_dev->reset_nb);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver litex_soc_ctrl_driver = {
|
||||
|
@ -169,6 +136,7 @@ static struct platform_driver litex_soc_ctrl_driver = {
|
|||
.of_match_table = of_match_ptr(litex_soc_ctrl_of_match)
|
||||
},
|
||||
.probe = litex_soc_ctrl_probe,
|
||||
.remove = litex_soc_ctrl_remove,
|
||||
};
|
||||
|
||||
module_platform_driver(litex_soc_ctrl_driver);
|
||||
|
|
|
@ -3,9 +3,6 @@
|
|||
* Common LiteX header providing
|
||||
* helper functions for accessing CSRs.
|
||||
*
|
||||
* Implementation of the functions is provided by
|
||||
* the LiteX SoC Controller driver.
|
||||
*
|
||||
* Copyright (C) 2019-2020 Antmicro <www.antmicro.com>
|
||||
*/
|
||||
|
||||
|
@ -13,90 +10,147 @@
|
|||
#define _LINUX_LITEX_H
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/compiler_types.h>
|
||||
|
||||
/*
|
||||
* The parameters below are true for LiteX SoCs configured for 8-bit CSR Bus,
|
||||
* 32-bit aligned.
|
||||
*
|
||||
* Supporting other configurations will require extending the logic in this
|
||||
* header and in the LiteX SoC controller driver.
|
||||
*/
|
||||
#define LITEX_REG_SIZE 0x4
|
||||
#define LITEX_SUBREG_SIZE 0x1
|
||||
/* 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
|
||||
#define LITEX_SUBREG_SIZE_BIT (LITEX_SUBREG_SIZE * 8)
|
||||
|
||||
#define WRITE_LITEX_SUBREGISTER(val, base_offset, subreg_id) \
|
||||
writel((u32 __force)cpu_to_le32(val), base_offset + (LITEX_REG_SIZE * subreg_id))
|
||||
/* LiteX subregisters of any width are always aligned on a 4-byte boundary */
|
||||
#define LITEX_SUBREG_ALIGN 0x4
|
||||
|
||||
#define READ_LITEX_SUBREGISTER(base_offset, subreg_id) \
|
||||
le32_to_cpu((__le32 __force)readl(base_offset + (LITEX_REG_SIZE * subreg_id)))
|
||||
static inline void _write_litex_subregister(u32 val, void __iomem *addr)
|
||||
{
|
||||
writel((u32 __force)cpu_to_le32(val), addr);
|
||||
}
|
||||
|
||||
void litex_set_reg(void __iomem *reg, unsigned long reg_sz, unsigned long val);
|
||||
static inline u32 _read_litex_subregister(void __iomem *addr)
|
||||
{
|
||||
return le32_to_cpu((__le32 __force)readl(addr));
|
||||
}
|
||||
|
||||
unsigned long litex_get_reg(void __iomem *reg, unsigned long reg_sz);
|
||||
/*
|
||||
* LiteX SoC Generator, depending on the configuration, can split a single
|
||||
* logical CSR (Control&Status Register) into a series of consecutive physical
|
||||
* registers.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* For details see: https://github.com/enjoy-digital/litex/wiki/CSR-Bus
|
||||
*/
|
||||
|
||||
/* 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)
|
||||
|
||||
/*
|
||||
* 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!
|
||||
*/
|
||||
|
||||
/**
|
||||
* _litex_set_reg() - Writes a value to the LiteX CSR (Control&Status Register)
|
||||
* @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
|
||||
*
|
||||
* This function splits a single (possibly multi-byte) LiteX CSR write into
|
||||
* a series of subregister writes with a proper offset.
|
||||
* NOTE: caller is responsible for ensuring (0 < reg_size <= sizeof(u64)).
|
||||
*/
|
||||
static inline void _litex_set_reg(void __iomem *reg, size_t reg_size, u64 val)
|
||||
{
|
||||
u8 shift = _litex_num_subregs(reg_size) * LITEX_SUBREG_SIZE_BIT;
|
||||
|
||||
while (shift > 0) {
|
||||
shift -= LITEX_SUBREG_SIZE_BIT;
|
||||
_write_litex_subregister(val >> shift, reg);
|
||||
reg += LITEX_SUBREG_ALIGN;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* _litex_get_reg() - Reads a value of the LiteX CSR (Control&Status Register)
|
||||
* @reg: Address of the CSR
|
||||
* @reg_size: The width of the CSR expressed in the number of bytes
|
||||
*
|
||||
* Return: Value read from the CSR
|
||||
*
|
||||
* 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.
|
||||
* NOTE: caller is responsible for ensuring (0 < reg_size <= sizeof(u64)).
|
||||
*/
|
||||
static inline u64 _litex_get_reg(void __iomem *reg, size_t reg_size)
|
||||
{
|
||||
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);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline void litex_write8(void __iomem *reg, u8 val)
|
||||
{
|
||||
WRITE_LITEX_SUBREGISTER(val, reg, 0);
|
||||
_litex_set_reg(reg, sizeof(u8), val);
|
||||
}
|
||||
|
||||
static inline void litex_write16(void __iomem *reg, u16 val)
|
||||
{
|
||||
WRITE_LITEX_SUBREGISTER(val >> 8, reg, 0);
|
||||
WRITE_LITEX_SUBREGISTER(val, reg, 1);
|
||||
_litex_set_reg(reg, sizeof(u16), val);
|
||||
}
|
||||
|
||||
static inline void litex_write32(void __iomem *reg, u32 val)
|
||||
{
|
||||
WRITE_LITEX_SUBREGISTER(val >> 24, reg, 0);
|
||||
WRITE_LITEX_SUBREGISTER(val >> 16, reg, 1);
|
||||
WRITE_LITEX_SUBREGISTER(val >> 8, reg, 2);
|
||||
WRITE_LITEX_SUBREGISTER(val, reg, 3);
|
||||
_litex_set_reg(reg, sizeof(u32), val);
|
||||
}
|
||||
|
||||
static inline void litex_write64(void __iomem *reg, u64 val)
|
||||
{
|
||||
WRITE_LITEX_SUBREGISTER(val >> 56, reg, 0);
|
||||
WRITE_LITEX_SUBREGISTER(val >> 48, reg, 1);
|
||||
WRITE_LITEX_SUBREGISTER(val >> 40, reg, 2);
|
||||
WRITE_LITEX_SUBREGISTER(val >> 32, reg, 3);
|
||||
WRITE_LITEX_SUBREGISTER(val >> 24, reg, 4);
|
||||
WRITE_LITEX_SUBREGISTER(val >> 16, reg, 5);
|
||||
WRITE_LITEX_SUBREGISTER(val >> 8, reg, 6);
|
||||
WRITE_LITEX_SUBREGISTER(val, reg, 7);
|
||||
_litex_set_reg(reg, sizeof(u64), val);
|
||||
}
|
||||
|
||||
static inline u8 litex_read8(void __iomem *reg)
|
||||
{
|
||||
return READ_LITEX_SUBREGISTER(reg, 0);
|
||||
return _litex_get_reg(reg, sizeof(u8));
|
||||
}
|
||||
|
||||
static inline u16 litex_read16(void __iomem *reg)
|
||||
{
|
||||
return (READ_LITEX_SUBREGISTER(reg, 0) << 8)
|
||||
| (READ_LITEX_SUBREGISTER(reg, 1));
|
||||
return _litex_get_reg(reg, sizeof(u16));
|
||||
}
|
||||
|
||||
static inline u32 litex_read32(void __iomem *reg)
|
||||
{
|
||||
return (READ_LITEX_SUBREGISTER(reg, 0) << 24)
|
||||
| (READ_LITEX_SUBREGISTER(reg, 1) << 16)
|
||||
| (READ_LITEX_SUBREGISTER(reg, 2) << 8)
|
||||
| (READ_LITEX_SUBREGISTER(reg, 3));
|
||||
return _litex_get_reg(reg, sizeof(u32));
|
||||
}
|
||||
|
||||
static inline u64 litex_read64(void __iomem *reg)
|
||||
{
|
||||
return ((u64)READ_LITEX_SUBREGISTER(reg, 0) << 56)
|
||||
| ((u64)READ_LITEX_SUBREGISTER(reg, 1) << 48)
|
||||
| ((u64)READ_LITEX_SUBREGISTER(reg, 2) << 40)
|
||||
| ((u64)READ_LITEX_SUBREGISTER(reg, 3) << 32)
|
||||
| ((u64)READ_LITEX_SUBREGISTER(reg, 4) << 24)
|
||||
| ((u64)READ_LITEX_SUBREGISTER(reg, 5) << 16)
|
||||
| ((u64)READ_LITEX_SUBREGISTER(reg, 6) << 8)
|
||||
| ((u64)READ_LITEX_SUBREGISTER(reg, 7));
|
||||
return _litex_get_reg(reg, sizeof(u64));
|
||||
}
|
||||
|
||||
#endif /* _LINUX_LITEX_H */
|
||||
|
|
Loading…
Reference in New Issue