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

Commit 56a8027c authored by Udipto Goswami's avatar Udipto Goswami
Browse files

usb: dwc3-msm: Add interconnect bus voting through dt-node



Currently, the bus votes are hardcoded in the driver,
therefore having different votes for different SOCs is
not possible as the vote values will remain the same for
all. However, it is possible to do it through dt files as
it would be different for every SOC.

Implemented this by introducing a function
dwc3_msm_interconnect_vote_populate which reads the dt
file values passed and update the existing matrix
bus_vote_values of NOM & SVS used for bus voting.

Change-Id: If22d4e98f76e2a2e7aaebfe632e20a2225e30b3c
Signed-off-by: default avatarUdipto Goswami <ugoswami@codeaurora.org>
parent 1fa28c49
Loading
Loading
Loading
Loading
+74 −1
Original line number Diff line number Diff line
@@ -298,6 +298,13 @@ enum msm_usb_irq {
	USB_MAX_IRQ
};

enum icc_paths {
	USB_DDR,
	USB_IPA,
	DDR_USB,
	USB_MAX_PATH
};

enum bus_vote {
	BUS_VOTE_NONE,
	BUS_VOTE_NOMINAL,
@@ -310,7 +317,7 @@ static const char * const icc_path_names[] = {
	"usb-ddr", "usb-ipa", "ddr-usb",
};

static const struct {
static struct {
	u32 avg, peak;
} bus_vote_values[BUS_VOTE_MAX][3] = {
	/* usb_ddr avg/peak, usb_ipa avg/peak, apps_usb avg/peak */
@@ -3889,6 +3896,68 @@ static ssize_t bus_vote_store(struct device *dev,
}
static DEVICE_ATTR_RW(bus_vote);

static int dwc3_msm_interconnect_vote_populate(struct dwc3_msm *mdwc)
{
	int ret_nom = 0, i = 0, j = 0, count = 0;
	int ret_svs = 0, ret = 0;
	u32 *vv_nom, *vv_svs;

	count = of_property_count_strings(mdwc->dev->of_node,
						"interconnect-names");
	if (count < 0) {
		dev_err(mdwc->dev, "No interconnects found.\n");
		return -EINVAL;
	}

	/* 2 signifies the two types of values avg & peak */
	vv_nom = kzalloc(count * 2 * sizeof(*vv_nom), GFP_KERNEL);
	if (!vv_nom)
		return -ENOMEM;

	vv_svs = kzalloc(count * 2 * sizeof(*vv_svs), GFP_KERNEL);
	if (!vv_svs)
		return -ENOMEM;

	/* of_property_read_u32_array returns 0 on success */
	ret_nom = of_property_read_u32_array(mdwc->dev->of_node,
				"qcom,interconnect-values-nom",
					vv_nom, count * 2);
	if (ret_nom) {
		dev_err(mdwc->dev, "Nominal values not found.\n");
		ret = ret_nom;
		goto icc_err;
	}

	ret_svs = of_property_read_u32_array(mdwc->dev->of_node,
				"qcom,interconnect-values-svs",
					vv_svs, count * 2);
	if (ret_svs) {
		dev_err(mdwc->dev, "Svs values not found.\n");
		ret = ret_svs;
		goto icc_err;
	}

	for (i = USB_DDR; i < count && i < USB_MAX_PATH; i++) {
		/* Updating votes NOMINAL */
		bus_vote_values[BUS_VOTE_NOMINAL][i].avg
						= vv_nom[j];
		bus_vote_values[BUS_VOTE_NOMINAL][i].peak
						= vv_nom[j+1];
		/* Updating votes SVS */
		bus_vote_values[BUS_VOTE_SVS][i].avg
						= vv_svs[j];
		bus_vote_values[BUS_VOTE_SVS][i].peak
						= vv_svs[j+1];
		j += 2;
	}
icc_err:
	/* freeing the temporary resource */
	kfree(vv_nom);
	kfree(vv_svs);

	return ret;
}

static int dwc_dpdm_cb(struct notifier_block *nb, unsigned long evt, void *p)
{
	struct dwc3_msm *mdwc = container_of(nb, struct dwc3_msm, dpdm_nb);
@@ -4260,6 +4329,10 @@ static int dwc3_msm_probe(struct platform_device *pdev)
		goto put_dwc3;
	}

	ret = dwc3_msm_interconnect_vote_populate(mdwc);
	if (ret)
		dev_err(&pdev->dev, "Dynamic voting failed\n");

	/* use default as nominal bus voting */
	mdwc->default_bus_vote = BUS_VOTE_NOMINAL;
	ret = of_property_read_u32(node, "qcom,default-bus-vote",