android_kernel_samsung_msm8976/Documentation/arm/msm/tspp2.txt

498 lines
19 KiB
Text
Raw Normal View History

Introduction
============
TSPP2 Driver
The TSPP2 (Transport Stream Packet Processor v2) is a hardware accelerator
designed to process MPEG-2 Transport Stream (TS) data. It can be used to
process broadcast TV services. The TSPP2 HW processes the TS packets, offloads
the host CPU and supports the real-time processing requirements of such
services.
TS data can be received either from TSIF (Transport Stream Interface) input
or from memory input, to support playing live broadcasts as well as
playback from memory. Recording is also supported.
TSPP2 is a significantly different HW unit than the TSPP unit described in
Documentation/arm/msm/tspp.txt. The functionality is enhanced and the HW
design is different.
Hardware description
====================
The TSPP2 HW contains the TSPP2 core, a BAM (Bus Access Manager, used for DMA
operations) unit, and a VBIF unit (IOMMU).
The TSPP2 HW supports:
a. Up to two TSIF inputs and up to eight memory inputs.
b. Various TS packet sizes (188/192 bytes) and formats (timestamp location).
c. PID filtering.
d. Raw transmit operation for section filtering or recording.
e. Full PES and separated PES transmit operation for audio and video playback.
f. Decryption and re-encryption operations for secure transport streams.
g. PCR extraction.
h. Indexing - identifying patterns in video streams.
The following diagram provides an overview of the TSPP2 HW:
+------------------------------------------------------------------+
| |
| +-------------+ +--------------------+ |
| | TSIF 0 +---> TSPP2 Core | |
| +-------------+ | | |
| | +---------------+ | |
| +-------------+ | | | | |
| | TSIF 1 +---> | Source 0 | | |
| +-------------+ | | | | |
| | | | | |
| | | | | |
| | | +------------+| | +--------------+ |
| | | | Filter 0 +|---------> BAM pipe 3 | |
| | | +------------+| | +--------------+ |
| | | +------------+| | +--------------+ |
| +-------------+ | | | Filter 1 +|---------> BAM pipe 4 | |
| | BAM pipe 0 +---> | +------------+| | +--------------+ |
| +-------------+ | | | | | |
| +-------------+ | +---------------+ | +--------------+ |
| | BAM pipe 1 +--->--------------------|----| | |
| +-------------+ | | | VBIF | |
| +-------------+ | | | IOMMU | |
| | BAM pipe 2 +--->--------------------|----| | |
| +-------------+ +--------------------+ +--------------+ |
+------------------------------------------------------------------+
A source is configured to have either a TSIF input (TSIF 0 or 1) or a
memory input (a BAM pipe). One or more filters are attached to the source.
Each filter has a 13-bit PID and mask values to perform the PID filtering.
Additionally, one or more operations are added to each filter to achieve the
required functionality. Each operation has specific parameters. The operation's
output is usually placed in an output pipe.
The TSPP HW uses its own virtual address space, mapping memory buffer addresses
using the VBIF IOMMU.
Software description
====================
The TSPP2 Linux kernel driver manages the TSPP2 core. The TSPP2 driver utilizes
the SPS driver to configure and manage the BAM unit, which is used to perform
DMA operations and move TS data to/from system memory.
The TSPP2 driver uses the ION driver to control the IOMMU and map user-allocated
buffers to the TSPP2 IOMMU domain.
The TSPP2 is a standard Linux platform device driver. It can be configured as a
loadable or built-in kernel module. The driver is supported only in platforms
that contain the TSPP2 HW.
The driver provides an abstraction of the TSPP2 HW functionality for
kernel-space clients. For example, the dvb/demux kernel driver, which provides
an API for upper layers to perform TS de-multiplexing (including PID filtering,
recording, indexing etc.), uses the TSPP2 driver to utilize the TSPP2 HW and
offload the CPU, instead of doing all the required processing in SW.
For further information please refer to Documentation/dvb/qcom-mpq.txt.
Terminology
-----------
This section describes some of the software "objects" implemented by the driver.
a. TSPP2 device: an instance of the TSPP2 device representing the TSPP2 HW and
its capabilities. The client identifies a device instance according to a
device ID.
b. Indexing table: A TSPP2 device contains 4 indexing tables. These tables are
used to identify patterns in the video stream and report on them.
The client identifies an indexing table according to a table ID.
c. Pipe: a BAM pipe used for DMA operations. The TSPP2 HW has a BAM unit with
31 pipes. A pipe contains a memory buffer and a corresponding descriptor ring,
and is used as the output for TSPP2 data (e.g. PES payload, PES headers,
indexing information etc.). For memory inputs, a pipe is used as the input
buffer where data can be written to for TSPP2 processing. BAM Pipes are
managed by the TSPP2 driver using the SPS driver which controls BAM HW. The
client is responsible for buffer memory allocation, and can control many
BAM-related pipe parameters.
d. Source: a source object represents data "stream" from the TS input,
through the filters and operations that perform the processing on the TS data,
until the output. A source has the following properties:
- Either a TSIF or a memory input.
- For memory input: an input pipe.
- Source-related configuration (e.g., packet size and format).
- One or more PID filters. Each filter contains operations.
- One or more output pipes.
The client is responsible to configure the source object as needed using the
appropriate API. The client identifies a source using a source handle, which
the driver provides when opening a source for use.
e. Filter: a filter object represents a PID filter which is used to get only the
TS packets with specific PIDs and filter out all other TS packets in the stream.
The client adds filters to the source object to define the processing of data.
Each filter has a 13-bit PID value and bit-mask, so a filter can be used to
get TS packets with various PID values. Note, however, that it is highly
recommended to use each filter with a unique PID (i.e., 0x1FFF mask), and it is
mandatory that the PIDs handled by each source's filters are mutually exclusive
(i.e., the client must not configure two filters in the same source that handle
the same PID values). A filter has up to 16 operations that instruct the TSPP2
HW how to process the data. The client identifies a filter using a filter
handle, which the driver provides when opening a filter for use.
f. Operation: an operation object represents a basic building block describing
how data is processed. Operations are added to a filter and are performed on
the data received by this filter, in the order they were added. One or more
operations may be required to achieve the desired functionality. For example,
a "section filtering" functionality requires a raw transmit operation, while a
"recording" functionality requires a raw transmit operations as well as an
indexing operation (to support trick modes).
Driver initialization
---------------------
The driver's probe function is invoked if there is a matching device tree node
(or platform device). The probe function gets the required memory resources
(i.e., register address spaces) and maps them to kernel space for the
driver's use. The probe function also request the required IRQs and gets the
TSPP2 IOMMU domain. Finally, the probe function resets all HW registers to
appropriate default values, and resets all the required software structures.
See API description in Interface section.
Usage examples
--------------
Section filtering example - opening a Raw filter with data from TSIF0:
----------------------------------------------------------------------
u32 dev_id = 0;
u32 src_handle;
u32 pipe_handle;
u32 filter_handle;
u32 iova;
u32 vaddress;
struct tspp2_config cfg = {...};
struct tspp2_pipe_config_params pipe_config;
struct tspp2_pipe_pull_mode_params pull_params = {0, 0};
struct tspp2_operation raw_op;
struct sps_event_notify event;
struct sps_iovec desc;
/* Open TSPP2 device for use */
tspp2_device_open(dev_id);
/* Set global configuration */
tspp2_config_set(dev_id, &cfg);
/* Open source with TSIF0 input */
tspp2_src_open(dev_id, TSPP2_INPUT_TSIF0, &src_handle);
/* Set parsing options if needed, for example: */
tspp2_src_parsing_option_set(src_handle,
TSPP2_SRC_PARSING_OPT_CHECK_CONTINUITY, 1);
/* Assume normal sync byte, assume no need for scrambling configuration */
/* Set packet size and format: */
tspp2_src_packet_format_set(src_handle, TSPP2_PACKET_FORMAT_188_RAW);
/* Since this is TSIF input, flow control is in push mode */
/* Allocate memory for output pipe via ION not shown here */
/* Open an output pipe for use */
pipe_config.ion_client = ...
pipe_config.buffer_handle = ...
pipe_config.buffer_size = ...
pipe_config.pipe_mode = TSPP2_SRC_PIPE_OUTPUT;
pipe_config.sps_cfg.descriptor_size = 188;
pipe_config.sps_cfg.setting = (SPS_O_AUTO_ENABLE | SPS_O_HYBRID |
SPS_O_OUT_OF_DESC | SPS_O_ACK_TRANSFERS);
pipe_config.sps_cfg.wakeup_events = SPS_O_OUT_OF_DESC;
pipe_config.sps_cfg.callback = ...
pipe_config.sps_cfg.user_info = ...
tspp2_pipe_open(dev_id, &pipe_config, &iova, &pipe_handle);
/* Attache the pipe to the source */
tspp2_src_pipe_attach(src_handle, pipe_handle, &pull_params);
/* Open a filter for PID 13 */
tspp2_filter_open(src_handle, 13, 0x1FFF, &filter_handle);
/* Add a raw transmit operation */
raw_op.type = TSPP2_OP_RAW_TRANSMIT;
raw_op.params.raw_transmit.input = TSPP2_OP_BUFFER_A;
raw_op.params.raw_transmit.timestamp_mode = TSPP2_OP_TIMESTAMP_NONE;
raw_op.params.raw_transmit.skip_ts_packets_with_errors = 0;
raw_op.params.raw_transmit.output_pipe_handle = pipe_handle;
tspp2_filter_operations_add(filter_handle, &raw_op, 1);
/* Enable filter and source to start getting data */
tspp2_filter_enable(filter_handle);
tspp2_source_enable(src_handle);
/*
* Data path: poll pipe (or get notifications from pipe via
* registered callback).
*/
tspp2_pipe_last_address_used_get(pipe_handle, &vaddress);
/* Process data... */
/* Get and release descriptors: */
tspp2_pipe_descriptor_get(pipe_handle, &desc);
tspp2_pipe_descriptor_put(pipe_handle, desc.addr, desc.size, ...);
/* Teardown: */
tspp2_src_disable(src_handle);
tspp2_filter_disable(filter_handle);
tspp2_filter_close(filter_handle);
tspp2_src_pipe_detach(src_handle, pipe_handle);
tspp2_pipe_close(pipe_handle);
tspp2_src_close(src_handle);
tspp2_device_close(dev_id);
Debug facilities
----------------
The TSPP2 driver supports several debug facilities via debugfs:
a. Ability to read the status of TSIF and TSPP2 HW registers via debugfs.
b. Ability to print HW statistics, error and performance counters via debugfs.
c. Ability to print SW status via debugfs.
Design
======
The TSPP2 driver is a regular Linux platform driver designed to support the
TSPP2 HW available on specific Qualcomm SoCs.
The driver provides an extensive kernel-space API to allow the client full
control over the configuration of the TSPP2 HW, while encapsulating HW
implementation details that are not relevant to the client.
The driver enforces HW restrictions and checks for input parameters
validity, providing a success or failure return value for each API function.
However, the driver does not enforce any high-level policy with regard to the
correct use of the TSPP2 HW for various use-cases.
Power Management
================
The TSPP2 driver prevents the CPU from sleeping while the HW is active by
using the wakeup_source API. When the HW is not active (i.e., no sources
configured), the driver indicates it is ready for system suspend by invoking
__pm_relax(). When the HW needs to be active (i.e., a source has been opened and
enabled), the driver invokes __pm_stay_awake().
In a similar manner, the driver enables the HW clocks only when needed.
The TSPP2 HW manages power saving automatically when the HW is not used.
No SW involvement is required.
SMP/multi-core
==============
The driver uses a mutex for mutual exclusion between kernel API calls.
A spinlock is used to protect accesses to its internal databases which can be
performed both from interrupt handler context and from API context.
Security
========
None.
Performance
===========
Control operations are not considered as performance critical.
Most of the control operations are assumed to be fairly uncommon.
Data-path operations involve only getting descriptors from the pipe and
releasing them back to the pipe for reuse.
Interface
=========
Kernel-space API
----------------
Control path API
-------------------
TSPP2 device open / close API:
------------------------------
int tspp2_device_open(u32 dev_id);
int tspp2_device_close(u32 dev_id);
Global configuration for the TSPP2 device:
------------------------------------------
int tspp2_config_set(u32 dev_id, const struct tspp2_config *cfg);
Set device global configuration.
int tspp2_config_get(u32 dev_id, struct tspp2_config *cfg);
Get current device global configuration.
Configure Indexing Tables:
--------------------------
int tspp2_indexing_prefix_set(u32 dev_id, u8 table_id, u32 value, u32 mask);
Set prefix value and mask of an indexing table.
int tspp2_indexing_patterns_add(u32 dev_id, u8 table_id, const u32 *values,
const u32 *masks, u8 patterns_num);
Add patterns to an indexing table.
int tspp2_indexing_patterns_clear(u32 dev_id, u8 table_id);
Clear all patterns of an indexing table
Opening and closing Pipes:
--------------------------
int tspp2_pipe_open(u32 dev_id, const struct tspp2_pipe_config_params *cfg,
u32 *iova, u32 *pipe_handle);
Open a pipe for use.
int tspp2_pipe_close(u32 pipe_handle);
Close an opened pipe.
Source configuration:
---------------------
int tspp2_src_open(u32 dev_id, enum tspp2_src_input input, u32 *src_handle);
Open a new source for use.
int tspp2_src_close(u32 src_handle);
Close an opened source.
int tspp2_src_parsing_option_set(u32 src_handle,
enum tspp2_src_parsing_option option, int value);
Set source parsing configuration option.
int tspp2_src_parsing_option_get(u32 src_handle,
enum tspp2_src_parsing_option option, int *value);
Get source parsing configuration option.
int tspp2_src_sync_byte_config_set(u32 src_handle, int check_sync_byte,
u8 sync_byte_value);
Set source sync byte configuration.
int tspp2_src_sync_byte_config_get(u32 src_handle, int *check_sync_byte,
u8 *sync_byte_value);
Get source sync byte configuration.
int tspp2_src_scrambling_config_set(u32 src_handle,
const struct tspp2_src_scrambling_config *cfg);
Set source scrambling configuration.
int tspp2_src_scrambling_config_get(u32 src_handle,
struct tspp2_src_scrambling_config *cfg);
Get source scrambling configuration.
int tspp2_src_packet_format_set(u32 src_handle,
enum tspp2_packet_format format);
Set source packet size and format.
int tspp2_src_pipe_attach(u32 src_handle, u32 pipe_handle,
const struct tspp2_pipe_pull_mode_params *cfg);
Attach a pipe to a source.
int tspp2_src_pipe_detach(u32 src_handle, u32 pipe_handle);
Detach a pipe from a source.
int tspp2_src_enable(u32 src_handle);
Enable source (start using it).
int tspp2_src_disable(u32 src_handle);
Disable source (stop using it).
int tspp2_src_filters_clear(u32 src_handle);
Clear all filters from a source.
Filter and Operation configuration:
-----------------------------------
int tspp2_filter_open(u32 src_handle, u16 pid, u16 mask, u32 *filter_handle);
Open a new filter and add it to a source.
int tspp2_filter_close(u32 filter_handle);
Close a filter.
int tspp2_filter_enable(u32 filter_handle);
Enable a filter.
int tspp2_filter_disable(u32 filter_handle);
Disable a filter.
int tspp2_filter_operations_set(u32 filter_handle,
const struct tspp2_operation *ops, u8 operations_num);
Set (add or update) operations to a filter.
int tspp2_filter_operations_clear(u32 filter_handle);
Clear all operations from a filter.
int tspp2_filter_current_scrambling_bits_get(u32 filter_handle,
u8 *scrambling_bits_value);
Get the current scrambling bits.
Events notifications registration:
----------------------------------
int tspp2_global_event_notification_register(u32 dev_id,
u32 global_event_bitmask,
void (*callback)(void *cookie),
void *cookie);
Get notified on a global event.
int tspp2_src_event_notification_register(u32 src_handle,
u32 src_event_bitmask,
void (*callback)(void *cookie),
void *cookie);
Get notified on a source event.
int tspp2_filter_event_notification_register(u32 filter_handle,
u32 filter_event_bitmask,
void (*callback)(void *cookie),
void *cookie);
Get notified on a filter event.
Data path API
----------------
int tspp2_pipe_descriptor_get(u32 pipe_handle, struct sps_iovec *desc);
Get a data descriptor from a pipe.
int tspp2_pipe_descriptor_put(u32 pipe_handle, u32 addr,
u32 size, u32 flags);
Put (release) a descriptor for reuse by the pipe.
int tspp2_pipe_last_address_used_get(u32 pipe_handle, u32 *address);
Get the last address the TSPP2 used.
int tspp2_data_write(u32 src_handle, u32 offset, u32 size);
Write (feed) data to a source.
User-space API
--------------
The TSPP2 driver does not provide any user-space API, only a kernel-space API.
The dvb/demux driver, which utilizes the TSPP2 driver (and HW), provides an
extensive user-space API, allowing upper layers to achieve complex demuxing
functionality.
For further information please refer to Documentation/dvb/qcom-mpq.txt.
Driver parameters
=================
The TSPP2 driver supports the following module parameter:
tspp2_iommu_bypass: Bypass VBIF/IOMMU and use physical buffer addresses
instead. This is mostly useful for debug purposes if something is wrong with
the IOMMU configuration. Default is false.
Platform-dependent parameters (e.g., IRQ numbers) are provided to the driver
via the device tree mechanism or the platform device data mechanism.
Config options
==============
To enable the driver, set CONFIG_TSPP2 to y (built-in) or m (kernel module)
in the kernel configuration menu.
Dependencies
============
a. The TSPP2 driver uses the SPS driver to control the BAM unit.
b. The TSPP2 driver uses the ION driver for IOMMU registration and buffer
mapping. The client is responsible to allocate memory buffers via ION.
User space utilities
====================
None.
Other
=====
None.
Known issues
============
None.
To do
=====
None.