mirror of
https://github.com/linux-msm/laptops-kernel.git
synced 2026-08-13 14:19:53 -07:00
Merge tag 'char-misc-4.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver updates from Greg KH: "Here is the "big" char and misc driver patches for 4.18-rc1. It's not a lot of stuff here, but there are some highlights: - coreboot driver updates - soundwire driver updates - android binder updates - fpga big sync, mostly documentation - lots of minor driver updates All of these have been in linux-next for a while with no reported issues" * tag 'char-misc-4.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (81 commits) vmw_balloon: fixing double free when batching mode is off MAINTAINERS: Add driver-api/fpga path fpga: clarify that unregister functions also free documentation: fpga: move fpga-region.txt to driver-api documentation: fpga: add bridge document to driver-api documentation: fpga: move fpga-mgr.txt to driver-api Documentation: fpga: move fpga overview to driver-api fpga: region: kernel-doc fixes fpga: bridge: kernel-doc fixes fpga: mgr: kernel-doc fixes fpga: use SPDX fpga: region: change api, add fpga_region_create/free fpga: bridge: change api, don't use drvdata fpga: manager: change api, don't use drvdata fpga: region: don't use drvdata in common fpga code Drivers: hv: vmbus: Removed an unnecessary cast from void * ver_linux: Drop redundant calls to system() to test if file is readable ver_linux: Move stderr redirection from function parameter to function body misc: IBM Virtual Management Channel Driver (VMC) rpmsg: Correct support for MODULE_DEVICE_TABLE() ...
This commit is contained in:
@@ -1,25 +1,25 @@
|
||||
What: /sys/bus/vmbus/devices/vmbus_*/id
|
||||
What: /sys/bus/vmbus/devices/<UUID>/id
|
||||
Date: Jul 2009
|
||||
KernelVersion: 2.6.31
|
||||
Contact: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Description: The VMBus child_relid of the device's primary channel
|
||||
Users: tools/hv/lsvmbus
|
||||
|
||||
What: /sys/bus/vmbus/devices/vmbus_*/class_id
|
||||
What: /sys/bus/vmbus/devices/<UUID>/class_id
|
||||
Date: Jul 2009
|
||||
KernelVersion: 2.6.31
|
||||
Contact: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Description: The VMBus interface type GUID of the device
|
||||
Users: tools/hv/lsvmbus
|
||||
|
||||
What: /sys/bus/vmbus/devices/vmbus_*/device_id
|
||||
What: /sys/bus/vmbus/devices/<UUID>/device_id
|
||||
Date: Jul 2009
|
||||
KernelVersion: 2.6.31
|
||||
Contact: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Description: The VMBus interface instance GUID of the device
|
||||
Users: tools/hv/lsvmbus
|
||||
|
||||
What: /sys/bus/vmbus/devices/vmbus_*/channel_vp_mapping
|
||||
What: /sys/bus/vmbus/devices/<UUID>/channel_vp_mapping
|
||||
Date: Jul 2015
|
||||
KernelVersion: 4.2.0
|
||||
Contact: K. Y. Srinivasan <kys@microsoft.com>
|
||||
@@ -28,112 +28,112 @@ Description: The mapping of which primary/sub channels are bound to which
|
||||
Format: <channel's child_relid:the bound cpu's number>
|
||||
Users: tools/hv/lsvmbus
|
||||
|
||||
What: /sys/bus/vmbus/devices/vmbus_*/device
|
||||
What: /sys/bus/vmbus/devices/<UUID>/device
|
||||
Date: Dec. 2015
|
||||
KernelVersion: 4.5
|
||||
Contact: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Description: The 16 bit device ID of the device
|
||||
Users: tools/hv/lsvmbus and user level RDMA libraries
|
||||
|
||||
What: /sys/bus/vmbus/devices/vmbus_*/vendor
|
||||
What: /sys/bus/vmbus/devices/<UUID>/vendor
|
||||
Date: Dec. 2015
|
||||
KernelVersion: 4.5
|
||||
Contact: K. Y. Srinivasan <kys@microsoft.com>
|
||||
Description: The 16 bit vendor ID of the device
|
||||
Users: tools/hv/lsvmbus and user level RDMA libraries
|
||||
|
||||
What: /sys/bus/vmbus/devices/vmbus_*/channels/NN
|
||||
What: /sys/bus/vmbus/devices/<UUID>/channels/<N>
|
||||
Date: September. 2017
|
||||
KernelVersion: 4.14
|
||||
Contact: Stephen Hemminger <sthemmin@microsoft.com>
|
||||
Description: Directory for per-channel information
|
||||
NN is the VMBUS relid associtated with the channel.
|
||||
|
||||
What: /sys/bus/vmbus/devices/vmbus_*/channels/NN/cpu
|
||||
What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/cpu
|
||||
Date: September. 2017
|
||||
KernelVersion: 4.14
|
||||
Contact: Stephen Hemminger <sthemmin@microsoft.com>
|
||||
Description: VCPU (sub)channel is affinitized to
|
||||
Users: tools/hv/lsvmbus and other debugging tools
|
||||
|
||||
What: /sys/bus/vmbus/devices/vmbus_*/channels/NN/cpu
|
||||
What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/cpu
|
||||
Date: September. 2017
|
||||
KernelVersion: 4.14
|
||||
Contact: Stephen Hemminger <sthemmin@microsoft.com>
|
||||
Description: VCPU (sub)channel is affinitized to
|
||||
Users: tools/hv/lsvmbus and other debugging tools
|
||||
|
||||
What: /sys/bus/vmbus/devices/vmbus_*/channels/NN/in_mask
|
||||
What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/in_mask
|
||||
Date: September. 2017
|
||||
KernelVersion: 4.14
|
||||
Contact: Stephen Hemminger <sthemmin@microsoft.com>
|
||||
Description: Host to guest channel interrupt mask
|
||||
Users: Debugging tools
|
||||
|
||||
What: /sys/bus/vmbus/devices/vmbus_*/channels/NN/latency
|
||||
What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/latency
|
||||
Date: September. 2017
|
||||
KernelVersion: 4.14
|
||||
Contact: Stephen Hemminger <sthemmin@microsoft.com>
|
||||
Description: Channel signaling latency
|
||||
Users: Debugging tools
|
||||
|
||||
What: /sys/bus/vmbus/devices/vmbus_*/channels/NN/out_mask
|
||||
What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/out_mask
|
||||
Date: September. 2017
|
||||
KernelVersion: 4.14
|
||||
Contact: Stephen Hemminger <sthemmin@microsoft.com>
|
||||
Description: Guest to host channel interrupt mask
|
||||
Users: Debugging tools
|
||||
|
||||
What: /sys/bus/vmbus/devices/vmbus_*/channels/NN/pending
|
||||
What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/pending
|
||||
Date: September. 2017
|
||||
KernelVersion: 4.14
|
||||
Contact: Stephen Hemminger <sthemmin@microsoft.com>
|
||||
Description: Channel interrupt pending state
|
||||
Users: Debugging tools
|
||||
|
||||
What: /sys/bus/vmbus/devices/vmbus_*/channels/NN/read_avail
|
||||
What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/read_avail
|
||||
Date: September. 2017
|
||||
KernelVersion: 4.14
|
||||
Contact: Stephen Hemminger <sthemmin@microsoft.com>
|
||||
Description: Bytes available to read
|
||||
Users: Debugging tools
|
||||
|
||||
What: /sys/bus/vmbus/devices/vmbus_*/channels/NN/write_avail
|
||||
What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/write_avail
|
||||
Date: September. 2017
|
||||
KernelVersion: 4.14
|
||||
Contact: Stephen Hemminger <sthemmin@microsoft.com>
|
||||
Description: Bytes available to write
|
||||
Users: Debugging tools
|
||||
|
||||
What: /sys/bus/vmbus/devices/vmbus_*/channels/NN/events
|
||||
What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/events
|
||||
Date: September. 2017
|
||||
KernelVersion: 4.14
|
||||
Contact: Stephen Hemminger <sthemmin@microsoft.com>
|
||||
Description: Number of times we have signaled the host
|
||||
Users: Debugging tools
|
||||
|
||||
What: /sys/bus/vmbus/devices/vmbus_*/channels/NN/interrupts
|
||||
What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/interrupts
|
||||
Date: September. 2017
|
||||
KernelVersion: 4.14
|
||||
Contact: Stephen Hemminger <sthemmin@microsoft.com>
|
||||
Description: Number of times we have taken an interrupt (incoming)
|
||||
Users: Debugging tools
|
||||
|
||||
What: /sys/bus/vmbus/devices/vmbus_*/channels/NN/subchannel_id
|
||||
What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/subchannel_id
|
||||
Date: January. 2018
|
||||
KernelVersion: 4.16
|
||||
Contact: Stephen Hemminger <sthemmin@microsoft.com>
|
||||
Description: Subchannel ID associated with VMBUS channel
|
||||
Users: Debugging tools and userspace drivers
|
||||
|
||||
What: /sys/bus/vmbus/devices/vmbus_*/channels/NN/monitor_id
|
||||
What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/monitor_id
|
||||
Date: January. 2018
|
||||
KernelVersion: 4.16
|
||||
Contact: Stephen Hemminger <sthemmin@microsoft.com>
|
||||
Description: Monitor bit associated with channel
|
||||
Users: Debugging tools and userspace drivers
|
||||
|
||||
What: /sys/bus/vmbus/devices/vmbus_*/channels/NN/ring
|
||||
What: /sys/bus/vmbus/devices/<UUID>/channels/<N>/ring
|
||||
Date: January. 2018
|
||||
KernelVersion: 4.16
|
||||
Contact: Stephen Hemminger <sthemmin@microsoft.com>
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
Lattice MachXO2 Slave SPI FPGA Manager
|
||||
|
||||
Lattice MachXO2 FPGAs support a method of loading the bitstream over
|
||||
'slave SPI' interface.
|
||||
|
||||
See 'MachXO2ProgrammingandConfigurationUsageGuide.pdf' on www.latticesemi.com
|
||||
|
||||
Required properties:
|
||||
- compatible: should contain "lattice,machxo2-slave-spi"
|
||||
- reg: spi chip select of the FPGA
|
||||
|
||||
Example for full FPGA configuration:
|
||||
|
||||
fpga-region0 {
|
||||
compatible = "fpga-region";
|
||||
fpga-mgr = <&fpga_mgr_spi>;
|
||||
#address-cells = <0x1>;
|
||||
#size-cells = <0x1>;
|
||||
};
|
||||
|
||||
spi1: spi@2000 {
|
||||
...
|
||||
|
||||
fpga_mgr_spi: fpga-mgr@0 {
|
||||
compatible = "lattice,machxo2-slave-spi";
|
||||
spi-max-frequency = <8000000>;
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,40 @@
|
||||
Zodiac Inflight Innovations RAVE EEPROM Bindings
|
||||
|
||||
RAVE SP EEPROM device is a "MFD cell" device exposing physical EEPROM
|
||||
attached to RAVE Supervisory Processor. It is expected that its Device
|
||||
Tree node is specified as a child of the node corresponding to the
|
||||
parent RAVE SP device (as documented in
|
||||
Documentation/devicetree/bindings/mfd/zii,rave-sp.txt)
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible: Should be "zii,rave-sp-eeprom"
|
||||
|
||||
Optional properties:
|
||||
|
||||
- zii,eeprom-name: Unique EEPROM identifier describing its function in the
|
||||
system. Will be used as created NVMEM deivce's name.
|
||||
|
||||
Data cells:
|
||||
|
||||
Data cells are child nodes of eerpom node, bindings for which are
|
||||
documented in Documentation/bindings/nvmem/nvmem.txt
|
||||
|
||||
Example:
|
||||
|
||||
rave-sp {
|
||||
compatible = "zii,rave-sp-rdu1";
|
||||
current-speed = <38400>;
|
||||
|
||||
eeprom@a4 {
|
||||
compatible = "zii,rave-sp-eeprom";
|
||||
reg = <0xa4 0x4000>;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
zii,eeprom-name = "main-eeprom";
|
||||
|
||||
wdt_timeout: wdt-timeout@81 {
|
||||
reg = <0x81 2>;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
FPGA Bridge
|
||||
===========
|
||||
|
||||
API to implement a new FPGA bridge
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. kernel-doc:: include/linux/fpga/fpga-bridge.h
|
||||
:functions: fpga_bridge
|
||||
|
||||
.. kernel-doc:: include/linux/fpga/fpga-bridge.h
|
||||
:functions: fpga_bridge_ops
|
||||
|
||||
.. kernel-doc:: drivers/fpga/fpga-bridge.c
|
||||
:functions: fpga_bridge_create
|
||||
|
||||
.. kernel-doc:: drivers/fpga/fpga-bridge.c
|
||||
:functions: fpga_bridge_free
|
||||
|
||||
.. kernel-doc:: drivers/fpga/fpga-bridge.c
|
||||
:functions: fpga_bridge_register
|
||||
|
||||
.. kernel-doc:: drivers/fpga/fpga-bridge.c
|
||||
:functions: fpga_bridge_unregister
|
||||
|
||||
API to control an FPGA bridge
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
You probably won't need these directly. FPGA regions should handle this.
|
||||
|
||||
.. kernel-doc:: drivers/fpga/fpga-bridge.c
|
||||
:functions: of_fpga_bridge_get
|
||||
|
||||
.. kernel-doc:: drivers/fpga/fpga-bridge.c
|
||||
:functions: fpga_bridge_get
|
||||
|
||||
.. kernel-doc:: drivers/fpga/fpga-bridge.c
|
||||
:functions: fpga_bridge_put
|
||||
|
||||
.. kernel-doc:: drivers/fpga/fpga-bridge.c
|
||||
:functions: fpga_bridge_get_to_list
|
||||
|
||||
.. kernel-doc:: drivers/fpga/fpga-bridge.c
|
||||
:functions: of_fpga_bridge_get_to_list
|
||||
|
||||
.. kernel-doc:: drivers/fpga/fpga-bridge.c
|
||||
:functions: fpga_bridge_enable
|
||||
|
||||
.. kernel-doc:: drivers/fpga/fpga-bridge.c
|
||||
:functions: fpga_bridge_disable
|
||||
@@ -0,0 +1,220 @@
|
||||
FPGA Manager
|
||||
============
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
The FPGA manager core exports a set of functions for programming an FPGA with
|
||||
an image. The API is manufacturer agnostic. All manufacturer specifics are
|
||||
hidden away in a low level driver which registers a set of ops with the core.
|
||||
The FPGA image data itself is very manufacturer specific, but for our purposes
|
||||
it's just binary data. The FPGA manager core won't parse it.
|
||||
|
||||
The FPGA image to be programmed can be in a scatter gather list, a single
|
||||
contiguous buffer, or a firmware file. Because allocating contiguous kernel
|
||||
memory for the buffer should be avoided, users are encouraged to use a scatter
|
||||
gather list instead if possible.
|
||||
|
||||
The particulars for programming the image are presented in a structure (struct
|
||||
fpga_image_info). This struct contains parameters such as pointers to the
|
||||
FPGA image as well as image-specific particulars such as whether the image was
|
||||
built for full or partial reconfiguration.
|
||||
|
||||
How to support a new FPGA device
|
||||
--------------------------------
|
||||
|
||||
To add another FPGA manager, write a driver that implements a set of ops. The
|
||||
probe function calls fpga_mgr_register(), such as::
|
||||
|
||||
static const struct fpga_manager_ops socfpga_fpga_ops = {
|
||||
.write_init = socfpga_fpga_ops_configure_init,
|
||||
.write = socfpga_fpga_ops_configure_write,
|
||||
.write_complete = socfpga_fpga_ops_configure_complete,
|
||||
.state = socfpga_fpga_ops_state,
|
||||
};
|
||||
|
||||
static int socfpga_fpga_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct socfpga_fpga_priv *priv;
|
||||
struct fpga_manager *mgr;
|
||||
int ret;
|
||||
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
/*
|
||||
* do ioremaps, get interrupts, etc. and save
|
||||
* them in priv
|
||||
*/
|
||||
|
||||
mgr = fpga_mgr_create(dev, "Altera SOCFPGA FPGA Manager",
|
||||
&socfpga_fpga_ops, priv);
|
||||
if (!mgr)
|
||||
return -ENOMEM;
|
||||
|
||||
platform_set_drvdata(pdev, mgr);
|
||||
|
||||
ret = fpga_mgr_register(mgr);
|
||||
if (ret)
|
||||
fpga_mgr_free(mgr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int socfpga_fpga_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct fpga_manager *mgr = platform_get_drvdata(pdev);
|
||||
|
||||
fpga_mgr_unregister(mgr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
The ops will implement whatever device specific register writes are needed to
|
||||
do the programming sequence for this particular FPGA. These ops return 0 for
|
||||
success or negative error codes otherwise.
|
||||
|
||||
The programming sequence is::
|
||||
1. .write_init
|
||||
2. .write or .write_sg (may be called once or multiple times)
|
||||
3. .write_complete
|
||||
|
||||
The .write_init function will prepare the FPGA to receive the image data. The
|
||||
buffer passed into .write_init will be atmost .initial_header_size bytes long,
|
||||
if the whole bitstream is not immediately available then the core code will
|
||||
buffer up at least this much before starting.
|
||||
|
||||
The .write function writes a buffer to the FPGA. The buffer may be contain the
|
||||
whole FPGA image or may be a smaller chunk of an FPGA image. In the latter
|
||||
case, this function is called multiple times for successive chunks. This interface
|
||||
is suitable for drivers which use PIO.
|
||||
|
||||
The .write_sg version behaves the same as .write except the input is a sg_table
|
||||
scatter list. This interface is suitable for drivers which use DMA.
|
||||
|
||||
The .write_complete function is called after all the image has been written
|
||||
to put the FPGA into operating mode.
|
||||
|
||||
The ops include a .state function which will read the hardware FPGA manager and
|
||||
return a code of type enum fpga_mgr_states. It doesn't result in a change in
|
||||
hardware state.
|
||||
|
||||
How to write an image buffer to a supported FPGA
|
||||
------------------------------------------------
|
||||
|
||||
Some sample code::
|
||||
|
||||
#include <linux/fpga/fpga-mgr.h>
|
||||
|
||||
struct fpga_manager *mgr;
|
||||
struct fpga_image_info *info;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Get a reference to FPGA manager. The manager is not locked, so you can
|
||||
* hold onto this reference without it preventing programming.
|
||||
*
|
||||
* This example uses the device node of the manager. Alternatively, use
|
||||
* fpga_mgr_get(dev) instead if you have the device.
|
||||
*/
|
||||
mgr = of_fpga_mgr_get(mgr_node);
|
||||
|
||||
/* struct with information about the FPGA image to program. */
|
||||
info = fpga_image_info_alloc(dev);
|
||||
|
||||
/* flags indicates whether to do full or partial reconfiguration */
|
||||
info->flags = FPGA_MGR_PARTIAL_RECONFIG;
|
||||
|
||||
/*
|
||||
* At this point, indicate where the image is. This is pseudo-code; you're
|
||||
* going to use one of these three.
|
||||
*/
|
||||
if (image is in a scatter gather table) {
|
||||
|
||||
info->sgt = [your scatter gather table]
|
||||
|
||||
} else if (image is in a buffer) {
|
||||
|
||||
info->buf = [your image buffer]
|
||||
info->count = [image buffer size]
|
||||
|
||||
} else if (image is in a firmware file) {
|
||||
|
||||
info->firmware_name = devm_kstrdup(dev, firmware_name, GFP_KERNEL);
|
||||
|
||||
}
|
||||
|
||||
/* Get exclusive control of FPGA manager */
|
||||
ret = fpga_mgr_lock(mgr);
|
||||
|
||||
/* Load the buffer to the FPGA */
|
||||
ret = fpga_mgr_buf_load(mgr, &info, buf, count);
|
||||
|
||||
/* Release the FPGA manager */
|
||||
fpga_mgr_unlock(mgr);
|
||||
fpga_mgr_put(mgr);
|
||||
|
||||
/* Deallocate the image info if you're done with it */
|
||||
fpga_image_info_free(info);
|
||||
|
||||
API for implementing a new FPGA Manager driver
|
||||
----------------------------------------------
|
||||
|
||||
.. kernel-doc:: include/linux/fpga/fpga-mgr.h
|
||||
:functions: fpga_manager
|
||||
|
||||
.. kernel-doc:: include/linux/fpga/fpga-mgr.h
|
||||
:functions: fpga_manager_ops
|
||||
|
||||
.. kernel-doc:: drivers/fpga/fpga-mgr.c
|
||||
:functions: fpga_mgr_create
|
||||
|
||||
.. kernel-doc:: drivers/fpga/fpga-mgr.c
|
||||
:functions: fpga_mgr_free
|
||||
|
||||
.. kernel-doc:: drivers/fpga/fpga-mgr.c
|
||||
:functions: fpga_mgr_register
|
||||
|
||||
.. kernel-doc:: drivers/fpga/fpga-mgr.c
|
||||
:functions: fpga_mgr_unregister
|
||||
|
||||
API for programming a FPGA
|
||||
--------------------------
|
||||
|
||||
.. kernel-doc:: include/linux/fpga/fpga-mgr.h
|
||||
:functions: fpga_image_info
|
||||
|
||||
.. kernel-doc:: include/linux/fpga/fpga-mgr.h
|
||||
:functions: fpga_mgr_states
|
||||
|
||||
.. kernel-doc:: drivers/fpga/fpga-mgr.c
|
||||
:functions: fpga_image_info_alloc
|
||||
|
||||
.. kernel-doc:: drivers/fpga/fpga-mgr.c
|
||||
:functions: fpga_image_info_free
|
||||
|
||||
.. kernel-doc:: drivers/fpga/fpga-mgr.c
|
||||
:functions: of_fpga_mgr_get
|
||||
|
||||
.. kernel-doc:: drivers/fpga/fpga-mgr.c
|
||||
:functions: fpga_mgr_get
|
||||
|
||||
.. kernel-doc:: drivers/fpga/fpga-mgr.c
|
||||
:functions: fpga_mgr_put
|
||||
|
||||
.. kernel-doc:: drivers/fpga/fpga-mgr.c
|
||||
:functions: fpga_mgr_lock
|
||||
|
||||
.. kernel-doc:: drivers/fpga/fpga-mgr.c
|
||||
:functions: fpga_mgr_unlock
|
||||
|
||||
.. kernel-doc:: include/linux/fpga/fpga-mgr.h
|
||||
:functions: fpga_mgr_states
|
||||
|
||||
Note - use :c:func:`fpga_region_program_fpga()` instead of :c:func:`fpga_mgr_load()`
|
||||
|
||||
.. kernel-doc:: drivers/fpga/fpga-mgr.c
|
||||
:functions: fpga_mgr_load
|
||||
@@ -0,0 +1,102 @@
|
||||
FPGA Region
|
||||
===========
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
This document is meant to be an brief overview of the FPGA region API usage. A
|
||||
more conceptual look at regions can be found in the Device Tree binding
|
||||
document [#f1]_.
|
||||
|
||||
For the purposes of this API document, let's just say that a region associates
|
||||
an FPGA Manager and a bridge (or bridges) with a reprogrammable region of an
|
||||
FPGA or the whole FPGA. The API provides a way to register a region and to
|
||||
program a region.
|
||||
|
||||
Currently the only layer above fpga-region.c in the kernel is the Device Tree
|
||||
support (of-fpga-region.c) described in [#f1]_. The DT support layer uses regions
|
||||
to program the FPGA and then DT to handle enumeration. The common region code
|
||||
is intended to be used by other schemes that have other ways of accomplishing
|
||||
enumeration after programming.
|
||||
|
||||
An fpga-region can be set up to know the following things:
|
||||
|
||||
* which FPGA manager to use to do the programming
|
||||
|
||||
* which bridges to disable before programming and enable afterwards.
|
||||
|
||||
Additional info needed to program the FPGA image is passed in the struct
|
||||
fpga_image_info including:
|
||||
|
||||
* pointers to the image as either a scatter-gather buffer, a contiguous
|
||||
buffer, or the name of firmware file
|
||||
|
||||
* flags indicating specifics such as whether the image if for partial
|
||||
reconfiguration.
|
||||
|
||||
How to program a FPGA using a region
|
||||
------------------------------------
|
||||
|
||||
First, allocate the info struct::
|
||||
|
||||
info = fpga_image_info_alloc(dev);
|
||||
if (!info)
|
||||
return -ENOMEM;
|
||||
|
||||
Set flags as needed, i.e.::
|
||||
|
||||
info->flags |= FPGA_MGR_PARTIAL_RECONFIG;
|
||||
|
||||
Point to your FPGA image, such as::
|
||||
|
||||
info->sgt = &sgt;
|
||||
|
||||
Add info to region and do the programming::
|
||||
|
||||
region->info = info;
|
||||
ret = fpga_region_program_fpga(region);
|
||||
|
||||
:c:func:`fpga_region_program_fpga()` operates on info passed in the
|
||||
fpga_image_info (region->info). This function will attempt to:
|
||||
|
||||
* lock the region's mutex
|
||||
* lock the region's FPGA manager
|
||||
* build a list of FPGA bridges if a method has been specified to do so
|
||||
* disable the bridges
|
||||
* program the FPGA
|
||||
* re-enable the bridges
|
||||
* release the locks
|
||||
|
||||
Then you will want to enumerate whatever hardware has appeared in the FPGA.
|
||||
|
||||
How to add a new FPGA region
|
||||
----------------------------
|
||||
|
||||
An example of usage can be seen in the probe function of [#f2]_.
|
||||
|
||||
.. [#f1] ../devicetree/bindings/fpga/fpga-region.txt
|
||||
.. [#f2] ../../drivers/fpga/of-fpga-region.c
|
||||
|
||||
API to program a FGPA
|
||||
---------------------
|
||||
|
||||
.. kernel-doc:: drivers/fpga/fpga-region.c
|
||||
:functions: fpga_region_program_fpga
|
||||
|
||||
API to add a new FPGA region
|
||||
----------------------------
|
||||
|
||||
.. kernel-doc:: include/linux/fpga/fpga-region.h
|
||||
:functions: fpga_region
|
||||
|
||||
.. kernel-doc:: drivers/fpga/fpga-region.c
|
||||
:functions: fpga_region_create
|
||||
|
||||
.. kernel-doc:: drivers/fpga/fpga-region.c
|
||||
:functions: fpga_region_free
|
||||
|
||||
.. kernel-doc:: drivers/fpga/fpga-region.c
|
||||
:functions: fpga_region_register
|
||||
|
||||
.. kernel-doc:: drivers/fpga/fpga-region.c
|
||||
:functions: fpga_region_unregister
|
||||
@@ -0,0 +1,13 @@
|
||||
==============
|
||||
FPGA Subsystem
|
||||
==============
|
||||
|
||||
:Author: Alan Tull
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
intro
|
||||
fpga-mgr
|
||||
fpga-bridge
|
||||
fpga-region
|
||||
@@ -0,0 +1,54 @@
|
||||
Introduction
|
||||
============
|
||||
|
||||
The FPGA subsystem supports reprogramming FPGAs dynamically under
|
||||
Linux. Some of the core intentions of the FPGA subsystems are:
|
||||
|
||||
* The FPGA subsystem is vendor agnostic.
|
||||
|
||||
* The FPGA subsystem separates upper layers (userspace interfaces and
|
||||
enumeration) from lower layers that know how to program a specific
|
||||
FPGA.
|
||||
|
||||
* Code should not be shared between upper and lower layers. This
|
||||
should go without saying. If that seems necessary, there's probably
|
||||
framework functionality that that can be added that will benefit
|
||||
other users. Write the linux-fpga mailing list and maintainers and
|
||||
seek out a solution that expands the framework for broad reuse.
|
||||
|
||||
* Generally, when adding code, think of the future. Plan for re-use.
|
||||
|
||||
The framework in the kernel is divided into:
|
||||
|
||||
FPGA Manager
|
||||
------------
|
||||
|
||||
If you are adding a new FPGA or a new method of programming a FPGA,
|
||||
this is the subsystem for you. Low level FPGA manager drivers contain
|
||||
the knowledge of how to program a specific device. This subsystem
|
||||
includes the framework in fpga-mgr.c and the low level drivers that
|
||||
are registered with it.
|
||||
|
||||
FPGA Bridge
|
||||
-----------
|
||||
|
||||
FPGA Bridges prevent spurious signals from going out of a FPGA or a
|
||||
region of a FPGA during programming. They are disabled before
|
||||
programming begins and re-enabled afterwards. An FPGA bridge may be
|
||||
actual hard hardware that gates a bus to a cpu or a soft ("freeze")
|
||||
bridge in FPGA fabric that surrounds a partial reconfiguration region
|
||||
of an FPGA. This subsystem includes fpga-bridge.c and the low level
|
||||
drivers that are registered with it.
|
||||
|
||||
FPGA Region
|
||||
-----------
|
||||
|
||||
If you are adding a new interface to the FPGA framework, add it on top
|
||||
of a FPGA region to allow the most reuse of your interface.
|
||||
|
||||
The FPGA Region framework (fpga-region.c) associates managers and
|
||||
bridges as reconfigurable regions. A region may refer to the whole
|
||||
FPGA in full reconfiguration or to a partial reconfiguration region.
|
||||
|
||||
The Device Tree FPGA Region support (of-fpga-region.c) handles
|
||||
reprogramming FPGAs when device tree overlays are applied.
|
||||
@@ -51,6 +51,7 @@ available subsections can be seen below.
|
||||
dmaengine/index
|
||||
slimbus
|
||||
soundwire/index
|
||||
fpga/index
|
||||
|
||||
.. only:: subproject and html
|
||||
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
========================
|
||||
SoundWire Error Handling
|
||||
========================
|
||||
|
||||
The SoundWire PHY was designed with care and errors on the bus are going to
|
||||
be very unlikely, and if they happen it should be limited to single bit
|
||||
errors. Examples of this design can be found in the synchronization
|
||||
mechanism (sync loss after two errors) and short CRCs used for the Bulk
|
||||
Register Access.
|
||||
|
||||
The errors can be detected with multiple mechanisms:
|
||||
|
||||
1. Bus clash or parity errors: This mechanism relies on low-level detectors
|
||||
that are independent of the payload and usages, and they cover both control
|
||||
and audio data. The current implementation only logs such errors.
|
||||
Improvements could be invalidating an entire programming sequence and
|
||||
restarting from a known position. In the case of such errors outside of a
|
||||
control/command sequence, there is no concealment or recovery for audio
|
||||
data enabled by the SoundWire protocol, the location of the error will also
|
||||
impact its audibility (most-significant bits will be more impacted in PCM),
|
||||
and after a number of such errors are detected the bus might be reset. Note
|
||||
that bus clashes due to programming errors (two streams using the same bit
|
||||
slots) or electrical issues during the transmit/receive transition cannot
|
||||
be distinguished, although a recurring bus clash when audio is enabled is a
|
||||
indication of a bus allocation issue. The interrupt mechanism can also help
|
||||
identify Slaves which detected a Bus Clash or a Parity Error, but they may
|
||||
not be responsible for the errors so resetting them individually is not a
|
||||
viable recovery strategy.
|
||||
|
||||
2. Command status: Each command is associated with a status, which only
|
||||
covers transmission of the data between devices. The ACK status indicates
|
||||
that the command was received and will be executed by the end of the
|
||||
current frame. A NAK indicates that the command was in error and will not
|
||||
be applied. In case of a bad programming (command sent to non-existent
|
||||
Slave or to a non-implemented register) or electrical issue, no response
|
||||
signals the command was ignored. Some Master implementations allow for a
|
||||
command to be retransmitted several times. If the retransmission fails,
|
||||
backtracking and restarting the entire programming sequence might be a
|
||||
solution. Alternatively some implementations might directly issue a bus
|
||||
reset and re-enumerate all devices.
|
||||
|
||||
3. Timeouts: In a number of cases such as ChannelPrepare or
|
||||
ClockStopPrepare, the bus driver is supposed to poll a register field until
|
||||
it transitions to a NotFinished value of zero. The MIPI SoundWire spec 1.1
|
||||
does not define timeouts but the MIPI SoundWire DisCo document adds
|
||||
recommendation on timeouts. If such configurations do not complete, the
|
||||
driver will return a -ETIMEOUT. Such timeouts are symptoms of a faulty
|
||||
Slave device and are likely impossible to recover from.
|
||||
|
||||
Errors during global reconfiguration sequences are extremely difficult to
|
||||
handle:
|
||||
|
||||
1. BankSwitch: An error during the last command issuing a BankSwitch is
|
||||
difficult to backtrack from. Retransmitting the Bank Switch command may be
|
||||
possible in a single segment setup, but this can lead to synchronization
|
||||
problems when enabling multiple bus segments (a command with side effects
|
||||
such as frame reconfiguration would be handled at different times). A global
|
||||
hard-reset might be the best solution.
|
||||
|
||||
Note that SoundWire does not provide a mechanism to detect illegal values
|
||||
written in valid registers. In a number of cases the standard even mentions
|
||||
that the Slave might behave in implementation-defined ways. The bus
|
||||
implementation does not provide a recovery mechanism for such errors, Slave
|
||||
or Master driver implementers are responsible for writing valid values in
|
||||
valid registers and implement additional range checking if needed.
|
||||
@@ -6,6 +6,9 @@ SoundWire Documentation
|
||||
:maxdepth: 1
|
||||
|
||||
summary
|
||||
stream
|
||||
error_handling
|
||||
locking
|
||||
|
||||
.. only:: subproject
|
||||
|
||||
|
||||
@@ -0,0 +1,106 @@
|
||||
=================
|
||||
SoundWire Locking
|
||||
=================
|
||||
|
||||
This document explains locking mechanism of the SoundWire Bus. Bus uses
|
||||
following locks in order to avoid race conditions in Bus operations on
|
||||
shared resources.
|
||||
|
||||
- Bus lock
|
||||
|
||||
- Message lock
|
||||
|
||||
Bus lock
|
||||
========
|
||||
|
||||
SoundWire Bus lock is a mutex and is part of Bus data structure
|
||||
(sdw_bus) which is used for every Bus instance. This lock is used to
|
||||
serialize each of the following operations(s) within SoundWire Bus instance.
|
||||
|
||||
- Addition and removal of Slave(s), changing Slave status.
|
||||
|
||||
- Prepare, Enable, Disable and De-prepare stream operations.
|
||||
|
||||
- Access of Stream data structure.
|
||||
|
||||
Message lock
|
||||
============
|
||||
|
||||
SoundWire message transfer lock. This mutex is part of
|
||||
Bus data structure (sdw_bus). This lock is used to serialize the message
|
||||
transfers (read/write) within a SoundWire Bus instance.
|
||||
|
||||
Below examples show how locks are acquired.
|
||||
|
||||
Example 1
|
||||
---------
|
||||
|
||||
Message transfer.
|
||||
|
||||
1. For every message transfer
|
||||
|
||||
a. Acquire Message lock.
|
||||
|
||||
b. Transfer message (Read/Write) to Slave1 or broadcast message on
|
||||
Bus in case of bank switch.
|
||||
|
||||
c. Release Message lock ::
|
||||
|
||||
+----------+ +---------+
|
||||
| | | |
|
||||
| Bus | | Master |
|
||||
| | | Driver |
|
||||
| | | |
|
||||
+----+-----+ +----+----+
|
||||
| |
|
||||
| bus->ops->xfer_msg() |
|
||||
<-------------------------------+ a. Acquire Message lock
|
||||
| | b. Transfer message
|
||||
| |
|
||||
+-------------------------------> c. Release Message lock
|
||||
| return success/error | d. Return success/error
|
||||
| |
|
||||
+ +
|
||||
|
||||
Example 2
|
||||
---------
|
||||
|
||||
Prepare operation.
|
||||
|
||||
1. Acquire lock for Bus instance associated with Master 1.
|
||||
|
||||
2. For every message transfer in Prepare operation
|
||||
|
||||
a. Acquire Message lock.
|
||||
|
||||
b. Transfer message (Read/Write) to Slave1 or broadcast message on
|
||||
Bus in case of bank switch.
|
||||
|
||||
c. Release Message lock.
|
||||
|
||||
3. Release lock for Bus instance associated with Master 1 ::
|
||||
|
||||
+----------+ +---------+
|
||||
| | | |
|
||||
| Bus | | Master |
|
||||
| | | Driver |
|
||||
| | | |
|
||||
+----+-----+ +----+----+
|
||||
| |
|
||||
| sdw_prepare_stream() |
|
||||
<-------------------------------+ 1. Acquire bus lock
|
||||
| | 2. Perform stream prepare
|
||||
| |
|
||||
| |
|
||||
| bus->ops->xfer_msg() |
|
||||
<-------------------------------+ a. Acquire Message lock
|
||||
| | b. Transfer message
|
||||
| |
|
||||
+-------------------------------> c. Release Message lock
|
||||
| return success/error | d. Return success/error
|
||||
| |
|
||||
| |
|
||||
| return success/error | 3. Release bus lock
|
||||
+-------------------------------> 4. Return success/error
|
||||
| |
|
||||
+ +
|
||||
@@ -0,0 +1,372 @@
|
||||
=========================
|
||||
Audio Stream in SoundWire
|
||||
=========================
|
||||
|
||||
An audio stream is a logical or virtual connection created between
|
||||
|
||||
(1) System memory buffer(s) and Codec(s)
|
||||
|
||||
(2) DSP memory buffer(s) and Codec(s)
|
||||
|
||||
(3) FIFO(s) and Codec(s)
|
||||
|
||||
(4) Codec(s) and Codec(s)
|
||||
|
||||
which is typically driven by a DMA(s) channel through the data link. An
|
||||
audio stream contains one or more channels of data. All channels within
|
||||
stream must have same sample rate and same sample size.
|
||||
|
||||
Assume a stream with two channels (Left & Right) is opened using SoundWire
|
||||
interface. Below are some ways a stream can be represented in SoundWire.
|
||||
|
||||
Stream Sample in memory (System memory, DSP memory or FIFOs) ::
|
||||
|
||||
-------------------------
|
||||
| L | R | L | R | L | R |
|
||||
-------------------------
|
||||
|
||||
Example 1: Stereo Stream with L and R channels is rendered from Master to
|
||||
Slave. Both Master and Slave is using single port. ::
|
||||
|
||||
+---------------+ Clock Signal +---------------+
|
||||
| Master +----------------------------------+ Slave |
|
||||
| Interface | | Interface |
|
||||
| | | 1 |
|
||||
| | Data Signal | |
|
||||
| L + R +----------------------------------+ L + R |
|
||||
| (Data) | Data Direction | (Data) |
|
||||
+---------------+ +-----------------------> +---------------+
|
||||
|
||||
|
||||
Example 2: Stereo Stream with L and R channels is captured from Slave to
|
||||
Master. Both Master and Slave is using single port. ::
|
||||
|
||||
|
||||
+---------------+ Clock Signal +---------------+
|
||||
| Master +----------------------------------+ Slave |
|
||||
| Interface | | Interface |
|
||||
| | | 1 |
|
||||
| | Data Signal | |
|
||||
| L + R +----------------------------------+ L + R |
|
||||
| (Data) | Data Direction | (Data) |
|
||||
+---------------+ <-----------------------+ +---------------+
|
||||
|
||||
|
||||
Example 3: Stereo Stream with L and R channels is rendered by Master. Each
|
||||
of the L and R channel is received by two different Slaves. Master and both
|
||||
Slaves are using single port. ::
|
||||
|
||||
+---------------+ Clock Signal +---------------+
|
||||
| Master +---------+------------------------+ Slave |
|
||||
| Interface | | | Interface |
|
||||
| | | | 1 |
|
||||
| | | Data Signal | |
|
||||
| L + R +---+------------------------------+ L |
|
||||
| (Data) | | | Data Direction | (Data) |
|
||||
+---------------+ | | +-------------> +---------------+
|
||||
| |
|
||||
| |
|
||||
| | +---------------+
|
||||
| +----------------------> | Slave |
|
||||
| | Interface |
|
||||
| | 2 |
|
||||
| | |
|
||||
+----------------------------> | R |
|
||||
| (Data) |
|
||||
+---------------+
|
||||
|
||||
|
||||
Example 4: Stereo Stream with L and R channel is rendered by two different
|
||||
Ports of the Master and is received by only single Port of the Slave
|
||||
interface. ::
|
||||
|
||||
+--------------------+
|
||||
| |
|
||||
| +--------------+ +----------------+
|
||||
| | || | |
|
||||
| | Data Port || L Channel | |
|
||||
| | 1 |------------+ | |
|
||||
| | L Channel || | +-----+----+ |
|
||||
| | (Data) || | L + R Channel || Data | |
|
||||
| Master +----------+ | +---+---------> || Port | |
|
||||
| Interface | | || 1 | |
|
||||
| +--------------+ | || | |
|
||||
| | || | +----------+ |
|
||||
| | Data Port |------------+ | |
|
||||
| | 2 || R Channel | Slave |
|
||||
| | R Channel || | Interface |
|
||||
| | (Data) || | 1 |
|
||||
| +--------------+ Clock Signal | L + R |
|
||||
| +---------------------------> | (Data) |
|
||||
+--------------------+ | |
|
||||
+----------------+
|
||||
|
||||
SoundWire Stream Management flow
|
||||
================================
|
||||
|
||||
Stream definitions
|
||||
------------------
|
||||
|
||||
(1) Current stream: This is classified as the stream on which operation has
|
||||
to be performed like prepare, enable, disable, de-prepare etc.
|
||||
|
||||
(2) Active stream: This is classified as the stream which is already active
|
||||
on Bus other than current stream. There can be multiple active streams
|
||||
on the Bus.
|
||||
|
||||
SoundWire Bus manages stream operations for each stream getting
|
||||
rendered/captured on the SoundWire Bus. This section explains Bus operations
|
||||
done for each of the stream allocated/released on Bus. Following are the
|
||||
stream states maintained by the Bus for each of the audio stream.
|
||||
|
||||
|
||||
SoundWire stream states
|
||||
-----------------------
|
||||
|
||||
Below shows the SoundWire stream states and state transition diagram. ::
|
||||
|
||||
+-----------+ +------------+ +----------+ +----------+
|
||||
| ALLOCATED +---->| CONFIGURED +---->| PREPARED +---->| ENABLED |
|
||||
| STATE | | STATE | | STATE | | STATE |
|
||||
+-----------+ +------------+ +----------+ +----+-----+
|
||||
^
|
||||
|
|
||||
|
|
||||
v
|
||||
+----------+ +------------+ +----+-----+
|
||||
| RELEASED |<----------+ DEPREPARED |<-------+ DISABLED |
|
||||
| STATE | | STATE | | STATE |
|
||||
+----------+ +------------+ +----------+
|
||||
|
||||
NOTE: State transition between prepare and deprepare is supported in Spec
|
||||
but not in the software (subsystem)
|
||||
|
||||
NOTE2: Stream state transition checks need to be handled by caller
|
||||
framework, for example ALSA/ASoC. No checks for stream transition exist in
|
||||
SoundWire subsystem.
|
||||
|
||||
Stream State Operations
|
||||
-----------------------
|
||||
|
||||
Below section explains the operations done by the Bus on Master(s) and
|
||||
Slave(s) as part of stream state transitions.
|
||||
|
||||
SDW_STREAM_ALLOCATED
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Allocation state for stream. This is the entry state
|
||||
of the stream. Operations performed before entering in this state:
|
||||
|
||||
(1) A stream runtime is allocated for the stream. This stream
|
||||
runtime is used as a reference for all the operations performed
|
||||
on the stream.
|
||||
|
||||
(2) The resources required for holding stream runtime information are
|
||||
allocated and initialized. This holds all stream related information
|
||||
such as stream type (PCM/PDM) and parameters, Master and Slave
|
||||
interface associated with the stream, stream state etc.
|
||||
|
||||
After all above operations are successful, stream state is set to
|
||||
``SDW_STREAM_ALLOCATED``.
|
||||
|
||||
Bus implements below API for allocate a stream which needs to be called once
|
||||
per stream. From ASoC DPCM framework, this stream state maybe linked to
|
||||
.startup() operation.
|
||||
|
||||
.. code-block:: c
|
||||
int sdw_alloc_stream(char * stream_name);
|
||||
|
||||
|
||||
SDW_STREAM_CONFIGURED
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Configuration state of stream. Operations performed before entering in
|
||||
this state:
|
||||
|
||||
(1) The resources allocated for stream information in SDW_STREAM_ALLOCATED
|
||||
state are updated here. This includes stream parameters, Master(s)
|
||||
and Slave(s) runtime information associated with current stream.
|
||||
|
||||
(2) All the Master(s) and Slave(s) associated with current stream provide
|
||||
the port information to Bus which includes port numbers allocated by
|
||||
Master(s) and Slave(s) for current stream and their channel mask.
|
||||
|
||||
After all above operations are successful, stream state is set to
|
||||
``SDW_STREAM_CONFIGURED``.
|
||||
|
||||
Bus implements below APIs for CONFIG state which needs to be called by
|
||||
the respective Master(s) and Slave(s) associated with stream. These APIs can
|
||||
only be invoked once by respective Master(s) and Slave(s). From ASoC DPCM
|
||||
framework, this stream state is linked to .hw_params() operation.
|
||||
|
||||
.. code-block:: c
|
||||
int sdw_stream_add_master(struct sdw_bus * bus,
|
||||
struct sdw_stream_config * stream_config,
|
||||
struct sdw_ports_config * ports_config,
|
||||
struct sdw_stream_runtime * stream);
|
||||
|
||||
int sdw_stream_add_slave(struct sdw_slave * slave,
|
||||
struct sdw_stream_config * stream_config,
|
||||
struct sdw_ports_config * ports_config,
|
||||
struct sdw_stream_runtime * stream);
|
||||
|
||||
|
||||
SDW_STREAM_PREPARED
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Prepare state of stream. Operations performed before entering in this state:
|
||||
|
||||
(1) Bus parameters such as bandwidth, frame shape, clock frequency,
|
||||
are computed based on current stream as well as already active
|
||||
stream(s) on Bus. Re-computation is required to accommodate current
|
||||
stream on the Bus.
|
||||
|
||||
(2) Transport and port parameters of all Master(s) and Slave(s) port(s) are
|
||||
computed for the current as well as already active stream based on frame
|
||||
shape and clock frequency computed in step 1.
|
||||
|
||||
(3) Computed Bus and transport parameters are programmed in Master(s) and
|
||||
Slave(s) registers. The banked registers programming is done on the
|
||||
alternate bank (bank currently unused). Port(s) are enabled for the
|
||||
already active stream(s) on the alternate bank (bank currently unused).
|
||||
This is done in order to not disrupt already active stream(s).
|
||||
|
||||
(4) Once all the values are programmed, Bus initiates switch to alternate
|
||||
bank where all new values programmed gets into effect.
|
||||
|
||||
(5) Ports of Master(s) and Slave(s) for current stream are prepared by
|
||||
programming PrepareCtrl register.
|
||||
|
||||
After all above operations are successful, stream state is set to
|
||||
``SDW_STREAM_PREPARED``.
|
||||
|
||||
Bus implements below API for PREPARE state which needs to be called once per
|
||||
stream. From ASoC DPCM framework, this stream state is linked to
|
||||
.prepare() operation.
|
||||
|
||||
.. code-block:: c
|
||||
int sdw_prepare_stream(struct sdw_stream_runtime * stream);
|
||||
|
||||
|
||||
SDW_STREAM_ENABLED
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Enable state of stream. The data port(s) are enabled upon entering this state.
|
||||
Operations performed before entering in this state:
|
||||
|
||||
(1) All the values computed in SDW_STREAM_PREPARED state are programmed
|
||||
in alternate bank (bank currently unused). It includes programming of
|
||||
already active stream(s) as well.
|
||||
|
||||
(2) All the Master(s) and Slave(s) port(s) for the current stream are
|
||||
enabled on alternate bank (bank currently unused) by programming
|
||||
ChannelEn register.
|
||||
|
||||
(3) Once all the values are programmed, Bus initiates switch to alternate
|
||||
bank where all new values programmed gets into effect and port(s)
|
||||
associated with current stream are enabled.
|
||||
|
||||
After all above operations are successful, stream state is set to
|
||||
``SDW_STREAM_ENABLED``.
|
||||
|
||||
Bus implements below API for ENABLE state which needs to be called once per
|
||||
stream. From ASoC DPCM framework, this stream state is linked to
|
||||
.trigger() start operation.
|
||||
|
||||
.. code-block:: c
|
||||
int sdw_enable_stream(struct sdw_stream_runtime * stream);
|
||||
|
||||
SDW_STREAM_DISABLED
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Disable state of stream. The data port(s) are disabled upon exiting this state.
|
||||
Operations performed before entering in this state:
|
||||
|
||||
(1) All the Master(s) and Slave(s) port(s) for the current stream are
|
||||
disabled on alternate bank (bank currently unused) by programming
|
||||
ChannelEn register.
|
||||
|
||||
(2) All the current configuration of Bus and active stream(s) are programmed
|
||||
into alternate bank (bank currently unused).
|
||||
|
||||
(3) Once all the values are programmed, Bus initiates switch to alternate
|
||||
bank where all new values programmed gets into effect and port(s) associated
|
||||
with current stream are disabled.
|
||||
|
||||
After all above operations are successful, stream state is set to
|
||||
``SDW_STREAM_DISABLED``.
|
||||
|
||||
Bus implements below API for DISABLED state which needs to be called once
|
||||
per stream. From ASoC DPCM framework, this stream state is linked to
|
||||
.trigger() stop operation.
|
||||
|
||||
.. code-block:: c
|
||||
int sdw_disable_stream(struct sdw_stream_runtime * stream);
|
||||
|
||||
|
||||
SDW_STREAM_DEPREPARED
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
De-prepare state of stream. Operations performed before entering in this
|
||||
state:
|
||||
|
||||
(1) All the port(s) of Master(s) and Slave(s) for current stream are
|
||||
de-prepared by programming PrepareCtrl register.
|
||||
|
||||
(2) The payload bandwidth of current stream is reduced from the total
|
||||
bandwidth requirement of bus and new parameters calculated and
|
||||
applied by performing bank switch etc.
|
||||
|
||||
After all above operations are successful, stream state is set to
|
||||
``SDW_STREAM_DEPREPARED``.
|
||||
|
||||
Bus implements below API for DEPREPARED state which needs to be called once
|
||||
per stream. From ASoC DPCM framework, this stream state is linked to
|
||||
.trigger() stop operation.
|
||||
|
||||
.. code-block:: c
|
||||
int sdw_deprepare_stream(struct sdw_stream_runtime * stream);
|
||||
|
||||
|
||||
SDW_STREAM_RELEASED
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Release state of stream. Operations performed before entering in this state:
|
||||
|
||||
(1) Release port resources for all Master(s) and Slave(s) port(s)
|
||||
associated with current stream.
|
||||
|
||||
(2) Release Master(s) and Slave(s) runtime resources associated with
|
||||
current stream.
|
||||
|
||||
(3) Release stream runtime resources associated with current stream.
|
||||
|
||||
After all above operations are successful, stream state is set to
|
||||
``SDW_STREAM_RELEASED``.
|
||||
|
||||
Bus implements below APIs for RELEASE state which needs to be called by
|
||||
all the Master(s) and Slave(s) associated with stream. From ASoC DPCM
|
||||
framework, this stream state is linked to .hw_free() operation.
|
||||
|
||||
.. code-block:: c
|
||||
int sdw_stream_remove_master(struct sdw_bus * bus,
|
||||
struct sdw_stream_runtime * stream);
|
||||
int sdw_stream_remove_slave(struct sdw_slave * slave,
|
||||
struct sdw_stream_runtime * stream);
|
||||
|
||||
|
||||
The .shutdown() ASoC DPCM operation calls below Bus API to release
|
||||
stream assigned as part of ALLOCATED state.
|
||||
|
||||
In .shutdown() the data structure maintaining stream state are freed up.
|
||||
|
||||
.. code-block:: c
|
||||
void sdw_release_stream(struct sdw_stream_runtime * stream);
|
||||
|
||||
Not Supported
|
||||
=============
|
||||
|
||||
1. A single port with multiple channels supported cannot be used between two
|
||||
streams or across stream. For example a port with 4 channels cannot be used
|
||||
to handle 2 independent stereo streams even though it's possible in theory
|
||||
in SoundWire.
|
||||
@@ -1,199 +0,0 @@
|
||||
FPGA Manager Core
|
||||
|
||||
Alan Tull 2015
|
||||
|
||||
Overview
|
||||
========
|
||||
|
||||
The FPGA manager core exports a set of functions for programming an FPGA with
|
||||
an image. The API is manufacturer agnostic. All manufacturer specifics are
|
||||
hidden away in a low level driver which registers a set of ops with the core.
|
||||
The FPGA image data itself is very manufacturer specific, but for our purposes
|
||||
it's just binary data. The FPGA manager core won't parse it.
|
||||
|
||||
The FPGA image to be programmed can be in a scatter gather list, a single
|
||||
contiguous buffer, or a firmware file. Because allocating contiguous kernel
|
||||
memory for the buffer should be avoided, users are encouraged to use a scatter
|
||||
gather list instead if possible.
|
||||
|
||||
The particulars for programming the image are presented in a structure (struct
|
||||
fpga_image_info). This struct contains parameters such as pointers to the
|
||||
FPGA image as well as image-specific particulars such as whether the image was
|
||||
built for full or partial reconfiguration.
|
||||
|
||||
API Functions:
|
||||
==============
|
||||
|
||||
To program the FPGA:
|
||||
--------------------
|
||||
|
||||
int fpga_mgr_load(struct fpga_manager *mgr,
|
||||
struct fpga_image_info *info);
|
||||
|
||||
Load the FPGA from an image which is indicated in the info. If successful,
|
||||
the FPGA ends up in operating mode. Return 0 on success or a negative error
|
||||
code.
|
||||
|
||||
To allocate or free a struct fpga_image_info:
|
||||
---------------------------------------------
|
||||
|
||||
struct fpga_image_info *fpga_image_info_alloc(struct device *dev);
|
||||
|
||||
void fpga_image_info_free(struct fpga_image_info *info);
|
||||
|
||||
To get/put a reference to a FPGA manager:
|
||||
-----------------------------------------
|
||||
|
||||
struct fpga_manager *of_fpga_mgr_get(struct device_node *node);
|
||||
struct fpga_manager *fpga_mgr_get(struct device *dev);
|
||||
void fpga_mgr_put(struct fpga_manager *mgr);
|
||||
|
||||
Given a DT node or device, get a reference to a FPGA manager. This pointer
|
||||
can be saved until you are ready to program the FPGA. fpga_mgr_put releases
|
||||
the reference.
|
||||
|
||||
|
||||
To get exclusive control of a FPGA manager:
|
||||
-------------------------------------------
|
||||
|
||||
int fpga_mgr_lock(struct fpga_manager *mgr);
|
||||
void fpga_mgr_unlock(struct fpga_manager *mgr);
|
||||
|
||||
The user should call fpga_mgr_lock and verify that it returns 0 before
|
||||
attempting to program the FPGA. Likewise, the user should call
|
||||
fpga_mgr_unlock when done programming the FPGA.
|
||||
|
||||
|
||||
To register or unregister the low level FPGA-specific driver:
|
||||
-------------------------------------------------------------
|
||||
|
||||
int fpga_mgr_register(struct device *dev, const char *name,
|
||||
const struct fpga_manager_ops *mops,
|
||||
void *priv);
|
||||
|
||||
void fpga_mgr_unregister(struct device *dev);
|
||||
|
||||
Use of these two functions is described below in "How To Support a new FPGA
|
||||
device."
|
||||
|
||||
|
||||
How to write an image buffer to a supported FPGA
|
||||
================================================
|
||||
#include <linux/fpga/fpga-mgr.h>
|
||||
|
||||
struct fpga_manager *mgr;
|
||||
struct fpga_image_info *info;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* Get a reference to FPGA manager. The manager is not locked, so you can
|
||||
* hold onto this reference without it preventing programming.
|
||||
*
|
||||
* This example uses the device node of the manager. Alternatively, use
|
||||
* fpga_mgr_get(dev) instead if you have the device.
|
||||
*/
|
||||
mgr = of_fpga_mgr_get(mgr_node);
|
||||
|
||||
/* struct with information about the FPGA image to program. */
|
||||
info = fpga_image_info_alloc(dev);
|
||||
|
||||
/* flags indicates whether to do full or partial reconfiguration */
|
||||
info->flags = FPGA_MGR_PARTIAL_RECONFIG;
|
||||
|
||||
/*
|
||||
* At this point, indicate where the image is. This is pseudo-code; you're
|
||||
* going to use one of these three.
|
||||
*/
|
||||
if (image is in a scatter gather table) {
|
||||
|
||||
info->sgt = [your scatter gather table]
|
||||
|
||||
} else if (image is in a buffer) {
|
||||
|
||||
info->buf = [your image buffer]
|
||||
info->count = [image buffer size]
|
||||
|
||||
} else if (image is in a firmware file) {
|
||||
|
||||
info->firmware_name = devm_kstrdup(dev, firmware_name, GFP_KERNEL);
|
||||
|
||||
}
|
||||
|
||||
/* Get exclusive control of FPGA manager */
|
||||
ret = fpga_mgr_lock(mgr);
|
||||
|
||||
/* Load the buffer to the FPGA */
|
||||
ret = fpga_mgr_buf_load(mgr, &info, buf, count);
|
||||
|
||||
/* Release the FPGA manager */
|
||||
fpga_mgr_unlock(mgr);
|
||||
fpga_mgr_put(mgr);
|
||||
|
||||
/* Deallocate the image info if you're done with it */
|
||||
fpga_image_info_free(info);
|
||||
|
||||
How to support a new FPGA device
|
||||
================================
|
||||
To add another FPGA manager, write a driver that implements a set of ops. The
|
||||
probe function calls fpga_mgr_register(), such as:
|
||||
|
||||
static const struct fpga_manager_ops socfpga_fpga_ops = {
|
||||
.write_init = socfpga_fpga_ops_configure_init,
|
||||
.write = socfpga_fpga_ops_configure_write,
|
||||
.write_complete = socfpga_fpga_ops_configure_complete,
|
||||
.state = socfpga_fpga_ops_state,
|
||||
};
|
||||
|
||||
static int socfpga_fpga_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct socfpga_fpga_priv *priv;
|
||||
int ret;
|
||||
|
||||
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
/* ... do ioremaps, get interrupts, etc. and save
|
||||
them in priv... */
|
||||
|
||||
return fpga_mgr_register(dev, "Altera SOCFPGA FPGA Manager",
|
||||
&socfpga_fpga_ops, priv);
|
||||
}
|
||||
|
||||
static int socfpga_fpga_remove(struct platform_device *pdev)
|
||||
{
|
||||
fpga_mgr_unregister(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
The ops will implement whatever device specific register writes are needed to
|
||||
do the programming sequence for this particular FPGA. These ops return 0 for
|
||||
success or negative error codes otherwise.
|
||||
|
||||
The programming sequence is:
|
||||
1. .write_init
|
||||
2. .write or .write_sg (may be called once or multiple times)
|
||||
3. .write_complete
|
||||
|
||||
The .write_init function will prepare the FPGA to receive the image data. The
|
||||
buffer passed into .write_init will be atmost .initial_header_size bytes long,
|
||||
if the whole bitstream is not immediately available then the core code will
|
||||
buffer up at least this much before starting.
|
||||
|
||||
The .write function writes a buffer to the FPGA. The buffer may be contain the
|
||||
whole FPGA image or may be a smaller chunk of an FPGA image. In the latter
|
||||
case, this function is called multiple times for successive chunks. This interface
|
||||
is suitable for drivers which use PIO.
|
||||
|
||||
The .write_sg version behaves the same as .write except the input is a sg_table
|
||||
scatter list. This interface is suitable for drivers which use DMA.
|
||||
|
||||
The .write_complete function is called after all the image has been written
|
||||
to put the FPGA into operating mode.
|
||||
|
||||
The ops include a .state function which will read the hardware FPGA manager and
|
||||
return a code of type enum fpga_mgr_states. It doesn't result in a change in
|
||||
hardware state.
|
||||
@@ -1,95 +0,0 @@
|
||||
FPGA Regions
|
||||
|
||||
Alan Tull 2017
|
||||
|
||||
CONTENTS
|
||||
- Introduction
|
||||
- The FPGA region API
|
||||
- Usage example
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
This document is meant to be an brief overview of the FPGA region API usage. A
|
||||
more conceptual look at regions can be found in [1].
|
||||
|
||||
For the purposes of this API document, let's just say that a region associates
|
||||
an FPGA Manager and a bridge (or bridges) with a reprogrammable region of an
|
||||
FPGA or the whole FPGA. The API provides a way to register a region and to
|
||||
program a region.
|
||||
|
||||
Currently the only layer above fpga-region.c in the kernel is the Device Tree
|
||||
support (of-fpga-region.c) described in [1]. The DT support layer uses regions
|
||||
to program the FPGA and then DT to handle enumeration. The common region code
|
||||
is intended to be used by other schemes that have other ways of accomplishing
|
||||
enumeration after programming.
|
||||
|
||||
An fpga-region can be set up to know the following things:
|
||||
* which FPGA manager to use to do the programming
|
||||
* which bridges to disable before programming and enable afterwards.
|
||||
|
||||
Additional info needed to program the FPGA image is passed in the struct
|
||||
fpga_image_info [2] including:
|
||||
* pointers to the image as either a scatter-gather buffer, a contiguous
|
||||
buffer, or the name of firmware file
|
||||
* flags indicating specifics such as whether the image if for partial
|
||||
reconfiguration.
|
||||
|
||||
===================
|
||||
The FPGA region API
|
||||
===================
|
||||
|
||||
To register or unregister a region:
|
||||
-----------------------------------
|
||||
|
||||
int fpga_region_register(struct device *dev,
|
||||
struct fpga_region *region);
|
||||
int fpga_region_unregister(struct fpga_region *region);
|
||||
|
||||
An example of usage can be seen in the probe function of [3]
|
||||
|
||||
To program an FPGA:
|
||||
-------------------
|
||||
int fpga_region_program_fpga(struct fpga_region *region);
|
||||
|
||||
This function operates on info passed in the fpga_image_info
|
||||
(region->info).
|
||||
|
||||
This function will attempt to:
|
||||
* lock the region's mutex
|
||||
* lock the region's FPGA manager
|
||||
* build a list of FPGA bridges if a method has been specified to do so
|
||||
* disable the bridges
|
||||
* program the FPGA
|
||||
* re-enable the bridges
|
||||
* release the locks
|
||||
|
||||
=============
|
||||
Usage example
|
||||
=============
|
||||
|
||||
First, allocate the info struct:
|
||||
|
||||
info = fpga_image_info_alloc(dev);
|
||||
if (!info)
|
||||
return -ENOMEM;
|
||||
|
||||
Set flags as needed, i.e.
|
||||
|
||||
info->flags |= FPGA_MGR_PARTIAL_RECONFIG;
|
||||
|
||||
Point to your FPGA image, such as:
|
||||
|
||||
info->sgt = &sgt;
|
||||
|
||||
Add info to region and do the programming:
|
||||
|
||||
region->info = info;
|
||||
ret = fpga_region_program_fpga(region);
|
||||
|
||||
Then enumerate whatever hardware has appeared in the FPGA.
|
||||
|
||||
--
|
||||
[1] ../devicetree/bindings/fpga/fpga-region.txt
|
||||
[2] ./fpga-mgr.txt
|
||||
[3] ../../drivers/fpga/of-fpga-region.c
|
||||
@@ -1,23 +0,0 @@
|
||||
Linux kernel FPGA support
|
||||
|
||||
Alan Tull 2017
|
||||
|
||||
The main point of this project has been to separate the out the upper layers
|
||||
that know when to reprogram a FPGA from the lower layers that know how to
|
||||
reprogram a specific FPGA device. The intention is to make this manufacturer
|
||||
agnostic, understanding that of course the FPGA images are very device specific
|
||||
themselves.
|
||||
|
||||
The framework in the kernel includes:
|
||||
* low level FPGA manager drivers that know how to program a specific device
|
||||
* the fpga-mgr framework they are registered with
|
||||
* low level FPGA bridge drivers for hard/soft bridges which are intended to
|
||||
be disable during FPGA programming
|
||||
* the fpga-bridge framework they are registered with
|
||||
* the fpga-region framework which associates and controls managers and bridges
|
||||
as reconfigurable regions
|
||||
* the of-fpga-region support for reprogramming FPGAs when device tree overlays
|
||||
are applied.
|
||||
|
||||
I would encourage you the user to add code that creates FPGA regions rather
|
||||
that trying to control managers and bridges separately.
|
||||
@@ -328,6 +328,7 @@ Code Seq#(hex) Include File Comments
|
||||
0xCA 80-BF uapi/scsi/cxlflash_ioctl.h
|
||||
0xCB 00-1F CBM serial IEC bus in development:
|
||||
<mailto:michael.klein@puffin.lb.shuttle.de>
|
||||
0xCC 00-0F drivers/misc/ibmvmc.h pseries VMC driver
|
||||
0xCD 01 linux/reiserfs_fs.h
|
||||
0xCF 02 fs/cifs/ioctl.c
|
||||
0xDB 00-0F drivers/char/mwave/mwavepub.h
|
||||
|
||||
@@ -0,0 +1,226 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0+
|
||||
======================================================
|
||||
IBM Virtual Management Channel Kernel Driver (IBMVMC)
|
||||
======================================================
|
||||
|
||||
:Authors:
|
||||
Dave Engebretsen <engebret@us.ibm.com>,
|
||||
Adam Reznechek <adreznec@linux.vnet.ibm.com>,
|
||||
Steven Royer <seroyer@linux.vnet.ibm.com>,
|
||||
Bryant G. Ly <bryantly@linux.vnet.ibm.com>,
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
Note: Knowledge of virtualization technology is required to understand
|
||||
this document.
|
||||
|
||||
A good reference document would be:
|
||||
|
||||
https://openpowerfoundation.org/wp-content/uploads/2016/05/LoPAPR_DRAFT_v11_24March2016_cmt1.pdf
|
||||
|
||||
The Virtual Management Channel (VMC) is a logical device which provides an
|
||||
interface between the hypervisor and a management partition. This interface
|
||||
is like a message passing interface. This management partition is intended
|
||||
to provide an alternative to systems that use a Hardware Management
|
||||
Console (HMC) - based system management.
|
||||
|
||||
The primary hardware management solution that is developed by IBM relies
|
||||
on an appliance server named the Hardware Management Console (HMC),
|
||||
packaged as an external tower or rack-mounted personal computer. In a
|
||||
Power Systems environment, a single HMC can manage multiple POWER
|
||||
processor-based systems.
|
||||
|
||||
Management Application
|
||||
----------------------
|
||||
|
||||
In the management partition, a management application exists which enables
|
||||
a system administrator to configure the system’s partitioning
|
||||
characteristics via a command line interface (CLI) or Representational
|
||||
State Transfer Application (REST API's).
|
||||
|
||||
The management application runs on a Linux logical partition on a
|
||||
POWER8 or newer processor-based server that is virtualized by PowerVM.
|
||||
System configuration, maintenance, and control functions which
|
||||
traditionally require an HMC can be implemented in the management
|
||||
application using a combination of HMC to hypervisor interfaces and
|
||||
existing operating system methods. This tool provides a subset of the
|
||||
functions implemented by the HMC and enables basic partition configuration.
|
||||
The set of HMC to hypervisor messages supported by the management
|
||||
application component are passed to the hypervisor over a VMC interface,
|
||||
which is defined below.
|
||||
|
||||
The VMC enables the management partition to provide basic partitioning
|
||||
functions:
|
||||
|
||||
- Logical Partitioning Configuration
|
||||
- Start, and stop actions for individual partitions
|
||||
- Display of partition status
|
||||
- Management of virtual Ethernet
|
||||
- Management of virtual Storage
|
||||
- Basic system management
|
||||
|
||||
Virtual Management Channel (VMC)
|
||||
--------------------------------
|
||||
|
||||
A logical device, called the Virtual Management Channel (VMC), is defined
|
||||
for communicating between the management application and the hypervisor. It
|
||||
basically creates the pipes that enable virtualization management
|
||||
software. This device is presented to a designated management partition as
|
||||
a virtual device.
|
||||
|
||||
This communication device uses Command/Response Queue (CRQ) and the
|
||||
Remote Direct Memory Access (RDMA) interfaces. A three-way handshake is
|
||||
defined that must take place to establish that both the hypervisor and
|
||||
management partition sides of the channel are running prior to
|
||||
sending/receiving any of the protocol messages.
|
||||
|
||||
This driver also utilizes Transport Event CRQs. CRQ messages are sent
|
||||
when the hypervisor detects one of the peer partitions has abnormally
|
||||
terminated, or one side has called H_FREE_CRQ to close their CRQ.
|
||||
Two new classes of CRQ messages are introduced for the VMC device. VMC
|
||||
Administrative messages are used for each partition using the VMC to
|
||||
communicate capabilities to their partner. HMC Interface messages are used
|
||||
for the actual flow of HMC messages between the management partition and
|
||||
the hypervisor. As most HMC messages far exceed the size of a CRQ buffer,
|
||||
a virtual DMA (RMDA) of the HMC message data is done prior to each HMC
|
||||
Interface CRQ message. Only the management partition drives RDMA
|
||||
operations; hypervisors never directly cause the movement of message data.
|
||||
|
||||
|
||||
Terminology
|
||||
-----------
|
||||
RDMA
|
||||
Remote Direct Memory Access is DMA transfer from the server to its
|
||||
client or from the server to its partner partition. DMA refers
|
||||
to both physical I/O to and from memory operations and to memory
|
||||
to memory move operations.
|
||||
CRQ
|
||||
Command/Response Queue a facility which is used to communicate
|
||||
between partner partitions. Transport events which are signaled
|
||||
from the hypervisor to partition are also reported in this queue.
|
||||
|
||||
Example Management Partition VMC Driver Interface
|
||||
=================================================
|
||||
|
||||
This section provides an example for the management application
|
||||
implementation where a device driver is used to interface to the VMC
|
||||
device. This driver consists of a new device, for example /dev/ibmvmc,
|
||||
which provides interfaces to open, close, read, write, and perform
|
||||
ioctl’s against the VMC device.
|
||||
|
||||
VMC Interface Initialization
|
||||
----------------------------
|
||||
|
||||
The device driver is responsible for initializing the VMC when the driver
|
||||
is loaded. It first creates and initializes the CRQ. Next, an exchange of
|
||||
VMC capabilities is performed to indicate the code version and number of
|
||||
resources available in both the management partition and the hypervisor.
|
||||
Finally, the hypervisor requests that the management partition create an
|
||||
initial pool of VMC buffers, one buffer for each possible HMC connection,
|
||||
which will be used for management application session initialization.
|
||||
Prior to completion of this initialization sequence, the device returns
|
||||
EBUSY to open() calls. EIO is returned for all open() failures.
|
||||
|
||||
::
|
||||
|
||||
Management Partition Hypervisor
|
||||
CRQ INIT
|
||||
---------------------------------------->
|
||||
CRQ INIT COMPLETE
|
||||
<----------------------------------------
|
||||
CAPABILITIES
|
||||
---------------------------------------->
|
||||
CAPABILITIES RESPONSE
|
||||
<----------------------------------------
|
||||
ADD BUFFER (HMC IDX=0,1,..) _
|
||||
<---------------------------------------- |
|
||||
ADD BUFFER RESPONSE | - Perform # HMCs Iterations
|
||||
----------------------------------------> -
|
||||
|
||||
VMC Interface Open
|
||||
------------------
|
||||
|
||||
After the basic VMC channel has been initialized, an HMC session level
|
||||
connection can be established. The application layer performs an open() to
|
||||
the VMC device and executes an ioctl() against it, indicating the HMC ID
|
||||
(32 bytes of data) for this session. If the VMC device is in an invalid
|
||||
state, EIO will be returned for the ioctl(). The device driver creates a
|
||||
new HMC session value (ranging from 1 to 255) and HMC index value (starting
|
||||
at index 0 and ranging to 254) for this HMC ID. The driver then does an
|
||||
RDMA of the HMC ID to the hypervisor, and then sends an Interface Open
|
||||
message to the hypervisor to establish the session over the VMC. After the
|
||||
hypervisor receives this information, it sends Add Buffer messages to the
|
||||
management partition to seed an initial pool of buffers for the new HMC
|
||||
connection. Finally, the hypervisor sends an Interface Open Response
|
||||
message, to indicate that it is ready for normal runtime messaging. The
|
||||
following illustrates this VMC flow:
|
||||
|
||||
::
|
||||
|
||||
Management Partition Hypervisor
|
||||
RDMA HMC ID
|
||||
---------------------------------------->
|
||||
Interface Open
|
||||
---------------------------------------->
|
||||
Add Buffer _
|
||||
<---------------------------------------- |
|
||||
Add Buffer Response | - Perform N Iterations
|
||||
----------------------------------------> -
|
||||
Interface Open Response
|
||||
<----------------------------------------
|
||||
|
||||
VMC Interface Runtime
|
||||
---------------------
|
||||
|
||||
During normal runtime, the management application and the hypervisor
|
||||
exchange HMC messages via the Signal VMC message and RDMA operations. When
|
||||
sending data to the hypervisor, the management application performs a
|
||||
write() to the VMC device, and the driver RDMA’s the data to the hypervisor
|
||||
and then sends a Signal Message. If a write() is attempted before VMC
|
||||
device buffers have been made available by the hypervisor, or no buffers
|
||||
are currently available, EBUSY is returned in response to the write(). A
|
||||
write() will return EIO for all other errors, such as an invalid device
|
||||
state. When the hypervisor sends a message to the management, the data is
|
||||
put into a VMC buffer and an Signal Message is sent to the VMC driver in
|
||||
the management partition. The driver RDMA’s the buffer into the partition
|
||||
and passes the data up to the appropriate management application via a
|
||||
read() to the VMC device. The read() request blocks if there is no buffer
|
||||
available to read. The management application may use select() to wait for
|
||||
the VMC device to become ready with data to read.
|
||||
|
||||
::
|
||||
|
||||
Management Partition Hypervisor
|
||||
MSG RDMA
|
||||
---------------------------------------->
|
||||
SIGNAL MSG
|
||||
---------------------------------------->
|
||||
SIGNAL MSG
|
||||
<----------------------------------------
|
||||
MSG RDMA
|
||||
<----------------------------------------
|
||||
|
||||
VMC Interface Close
|
||||
-------------------
|
||||
|
||||
HMC session level connections are closed by the management partition when
|
||||
the application layer performs a close() against the device. This action
|
||||
results in an Interface Close message flowing to the hypervisor, which
|
||||
causes the session to be terminated. The device driver must free any
|
||||
storage allocated for buffers for this HMC connection.
|
||||
|
||||
::
|
||||
|
||||
Management Partition Hypervisor
|
||||
INTERFACE CLOSE
|
||||
---------------------------------------->
|
||||
INTERFACE CLOSE RESPONSE
|
||||
<----------------------------------------
|
||||
|
||||
Additional Information
|
||||
======================
|
||||
|
||||
For more information on the documentation for CRQ Messages, VMC Messages,
|
||||
HMC interface Buffers, and signal messages please refer to the Linux on
|
||||
Power Architecture Platform Reference. Section F.
|
||||
@@ -177,11 +177,11 @@ Here is an example of the debugging output format:
|
||||
ARM external debug module:
|
||||
coresight-cpu-debug 850000.debug: CPU[0]:
|
||||
coresight-cpu-debug 850000.debug: EDPRSR: 00000001 (Power:On DLK:Unlock)
|
||||
coresight-cpu-debug 850000.debug: EDPCSR: [<ffff00000808e9bc>] handle_IPI+0x174/0x1d8
|
||||
coresight-cpu-debug 850000.debug: EDPCSR: handle_IPI+0x174/0x1d8
|
||||
coresight-cpu-debug 850000.debug: EDCIDSR: 00000000
|
||||
coresight-cpu-debug 850000.debug: EDVIDSR: 90000000 (State:Non-secure Mode:EL1/0 Width:64bits VMID:0)
|
||||
coresight-cpu-debug 852000.debug: CPU[1]:
|
||||
coresight-cpu-debug 852000.debug: EDPRSR: 00000001 (Power:On DLK:Unlock)
|
||||
coresight-cpu-debug 852000.debug: EDPCSR: [<ffff0000087fab34>] debug_notifier_call+0x23c/0x358
|
||||
coresight-cpu-debug 852000.debug: EDPCSR: debug_notifier_call+0x23c/0x358
|
||||
coresight-cpu-debug 852000.debug: EDCIDSR: 00000000
|
||||
coresight-cpu-debug 852000.debug: EDVIDSR: 90000000 (State:Non-secure Mode:EL1/0 Width:64bits VMID:0)
|
||||
|
||||
+8
-1
@@ -5586,6 +5586,7 @@ S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/atull/linux-fpga.git
|
||||
Q: http://patchwork.kernel.org/project/linux-fpga/list/
|
||||
F: Documentation/fpga/
|
||||
F: Documentation/driver-api/fpga/
|
||||
F: Documentation/devicetree/bindings/fpga/
|
||||
F: drivers/fpga/
|
||||
F: include/linux/fpga/
|
||||
@@ -6773,6 +6774,12 @@ L: linux-scsi@vger.kernel.org
|
||||
S: Supported
|
||||
F: drivers/scsi/ibmvscsi/ibmvfc*
|
||||
|
||||
IBM Power Virtual Management Channel Driver
|
||||
M: Bryant G. Ly <bryantly@linux.vnet.ibm.com>
|
||||
M: Steven Royer <seroyer@linux.vnet.ibm.com>
|
||||
S: Supported
|
||||
F: drivers/misc/ibmvmc.*
|
||||
|
||||
IBM Power Virtual SCSI Device Drivers
|
||||
M: Tyrel Datwyler <tyreld@linux.vnet.ibm.com>
|
||||
L: linux-scsi@vger.kernel.org
|
||||
@@ -13136,7 +13143,7 @@ F: include/uapi/sound/
|
||||
F: sound/
|
||||
|
||||
SOUND - COMPRESSED AUDIO
|
||||
M: Vinod Koul <vinod.koul@intel.com>
|
||||
M: Vinod Koul <vkoul@kernel.org>
|
||||
L: alsa-devel@alsa-project.org (moderated for non-subscribers)
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git
|
||||
S: Supported
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user