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

Commit 0901f3e8 authored by Anirudh Ghayal's avatar Anirudh Ghayal Committed by Gerrit - the friendly Code Review server
Browse files

regulator: cpr-regulator: Add support for mem-acc regulator requests



The memory accelerator controls delays while accessing
memories. These delays vary based on the power-mode.
Provide the power-mode (corner) information from CPR
to the memory accelerator driver through the regulator
interface.

Change-Id: I9c13df1695d760aa7b4797f3ba5dc65590cf21e6
Signed-off-by: default avatarAnirudh Ghayal <aghayal@codeaurora.org>
parent ced3bc99
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -275,6 +275,9 @@ Optional properties:
- qcom,cpr-init-voltage-step:	The voltage step size in microvolts of the CPR initial voltage fuses described by the
				qcom,cpr-fuse-init-voltage property.
				This property is required if qcom,cpr-fuse-init-voltage is present.
- mem-acc-supply:		Regulator to vote for the memory accelerator configuration.
				Not Present: memory accelerator configuration not supported.

Example:
	apc_vreg_corner: regulator@f9018000 {
		status = "okay";
+39 −7
Original line number Diff line number Diff line
@@ -189,6 +189,9 @@ struct cpr_regulator {
	int			vdd_mx_vmin;
	int			vdd_mx_corner_map[CPR_FUSE_CORNER_MAX];

	/* mem-acc regulator */
	struct regulator	*mem_acc_vreg;

	/* CPR parameters */
	u64		cpr_fuse_bits;
	bool		cpr_fuse_disable;
@@ -550,15 +553,15 @@ static int cpr_scale_voltage(struct cpr_regulator *cpr_vreg, int corner,
			     int new_apc_volt, enum voltage_change_dir dir)
{
	int rc = 0, vdd_mx_vmin = 0;
	int fuse_corner = cpr_vreg->corner_map[corner];

	/* No MX scaling if no vdd_mx */
	if (cpr_vreg->vdd_mx == NULL)
		dir = NO_CHANGE;

	if (dir != NO_CHANGE) {
	/* Determine the vdd_mx voltage */
	if (dir != NO_CHANGE && cpr_vreg->vdd_mx != NULL)
		vdd_mx_vmin = cpr_mx_get(cpr_vreg, corner, new_apc_volt);
	}

	if (cpr_vreg->mem_acc_vreg && dir == DOWN)
		rc = regulator_set_voltage(cpr_vreg->mem_acc_vreg,
					fuse_corner, fuse_corner);

	if (vdd_mx_vmin && dir == UP) {
		if (vdd_mx_vmin != cpr_vreg->vdd_mx_vmin)
@@ -568,6 +571,10 @@ static int cpr_scale_voltage(struct cpr_regulator *cpr_vreg, int corner,
	if (!rc)
		rc = cpr_apc_set(cpr_vreg, new_apc_volt);

	if (!rc && cpr_vreg->mem_acc_vreg && dir == UP)
		rc = regulator_set_voltage(cpr_vreg->mem_acc_vreg,
					fuse_corner, fuse_corner);

	if (!rc && vdd_mx_vmin && dir == DOWN) {
		if (vdd_mx_vmin != cpr_vreg->vdd_mx_vmin)
			rc = cpr_mx_set(cpr_vreg, corner, vdd_mx_vmin);
@@ -2145,6 +2152,25 @@ static int cpr_voltage_plan_init(struct platform_device *pdev,
	return 0;
}

static int cpr_mem_acc_init(struct platform_device *pdev,
				struct cpr_regulator *cpr_vreg)
{
	int rc;

	if (of_property_read_bool(pdev->dev.of_node, "mem-acc-supply")) {
		cpr_vreg->mem_acc_vreg = devm_regulator_get(&pdev->dev,
							"mem-acc");
		if (IS_ERR_OR_NULL(cpr_vreg->mem_acc_vreg)) {
			rc = PTR_RET(cpr_vreg->mem_acc_vreg);
			if (rc != -EPROBE_DEFER)
				pr_err("devm_regulator_get: mem-acc: rc=%d\n",
				       rc);
			return rc;
		}
	}
	return 0;
}

#if defined(CONFIG_DEBUG_FS)

static ssize_t cpr_debugfs_read(struct file *file, char __user *buff,
@@ -2291,6 +2317,12 @@ static int cpr_regulator_probe(struct platform_device *pdev)
		return -ENOMEM;
	}

	rc = cpr_mem_acc_init(pdev, cpr_vreg);
	if (rc) {
		pr_err("mem_acc intialization error rc=%d\n", rc);
		return rc;
	}

	rc = cpr_efuse_init(pdev, cpr_vreg);
	if (rc) {
		pr_err("Wrong eFuse address specified: rc=%d\n", rc);