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

Commit c145aa4b authored by qctecmdr's avatar qctecmdr Committed by Gerrit - the friendly Code Review server
Browse files

Merge "drivers: soc: qcom: Port bam dmux driver"

parents 58b51962 f1870b71
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -904,6 +904,16 @@ config QTI_CRYPTO_TZ
	 performing hardware based file encryption. This means keys are
	 programmed and managed through SCM calls to TZ where ICE driver
	 will configure keys.

config MSM_BAM_DMUX
	bool "BAM Data Mux Driver"
	depends on SPS
	help
	 Support Muxed Data Channels over BAM interface.
	 BAM has a limited number of pipes.  This driver
	 provides a means to support more logical channels
	 via muxing than BAM could without muxing.

endmenu

config QCOM_HYP_CORE_CTL
+1 −0
Original line number Diff line number Diff line
@@ -107,3 +107,4 @@ obj-$(CONFIG_QTI_CRYPTO_COMMON) += crypto-qti-common.o
obj-$(CONFIG_QTI_CRYPTO_TZ) += crypto-qti-tz.o
obj-$(CONFIG_QTI_HW_KEY_MANAGER) += hwkm_qti.o
hwkm_qti-y += hwkm.o
obj-$(CONFIG_MSM_BAM_DMUX) += bam_dmux.o
+2889 −0

File added.

Preview size limit exceeded, changes collapsed.

+193 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2013-2014, 2019 The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * 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.
 */

#ifndef _BAM_DMUX_PRIVATE_H
#define _BAM_DMUX_PRIVATE_H

#include <linux/types.h>
#include <linux/dma-mapping.h>

#include <linux/msm-sps.h>
#include <linux/soc/qcom/smem_state.h>

#define BAM_MUX_HDR_MAGIC_NO			0x33fc
#define BAM_MUX_HDR_CMD_DATA			0
#define BAM_MUX_HDR_CMD_OPEN			1
#define BAM_MUX_HDR_CMD_CLOSE			2
#define BAM_MUX_HDR_CMD_STATUS			3 /* unused */
#define BAM_MUX_HDR_CMD_OPEN_NO_A2_PC		4
#define DEFAULT_BUFFER_SIZE			SZ_2K

#define DYNAMIC_MTU_MASK			0x2
#define MTU_SIZE_MASK				0xc0
#define MTU_SIZE_SHIFT				0x6
#define DL_POOL_SIZE_SHIFT			0x4

/**
 * struct bam_ops_if - collection of function pointers to allow swappable
 * runtime functionality
 * @smsm_change_state_ptr: pointer to smsm_change_state function
 * @smsm_get_state_ptr: pointer to smsm_get_state function
 * @smsm_state_cb_register_ptr: pointer to smsm_state_cb_register function
 * @smsm_state_cb_deregister_ptr: pointer to smsm_state_cb_deregister function
 * @sps_connect_ptr: pointer to sps_connect function
 * @sps_disconnect_ptr: pointer to sps_disconnect function
 * @sps_register_bam_device_ptr: pointer to sps_register_bam_device
 * @sps_deregister_bam_device_ptr: pointer to sps_deregister_bam_device
 * function
 * @sps_alloc_endpoint_ptr: pointer to sps_alloc_endpoint function
 * @sps_free_endpoint_ptr: pointer to sps_free_endpoint function
 * @sps_set_config_ptr: pointer to sps_set_config function
 * @sps_get_config_ptr: pointer to sps_get_config function
 * @sps_device_reset_ptr: pointer to sps_device_reset function
 * @sps_register_event_ptr: pointer to sps_register_event function
 * @sps_transfer_one_ptr: pointer to sps_transfer_one function
 * @sps_get_iovec_ptr: pointer to sps_get_iovec function
 * @sps_get_unused_desc_num_ptr: pointer to sps_get_unused_desc_num function
 * @dma_to: enum for the direction of dma operations to device
 * @dma_from: enum for the direction of dma operations from device
 *
 * This struct contains the interface from bam_dmux to smsm and sps. The
 * pointers can be swapped out at run time to provide different functionality.
 */
struct bam_ops_if {
	/* smsm */
	int (*smsm_change_state_ptr)(struct qcom_smem_state *state, u32 mask,
		u32 value);

	struct qcom_smem_state *(*smsm_get_state_ptr)(struct device *dev,
		const char *con_id, unsigned int *bit);

	struct qcom_smem_state *(*smsm_state_cb_register_ptr)(
		struct device_node *of_node,
		const struct qcom_smem_state_ops *ops, void *priv);

	void (*smsm_state_cb_deregister_ptr)(struct qcom_smem_state *state);

	/* sps */
	int (*sps_connect_ptr)(struct sps_pipe *h, struct sps_connect *connect);

	int (*sps_disconnect_ptr)(struct sps_pipe *h);

	int (*sps_register_bam_device_ptr)(
		const struct sps_bam_props *bam_props,
		unsigned long *dev_handle);

	int (*sps_deregister_bam_device_ptr)(unsigned long dev_handle);

	struct sps_pipe *(*sps_alloc_endpoint_ptr)(void);

	int (*sps_free_endpoint_ptr)(struct sps_pipe *h);

	int (*sps_set_config_ptr)(struct sps_pipe *h,
		struct sps_connect *config);

	int (*sps_get_config_ptr)(struct sps_pipe *h,
		struct sps_connect *config);

	int (*sps_device_reset_ptr)(unsigned long dev);

	int (*sps_register_event_ptr)(struct sps_pipe *h,
		struct sps_register_event *reg);

	int (*sps_transfer_one_ptr)(struct sps_pipe *h,
		phys_addr_t addr, u32 size,
		void *user, u32 flags);

	int (*sps_get_iovec_ptr)(struct sps_pipe *h,
		struct sps_iovec *iovec);

	int (*sps_get_unused_desc_num_ptr)(struct sps_pipe *h,
		u32 *desc_num);

	enum dma_data_direction dma_to;

	enum dma_data_direction dma_from;


	struct device_node *node;

	u32 *smem_state;

	void *pwr_state;

	void *pwr_ack_state;
};

/**
 * struct bam_mux_hdr - struct which contains bam dmux header info
 * @magic_num: magic number placed at start to ensure that it is actually a
 * valid bam dmux header
 * @signal: optional signaling bits with commmand type specific definitions
 * @cmd: the command
 * @pad_len: the length of padding
 * @ch_id: the id of the bam dmux channel that this is sent on
 * @pkt_len: the length of the packet that this is the header of
 */
struct bam_mux_hdr {
	uint16_t magic_num;
	uint8_t signal;
	uint8_t cmd;
	uint8_t pad_len;
	uint8_t ch_id;
	uint16_t pkt_len;
};

/**
 * struct rx_pkt_info - struct describing an rx packet
 * @skb: socket buffer containing the packet
 * @dma_address: dma mapped address of the packet
 * @work: work_struct for processing the packet
 * @list_node: list_head for placing this on a list
 * @sps_size: size of the sps_iovec for this packet
 * @len: total length of the buffer containing this packet
 */
struct rx_pkt_info {
	struct sk_buff *skb;
	dma_addr_t dma_address;
	struct work_struct work;
	struct list_head list_node;
	uint16_t sps_size;
	uint16_t len;
};

/**
 * struct tx_pkt_info - struct describing a tx packet
 * @skb: socket buffer containing the packet
 * @dma_address: dma mapped address of the packet
 * @is_cmd: signifies whether this is a command or data packet
 * @len: length og the packet
 * @work: work_struct for processing this packet
 * @list_node: list_head for placing this on a list
 * @ts_sec: seconds portion of the timestamp
 * @ts_nsec: nanoseconds portion of the timestamp
 *
 */
struct tx_pkt_info {
	struct sk_buff *skb;
	dma_addr_t dma_address;
	char is_cmd;
	uint32_t len;
	struct work_struct work;
	struct list_head list_node;
	unsigned int ts_sec;
	unsigned long ts_nsec;
};

void msm_bam_dmux_set_bam_ops(struct bam_ops_if *ops);

void msm_bam_dmux_deinit(void);

void msm_bam_dmux_reinit(void);

#endif /* _BAM_DMUX_PRIVATE_H */
+139 −0
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/* Copyright (c) 2011-2012, 2014, 2019 The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * 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.
 */

#include <linux/types.h>
#include <linux/skbuff.h>

#ifndef _BAM_DMUX_H
#define _BAM_DMUX_H

#define BAM_DMUX_CH_NAME_MAX_LEN	20

enum {
	BAM_DMUX_DATA_RMNET_0,
	BAM_DMUX_DATA_RMNET_1,
	BAM_DMUX_DATA_RMNET_2,
	BAM_DMUX_DATA_RMNET_3,
	BAM_DMUX_DATA_RMNET_4,
	BAM_DMUX_DATA_RMNET_5,
	BAM_DMUX_DATA_RMNET_6,
	BAM_DMUX_DATA_RMNET_7,
	BAM_DMUX_USB_RMNET_0,
	BAM_DMUX_RESERVED_0, /* 9..11 are reserved*/
	BAM_DMUX_RESERVED_1,
	BAM_DMUX_RESERVED_2,
	BAM_DMUX_DATA_REV_RMNET_0,
	BAM_DMUX_DATA_REV_RMNET_1,
	BAM_DMUX_DATA_REV_RMNET_2,
	BAM_DMUX_DATA_REV_RMNET_3,
	BAM_DMUX_DATA_REV_RMNET_4,
	BAM_DMUX_DATA_REV_RMNET_5,
	BAM_DMUX_DATA_REV_RMNET_6,
	BAM_DMUX_DATA_REV_RMNET_7,
	BAM_DMUX_DATA_REV_RMNET_8,
	BAM_DMUX_USB_DPL,
	BAM_DMUX_NUM_CHANNELS
};

/* event type enum */
enum {
	BAM_DMUX_RECEIVE, /* data is struct sk_buff */
	BAM_DMUX_WRITE_DONE, /* data is struct sk_buff */
	BAM_DMUX_UL_CONNECTED, /* data is null */
	BAM_DMUX_UL_DISCONNECTED, /*data is null */
	BAM_DMUX_TRANSMIT_SIZE, /* data is maximum negotiated transmit MTU */
};

/*
 * Open a bam_dmux logical channel
 *     id - the logical channel to open
 *     priv - private data pointer to be passed to the notify callback
 *     notify - event callback function
 *          priv - private data pointer passed to msm_bam_dmux_open()
 *          event_type - type of event
 *          data - data relevant to event.  May not be valid. See event_type
 *                    enum for valid cases.
 */
#ifdef CONFIG_MSM_BAM_DMUX
int msm_bam_dmux_open(uint32_t id, void *priv,
		       void (*notify)(void *priv, int event_type,
						unsigned long data));

int msm_bam_dmux_close(uint32_t id);

int msm_bam_dmux_write(uint32_t id, struct sk_buff *skb);

int msm_bam_dmux_kickoff_ul_wakeup(void);

int msm_bam_dmux_ul_power_vote(void);

int msm_bam_dmux_ul_power_unvote(void);

int msm_bam_dmux_is_ch_full(uint32_t id);

int msm_bam_dmux_is_ch_low(uint32_t id);

int msm_bam_dmux_reg_notify(void *priv,
		       void (*notify)(void *priv, int event_type,
						unsigned long data));
#else
static inline int msm_bam_dmux_open(uint32_t id, void *priv,
		       void (*notify)(void *priv, int event_type,
						unsigned long data))
{
	return -ENODEV;
}

static inline int msm_bam_dmux_close(uint32_t id)
{
	return -ENODEV;
}

static inline int msm_bam_dmux_write(uint32_t id, struct sk_buff *skb)
{
	return -ENODEV;
}

static inline int msm_bam_dmux_kickoff_ul_wakeup(void)
{
	return -ENODEV;
}

static inline int msm_bam_dmux_ul_power_vote(void)
{
	return -ENODEV;
}

static inline int msm_bam_dmux_ul_power_unvote(void)
{
	return -ENODEV;
}

static inline int msm_bam_dmux_is_ch_full(uint32_t id)
{
	return -ENODEV;
}

static inline int msm_bam_dmux_is_ch_low(uint32_t id)
{
	return -ENODEV;
}

static inline int msm_bam_dmux_reg_notify(void *priv,
		       void (*notify)(void *priv, int event_type,
						unsigned long data))
{
	return -ENODEV;
}
#endif
#endif /* _BAM_DMUX_H */