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

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

Merge "diag: Query and configure hardware acceleration"

parents f5569701 b5e70193
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
@@ -2365,6 +2365,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;
@@ -2741,6 +2804,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
@@ -2796,6 +2906,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;
	}
@@ -2827,6 +2940,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