Add a uclass for AXI (Advanced eXtensible Interface) busses, and a driver for the gdsys IHS AXI bus on IHS FPGAs. Signed-off-by: Mario Six <mario.six@gdsys.cc> Reviewed-by: Simon Glass <sjg@chromium.org>lime2-spi
parent
f05ebbf47a
commit
a63e54ab5f
@ -0,0 +1,13 @@ |
|||||||
|
menuconfig AXI |
||||||
|
bool "AXI bus drivers" |
||||||
|
help |
||||||
|
Support AXI (Advanced eXtensible Interface) busses, a on-chip |
||||||
|
interconnect specification for managing functional blocks in SoC |
||||||
|
designs, which is also often used in designs involving FPGAs (e.g. |
||||||
|
communication with IP cores in Xilinx FPGAs). |
||||||
|
|
||||||
|
These types of busses expose a virtual address space that can be |
||||||
|
accessed using different address widths (8, 16, and 32 are supported |
||||||
|
for now). |
||||||
|
|
||||||
|
Other similar bus architectures may be compatible as well. |
@ -0,0 +1,8 @@ |
|||||||
|
#
|
||||||
|
# (C) Copyright 2017
|
||||||
|
# Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: GPL-2.0+
|
||||||
|
#
|
||||||
|
|
||||||
|
obj-$(CONFIG_AXI) += axi-uclass.o
|
@ -0,0 +1,39 @@ |
|||||||
|
// SPDX-License-Identifier: GPL-2.0+
|
||||||
|
/*
|
||||||
|
* (C) Copyright 2017 |
||||||
|
* Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <common.h> |
||||||
|
#include <dm.h> |
||||||
|
#include <axi.h> |
||||||
|
|
||||||
|
int axi_read(struct udevice *dev, ulong address, void *data, |
||||||
|
enum axi_size_t size) |
||||||
|
{ |
||||||
|
struct axi_ops *ops = axi_get_ops(dev); |
||||||
|
|
||||||
|
if (!ops->read) |
||||||
|
return -ENOSYS; |
||||||
|
|
||||||
|
return ops->read(dev, address, data, size); |
||||||
|
} |
||||||
|
|
||||||
|
int axi_write(struct udevice *dev, ulong address, void *data, |
||||||
|
enum axi_size_t size) |
||||||
|
{ |
||||||
|
struct axi_ops *ops = axi_get_ops(dev); |
||||||
|
|
||||||
|
if (!ops->write) |
||||||
|
return -ENOSYS; |
||||||
|
|
||||||
|
return ops->write(dev, address, data, size); |
||||||
|
} |
||||||
|
|
||||||
|
UCLASS_DRIVER(axi) = { |
||||||
|
.id = UCLASS_AXI, |
||||||
|
.name = "axi", |
||||||
|
.post_bind = dm_scan_fdt_dev, |
||||||
|
.flags = DM_UC_FLAG_SEQ_ALIAS, |
||||||
|
}; |
||||||
|
|
@ -0,0 +1,78 @@ |
|||||||
|
/* SPDX-License-Identifier: GPL-2.0+ */ |
||||||
|
/*
|
||||||
|
* (C) Copyright 2017 |
||||||
|
* Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef _AXI_H_ |
||||||
|
#define _AXI_H_ |
||||||
|
|
||||||
|
enum axi_size_t { |
||||||
|
AXI_SIZE_8, |
||||||
|
AXI_SIZE_16, |
||||||
|
AXI_SIZE_32, |
||||||
|
}; |
||||||
|
|
||||||
|
/**
|
||||||
|
* struct axi_ops - driver operations for AXI uclass |
||||||
|
* |
||||||
|
* Drivers should support these operations unless otherwise noted. These |
||||||
|
* operations are intended to be used by uclass code, not directly from |
||||||
|
* other code. |
||||||
|
*/ |
||||||
|
struct axi_ops { |
||||||
|
/**
|
||||||
|
* read() - Read a single value from a specified address on a AXI bus |
||||||
|
* |
||||||
|
* @dev: AXI bus to read from. |
||||||
|
* @address: The address to read from. |
||||||
|
* @data: Pointer to a variable that takes the data value read |
||||||
|
* from the address on the AXI bus. |
||||||
|
* @size: The size of the data to be read. |
||||||
|
* @return 0 if OK, -ve on error. |
||||||
|
*/ |
||||||
|
int (*read)(struct udevice *dev, ulong address, void *data, |
||||||
|
enum axi_size_t size); |
||||||
|
|
||||||
|
/**
|
||||||
|
* write() - Write a single value to a specified address on a AXI bus |
||||||
|
* |
||||||
|
* @dev: AXI bus to write to. |
||||||
|
* @address: The address to write to. |
||||||
|
* @data: Pointer to the data value to be written to the address |
||||||
|
* on the AXI bus. |
||||||
|
* @size: The size of the data to write. |
||||||
|
* @return 0 if OK, -ve on error. |
||||||
|
*/ |
||||||
|
int (*write)(struct udevice *dev, ulong address, void *data, |
||||||
|
enum axi_size_t size); |
||||||
|
}; |
||||||
|
|
||||||
|
#define axi_get_ops(dev) ((struct axi_ops *)(dev)->driver->ops) |
||||||
|
|
||||||
|
/**
|
||||||
|
* axi_read() - Read a single value from a specified address on a AXI bus |
||||||
|
* |
||||||
|
* @dev: AXI bus to read from. |
||||||
|
* @address: The address to read from. |
||||||
|
* @data: Pointer to a variable that takes the data value read from the |
||||||
|
* address on the AXI bus. |
||||||
|
* @size: The size of the data to write. |
||||||
|
* @return 0 if OK, -ve on error. |
||||||
|
*/ |
||||||
|
int axi_read(struct udevice *dev, ulong address, void *data, |
||||||
|
enum axi_size_t size); |
||||||
|
|
||||||
|
/**
|
||||||
|
* axi_write() - Write a single value to a specified address on a AXI bus |
||||||
|
* |
||||||
|
* @dev: AXI bus to write to. |
||||||
|
* @address: The address to write to. |
||||||
|
* @data: Pointer to the data value to be written to the address on the |
||||||
|
* AXI bus. |
||||||
|
* @size: The size of the data to write. |
||||||
|
* @return 0 if OK, -ve on error. |
||||||
|
*/ |
||||||
|
int axi_write(struct udevice *dev, ulong address, void *data, |
||||||
|
enum axi_size_t size); |
||||||
|
#endif |
Loading…
Reference in new issue