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

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

Merge "Merge remote-tracking branch 'dev/msm-4.14-camx' into msm-4.14 10/15"

parents 5fb0dbf7 b00a8d5c
Loading
Loading
Loading
Loading
+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 = *dump_info->src_start;
		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_ */
+16 −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
@@ -229,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()
 *
+74 −5
Original line number Diff line number Diff line
@@ -1045,6 +1045,72 @@ int32_t cam_context_dump_pf_info_to_hw(struct cam_context *ctx,
	return rc;
}

static int cam_context_dump_context(struct cam_context *ctx,
	struct cam_hw_dump_args *dump_args)
{
	int rc = 0;
	struct cam_context_dump_header *hdr;
	char *dst;
	uint64_t *addr, *start;
	uintptr_t cpu_addr;
	size_t    buf_len;
	uint32_t min_len, remain_len;
	struct cam_ctx_request *req;
	int i;

	if (list_empty(&ctx->active_req_list)) {
		CAM_ERR(CAM_CTXT, "[%s][%d] no active request",
			ctx->dev_name, ctx->ctx_id);
		return -EIO;
	}
	rc  = cam_mem_get_cpu_buf(dump_args->buf_handle,
		&cpu_addr, &buf_len);
	if (!cpu_addr || !buf_len || rc) {
		CAM_ERR(CAM_CTXT,
			"lnvalid addr %u len %zu rc %d",
			dump_args->buf_handle, buf_len, rc);
		return rc;
	}
	remain_len = buf_len - dump_args->offset;
	min_len =  2 * (sizeof(struct cam_context_dump_header) +
		    CAM_CONTEXT_DUMP_TAG_MAX_LEN);
	if (remain_len < min_len) {
		CAM_ERR(CAM_CTXT, "dump buffer exhaust %d %d",
			remain_len, min_len);
		goto end;
	}
	dst = (char *)cpu_addr + dump_args->offset;
	hdr = (struct cam_context_dump_header *)dst;
	snprintf(hdr->tag, CAM_CONTEXT_DUMP_TAG_MAX_LEN,
		"%s_CTXT_DUMP:", ctx->dev_name);
	hdr->word_size = sizeof(uint64_t);
	addr = (uint64_t *)(dst + sizeof(struct cam_context_dump_header));
	start = addr;
	req = list_first_entry(&ctx->active_req_list,
		struct cam_ctx_request, list);
	*addr++ = ctx->ctx_id;
	*addr++ = refcount_read(&(ctx->refcount.refcount));
	*addr++ = ctx->last_flush_req;
	*addr++ = ctx->state;
	*addr++ = req->num_out_map_entries;
	for (i = 0; i < req->num_out_map_entries; i++)
		if (req->out_map_entries[i].sync_id != -1)
			*addr++ = req->out_map_entries[i].sync_id;
	for (i = 0; i < req->num_in_map_entries; i++)
		if (req->in_map_entries[i].sync_id != -1)
			*addr++ = req->in_map_entries[i].sync_id;
	*addr++ = req->num_in_map_entries;
	hdr->size = hdr->word_size * (addr - start);
	dump_args->offset += hdr->size +
		sizeof(struct cam_context_dump_header);
end:
	rc  = cam_mem_put_cpu_buf(dump_args->buf_handle);
	if (rc)
		CAM_ERR(CAM_CTXT, "Cpu put failed handle %u",
			dump_args->buf_handle);
	return rc;
}

int32_t cam_context_dump_dev_to_hw(struct cam_context *ctx,
	struct cam_dump_req_cmd *cmd)
{
@@ -1074,11 +1140,14 @@ int32_t cam_context_dump_dev_to_hw(struct cam_context *ctx,
			    ctx->dev_name, ctx->ctx_id, dump_args.buf_handle);
			return rc;
		}
		if (dump_args.offset != cmd->offset) {
			cam_context_dump_context(ctx, &dump_args);
			CAM_INFO(CAM_CTXT, "[%s] ctx: %d Filled Length %d",
				ctx->dev_name, ctx->ctx_id,
				dump_args.offset - cmd->offset);
		/* Drivers update offest upto which the buffer is written*/
			/* Drivers update the offest */
			cmd->offset  = dump_args.offset;
		}
	} else {
		CAM_INFO(CAM_CTXT, "%s hw dump not registered", ctx->dev_name);
	}
+13 −0
Original line number Diff line number Diff line
@@ -124,6 +124,18 @@ static int __cam_fd_ctx_release_dev_in_activated(struct cam_context *ctx,
	return rc;
}

static int __cam_fd_ctx_dump_dev_in_activated(struct cam_context *ctx,
	struct cam_dump_req_cmd *cmd)
{
	int rc;

	rc = cam_context_dump_dev_to_hw(ctx, cmd);
	if (rc)
		CAM_ERR(CAM_FD, "Failed to dump device, rc=%d", rc);

	return rc;
}

static int __cam_fd_ctx_flush_dev_in_activated(struct cam_context *ctx,
	struct cam_flush_dev_cmd *cmd)
{
@@ -203,6 +215,7 @@ static struct cam_ctx_ops
			.release_dev = __cam_fd_ctx_release_dev_in_activated,
			.config_dev = __cam_fd_ctx_config_dev_in_activated,
			.flush_dev = __cam_fd_ctx_flush_dev_in_activated,
			.dump_dev = __cam_fd_ctx_dump_dev_in_activated,
		},
		.crm_ops = {},
		.irq_ops = __cam_fd_ctx_handle_irq_in_activated,
Loading