mirror of
https://github.com/team-infusion-developers/android_kernel_samsung_msm8976.git
synced 2024-11-01 10:33:27 +00:00
b4ff705d27
Add support to enable and disable the power regulator and relevant clocks that the TSPP2 HW unit requires. Change-Id: I29cbb9df6267c44f94bfeef6558e206b2b162248 Signed-off-by: Liron Kuch <lkuch@codeaurora.org>
497 lines
19 KiB
Text
497 lines
19 KiB
Text
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.
|