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

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

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

parents 060b3e94 56a8027c
Loading
Loading
Loading
Loading
+74 −1
Original line number Diff line number Diff line
@@ -303,6 +303,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,
@@ -315,7 +322,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 */
@@ -3948,6 +3955,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);
@@ -4319,6 +4388,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",