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

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

Merge "msm: ais: Sync to latest mobile camera"

parents 83cd3110 ced9727a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
obj-$(CONFIG_MSM_AIS) += cam_req_mgr/
obj-$(CONFIG_MSM_AIS) += cam_hyp_intf/
obj-$(CONFIG_MSM_AIS) += cam_utils/
obj-$(CONFIG_MSM_AIS) += cam_core/
obj-$(CONFIG_MSM_AIS) += cam_sync/
+148 −1
Original line number Diff line number Diff line
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-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
@@ -714,3 +714,150 @@ void cam_cdm_util_dump_cmd_buf(
		}
	} while (buf_now <= cmd_buf_end);
}

static long cam_cdm_util_dump_reg_cont_cmd_v2(
	uint32_t *cmd_buf_addr,
	struct cam_cdm_cmd_buf_dump_info *dump_info)
{
	long ret = 0;
	struct cdm_regcontinuous_cmd *p_regcont_cmd;
	uint32_t *temp_ptr = cmd_buf_addr;
	int i = 0;
	struct cam_cdm_cmd_dump_header *hdr;
	uint32_t *addr, *start;
	uint8_t *dst;
	uint32_t min_len, remain_len;

	p_regcont_cmd = (struct cdm_regcontinuous_cmd *)temp_ptr;
	temp_ptr += CDMCmdHeaderSizes[CAM_CDM_CMD_REG_CONT];
	ret += CDMCmdHeaderSizes[CAM_CDM_CMD_REG_CONT];
	CAM_DBG(CAM_CDM, "REG_CONT: COUNT: %u OFFSET: 0x%X",
		p_regcont_cmd->count, p_regcont_cmd->offset);

	min_len = (sizeof(uint32_t) * p_regcont_cmd->count) +
		sizeof(struct cam_cdm_cmd_dump_header);
	remain_len = dump_info->dst_max_size - dump_info->dst_offset;
	if (remain_len < min_len) {
		CAM_ERR_RATE_LIMIT(CAM_CDM, "Dump buffer exhaust %d %d",
			remain_len, min_len);
		return ret;
	}
	dst = (char *)dump_info->dst_start + dump_info->dst_offset;
	hdr = (struct cam_cdm_cmd_dump_header *)dst;
	snprintf(hdr->tag, CAM_CDM_CMD_TAG_MAX_LEN, "CDM_REG_CONT:");
	hdr->word_size = sizeof(uint32_t);
	addr = (uint32_t *)(dst + sizeof(struct cam_cdm_cmd_dump_header));
	start = addr;
	*addr++ = p_regcont_cmd->offset;
	*addr++ = p_regcont_cmd->count;
	for (i = 0; i < p_regcont_cmd->count; i++) {
		*addr = *temp_ptr;
		temp_ptr++;
		addr++;
		ret++;
	}
	hdr->size = hdr->word_size * (addr - start);
	dump_info->dst_offset += hdr->size +
		sizeof(struct cam_cdm_cmd_dump_header);
	return ret;
}

static long cam_cdm_util_dump_reg_random_cmd_v2(
	uint32_t *cmd_buf_addr,
	struct cam_cdm_cmd_buf_dump_info *dump_info)
{
	struct cdm_regrandom_cmd *p_regrand_cmd;
	uint32_t *temp_ptr = cmd_buf_addr;
	long ret = 0;
	int i = 0;
	uint32_t *addr, *start;
	struct cam_cdm_cmd_dump_header *hdr;
	uint8_t *dst;
	uint32_t min_len, remain_len;

	p_regrand_cmd = (struct cdm_regrandom_cmd *)temp_ptr;
	temp_ptr += CDMCmdHeaderSizes[CAM_CDM_CMD_REG_RANDOM];
	ret += CDMCmdHeaderSizes[CAM_CDM_CMD_REG_RANDOM];

	min_len = (2 * sizeof(uint32_t) * p_regrand_cmd->count) +
		sizeof(struct cam_cdm_cmd_dump_header);
	remain_len = dump_info->dst_max_size - dump_info->dst_offset;
	if (remain_len < min_len) {
		CAM_ERR_RATE_LIMIT(CAM_CDM, "Dump buffer exhaust %d %d",
			remain_len, min_len);
		return ret;
	}
	dst = (char *)dump_info->dst_start + dump_info->dst_offset;
	hdr = (struct cam_cdm_cmd_dump_header *)dst;
	snprintf(hdr->tag, CAM_CDM_CMD_TAG_MAX_LEN, "CDM_REG_RANDOM:");
	hdr->word_size = sizeof(uint32_t);
	addr = (uint32_t *)(dst + sizeof(struct cam_cdm_cmd_dump_header));
	start = addr;
	*addr++ = p_regrand_cmd->count;
	for (i = 0; i < p_regrand_cmd->count; i++) {
		addr[0] = temp_ptr[0] & CAM_CDM_REG_OFFSET_MASK;
		addr[1] = temp_ptr[1];
		temp_ptr += 2;
		addr += 2;
		ret += 2;
	}
	hdr->size = hdr->word_size * (addr - start);
	dump_info->dst_offset += hdr->size +
		sizeof(struct cam_cdm_cmd_dump_header);
	return ret;
}

void cam_cdm_util_dump_cmd_bufs_v2(
	struct cam_cdm_cmd_buf_dump_info *dump_info)
{
	uint32_t cmd = 0;
	uint32_t *buf_now;

	if (!dump_info || !dump_info->src_start || !dump_info->src_end ||
			!dump_info->dst_start) {
		CAM_INFO(CAM_CDM, "Invalid args");
		return;
	}
	buf_now = dump_info->src_start;
	do {
		cmd = *buf_now;
		cmd = cmd >> CAM_CDM_COMMAND_OFFSET;

		switch (cmd) {
		case CAM_CDM_CMD_DMI:
		case CAM_CDM_CMD_DMI_32:
		case CAM_CDM_CMD_DMI_64:
			buf_now += CDMCmdHeaderSizes[CAM_CDM_CMD_DMI];
			break;
		case CAM_CDM_CMD_REG_CONT:
			buf_now += cam_cdm_util_dump_reg_cont_cmd_v2(buf_now,
				dump_info);
			break;
		case CAM_CDM_CMD_REG_RANDOM:
			buf_now += cam_cdm_util_dump_reg_random_cmd_v2(buf_now,
				dump_info);
			break;
		case CAM_CDM_CMD_BUFF_INDIRECT:
			buf_now += CDMCmdHeaderSizes[CAM_CDM_CMD_BUFF_INDIRECT];
			break;
		case CAM_CDM_CMD_GEN_IRQ:
			buf_now += CDMCmdHeaderSizes[CAM_CDM_CMD_GEN_IRQ];
			break;
		case CAM_CDM_CMD_WAIT_EVENT:
			buf_now += CDMCmdHeaderSizes[CAM_CDM_CMD_WAIT_EVENT];
			break;
		case CAM_CDM_CMD_CHANGE_BASE:
			buf_now += CDMCmdHeaderSizes[CAM_CDM_CMD_CHANGE_BASE];
			break;
		case CAM_CDM_CMD_PERF_CTRL:
			buf_now += CDMCmdHeaderSizes[CAM_CDM_CMD_PERF_CTRL];
			break;
		default:
			CAM_INFO(CAM_CDM, "Invalid CMD: 0x%x buf 0x%x",
				cmd, *buf_now);
			buf_now++;
			break;
		}
	} while (buf_now <= dump_info->src_end);

}
+43 −1
Original line number Diff line number Diff line
/* Copyright (c) 2017-2018, The Linux Foundation. All rights reserved.
/* Copyright (c) 2017-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
@@ -13,6 +13,9 @@
#ifndef _CAM_CDM_UTIL_H_
#define _CAM_CDM_UTIL_H_

/* Max len for tag name for header while dumping cmd buffer*/
#define CAM_CDM_CMD_TAG_MAX_LEN 32

enum cam_cdm_command {
	CAM_CDM_CMD_UNUSED = 0x0,
	CAM_CDM_CMD_DMI = 0x1,
@@ -151,6 +154,34 @@ void (*cdm_write_genirq)(
	uint32_t  userdata);
};

/**
 * struct cam_cdm_cmd_buf_dump_info; - Camera CDM dump info
 * @src_start:       source start address
 * @src_end:         source end   address
 * @dst_start:       dst start address
 * @dst_offset:      dst offset
 * @dst_max_size     max size of destination buffer
 */
struct cam_cdm_cmd_buf_dump_info {
	uint32_t *src_start;
	uint32_t *src_end;
	uintptr_t dst_start;
	uint32_t  dst_offset;
	uint32_t  dst_max_size;
};

/**
 * struct cam_cdm_cmd_dump_header- Camera CDM dump header
 * @tag:       tag name for header
 * @size:      size of data
 * @word_size: size of each word
 */
struct cam_cdm_cmd_dump_header {
	char      tag[CAM_CDM_CMD_TAG_MAX_LEN];
	uint64_t  size;
	uint32_t  word_size;
};

/**
 * cam_cdm_util_log_cmd_bufs()
 *
@@ -163,6 +194,17 @@ void (*cdm_write_genirq)(
void cam_cdm_util_dump_cmd_buf(
	uint32_t *cmd_buffer_start, uint32_t *cmd_buffer_end);

/**
 * cam_cdm_util_dump_cmd_bufs_v2()
 *
 * @brief:        Util function to log cdm command buffers
 *                to a buffer
 *
 * @dump_info:    Information about source and destination buffers
 *
 */
void cam_cdm_util_dump_cmd_bufs_v2(
	struct cam_cdm_cmd_buf_dump_info *dump_info);


#endif /* _CAM_CDM_UTIL_H_ */
+49 −0
Original line number Diff line number Diff line
@@ -234,6 +234,28 @@ int cam_context_handle_crm_process_evt(struct cam_context *ctx,
	return rc;
}

int cam_context_handle_crm_dump_req(struct cam_context *ctx,
	struct cam_req_mgr_dump_info *dump)
{
	int rc = 0;

	if (!ctx->state_machine) {
		CAM_ERR(CAM_CORE, "Context is not ready");
		return -EINVAL;
	}
	mutex_lock(&ctx->ctx_mutex);
	if (ctx->state_machine[ctx->state].crm_ops.dump_req) {
		rc = ctx->state_machine[ctx->state].crm_ops.dump_req(ctx,
			dump);
	} else {
		CAM_ERR(CAM_CORE, "No crm dump req in dev %d, state %d",
			ctx->dev_hdl, ctx->state);
	}
	mutex_unlock(&ctx->ctx_mutex);

	return rc;
}

int cam_context_dump_pf_info(struct cam_context *ctx, unsigned long iova,
	uint32_t buf_info)
{
@@ -502,6 +524,33 @@ int cam_context_handle_stop_dev(struct cam_context *ctx,
	return rc;
}

int cam_context_handle_dump_dev(struct cam_context *ctx,
	struct cam_dump_req_cmd *cmd)
{
	int rc = 0;

	if (!ctx || !ctx->state_machine) {
		CAM_ERR(CAM_CORE, "Context is not ready");
		return -EINVAL;
	}

	if (!cmd) {
		CAM_ERR(CAM_CORE, "Invalid stop device command payload");
		return -EINVAL;
	}

	mutex_lock(&ctx->ctx_mutex);
	if (ctx->state_machine[ctx->state].ioctl_ops.dump_dev)
		rc = ctx->state_machine[ctx->state].ioctl_ops.dump_dev(
			ctx, cmd);
	else
		CAM_WARN(CAM_CORE, "No dump device in dev %d, name %s state %d",
			ctx->dev_hdl, ctx->dev_name, ctx->state);
	mutex_unlock(&ctx->ctx_mutex);

	return rc;
}

int cam_context_init(struct cam_context *ctx,
	const char *dev_name,
	uint64_t dev_id,
+48 −0
Original line number Diff line number Diff line
@@ -25,6 +25,9 @@ struct cam_context;
/* max device name string length*/
#define CAM_CTX_DEV_NAME_MAX_LENGTH 20

/* max tag  dump header string length*/
#define CAM_CONTEXT_DUMP_TAG_MAX_LEN 32

/* max request number */
#define CAM_CTX_REQ_MAX              20
#define CAM_CTX_CFG_MAX              20
@@ -92,6 +95,7 @@ struct cam_ctx_request {
 * @flush_dev:             Function pointer for flush device
 * @acquire_hw:            Function pointer for acquire hw
 * @release_hw:            Function pointer for release hw
 * @dump_dev:              Function pointer for dump dev
 *
 */
struct cam_ctx_ioctl_ops {
@@ -109,6 +113,9 @@ struct cam_ctx_ioctl_ops {
			struct cam_flush_dev_cmd *cmd);
	int (*acquire_hw)(struct cam_context *ctx, void *args);
	int (*release_hw)(struct cam_context *ctx, void *args);
	int (*dump_dev)(struct cam_context *ctx,
			struct cam_dump_req_cmd *cmd);

};

/**
@@ -120,6 +127,7 @@ struct cam_ctx_ioctl_ops {
 * @apply_req:             Apply setting for the context
 * @flush_req:             Flush request to remove request ids
 * @process_evt:           Handle event notification from CRM.(optional)
 * @dump_req:              Dump information for the issue request
 *
 */
struct cam_ctx_crm_ops {
@@ -135,6 +143,8 @@ struct cam_ctx_crm_ops {
			struct cam_req_mgr_flush_request *flush);
	int (*process_evt)(struct cam_context *ctx,
			struct cam_req_mgr_link_evt_data *evt_data);
	int (*dump_req)(struct cam_context *ctx,
			struct cam_req_mgr_dump_info *dump);
};


@@ -222,6 +232,19 @@ struct cam_context {
	uint32_t                     last_flush_req;
};

/**
 * struct cam_context_dump_header -  Function for context dump header
 *
 * @tag         :    Tag for context dump header
 * @size        :    Size of data
 * @word_size   :    Word size of data
 */
struct cam_context_dump_header {
	char      tag[CAM_CONTEXT_DUMP_TAG_MAX_LEN];
	uint64_t  size;
	uint32_t  word_size;
};

/**
 * cam_context_shutdown()
 *
@@ -304,6 +327,18 @@ int cam_context_handle_crm_flush_req(struct cam_context *ctx,
int cam_context_handle_crm_process_evt(struct cam_context *ctx,
	struct cam_req_mgr_link_evt_data *process_evt);

/**
 * cam_context_handle_crm_dump_req()
 *
 * @brief:        Handle CRM dump request
 *
 * @ctx:          Object pointer for cam_context
 * @dump:         Request to dump
 *
 */
int cam_context_handle_crm_dump_req(struct cam_context *ctx,
	struct cam_req_mgr_dump_info *dump);

/**
 * cam_context_dump_pf_info()
 *
@@ -413,6 +448,19 @@ int cam_context_handle_start_dev(struct cam_context *ctx,
int cam_context_handle_stop_dev(struct cam_context *ctx,
		struct cam_start_stop_dev_cmd *cmd);


/**
 * cam_context_handle_dump_dev()
 *
 * @brief:        Handle dump device command
 *
 * @ctx:          Object pointer for cam_context
 * @cmd:          Dump device command payload
 *
 */
int cam_context_handle_dump_dev(struct cam_context *ctx,
	struct cam_dump_req_cmd *cmd);

/**
 * cam_context_deinit()
 *
Loading