All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/4] Support qcom GDSC hardware
@ 2014-04-04 18:45 ` Stephen Boyd
  0 siblings, 0 replies; 21+ messages in thread
From: Stephen Boyd @ 2014-04-04 18:45 UTC (permalink / raw)
  To: Mike Turquette
  Cc: linux-kernel, linux-arm-msm, linux-arm-kernel, Mark Brown,
	Saravana Kannan, Kumar Gala, Matt Wagantall

These patches add support for the multimedia GDSCs on the
apq8074 dragonboard. The first two patches (and potentially the last)
should go through Mike's tree and the DTS patch should go through
the qcom tree. Patches are based on v3.14. The probe will conflict with
patches I sent to consolidate things. I'll rework these patches on top of
that if the gdsc.c file is acked/reviewed.

Stephen Boyd (4):
  clk: qcom: Add support for GDSCs
  clk: qcom: Add GDSCs within 8974 multimedia clock controller
  ARM: dts: qcom: Add GDSC nodes underneath clock controller
  devicetree: bindings: qcom,mmcc: Document GDSC binding

 .../devicetree/bindings/clock/qcom,mmcc.txt        |  42 +++
 arch/arm/boot/dts/qcom-apq8074-dragonboard.dts     |  18 +
 arch/arm/boot/dts/qcom-msm8974.dtsi                |  26 ++
 drivers/clk/qcom/Makefile                          |   1 +
 drivers/clk/qcom/gdsc.c                            | 361 +++++++++++++++++++++
 drivers/clk/qcom/gdsc.h                            |  32 ++
 drivers/clk/qcom/mmcc-msm8974.c                    |  86 ++++-
 7 files changed, 564 insertions(+), 2 deletions(-)
 create mode 100644 drivers/clk/qcom/gdsc.c
 create mode 100644 drivers/clk/qcom/gdsc.h

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 0/4] Support qcom GDSC hardware
@ 2014-04-04 18:45 ` Stephen Boyd
  0 siblings, 0 replies; 21+ messages in thread
From: Stephen Boyd @ 2014-04-04 18:45 UTC (permalink / raw)
  To: linux-arm-kernel

These patches add support for the multimedia GDSCs on the
apq8074 dragonboard. The first two patches (and potentially the last)
should go through Mike's tree and the DTS patch should go through
the qcom tree. Patches are based on v3.14. The probe will conflict with
patches I sent to consolidate things. I'll rework these patches on top of
that if the gdsc.c file is acked/reviewed.

Stephen Boyd (4):
  clk: qcom: Add support for GDSCs
  clk: qcom: Add GDSCs within 8974 multimedia clock controller
  ARM: dts: qcom: Add GDSC nodes underneath clock controller
  devicetree: bindings: qcom,mmcc: Document GDSC binding

 .../devicetree/bindings/clock/qcom,mmcc.txt        |  42 +++
 arch/arm/boot/dts/qcom-apq8074-dragonboard.dts     |  18 +
 arch/arm/boot/dts/qcom-msm8974.dtsi                |  26 ++
 drivers/clk/qcom/Makefile                          |   1 +
 drivers/clk/qcom/gdsc.c                            | 361 +++++++++++++++++++++
 drivers/clk/qcom/gdsc.h                            |  32 ++
 drivers/clk/qcom/mmcc-msm8974.c                    |  86 ++++-
 7 files changed, 564 insertions(+), 2 deletions(-)
 create mode 100644 drivers/clk/qcom/gdsc.c
 create mode 100644 drivers/clk/qcom/gdsc.h

-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 1/4] clk: qcom: Add support for GDSCs
  2014-04-04 18:45 ` Stephen Boyd
  (?)
@ 2014-04-04 18:45   ` Stephen Boyd
  -1 siblings, 0 replies; 21+ messages in thread
From: Stephen Boyd @ 2014-04-04 18:45 UTC (permalink / raw)
  To: Mike Turquette
  Cc: Saravana Kannan, linux-arm-msm, linux-kernel, Mark Brown,
	Matt Wagantall, linux-arm-kernel

GDSCs (Global Distributed Switch Controllers) are responsible for
safely collapsing and restoring power to peripherals in the SoC.
Add support for these controllers to the clock driver as the
registers are scattered throughout the clock controller register
space.

This is largely based on code originally written by Matt
Wagantall[1].

[1] https://www.codeaurora.org/cgit/quic/la/kernel/msm/tree/arch/arm/mach-msm/gdsc.c?h=msm-3.4
Cc: Matt Wagantall <mattw@codeaurora.org>
Cc: Mark Brown <broonie@kernel.org>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 drivers/clk/qcom/Makefile |   1 +
 drivers/clk/qcom/gdsc.c   | 361 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/qcom/gdsc.h   |  32 ++++
 3 files changed, 394 insertions(+)
 create mode 100644 drivers/clk/qcom/gdsc.c
 create mode 100644 drivers/clk/qcom/gdsc.h

diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index f60db2ef1aee..2bc09576990a 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -6,6 +6,7 @@ clk-qcom-y += clk-rcg.o
 clk-qcom-y += clk-rcg2.o
 clk-qcom-y += clk-branch.o
 clk-qcom-y += reset.o
+clk-qcom-y += gdsc.o
 
 obj-$(CONFIG_MSM_GCC_8660) += gcc-msm8660.o
 obj-$(CONFIG_MSM_GCC_8960) += gcc-msm8960.o
diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
new file mode 100644
index 000000000000..a885fe4bdf38
--- /dev/null
+++ b/drivers/clk/qcom/gdsc.c
@@ -0,0 +1,361 @@
+/*
+ * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/export.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/slab.h>
+#include <linux/reset-controller.h>
+#include <linux/regmap.h>
+
+#include "gdsc.h"
+
+#define PWR_ON_MASK		BIT(31)
+#define EN_REST_WAIT_MASK	(0xF << 20)
+#define EN_FEW_WAIT_MASK	(0xF << 16)
+#define CLK_DIS_WAIT_MASK	(0xF << 12)
+#define SW_OVERRIDE_MASK	BIT(2)
+#define HW_CONTROL_MASK		BIT(1)
+#define SW_COLLAPSE_MASK	BIT(0)
+
+/* Wait 2^n CXO cycles between all states. Here, n=2 (4 cycles). */
+#define EN_REST_WAIT_VAL	(0x2 << 20)
+#define EN_FEW_WAIT_VAL		(0x8 << 16)
+#define CLK_DIS_WAIT_VAL	(0x2 << 12)
+
+#define RETAIN_MEM		BIT(14)
+#define RETAIN_PERIPH		BIT(13)
+
+#define TIMEOUT_US		100
+
+struct gdsc {
+	struct regulator_dev	*rdev;
+	struct regulator_desc	rdesc;
+	struct reset_controller_dev *rcdev;
+	struct regmap		*regmap;
+	u32			gdscr;
+	unsigned int		*cxcs;
+	int			cxc_count;
+	unsigned int		*resets;
+	int			reset_count;
+	bool			toggle_mem;
+	bool			toggle_periph;
+	bool			toggle_logic;
+	bool			resets_asserted;
+};
+
+static int gdsc_is_enabled(struct regulator_dev *rdev)
+{
+	unsigned int val;
+	struct gdsc *sc = rdev_get_drvdata(rdev);
+
+	if (!sc->toggle_logic)
+		return !sc->resets_asserted;
+
+	regmap_read(sc->regmap, sc->gdscr, &val);
+	return !!(val & PWR_ON_MASK);
+}
+
+static int gdsc_poll_enable(struct gdsc *sc, bool en)
+{
+	unsigned long timeout;
+	unsigned int val;
+	unsigned int check = en ? PWR_ON_MASK : 0;
+
+	timeout = jiffies + usecs_to_jiffies(TIMEOUT_US);
+	do {
+		regmap_read(sc->regmap, sc->gdscr, &val);
+		if ((val & PWR_ON_MASK) == check)
+			return 0;
+	} while (time_before(jiffies, timeout));
+
+	regmap_read(sc->regmap, sc->gdscr, &val);
+	if ((val & PWR_ON_MASK) == check)
+		return 0;
+
+	pr_err("%s %s timed out\n", en ? "enabling" : "disabling",
+	       sc->rdesc.name);
+	return -ETIMEDOUT;
+}
+
+static int gdsc_toggle_logic(struct gdsc *sc, bool en)
+{
+	int ret;
+	u32 val;
+
+	regmap_read(sc->regmap, sc->gdscr, &val);
+	if (val & HW_CONTROL_MASK) {
+		dev_warn(&sc->rdev->dev,
+			"Invalid %s while %s is under HW control\n",
+			en ? "enable" : "disable", sc->rdesc.name);
+		return -EBUSY;
+	}
+
+	val = en ? 0 : SW_COLLAPSE_MASK;
+	ret = regmap_update_bits(sc->regmap, sc->gdscr, SW_COLLAPSE_MASK, val);
+	if (ret)
+		return ret;
+
+	return gdsc_poll_enable(sc, en);
+}
+
+static int gdsc_enable(struct regulator_dev *rdev)
+{
+	struct gdsc *sc = rdev_get_drvdata(rdev);
+	u32 mask;
+	int i, ret;
+
+	if (sc->toggle_logic) {
+		ret = gdsc_toggle_logic(sc, true);
+		if (ret)
+			return ret;
+	} else {
+		for (i = 0; i < sc->reset_count; i++)
+			sc->rcdev->ops->deassert(sc->rcdev, sc->resets[i]);
+		sc->resets_asserted = false;
+	}
+
+
+	for (i = 0; i < sc->cxc_count; i++) {
+		mask = 0;
+		if (sc->toggle_mem) {
+			mask |= RETAIN_MEM;
+			regmap_update_bits(sc->regmap, sc->cxcs[i], mask, mask);
+		}
+		udelay(1);
+		if (sc->toggle_periph) {
+			mask |= RETAIN_PERIPH;
+			regmap_update_bits(sc->regmap, sc->cxcs[i], mask, mask);
+		}
+	}
+
+	/*
+	 * If clocks to this power domain were already on, they will take an
+	 * additional 4 clock cycles to re-enable after the rail is enabled.
+	 * Delay to account for this. A delay is also needed to ensure clocks
+	 * are not enabled within 400ns of enabling power to the memories.
+	 */
+	udelay(1);
+
+	return 0;
+}
+
+static int gdsc_disable(struct regulator_dev *rdev)
+{
+	struct gdsc *sc = rdev_get_drvdata(rdev);
+	u32 mask = 0;
+	int i, ret = 0;
+
+	if (sc->toggle_mem)
+		mask |= RETAIN_MEM;
+	if (sc->toggle_periph)
+		mask |= RETAIN_PERIPH;
+
+	for (i = sc->cxc_count - 1; i >= 0; i--)
+		regmap_update_bits(sc->regmap, sc->cxcs[i], mask, 0);
+
+	if (sc->toggle_logic) {
+		ret = gdsc_toggle_logic(sc, false);
+		if (ret)
+			return ret;
+	} else {
+		for (i = sc->reset_count - 1; i >= 0; i--)
+			sc->rcdev->ops->assert(sc->rcdev, sc->resets[i]);
+		sc->resets_asserted = true;
+	}
+
+	return ret;
+}
+
+static unsigned int gdsc_get_mode(struct regulator_dev *rdev)
+{
+	struct gdsc *sc = rdev_get_drvdata(rdev);
+	unsigned int val;
+
+	regmap_read(sc->regmap, sc->gdscr, &val);
+	if (val & HW_CONTROL_MASK)
+		return REGULATOR_MODE_FAST;
+	return REGULATOR_MODE_NORMAL;
+}
+
+static int gdsc_set_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+	struct gdsc *sc = rdev_get_drvdata(rdev);
+	unsigned int val;
+	int ret;
+
+	regmap_read(sc->regmap, sc->gdscr, &val);
+
+	/*
+	 * HW control can only be enable/disabled when SW_COLLAPSE
+	 * indicates on.
+	 */
+	if (val & SW_COLLAPSE_MASK) {
+		dev_err(&rdev->dev, "can't enable hw collapse now\n");
+		return -EBUSY;
+	}
+
+	switch (mode) {
+	case REGULATOR_MODE_FAST:
+		/* Turn on HW trigger mode */
+		val |= HW_CONTROL_MASK;
+		regmap_write(sc->regmap, sc->gdscr, val);
+		/*
+		 * There may be a race with internal HW trigger signal,
+		 * that will result in GDSC going through a power down and
+		 * up cycle.  In case HW trigger signal is controlled by
+		 * firmware that also poll same status bits as we do, FW
+		 * might read an 'on' status before the GDSC can finish
+		 * power cycle.  We wait 1us before returning to ensure
+		 * FW can't immediately poll the status bit.
+		 */
+		mb();
+		udelay(1);
+		break;
+
+	case REGULATOR_MODE_NORMAL:
+		/* Turn off HW trigger mode */
+		val &= ~HW_CONTROL_MASK;
+		regmap_write(sc->regmap, sc->gdscr, val);
+		/*
+		 * There may be a race with internal HW trigger signal,
+		 * that will result in GDSC going through a power down and
+		 * up cycle.  If we poll too early, status bit will
+		 * indicate 'on' before the GDSC can finish the power cycle.
+		 * Account for this case by waiting 1us before polling.
+		 */
+		mb();
+		udelay(1);
+		ret = gdsc_poll_enable(sc, true);
+		if (ret) {
+			dev_err(&rdev->dev, "%s set_mode timed out\n",
+				sc->rdesc.name);
+			return ret;
+		}
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static struct regulator_ops gdsc_ops = {
+	.is_enabled = gdsc_is_enabled,
+	.enable = gdsc_enable,
+	.disable = gdsc_disable,
+	.set_mode = gdsc_set_mode,
+	.get_mode = gdsc_get_mode,
+};
+
+int gdsc_register(struct device *pdev, struct of_regulator_match *match,
+		  struct reset_controller_dev *rcdev)
+{
+	static atomic_t gdsc_count = ATOMIC_INIT(-1);
+	struct regulator_config reg_config = {};
+	struct regulator_init_data *init_data;
+	struct gdsc *sc;
+	unsigned int val, mask;
+	bool retain_mem, retain_periph, support_hw_trigger;
+	int i, ret;
+	struct device_node *np;
+	struct gdsc_desc *desc;
+
+	sc = devm_kzalloc(pdev, sizeof(*sc), GFP_KERNEL);
+	if (!sc)
+		return -ENOMEM;
+
+	np = match->of_node;
+	desc = match->driver_data;
+	init_data = match->init_data;
+
+	if (of_get_property(np, "parent-supply", NULL))
+		init_data->supply_regulator = "parent";
+
+	ret = of_property_read_string(np, "regulator-name", &sc->rdesc.name);
+	if (ret)
+		return ret;
+
+	sc->regmap = dev_get_regmap(pdev, NULL);
+	sc->gdscr = desc->gdscr;
+	sc->cxcs = desc->cxcs;
+	sc->cxc_count = desc->cxc_count;
+	sc->resets = desc->resets;
+	sc->reset_count = desc->reset_count;
+	sc->rcdev = rcdev;
+
+	sc->rdesc.id = atomic_inc_return(&gdsc_count);
+	sc->rdesc.ops = &gdsc_ops;
+	sc->rdesc.type = REGULATOR_VOLTAGE;
+	sc->rdesc.owner = THIS_MODULE;
+
+	/*
+	 * Disable HW trigger: collapse/restore occur based on registers writes.
+	 * Disable SW override: Use hardware state-machine for sequencing.
+	 * Configure wait time between states.
+	 */
+	mask = HW_CONTROL_MASK | SW_OVERRIDE_MASK |
+	       EN_REST_WAIT_MASK | EN_FEW_WAIT_MASK | CLK_DIS_WAIT_MASK;
+	val = EN_REST_WAIT_VAL | EN_FEW_WAIT_VAL | CLK_DIS_WAIT_VAL;
+	regmap_update_bits(sc->regmap, sc->gdscr, mask, val);
+
+	retain_mem = of_property_read_bool(np, "qcom,retain-mem");
+	sc->toggle_mem = !retain_mem;
+	retain_periph = of_property_read_bool(np, "qcom,retain-periph");
+	sc->toggle_periph = !retain_periph;
+	sc->toggle_logic = !of_property_read_bool(np,
+						"qcom,skip-logic-collapse");
+	support_hw_trigger = of_property_read_bool(np,
+						    "qcom,support-hw-trigger");
+	if (support_hw_trigger) {
+		init_data->constraints.valid_ops_mask |= REGULATOR_CHANGE_MODE;
+		init_data->constraints.valid_modes_mask |=
+				REGULATOR_MODE_NORMAL | REGULATOR_MODE_FAST;
+	}
+
+	if (!sc->toggle_logic) {
+		ret = gdsc_toggle_logic(sc, true);
+		if (ret)
+			return ret;
+	}
+
+	regmap_read(sc->regmap, sc->gdscr, &val);
+	mask = RETAIN_MEM | RETAIN_PERIPH;
+	val = 0;
+	if (retain_mem || (val & PWR_ON_MASK))
+		val |= RETAIN_MEM;
+	if (retain_periph || (val & PWR_ON_MASK))
+		val |= RETAIN_PERIPH;
+
+	for (i = 0; i < sc->cxc_count; i++)
+		regmap_update_bits(sc->regmap, sc->cxcs[i], mask, val);
+
+	reg_config.dev = pdev;
+	reg_config.init_data = init_data;
+	reg_config.driver_data = sc;
+	reg_config.of_node = np;
+	sc->rdev = devm_regulator_register(pdev, &sc->rdesc, &reg_config);
+	if (IS_ERR(sc->rdev)) {
+		dev_err(pdev, "regulator_register(\"%s\") failed.\n",
+			sc->rdesc.name);
+		return PTR_ERR(sc->rdev);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(gdsc_register);
diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
new file mode 100644
index 000000000000..bd034c5071a9
--- /dev/null
+++ b/drivers/clk/qcom/gdsc.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __QCOM_GDSC_H__
+#define __QCOM_GDSC_H__
+
+struct device;
+struct device_node;
+struct of_regulator_match;
+
+struct gdsc_desc {
+	unsigned int gdscr;
+	unsigned int *cxcs;
+	int cxc_count;
+	unsigned int *resets;
+	int reset_count;
+};
+
+extern int gdsc_register(struct device *pdev, struct of_regulator_match *match,
+			 struct reset_controller_dev *rcdev);
+
+#endif
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 1/4] clk: qcom: Add support for GDSCs
@ 2014-04-04 18:45   ` Stephen Boyd
  0 siblings, 0 replies; 21+ messages in thread
From: Stephen Boyd @ 2014-04-04 18:45 UTC (permalink / raw)
  To: Mike Turquette
  Cc: linux-kernel, linux-arm-msm, linux-arm-kernel, Mark Brown,
	Saravana Kannan, Matt Wagantall

GDSCs (Global Distributed Switch Controllers) are responsible for
safely collapsing and restoring power to peripherals in the SoC.
Add support for these controllers to the clock driver as the
registers are scattered throughout the clock controller register
space.

This is largely based on code originally written by Matt
Wagantall[1].

[1] https://www.codeaurora.org/cgit/quic/la/kernel/msm/tree/arch/arm/mach-msm/gdsc.c?h=msm-3.4
Cc: Matt Wagantall <mattw@codeaurora.org>
Cc: Mark Brown <broonie@kernel.org>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 drivers/clk/qcom/Makefile |   1 +
 drivers/clk/qcom/gdsc.c   | 361 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/qcom/gdsc.h   |  32 ++++
 3 files changed, 394 insertions(+)
 create mode 100644 drivers/clk/qcom/gdsc.c
 create mode 100644 drivers/clk/qcom/gdsc.h

diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index f60db2ef1aee..2bc09576990a 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -6,6 +6,7 @@ clk-qcom-y += clk-rcg.o
 clk-qcom-y += clk-rcg2.o
 clk-qcom-y += clk-branch.o
 clk-qcom-y += reset.o
+clk-qcom-y += gdsc.o
 
 obj-$(CONFIG_MSM_GCC_8660) += gcc-msm8660.o
 obj-$(CONFIG_MSM_GCC_8960) += gcc-msm8960.o
diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
new file mode 100644
index 000000000000..a885fe4bdf38
--- /dev/null
+++ b/drivers/clk/qcom/gdsc.c
@@ -0,0 +1,361 @@
+/*
+ * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/export.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/slab.h>
+#include <linux/reset-controller.h>
+#include <linux/regmap.h>
+
+#include "gdsc.h"
+
+#define PWR_ON_MASK		BIT(31)
+#define EN_REST_WAIT_MASK	(0xF << 20)
+#define EN_FEW_WAIT_MASK	(0xF << 16)
+#define CLK_DIS_WAIT_MASK	(0xF << 12)
+#define SW_OVERRIDE_MASK	BIT(2)
+#define HW_CONTROL_MASK		BIT(1)
+#define SW_COLLAPSE_MASK	BIT(0)
+
+/* Wait 2^n CXO cycles between all states. Here, n=2 (4 cycles). */
+#define EN_REST_WAIT_VAL	(0x2 << 20)
+#define EN_FEW_WAIT_VAL		(0x8 << 16)
+#define CLK_DIS_WAIT_VAL	(0x2 << 12)
+
+#define RETAIN_MEM		BIT(14)
+#define RETAIN_PERIPH		BIT(13)
+
+#define TIMEOUT_US		100
+
+struct gdsc {
+	struct regulator_dev	*rdev;
+	struct regulator_desc	rdesc;
+	struct reset_controller_dev *rcdev;
+	struct regmap		*regmap;
+	u32			gdscr;
+	unsigned int		*cxcs;
+	int			cxc_count;
+	unsigned int		*resets;
+	int			reset_count;
+	bool			toggle_mem;
+	bool			toggle_periph;
+	bool			toggle_logic;
+	bool			resets_asserted;
+};
+
+static int gdsc_is_enabled(struct regulator_dev *rdev)
+{
+	unsigned int val;
+	struct gdsc *sc = rdev_get_drvdata(rdev);
+
+	if (!sc->toggle_logic)
+		return !sc->resets_asserted;
+
+	regmap_read(sc->regmap, sc->gdscr, &val);
+	return !!(val & PWR_ON_MASK);
+}
+
+static int gdsc_poll_enable(struct gdsc *sc, bool en)
+{
+	unsigned long timeout;
+	unsigned int val;
+	unsigned int check = en ? PWR_ON_MASK : 0;
+
+	timeout = jiffies + usecs_to_jiffies(TIMEOUT_US);
+	do {
+		regmap_read(sc->regmap, sc->gdscr, &val);
+		if ((val & PWR_ON_MASK) == check)
+			return 0;
+	} while (time_before(jiffies, timeout));
+
+	regmap_read(sc->regmap, sc->gdscr, &val);
+	if ((val & PWR_ON_MASK) == check)
+		return 0;
+
+	pr_err("%s %s timed out\n", en ? "enabling" : "disabling",
+	       sc->rdesc.name);
+	return -ETIMEDOUT;
+}
+
+static int gdsc_toggle_logic(struct gdsc *sc, bool en)
+{
+	int ret;
+	u32 val;
+
+	regmap_read(sc->regmap, sc->gdscr, &val);
+	if (val & HW_CONTROL_MASK) {
+		dev_warn(&sc->rdev->dev,
+			"Invalid %s while %s is under HW control\n",
+			en ? "enable" : "disable", sc->rdesc.name);
+		return -EBUSY;
+	}
+
+	val = en ? 0 : SW_COLLAPSE_MASK;
+	ret = regmap_update_bits(sc->regmap, sc->gdscr, SW_COLLAPSE_MASK, val);
+	if (ret)
+		return ret;
+
+	return gdsc_poll_enable(sc, en);
+}
+
+static int gdsc_enable(struct regulator_dev *rdev)
+{
+	struct gdsc *sc = rdev_get_drvdata(rdev);
+	u32 mask;
+	int i, ret;
+
+	if (sc->toggle_logic) {
+		ret = gdsc_toggle_logic(sc, true);
+		if (ret)
+			return ret;
+	} else {
+		for (i = 0; i < sc->reset_count; i++)
+			sc->rcdev->ops->deassert(sc->rcdev, sc->resets[i]);
+		sc->resets_asserted = false;
+	}
+
+
+	for (i = 0; i < sc->cxc_count; i++) {
+		mask = 0;
+		if (sc->toggle_mem) {
+			mask |= RETAIN_MEM;
+			regmap_update_bits(sc->regmap, sc->cxcs[i], mask, mask);
+		}
+		udelay(1);
+		if (sc->toggle_periph) {
+			mask |= RETAIN_PERIPH;
+			regmap_update_bits(sc->regmap, sc->cxcs[i], mask, mask);
+		}
+	}
+
+	/*
+	 * If clocks to this power domain were already on, they will take an
+	 * additional 4 clock cycles to re-enable after the rail is enabled.
+	 * Delay to account for this. A delay is also needed to ensure clocks
+	 * are not enabled within 400ns of enabling power to the memories.
+	 */
+	udelay(1);
+
+	return 0;
+}
+
+static int gdsc_disable(struct regulator_dev *rdev)
+{
+	struct gdsc *sc = rdev_get_drvdata(rdev);
+	u32 mask = 0;
+	int i, ret = 0;
+
+	if (sc->toggle_mem)
+		mask |= RETAIN_MEM;
+	if (sc->toggle_periph)
+		mask |= RETAIN_PERIPH;
+
+	for (i = sc->cxc_count - 1; i >= 0; i--)
+		regmap_update_bits(sc->regmap, sc->cxcs[i], mask, 0);
+
+	if (sc->toggle_logic) {
+		ret = gdsc_toggle_logic(sc, false);
+		if (ret)
+			return ret;
+	} else {
+		for (i = sc->reset_count - 1; i >= 0; i--)
+			sc->rcdev->ops->assert(sc->rcdev, sc->resets[i]);
+		sc->resets_asserted = true;
+	}
+
+	return ret;
+}
+
+static unsigned int gdsc_get_mode(struct regulator_dev *rdev)
+{
+	struct gdsc *sc = rdev_get_drvdata(rdev);
+	unsigned int val;
+
+	regmap_read(sc->regmap, sc->gdscr, &val);
+	if (val & HW_CONTROL_MASK)
+		return REGULATOR_MODE_FAST;
+	return REGULATOR_MODE_NORMAL;
+}
+
+static int gdsc_set_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+	struct gdsc *sc = rdev_get_drvdata(rdev);
+	unsigned int val;
+	int ret;
+
+	regmap_read(sc->regmap, sc->gdscr, &val);
+
+	/*
+	 * HW control can only be enable/disabled when SW_COLLAPSE
+	 * indicates on.
+	 */
+	if (val & SW_COLLAPSE_MASK) {
+		dev_err(&rdev->dev, "can't enable hw collapse now\n");
+		return -EBUSY;
+	}
+
+	switch (mode) {
+	case REGULATOR_MODE_FAST:
+		/* Turn on HW trigger mode */
+		val |= HW_CONTROL_MASK;
+		regmap_write(sc->regmap, sc->gdscr, val);
+		/*
+		 * There may be a race with internal HW trigger signal,
+		 * that will result in GDSC going through a power down and
+		 * up cycle.  In case HW trigger signal is controlled by
+		 * firmware that also poll same status bits as we do, FW
+		 * might read an 'on' status before the GDSC can finish
+		 * power cycle.  We wait 1us before returning to ensure
+		 * FW can't immediately poll the status bit.
+		 */
+		mb();
+		udelay(1);
+		break;
+
+	case REGULATOR_MODE_NORMAL:
+		/* Turn off HW trigger mode */
+		val &= ~HW_CONTROL_MASK;
+		regmap_write(sc->regmap, sc->gdscr, val);
+		/*
+		 * There may be a race with internal HW trigger signal,
+		 * that will result in GDSC going through a power down and
+		 * up cycle.  If we poll too early, status bit will
+		 * indicate 'on' before the GDSC can finish the power cycle.
+		 * Account for this case by waiting 1us before polling.
+		 */
+		mb();
+		udelay(1);
+		ret = gdsc_poll_enable(sc, true);
+		if (ret) {
+			dev_err(&rdev->dev, "%s set_mode timed out\n",
+				sc->rdesc.name);
+			return ret;
+		}
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static struct regulator_ops gdsc_ops = {
+	.is_enabled = gdsc_is_enabled,
+	.enable = gdsc_enable,
+	.disable = gdsc_disable,
+	.set_mode = gdsc_set_mode,
+	.get_mode = gdsc_get_mode,
+};
+
+int gdsc_register(struct device *pdev, struct of_regulator_match *match,
+		  struct reset_controller_dev *rcdev)
+{
+	static atomic_t gdsc_count = ATOMIC_INIT(-1);
+	struct regulator_config reg_config = {};
+	struct regulator_init_data *init_data;
+	struct gdsc *sc;
+	unsigned int val, mask;
+	bool retain_mem, retain_periph, support_hw_trigger;
+	int i, ret;
+	struct device_node *np;
+	struct gdsc_desc *desc;
+
+	sc = devm_kzalloc(pdev, sizeof(*sc), GFP_KERNEL);
+	if (!sc)
+		return -ENOMEM;
+
+	np = match->of_node;
+	desc = match->driver_data;
+	init_data = match->init_data;
+
+	if (of_get_property(np, "parent-supply", NULL))
+		init_data->supply_regulator = "parent";
+
+	ret = of_property_read_string(np, "regulator-name", &sc->rdesc.name);
+	if (ret)
+		return ret;
+
+	sc->regmap = dev_get_regmap(pdev, NULL);
+	sc->gdscr = desc->gdscr;
+	sc->cxcs = desc->cxcs;
+	sc->cxc_count = desc->cxc_count;
+	sc->resets = desc->resets;
+	sc->reset_count = desc->reset_count;
+	sc->rcdev = rcdev;
+
+	sc->rdesc.id = atomic_inc_return(&gdsc_count);
+	sc->rdesc.ops = &gdsc_ops;
+	sc->rdesc.type = REGULATOR_VOLTAGE;
+	sc->rdesc.owner = THIS_MODULE;
+
+	/*
+	 * Disable HW trigger: collapse/restore occur based on registers writes.
+	 * Disable SW override: Use hardware state-machine for sequencing.
+	 * Configure wait time between states.
+	 */
+	mask = HW_CONTROL_MASK | SW_OVERRIDE_MASK |
+	       EN_REST_WAIT_MASK | EN_FEW_WAIT_MASK | CLK_DIS_WAIT_MASK;
+	val = EN_REST_WAIT_VAL | EN_FEW_WAIT_VAL | CLK_DIS_WAIT_VAL;
+	regmap_update_bits(sc->regmap, sc->gdscr, mask, val);
+
+	retain_mem = of_property_read_bool(np, "qcom,retain-mem");
+	sc->toggle_mem = !retain_mem;
+	retain_periph = of_property_read_bool(np, "qcom,retain-periph");
+	sc->toggle_periph = !retain_periph;
+	sc->toggle_logic = !of_property_read_bool(np,
+						"qcom,skip-logic-collapse");
+	support_hw_trigger = of_property_read_bool(np,
+						    "qcom,support-hw-trigger");
+	if (support_hw_trigger) {
+		init_data->constraints.valid_ops_mask |= REGULATOR_CHANGE_MODE;
+		init_data->constraints.valid_modes_mask |=
+				REGULATOR_MODE_NORMAL | REGULATOR_MODE_FAST;
+	}
+
+	if (!sc->toggle_logic) {
+		ret = gdsc_toggle_logic(sc, true);
+		if (ret)
+			return ret;
+	}
+
+	regmap_read(sc->regmap, sc->gdscr, &val);
+	mask = RETAIN_MEM | RETAIN_PERIPH;
+	val = 0;
+	if (retain_mem || (val & PWR_ON_MASK))
+		val |= RETAIN_MEM;
+	if (retain_periph || (val & PWR_ON_MASK))
+		val |= RETAIN_PERIPH;
+
+	for (i = 0; i < sc->cxc_count; i++)
+		regmap_update_bits(sc->regmap, sc->cxcs[i], mask, val);
+
+	reg_config.dev = pdev;
+	reg_config.init_data = init_data;
+	reg_config.driver_data = sc;
+	reg_config.of_node = np;
+	sc->rdev = devm_regulator_register(pdev, &sc->rdesc, &reg_config);
+	if (IS_ERR(sc->rdev)) {
+		dev_err(pdev, "regulator_register(\"%s\") failed.\n",
+			sc->rdesc.name);
+		return PTR_ERR(sc->rdev);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(gdsc_register);
diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
new file mode 100644
index 000000000000..bd034c5071a9
--- /dev/null
+++ b/drivers/clk/qcom/gdsc.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __QCOM_GDSC_H__
+#define __QCOM_GDSC_H__
+
+struct device;
+struct device_node;
+struct of_regulator_match;
+
+struct gdsc_desc {
+	unsigned int gdscr;
+	unsigned int *cxcs;
+	int cxc_count;
+	unsigned int *resets;
+	int reset_count;
+};
+
+extern int gdsc_register(struct device *pdev, struct of_regulator_match *match,
+			 struct reset_controller_dev *rcdev);
+
+#endif
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 1/4] clk: qcom: Add support for GDSCs
@ 2014-04-04 18:45   ` Stephen Boyd
  0 siblings, 0 replies; 21+ messages in thread
From: Stephen Boyd @ 2014-04-04 18:45 UTC (permalink / raw)
  To: linux-arm-kernel

GDSCs (Global Distributed Switch Controllers) are responsible for
safely collapsing and restoring power to peripherals in the SoC.
Add support for these controllers to the clock driver as the
registers are scattered throughout the clock controller register
space.

This is largely based on code originally written by Matt
Wagantall[1].

[1] https://www.codeaurora.org/cgit/quic/la/kernel/msm/tree/arch/arm/mach-msm/gdsc.c?h=msm-3.4
Cc: Matt Wagantall <mattw@codeaurora.org>
Cc: Mark Brown <broonie@kernel.org>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 drivers/clk/qcom/Makefile |   1 +
 drivers/clk/qcom/gdsc.c   | 361 ++++++++++++++++++++++++++++++++++++++++++++++
 drivers/clk/qcom/gdsc.h   |  32 ++++
 3 files changed, 394 insertions(+)
 create mode 100644 drivers/clk/qcom/gdsc.c
 create mode 100644 drivers/clk/qcom/gdsc.h

diff --git a/drivers/clk/qcom/Makefile b/drivers/clk/qcom/Makefile
index f60db2ef1aee..2bc09576990a 100644
--- a/drivers/clk/qcom/Makefile
+++ b/drivers/clk/qcom/Makefile
@@ -6,6 +6,7 @@ clk-qcom-y += clk-rcg.o
 clk-qcom-y += clk-rcg2.o
 clk-qcom-y += clk-branch.o
 clk-qcom-y += reset.o
+clk-qcom-y += gdsc.o
 
 obj-$(CONFIG_MSM_GCC_8660) += gcc-msm8660.o
 obj-$(CONFIG_MSM_GCC_8960) += gcc-msm8960.o
diff --git a/drivers/clk/qcom/gdsc.c b/drivers/clk/qcom/gdsc.c
new file mode 100644
index 000000000000..a885fe4bdf38
--- /dev/null
+++ b/drivers/clk/qcom/gdsc.c
@@ -0,0 +1,361 @@
+/*
+ * Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/export.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/of.h>
+#include <linux/regulator/driver.h>
+#include <linux/regulator/machine.h>
+#include <linux/regulator/of_regulator.h>
+#include <linux/slab.h>
+#include <linux/reset-controller.h>
+#include <linux/regmap.h>
+
+#include "gdsc.h"
+
+#define PWR_ON_MASK		BIT(31)
+#define EN_REST_WAIT_MASK	(0xF << 20)
+#define EN_FEW_WAIT_MASK	(0xF << 16)
+#define CLK_DIS_WAIT_MASK	(0xF << 12)
+#define SW_OVERRIDE_MASK	BIT(2)
+#define HW_CONTROL_MASK		BIT(1)
+#define SW_COLLAPSE_MASK	BIT(0)
+
+/* Wait 2^n CXO cycles between all states. Here, n=2 (4 cycles). */
+#define EN_REST_WAIT_VAL	(0x2 << 20)
+#define EN_FEW_WAIT_VAL		(0x8 << 16)
+#define CLK_DIS_WAIT_VAL	(0x2 << 12)
+
+#define RETAIN_MEM		BIT(14)
+#define RETAIN_PERIPH		BIT(13)
+
+#define TIMEOUT_US		100
+
+struct gdsc {
+	struct regulator_dev	*rdev;
+	struct regulator_desc	rdesc;
+	struct reset_controller_dev *rcdev;
+	struct regmap		*regmap;
+	u32			gdscr;
+	unsigned int		*cxcs;
+	int			cxc_count;
+	unsigned int		*resets;
+	int			reset_count;
+	bool			toggle_mem;
+	bool			toggle_periph;
+	bool			toggle_logic;
+	bool			resets_asserted;
+};
+
+static int gdsc_is_enabled(struct regulator_dev *rdev)
+{
+	unsigned int val;
+	struct gdsc *sc = rdev_get_drvdata(rdev);
+
+	if (!sc->toggle_logic)
+		return !sc->resets_asserted;
+
+	regmap_read(sc->regmap, sc->gdscr, &val);
+	return !!(val & PWR_ON_MASK);
+}
+
+static int gdsc_poll_enable(struct gdsc *sc, bool en)
+{
+	unsigned long timeout;
+	unsigned int val;
+	unsigned int check = en ? PWR_ON_MASK : 0;
+
+	timeout = jiffies + usecs_to_jiffies(TIMEOUT_US);
+	do {
+		regmap_read(sc->regmap, sc->gdscr, &val);
+		if ((val & PWR_ON_MASK) == check)
+			return 0;
+	} while (time_before(jiffies, timeout));
+
+	regmap_read(sc->regmap, sc->gdscr, &val);
+	if ((val & PWR_ON_MASK) == check)
+		return 0;
+
+	pr_err("%s %s timed out\n", en ? "enabling" : "disabling",
+	       sc->rdesc.name);
+	return -ETIMEDOUT;
+}
+
+static int gdsc_toggle_logic(struct gdsc *sc, bool en)
+{
+	int ret;
+	u32 val;
+
+	regmap_read(sc->regmap, sc->gdscr, &val);
+	if (val & HW_CONTROL_MASK) {
+		dev_warn(&sc->rdev->dev,
+			"Invalid %s while %s is under HW control\n",
+			en ? "enable" : "disable", sc->rdesc.name);
+		return -EBUSY;
+	}
+
+	val = en ? 0 : SW_COLLAPSE_MASK;
+	ret = regmap_update_bits(sc->regmap, sc->gdscr, SW_COLLAPSE_MASK, val);
+	if (ret)
+		return ret;
+
+	return gdsc_poll_enable(sc, en);
+}
+
+static int gdsc_enable(struct regulator_dev *rdev)
+{
+	struct gdsc *sc = rdev_get_drvdata(rdev);
+	u32 mask;
+	int i, ret;
+
+	if (sc->toggle_logic) {
+		ret = gdsc_toggle_logic(sc, true);
+		if (ret)
+			return ret;
+	} else {
+		for (i = 0; i < sc->reset_count; i++)
+			sc->rcdev->ops->deassert(sc->rcdev, sc->resets[i]);
+		sc->resets_asserted = false;
+	}
+
+
+	for (i = 0; i < sc->cxc_count; i++) {
+		mask = 0;
+		if (sc->toggle_mem) {
+			mask |= RETAIN_MEM;
+			regmap_update_bits(sc->regmap, sc->cxcs[i], mask, mask);
+		}
+		udelay(1);
+		if (sc->toggle_periph) {
+			mask |= RETAIN_PERIPH;
+			regmap_update_bits(sc->regmap, sc->cxcs[i], mask, mask);
+		}
+	}
+
+	/*
+	 * If clocks to this power domain were already on, they will take an
+	 * additional 4 clock cycles to re-enable after the rail is enabled.
+	 * Delay to account for this. A delay is also needed to ensure clocks
+	 * are not enabled within 400ns of enabling power to the memories.
+	 */
+	udelay(1);
+
+	return 0;
+}
+
+static int gdsc_disable(struct regulator_dev *rdev)
+{
+	struct gdsc *sc = rdev_get_drvdata(rdev);
+	u32 mask = 0;
+	int i, ret = 0;
+
+	if (sc->toggle_mem)
+		mask |= RETAIN_MEM;
+	if (sc->toggle_periph)
+		mask |= RETAIN_PERIPH;
+
+	for (i = sc->cxc_count - 1; i >= 0; i--)
+		regmap_update_bits(sc->regmap, sc->cxcs[i], mask, 0);
+
+	if (sc->toggle_logic) {
+		ret = gdsc_toggle_logic(sc, false);
+		if (ret)
+			return ret;
+	} else {
+		for (i = sc->reset_count - 1; i >= 0; i--)
+			sc->rcdev->ops->assert(sc->rcdev, sc->resets[i]);
+		sc->resets_asserted = true;
+	}
+
+	return ret;
+}
+
+static unsigned int gdsc_get_mode(struct regulator_dev *rdev)
+{
+	struct gdsc *sc = rdev_get_drvdata(rdev);
+	unsigned int val;
+
+	regmap_read(sc->regmap, sc->gdscr, &val);
+	if (val & HW_CONTROL_MASK)
+		return REGULATOR_MODE_FAST;
+	return REGULATOR_MODE_NORMAL;
+}
+
+static int gdsc_set_mode(struct regulator_dev *rdev, unsigned int mode)
+{
+	struct gdsc *sc = rdev_get_drvdata(rdev);
+	unsigned int val;
+	int ret;
+
+	regmap_read(sc->regmap, sc->gdscr, &val);
+
+	/*
+	 * HW control can only be enable/disabled when SW_COLLAPSE
+	 * indicates on.
+	 */
+	if (val & SW_COLLAPSE_MASK) {
+		dev_err(&rdev->dev, "can't enable hw collapse now\n");
+		return -EBUSY;
+	}
+
+	switch (mode) {
+	case REGULATOR_MODE_FAST:
+		/* Turn on HW trigger mode */
+		val |= HW_CONTROL_MASK;
+		regmap_write(sc->regmap, sc->gdscr, val);
+		/*
+		 * There may be a race with internal HW trigger signal,
+		 * that will result in GDSC going through a power down and
+		 * up cycle.  In case HW trigger signal is controlled by
+		 * firmware that also poll same status bits as we do, FW
+		 * might read an 'on' status before the GDSC can finish
+		 * power cycle.  We wait 1us before returning to ensure
+		 * FW can't immediately poll the status bit.
+		 */
+		mb();
+		udelay(1);
+		break;
+
+	case REGULATOR_MODE_NORMAL:
+		/* Turn off HW trigger mode */
+		val &= ~HW_CONTROL_MASK;
+		regmap_write(sc->regmap, sc->gdscr, val);
+		/*
+		 * There may be a race with internal HW trigger signal,
+		 * that will result in GDSC going through a power down and
+		 * up cycle.  If we poll too early, status bit will
+		 * indicate 'on' before the GDSC can finish the power cycle.
+		 * Account for this case by waiting 1us before polling.
+		 */
+		mb();
+		udelay(1);
+		ret = gdsc_poll_enable(sc, true);
+		if (ret) {
+			dev_err(&rdev->dev, "%s set_mode timed out\n",
+				sc->rdesc.name);
+			return ret;
+		}
+		break;
+	default:
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static struct regulator_ops gdsc_ops = {
+	.is_enabled = gdsc_is_enabled,
+	.enable = gdsc_enable,
+	.disable = gdsc_disable,
+	.set_mode = gdsc_set_mode,
+	.get_mode = gdsc_get_mode,
+};
+
+int gdsc_register(struct device *pdev, struct of_regulator_match *match,
+		  struct reset_controller_dev *rcdev)
+{
+	static atomic_t gdsc_count = ATOMIC_INIT(-1);
+	struct regulator_config reg_config = {};
+	struct regulator_init_data *init_data;
+	struct gdsc *sc;
+	unsigned int val, mask;
+	bool retain_mem, retain_periph, support_hw_trigger;
+	int i, ret;
+	struct device_node *np;
+	struct gdsc_desc *desc;
+
+	sc = devm_kzalloc(pdev, sizeof(*sc), GFP_KERNEL);
+	if (!sc)
+		return -ENOMEM;
+
+	np = match->of_node;
+	desc = match->driver_data;
+	init_data = match->init_data;
+
+	if (of_get_property(np, "parent-supply", NULL))
+		init_data->supply_regulator = "parent";
+
+	ret = of_property_read_string(np, "regulator-name", &sc->rdesc.name);
+	if (ret)
+		return ret;
+
+	sc->regmap = dev_get_regmap(pdev, NULL);
+	sc->gdscr = desc->gdscr;
+	sc->cxcs = desc->cxcs;
+	sc->cxc_count = desc->cxc_count;
+	sc->resets = desc->resets;
+	sc->reset_count = desc->reset_count;
+	sc->rcdev = rcdev;
+
+	sc->rdesc.id = atomic_inc_return(&gdsc_count);
+	sc->rdesc.ops = &gdsc_ops;
+	sc->rdesc.type = REGULATOR_VOLTAGE;
+	sc->rdesc.owner = THIS_MODULE;
+
+	/*
+	 * Disable HW trigger: collapse/restore occur based on registers writes.
+	 * Disable SW override: Use hardware state-machine for sequencing.
+	 * Configure wait time between states.
+	 */
+	mask = HW_CONTROL_MASK | SW_OVERRIDE_MASK |
+	       EN_REST_WAIT_MASK | EN_FEW_WAIT_MASK | CLK_DIS_WAIT_MASK;
+	val = EN_REST_WAIT_VAL | EN_FEW_WAIT_VAL | CLK_DIS_WAIT_VAL;
+	regmap_update_bits(sc->regmap, sc->gdscr, mask, val);
+
+	retain_mem = of_property_read_bool(np, "qcom,retain-mem");
+	sc->toggle_mem = !retain_mem;
+	retain_periph = of_property_read_bool(np, "qcom,retain-periph");
+	sc->toggle_periph = !retain_periph;
+	sc->toggle_logic = !of_property_read_bool(np,
+						"qcom,skip-logic-collapse");
+	support_hw_trigger = of_property_read_bool(np,
+						    "qcom,support-hw-trigger");
+	if (support_hw_trigger) {
+		init_data->constraints.valid_ops_mask |= REGULATOR_CHANGE_MODE;
+		init_data->constraints.valid_modes_mask |=
+				REGULATOR_MODE_NORMAL | REGULATOR_MODE_FAST;
+	}
+
+	if (!sc->toggle_logic) {
+		ret = gdsc_toggle_logic(sc, true);
+		if (ret)
+			return ret;
+	}
+
+	regmap_read(sc->regmap, sc->gdscr, &val);
+	mask = RETAIN_MEM | RETAIN_PERIPH;
+	val = 0;
+	if (retain_mem || (val & PWR_ON_MASK))
+		val |= RETAIN_MEM;
+	if (retain_periph || (val & PWR_ON_MASK))
+		val |= RETAIN_PERIPH;
+
+	for (i = 0; i < sc->cxc_count; i++)
+		regmap_update_bits(sc->regmap, sc->cxcs[i], mask, val);
+
+	reg_config.dev = pdev;
+	reg_config.init_data = init_data;
+	reg_config.driver_data = sc;
+	reg_config.of_node = np;
+	sc->rdev = devm_regulator_register(pdev, &sc->rdesc, &reg_config);
+	if (IS_ERR(sc->rdev)) {
+		dev_err(pdev, "regulator_register(\"%s\") failed.\n",
+			sc->rdesc.name);
+		return PTR_ERR(sc->rdev);
+	}
+
+	return 0;
+}
+EXPORT_SYMBOL(gdsc_register);
diff --git a/drivers/clk/qcom/gdsc.h b/drivers/clk/qcom/gdsc.h
new file mode 100644
index 000000000000..bd034c5071a9
--- /dev/null
+++ b/drivers/clk/qcom/gdsc.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2014, The Linux Foundation. All rights reserved.
+ *
+ * This software is licensed under the terms of the GNU General Public
+ * License version 2, as published by the Free Software Foundation, and
+ * may be copied, distributed, and modified under those terms.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#ifndef __QCOM_GDSC_H__
+#define __QCOM_GDSC_H__
+
+struct device;
+struct device_node;
+struct of_regulator_match;
+
+struct gdsc_desc {
+	unsigned int gdscr;
+	unsigned int *cxcs;
+	int cxc_count;
+	unsigned int *resets;
+	int reset_count;
+};
+
+extern int gdsc_register(struct device *pdev, struct of_regulator_match *match,
+			 struct reset_controller_dev *rcdev);
+
+#endif
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 2/4] clk: qcom: Add GDSCs within 8974 multimedia clock controller
  2014-04-04 18:45 ` Stephen Boyd
@ 2014-04-04 18:45   ` Stephen Boyd
  -1 siblings, 0 replies; 21+ messages in thread
From: Stephen Boyd @ 2014-04-04 18:45 UTC (permalink / raw)
  To: Mike Turquette
  Cc: linux-kernel, linux-arm-msm, linux-arm-kernel, Mark Brown,
	Saravana Kannan

Add the necessary data and register the GDSCs that are present on
the 8974 multimedia clock controller.

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 drivers/clk/qcom/mmcc-msm8974.c | 86 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 84 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/qcom/mmcc-msm8974.c b/drivers/clk/qcom/mmcc-msm8974.c
index c95774514b81..1e7f69716d2f 100644
--- a/drivers/clk/qcom/mmcc-msm8974.c
+++ b/drivers/clk/qcom/mmcc-msm8974.c
@@ -21,6 +21,7 @@
 #include <linux/clk-provider.h>
 #include <linux/regmap.h>
 #include <linux/reset-controller.h>
+#include <linux/regulator/of_regulator.h>
 
 #include <dt-bindings/clock/qcom,mmcc-msm8974.h>
 #include <dt-bindings/reset/qcom,mmcc-msm8974.h>
@@ -30,6 +31,7 @@
 #include "clk-rcg.h"
 #include "clk-branch.h"
 #include "reset.h"
+#include "gdsc.h"
 
 #define P_XO		0
 #define P_MMPLL0	1
@@ -2516,6 +2518,60 @@ static const struct qcom_reset_map mmcc_msm8974_resets[] = {
 	[OCMEMNOC_RESET] = { 0x50b0 },
 };
 
+static struct gdsc_desc gdsc_venus = {
+	.gdscr = 0x1024,
+	.cxcs = (unsigned int []){ 0x1028 },
+	.cxc_count = 1,
+	.resets = (unsigned int []){ VENUS0_RESET },
+	.reset_count = 1,
+};
+
+static struct gdsc_desc gdsc_mdss = {
+	.gdscr = 0x2304,
+	.cxcs = (unsigned int []){ 0x231c, 0x2320 },
+	.cxc_count = 2,
+	.resets = (unsigned int []){ MDSS_RESET },
+	.reset_count = 1,
+};
+
+static struct gdsc_desc gdsc_jpeg = {
+	.gdscr = 0x35a4,
+	.cxcs = (unsigned int []){ 0x35a8, 0x35ac, 0x35b0 },
+	.cxc_count = 3,
+	.resets = (unsigned int []){ CAMSS_JPEG_RESET },
+	.reset_count = 1,
+};
+
+static struct gdsc_desc gdsc_vfe = {
+	.gdscr = 0x36a4,
+	.cxcs = (unsigned int []){ 0x36a8, 0x36ac, 0x3704, 0x3714, 0x36b0 },
+	.cxc_count = 5,
+	.resets = (unsigned int []){ CAMSS_VFE_RESET, CAMSS_CSI_VFE0_RESET,
+				     CAMSS_CSI_VFE1_RESET },
+	.reset_count = 3,
+};
+
+static struct gdsc_desc gdsc_oxili_gx = {
+	.gdscr = 0x4024,
+	.cxcs = (unsigned int []){ 0x4028 },
+	.cxc_count = 1,
+	.resets = (unsigned int []){ OXILI_RESET },
+	.reset_count = 1,
+};
+
+static struct gdsc_desc gdsc_oxili_cx = {
+	.gdscr = 0x4034,
+};
+
+static struct of_regulator_match mmcc_msm8974_gdscs[] = {
+	{ .name = "gdsc_venus", .driver_data = &gdsc_venus },
+	{ .name = "gdsc_mdss", .driver_data = &gdsc_mdss },
+	{ .name = "gdsc_jpeg", .driver_data = &gdsc_jpeg },
+	{ .name = "gdsc_vfe", .driver_data = &gdsc_vfe },
+	{ .name = "gdsc_oxili_gx", .driver_data = &gdsc_oxili_gx },
+	{ .name = "gdsc_oxili_cx", .driver_data = &gdsc_oxili_cx },
+};
+
 static const struct regmap_config mmcc_msm8974_regmap_config = {
 	.reg_bits	= 32,
 	.reg_stride	= 4,
@@ -2540,7 +2596,7 @@ static int mmcc_msm8974_probe(struct platform_device *pdev)
 {
 	void __iomem *base;
 	struct resource *res;
-	int i, ret;
+	int i, ret, num;
 	struct device *dev = &pdev->dev;
 	struct clk *clk;
 	struct clk_onecell_data *data;
@@ -2549,6 +2605,7 @@ static int mmcc_msm8974_probe(struct platform_device *pdev)
 	size_t num_clks;
 	struct qcom_reset_controller *reset;
 	struct qcom_cc *cc;
+	struct device_node *regs;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	base = devm_ioremap_resource(dev, res);
@@ -2597,8 +2654,33 @@ static int mmcc_msm8974_probe(struct platform_device *pdev)
 
 	ret = reset_controller_register(&reset->rcdev);
 	if (ret)
-		of_clk_del_provider(dev->of_node);
+		goto err_reset;
+
+	regs = of_get_child_by_name(dev->of_node, "regulators");
+	if (!regs)
+		return 0;
+
+	num = of_regulator_match(&pdev->dev, regs, mmcc_msm8974_gdscs,
+				 ARRAY_SIZE(mmcc_msm8974_gdscs));
+	of_node_put(regs);
+	if (num < 0) {
+		dev_err(&pdev->dev, "Regulator match failed\n");
+		ret = num;
+		goto err_regs;
+	}
+
+	for (i = 0; i < num; i++) {
+		ret = gdsc_register(&pdev->dev, &mmcc_msm8974_gdscs[i],
+				    &reset->rcdev);
+		if (ret)
+			goto err_regs;
+	}
 
+	return 0;
+err_regs:
+	reset_controller_unregister(&reset->rcdev);
+err_reset:
+	of_clk_del_provider(dev->of_node);
 	return ret;
 }
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 2/4] clk: qcom: Add GDSCs within 8974 multimedia clock controller
@ 2014-04-04 18:45   ` Stephen Boyd
  0 siblings, 0 replies; 21+ messages in thread
From: Stephen Boyd @ 2014-04-04 18:45 UTC (permalink / raw)
  To: linux-arm-kernel

Add the necessary data and register the GDSCs that are present on
the 8974 multimedia clock controller.

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 drivers/clk/qcom/mmcc-msm8974.c | 86 ++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 84 insertions(+), 2 deletions(-)

diff --git a/drivers/clk/qcom/mmcc-msm8974.c b/drivers/clk/qcom/mmcc-msm8974.c
index c95774514b81..1e7f69716d2f 100644
--- a/drivers/clk/qcom/mmcc-msm8974.c
+++ b/drivers/clk/qcom/mmcc-msm8974.c
@@ -21,6 +21,7 @@
 #include <linux/clk-provider.h>
 #include <linux/regmap.h>
 #include <linux/reset-controller.h>
+#include <linux/regulator/of_regulator.h>
 
 #include <dt-bindings/clock/qcom,mmcc-msm8974.h>
 #include <dt-bindings/reset/qcom,mmcc-msm8974.h>
@@ -30,6 +31,7 @@
 #include "clk-rcg.h"
 #include "clk-branch.h"
 #include "reset.h"
+#include "gdsc.h"
 
 #define P_XO		0
 #define P_MMPLL0	1
@@ -2516,6 +2518,60 @@ static const struct qcom_reset_map mmcc_msm8974_resets[] = {
 	[OCMEMNOC_RESET] = { 0x50b0 },
 };
 
+static struct gdsc_desc gdsc_venus = {
+	.gdscr = 0x1024,
+	.cxcs = (unsigned int []){ 0x1028 },
+	.cxc_count = 1,
+	.resets = (unsigned int []){ VENUS0_RESET },
+	.reset_count = 1,
+};
+
+static struct gdsc_desc gdsc_mdss = {
+	.gdscr = 0x2304,
+	.cxcs = (unsigned int []){ 0x231c, 0x2320 },
+	.cxc_count = 2,
+	.resets = (unsigned int []){ MDSS_RESET },
+	.reset_count = 1,
+};
+
+static struct gdsc_desc gdsc_jpeg = {
+	.gdscr = 0x35a4,
+	.cxcs = (unsigned int []){ 0x35a8, 0x35ac, 0x35b0 },
+	.cxc_count = 3,
+	.resets = (unsigned int []){ CAMSS_JPEG_RESET },
+	.reset_count = 1,
+};
+
+static struct gdsc_desc gdsc_vfe = {
+	.gdscr = 0x36a4,
+	.cxcs = (unsigned int []){ 0x36a8, 0x36ac, 0x3704, 0x3714, 0x36b0 },
+	.cxc_count = 5,
+	.resets = (unsigned int []){ CAMSS_VFE_RESET, CAMSS_CSI_VFE0_RESET,
+				     CAMSS_CSI_VFE1_RESET },
+	.reset_count = 3,
+};
+
+static struct gdsc_desc gdsc_oxili_gx = {
+	.gdscr = 0x4024,
+	.cxcs = (unsigned int []){ 0x4028 },
+	.cxc_count = 1,
+	.resets = (unsigned int []){ OXILI_RESET },
+	.reset_count = 1,
+};
+
+static struct gdsc_desc gdsc_oxili_cx = {
+	.gdscr = 0x4034,
+};
+
+static struct of_regulator_match mmcc_msm8974_gdscs[] = {
+	{ .name = "gdsc_venus", .driver_data = &gdsc_venus },
+	{ .name = "gdsc_mdss", .driver_data = &gdsc_mdss },
+	{ .name = "gdsc_jpeg", .driver_data = &gdsc_jpeg },
+	{ .name = "gdsc_vfe", .driver_data = &gdsc_vfe },
+	{ .name = "gdsc_oxili_gx", .driver_data = &gdsc_oxili_gx },
+	{ .name = "gdsc_oxili_cx", .driver_data = &gdsc_oxili_cx },
+};
+
 static const struct regmap_config mmcc_msm8974_regmap_config = {
 	.reg_bits	= 32,
 	.reg_stride	= 4,
@@ -2540,7 +2596,7 @@ static int mmcc_msm8974_probe(struct platform_device *pdev)
 {
 	void __iomem *base;
 	struct resource *res;
-	int i, ret;
+	int i, ret, num;
 	struct device *dev = &pdev->dev;
 	struct clk *clk;
 	struct clk_onecell_data *data;
@@ -2549,6 +2605,7 @@ static int mmcc_msm8974_probe(struct platform_device *pdev)
 	size_t num_clks;
 	struct qcom_reset_controller *reset;
 	struct qcom_cc *cc;
+	struct device_node *regs;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	base = devm_ioremap_resource(dev, res);
@@ -2597,8 +2654,33 @@ static int mmcc_msm8974_probe(struct platform_device *pdev)
 
 	ret = reset_controller_register(&reset->rcdev);
 	if (ret)
-		of_clk_del_provider(dev->of_node);
+		goto err_reset;
+
+	regs = of_get_child_by_name(dev->of_node, "regulators");
+	if (!regs)
+		return 0;
+
+	num = of_regulator_match(&pdev->dev, regs, mmcc_msm8974_gdscs,
+				 ARRAY_SIZE(mmcc_msm8974_gdscs));
+	of_node_put(regs);
+	if (num < 0) {
+		dev_err(&pdev->dev, "Regulator match failed\n");
+		ret = num;
+		goto err_regs;
+	}
+
+	for (i = 0; i < num; i++) {
+		ret = gdsc_register(&pdev->dev, &mmcc_msm8974_gdscs[i],
+				    &reset->rcdev);
+		if (ret)
+			goto err_regs;
+	}
 
+	return 0;
+err_regs:
+	reset_controller_unregister(&reset->rcdev);
+err_reset:
+	of_clk_del_provider(dev->of_node);
 	return ret;
 }
 
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 3/4] ARM: dts: qcom: Add GDSC nodes underneath clock controller
  2014-04-04 18:45 ` Stephen Boyd
  (?)
@ 2014-04-04 18:45   ` Stephen Boyd
  -1 siblings, 0 replies; 21+ messages in thread
From: Stephen Boyd @ 2014-04-04 18:45 UTC (permalink / raw)
  To: Kumar Gala
  Cc: Saravana Kannan, linux-arm-msm, linux-kernel, Mark Brown,
	Mike Turquette, linux-arm-kernel

Add nodes for the GDSCs present on the multimedia clock
controller in 8974.

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 arch/arm/boot/dts/qcom-apq8074-dragonboard.dts | 18 ++++++++++++++++++
 arch/arm/boot/dts/qcom-msm8974.dtsi            | 26 ++++++++++++++++++++++++++
 2 files changed, 44 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
index 13ac3e222495..478e89de0f38 100644
--- a/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
+++ b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
@@ -3,4 +3,22 @@
 / {
 	model = "Qualcomm APQ8074 Dragonboard";
 	compatible = "qcom,apq8074-dragonboard", "qcom,apq8074";
+
+};
+
+&gdsc_venus {
+	qcom,skip-logic-collapse;
+	qcom,retain-periph;
+	qcom,retain-mem;
+};
+
+&gdsc_mdss {
+	qcom,skip-logic-collapse;
+	qcom,retain-periph;
+	qcom,retain-mem;
+};
+
+&gdsc_oxili_gx {
+	qcom,retain-mem;
+	qcom,retain-periph;
 };
diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
index 9e5dadb101eb..e38ae30930b2 100644
--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
@@ -108,6 +108,32 @@
 			#clock-cells = <1>;
 			#reset-cells = <1>;
 			reg = <0xfd8c0000 0x6000>;
+
+			regulators {
+				gdsc_venus: gdsc_venus {
+					regulator-name = "gdsc_venus";
+				};
+
+				gdsc_mdss: gdsc_mdss {
+					regulator-name = "gdsc_mdss";
+				};
+
+				gdsc_jpeg: gdsc_jpeg {
+					regulator-name = "gdsc_jpeg";
+				};
+
+				gdsc_vfe: gdsc_vfe {
+					regulator-name = "gdsc_vfe";
+				};
+
+				gdsc_oxili_gx: gdsc_oxili_gx {
+					regulator-name = "gdsc_oxili_gx";
+				};
+
+				gdsc_oxili_cx: gdsc_oxili_cx {
+					regulator-name = "gdsc_oxili_cx";
+				};
+			};
 		};
 
 		serial@f991e000 {
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 3/4] ARM: dts: qcom: Add GDSC nodes underneath clock controller
@ 2014-04-04 18:45   ` Stephen Boyd
  0 siblings, 0 replies; 21+ messages in thread
From: Stephen Boyd @ 2014-04-04 18:45 UTC (permalink / raw)
  To: Kumar Gala
  Cc: linux-kernel, linux-arm-msm, linux-arm-kernel, Mark Brown,
	Saravana Kannan, Mike Turquette

Add nodes for the GDSCs present on the multimedia clock
controller in 8974.

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 arch/arm/boot/dts/qcom-apq8074-dragonboard.dts | 18 ++++++++++++++++++
 arch/arm/boot/dts/qcom-msm8974.dtsi            | 26 ++++++++++++++++++++++++++
 2 files changed, 44 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
index 13ac3e222495..478e89de0f38 100644
--- a/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
+++ b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
@@ -3,4 +3,22 @@
 / {
 	model = "Qualcomm APQ8074 Dragonboard";
 	compatible = "qcom,apq8074-dragonboard", "qcom,apq8074";
+
+};
+
+&gdsc_venus {
+	qcom,skip-logic-collapse;
+	qcom,retain-periph;
+	qcom,retain-mem;
+};
+
+&gdsc_mdss {
+	qcom,skip-logic-collapse;
+	qcom,retain-periph;
+	qcom,retain-mem;
+};
+
+&gdsc_oxili_gx {
+	qcom,retain-mem;
+	qcom,retain-periph;
 };
diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
index 9e5dadb101eb..e38ae30930b2 100644
--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
@@ -108,6 +108,32 @@
 			#clock-cells = <1>;
 			#reset-cells = <1>;
 			reg = <0xfd8c0000 0x6000>;
+
+			regulators {
+				gdsc_venus: gdsc_venus {
+					regulator-name = "gdsc_venus";
+				};
+
+				gdsc_mdss: gdsc_mdss {
+					regulator-name = "gdsc_mdss";
+				};
+
+				gdsc_jpeg: gdsc_jpeg {
+					regulator-name = "gdsc_jpeg";
+				};
+
+				gdsc_vfe: gdsc_vfe {
+					regulator-name = "gdsc_vfe";
+				};
+
+				gdsc_oxili_gx: gdsc_oxili_gx {
+					regulator-name = "gdsc_oxili_gx";
+				};
+
+				gdsc_oxili_cx: gdsc_oxili_cx {
+					regulator-name = "gdsc_oxili_cx";
+				};
+			};
 		};
 
 		serial@f991e000 {
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 3/4] ARM: dts: qcom: Add GDSC nodes underneath clock controller
@ 2014-04-04 18:45   ` Stephen Boyd
  0 siblings, 0 replies; 21+ messages in thread
From: Stephen Boyd @ 2014-04-04 18:45 UTC (permalink / raw)
  To: linux-arm-kernel

Add nodes for the GDSCs present on the multimedia clock
controller in 8974.

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 arch/arm/boot/dts/qcom-apq8074-dragonboard.dts | 18 ++++++++++++++++++
 arch/arm/boot/dts/qcom-msm8974.dtsi            | 26 ++++++++++++++++++++++++++
 2 files changed, 44 insertions(+)

diff --git a/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
index 13ac3e222495..478e89de0f38 100644
--- a/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
+++ b/arch/arm/boot/dts/qcom-apq8074-dragonboard.dts
@@ -3,4 +3,22 @@
 / {
 	model = "Qualcomm APQ8074 Dragonboard";
 	compatible = "qcom,apq8074-dragonboard", "qcom,apq8074";
+
+};
+
+&gdsc_venus {
+	qcom,skip-logic-collapse;
+	qcom,retain-periph;
+	qcom,retain-mem;
+};
+
+&gdsc_mdss {
+	qcom,skip-logic-collapse;
+	qcom,retain-periph;
+	qcom,retain-mem;
+};
+
+&gdsc_oxili_gx {
+	qcom,retain-mem;
+	qcom,retain-periph;
 };
diff --git a/arch/arm/boot/dts/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom-msm8974.dtsi
index 9e5dadb101eb..e38ae30930b2 100644
--- a/arch/arm/boot/dts/qcom-msm8974.dtsi
+++ b/arch/arm/boot/dts/qcom-msm8974.dtsi
@@ -108,6 +108,32 @@
 			#clock-cells = <1>;
 			#reset-cells = <1>;
 			reg = <0xfd8c0000 0x6000>;
+
+			regulators {
+				gdsc_venus: gdsc_venus {
+					regulator-name = "gdsc_venus";
+				};
+
+				gdsc_mdss: gdsc_mdss {
+					regulator-name = "gdsc_mdss";
+				};
+
+				gdsc_jpeg: gdsc_jpeg {
+					regulator-name = "gdsc_jpeg";
+				};
+
+				gdsc_vfe: gdsc_vfe {
+					regulator-name = "gdsc_vfe";
+				};
+
+				gdsc_oxili_gx: gdsc_oxili_gx {
+					regulator-name = "gdsc_oxili_gx";
+				};
+
+				gdsc_oxili_cx: gdsc_oxili_cx {
+					regulator-name = "gdsc_oxili_cx";
+				};
+			};
 		};
 
 		serial at f991e000 {
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 4/4] devicetree: bindings: qcom,mmcc: Document GDSC binding
  2014-04-04 18:45 ` Stephen Boyd
  (?)
@ 2014-04-04 18:45   ` Stephen Boyd
  -1 siblings, 0 replies; 21+ messages in thread
From: Stephen Boyd @ 2014-04-04 18:45 UTC (permalink / raw)
  To: Mike Turquette
  Cc: devicetree, Saravana Kannan, linux-arm-msm, linux-kernel,
	Mark Brown, linux-arm-kernel

Document the GDSC nodes present within the multimedia clock
controller.

Cc: <devicetree@vger.kernel.org>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 .../devicetree/bindings/clock/qcom,mmcc.txt        | 42 ++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/qcom,mmcc.txt b/Documentation/devicetree/bindings/clock/qcom,mmcc.txt
index d572e9964c54..695f86ad94ea 100644
--- a/Documentation/devicetree/bindings/clock/qcom,mmcc.txt
+++ b/Documentation/devicetree/bindings/clock/qcom,mmcc.txt
@@ -19,3 +19,45 @@ Example:
 		#clock-cells = <1>;
 		#reset-cells = <1>;
 	};
+
+Qualcomm Global Distributed Switch Controller (GDSC) Binding
+------------------------------------------------------------
+
+The GDSC is responsible for safely collapsing and restoring power to
+peripheral cores on chipsets like msm8974 for power savings.
+
+Required properties:
+ - regulator-name:  A string used as a descriptive name for regulator outputs
+
+Optional properties:
+ - parent-supply:   phandle to the parent supply/regulator node
+ - 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.
+
+Example:
+	clock-controller@4000000 {
+		compatible = "qcom,mmcc-msm8974";
+		reg = <0x4000000 0x1000>;
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+
+		regulators {
+			gdsc_oxili_gx: gdsc_oxili_gx {
+				regulator-name = "gdsc_oxili_gx";
+				parent-supply = <&pm8841_s4>;
+				qcom,retain-mem;
+				qcom,retain-periph;
+				qcom,skip-logic-collapse;
+				qcom,support-hw-trigger;
+			};
+		};
+	};
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 4/4] devicetree: bindings: qcom,mmcc: Document GDSC binding
@ 2014-04-04 18:45   ` Stephen Boyd
  0 siblings, 0 replies; 21+ messages in thread
From: Stephen Boyd @ 2014-04-04 18:45 UTC (permalink / raw)
  To: Mike Turquette
  Cc: linux-kernel, linux-arm-msm, linux-arm-kernel, Mark Brown,
	Saravana Kannan, devicetree

Document the GDSC nodes present within the multimedia clock
controller.

Cc: <devicetree@vger.kernel.org>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 .../devicetree/bindings/clock/qcom,mmcc.txt        | 42 ++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/qcom,mmcc.txt b/Documentation/devicetree/bindings/clock/qcom,mmcc.txt
index d572e9964c54..695f86ad94ea 100644
--- a/Documentation/devicetree/bindings/clock/qcom,mmcc.txt
+++ b/Documentation/devicetree/bindings/clock/qcom,mmcc.txt
@@ -19,3 +19,45 @@ Example:
 		#clock-cells = <1>;
 		#reset-cells = <1>;
 	};
+
+Qualcomm Global Distributed Switch Controller (GDSC) Binding
+------------------------------------------------------------
+
+The GDSC is responsible for safely collapsing and restoring power to
+peripheral cores on chipsets like msm8974 for power savings.
+
+Required properties:
+ - regulator-name:  A string used as a descriptive name for regulator outputs
+
+Optional properties:
+ - parent-supply:   phandle to the parent supply/regulator node
+ - 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.
+
+Example:
+	clock-controller@4000000 {
+		compatible = "qcom,mmcc-msm8974";
+		reg = <0x4000000 0x1000>;
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+
+		regulators {
+			gdsc_oxili_gx: gdsc_oxili_gx {
+				regulator-name = "gdsc_oxili_gx";
+				parent-supply = <&pm8841_s4>;
+				qcom,retain-mem;
+				qcom,retain-periph;
+				qcom,skip-logic-collapse;
+				qcom,support-hw-trigger;
+			};
+		};
+	};
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 4/4] devicetree: bindings: qcom,mmcc: Document GDSC binding
@ 2014-04-04 18:45   ` Stephen Boyd
  0 siblings, 0 replies; 21+ messages in thread
From: Stephen Boyd @ 2014-04-04 18:45 UTC (permalink / raw)
  To: linux-arm-kernel

Document the GDSC nodes present within the multimedia clock
controller.

Cc: <devicetree@vger.kernel.org>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
---
 .../devicetree/bindings/clock/qcom,mmcc.txt        | 42 ++++++++++++++++++++++
 1 file changed, 42 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/qcom,mmcc.txt b/Documentation/devicetree/bindings/clock/qcom,mmcc.txt
index d572e9964c54..695f86ad94ea 100644
--- a/Documentation/devicetree/bindings/clock/qcom,mmcc.txt
+++ b/Documentation/devicetree/bindings/clock/qcom,mmcc.txt
@@ -19,3 +19,45 @@ Example:
 		#clock-cells = <1>;
 		#reset-cells = <1>;
 	};
+
+Qualcomm Global Distributed Switch Controller (GDSC) Binding
+------------------------------------------------------------
+
+The GDSC is responsible for safely collapsing and restoring power to
+peripheral cores on chipsets like msm8974 for power savings.
+
+Required properties:
+ - regulator-name:  A string used as a descriptive name for regulator outputs
+
+Optional properties:
+ - parent-supply:   phandle to the parent supply/regulator node
+ - 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.
+
+Example:
+	clock-controller at 4000000 {
+		compatible = "qcom,mmcc-msm8974";
+		reg = <0x4000000 0x1000>;
+		#clock-cells = <1>;
+		#reset-cells = <1>;
+
+		regulators {
+			gdsc_oxili_gx: gdsc_oxili_gx {
+				regulator-name = "gdsc_oxili_gx";
+				parent-supply = <&pm8841_s4>;
+				qcom,retain-mem;
+				qcom,retain-periph;
+				qcom,skip-logic-collapse;
+				qcom,support-hw-trigger;
+			};
+		};
+	};
-- 
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [PATCH 0/4] Support qcom GDSC hardware
  2014-04-04 18:45 ` Stephen Boyd
@ 2014-04-15 17:56   ` Stephen Boyd
  -1 siblings, 0 replies; 21+ messages in thread
From: Stephen Boyd @ 2014-04-15 17:56 UTC (permalink / raw)
  To: Mike Turquette, Mark Brown
  Cc: Saravana Kannan, linux-arm-msm, linux-kernel, Matt Wagantall,
	Kumar Gala, linux-arm-kernel

On 04/04/14 11:45, Stephen Boyd wrote:
> These patches add support for the multimedia GDSCs on the
> apq8074 dragonboard. The first two patches (and potentially the last)
> should go through Mike's tree and the DTS patch should go through
> the qcom tree. Patches are based on v3.14. The probe will conflict with
> patches I sent to consolidate things. I'll rework these patches on top of
> that if the gdsc.c file is acked/reviewed.

Any comments?

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 0/4] Support qcom GDSC hardware
@ 2014-04-15 17:56   ` Stephen Boyd
  0 siblings, 0 replies; 21+ messages in thread
From: Stephen Boyd @ 2014-04-15 17:56 UTC (permalink / raw)
  To: linux-arm-kernel

On 04/04/14 11:45, Stephen Boyd wrote:
> These patches add support for the multimedia GDSCs on the
> apq8074 dragonboard. The first two patches (and potentially the last)
> should go through Mike's tree and the DTS patch should go through
> the qcom tree. Patches are based on v3.14. The probe will conflict with
> patches I sent to consolidate things. I'll rework these patches on top of
> that if the gdsc.c file is acked/reviewed.

Any comments?

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 4/4] devicetree: bindings: qcom, mmcc: Document GDSC binding
  2014-04-04 18:45   ` Stephen Boyd
@ 2014-04-29  7:07     ` Mike Turquette
  -1 siblings, 0 replies; 21+ messages in thread
From: Mike Turquette @ 2014-04-29  7:07 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: devicetree, Saravana Kannan, linux-arm-msm, linux-kernel,
	Mark Brown, linux-arm-kernel

Quoting Stephen Boyd (2014-04-04 11:45:36)
> +Example:
> +       clock-controller@4000000 {
> +               compatible = "qcom,mmcc-msm8974";
> +               reg = <0x4000000 0x1000>;
> +               #clock-cells = <1>;
> +               #reset-cells = <1>;
> +
> +               regulators {
> +                       gdsc_oxili_gx: gdsc_oxili_gx {
> +                               regulator-name = "gdsc_oxili_gx";

Hi Stephen,

It makes sense to model the gdsc's as regulators. It also makes sense to
nest them within the clock-controller node, assuming that matches the
register manual for your part.

However, does it make sense to put this new code under drivers/clk/qcom?
I don't see a compelling reason. How about breaking the registers out
into a header for easier reuse?

Regards,
Mike

> +                               parent-supply = <&pm8841_s4>;
> +                               qcom,retain-mem;
> +                               qcom,retain-periph;
> +                               qcom,skip-logic-collapse;
> +                               qcom,support-hw-trigger;
> +                       };
> +               };
> +       };
> -- 
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> hosted by The Linux Foundation
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 4/4] devicetree: bindings: qcom, mmcc: Document GDSC binding
@ 2014-04-29  7:07     ` Mike Turquette
  0 siblings, 0 replies; 21+ messages in thread
From: Mike Turquette @ 2014-04-29  7:07 UTC (permalink / raw)
  To: linux-arm-kernel

Quoting Stephen Boyd (2014-04-04 11:45:36)
> +Example:
> +       clock-controller at 4000000 {
> +               compatible = "qcom,mmcc-msm8974";
> +               reg = <0x4000000 0x1000>;
> +               #clock-cells = <1>;
> +               #reset-cells = <1>;
> +
> +               regulators {
> +                       gdsc_oxili_gx: gdsc_oxili_gx {
> +                               regulator-name = "gdsc_oxili_gx";

Hi Stephen,

It makes sense to model the gdsc's as regulators. It also makes sense to
nest them within the clock-controller node, assuming that matches the
register manual for your part.

However, does it make sense to put this new code under drivers/clk/qcom?
I don't see a compelling reason. How about breaking the registers out
into a header for easier reuse?

Regards,
Mike

> +                               parent-supply = <&pm8841_s4>;
> +                               qcom,retain-mem;
> +                               qcom,retain-periph;
> +                               qcom,skip-logic-collapse;
> +                               qcom,support-hw-trigger;
> +                       };
> +               };
> +       };
> -- 
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum,
> hosted by The Linux Foundation
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 4/4] devicetree: bindings: qcom,mmcc: Document GDSC binding
  2014-04-29  7:07     ` Mike Turquette
@ 2014-04-30 21:16       ` Stephen Boyd
  -1 siblings, 0 replies; 21+ messages in thread
From: Stephen Boyd @ 2014-04-30 21:16 UTC (permalink / raw)
  To: Mike Turquette
  Cc: linux-kernel, linux-arm-msm, linux-arm-kernel, Mark Brown,
	Saravana Kannan, devicetree

On 04/29, Mike Turquette wrote:
> Quoting Stephen Boyd (2014-04-04 11:45:36)
> > +Example:
> > +       clock-controller@4000000 {
> > +               compatible = "qcom,mmcc-msm8974";
> > +               reg = <0x4000000 0x1000>;
> > +               #clock-cells = <1>;
> > +               #reset-cells = <1>;
> > +
> > +               regulators {
> > +                       gdsc_oxili_gx: gdsc_oxili_gx {
> > +                               regulator-name = "gdsc_oxili_gx";
> 
> Hi Stephen,
> 
> It makes sense to model the gdsc's as regulators. It also makes sense to
> nest them within the clock-controller node, assuming that matches the
> register manual for your part.
> 
> However, does it make sense to put this new code under drivers/clk/qcom?
> I don't see a compelling reason. How about breaking the registers out
> into a header for easier reuse?

What registers are we talking about? I put this under
drivers/clk/qcom because it's one device that happens to have all
these different driver subsystems in it (clocks, reset, gdsc).

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 4/4] devicetree: bindings: qcom,mmcc: Document GDSC binding
@ 2014-04-30 21:16       ` Stephen Boyd
  0 siblings, 0 replies; 21+ messages in thread
From: Stephen Boyd @ 2014-04-30 21:16 UTC (permalink / raw)
  To: linux-arm-kernel

On 04/29, Mike Turquette wrote:
> Quoting Stephen Boyd (2014-04-04 11:45:36)
> > +Example:
> > +       clock-controller at 4000000 {
> > +               compatible = "qcom,mmcc-msm8974";
> > +               reg = <0x4000000 0x1000>;
> > +               #clock-cells = <1>;
> > +               #reset-cells = <1>;
> > +
> > +               regulators {
> > +                       gdsc_oxili_gx: gdsc_oxili_gx {
> > +                               regulator-name = "gdsc_oxili_gx";
> 
> Hi Stephen,
> 
> It makes sense to model the gdsc's as regulators. It also makes sense to
> nest them within the clock-controller node, assuming that matches the
> register manual for your part.
> 
> However, does it make sense to put this new code under drivers/clk/qcom?
> I don't see a compelling reason. How about breaking the registers out
> into a header for easier reuse?

What registers are we talking about? I put this under
drivers/clk/qcom because it's one device that happens to have all
these different driver subsystems in it (clocks, reset, gdsc).

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
hosted by The Linux Foundation

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 0/4] Support qcom GDSC hardware
  2014-04-15 17:56   ` Stephen Boyd
@ 2014-12-19  8:01     ` Ivan T. Ivanov
  -1 siblings, 0 replies; 21+ messages in thread
From: Ivan T. Ivanov @ 2014-12-19  8:01 UTC (permalink / raw)
  To: Mike Turquette, Mark Brown
  Cc: Stephen Boyd, Saravana Kannan, linux-arm-msm, linux-kernel,
	Matt Wagantall, Kumar Gala, linux-arm-kernel


On Tue, 2014-04-15 at 10:56 -0700, Stephen Boyd wrote:
> On 04/04/14 11:45, Stephen Boyd wrote:
> > These patches add support for the multimedia GDSCs on the
> > apq8074 dragonboard. The first two patches (and potentially the last)
> > should go through Mike's tree and the DTS patch should go through
> > the qcom tree. Patches are based on v3.14. The probe will conflict with
> > patches I sent to consolidate things. I'll rework these patches on top of
> > that if the gdsc.c file is acked/reviewed.
> 
> Any comments?
> 

Hi,

It will nice if we can progress on this. They are several drivers posted 
already which depends on these regulators, USB3.0 and PCIe, at least.

Thank you.
Ivan

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 0/4] Support qcom GDSC hardware
@ 2014-12-19  8:01     ` Ivan T. Ivanov
  0 siblings, 0 replies; 21+ messages in thread
From: Ivan T. Ivanov @ 2014-12-19  8:01 UTC (permalink / raw)
  To: linux-arm-kernel


On Tue, 2014-04-15 at 10:56 -0700, Stephen Boyd wrote:
> On 04/04/14 11:45, Stephen Boyd wrote:
> > These patches add support for the multimedia GDSCs on the
> > apq8074 dragonboard. The first two patches (and potentially the last)
> > should go through Mike's tree and the DTS patch should go through
> > the qcom tree. Patches are based on v3.14. The probe will conflict with
> > patches I sent to consolidate things. I'll rework these patches on top of
> > that if the gdsc.c file is acked/reviewed.
> 
> Any comments?
> 

Hi,

It will nice if we can progress on this. They are several drivers posted 
already which depends on these regulators, USB3.0 and PCIe, at least.

Thank you.
Ivan

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2014-12-19  8:01 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-04-04 18:45 [PATCH 0/4] Support qcom GDSC hardware Stephen Boyd
2014-04-04 18:45 ` Stephen Boyd
2014-04-04 18:45 ` [PATCH 1/4] clk: qcom: Add support for GDSCs Stephen Boyd
2014-04-04 18:45   ` Stephen Boyd
2014-04-04 18:45   ` Stephen Boyd
2014-04-04 18:45 ` [PATCH 2/4] clk: qcom: Add GDSCs within 8974 multimedia clock controller Stephen Boyd
2014-04-04 18:45   ` Stephen Boyd
2014-04-04 18:45 ` [PATCH 3/4] ARM: dts: qcom: Add GDSC nodes underneath " Stephen Boyd
2014-04-04 18:45   ` Stephen Boyd
2014-04-04 18:45   ` Stephen Boyd
2014-04-04 18:45 ` [PATCH 4/4] devicetree: bindings: qcom,mmcc: Document GDSC binding Stephen Boyd
2014-04-04 18:45   ` Stephen Boyd
2014-04-04 18:45   ` Stephen Boyd
2014-04-29  7:07   ` [PATCH 4/4] devicetree: bindings: qcom, mmcc: " Mike Turquette
2014-04-29  7:07     ` Mike Turquette
2014-04-30 21:16     ` [PATCH 4/4] devicetree: bindings: qcom,mmcc: " Stephen Boyd
2014-04-30 21:16       ` Stephen Boyd
2014-04-15 17:56 ` [PATCH 0/4] Support qcom GDSC hardware Stephen Boyd
2014-04-15 17:56   ` Stephen Boyd
2014-12-19  8:01   ` Ivan T. Ivanov
2014-12-19  8:01     ` Ivan T. Ivanov

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.