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

Commit b5e70193 authored by Manoj Prabhu B's avatar Manoj Prabhu B Committed by Gerrit - the friendly Code Review server
Browse files

diag: Query and configure hardware acceleration



Support to query the peripherals support for different
acceleration types and version through IOCTL is added.
PASSTHRU packets configuring hardware acceleration through
its type and version is formulated and broadcasted to
peripherals by diag id masks.

Change-Id: Ieb566302598ea84e68171945fe278f748d1541a2
Signed-off-by: default avatarManoj Prabhu B <bmanoj@codeaurora.org>
parent af96f07f
Loading
Loading
Loading
Loading
+116 −0
Original line number Diff line number Diff line
@@ -327,6 +327,40 @@ do { \

#define DIAGID_V2_FEATURE_COUNT 3

/*
 * HW Acceleration operation definition
 */
#define DIAG_HW_ACCEL_OP_DISABLE	0
#define DIAG_HW_ACCEL_OP_ENABLE	1
#define DIAG_HW_ACCEL_OP_QUERY	2

/*
 * HW Acceleration TYPE definition
 */
#define DIAG_HW_ACCEL_TYPE_ALL	0
#define DIAG_HW_ACCEL_TYPE_STM	1
#define DIAG_HW_ACCEL_TYPE_ATB	2
#define DIAG_HW_ACCEL_TYPE_MAX	2

#define DIAG_HW_ACCEL_VER_MIN 1
#define DIAG_HW_ACCEL_VER_MAX 1

/*
 * HW Acceleration CMD Error codes
 */
#define DIAG_HW_ACCEL_STATUS_SUCCESS	0
#define DIAG_HW_ACCEL_FAIL	1
#define DIAG_HW_ACCEL_INVALID_TYPE	2
#define DIAG_HW_ACCEL_INVALID_VER	3

/*
 * HW Acceleration Transport types
 */
#define DIAG_TRANSPORT_UNKNOWN 0
#define DIAG_TRANSPORT_UART    1
#define DIAG_TRANSPORT_USB     2
#define DIAG_TRANSPORT_PCIE    3

/* List of remote processor supported */
enum remote_procs {
	MDM = 1,
@@ -348,6 +382,86 @@ struct diag_cmd_ext_mobile_rsp_t {
	uint32_t chip_id;
} __packed;

/*
 * hw acceleration command request payload structure
 */
struct diag_hw_accel_op_t {
	uint8_t hw_accel_type;
	uint8_t hw_accel_ver;
	uint32_t diagid_mask;
} __packed;

/*
 * hw acceleration command request structure
 */

struct diag_hw_accel_cmd_req_t {
	struct diag_pkt_header_t header;
	uint8_t version;
	uint8_t operation;
	uint16_t reserved;
	struct diag_hw_accel_op_t op_req;
} __packed;

/*
 * hw acceleration command response payload structure
 */

struct diag_hw_accel_op_resp_payload_t {
	uint8_t status;
	uint8_t hw_accel_type;
	uint8_t hw_accel_ver;
	uint32_t diagid_status;
} __packed;

/*
 * hw acceleration command op response structure
 */

struct diag_hw_accel_cmd_op_resp_t {
	struct diag_pkt_header_t header;
	uint8_t version;
	uint8_t operation;
	uint16_t reserved;
	struct diag_hw_accel_op_resp_payload_t op_rsp;
} __packed;

/*
 * hw acceleration query response sub payload
 * in mulitples of the num_accel_rsp
 */

struct diag_hw_accel_query_sub_payload_rsp_t {
	uint8_t hw_accel_type;
	uint8_t hw_accel_ver;
	uint32_t diagid_mask_supported;
	uint32_t diagid_mask_enabled;
} __packed;

/*
 * hw acceleration query operation response payload structure
 */

struct diag_hw_accel_query_rsp_payload_t {
	uint8_t status;
	uint8_t diag_transport;
	uint8_t num_accel_rsp;
	struct diag_hw_accel_query_sub_payload_rsp_t
		sub_query_rsp[DIAG_HW_ACCEL_TYPE_MAX][DIAG_HW_ACCEL_VER_MAX];
} __packed;

/*
 * hw acceleration command query response structure
 */

struct diag_hw_accel_cmd_query_resp_t {
	struct diag_pkt_header_t header;
	uint8_t version;
	uint8_t operation;
	uint16_t reserved;
	struct diag_hw_accel_query_rsp_payload_t query_rsp;
} __packed;

struct diag_cmd_diag_id_query_req_t {
	struct diag_pkt_header_t header;
	uint8_t version;
@@ -361,6 +475,7 @@ struct diag_id_tbl_t {
	uint8_t pd_feature_mask;
	char *process_name;
} __packed;

struct diag_id_t {
	uint8_t diag_id;
	uint8_t len;
@@ -801,5 +916,6 @@ void diag_record_stats(int type, int flag);
struct diag_md_session_t *diag_md_session_get_pid(int pid);
struct diag_md_session_t *diag_md_session_get_peripheral(uint8_t peripheral);
int diag_md_session_match_pid_peripheral(int pid, uint8_t peripheral);
int diag_map_hw_accel_type_ver(uint8_t hw_accel_type, uint8_t hw_accel_ver);

#endif
+116 −0
Original line number Diff line number Diff line
@@ -2359,6 +2359,69 @@ static int diag_ioctl_query_pd_logging(struct diag_logging_mode_param_t *param)
	return ret;
}

int diag_map_hw_accel_type_ver(
	uint8_t hw_accel_type, uint8_t hw_accel_ver)
{
	int index = -EINVAL;

	if (hw_accel_ver == DIAG_HW_ACCEL_VER_MIN) {
		switch (hw_accel_type) {
		case DIAG_HW_ACCEL_TYPE_STM:
			index = DIAG_HW_ACCEL_TYPE_STM;
			break;
		case DIAG_HW_ACCEL_TYPE_ATB:
			index = DIAG_HW_ACCEL_TYPE_ATB;
			break;
		default:
			index = -EINVAL;
			break;
		}
	}
	return index;
}

static int diag_ioctl_query_pd_featuremask(
	struct diag_hw_accel_query_sub_payload_rsp_t *query_params)
{
	int f_index = -1;

	if (!query_params)
		return -EINVAL;

	if (query_params->hw_accel_type > DIAG_HW_ACCEL_TYPE_MAX ||
		query_params->hw_accel_ver > DIAG_HW_ACCEL_VER_MAX) {
		DIAG_LOG(DIAG_DEBUG_USERSPACE, "Invalid parameters\n");
		return -EINVAL;
	}

	mutex_lock(&driver->diagid_v2_mutex);

	f_index = diag_map_hw_accel_type_ver(query_params->hw_accel_type,
				query_params->hw_accel_ver);
	if (f_index < 0) {
		DIAG_LOG(DIAG_DEBUG_USERSPACE, "Invalid feature index\n");
		query_params->diagid_mask_supported = 0;
		query_params->diagid_mask_enabled = 0;
	} else {
		query_params->diagid_mask_supported = DIAGIDV2_FEATURE(f_index);
		query_params->diagid_mask_enabled = DIAGIDV2_STATUS(f_index);
		DIAG_LOG(DIAG_DEBUG_USERSPACE,
		"HW acceleration: type: %d, ver:%d, supported diagid mask: %d, enabled diagid mask: %d\n",
		query_params->hw_accel_type,
		query_params->hw_accel_ver,
		query_params->diagid_mask_supported,
		query_params->diagid_mask_enabled);
	}
	mutex_unlock(&driver->diagid_v2_mutex);
	return 0;
}

static int diag_ioctl_passthru_control_func(
	struct diag_hw_accel_cmd_req_t *req_params)
{
	return diag_send_passtru_ctrl_pkt(req_params);
}

static void diag_ioctl_query_session_pid(struct diag_query_pid_t *param)
{
	int prev_pid = 0, test_pid = 0, i = 0, count = 0;
@@ -2735,6 +2798,53 @@ static long diagchar_ioctl_mdlog(struct file *filp,
	return result;
}

static long diagchar_ioctl_hw_accel(struct file *filp,
			   unsigned int iocmd, unsigned long ioarg)
{
	int result = -EINVAL;
	struct diag_hw_accel_query_sub_payload_rsp_t query_params;
	struct diag_hw_accel_cmd_req_t req_params;

	switch (iocmd) {
	case DIAG_IOCTL_QUERY_PD_FEATUREMASK:
		if (copy_from_user((void *)&query_params, (void __user *)ioarg,
			sizeof(struct diag_hw_accel_query_sub_payload_rsp_t))) {
			result = -EFAULT;
			break;
		}
		result = diag_ioctl_query_pd_featuremask(&query_params);
		if (result) {
			DIAG_LOG(DIAG_DEBUG_USERSPACE, "%02x %02x %02x %02x\n",
			query_params.hw_accel_type,
			query_params.hw_accel_ver,
			query_params.diagid_mask_supported,
			query_params.diagid_mask_enabled);
			break;
		}
		if (copy_to_user((void __user *)ioarg, &query_params,
				sizeof(query_params)))
			result = -EFAULT;
		else
			result = 0;
		break;
	case DIAG_IOCTL_PASSTHRU_CONTROL:
		if (copy_from_user((void *)&req_params, (void __user *)ioarg,
				   sizeof(struct diag_hw_accel_cmd_req_t))) {
			result = -EFAULT;
			break;
		}
		result = diag_ioctl_passthru_control_func(&req_params);
		if (result)
			break;
		if (copy_to_user((void __user *)ioarg, &req_params,
				sizeof(req_params)))
			result = -EFAULT;
		else
			result = 0;
		break;
	}
	return result;
}
#ifdef CONFIG_COMPAT
/*
 * @sync_obj_name: name of the synchronization object associated with this proc
@@ -2790,6 +2900,9 @@ long diagchar_compat_ioctl(struct file *filp,
	} else if (iocmd >= DIAG_IOCTL_QUERY_PD_LOGGING &&
			iocmd <= DIAG_IOCTL_QUERY_MD_PID) {
		result = diagchar_ioctl_mdlog(filp, iocmd, ioarg);
	} else if (iocmd >= DIAG_IOCTL_QUERY_PD_FEATUREMASK &&
			iocmd <= DIAG_IOCTL_PASSTHRU_CONTROL) {
		result = diagchar_ioctl_hw_accel(filp, iocmd, ioarg);
	} else {
		result = -EINVAL;
	}
@@ -2821,6 +2934,9 @@ long diagchar_ioctl(struct file *filp,
	} else if (iocmd >= DIAG_IOCTL_QUERY_PD_LOGGING &&
			iocmd <= DIAG_IOCTL_QUERY_MD_PID) {
		result = diagchar_ioctl_mdlog(filp, iocmd, ioarg);
	} else if (iocmd >= DIAG_IOCTL_QUERY_PD_FEATUREMASK &&
			iocmd <= DIAG_IOCTL_PASSTHRU_CONTROL) {
		result = diagchar_ioctl_hw_accel(filp, iocmd, ioarg);
	} else {
		result = -EINVAL;
	}
+68 −0
Original line number Diff line number Diff line
@@ -1746,6 +1746,74 @@ int diag_send_buffering_wm_values(uint8_t peripheral,
	return err;
}

int diag_send_passtru_ctrl_pkt(struct diag_hw_accel_cmd_req_t *req_params)
{
	struct diag_ctrl_passthru ctrl_pkt;
	int f_index = -1, err = 0;
	uint32_t diagid_mask = 0, diagid_status = 0;
	uint8_t i, hw_accel_type, hw_accel_ver;

	if (!req_params || req_params->operation > DIAG_HW_ACCEL_OP_QUERY) {
		DIAG_LOG(DIAG_DEBUG_USERSPACE, "Invalid Operation\n");
		return -EINVAL;
	}

	hw_accel_type = req_params->op_req.hw_accel_type;
	hw_accel_ver = req_params->op_req.hw_accel_ver;

	DIAG_LOG(DIAG_DEBUG_USERSPACE,
		"Received request for HW acceleration operation (%d) on hw_accel_type: %d, hw_accel_ver: %d\n",
		req_params->operation, hw_accel_type, hw_accel_ver);

	if (hw_accel_type > DIAG_HW_ACCEL_TYPE_MAX ||
		hw_accel_ver > DIAG_HW_ACCEL_VER_MAX) {
		DIAG_LOG(DIAG_DEBUG_USERSPACE, "Invalid Parameters\n");
		return -EINVAL;
	}

	f_index = diag_map_hw_accel_type_ver(hw_accel_type, hw_accel_ver);
	if (f_index < 0) {
		DIAG_LOG(DIAG_DEBUG_USERSPACE, "Invalid feature index\n");
		return -EINVAL;
	}

	mutex_lock(&driver->diagid_v2_mutex);

	diagid_mask = req_params->op_req.diagid_mask;
	diagid_status = (DIAGIDV2_FEATURE(f_index) & diagid_mask);

	if (req_params->operation == DIAG_HW_ACCEL_OP_DISABLE)
		DIAGIDV2_STATUS(f_index) &= ~diagid_status;
	else
		DIAGIDV2_STATUS(f_index) |= diagid_status;

	req_params->op_req.diagid_mask = DIAGIDV2_STATUS(f_index);

	mutex_unlock(&driver->diagid_v2_mutex);

	/*
	 * PASSTHRU Control Packet Formation to be sent to peripherals
	 */
	ctrl_pkt.header.pkt_id = DIAG_CTRL_MSG_PASSTHRU;
	ctrl_pkt.header.version = 1;
	ctrl_pkt.diagid_mask = diagid_mask;
	ctrl_pkt.hw_accel_type = hw_accel_type;
	ctrl_pkt.hw_accel_ver = hw_accel_ver;
	ctrl_pkt.control_data = req_params->operation;
	ctrl_pkt.header.len = sizeof(ctrl_pkt.header.version) +
		sizeof(ctrl_pkt.diagid_mask) + sizeof(ctrl_pkt.hw_accel_type) +
		sizeof(ctrl_pkt.hw_accel_ver) + sizeof(ctrl_pkt.control_data);
	for (i = 0; i < NUM_PERIPHERALS; i++) {
		err = diagfwd_write(i, TYPE_CNTL, &ctrl_pkt, sizeof(ctrl_pkt));
		if (err && err != -ENODEV) {
			pr_err("diag: Unable to send PASSTHRU ctrl packet to peripheral %d, err: %d\n",
				i, err);
			return err;
		}
	}
	return 0;
}

int diagfwd_cntl_init(void)
{
	uint8_t peripheral = 0;
+12 −2
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@
#define DIAG_CTRL_MSG_PD_STATUS			30
#define DIAG_CTRL_MSG_TIME_SYNC_PKT		31
#define DIAG_CTRL_MSG_DIAGID	33
#define DIAG_CTRL_MSG_PASSTHRU	35
/*
 * Feature Mask Definitions: Feature mask is used to specify Diag features
 * supported by the Apps processor
@@ -364,7 +365,7 @@ struct diag_ctrl_diagid_header {
struct diag_ctrl_diagid {
	struct diag_ctrl_diagid_header header;
	uint32_t diag_id;
	char process_name[30];
	char process_name[MAX_DIAGID_STR_LEN];
} __packed;

struct diag_ctrl_diagid_v2 {
@@ -372,7 +373,15 @@ struct diag_ctrl_diagid_v2 {
	uint32_t diag_id;
	uint32_t feature_len;
	uint32_t pd_feature_mask;
	char process_name[30];
	char process_name[MAX_DIAGID_STR_LEN];
} __packed;

struct diag_ctrl_passthru {
	struct diag_ctrl_diagid_header header;
	uint32_t diagid_mask;
	uint8_t hw_accel_type;
	uint8_t hw_accel_ver;
	uint8_t control_data;
} __packed;

int diagfwd_cntl_init(void);
@@ -397,4 +406,5 @@ int diag_send_buffering_tx_mode_pkt(uint8_t peripheral,
		    uint8_t diag_id, struct diag_buffering_mode_t *params);
int diag_send_buffering_wm_values(uint8_t peripheral,
		    uint8_t diag_id, struct diag_buffering_mode_t *params);
int diag_send_passtru_ctrl_pkt(struct diag_hw_accel_cmd_req_t *req_params);
#endif
+2 −0
Original line number Diff line number Diff line
@@ -60,6 +60,8 @@
#define DIAG_IOCTL_QUERY_PD_LOGGING	39
#define DIAG_IOCTL_QUERY_CON_ALL	40
#define DIAG_IOCTL_QUERY_MD_PID	41
#define DIAG_IOCTL_QUERY_PD_FEATUREMASK	42
#define DIAG_IOCTL_PASSTHRU_CONTROL	43

/* PC Tools IDs */
#define APQ8060_TOOLS_ID	4062