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

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

Merge "mhi: cntrl: qcom: check sfr support from device tree"

parents 5b91ab81 b230a90f
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@
		/* mhi bus specific settings */
		mhi,max-channels = <111>;
		mhi,timeout = <2000>;
		mhi,name = "esoc0";

		mhi_channels {
			#address-cells = <1>;
+1 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@
	esoc-0 = <&mdm3>;
	qcom,smmu-cfg = <0x1d>;
	qcom,addr-win = <0x0 0x20000000 0x0 0x2fffffff>;
	mhi,sfr-support;

	/* controller noc frequency scaling configuration */
	qcom,msm-bus,name = "mhi0";
+4 −0
Original line number Diff line number Diff line
@@ -756,6 +756,10 @@ static struct mhi_controller *mhi_register_controller(struct pci_dev *pci_dev)
	mhi_cntrl->remote_timer_freq = 19200000;
	mhi_cntrl->local_timer_freq = 19200000;

	/* setup host support for SFR retreival */
	if (of_property_read_bool(of_node, "mhi,sfr-support"))
		mhi_cntrl->sfr_len = MHI_MAX_SFR_LEN;

	ret = of_register_mhi_controller(mhi_cntrl);
	if (ret)
		goto error_register;
+2 −0
Original line number Diff line number Diff line
@@ -34,6 +34,8 @@
#define REMOTE_TIME_REMAINDER_US(x) (REMOTE_TICKS_TO_US((x)) % \
					(REMOTE_TICKS_TO_SEC((x)) * 1000000ULL))

#define MHI_MAX_SFR_LEN (256)

extern const char * const mhi_ee_str[MHI_EE_MAX];
#define TO_MHI_EXEC_STR(ee) (ee >= MHI_EE_MAX ? "INVALID_EE" : mhi_ee_str[ee])

+78 −0
Original line number Diff line number Diff line
@@ -82,6 +82,19 @@ static const char * const mhi_pm_state_str[] = {

struct mhi_bus mhi_bus;

struct mhi_controller *find_mhi_controller_by_name(const char *name)
{
	struct mhi_controller *mhi_cntrl, *tmp_cntrl;

	list_for_each_entry_safe(mhi_cntrl, tmp_cntrl, &mhi_bus.controller_list,
				 node) {
		if (mhi_cntrl->name && (!strcmp(name, mhi_cntrl->name)))
			return mhi_cntrl;
	}

	return NULL;
}

const char *to_mhi_pm_state_str(enum MHI_PM_STATE state)
{
	int index = find_last_bit((unsigned long *)&state, 32);
@@ -664,6 +677,42 @@ int mhi_init_timesync(struct mhi_controller *mhi_cntrl)
	return ret;
}

int mhi_init_sfr(struct mhi_controller *mhi_cntrl)
{
	struct mhi_sfr_info *sfr_info = mhi_cntrl->mhi_sfr;
	int ret = -EIO;

	if (!sfr_info)
		return ret;

	/* do a clean-up if we reach here post SSR */
	memset(sfr_info->str, 0, sfr_info->len);

	sfr_info->buf_addr = mhi_alloc_coherent(mhi_cntrl, sfr_info->len,
					&sfr_info->dma_addr, GFP_KERNEL);
	if (!sfr_info->buf_addr) {
		MHI_ERR("Failed to allocate memory for sfr\n");
		return -ENOMEM;
	}

	init_completion(&sfr_info->completion);

	ret = mhi_send_cmd(mhi_cntrl, NULL, MHI_CMD_SFR_CFG);
	if (ret) {
		MHI_ERR("Failed to send sfr cfg cmd\n");
		return ret;
	}

	ret = wait_for_completion_timeout(&sfr_info->completion,
			msecs_to_jiffies(mhi_cntrl->timeout_ms));
	if (!ret || sfr_info->ccs != MHI_EV_CC_SUCCESS) {
		MHI_ERR("Failed to get sfr cfg cmd completion\n");
		return -EIO;
	}

	return 0;
}

static int mhi_init_bw_scale(struct mhi_controller *mhi_cntrl)
{
	int ret, er_index;
@@ -1303,6 +1352,8 @@ static int of_parse_dt(struct mhi_controller *mhi_cntrl,
	if (!ret)
		mhi_cntrl->bhie = mhi_cntrl->regs + bhie_offset;

	of_property_read_string(of_node, "mhi,name", &mhi_cntrl->name);

	return 0;

error_ev_cfg:
@@ -1319,6 +1370,7 @@ int of_register_mhi_controller(struct mhi_controller *mhi_cntrl)
	struct mhi_chan *mhi_chan;
	struct mhi_cmd *mhi_cmd;
	struct mhi_device *mhi_dev;
	struct mhi_sfr_info *sfr_info;
	u32 soc_info;

	if (!mhi_cntrl->of_node)
@@ -1439,6 +1491,23 @@ int of_register_mhi_controller(struct mhi_controller *mhi_cntrl)

	mhi_cntrl->mhi_dev = mhi_dev;

	if (mhi_cntrl->sfr_len) {
		sfr_info = kzalloc(sizeof(*sfr_info), GFP_KERNEL);
		if (!sfr_info) {
			ret = -ENOMEM;
			goto error_add_dev;
		}

		sfr_info->str = kzalloc(mhi_cntrl->sfr_len, GFP_KERNEL);
		if (!sfr_info->str) {
			ret = -ENOMEM;
			goto error_alloc_sfr;
		}

		sfr_info->len = mhi_cntrl->sfr_len;
		mhi_cntrl->mhi_sfr = sfr_info;
	}

	mhi_cntrl->parent = debugfs_lookup(mhi_bus_type.name, NULL);
	mhi_cntrl->klog_lvl = MHI_MSG_LVL_ERROR;

@@ -1449,6 +1518,9 @@ int of_register_mhi_controller(struct mhi_controller *mhi_cntrl)

	return 0;

error_alloc_sfr:
	kfree(sfr_info);

error_add_dev:
	mhi_dealloc_device(mhi_cntrl, mhi_dev);

@@ -1466,12 +1538,18 @@ EXPORT_SYMBOL(of_register_mhi_controller);
void mhi_unregister_mhi_controller(struct mhi_controller *mhi_cntrl)
{
	struct mhi_device *mhi_dev = mhi_cntrl->mhi_dev;
	struct mhi_sfr_info *sfr_info = mhi_cntrl->mhi_sfr;

	kfree(mhi_cntrl->mhi_cmd);
	kfree(mhi_cntrl->mhi_event);
	kfree(mhi_cntrl->mhi_chan);
	kfree(mhi_cntrl->mhi_tsync);

	if (sfr_info) {
		kfree(sfr_info->str);
		kfree(sfr_info);
	}

	device_del(&mhi_dev->dev);
	put_device(&mhi_dev->dev);

Loading