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

Commit ee807353 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "ASoC: wcd_cpe: Add CPE FTM feature"

parents 0153c0db ef48ca58
Loading
Loading
Loading
Loading
+86 −6
Original line number Diff line number Diff line
@@ -108,7 +108,15 @@ static struct wcd_cmi_afe_port_data afe_ports[WCD_CPE_AFE_MAX_PORTS + 1];
static void wcd_cpe_svc_event_cb(const struct cpe_svc_notification *param);
static int wcd_cpe_setup_irqs(struct wcd_cpe_core *core);
static void wcd_cpe_cleanup_irqs(struct wcd_cpe_core *core);
static ssize_t cpe_ftm_test_trigger(struct file *file,
				     const char __user *user_buf,
				     size_t count, loff_t *ppos);
static u32 ramdump_enable;
static u32 cpe_ftm_test_status;
static const struct file_operations cpe_ftm_test_trigger_fops = {
	.open = simple_open,
	.write = cpe_ftm_test_trigger,
};

static int wcd_cpe_afe_svc_cmd_mode(void *core_handle,
				    u8 mode);
@@ -372,6 +380,14 @@ static int wcd_cpe_enable_cpe_clks(struct wcd_cpe_core *core, bool enable)
		return ret;
	}

	if (!enable && core->cpe_clk_ref > 0)
		core->cpe_clk_ref--;

	/*
	 * CPE clk will be enabled at the first time
	 * and be disabled at the last time.
	 */
	if (core->cpe_clk_ref == 0) {
		ret = core->cpe_cdc_cb->cpe_clk_en(core->codec, enable);
		if (ret) {
			dev_err(core->dev,
@@ -379,6 +395,10 @@ static int wcd_cpe_enable_cpe_clks(struct wcd_cpe_core *core, bool enable)
				__func__, ret);
			goto cpe_clk_fail;
		}
	}

	if (enable)
		core->cpe_clk_ref++;

	return 0;

@@ -1650,6 +1670,22 @@ static int wcd_cpe_debugfs_init(struct wcd_cpe_core *core)
		goto err_create_entry;
	}

	if (!debugfs_create_file("cpe_ftm_test_trigger", S_IWUSR,
				dir, core, &cpe_ftm_test_trigger_fops)) {
		dev_err(core->dev, "%s: Failed to create debugfs node %s\n",
			__func__, "cpe_ftm_test_trigger");
		rc = -ENODEV;
		goto err_create_entry;
	}

	if (!debugfs_create_u32("cpe_ftm_test_status", S_IRUGO,
				dir, &cpe_ftm_test_status)) {
		dev_err(core->dev, "%s: Failed to create debugfs node %s\n",
			__func__, "cpe_ftm_test_status");
		rc = -ENODEV;
		goto err_create_entry;
	}

err_create_entry:
	debugfs_remove(dir);

@@ -1757,6 +1793,49 @@ done:
	return rc;
}

static ssize_t cpe_ftm_test_trigger(struct file *file,
				     const char __user *user_buf,
				     size_t count, loff_t *ppos)
{
	struct wcd_cpe_core *core = file->private_data;
	int ret = 0;

	/* Enable the clks for cpe */
	ret = wcd_cpe_enable_cpe_clks(core, true);
	if (IS_ERR_VALUE(ret)) {
		dev_err(core->dev,
			"%s: CPE clk enable failed, err = %d\n",
			__func__, ret);
		goto done;
	}

	/* Get the CPE_STATUS */
	ret = cpe_svc_ftm_test(core->cpe_handle, &cpe_ftm_test_status);
	if (IS_ERR_VALUE(ret)) {
		dev_err(core->dev,
			"%s: CPE FTM test failed, err = %d\n",
			__func__, ret);
		if (ret == CPE_SVC_BUSY) {
			cpe_ftm_test_status = 1;
			ret = 0;
		}
	}

	/* Disable the clks for cpe */
	ret = wcd_cpe_enable_cpe_clks(core, false);
	if (IS_ERR_VALUE(ret)) {
		dev_err(core->dev,
			"%s: CPE clk disable failed, err = %d\n",
			__func__, ret);
	}

done:
	if (ret < 0)
		return ret;
	else
		return count;
}

static int wcd_cpe_validate_params(
	struct snd_soc_codec *codec,
	struct wcd_cpe_params *params)
@@ -1844,6 +1923,7 @@ struct wcd_cpe_core *wcd_cpe_init(const char *img_fname,
	init_waitqueue_head(&core->ssr_entry.offline_poll_wait);
	mutex_init(&core->ssr_lock);
	core->cpe_users = 0;
	core->cpe_clk_ref = 0;

	/*
	 * By default, during probe, it is assumed that
+3 −0
Original line number Diff line number Diff line
@@ -182,6 +182,9 @@ struct wcd_cpe_core {

	/* Kobject for sysfs entry */
	struct kobject cpe_kobj;

	/* Reference count for cpe clk*/
	int cpe_clk_ref;
};

struct wcd_cpe_params {
+143 −0
Original line number Diff line number Diff line
@@ -141,6 +141,7 @@ enum cpe_command {
	CPE_LAB_CFG_SB,
	CPE_CMD_CANCEL_MEMACCESS,
	CPE_CMD_PROC_INCOMING_MSG,
	CPE_CMD_FTM_TEST,
};

enum cpe_process_result {
@@ -181,6 +182,11 @@ struct cpe_info {
	struct completion core_svc_cmd_compl;
};

struct cpe_tgt_waiti_info {
	u8 tgt_waiti_size;
	u8 *tgt_waiti_data;
};

struct cpe_svc_tgt_abstraction {
	enum cpe_svc_result (*tgt_boot) (int debug_mode);

@@ -218,6 +224,7 @@ struct cpe_svc_tgt_abstraction {
				(bool);
	u8 *inbox;
	u8 *outbox;
	struct cpe_tgt_waiti_info *tgt_waiti_info;
};

static enum cpe_svc_result cpe_tgt_tomtom_init(
@@ -1374,6 +1381,7 @@ static enum cpe_svc_result cpe_mt_validate_cmd(
		case CPE_CMD_PROCESS_IRQ:
		case CPE_CMD_KILL_THREAD:
		case CPE_CMD_DEINITIALIZE:
		case CPE_CMD_FTM_TEST:
			rc = CPE_SVC_SUCCESS;
			break;
		default:
@@ -1387,6 +1395,7 @@ static enum cpe_svc_result cpe_mt_validate_cmd(
		case CPE_CMD_RESET:
		case CPE_CMD_DL_SEGMENT:
		case CPE_CMD_BOOT:
		case CPE_CMD_FTM_TEST:
			rc = CPE_SVC_SUCCESS;
			break;
		default:
@@ -1403,6 +1412,9 @@ static enum cpe_svc_result cpe_mt_validate_cmd(
		case CPE_CMD_SHUTDOWN:
			rc = CPE_SVC_SUCCESS;
			break;
		case CPE_CMD_FTM_TEST:
			rc = CPE_SVC_BUSY;
			break;
		default:
			rc = CPE_SVC_NOT_READY;
			break;
@@ -1421,6 +1433,9 @@ static enum cpe_svc_result cpe_mt_validate_cmd(
		case CPE_CMD_PROC_INCOMING_MSG:
			rc = CPE_SVC_SUCCESS;
			break;
		case CPE_CMD_FTM_TEST:
			rc = CPE_SVC_BUSY;
			break;
		default:
			rc = CPE_SVC_FAILED;
			break;
@@ -1438,6 +1453,9 @@ static enum cpe_svc_result cpe_mt_validate_cmd(
		case CPE_CMD_PROC_INCOMING_MSG:
			rc = CPE_SVC_SUCCESS;
			break;
		case CPE_CMD_FTM_TEST:
			rc = CPE_SVC_BUSY;
			break;
		default:
			rc = CPE_SVC_FAILED;
			break;
@@ -1971,6 +1989,115 @@ enum cmi_api_result cmi_send_msg(void *message)
	return rc;
}

enum cpe_svc_result cpe_svc_ftm_test(void *cpe_handle, u32 *status)
{
	enum cpe_svc_result rc = CPE_SVC_SUCCESS;
	struct cpe_info *t_info = (struct cpe_info *)cpe_handle;
	struct cpe_svc_mem_segment backup_seg;
	struct cpe_svc_mem_segment waiti_seg;
	u8 *backup_data = NULL;

	CPE_SVC_GRAB_LOCK(&cpe_d.cpe_api_mutex, "cpe_api");
	if (!t_info)
		t_info = cpe_d.cpe_default_handle;

	rc = cpe_is_command_valid(t_info, CPE_CMD_FTM_TEST);
	if (rc != CPE_SVC_SUCCESS) {
		pr_err("%s: cmd validation fail, cmd = %d\n",
			__func__, CPE_CMD_FTM_TEST);
		goto fail_cmd;
	}

	if (t_info && t_info->tgt) {
		backup_data = kzalloc(
				t_info->tgt->tgt_waiti_info->tgt_waiti_size,
				GFP_KERNEL);

		/* CPE reset */
		rc = t_info->tgt->tgt_reset();
		if (rc != CPE_SVC_SUCCESS) {
			pr_err("%s: CPE reset fail! err = %d\n",
				__func__, rc);
			goto err_return;
		}

		/* Back up the 4 byte IRAM data first */
		backup_seg.type = CPE_SVC_INSTRUCTION_MEM;
		backup_seg.cpe_addr =
			t_info->tgt->tgt_get_cpe_info()->IRAM_offset;
		backup_seg.size = t_info->tgt->tgt_waiti_info->tgt_waiti_size;
		backup_seg.data = backup_data;

		pr_debug("%s: Backing up IRAM data from CPE\n",
			__func__);

		rc = t_info->tgt->tgt_read_ram(t_info, &backup_seg);
		if (rc != CPE_SVC_SUCCESS) {
			pr_err("%s: Fail to backup CPE IRAM data, err = %d\n",
				__func__, rc);
			goto err_return;
		}

		pr_debug("%s: Complete backing up IRAM data from CPE\n",
			__func__);

		/* Write the WAITI instruction data */
		waiti_seg.type = CPE_SVC_INSTRUCTION_MEM;
		waiti_seg.cpe_addr =
			t_info->tgt->tgt_get_cpe_info()->IRAM_offset;
		waiti_seg.size = t_info->tgt->tgt_waiti_info->tgt_waiti_size;
		waiti_seg.data = t_info->tgt->tgt_waiti_info->tgt_waiti_data;

		rc = t_info->tgt->tgt_write_ram(t_info, &waiti_seg);
		if (rc != CPE_SVC_SUCCESS) {
			pr_err("%s: Fail to write the WAITI data, err = %d\n",
				__func__, rc);
			goto restore_iram;
		}

		/* Boot up cpe to execute the WAITI instructions */
		rc = t_info->tgt->tgt_boot(1);
		if (rc != CPE_SVC_SUCCESS) {
			pr_err("%s: Fail to boot CPE, err = %d\n",
				__func__, rc);
			goto reset;
		}

		/*
		 * 1ms delay is suggested by the hw team to
		 * wait for cpe to boot up.
		 */
		usleep_range(1000, 1100);

		/* Check if the cpe init is done after executing the WAITI */
		*status = t_info->tgt->tgt_cpar_init_done();

reset:
		/* Set the cpe back to reset state */
		rc = t_info->tgt->tgt_reset();
		if (rc != CPE_SVC_SUCCESS) {
			pr_err("%s: CPE reset fail! err = %d\n",
				__func__, rc);
			goto restore_iram;
		}

restore_iram:
		/* Restore the IRAM 4 bytes data */
		rc = t_info->tgt->tgt_write_ram(t_info, &backup_seg);
		if (rc != CPE_SVC_SUCCESS) {
			pr_err("%s: Fail to restore the IRAM data, err = %d\n",
				__func__, rc);
			goto err_return;
		}
	}

err_return:
	kfree(backup_data);
fail_cmd:
	CPE_SVC_REL_LOCK(&cpe_d.cpe_api_mutex, "cpe_api");
	return rc;
}

static enum cpe_svc_result cpe_tgt_tomtom_boot(int debug_mode)
{
	enum cpe_svc_result rc = CPE_SVC_SUCCESS;
@@ -2319,6 +2446,13 @@ static enum cpe_svc_result cpe_tgt_tomtom_deinit(
	return CPE_SVC_SUCCESS;
}

static u8 cpe_tgt_tomtom_waiti_data[] = {0x00, 0x70, 0x00, 0x00};

static struct cpe_tgt_waiti_info cpe_tgt_tomtom_waiti_info = {
	.tgt_waiti_size = ARRAY_SIZE(cpe_tgt_tomtom_waiti_data),
	.tgt_waiti_data = cpe_tgt_tomtom_waiti_data,
};

static enum cpe_svc_result cpe_tgt_tomtom_init(
		struct cpe_svc_codec_info_v1 *codec_info,
		struct cpe_svc_tgt_abstraction *param)
@@ -2343,6 +2477,7 @@ static enum cpe_svc_result cpe_tgt_tomtom_init(
		param->tgt_get_cpe_info = cpe_tgt_tomtom_get_cpe_info;
		param->tgt_deinit = cpe_tgt_tomtom_deinit;
		param->tgt_voice_tx_lab = cpe_tgt_tomtom_voicetx;
		param->tgt_waiti_info = &cpe_tgt_tomtom_waiti_info;

		param->inbox = kzalloc(TOMTOM_A_SVASS_SPE_INBOX_SIZE,
				       GFP_KERNEL);
@@ -2753,6 +2888,13 @@ static enum cpe_svc_result
	return rc;
}

static u8 cpe_tgt_wcd9335_waiti_data[] = {0x00, 0x70, 0x00, 0x00};

static struct cpe_tgt_waiti_info cpe_tgt_wcd9335_waiti_info = {
	.tgt_waiti_size = ARRAY_SIZE(cpe_tgt_wcd9335_waiti_data),
	.tgt_waiti_data = cpe_tgt_wcd9335_waiti_data,
};

static enum cpe_svc_result cpe_tgt_wcd9335_init(
		struct cpe_svc_codec_info_v1 *codec_info,
		struct cpe_svc_tgt_abstraction *param)
@@ -2777,6 +2919,7 @@ static enum cpe_svc_result cpe_tgt_wcd9335_init(
		param->tgt_get_cpe_info = cpe_tgt_wcd9335_get_cpe_info;
		param->tgt_deinit = cpe_tgt_wcd9335_deinit;
		param->tgt_voice_tx_lab = cpe_tgt_wcd9335_voicetx;
		param->tgt_waiti_info = &cpe_tgt_wcd9335_waiti_info;

		param->inbox = kzalloc(WCD9335_CPE_SS_SPE_INBOX_SIZE,
				       GFP_KERNEL);
+2 −0
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ enum cpe_svc_result {
	CPE_SVC_INVALID_HANDLE		= -EINVAL,
	CPE_SVC_NOT_READY		= -ENOTREADY,
	CPE_SVC_SHUTTING_DOWN		= -ESHUTDOWN,
	CPE_SVC_BUSY			= -EBUSY,
};

enum cpe_svc_event {
@@ -174,4 +175,5 @@ enum cpe_svc_result cpe_svc_set_debug_mode(void *cpe_handle, u32 mode);

const struct cpe_svc_hw_cfg *cpe_svc_get_hw_cfg(void *cpe_handle);
enum cpe_svc_result cpe_svc_toggle_lab(void *cpe_handle, bool enable);
enum cpe_svc_result cpe_svc_ftm_test(void *cpe_handle, u32 *status);
#endif /*__CPE_SERVICES__*/