Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit fd1296ba authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "Migrate mpq demux driver from kernel 4.4 to 4.9"

parents 0db3f6d4 ba29a3e8
Loading
Loading
Loading
Loading
+82 −0
Original line number Diff line number Diff line
* TSPP ( QTI Transport Stream Packet Processor )

Hardware driver for QTI TSIF 12seg wrapper core, which consists of a TSPP, a
BAM (Bus access manager, used for DMA) and two TSIF inputs.

The TSPP driver is responsible for:
 - TSPP/TSIF hardware configuration (using SPS driver to configure BAM hardware)
 - TSIF GPIO/Clocks configuration
 - Memory resource management
 - Handling TSIF/TSPP interrupts and BAM events
 - TSPP Power management

Required properties:
- compatible : Should be "qcom,msm_tspp"
- reg : Specifies the base physical addresses and sizes of TSIF, TSPP & BAM registers.
- reg-names : Specifies the register names of TSIF, TSPP & BAM base registers.
- interrupts : Specifies the interrupts associated with TSIF 12 seg core.
- interrupt-names: Specifies interrupt names for TSIF, TSPP & BAM interrupts.
- clock-names: Specifies the clock names used for interface & reference clocks.
- clocks: GCC_TSIF_AHB_CLK clock for interface clock & GCC_TSIF_REF_CLK clock for reference clock.
- qcom, msm_bus,name: Should be "tsif"
- qcom, msm_bus,num_cases: Depends on the use cases for bus scaling
- qcom, msm_bus,num_paths: The paths for source and destination ports
- qcom, msm_bus,vectors: Vectors for bus topology.
- pinctrl-names: Names for the TSIF mode configuration to specify which TSIF interface is active.

Optional properties:
  - qcom,lpass-timer-tts : Indicates to add time stamps to TS packets from LPASS timer.
                           bydefault time stamps will be added from TFIS internal counter.

Example:

        tspp: msm_tspp@0x8880000 {
                compatible = "qcom,msm_tspp";
                reg = <0x088a7000 0x200>, /* MSM_TSIF0_PHYS */
                      <0x088a8000 0x200>, /* MSM_TSIF1_PHYS */
                      <0x088a9000 0x1000>, /* MSM_TSPP_PHYS  */
                      <0x08884000 0x23000>; /* MSM_TSPP_BAM_PHYS */
                reg-names = "MSM_TSIF0_PHYS",
                        "MSM_TSIF1_PHYS",
                        "MSM_TSPP_PHYS",
                        "MSM_TSPP_BAM_PHYS";
                interrupts = <0 121 0>, /* TSIF_TSPP_IRQ */
                        <0 119 0>, /* TSIF0_IRQ */
                        <0 120 0>, /* TSIF1_IRQ */
                        <0 122 0>; /* TSIF_BAM_IRQ */
                interrupt-names = "TSIF_TSPP_IRQ",
                        "TSIF0_IRQ",
                        "TSIF1_IRQ",
                        "TSIF_BAM_IRQ";

                clock-names = "iface_clk", "ref_clk";
                clocks = <&clock_gcc GCC_TSIF_AHB_CLK>,
                        <&clock_gcc GCC_TSIF_REF_CLK>;

                qcom,msm-bus,name = "tsif";
                qcom,msm-bus,num-cases = <2>;
                qcom,msm-bus,num-paths = <1>;
                qcom,msm-bus,vectors-KBps =
                                <82 512 0 0>, /* No vote */
                                <82 512 12288 24576>;
                                /* Max. bandwidth, 2xTSIF, each max of 96Mbps */

                pinctrl-names = "disabled",
                        "tsif0-mode1", "tsif0-mode2",
                        "tsif1-mode1", "tsif1-mode2",
                        "dual-tsif-mode1", "dual-tsif-mode2";

                pinctrl-0 = <>;                         /* disabled */
                pinctrl-1 = <&tsif0_signals_active>;    /* tsif0-mode1 */
                pinctrl-2 = <&tsif0_signals_active
                        &tsif0_sync_active>;            /* tsif0-mode2 */
                pinctrl-3 = <&tsif1_signals_active>;    /* tsif1-mode1 */
                pinctrl-4 = <&tsif1_signals_active
                        &tsif1_sync_active>;            /* tsif1-mode2 */
                pinctrl-5 = <&tsif0_signals_active
                        &tsif1_signals_active>;         /* dual-tsif-mode1 */
                pinctrl-6 = <&tsif0_signals_active
                        &tsif0_sync_active
                        &tsif1_signals_active
                        &tsif1_sync_active>;            /* dual-tsif-mode2 */
        };
+215 −9
Original line number Diff line number Diff line
@@ -40,6 +40,8 @@
 * Common definitions
 */

#define DMX_EVENT_QUEUE_SIZE 500 /* number of events */

/*
 * DMX_MAX_FILTER_SIZE: Maximum length (in bytes) of a section/PES filter.
 */
@@ -60,6 +62,104 @@
#define DMX_MAX_SECFEED_SIZE (DMX_MAX_SECTION_SIZE + 188)
#endif

/*
 * enum dmx_success: Success codes for the Demux Callback API.
 */
enum dmx_success {
	DMX_OK = 0, /* Received Ok */
	DMX_OK_PES_END, /* Received OK, data reached end of PES packet */
	DMX_OK_PCR, /* Received OK, data with new PCR/STC pair */
	DMX_OK_EOS, /* Received OK, reached End-of-Stream (EOS) */
	DMX_OK_MARKER, /* Received OK, reached a data Marker */
	DMX_LENGTH_ERROR, /* Incorrect length */
	DMX_OVERRUN_ERROR, /* Receiver ring buffer overrun */
	DMX_CRC_ERROR, /* Incorrect CRC */
	DMX_FRAME_ERROR, /* Frame alignment error */
	DMX_FIFO_ERROR, /* Receiver FIFO overrun */
	DMX_MISSED_ERROR, /* Receiver missed packet */
	DMX_OK_DECODER_BUF, /* Received OK, new ES data in decoder buffer */
	DMX_OK_IDX, /* Received OK, new index event */
	DMX_OK_SCRAMBLING_STATUS, /* Received OK, new scrambling status */
};


/*
 * struct dmx_data_ready: Parameters for event notification callback.
 * Event notification notifies demux device that data is written
 * and available in the device's output buffer or provides
 * notification on errors and other events. In the latter case
 * data_length is zero.
 */
struct dmx_data_ready {
	enum dmx_success status;

	/*
	 * data_length may be 0 in case of DMX_OK_PES_END or DMX_OK_EOS
	 * and in non-DMX_OK_XXX events. In DMX_OK_PES_END,
	 * data_length is for data coming after the end of PES.
	 */
	int data_length;

	union {
		struct {
			int start_gap;
			int actual_length;
			int disc_indicator_set;
			int pes_length_mismatch;
			u64 stc;
			u32 tei_counter;
			u32 cont_err_counter;
			u32 ts_packets_num;
		} pes_end;

		struct {
			u64 pcr;
			u64 stc;
			int disc_indicator_set;
		} pcr;

		struct {
			int handle;
			int cookie;
			u32 offset;
			u32 len;
			int pts_exists;
			u64 pts;
			int dts_exists;
			u64 dts;
			u32 tei_counter;
			u32 cont_err_counter;
			u32 ts_packets_num;
			u32 ts_dropped_bytes;
			u64 stc;
		} buf;

		struct {
			u64 id;
		} marker;

		struct dmx_index_event_info idx_event;
		struct dmx_scrambling_status_event_info scrambling_bits;
	};
};

/*
 * struct data_buffer: Parameters of buffer allocated by
 * demux device for input/output. Can be used to directly map the
 * demux-device buffer to HW output if HW supports it.
 */
struct data_buffer {
	/* dvb_ringbuffer managed by demux-device */
	const struct dvb_ringbuffer *ringbuff;


	/*
	 * Private handle returned by kernel demux when
	 * map_buffer is called in case external buffer
	 * is used. NULL if buffer is allocated internally.
	 */
	void *priv_handle;
};
/*
 * TS packet reception
 */
@@ -95,10 +195,18 @@ enum ts_filter_type {
 * Using this API, the client can set the filtering properties to start/stop
 * filtering TS packets on a particular TS feed.
 */
struct dmx_ts_feed;

typedef int (*dmx_ts_data_ready_cb)(
		struct dmx_ts_feed *source,
		struct dmx_data_ready *dmx_data_ready);

struct dmx_ts_feed {
	int is_filtering;
	struct dmx_demux *parent;
	struct data_buffer buffer;
	void *priv;
	struct dmx_decoder_buffers *decoder_buffers;
	int (*set)(struct dmx_ts_feed *feed,
		   u16 pid,
		   int type,
@@ -107,6 +215,34 @@ struct dmx_ts_feed {
		   ktime_t timeout);
	int (*start_filtering)(struct dmx_ts_feed *feed);
	int (*stop_filtering)(struct dmx_ts_feed *feed);
	int (*set_video_codec)(struct dmx_ts_feed *feed,
				enum dmx_video_codec video_codec);
	int (*set_idx_params)(struct dmx_ts_feed *feed,
				struct dmx_indexing_params *idx_params);
	int (*get_decoder_buff_status)(
			struct dmx_ts_feed *feed,
			struct dmx_buffer_status *dmx_buffer_status);
	int (*reuse_decoder_buffer)(
			struct dmx_ts_feed *feed,
			int cookie);
	int (*data_ready_cb)(struct dmx_ts_feed *feed,
			dmx_ts_data_ready_cb callback);
	int (*notify_data_read)(struct dmx_ts_feed *feed,
			u32 bytes_num);
	int (*set_tsp_out_format)(struct dmx_ts_feed *feed,
				enum dmx_tsp_format_t tsp_format);
	int (*set_secure_mode)(struct dmx_ts_feed *feed,
				struct dmx_secure_mode *sec_mode);
	int (*set_cipher_ops)(struct dmx_ts_feed *feed,
				struct dmx_cipher_operations *cipher_ops);
	int (*oob_command)(struct dmx_ts_feed *feed,
			struct dmx_oob_command *cmd);
	int (*ts_insertion_init)(struct dmx_ts_feed *feed);
	int (*ts_insertion_terminate)(struct dmx_ts_feed *feed);
	int (*ts_insertion_insert_buffer)(struct dmx_ts_feed *feed,
			char *data, size_t size);
	int (*get_scrambling_bits)(struct dmx_ts_feed *feed, u8 *value);
	int (*flush_buffer)(struct dmx_ts_feed *feed, size_t length);
};

/*
@@ -131,14 +267,21 @@ struct dmx_ts_feed {
 * corresponding bits are compared. The filter only accepts sections that are
 * equal to filter_value in all the tested bit positions.
 */

struct dmx_section_feed;
struct dmx_section_filter {
	u8 filter_value[DMX_MAX_FILTER_SIZE];
	u8 filter_mask[DMX_MAX_FILTER_SIZE];
	u8 filter_mode[DMX_MAX_FILTER_SIZE];
	struct dmx_section_feed *parent; /* Back-pointer */
	struct data_buffer buffer;
	void *priv; /* Pointer to private data of the API client */
};

typedef int (*dmx_section_data_ready_cb)(
		struct dmx_section_filter *source,
		struct dmx_data_ready *dmx_data_ready);

/**
 * struct dmx_section_feed - Structure that contains a section feed filter
 *
@@ -189,8 +332,24 @@ struct dmx_section_feed {
			      struct dmx_section_filter *filter);
	int (*start_filtering)(struct dmx_section_feed *feed);
	int (*stop_filtering)(struct dmx_section_feed *feed);
	int (*data_ready_cb)(struct dmx_section_feed *feed,
			dmx_section_data_ready_cb callback);
	int (*notify_data_read)(struct dmx_section_filter *filter,
			u32 bytes_num);
	int (*set_secure_mode)(struct dmx_section_feed *feed,
				struct dmx_secure_mode *sec_mode);
	int (*set_cipher_ops)(struct dmx_section_feed *feed,
				struct dmx_cipher_operations *cipher_ops);
	int (*oob_command)(struct dmx_section_feed *feed,
				struct dmx_oob_command *cmd);
	int (*get_scrambling_bits)(struct dmx_section_feed *feed, u8 *value);
	int (*flush_buffer)(struct dmx_section_feed *feed, size_t length);
};

/*
 * Callback functions
 */

/**
 * typedef dmx_ts_cb - DVB demux TS filter callback function prototype
 *
@@ -295,9 +454,19 @@ typedef int (*dmx_section_cb)(const u8 *buffer1,
			      size_t buffer2_len,
			      struct dmx_section_filter *source);

/*
 * DVB Front-End
 */
typedef int (*dmx_ts_fullness) (
				struct dmx_ts_feed *source,
				int required_space,
				int wait);

typedef int (*dmx_section_fullness) (
				struct dmx_section_filter *source,
				int required_space,
				int wait);

/*--------------------------------------------------------------------------*/
/* DVB Front-End */
/*--------------------------------------------------------------------------*/

/**
 * enum dmx_frontend_source - Used to identify the type of frontend
@@ -312,6 +481,13 @@ typedef int (*dmx_section_cb)(const u8 *buffer1,
enum dmx_frontend_source {
	DMX_MEMORY_FE,
	DMX_FRONTEND_0,
	DMX_FRONTEND_1,
	DMX_FRONTEND_2,
	DMX_FRONTEND_3,
	DMX_STREAM_0,    /* external stream input, e.g. LVDS */
	DMX_STREAM_1,
	DMX_STREAM_2,
	DMX_STREAM_3
};

/**
@@ -345,14 +521,24 @@ struct dmx_frontend {
 */
enum dmx_demux_caps {
	DMX_TS_FILTERING = 1,
	DMX_PES_FILTERING = 2,
	DMX_SECTION_FILTERING = 4,
	DMX_MEMORY_BASED_FILTERING = 8,
	DMX_CRC_CHECKING = 16,
	DMX_TS_DESCRAMBLING = 32
};

/*
 * Demux resource type identifier.
 */

/*
 * DMX_FE_ENTRY(): Casts elements in the list of registered
 * front-ends from the generic type struct list_head
 * to the type * struct dmx_frontend.
 *
 */

/**
 * DMX_FE_ENTRY - Casts elements in the list of registered
 *		  front-ends from the generic type struct list_head
@@ -557,6 +743,10 @@ struct dmx_demux {
	enum dmx_demux_caps capabilities;
	struct dmx_frontend *frontend;
	void *priv;
	struct data_buffer dvr_input; /* DVR input buffer */
	int dvr_input_protected;
	struct dentry *debugfs_demux_dir; /* debugfs dir */

	int (*open)(struct dmx_demux *demux);
	int (*close)(struct dmx_demux *demux);
	int (*write)(struct dmx_demux *demux, const char __user *buf,
@@ -582,15 +772,31 @@ struct dmx_demux {

	int (*get_pes_pids)(struct dmx_demux *demux, u16 *pids);

	/* private: */
	int (*get_caps)(struct dmx_demux *demux, struct dmx_caps *caps);

	int (*set_source)(struct dmx_demux *demux, const dmx_source_t *src);

	int (*set_tsp_format)(struct dmx_demux *demux,
				enum dmx_tsp_format_t tsp_format);

	int (*set_playback_mode)(struct dmx_demux *demux,
				 enum dmx_playback_mode_t mode,
				 dmx_ts_fullness ts_fullness_callback,
				 dmx_section_fullness sec_fullness_callback);

	int (*write_cancel)(struct dmx_demux *demux);

	/*
	 * Only used at av7110, to read some data from firmware.
	 * As this was never documented, we have no clue about what's
	 * there, and its usage on other drivers aren't encouraged.
	 */
	int (*get_stc)(struct dmx_demux *demux, unsigned int num,
		       u64 *stc, unsigned int *base);

	int (*map_buffer)(struct dmx_demux *demux,
			struct dmx_buffer *dmx_buffer,
			void **priv_handle, void **mem);

	int (*unmap_buffer)(struct dmx_demux *demux,
			void *priv_handle);

	int (*get_tsp_size)(struct dmx_demux *demux);
};

#endif /* #ifndef __DEMUX_H */
Loading