code:
.. SPDX-License-Identifier: GPL-2.0

===
MHI
===

.. toctree::
   :maxdepth: 1

   mhi
   topology

.. only::  subproject and html

   Indices
   =======

   * :ref:`genindex`

repo_name: angery/linux


code:
.. SPDX-License-Identifier: GPL-2.0

==========================
MHI (Modem Host Interface)
==========================

This document provides information about the MHI protocol.

Overview
========

MHI is a protocol developed by Qualcomm Innovation Center, Inc. It is used
by the host processors to control and communicate with modem devices over high
speed peripheral buses or shared memory. Even though MHI can be easily adapted
to any peripheral buses, it is primarily used with PCIe based devices. MHI
provides logical channels over the physical buses and allows transporting the
modem protocols, such as IP data packets, modem control messages, and
diagnostics over at least one of those logical channels. Also, the MHI
protocol provides data acknowledgment feature and manages the power state of the
modems via one or more logical channels.

MHI Internals
=============

MMIO
----

MMIO (Memory mapped IO) consists of a set of registers in the device hardware,
which are mapped to the host memory space by the peripheral buses like PCIe.
Following are the major components of MMIO register space:

MHI control registers: Access to MHI configurations registers

MHI BHI registers: BHI (Boot Host Interface) registers are used by the host
for downloading the firmware to the device before MHI initialization.

Channel Doorbell array: Channel Doorbell (DB) registers used by the host to
notify the device when there is new work to do.

Event Doorbell array: Associated with event context array, the Event Doorbell
(DB) registers are used by the host to notify the device when new events are
available.

Debug registers: A set of registers and counters used by the device to expose
debugging information like performance, functional, and stability to the host.

Data structures
---------------

All data structures used by MHI are in the host system memory. Using the
physical interface, the device accesses those data structures. MHI data
structures and data buffers in the host system memory regions are mapped for
the device.

Channel context array: All channel configurations are organized in channel
context data array.

Transfer rings: Used by the host to schedule work items for a channel. The
transfer rings are organized as a circular queue of Transfer Descriptors (TD).

Event context array: All event configurations are organized in the event context
data array.

Event rings: Used by the device to send completion and state transition messages
to the host

Command context array: All command configurations are organized in command
context data array.

Command rings: Used by the host to send MHI commands to the device. The command
rings are organized as a circular queue of Command Descriptors (CD).

Channels
--------

MHI channels are logical, unidirectional data pipes between a host and a device.
The concept of channels in MHI is similar to endpoints in USB. MHI supports up
to 256 channels. However, specific device implementations may support less than
the maximum number of channels allowed.

Two unidirectional channels with their associated transfer rings form a
bidirectional data pipe, which can be used by the upper-layer protocols to
transport application data packets (such as IP packets, modem control messages,
diagnostics messages, and so on). Each channel is associated with a single
transfer ring.

Transfer rings
--------------

Transfers between the host and device are organized by channels and defined by
Transfer Descriptors (TD). TDs are managed through transfer rings, which are
defined for each channel between the device and host and reside in the host
memory. TDs consist of one or more ring elements (or transfer blocks)::

        [Read Pointer (RP)] ----------->[Ring Element] } TD
        [Write Pointer (WP)]-           [Ring Element]
                             -          [Ring Element]
                              --------->[Ring Element]
                                        [Ring Element]

Below is the basic usage of transfer rings:

* Host allocates memory for transfer ring.
* Host sets the base pointer, read pointer, and write pointer in corresponding
  channel context.
* Ring is considered empty when RP == WP.
* Ring is considered full when WP + 1 == RP.
* RP indicates the next element to be serviced by the device.
* When the host has a new buffer to send, it updates the ring element with
  buffer information, increments the WP to the next element and rings the
  associated channel DB.

Event rings
-----------

Events from the device to host are organized in event rings and defined by Event
Descriptors (ED). Event rings are used by the device to report events such as
data transfer completion status, command completion status, and state changes
to the host. Event rings are the array of EDs that resides in the host
memory. EDs consist of one or more ring elements (or transfer blocks)::

        [Read Pointer (RP)] ----------->[Ring Element] } ED
        [Write Pointer (WP)]-           [Ring Element]
                             -          [Ring Element]
                              --------->[Ring Element]
                                        [Ring Element]

Below is the basic usage of event rings:

* Host allocates memory for event ring.
* Host sets the base pointer, read pointer, and write pointer in corresponding
  channel context.
* Both host and device has a local copy of RP, WP.
* Ring is considered empty (no events to service) when WP + 1 == RP.
* Ring is considered full of events when RP == WP.
* When there is a new event the device needs to send, the device updates ED
  pointed by RP, increments the RP to the next element and triggers the
  interrupt.

Ring Element
------------

A Ring Element is a data structure used to transfer a single block
of data between the host and the device. Transfer ring element types contain a
single buffer pointer, the size of the buffer, and additional control
information. Other ring element types may only contain control and status
information. For single buffer operations, a ring descriptor is composed of a
single element. For large multi-buffer operations (such as scatter and gather),
elements can be chained to form a longer descriptor.

MHI Operations
==============

MHI States
----------

MHI_STATE_RESET
~~~~~~~~~~~~~~~
MHI is in reset state after power-up or hardware reset. The host is not allowed
to access device MMIO register space.

MHI_STATE_READY
~~~~~~~~~~~~~~~
MHI is ready for initialization. The host can start MHI initialization by
programming MMIO registers.

MHI_STATE_M0
~~~~~~~~~~~~
MHI is running and operational in the device. The host can start channels by
issuing channel start command.

MHI_STATE_M1
~~~~~~~~~~~~
MHI operation is suspended by the device. This state is entered when the
device detects inactivity at the physical interface within a preset time.

MHI_STATE_M2
~~~~~~~~~~~~
MHI is in low power state. MHI operation is suspended and the device may
enter lower power mode.

MHI_STATE_M3
~~~~~~~~~~~~
MHI operation stopped by the host. This state is entered when the host suspends
MHI operation.

MHI Initialization
------------------

After system boots, the device is enumerated over the physical interface.
In the case of PCIe, the device is enumerated and assigned BAR-0 for
the device's MMIO register space. To initialize the MHI in a device,
the host performs the following operations:

* Allocates the MHI context for event, channel and command arrays.
* Initializes the context array, and prepares interrupts.
* Waits until the device enters READY state.
* Programs MHI MMIO registers and sets device into MHI_M0 state.
* Waits for the device to enter M0 state.

MHI Data Transfer
-----------------

MHI data transfer is initiated by the host to transfer data to the device.
Following are the sequence of operations performed by the host to transfer
data to device:

* Host prepares TD with buffer information.
* Host increments the WP of the corresponding channel transfer ring.
* Host rings the channel DB register.
* Device wakes up to process the TD.
* Device generates a completion event for the processed TD by updating ED.
* Device increments the RP of the corresponding event ring.
* Device triggers IRQ to wake up the host.
* Host wakes up and checks the event ring for completion event.
* Host updates the WP of the corresponding event ring to indicate that the
  data transfer has been completed successfully.


code:
.. SPDX-License-Identifier: GPL-2.0

============
MHI Topology
============

This document provides information about the MHI topology modeling and
representation in the kernel.

MHI Controller
--------------

MHI controller driver manages the interaction with the MHI client devices
such as the external modems and WiFi chipsets. It is also the MHI bus master
which is in charge of managing the physical link between the host and device.
It is however not involved in the actual data transfer as the data transfer
is taken care by the physical bus such as PCIe. Each controller driver exposes
channels and events based on the client device type.

Below are the roles of the MHI controller driver:

* Turns on the physical bus and establishes the link to the device
* Configures IRQs, IOMMU, and IOMEM
* Allocates struct mhi_controller and registers with the MHI bus framework
  with channel and event configurations using mhi_register_controller.
* Initiates power on and shutdown sequence
* Initiates suspend and resume power management operations of the device.

MHI Device
----------

MHI device is the logical device which binds to a maximum of two MHI channels
for bi-directional communication. Once MHI is in powered on state, the MHI
core will create MHI devices based on the channel configuration exposed
by the controller. There can be a single MHI device for each channel or for a
couple of channels.

Each supported device is enumerated in::

        /sys/bus/mhi/devices/

MHI Driver
----------

MHI driver is the client driver which binds to one or more MHI devices. The MHI
driver sends and receives the upper-layer protocol packets like IP packets,
modem control messages, and diagnostics messages over MHI. The MHI core will
bind the MHI devices to the MHI driver.

Each supported driver is enumerated in::

        /sys/bus/mhi/drivers/

Below are the roles of the MHI driver:

* Registers the driver with the MHI bus framework using mhi_driver_register.
* Prepares the device for transfer by calling mhi_prepare_for_transfer.
* Initiates data transfer by calling mhi_queue_transfer.
* Once the data transfer is finished, calls mhi_unprepare_from_transfer to
  end data transfer.


code:
.. SPDX-License-Identifier: GPL-2.0

BMIPS DeviceTree Booting
------------------------

  Some bootloaders only support a single entry point, at the start of the
  kernel image.  Other bootloaders will jump to the ELF start address.
  Both schemes are supported; CONFIG_BOOT_RAW=y and CONFIG_NO_EXCEPT_FILL=y,
  so the first instruction immediately jumps to kernel_entry().

  Similar to the arch/arm case (b), a DT-aware bootloader is expected to
  set up the following registers:

         a0 : 0

         a1 : 0xffffffff

         a2 : Physical pointer to the device tree block (defined in chapter
         II) in RAM.  The device tree can be located anywhere in the first
         512MB of the physical address space (0x00000000 - 0x1fffffff),
         aligned on a 64 bit boundary.

  Legacy bootloaders do not use this convention, and they do not pass in a
  DT block.  In this case, Linux will look for a builtin DTB, selected via
  CONFIG_DT_*.

  This convention is defined for 32-bit systems only, as there are not
  currently any 64-bit BMIPS implementations.


code:
.. SPDX-License-Identifier: GPL-2.0

.. kernel-feat:: $srctree/Documentation/features mips


code:
.. SPDX-License-Identifier: GPL-2.0

===========================
MIPS-specific Documentation
===========================

.. toctree::
   :maxdepth: 2
   :numbered:

   booting
   ingenic-tcu

   features

.. only::  subproject and html

   Indices
   =======

   * :ref:`genindex`


code:
.. SPDX-License-Identifier: GPL-2.0

===============================================
Ingenic JZ47xx SoCs Timer/Counter Unit hardware
===============================================

The Timer/Counter Unit (TCU) in Ingenic JZ47xx SoCs is a multi-function
hardware block. It features up to eight channels, that can be used as
counters, timers, or PWM.

- JZ4725B, JZ4750, JZ4755 only have six TCU channels. The other SoCs all
  have eight channels.

- JZ4725B introduced a separate channel, called Operating System Timer
  (OST). It is a 32-bit programmable timer. On JZ4760B and above, it is
  64-bit.

- Each one of the TCU channels has its own clock, which can be reparented to three
  different clocks (pclk, ext, rtc), gated, and reclocked, through their TCSR register.

    - The watchdog and OST hardware blocks also feature a TCSR register with the same
      format in their register space.
    - The TCU registers used to gate/ungate can also gate/ungate the watchdog and
      OST clocks.

- Each TCU channel works in one of two modes:

    - mode TCU1: channels cannot work in sleep mode, but are easier to
      operate.
    - mode TCU2: channels can work in sleep mode, but the operation is a bit
      more complicated than with TCU1 channels.

- The mode of each TCU channel depends on the SoC used:

    - On the oldest SoCs (up to JZ4740), all of the eight channels operate in
      TCU1 mode.
    - On JZ4725B, channel 5 operates as TCU2, the others operate as TCU1.
    - On newest SoCs (JZ4750 and above), channels 1-2 operate as TCU2, the
      others operate as TCU1.

- Each channel can generate an interrupt. Some channels share an interrupt
  line, some don't, and this changes between SoC versions:

    - on older SoCs (JZ4740 and below), channel 0 and channel 1 have their
      own interrupt line; channels 2-7 share the last interrupt line.
    - On JZ4725B, channel 0 has its own interrupt; channels 1-5 share one
      interrupt line; the OST uses the last interrupt line.
    - on newer SoCs (JZ4750 and above), channel 5 has its own interrupt;
      channels 0-4 and (if eight channels) 6-7 all share one interrupt line;
      the OST uses the last interrupt line.

Implementation
==============

The functionalities of the TCU hardware are spread across multiple drivers:

===========  =====
clocks       drivers/clk/ingenic/tcu.c
interrupts   drivers/irqchip/irq-ingenic-tcu.c
timers       drivers/clocksource/ingenic-timer.c
OST          drivers/clocksource/ingenic-ost.c
PWM          drivers/pwm/pwm-jz4740.c
watchdog     drivers/watchdog/jz4740_wdt.c
===========  =====

Because various functionalities of the TCU that belong to different drivers
and frameworks can be controlled from the same registers, all of these
drivers access their registers through the same regmap.

For more information regarding the devicetree bindings of the TCU drivers,
have a look at Documentation/devicetree/bindings/timer/ingenic,tcu.yaml.


code:
.. SPDX-License-Identifier: GPL-2.0

=============================
AD525x Digital Potentiometers
=============================

The ad525x_dpot driver exports a simple sysfs interface.  This allows you to
work with the immediate resistance settings as well as update the saved startup
settings.  Access to the factory programmed tolerance is also provided, but
interpretation of this settings is required by the end application according to
the specific part in use.

Files
=====

Each dpot device will have a set of eeprom, rdac, and tolerance files.  How
many depends on the actual part you have, as will the range of allowed values.

The eeprom files are used to program the startup value of the device.

The rdac files are used to program the immediate value of the device.

The tolerance files are the read-only factory programmed tolerance settings
and may vary greatly on a part-by-part basis.  For exact interpretation of
this field, please consult the datasheet for your part.  This is presented
as a hex file for easier parsing.

Example
=======

Locate the device in your sysfs tree.  This is probably easiest by going into
the common i2c directory and locating the device by the i2c slave address::

	# ls /sys/bus/i2c/devices/
	0-0022  0-0027  0-002f

So assuming the device in question is on the first i2c bus and has the slave
address of 0x2f, we descend (unrelated sysfs entries have been trimmed)::

	# ls /sys/bus/i2c/devices/0-002f/
	eeprom0 rdac0 tolerance0

You can use simple reads/writes to access these files::

	# cd /sys/bus/i2c/devices/0-002f/

	# cat eeprom0
	0
	# echo 10 > eeprom0
	# cat eeprom0
	10

	# cat rdac0
	5
	# echo 3 > rdac0
	# cat rdac0
	3


code:
.. SPDX-License-Identifier: GPL-2.0

======================
Kernel driver apds990x
======================

Supported chips:
Avago APDS990X

Data sheet:
Not freely available

Author:
Samu Onkalo <samu.p.onkalo@nokia.com>

Description
-----------

APDS990x is a combined ambient light and proximity sensor. ALS and proximity
functionality are highly connected. ALS measurement path must be running
while the proximity functionality is enabled.

ALS produces raw measurement values for two channels: Clear channel
(infrared + visible light) and IR only. However, threshold comparisons happen
using clear channel only. Lux value and the threshold level on the HW
might vary quite much depending the spectrum of the light source.

Driver makes necessary conversions to both directions so that user handles
only lux values. Lux value is calculated using information from the both
channels. HW threshold level is calculated from the given lux value to match
with current type of the lightning. Sometimes inaccuracy of the estimations
lead to false interrupt, but that doesn't harm.

ALS contains 4 different gain steps. Driver automatically
selects suitable gain step. After each measurement, reliability of the results
is estimated and new measurement is triggered if necessary.

Platform data can provide tuned values to the conversion formulas if
values are known. Otherwise plain sensor default values are used.

Proximity side is little bit simpler. There is no need for complex conversions.
It produces directly usable values.

Driver controls chip operational state using pm_runtime framework.
Voltage regulators are controlled based on chip operational state.

SYSFS
-----

chip_id
	RO - shows detected chip type and version

power_state
	RW - enable / disable chip. Uses counting logic

	     1 enables the chip
	     0 disables the chip
lux0_input
	RO - measured lux value

	     sysfs_notify called when threshold interrupt occurs

lux0_sensor_range
	RO - lux0_input max value.

	     Actually never reaches since sensor tends
	     to saturate much before that. Real max value varies depending
	     on the light spectrum etc.

lux0_rate
	RW - measurement rate in Hz

lux0_rate_avail
	RO - supported measurement rates

lux0_calibscale
	RW - calibration value.

	     Set to neutral value by default.
	     Output results are multiplied with calibscale / calibscale_default
	     value.

lux0_calibscale_default
	RO - neutral calibration value

lux0_thresh_above_value
	RW - HI level threshold value.

	     All results above the value
	     trigs an interrupt. 65535 (i.e. sensor_range) disables the above
	     interrupt.

lux0_thresh_below_value
	RW - LO level threshold value.

	     All results below the value
	     trigs an interrupt. 0 disables the below interrupt.

prox0_raw
	RO - measured proximity value

	     sysfs_notify called when threshold interrupt occurs

prox0_sensor_range
	RO - prox0_raw max value (1023)

prox0_raw_en
	RW - enable / disable proximity - uses counting logic

	     - 1 enables the proximity
	     - 0 disables the proximity

prox0_reporting_mode
	RW - trigger / periodic.

	     In "trigger" mode the driver tells two possible
	     values: 0 or prox0_sensor_range value. 0 means no proximity,
	     1023 means proximity. This causes minimal number of interrupts.
	     In "periodic" mode the driver reports all values above
	     prox0_thresh_above. This causes more interrupts, but it can give
	     _rough_ estimate about the distance.

prox0_reporting_mode_avail
	RO - accepted values to prox0_reporting_mode (trigger, periodic)

prox0_thresh_above_value
	RW - threshold level which trigs proximity events.


code:
.. SPDX-License-Identifier: GPL-2.0

=======================
Kernel driver bh1770glc
=======================

Supported chips:

- ROHM BH1770GLC
- OSRAM SFH7770

Data sheet:
Not freely available

Author:
Samu Onkalo <samu.p.onkalo@nokia.com>

Description
-----------
BH1770GLC and SFH7770 are combined ambient light and proximity sensors.
ALS and proximity parts operates on their own, but they shares common I2C
interface and interrupt logic. In principle they can run on their own,
but ALS side results are used to estimate reliability of the proximity sensor.

ALS produces 16 bit lux values. The chip contains interrupt logic to produce
low and high threshold interrupts.

Proximity part contains IR-led driver up to 3 IR leds. The chip measures
amount of reflected IR light and produces proximity result. Resolution is
8 bit. Driver supports only one channel. Driver uses ALS results to estimate
reliability of the proximity results. Thus ALS is always running while
proximity detection is needed.

Driver uses threshold interrupts to avoid need for polling the values.
Proximity low interrupt doesn't exists in the chip. This is simulated
by using a delayed work. As long as there is proximity threshold above
interrupts the delayed work is pushed forward. So, when proximity level goes
below the threshold value, there is no interrupt and the delayed work will
finally run. This is handled as no proximity indication.

Chip state is controlled via runtime pm framework when enabled in config.

Calibscale factor is used to hide differences between the chips. By default
value set to neutral state meaning factor of 1.00. To get proper values,
calibrated source of light is needed as a reference. Calibscale factor is set
so that measurement produces about the expected lux value.

SYSFS
-----

chip_id
	RO - shows detected chip type and version

power_state
	RW - enable / disable chip

	Uses counting logic

	     - 1 enables the chip
	     - 0 disables the chip

lux0_input
	RO - measured lux value

	     sysfs_notify called when threshold interrupt occurs

lux0_sensor_range
	RO - lux0_input max value

lux0_rate
	RW - measurement rate in Hz

lux0_rate_avail
	RO - supported measurement rates

lux0_thresh_above_value
	RW - HI level threshold value

	     All results above the value
	     trigs an interrupt. 65535 (i.e. sensor_range) disables the above
	     interrupt.

lux0_thresh_below_value
	RW - LO level threshold value

	     All results below the value
	     trigs an interrupt. 0 disables the below interrupt.

lux0_calibscale
	RW - calibration value

	     Set to neutral value by default.
	     Output results are multiplied with calibscale / calibscale_default
	     value.

lux0_calibscale_default
	RO - neutral calibration value

prox0_raw
	RO - measured proximity value

	     sysfs_notify called when threshold interrupt occurs

prox0_sensor_range
	RO - prox0_raw max value

prox0_raw_en
	RW - enable / disable proximity

	     Uses counting logic

	     - 1 enables the proximity
	     - 0 disables the proximity

prox0_thresh_above_count
	RW - number of proximity interrupts needed before triggering the event

prox0_rate_above
	RW - Measurement rate (in Hz) when the level is above threshold
	i.e. when proximity on has been reported.

prox0_rate_below
	RW - Measurement rate (in Hz) when the level is below threshold
	i.e. when proximity off has been reported.

prox0_rate_avail
	RO - Supported proximity measurement rates in Hz

prox0_thresh_above0_value
	RW - threshold level which trigs proximity events.

	     Filtered by persistence filter (prox0_thresh_above_count)

prox0_thresh_above1_value
	RW - threshold level which trigs event immediately


code:
.. SPDX-License-Identifier: GPL-2.0
.. include:: <isonum.txt>

===============
C2 port support
===============

(C) Copyright 2007 Rodolfo Giometti <giometti@enneenne.com>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

Overview
--------

This driver implements the support for Linux of Silicon Labs (Silabs)
C2 Interface used for in-system programming of micro controllers.

By using this driver you can reprogram the in-system flash without EC2
or EC3 debug adapter. This solution is also useful in those systems
where the micro controller is connected via special GPIOs pins.

References
----------

The C2 Interface main references are at (https://www.silabs.com)
Silicon Laboratories site], see:

- AN127: FLASH Programming via the C2 Interface at
  https://www.silabs.com/Support Documents/TechnicalDocs/an127.pdf

- C2 Specification at
  https://www.silabs.com/pages/DownloadDoc.aspx?FILEURL=Support%20Documents/TechnicalDocs/an127.pdf&src=SearchResults

however it implements a two wire serial communication protocol (bit
banging) designed to enable in-system programming, debugging, and
boundary-scan testing on low pin-count Silicon Labs devices. Currently
this code supports only flash programming but extensions are easy to
add.

Using the driver
----------------

Once the driver is loaded you can use sysfs support to get C2port's
info or read/write in-system flash::

  # ls /sys/class/c2port/c2port0/
  access            flash_block_size  flash_erase       rev_id
  dev_id            flash_blocks_num  flash_size        subsystem/
  flash_access      flash_data        reset             uevent

Initially the C2port access is disabled since you hardware may have
such lines multiplexed with other devices so, to get access to the
C2port, you need the command::

  # echo 1 > /sys/class/c2port/c2port0/access

after that you should read the device ID and revision ID of the
connected micro controller::

  # cat /sys/class/c2port/c2port0/dev_id
  8
  # cat /sys/class/c2port/c2port0/rev_id
  1

However, for security reasons, the in-system flash access in not
enabled yet, to do so you need the command::

  # echo 1 > /sys/class/c2port/c2port0/flash_access

After that you can read the whole flash::

  # cat /sys/class/c2port/c2port0/flash_data > image

erase it::

  # echo 1 > /sys/class/c2port/c2port0/flash_erase

and write it::

  # cat image > /sys/class/c2port/c2port0/flash_data

after writing you have to reset the device to execute the new code::

  # echo 1 > /sys/class/c2port/c2port0/reset


code:
.. SPDX-License-Identifier: GPL-2.0

===========================================================================
Driver for Synopsys DesignWare PCIe traffic generator (also known as xData)
===========================================================================

Supported chips:
Synopsys DesignWare PCIe prototype solution

Datasheet:
Not freely available

Author:
Gustavo Pimentel <gustavo.pimentel@synopsys.com>

Description
-----------

This driver should be used as a host-side (Root Complex) driver and Synopsys
DesignWare prototype that includes this IP.

The dw-xdata-pcie driver can be used to enable/disable PCIe traffic
generator in either direction (mutual exclusion) besides allowing the
PCIe link performance analysis.

The interaction with this driver is done through the module parameter and
can be changed in runtime. The driver outputs the requested command state
information to ``/var/log/kern.log`` or dmesg.

Example
-------

Write TLPs traffic generation - Root Complex to Endpoint direction
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Generate traffic::

 # echo 1 > /sys/class/misc/dw-xdata-pcie.0/write

Get link throughput in MB/s::

 # cat /sys/class/misc/dw-xdata-pcie.0/write
 204

Stop traffic in any direction::

 # echo 0 > /sys/class/misc/dw-xdata-pcie.0/write

Read TLPs traffic generation - Endpoint to Root Complex direction
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Generate traffic::

 # echo 1 > /sys/class/misc/dw-xdata-pcie.0/read

Get link throughput in MB/s::

 # cat /sys/class/misc/dw-xdata-pcie.0/read
 199

Stop traffic in any direction::

 # echo 0 > /sys/class/misc/dw-xdata-pcie.0/read


code:
====================
Kernel driver eeprom
====================

Supported chips:

  * Any EEPROM chip in the designated address range

    Prefix: 'eeprom'

    Addresses scanned: I2C 0x50 - 0x57

    Datasheets: Publicly available from:

                Atmel (www.atmel.com),
                Catalyst (www.catsemi.com),
                Fairchild (www.fairchildsemi.com),
                Microchip (www.microchip.com),
                Philips (www.semiconductor.philips.com),
                Rohm (www.rohm.com),
                ST (www.st.com),
                Xicor (www.xicor.com),
                and others.

        ========= ============= ============================================
        Chip      Size (bits)   Address
        ========= ============= ============================================
        24C01     1K            0x50 (shadows at 0x51 - 0x57)
        24C01A    1K            0x50 - 0x57 (Typical device on DIMMs)
        24C02     2K            0x50 - 0x57
        24C04     4K            0x50, 0x52, 0x54, 0x56
                                (additional data at 0x51, 0x53, 0x55, 0x57)
        24C08     8K            0x50, 0x54 (additional data at 0x51, 0x52,
                                0x53, 0x55, 0x56, 0x57)
        24C16     16K           0x50 (additional data at 0x51 - 0x57)
        Sony      2K            0x57

        Atmel     34C02B  2K    0x50 - 0x57, SW write protect at 0x30-37
        Catalyst  34FC02  2K    0x50 - 0x57, SW write protect at 0x30-37
        Catalyst  34RC02  2K    0x50 - 0x57, SW write protect at 0x30-37
        Fairchild 34W02   2K    0x50 - 0x57, SW write protect at 0x30-37
        Microchip 24AA52  2K    0x50 - 0x57, SW write protect at 0x30-37
        ST        M34C02  2K    0x50 - 0x57, SW write protect at 0x30-37
        ========= ============= ============================================

Authors:
        - Frodo Looijaard <frodol@dds.nl>,
        - Philip Edelbrock <phil@netroedge.com>,
        - Jean Delvare <jdelvare@suse.de>,
        - Greg Kroah-Hartman <greg@kroah.com>,
        - IBM Corp.

Description
-----------

This is a simple EEPROM module meant to enable reading the first 256 bytes
of an EEPROM (on a SDRAM DIMM for example). However, it will access serial
EEPROMs on any I2C adapter. The supported devices are generically called
24Cxx, and are listed above; however the numbering for these
industry-standard devices may vary by manufacturer.

This module was a programming exercise to get used to the new project
organization laid out by Frodo, but it should be at least completely
effective for decoding the contents of EEPROMs on DIMMs.

DIMMS will typically contain a 24C01A or 24C02, or the 34C02 variants.
The other devices will not be found on a DIMM because they respond to more
than one address.

DDC Monitors may contain any device. Often a 24C01, which responds to all 8
addresses, is found.

Recent Sony Vaio laptops have an EEPROM at 0x57. We couldn't get the
specification, so it is guess work and far from being complete.

The Microchip 24AA52/24LCS52, ST M34C02, and others support an additional
software write protect register at 0x30 - 0x37 (0x20 less than the memory
location). The chip responds to "write quick" detection at this address but
does not respond to byte reads. If this register is present, the lower 128
bytes of the memory array are not write protected. Any byte data write to
this address will write protect the memory array permanently, and the
device will no longer respond at the 0x30-37 address. The eeprom driver
does not support this register.

Lacking functionality
---------------------

* Full support for larger devices (24C04, 24C08, 24C16). These are not
  typically found on a PC. These devices will appear as separate devices at
  multiple addresses.

* Support for really large devices (24C32, 24C64, 24C128, 24C256, 24C512).
  These devices require two-byte address fields and are not supported.

* Enable Writing. Again, no technical reason why not, but making it easy
  to change the contents of the EEPROMs (on DIMMs anyway) also makes it easy
  to disable the DIMMs (potentially preventing the computer from booting)
  until the values are restored somehow.

Use
---

After inserting the module (and any other required SMBus/i2c modules), you
should have some EEPROM directories in ``/sys/bus/i2c/devices/*`` of names such
as "0-0050". Inside each of these is a series of files, the eeprom file
contains the binary data from EEPROM.


code:
.. 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.


code:
========================
Kernel driver ics932s401
========================

Supported chips:

  * IDT ICS932S401

    Prefix: 'ics932s401'

    Addresses scanned: I2C 0x69

    Datasheet: Publicly available at the IDT website

Author: Darrick J. Wong

Description
-----------

This driver implements support for the IDT ICS932S401 chip family.

This chip has 4 clock outputs--a base clock for the CPU (which is likely
multiplied to get the real CPU clock), a system clock, a PCI clock, a USB
clock, and a reference clock.  The driver reports selected and actual
frequency.  If spread spectrum mode is enabled, the driver also reports by what
percent the clock signal is being spread, which should be between 0 and -0.5%.
All frequencies are reported in KHz.

The ICS932S401 monitors all inputs continuously. The driver will not read
the registers more often than once every other second.

Special Features
----------------

The clocks could be reprogrammed to increase system speed.  I will not help you
do this, as you risk damaging your system!


code:
.. SPDX-License-Identifier: GPL-2.0

============================================
Assorted Miscellaneous Devices Documentation
============================================

This documentation contains information for assorted devices that do not
fit into other categories.

.. class:: toc-title

	   Table of contents

.. toctree::
   :maxdepth: 2

   ad525x_dpot
   apds990x
   bh1770glc
   eeprom
   c2port
   dw-xdata-pcie
   ibmvmc
   ics932s401
   isl29003
   lis3lv02d
   max6875
   oxsemi-tornado
   pci-endpoint-test
   spear-pcie-gadget
   uacce
   xilinx_sdfec


code:
======================
Kernel driver isl29003
======================

Supported chips:

* Intersil ISL29003

Prefix: 'isl29003'

Addresses scanned: none

Datasheet:
http://www.intersil.com/data/fn/fn7464.pdf

Author: Daniel Mack <daniel@caiaq.de>

Description
-----------
The ISL29003 is an integrated light sensor with a 16-bit integrating type
ADC, I2C user programmable lux range select for optimized counts/lux, and
I2C multi-function control and monitoring capabilities. The internal ADC
provides 16-bit resolution while rejecting 50Hz and 60Hz flicker caused by
artificial light sources.

The driver allows to set the lux range, the bit resolution, the operational
mode (see below) and the power state of device and can read the current lux
value, of course.

Detection
---------

The ISL29003 does not have an ID register which could be used to identify
it, so the detection routine will just try to read from the configured I2C
address and consider the device to be present as soon as it ACKs the
transfer.

Sysfs entries
-------------

range:
        == ===========================
	0: 0 lux to 1000 lux (default)
	1: 0 lux to 4000 lux
	2: 0 lux to 16,000 lux
	3: 0 lux to 64,000 lux
        == ===========================

resolution:
        == =====================
	0: 2^16 cycles (default)
	1: 2^12 cycles
	2: 2^8 cycles
	3: 2^4 cycles
        == =====================

mode:
        == =================================================
	0: diode1's current (unsigned 16bit) (default)
	1: diode1's current (unsigned 16bit)
	2: difference between diodes (l1 - l2, signed 15bit)
        == =================================================

power_state:
        == =================================================
	0: device is disabled (default)
	1: device is enabled
        == =================================================

lux (read only):
	returns the value from the last sensor reading


code:
=======================
Kernel driver lis3lv02d
=======================

Supported chips:

  * STMicroelectronics LIS3LV02DL, LIS3LV02DQ (12 bits precision)
  * STMicroelectronics LIS302DL, LIS3L02DQ, LIS331DL (8 bits) and
    LIS331DLH (16 bits)

Authors:
        - Yan Burman <burman.yan@gmail.com>
	- Eric Piel <eric.piel@tremplin-utc.net>

Description
-----------

This driver provides support for the accelerometer found in various HP laptops
sporting the feature officially called "HP Mobile Data Protection System 3D" or
"HP 3D DriveGuard". It detects automatically laptops with this sensor. Known
models (full list can be found in drivers/platform/x86/hp_accel.c) will have
their axis automatically oriented on standard way (eg: you can directly play
neverball). The accelerometer data is readable via
/sys/devices/platform/lis3lv02d. Reported values are scaled
to mg values (1/1000th of earth gravity).

Sysfs attributes under /sys/devices/platform/lis3lv02d/:

position
      - 3D position that the accelerometer reports. Format: "(x,y,z)"
rate
      - read reports the sampling rate of the accelerometer device in HZ.
	write changes sampling rate of the accelerometer device.
	Only values which are supported by HW are accepted.
selftest
      - performs selftest for the chip as specified by chip manufacturer.

This driver also provides an absolute input class device, allowing
the laptop to act as a pinball machine-esque joystick. Joystick device can be
calibrated. Joystick device can be in two different modes.
By default output values are scaled between -32768 .. 32767. In joystick raw
mode, joystick and sysfs position entry have the same scale. There can be
small difference due to input system fuzziness feature.
Events are also available as input event device.

Selftest is meant only for hardware diagnostic purposes. It is not meant to be
used during normal operations. Position data is not corrupted during selftest
but interrupt behaviour is not guaranteed to work reliably. In test mode, the
sensing element is internally moved little bit. Selftest measures difference
between normal mode and test mode. Chip specifications tell the acceptance
limit for each type of the chip. Limits are provided via platform data
to allow adjustment of the limits without a change to the actual driver.
Seltest returns either "OK x y z" or "FAIL x y z" where x, y and z are
measured difference between modes. Axes are not remapped in selftest mode.
Measurement values are provided to help HW diagnostic applications to make
final decision.

On HP laptops, if the led infrastructure is activated, support for a led
indicating disk protection will be provided as /sys/class/leds/hp::hddprotect.

Another feature of the driver is misc device called "freefall" that
acts similar to /dev/rtc and reacts on free-fall interrupts received
from the device. It supports blocking operations, poll/select and
fasync operation modes. You must read 1 bytes from the device.  The
result is number of free-fall interrupts since the last successful
read (or 255 if number of interrupts would not fit). See the freefall.c
file for an example on using the device.

Axes orientation
----------------

For better compatibility between the various laptops. The values reported by
the accelerometer are converted into a "standard" organisation of the axes
(aka "can play neverball out of the box"):

 * When the laptop is horizontal the position reported is about 0 for X and Y
   and a positive value for Z
 * If the left side is elevated, X increases (becomes positive)
 * If the front side (where the touchpad is) is elevated, Y decreases
   (becomes negative)
 * If the laptop is put upside-down, Z becomes negative

If your laptop model is not recognized (cf "dmesg"), you can send an
email to the maintainer to add it to the database.  When reporting a new
laptop, please include the output of "dmidecode" plus the value of
/sys/devices/platform/lis3lv02d/position in these four cases.

Q&A
---

Q: How do I safely simulate freefall? I have an HP "portable
workstation" which has about 3.5kg and a plastic case, so letting it
fall to the ground is out of question...

A: The sensor is pretty sensitive, so your hands can do it. Lift it
into free space, follow the fall with your hands for like 10
centimeters. That should be enough to trigger the detection.


code:
=====================
Kernel driver max6875
=====================

Supported chips:

  * Maxim MAX6874, MAX6875

    Prefix: 'max6875'

    Addresses scanned: None (see below)

    Datasheet: http://pdfserv.maxim-ic.com/en/ds/MAX6874-MAX6875.pdf

Author: Ben Gardner <bgardner@wabtec.com>

Description
-----------

The Maxim MAX6875 is an EEPROM-programmable power-supply sequencer/supervisor.
It provides timed outputs that can be used as a watchdog, if properly wired.
It also provides 512 bytes of user EEPROM.

At reset, the MAX6875 reads the configuration EEPROM into its configuration
registers.  The chip then begins to operate according to the values in the
registers.

The Maxim MAX6874 is a similar, mostly compatible device, with more inputs
and outputs:

===========  ===     ===    ====
-            vin     gpi    vout
===========  ===     ===    ====
MAX6874        6       4       8
MAX6875        4       3       5
===========  ===     ===    ====

See the datasheet for more information.

Sysfs entries
-------------

eeprom        - 512 bytes of user-defined EEPROM space.

General Remarks
---------------

Valid addresses for the MAX6875 are 0x50 and 0x52.

Valid addresses for the MAX6874 are 0x50, 0x52, 0x54 and 0x56.

The driver does not probe any address, so you explicitly instantiate the
devices.

Example::

  $ modprobe max6875
  $ echo max6875 0x50 > /sys/bus/i2c/devices/i2c-0/new_device

The MAX6874/MAX6875 ignores address bit 0, so this driver attaches to multiple
addresses.  For example, for address 0x50, it also reserves 0x51.
The even-address instance is called 'max6875', the odd one is 'dummy'.

Programming the chip using i2c-dev
----------------------------------

Use the i2c-dev interface to access and program the chips.

Reads and writes are performed differently depending on the address range.

The configuration registers are at addresses 0x00 - 0x45.

Use i2c_smbus_write_byte_data() to write a register and
i2c_smbus_read_byte_data() to read a register.

The command is the register number.

Examples:

To write a 1 to register 0x45::

  i2c_smbus_write_byte_data(fd, 0x45, 1);

To read register 0x45::

  value = i2c_smbus_read_byte_data(fd, 0x45);

The configuration EEPROM is at addresses 0x8000 - 0x8045.

The user EEPROM is at addresses 0x8100 - 0x82ff.

Use i2c_smbus_write_word_data() to write a byte to EEPROM.

The command is the upper byte of the address: 0x80, 0x81, or 0x82.
The data word is the lower part of the address or'd with data << 8::

  cmd = address >> 8;
  val = (address & 0xff) | (data << 8);

Example:

To write 0x5a to address 0x8003::

  i2c_smbus_write_word_data(fd, 0x80, 0x5a03);

Reading data from the EEPROM is a little more complicated.

Use i2c_smbus_write_byte_data() to set the read address and then
i2c_smbus_read_byte() or i2c_smbus_read_i2c_block_data() to read the data.

Example:

To read data starting at offset 0x8100, first set the address::

  i2c_smbus_write_byte_data(fd, 0x81, 0x00);

And then read the data::

  value = i2c_smbus_read_byte(fd);

or::

  count = i2c_smbus_read_i2c_block_data(fd, 0x84, 16, buffer);

The block read should read 16 bytes.

0x84 is the block read command.

See the datasheet for more details.


code:
.. SPDX-License-Identifier: GPL-2.0

====================================================================
Notes on Oxford Semiconductor PCIe (Tornado) 950 serial port devices
====================================================================

Oxford Semiconductor PCIe (Tornado) 950 serial port devices are driven
by a fixed 62.5MHz clock input derived from the 100MHz PCI Express clock.

The baud rate produced by the baud generator is obtained from this input
frequency by dividing it by the clock prescaler, which can be set to any
value from 1 to 63.875 in increments of 0.125, and then the usual 16-bit
divisor is used as with the original 8250, to divide the frequency by a
value from 1 to 65535.  Finally a programmable oversampling rate is used
that can take any value from 4 to 16 to divide the frequency further and
determine the actual baud rate used.  Baud rates from 15625000bps down
to 0.933bps can be obtained this way.

By default the oversampling rate is set to 16 and the clock prescaler is
set to 33.875, meaning that the frequency to be used as the reference
for the usual 16-bit divisor is 115313.653, which is close enough to the
frequency of 115200 used by the original 8250 for the same values to be
used for the divisor to obtain the requested baud rates by software that
is unaware of the extra clock controls available.

The oversampling rate is programmed with the TCR register and the clock
prescaler is programmed with the CPR/CPR2 register pair [OX200]_ [OX952]_
[OX954]_ [OX958]_.  To switch away from the default value of 33.875 for
the prescaler the enhanced mode has to be explicitly enabled though, by
setting bit 4 of the EFR.  In that mode setting bit 7 in the MCR enables
the prescaler or otherwise it is bypassed as if the value of 1 was used.
Additionally writing any value to CPR clears CPR2 for compatibility with
old software written for older conventional PCI Oxford Semiconductor
devices that do not have the extra prescaler's 9th bit in CPR2, so the
CPR/CPR2 register pair has to be programmed in the right order.

By using these parameters rates from 15625000bps down to 1bps can be
obtained, with either exact or highly-accurate actual bit rates for
standard and many non-standard rates.

Here are the figures for the standard and some non-standard baud rates
(including those quoted in Oxford Semiconductor documentation), giving
the requested rate (r), the actual rate yielded (a) and its deviation
from the requested rate (d), and the values of the oversampling rate
(tcr), the clock prescaler (cpr) and the divisor (div) produced by the
new ``get_divisor`` handler:

::

 r: 15625000, a: 15625000.00, d:  0.0000%, tcr:  4, cpr:  1.000, div:     1
 r: 12500000, a: 12500000.00, d:  0.0000%, tcr:  5, cpr:  1.000, div:     1
 r: 10416666, a: 10416666.67, d:  0.0000%, tcr:  6, cpr:  1.000, div:     1
 r:  8928571, a:  8928571.43, d:  0.0000%, tcr:  7, cpr:  1.000, div:     1
 r:  7812500, a:  7812500.00, d:  0.0000%, tcr:  8, cpr:  1.000, div:     1
 r:  4000000, a:  4000000.00, d:  0.0000%, tcr:  5, cpr:  3.125, div:     1
 r:  3686400, a:  3676470.59, d: -0.2694%, tcr:  8, cpr:  2.125, div:     1
 r:  3500000, a:  3496503.50, d: -0.0999%, tcr: 13, cpr:  1.375, div:     1
 r:  3000000, a:  2976190.48, d: -0.7937%, tcr: 14, cpr:  1.500, div:     1
 r:  2500000, a:  2500000.00, d:  0.0000%, tcr: 10, cpr:  2.500, div:     1
 r:  2000000, a:  2000000.00, d:  0.0000%, tcr: 10, cpr:  3.125, div:     1
 r:  1843200, a:  1838235.29, d: -0.2694%, tcr: 16, cpr:  2.125, div:     1
 r:  1500000, a:  1492537.31, d: -0.4975%, tcr:  5, cpr:  8.375, div:     1
 r:  1152000, a:  1152073.73, d:  0.0064%, tcr: 14, cpr:  3.875, div:     1
 r:   921600, a:   919117.65, d: -0.2694%, tcr: 16, cpr:  2.125, div:     2
 r:   576000, a:   576036.87, d:  0.0064%, tcr: 14, cpr:  3.875, div:     2
 r:   460800, a:   460829.49, d:  0.0064%, tcr:  7, cpr:  3.875, div:     5
 r:   230400, a:   230414.75, d:  0.0064%, tcr: 14, cpr:  3.875, div:     5
 r:   115200, a:   115207.37, d:  0.0064%, tcr: 14, cpr:  1.250, div:    31
 r:    57600, a:    57603.69, d:  0.0064%, tcr:  8, cpr:  3.875, div:    35
 r:    38400, a:    38402.46, d:  0.0064%, tcr: 14, cpr:  3.875, div:    30
 r:    19200, a:    19201.23, d:  0.0064%, tcr:  8, cpr:  3.875, div:   105
 r:     9600, a:     9600.06, d:  0.0006%, tcr:  9, cpr:  1.125, div:   643
 r:     4800, a:     4799.98, d: -0.0004%, tcr:  7, cpr:  2.875, div:   647
 r:     2400, a:     2400.02, d:  0.0008%, tcr:  9, cpr:  2.250, div:  1286
 r:     1200, a:     1200.00, d:  0.0000%, tcr: 14, cpr:  2.875, div:  1294
 r:      300, a:      300.00, d:  0.0000%, tcr: 11, cpr:  2.625, div:  7215
 r:      200, a:      200.00, d:  0.0000%, tcr: 16, cpr:  1.250, div: 15625
 r:      150, a:      150.00, d:  0.0000%, tcr: 13, cpr:  2.250, div: 14245
 r:      134, a:      134.00, d:  0.0000%, tcr: 11, cpr:  2.625, div: 16153
 r:      110, a:      110.00, d:  0.0000%, tcr: 12, cpr:  1.000, div: 47348
 r:       75, a:       75.00, d:  0.0000%, tcr:  4, cpr:  5.875, div: 35461
 r:       50, a:       50.00, d:  0.0000%, tcr: 16, cpr:  1.250, div: 62500
 r:       25, a:       25.00, d:  0.0000%, tcr: 16, cpr:  2.500, div: 62500
 r:        4, a:        4.00, d:  0.0000%, tcr: 16, cpr: 20.000, div: 48828
 r:        2, a:        2.00, d:  0.0000%, tcr: 16, cpr: 40.000, div: 48828
 r:        1, a:        1.00, d:  0.0000%, tcr: 16, cpr: 63.875, div: 61154

With the baud base set to 15625000 and the unsigned 16-bit UART_DIV_MAX
limitation imposed by ``serial8250_get_baud_rate`` standard baud rates
below 300bps become unavailable in the regular way, e.g. the rate of
200bps requires the baud base to be divided by 78125 and that is beyond
the unsigned 16-bit range.  The historic spd_cust feature can still be
used by encoding the values for, the prescaler, the oversampling rate
and the clock divisor (DLM/DLL) as follows to obtain such rates if so
required:

::

  31 29 28             20 19   16 15                            0
 +-----+-----------------+-------+-------------------------------+
 |0 0 0|    CPR2:CPR     |  TCR  |            DLM:DLL            |
 +-----+-----------------+-------+-------------------------------+

Use a value such encoded for the ``custom_divisor`` field along with the
ASYNC_SPD_CUST flag set in the ``flags`` field in ``struct serial_struct``
passed with the TIOCSSERIAL ioctl(2), such as with the setserial(8)
utility and its ``divisor`` and ``spd_cust`` parameters, and then select
the baud rate of 38400bps.  Note that the value of 0 in TCR sets the
oversampling rate to 16 and prescaler values below 1 in CPR2/CPR are
clamped by the driver to 1.

For example the value of 0x1f4004e2 will set CPR2/CPR, TCR and DLM/DLL
respectively to 0x1f4, 0x0 and 0x04e2, choosing the prescaler value,
the oversampling rate and the clock divisor of 62.500, 16 and 1250
respectively.  These parameters will set the baud rate for the serial
port to 62500000 / 62.500 / 1250 / 16 = 50bps.

Maciej W. Rozycki  <macro@orcam.me.uk>

.. [OX200] "OXPCIe200 PCI Express Multi-Port Bridge", Oxford Semiconductor,
   Inc., DS-0045, 10 Nov 2008, Section "950 Mode", pp. 64-65

.. [OX952] "OXPCIe952 PCI Express Bridge to Dual Serial & Parallel Port",
   Oxford Semiconductor, Inc., DS-0046, Mar 06 08, Section "950 Mode",
   p. 20

.. [OX954] "OXPCIe954 PCI Express Bridge to Quad Serial Port", Oxford
   Semiconductor, Inc., DS-0047, Feb 08, Section "950 Mode", p. 20

.. [OX958] "OXPCIe958 PCI Express Bridge to Octal Serial Port", Oxford
   Semiconductor, Inc., DS-0048, Feb 08, Section "950 Mode", p. 20


code:
.. SPDX-License-Identifier: GPL-2.0

=====================================
Driver for PCI Endpoint Test Function
=====================================

This driver should be used as a host side driver if the root complex is
connected to a configurable PCI endpoint running ``pci_epf_test`` function
driver configured according to [1]_.

The "pci_endpoint_test" driver can be used to perform the following tests.

The PCI driver for the test device performs the following tests:

	#) verifying addresses programmed in BAR
	#) raise legacy IRQ
	#) raise MSI IRQ
	#) raise MSI-X IRQ
	#) read data
	#) write data
	#) copy data

This misc driver creates /dev/pci-endpoint-test.<num> for every
``pci_epf_test`` function connected to the root complex and "ioctls"
should be used to perform the above tests.

ioctl
-----

 PCITEST_BAR:
	      Tests the BAR. The number of the BAR to be tested
	      should be passed as argument.
 PCITEST_LEGACY_IRQ:
	      Tests legacy IRQ
 PCITEST_MSI:
	      Tests message signalled interrupts. The MSI number
	      to be tested should be passed as argument.
 PCITEST_MSIX:
	      Tests message signalled interrupts. The MSI-X number
	      to be tested should be passed as argument.
 PCITEST_SET_IRQTYPE:
	      Changes driver IRQ type configuration. The IRQ type
	      should be passed as argument (0: Legacy, 1:MSI, 2:MSI-X).
 PCITEST_GET_IRQTYPE:
	      Gets driver IRQ type configuration.
 PCITEST_WRITE:
	      Perform write tests. The size of the buffer should be passed
	      as argument.
 PCITEST_READ:
	      Perform read tests. The size of the buffer should be passed
	      as argument.
 PCITEST_COPY:
	      Perform read tests. The size of the buffer should be passed
	      as argument.

.. [1] Documentation/PCI/endpoint/function/binding/pci-test.rst


code:
.. SPDX-License-Identifier: GPL-2.0

========================
Spear PCIe Gadget Driver
========================

Author
======
Pratyush Anand (pratyush.anand@gmail.com)

Location
========
driver/misc/spear13xx_pcie_gadget.c

Supported Chip:
===============
SPEAr1300
SPEAr1310

Menuconfig option:
==================
Device Drivers
	Misc devices
		PCIe gadget support for SPEAr13XX platform

purpose
=======
This driver has several nodes which can be read/written by configfs interface.
Its main purpose is to configure selected dual mode PCIe controller as device
and then program its various registers to configure it as a particular device
type. This driver can be used to show spear's PCIe device capability.

Description of different nodes:
===============================

read behavior of nodes:
-----------------------

=============== ==============================================================
link 		gives ltssm status.
int_type 	type of supported interrupt
no_of_msi 	zero if MSI is not enabled by host. A positive value is the
		number of MSI vector granted.
vendor_id	returns programmed vendor id (hex)
device_id	returns programmed device id(hex)
bar0_size:	returns size of bar0 in hex.
bar0_address	returns address of bar0 mapped area in hex.
bar0_rw_offset	returns offset of bar0 for which bar0_data will return value.
bar0_data	returns data at bar0_rw_offset.
=============== ==============================================================

write behavior of nodes:
------------------------

=============== ================================================================
link 		write UP to enable ltsmm DOWN to disable
int_type	write interrupt type to be configured and (int_type could be
		INTA, MSI or NO_INT). Select MSI only when you have programmed
		no_of_msi node.
no_of_msi	number of MSI vector needed.
inta		write 1 to assert INTA and 0 to de-assert.
send_msi	write MSI vector to be sent.
vendor_id	write vendor id(hex) to be programmed.
device_id	write device id(hex) to be programmed.
bar0_size	write size of bar0 in hex. default bar0 size is 1000 (hex)
		bytes.
bar0_address	write	address of bar0 mapped area in hex. (default mapping of
		bar0 is SYSRAM1(E0800000). Always program bar size before bar
		address. Kernel might modify bar size and address for alignment,
		so read back bar size and address after writing to cross check.
bar0_rw_offset	write offset of bar0 for which	bar0_data will write value.
bar0_data	write data to be written at bar0_rw_offset.
=============== ================================================================

Node programming example
========================

Program all PCIe registers in such a way that when this device is connected
to the PCIe host, then host sees this device as 1MB RAM.

::

    #mount -t configfs none /Config

For nth PCIe Device Controller::

    # cd /config/pcie_gadget.n/

Now you have all the nodes in this directory.
program vendor id as 0x104a::

    # echo 104A >> vendor_id

program device id as 0xCD80::

    # echo CD80 >> device_id

program BAR0 size as 1MB::

    # echo 100000 >> bar0_size

check for programmed bar0 size::

    # cat bar0_size

Program BAR0 Address as DDR (0x2100000). This is the physical address of
memory, which is to be made visible to PCIe host. Similarly any other peripheral
can also be made visible to PCIe host. E.g., if you program base address of UART
as BAR0 address then when this device will be connected to a host, it will be
visible as UART.

::

    # echo 2100000 >> bar0_address

program interrupt type : INTA::

    # echo INTA >> int_type

go for link up now::

    # echo UP >> link

It will have to be insured that, once link up is done on gadget, then only host
is initialized and start to search PCIe devices on its port.

::

    /*wait till link is up*/
    # cat link

Wait till it returns UP.

To assert INTA::

    # echo 1 >> inta

To de-assert INTA::

    # echo 0 >> inta

if MSI is to be used as interrupt, program no of msi vector needed (say4)::

    # echo 4 >> no_of_msi

select MSI as interrupt type::

    # echo MSI >> int_type

go for link up now::

    # echo UP >> link

wait till link is up::

    # cat link

An application can repetitively read this node till link is found UP. It can
sleep between two read.

wait till msi is enabled::

    # cat no_of_msi

Should return 4 (number of requested MSI vector)

to send msi vector 2::

    # echo 2 >> send_msi
    # cd -


code:
.. SPDX-License-Identifier: GPL-2.0

Introduction of Uacce
---------------------

Uacce (Unified/User-space-access-intended Accelerator Framework) targets to
provide Shared Virtual Addressing (SVA) between accelerators and processes.
So accelerator can access any data structure of the main cpu.
This differs from the data sharing between cpu and io device, which share
only data content rather than address.
Because of the unified address, hardware and user space of process can
share the same virtual address in the communication.
Uacce takes the hardware accelerator as a heterogeneous processor, while
IOMMU share the same CPU page tables and as a result the same translation
from va to pa.

::

         __________________________       __________________________
        |                          |     |                          |
        |  User application (CPU)  |     |   Hardware Accelerator   |
        |__________________________|     |__________________________|

                     |                                 |
                     | va                              | va
                     V                                 V
                 __________                        __________
                |          |                      |          |
                |   MMU    |                      |  IOMMU   |
                |__________|                      |__________|
                     |                                 |
                     |                                 |
                     V pa                              V pa
                 _______________________________________
                |                                       |
                |              Memory                   |
                |_______________________________________|

Architecture
------------

Uacce is the kernel module, taking charge of iommu and address sharing.
The user drivers and libraries are called WarpDrive.

The uacce device, built around the IOMMU SVA API, can access multiple
address spaces, including the one without PASID.

A virtual concept, queue, is used for the communication. It provides a
FIFO-like interface. And it maintains a unified address space between the
application and all involved hardware.

::

                             ___________________                  ________________
                            |                   |   user API     |                |
                            | WarpDrive library | ------------>  |  user driver   |
                            |___________________|                |________________|
                                     |                                    |
                                     |                                    |
                                     | queue fd                           |
                                     |                                    |
                                     |                                    |
                                     v                                    |
     ___________________         _________                                |
    |                   |       |         |                               | mmap memory
    | Other framework   |       |  uacce  |                               | r/w interface
    | crypto/nic/others |       |_________|                               |
    |___________________|                                                 |
             |                       |                                    |
             | register              | register                           |
             |                       |                                    |
             |                       |                                    |
             |                _________________       __________          |
             |               |                 |     |          |         |
              -------------  |  Device Driver  |     |  IOMMU   |         |
                             |_________________|     |__________|         |
                                     |                                    |
                                     |                                    V
                                     |                            ___________________
                                     |                           |                   |
                                     --------------------------  |  Device(Hardware) |
                                                                 |___________________|

How does it work
----------------

Uacce uses mmap and IOMMU to play the trick.

Uacce creates a chrdev for every device registered to it. New queue is
created when user application open the chrdev. The file descriptor is used
as the user handle of the queue.
The accelerator device present itself as an Uacce object, which exports as
a chrdev to the user space. The user application communicates with the
hardware by ioctl (as control path) or share memory (as data path).

The control path to the hardware is via file operation, while data path is
via mmap space of the queue fd.

The queue file address space:

::

   /**
   * enum uacce_qfrt: qfrt type
   * @UACCE_QFRT_MMIO: device mmio region
   * @UACCE_QFRT_DUS: device user share region
   */
  enum uacce_qfrt {
          UACCE_QFRT_MMIO = 0,
          UACCE_QFRT_DUS = 1,
  };

All regions are optional and differ from device type to type.
Each region can be mmapped only once, otherwise -EEXIST returns.

The device mmio region is mapped to the hardware mmio space. It is generally
used for doorbell or other notification to the hardware. It is not fast enough
as data channel.

The device user share region is used for share data buffer between user process
and device.

The Uacce register API
----------------------

The register API is defined in uacce.h.

::

  struct uacce_interface {
    char name[UACCE_MAX_NAME_SIZE];
    unsigned int flags;
    const struct uacce_ops *ops;
  };

According to the IOMMU capability, uacce_interface flags can be:

::

  /**
   * UACCE Device flags:
   * UACCE_DEV_SVA: Shared Virtual Addresses
   *              Support PASID
   *              Support device page faults (PCI PRI or SMMU Stall)
   */
  #define UACCE_DEV_SVA               BIT(0)

  struct uacce_device *uacce_alloc(struct device *parent,
                                   struct uacce_interface *interface);
  int uacce_register(struct uacce_device *uacce);
  void uacce_remove(struct uacce_device *uacce);

uacce_register results can be:

a. If uacce module is not compiled, ERR_PTR(-ENODEV)

b. Succeed with the desired flags

c. Succeed with the negotiated flags, for example

  uacce_interface.flags = UACCE_DEV_SVA but uacce->flags = ~UACCE_DEV_SVA

  So user driver need check return value as well as the negotiated uacce->flags.

The user driver
---------------

The queue file mmap space will need a user driver to wrap the communication
protocol. Uacce provides some attributes in sysfs for the user driver to
match the right accelerator accordingly.
More details in Documentation/ABI/testing/sysfs-driver-uacce.


code:
.. SPDX-License-Identifier: GPL-2.0+

====================
Xilinx SD-FEC Driver
====================

Overview
========

This driver supports SD-FEC Integrated Block for Zynq |Ultrascale+ (TM)| RFSoCs.

.. |Ultrascale+ (TM)| unicode:: Ultrascale+ U+2122
   .. with trademark sign

For a full description of SD-FEC core features, see the `SD-FEC Product Guide (PG256) <https://www.xilinx.com/cgi-bin/docs/ipdoc?c=sd_fec;v=latest;d=pg256-sdfec-integrated-block.pdf>`_

This driver supports the following features:

  - Retrieval of the Integrated Block configuration and status information
  - Configuration of LDPC codes
  - Configuration of Turbo decoding
  - Monitoring errors

Missing features, known issues, and limitations of the SD-FEC driver are as
follows:

  - Only allows a single open file handler to any instance of the driver at any time
  - Reset of the SD-FEC Integrated Block is not controlled by this driver
  - Does not support shared LDPC code table wraparound

The device tree entry is described in:
`linux-xlnx/Documentation/devicetree/bindings/misc/xlnx,sd-fec.txt <https://github.com/Xilinx/linux-xlnx/blob/master/Documentation/devicetree/bindings/misc/xlnx%2Csd-fec.txt>`_

Modes of Operation
------------------

The driver works with the SD-FEC core in two modes of operation:

  - Run-time configuration
  - Programmable Logic (PL) initialization

Run-time Configuration
~~~~~~~~~~~~~~~~~~~~~~

For Run-time configuration the role of driver is to allow the software application to do the following:

	- Load the configuration parameters for either Turbo decode or LDPC encode or decode
	- Activate the SD-FEC core
	- Monitor the SD-FEC core for errors
	- Retrieve the status and configuration of the SD-FEC core

Programmable Logic (PL) Initialization
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

For PL initialization, supporting logic loads configuration parameters for either
the Turbo decode or LDPC encode or decode.  The role of the driver is to allow
the software application to do the following:

	- Activate the SD-FEC core
	- Monitor the SD-FEC core for errors
	- Retrieve the status and configuration of the SD-FEC core

Driver Structure
================

The driver provides a platform device where the ``probe`` and ``remove``
operations are provided.

  - probe: Updates configuration register with device-tree entries plus determines the current activate state of the core, for example, is the core bypassed or has the core been started.

The driver defines the following driver file operations to provide user
application interfaces:

  - open: Implements restriction that only a single file descriptor can be open per SD-FEC instance at any time
  - release: Allows another file descriptor to be open, that is after current file descriptor is closed
  - poll: Provides a method to monitor for SD-FEC Error events
  - unlocked_ioctl: Provides the following ioctl commands that allows the application configure the SD-FEC core:

		- :c:macro:`XSDFEC_START_DEV`
		- :c:macro:`XSDFEC_STOP_DEV`
		- :c:macro:`XSDFEC_GET_STATUS`
		- :c:macro:`XSDFEC_SET_IRQ`
		- :c:macro:`XSDFEC_SET_TURBO`
		- :c:macro:`XSDFEC_ADD_LDPC_CODE_PARAMS`
		- :c:macro:`XSDFEC_GET_CONFIG`
		- :c:macro:`XSDFEC_SET_ORDER`
		- :c:macro:`XSDFEC_SET_BYPASS`
		- :c:macro:`XSDFEC_IS_ACTIVE`
		- :c:macro:`XSDFEC_CLEAR_STATS`
		- :c:macro:`XSDFEC_SET_DEFAULT_CONFIG`

Driver Usage
============

Overview
--------

After opening the driver, the user should find out what operations need to be
performed to configure and activate the SD-FEC core and determine the
configuration of the driver.
The following outlines the flow the user should perform:

  - Determine Configuration
  - Set the order, if not already configured as desired
  - Set Turbo decode, LPDC encode or decode parameters, depending on how the
    SD-FEC core is configured plus if the SD-FEC has not been configured for PL
    initialization
  - Enable interrupts, if not already enabled
  - Bypass the SD-FEC core, if required
  - Start the SD-FEC core if not already started
  - Get the SD-FEC core status
  - Monitor for interrupts
  - Stop the SD-FEC core

Note: When monitoring for interrupts if a critical error is detected where a reset is required, the driver will be required to load the default configuration.

Determine Configuration
-----------------------

Determine the configuration of the SD-FEC core by using the ioctl
:c:macro:`XSDFEC_GET_CONFIG`.

Set the Order
-------------

Setting the order determines how the order of Blocks can change from input to output.

Setting the order is done by using the ioctl :c:macro:`XSDFEC_SET_ORDER`

Setting the order can only be done if the following restrictions are met:

	- The ``state`` member of struct :c:type:`xsdfec_status <xsdfec_status>` filled by the ioctl :c:macro:`XSDFEC_GET_STATUS` indicates the SD-FEC core has not STARTED

Add LDPC Codes
--------------

The following steps indicate how to add LDPC codes to the SD-FEC core:

	- Use the auto-generated parameters to fill the :c:type:`struct xsdfec_ldpc_params <xsdfec_ldpc_params>` for the desired LDPC code.
	- Set the SC, QA, and LA table offsets for the LPDC parameters and the parameters in the structure :c:type:`struct xsdfec_ldpc_params <xsdfec_ldpc_params>`
	- Set the desired Code Id value in the structure :c:type:`struct xsdfec_ldpc_params <xsdfec_ldpc_params>`
	- Add the LPDC Code Parameters using the ioctl :c:macro:`XSDFEC_ADD_LDPC_CODE_PARAMS`
	- For the applied LPDC Code Parameter use the function :c:func:`xsdfec_calculate_shared_ldpc_table_entry_size` to calculate the size of shared LPDC code tables. This allows the user to determine the shared table usage so when selecting the table offsets for the next LDPC code parameters unused table areas can be selected.
	- Repeat for each LDPC code parameter.

Adding LDPC codes can only be done if the following restrictions are met:

	- The ``code`` member of :c:type:`struct xsdfec_config <xsdfec_config>` filled by the ioctl :c:macro:`XSDFEC_GET_CONFIG` indicates the SD-FEC core is configured as LDPC
	- The ``code_wr_protect`` of :c:type:`struct xsdfec_config <xsdfec_config>` filled by the ioctl :c:macro:`XSDFEC_GET_CONFIG` indicates that write protection is not enabled
	- The ``state`` member of struct :c:type:`xsdfec_status <xsdfec_status>` filled by the ioctl :c:macro:`XSDFEC_GET_STATUS` indicates the SD-FEC core has not started

Set Turbo Decode
----------------

Configuring the Turbo decode parameters is done by using the ioctl :c:macro:`XSDFEC_SET_TURBO` using auto-generated parameters to fill the :c:type:`struct xsdfec_turbo <xsdfec_turbo>` for the desired Turbo code.

Adding Turbo decode can only be done if the following restrictions are met:

	- The ``code`` member of :c:type:`struct xsdfec_config <xsdfec_config>` filled by the ioctl :c:macro:`XSDFEC_GET_CONFIG` indicates the SD-FEC core is configured as TURBO
	- The ``state`` member of struct :c:type:`xsdfec_status <xsdfec_status>` filled by the ioctl :c:macro:`XSDFEC_GET_STATUS` indicates the SD-FEC core has not STARTED

Enable Interrupts
-----------------

Enabling or disabling interrupts is done by using the ioctl :c:macro:`XSDFEC_SET_IRQ`. The members of the parameter passed, :c:type:`struct xsdfec_irq <xsdfec_irq>`, to the ioctl are used to set and clear different categories of interrupts. The category of interrupt is controlled as following:

  - ``enable_isr`` controls the ``tlast`` interrupts
  - ``enable_ecc_isr`` controls the ECC interrupts

If the ``code`` member of :c:type:`struct xsdfec_config <xsdfec_config>` filled by the ioctl :c:macro:`XSDFEC_GET_CONFIG` indicates the SD-FEC core is configured as TURBO then the enabling ECC errors is not required.

Bypass the SD-FEC
-----------------

Bypassing the SD-FEC is done by using the ioctl :c:macro:`XSDFEC_SET_BYPASS`

Bypassing the SD-FEC can only be done if the following restrictions are met:

	- The ``state`` member of :c:type:`struct xsdfec_status <xsdfec_status>` filled by the ioctl :c:macro:`XSDFEC_GET_STATUS` indicates the SD-FEC core has not STARTED

Start the SD-FEC core
---------------------

Start the SD-FEC core by using the ioctl :c:macro:`XSDFEC_START_DEV`

Get SD-FEC Status
-----------------

Get the SD-FEC status of the device by using the ioctl :c:macro:`XSDFEC_GET_STATUS`, which will fill the :c:type:`struct xsdfec_status <xsdfec_status>`

Monitor for Interrupts
----------------------

	- Use the poll system call to monitor for an interrupt. The poll system call waits for an interrupt to wake it up or times out if no interrupt occurs.
	- On return Poll ``revents`` will indicate whether stats and/or state have been updated
		- ``POLLPRI`` indicates a critical error and the user should use :c:macro:`XSDFEC_GET_STATUS` and :c:macro:`XSDFEC_GET_STATS` to confirm
		- ``POLLRDNORM`` indicates a non-critical error has occurred and the user should use  :c:macro:`XSDFEC_GET_STATS` to confirm
	- Get stats by using the ioctl :c:macro:`XSDFEC_GET_STATS`
		- For critical error the ``isr_err_count`` or ``uecc_count`` member  of :c:type:`struct xsdfec_stats <xsdfec_stats>` is non-zero
		- For non-critical errors the ``cecc_count`` member of :c:type:`struct xsdfec_stats <xsdfec_stats>` is non-zero
	- Get state by using the ioctl :c:macro:`XSDFEC_GET_STATUS`
		- For a critical error the ``state`` of :c:type:`xsdfec_status <xsdfec_status>` will indicate a Reset Is Required
	- Clear stats by using the ioctl :c:macro:`XSDFEC_CLEAR_STATS`

If a critical error is detected where a reset is required. The application is required to call the ioctl :c:macro:`XSDFEC_SET_DEFAULT_CONFIG`, after the reset and it is not required to call the ioctl :c:macro:`XSDFEC_STOP_DEV`

Note: Using poll system call prevents busy looping using :c:macro:`XSDFEC_GET_STATS` and :c:macro:`XSDFEC_GET_STATUS`

Stop the SD-FEC Core
---------------------

Stop the device by using the ioctl :c:macro:`XSDFEC_STOP_DEV`

Set the Default Configuration
-----------------------------

Load default configuration by using the ioctl :c:macro:`XSDFEC_SET_DEFAULT_CONFIG` to restore the driver.

Limitations
-----------

Users should not duplicate SD-FEC device file handlers, for example fork() or dup() a process that has a created an SD-FEC file handler.

Driver IOCTLs
==============

.. c:macro:: XSDFEC_START_DEV
.. kernel-doc:: include/uapi/misc/xilinx_sdfec.h
   :doc: XSDFEC_START_DEV

.. c:macro:: XSDFEC_STOP_DEV
.. kernel-doc:: include/uapi/misc/xilinx_sdfec.h
   :doc: XSDFEC_STOP_DEV

.. c:macro:: XSDFEC_GET_STATUS
.. kernel-doc:: include/uapi/misc/xilinx_sdfec.h
   :doc: XSDFEC_GET_STATUS

.. c:macro:: XSDFEC_SET_IRQ
.. kernel-doc:: include/uapi/misc/xilinx_sdfec.h
   :doc: XSDFEC_SET_IRQ

.. c:macro:: XSDFEC_SET_TURBO
.. kernel-doc:: include/uapi/misc/xilinx_sdfec.h
   :doc: XSDFEC_SET_TURBO

.. c:macro:: XSDFEC_ADD_LDPC_CODE_PARAMS
.. kernel-doc:: include/uapi/misc/xilinx_sdfec.h
   :doc: XSDFEC_ADD_LDPC_CODE_PARAMS

.. c:macro:: XSDFEC_GET_CONFIG
.. kernel-doc:: include/uapi/misc/xilinx_sdfec.h
   :doc: XSDFEC_GET_CONFIG

.. c:macro:: XSDFEC_SET_ORDER
.. kernel-doc:: include/uapi/misc/xilinx_sdfec.h
   :doc: XSDFEC_SET_ORDER

.. c:macro:: XSDFEC_SET_BYPASS
.. kernel-doc:: include/uapi/misc/xilinx_sdfec.h
   :doc: XSDFEC_SET_BYPASS

.. c:macro:: XSDFEC_IS_ACTIVE
.. kernel-doc:: include/uapi/misc/xilinx_sdfec.h
   :doc: XSDFEC_IS_ACTIVE

.. c:macro:: XSDFEC_CLEAR_STATS
.. kernel-doc:: include/uapi/misc/xilinx_sdfec.h
   :doc: XSDFEC_CLEAR_STATS

.. c:macro:: XSDFEC_GET_STATS
.. kernel-doc:: include/uapi/misc/xilinx_sdfec.h
   :doc: XSDFEC_GET_STATS

.. c:macro:: XSDFEC_SET_DEFAULT_CONFIG
.. kernel-doc:: include/uapi/misc/xilinx_sdfec.h
   :doc: XSDFEC_SET_DEFAULT_CONFIG

Driver Type Definitions
=======================

.. kernel-doc:: include/uapi/misc/xilinx_sdfec.h
   :internal:


code:
.. _active_mm:

=========
Active MM
=========

::

 List:       linux-kernel
 Subject:    Re: active_mm
 From:       Linus Torvalds <torvalds () transmeta ! com>
 Date:       1999-07-30 21:36:24

 Cc'd to linux-kernel, because I don't write explanations all that often,
 and when I do I feel better about more people reading them.

 On Fri, 30 Jul 1999, David Mosberger wrote:
 >
 > Is there a brief description someplace on how "mm" vs. "active_mm" in
 > the task_struct are supposed to be used?  (My apologies if this was
 > discussed on the mailing lists---I just returned from vacation and
 > wasn't able to follow linux-kernel for a while).

 Basically, the new setup is:

  - we have "real address spaces" and "anonymous address spaces". The
    difference is that an anonymous address space doesn't care about the
    user-level page tables at all, so when we do a context switch into an
    anonymous address space we just leave the previous address space
    active.

    The obvious use for a "anonymous address space" is any thread that
    doesn't need any user mappings - all kernel threads basically fall into
    this category, but even "real" threads can temporarily say that for
    some amount of time they are not going to be interested in user space,
    and that the scheduler might as well try to avoid wasting time on
    switching the VM state around. Currently only the old-style bdflush
    sync does that.

  - "tsk->mm" points to the "real address space". For an anonymous process,
    tsk->mm will be NULL, for the logical reason that an anonymous process
    really doesn't _have_ a real address space at all.

  - however, we obviously need to keep track of which address space we
    "stole" for such an anonymous user. For that, we have "tsk->active_mm",
    which shows what the currently active address space is.

    The rule is that for a process with a real address space (ie tsk->mm is
    non-NULL) the active_mm obviously always has to be the same as the real
    one.

    For a anonymous process, tsk->mm == NULL, and tsk->active_mm is the
    "borrowed" mm while the anonymous process is running. When the
    anonymous process gets scheduled away, the borrowed address space is
    returned and cleared.

 To support all that, the "struct mm_struct" now has two counters: a
 "mm_users" counter that is how many "real address space users" there are,
 and a "mm_count" counter that is the number of "lazy" users (ie anonymous
 users) plus one if there are any real users.

 Usually there is at least one real user, but it could be that the real
 user exited on another CPU while a lazy user was still active, so you do
 actually get cases where you have a address space that is _only_ used by
 lazy users. That is often a short-lived state, because once that thread
 gets scheduled away in favour of a real thread, the "zombie" mm gets
 released because "mm_count" becomes zero.

 Also, a new rule is that _nobody_ ever has "init_mm" as a real MM any
 more. "init_mm" should be considered just a "lazy context when no other
 context is available", and in fact it is mainly used just at bootup when
 no real VM has yet been created. So code that used to check

 	if (current->mm == &init_mm)

 should generally just do

 	if (!current->mm)

 instead (which makes more sense anyway - the test is basically one of "do
 we have a user context", and is generally done by the page fault handler
 and things like that).

 Anyway, I put a pre-patch-2.3.13-1 on ftp.kernel.org just a moment ago,
 because it slightly changes the interfaces to accommodate the alpha (who
 would have thought it, but the alpha actually ends up having one of the
 ugliest context switch codes - unlike the other architectures where the MM
 and register state is separate, the alpha PALcode joins the two, and you
 need to switch both together).

 (From http://marc.info/?l=linux-kernel&m=93337278602211&w=2)


code:
.. _balance:

================
Memory Balancing
================

Started Jan 2000 by Kanoj Sarcar <kanoj@sgi.com>

Memory balancing is needed for !__GFP_ATOMIC and !__GFP_KSWAPD_RECLAIM as
well as for non __GFP_IO allocations.

The first reason why a caller may avoid reclaim is that the caller can not
sleep due to holding a spinlock or is in interrupt context. The second may
be that the caller is willing to fail the allocation without incurring the
overhead of page reclaim. This may happen for opportunistic high-order
allocation requests that have order-0 fallback options. In such cases,
the caller may also wish to avoid waking kswapd.

__GFP_IO allocation requests are made to prevent file system deadlocks.

In the absence of non sleepable allocation requests, it seems detrimental
to be doing balancing. Page reclamation can be kicked off lazily, that
is, only when needed (aka zone free memory is 0), instead of making it
a proactive process.

That being said, the kernel should try to fulfill requests for direct
mapped pages from the direct mapped pool, instead of falling back on
the dma pool, so as to keep the dma pool filled for dma requests (atomic
or not). A similar argument applies to highmem and direct mapped pages.
OTOH, if there is a lot of free dma pages, it is preferable to satisfy
regular memory requests by allocating one from the dma pool, instead
of incurring the overhead of regular zone balancing.

In 2.2, memory balancing/page reclamation would kick off only when the
_total_ number of free pages fell below 1/64 th of total memory. With the
right ratio of dma and regular memory, it is quite possible that balancing
would not be done even when the dma zone was completely empty. 2.2 has
been running production machines of varying memory sizes, and seems to be
doing fine even with the presence of this problem. In 2.3, due to
HIGHMEM, this problem is aggravated.

In 2.3, zone balancing can be done in one of two ways: depending on the
zone size (and possibly of the size of lower class zones), we can decide
at init time how many free pages we should aim for while balancing any
zone. The good part is, while balancing, we do not need to look at sizes
of lower class zones, the bad part is, we might do too frequent balancing
due to ignoring possibly lower usage in the lower class zones. Also,
with a slight change in the allocation routine, it is possible to reduce
the memclass() macro to be a simple equality.

Another possible solution is that we balance only when the free memory
of a zone _and_ all its lower class zones falls below 1/64th of the
total memory in the zone and its lower class zones. This fixes the 2.2
balancing problem, and stays as close to 2.2 behavior as possible. Also,
the balancing algorithm works the same way on the various architectures,
which have different numbers and types of zones. If we wanted to get
fancy, we could assign different weights to free pages in different
zones in the future.

Note that if the size of the regular zone is huge compared to dma zone,
it becomes less significant to consider the free dma pages while
deciding whether to balance the regular zone. The first solution
becomes more attractive then.

The appended patch implements the second solution. It also "fixes" two
problems: first, kswapd is woken up as in 2.2 on low memory conditions
for non-sleepable allocations. Second, the HIGHMEM zone is also balanced,
so as to give a fighting chance for replace_with_highmem() to get a
HIGHMEM page, as well as to ensure that HIGHMEM allocations do not
fall back into regular zone. This also makes sure that HIGHMEM pages
are not leaked (for example, in situations where a HIGHMEM page is in
the swapcache but is not being used by anyone)

kswapd also needs to know about the zones it should balance. kswapd is
primarily needed in a situation where balancing can not be done,
probably because all allocation requests are coming from intr context
and all process contexts are sleeping. For 2.3, kswapd does not really
need to balance the highmem zone, since intr context does not request
highmem pages. kswapd looks at the zone_wake_kswapd field in the zone
structure to decide whether a zone needs balancing.

Page stealing from process memory and shm is done if stealing the page would
alleviate memory pressure on any zone in the page's node that has fallen below
its watermark.

watemark[WMARK_MIN/WMARK_LOW/WMARK_HIGH]/low_on_memory/zone_wake_kswapd: These
are per-zone fields, used to determine when a zone needs to be balanced. When
the number of pages falls below watermark[WMARK_MIN], the hysteric field
low_on_memory gets set. This stays set till the number of free pages becomes
watermark[WMARK_HIGH]. When low_on_memory is set, page allocation requests will
try to free some pages in the zone (providing GFP_WAIT is set in the request).
Orthogonal to this, is the decision to poke kswapd to free some zone pages.
That decision is not hysteresis based, and is done when the number of free
pages is below watermark[WMARK_LOW]; in which case zone_wake_kswapd is also set.

(Good) Ideas that I have heard:

1. Dynamic experience should influence balancing: number of failed requests
   for a zone can be tracked and fed into the balancing scheme (jalvo@mbay.net)
2. Implement a replace_with_highmem()-like replace_with_regular() to preserve
   dma pages. (lkd@tantalophile.demon.co.uk)


code:
.. SPDX-License-Identifier: GPL-2.0

===========
Boot Memory
===========


code:
.. SPDX-License-Identifier: GPL-2.0

=============
API Reference
=============

Kernel space programs can use every feature of DAMON using below APIs.  All you
need to do is including ``damon.h``, which is located in ``include/linux/`` of
the source tree.

Structures
==========

.. kernel-doc:: include/linux/damon.h

Functions
=========

.. kernel-doc:: mm/damon/core.c