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

Commit be964309 authored by Kyle Yan's avatar Kyle Yan Committed by Gerrit - the friendly Code Review server
Browse files

Merge "clk: qcom: gdsc-regulator: Add the qcom,poll-cfg-gdscr flag" into msm-4.8

parents 6ff6fd55 522c8036
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -56,6 +56,9 @@ Optional properties:
 - reset-names: reset signal name strings sorted in the same order as the resets
			property. These can be supplied only if we support
			qcom,skip-logic-collapse.
 - qcom,poll-cfg-gdscr:	Poll the CFG register of the GDSC to determine if the
			GDSC is enabled/disabled. This flag should not be set
			in conjunction with "hw-ctrl-addr".

Example:
	gdsc_oxili_gx: qcom,gdsc@fd8c4024 {
+66 −10
Original line number Diff line number Diff line
@@ -36,6 +36,10 @@
#define HW_CONTROL_MASK		BIT(1)
#define SW_COLLAPSE_MASK	BIT(0)

/* CFG_GDSCR */
#define GDSC_POWER_UP_COMPLETE		BIT(16)
#define GDSC_POWER_DOWN_COMPLETE	BIT(15)

/* Domain Address */
#define GMEM_CLAMP_IO_MASK	BIT(0)
#define GMEM_RESET_MASK         BIT(4)
@@ -45,6 +49,7 @@

/* Register Offset */
#define REG_OFFSET		0x0
#define CFG_GDSCR_OFFSET	0x4

/* Timeout Delay */
#define TIMEOUT_US		100
@@ -69,6 +74,7 @@ struct gdsc {
	bool			is_gdsc_enabled;
	bool			allow_clear;
	bool			reset_aon;
	bool			poll_cfg_gdscr;
	int			clock_count;
	int			reset_count;
	int			root_clk_idx;
@@ -128,6 +134,31 @@ static int poll_gdsc_status(struct gdsc *sc, enum gdscr_status status)
	return -ETIMEDOUT;
}

static int poll_cfg_gdsc_status(struct gdsc *sc, enum gdscr_status status)
{
	struct regmap *regmap = sc->regmap;
	int count = sc->gds_timeout;
	u32 val;

	for (; count > 0; count--) {
		regmap_read(regmap, CFG_GDSCR_OFFSET, &val);

		switch (status) {
		case ENABLED:
			if (val & GDSC_POWER_UP_COMPLETE)
				return 0;
			break;
		case DISABLED:
			if (val & GDSC_POWER_DOWN_COMPLETE)
				return 0;
			break;
		}
		udelay(1);
	}

	return -ETIMEDOUT;
}

static int gdsc_is_enabled(struct regulator_dev *rdev)
{
	struct gdsc *sc = rdev_get_drvdata(rdev);
@@ -154,7 +185,7 @@ static int gdsc_is_enabled(struct regulator_dev *rdev)
static int gdsc_enable(struct regulator_dev *rdev)
{
	struct gdsc *sc = rdev_get_drvdata(rdev);
	uint32_t regval, hw_ctrl_regval = 0x0;
	uint32_t regval, cfg_regval, hw_ctrl_regval = 0x0;
	int i, ret = 0;

	mutex_lock(&gdsc_seq_lock);
@@ -230,6 +261,9 @@ static int gdsc_enable(struct regulator_dev *rdev)
		mb();
		udelay(1);

		if (sc->poll_cfg_gdscr)
			ret = poll_cfg_gdsc_status(sc, ENABLED);
		else
			ret = poll_gdsc_status(sc, ENABLED);
		if (ret) {
			regmap_read(sc->regmap, REG_OFFSET, &regval);
@@ -260,11 +294,21 @@ static int gdsc_enable(struct regulator_dev *rdev)
					regval);
				udelay(sc->gds_timeout);

				regmap_read(sc->regmap, REG_OFFSET, &regval);
				if (sc->poll_cfg_gdscr) {
					regmap_read(sc->regmap, REG_OFFSET,
							&regval);
					regmap_read(sc->regmap,
						CFG_GDSCR_OFFSET, &cfg_regval);
					dev_err(&rdev->dev, "%s final state: gdscr - 0x%x, cfg_gdscr - 0x%x (%d us after timeout)\n",
						sc->rdesc.name, regval,
						cfg_regval, sc->gds_timeout);
				} else {
					regmap_read(sc->regmap, REG_OFFSET,
							&regval);
					dev_err(&rdev->dev, "%s final state: 0x%x (%d us after timeout)\n",
						sc->rdesc.name, regval,
						sc->gds_timeout);

				}
				mutex_unlock(&gdsc_seq_lock);

				return ret;
@@ -346,6 +390,9 @@ static int gdsc_disable(struct regulator_dev *rdev)
			 */
			udelay(TIMEOUT_US);
		} else {
			if (sc->poll_cfg_gdscr)
				ret = poll_cfg_gdsc_status(sc, DISABLED);
			else
				ret = poll_gdsc_status(sc, DISABLED);
			if (ret)
				dev_err(&rdev->dev, "%s disable timed out: 0x%x\n",
@@ -434,6 +481,9 @@ static int gdsc_set_mode(struct regulator_dev *rdev, unsigned int mode)
		mb();
		udelay(1);

		if (sc->poll_cfg_gdscr)
			ret = poll_cfg_gdsc_status(sc, ENABLED);
		else
			ret = poll_gdsc_status(sc, ENABLED);
		if (ret)
			dev_err(&rdev->dev, "%s set_mode timed out: 0x%x\n",
@@ -531,6 +581,9 @@ static int gdsc_probe(struct platform_device *pdev)
			return -ENODEV;
	}

	sc->poll_cfg_gdscr = of_property_read_bool(pdev->dev.of_node,
						"qcom,poll-cfg-gdscr");

	sc->gds_timeout = TIMEOUT_US;

	ret = of_property_read_u32(pdev->dev.of_node, "qcom,gds-timeout",
@@ -667,6 +720,9 @@ static int gdsc_probe(struct platform_device *pdev)
		regval &= ~SW_COLLAPSE_MASK;
		regmap_write(sc->regmap, REG_OFFSET, regval);

		if (sc->poll_cfg_gdscr)
			ret = poll_cfg_gdsc_status(sc, ENABLED);
		else
			ret = poll_gdsc_status(sc, ENABLED);
		if (ret) {
			dev_err(&pdev->dev, "%s enable timed out: 0x%x\n",