Linux-ARM-Kernel Archive on lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] PPC: powernv: remove redundant cpuidle_idle_call()
From: Preeti U Murthy @ 2014-02-14 11:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1391696188-14540-1-git-send-email-nicolas.pitre@linaro.org>

Hi Nicolas,

You will have to include the below patch with yours. You
could squash the two I guess, I have added the changelog
just for clarity. And you also might want to change the subject to
cpuidle/powernv. It gives a better picture.

Thanks

Regards
Preeti U Murthy


cpuidle/powernv: Add ppc64_runlatch_off/on() to idle routines

Following moving of cpuidle_idle_call() to the generic idle loop, we need to
add the runlatch functions to the idle routines on powernv which was earlier
taken care of by the arch specific idle routine.

Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>
---
 drivers/cpuidle/cpuidle-powernv.c |    5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/cpuidle/cpuidle-powernv.c b/drivers/cpuidle/cpuidle-powernv.c
index 78fd174..f48607c 100644
--- a/drivers/cpuidle/cpuidle-powernv.c
+++ b/drivers/cpuidle/cpuidle-powernv.c
@@ -14,6 +14,7 @@
 
 #include <asm/machdep.h>
 #include <asm/firmware.h>
+#include <asm/runlatch.h>
 
 struct cpuidle_driver powernv_idle_driver = {
 	.name             = "powernv_idle",
@@ -30,12 +31,14 @@ static int snooze_loop(struct cpuidle_device *dev,
 	local_irq_enable();
 	set_thread_flag(TIF_POLLING_NRFLAG);
 
+	ppc64_runlatch_off();
 	while (!need_resched()) {
 		HMT_low();
 		HMT_very_low();
 	}
 
 	HMT_medium();
+	ppc64_runlatch_on();
 	clear_thread_flag(TIF_POLLING_NRFLAG);
 	smp_mb();
 	return index;
@@ -45,7 +48,9 @@ static int nap_loop(struct cpuidle_device *dev,
 			struct cpuidle_driver *drv,
 			int index)
 {
+	ppc64_runlatch_off();
 	power7_idle();
+	ppc64_runlatch_on();
 	return index;
 }

 
On 02/06/2014 07:46 PM, Nicolas Pitre wrote:
> The core idle loop now takes care of it.
> 
> Signed-off-by: Nicolas Pitre <nico@linaro.org>
> ---
>  arch/powerpc/platforms/powernv/setup.c | 13 +------------
>  1 file changed, 1 insertion(+), 12 deletions(-)
> 
> diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c
> index 21166f65c9..a932feb290 100644
> --- a/arch/powerpc/platforms/powernv/setup.c
> +++ b/arch/powerpc/platforms/powernv/setup.c
> @@ -26,7 +26,6 @@
>  #include <linux/of_fdt.h>
>  #include <linux/interrupt.h>
>  #include <linux/bug.h>
> -#include <linux/cpuidle.h>
> 
>  #include <asm/machdep.h>
>  #include <asm/firmware.h>
> @@ -217,16 +216,6 @@ static int __init pnv_probe(void)
>  	return 1;
>  }
> 
> -void powernv_idle(void)
> -{
> -	/* Hook to cpuidle framework if available, else
> -	 * call on default platform idle code
> -	 */
> -	if (cpuidle_idle_call()) {
> -		power7_idle();
> -	}
> -}
> -
>  define_machine(powernv) {
>  	.name			= "PowerNV",
>  	.probe			= pnv_probe,
> @@ -236,7 +225,7 @@ define_machine(powernv) {
>  	.show_cpuinfo		= pnv_show_cpuinfo,
>  	.progress		= pnv_progress,
>  	.machine_shutdown	= pnv_shutdown,
> -	.power_save             = powernv_idle,
> +	.power_save             = power7_idle,
>  	.calibrate_decr		= generic_calibrate_decr,
>  #ifdef CONFIG_KEXEC
>  	.kexec_cpu_down		= pnv_kexec_cpu_down,
> 

^ permalink raw reply related

* [PATCH 1/4] phy: miphy365x: Add Device Tree bindings for the MiPHY365x
From: Lee Jones @ 2014-02-14 11:23 UTC (permalink / raw)
  To: linux-arm-kernel

The MiPHY365x is a Generic PHY which can serve various SATA or PCIe
devices. It has 2 ports which it can use for either; both SATA, both
PCIe or one of each in any configuration.

Cc: devicetree at vger.kernel.org
Cc: Srinivas Kandagatla <srinivas.kandagatla@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 .../devicetree/bindings/phy/phy-miphy365x.txt      | 54 ++++++++++++++++++++++
 1 file changed, 54 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/phy/phy-miphy365x.txt

diff --git a/Documentation/devicetree/bindings/phy/phy-miphy365x.txt b/Documentation/devicetree/bindings/phy/phy-miphy365x.txt
new file mode 100644
index 0000000..96f269f
--- /dev/null
+++ b/Documentation/devicetree/bindings/phy/phy-miphy365x.txt
@@ -0,0 +1,54 @@
+STMicroelectronics STi MIPHY365x PHY binding
+============================================
+
+This binding describes a miphy device that is used to control PHY hardware
+for SATA and PCIe.
+
+Required properties:
+- compatible: Should be "st,miphy365x-phy"
+- #phy-cells: Should be 2 (See second example)
+		First cell is the port number; MIPHY_PORT_{0,1}
+		Second cell is device type; MIPHY_TYPE_{SATA,PCI}
+- reg:	      Address and length of the register set for the device
+- reg-names:  The names of the register addresses corresponding to the
+	      registers filled in "reg"
+		Options are; sata{0,1} and pcie{0,1} (See first example)
+- st,syscfg : Should be a phandle of the system configuration register group
+	      which contain the SATA, PCIe mode setting bits
+
+Optional properties:
+- st,sata-gen	     : Generation of locally attached SATA IP. Expected values
+		       are {1,2,3). If not supplied generation 1 hardware will
+		       be expected
+- st,pcie-tx-pol-inv : Bool property to invert the polarity PCIe Tx (Txn/Txp)
+- st,sata-tx-pol-inv : Bool property to invert the polarity SATA Tx (Txn/Txp)
+
+Example:
+
+	miphy365x_phy: miphy365x at 0 {
+		compatible = "st,miphy365x-phy";
+		#phy-cells = <2>;
+		reg =	<0xfe382000 0x100>,
+			<0xfe38a000 0x100>,
+			<0xfe394000 0x100>,
+			<0xfe804000 0x100>;
+		reg-names = "sata0", "sata1", "pcie0", "pcie1";
+		st,syscfg= <&syscfg_rear>;
+	};
+
+Specifying phy control of devices
+=================================
+
+Device nodes should specify the configuration required in their "phys"
+property, containing a phandle to the miphy device node, a port number
+and a device type.
+
+Example:
+
+#include <dt-bindings/phy/phy-miphy365x.h>
+
+	sata0: sata at fe380000 {
+		...
+		phys	  = <&miphy365x_phy MIPHY_PORT_0 MIPHY_TYPE_SATA>;
+		...
+	};
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH 2/4] phy: miphy365x: Add MiPHY365x header file for DT x Driver defines
From: Lee Jones @ 2014-02-14 11:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392377036-12816-1-git-send-email-lee.jones@linaro.org>

This provides the shared header file which will be reference from both
the MiPHY365x driver and its associated Device Tree node(s).

Cc: devicetree at vger.kernel.org
Cc: Srinivas Kandagatla <srinivas.kandagatla@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 include/dt-bindings/phy/phy-miphy365x.h | 25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)
 create mode 100644 include/dt-bindings/phy/phy-miphy365x.h

diff --git a/include/dt-bindings/phy/phy-miphy365x.h b/include/dt-bindings/phy/phy-miphy365x.h
new file mode 100644
index 0000000..8757c02
--- /dev/null
+++ b/include/dt-bindings/phy/phy-miphy365x.h
@@ -0,0 +1,25 @@
+/*
+ * This header provides constants for the phy framework
+ * based on the STMicroelectronics miphy365x.
+ */
+#ifndef _DT_BINDINGS_PHY_MIPHY
+#define _DT_BINDINGS_PHY_MIPHY
+
+/* Supports 16 ports without a datatype change (u8 & 0xF0). */
+#define MIPHY_PORT_0			0
+#define MIPHY_PORT_1			1
+#define MIPHY_PORT_2			2
+#define MIPHY_PORT_3			3
+
+/* Supports 16 types without a datatype change (u8 & 0x0F). */
+#define MIPHY_TYPE_SHIFT		4
+#define MIPHY_TYPE_SATA			(0 << MIPHY_TYPE_SHIFT)
+#define MIPHY_TYPE_PCIE			(1 << MIPHY_TYPE_SHIFT)
+#define MIPHY_TYPE_USB			(2 << MIPHY_TYPE_SHIFT)
+
+#define MIPHY_SATA_PORT0		(MIPHY_TYPE_SATA) | (MIPHY_PORT_0)
+#define MIPHY_SATA_PORT1		(MIPHY_TYPE_SATA) | (MIPHY_PORT_1)
+#define MIPHY_PCIE_PORT0		(MIPHY_TYPE_PCIE) | (MIPHY_PORT_0)
+#define MIPHY_PCIE_PORT1		(MIPHY_TYPE_PCIE) | (MIPHY_PORT_1)
+
+#endif /* _DT_BINDINGS_PHY_MIPHY */
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH 3/4] ARM: DT: STi: Add DT node for MiPHY365x
From: Lee Jones @ 2014-02-14 11:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392377036-12816-1-git-send-email-lee.jones@linaro.org>

The MiPHY365x is a Generic PHY which can serve various SATA or PCIe
devices. It has 2 ports which it can use for either; both SATA, both
PCIe or one of each in any configuration.

Cc: devicetree at vger.kernel.org
Cc: Srinivas Kandagatla <srinivas.kandagatla@st.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 arch/arm/boot/dts/stih416-b2020-revE.dts |  6 +++++-
 arch/arm/boot/dts/stih416-b2020.dts      |  6 ++++++
 arch/arm/boot/dts/stih416.dtsi           | 13 +++++++++++++
 3 files changed, 24 insertions(+), 1 deletion(-)

diff --git a/arch/arm/boot/dts/stih416-b2020-revE.dts b/arch/arm/boot/dts/stih416-b2020-revE.dts
index a874570..dbe67fa 100644
--- a/arch/arm/boot/dts/stih416-b2020-revE.dts
+++ b/arch/arm/boot/dts/stih416-b2020-revE.dts
@@ -32,6 +32,10 @@
 		ethernet1: ethernet at fef08000 {
 			snps,reset-gpio 	= <&PIO0 7>;
 		};
-	};
 
+		miphy365x_phy: miphy365x at 0 {
+			st,pcie_tx_pol_inv = <1>;
+			st,sata_gen = "gen3";
+		};
+	};
 };
diff --git a/arch/arm/boot/dts/stih416-b2020.dts b/arch/arm/boot/dts/stih416-b2020.dts
index 276f28d..fd9cbad 100644
--- a/arch/arm/boot/dts/stih416-b2020.dts
+++ b/arch/arm/boot/dts/stih416-b2020.dts
@@ -13,4 +13,10 @@
 	model = "STiH416 B2020";
 	compatible = "st,stih416", "st,stih416-b2020";
 
+	soc {
+		miphy365x_phy: miphy365x at 0 {
+			st,pcie_tx_pol_inv = <1>;
+			st,sata_gen = "gen3";
+		};
+	};
 };
diff --git a/arch/arm/boot/dts/stih416.dtsi b/arch/arm/boot/dts/stih416.dtsi
index 85b8063..9fd8efb 100644
--- a/arch/arm/boot/dts/stih416.dtsi
+++ b/arch/arm/boot/dts/stih416.dtsi
@@ -9,6 +9,8 @@
 #include "stih41x.dtsi"
 #include "stih416-clock.dtsi"
 #include "stih416-pinctrl.dtsi"
+
+#include <dt-bindings/phy/phy-miphy365x.h>
 #include <dt-bindings/interrupt-controller/arm-gic.h>
 #include <dt-bindings/reset-controller/stih416-resets.h>
 / {
@@ -140,5 +142,16 @@
 			clocks		= <&CLK_S_ICN_REG_0>;
 		};
 
+		miphy365x_phy: miphy365x at 0 {
+			compatible      = "st,miphy365x-phy";
+			reg        	= <0xfe382000 0x100>,
+					  <0xfe38a000 0x100>,
+					  <0xfe394000 0x100>,
+					  <0xfe804000 0x100>;
+			reg-names  	= "sata0", "sata1", "pcie0", "pcie1";
+
+			#phy-cells 	= <2>;
+			st,syscfg  	= <&syscfg_rear>;
+		};
 	};
 };
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH 4/4] phy: miphy365x: Provide support for the MiPHY356x Generic PHY
From: Lee Jones @ 2014-02-14 11:23 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392377036-12816-1-git-send-email-lee.jones@linaro.org>

The MiPHY365x is a Generic PHY which can serve various SATA or PCIe
devices. It has 2 ports which it can use for either; both SATA, both
PCIe or one of each in any configuration.

Cc: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Lee Jones <lee.jones@linaro.org>
---
 drivers/phy/Kconfig         |  10 +
 drivers/phy/Makefile        |   1 +
 drivers/phy/phy-miphy365x.c | 614 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 625 insertions(+)
 create mode 100644 drivers/phy/phy-miphy365x.c

diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index 330ef2d..55d94cb 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -21,6 +21,16 @@ config PHY_EXYNOS_MIPI_VIDEO
 	  Support for MIPI CSI-2 and MIPI DSI DPHY found on Samsung S5P
 	  and EXYNOS SoCs.
 
+config PHY_MIPHY365X
+	tristate "STMicroelectronics MIPHY365X PHY driver for STiH41x series"
+	depends on ARCH_STI
+	depends on GENERIC_PHY
+	depends on HAS_IOMEM
+	depends on OF
+	help
+	  Enable this to support the miphy transceiver (for SATA/PCIE)
+	  that is part of STMicroelectronics STiH41x SoC series.
+
 config OMAP_USB2
 	tristate "OMAP USB2 PHY Driver"
 	depends on ARCH_OMAP2PLUS
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index d0caae9..5879639 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -5,5 +5,6 @@
 obj-$(CONFIG_GENERIC_PHY)		+= phy-core.o
 obj-$(CONFIG_PHY_EXYNOS_DP_VIDEO)	+= phy-exynos-dp-video.o
 obj-$(CONFIG_PHY_EXYNOS_MIPI_VIDEO)	+= phy-exynos-mipi-video.o
+obj-$(CONFIG_PHY_MIPHY365X)		+= phy-miphy365x.o
 obj-$(CONFIG_OMAP_USB2)			+= phy-omap-usb2.o
 obj-$(CONFIG_TWL4030_USB)		+= phy-twl4030-usb.o
diff --git a/drivers/phy/phy-miphy365x.c b/drivers/phy/phy-miphy365x.c
new file mode 100644
index 0000000..ac1e43d
--- /dev/null
+++ b/drivers/phy/phy-miphy365x.c
@@ -0,0 +1,614 @@
+/*
+ * Copyright (C) 2014 STMicroelectronics
+ *
+ * STMicroelectronics PHY driver MiPHY365 (for SoC STiH416).
+ *
+ * Author: Alexandre Torgue <alexandre.torgue@st.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <linux/platform_device.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/clk.h>
+#include <linux/phy/phy.h>
+#include <linux/delay.h>
+#include <linux/mfd/syscon.h>
+#include <linux/regmap.h>
+
+#include <dt-bindings/phy/phy-miphy365x.h>
+
+#define HFC_TIMEOUT		50
+
+#define SYSCFG_2521		0x824
+#define SYSCFG_2522		0x828
+#define SYSCFG_PCIE_SATA_MASK	BIT(1)
+#define SYSCFG_PCIE_SATA_POS	1
+
+/* MiPHY365x register definitiona */
+#define RESET_REG		0x00
+#define RST_PLL			BIT(1)
+#define RST_PLL_CAL		BIT(2)
+#define RST_RX			BIT(4)
+#define RST_MACRO		BIT(7)
+
+#define STATUS_REG		0x01
+#define IDLL_RDY		BIT(0)
+#define PLL_RDY			BIT(1)
+#define DES_BIT_LOCK		BIT(2)
+#define DES_SYMBOL_LOCK		BIT(3)
+
+#define CTRL_REG		0x02
+#define TERM_EN			BIT(0)
+#define PCI_EN			BIT(2)
+#define DES_BIT_LOCK_EN		BIT(3)
+#define TX_POL			BIT(5)
+
+#define INT_CTRL_REG		0x03
+
+#define BOUNDARY1_REG		0x10
+#define SPDSEL_SEL		BIT(0)
+
+#define BOUNDARY3_REG		0x12
+#define TX_SPDSEL_GEN1_VAL	0
+#define TX_SPDSEL_GEN2_VAL	0x01
+#define TX_SPDSEL_GEN3_VAL	0x02
+#define RX_SPDSEL_GEN1_VAL	0
+#define RX_SPDSEL_GEN2_VAL	(0x01 << 3)
+#define RX_SPDSEL_GEN3_VAL	(0x02 << 3)
+
+#define PCIE_REG		0x16
+
+#define BUF_SEL_REG		0x20
+#define CONF_GEN_SEL_GEN3	0x02
+#define CONF_GEN_SEL_GEN2	0x01
+#define PD_VDDTFILTER		BIT(4)
+
+#define TXBUF1_REG		0x21
+#define SWING_VAL		0x04
+#define SWING_VAL_GEN1		0x03
+#define PREEMPH_VAL		(0x3 << 5)
+
+#define TXBUF2_REG		0x22
+#define TXSLEW_VAL		0x2
+#define TXSLEW_VAL_GEN1		0x4
+
+#define RXBUF_OFFSET_CTRL_REG	0x23
+
+#define RXBUF_REG		0x25
+#define SDTHRES_VAL		0x01
+#define EQ_ON3			(0x03 << 4)
+#define EQ_ON1			(0x01 << 4)
+
+#define COMP_CTRL1_REG		0x40
+#define START_COMSR		BIT(0)
+#define START_COMZC		BIT(1)
+#define COMSR_DONE		BIT(2)
+#define COMZC_DONE		BIT(3)
+#define COMP_AUTO_LOAD		BIT(4)
+
+#define COMP_CTRL2_REG		0x41
+#define COMP_2MHZ_RAT_GEN1	0x1e
+#define COMP_2MHZ_RAT		0xf
+
+#define COMP_CTRL3_REG		0x42
+#define COMSR_COMP_REF		0x33
+
+#define COMP_IDLL_REG		0x47
+#define COMZC_IDLL		0x2a
+
+#define PLL_CTRL1_REG		0x50
+#define PLL_START_CAL		BIT(0)
+#define BUF_EN			BIT(2)
+#define SYNCHRO_TX		BIT(3)
+#define SSC_EN			BIT(6)
+#define CONFIG_PLL		BIT(7)
+
+#define PLL_CTRL2_REG		0x51
+#define BYPASS_PLL_CAL		BIT(1)
+
+#define PLL_RAT_REG		0x52
+
+#define PLL_SSC_STEP_MSB_REG	0x56
+#define PLL_SSC_STEP_MSB_VAL	0x03
+
+#define PLL_SSC_STEP_LSB_REG	0x57
+#define PLL_SSC_STEP_LSB_VAL	0x63
+
+#define PLL_SSC_PER_MSB_REG	0x58
+#define PLL_SSC_PER_MSB_VAL	0
+
+#define PLL_SSC_PER_LSB_REG	0x59
+#define PLL_SSC_PER_LSB_VAL	0xf1
+
+#define IDLL_TEST_REG		0x72
+#define START_CLK_HF		BIT(6)
+
+#define DES_BITLOCK_REG		0x86
+#define BIT_LOCK_LEVEL		0x01
+#define BIT_LOCK_CNT_512	(0x03 << 5)
+
+static u8 ports[] = { MIPHY_PORT_0, MIPHY_PORT_1 };
+
+struct miphy365x_phy {
+	struct phy *phy;
+	void __iomem *base;
+	void __iomem *sata;
+	void __iomem *pcie;
+	u8 type;
+	u8 port;
+};
+
+struct miphy365x_dev {
+	struct device *dev;
+	struct mutex miphy_mutex;
+	struct miphy365x_phy phys[ARRAY_SIZE(ports)];
+	bool pcie_tx_pol_inv;
+	bool sata_tx_pol_inv;
+	u32 sata_gen;
+	struct regmap *regmap;
+};
+
+enum miphy_sata_gen {
+	SATA_GEN1 = 1,
+	SATA_GEN2,
+	SATA_GEN3
+};
+
+static u8 rx_tx_spd[] = {
+	TX_SPDSEL_GEN1_VAL | RX_SPDSEL_GEN1_VAL,
+	TX_SPDSEL_GEN2_VAL | RX_SPDSEL_GEN2_VAL,
+	TX_SPDSEL_GEN3_VAL | RX_SPDSEL_GEN3_VAL
+};
+
+#define miphy365x_phy_to_dev(inst) \
+	container_of((inst), struct miphy365x_dev, phys[(inst)->port]);
+
+/*
+ * This function selects the system configuration,
+ * either two SATA, one SATA and one PCIe, or two PCIe lanes.
+ */
+static int miphy365x_set_path(struct miphy365x_phy *miphy_phy,
+			      struct miphy365x_dev *miphy_dev)
+{
+	u8 config = miphy_phy->type | miphy_phy->port;
+	u32 mask  = SYSCFG_PCIE_SATA_MASK;
+	u32 reg;
+	bool sata;
+
+	switch (config) {
+	case MIPHY_SATA_PORT0:
+		reg = SYSCFG_2521;
+		sata = true;
+		break;
+	case MIPHY_PCIE_PORT1:
+		reg = SYSCFG_2522;
+		sata = false;
+		break;
+	default:
+		dev_err(miphy_dev->dev, "Configuration not supported\n");
+		return -EINVAL;
+	}
+
+	return regmap_update_bits(miphy_dev->regmap, reg, mask,
+				  sata << SYSCFG_PCIE_SATA_POS);
+}
+
+static void miphy365x_phy_init_pcie_port(struct miphy365x_phy *miphy_phy,
+					 struct miphy365x_dev *miphy_dev)
+{
+	u8 val;
+
+	if (!miphy_dev->pcie_tx_pol_inv)
+		return;
+
+	/* Invert Tx polarity and clear pci_txdetect_pol bit */
+	val = TERM_EN | PCI_EN | DES_BIT_LOCK_EN | TX_POL;
+	writeb_relaxed(val, miphy_phy->base + CTRL_REG);
+	writeb_relaxed(0x00, miphy_phy->base + PCIE_REG);
+}
+
+static inline int miphy365x_phy_hfc_not_rdy(struct miphy365x_phy *miphy_phy,
+					    struct miphy365x_dev *miphy_dev)
+{
+	int timeout = HFC_TIMEOUT;
+	u8 mask = IDLL_RDY | PLL_RDY;
+	u8 regval;
+
+	do {
+		regval = readb_relaxed(miphy_phy->base + STATUS_REG);
+		usleep_range(2000, 2500);
+	} while (timeout-- && (regval & mask));
+
+	if (timeout < 0) {
+		dev_err(miphy_dev->dev, "HFC ready timeout!\n");
+		return -EBUSY;
+	}
+
+	return 0;
+}
+
+static inline int miphy365x_phy_rdy(struct miphy365x_phy *miphy_phy,
+				    struct miphy365x_dev *miphy_dev)
+{
+	int timeout = HFC_TIMEOUT;
+	u8 mask = IDLL_RDY | PLL_RDY;
+	u8 regval;
+
+	do {
+		regval = readb_relaxed(miphy_phy->base + STATUS_REG);
+		usleep_range(2000, 2500);
+	} while (timeout-- && ((regval & mask) != mask));
+
+	if (timeout < 0) {
+		dev_err(miphy_dev->dev, "PHY not ready timeout!\n");
+		return -EBUSY;
+	}
+
+	return 0;
+}
+
+static inline void miphy365x_phy_set_comp(struct miphy365x_phy *miphy_phy,
+					  struct miphy365x_dev *miphy_dev)
+{
+	u8 val, mask;
+
+	if (miphy_dev->sata_gen == SATA_GEN1)
+		writeb_relaxed(COMP_2MHZ_RAT_GEN1,
+			       miphy_phy->base + COMP_CTRL2_REG);
+	else
+		writeb_relaxed(COMP_2MHZ_RAT,
+			       miphy_phy->base + COMP_CTRL2_REG);
+
+	if (miphy_dev->sata_gen != SATA_GEN3) {
+		writeb_relaxed(COMSR_COMP_REF,
+			       miphy_phy->base + COMP_CTRL3_REG);
+		/*
+		 * Force VCO current to value defined by address 0x5A
+		 * and disable PCIe100Mref bit
+		 * Enable auto load compensation for pll_i_bias
+		 */
+		writeb_relaxed(BYPASS_PLL_CAL, miphy_phy->base + PLL_CTRL2_REG);
+		writeb_relaxed(COMZC_IDLL, miphy_phy->base + COMP_IDLL_REG);
+	}
+
+	/*
+	 * Force restart compensation and enable auto load
+	 * for Comzc_Tx, Comzc_Rx and Comsr on macro
+	 */
+	val = START_COMSR | START_COMZC | COMP_AUTO_LOAD;
+	writeb_relaxed(val, miphy_phy->base + COMP_CTRL1_REG);
+
+	mask = COMSR_DONE | COMZC_DONE;
+	while ((readb_relaxed(miphy_phy->base + COMP_CTRL1_REG) & mask)	!= mask)
+		cpu_relax();
+}
+
+static inline void miphy365x_phy_set_ssc(struct miphy365x_phy *miphy_phy,
+					 struct miphy365x_dev *miphy_dev)
+{
+	u8 val;
+
+	/*
+	 * SSC Settings. SSC will be enabled through Link
+	 * SSC Ampl. = 0.4%
+	 * SSC Freq = 31KHz
+	 */
+	writeb_relaxed(PLL_SSC_STEP_MSB_VAL,
+			miphy_phy->base + PLL_SSC_STEP_MSB_REG);
+	writeb_relaxed(PLL_SSC_STEP_LSB_VAL,
+			miphy_phy->base + PLL_SSC_STEP_LSB_REG);
+	writeb_relaxed(PLL_SSC_PER_MSB_VAL,
+			miphy_phy->base + PLL_SSC_PER_MSB_REG);
+	writeb_relaxed(PLL_SSC_PER_LSB_VAL,
+			miphy_phy->base + PLL_SSC_PER_LSB_REG);
+
+	/* SSC Settings complete */
+	if (miphy_dev->sata_gen == SATA_GEN1) {
+		val = PLL_START_CAL | BUF_EN | SYNCHRO_TX | CONFIG_PLL;
+		writeb_relaxed(val, miphy_phy->base + PLL_CTRL1_REG);
+	} else {
+		val = SSC_EN | PLL_START_CAL | BUF_EN | SYNCHRO_TX | CONFIG_PLL;
+		writeb_relaxed(val, miphy_phy->base + PLL_CTRL1_REG);
+	}
+}
+
+static int miphy365x_phy_init_sata_port(struct miphy365x_phy *miphy_phy,
+					struct miphy365x_dev *miphy_dev)
+{
+	int ret;
+	u8 val;
+
+	/*
+	 * Force PHY macro reset, PLL calibration reset, PLL reset
+	 * and assert Deserializer Reset
+	 */
+	val = RST_PLL | RST_PLL_CAL | RST_RX | RST_MACRO;
+	writeb_relaxed(val, miphy_phy->base + RESET_REG);
+
+	if (miphy_dev->sata_tx_pol_inv)
+		writeb_relaxed(TX_POL, miphy_phy->base + CTRL_REG);
+
+	/*
+	 * Force macro1 to use rx_lspd, tx_lspd
+	 * Force Rx_Clock on first I-DLL phase
+	 * Force Des in HP mode on macro, rx_lspd, tx_lspd for Gen2/3
+	 */
+	writeb_relaxed(SPDSEL_SEL, miphy_phy->base + BOUNDARY1_REG);
+	writeb_relaxed(START_CLK_HF, miphy_phy->base + IDLL_TEST_REG);
+	val = rx_tx_spd[miphy_dev->sata_gen];
+	writeb_relaxed(val, miphy_phy->base + BOUNDARY3_REG);
+
+	/* Wait for HFC_READY = 0 */
+	ret = miphy365x_phy_hfc_not_rdy(miphy_phy, miphy_dev);
+	if (ret)
+		return ret;
+
+	/* Compensation Recalibration */
+	miphy365x_phy_set_comp(miphy_phy, miphy_dev);
+
+	switch (miphy_dev->sata_gen) {
+	case SATA_GEN3:
+		/*
+		 * TX Swing target 550-600mv peak to peak diff
+		 * Tx Slew target 90-110ps rising/falling time
+		 * Rx Eq ON3, Sigdet threshold SDTH1
+		 */
+		val = PD_VDDTFILTER | CONF_GEN_SEL_GEN3;
+		writeb_relaxed(val, miphy_phy->base + BUF_SEL_REG);
+		val = SWING_VAL | PREEMPH_VAL;
+		writeb_relaxed(val, miphy_phy->base + TXBUF1_REG);
+		writeb_relaxed(TXSLEW_VAL, miphy_phy->base + TXBUF2_REG);
+		writeb_relaxed(0x00, miphy_phy->base + RXBUF_OFFSET_CTRL_REG);
+		val = SDTHRES_VAL | EQ_ON3;
+		writeb_relaxed(val, miphy_phy->base + RXBUF_REG);
+		break;
+	case SATA_GEN2:
+		/*
+		 * conf gen sel=0x1 to program Gen2 banked registers
+		 * VDDT filter ON
+		 * Tx Swing target 550-600mV peak-to-peak diff
+		 * Tx Slew target 90-110 ps rising/falling time
+		 * RX Equalization ON1, Sigdet threshold SDTH1
+		 */
+		writeb_relaxed(CONF_GEN_SEL_GEN2,
+			       miphy_phy->base + BUF_SEL_REG);
+		writeb_relaxed(SWING_VAL, miphy_phy->base + TXBUF1_REG);
+		writeb_relaxed(TXSLEW_VAL, miphy_phy->base + TXBUF2_REG);
+		val = SDTHRES_VAL | EQ_ON1;
+		writeb_relaxed(val, miphy_phy->base + RXBUF_REG);
+		break;
+	case SATA_GEN1:
+		/*
+		 * conf gen sel = 00b to program Gen1 banked registers
+		 * VDDT filter ON
+		 * Tx Swing target 500-550mV peak-to-peak diff
+		 * Tx Slew target120-140 ps rising/falling time
+		 */
+		writeb_relaxed(PD_VDDTFILTER, miphy_phy->base + BUF_SEL_REG);
+		writeb_relaxed(SWING_VAL_GEN1, miphy_phy->base + TXBUF1_REG);
+		writeb_relaxed(TXSLEW_VAL_GEN1,	miphy_phy->base + TXBUF2_REG);
+		break;
+	default:
+		break;
+	}
+
+	/* Force Macro1 in partial mode & release pll cal reset */
+	writeb_relaxed(RST_RX, miphy_phy->base + RESET_REG);
+	usleep_range(100, 150);
+
+	miphy365x_phy_set_ssc(miphy_phy, miphy_dev);
+
+	/* Wait for phy_ready */
+	ret = miphy365x_phy_rdy(miphy_phy, miphy_dev);
+	if (ret)
+		return ret;
+
+	/*
+	 * Enable macro1 to use rx_lspd & tx_lspd
+	 * Release Rx_Clock on first I-DLL phase on macro1
+	 * Assert deserializer reset
+	 * des_bit_lock_en is set
+	 * bit lock detection strength
+	 * Deassert deserializer reset
+	 */
+	writeb_relaxed(0x00, miphy_phy->base + BOUNDARY1_REG);
+	writeb_relaxed(0x00, miphy_phy->base + IDLL_TEST_REG);
+	writeb_relaxed(RST_RX, miphy_phy->base + RESET_REG);
+	val = miphy_dev->sata_tx_pol_inv ?
+		(TX_POL | DES_BIT_LOCK_EN) : DES_BIT_LOCK_EN;
+	writeb_relaxed(val, miphy_phy->base + CTRL_REG);
+
+	val = BIT_LOCK_CNT_512 | BIT_LOCK_LEVEL;
+	writeb_relaxed(val, miphy_phy->base + DES_BITLOCK_REG);
+	writeb_relaxed(0x00, miphy_phy->base + RESET_REG);
+
+	return 0;
+}
+
+static int miphy365x_phy_init(struct phy *phy)
+{
+	int ret = 0;
+	struct miphy365x_phy *miphy_phy = phy_get_drvdata(phy);
+	struct miphy365x_dev *miphy_dev = miphy365x_phy_to_dev(miphy_phy);
+
+	mutex_lock(&miphy_dev->miphy_mutex);
+
+	ret = miphy365x_set_path(miphy_phy, miphy_dev);
+	if (ret) {
+		mutex_unlock(&miphy_dev->miphy_mutex);
+		return ret;
+	}
+
+	/* Initialise Miphy for PCIe or SATA */
+	if (miphy_phy->type == MIPHY_TYPE_PCIE)
+		miphy365x_phy_init_pcie_port(miphy_phy, miphy_dev);
+	else
+		ret = miphy365x_phy_init_sata_port(miphy_phy, miphy_dev);
+
+	mutex_unlock(&miphy_dev->miphy_mutex);
+
+	return ret;
+}
+
+static struct phy *miphy365x_phy_xlate(struct device *dev,
+				       struct of_phandle_args *args)
+{
+	struct miphy365x_dev *state = dev_get_drvdata(dev);
+	u8 port = args->args[0];
+	u8 type = args->args[1];
+
+	if (WARN_ON(port >= ARRAY_SIZE(ports)))
+		return ERR_PTR(-EINVAL);
+
+	if (type == MIPHY_TYPE_SATA)
+		state->phys[port].base = state->phys[port].sata;
+	else if (type == MIPHY_TYPE_PCIE)
+		state->phys[port].base = state->phys[port].pcie;
+	else {
+		WARN(1, "Invalid type specified in DT");
+		return ERR_PTR(-EINVAL);
+	}
+
+	state->phys[port].type = type;
+
+	return state->phys[port].phy;
+}
+
+static struct phy_ops miphy365x_phy_ops = {
+	.init		= miphy365x_phy_init,
+	.owner		= THIS_MODULE,
+};
+
+static int miphy365x_phy_get_base_addr(struct platform_device *pdev,
+				       struct miphy365x_phy *phy, u8 port)
+{
+	struct resource *res;
+	char type[6];
+
+	sprintf(type, "sata%d", port);
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, type);
+	if (!res)
+		return -ENODEV;
+
+	phy->sata = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+	if (!phy->sata)
+		return -ENOMEM;
+
+	sprintf(type, "pcie%d", port);
+
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, type);
+	if (!res)
+		return -ENODEV;
+
+	phy->pcie = devm_ioremap(&pdev->dev, res->start, resource_size(res));
+	if (!phy->pcie)
+		return -ENOMEM;
+
+	return 0;
+}
+
+static int miphy365x_phy_of_probe(struct device_node *np,
+				  struct miphy365x_dev *phy_dev)
+{
+	phy_dev->regmap = syscon_regmap_lookup_by_phandle(np, "st,syscfg");
+	if (IS_ERR(phy_dev->regmap)) {
+		dev_err(phy_dev->dev, "No syscfg phandle specified\n");
+		return PTR_ERR(phy_dev->regmap);
+	}
+
+	of_property_read_u32(np, "st,sata-gen", &phy_dev->sata_gen);
+	if (!phy_dev->sata_gen)
+		phy_dev->sata_gen = SATA_GEN1;
+
+	phy_dev->pcie_tx_pol_inv =
+		of_property_read_bool(np, "st,pcie-tx-pol-inv");
+
+	phy_dev->sata_tx_pol_inv =
+		of_property_read_bool(np, "st,sata-tx-pol-inv");
+
+	return 0;
+}
+
+static int miphy365x_phy_probe(struct platform_device *pdev)
+{
+	struct device_node *np = pdev->dev.of_node;
+	struct miphy365x_dev *phy_dev;
+	struct device *dev = &pdev->dev;
+	struct phy_provider *provider;
+	u8 port;
+	int ret;
+
+	if (!np) {
+		dev_err(dev, "No DT node found\n");
+		return -EINVAL;
+	}
+
+	phy_dev = devm_kzalloc(dev, sizeof(*phy_dev), GFP_KERNEL);
+	if (!phy_dev)
+		return -ENOMEM;
+
+	ret = miphy365x_phy_of_probe(np, phy_dev);
+	if (ret)
+		return ret;
+
+	phy_dev->dev = dev;
+
+	dev_set_drvdata(dev, phy_dev);
+
+	mutex_init(&phy_dev->miphy_mutex);
+
+	for (port = 0; port < ARRAY_SIZE(ports); port++) {
+		struct phy *phy;
+
+		phy = devm_phy_create(dev, &miphy365x_phy_ops, NULL);
+		if (IS_ERR(phy)) {
+			dev_err(dev, "failed to create PHY on port %d\n", port);
+			return PTR_ERR(phy);
+		}
+
+		phy_dev->phys[port].phy  = phy;
+		phy_dev->phys[port].port = port;
+
+		ret = miphy365x_phy_get_base_addr(pdev,
+					&phy_dev->phys[port], port);
+		if (ret)
+			return ret;
+
+		phy_set_drvdata(phy, &phy_dev->phys[port]);
+	}
+
+	provider = devm_of_phy_provider_register(dev, miphy365x_phy_xlate);
+	if (IS_ERR(provider))
+		return PTR_ERR(provider);
+
+	return 0;
+}
+
+static const struct of_device_id miphy365x_phy_of_match[] = {
+	{ .compatible = "st,miphy365x-phy", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, miphy365x_phy_of_match);
+
+static struct platform_driver miphy365x_phy_driver = {
+	.probe	= miphy365x_phy_probe,
+	.driver = {
+		.name	= "miphy365x-phy",
+		.owner	= THIS_MODULE,
+		.of_match_table	= miphy365x_phy_of_match,
+	}
+};
+module_platform_driver(miphy365x_phy_driver);
+
+MODULE_AUTHOR("Alexandre Torgue <alexandre.torgue@st.com>");
+MODULE_DESCRIPTION("STMicroelectronics miphy365x driver");
+MODULE_LICENSE("GPL v2");
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH 1/2] PPC: powernv: remove redundant cpuidle_idle_call()
From: Deepthi Dharwar @ 2014-02-14 11:25 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52FDFB4C.7010607@linux.vnet.ibm.com>

On 02/14/2014 04:47 PM, Preeti U Murthy wrote:
> Hi Nicolas,
> 
> You will have to include the below patch with yours. You
> could squash the two I guess, I have added the changelog
> just for clarity. And you also might want to change the subject to
> cpuidle/powernv. It gives a better picture.
> 
> Thanks
> 
> Regards
> Preeti U Murthy
> 
> 
> cpuidle/powernv: Add ppc64_runlatch_off/on() to idle routines
> 
> Following moving of cpuidle_idle_call() to the generic idle loop, we need to
> add the runlatch functions to the idle routines on powernv which was earlier
> taken care of by the arch specific idle routine.
> 
> Signed-off-by: Preeti U Murthy <preeti@linux.vnet.ibm.com>

Reviewed-by: Deepthi Dharwar <deepthi@linux.vnet.ibm.com>

> ---
>  drivers/cpuidle/cpuidle-powernv.c |    5 +++++
>  1 file changed, 5 insertions(+)
> 
> diff --git a/drivers/cpuidle/cpuidle-powernv.c b/drivers/cpuidle/cpuidle-powernv.c
> index 78fd174..f48607c 100644
> --- a/drivers/cpuidle/cpuidle-powernv.c
> +++ b/drivers/cpuidle/cpuidle-powernv.c
> @@ -14,6 +14,7 @@
> 
>  #include <asm/machdep.h>
>  #include <asm/firmware.h>
> +#include <asm/runlatch.h>
> 
>  struct cpuidle_driver powernv_idle_driver = {
>  	.name             = "powernv_idle",
> @@ -30,12 +31,14 @@ static int snooze_loop(struct cpuidle_device *dev,
>  	local_irq_enable();
>  	set_thread_flag(TIF_POLLING_NRFLAG);
> 
> +	ppc64_runlatch_off();
>  	while (!need_resched()) {
>  		HMT_low();
>  		HMT_very_low();
>  	}
> 
>  	HMT_medium();
> +	ppc64_runlatch_on();
>  	clear_thread_flag(TIF_POLLING_NRFLAG);
>  	smp_mb();
>  	return index;
> @@ -45,7 +48,9 @@ static int nap_loop(struct cpuidle_device *dev,
>  			struct cpuidle_driver *drv,
>  			int index)
>  {
> +	ppc64_runlatch_off();
>  	power7_idle();
> +	ppc64_runlatch_on();
>  	return index;
>  }
> 
> 
> On 02/06/2014 07:46 PM, Nicolas Pitre wrote:
>> The core idle loop now takes care of it.
>>
>> Signed-off-by: Nicolas Pitre <nico@linaro.org>
>> ---
>>  arch/powerpc/platforms/powernv/setup.c | 13 +------------
>>  1 file changed, 1 insertion(+), 12 deletions(-)
>>
>> diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c
>> index 21166f65c9..a932feb290 100644
>> --- a/arch/powerpc/platforms/powernv/setup.c
>> +++ b/arch/powerpc/platforms/powernv/setup.c
>> @@ -26,7 +26,6 @@
>>  #include <linux/of_fdt.h>
>>  #include <linux/interrupt.h>
>>  #include <linux/bug.h>
>> -#include <linux/cpuidle.h>
>>
>>  #include <asm/machdep.h>
>>  #include <asm/firmware.h>
>> @@ -217,16 +216,6 @@ static int __init pnv_probe(void)
>>  	return 1;
>>  }
>>
>> -void powernv_idle(void)
>> -{
>> -	/* Hook to cpuidle framework if available, else
>> -	 * call on default platform idle code
>> -	 */
>> -	if (cpuidle_idle_call()) {
>> -		power7_idle();
>> -	}
>> -}
>> -
>>  define_machine(powernv) {
>>  	.name			= "PowerNV",
>>  	.probe			= pnv_probe,
>> @@ -236,7 +225,7 @@ define_machine(powernv) {
>>  	.show_cpuinfo		= pnv_show_cpuinfo,
>>  	.progress		= pnv_progress,
>>  	.machine_shutdown	= pnv_shutdown,
>> -	.power_save             = powernv_idle,
>> +	.power_save             = power7_idle,
>>  	.calibrate_decr		= generic_calibrate_decr,
>>  #ifdef CONFIG_KEXEC
>>  	.kexec_cpu_down		= pnv_kexec_cpu_down,
>>
> 
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev at lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
> 

^ permalink raw reply

* [PATCH RFC v3 3/3] Documentation: arm: define DT idle states bindings
From: Lorenzo Pieralisi @ 2014-02-14 11:27 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140214002926.1014.3599@capellas-linux>

On Fri, Feb 14, 2014 at 12:29:26AM +0000, Sebastian Capella wrote:
> Quoting Lorenzo Pieralisi (2014-02-13 04:47:32)
> 
> > Such as ? "idle-states" ?
> 
> That sounds good to me.  Our preference is for idle-states to be used
> for name of the idle-states.txt node.

Ok, so s/cpu-idle-state/idle-state everywhere, inclusive of state nodes
compatible properties ("arm,cpu-idle-state" becomes "arm,idle-state") ?

> > > During last connect, we'd discussed that the small set of
> > > states here could apply to a single node, which can represent a cpu, a
> > > cluster with cache etc.  Then the complexities of the system power state
> > > would be represented using a heirarchy, with each node in the
> > > tree having its own state from the list above.  This would allow
> > > a fairly rich system state while having just a few power states defined
> > > at each level.  Is this how you're intending these bindings to go?
> >
> > Yes, CPUs point at states that can be reached by that CPU (eg a CPU core
> > gating state is represented by a single node pointed at by all CPUs in the
> > system - it the same state data, different power domains though).
> > 
> > States are hierarchical, which means that a parent state implies entry on all
> > substates that's how cluster states are defined.
> 
> The cpu 0 node, in its cpu-idle-state array is also pointing at a cluster
> node right?  STATE0 -> power-domains refers to <pd_clusters 0>.  Is it
> correct that if the cpu's workload is such that it tolerates the
> 500/1000/2500 entry/exit latency/min-residency, it will call the
> entry-method with the psci-power-state of 0x10100000 matching that node?

Yes. As we know, since it is a cluster state, that might happen or not
depending on the state of other CPUs.

> > > Also, would it be nice to have a name field for each state?
> > 
> > There is:
> > 
> > "The state node name shall be "stateN", where N = {0, 1, ...} is
> > the node number; state nodes which are siblings within a single
> > common parent node must be given a unique and sequential N value,
> > starting from 0."
> > I can remove the rule and allow people to call states as they wish
> > since they already have a compatible property to match them.
> > 
> > Actually, states can be called with any name, provided it is unique.
> 
> Sorry, I was referring to a descriptive name string property.  Something
> that can be useful to help a human understand what's going on.  Naming
> the nodes might work too.

I do not like that, but I can remove the naming scheme and let people
find a naming scheme that complies with DT rules (nodes within a parent
must have a unique name). Not sure this would make dts more readable, but
I do not think it is a problem either.

> > > > +       A state node can contain state child nodes. A state node with
> > > > +       children represents a hierarchical state, which is a superset of
> > > > +       the child states. Hierarchical states require all CPUs on which
> > > > +       they are valid to request the state in order for it to be entered.
> > > 
> > > Is it possible for a cpu to request a deeper state and unblock other cpus
> > > from entering this state?
> > 
> > That's not DT bindings business, hierarchical states define states that
> > require all CPUs on which they are valid to enter that state for it to
> > be considered "enabled".
> > 
> > It is a hard nut to crack. In x86 this stuff does not exist and it is
> > managed in HW, basically an idle state is always per-cpu (but it might
> > end up becoming a package state when all CPUs in a package enter that
> > state). On ARM, we want to define hierarchical states explicitly to
> > link resources (ie caches) to them.
> > 
> > CPUs are not prevented from requesting a hierarchical state, but the
> > state only becomes "enabled" when all CPUs on which it is valid request
> > it.
> 
> The way we've seen it work, is a cpu tries to enter the lowest state it can
> tolerate (including for eg. cluster off).  The system level code then looks
> at the allowable states from all the cpus and selects the lowest power
> state permissible for the heirarchies.
> 
> Eg. this way, the last cpu preventing a cluster from going to sleep enters
> cluster sleep state (where peer cpu's have already voted for cluster
> sleep) and the cluster will sleep.  Alternately if the same cpu cannot
> tolerate the additional latency of the cluster sleeping, it will vote
> only for cpu-sleep, then the cluster remains in a state where all cpu's are
> sleeping but the cluster remains up.

That's exactly what these bindings are meant to describe too and I think they
do. There is also loads of information that can be used for tuning (what
caches are affected by an idle state, what CPUs "share" an idle-state
and so on).

> > I cannot think of any other way of to express this properly but still in
> > a compact way.
> 
> You're doing a great job by the way!  Thanks! :)

Thank you, we are almost there.

> > > "all CPUs on which they are valid" is this determined by seeing which
> > > state's phandle is in each cpu->cpu-idle-states?
> > 
> > Yes, does it make sense ?
> 
> Yup, maybe adding a little parenthetical text like below may help others
> as well?
> 
> Hierarchical states require all CPUs on which they are valid (ie. CPU nodes
> containing cpu-idle-state arrays having a phandle reference to the state)
> to request the state in order for it to be entered.

OK, applied.

> > 
> > > Definition: It represents an idle state index.
> > > 
> > >         Index 0 and 1 shall not be specified and are reserved for ARM
> > >         states where index 0 is running, and index 1 is idle_standby
> > >         entered by executing a wfi instruction (SBSA,[3])
> > > 
> > > What mechanism is used to order the power states WRT power consumption?
> > 
> > I think we should use index for that. The higher the index the lower the
> > power consumption.
> 
> Ok, I think I get it now.
> If we decouple index and SBSA states, do we really need to reserve index
> 0 and 1 then?

What I will do: move the entry-method to top-level cpu-idle-states node
(soon to be idle-states node) and add a property there:

"arm,has-idlewfi"

which allows me to prevent people from adding an explicit state that just
executes the wfi instruction on entry.

This way we can have a *global* entry-method, and we can also detect if the
platform supports wfi in its bare form.

Yes, index can start from 0, disallowing 0 and 1 was a (odd) way to prevent
people from adding wfi to DT. If the platform supports simple idlestandby
(ie wfi) it has to add the boolean property above.

How does that sound ?

> > > Can this field be used to combine both psci and non-psci states in any order?
> > 
> > No. I will enforce a unique entry method.
> 
> So a single entry-method for all  states in idle-states node?
> Should this be specified once only then?

Yes, see above.

> Should we not allow more flexibility here to mix methods where some
> states use one method and some use others?  Is this mostly a security
> concern?  What if a vendor wants to introduce a state between wfi and
> cpu-sleep?

entry-method-param is the way to differentiate. One interface/entry-method
(PSCI or vendor specific), different state parameters.

We are not installing multiple back-ends to enter different idle states,
are we ? That would be awkward.

ACK ?

> > > I assume psci will be turning off the powerdomains not Linux right?
> > 
> > This is not a PSCI only document, and even if it was, we still need to deal
> > with devices. Which means we need to know what we have to save/restore (PMU,
> > arch timer, GIC), and power domains help us detect that.
> 
> > > > +
> > > > +cpus {
> > > > +       #size-cells = <0>;
> > > > +       #address-cells = <2>;
> > > > +
> > > > +       cpu-idle-states {
> > > > +
> > > > +               STATE0: state0 {
> > > > +                       compatible = "arm,cpu-idle-state";
> > > > +                       index = <3>;
> > > 
> > > Are the index fields of nested states independent of each other or
> > > sequential?
> > ...
> > I understand index is misleading and either I remove it, or I
> > leave it there to define power savings scale as you mentioned.
> 
> I like index, but I was confused.  You cleared it up pretty quick with
> your earlier comment.  Removing the numbering may help, but I think
> keeping the index is useful.

I will leave the index to sort the states according to power consumption.

Thanks !
Lorenzo

^ permalink raw reply

* [PATCH V2 2/3] ARM: dts: add dts files for exynos5260 SoC
From: Rahul Sharma @ 2014-02-14 11:28 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAPdUM4Pu-CbuNwwjrd_8itbSbjKqTBLE5u_T_vO89jreOy4=kQ@mail.gmail.com>

On 14 February 2014 08:54, Rahul Sharma <r.sh.open@gmail.com> wrote:
> Thanks Tomasz,
>
> I will add these changes to v3.
>
> Regards,
> Rahul Sharma.
>
> On 11 February 2014 15:34, Tomasz Figa <tomasz.figa@gmail.com> wrote:
>> Hi Rahul,
>>
>>
>> On 11.02.2014 06:22, Rahul Sharma wrote:
>>>
>>> Hi Tomasz,
>>>
>>> On 6 February 2014 18:51, Tomasz Figa <t.figa@samsung.com> wrote:
>>>>
>>>> Hi Rahul, Pankaj, Arun,
>>>>
>>>> [adding linux-arm-kernel, devicetree MLs and DT people on Cc]
>>>>
>>>> I think it's good time to stop accepting DTS files like this and force
>>>> new
>>>> ones to use the proper structure with soc node, labels for every node and
>>>> node references.
>>>
>>>
>>> I am unable to find information on SoC node and grouping inside SoC node.
>>> Please
>>> share some pointers.
>>
>>
>> Well, there is not much information needed about this. Basically all the
>> devices built into the SoC should be listed under respective bus nodes or a
>> single soc node, instead of root level. Such node should be a "simple-bus"
>> and just group the components together to separate board-specific devices
>> (which are still at root level) from SoC devices.
>>
>> Even though it might seem useless, it improves DT readability a bit and
>> still most of the platforms use this approach, so for consistency, Exynos
>> should use too.
>>
>> Just for reference, back in April 2013, in his review of S3C64xx DT series
>> [1], Rob Herring requested that we don't submit any new device trees using
>> flat approach and start using bus hierarchy.
>>
>> [1]
>> http://lists.infradead.org/pipermail/linux-arm-kernel/2013-April/163659.html
>>
>>
>>>>
>>>>> +               spi0_bus: spi0-bus {
>>>>> +                       samsung,pins = "gpa2-0", "gpa2-1", "gpa2-2",
>>>>> "gpa2-3";
>>>>
>>>>
>>>>
>>>> What is the reason for SPI0 to have 4 pins, while SPI1 has just 3?
>>>>
>>>
>>> I should align SPI1 with SPI0.
>>>
>>
>> Are you sure that SPI0 is the correct one? SPI usually uses four pins - SDI,
>> SDO, SCK and nCS, but we always used to treat nCS as a simple GPIO, due to
>> the fact that the controller can only support one dedicated chip select and
>> with direct GPIO control you can have more.
>>
>> What is the fourth pin here?
>>

As you said, these are CLK, SS, MISO, MOSI (gpa2-0 to gpa2-3). Fourth pin is
CS. It can be defined as a simple GPIO but better to include it in the
SPI pingroup
as it belongs to there.

Regards,
Rahul Sharma.

>>
>>>>
>>>>> +               cpu at 1 {
>>>>> +                       device_type = "cpu";
>>>>> +                       compatible = "arm,cortex-a15";
>>>>> +                       reg = <1>;
>>>>> +                       cci-control-port = <&cci_control1>;
>>>>> +               };
>>>>> +               cpu at 100 {
>>>>> +                       device_type = "cpu";
>>>>> +                       compatible = "arm,cortex-a7";
>>>>> +                       reg = <0x100>;
>>>>> +                       cci-control-port = <&cci_control0>;
>>>>> +               };
>>>>> +               cpu at 101 {
>>>>> +                       device_type = "cpu";
>>>>> +                       compatible = "arm,cortex-a7";
>>>>> +                       reg = <0x101>;
>>>>> +                       cci-control-port = <&cci_control0>;
>>>>> +               };
>>>>> +               cpu at 102 {
>>>>> +                       device_type = "cpu";
>>>>> +                       compatible = "arm,cortex-a7";
>>>>> +                       reg = <0x102>;
>>>>> +                       cci-control-port = <&cci_control0>;
>>>>> +               };
>>>>> +               cpu at 103 {
>>>>> +                       device_type = "cpu";
>>>>> +                       compatible = "arm,cortex-a7";
>>>>> +                       reg = <0x103>;
>>>>> +                       cci-control-port = <&cci_control0>;
>>>>> +               };
>>>>> +       };
>>>>> +
>>>>> +       cmus {
>>>>> +               #address-cells = <1>;
>>>>> +               #size-cells = <1>;
>>>>> +               ranges;
>>>>> +
>>>>
>>>>
>>>>
>>>> I don't think there is a need to group these nodes under a parent node
>>>> that
>>>> doesn't give any additional information, especially when the CMUs are
>>>> scattered trough the whole address space, while we'd like to keep the
>>>> nodes
>>>> ordered by their addresses, as most platforms do.
>>>>
>>>
>>> This is exactly the same case as "cpus". I mean, "cpus" also doesn't
>>> provide
>>> any common information about child cpu nodes. This looks to me as a
>>> logical
>>> grouping and I have implemented same thing for cmu nodes.
>>> I am ok with removing this grouping Just want to understand the rational
>>> behind
>>> grouping cpus which seems similar to cmus.
>>
>>
>> The "cpus" node is a defined standard node that should be present at root of
>> device tree and include subnodes for all CPUs. This is a standard binding
>> defined for low level code to be able to simply find nodes of all CPUs in
>> the system - so they can expect that at /cpus node all the subnodes are
>> subsequent CPUs.
>>
>>
>>> Similarly "soc" is just a logical entity used to group SoC elements which
>>> looks
>>> optional to me. What are we achieving with this? Please help me in
>>> understanding
>>> this better.
>>
>>
>> Also "soc" has a slightly wider meaning. It is a node grouping all nodes
>> from a single address space - the node specifies #address-cells and
>> #size-cells of this address space and all the devices under this
>> "simple-bus" can be accessed using addresses in this format. In addition, it
>> separates board-level devices from generic SoC devices.
>>
>> Now, in case of "cmus", the only purpose is to group all CMU nodes together
>> and, while this improves readability a bit, it doesn't make the DT better
>> express the hardware topology, because the CMUs in the hardware are in fact
>> scattered through the whole address space, not under a contiguous block of
>> it, as the grouping would suggest.
>>
>> Best regards,
>> Tomasz

^ permalink raw reply

* [PATCH 1/5] i2c: mv64xxx: put offload check into offload prepare function
From: Gregory CLEMENT @ 2014-02-14 11:38 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392323793-4125-2-git-send-email-wsa@the-dreams.de>

On 13/02/2014 21:36, Wolfram Sang wrote:
> It makes code simpler to read and prepares a reorganization needed for a
> bugfix.
> 
> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>

Tested-by: Gregory CLEMENT <gregory.clement@free-electrons.com>

As expected it didn't fix the issue I had, but it didn't introduce
any visible regression too.

> ---
>  drivers/i2c/busses/i2c-mv64xxx.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
> index b8c5187..ba64978 100644
> --- a/drivers/i2c/busses/i2c-mv64xxx.c
> +++ b/drivers/i2c/busses/i2c-mv64xxx.c
> @@ -204,6 +204,9 @@ static int mv64xxx_i2c_offload_msg(struct mv64xxx_i2c_data *drv_data)
>  	unsigned long ctrl_reg;
>  	struct i2c_msg *msg = drv_data->msgs;
>  
> +	if (!drv_data->offload_enabled)
> +		return -EOPNOTSUPP;
> +
>  	drv_data->msg = msg;
>  	drv_data->byte_posn = 0;
>  	drv_data->bytes_left = msg->len;
> @@ -433,8 +436,7 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
>  
>  		drv_data->msgs++;
>  		drv_data->num_msgs--;
> -		if (!(drv_data->offload_enabled &&
> -				mv64xxx_i2c_offload_msg(drv_data))) {
> +		if (mv64xxx_i2c_offload_msg(drv_data) < 0) {
>  			drv_data->cntl_bits |= MV64XXX_I2C_REG_CONTROL_START;
>  			writel(drv_data->cntl_bits,
>  			drv_data->reg_base + drv_data->reg_offsets.control);
> 


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

^ permalink raw reply

* [PATCH] ARM: imx6: fix !CONFIG_PM and !CONFIG_CPU_IDLE build
From: Lucas Stach @ 2014-02-14 11:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140213141944.GC20842@S2101-09.ap.freescale.net>

Hi Shawn,

Am Donnerstag, den 13.02.2014, 22:19 +0800 schrieb Shawn Guo:
> Hi Lucas,
> 
> On Wed, Feb 12, 2014 at 11:45:48AM +0100, Lucas Stach wrote:
> > When building a kernel with only CONFIG_CPU_IDLE, but no
> > CONFIG_PM we still need the functions to set the lpm mode
> > and chicken bits.
> > 
> > Also if both options are unset, we have to stub out the
> > set_lpm function, as this one is called from the clk
> > driver directly.
> > 
> > Signed-off-by: Lucas Stach <l.stach@pengutronix.de>
> > ---
> > This fix depends on an earlier one by Philipp:
> > "ARM: imx6: Initialize low-power mode early again"
> > 
> > Both should go to stable after a sensible sinking time.
> > ---
> >  arch/arm/mach-imx/Makefile   |   9 +++-
> >  arch/arm/mach-imx/common.h   |  11 +++--
> >  arch/arm/mach-imx/pm-imx6q.c | 112 ++++++++++++++++++++++---------------------
> >  3 files changed, 72 insertions(+), 60 deletions(-)
> 
> Since we already have so many stuff in pm-imx6q.c needed by a !CONFIG_PM
> build, maybe we should build pm-imx6q.c without CONFIG_PM condition,
> something like the following?
> 
Yes, while thinking about this again it seems to make sense. I first was
a bit afraid of calling pm_init unconditionally, but aside from a bit
increased binary size it should be harmless and it simplifies things a
lot, compared with my patch.

So feel free to take yours.

Regards,
Lucas
> Shawn
> 
> ---8<-----------
> 
> diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile
> index befcaf5..ec41964 100644
> --- a/arch/arm/mach-imx/Makefile
> +++ b/arch/arm/mach-imx/Makefile
> @@ -101,11 +101,9 @@ obj-$(CONFIG_HOTPLUG_CPU) += hotplug.o
>  obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o mach-imx6q.o
>  obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o mach-imx6sl.o
> 
> -ifeq ($(CONFIG_PM),y)
>  obj-$(CONFIG_SOC_IMX6Q) += pm-imx6q.o headsmp.o
>  # i.MX6SL reuses i.MX6Q code
>  obj-$(CONFIG_SOC_IMX6SL) += pm-imx6q.o headsmp.o
> -endif
> 
>  # i.MX5 based machines
>  obj-$(CONFIG_MACH_MX51_BABBAGE) += mach-mx51_babbage.o
> diff --git a/arch/arm/mach-imx/common.h b/arch/arm/mach-imx/common.h
> index 59c3b9b..baf439d 100644
> --- a/arch/arm/mach-imx/common.h
> +++ b/arch/arm/mach-imx/common.h
> @@ -144,13 +144,11 @@ void imx6q_set_chicken_bit(void);
>  void imx_cpu_die(unsigned int cpu);
>  int imx_cpu_kill(unsigned int cpu);
> 
> -#ifdef CONFIG_PM
>  void imx6q_pm_init(void);
>  void imx6q_pm_set_ccm_base(void __iomem *base);
> +#ifdef CONFIG_PM
>  void imx5_pm_init(void);
>  #else
> -static inline void imx6q_pm_init(void) {}
> -static inline void imx6q_pm_set_ccm_base(void __iomem *base) {}
>  static inline void imx5_pm_init(void) {}
>  #endif
> 
> 
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

-- 
Pengutronix e.K.                           | Lucas Stach                 |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-5076 |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply

* [PATCH 2/5] i2c: mv64xxx: refactor message start to ensure proper initialization
From: Gregory CLEMENT @ 2014-02-14 11:39 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392323793-4125-3-git-send-email-wsa@the-dreams.de>

On 13/02/2014 21:36, Wolfram Sang wrote:
> Because the offload mechanism can fall back to a standard transfer,
> having two seperate initialization states is unfortunate. Let's just
> have one state which does things consistently. This fixes a bug where
> some preparation was missing when the fallback happened. And it makes
> the code much easier to follow.
> 
> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>


Tested-by: Gregory CLEMENT <gregory.clement@free-electrons.com>

With this one the bug we observed was fixed.


Thanks,

Gregory


> ---
>  drivers/i2c/busses/i2c-mv64xxx.c | 27 ++++++++++-----------------
>  1 file changed, 10 insertions(+), 17 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
> index ba64978..d52d849 100644
> --- a/drivers/i2c/busses/i2c-mv64xxx.c
> +++ b/drivers/i2c/busses/i2c-mv64xxx.c
> @@ -97,7 +97,6 @@ enum {
>  enum {
>  	MV64XXX_I2C_ACTION_INVALID,
>  	MV64XXX_I2C_ACTION_CONTINUE,
> -	MV64XXX_I2C_ACTION_OFFLOAD_SEND_START,
>  	MV64XXX_I2C_ACTION_SEND_START,
>  	MV64XXX_I2C_ACTION_SEND_RESTART,
>  	MV64XXX_I2C_ACTION_OFFLOAD_RESTART,
> @@ -460,15 +459,14 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
>  			drv_data->reg_base + drv_data->reg_offsets.control);
>  		break;
>  
> -	case MV64XXX_I2C_ACTION_OFFLOAD_SEND_START:
> -		if (!mv64xxx_i2c_offload_msg(drv_data))
> -			break;
> -		else
> -			drv_data->action = MV64XXX_I2C_ACTION_SEND_START;
> -		/* FALLTHRU */
>  	case MV64XXX_I2C_ACTION_SEND_START:
> -		writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START,
> -			drv_data->reg_base + drv_data->reg_offsets.control);
> +		/* Can we offload this msg ? */
> +		if (mv64xxx_i2c_offload_msg(drv_data) < 0) {
> +			/* No, switch to standard path */
> +			mv64xxx_i2c_prepare_for_io(drv_data, drv_data->msgs);
> +			writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START,
> +				drv_data->reg_base + drv_data->reg_offsets.control);
> +		}
>  		break;
>  
>  	case MV64XXX_I2C_ACTION_SEND_ADDR_1:
> @@ -627,15 +625,10 @@ mv64xxx_i2c_execute_msg(struct mv64xxx_i2c_data *drv_data, struct i2c_msg *msg,
>  	unsigned long	flags;
>  
>  	spin_lock_irqsave(&drv_data->lock, flags);
> -	if (drv_data->offload_enabled) {
> -		drv_data->action = MV64XXX_I2C_ACTION_OFFLOAD_SEND_START;
> -		drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_START_COND;
> -	} else {
> -		mv64xxx_i2c_prepare_for_io(drv_data, msg);
>  
> -		drv_data->action = MV64XXX_I2C_ACTION_SEND_START;
> -		drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_START_COND;
> -	}
> +	drv_data->action = MV64XXX_I2C_ACTION_SEND_START;
> +	drv_data->state = MV64XXX_I2C_STATE_WAITING_FOR_START_COND;
> +
>  	drv_data->send_stop = is_last;
>  	drv_data->block = 1;
>  	mv64xxx_i2c_do_action(drv_data);
> 


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

^ permalink raw reply

* [PATCH 3/5] i2c: mv64xxx: refactor send_start
From: Gregory CLEMENT @ 2014-02-14 11:42 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392323793-4125-4-git-send-email-wsa@the-dreams.de>

On 13/02/2014 21:36, Wolfram Sang wrote:
> For start and restart, we are doing the same thing. Let's consolidate
> that.
> 
> Signed-off-by: Wolfram Sang <wsa@the-dreams.de>

With my first tests it continue to work with this change,
but I want to have a closer look on it

Thanks,

Gregory


> ---
>  drivers/i2c/busses/i2c-mv64xxx.c | 30 ++++++++++++++++--------------
>  1 file changed, 16 insertions(+), 14 deletions(-)
> 
> diff --git a/drivers/i2c/busses/i2c-mv64xxx.c b/drivers/i2c/busses/i2c-mv64xxx.c
> index d52d849..9c37b59 100644
> --- a/drivers/i2c/busses/i2c-mv64xxx.c
> +++ b/drivers/i2c/busses/i2c-mv64xxx.c
> @@ -419,6 +419,17 @@ mv64xxx_i2c_fsm(struct mv64xxx_i2c_data *drv_data, u32 status)
>  	}
>  }
>  
> +static void mv64xxx_i2c_send_start(struct mv64xxx_i2c_data *drv_data)
> +{
> +	/* Can we offload this msg ? */
> +	if (mv64xxx_i2c_offload_msg(drv_data) < 0) {
> +		/* No, switch to standard path */
> +		mv64xxx_i2c_prepare_for_io(drv_data, drv_data->msgs);
> +		writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START,
> +			drv_data->reg_base + drv_data->reg_offsets.control);
> +	}
> +}
> +
>  static void
>  mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
>  {
> @@ -435,14 +446,11 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
>  
>  		drv_data->msgs++;
>  		drv_data->num_msgs--;
> -		if (mv64xxx_i2c_offload_msg(drv_data) < 0) {
> -			drv_data->cntl_bits |= MV64XXX_I2C_REG_CONTROL_START;
> -			writel(drv_data->cntl_bits,
> -			drv_data->reg_base + drv_data->reg_offsets.control);
> +		// CHECKME: Does it work? Order of writel and prepare_for_io is
> +		// exchanged. Also, do we need to change cntl_bits in drv_data
> +		// with |= MV64XXX_I2C_REG_CONTROL_START?
> +		mv64xxx_i2c_send_start(drv_data);
>  
> -			/* Setup for the next message */
> -			mv64xxx_i2c_prepare_for_io(drv_data, drv_data->msgs);
> -		}
>  		if (drv_data->errata_delay)
>  			udelay(5);
>  
> @@ -460,13 +468,7 @@ mv64xxx_i2c_do_action(struct mv64xxx_i2c_data *drv_data)
>  		break;
>  
>  	case MV64XXX_I2C_ACTION_SEND_START:
> -		/* Can we offload this msg ? */
> -		if (mv64xxx_i2c_offload_msg(drv_data) < 0) {
> -			/* No, switch to standard path */
> -			mv64xxx_i2c_prepare_for_io(drv_data, drv_data->msgs);
> -			writel(drv_data->cntl_bits | MV64XXX_I2C_REG_CONTROL_START,
> -				drv_data->reg_base + drv_data->reg_offsets.control);
> -		}
> +		mv64xxx_i2c_send_start(drv_data);
>  		break;
>  
>  	case MV64XXX_I2C_ACTION_SEND_ADDR_1:
> 


-- 
Gregory Clement, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com

^ permalink raw reply

* [PATCH V2 2/3] ARM: dts: add dts files for exynos5260 SoC
From: Tomasz Figa @ 2014-02-14 11:49 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAPdUM4Pr7UC3wzYMsO+sYQHRDGixSNsR3XQuHBomsi-H-dfOZw@mail.gmail.com>

On 14.02.2014 12:28, Rahul Sharma wrote:
> On 14 February 2014 08:54, Rahul Sharma <r.sh.open@gmail.com> wrote:
>> Thanks Tomasz,
>>
>> I will add these changes to v3.
>>
>> Regards,
>> Rahul Sharma.
>>
>> On 11 February 2014 15:34, Tomasz Figa <tomasz.figa@gmail.com> wrote:
>>> Hi Rahul,
>>>
>>>
>>> On 11.02.2014 06:22, Rahul Sharma wrote:
>>>>
>>>> Hi Tomasz,
>>>>
>>>> On 6 February 2014 18:51, Tomasz Figa <t.figa@samsung.com> wrote:
>>>>>
>>>>> Hi Rahul, Pankaj, Arun,
>>>>>
>>>>> [adding linux-arm-kernel, devicetree MLs and DT people on Cc]
>>>>>
>>>>> I think it's good time to stop accepting DTS files like this and force
>>>>> new
>>>>> ones to use the proper structure with soc node, labels for every node and
>>>>> node references.
>>>>
>>>>
>>>> I am unable to find information on SoC node and grouping inside SoC node.
>>>> Please
>>>> share some pointers.
>>>
>>>
>>> Well, there is not much information needed about this. Basically all the
>>> devices built into the SoC should be listed under respective bus nodes or a
>>> single soc node, instead of root level. Such node should be a "simple-bus"
>>> and just group the components together to separate board-specific devices
>>> (which are still at root level) from SoC devices.
>>>
>>> Even though it might seem useless, it improves DT readability a bit and
>>> still most of the platforms use this approach, so for consistency, Exynos
>>> should use too.
>>>
>>> Just for reference, back in April 2013, in his review of S3C64xx DT series
>>> [1], Rob Herring requested that we don't submit any new device trees using
>>> flat approach and start using bus hierarchy.
>>>
>>> [1]
>>> http://lists.infradead.org/pipermail/linux-arm-kernel/2013-April/163659.html
>>>
>>>
>>>>>
>>>>>> +               spi0_bus: spi0-bus {
>>>>>> +                       samsung,pins = "gpa2-0", "gpa2-1", "gpa2-2",
>>>>>> "gpa2-3";
>>>>>
>>>>>
>>>>>
>>>>> What is the reason for SPI0 to have 4 pins, while SPI1 has just 3?
>>>>>
>>>>
>>>> I should align SPI1 with SPI0.
>>>>
>>>
>>> Are you sure that SPI0 is the correct one? SPI usually uses four pins - SDI,
>>> SDO, SCK and nCS, but we always used to treat nCS as a simple GPIO, due to
>>> the fact that the controller can only support one dedicated chip select and
>>> with direct GPIO control you can have more.
>>>
>>> What is the fourth pin here?
>>>
>
> As you said, these are CLK, SS, MISO, MOSI (gpa2-0 to gpa2-3). Fourth pin is
> CS. It can be defined as a simple GPIO but better to include it in the
> SPI pingroup
> as it belongs to there.

I have to disagree here.

If you define a pin in pinctrl group then it is tied to this specific 
hardware function and you can't use it as GPIO.

Since it's board specific to use it as HW chip select or GPIO chip 
select (the usual setup), it should not be included in this group.

Best regards,
Tomasz

^ permalink raw reply

* [PATCH RESEND] ARM: mcpm: Make all mcpm functions notrace
From: Jon Medhurst (Tixy) @ 2014-02-14 11:52 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <alpine.LFD.2.11.1402131542120.17677@knanqh.ubzr>

On Thu, 2014-02-13 at 15:42 -0500, Nicolas Pitre wrote:
> On Thu, 13 Feb 2014, Jon Medhurst (Tixy) wrote:
> 
> > From: Dave Martin <dave.martin@linaro.org>
> > 
> > The functions in mcpm_entry.c are mostly intended for use during
> > scary cache and coherency disabling sequences, or do other things
> > which confuse trace ...  like powering a CPU down and not
> > returning.  Similarly for the backend code.
> > 
> > For simplicity, this patch just makes whole files notrace.
> > There should be more than enough traceable points on the paths to
> > these functions, but we can be more fine-grained later if there is
> > a need for it.
> > 
> > Signed-off-by: Dave Martin <dave.martin@linaro.org>
> > 
> > Also added spc.o to the list of files as it contains functions used by
> > MCPM code which have comments comments like: "might be used in code
> > paths where normal cacheable locks are not working"
> > 
> > Signed-off-by: Jon Medhurst <tixy@linaro.org>
> 
> Acked-by: Nicolas Pitre <nico@linaro.org>
> 
> Please send to RMK's patch system.

Thanks, added as patch 7962/2 [1]. (My first attempt accidentally
omitted the "From: Dave Martin" line - I hope the patch system
understands such lines).

[1] http://www.arm.linux.org.uk/developer/patches/viewpatch.php?id=7962/2

-- 
Tixy

^ permalink raw reply

* [PATCH 6/6] RFC: ARM: integrator: get rid of <mach/memory.h>
From: Arnd Bergmann @ 2014-02-14 12:02 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392373771-17303-7-git-send-email-linus.walleij@linaro.org>

On Friday 14 February 2014 11:29:31 Linus Walleij wrote:
> The Integrator has a custom <mach/memory.h> header defining the
> BUS_OFFSET for *_to_bus and bus_to_* operations as offset from
> 0x80000000.
> 
> I have searched the documentation and cannot find any clue to
> this set-up. The Integrators have no intrinsic DMA engine(s)
> that need to perform any bus translations. The only thing I can
> think of is the PCIv3 host found in the Integrator/AP. After
> searching its documentation I cannot find any hint whatsoever
> saying that it would perform DMA operations to memory offset
> to 0x80000000. The PCIv3 driver does not configure anything
> for DMA, and the hardware contains registers to configure
> the local (CPU) side address translation. When I dump the
> default values of these registers (the Linux driver does not
> touch them) they contain zeroes meaning a 1-to-1 mapping to
> the bus.

I think this will be break bus-mastering PCI adapters. In theory
any PCI add-on card can be a bus-master and write to the host
memory. An offset of 0x80000000 in the PCI host is not uncommon
for this. Basically what the PCI host does is forward any PCI
transaction with a destination below 2GB to the PCI bus so it
can target an MMIO register, and forward transactions above
2GB to the parent bus, flipping the high-order bit in the process.

In the old days, we had virt_to_bus() and bus_to_virt() as
interfaces for drivers to convert between a kernel pointer
and an address that can be used for DMA. We have long ago
(except for a handful of drivers that depend on CONFIG_TO_BUS
and won't build on integrator or multiplatform) stopped using
those in drivers, since the translation may be dependent on
the specific device (e.g. different offsets), or may be nonlinear
in case of an IOMMU.

The interface that drivers use now is defined in dma-mapping.h
and abstracted through dma_map_ops on ARM and some other
architectures. What you need for a multiplatform kernel to
work on integrator is to set the dma_map_ops for all PCI
devices to an implementation that adds the correct offset.

One way to do this would be to define an integrator specific
dma_map_ops struct that adds a constant value for each operation
and then calls into the regular arm_dma_ops. That would be
an easy way out, but would not help the next person with the
same problem.
A more sophisticated approach, following what we did on
powerpc, would be to add an offset field to struct dev_archdata
and apply that in pfn_to_dma/dma_to_pfn/dma_to_virt/virt_to_dma
so it gets used by all dma_map_ops implementations. For PCI
devices, you probably have to copy the offset from the parent
in the pcibios_add_device() function in that case, while for
devices probed through DT (only the pci host bridge in this
case), you have to parse the "dma_ranges" property.

	Arnd

^ permalink raw reply

* [PATCH 00/26] OMAP dma engine rework
From: Sricharan R @ 2014-02-14 12:54 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140210155531.GB26684@n2100.arm.linux.org.uk>

On Monday 10 February 2014 09:25 PM, Russell King - ARM Linux wrote:
> This is the current set of patches for the OMAP DMA engine rework,
> which should now work correctly on OMAP1 platforms thanks to Tony's
> testing.
> 
> It would be good to get this validated by others across a range of
> OMAP platforms, and queued up for the next merge window, so it can
> be built upon.
> 
> Acks appreciated, and once sufficient have been added, I'll send a
> pull request for this to Vinod.
> 
>  arch/arm/mach-omap1/dma.c | 191 ++++++--------
>  arch/arm/mach-omap2/dma.c | 183 ++++++-------
>  arch/arm/plat-omap/dma.c  |  17 +-
>  drivers/dma/omap-dma.c    | 659 +++++++++++++++++++++++++++++++++++++++++-----
>  include/linux/omap-dma.h  |  25 +-
>  5 files changed, 784 insertions(+), 291 deletions(-)
> 
Tested this on DRA7XX with MMC peripheral DMA

Regards,
 Sricharan

^ permalink raw reply

* imx6: usbhc2/3 and HSIC
From: Christian Gmeiner @ 2014-02-14 12:55 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <CAH9NwWf8rc+PJygNP45x669nyiPqirF_PHOXGEQ_CX7PWaB7pQ@mail.gmail.com>

2014-01-27 17:42 GMT+01:00 Christian Gmeiner <christian.gmeiner@gmail.com>:
> Hi Lucas
>
> 2014-01-27 Lucas Stach <l.stach@pengutronix.de>:
>> Hi Christian,
>>
>> Am Montag, den 27.01.2014, 10:22 +0100 schrieb Christian Gmeiner:
>>> Hi all...
>>>
>>> does anyone used the usbhc2 or usbhc3 in HSIC mode? I am trying my
>>> luck but I do not
>>> get it to work. Is there anything special I need to take care of?
>>>
>> I remember we had this working on a board back in the 3.10 days. The
>> only thing I remember which is specific to HSIC is in the attached
>> patch. This isn't really clean and should be done in a better way for
>> mainline, but maybe it provides some pointers for you.
>>
>
> Thanks for the small patch... I got it almost working - the HSIC
> device seems to have some problems.
> I hope to find some time soon to get this stuff into mainline.
>

It does not work :(

Here are some logs: http://dpaste.com/hold/1617947/
It looks like EHCI takes over and does one port (the HSIC?). The problem
seems now that the port never changes its status to connected, but I am
100% sure that there is a LAN9730 [1] connected to that usbhc.

[1] http://www.microchip.com/wwwproducts/Devices.aspx?product=LAN9730

greets
--
Christian Gmeiner, MSc

https://soundcloud.com/christian-gmeiner

^ permalink raw reply

* [PATCH v7 03/12] mfd: omap-usb-host: Use clock names as per function for reference clocks
From: Roger Quadros @ 2014-02-14 13:12 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140214100915.GD7380@lee--X1>

On 02/14/2014 12:09 PM, Lee Jones wrote:
>> Use a meaningful name for the reference clocks so that it indicates the function.
>>
>> CC: Lee Jones <lee.jones@linaro.org>
>> CC: Samuel Ortiz <sameo@linux.intel.com>
>> Signed-off-by: Roger Quadros <rogerq@ti.com>
>> ---
>>  drivers/mfd/omap-usb-host.c | 6 +++---
>>  1 file changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
>> index 60a3bed..ce620a8 100644
>> --- a/drivers/mfd/omap-usb-host.c
>> +++ b/drivers/mfd/omap-usb-host.c
>> @@ -714,21 +714,21 @@ static int usbhs_omap_probe(struct platform_device *pdev)
>>  		goto err_mem;
>>  	}
>>  
>> -	omap->xclk60mhsp1_ck = devm_clk_get(dev, "xclk60mhsp1_ck");
>> +	omap->xclk60mhsp1_ck = devm_clk_get(dev, "refclk_60m_ext_p1");
> 
> You can't do that. These changes will have to be in the same patch as
> the core change i.e. where they are initialised.

I'm not touching them anywhere in this series. When core changes are you
referring to?

> 
>>  	if (IS_ERR(omap->xclk60mhsp1_ck)) {
>>  		ret = PTR_ERR(omap->xclk60mhsp1_ck);
>>  		dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret);
>>  		goto err_mem;
>>  	}
>>  
>> -	omap->xclk60mhsp2_ck = devm_clk_get(dev, "xclk60mhsp2_ck");
>> +	omap->xclk60mhsp2_ck = devm_clk_get(dev, "refclk_60m_ext_p2");
>>  	if (IS_ERR(omap->xclk60mhsp2_ck)) {
>>  		ret = PTR_ERR(omap->xclk60mhsp2_ck);
>>  		dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret);
>>  		goto err_mem;
>>  	}
>>  
>> -	omap->init_60m_fclk = devm_clk_get(dev, "init_60m_fclk");
>> +	omap->init_60m_fclk = devm_clk_get(dev, "refclk_60m_int");
>>  	if (IS_ERR(omap->init_60m_fclk)) {
>>  		ret = PTR_ERR(omap->init_60m_fclk);
>>  		dev_err(dev, "init_60m_fclk failed error:%d\n", ret);
> 

--
cheers,
-roger

^ permalink raw reply

* [PATCH] ARM: OMAP3+: DPLL: stop reparenting to same parent if already done
From: Tero Kristo @ 2014-02-14 13:13 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140213231317.GN28216@atomide.com>

On 02/14/2014 01:13 AM, Tony Lindgren wrote:
> * Nishanth Menon <nm@ti.com> [140205 01:06]:
>> omap3_noncore_dpll_set_rate forces a reparent to the same clk_ref
>> for every call that takes place. This is an can be done only if a change
>> is detected.
>>
>> Signed-off-by: Nishanth Menon <nm@ti.com>
>
> Would like to see acks on this too before applying.

Looks good to me, ack.

-Tero

>
> Tony
>
>> ---
>>   arch/arm/mach-omap2/dpll3xxx.c |    2 +-
>>   1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c
>> index 3185ced..d9bcbf7 100644
>> --- a/arch/arm/mach-omap2/dpll3xxx.c
>> +++ b/arch/arm/mach-omap2/dpll3xxx.c
>> @@ -525,7 +525,7 @@ int omap3_noncore_dpll_set_rate(struct clk_hw *hw, unsigned long rate,
>>   	* stuff is inherited for free
>>   	*/
>>
>> -	if (!ret)
>> +	if (!ret && clk_get_parent(hw->clk) != new_parent)
>>   		__clk_reparent(hw->clk, new_parent);
>>
>>   	return 0;
>> --
>> 1.7.9.5
>>

^ permalink raw reply

* [PATCH 1/2] mfd: twl4030-madc: Add devicetree support.
From: Marek Belisko @ 2014-02-14 13:17 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Marek Belisko <marek@goldelico.com>
---
 .../devicetree/bindings/mfd/twl4030-madc.txt       | 18 +++++++++++++
 drivers/mfd/twl4030-madc.c                         | 31 ++++++++++++++++++++--
 2 files changed, 47 insertions(+), 2 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/mfd/twl4030-madc.txt

diff --git a/Documentation/devicetree/bindings/mfd/twl4030-madc.txt b/Documentation/devicetree/bindings/mfd/twl4030-madc.txt
new file mode 100644
index 0000000..9df66ab
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/twl4030-madc.txt
@@ -0,0 +1,18 @@
+Texas Instruments TWL family (twl4030) analog signal conversion monitor module
+
+Required properties:
+- compatible : must be "ti,twl4030-madc"
+- interrupts : interrupt number
+
+Example:
+twl: twl at 48 {
+	reg = <0x48>;
+	interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+	interrupt-parent = <&intc>;
+
+	twl_madc: madc {
+		compatible = "ti,twl4030-madc";
+		interrupts = <1>;
+	};
+};
+
diff --git a/drivers/mfd/twl4030-madc.c b/drivers/mfd/twl4030-madc.c
index 4c583e4..9a2bbcf 100644
--- a/drivers/mfd/twl4030-madc.c
+++ b/drivers/mfd/twl4030-madc.c
@@ -695,6 +695,29 @@ static int twl4030_madc_set_power(struct twl4030_madc_data *madc, int on)
 	return 0;
 }
 
+#ifdef CONFIG_OF
+static struct twl4030_madc_platform_data *
+	twl4030_madc_of_parse(struct platform_device *pdev)
+{
+	struct twl4030_madc_platform_data *pdata;
+
+	pdata = devm_kzalloc(&pdev->dev,
+			sizeof(struct twl4030_madc_platform_data), GFP_KERNEL);
+	if (!pdata)
+		return ERR_PTR(-ENOMEM);
+
+	pdata->irq_line = platform_get_irq(pdev, 0);
+
+	return pdata;
+}
+
+static const struct of_device_id twl4030_madc_dt_match_table[] = {
+	{ .compatible = "ti,twl4030-madc" },
+	{},
+};
+
+#endif
+
 /*
  * Initialize MADC and request for threaded irq
  */
@@ -706,8 +729,11 @@ static int twl4030_madc_probe(struct platform_device *pdev)
 	u8 regval;
 
 	if (!pdata) {
-		dev_err(&pdev->dev, "platform_data not available\n");
-		return -EINVAL;
+		pdata = twl4030_madc_of_parse(pdev);
+		if (!pdata) {
+			dev_err(&pdev->dev, "platform_data not available\n");
+			return -EINVAL;
+		}
 	}
 	madc = kzalloc(sizeof(*madc), GFP_KERNEL);
 	if (!madc)
@@ -807,6 +833,7 @@ static struct platform_driver twl4030_madc_driver = {
 	.driver = {
 		   .name = "twl4030_madc",
 		   .owner = THIS_MODULE,
+		   .of_match_table = of_match_ptr(twl4030_madc_dt_match_table),
 		   },
 };
 
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH 2/2] ARM: dts: twl4030: Add twl4030-madc node.
From: Marek Belisko @ 2014-02-14 13:17 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <1392383861-14169-1-git-send-email-marek@goldelico.com>

Signed-off-by: Marek Belisko <marek@goldelico.com>
---
 arch/arm/boot/dts/twl4030.dtsi | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/arch/arm/boot/dts/twl4030.dtsi b/arch/arm/boot/dts/twl4030.dtsi
index 4217096..e6dec53 100644
--- a/arch/arm/boot/dts/twl4030.dtsi
+++ b/arch/arm/boot/dts/twl4030.dtsi
@@ -145,4 +145,9 @@
 		compatible = "ti,twl4030-pwrbutton";
 		interrupts = <8>;
 	};
+
+	twl_madc: madc {
+		compatible = "ti,twl4030-madc";
+		interrupts = <1>;
+	};
 };
-- 
1.8.3.2

^ permalink raw reply related

* [PATCH] ARM: OMAP2+: clock: fix clkoutx2 with CLK_SET_RATE_PARENT
From: Tero Kristo @ 2014-02-14 13:29 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140213231222.GM28216@atomide.com>

On 02/14/2014 01:12 AM, Tony Lindgren wrote:
> * Tomi Valkeinen <tomi.valkeinen@ti.com> [140130 03:19]:
>> If CLK_SET_RATE_PARENT is set for a clkoutx2 clock, calling
>> clk_set_rate() on the clock "skips" the x2 multiplier as there are no
>> set_rate and round_rate functions defined for the clkoutx2.
>>
>> This results in getting double the requested clock rates, breaking the
>> display on omap3430 based devices. This got broken when
>> d0f58bd3bba3877fb1af4664c4e33273d36f00e4 and related patches were merged
>> for v3.14, as omapdss driver now relies more on the clk-framework and
>> CLK_SET_RATE_PARENT.
>>
>> This patch implements set_rate and round_rate for clkoutx2.
>>
>> Tested on OMAP3430, OMAP3630, OMAP4460.
>>
>> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
>
> Would like to see acks from Paul and Tero on this too before applying.

Looks good to me, so ack. However, one approach to fix this problem 
would be just to delete cclock3xxx_data.c file, as the same issue is 
inherently fixed in DT boot.

Do you want the patch for deleting cclock3xxx_data.c already btw? :)

-Tero

>
> Tony
>
>> ---
>>   arch/arm/mach-omap2/cclock3xxx_data.c |  2 +
>>   arch/arm/mach-omap2/dpll3xxx.c        | 92 +++++++++++++++++++++++++++++------
>>   include/linux/clk/ti.h                |  4 ++
>>   3 files changed, 83 insertions(+), 15 deletions(-)
>>
>> diff --git a/arch/arm/mach-omap2/cclock3xxx_data.c b/arch/arm/mach-omap2/cclock3xxx_data.c
>> index 3b05aea56d1f..11ed9152e665 100644
>> --- a/arch/arm/mach-omap2/cclock3xxx_data.c
>> +++ b/arch/arm/mach-omap2/cclock3xxx_data.c
>> @@ -433,7 +433,9 @@ static const struct clk_ops dpll4_m5x2_ck_ops = {
>>   	.enable		= &omap2_dflt_clk_enable,
>>   	.disable	= &omap2_dflt_clk_disable,
>>   	.is_enabled	= &omap2_dflt_clk_is_enabled,
>> +	.set_rate	= &omap3_clkoutx2_set_rate,
>>   	.recalc_rate	= &omap3_clkoutx2_recalc,
>> +	.round_rate	= &omap3_clkoutx2_round_rate,
>>   };
>>
>>   static const struct clk_ops dpll4_m5x2_ck_3630_ops = {
>> diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c
>> index 3185ced807c9..3c418ea54bbe 100644
>> --- a/arch/arm/mach-omap2/dpll3xxx.c
>> +++ b/arch/arm/mach-omap2/dpll3xxx.c
>> @@ -623,6 +623,32 @@ void omap3_dpll_deny_idle(struct clk_hw_omap *clk)
>>
>>   /* Clock control for DPLL outputs */
>>
>> +/* Find the parent DPLL for the given clkoutx2 clock */
>> +static struct clk_hw_omap *omap3_find_clkoutx2_dpll(struct clk_hw *hw)
>> +{
>> +	struct clk_hw_omap *pclk = NULL;
>> +	struct clk *parent;
>> +
>> +	/* Walk up the parents of clk, looking for a DPLL */
>> +	do {
>> +		do {
>> +			parent = __clk_get_parent(hw->clk);
>> +			hw = __clk_get_hw(parent);
>> +		} while (hw && (__clk_get_flags(hw->clk) & CLK_IS_BASIC));
>> +		if (!hw)
>> +			break;
>> +		pclk = to_clk_hw_omap(hw);
>> +	} while (pclk && !pclk->dpll_data);
>> +
>> +	/* clk does not have a DPLL as a parent?  error in the clock data */
>> +	if (!pclk) {
>> +		WARN_ON(1);
>> +		return NULL;
>> +	}
>> +
>> +	return pclk;
>> +}
>> +
>>   /**
>>    * omap3_clkoutx2_recalc - recalculate DPLL X2 output virtual clock rate
>>    * @clk: DPLL output struct clk
>> @@ -637,27 +663,14 @@ unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw,
>>   	unsigned long rate;
>>   	u32 v;
>>   	struct clk_hw_omap *pclk = NULL;
>> -	struct clk *parent;
>>
>>   	if (!parent_rate)
>>   		return 0;
>>
>> -	/* Walk up the parents of clk, looking for a DPLL */
>> -	do {
>> -		do {
>> -			parent = __clk_get_parent(hw->clk);
>> -			hw = __clk_get_hw(parent);
>> -		} while (hw && (__clk_get_flags(hw->clk) & CLK_IS_BASIC));
>> -		if (!hw)
>> -			break;
>> -		pclk = to_clk_hw_omap(hw);
>> -	} while (pclk && !pclk->dpll_data);
>> +	pclk = omap3_find_clkoutx2_dpll(hw);
>>
>> -	/* clk does not have a DPLL as a parent?  error in the clock data */
>> -	if (!pclk) {
>> -		WARN_ON(1);
>> +	if (!pclk)
>>   		return 0;
>> -	}
>>
>>   	dd = pclk->dpll_data;
>>
>> @@ -672,6 +685,55 @@ unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw,
>>   	return rate;
>>   }
>>
>> +int omap3_clkoutx2_set_rate(struct clk_hw *hw, unsigned long rate,
>> +					unsigned long parent_rate)
>> +{
>> +	return 0;
>> +}
>> +
>> +long omap3_clkoutx2_round_rate(struct clk_hw *hw, unsigned long rate,
>> +		unsigned long *prate)
>> +{
>> +	const struct dpll_data *dd;
>> +	u32 v;
>> +	struct clk_hw_omap *pclk = NULL;
>> +
>> +	if (!*prate)
>> +		return 0;
>> +
>> +	pclk = omap3_find_clkoutx2_dpll(hw);
>> +
>> +	if (!pclk)
>> +		return 0;
>> +
>> +	dd = pclk->dpll_data;
>> +
>> +	/* TYPE J does not have a clkoutx2 */
>> +	if (dd->flags & DPLL_J_TYPE) {
>> +		*prate = __clk_round_rate(__clk_get_parent(pclk->hw.clk), rate);
>> +		return *prate;
>> +	}
>> +
>> +	WARN_ON(!dd->enable_mask);
>> +
>> +	v = omap2_clk_readl(pclk, dd->control_reg) & dd->enable_mask;
>> +	v >>= __ffs(dd->enable_mask);
>> +
>> +	/* If in bypass, the rate is fixed to the bypass rate*/
>> +	if (v != OMAP3XXX_EN_DPLL_LOCKED)
>> +		return *prate;
>> +
>> +	if (__clk_get_flags(hw->clk) & CLK_SET_RATE_PARENT) {
>> +		unsigned long best_parent;
>> +
>> +		best_parent = (rate / 2);
>> +		*prate = __clk_round_rate(__clk_get_parent(hw->clk),
>> +				best_parent);
>> +	}
>> +
>> +	return *prate * 2;
>> +}
>> +
>>   /* OMAP3/4 non-CORE DPLL clkops */
>>   const struct clk_hw_omap_ops clkhwops_omap3_dpll = {
>>   	.allow_idle	= omap3_dpll_allow_idle,
>> diff --git a/include/linux/clk/ti.h b/include/linux/clk/ti.h
>> index 092b64168d7f..4a21a872dbbd 100644
>> --- a/include/linux/clk/ti.h
>> +++ b/include/linux/clk/ti.h
>> @@ -245,6 +245,10 @@ long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate,
>>   void omap2_init_clk_clkdm(struct clk_hw *clk);
>>   unsigned long omap3_clkoutx2_recalc(struct clk_hw *hw,
>>   				    unsigned long parent_rate);
>> +int omap3_clkoutx2_set_rate(struct clk_hw *hw, unsigned long rate,
>> +					unsigned long parent_rate);
>> +long omap3_clkoutx2_round_rate(struct clk_hw *hw, unsigned long rate,
>> +		unsigned long *prate);
>>   int omap2_clkops_enable_clkdm(struct clk_hw *hw);
>>   void omap2_clkops_disable_clkdm(struct clk_hw *hw);
>>   int omap2_clk_disable_autoidle_all(void);
>> --
>> 1.8.3.2
>>

^ permalink raw reply

* [PATCH 2/2] ARM: OMAP2+: fix dpll round_rate() to actually round
From: Tero Kristo @ 2014-02-14 13:32 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <20140213230011.GH28216@atomide.com>

On 02/14/2014 01:00 AM, Tony Lindgren wrote:
> * Tomi Valkeinen <tomi.valkeinen@ti.com> [140116 23:47]:
>> omap2_dpll_round_rate() doesn't actually round the given rate, even if
>> the name and the description so hints. Instead it only tries to find an
>> exact rate match, or if that fails, return ~0 as an error.
>>
>> What this basically means is that the user of the clock needs to know
>> what rates the dpll can support, which obviously isn't right.
>>
>> This patch adds a simple method of rounding: during the iteration, the
>> code keeps track of the closest rate match. If no exact match is found,
>> the closest is returned.
>>
>> Signed-off-by: Tomi Valkeinen <tomi.valkeinen@ti.com>
>
> Paul & Tero, please ack if you want me to queue this.

The patches look good to me and based on quick testing they don't seem 
to cause any visible problems (namely this one), so acked.

-Tero

>
> Tony
>
>> ---
>>   arch/arm/mach-omap2/clkt_dpll.c | 17 ++++++++++++-----
>>   1 file changed, 12 insertions(+), 5 deletions(-)
>>
>> diff --git a/arch/arm/mach-omap2/clkt_dpll.c b/arch/arm/mach-omap2/clkt_dpll.c
>> index 1f1708ef77bb..1b4e68dfb713 100644
>> --- a/arch/arm/mach-omap2/clkt_dpll.c
>> +++ b/arch/arm/mach-omap2/clkt_dpll.c
>> @@ -298,6 +298,7 @@ long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate,
>>   	struct dpll_data *dd;
>>   	unsigned long ref_rate;
>>   	const char *clk_name;
>> +	unsigned long diff, closest_diff = ~0;
>>
>>   	if (!clk || !clk->dpll_data)
>>   		return ~0;
>> @@ -345,20 +346,26 @@ long omap2_dpll_round_rate(struct clk_hw *hw, unsigned long target_rate,
>>   		pr_debug("clock: %s: m = %d: n = %d: new_rate = %lu\n",
>>   			 clk_name, m, n, new_rate);
>>
>> -		if (target_rate == new_rate) {
>> +		diff = max(target_rate, new_rate) - min(target_rate, new_rate);
>> +
>> +		if (diff < closest_diff) {
>> +			closest_diff = diff;
>> +
>>   			dd->last_rounded_m = m;
>>   			dd->last_rounded_n = n;
>> -			dd->last_rounded_rate = target_rate;
>> -			break;
>> +			dd->last_rounded_rate = new_rate;
>> +
>> +			if (diff == 0)
>> +				break;
>>   		}
>>   	}
>>
>> -	if (target_rate != new_rate) {
>> +	if (closest_diff == ~0) {
>>   		pr_debug("clock: %s: cannot round to rate %lu\n",
>>   			 clk_name, target_rate);
>>   		return ~0;
>>   	}
>>
>> -	return target_rate;
>> +	return dd->last_rounded_rate;
>>   }
>>
>> --
>> 1.8.3.2
>>

^ permalink raw reply

* [PATCH v7 03/12] mfd: omap-usb-host: Use clock names as per function for reference clocks
From: Lee Jones @ 2014-02-14 13:33 UTC (permalink / raw)
  To: linux-arm-kernel
In-Reply-To: <52FE164F.80503@ti.com>

> >> Use a meaningful name for the reference clocks so that it indicates the function.
> >>
> >> CC: Lee Jones <lee.jones@linaro.org>
> >> CC: Samuel Ortiz <sameo@linux.intel.com>
> >> Signed-off-by: Roger Quadros <rogerq@ti.com>
> >> ---
> >>  drivers/mfd/omap-usb-host.c | 6 +++---
> >>  1 file changed, 3 insertions(+), 3 deletions(-)
> >>
> >> diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
> >> index 60a3bed..ce620a8 100644
> >> --- a/drivers/mfd/omap-usb-host.c
> >> +++ b/drivers/mfd/omap-usb-host.c
> >> @@ -714,21 +714,21 @@ static int usbhs_omap_probe(struct platform_device *pdev)
> >>  		goto err_mem;
> >>  	}
> >>  
> >> -	omap->xclk60mhsp1_ck = devm_clk_get(dev, "xclk60mhsp1_ck");
> >> +	omap->xclk60mhsp1_ck = devm_clk_get(dev, "refclk_60m_ext_p1");
> > 
> > You can't do that. These changes will have to be in the same patch as
> > the core change i.e. where they are initialised.
> 
> I'm not touching them anywhere in this series. When core changes are you
> referring to?

The ones in:
  arch/arm/mach-omap2/cclock3xxx_data.c

> >>  	if (IS_ERR(omap->xclk60mhsp1_ck)) {
> >>  		ret = PTR_ERR(omap->xclk60mhsp1_ck);
> >>  		dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret);
> >>  		goto err_mem;
> >>  	}
> >>  
> >> -	omap->xclk60mhsp2_ck = devm_clk_get(dev, "xclk60mhsp2_ck");
> >> +	omap->xclk60mhsp2_ck = devm_clk_get(dev, "refclk_60m_ext_p2");
> >>  	if (IS_ERR(omap->xclk60mhsp2_ck)) {
> >>  		ret = PTR_ERR(omap->xclk60mhsp2_ck);
> >>  		dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret);
> >>  		goto err_mem;
> >>  	}
> >>  
> >> -	omap->init_60m_fclk = devm_clk_get(dev, "init_60m_fclk");
> >> +	omap->init_60m_fclk = devm_clk_get(dev, "refclk_60m_int");
> >>  	if (IS_ERR(omap->init_60m_fclk)) {
> >>  		ret = PTR_ERR(omap->init_60m_fclk);
> >>  		dev_err(dev, "init_60m_fclk failed error:%d\n", ret);
> > 
> 

-- 
Lee Jones
Linaro STMicroelectronics Landing Team Lead
Linaro.org ? Open source software for ARM SoCs
Follow Linaro: Facebook | Twitter | Blog

^ permalink raw reply

* [PATCH v3 0/3] exynos: arch: add support for exynos5260 SoC
From: Rahul Sharma @ 2014-02-14 13:37 UTC (permalink / raw)
  To: linux-arm-kernel

From: Rahul Sharma <Rahul.Sharma@samsung.com>

V3:
  1) Addressed review comments from Tomasz figa.

V2:
  1) Split up DT patch into SoC and Board patch.

This series is dependent on Sachin's patch
"ARM: EXYNOS: Consolidate CPU init code" at
http://comments.gmane.org/gmane.linux.kernel.samsung-soc/26560

This series is based on Kukjin's for-next branch at
http://git.kernel.org/?p=linux/kernel/git/kgene/linux-samsung.git

Pankaj Dubey (1):
  ARM: EXYNOS: initial board support for exynos5260 SoC

Rahul Sharma (2):
  ARM: dts: add dts files for exynos5260 SoC
  ARM: dts: add dts files for xyref5260 board

 arch/arm/boot/dts/Makefile                      |    1 +
 arch/arm/boot/dts/exynos5260-pinctrl.dtsi       |  574 +++++++++++++++++++++++
 arch/arm/boot/dts/exynos5260-xyref5260-evt0.dts |  105 +++++
 arch/arm/boot/dts/exynos5260.dtsi               |  304 ++++++++++++
 arch/arm/mach-exynos/Kconfig                    |    9 +
 arch/arm/mach-exynos/common.c                   |   11 +
 arch/arm/mach-exynos/include/mach/map.h         |    1 +
 arch/arm/mach-exynos/mach-exynos5-dt.c          |    1 +
 arch/arm/plat-samsung/include/plat/cpu.h        |    8 +
 9 files changed, 1014 insertions(+)
 create mode 100644 arch/arm/boot/dts/exynos5260-pinctrl.dtsi
 create mode 100644 arch/arm/boot/dts/exynos5260-xyref5260-evt0.dts
 create mode 100644 arch/arm/boot/dts/exynos5260.dtsi

-- 
1.7.9.5

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox