All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCHv2 0/3] ARM: K2G: support for TI-SCI Clocks
@ 2016-09-01 12:40 ` Tero Kristo
  0 siblings, 0 replies; 29+ messages in thread
From: Tero Kristo @ 2016-09-01 12:40 UTC (permalink / raw)
  To: sboyd-sgV2jX0FEOL9JmXXK+q4OQ, mturquette-rdvid1DuHRBWk0Htik3J/w,
	linux-clk-u79uwXL29TY76Z2rM5mHXA
  Cc: ssantosh-DgEjT+Ai2ygdnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	nm-l0cyMroinI0

Hi,

Changes compared to previous version:
- converted the driver to use xlate hw functionality instead of legacy
  xlate
- bunch of other fixes proposed by Stephen Boyd

Series still depends on https://lkml.org/lkml/2016/8/19/768, pull
request for this has been sent out so it would be possible to
pull this to clock tree also and merge this for 4.9.

Boot tested locally with Nishanth's integrated SCI branch, and seems to
be working fine.

Refer to v1 cover letter for more details if required:
https://lkml.org/lkml/2016/8/19/811

-Tero

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCHv2 0/3] ARM: K2G: support for TI-SCI Clocks
@ 2016-09-01 12:40 ` Tero Kristo
  0 siblings, 0 replies; 29+ messages in thread
From: Tero Kristo @ 2016-09-01 12:40 UTC (permalink / raw)
  To: sboyd, mturquette, linux-clk; +Cc: ssantosh, devicetree, linux-arm-kernel, nm

Hi,

Changes compared to previous version:
- converted the driver to use xlate hw functionality instead of legacy
  xlate
- bunch of other fixes proposed by Stephen Boyd

Series still depends on https://lkml.org/lkml/2016/8/19/768, pull
request for this has been sent out so it would be possible to
pull this to clock tree also and merge this for 4.9.

Boot tested locally with Nishanth's integrated SCI branch, and seems to
be working fine.

Refer to v1 cover letter for more details if required:
https://lkml.org/lkml/2016/8/19/811

-Tero

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

* [PATCHv2 0/3] ARM: K2G: support for TI-SCI Clocks
@ 2016-09-01 12:40 ` Tero Kristo
  0 siblings, 0 replies; 29+ messages in thread
From: Tero Kristo @ 2016-09-01 12:40 UTC (permalink / raw)
  To: linux-arm-kernel

Hi,

Changes compared to previous version:
- converted the driver to use xlate hw functionality instead of legacy
  xlate
- bunch of other fixes proposed by Stephen Boyd

Series still depends on https://lkml.org/lkml/2016/8/19/768, pull
request for this has been sent out so it would be possible to
pull this to clock tree also and merge this for 4.9.

Boot tested locally with Nishanth's integrated SCI branch, and seems to
be working fine.

Refer to v1 cover letter for more details if required:
https://lkml.org/lkml/2016/8/19/811

-Tero

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

* [PATCHv2 1/3] Documentation: dt: Add TI SCI clock driver
  2016-09-01 12:40 ` Tero Kristo
  (?)
@ 2016-09-01 12:40   ` Tero Kristo
  -1 siblings, 0 replies; 29+ messages in thread
From: Tero Kristo @ 2016-09-01 12:40 UTC (permalink / raw)
  To: sboyd, mturquette, linux-clk; +Cc: ssantosh, devicetree, linux-arm-kernel, nm

Add a clock implementation, TI SCI clock, that will hook to the common
clock framework, and allow each clock to be controlled via TI SCI
protocol.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
Tested-by: Dave Gerlach <d-gerlach@ti.com>
Signed-off-by: Nishanth Menon <nm@ti.com>
---
 .../devicetree/bindings/clock/ti,sci-clk.txt       | 51 ++++++++++++++++++++++
 MAINTAINERS                                        |  1 +
 2 files changed, 52 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/ti,sci-clk.txt

diff --git a/Documentation/devicetree/bindings/clock/ti,sci-clk.txt b/Documentation/devicetree/bindings/clock/ti,sci-clk.txt
new file mode 100644
index 0000000..231cb80
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/ti,sci-clk.txt
@@ -0,0 +1,51 @@
+Texas Instruments TI-SCI Clocks
+===============================
+
+All clocks on Texas Instruments' SoCs that contain a System Controller,
+are only controlled by this entity. Communication between a host processor
+running an OS and the System Controller happens through a protocol known
+as TI-SCI[1]. This clock implementation plugs into the common clock
+framework and makes use of the TI-SCI protocol on clock API requests.
+
+[1] Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
+
+Required properties:
+-------------------
+- compatible: Must be "ti,sci-clk"
+- #clock-cells: Shall be 2.
+  In clock consumers, this cell represents the device ID and clock ID
+  exposed by the PM firmware. The assignments can be found in the header
+  files <dt-bindings/genpd/<soc>.h> (which covers the device IDs) and
+  <dt-bindings/clock/<soc>.h> (which covers the clock IDs), where <soc>
+  is the SoC involved, for example 'k2g'.
+- ti,sci: Phandle to the TI SCI device to use for managing the clocks
+
+Optional properties:
+-------------------
+- ti,ssc-clocks: Array of phandle clocks that shall enable spread spectrum
+		 clocking while enabled
+- ti,allow-freq-change-clocks: Array of phandle clocks that shall allow
+			       dynamic clock frequency changes by firmware
+- ti,input-term-clocks: Array of phandle clocks that shall enable input
+			termination
+
+Examples:
+--------
+
+k2g_clks: k2g_clks {
+	compatible = "ti,sci-clk";
+	ti,sci = <&pmmc>;
+	#clock-cells = <2>;
+};
+
+dummy_node@1234 {
+	clocks = <&k2g_clks K2G_DEV_DUMMY K2G_DEV_DUMMY_FCK>;
+};
+
+dummy_node2@2345 {
+	clocks = <&k2g_clks K2G_DEV_DUMMY2 K2G_DEV_DUMMY_X1_CLK>;
+};
+
+&k2g_clks {
+	ti,ssc-clocks = <&k2g_clks K2G_DEV_DUMMY K2G_DEV_DUMMY_FCK>;
+};
diff --git a/MAINTAINERS b/MAINTAINERS
index 0c5e3d1..ef88726 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11573,6 +11573,7 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
 F:	drivers/firmware/ti_sci*
 F:	include/linux/soc/ti/ti_sci_protocol.h
+F:	Documentation/devicetree/bindings/clock/ti,sci-clk.txt
 
 THANKO'S RAREMONO AM/FM/SW RADIO RECEIVER USB DRIVER
 M:	Hans Verkuil <hverkuil@xs4all.nl>
-- 
1.9.1


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

* [PATCHv2 1/3] Documentation: dt: Add TI SCI clock driver
@ 2016-09-01 12:40   ` Tero Kristo
  0 siblings, 0 replies; 29+ messages in thread
From: Tero Kristo @ 2016-09-01 12:40 UTC (permalink / raw)
  To: sboyd, mturquette, linux-clk; +Cc: ssantosh, devicetree, linux-arm-kernel, nm

Add a clock implementation, TI SCI clock, that will hook to the common
clock framework, and allow each clock to be controlled via TI SCI
protocol.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
Tested-by: Dave Gerlach <d-gerlach@ti.com>
Signed-off-by: Nishanth Menon <nm@ti.com>
---
 .../devicetree/bindings/clock/ti,sci-clk.txt       | 51 ++++++++++++++++++++++
 MAINTAINERS                                        |  1 +
 2 files changed, 52 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/ti,sci-clk.txt

diff --git a/Documentation/devicetree/bindings/clock/ti,sci-clk.txt b/Documentation/devicetree/bindings/clock/ti,sci-clk.txt
new file mode 100644
index 0000000..231cb80
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/ti,sci-clk.txt
@@ -0,0 +1,51 @@
+Texas Instruments TI-SCI Clocks
+===============================
+
+All clocks on Texas Instruments' SoCs that contain a System Controller,
+are only controlled by this entity. Communication between a host processor
+running an OS and the System Controller happens through a protocol known
+as TI-SCI[1]. This clock implementation plugs into the common clock
+framework and makes use of the TI-SCI protocol on clock API requests.
+
+[1] Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
+
+Required properties:
+-------------------
+- compatible: Must be "ti,sci-clk"
+- #clock-cells: Shall be 2.
+  In clock consumers, this cell represents the device ID and clock ID
+  exposed by the PM firmware. The assignments can be found in the header
+  files <dt-bindings/genpd/<soc>.h> (which covers the device IDs) and
+  <dt-bindings/clock/<soc>.h> (which covers the clock IDs), where <soc>
+  is the SoC involved, for example 'k2g'.
+- ti,sci: Phandle to the TI SCI device to use for managing the clocks
+
+Optional properties:
+-------------------
+- ti,ssc-clocks: Array of phandle clocks that shall enable spread spectrum
+		 clocking while enabled
+- ti,allow-freq-change-clocks: Array of phandle clocks that shall allow
+			       dynamic clock frequency changes by firmware
+- ti,input-term-clocks: Array of phandle clocks that shall enable input
+			termination
+
+Examples:
+--------
+
+k2g_clks: k2g_clks {
+	compatible = "ti,sci-clk";
+	ti,sci = <&pmmc>;
+	#clock-cells = <2>;
+};
+
+dummy_node@1234 {
+	clocks = <&k2g_clks K2G_DEV_DUMMY K2G_DEV_DUMMY_FCK>;
+};
+
+dummy_node2@2345 {
+	clocks = <&k2g_clks K2G_DEV_DUMMY2 K2G_DEV_DUMMY_X1_CLK>;
+};
+
+&k2g_clks {
+	ti,ssc-clocks = <&k2g_clks K2G_DEV_DUMMY K2G_DEV_DUMMY_FCK>;
+};
diff --git a/MAINTAINERS b/MAINTAINERS
index 0c5e3d1..ef88726 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11573,6 +11573,7 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
 F:	drivers/firmware/ti_sci*
 F:	include/linux/soc/ti/ti_sci_protocol.h
+F:	Documentation/devicetree/bindings/clock/ti,sci-clk.txt
 
 THANKO'S RAREMONO AM/FM/SW RADIO RECEIVER USB DRIVER
 M:	Hans Verkuil <hverkuil@xs4all.nl>
-- 
1.9.1

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

* [PATCHv2 1/3] Documentation: dt: Add TI SCI clock driver
@ 2016-09-01 12:40   ` Tero Kristo
  0 siblings, 0 replies; 29+ messages in thread
From: Tero Kristo @ 2016-09-01 12:40 UTC (permalink / raw)
  To: linux-arm-kernel

Add a clock implementation, TI SCI clock, that will hook to the common
clock framework, and allow each clock to be controlled via TI SCI
protocol.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
Tested-by: Dave Gerlach <d-gerlach@ti.com>
Signed-off-by: Nishanth Menon <nm@ti.com>
---
 .../devicetree/bindings/clock/ti,sci-clk.txt       | 51 ++++++++++++++++++++++
 MAINTAINERS                                        |  1 +
 2 files changed, 52 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/clock/ti,sci-clk.txt

diff --git a/Documentation/devicetree/bindings/clock/ti,sci-clk.txt b/Documentation/devicetree/bindings/clock/ti,sci-clk.txt
new file mode 100644
index 0000000..231cb80
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/ti,sci-clk.txt
@@ -0,0 +1,51 @@
+Texas Instruments TI-SCI Clocks
+===============================
+
+All clocks on Texas Instruments' SoCs that contain a System Controller,
+are only controlled by this entity. Communication between a host processor
+running an OS and the System Controller happens through a protocol known
+as TI-SCI[1]. This clock implementation plugs into the common clock
+framework and makes use of the TI-SCI protocol on clock API requests.
+
+[1] Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
+
+Required properties:
+-------------------
+- compatible: Must be "ti,sci-clk"
+- #clock-cells: Shall be 2.
+  In clock consumers, this cell represents the device ID and clock ID
+  exposed by the PM firmware. The assignments can be found in the header
+  files <dt-bindings/genpd/<soc>.h> (which covers the device IDs) and
+  <dt-bindings/clock/<soc>.h> (which covers the clock IDs), where <soc>
+  is the SoC involved, for example 'k2g'.
+- ti,sci: Phandle to the TI SCI device to use for managing the clocks
+
+Optional properties:
+-------------------
+- ti,ssc-clocks: Array of phandle clocks that shall enable spread spectrum
+		 clocking while enabled
+- ti,allow-freq-change-clocks: Array of phandle clocks that shall allow
+			       dynamic clock frequency changes by firmware
+- ti,input-term-clocks: Array of phandle clocks that shall enable input
+			termination
+
+Examples:
+--------
+
+k2g_clks: k2g_clks {
+	compatible = "ti,sci-clk";
+	ti,sci = <&pmmc>;
+	#clock-cells = <2>;
+};
+
+dummy_node at 1234 {
+	clocks = <&k2g_clks K2G_DEV_DUMMY K2G_DEV_DUMMY_FCK>;
+};
+
+dummy_node2 at 2345 {
+	clocks = <&k2g_clks K2G_DEV_DUMMY2 K2G_DEV_DUMMY_X1_CLK>;
+};
+
+&k2g_clks {
+	ti,ssc-clocks = <&k2g_clks K2G_DEV_DUMMY K2G_DEV_DUMMY_FCK>;
+};
diff --git a/MAINTAINERS b/MAINTAINERS
index 0c5e3d1..ef88726 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11573,6 +11573,7 @@ S:	Maintained
 F:	Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
 F:	drivers/firmware/ti_sci*
 F:	include/linux/soc/ti/ti_sci_protocol.h
+F:	Documentation/devicetree/bindings/clock/ti,sci-clk.txt
 
 THANKO'S RAREMONO AM/FM/SW RADIO RECEIVER USB DRIVER
 M:	Hans Verkuil <hverkuil@xs4all.nl>
-- 
1.9.1

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

* [PATCHv2 2/3] dt-binding: clock: Add k2g clock definitions
  2016-09-01 12:40 ` Tero Kristo
  (?)
@ 2016-09-01 12:40     ` Tero Kristo
  -1 siblings, 0 replies; 29+ messages in thread
From: Tero Kristo @ 2016-09-01 12:40 UTC (permalink / raw)
  To: sboyd-sgV2jX0FEOL9JmXXK+q4OQ, mturquette-rdvid1DuHRBWk0Htik3J/w,
	linux-clk-u79uwXL29TY76Z2rM5mHXA
  Cc: ssantosh-DgEjT+Ai2ygdnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	nm-l0cyMroinI0

Add identifiers for the K2G clocks managed by the PMMC.

Signed-off-by: Tero Kristo <t-kristo-l0cyMroinI0@public.gmane.org>
Tested-by: Dave Gerlach <d-gerlach-l0cyMroinI0@public.gmane.org>
Signed-off-by: Nishanth Menon <nm-l0cyMroinI0@public.gmane.org>
---
 MAINTAINERS                     |   1 +
 include/dt-bindings/clock/k2g.h | 234 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 235 insertions(+)
 create mode 100644 include/dt-bindings/clock/k2g.h

diff --git a/MAINTAINERS b/MAINTAINERS
index ef88726..bcb7b9e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11574,6 +11574,7 @@ F:	Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
 F:	drivers/firmware/ti_sci*
 F:	include/linux/soc/ti/ti_sci_protocol.h
 F:	Documentation/devicetree/bindings/clock/ti,sci-clk.txt
+F:	include/dt-bindings/clock/k2g.h
 
 THANKO'S RAREMONO AM/FM/SW RADIO RECEIVER USB DRIVER
 M:	Hans Verkuil <hverkuil-qWit8jRvyhVmR6Xm/wNWPw@public.gmane.org>
diff --git a/include/dt-bindings/clock/k2g.h b/include/dt-bindings/clock/k2g.h
new file mode 100644
index 0000000..cddffc3
--- /dev/null
+++ b/include/dt-bindings/clock/k2g.h
@@ -0,0 +1,234 @@
+/*
+ * TI K2G SoC clock definitions
+ *
+ * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 __DT_BINDINGS_CLOCK_K2G_H__
+#define __DT_BINDINGS_CLOCK_K2G_H__
+
+/*
+ * The clock IDs listed in this file are describing the clocks at IP's
+ * boundaries. The firmware is not exposing any of the generic clocks
+ * from the system, those are handled internally by the firmware.
+ */
+#define K2G_DEV_PMMC_MPM_VBUS_CLK		0
+#define K2G_DEV_PMMC_MPM_FUNC_32K_CLK		1
+#define K2G_DEV_PMMC_MPM_FUNC_OSC_CLK		2
+#define K2G_DEV_PMMC_MPM_DAP_CLK		3
+
+#define K2G_DEV_MLB_MLB_SYS_CLK			0
+#define K2G_DEV_MLB_MLB_SHB_OCP_CLK		1
+#define K2G_DEV_MLB_MLB_SPB_OCP_CLK		2
+#define K2G_DEV_MLB_MLB_IO_CLK			3
+#define K2G_DEV_MLB_MLBP_IO_CLK			4
+
+#define K2G_DEV_DSS_PI_DSS_OCP_CLK		0
+#define K2G_DEV_DSS_PI_DSS_VP_CLK		1
+
+#define K2G_DEV_MCBSP_VBUS_CLK			0
+#define K2G_DEV_MCBSP_CLKS			1
+#define K2G_DEV_MCBSP_CLKS_PARENT_AUDIO_OSC	2
+#define K2G_DEV_MCBSP_CLKS_PARENT_MLB_IO_CLK	3
+#define K2G_DEV_MCBSP_CLKS_PARENT_MLBP_IO_CLK	4
+#define K2G_DEV_MCBSP_CLKS_PARENT_SYS_OSCCLK	5
+#define K2G_DEV_MCBSP_CLKS_PARENT_XREFCLK	6
+#define K2G_DEV_MCBSP_CLKS_PARENT_UART_PLL	7
+
+#define K2G_DEV_MCASP_VBUS_CLK			0
+#define K2G_DEV_MCASP_AUX_CLK			1
+#define K2G_DEV_MCASP_AUX_CLK_PARENT_AUDIO_OSC		2
+#define K2G_DEV_MCASP_AUX_CLK_PARENT_MLB_IO_CLK		3
+#define K2G_DEV_MCASP_AUX_CLK_PARENT_MLBP_IO_CLK	4
+#define K2G_DEV_MCASP_AUX_CLK_PARENT_SYS_OSCCLK		5
+#define K2G_DEV_MCASP_AUX_CLK_PARENT_XREFCLK		6
+#define K2G_DEV_MCASP_AUX_CLK_PARENT_UART_PLL		7
+
+#define K2G_DEV_DCAN_VBUS_CLK			0
+#define K2G_DEV_DCAN_CAN_CLK			1
+
+#define K2G_DEV_EMIF_V_CLK			0
+#define K2G_DEV_EMIF_M_CLK			1
+#define K2G_DEV_EMIF_DFT_LOCAL_CLK		2
+#define K2G_DEV_EMIF_PUB_CTL_CLK		3
+#define K2G_DEV_EMIF_PHY_CTL_CLK		4
+#define K2G_DEV_EMIF_VBUSP_CLK			5
+
+#define K2G_DEV_MMCHS_VBUS_CLK			0
+#define K2G_DEV_MMCHS_CLK_ADPI			1
+#define K2G_DEV_MMCHS_CLK32K			2
+
+#define K2G_DEV_GPMC_GPMC_FCLK			0
+
+#define K2G_DEV_ELM_CLK				0
+
+#define K2G_DEV_SPI_VBUSP_CLK			0
+
+#define K2G_DEV_ICSS_VCLK_CLK			0
+#define K2G_DEV_ICSS_CORE_CLK			1
+#define K2G_DEV_ICSS_CORE_CLK_PARENT_ICSS_PLL	2
+#define K2G_DEV_ICSS_CORE_CLK_PARENT_NSS_PLL	3
+#define K2G_DEV_ICSS_UCLK_CLK			4
+#define K2G_DEV_ICSS_IEPCLK_CLK			5
+
+#define K2G_DEV_USB_BUS_CLK			0
+#define K2G_DEV_USB_PHYMMR_CLK			1
+#define K2G_DEV_USB_SUSP_CLK			2
+#define K2G_DEV_USB_REF_CLK			3
+#define K2G_DEV_USB_DFT_ULPI_CLK		4
+#define K2G_DEV_USB_DFT_UTMI_CLK		5
+#define K2G_DEV_USB_CLKCORE			6
+
+#define K2G_DEV_NSS_VCLK			0
+#define K2G_DEV_NSS_SA_UL_CLK			1
+#define K2G_DEV_NSS_SA_UL_X1_CLK		2
+#define K2G_DEV_NSS_ESW_CLK			3
+/*
+ * Mux register is internal to the CPTS, so we must allow NSS to control it.
+ * CPTS_REFCLK_P/N is a direct input to this mux, so ignore it is ignored
+ * in the SoC clock tree.
+ */
+#define K2G_DEV_NSS_CPTS_CHIP_CLK1_2		4
+#define K2G_DEV_NSS_CPTS_CHIP_CLK1_3		5
+#define K2G_DEV_NSS_CPTS_TIMI0			6
+#define K2G_DEV_NSS_CPTS_TIMI1			7
+#define K2G_DEV_NSS_CPTS_NSS_PLL		8
+#define K2G_DEV_NSS_GMII_RFTCLK			9
+#define K2G_DEV_NSS_RGMII_MHZ_5_CLK		10
+#define K2G_DEV_NSS_RGMII_MHZ_50_CLK		11
+#define K2G_DEV_NSS_RGMII_MHZ_250_CLK		12
+#define K2G_DEV_NSS_RMII_MHZ_50_CLK		13
+
+#define K2G_DEV_PCIE_VBUS_CLK			0
+
+#define K2G_DEV_OTP_VBUS_CLK			0
+
+#define K2G_DEV_GPIO_VBUS_CLK			0
+
+#define K2G_DEV_TIMER64_VBUS_CLK		0
+#define K2G_DEV_TIMER64_TINL			1
+#define K2G_DEV_TIMER64_TINL_PARENT_TIMI0	2
+#define K2G_DEV_TIMER64_TINL_PARENT_TIMI1	3
+#define K2G_DEV_TIMER64_TINH			4
+#define K2G_DEV_TIMER64_TINH_PARENT_TIMI0	5
+#define K2G_DEV_TIMER64_TINH_PARENT_TIMI1	6
+#define K2G_DEV_TIMER64_TOUTL			7
+#define K2G_DEV_TIMER64_TOUTH			8
+
+#define K2G_DEV_SEC_MGR_SEC_CLK_PI		0
+
+#define K2G_DEV_MSGMGR_VBUS_CLK			0
+
+#define K2G_DEV_BOOTCFG_VBUS_CLK		0
+
+#define K2G_DEV_ARM_BOOTROM_VBUS_CLK		0
+
+#define K2G_DEV_DSP_BOOTROM_VBUS_CLK		0
+
+#define K2G_DEV_DEBUGSS_VBUSP_CTTBRCLK_CLK	0
+#define K2G_DEV_DEBUGSS_VBUSP_STMD0_CLK		1
+#define K2G_DEV_DEBUGSS_VBUSP_SLAVE_CLK		2
+#define K2G_DEV_DEBUGSS_VBUSP_MASTER_CLK	3
+#define K2G_DEV_DEBUGSS_TCK			4
+#define K2G_DEV_DEBUGSS_CS_TRCEXPT_CLK		5
+#define K2G_DEV_DEBUGSS_DSP_TRACECLK		6
+#define K2G_DEV_DEBUGSS_STMXPT_CLK		7
+
+#define K2G_DEV_UART_CBA_CLK_PI			0
+
+#define K2G_DEV_EHRPWM_VBUS_CLK			0
+
+#define K2G_DEV_EQEP_VBUS_CLK			0
+
+#define K2G_DEV_ECAP_VBUS_CLK			0
+
+#define K2G_DEV_I2C_VBUS_CLK			0
+
+#define K2G_DEV_CP_TRACER_CP_TRACER_CLK		0
+
+#define K2G_DEV_EDMA_TPTC_CLK			0
+#define K2G_DEV_EDMA_TPCC_CLK			1
+
+#define K2G_DEV_SEMAPHORE_VBUS_CLK		0
+
+#define K2G_DEV_INTC_VBUS_CLK			0
+
+#define K2G_DEV_GIC_VBUS_CLK			0
+
+#define K2G_DEV_QSPI_QSPI_CLK			0
+#define K2G_DEV_QSPI_DATA_BUS_CLK		1
+#define K2G_DEV_QSPI_CFG_BUS_CLK		2
+#define K2G_DEV_QSPI_QSPI_CLK_O			3
+#define K2G_DEV_QSPI_QSPI_CLK_I			4
+
+#define K2G_DEV_ARM_64B_COUNTER_CLK_INPUT	0
+#define K2G_DEV_ARM_64B_COUNTER_VBUSP_CLK	1
+
+#define K2G_DEV_TETRIS_CORE_CLK			0
+#define K2G_DEV_TETRIS_SUBSYS_CLK		1
+
+#define K2G_DEV_CGEM_CORE_CLK			0
+#define K2G_DEV_CGEM_TRACE_CLK			1
+
+#define K2G_DEV_MSMC_VBUS_CLK			0
+
+#define K2G_DEV_DFT_SS_VBUS_CLK			0
+#define K2G_DEV_DFT_SS_TCK			1
+
+#define K2G_DEV_CBASS_VBUS_CLK			0
+
+#define K2G_DEV_SMARTREFLEX_SCLK_CLK		0
+#define K2G_DEV_SMARTREFLEX_REFCLK1_CLK		1
+#define K2G_DEV_SMARTREFLEX_TEMPMCLK_CLK	2
+
+#define K2G_DEV_EFUSE_VBUS_CLK			0
+
+/* Outputs from board (inputs to SoC) */
+#define K2G_DEV_BOARD_SYS_OSCIN			0
+#define K2G_DEV_BOARD_SYS_CLK			1
+#define K2G_DEV_BOARD_AUDIO_OSCIN		2
+#define K2G_DEV_BOARD_DDR			3
+#define K2G_DEV_BOARD_MLBCLK			4
+#define K2G_DEV_BOARD_MLBPCLK			5
+#define K2G_DEV_BOARD_XREFCLK			6
+#define K2G_DEV_BOARD_TIMI0			7
+#define K2G_DEV_BOARD_TIMI1			8
+
+/* Inputs to board (outputs from SoC) */
+#define K2G_DEV_BOARD_SYSCLKOUT			10
+#define K2G_DEV_BOARD_OBSCLK			11
+#define K2G_DEV_BOARD_OBSCLK_PARENT_MAIN_PLL	12
+#define K2G_DEV_BOARD_OBSCLK_PARENT_DSS_PLL	13
+#define K2G_DEV_BOARD_OBSCLK_PARENT_ARM_PLL	14
+#define K2G_DEV_BOARD_OBSCLK_PARENT_UART_PLL	15
+#define K2G_DEV_BOARD_OBSCLK_PARENT_ICSS_PLL	16
+#define K2G_DEV_BOARD_OBSCLK_PARENT_DDR_PLL	17
+#define K2G_DEV_BOARD_OBSCLK_PARENT_PLL_CTRL	18
+#define K2G_DEV_BOARD_OBSCLK_PARENT_NSS_PLL	19
+#define K2G_DEV_BOARD_OBSCLK_PARENT_SYSOSC	20
+#define K2G_DEV_BOARD_MII_CLKOUT		21
+#define K2G_DEV_BOARD_TIMO0			22
+#define K2G_DEV_BOARD_TIMO1			23
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_0L	24
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_0H	25
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_1L	26
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_1H	27
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_2L	28
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_2H	29
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_3L	30
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_3H	31
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_4L	32
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_4H	33
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_5L	34
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_5H	35
+
+#endif
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCHv2 2/3] dt-binding: clock: Add k2g clock definitions
@ 2016-09-01 12:40     ` Tero Kristo
  0 siblings, 0 replies; 29+ messages in thread
From: Tero Kristo @ 2016-09-01 12:40 UTC (permalink / raw)
  To: sboyd, mturquette, linux-clk; +Cc: ssantosh, devicetree, linux-arm-kernel, nm

Add identifiers for the K2G clocks managed by the PMMC.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
Tested-by: Dave Gerlach <d-gerlach@ti.com>
Signed-off-by: Nishanth Menon <nm@ti.com>
---
 MAINTAINERS                     |   1 +
 include/dt-bindings/clock/k2g.h | 234 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 235 insertions(+)
 create mode 100644 include/dt-bindings/clock/k2g.h

diff --git a/MAINTAINERS b/MAINTAINERS
index ef88726..bcb7b9e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11574,6 +11574,7 @@ F:	Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
 F:	drivers/firmware/ti_sci*
 F:	include/linux/soc/ti/ti_sci_protocol.h
 F:	Documentation/devicetree/bindings/clock/ti,sci-clk.txt
+F:	include/dt-bindings/clock/k2g.h
 
 THANKO'S RAREMONO AM/FM/SW RADIO RECEIVER USB DRIVER
 M:	Hans Verkuil <hverkuil@xs4all.nl>
diff --git a/include/dt-bindings/clock/k2g.h b/include/dt-bindings/clock/k2g.h
new file mode 100644
index 0000000..cddffc3
--- /dev/null
+++ b/include/dt-bindings/clock/k2g.h
@@ -0,0 +1,234 @@
+/*
+ * TI K2G SoC clock definitions
+ *
+ * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 __DT_BINDINGS_CLOCK_K2G_H__
+#define __DT_BINDINGS_CLOCK_K2G_H__
+
+/*
+ * The clock IDs listed in this file are describing the clocks at IP's
+ * boundaries. The firmware is not exposing any of the generic clocks
+ * from the system, those are handled internally by the firmware.
+ */
+#define K2G_DEV_PMMC_MPM_VBUS_CLK		0
+#define K2G_DEV_PMMC_MPM_FUNC_32K_CLK		1
+#define K2G_DEV_PMMC_MPM_FUNC_OSC_CLK		2
+#define K2G_DEV_PMMC_MPM_DAP_CLK		3
+
+#define K2G_DEV_MLB_MLB_SYS_CLK			0
+#define K2G_DEV_MLB_MLB_SHB_OCP_CLK		1
+#define K2G_DEV_MLB_MLB_SPB_OCP_CLK		2
+#define K2G_DEV_MLB_MLB_IO_CLK			3
+#define K2G_DEV_MLB_MLBP_IO_CLK			4
+
+#define K2G_DEV_DSS_PI_DSS_OCP_CLK		0
+#define K2G_DEV_DSS_PI_DSS_VP_CLK		1
+
+#define K2G_DEV_MCBSP_VBUS_CLK			0
+#define K2G_DEV_MCBSP_CLKS			1
+#define K2G_DEV_MCBSP_CLKS_PARENT_AUDIO_OSC	2
+#define K2G_DEV_MCBSP_CLKS_PARENT_MLB_IO_CLK	3
+#define K2G_DEV_MCBSP_CLKS_PARENT_MLBP_IO_CLK	4
+#define K2G_DEV_MCBSP_CLKS_PARENT_SYS_OSCCLK	5
+#define K2G_DEV_MCBSP_CLKS_PARENT_XREFCLK	6
+#define K2G_DEV_MCBSP_CLKS_PARENT_UART_PLL	7
+
+#define K2G_DEV_MCASP_VBUS_CLK			0
+#define K2G_DEV_MCASP_AUX_CLK			1
+#define K2G_DEV_MCASP_AUX_CLK_PARENT_AUDIO_OSC		2
+#define K2G_DEV_MCASP_AUX_CLK_PARENT_MLB_IO_CLK		3
+#define K2G_DEV_MCASP_AUX_CLK_PARENT_MLBP_IO_CLK	4
+#define K2G_DEV_MCASP_AUX_CLK_PARENT_SYS_OSCCLK		5
+#define K2G_DEV_MCASP_AUX_CLK_PARENT_XREFCLK		6
+#define K2G_DEV_MCASP_AUX_CLK_PARENT_UART_PLL		7
+
+#define K2G_DEV_DCAN_VBUS_CLK			0
+#define K2G_DEV_DCAN_CAN_CLK			1
+
+#define K2G_DEV_EMIF_V_CLK			0
+#define K2G_DEV_EMIF_M_CLK			1
+#define K2G_DEV_EMIF_DFT_LOCAL_CLK		2
+#define K2G_DEV_EMIF_PUB_CTL_CLK		3
+#define K2G_DEV_EMIF_PHY_CTL_CLK		4
+#define K2G_DEV_EMIF_VBUSP_CLK			5
+
+#define K2G_DEV_MMCHS_VBUS_CLK			0
+#define K2G_DEV_MMCHS_CLK_ADPI			1
+#define K2G_DEV_MMCHS_CLK32K			2
+
+#define K2G_DEV_GPMC_GPMC_FCLK			0
+
+#define K2G_DEV_ELM_CLK				0
+
+#define K2G_DEV_SPI_VBUSP_CLK			0
+
+#define K2G_DEV_ICSS_VCLK_CLK			0
+#define K2G_DEV_ICSS_CORE_CLK			1
+#define K2G_DEV_ICSS_CORE_CLK_PARENT_ICSS_PLL	2
+#define K2G_DEV_ICSS_CORE_CLK_PARENT_NSS_PLL	3
+#define K2G_DEV_ICSS_UCLK_CLK			4
+#define K2G_DEV_ICSS_IEPCLK_CLK			5
+
+#define K2G_DEV_USB_BUS_CLK			0
+#define K2G_DEV_USB_PHYMMR_CLK			1
+#define K2G_DEV_USB_SUSP_CLK			2
+#define K2G_DEV_USB_REF_CLK			3
+#define K2G_DEV_USB_DFT_ULPI_CLK		4
+#define K2G_DEV_USB_DFT_UTMI_CLK		5
+#define K2G_DEV_USB_CLKCORE			6
+
+#define K2G_DEV_NSS_VCLK			0
+#define K2G_DEV_NSS_SA_UL_CLK			1
+#define K2G_DEV_NSS_SA_UL_X1_CLK		2
+#define K2G_DEV_NSS_ESW_CLK			3
+/*
+ * Mux register is internal to the CPTS, so we must allow NSS to control it.
+ * CPTS_REFCLK_P/N is a direct input to this mux, so ignore it is ignored
+ * in the SoC clock tree.
+ */
+#define K2G_DEV_NSS_CPTS_CHIP_CLK1_2		4
+#define K2G_DEV_NSS_CPTS_CHIP_CLK1_3		5
+#define K2G_DEV_NSS_CPTS_TIMI0			6
+#define K2G_DEV_NSS_CPTS_TIMI1			7
+#define K2G_DEV_NSS_CPTS_NSS_PLL		8
+#define K2G_DEV_NSS_GMII_RFTCLK			9
+#define K2G_DEV_NSS_RGMII_MHZ_5_CLK		10
+#define K2G_DEV_NSS_RGMII_MHZ_50_CLK		11
+#define K2G_DEV_NSS_RGMII_MHZ_250_CLK		12
+#define K2G_DEV_NSS_RMII_MHZ_50_CLK		13
+
+#define K2G_DEV_PCIE_VBUS_CLK			0
+
+#define K2G_DEV_OTP_VBUS_CLK			0
+
+#define K2G_DEV_GPIO_VBUS_CLK			0
+
+#define K2G_DEV_TIMER64_VBUS_CLK		0
+#define K2G_DEV_TIMER64_TINL			1
+#define K2G_DEV_TIMER64_TINL_PARENT_TIMI0	2
+#define K2G_DEV_TIMER64_TINL_PARENT_TIMI1	3
+#define K2G_DEV_TIMER64_TINH			4
+#define K2G_DEV_TIMER64_TINH_PARENT_TIMI0	5
+#define K2G_DEV_TIMER64_TINH_PARENT_TIMI1	6
+#define K2G_DEV_TIMER64_TOUTL			7
+#define K2G_DEV_TIMER64_TOUTH			8
+
+#define K2G_DEV_SEC_MGR_SEC_CLK_PI		0
+
+#define K2G_DEV_MSGMGR_VBUS_CLK			0
+
+#define K2G_DEV_BOOTCFG_VBUS_CLK		0
+
+#define K2G_DEV_ARM_BOOTROM_VBUS_CLK		0
+
+#define K2G_DEV_DSP_BOOTROM_VBUS_CLK		0
+
+#define K2G_DEV_DEBUGSS_VBUSP_CTTBRCLK_CLK	0
+#define K2G_DEV_DEBUGSS_VBUSP_STMD0_CLK		1
+#define K2G_DEV_DEBUGSS_VBUSP_SLAVE_CLK		2
+#define K2G_DEV_DEBUGSS_VBUSP_MASTER_CLK	3
+#define K2G_DEV_DEBUGSS_TCK			4
+#define K2G_DEV_DEBUGSS_CS_TRCEXPT_CLK		5
+#define K2G_DEV_DEBUGSS_DSP_TRACECLK		6
+#define K2G_DEV_DEBUGSS_STMXPT_CLK		7
+
+#define K2G_DEV_UART_CBA_CLK_PI			0
+
+#define K2G_DEV_EHRPWM_VBUS_CLK			0
+
+#define K2G_DEV_EQEP_VBUS_CLK			0
+
+#define K2G_DEV_ECAP_VBUS_CLK			0
+
+#define K2G_DEV_I2C_VBUS_CLK			0
+
+#define K2G_DEV_CP_TRACER_CP_TRACER_CLK		0
+
+#define K2G_DEV_EDMA_TPTC_CLK			0
+#define K2G_DEV_EDMA_TPCC_CLK			1
+
+#define K2G_DEV_SEMAPHORE_VBUS_CLK		0
+
+#define K2G_DEV_INTC_VBUS_CLK			0
+
+#define K2G_DEV_GIC_VBUS_CLK			0
+
+#define K2G_DEV_QSPI_QSPI_CLK			0
+#define K2G_DEV_QSPI_DATA_BUS_CLK		1
+#define K2G_DEV_QSPI_CFG_BUS_CLK		2
+#define K2G_DEV_QSPI_QSPI_CLK_O			3
+#define K2G_DEV_QSPI_QSPI_CLK_I			4
+
+#define K2G_DEV_ARM_64B_COUNTER_CLK_INPUT	0
+#define K2G_DEV_ARM_64B_COUNTER_VBUSP_CLK	1
+
+#define K2G_DEV_TETRIS_CORE_CLK			0
+#define K2G_DEV_TETRIS_SUBSYS_CLK		1
+
+#define K2G_DEV_CGEM_CORE_CLK			0
+#define K2G_DEV_CGEM_TRACE_CLK			1
+
+#define K2G_DEV_MSMC_VBUS_CLK			0
+
+#define K2G_DEV_DFT_SS_VBUS_CLK			0
+#define K2G_DEV_DFT_SS_TCK			1
+
+#define K2G_DEV_CBASS_VBUS_CLK			0
+
+#define K2G_DEV_SMARTREFLEX_SCLK_CLK		0
+#define K2G_DEV_SMARTREFLEX_REFCLK1_CLK		1
+#define K2G_DEV_SMARTREFLEX_TEMPMCLK_CLK	2
+
+#define K2G_DEV_EFUSE_VBUS_CLK			0
+
+/* Outputs from board (inputs to SoC) */
+#define K2G_DEV_BOARD_SYS_OSCIN			0
+#define K2G_DEV_BOARD_SYS_CLK			1
+#define K2G_DEV_BOARD_AUDIO_OSCIN		2
+#define K2G_DEV_BOARD_DDR			3
+#define K2G_DEV_BOARD_MLBCLK			4
+#define K2G_DEV_BOARD_MLBPCLK			5
+#define K2G_DEV_BOARD_XREFCLK			6
+#define K2G_DEV_BOARD_TIMI0			7
+#define K2G_DEV_BOARD_TIMI1			8
+
+/* Inputs to board (outputs from SoC) */
+#define K2G_DEV_BOARD_SYSCLKOUT			10
+#define K2G_DEV_BOARD_OBSCLK			11
+#define K2G_DEV_BOARD_OBSCLK_PARENT_MAIN_PLL	12
+#define K2G_DEV_BOARD_OBSCLK_PARENT_DSS_PLL	13
+#define K2G_DEV_BOARD_OBSCLK_PARENT_ARM_PLL	14
+#define K2G_DEV_BOARD_OBSCLK_PARENT_UART_PLL	15
+#define K2G_DEV_BOARD_OBSCLK_PARENT_ICSS_PLL	16
+#define K2G_DEV_BOARD_OBSCLK_PARENT_DDR_PLL	17
+#define K2G_DEV_BOARD_OBSCLK_PARENT_PLL_CTRL	18
+#define K2G_DEV_BOARD_OBSCLK_PARENT_NSS_PLL	19
+#define K2G_DEV_BOARD_OBSCLK_PARENT_SYSOSC	20
+#define K2G_DEV_BOARD_MII_CLKOUT		21
+#define K2G_DEV_BOARD_TIMO0			22
+#define K2G_DEV_BOARD_TIMO1			23
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_0L	24
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_0H	25
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_1L	26
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_1H	27
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_2L	28
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_2H	29
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_3L	30
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_3H	31
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_4L	32
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_4H	33
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_5L	34
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_5H	35
+
+#endif
-- 
1.9.1

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

* [PATCHv2 2/3] dt-binding: clock: Add k2g clock definitions
@ 2016-09-01 12:40     ` Tero Kristo
  0 siblings, 0 replies; 29+ messages in thread
From: Tero Kristo @ 2016-09-01 12:40 UTC (permalink / raw)
  To: linux-arm-kernel

Add identifiers for the K2G clocks managed by the PMMC.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
Tested-by: Dave Gerlach <d-gerlach@ti.com>
Signed-off-by: Nishanth Menon <nm@ti.com>
---
 MAINTAINERS                     |   1 +
 include/dt-bindings/clock/k2g.h | 234 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 235 insertions(+)
 create mode 100644 include/dt-bindings/clock/k2g.h

diff --git a/MAINTAINERS b/MAINTAINERS
index ef88726..bcb7b9e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11574,6 +11574,7 @@ F:	Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
 F:	drivers/firmware/ti_sci*
 F:	include/linux/soc/ti/ti_sci_protocol.h
 F:	Documentation/devicetree/bindings/clock/ti,sci-clk.txt
+F:	include/dt-bindings/clock/k2g.h
 
 THANKO'S RAREMONO AM/FM/SW RADIO RECEIVER USB DRIVER
 M:	Hans Verkuil <hverkuil@xs4all.nl>
diff --git a/include/dt-bindings/clock/k2g.h b/include/dt-bindings/clock/k2g.h
new file mode 100644
index 0000000..cddffc3
--- /dev/null
+++ b/include/dt-bindings/clock/k2g.h
@@ -0,0 +1,234 @@
+/*
+ * TI K2G SoC clock definitions
+ *
+ * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * 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 __DT_BINDINGS_CLOCK_K2G_H__
+#define __DT_BINDINGS_CLOCK_K2G_H__
+
+/*
+ * The clock IDs listed in this file are describing the clocks at IP's
+ * boundaries. The firmware is not exposing any of the generic clocks
+ * from the system, those are handled internally by the firmware.
+ */
+#define K2G_DEV_PMMC_MPM_VBUS_CLK		0
+#define K2G_DEV_PMMC_MPM_FUNC_32K_CLK		1
+#define K2G_DEV_PMMC_MPM_FUNC_OSC_CLK		2
+#define K2G_DEV_PMMC_MPM_DAP_CLK		3
+
+#define K2G_DEV_MLB_MLB_SYS_CLK			0
+#define K2G_DEV_MLB_MLB_SHB_OCP_CLK		1
+#define K2G_DEV_MLB_MLB_SPB_OCP_CLK		2
+#define K2G_DEV_MLB_MLB_IO_CLK			3
+#define K2G_DEV_MLB_MLBP_IO_CLK			4
+
+#define K2G_DEV_DSS_PI_DSS_OCP_CLK		0
+#define K2G_DEV_DSS_PI_DSS_VP_CLK		1
+
+#define K2G_DEV_MCBSP_VBUS_CLK			0
+#define K2G_DEV_MCBSP_CLKS			1
+#define K2G_DEV_MCBSP_CLKS_PARENT_AUDIO_OSC	2
+#define K2G_DEV_MCBSP_CLKS_PARENT_MLB_IO_CLK	3
+#define K2G_DEV_MCBSP_CLKS_PARENT_MLBP_IO_CLK	4
+#define K2G_DEV_MCBSP_CLKS_PARENT_SYS_OSCCLK	5
+#define K2G_DEV_MCBSP_CLKS_PARENT_XREFCLK	6
+#define K2G_DEV_MCBSP_CLKS_PARENT_UART_PLL	7
+
+#define K2G_DEV_MCASP_VBUS_CLK			0
+#define K2G_DEV_MCASP_AUX_CLK			1
+#define K2G_DEV_MCASP_AUX_CLK_PARENT_AUDIO_OSC		2
+#define K2G_DEV_MCASP_AUX_CLK_PARENT_MLB_IO_CLK		3
+#define K2G_DEV_MCASP_AUX_CLK_PARENT_MLBP_IO_CLK	4
+#define K2G_DEV_MCASP_AUX_CLK_PARENT_SYS_OSCCLK		5
+#define K2G_DEV_MCASP_AUX_CLK_PARENT_XREFCLK		6
+#define K2G_DEV_MCASP_AUX_CLK_PARENT_UART_PLL		7
+
+#define K2G_DEV_DCAN_VBUS_CLK			0
+#define K2G_DEV_DCAN_CAN_CLK			1
+
+#define K2G_DEV_EMIF_V_CLK			0
+#define K2G_DEV_EMIF_M_CLK			1
+#define K2G_DEV_EMIF_DFT_LOCAL_CLK		2
+#define K2G_DEV_EMIF_PUB_CTL_CLK		3
+#define K2G_DEV_EMIF_PHY_CTL_CLK		4
+#define K2G_DEV_EMIF_VBUSP_CLK			5
+
+#define K2G_DEV_MMCHS_VBUS_CLK			0
+#define K2G_DEV_MMCHS_CLK_ADPI			1
+#define K2G_DEV_MMCHS_CLK32K			2
+
+#define K2G_DEV_GPMC_GPMC_FCLK			0
+
+#define K2G_DEV_ELM_CLK				0
+
+#define K2G_DEV_SPI_VBUSP_CLK			0
+
+#define K2G_DEV_ICSS_VCLK_CLK			0
+#define K2G_DEV_ICSS_CORE_CLK			1
+#define K2G_DEV_ICSS_CORE_CLK_PARENT_ICSS_PLL	2
+#define K2G_DEV_ICSS_CORE_CLK_PARENT_NSS_PLL	3
+#define K2G_DEV_ICSS_UCLK_CLK			4
+#define K2G_DEV_ICSS_IEPCLK_CLK			5
+
+#define K2G_DEV_USB_BUS_CLK			0
+#define K2G_DEV_USB_PHYMMR_CLK			1
+#define K2G_DEV_USB_SUSP_CLK			2
+#define K2G_DEV_USB_REF_CLK			3
+#define K2G_DEV_USB_DFT_ULPI_CLK		4
+#define K2G_DEV_USB_DFT_UTMI_CLK		5
+#define K2G_DEV_USB_CLKCORE			6
+
+#define K2G_DEV_NSS_VCLK			0
+#define K2G_DEV_NSS_SA_UL_CLK			1
+#define K2G_DEV_NSS_SA_UL_X1_CLK		2
+#define K2G_DEV_NSS_ESW_CLK			3
+/*
+ * Mux register is internal to the CPTS, so we must allow NSS to control it.
+ * CPTS_REFCLK_P/N is a direct input to this mux, so ignore it is ignored
+ * in the SoC clock tree.
+ */
+#define K2G_DEV_NSS_CPTS_CHIP_CLK1_2		4
+#define K2G_DEV_NSS_CPTS_CHIP_CLK1_3		5
+#define K2G_DEV_NSS_CPTS_TIMI0			6
+#define K2G_DEV_NSS_CPTS_TIMI1			7
+#define K2G_DEV_NSS_CPTS_NSS_PLL		8
+#define K2G_DEV_NSS_GMII_RFTCLK			9
+#define K2G_DEV_NSS_RGMII_MHZ_5_CLK		10
+#define K2G_DEV_NSS_RGMII_MHZ_50_CLK		11
+#define K2G_DEV_NSS_RGMII_MHZ_250_CLK		12
+#define K2G_DEV_NSS_RMII_MHZ_50_CLK		13
+
+#define K2G_DEV_PCIE_VBUS_CLK			0
+
+#define K2G_DEV_OTP_VBUS_CLK			0
+
+#define K2G_DEV_GPIO_VBUS_CLK			0
+
+#define K2G_DEV_TIMER64_VBUS_CLK		0
+#define K2G_DEV_TIMER64_TINL			1
+#define K2G_DEV_TIMER64_TINL_PARENT_TIMI0	2
+#define K2G_DEV_TIMER64_TINL_PARENT_TIMI1	3
+#define K2G_DEV_TIMER64_TINH			4
+#define K2G_DEV_TIMER64_TINH_PARENT_TIMI0	5
+#define K2G_DEV_TIMER64_TINH_PARENT_TIMI1	6
+#define K2G_DEV_TIMER64_TOUTL			7
+#define K2G_DEV_TIMER64_TOUTH			8
+
+#define K2G_DEV_SEC_MGR_SEC_CLK_PI		0
+
+#define K2G_DEV_MSGMGR_VBUS_CLK			0
+
+#define K2G_DEV_BOOTCFG_VBUS_CLK		0
+
+#define K2G_DEV_ARM_BOOTROM_VBUS_CLK		0
+
+#define K2G_DEV_DSP_BOOTROM_VBUS_CLK		0
+
+#define K2G_DEV_DEBUGSS_VBUSP_CTTBRCLK_CLK	0
+#define K2G_DEV_DEBUGSS_VBUSP_STMD0_CLK		1
+#define K2G_DEV_DEBUGSS_VBUSP_SLAVE_CLK		2
+#define K2G_DEV_DEBUGSS_VBUSP_MASTER_CLK	3
+#define K2G_DEV_DEBUGSS_TCK			4
+#define K2G_DEV_DEBUGSS_CS_TRCEXPT_CLK		5
+#define K2G_DEV_DEBUGSS_DSP_TRACECLK		6
+#define K2G_DEV_DEBUGSS_STMXPT_CLK		7
+
+#define K2G_DEV_UART_CBA_CLK_PI			0
+
+#define K2G_DEV_EHRPWM_VBUS_CLK			0
+
+#define K2G_DEV_EQEP_VBUS_CLK			0
+
+#define K2G_DEV_ECAP_VBUS_CLK			0
+
+#define K2G_DEV_I2C_VBUS_CLK			0
+
+#define K2G_DEV_CP_TRACER_CP_TRACER_CLK		0
+
+#define K2G_DEV_EDMA_TPTC_CLK			0
+#define K2G_DEV_EDMA_TPCC_CLK			1
+
+#define K2G_DEV_SEMAPHORE_VBUS_CLK		0
+
+#define K2G_DEV_INTC_VBUS_CLK			0
+
+#define K2G_DEV_GIC_VBUS_CLK			0
+
+#define K2G_DEV_QSPI_QSPI_CLK			0
+#define K2G_DEV_QSPI_DATA_BUS_CLK		1
+#define K2G_DEV_QSPI_CFG_BUS_CLK		2
+#define K2G_DEV_QSPI_QSPI_CLK_O			3
+#define K2G_DEV_QSPI_QSPI_CLK_I			4
+
+#define K2G_DEV_ARM_64B_COUNTER_CLK_INPUT	0
+#define K2G_DEV_ARM_64B_COUNTER_VBUSP_CLK	1
+
+#define K2G_DEV_TETRIS_CORE_CLK			0
+#define K2G_DEV_TETRIS_SUBSYS_CLK		1
+
+#define K2G_DEV_CGEM_CORE_CLK			0
+#define K2G_DEV_CGEM_TRACE_CLK			1
+
+#define K2G_DEV_MSMC_VBUS_CLK			0
+
+#define K2G_DEV_DFT_SS_VBUS_CLK			0
+#define K2G_DEV_DFT_SS_TCK			1
+
+#define K2G_DEV_CBASS_VBUS_CLK			0
+
+#define K2G_DEV_SMARTREFLEX_SCLK_CLK		0
+#define K2G_DEV_SMARTREFLEX_REFCLK1_CLK		1
+#define K2G_DEV_SMARTREFLEX_TEMPMCLK_CLK	2
+
+#define K2G_DEV_EFUSE_VBUS_CLK			0
+
+/* Outputs from board (inputs to SoC) */
+#define K2G_DEV_BOARD_SYS_OSCIN			0
+#define K2G_DEV_BOARD_SYS_CLK			1
+#define K2G_DEV_BOARD_AUDIO_OSCIN		2
+#define K2G_DEV_BOARD_DDR			3
+#define K2G_DEV_BOARD_MLBCLK			4
+#define K2G_DEV_BOARD_MLBPCLK			5
+#define K2G_DEV_BOARD_XREFCLK			6
+#define K2G_DEV_BOARD_TIMI0			7
+#define K2G_DEV_BOARD_TIMI1			8
+
+/* Inputs to board (outputs from SoC) */
+#define K2G_DEV_BOARD_SYSCLKOUT			10
+#define K2G_DEV_BOARD_OBSCLK			11
+#define K2G_DEV_BOARD_OBSCLK_PARENT_MAIN_PLL	12
+#define K2G_DEV_BOARD_OBSCLK_PARENT_DSS_PLL	13
+#define K2G_DEV_BOARD_OBSCLK_PARENT_ARM_PLL	14
+#define K2G_DEV_BOARD_OBSCLK_PARENT_UART_PLL	15
+#define K2G_DEV_BOARD_OBSCLK_PARENT_ICSS_PLL	16
+#define K2G_DEV_BOARD_OBSCLK_PARENT_DDR_PLL	17
+#define K2G_DEV_BOARD_OBSCLK_PARENT_PLL_CTRL	18
+#define K2G_DEV_BOARD_OBSCLK_PARENT_NSS_PLL	19
+#define K2G_DEV_BOARD_OBSCLK_PARENT_SYSOSC	20
+#define K2G_DEV_BOARD_MII_CLKOUT		21
+#define K2G_DEV_BOARD_TIMO0			22
+#define K2G_DEV_BOARD_TIMO1			23
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_0L	24
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_0H	25
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_1L	26
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_1H	27
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_2L	28
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_2H	29
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_3L	30
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_3H	31
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_4L	32
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_4H	33
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_5L	34
+#define K2G_DEV_BOARD_TIMO_PARENT_TIMER64_5H	35
+
+#endif
-- 
1.9.1

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

* [PATCHv2 3/3] clk: keystone: Add sci-clk driver support
  2016-09-01 12:40 ` Tero Kristo
  (?)
@ 2016-09-01 12:40     ` Tero Kristo
  -1 siblings, 0 replies; 29+ messages in thread
From: Tero Kristo @ 2016-09-01 12:40 UTC (permalink / raw)
  To: sboyd-sgV2jX0FEOL9JmXXK+q4OQ, mturquette-rdvid1DuHRBWk0Htik3J/w,
	linux-clk-u79uwXL29TY76Z2rM5mHXA
  Cc: ssantosh-DgEjT+Ai2ygdnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	nm-l0cyMroinI0

In K2G, the clock handling is done through firmware executing on a
separate core. Linux kernel needs to communicate to the firmware
through TI system control interface to access any power management
related resources, including clocks.

The keystone sci-clk driver does this, by communicating to the
firmware through the TI SCI driver. The driver adds support for
registering clocks through DT, and basic required clock operations
like prepare/get_rate, etc.

Signed-off-by: Tero Kristo <t-kristo-l0cyMroinI0@public.gmane.org>
---
 MAINTAINERS                    |   1 +
 drivers/clk/Kconfig            |   9 +
 drivers/clk/keystone/Makefile  |   1 +
 drivers/clk/keystone/sci-clk.c | 537 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 548 insertions(+)
 create mode 100644 drivers/clk/keystone/sci-clk.c

diff --git a/MAINTAINERS b/MAINTAINERS
index bcb7b9e..2ed4d38 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11575,6 +11575,7 @@ F:	drivers/firmware/ti_sci*
 F:	include/linux/soc/ti/ti_sci_protocol.h
 F:	Documentation/devicetree/bindings/clock/ti,sci-clk.txt
 F:	include/dt-bindings/clock/k2g.h
+F:	drivers/clk/keystone/sci-clk.c
 
 THANKO'S RAREMONO AM/FM/SW RADIO RECEIVER USB DRIVER
 M:	Hans Verkuil <hverkuil-qWit8jRvyhVmR6Xm/wNWPw@public.gmane.org>
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index e2d9bd7..dbe792a7 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -179,6 +179,15 @@ config COMMON_CLK_NXP
 	---help---
 	  Support for clock providers on NXP platforms.
 
+config TI_SCI_CLK
+	tristate "TI System Control Interface clock drivers"
+	depends on (TI_SCI_PROTOCOL && COMMON_CLK_KEYSTONE) || COMPILE_TEST
+	default TI_SCI_PROTOCOL
+	---help---
+	  This adds the clock driver support over TI System Control Interface.
+	  If you wish to use clock resources from the PMMC firmware, say Y.
+	  Otherwise, say N.
+
 config COMMON_CLK_PALMAS
 	tristate "Clock driver for TI Palmas devices"
 	depends on MFD_PALMAS
diff --git a/drivers/clk/keystone/Makefile b/drivers/clk/keystone/Makefile
index 0477cf6..0e7993d 100644
--- a/drivers/clk/keystone/Makefile
+++ b/drivers/clk/keystone/Makefile
@@ -1 +1,2 @@
 obj-y			+= pll.o gate.o
+obj-$(CONFIG_TI_SCI_CLK)	+= sci-clk.o
diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
new file mode 100644
index 0000000..852fc49
--- /dev/null
+++ b/drivers/clk/keystone/sci-clk.c
@@ -0,0 +1,537 @@
+/*
+ * SCI Clock driver for keystone based devices
+ *
+ * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/
+ *	Tero Kristo <t-kristo-l0cyMroinI0@public.gmane.org>
+ *
+ * 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.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/soc/ti/ti_sci_protocol.h>
+
+#define SCI_CLK_SSC_ENABLE		BIT(0)
+#define SCI_CLK_ALLOW_FREQ_CHANGE	BIT(1)
+#define SCI_CLK_INPUT_TERMINATION	BIT(2)
+
+/**
+ * struct sci_clk_provider - TI SCI clock provider representation
+ * @sci:    Handle to the System Control Interface protocol handler
+ * @ops:    Pointer to the SCI ops to be used by the clocks
+ * @dev:    Device pointer for the clock provider
+ * @clocks: List of all registered clocks
+ * @lock:   Mutex for locking access to the @clocks list
+ */
+struct sci_clk_provider {
+	const struct ti_sci_handle *sci;
+	const struct ti_sci_clk_ops *ops;
+	struct device *dev;
+	struct list_head clocks;
+	struct mutex lock; /* Protects access to the @clocks list */
+};
+
+/**
+ * struct sci_clk - TI SCI clock representation
+ * @hw:		 Hardware clock cookie for common clock framework
+ * @dev_id:	 Device index
+ * @clk_id:	 Clock index
+ * @node:	 Clocks list link
+ * @provider:	 Master clock provider
+ * @flags:	 Flags for the clock
+ */
+struct sci_clk {
+	struct clk_hw hw;
+	u16 dev_id;
+	u8 clk_id;
+	struct list_head node;
+	struct sci_clk_provider *provider;
+	u8 flags;
+};
+
+#define to_sci_clk(_hw) container_of(_hw, struct sci_clk, hw)
+
+/**
+ * sci_clk_prepare - Prepare (enable) a TI SCI clock
+ * @hw: clock to prepare
+ *
+ * Prepares a clock to be actively used. Returns the SCI protocol status.
+ */
+static int sci_clk_prepare(struct clk_hw *hw)
+{
+	struct sci_clk *clk = to_sci_clk(hw);
+	bool enable_ssc = clk->flags & SCI_CLK_SSC_ENABLE;
+	bool allow_freq_change = clk->flags & SCI_CLK_ALLOW_FREQ_CHANGE;
+	bool input_termination = clk->flags & SCI_CLK_INPUT_TERMINATION;
+
+	return clk->provider->ops->get_clock(clk->provider->sci, clk->dev_id,
+					     clk->clk_id, enable_ssc,
+					     allow_freq_change,
+					     input_termination);
+}
+
+/**
+ * sci_clk_unprepare - Un-prepares (disables) a TI SCI clock
+ * @hw: clock to unprepare
+ *
+ * Un-prepares a clock from active state.
+ */
+static void sci_clk_unprepare(struct clk_hw *hw)
+{
+	struct sci_clk *clk = to_sci_clk(hw);
+	int ret;
+
+	ret = clk->provider->ops->put_clock(clk->provider->sci, clk->dev_id,
+					    clk->clk_id);
+	if (ret)
+		dev_err(clk->provider->dev,
+			"unprepare failed for dev=%d, clk=%d, ret=%d\n",
+			clk->dev_id, clk->clk_id, ret);
+}
+
+/**
+ * sci_clk_is_prepared - Check if a TI SCI clock is prepared or not
+ * @hw: clock to check status for
+ *
+ * Checks if a clock is prepared (enabled) in hardware. Returns non-zero
+ * value if clock is enabled, zero otherwise.
+ */
+static int sci_clk_is_prepared(struct clk_hw *hw)
+{
+	struct sci_clk *clk = to_sci_clk(hw);
+	bool req_state, current_state;
+	int ret;
+
+	ret = clk->provider->ops->is_on(clk->provider->sci, clk->dev_id,
+					clk->clk_id, &req_state,
+					&current_state);
+	if (ret) {
+		dev_err(clk->provider->dev,
+			"is_prepared failed for dev=%d, clk=%d, ret=%d\n",
+			clk->dev_id, clk->clk_id, ret);
+		return 0;
+	}
+
+	return req_state;
+}
+
+/**
+ * sci_clk_recalc_rate - Get clock rate for a TI SCI clock
+ * @hw: clock to get rate for
+ * @parent_rate: parent rate provided by common clock framework, not used
+ *
+ * Gets the current clock rate of a TI SCI clock. Returns the current
+ * clock rate, or zero in failure.
+ */
+static unsigned long sci_clk_recalc_rate(struct clk_hw *hw,
+					 unsigned long parent_rate)
+{
+	struct sci_clk *clk = to_sci_clk(hw);
+	u64 freq;
+	int ret;
+
+	ret = clk->provider->ops->get_freq(clk->provider->sci, clk->dev_id,
+					   clk->clk_id, &freq);
+	if (ret) {
+		dev_err(clk->provider->dev,
+			"recalc-rate failed for dev=%d, clk=%d, ret=%d\n",
+			clk->dev_id, clk->clk_id, ret);
+		return 0;
+	}
+
+	return (u32)freq;
+}
+
+/**
+ * sci_clk_determine_rate - Determines a clock rate a clock can be set to
+ * @hw: clock to change rate for
+ * @req: requested rate configuration for the clock
+ *
+ * Determines a suitable clock rate and parent for a TI SCI clock.
+ * The parent handling is un-used, as generally the parent clock rates
+ * are not known by the kernel; instead these are internally handled
+ * by the firmware. Returns 0 on success, negative error value on failure.
+ */
+static int sci_clk_determine_rate(struct clk_hw *hw,
+				  struct clk_rate_request *req)
+{
+	struct sci_clk *clk = to_sci_clk(hw);
+	int ret;
+	u64 new_rate;
+
+	ret = clk->provider->ops->get_best_match_freq(clk->provider->sci,
+						      clk->dev_id,
+						      clk->clk_id,
+						      req->min_rate,
+						      req->rate,
+						      req->max_rate,
+						      &new_rate);
+	if (ret) {
+		dev_err(clk->provider->dev,
+			"determine-rate failed for dev=%d, clk=%d, ret=%d\n",
+			clk->dev_id, clk->clk_id, ret);
+		return ret;
+	}
+
+	req->rate = new_rate;
+
+	return 0;
+}
+
+/**
+ * sci_clk_set_rate - Set rate for a TI SCI clock
+ * @hw: clock to change rate for
+ * @rate: target rate for the clock
+ * @parent_rate: rate of the clock parent, not used for TI SCI clocks
+ *
+ * Sets a clock frequency for a TI SCI clock. Returns the TI SCI
+ * protocol status.
+ */
+static int sci_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+			    unsigned long parent_rate)
+{
+	struct sci_clk *clk = to_sci_clk(hw);
+
+	return clk->provider->ops->set_freq(clk->provider->sci, clk->dev_id,
+					    clk->clk_id, rate, rate, rate);
+}
+
+/**
+ * sci_clk_get_parent - Get the current parent of a TI SCI clock
+ * @hw: clock to get parent for
+ *
+ * Returns the index of the currently selected parent for a TI SCI clock.
+ */
+static u8 sci_clk_get_parent(struct clk_hw *hw)
+{
+	struct sci_clk *clk = to_sci_clk(hw);
+	u8 parent_id;
+	int ret;
+
+	ret = clk->provider->ops->get_parent(clk->provider->sci, clk->dev_id,
+					     clk->clk_id, &parent_id);
+	if (ret) {
+		dev_err(clk->provider->dev,
+			"get-parent failed for dev=%d, clk=%d, ret=%d\n",
+			clk->dev_id, clk->clk_id, ret);
+		return 0;
+	}
+
+	return parent_id - clk->clk_id - 1;
+}
+
+/**
+ * sci_clk_set_parent - Set the parent of a TI SCI clock
+ * @hw: clock to set parent for
+ * @index: new parent index for the clock
+ *
+ * Sets the parent of a TI SCI clock. Return TI SCI protocol status.
+ */
+static int sci_clk_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct sci_clk *clk = to_sci_clk(hw);
+
+	return clk->provider->ops->set_parent(clk->provider->sci, clk->dev_id,
+					      clk->clk_id,
+					      index + 1 + clk->clk_id);
+}
+
+static const struct clk_ops sci_clk_ops = {
+	.prepare = sci_clk_prepare,
+	.unprepare = sci_clk_unprepare,
+	.is_prepared = sci_clk_is_prepared,
+	.recalc_rate = sci_clk_recalc_rate,
+	.determine_rate = sci_clk_determine_rate,
+	.set_rate = sci_clk_set_rate,
+	.get_parent = sci_clk_get_parent,
+	.set_parent = sci_clk_set_parent,
+};
+
+/**
+ * _sci_clk_get - Gets a handle for an SCI clock
+ * @provider: Handle to SCI clock provider
+ * @dev_id: device ID for the clock to register
+ * @clk_id: clock ID for the clock to register
+ * @parse_parents: indicator whether parents for this clock should be handled
+ *
+ * Gets a handle to an existing TI SCI hw clock, or builds a new clock
+ * entry and registers it with the common clock framework. Called from
+ * the common clock framework, when a corresponding of_clk_get call is
+ * executed, or recursively from itself when parsing parent clocks.
+ * Returns a pointer to the hw clock struct, or ERR_PTR value in failure.
+ */
+static struct clk_hw *_sci_clk_get(struct sci_clk_provider *provider,
+				   u16 dev_id, u8 clk_id, bool parse_parents)
+{
+	struct clk_init_data init = { NULL };
+	struct sci_clk *sci_clk = NULL;
+	char *name = NULL;
+	char **parent_names = NULL;
+	int i;
+	int ret;
+
+	list_for_each_entry(sci_clk, &provider->clocks, node)
+		if (sci_clk->dev_id == dev_id && sci_clk->clk_id == clk_id)
+			return &sci_clk->hw;
+
+	sci_clk = devm_kzalloc(provider->dev, sizeof(*sci_clk), GFP_KERNEL);
+	if (!sci_clk) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	sci_clk->dev_id = dev_id;
+	sci_clk->clk_id = clk_id;
+	sci_clk->provider = provider;
+
+	if (parse_parents) {
+		ret = provider->ops->get_num_parents(provider->sci, dev_id,
+						     clk_id,
+						     &init.num_parents);
+		if (ret)
+			goto err;
+	}
+
+	name = kasprintf(GFP_KERNEL, "%s:%d:%d", dev_name(provider->dev),
+			 sci_clk->dev_id, sci_clk->clk_id);
+
+	init.name = name;
+
+	if (init.num_parents < 2)
+		init.num_parents = 0;
+
+	if (init.num_parents) {
+		parent_names = devm_kcalloc(provider->dev, init.num_parents,
+					    sizeof(char *), GFP_KERNEL);
+
+		if (!parent_names) {
+			ret = -ENOMEM;
+			goto err;
+		}
+
+		for (i = 0; i < init.num_parents; i++) {
+			char *parent_name;
+
+			parent_name = devm_kzalloc(provider->dev, 20,
+						   GFP_KERNEL);
+			if (!parent_name) {
+				ret = -ENOMEM;
+				goto err;
+			}
+			snprintf(parent_name, 20, "%s:%d:%d",
+				 dev_name(provider->dev), sci_clk->dev_id,
+				 sci_clk->clk_id + 1 + i);
+			parent_names[i] = parent_name;
+
+			_sci_clk_get(provider, dev_id, clk_id + 1 + i, false);
+		}
+		init.parent_names = (const char * const *)parent_names;
+	}
+
+	init.ops = &sci_clk_ops;
+	sci_clk->hw.init = &init;
+
+	ret = devm_clk_hw_register(provider->dev, &sci_clk->hw);
+	if (ret) {
+		dev_err(provider->dev, "failed clk register with %d\n", ret);
+		goto err;
+	} else {
+		list_add(&sci_clk->node, &provider->clocks);
+	}
+
+	kfree(name);
+
+	return &sci_clk->hw;
+
+err:
+	if (parent_names) {
+		for (i = 0; i < init.num_parents; i++)
+			devm_kfree(provider->dev, parent_names[i]);
+
+		devm_kfree(provider->dev, parent_names);
+	}
+
+	devm_kfree(provider->dev, sci_clk);
+
+	kfree(name);
+
+	return ERR_PTR(ret);
+}
+
+/**
+ * sci_clk_get - Xlate function for getting clock handles
+ * @clkspec: device tree clock specifier
+ * @data: pointer to the clock provider
+ *
+ * Xlate function for retrieving clock TI SCI hw clock handles based on
+ * device tree clock specifier. Called from the common clock framework,
+ * when a corresponding of_clk_get call is executed. Returns a pointer
+ * to the TI SCI hw clock struct, or ERR_PTR value in failure.
+ */
+static struct clk_hw *sci_clk_get(struct of_phandle_args *clkspec, void *data)
+{
+	struct sci_clk_provider *provider = data;
+	struct clk_hw *clk;
+	u16 dev_id;
+	u8 clk_id;
+
+	if (clkspec->args_count != 2)
+		return ERR_PTR(-EINVAL);
+
+	mutex_lock(&provider->lock);
+
+	dev_id = clkspec->args[0];
+	clk_id = clkspec->args[1];
+
+	clk = _sci_clk_get(provider, dev_id, clk_id, true);
+
+	mutex_unlock(&provider->lock);
+
+	return clk;
+}
+
+static const struct of_device_id ti_sci_clk_of_match[] = {
+	{ .compatible = "ti,sci-clk" },
+	{ /* Sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, ti_sci_clk_of_match);
+
+/**
+ * ti_sci_clk_parse_flags - Helper function to parse clock flag arrays
+ * @provider: clock provider handle
+ * @list_name: property name containing the clocks list
+ * @flag: flag to apply to the list of clocks
+ *
+ * Parses a DT list based on the provided data, and applies the flag value
+ * for each of the clocks identified by the list. Return 0 for success,
+ * negative error value for failure.
+ */
+static int ti_sci_clk_parse_flags(struct sci_clk_provider *provider,
+				  const char *list_name, u8 flag)
+{
+	int num_clks;
+	int i;
+	struct device_node *np = provider->dev->of_node;
+	struct device *dev = provider->dev;
+
+	num_clks = of_count_phandle_with_args(np, list_name, "#clock-cells");
+
+	for (i = 0; i < num_clks; i++) {
+		struct of_phandle_args clkspec;
+		struct sci_clk *sci_clk;
+		struct clk_hw *clk;
+		int ret;
+
+		ret = of_parse_phandle_with_args(np, list_name, "#clock-cells",
+						 i, &clkspec);
+		if (ret) {
+			dev_err(dev, "Failed to parse %s[%d] = %d\n", list_name,
+				i, ret);
+			return ret;
+		}
+		clk = sci_clk_get(&clkspec, provider);
+		if (IS_ERR(clk)) {
+			dev_err(dev, "clk_get failed for %s[%d] = %ld\n",
+				list_name, i, PTR_ERR(clk));
+			return PTR_ERR(clk);
+		}
+		sci_clk = to_sci_clk(clk);
+
+		sci_clk->flags |= flag;
+	}
+
+	return 0;
+}
+
+/**
+ * ti_sci_clk_probe - Probe function for the TI SCI clock driver
+ * @pdev: platform device pointer to be probed
+ *
+ * Probes the TI SCI clock device. Allocates a new clock provider
+ * and registers this to the common clock framework. Also applies
+ * any required flags to the identified clocks via clock lists
+ * supplied from DT. Returns 0 for success, negative error value
+ * for failure.
+ */
+static int ti_sci_clk_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct sci_clk_provider *provider;
+	const struct ti_sci_handle *handle;
+	int ret;
+
+	if (!np) {
+		dev_err(dev, "OF data missing\n");
+		return -EINVAL;
+	}
+
+	handle = devm_ti_sci_get_handle(dev);
+	if (IS_ERR(handle))
+		return PTR_ERR(handle);
+
+	provider = devm_kzalloc(dev, sizeof(*provider), GFP_KERNEL);
+	if (!provider)
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&provider->clocks);
+	mutex_init(&provider->lock);
+
+	provider->sci = handle;
+	provider->ops = &handle->ops.clk_ops;
+	provider->dev = dev;
+
+	ret = of_clk_add_hw_provider(np, sci_clk_get, provider);
+	if (ret)
+		return ret;
+
+	ti_sci_clk_parse_flags(provider, "ti,ssc-clocks", SCI_CLK_SSC_ENABLE);
+	ti_sci_clk_parse_flags(provider, "ti,allow-freq-change-clocks",
+			       SCI_CLK_ALLOW_FREQ_CHANGE);
+	ti_sci_clk_parse_flags(provider, "ti,input-term-clocks",
+			       SCI_CLK_INPUT_TERMINATION);
+
+	return 0;
+}
+
+/**
+ * ti_sci_clk_remove - Remove TI SCI clock device
+ * @pdev: platform device pointer for the device to be removed
+ *
+ * Removes the TI SCI device. Unregisters the clock provider registered
+ * via common clock framework. Any memory allocated for the device will
+ * be free'd silently via the devm framework. Returns 0 always.
+ */
+static int ti_sci_clk_remove(struct platform_device *pdev)
+{
+	of_clk_del_provider(pdev->dev.of_node);
+
+	return 0;
+}
+
+static struct platform_driver ti_sci_clk_driver = {
+	.probe = ti_sci_clk_probe,
+	.remove = ti_sci_clk_remove,
+	.driver = {
+		.name = "ti-sci-clk",
+		.of_match_table = of_match_ptr(ti_sci_clk_of_match),
+	},
+};
+module_platform_driver(ti_sci_clk_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("TI System Control Interface(SCI) Clock driver");
+MODULE_AUTHOR("Tero Kristo");
+MODULE_ALIAS("platform:ti-sci-clk");
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* [PATCHv2 3/3] clk: keystone: Add sci-clk driver support
@ 2016-09-01 12:40     ` Tero Kristo
  0 siblings, 0 replies; 29+ messages in thread
From: Tero Kristo @ 2016-09-01 12:40 UTC (permalink / raw)
  To: sboyd, mturquette, linux-clk; +Cc: ssantosh, devicetree, linux-arm-kernel, nm

In K2G, the clock handling is done through firmware executing on a
separate core. Linux kernel needs to communicate to the firmware
through TI system control interface to access any power management
related resources, including clocks.

The keystone sci-clk driver does this, by communicating to the
firmware through the TI SCI driver. The driver adds support for
registering clocks through DT, and basic required clock operations
like prepare/get_rate, etc.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 MAINTAINERS                    |   1 +
 drivers/clk/Kconfig            |   9 +
 drivers/clk/keystone/Makefile  |   1 +
 drivers/clk/keystone/sci-clk.c | 537 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 548 insertions(+)
 create mode 100644 drivers/clk/keystone/sci-clk.c

diff --git a/MAINTAINERS b/MAINTAINERS
index bcb7b9e..2ed4d38 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11575,6 +11575,7 @@ F:	drivers/firmware/ti_sci*
 F:	include/linux/soc/ti/ti_sci_protocol.h
 F:	Documentation/devicetree/bindings/clock/ti,sci-clk.txt
 F:	include/dt-bindings/clock/k2g.h
+F:	drivers/clk/keystone/sci-clk.c
 
 THANKO'S RAREMONO AM/FM/SW RADIO RECEIVER USB DRIVER
 M:	Hans Verkuil <hverkuil@xs4all.nl>
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index e2d9bd7..dbe792a7 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -179,6 +179,15 @@ config COMMON_CLK_NXP
 	---help---
 	  Support for clock providers on NXP platforms.
 
+config TI_SCI_CLK
+	tristate "TI System Control Interface clock drivers"
+	depends on (TI_SCI_PROTOCOL && COMMON_CLK_KEYSTONE) || COMPILE_TEST
+	default TI_SCI_PROTOCOL
+	---help---
+	  This adds the clock driver support over TI System Control Interface.
+	  If you wish to use clock resources from the PMMC firmware, say Y.
+	  Otherwise, say N.
+
 config COMMON_CLK_PALMAS
 	tristate "Clock driver for TI Palmas devices"
 	depends on MFD_PALMAS
diff --git a/drivers/clk/keystone/Makefile b/drivers/clk/keystone/Makefile
index 0477cf6..0e7993d 100644
--- a/drivers/clk/keystone/Makefile
+++ b/drivers/clk/keystone/Makefile
@@ -1 +1,2 @@
 obj-y			+= pll.o gate.o
+obj-$(CONFIG_TI_SCI_CLK)	+= sci-clk.o
diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
new file mode 100644
index 0000000..852fc49
--- /dev/null
+++ b/drivers/clk/keystone/sci-clk.c
@@ -0,0 +1,537 @@
+/*
+ * SCI Clock driver for keystone based devices
+ *
+ * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/
+ *	Tero Kristo <t-kristo@ti.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.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/soc/ti/ti_sci_protocol.h>
+
+#define SCI_CLK_SSC_ENABLE		BIT(0)
+#define SCI_CLK_ALLOW_FREQ_CHANGE	BIT(1)
+#define SCI_CLK_INPUT_TERMINATION	BIT(2)
+
+/**
+ * struct sci_clk_provider - TI SCI clock provider representation
+ * @sci:    Handle to the System Control Interface protocol handler
+ * @ops:    Pointer to the SCI ops to be used by the clocks
+ * @dev:    Device pointer for the clock provider
+ * @clocks: List of all registered clocks
+ * @lock:   Mutex for locking access to the @clocks list
+ */
+struct sci_clk_provider {
+	const struct ti_sci_handle *sci;
+	const struct ti_sci_clk_ops *ops;
+	struct device *dev;
+	struct list_head clocks;
+	struct mutex lock; /* Protects access to the @clocks list */
+};
+
+/**
+ * struct sci_clk - TI SCI clock representation
+ * @hw:		 Hardware clock cookie for common clock framework
+ * @dev_id:	 Device index
+ * @clk_id:	 Clock index
+ * @node:	 Clocks list link
+ * @provider:	 Master clock provider
+ * @flags:	 Flags for the clock
+ */
+struct sci_clk {
+	struct clk_hw hw;
+	u16 dev_id;
+	u8 clk_id;
+	struct list_head node;
+	struct sci_clk_provider *provider;
+	u8 flags;
+};
+
+#define to_sci_clk(_hw) container_of(_hw, struct sci_clk, hw)
+
+/**
+ * sci_clk_prepare - Prepare (enable) a TI SCI clock
+ * @hw: clock to prepare
+ *
+ * Prepares a clock to be actively used. Returns the SCI protocol status.
+ */
+static int sci_clk_prepare(struct clk_hw *hw)
+{
+	struct sci_clk *clk = to_sci_clk(hw);
+	bool enable_ssc = clk->flags & SCI_CLK_SSC_ENABLE;
+	bool allow_freq_change = clk->flags & SCI_CLK_ALLOW_FREQ_CHANGE;
+	bool input_termination = clk->flags & SCI_CLK_INPUT_TERMINATION;
+
+	return clk->provider->ops->get_clock(clk->provider->sci, clk->dev_id,
+					     clk->clk_id, enable_ssc,
+					     allow_freq_change,
+					     input_termination);
+}
+
+/**
+ * sci_clk_unprepare - Un-prepares (disables) a TI SCI clock
+ * @hw: clock to unprepare
+ *
+ * Un-prepares a clock from active state.
+ */
+static void sci_clk_unprepare(struct clk_hw *hw)
+{
+	struct sci_clk *clk = to_sci_clk(hw);
+	int ret;
+
+	ret = clk->provider->ops->put_clock(clk->provider->sci, clk->dev_id,
+					    clk->clk_id);
+	if (ret)
+		dev_err(clk->provider->dev,
+			"unprepare failed for dev=%d, clk=%d, ret=%d\n",
+			clk->dev_id, clk->clk_id, ret);
+}
+
+/**
+ * sci_clk_is_prepared - Check if a TI SCI clock is prepared or not
+ * @hw: clock to check status for
+ *
+ * Checks if a clock is prepared (enabled) in hardware. Returns non-zero
+ * value if clock is enabled, zero otherwise.
+ */
+static int sci_clk_is_prepared(struct clk_hw *hw)
+{
+	struct sci_clk *clk = to_sci_clk(hw);
+	bool req_state, current_state;
+	int ret;
+
+	ret = clk->provider->ops->is_on(clk->provider->sci, clk->dev_id,
+					clk->clk_id, &req_state,
+					&current_state);
+	if (ret) {
+		dev_err(clk->provider->dev,
+			"is_prepared failed for dev=%d, clk=%d, ret=%d\n",
+			clk->dev_id, clk->clk_id, ret);
+		return 0;
+	}
+
+	return req_state;
+}
+
+/**
+ * sci_clk_recalc_rate - Get clock rate for a TI SCI clock
+ * @hw: clock to get rate for
+ * @parent_rate: parent rate provided by common clock framework, not used
+ *
+ * Gets the current clock rate of a TI SCI clock. Returns the current
+ * clock rate, or zero in failure.
+ */
+static unsigned long sci_clk_recalc_rate(struct clk_hw *hw,
+					 unsigned long parent_rate)
+{
+	struct sci_clk *clk = to_sci_clk(hw);
+	u64 freq;
+	int ret;
+
+	ret = clk->provider->ops->get_freq(clk->provider->sci, clk->dev_id,
+					   clk->clk_id, &freq);
+	if (ret) {
+		dev_err(clk->provider->dev,
+			"recalc-rate failed for dev=%d, clk=%d, ret=%d\n",
+			clk->dev_id, clk->clk_id, ret);
+		return 0;
+	}
+
+	return (u32)freq;
+}
+
+/**
+ * sci_clk_determine_rate - Determines a clock rate a clock can be set to
+ * @hw: clock to change rate for
+ * @req: requested rate configuration for the clock
+ *
+ * Determines a suitable clock rate and parent for a TI SCI clock.
+ * The parent handling is un-used, as generally the parent clock rates
+ * are not known by the kernel; instead these are internally handled
+ * by the firmware. Returns 0 on success, negative error value on failure.
+ */
+static int sci_clk_determine_rate(struct clk_hw *hw,
+				  struct clk_rate_request *req)
+{
+	struct sci_clk *clk = to_sci_clk(hw);
+	int ret;
+	u64 new_rate;
+
+	ret = clk->provider->ops->get_best_match_freq(clk->provider->sci,
+						      clk->dev_id,
+						      clk->clk_id,
+						      req->min_rate,
+						      req->rate,
+						      req->max_rate,
+						      &new_rate);
+	if (ret) {
+		dev_err(clk->provider->dev,
+			"determine-rate failed for dev=%d, clk=%d, ret=%d\n",
+			clk->dev_id, clk->clk_id, ret);
+		return ret;
+	}
+
+	req->rate = new_rate;
+
+	return 0;
+}
+
+/**
+ * sci_clk_set_rate - Set rate for a TI SCI clock
+ * @hw: clock to change rate for
+ * @rate: target rate for the clock
+ * @parent_rate: rate of the clock parent, not used for TI SCI clocks
+ *
+ * Sets a clock frequency for a TI SCI clock. Returns the TI SCI
+ * protocol status.
+ */
+static int sci_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+			    unsigned long parent_rate)
+{
+	struct sci_clk *clk = to_sci_clk(hw);
+
+	return clk->provider->ops->set_freq(clk->provider->sci, clk->dev_id,
+					    clk->clk_id, rate, rate, rate);
+}
+
+/**
+ * sci_clk_get_parent - Get the current parent of a TI SCI clock
+ * @hw: clock to get parent for
+ *
+ * Returns the index of the currently selected parent for a TI SCI clock.
+ */
+static u8 sci_clk_get_parent(struct clk_hw *hw)
+{
+	struct sci_clk *clk = to_sci_clk(hw);
+	u8 parent_id;
+	int ret;
+
+	ret = clk->provider->ops->get_parent(clk->provider->sci, clk->dev_id,
+					     clk->clk_id, &parent_id);
+	if (ret) {
+		dev_err(clk->provider->dev,
+			"get-parent failed for dev=%d, clk=%d, ret=%d\n",
+			clk->dev_id, clk->clk_id, ret);
+		return 0;
+	}
+
+	return parent_id - clk->clk_id - 1;
+}
+
+/**
+ * sci_clk_set_parent - Set the parent of a TI SCI clock
+ * @hw: clock to set parent for
+ * @index: new parent index for the clock
+ *
+ * Sets the parent of a TI SCI clock. Return TI SCI protocol status.
+ */
+static int sci_clk_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct sci_clk *clk = to_sci_clk(hw);
+
+	return clk->provider->ops->set_parent(clk->provider->sci, clk->dev_id,
+					      clk->clk_id,
+					      index + 1 + clk->clk_id);
+}
+
+static const struct clk_ops sci_clk_ops = {
+	.prepare = sci_clk_prepare,
+	.unprepare = sci_clk_unprepare,
+	.is_prepared = sci_clk_is_prepared,
+	.recalc_rate = sci_clk_recalc_rate,
+	.determine_rate = sci_clk_determine_rate,
+	.set_rate = sci_clk_set_rate,
+	.get_parent = sci_clk_get_parent,
+	.set_parent = sci_clk_set_parent,
+};
+
+/**
+ * _sci_clk_get - Gets a handle for an SCI clock
+ * @provider: Handle to SCI clock provider
+ * @dev_id: device ID for the clock to register
+ * @clk_id: clock ID for the clock to register
+ * @parse_parents: indicator whether parents for this clock should be handled
+ *
+ * Gets a handle to an existing TI SCI hw clock, or builds a new clock
+ * entry and registers it with the common clock framework. Called from
+ * the common clock framework, when a corresponding of_clk_get call is
+ * executed, or recursively from itself when parsing parent clocks.
+ * Returns a pointer to the hw clock struct, or ERR_PTR value in failure.
+ */
+static struct clk_hw *_sci_clk_get(struct sci_clk_provider *provider,
+				   u16 dev_id, u8 clk_id, bool parse_parents)
+{
+	struct clk_init_data init = { NULL };
+	struct sci_clk *sci_clk = NULL;
+	char *name = NULL;
+	char **parent_names = NULL;
+	int i;
+	int ret;
+
+	list_for_each_entry(sci_clk, &provider->clocks, node)
+		if (sci_clk->dev_id == dev_id && sci_clk->clk_id == clk_id)
+			return &sci_clk->hw;
+
+	sci_clk = devm_kzalloc(provider->dev, sizeof(*sci_clk), GFP_KERNEL);
+	if (!sci_clk) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	sci_clk->dev_id = dev_id;
+	sci_clk->clk_id = clk_id;
+	sci_clk->provider = provider;
+
+	if (parse_parents) {
+		ret = provider->ops->get_num_parents(provider->sci, dev_id,
+						     clk_id,
+						     &init.num_parents);
+		if (ret)
+			goto err;
+	}
+
+	name = kasprintf(GFP_KERNEL, "%s:%d:%d", dev_name(provider->dev),
+			 sci_clk->dev_id, sci_clk->clk_id);
+
+	init.name = name;
+
+	if (init.num_parents < 2)
+		init.num_parents = 0;
+
+	if (init.num_parents) {
+		parent_names = devm_kcalloc(provider->dev, init.num_parents,
+					    sizeof(char *), GFP_KERNEL);
+
+		if (!parent_names) {
+			ret = -ENOMEM;
+			goto err;
+		}
+
+		for (i = 0; i < init.num_parents; i++) {
+			char *parent_name;
+
+			parent_name = devm_kzalloc(provider->dev, 20,
+						   GFP_KERNEL);
+			if (!parent_name) {
+				ret = -ENOMEM;
+				goto err;
+			}
+			snprintf(parent_name, 20, "%s:%d:%d",
+				 dev_name(provider->dev), sci_clk->dev_id,
+				 sci_clk->clk_id + 1 + i);
+			parent_names[i] = parent_name;
+
+			_sci_clk_get(provider, dev_id, clk_id + 1 + i, false);
+		}
+		init.parent_names = (const char * const *)parent_names;
+	}
+
+	init.ops = &sci_clk_ops;
+	sci_clk->hw.init = &init;
+
+	ret = devm_clk_hw_register(provider->dev, &sci_clk->hw);
+	if (ret) {
+		dev_err(provider->dev, "failed clk register with %d\n", ret);
+		goto err;
+	} else {
+		list_add(&sci_clk->node, &provider->clocks);
+	}
+
+	kfree(name);
+
+	return &sci_clk->hw;
+
+err:
+	if (parent_names) {
+		for (i = 0; i < init.num_parents; i++)
+			devm_kfree(provider->dev, parent_names[i]);
+
+		devm_kfree(provider->dev, parent_names);
+	}
+
+	devm_kfree(provider->dev, sci_clk);
+
+	kfree(name);
+
+	return ERR_PTR(ret);
+}
+
+/**
+ * sci_clk_get - Xlate function for getting clock handles
+ * @clkspec: device tree clock specifier
+ * @data: pointer to the clock provider
+ *
+ * Xlate function for retrieving clock TI SCI hw clock handles based on
+ * device tree clock specifier. Called from the common clock framework,
+ * when a corresponding of_clk_get call is executed. Returns a pointer
+ * to the TI SCI hw clock struct, or ERR_PTR value in failure.
+ */
+static struct clk_hw *sci_clk_get(struct of_phandle_args *clkspec, void *data)
+{
+	struct sci_clk_provider *provider = data;
+	struct clk_hw *clk;
+	u16 dev_id;
+	u8 clk_id;
+
+	if (clkspec->args_count != 2)
+		return ERR_PTR(-EINVAL);
+
+	mutex_lock(&provider->lock);
+
+	dev_id = clkspec->args[0];
+	clk_id = clkspec->args[1];
+
+	clk = _sci_clk_get(provider, dev_id, clk_id, true);
+
+	mutex_unlock(&provider->lock);
+
+	return clk;
+}
+
+static const struct of_device_id ti_sci_clk_of_match[] = {
+	{ .compatible = "ti,sci-clk" },
+	{ /* Sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, ti_sci_clk_of_match);
+
+/**
+ * ti_sci_clk_parse_flags - Helper function to parse clock flag arrays
+ * @provider: clock provider handle
+ * @list_name: property name containing the clocks list
+ * @flag: flag to apply to the list of clocks
+ *
+ * Parses a DT list based on the provided data, and applies the flag value
+ * for each of the clocks identified by the list. Return 0 for success,
+ * negative error value for failure.
+ */
+static int ti_sci_clk_parse_flags(struct sci_clk_provider *provider,
+				  const char *list_name, u8 flag)
+{
+	int num_clks;
+	int i;
+	struct device_node *np = provider->dev->of_node;
+	struct device *dev = provider->dev;
+
+	num_clks = of_count_phandle_with_args(np, list_name, "#clock-cells");
+
+	for (i = 0; i < num_clks; i++) {
+		struct of_phandle_args clkspec;
+		struct sci_clk *sci_clk;
+		struct clk_hw *clk;
+		int ret;
+
+		ret = of_parse_phandle_with_args(np, list_name, "#clock-cells",
+						 i, &clkspec);
+		if (ret) {
+			dev_err(dev, "Failed to parse %s[%d] = %d\n", list_name,
+				i, ret);
+			return ret;
+		}
+		clk = sci_clk_get(&clkspec, provider);
+		if (IS_ERR(clk)) {
+			dev_err(dev, "clk_get failed for %s[%d] = %ld\n",
+				list_name, i, PTR_ERR(clk));
+			return PTR_ERR(clk);
+		}
+		sci_clk = to_sci_clk(clk);
+
+		sci_clk->flags |= flag;
+	}
+
+	return 0;
+}
+
+/**
+ * ti_sci_clk_probe - Probe function for the TI SCI clock driver
+ * @pdev: platform device pointer to be probed
+ *
+ * Probes the TI SCI clock device. Allocates a new clock provider
+ * and registers this to the common clock framework. Also applies
+ * any required flags to the identified clocks via clock lists
+ * supplied from DT. Returns 0 for success, negative error value
+ * for failure.
+ */
+static int ti_sci_clk_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct sci_clk_provider *provider;
+	const struct ti_sci_handle *handle;
+	int ret;
+
+	if (!np) {
+		dev_err(dev, "OF data missing\n");
+		return -EINVAL;
+	}
+
+	handle = devm_ti_sci_get_handle(dev);
+	if (IS_ERR(handle))
+		return PTR_ERR(handle);
+
+	provider = devm_kzalloc(dev, sizeof(*provider), GFP_KERNEL);
+	if (!provider)
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&provider->clocks);
+	mutex_init(&provider->lock);
+
+	provider->sci = handle;
+	provider->ops = &handle->ops.clk_ops;
+	provider->dev = dev;
+
+	ret = of_clk_add_hw_provider(np, sci_clk_get, provider);
+	if (ret)
+		return ret;
+
+	ti_sci_clk_parse_flags(provider, "ti,ssc-clocks", SCI_CLK_SSC_ENABLE);
+	ti_sci_clk_parse_flags(provider, "ti,allow-freq-change-clocks",
+			       SCI_CLK_ALLOW_FREQ_CHANGE);
+	ti_sci_clk_parse_flags(provider, "ti,input-term-clocks",
+			       SCI_CLK_INPUT_TERMINATION);
+
+	return 0;
+}
+
+/**
+ * ti_sci_clk_remove - Remove TI SCI clock device
+ * @pdev: platform device pointer for the device to be removed
+ *
+ * Removes the TI SCI device. Unregisters the clock provider registered
+ * via common clock framework. Any memory allocated for the device will
+ * be free'd silently via the devm framework. Returns 0 always.
+ */
+static int ti_sci_clk_remove(struct platform_device *pdev)
+{
+	of_clk_del_provider(pdev->dev.of_node);
+
+	return 0;
+}
+
+static struct platform_driver ti_sci_clk_driver = {
+	.probe = ti_sci_clk_probe,
+	.remove = ti_sci_clk_remove,
+	.driver = {
+		.name = "ti-sci-clk",
+		.of_match_table = of_match_ptr(ti_sci_clk_of_match),
+	},
+};
+module_platform_driver(ti_sci_clk_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("TI System Control Interface(SCI) Clock driver");
+MODULE_AUTHOR("Tero Kristo");
+MODULE_ALIAS("platform:ti-sci-clk");
-- 
1.9.1

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

* [PATCHv2 3/3] clk: keystone: Add sci-clk driver support
@ 2016-09-01 12:40     ` Tero Kristo
  0 siblings, 0 replies; 29+ messages in thread
From: Tero Kristo @ 2016-09-01 12:40 UTC (permalink / raw)
  To: linux-arm-kernel

In K2G, the clock handling is done through firmware executing on a
separate core. Linux kernel needs to communicate to the firmware
through TI system control interface to access any power management
related resources, including clocks.

The keystone sci-clk driver does this, by communicating to the
firmware through the TI SCI driver. The driver adds support for
registering clocks through DT, and basic required clock operations
like prepare/get_rate, etc.

Signed-off-by: Tero Kristo <t-kristo@ti.com>
---
 MAINTAINERS                    |   1 +
 drivers/clk/Kconfig            |   9 +
 drivers/clk/keystone/Makefile  |   1 +
 drivers/clk/keystone/sci-clk.c | 537 +++++++++++++++++++++++++++++++++++++++++
 4 files changed, 548 insertions(+)
 create mode 100644 drivers/clk/keystone/sci-clk.c

diff --git a/MAINTAINERS b/MAINTAINERS
index bcb7b9e..2ed4d38 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -11575,6 +11575,7 @@ F:	drivers/firmware/ti_sci*
 F:	include/linux/soc/ti/ti_sci_protocol.h
 F:	Documentation/devicetree/bindings/clock/ti,sci-clk.txt
 F:	include/dt-bindings/clock/k2g.h
+F:	drivers/clk/keystone/sci-clk.c
 
 THANKO'S RAREMONO AM/FM/SW RADIO RECEIVER USB DRIVER
 M:	Hans Verkuil <hverkuil@xs4all.nl>
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index e2d9bd7..dbe792a7 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -179,6 +179,15 @@ config COMMON_CLK_NXP
 	---help---
 	  Support for clock providers on NXP platforms.
 
+config TI_SCI_CLK
+	tristate "TI System Control Interface clock drivers"
+	depends on (TI_SCI_PROTOCOL && COMMON_CLK_KEYSTONE) || COMPILE_TEST
+	default TI_SCI_PROTOCOL
+	---help---
+	  This adds the clock driver support over TI System Control Interface.
+	  If you wish to use clock resources from the PMMC firmware, say Y.
+	  Otherwise, say N.
+
 config COMMON_CLK_PALMAS
 	tristate "Clock driver for TI Palmas devices"
 	depends on MFD_PALMAS
diff --git a/drivers/clk/keystone/Makefile b/drivers/clk/keystone/Makefile
index 0477cf6..0e7993d 100644
--- a/drivers/clk/keystone/Makefile
+++ b/drivers/clk/keystone/Makefile
@@ -1 +1,2 @@
 obj-y			+= pll.o gate.o
+obj-$(CONFIG_TI_SCI_CLK)	+= sci-clk.o
diff --git a/drivers/clk/keystone/sci-clk.c b/drivers/clk/keystone/sci-clk.c
new file mode 100644
index 0000000..852fc49
--- /dev/null
+++ b/drivers/clk/keystone/sci-clk.c
@@ -0,0 +1,537 @@
+/*
+ * SCI Clock driver for keystone based devices
+ *
+ * Copyright (C) 2015-2016 Texas Instruments Incorporated - http://www.ti.com/
+ *	Tero Kristo <t-kristo@ti.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.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of_address.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/soc/ti/ti_sci_protocol.h>
+
+#define SCI_CLK_SSC_ENABLE		BIT(0)
+#define SCI_CLK_ALLOW_FREQ_CHANGE	BIT(1)
+#define SCI_CLK_INPUT_TERMINATION	BIT(2)
+
+/**
+ * struct sci_clk_provider - TI SCI clock provider representation
+ * @sci:    Handle to the System Control Interface protocol handler
+ * @ops:    Pointer to the SCI ops to be used by the clocks
+ * @dev:    Device pointer for the clock provider
+ * @clocks: List of all registered clocks
+ * @lock:   Mutex for locking access to the @clocks list
+ */
+struct sci_clk_provider {
+	const struct ti_sci_handle *sci;
+	const struct ti_sci_clk_ops *ops;
+	struct device *dev;
+	struct list_head clocks;
+	struct mutex lock; /* Protects access to the @clocks list */
+};
+
+/**
+ * struct sci_clk - TI SCI clock representation
+ * @hw:		 Hardware clock cookie for common clock framework
+ * @dev_id:	 Device index
+ * @clk_id:	 Clock index
+ * @node:	 Clocks list link
+ * @provider:	 Master clock provider
+ * @flags:	 Flags for the clock
+ */
+struct sci_clk {
+	struct clk_hw hw;
+	u16 dev_id;
+	u8 clk_id;
+	struct list_head node;
+	struct sci_clk_provider *provider;
+	u8 flags;
+};
+
+#define to_sci_clk(_hw) container_of(_hw, struct sci_clk, hw)
+
+/**
+ * sci_clk_prepare - Prepare (enable) a TI SCI clock
+ * @hw: clock to prepare
+ *
+ * Prepares a clock to be actively used. Returns the SCI protocol status.
+ */
+static int sci_clk_prepare(struct clk_hw *hw)
+{
+	struct sci_clk *clk = to_sci_clk(hw);
+	bool enable_ssc = clk->flags & SCI_CLK_SSC_ENABLE;
+	bool allow_freq_change = clk->flags & SCI_CLK_ALLOW_FREQ_CHANGE;
+	bool input_termination = clk->flags & SCI_CLK_INPUT_TERMINATION;
+
+	return clk->provider->ops->get_clock(clk->provider->sci, clk->dev_id,
+					     clk->clk_id, enable_ssc,
+					     allow_freq_change,
+					     input_termination);
+}
+
+/**
+ * sci_clk_unprepare - Un-prepares (disables) a TI SCI clock
+ * @hw: clock to unprepare
+ *
+ * Un-prepares a clock from active state.
+ */
+static void sci_clk_unprepare(struct clk_hw *hw)
+{
+	struct sci_clk *clk = to_sci_clk(hw);
+	int ret;
+
+	ret = clk->provider->ops->put_clock(clk->provider->sci, clk->dev_id,
+					    clk->clk_id);
+	if (ret)
+		dev_err(clk->provider->dev,
+			"unprepare failed for dev=%d, clk=%d, ret=%d\n",
+			clk->dev_id, clk->clk_id, ret);
+}
+
+/**
+ * sci_clk_is_prepared - Check if a TI SCI clock is prepared or not
+ * @hw: clock to check status for
+ *
+ * Checks if a clock is prepared (enabled) in hardware. Returns non-zero
+ * value if clock is enabled, zero otherwise.
+ */
+static int sci_clk_is_prepared(struct clk_hw *hw)
+{
+	struct sci_clk *clk = to_sci_clk(hw);
+	bool req_state, current_state;
+	int ret;
+
+	ret = clk->provider->ops->is_on(clk->provider->sci, clk->dev_id,
+					clk->clk_id, &req_state,
+					&current_state);
+	if (ret) {
+		dev_err(clk->provider->dev,
+			"is_prepared failed for dev=%d, clk=%d, ret=%d\n",
+			clk->dev_id, clk->clk_id, ret);
+		return 0;
+	}
+
+	return req_state;
+}
+
+/**
+ * sci_clk_recalc_rate - Get clock rate for a TI SCI clock
+ * @hw: clock to get rate for
+ * @parent_rate: parent rate provided by common clock framework, not used
+ *
+ * Gets the current clock rate of a TI SCI clock. Returns the current
+ * clock rate, or zero in failure.
+ */
+static unsigned long sci_clk_recalc_rate(struct clk_hw *hw,
+					 unsigned long parent_rate)
+{
+	struct sci_clk *clk = to_sci_clk(hw);
+	u64 freq;
+	int ret;
+
+	ret = clk->provider->ops->get_freq(clk->provider->sci, clk->dev_id,
+					   clk->clk_id, &freq);
+	if (ret) {
+		dev_err(clk->provider->dev,
+			"recalc-rate failed for dev=%d, clk=%d, ret=%d\n",
+			clk->dev_id, clk->clk_id, ret);
+		return 0;
+	}
+
+	return (u32)freq;
+}
+
+/**
+ * sci_clk_determine_rate - Determines a clock rate a clock can be set to
+ * @hw: clock to change rate for
+ * @req: requested rate configuration for the clock
+ *
+ * Determines a suitable clock rate and parent for a TI SCI clock.
+ * The parent handling is un-used, as generally the parent clock rates
+ * are not known by the kernel; instead these are internally handled
+ * by the firmware. Returns 0 on success, negative error value on failure.
+ */
+static int sci_clk_determine_rate(struct clk_hw *hw,
+				  struct clk_rate_request *req)
+{
+	struct sci_clk *clk = to_sci_clk(hw);
+	int ret;
+	u64 new_rate;
+
+	ret = clk->provider->ops->get_best_match_freq(clk->provider->sci,
+						      clk->dev_id,
+						      clk->clk_id,
+						      req->min_rate,
+						      req->rate,
+						      req->max_rate,
+						      &new_rate);
+	if (ret) {
+		dev_err(clk->provider->dev,
+			"determine-rate failed for dev=%d, clk=%d, ret=%d\n",
+			clk->dev_id, clk->clk_id, ret);
+		return ret;
+	}
+
+	req->rate = new_rate;
+
+	return 0;
+}
+
+/**
+ * sci_clk_set_rate - Set rate for a TI SCI clock
+ * @hw: clock to change rate for
+ * @rate: target rate for the clock
+ * @parent_rate: rate of the clock parent, not used for TI SCI clocks
+ *
+ * Sets a clock frequency for a TI SCI clock. Returns the TI SCI
+ * protocol status.
+ */
+static int sci_clk_set_rate(struct clk_hw *hw, unsigned long rate,
+			    unsigned long parent_rate)
+{
+	struct sci_clk *clk = to_sci_clk(hw);
+
+	return clk->provider->ops->set_freq(clk->provider->sci, clk->dev_id,
+					    clk->clk_id, rate, rate, rate);
+}
+
+/**
+ * sci_clk_get_parent - Get the current parent of a TI SCI clock
+ * @hw: clock to get parent for
+ *
+ * Returns the index of the currently selected parent for a TI SCI clock.
+ */
+static u8 sci_clk_get_parent(struct clk_hw *hw)
+{
+	struct sci_clk *clk = to_sci_clk(hw);
+	u8 parent_id;
+	int ret;
+
+	ret = clk->provider->ops->get_parent(clk->provider->sci, clk->dev_id,
+					     clk->clk_id, &parent_id);
+	if (ret) {
+		dev_err(clk->provider->dev,
+			"get-parent failed for dev=%d, clk=%d, ret=%d\n",
+			clk->dev_id, clk->clk_id, ret);
+		return 0;
+	}
+
+	return parent_id - clk->clk_id - 1;
+}
+
+/**
+ * sci_clk_set_parent - Set the parent of a TI SCI clock
+ * @hw: clock to set parent for
+ * @index: new parent index for the clock
+ *
+ * Sets the parent of a TI SCI clock. Return TI SCI protocol status.
+ */
+static int sci_clk_set_parent(struct clk_hw *hw, u8 index)
+{
+	struct sci_clk *clk = to_sci_clk(hw);
+
+	return clk->provider->ops->set_parent(clk->provider->sci, clk->dev_id,
+					      clk->clk_id,
+					      index + 1 + clk->clk_id);
+}
+
+static const struct clk_ops sci_clk_ops = {
+	.prepare = sci_clk_prepare,
+	.unprepare = sci_clk_unprepare,
+	.is_prepared = sci_clk_is_prepared,
+	.recalc_rate = sci_clk_recalc_rate,
+	.determine_rate = sci_clk_determine_rate,
+	.set_rate = sci_clk_set_rate,
+	.get_parent = sci_clk_get_parent,
+	.set_parent = sci_clk_set_parent,
+};
+
+/**
+ * _sci_clk_get - Gets a handle for an SCI clock
+ * @provider: Handle to SCI clock provider
+ * @dev_id: device ID for the clock to register
+ * @clk_id: clock ID for the clock to register
+ * @parse_parents: indicator whether parents for this clock should be handled
+ *
+ * Gets a handle to an existing TI SCI hw clock, or builds a new clock
+ * entry and registers it with the common clock framework. Called from
+ * the common clock framework, when a corresponding of_clk_get call is
+ * executed, or recursively from itself when parsing parent clocks.
+ * Returns a pointer to the hw clock struct, or ERR_PTR value in failure.
+ */
+static struct clk_hw *_sci_clk_get(struct sci_clk_provider *provider,
+				   u16 dev_id, u8 clk_id, bool parse_parents)
+{
+	struct clk_init_data init = { NULL };
+	struct sci_clk *sci_clk = NULL;
+	char *name = NULL;
+	char **parent_names = NULL;
+	int i;
+	int ret;
+
+	list_for_each_entry(sci_clk, &provider->clocks, node)
+		if (sci_clk->dev_id == dev_id && sci_clk->clk_id == clk_id)
+			return &sci_clk->hw;
+
+	sci_clk = devm_kzalloc(provider->dev, sizeof(*sci_clk), GFP_KERNEL);
+	if (!sci_clk) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	sci_clk->dev_id = dev_id;
+	sci_clk->clk_id = clk_id;
+	sci_clk->provider = provider;
+
+	if (parse_parents) {
+		ret = provider->ops->get_num_parents(provider->sci, dev_id,
+						     clk_id,
+						     &init.num_parents);
+		if (ret)
+			goto err;
+	}
+
+	name = kasprintf(GFP_KERNEL, "%s:%d:%d", dev_name(provider->dev),
+			 sci_clk->dev_id, sci_clk->clk_id);
+
+	init.name = name;
+
+	if (init.num_parents < 2)
+		init.num_parents = 0;
+
+	if (init.num_parents) {
+		parent_names = devm_kcalloc(provider->dev, init.num_parents,
+					    sizeof(char *), GFP_KERNEL);
+
+		if (!parent_names) {
+			ret = -ENOMEM;
+			goto err;
+		}
+
+		for (i = 0; i < init.num_parents; i++) {
+			char *parent_name;
+
+			parent_name = devm_kzalloc(provider->dev, 20,
+						   GFP_KERNEL);
+			if (!parent_name) {
+				ret = -ENOMEM;
+				goto err;
+			}
+			snprintf(parent_name, 20, "%s:%d:%d",
+				 dev_name(provider->dev), sci_clk->dev_id,
+				 sci_clk->clk_id + 1 + i);
+			parent_names[i] = parent_name;
+
+			_sci_clk_get(provider, dev_id, clk_id + 1 + i, false);
+		}
+		init.parent_names = (const char * const *)parent_names;
+	}
+
+	init.ops = &sci_clk_ops;
+	sci_clk->hw.init = &init;
+
+	ret = devm_clk_hw_register(provider->dev, &sci_clk->hw);
+	if (ret) {
+		dev_err(provider->dev, "failed clk register with %d\n", ret);
+		goto err;
+	} else {
+		list_add(&sci_clk->node, &provider->clocks);
+	}
+
+	kfree(name);
+
+	return &sci_clk->hw;
+
+err:
+	if (parent_names) {
+		for (i = 0; i < init.num_parents; i++)
+			devm_kfree(provider->dev, parent_names[i]);
+
+		devm_kfree(provider->dev, parent_names);
+	}
+
+	devm_kfree(provider->dev, sci_clk);
+
+	kfree(name);
+
+	return ERR_PTR(ret);
+}
+
+/**
+ * sci_clk_get - Xlate function for getting clock handles
+ * @clkspec: device tree clock specifier
+ * @data: pointer to the clock provider
+ *
+ * Xlate function for retrieving clock TI SCI hw clock handles based on
+ * device tree clock specifier. Called from the common clock framework,
+ * when a corresponding of_clk_get call is executed. Returns a pointer
+ * to the TI SCI hw clock struct, or ERR_PTR value in failure.
+ */
+static struct clk_hw *sci_clk_get(struct of_phandle_args *clkspec, void *data)
+{
+	struct sci_clk_provider *provider = data;
+	struct clk_hw *clk;
+	u16 dev_id;
+	u8 clk_id;
+
+	if (clkspec->args_count != 2)
+		return ERR_PTR(-EINVAL);
+
+	mutex_lock(&provider->lock);
+
+	dev_id = clkspec->args[0];
+	clk_id = clkspec->args[1];
+
+	clk = _sci_clk_get(provider, dev_id, clk_id, true);
+
+	mutex_unlock(&provider->lock);
+
+	return clk;
+}
+
+static const struct of_device_id ti_sci_clk_of_match[] = {
+	{ .compatible = "ti,sci-clk" },
+	{ /* Sentinel */ },
+};
+MODULE_DEVICE_TABLE(of, ti_sci_clk_of_match);
+
+/**
+ * ti_sci_clk_parse_flags - Helper function to parse clock flag arrays
+ * @provider: clock provider handle
+ * @list_name: property name containing the clocks list
+ * @flag: flag to apply to the list of clocks
+ *
+ * Parses a DT list based on the provided data, and applies the flag value
+ * for each of the clocks identified by the list. Return 0 for success,
+ * negative error value for failure.
+ */
+static int ti_sci_clk_parse_flags(struct sci_clk_provider *provider,
+				  const char *list_name, u8 flag)
+{
+	int num_clks;
+	int i;
+	struct device_node *np = provider->dev->of_node;
+	struct device *dev = provider->dev;
+
+	num_clks = of_count_phandle_with_args(np, list_name, "#clock-cells");
+
+	for (i = 0; i < num_clks; i++) {
+		struct of_phandle_args clkspec;
+		struct sci_clk *sci_clk;
+		struct clk_hw *clk;
+		int ret;
+
+		ret = of_parse_phandle_with_args(np, list_name, "#clock-cells",
+						 i, &clkspec);
+		if (ret) {
+			dev_err(dev, "Failed to parse %s[%d] = %d\n", list_name,
+				i, ret);
+			return ret;
+		}
+		clk = sci_clk_get(&clkspec, provider);
+		if (IS_ERR(clk)) {
+			dev_err(dev, "clk_get failed for %s[%d] = %ld\n",
+				list_name, i, PTR_ERR(clk));
+			return PTR_ERR(clk);
+		}
+		sci_clk = to_sci_clk(clk);
+
+		sci_clk->flags |= flag;
+	}
+
+	return 0;
+}
+
+/**
+ * ti_sci_clk_probe - Probe function for the TI SCI clock driver
+ * @pdev: platform device pointer to be probed
+ *
+ * Probes the TI SCI clock device. Allocates a new clock provider
+ * and registers this to the common clock framework. Also applies
+ * any required flags to the identified clocks via clock lists
+ * supplied from DT. Returns 0 for success, negative error value
+ * for failure.
+ */
+static int ti_sci_clk_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct sci_clk_provider *provider;
+	const struct ti_sci_handle *handle;
+	int ret;
+
+	if (!np) {
+		dev_err(dev, "OF data missing\n");
+		return -EINVAL;
+	}
+
+	handle = devm_ti_sci_get_handle(dev);
+	if (IS_ERR(handle))
+		return PTR_ERR(handle);
+
+	provider = devm_kzalloc(dev, sizeof(*provider), GFP_KERNEL);
+	if (!provider)
+		return -ENOMEM;
+
+	INIT_LIST_HEAD(&provider->clocks);
+	mutex_init(&provider->lock);
+
+	provider->sci = handle;
+	provider->ops = &handle->ops.clk_ops;
+	provider->dev = dev;
+
+	ret = of_clk_add_hw_provider(np, sci_clk_get, provider);
+	if (ret)
+		return ret;
+
+	ti_sci_clk_parse_flags(provider, "ti,ssc-clocks", SCI_CLK_SSC_ENABLE);
+	ti_sci_clk_parse_flags(provider, "ti,allow-freq-change-clocks",
+			       SCI_CLK_ALLOW_FREQ_CHANGE);
+	ti_sci_clk_parse_flags(provider, "ti,input-term-clocks",
+			       SCI_CLK_INPUT_TERMINATION);
+
+	return 0;
+}
+
+/**
+ * ti_sci_clk_remove - Remove TI SCI clock device
+ * @pdev: platform device pointer for the device to be removed
+ *
+ * Removes the TI SCI device. Unregisters the clock provider registered
+ * via common clock framework. Any memory allocated for the device will
+ * be free'd silently via the devm framework. Returns 0 always.
+ */
+static int ti_sci_clk_remove(struct platform_device *pdev)
+{
+	of_clk_del_provider(pdev->dev.of_node);
+
+	return 0;
+}
+
+static struct platform_driver ti_sci_clk_driver = {
+	.probe = ti_sci_clk_probe,
+	.remove = ti_sci_clk_remove,
+	.driver = {
+		.name = "ti-sci-clk",
+		.of_match_table = of_match_ptr(ti_sci_clk_of_match),
+	},
+};
+module_platform_driver(ti_sci_clk_driver);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("TI System Control Interface(SCI) Clock driver");
+MODULE_AUTHOR("Tero Kristo");
+MODULE_ALIAS("platform:ti-sci-clk");
-- 
1.9.1

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

* Re: [PATCHv2 3/3] clk: keystone: Add sci-clk driver support
  2016-09-01 12:40     ` Tero Kristo
  (?)
@ 2016-09-02 23:32         ` Stephen Boyd
  -1 siblings, 0 replies; 29+ messages in thread
From: Stephen Boyd @ 2016-09-02 23:32 UTC (permalink / raw)
  To: Tero Kristo
  Cc: mturquette-rdvid1DuHRBWk0Htik3J/w,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	ssantosh-DgEjT+Ai2ygdnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	nm-l0cyMroinI0

On 09/01, Tero Kristo wrote:
> +
> +/**
> + * _sci_clk_get - Gets a handle for an SCI clock
> + * @provider: Handle to SCI clock provider
> + * @dev_id: device ID for the clock to register
> + * @clk_id: clock ID for the clock to register
> + * @parse_parents: indicator whether parents for this clock should be handled
> + *
> + * Gets a handle to an existing TI SCI hw clock, or builds a new clock
> + * entry and registers it with the common clock framework. Called from
> + * the common clock framework, when a corresponding of_clk_get call is
> + * executed, or recursively from itself when parsing parent clocks.
> + * Returns a pointer to the hw clock struct, or ERR_PTR value in failure.
> + */
> +static struct clk_hw *_sci_clk_get(struct sci_clk_provider *provider,
> +				   u16 dev_id, u8 clk_id, bool parse_parents)

I still don't get it. We should be registering hw pointers in
probe and handing them out in the xlate function. Not register
hws in the xlate function and then handing them out as well. I
haven't reviewed anything else in this patch.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCHv2 3/3] clk: keystone: Add sci-clk driver support
@ 2016-09-02 23:32         ` Stephen Boyd
  0 siblings, 0 replies; 29+ messages in thread
From: Stephen Boyd @ 2016-09-02 23:32 UTC (permalink / raw)
  To: Tero Kristo
  Cc: mturquette, linux-clk, ssantosh, devicetree, linux-arm-kernel, nm

On 09/01, Tero Kristo wrote:
> +
> +/**
> + * _sci_clk_get - Gets a handle for an SCI clock
> + * @provider: Handle to SCI clock provider
> + * @dev_id: device ID for the clock to register
> + * @clk_id: clock ID for the clock to register
> + * @parse_parents: indicator whether parents for this clock should be handled
> + *
> + * Gets a handle to an existing TI SCI hw clock, or builds a new clock
> + * entry and registers it with the common clock framework. Called from
> + * the common clock framework, when a corresponding of_clk_get call is
> + * executed, or recursively from itself when parsing parent clocks.
> + * Returns a pointer to the hw clock struct, or ERR_PTR value in failure.
> + */
> +static struct clk_hw *_sci_clk_get(struct sci_clk_provider *provider,
> +				   u16 dev_id, u8 clk_id, bool parse_parents)

I still don't get it. We should be registering hw pointers in
probe and handing them out in the xlate function. Not register
hws in the xlate function and then handing them out as well. I
haven't reviewed anything else in this patch.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

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

* [PATCHv2 3/3] clk: keystone: Add sci-clk driver support
@ 2016-09-02 23:32         ` Stephen Boyd
  0 siblings, 0 replies; 29+ messages in thread
From: Stephen Boyd @ 2016-09-02 23:32 UTC (permalink / raw)
  To: linux-arm-kernel

On 09/01, Tero Kristo wrote:
> +
> +/**
> + * _sci_clk_get - Gets a handle for an SCI clock
> + * @provider: Handle to SCI clock provider
> + * @dev_id: device ID for the clock to register
> + * @clk_id: clock ID for the clock to register
> + * @parse_parents: indicator whether parents for this clock should be handled
> + *
> + * Gets a handle to an existing TI SCI hw clock, or builds a new clock
> + * entry and registers it with the common clock framework. Called from
> + * the common clock framework, when a corresponding of_clk_get call is
> + * executed, or recursively from itself when parsing parent clocks.
> + * Returns a pointer to the hw clock struct, or ERR_PTR value in failure.
> + */
> +static struct clk_hw *_sci_clk_get(struct sci_clk_provider *provider,
> +				   u16 dev_id, u8 clk_id, bool parse_parents)

I still don't get it. We should be registering hw pointers in
probe and handing them out in the xlate function. Not register
hws in the xlate function and then handing them out as well. I
haven't reviewed anything else in this patch.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

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

* Re: [PATCHv2 3/3] clk: keystone: Add sci-clk driver support
  2016-09-02 23:32         ` Stephen Boyd
  (?)
@ 2016-09-05  7:07           ` Tero Kristo
  -1 siblings, 0 replies; 29+ messages in thread
From: Tero Kristo @ 2016-09-05  7:07 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: mturquette, linux-clk, ssantosh, devicetree, linux-arm-kernel, nm

On 03/09/16 02:32, Stephen Boyd wrote:
> On 09/01, Tero Kristo wrote:
>> +
>> +/**
>> + * _sci_clk_get - Gets a handle for an SCI clock
>> + * @provider: Handle to SCI clock provider
>> + * @dev_id: device ID for the clock to register
>> + * @clk_id: clock ID for the clock to register
>> + * @parse_parents: indicator whether parents for this clock should be handled
>> + *
>> + * Gets a handle to an existing TI SCI hw clock, or builds a new clock
>> + * entry and registers it with the common clock framework. Called from
>> + * the common clock framework, when a corresponding of_clk_get call is
>> + * executed, or recursively from itself when parsing parent clocks.
>> + * Returns a pointer to the hw clock struct, or ERR_PTR value in failure.
>> + */
>> +static struct clk_hw *_sci_clk_get(struct sci_clk_provider *provider,
>> +				   u16 dev_id, u8 clk_id, bool parse_parents)
>
> I still don't get it. We should be registering hw pointers in
> probe and handing them out in the xlate function. Not register
> hws in the xlate function and then handing them out as well. I
> haven't reviewed anything else in this patch.

Ok, let me try to explain the functionality.

Probe time hw pointer registration is only needed for special clocks 
that require extra flags, like adding the spread spectrum flag. There is 
ever going to be only handful of these.

Xlate checks out the sci_clk list, and picks up an existing hw clock if 
it is there. If not, it will create a new one. The reason this is done 
like this, the device IDs / clock IDs don't mean anything to the driver 
itself, the driver just passes these forward to the underlying SCI fwk. 
And, we don't have inherent knowledge of valid device / clock IDs 
either, the SCI fwk returns a failure if a specific clock ID is bad. The 
device / clock IDs are going to be different between different 
generations of SoC also, and in addition there can be holes in the ID 
ranges.

-Tero

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

* Re: [PATCHv2 3/3] clk: keystone: Add sci-clk driver support
@ 2016-09-05  7:07           ` Tero Kristo
  0 siblings, 0 replies; 29+ messages in thread
From: Tero Kristo @ 2016-09-05  7:07 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: mturquette, linux-clk, ssantosh, devicetree, linux-arm-kernel, nm

On 03/09/16 02:32, Stephen Boyd wrote:
> On 09/01, Tero Kristo wrote:
>> +
>> +/**
>> + * _sci_clk_get - Gets a handle for an SCI clock
>> + * @provider: Handle to SCI clock provider
>> + * @dev_id: device ID for the clock to register
>> + * @clk_id: clock ID for the clock to register
>> + * @parse_parents: indicator whether parents for this clock should be handled
>> + *
>> + * Gets a handle to an existing TI SCI hw clock, or builds a new clock
>> + * entry and registers it with the common clock framework. Called from
>> + * the common clock framework, when a corresponding of_clk_get call is
>> + * executed, or recursively from itself when parsing parent clocks.
>> + * Returns a pointer to the hw clock struct, or ERR_PTR value in failure.
>> + */
>> +static struct clk_hw *_sci_clk_get(struct sci_clk_provider *provider,
>> +				   u16 dev_id, u8 clk_id, bool parse_parents)
>
> I still don't get it. We should be registering hw pointers in
> probe and handing them out in the xlate function. Not register
> hws in the xlate function and then handing them out as well. I
> haven't reviewed anything else in this patch.

Ok, let me try to explain the functionality.

Probe time hw pointer registration is only needed for special clocks 
that require extra flags, like adding the spread spectrum flag. There is 
ever going to be only handful of these.

Xlate checks out the sci_clk list, and picks up an existing hw clock if 
it is there. If not, it will create a new one. The reason this is done 
like this, the device IDs / clock IDs don't mean anything to the driver 
itself, the driver just passes these forward to the underlying SCI fwk. 
And, we don't have inherent knowledge of valid device / clock IDs 
either, the SCI fwk returns a failure if a specific clock ID is bad. The 
device / clock IDs are going to be different between different 
generations of SoC also, and in addition there can be holes in the ID 
ranges.

-Tero

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

* [PATCHv2 3/3] clk: keystone: Add sci-clk driver support
@ 2016-09-05  7:07           ` Tero Kristo
  0 siblings, 0 replies; 29+ messages in thread
From: Tero Kristo @ 2016-09-05  7:07 UTC (permalink / raw)
  To: linux-arm-kernel

On 03/09/16 02:32, Stephen Boyd wrote:
> On 09/01, Tero Kristo wrote:
>> +
>> +/**
>> + * _sci_clk_get - Gets a handle for an SCI clock
>> + * @provider: Handle to SCI clock provider
>> + * @dev_id: device ID for the clock to register
>> + * @clk_id: clock ID for the clock to register
>> + * @parse_parents: indicator whether parents for this clock should be handled
>> + *
>> + * Gets a handle to an existing TI SCI hw clock, or builds a new clock
>> + * entry and registers it with the common clock framework. Called from
>> + * the common clock framework, when a corresponding of_clk_get call is
>> + * executed, or recursively from itself when parsing parent clocks.
>> + * Returns a pointer to the hw clock struct, or ERR_PTR value in failure.
>> + */
>> +static struct clk_hw *_sci_clk_get(struct sci_clk_provider *provider,
>> +				   u16 dev_id, u8 clk_id, bool parse_parents)
>
> I still don't get it. We should be registering hw pointers in
> probe and handing them out in the xlate function. Not register
> hws in the xlate function and then handing them out as well. I
> haven't reviewed anything else in this patch.

Ok, let me try to explain the functionality.

Probe time hw pointer registration is only needed for special clocks 
that require extra flags, like adding the spread spectrum flag. There is 
ever going to be only handful of these.

Xlate checks out the sci_clk list, and picks up an existing hw clock if 
it is there. If not, it will create a new one. The reason this is done 
like this, the device IDs / clock IDs don't mean anything to the driver 
itself, the driver just passes these forward to the underlying SCI fwk. 
And, we don't have inherent knowledge of valid device / clock IDs 
either, the SCI fwk returns a failure if a specific clock ID is bad. The 
device / clock IDs are going to be different between different 
generations of SoC also, and in addition there can be holes in the ID 
ranges.

-Tero

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

* Re: [PATCHv2 1/3] Documentation: dt: Add TI SCI clock driver
  2016-09-01 12:40   ` Tero Kristo
  (?)
@ 2016-09-12 13:10       ` Rob Herring
  -1 siblings, 0 replies; 29+ messages in thread
From: Rob Herring @ 2016-09-12 13:10 UTC (permalink / raw)
  To: Tero Kristo
  Cc: sboyd-sgV2jX0FEOL9JmXXK+q4OQ, mturquette-rdvid1DuHRBWk0Htik3J/w,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	ssantosh-DgEjT+Ai2ygdnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	nm-l0cyMroinI0

On Thu, Sep 01, 2016 at 03:40:33PM +0300, Tero Kristo wrote:
> Add a clock implementation, TI SCI clock, that will hook to the common
> clock framework, and allow each clock to be controlled via TI SCI
> protocol.
> 
> Signed-off-by: Tero Kristo <t-kristo-l0cyMroinI0@public.gmane.org>
> Tested-by: Dave Gerlach <d-gerlach-l0cyMroinI0@public.gmane.org>
> Signed-off-by: Nishanth Menon <nm-l0cyMroinI0@public.gmane.org>
> ---
>  .../devicetree/bindings/clock/ti,sci-clk.txt       | 51 ++++++++++++++++++++++
>  MAINTAINERS                                        |  1 +
>  2 files changed, 52 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/ti,sci-clk.txt
> 
> diff --git a/Documentation/devicetree/bindings/clock/ti,sci-clk.txt b/Documentation/devicetree/bindings/clock/ti,sci-clk.txt
> new file mode 100644
> index 0000000..231cb80
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/ti,sci-clk.txt
> @@ -0,0 +1,51 @@
> +Texas Instruments TI-SCI Clocks
> +===============================
> +
> +All clocks on Texas Instruments' SoCs that contain a System Controller,
> +are only controlled by this entity. Communication between a host processor
> +running an OS and the System Controller happens through a protocol known
> +as TI-SCI[1]. This clock implementation plugs into the common clock
> +framework and makes use of the TI-SCI protocol on clock API requests.
> +
> +[1] Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
> +
> +Required properties:
> +-------------------
> +- compatible: Must be "ti,sci-clk"
> +- #clock-cells: Shall be 2.
> +  In clock consumers, this cell represents the device ID and clock ID
> +  exposed by the PM firmware. The assignments can be found in the header
> +  files <dt-bindings/genpd/<soc>.h> (which covers the device IDs) and
> +  <dt-bindings/clock/<soc>.h> (which covers the clock IDs), where <soc>
> +  is the SoC involved, for example 'k2g'.
> +- ti,sci: Phandle to the TI SCI device to use for managing the clocks
> +
> +Optional properties:
> +-------------------
> +- ti,ssc-clocks: Array of phandle clocks that shall enable spread spectrum
> +		 clocking while enabled
> +- ti,allow-freq-change-clocks: Array of phandle clocks that shall allow
> +			       dynamic clock frequency changes by firmware
> +- ti,input-term-clocks: Array of phandle clocks that shall enable input
> +			termination

These seem like a random set of features to control. What determines the 
clocks for these? If it is based on the SoC, then make your compatible 
string SoC specific and don't put this into DT.

Rob
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCHv2 1/3] Documentation: dt: Add TI SCI clock driver
@ 2016-09-12 13:10       ` Rob Herring
  0 siblings, 0 replies; 29+ messages in thread
From: Rob Herring @ 2016-09-12 13:10 UTC (permalink / raw)
  To: Tero Kristo
  Cc: sboyd, mturquette, linux-clk, ssantosh, devicetree, linux-arm-kernel, nm

On Thu, Sep 01, 2016 at 03:40:33PM +0300, Tero Kristo wrote:
> Add a clock implementation, TI SCI clock, that will hook to the common
> clock framework, and allow each clock to be controlled via TI SCI
> protocol.
> 
> Signed-off-by: Tero Kristo <t-kristo@ti.com>
> Tested-by: Dave Gerlach <d-gerlach@ti.com>
> Signed-off-by: Nishanth Menon <nm@ti.com>
> ---
>  .../devicetree/bindings/clock/ti,sci-clk.txt       | 51 ++++++++++++++++++++++
>  MAINTAINERS                                        |  1 +
>  2 files changed, 52 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/ti,sci-clk.txt
> 
> diff --git a/Documentation/devicetree/bindings/clock/ti,sci-clk.txt b/Documentation/devicetree/bindings/clock/ti,sci-clk.txt
> new file mode 100644
> index 0000000..231cb80
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/ti,sci-clk.txt
> @@ -0,0 +1,51 @@
> +Texas Instruments TI-SCI Clocks
> +===============================
> +
> +All clocks on Texas Instruments' SoCs that contain a System Controller,
> +are only controlled by this entity. Communication between a host processor
> +running an OS and the System Controller happens through a protocol known
> +as TI-SCI[1]. This clock implementation plugs into the common clock
> +framework and makes use of the TI-SCI protocol on clock API requests.
> +
> +[1] Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
> +
> +Required properties:
> +-------------------
> +- compatible: Must be "ti,sci-clk"
> +- #clock-cells: Shall be 2.
> +  In clock consumers, this cell represents the device ID and clock ID
> +  exposed by the PM firmware. The assignments can be found in the header
> +  files <dt-bindings/genpd/<soc>.h> (which covers the device IDs) and
> +  <dt-bindings/clock/<soc>.h> (which covers the clock IDs), where <soc>
> +  is the SoC involved, for example 'k2g'.
> +- ti,sci: Phandle to the TI SCI device to use for managing the clocks
> +
> +Optional properties:
> +-------------------
> +- ti,ssc-clocks: Array of phandle clocks that shall enable spread spectrum
> +		 clocking while enabled
> +- ti,allow-freq-change-clocks: Array of phandle clocks that shall allow
> +			       dynamic clock frequency changes by firmware
> +- ti,input-term-clocks: Array of phandle clocks that shall enable input
> +			termination

These seem like a random set of features to control. What determines the 
clocks for these? If it is based on the SoC, then make your compatible 
string SoC specific and don't put this into DT.

Rob

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

* [PATCHv2 1/3] Documentation: dt: Add TI SCI clock driver
@ 2016-09-12 13:10       ` Rob Herring
  0 siblings, 0 replies; 29+ messages in thread
From: Rob Herring @ 2016-09-12 13:10 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Sep 01, 2016 at 03:40:33PM +0300, Tero Kristo wrote:
> Add a clock implementation, TI SCI clock, that will hook to the common
> clock framework, and allow each clock to be controlled via TI SCI
> protocol.
> 
> Signed-off-by: Tero Kristo <t-kristo@ti.com>
> Tested-by: Dave Gerlach <d-gerlach@ti.com>
> Signed-off-by: Nishanth Menon <nm@ti.com>
> ---
>  .../devicetree/bindings/clock/ti,sci-clk.txt       | 51 ++++++++++++++++++++++
>  MAINTAINERS                                        |  1 +
>  2 files changed, 52 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/clock/ti,sci-clk.txt
> 
> diff --git a/Documentation/devicetree/bindings/clock/ti,sci-clk.txt b/Documentation/devicetree/bindings/clock/ti,sci-clk.txt
> new file mode 100644
> index 0000000..231cb80
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/clock/ti,sci-clk.txt
> @@ -0,0 +1,51 @@
> +Texas Instruments TI-SCI Clocks
> +===============================
> +
> +All clocks on Texas Instruments' SoCs that contain a System Controller,
> +are only controlled by this entity. Communication between a host processor
> +running an OS and the System Controller happens through a protocol known
> +as TI-SCI[1]. This clock implementation plugs into the common clock
> +framework and makes use of the TI-SCI protocol on clock API requests.
> +
> +[1] Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
> +
> +Required properties:
> +-------------------
> +- compatible: Must be "ti,sci-clk"
> +- #clock-cells: Shall be 2.
> +  In clock consumers, this cell represents the device ID and clock ID
> +  exposed by the PM firmware. The assignments can be found in the header
> +  files <dt-bindings/genpd/<soc>.h> (which covers the device IDs) and
> +  <dt-bindings/clock/<soc>.h> (which covers the clock IDs), where <soc>
> +  is the SoC involved, for example 'k2g'.
> +- ti,sci: Phandle to the TI SCI device to use for managing the clocks
> +
> +Optional properties:
> +-------------------
> +- ti,ssc-clocks: Array of phandle clocks that shall enable spread spectrum
> +		 clocking while enabled
> +- ti,allow-freq-change-clocks: Array of phandle clocks that shall allow
> +			       dynamic clock frequency changes by firmware
> +- ti,input-term-clocks: Array of phandle clocks that shall enable input
> +			termination

These seem like a random set of features to control. What determines the 
clocks for these? If it is based on the SoC, then make your compatible 
string SoC specific and don't put this into DT.

Rob

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

* Re: [PATCHv2 3/3] clk: keystone: Add sci-clk driver support
  2016-09-05  7:07           ` Tero Kristo
@ 2016-09-16 23:01             ` Stephen Boyd
  -1 siblings, 0 replies; 29+ messages in thread
From: Stephen Boyd @ 2016-09-16 23:01 UTC (permalink / raw)
  To: Tero Kristo
  Cc: mturquette, linux-clk, ssantosh, devicetree, linux-arm-kernel, nm

On 09/05, Tero Kristo wrote:
> On 03/09/16 02:32, Stephen Boyd wrote:
> >I still don't get it. We should be registering hw pointers in
> >probe and handing them out in the xlate function. Not register
> >hws in the xlate function and then handing them out as well. I
> >haven't reviewed anything else in this patch.
> 
> Ok, let me try to explain the functionality.
> 
> Probe time hw pointer registration is only needed for special clocks
> that require extra flags, like adding the spread spectrum flag.
> There is ever going to be only handful of these.
> 
> Xlate checks out the sci_clk list, and picks up an existing hw clock
> if it is there. If not, it will create a new one. The reason this is
> done like this, the device IDs / clock IDs don't mean anything to
> the driver itself, the driver just passes these forward to the
> underlying SCI fwk. And, we don't have inherent knowledge of valid
> device / clock IDs either, the SCI fwk returns a failure if a
> specific clock ID is bad. The device / clock IDs are going to be
> different between different generations of SoC also, and in addition
> there can be holes in the ID ranges.

Ok. Thanks for the explanation.

I understand the desire to make this SoC agnostic and consumer/dt
driven. Constructor pattern and all. Unfortunately the OF clk
provider is a getter pattern; not a constructor pattern. I'm
seriously concerned about the locking here because we're in the
framework creating a clk and tying it into a consumer list which
could cause all sorts of problems if we want to reenter the
framework and register more clks. Recursion abounds and my head
explodes! The recursive clk prepare mutex is not something anyone
should be thrilled about keeping around.

So, just don't do this. Instead, register the clks during probe
that exist for the firmware. That list could be discoverable with
firmware calls, or known based on different compatible strings
from DT that have the soc name in it, or something else. Even
scanning the entire DT tree for

	clocks = <&my_clk_node x y>
	
would be better, but probably hugely inefficient and outright
buggy with DT overlays so don't do it. If the firmware can't tell
us what clks are there, just have a table based on compatible
string and be done.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

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

* [PATCHv2 3/3] clk: keystone: Add sci-clk driver support
@ 2016-09-16 23:01             ` Stephen Boyd
  0 siblings, 0 replies; 29+ messages in thread
From: Stephen Boyd @ 2016-09-16 23:01 UTC (permalink / raw)
  To: linux-arm-kernel

On 09/05, Tero Kristo wrote:
> On 03/09/16 02:32, Stephen Boyd wrote:
> >I still don't get it. We should be registering hw pointers in
> >probe and handing them out in the xlate function. Not register
> >hws in the xlate function and then handing them out as well. I
> >haven't reviewed anything else in this patch.
> 
> Ok, let me try to explain the functionality.
> 
> Probe time hw pointer registration is only needed for special clocks
> that require extra flags, like adding the spread spectrum flag.
> There is ever going to be only handful of these.
> 
> Xlate checks out the sci_clk list, and picks up an existing hw clock
> if it is there. If not, it will create a new one. The reason this is
> done like this, the device IDs / clock IDs don't mean anything to
> the driver itself, the driver just passes these forward to the
> underlying SCI fwk. And, we don't have inherent knowledge of valid
> device / clock IDs either, the SCI fwk returns a failure if a
> specific clock ID is bad. The device / clock IDs are going to be
> different between different generations of SoC also, and in addition
> there can be holes in the ID ranges.

Ok. Thanks for the explanation.

I understand the desire to make this SoC agnostic and consumer/dt
driven. Constructor pattern and all. Unfortunately the OF clk
provider is a getter pattern; not a constructor pattern. I'm
seriously concerned about the locking here because we're in the
framework creating a clk and tying it into a consumer list which
could cause all sorts of problems if we want to reenter the
framework and register more clks. Recursion abounds and my head
explodes! The recursive clk prepare mutex is not something anyone
should be thrilled about keeping around.

So, just don't do this. Instead, register the clks during probe
that exist for the firmware. That list could be discoverable with
firmware calls, or known based on different compatible strings
from DT that have the soc name in it, or something else. Even
scanning the entire DT tree for

	clocks = <&my_clk_node x y>
	
would be better, but probably hugely inefficient and outright
buggy with DT overlays so don't do it. If the firmware can't tell
us what clks are there, just have a table based on compatible
string and be done.

-- 
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project

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

* Re: [PATCHv2 1/3] Documentation: dt: Add TI SCI clock driver
  2016-09-12 13:10       ` Rob Herring
  (?)
@ 2016-09-23  8:04         ` Tero Kristo
  -1 siblings, 0 replies; 29+ messages in thread
From: Tero Kristo @ 2016-09-23  8:04 UTC (permalink / raw)
  To: Rob Herring
  Cc: sboyd-sgV2jX0FEOL9JmXXK+q4OQ, mturquette-rdvid1DuHRBWk0Htik3J/w,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	ssantosh-DgEjT+Ai2ygdnm+yROfE0A,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	nm-l0cyMroinI0

On 12/09/16 16:10, Rob Herring wrote:
> On Thu, Sep 01, 2016 at 03:40:33PM +0300, Tero Kristo wrote:
>> Add a clock implementation, TI SCI clock, that will hook to the common
>> clock framework, and allow each clock to be controlled via TI SCI
>> protocol.
>>
>> Signed-off-by: Tero Kristo <t-kristo-l0cyMroinI0@public.gmane.org>
>> Tested-by: Dave Gerlach <d-gerlach-l0cyMroinI0@public.gmane.org>
>> Signed-off-by: Nishanth Menon <nm-l0cyMroinI0@public.gmane.org>
>> ---
>>  .../devicetree/bindings/clock/ti,sci-clk.txt       | 51 ++++++++++++++++++++++
>>  MAINTAINERS                                        |  1 +
>>  2 files changed, 52 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/clock/ti,sci-clk.txt
>>
>> diff --git a/Documentation/devicetree/bindings/clock/ti,sci-clk.txt b/Documentation/devicetree/bindings/clock/ti,sci-clk.txt
>> new file mode 100644
>> index 0000000..231cb80
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/ti,sci-clk.txt
>> @@ -0,0 +1,51 @@
>> +Texas Instruments TI-SCI Clocks
>> +===============================
>> +
>> +All clocks on Texas Instruments' SoCs that contain a System Controller,
>> +are only controlled by this entity. Communication between a host processor
>> +running an OS and the System Controller happens through a protocol known
>> +as TI-SCI[1]. This clock implementation plugs into the common clock
>> +framework and makes use of the TI-SCI protocol on clock API requests.
>> +
>> +[1] Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
>> +
>> +Required properties:
>> +-------------------
>> +- compatible: Must be "ti,sci-clk"
>> +- #clock-cells: Shall be 2.
>> +  In clock consumers, this cell represents the device ID and clock ID
>> +  exposed by the PM firmware. The assignments can be found in the header
>> +  files <dt-bindings/genpd/<soc>.h> (which covers the device IDs) and
>> +  <dt-bindings/clock/<soc>.h> (which covers the clock IDs), where <soc>
>> +  is the SoC involved, for example 'k2g'.
>> +- ti,sci: Phandle to the TI SCI device to use for managing the clocks
>> +
>> +Optional properties:
>> +-------------------
>> +- ti,ssc-clocks: Array of phandle clocks that shall enable spread spectrum
>> +		 clocking while enabled
>> +- ti,allow-freq-change-clocks: Array of phandle clocks that shall allow
>> +			       dynamic clock frequency changes by firmware
>> +- ti,input-term-clocks: Array of phandle clocks that shall enable input
>> +			termination
>
> These seem like a random set of features to control. What determines the
> clocks for these? If it is based on the SoC, then make your compatible
> string SoC specific and don't put this into DT.

Currently nobody seems to be using these flags, so I will just drop the 
support for these from the next rev. If anybody will need them at some 
point, I will figure out how to support these.

-Tero
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCHv2 1/3] Documentation: dt: Add TI SCI clock driver
@ 2016-09-23  8:04         ` Tero Kristo
  0 siblings, 0 replies; 29+ messages in thread
From: Tero Kristo @ 2016-09-23  8:04 UTC (permalink / raw)
  To: Rob Herring
  Cc: sboyd, mturquette, linux-clk, ssantosh, devicetree, linux-arm-kernel, nm

On 12/09/16 16:10, Rob Herring wrote:
> On Thu, Sep 01, 2016 at 03:40:33PM +0300, Tero Kristo wrote:
>> Add a clock implementation, TI SCI clock, that will hook to the common
>> clock framework, and allow each clock to be controlled via TI SCI
>> protocol.
>>
>> Signed-off-by: Tero Kristo <t-kristo@ti.com>
>> Tested-by: Dave Gerlach <d-gerlach@ti.com>
>> Signed-off-by: Nishanth Menon <nm@ti.com>
>> ---
>>  .../devicetree/bindings/clock/ti,sci-clk.txt       | 51 ++++++++++++++++++++++
>>  MAINTAINERS                                        |  1 +
>>  2 files changed, 52 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/clock/ti,sci-clk.txt
>>
>> diff --git a/Documentation/devicetree/bindings/clock/ti,sci-clk.txt b/Documentation/devicetree/bindings/clock/ti,sci-clk.txt
>> new file mode 100644
>> index 0000000..231cb80
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/ti,sci-clk.txt
>> @@ -0,0 +1,51 @@
>> +Texas Instruments TI-SCI Clocks
>> +===============================
>> +
>> +All clocks on Texas Instruments' SoCs that contain a System Controller,
>> +are only controlled by this entity. Communication between a host processor
>> +running an OS and the System Controller happens through a protocol known
>> +as TI-SCI[1]. This clock implementation plugs into the common clock
>> +framework and makes use of the TI-SCI protocol on clock API requests.
>> +
>> +[1] Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
>> +
>> +Required properties:
>> +-------------------
>> +- compatible: Must be "ti,sci-clk"
>> +- #clock-cells: Shall be 2.
>> +  In clock consumers, this cell represents the device ID and clock ID
>> +  exposed by the PM firmware. The assignments can be found in the header
>> +  files <dt-bindings/genpd/<soc>.h> (which covers the device IDs) and
>> +  <dt-bindings/clock/<soc>.h> (which covers the clock IDs), where <soc>
>> +  is the SoC involved, for example 'k2g'.
>> +- ti,sci: Phandle to the TI SCI device to use for managing the clocks
>> +
>> +Optional properties:
>> +-------------------
>> +- ti,ssc-clocks: Array of phandle clocks that shall enable spread spectrum
>> +		 clocking while enabled
>> +- ti,allow-freq-change-clocks: Array of phandle clocks that shall allow
>> +			       dynamic clock frequency changes by firmware
>> +- ti,input-term-clocks: Array of phandle clocks that shall enable input
>> +			termination
>
> These seem like a random set of features to control. What determines the
> clocks for these? If it is based on the SoC, then make your compatible
> string SoC specific and don't put this into DT.

Currently nobody seems to be using these flags, so I will just drop the 
support for these from the next rev. If anybody will need them at some 
point, I will figure out how to support these.

-Tero

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

* [PATCHv2 1/3] Documentation: dt: Add TI SCI clock driver
@ 2016-09-23  8:04         ` Tero Kristo
  0 siblings, 0 replies; 29+ messages in thread
From: Tero Kristo @ 2016-09-23  8:04 UTC (permalink / raw)
  To: linux-arm-kernel

On 12/09/16 16:10, Rob Herring wrote:
> On Thu, Sep 01, 2016 at 03:40:33PM +0300, Tero Kristo wrote:
>> Add a clock implementation, TI SCI clock, that will hook to the common
>> clock framework, and allow each clock to be controlled via TI SCI
>> protocol.
>>
>> Signed-off-by: Tero Kristo <t-kristo@ti.com>
>> Tested-by: Dave Gerlach <d-gerlach@ti.com>
>> Signed-off-by: Nishanth Menon <nm@ti.com>
>> ---
>>  .../devicetree/bindings/clock/ti,sci-clk.txt       | 51 ++++++++++++++++++++++
>>  MAINTAINERS                                        |  1 +
>>  2 files changed, 52 insertions(+)
>>  create mode 100644 Documentation/devicetree/bindings/clock/ti,sci-clk.txt
>>
>> diff --git a/Documentation/devicetree/bindings/clock/ti,sci-clk.txt b/Documentation/devicetree/bindings/clock/ti,sci-clk.txt
>> new file mode 100644
>> index 0000000..231cb80
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/clock/ti,sci-clk.txt
>> @@ -0,0 +1,51 @@
>> +Texas Instruments TI-SCI Clocks
>> +===============================
>> +
>> +All clocks on Texas Instruments' SoCs that contain a System Controller,
>> +are only controlled by this entity. Communication between a host processor
>> +running an OS and the System Controller happens through a protocol known
>> +as TI-SCI[1]. This clock implementation plugs into the common clock
>> +framework and makes use of the TI-SCI protocol on clock API requests.
>> +
>> +[1] Documentation/devicetree/bindings/arm/keystone/ti,sci.txt
>> +
>> +Required properties:
>> +-------------------
>> +- compatible: Must be "ti,sci-clk"
>> +- #clock-cells: Shall be 2.
>> +  In clock consumers, this cell represents the device ID and clock ID
>> +  exposed by the PM firmware. The assignments can be found in the header
>> +  files <dt-bindings/genpd/<soc>.h> (which covers the device IDs) and
>> +  <dt-bindings/clock/<soc>.h> (which covers the clock IDs), where <soc>
>> +  is the SoC involved, for example 'k2g'.
>> +- ti,sci: Phandle to the TI SCI device to use for managing the clocks
>> +
>> +Optional properties:
>> +-------------------
>> +- ti,ssc-clocks: Array of phandle clocks that shall enable spread spectrum
>> +		 clocking while enabled
>> +- ti,allow-freq-change-clocks: Array of phandle clocks that shall allow
>> +			       dynamic clock frequency changes by firmware
>> +- ti,input-term-clocks: Array of phandle clocks that shall enable input
>> +			termination
>
> These seem like a random set of features to control. What determines the
> clocks for these? If it is based on the SoC, then make your compatible
> string SoC specific and don't put this into DT.

Currently nobody seems to be using these flags, so I will just drop the 
support for these from the next rev. If anybody will need them at some 
point, I will figure out how to support these.

-Tero

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

* Re: [PATCHv2 3/3] clk: keystone: Add sci-clk driver support
  2016-09-16 23:01             ` Stephen Boyd
  (?)
@ 2016-09-23  8:06               ` Tero Kristo
  -1 siblings, 0 replies; 29+ messages in thread
From: Tero Kristo @ 2016-09-23  8:06 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: nm, devicetree, mturquette, ssantosh, linux-clk, linux-arm-kernel

On 17/09/16 02:01, Stephen Boyd wrote:
> On 09/05, Tero Kristo wrote:
>> On 03/09/16 02:32, Stephen Boyd wrote:
>>> I still don't get it. We should be registering hw pointers in
>>> probe and handing them out in the xlate function. Not register
>>> hws in the xlate function and then handing them out as well. I
>>> haven't reviewed anything else in this patch.
>>
>> Ok, let me try to explain the functionality.
>>
>> Probe time hw pointer registration is only needed for special clocks
>> that require extra flags, like adding the spread spectrum flag.
>> There is ever going to be only handful of these.
>>
>> Xlate checks out the sci_clk list, and picks up an existing hw clock
>> if it is there. If not, it will create a new one. The reason this is
>> done like this, the device IDs / clock IDs don't mean anything to
>> the driver itself, the driver just passes these forward to the
>> underlying SCI fwk. And, we don't have inherent knowledge of valid
>> device / clock IDs either, the SCI fwk returns a failure if a
>> specific clock ID is bad. The device / clock IDs are going to be
>> different between different generations of SoC also, and in addition
>> there can be holes in the ID ranges.
>
> Ok. Thanks for the explanation.
>
> I understand the desire to make this SoC agnostic and consumer/dt
> driven. Constructor pattern and all. Unfortunately the OF clk
> provider is a getter pattern; not a constructor pattern. I'm
> seriously concerned about the locking here because we're in the
> framework creating a clk and tying it into a consumer list which
> could cause all sorts of problems if we want to reenter the
> framework and register more clks. Recursion abounds and my head
> explodes! The recursive clk prepare mutex is not something anyone
> should be thrilled about keeping around.
>
> So, just don't do this. Instead, register the clks during probe
> that exist for the firmware. That list could be discoverable with
> firmware calls, or known based on different compatible strings
> from DT that have the soc name in it, or something else. Even
> scanning the entire DT tree for
>
> 	clocks = <&my_clk_node x y>
> 	
> would be better, but probably hugely inefficient and outright
> buggy with DT overlays so don't do it. If the firmware can't tell
> us what clks are there, just have a table based on compatible
> string and be done.

Ok, I will add a static mapping of valid clock IDs within the driver and 
init all of these during probe. I have a working solution for this 
already, but will post it out only once 4.9-rc1 is out.

-Tero

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

* Re: [PATCHv2 3/3] clk: keystone: Add sci-clk driver support
@ 2016-09-23  8:06               ` Tero Kristo
  0 siblings, 0 replies; 29+ messages in thread
From: Tero Kristo @ 2016-09-23  8:06 UTC (permalink / raw)
  To: Stephen Boyd
  Cc: mturquette, linux-clk, ssantosh, devicetree, linux-arm-kernel, nm

On 17/09/16 02:01, Stephen Boyd wrote:
> On 09/05, Tero Kristo wrote:
>> On 03/09/16 02:32, Stephen Boyd wrote:
>>> I still don't get it. We should be registering hw pointers in
>>> probe and handing them out in the xlate function. Not register
>>> hws in the xlate function and then handing them out as well. I
>>> haven't reviewed anything else in this patch.
>>
>> Ok, let me try to explain the functionality.
>>
>> Probe time hw pointer registration is only needed for special clocks
>> that require extra flags, like adding the spread spectrum flag.
>> There is ever going to be only handful of these.
>>
>> Xlate checks out the sci_clk list, and picks up an existing hw clock
>> if it is there. If not, it will create a new one. The reason this is
>> done like this, the device IDs / clock IDs don't mean anything to
>> the driver itself, the driver just passes these forward to the
>> underlying SCI fwk. And, we don't have inherent knowledge of valid
>> device / clock IDs either, the SCI fwk returns a failure if a
>> specific clock ID is bad. The device / clock IDs are going to be
>> different between different generations of SoC also, and in addition
>> there can be holes in the ID ranges.
>
> Ok. Thanks for the explanation.
>
> I understand the desire to make this SoC agnostic and consumer/dt
> driven. Constructor pattern and all. Unfortunately the OF clk
> provider is a getter pattern; not a constructor pattern. I'm
> seriously concerned about the locking here because we're in the
> framework creating a clk and tying it into a consumer list which
> could cause all sorts of problems if we want to reenter the
> framework and register more clks. Recursion abounds and my head
> explodes! The recursive clk prepare mutex is not something anyone
> should be thrilled about keeping around.
>
> So, just don't do this. Instead, register the clks during probe
> that exist for the firmware. That list could be discoverable with
> firmware calls, or known based on different compatible strings
> from DT that have the soc name in it, or something else. Even
> scanning the entire DT tree for
>
> 	clocks = <&my_clk_node x y>
> 	
> would be better, but probably hugely inefficient and outright
> buggy with DT overlays so don't do it. If the firmware can't tell
> us what clks are there, just have a table based on compatible
> string and be done.

Ok, I will add a static mapping of valid clock IDs within the driver and 
init all of these during probe. I have a working solution for this 
already, but will post it out only once 4.9-rc1 is out.

-Tero

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

* [PATCHv2 3/3] clk: keystone: Add sci-clk driver support
@ 2016-09-23  8:06               ` Tero Kristo
  0 siblings, 0 replies; 29+ messages in thread
From: Tero Kristo @ 2016-09-23  8:06 UTC (permalink / raw)
  To: linux-arm-kernel

On 17/09/16 02:01, Stephen Boyd wrote:
> On 09/05, Tero Kristo wrote:
>> On 03/09/16 02:32, Stephen Boyd wrote:
>>> I still don't get it. We should be registering hw pointers in
>>> probe and handing them out in the xlate function. Not register
>>> hws in the xlate function and then handing them out as well. I
>>> haven't reviewed anything else in this patch.
>>
>> Ok, let me try to explain the functionality.
>>
>> Probe time hw pointer registration is only needed for special clocks
>> that require extra flags, like adding the spread spectrum flag.
>> There is ever going to be only handful of these.
>>
>> Xlate checks out the sci_clk list, and picks up an existing hw clock
>> if it is there. If not, it will create a new one. The reason this is
>> done like this, the device IDs / clock IDs don't mean anything to
>> the driver itself, the driver just passes these forward to the
>> underlying SCI fwk. And, we don't have inherent knowledge of valid
>> device / clock IDs either, the SCI fwk returns a failure if a
>> specific clock ID is bad. The device / clock IDs are going to be
>> different between different generations of SoC also, and in addition
>> there can be holes in the ID ranges.
>
> Ok. Thanks for the explanation.
>
> I understand the desire to make this SoC agnostic and consumer/dt
> driven. Constructor pattern and all. Unfortunately the OF clk
> provider is a getter pattern; not a constructor pattern. I'm
> seriously concerned about the locking here because we're in the
> framework creating a clk and tying it into a consumer list which
> could cause all sorts of problems if we want to reenter the
> framework and register more clks. Recursion abounds and my head
> explodes! The recursive clk prepare mutex is not something anyone
> should be thrilled about keeping around.
>
> So, just don't do this. Instead, register the clks during probe
> that exist for the firmware. That list could be discoverable with
> firmware calls, or known based on different compatible strings
> from DT that have the soc name in it, or something else. Even
> scanning the entire DT tree for
>
> 	clocks = <&my_clk_node x y>
> 	
> would be better, but probably hugely inefficient and outright
> buggy with DT overlays so don't do it. If the firmware can't tell
> us what clks are there, just have a table based on compatible
> string and be done.

Ok, I will add a static mapping of valid clock IDs within the driver and 
init all of these during probe. I have a working solution for this 
already, but will post it out only once 4.9-rc1 is out.

-Tero

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

end of thread, other threads:[~2016-09-23  8:06 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-09-01 12:40 [PATCHv2 0/3] ARM: K2G: support for TI-SCI Clocks Tero Kristo
2016-09-01 12:40 ` Tero Kristo
2016-09-01 12:40 ` Tero Kristo
2016-09-01 12:40 ` [PATCHv2 1/3] Documentation: dt: Add TI SCI clock driver Tero Kristo
2016-09-01 12:40   ` Tero Kristo
2016-09-01 12:40   ` Tero Kristo
     [not found]   ` <1472733635-22661-2-git-send-email-t-kristo-l0cyMroinI0@public.gmane.org>
2016-09-12 13:10     ` Rob Herring
2016-09-12 13:10       ` Rob Herring
2016-09-12 13:10       ` Rob Herring
2016-09-23  8:04       ` Tero Kristo
2016-09-23  8:04         ` Tero Kristo
2016-09-23  8:04         ` Tero Kristo
     [not found] ` <1472733635-22661-1-git-send-email-t-kristo-l0cyMroinI0@public.gmane.org>
2016-09-01 12:40   ` [PATCHv2 2/3] dt-binding: clock: Add k2g clock definitions Tero Kristo
2016-09-01 12:40     ` Tero Kristo
2016-09-01 12:40     ` Tero Kristo
2016-09-01 12:40   ` [PATCHv2 3/3] clk: keystone: Add sci-clk driver support Tero Kristo
2016-09-01 12:40     ` Tero Kristo
2016-09-01 12:40     ` Tero Kristo
     [not found]     ` <1472733635-22661-4-git-send-email-t-kristo-l0cyMroinI0@public.gmane.org>
2016-09-02 23:32       ` Stephen Boyd
2016-09-02 23:32         ` Stephen Boyd
2016-09-02 23:32         ` Stephen Boyd
2016-09-05  7:07         ` Tero Kristo
2016-09-05  7:07           ` Tero Kristo
2016-09-05  7:07           ` Tero Kristo
2016-09-16 23:01           ` Stephen Boyd
2016-09-16 23:01             ` Stephen Boyd
2016-09-23  8:06             ` Tero Kristo
2016-09-23  8:06               ` Tero Kristo
2016-09-23  8:06               ` Tero Kristo

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.