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

Commit bac1ddf6 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "ARM: dts: msm: Add force-enable-root-clk property to gpu_gx GDSC on msm8996"

parents b483b5d2 64bbf188
Loading
Loading
Loading
Loading
+52 −0
Original line number Original line Diff line number Diff line
Qualcomm Global Distributed Switch Controller (GDSC) Regulator Driver

The GDSC driver, implemented under the regulator framework, is responsible for
safely collapsing and restoring power to peripheral cores on chipsets like
msm8974 for power savings.

Required properties:
 - compatible:      Must be "qcom,gdsc"
 - regulator-name:  A string used as a descriptive name for regulator outputs
 - reg:             The address of the GDSCR register

Optional properties:
 - parent-supply:   phandle to the parent supply/regulator node
 - clock-names:     List of string names for core clocks
 - qcom,retain-mem:  Presence denotes a hardware requirement to leave the
		     forced core memory retention signals in the core's clock
		     branch control registers asserted.
 - qcom,retain-periph: Presence denotes a hardware requirement to leave the
		     forced periph memory retention signal in the core's clock
		     branch control registers asserted.
 - qcom,skip-logic-collapse: Presence denotes a requirement to leave power to
                             the core's logic enabled.
 - qcom,support-hw-trigger: Presence denotes a hardware feature to switch
			    on/off this regulator based on internal HW signals
			    to save more power.
 - qcom,enable-root-clk: Presence denotes that the clocks in the "clocks"
			property are required to be enabled before gdsc is
			turned on and disabled before turning off gdsc. This
			will be used in subsystems where reset is synchronous
			and root clk is active without sw being aware of its
			state. The clock-name which denotes the root clock
			should be named as "core_root_clk".
 - qcom,force-enable-root-clk: If set, denotes that the root clock should be
			force enabled before turning on the GDSC and then be
			immediately force disabled. Likewise for GDSC disable.
			This is used in cases where the core root clock needs
			to be force-enabled prior to turning on the core. The
			clock-name which denotes the root clock should be
			"core_root_clk".
 - reg-names:		Names of the bases for the above "reg" registers.
			Ex. "base", "domain_addr".
 - qcom,no-status-check-on-disable: Do not poll the status bit when GDSC
			is disabled.

Example:
	gdsc_oxili_gx: qcom,gdsc@fd8c4024 {
		compatible = "qcom,gdsc";
		regulator-name = "gdsc_oxili_gx";
		parent-supply = <&pm8841_s4>;
		reg = <0xfd8c4024 0x4>;
		clock-names = "core_clk";
	};
+1 −1
Original line number Original line Diff line number Diff line
@@ -3639,7 +3639,7 @@
	clocks = <&clock_gcc clk_gcc_mmss_bimc_gfx_clk>,
	clocks = <&clock_gcc clk_gcc_mmss_bimc_gfx_clk>,
		 <&clock_gpu clk_gpu_gx_gfx3d_clk>,
		 <&clock_gpu clk_gpu_gx_gfx3d_clk>,
		 <&clock_gpu clk_gfx3d_clk_src>;
		 <&clock_gpu clk_gfx3d_clk_src>;
	qcom,enable-root-clk;
	qcom,force-enable-root-clk;
	parent-supply = <&gfx_vreg>;
	parent-supply = <&gfx_vreg>;
	status = "ok";
	status = "ok";
};
};
+18 −4
Original line number Original line Diff line number Diff line
@@ -53,6 +53,7 @@ struct gdsc {
	bool			toggle_logic;
	bool			toggle_logic;
	bool			resets_asserted;
	bool			resets_asserted;
	bool			root_en;
	bool			root_en;
	bool			force_root_en;
	int			root_clk_idx;
	int			root_clk_idx;
	bool			no_status_check_on_disable;
	bool			no_status_check_on_disable;
	void __iomem		*domain_addr;
	void __iomem		*domain_addr;
@@ -85,7 +86,7 @@ static int gdsc_enable(struct regulator_dev *rdev)
	uint32_t regval;
	uint32_t regval;
	int i, ret;
	int i, ret;


	if (sc->root_en)
	if (sc->root_en || sc->force_root_en)
		clk_prepare_enable(sc->clocks[sc->root_clk_idx]);
		clk_prepare_enable(sc->clocks[sc->root_clk_idx]);


	if (sc->toggle_logic) {
	if (sc->toggle_logic) {
@@ -147,6 +148,12 @@ static int gdsc_enable(struct regulator_dev *rdev)
	 */
	 */
	udelay(1);
	udelay(1);


	/* Delay to account for staggered memory powerup. */
	udelay(1);

	if (sc->force_root_en)
		clk_disable_unprepare(sc->clocks[sc->root_clk_idx]);

	return 0;
	return 0;
}
}


@@ -156,6 +163,9 @@ static int gdsc_disable(struct regulator_dev *rdev)
	uint32_t regval;
	uint32_t regval;
	int i, ret = 0;
	int i, ret = 0;


	if (sc->force_root_en)
		clk_prepare_enable(sc->clocks[sc->root_clk_idx]);

	for (i = sc->clock_count-1; i >= 0; i--) {
	for (i = sc->clock_count-1; i >= 0; i--) {
		if (unlikely(i == sc->root_clk_idx))
		if (unlikely(i == sc->root_clk_idx))
			continue;
			continue;
@@ -165,6 +175,9 @@ static int gdsc_disable(struct regulator_dev *rdev)
			clk_set_flags(sc->clocks[i], CLKFLAG_NORETAIN_PERIPH);
			clk_set_flags(sc->clocks[i], CLKFLAG_NORETAIN_PERIPH);
	}
	}


	/* Delay to account for staggered memory powerdown. */
	udelay(1);

	if (sc->toggle_logic) {
	if (sc->toggle_logic) {
		regval = readl_relaxed(sc->gdscr);
		regval = readl_relaxed(sc->gdscr);
		if (regval & HW_CONTROL_MASK) {
		if (regval & HW_CONTROL_MASK) {
@@ -207,7 +220,7 @@ static int gdsc_disable(struct regulator_dev *rdev)
		sc->resets_asserted = true;
		sc->resets_asserted = true;
	}
	}


	if (sc->root_en)
	if (sc->root_en || sc->force_root_en)
		clk_disable_unprepare(sc->clocks[sc->root_clk_idx]);
		clk_disable_unprepare(sc->clocks[sc->root_clk_idx]);


	return ret;
	return ret;
@@ -356,7 +369,8 @@ static int gdsc_probe(struct platform_device *pdev)


	sc->root_en = of_property_read_bool(pdev->dev.of_node,
	sc->root_en = of_property_read_bool(pdev->dev.of_node,
						"qcom,enable-root-clk");
						"qcom,enable-root-clk");

	sc->force_root_en = of_property_read_bool(pdev->dev.of_node,
						"qcom,force-enable-root-clk");
	for (i = 0; i < sc->clock_count; i++) {
	for (i = 0; i < sc->clock_count; i++) {
		const char *clock_name;
		const char *clock_name;
		of_property_read_string_index(pdev->dev.of_node, "clock-names",
		of_property_read_string_index(pdev->dev.of_node, "clock-names",
@@ -374,7 +388,7 @@ static int gdsc_probe(struct platform_device *pdev)
			sc->root_clk_idx = i;
			sc->root_clk_idx = i;
	}
	}


	if (sc->root_en && (sc->root_clk_idx == -1)) {
	if ((sc->root_en || sc->force_root_en) && (sc->root_clk_idx == -1)) {
		dev_err(&pdev->dev, "Failed to get root clock name\n");
		dev_err(&pdev->dev, "Failed to get root clock name\n");
		return -EINVAL;
		return -EINVAL;
	}
	}