devicetree.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/14] Introduce STM32MP1 clock driver
@ 2018-02-02 14:03 gabriel.fernandez-qxv4g6HH51o
  2018-02-02 14:03 ` [PATCH 02/14] dt-bindings: clock: add STM32MP1 clocks gabriel.fernandez
                   ` (6 more replies)
  0 siblings, 7 replies; 22+ messages in thread
From: gabriel.fernandez-qxv4g6HH51o @ 2018-02-02 14:03 UTC (permalink / raw)
  To: Rob Herring, Mark Rutland, Lee Jones, Maxime Coquelin,
	Alexandre Torgue, Michael Turquette, Stephen Boyd,
	Gabriel Fernandez
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	gabriel.fernandez.st-Re5JQEeQqe8AvxtiuMwx3w,
	olivier.bideau-qxv4g6HH51o

From: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>

This patch-set introduces clock driver for STM32MP157 based on Arm Cortex-A7.
The driver patch is splitted in several patches (by kind of clock) to facilitate
code reviewing.

Gabriel Fernandez (14):
  dt-bindings: Document STM32MP1 Reset Clock Controller (RCC) bindings
  dt-bindings: clock: add STM32MP1 clocks
  clk: stm32mp1: Introduce STM32MP1 clock driver
  clk: stm32mp1: add MP1 gate for osc hse/hsi/csi oscillators
  clk: stm32mp1: add Source Clocks for PLLs
  clk: stm32mp1: add PLL clocks
  clk: stm32mp1: add Post-dividers for PLL
  clk: stm32mp1: add Sub System clocks
  clk: stm32mp1: add Kernel timers
  clk: stm32mp1: add Peripheral clocks
  clk: stm32mp1: add Kernel clocks
  clk: stm32mp1: add RTC clock
  clk: stm32mp1: add MCO clocks
  clk: stm32mp1: add Debug clocks

 .../devicetree/bindings/mfd/st,stm32-rcc.txt       |   85 +
 drivers/clk/Kconfig                                |    6 +
 drivers/clk/Makefile                               |    1 +
 drivers/clk/clk-stm32mp1.c                         | 1705 ++++++++++++++++++++
 include/dt-bindings/clock/stm32mp1-clks.h          |  248 +++
 5 files changed, 2045 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
 create mode 100644 drivers/clk/clk-stm32mp1.c
 create mode 100644 include/dt-bindings/clock/stm32mp1-clks.h

-- 
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	[flat|nested] 22+ messages in thread

* [PATCH 01/14] dt-bindings: Document STM32MP1 Reset Clock Controller (RCC) bindings
       [not found] ` <1517580222-23301-1-git-send-email-gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
@ 2018-02-02 14:03   ` gabriel.fernandez-qxv4g6HH51o
  2018-02-05  6:09     ` Rob Herring
  2018-02-02 14:03   ` [PATCH 03/14] clk: stm32mp1: Introduce STM32MP1 clock driver gabriel.fernandez-qxv4g6HH51o
                     ` (6 subsequent siblings)
  7 siblings, 1 reply; 22+ messages in thread
From: gabriel.fernandez-qxv4g6HH51o @ 2018-02-02 14:03 UTC (permalink / raw)
  To: Rob Herring, Mark Rutland, Lee Jones, Maxime Coquelin,
	Alexandre Torgue, Michael Turquette, Stephen Boyd,
	Gabriel Fernandez
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	gabriel.fernandez.st-Re5JQEeQqe8AvxtiuMwx3w,
	olivier.bideau-qxv4g6HH51o

From: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>

The RCC block is responsible of the management of the clock and reset
generation for the complete circuit.

Signed-off-by: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
---
 .../devicetree/bindings/mfd/st,stm32-rcc.txt       | 85 ++++++++++++++++++++++
 1 file changed, 85 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt

diff --git a/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt b/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
new file mode 100644
index 0000000..28017a1
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
@@ -0,0 +1,85 @@
+STMicroelectronics STM32 Peripheral Reset Clock Controller
+==========================================================
+
+The RCC IP is both a reset and a clock controller.
+
+Please also refer to reset.txt for common reset controller binding usage.
+
+Please also refer to clock-bindings.txt for common clock controller
+binding usage.
+
+
+Required properties:
+- compatible: "simple-mfd", "syscon"
+- reg: should be register base and length as documented in the datasheet
+
+- Sub-nodes:
+  - compatible: "st,stm32mp1-rcc-clk"
+	- #clock-cells: 1, device nodes should specify the clock in their
+	  "clocks" property, containing a phandle to the clock device node,
+	  an index specifying the clock to use.
+
+  - compatible: "st,stm32mp1-rcc-rst"
+	- #reset-cells: Shall be 1
+
+Example:
+	rcc: rcc@50000000 {
+		compatible = "syscon", "simple-mfd";
+		reg = <0x50000000 0x1000>;
+
+		rcc_clk: rcc-clk@50000000 {
+			#clock-cells = <1>;
+			compatible = "st,stm32mp1-rcc-clk";
+		};
+
+		rcc_rst: rcc-reset@50000000 {
+			#reset-cells = <1>;
+			compatible = "st,stm32mp1-rcc-rst";
+		};
+	};
+
+Specifying clocks
+=================
+
+All available clocks are defined as preprocessor macros in
+dt-bindings/clock/stm32mp1-clks.h header and can be used in device
+tree sources.
+
+Example:
+
+	/* Accessing DMA1 clock */
+	... {
+		clocks = <&rcc_clk DMA1>
+	};
+
+	/* Accessing SPI6 kernel clock */
+	... {
+		clocks = <&rcc_clk SPI6_K>
+	};
+
+Specifying softreset control of devices
+=======================================
+
+Device nodes should specify the reset channel required in their "resets"
+property, containing a phandle to the reset device node and an index specifying
+which channel to use.
+The index is the bit number within the RCC registers bank, starting from RCC
+base address.
+It is calculated as: index = register_offset / 4 * 32 + bit_offset.
+Where bit_offset is the bit offset within the register.
+
+For example on STM32MP1, for LTDC reset:
+ ltdc = APB4_RSTSETR_offset / 4 * 32 + LTDC_bit_offset
+      = 0x180 / 4 * 32 + 0 = 3072
+
+The list of valid indices for STM32MP1 is available in:
+include/dt-bindings/reset-controller/stm32mp1-resets.h
+
+This file implements defines like:
+#define LTDC_R	3072
+
+example:
+
+	ltdc {
+		resets = <&rcc_rst LTDC_R>;
+	};
-- 
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] 22+ messages in thread

* [PATCH 02/14] dt-bindings: clock: add STM32MP1 clocks
  2018-02-02 14:03 [PATCH 00/14] Introduce STM32MP1 clock driver gabriel.fernandez-qxv4g6HH51o
@ 2018-02-02 14:03 ` gabriel.fernandez
       [not found]   ` <1517580222-23301-3-git-send-email-gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
  2018-02-02 14:03 ` [PATCH 04/14] clk: stm32mp1: add MP1 gate for osc hse/hsi/csi oscillators gabriel.fernandez
                   ` (5 subsequent siblings)
  6 siblings, 1 reply; 22+ messages in thread
From: gabriel.fernandez @ 2018-02-02 14:03 UTC (permalink / raw)
  To: Rob Herring, Mark Rutland, Lee Jones, Maxime Coquelin,
	Alexandre Torgue, Michael Turquette, Stephen Boyd,
	Gabriel Fernandez
  Cc: devicetree, olivier.bideau, linux-kernel, gabriel.fernandez.st,
	linux-clk, linux-arm-kernel

From: Gabriel Fernandez <gabriel.fernandez@st.com>

This patch adds the clock binding entry for STM32MP1

Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
---
 include/dt-bindings/clock/stm32mp1-clks.h | 248 ++++++++++++++++++++++++++++++
 1 file changed, 248 insertions(+)
 create mode 100644 include/dt-bindings/clock/stm32mp1-clks.h

diff --git a/include/dt-bindings/clock/stm32mp1-clks.h b/include/dt-bindings/clock/stm32mp1-clks.h
new file mode 100644
index 0000000..11978f7
--- /dev/null
+++ b/include/dt-bindings/clock/stm32mp1-clks.h
@@ -0,0 +1,248 @@
+/* SPDX-License-Identifier: GPL-2.0 or BSD-3-Clause */
+/*
+ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
+ * Author: Gabriel Fernandez <gabriel.fernandez@st.com> for STMicroelectronics.
+ */
+
+#ifndef _DT_BINDINGS_STM32MP1_CLKS_H_
+#define _DT_BINDINGS_STM32MP1_CLKS_H_
+
+/* OSCILLATOR clocks */
+#define CK_HSE		0
+#define CK_CSI		1
+#define CK_LSI		2
+#define CK_LSE		3
+#define CK_HSI		4
+#define CK_HSE_DIV2	5
+
+/* Bus clocks */
+#define TIM2		6
+#define TIM3		7
+#define TIM4		8
+#define TIM5		9
+#define TIM6		10
+#define TIM7		11
+#define TIM12		12
+#define TIM13		13
+#define TIM14		14
+#define LPTIM1		15
+#define SPI2		16
+#define SPI3		17
+#define USART2		18
+#define USART3		19
+#define UART4		20
+#define UART5		21
+#define UART7		22
+#define UART8		23
+#define I2C1		24
+#define I2C2		25
+#define I2C3		26
+#define I2C5		27
+#define SPDIF		28
+#define CEC		29
+#define DAC12		30
+#define MDIO		31
+#define TIM1		32
+#define TIM8		33
+#define TIM15		34
+#define TIM16		35
+#define TIM17		36
+#define SPI1		37
+#define SPI4		38
+#define SPI5		39
+#define USART6		40
+#define SAI1		41
+#define SAI2		42
+#define SAI3		43
+#define DFSDM		44
+#define FDCAN		45
+#define LPTIM2		46
+#define LPTIM3		47
+#define LPTIM4		48
+#define LPTIM5		49
+#define SAI4		50
+#define SYSCFG		51
+#define VREF		52
+#define TMPSENS		53
+#define PMBCTRL		54
+#define HDP		55
+#define LTDC		56
+#define DSI		57
+#define IWDG2		58
+#define USBPHY		59
+#define STGENRO		60
+#define SPI6		61
+#define I2C4		62
+#define I2C6		63
+#define USART1		64
+#define RTCAPB		65
+#define TZC		66
+#define TZPC		67
+#define IWDG1		68
+#define BSEC		69
+#define STGEN		70
+#define DMA1		71
+#define DMA2		72
+#define DMAMUX		73
+#define ADC12		74
+#define USBO		75
+#define SDMMC3		76
+#define DCMI		77
+#define CRYP2		78
+#define HASH2		79
+#define RNG2		80
+#define CRC2		81
+#define HSEM		82
+#define IPCC		83
+#define GPIOA		84
+#define GPIOB		85
+#define GPIOC		86
+#define GPIOD		87
+#define GPIOE		88
+#define GPIOF		89
+#define GPIOG		90
+#define GPIOH		91
+#define GPIOI		92
+#define GPIOJ		93
+#define GPIOK		94
+#define GPIOZ		95
+#define CRYP1		96
+#define HASH1		97
+#define RNG1		98
+#define BKPSRAM		99
+#define MDMA		100
+#define GPU		102
+#define ETHCK		103
+#define ETHTX		104
+#define ETHRX		105
+#define ETHMAC		106
+#define FMC		107
+#define QSPI		108
+#define SDMMC1		109
+#define SDMMC2		110
+#define CRC1		111
+#define USBH		112
+#define ETHSTP		113
+
+/* Kernel clocks */
+#define SDMMC1_K	114
+#define SDMMC2_K	115
+#define SDMMC3_K	116
+#define FMC_K		117
+#define QSPI_K		118
+#define ETHMAC_K	119
+#define RNG1_K		120
+#define RNG2_K		121
+#define GPU_K		122
+#define USBPHY_K	123
+#define STGEN_K		124
+#define SPDIF_K		125
+#define SPI1_K		126
+#define SPI2_K		127
+#define SPI3_K		128
+#define SPI4_K		129
+#define SPI5_K		130
+#define SPI6_K		131
+#define CEC_K		132
+#define I2C1_K		133
+#define I2C2_K		134
+#define I2C3_K		135
+#define I2C4_K		136
+#define I2C5_K		137
+#define I2C6_K		138
+#define LPTIM1_K	139
+#define LPTIM2_K	140
+#define LPTIM3_K	141
+#define LPTIM4_K	142
+#define LPTIM5_K	143
+#define USART1_K	144
+#define USART2_K	145
+#define USART3_K	146
+#define UART4_K		147
+#define UART5_K		148
+#define USART6_K	149
+#define UART7_K		150
+#define UART8_K		151
+#define DFSDM_K		152
+#define FDCAN_K		153
+#define SAI1_K		154
+#define SAI2_K		155
+#define SAI3_K		156
+#define SAI4_K		157
+#define ADC12_K		158
+#define DSI_K		159
+#define ADFSDM_K	160
+#define USBO_K		161
+#define LTDC_K		162
+
+/* PLL */
+#define PLL1		163
+#define PLL2		164
+#define PLL3		165
+#define PLL4		166
+
+/* ODF */
+#define PLL1_P		167
+#define PLL1_Q		168
+#define PLL1_R		169
+#define PLL2_P		170
+#define PLL2_Q		171
+#define PLL2_R		172
+#define PLL3_P		173
+#define PLL3_Q		174
+#define PLL3_R		175
+#define PLL4_P		176
+#define PLL4_Q		177
+#define PLL4_R		178
+
+/* AUX */
+#define RTC		179
+
+/* MCLK */
+#define CK_PER		180
+#define CK_MPU		181
+#define CK_AXI		182
+#define CK_MCU		183
+
+/* Time base */
+#define TIM2_K		184
+#define TIM3_K		185
+#define TIM4_K		186
+#define TIM5_K		187
+#define TIM6_K		188
+#define TIM7_K		189
+#define TIM12_K		190
+#define TIM13_K		191
+#define TIM14_K		192
+#define TIM1_K		193
+#define TIM8_K		194
+#define TIM15_K		195
+#define TIM16_K		196
+#define TIM17_K		197
+
+/* MCO clocks */
+#define CK_MCO1		198
+#define CK_MCO2		199
+
+/* TRACE & DEBUG clocks */
+#define DBG		200
+#define CK_DBG		201
+#define CK_TRACE	202
+
+/* DDR */
+#define DDRC1		203
+#define DDRC1LP		204
+#define DDRC2		205
+#define DDRC2LP		206
+#define DDRPHYC		207
+#define DDRPHYCLP	208
+#define DDRCAPB		209
+#define DDRCAPBLP	210
+#define AXIDCG		211
+#define DDRPHYCAPB	212
+#define DDRPHYCAPBLP	213
+#define DDRPERFM	214
+
+#define STM32MP1_LAST_CLK 215
+
+#endif /* _DT_BINDINGS_STM32MP1_CLKS_H_ */
-- 
1.9.1

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

* [PATCH 03/14] clk: stm32mp1: Introduce STM32MP1 clock driver
       [not found] ` <1517580222-23301-1-git-send-email-gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
  2018-02-02 14:03   ` [PATCH 01/14] dt-bindings: Document STM32MP1 Reset Clock Controller (RCC) bindings gabriel.fernandez-qxv4g6HH51o
@ 2018-02-02 14:03   ` gabriel.fernandez-qxv4g6HH51o
  2018-02-02 14:03   ` [PATCH 05/14] clk: stm32mp1: add Source Clocks for PLLs gabriel.fernandez-qxv4g6HH51o
                     ` (5 subsequent siblings)
  7 siblings, 0 replies; 22+ messages in thread
From: gabriel.fernandez-qxv4g6HH51o @ 2018-02-02 14:03 UTC (permalink / raw)
  To: Rob Herring, Mark Rutland, Lee Jones, Maxime Coquelin,
	Alexandre Torgue, Michael Turquette, Stephen Boyd,
	Gabriel Fernandez
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	gabriel.fernandez.st-Re5JQEeQqe8AvxtiuMwx3w,
	olivier.bideau-qxv4g6HH51o

From: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>

This patch introduces the mechanism to probe stm32mp1 driver.

It also defines registers and clocks source definition.

This patch also introduces the generic mechanism to register
a clock (a simple gate).

All clocks will be defined in one table.

Signed-off-by: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
---
 drivers/clk/Kconfig        |   6 +
 drivers/clk/Makefile       |   1 +
 drivers/clk/clk-stm32mp1.c | 513 +++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 520 insertions(+)
 create mode 100644 drivers/clk/clk-stm32mp1.c

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 1c4e1aa..517c4b3 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -226,6 +226,12 @@ config COMMON_CLK_VC5
 	  This driver supports the IDT VersaClock 5 and VersaClock 6
 	  programmable clock generators.
 
+config COMMON_CLK_STM32MP157
+	def_bool COMMON_CLK && MACH_STM32MP157
+	help
+	---help---
+	  Support for stm32mp157 SoC family clocks
+
 source "drivers/clk/bcm/Kconfig"
 source "drivers/clk/hisilicon/Kconfig"
 source "drivers/clk/imgtec/Kconfig"
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index f7f761b..69f6f59 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -46,6 +46,7 @@ obj-$(CONFIG_COMMON_CLK_SI514)		+= clk-si514.o
 obj-$(CONFIG_COMMON_CLK_SI570)		+= clk-si570.o
 obj-$(CONFIG_ARCH_STM32)		+= clk-stm32f4.o
 obj-$(CONFIG_ARCH_STM32)		+= clk-stm32h7.o
+obj-$(CONFIG_COMMON_CLK_STM32MP157)	+= clk-stm32mp1.o
 obj-$(CONFIG_ARCH_TANGO)		+= clk-tango4.o
 obj-$(CONFIG_CLK_TWL6040)		+= clk-twl6040.o
 obj-$(CONFIG_ARCH_U300)			+= clk-u300.o
diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
new file mode 100644
index 0000000..6e39e85
--- /dev/null
+++ b/drivers/clk/clk-stm32mp1.c
@@ -0,0 +1,513 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) STMicroelectronics 2018 - All Rights Reserved
+ * Author: Olivier Bideau <olivier.bideau-qxv4g6HH51o@public.gmane.org> for STMicroelectronics.
+ * Author: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org> for STMicroelectronics.
+ */
+
+#include <linux/clk.h>
+#include <linux/clk-provider.h>
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+
+#include <dt-bindings/clock/stm32mp1-clks.h>
+
+static DEFINE_SPINLOCK(rlock);
+
+#define RCC_OCENSETR		0x0C
+#define RCC_OCENCLRR		0x10
+#define RCC_OCRDYR		0x808
+#define RCC_HSICFGR		0x18
+#define RCC_RDLSICR		0x144
+#define RCC_PLL1CR		0x80
+#define RCC_PLL1CFGR1		0x84
+#define RCC_PLL1CFGR2		0x88
+#define RCC_PLL2CR		0x94
+#define RCC_PLL2CFGR1		0x98
+#define RCC_PLL2CFGR2		0x9C
+#define RCC_PLL3CR		0x880
+#define RCC_PLL3CFGR1		0x884
+#define RCC_PLL3CFGR2		0x888
+#define RCC_PLL4CR		0x894
+#define RCC_PLL4CFGR1		0x898
+#define RCC_PLL4CFGR2		0x89C
+#define RCC_APB1ENSETR		0xA00
+#define RCC_APB2ENSETR		0xA08
+#define RCC_APB3ENSETR		0xA10
+#define RCC_APB4ENSETR		0x200
+#define RCC_APB5ENSETR		0x208
+#define RCC_AHB2ENSETR		0xA18
+#define RCC_AHB3ENSETR		0xA20
+#define RCC_AHB4ENSETR		0xA28
+#define RCC_AHB5ENSETR		0x210
+#define RCC_AHB6ENSETR		0x218
+#define RCC_AHB6LPENSETR	0x318
+#define RCC_RCK12SELR		0x28
+#define RCC_RCK3SELR		0x820
+#define RCC_RCK4SELR		0x824
+#define RCC_MPCKSELR		0x20
+#define RCC_ASSCKSELR		0x24
+#define RCC_MSSCKSELR		0x48
+#define RCC_SPI6CKSELR		0xC4
+#define RCC_SDMMC12CKSELR	0x8F4
+#define RCC_SDMMC3CKSELR	0x8F8
+#define RCC_FMCCKSELR		0x904
+#define RCC_I2C4CKSELR		0xC0
+#define RCC_I2C12CKSELR		0x8C0
+#define RCC_I2C35CKSELR		0x8C4
+#define RCC_UART1CKSELR		0xC8
+#define RCC_QSPICKSELR		0x900
+#define RCC_ETHCKSELR		0x8FC
+#define RCC_RNG1CKSELR		0xCC
+#define RCC_RNG2CKSELR		0x920
+#define RCC_GPUCKSELR		0x938
+#define RCC_USBCKSELR		0x91C
+#define RCC_STGENCKSELR		0xD4
+#define RCC_SPDIFCKSELR		0x914
+#define RCC_SPI2S1CKSELR	0x8D8
+#define RCC_SPI2S23CKSELR	0x8DC
+#define RCC_SPI2S45CKSELR	0x8E0
+#define RCC_CECCKSELR		0x918
+#define RCC_LPTIM1CKSELR	0x934
+#define RCC_LPTIM23CKSELR	0x930
+#define RCC_LPTIM45CKSELR	0x92C
+#define RCC_UART24CKSELR	0x8E8
+#define RCC_UART35CKSELR	0x8EC
+#define RCC_UART6CKSELR		0x8E4
+#define RCC_UART78CKSELR	0x8F0
+#define RCC_DFSDMCKSELR		0x910
+#define RCC_FDCANCKSELR		0x90C
+#define RCC_SAI1CKSELR		0x8C8
+#define RCC_SAI2CKSELR		0x8CC
+#define RCC_SAI3CKSELR		0x8D0
+#define RCC_SAI4CKSELR		0x8D4
+#define RCC_ADCCKSELR		0x928
+#define RCC_MPCKDIVR		0x2C
+#define RCC_DSICKSELR		0x924
+#define RCC_CPERCKSELR		0xD0
+#define RCC_GRSTCSETR		0x404
+#define RCC_MCO1CFGR		0x800
+#define RCC_MCO2CFGR		0x804
+#define RCC_BDCR		0x140
+#define RCC_AXIDIVR		0x30
+#define RCC_MCUDIVR		0x830
+#define RCC_APB1DIVR		0x834
+#define RCC_APB2DIVR		0x838
+#define RCC_APB3DIVR		0x83C
+#define RCC_APB4DIVR		0x3C
+#define RCC_APB5DIVR		0x40
+#define RCC_TIMG1PRER		0x828
+#define RCC_TIMG2PRER		0x82C
+#define RCC_RTCDIVR		0x44
+#define RCC_DBGCFGR		0x80C
+
+#define RCC_CLR	0x4
+
+static const char * const ref12_parents[] = {
+	"ck_hsi", "ck_hse"
+};
+
+static const char * const ref3_parents[] = {
+	"ck_hsi", "ck_hse", "ck_csi"
+};
+
+static const char * const ref4_parents[] = {
+	"ck_hsi", "ck_hse", "ck_csi"
+};
+
+static const char * const cpu_src[] = {
+	"ck_hsi", "ck_hse", "pll1_p"
+};
+
+static const char * const axi_src[] = {
+	"ck_hsi", "ck_hse", "pll2_p", "pll3_p"
+};
+
+static const char * const per_src[] = {
+	"ck_hsi", "ck_csi", "ck_hse"
+};
+
+static const char * const mcu_src[] = {
+	"ck_hsi", "ck_hse", "ck_csi", "pll3_p"
+};
+
+static const char * const sdmmc1_src[] = {
+	"ck_axi", "pll3_r", "pll4_p", "ck_hsi"
+};
+
+static const char * const sdmmc2_src[] = {
+	"ck_axi", "pll3_r", "pll4_p", "ck_hsi"
+};
+
+static const char * const sdmmc3_src[] = {
+	"ck_mcu", "pll3_r", "pll4_p", "ck_hsi"
+};
+
+static const char * const fmc_src[] = {
+	"ck_axi", "pll3_r", "pll4_p", "ck_per"
+};
+
+static const char * const qspi_src[] = {
+	"ck_axi", "pll3_r", "pll4_p", "ck_per"
+};
+
+static const char * const eth_src[] = {
+	"pll4_p", "pll3_q"
+};
+
+static const char * const rng_src[] = {
+	"ck_csi", "pll4_r", "ck_lse", "ck_lsi"
+};
+
+static const char * const usbphy_src[] = {
+	"ck_hse", "pll4_r", "clk-hse-div2"
+};
+
+static const char * const usbo_src[] = {
+	"pll4_r", "ck_usbo_48m"
+};
+
+static const char * const stgen_src[] = {
+	"ck_hsi", "ck_hse"
+};
+
+static const char * const spdif_src[] = {
+	"pll4_p", "pll3_q", "ck_hsi"
+};
+
+static const char * const spi1_src[] = {
+	"pll4_p", "pll3_q", "i2s_ckin", "ck_per"
+};
+
+static const char * const spi2_src[] = {
+	"pll4_p", "pll3_q", "i2s_ckin", "ck_per"
+};
+
+static const char * const spi3_src[] = {
+	"pll4_p", "pll3_q", "i2s_ckin", "ck_per"
+};
+
+static const char * const spi4_src[] = {
+	"pclk2", "pll4_q", "ck_hsi", "ck_csi", "ck_hse"
+};
+
+const char * const spi5_src[] = {
+	"pclk2", "pll4_q", "ck_hsi", "ck_csi", "ck_hse"
+};
+
+static const char * const spi6_src[] = {
+	"pclk5", "pll4_q", "ck_hsi", "ck_csi", "ck_hse", "pll3_q"
+};
+
+static const char * const cec_src[] = {
+	"ck_lse", "ck_lsi", "ck_csi"
+};
+
+static const char * const i2c1_src[] = {
+	"pclk1", "pll4_r", "ck_hsi", "ck_csi"
+};
+
+static const char * const i2c2_src[] = {
+	"pclk1", "pll4_r", "ck_hsi", "ck_csi"
+};
+
+static const char * const i2c3_src[] = {
+	"pclk1", "pll4_r", "ck_hsi", "ck_csi"
+};
+
+static const char * const i2c4_src[] = {
+	"pclk5", "pll3_q", "ck_hsi", "ck_csi"
+};
+
+static const char * const i2c5_src[] = {
+	"pclk1", "pll4_r", "ck_hsi", "ck_csi"
+};
+
+static const char * const i2c6_src[] = {
+	"pclk5", "pll3_q", "ck_hsi", "ck_csi"
+};
+
+static const char * const lptim1_src[] = {
+	"pclk1", "pll4_p", "pll3_q", "ck_lse", "ck_lsi", "ck_per"
+};
+
+static const char * const lptim2_src[] = {
+	"pclk3", "pll4_q", "ck_per", "ck_lse", "ck_lsi"
+};
+
+static const char * const lptim3_src[] = {
+	"pclk3", "pll4_q", "ck_per", "ck_lse", "ck_lsi"
+};
+
+static const char * const lptim4_src[] = {
+	"pclk3", "pll4_p", "pll3_q", "ck_lse", "ck_lsi", "ck_per"
+};
+
+static const char * const lptim5_src[] = {
+	"pclk3", "pll4_p", "pll3_q", "ck_lse", "ck_lsi", "ck_per"
+};
+
+static const char * const usart1_src[] = {
+	"pclk5", "pll3_q", "ck_hsi", "ck_csi", "pll4_q", "ck_hse"
+};
+
+const char * const usart2_src[] = {
+	"pclk1", "pll4_q", "ck_hsi", "ck_csi", "ck_hse"
+};
+
+static const char * const usart3_src[] = {
+	"pclk1", "pll4_q", "ck_hsi", "ck_csi", "ck_hse"
+};
+
+static const char * const uart4_src[] = {
+	"pclk1", "pll4_q", "ck_hsi", "ck_csi", "ck_hse"
+};
+
+static const char * const uart5_src[] = {
+	"pclk1", "pll4_q", "ck_hsi", "ck_csi", "ck_hse"
+};
+
+static const char * const usart6_src[] = {
+	"pclk2", "pll4_q", "ck_hsi", "ck_csi", "ck_hse"
+};
+
+static const char * const uart7_src[] = {
+	"pclk1", "pll4_q", "ck_hsi", "ck_csi", "ck_hse"
+};
+
+static const char * const uart8_src[] = {
+	"pclk1", "pll4_q", "ck_hsi", "ck_csi", "ck_hse"
+};
+
+static const char * const adfsdm_src[] = {
+	"pll4_q", "pll3_q", "i2s_ckin", "ck_per"
+};
+
+static const char * const dfsdm_src[] = {
+	"pclk2", "ck_mcu"
+};
+
+static const char * const fdcan_src[] = {
+	"ck_hse", "pll3_q", "pll4_q"
+};
+
+static const char * const sai_src[] = {
+	"pll4_q", "pll3_q", "i2s_ckin", "ck_per"
+};
+
+static const char * const sai2_src[] = {
+	"pll4_q", "pll3_q", "i2s_ckin", "ck_per", "spdif_ck_symb"
+};
+
+static const char * const adc12_src[] = {
+	"pll4_q", "ck_per"
+};
+
+static const char * const dsi_src[] = {
+	"ck_dsi_phy", "pll4_p"
+};
+
+static const char * const rtc_src[] = {
+	"off", "ck_lse", "ck_lsi", "ck_hse_rtc"
+};
+
+static const char * const ltdc_src[] = {
+	"pll4_q"
+};
+
+static const char * const ck_trace_src[] = {
+	"ck_axi"
+};
+
+static const char * const mco1_src[] = {
+	"ck_hsi", "ck_hse", "ck_csi", "ck_lsi", "ck_lse"
+};
+
+static const char * const mco2_src[] = {
+	"ck_mpu", "ck_axi", "ck_mcu", "pll4_p", "ck_hse", "ck_hsi"
+};
+
+struct clock_config {
+	u32 id;
+	const char *name;
+	union {
+		const char *parent_name;
+		const char * const *parent_names;
+	};
+	int num_parents;
+	unsigned long flags;
+	void *cfg;
+	struct clk_hw * (*func)(struct device *dev,
+				struct clk_hw_onecell_data *clk_data,
+				void __iomem *base, spinlock_t *lock,
+				const struct clock_config *cfg);
+};
+
+#define NO_ID ~0
+
+struct gate_cfg {
+	u32 reg_off;
+	u8 bit_idx;
+	u8 gate_flags;
+};
+
+static struct clk_hw *
+_clk_hw_register_gate(struct device *dev,
+		      struct clk_hw_onecell_data *clk_data,
+		      void __iomem *base, spinlock_t *lock,
+		      const struct clock_config *cfg)
+{
+	struct gate_cfg *gate_cfg = cfg->cfg;
+
+	return clk_hw_register_gate(dev,
+				    cfg->name,
+				    cfg->parent_name,
+				    cfg->flags,
+				    gate_cfg->reg_off + base,
+				    gate_cfg->bit_idx,
+				    gate_cfg->gate_flags,
+				    lock);
+}
+
+#define GATE(_id, _name, _parent, _flags, _offset, _bit_idx, _gate_flags)\
+{\
+	.id		= _id,\
+	.name		= _name,\
+	.parent_name	= _parent,\
+	.flags		= _flags,\
+	.cfg		=  &(struct gate_cfg) {\
+		.reg_off	= _offset,\
+		.bit_idx	= _bit_idx,\
+		.gate_flags	= _gate_flags,\
+	},\
+	.func		= _clk_hw_register_gate,\
+}
+
+static const struct clock_config stm32mp1_clock_cfg[] = {
+	/*  External / Internal Oscillators */
+	GATE(CK_LSI, "ck_lsi", "clk-lsi", 0, RCC_RDLSICR, 0, 0),
+	GATE(CK_LSE, "ck_lse", "clk-lse", 0, RCC_BDCR, 0, 0),
+};
+
+struct stm32_clock_match_data {
+	const struct clock_config *cfg;
+	unsigned int num;
+	unsigned int maxbinding;
+};
+
+static struct stm32_clock_match_data stm32mp1_data = {
+	.cfg		= stm32mp1_clock_cfg,
+	.num		= ARRAY_SIZE(stm32mp1_clock_cfg),
+	.maxbinding	= STM32MP1_LAST_CLK,
+};
+
+static const struct of_device_id stm32mp1_match_data[] = {
+	{
+		.compatible = "st,stm32mp1-rcc-clk",
+		.data = &stm32mp1_data,
+	},
+	{ }
+};
+
+static int stm32_register_hw_clk(struct device *dev,
+				 struct clk_hw_onecell_data *clk_data,
+				 void __iomem *base, spinlock_t *lock,
+				 const struct clock_config *cfg)
+{
+	static struct clk_hw **hws;
+	struct clk_hw *hw = ERR_PTR(-ENOENT);
+
+	hws = clk_data->hws;
+
+	if (cfg->func)
+		hw = (*cfg->func)(dev, clk_data, base, lock, cfg);
+
+	if (IS_ERR(hw)) {
+		pr_err("Unable to register %s\n", cfg->name);
+		return  PTR_ERR(hw);
+	}
+
+	if (cfg->id != NO_ID)
+		hws[cfg->id] = hw;
+
+	return 0;
+}
+
+static int stm32_rcc_init(struct device_node *np,
+			  void __iomem *base,
+			  const struct of_device_id *match_data)
+{
+	struct clk_hw_onecell_data *clk_data;
+	struct clk_hw **hws;
+	const struct of_device_id *match;
+	const struct stm32_clock_match_data *data;
+	int err, n, max_binding;
+
+	match = of_match_node(match_data, np);
+	if (!match) {
+		pr_err("%s: match data not found\n", __func__);
+		return -ENODEV;
+	}
+
+	data = match->data;
+
+	max_binding =  data->maxbinding;
+
+	clk_data = kzalloc(sizeof(*clk_data) +
+				  sizeof(*clk_data->hws) * max_binding,
+				  GFP_KERNEL);
+	if (!clk_data)
+		return -ENOMEM;
+
+	clk_data->num = max_binding;
+
+	hws = clk_data->hws;
+
+	for (n = 0; n < max_binding; n++)
+		hws[n] = ERR_PTR(-ENOENT);
+
+	for (n = 0; n < data->num; n++) {
+		err = stm32_register_hw_clk(NULL, clk_data, base, &rlock,
+					    &data->cfg[n]);
+		if (err) {
+			pr_err("%s: can't register  %s\n", __func__,
+			       data->cfg[n].name);
+
+			kfree(clk_data);
+
+			return err;
+		}
+	}
+
+	return of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
+}
+
+static void stm32mp1_rcc_init(struct device_node *np)
+{
+	struct device_node *parent;
+	void __iomem *base;
+
+	parent = of_get_parent(np);
+	if (!parent) {
+		pr_err("%s: parent should be syscon node\n", __func__);
+		return;
+	}
+
+	base = of_iomap(parent, 0);
+	if (!base) {
+		pr_err("%s: unable to map resource", parent->name);
+		of_node_put(parent);
+		return;
+	}
+
+	if (stm32_rcc_init(np, base, stm32mp1_match_data)) {
+		iounmap(base);
+		of_node_put(parent);
+	}
+}
+
+CLK_OF_DECLARE(stm32mp1_rcc, "st,stm32mp1-rcc-clk", stm32mp1_rcc_init);
-- 
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] 22+ messages in thread

* [PATCH 04/14] clk: stm32mp1: add MP1 gate for osc hse/hsi/csi oscillators
  2018-02-02 14:03 [PATCH 00/14] Introduce STM32MP1 clock driver gabriel.fernandez-qxv4g6HH51o
  2018-02-02 14:03 ` [PATCH 02/14] dt-bindings: clock: add STM32MP1 clocks gabriel.fernandez
@ 2018-02-02 14:03 ` gabriel.fernandez
       [not found] ` <1517580222-23301-1-git-send-email-gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 22+ messages in thread
From: gabriel.fernandez @ 2018-02-02 14:03 UTC (permalink / raw)
  To: Rob Herring, Mark Rutland, Lee Jones, Maxime Coquelin,
	Alexandre Torgue, Michael Turquette, Stephen Boyd,
	Gabriel Fernandez
  Cc: devicetree, olivier.bideau, linux-kernel, gabriel.fernandez.st,
	linux-clk, linux-arm-kernel

From: Gabriel Fernandez <gabriel.fernandez@st.com>

MP1 Gate is a gate with a set and a clear register.
This patch also introduces divider and fixed factor clocks.

Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
---
 drivers/clk/clk-stm32mp1.c | 186 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 186 insertions(+)

diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
index 6e39e85..be5a4e5 100644
--- a/drivers/clk/clk-stm32mp1.c
+++ b/drivers/clk/clk-stm32mp1.c
@@ -355,6 +355,19 @@ struct gate_cfg {
 	u8 gate_flags;
 };
 
+struct fixed_factor_cfg {
+	unsigned int mult;
+	unsigned int div;
+};
+
+struct div_cfg {
+	u32 reg_off;
+	u8 shift;
+	u8 width;
+	u8 div_flags;
+	const struct clk_div_table *table;
+};
+
 static struct clk_hw *
 _clk_hw_register_gate(struct device *dev,
 		      struct clk_hw_onecell_data *clk_data,
@@ -373,6 +386,122 @@ struct gate_cfg {
 				    lock);
 }
 
+static struct clk_hw *
+_clk_hw_register_fixed_factor(struct device *dev,
+			      struct clk_hw_onecell_data *clk_data,
+			      void __iomem *base, spinlock_t *lock,
+			      const struct clock_config *cfg)
+{
+	struct fixed_factor_cfg *ff_cfg = cfg->cfg;
+
+	return clk_hw_register_fixed_factor(dev, cfg->name, cfg->parent_name,
+					    cfg->flags, ff_cfg->mult,
+					    ff_cfg->div);
+}
+
+static struct clk_hw *
+_clk_hw_register_divider_table(struct device *dev,
+			       struct clk_hw_onecell_data *clk_data,
+			       void __iomem *base, spinlock_t *lock,
+			       const struct clock_config *cfg)
+{
+	struct div_cfg *div_cfg = cfg->cfg;
+
+	return clk_hw_register_divider_table(dev,
+					     cfg->name,
+					     cfg->parent_name,
+					     cfg->flags,
+					     div_cfg->reg_off + base,
+					     div_cfg->shift,
+					     div_cfg->width,
+					     div_cfg->div_flags,
+					     div_cfg->table,
+					     lock);
+}
+
+/* MP1 Gate clock with set & clear registers */
+
+static int mp1_gate_clk_enable(struct clk_hw *hw)
+{
+	if (!clk_gate_ops.is_enabled(hw))
+		clk_gate_ops.enable(hw);
+
+	return 0;
+}
+
+static void mp1_gate_clk_disable(struct clk_hw *hw)
+{
+	struct clk_gate *gate = to_clk_gate(hw);
+	unsigned long flags = 0;
+
+	if (clk_gate_ops.is_enabled(hw)) {
+		spin_lock_irqsave(gate->lock, flags);
+		writel_relaxed(BIT(gate->bit_idx), gate->reg + RCC_CLR);
+		spin_unlock_irqrestore(gate->lock, flags);
+	}
+}
+
+const struct clk_ops mp1_gate_clk_ops = {
+	.enable		= mp1_gate_clk_enable,
+	.disable	= mp1_gate_clk_disable,
+	.is_enabled	= clk_gate_is_enabled,
+};
+
+static struct clk_hw *clk_register_mp1_gate(struct device *dev,
+					    const char *name,
+					    const char *parent_name,
+					    unsigned long flags,
+					    void __iomem *reg, u8 bit_idx,
+					    u8 clk_gate_flags, spinlock_t *lock)
+{
+	struct clk_init_data init = { NULL };
+	struct clk_gate *gate;
+	int ret;
+	struct clk_hw *hw;
+
+	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+	if (!gate)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &mp1_gate_clk_ops;
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+	init.flags = flags;
+
+	gate->reg = reg;
+	gate->bit_idx = bit_idx;
+	gate->lock = lock;
+
+	gate->hw.init = &init;
+	hw = &gate->hw;
+
+	ret = clk_hw_register(dev, hw);
+	if (ret) {
+		kfree(gate);
+		hw = ERR_PTR(ret);
+	}
+	return hw;
+}
+
+static struct clk_hw *
+_clk_register_mp1_gate(struct device *dev,
+		       struct clk_hw_onecell_data *clk_data,
+		       void __iomem *base, spinlock_t *lock,
+		       const struct clock_config *cfg)
+{
+	struct gate_cfg *gate_cfg = cfg->cfg;
+
+	return clk_register_mp1_gate(dev,
+				     cfg->name,
+				     cfg->parent_name,
+				     cfg->flags,
+				     gate_cfg->reg_off + base,
+				     gate_cfg->bit_idx,
+				     gate_cfg->gate_flags,
+				     lock);
+}
+
 #define GATE(_id, _name, _parent, _flags, _offset, _bit_idx, _gate_flags)\
 {\
 	.id		= _id,\
@@ -387,10 +516,67 @@ struct gate_cfg {
 	.func		= _clk_hw_register_gate,\
 }
 
+#define FIXED_FACTOR(_id, _name, _parent, _flags, _mult, _div)\
+{\
+	.id		= _id,\
+	.name		= _name,\
+	.parent_name	= _parent,\
+	.flags		= _flags,\
+	.cfg		=  &(struct fixed_factor_cfg) {\
+		.mult = _mult,\
+		.div = _div,\
+	},\
+	.func		= _clk_hw_register_fixed_factor,\
+}
+
+#define DIV_TABLE(_id, _name, _parent, _flags, _offset, _shift, _width,\
+		  _div_flags, _div_table)\
+{\
+	.id		= _id,\
+	.name		= _name,\
+	.parent_name	= _parent,\
+	.flags		= _flags,\
+	.cfg		=  &(struct div_cfg) {\
+		.reg_off	= _offset,\
+		.shift		= _shift,\
+		.width		= _width,\
+		.div_flags	= _div_flags,\
+		.table		= _div_table,\
+	},\
+	.func		= _clk_hw_register_divider_table,\
+}
+
+#define DIV(_id, _name, _parent, _flags, _offset, _shift, _width, _div_flags)\
+	DIV_TABLE(_id, _name, _parent, _flags, _offset, _shift, _width,\
+		  _div_flags, NULL)
+
+#define MP1_GATE(_id, _name, _parent, _flags, _offset, _bit_idx, _gate_flags)\
+{\
+	.id		= _id,\
+	.name		= _name,\
+	.parent_name	= _parent,\
+	.flags		= _flags,\
+	.cfg		=  &(struct gate_cfg) {\
+		.reg_off	= _offset,\
+		.bit_idx	= _bit_idx,\
+		.gate_flags	= _gate_flags,\
+	},\
+	.func		= _clk_register_mp1_gate,\
+}
+
 static const struct clock_config stm32mp1_clock_cfg[] = {
+	/* Oscillator divider */
+	DIV(NO_ID, "clk-hsi-div", "clk-hsi", 0, RCC_HSICFGR, 0, 2,
+	    CLK_DIVIDER_READ_ONLY),
+
 	/*  External / Internal Oscillators */
+	MP1_GATE(CK_HSE, "ck_hse", "clk-hse", 0, RCC_OCENSETR, 8, 0),
+	MP1_GATE(CK_CSI, "ck_csi", "clk-csi", 0, RCC_OCENSETR, 4, 0),
+	MP1_GATE(CK_HSI, "ck_hsi", "clk-hsi-div", 0, RCC_OCENSETR, 0, 0),
 	GATE(CK_LSI, "ck_lsi", "clk-lsi", 0, RCC_RDLSICR, 0, 0),
 	GATE(CK_LSE, "ck_lse", "clk-lse", 0, RCC_BDCR, 0, 0),
+
+	FIXED_FACTOR(CK_HSE_DIV2, "clk-hse-div2", "ck_hse", 0, 1, 2),
 };
 
 struct stm32_clock_match_data {
-- 
1.9.1

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

* [PATCH 05/14] clk: stm32mp1: add Source Clocks for PLLs
       [not found] ` <1517580222-23301-1-git-send-email-gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
  2018-02-02 14:03   ` [PATCH 01/14] dt-bindings: Document STM32MP1 Reset Clock Controller (RCC) bindings gabriel.fernandez-qxv4g6HH51o
  2018-02-02 14:03   ` [PATCH 03/14] clk: stm32mp1: Introduce STM32MP1 clock driver gabriel.fernandez-qxv4g6HH51o
@ 2018-02-02 14:03   ` gabriel.fernandez-qxv4g6HH51o
  2018-02-02 14:03   ` [PATCH 06/14] clk: stm32mp1: add PLL clocks gabriel.fernandez-qxv4g6HH51o
                     ` (4 subsequent siblings)
  7 siblings, 0 replies; 22+ messages in thread
From: gabriel.fernandez-qxv4g6HH51o @ 2018-02-02 14:03 UTC (permalink / raw)
  To: Rob Herring, Mark Rutland, Lee Jones, Maxime Coquelin,
	Alexandre Torgue, Michael Turquette, Stephen Boyd,
	Gabriel Fernandez
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	gabriel.fernandez.st-Re5JQEeQqe8AvxtiuMwx3w,
	olivier.bideau-qxv4g6HH51o

From: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>

This patch adds source clocks for PLLs
This patch also introduces MUX clock API.

Signed-off-by: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
---
 drivers/clk/clk-stm32mp1.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 48 insertions(+)

diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
index be5a4e5..1c9a84a 100644
--- a/drivers/clk/clk-stm32mp1.c
+++ b/drivers/clk/clk-stm32mp1.c
@@ -368,6 +368,14 @@ struct div_cfg {
 	const struct clk_div_table *table;
 };
 
+struct mux_cfg {
+	u32 reg_off;
+	u8 shift;
+	u8 width;
+	u8 mux_flags;
+	u32 *table;
+};
+
 static struct clk_hw *
 _clk_hw_register_gate(struct device *dev,
 		      struct clk_hw_onecell_data *clk_data,
@@ -419,6 +427,20 @@ struct div_cfg {
 					     lock);
 }
 
+static struct clk_hw *
+_clk_hw_register_mux(struct device *dev,
+		     struct clk_hw_onecell_data *clk_data,
+		     void __iomem *base, spinlock_t *lock,
+		     const struct clock_config *cfg)
+{
+	struct mux_cfg *mux_cfg = cfg->cfg;
+
+	return clk_hw_register_mux(dev, cfg->name, cfg->parent_names,
+				   cfg->num_parents, cfg->flags,
+				   mux_cfg->reg_off + base, mux_cfg->shift,
+				   mux_cfg->width, mux_cfg->mux_flags, lock);
+}
+
 /* MP1 Gate clock with set & clear registers */
 
 static int mp1_gate_clk_enable(struct clk_hw *hw)
@@ -550,6 +572,22 @@ static struct clk_hw *clk_register_mp1_gate(struct device *dev,
 	DIV_TABLE(_id, _name, _parent, _flags, _offset, _shift, _width,\
 		  _div_flags, NULL)
 
+#define MUX(_id, _name, _parents, _flags, _offset, _shift, _width, _mux_flags)\
+{\
+	.id		= _id,\
+	.name		= _name,\
+	.parent_names	= _parents,\
+	.num_parents	= ARRAY_SIZE(_parents),\
+	.flags		= _flags,\
+	.cfg		=  &(struct mux_cfg) {\
+		.reg_off	= _offset,\
+		.shift		= _shift,\
+		.width		= _width,\
+		.mux_flags	= _mux_flags,\
+	},\
+	.func		= _clk_hw_register_mux,\
+}
+
 #define MP1_GATE(_id, _name, _parent, _flags, _offset, _bit_idx, _gate_flags)\
 {\
 	.id		= _id,\
@@ -577,6 +615,16 @@ static struct clk_hw *clk_register_mp1_gate(struct device *dev,
 	GATE(CK_LSE, "ck_lse", "clk-lse", 0, RCC_BDCR, 0, 0),
 
 	FIXED_FACTOR(CK_HSE_DIV2, "clk-hse-div2", "ck_hse", 0, 1, 2),
+
+	/* ref clock pll */
+	MUX(NO_ID, "ref1", ref12_parents, CLK_OPS_PARENT_ENABLE, RCC_RCK12SELR,
+	    0, 2, CLK_MUX_READ_ONLY),
+
+	MUX(NO_ID, "ref3", ref3_parents, CLK_OPS_PARENT_ENABLE, RCC_RCK3SELR,
+	    0, 2, CLK_MUX_READ_ONLY),
+
+	MUX(NO_ID, "ref4", ref4_parents, CLK_OPS_PARENT_ENABLE, RCC_RCK4SELR,
+	    0, 2, CLK_MUX_READ_ONLY),
 };
 
 struct stm32_clock_match_data {
-- 
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] 22+ messages in thread

* [PATCH 06/14] clk: stm32mp1: add PLL clocks
       [not found] ` <1517580222-23301-1-git-send-email-gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
                     ` (2 preceding siblings ...)
  2018-02-02 14:03   ` [PATCH 05/14] clk: stm32mp1: add Source Clocks for PLLs gabriel.fernandez-qxv4g6HH51o
@ 2018-02-02 14:03   ` gabriel.fernandez-qxv4g6HH51o
  2018-02-02 14:03   ` [PATCH 07/14] clk: stm32mp1: add Post-dividers for PLL gabriel.fernandez-qxv4g6HH51o
                     ` (3 subsequent siblings)
  7 siblings, 0 replies; 22+ messages in thread
From: gabriel.fernandez-qxv4g6HH51o @ 2018-02-02 14:03 UTC (permalink / raw)
  To: Rob Herring, Mark Rutland, Lee Jones, Maxime Coquelin,
	Alexandre Torgue, Michael Turquette, Stephen Boyd,
	Gabriel Fernandez
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	gabriel.fernandez.st-Re5JQEeQqe8AvxtiuMwx3w,
	olivier.bideau-qxv4g6HH51o

From: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>

STMP32MP1 has 4 PLLs.
PLL supports integer and fractional mode.
Each PLL has 3 output dividers (p, q, r)

Signed-off-by: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
---
 drivers/clk/clk-stm32mp1.c | 209 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 209 insertions(+)

diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
index 1c9a84a..33f0d09 100644
--- a/drivers/clk/clk-stm32mp1.c
+++ b/drivers/clk/clk-stm32mp1.c
@@ -7,6 +7,7 @@
 
 #include <linux/clk.h>
 #include <linux/clk-provider.h>
+#include <linux/delay.h>
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/of.h>
@@ -506,6 +507,181 @@ static struct clk_hw *clk_register_mp1_gate(struct device *dev,
 	return hw;
 }
 
+/* STM32 PLL */
+
+struct stm32_pll_obj {
+	/* lock pll enable/disable registers */
+	spinlock_t *lock;
+	void __iomem *reg;
+	struct clk_hw hw;
+};
+
+#define to_pll(_hw) container_of(_hw, struct stm32_pll_obj, hw)
+
+#define PLL_ON		BIT(0)
+#define PLL_RDY		BIT(1)
+#define DIVN_MASK	0x1FF
+#define DIVM_MASK	0x3F
+#define DIVM_SHIFT	16
+#define DIVN_SHIFT	0
+#define FRAC_OFFSET	0xC
+#define FRAC_MASK	0x1FFF
+#define FRAC_SHIFT	3
+#define FRACLE		BIT(16)
+
+static int __pll_is_enabled(struct clk_hw *hw)
+{
+	struct stm32_pll_obj *clk_elem = to_pll(hw);
+
+	return readl_relaxed(clk_elem->reg) & PLL_ON;
+}
+
+#define TIMEOUT 5
+
+static int pll_enable(struct clk_hw *hw)
+{
+	struct stm32_pll_obj *clk_elem = to_pll(hw);
+	u32 reg;
+	unsigned long flags = 0;
+	unsigned int timeout = TIMEOUT;
+	int bit_status = 0;
+
+	spin_lock_irqsave(clk_elem->lock, flags);
+
+	if (__pll_is_enabled(hw))
+		goto unlock;
+
+	reg = readl_relaxed(clk_elem->reg);
+	reg |= PLL_ON;
+	writel_relaxed(reg, clk_elem->reg);
+
+	/* We can't use readl_poll_timeout() because we can be blocked if
+	 * someone enables this clock before clocksource changes.
+	 * Only jiffies counter is available. Jiffies are incremented by
+	 * interruptions and enable op does not allow to be interrupted.
+	 */
+	do {
+		bit_status = !(readl_relaxed(clk_elem->reg) & PLL_RDY);
+
+		if (bit_status)
+			udelay(120);
+
+	} while (bit_status && --timeout);
+
+unlock:
+	spin_unlock_irqrestore(clk_elem->lock, flags);
+
+	return bit_status;
+}
+
+static void pll_disable(struct clk_hw *hw)
+{
+	struct stm32_pll_obj *clk_elem = to_pll(hw);
+	u32 reg;
+	unsigned long flags = 0;
+
+	spin_lock_irqsave(clk_elem->lock, flags);
+
+	reg = readl_relaxed(clk_elem->reg);
+	reg &= ~PLL_ON;
+	writel_relaxed(reg, clk_elem->reg);
+
+	spin_unlock_irqrestore(clk_elem->lock, flags);
+}
+
+static u32 pll_frac_val(struct clk_hw *hw)
+{
+	struct stm32_pll_obj *clk_elem = to_pll(hw);
+	u32 reg, frac = 0;
+
+	reg = readl_relaxed(clk_elem->reg + FRAC_OFFSET);
+	if (reg & FRACLE)
+		frac = (reg >> FRAC_SHIFT) & FRAC_MASK;
+
+	return frac;
+}
+
+static unsigned long pll_recalc_rate(struct clk_hw *hw,
+				     unsigned long parent_rate)
+{
+	struct stm32_pll_obj *clk_elem = to_pll(hw);
+	u32 reg;
+	u32 frac, divm, divn;
+	u64 rate, rate_frac = 0;
+
+	reg = readl_relaxed(clk_elem->reg + 4);
+
+	divm = ((reg >> DIVM_SHIFT) & DIVM_MASK) + 1;
+	divn = ((reg >> DIVN_SHIFT) & DIVN_MASK) + 1;
+	rate = (u64)parent_rate * divn;
+
+	do_div(rate, divm);
+
+	frac = pll_frac_val(hw);
+	if (frac) {
+		rate_frac = (u64)parent_rate * (u64)frac;
+		do_div(rate_frac, (divm * 8192));
+	}
+
+	return rate + rate_frac;
+}
+
+static int pll_is_enabled(struct clk_hw *hw)
+{
+	struct stm32_pll_obj *clk_elem = to_pll(hw);
+	unsigned long flags = 0;
+	int ret;
+
+	spin_lock_irqsave(clk_elem->lock, flags);
+	ret = __pll_is_enabled(hw);
+	spin_unlock_irqrestore(clk_elem->lock, flags);
+
+	return ret;
+}
+
+static const struct clk_ops pll_ops = {
+	.enable = pll_enable,
+	.disable = pll_disable,
+	.recalc_rate = pll_recalc_rate,
+	.is_enabled = pll_is_enabled,
+};
+
+static struct clk_hw *clk_register_pll(struct device *dev, const char *name,
+				       const char *parent_name,
+				       void __iomem *reg,
+				       unsigned long flags,
+				       spinlock_t *lock)
+{
+	struct stm32_pll_obj *element;
+	struct clk_init_data init;
+	struct clk_hw *hw;
+	int err;
+
+	element = kzalloc(sizeof(*element), GFP_KERNEL);
+	if (!element)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &pll_ops;
+	init.flags = flags;
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+
+	element->hw.init = &init;
+	element->reg = reg;
+	element->lock = lock;
+
+	hw = &element->hw;
+	err = clk_hw_register(dev, hw);
+
+	if (err) {
+		kfree(element);
+		return ERR_PTR(err);
+	}
+
+	return hw;
+}
+
 static struct clk_hw *
 _clk_register_mp1_gate(struct device *dev,
 		       struct clk_hw_onecell_data *clk_data,
@@ -524,6 +700,21 @@ static struct clk_hw *clk_register_mp1_gate(struct device *dev,
 				     lock);
 }
 
+struct stm32_pll_cfg {
+	u32 offset;
+};
+
+struct clk_hw *_clk_register_pll(struct device *dev,
+				 struct clk_hw_onecell_data *clk_data,
+				 void __iomem *base, spinlock_t *lock,
+				 const struct clock_config *cfg)
+{
+	struct stm32_pll_cfg *stm_pll_cfg = cfg->cfg;
+
+	return clk_register_pll(dev, cfg->name, cfg->parent_name,
+				base + stm_pll_cfg->offset, cfg->flags, lock);
+}
+
 #define GATE(_id, _name, _parent, _flags, _offset, _bit_idx, _gate_flags)\
 {\
 	.id		= _id,\
@@ -602,6 +793,18 @@ static struct clk_hw *clk_register_mp1_gate(struct device *dev,
 	.func		= _clk_register_mp1_gate,\
 }
 
+#define PLL(_id, _name, _parent, _flags, _offset)\
+{\
+	.id		= _id,\
+	.name		= _name,\
+	.parent_name	= _parent,\
+	.flags		= _flags,\
+	.cfg		=  &(struct stm32_pll_cfg) {\
+		.offset = _offset,\
+	},\
+	.func		= _clk_register_pll,\
+}
+
 static const struct clock_config stm32mp1_clock_cfg[] = {
 	/* Oscillator divider */
 	DIV(NO_ID, "clk-hsi-div", "clk-hsi", 0, RCC_HSICFGR, 0, 2,
@@ -625,6 +828,12 @@ static struct clk_hw *clk_register_mp1_gate(struct device *dev,
 
 	MUX(NO_ID, "ref4", ref4_parents, CLK_OPS_PARENT_ENABLE, RCC_RCK4SELR,
 	    0, 2, CLK_MUX_READ_ONLY),
+
+	/* PLLs */
+	PLL(PLL1, "pll1", "ref1", CLK_IGNORE_UNUSED, RCC_PLL1CR),
+	PLL(PLL2, "pll2", "ref1", CLK_IGNORE_UNUSED, RCC_PLL2CR),
+	PLL(PLL3, "pll3", "ref3", CLK_IGNORE_UNUSED, RCC_PLL3CR),
+	PLL(PLL4, "pll4", "ref4", CLK_IGNORE_UNUSED, RCC_PLL4CR),
 };
 
 struct stm32_clock_match_data {
-- 
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] 22+ messages in thread

* [PATCH 07/14] clk: stm32mp1: add Post-dividers for PLL
       [not found] ` <1517580222-23301-1-git-send-email-gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
                     ` (3 preceding siblings ...)
  2018-02-02 14:03   ` [PATCH 06/14] clk: stm32mp1: add PLL clocks gabriel.fernandez-qxv4g6HH51o
@ 2018-02-02 14:03   ` gabriel.fernandez-qxv4g6HH51o
  2018-02-02 14:03   ` [PATCH 08/14] clk: stm32mp1: add Sub System clocks gabriel.fernandez-qxv4g6HH51o
                     ` (2 subsequent siblings)
  7 siblings, 0 replies; 22+ messages in thread
From: gabriel.fernandez-qxv4g6HH51o @ 2018-02-02 14:03 UTC (permalink / raw)
  To: Rob Herring, Mark Rutland, Lee Jones, Maxime Coquelin,
	Alexandre Torgue, Michael Turquette, Stephen Boyd,
	Gabriel Fernandez
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	gabriel.fernandez.st-Re5JQEeQqe8AvxtiuMwx3w,
	olivier.bideau-qxv4g6HH51o

From: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>

Each PLL has 3 outputs with post-dividers.

pll1_p is dedicated for Cortex-A7
pll1_q is not connected
pll1_r is not connected

pll2_p is dedicated for AXI
pll2_q is dedicated for GPU
pll2_r is dedicated for DDR

pll3_p is dedicated for mcu
pll3_q is for Peripheral Kernel Clock
pll3_r is for Peripheral Kernel Clock

pll4_p is for Peripheral Kernel Clock
pll4_q is for Peripheral Kernel Clock
pll4_r is for Peripheral Kernel Clock

Signed-off-by: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
---
 drivers/clk/clk-stm32mp1.c | 257 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 257 insertions(+)

diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
index 33f0d09..15cd488 100644
--- a/drivers/clk/clk-stm32mp1.c
+++ b/drivers/clk/clk-stm32mp1.c
@@ -377,6 +377,147 @@ struct mux_cfg {
 	u32 *table;
 };
 
+/* STM32 Composite clock */
+struct composite_cfg {
+	struct gate_cfg	*gate;
+	struct mux_cfg	*mux;
+	struct div_cfg	*div;
+	const struct clk_ops *mux_ops;
+	const struct clk_ops *div_ops;
+	const struct clk_ops *gate_ops;
+};
+
+static struct clk_mux *_get_cmux(void __iomem *reg, u8 shift, u8 width,
+				 u32 flags, u32 *table, spinlock_t *lock)
+{
+	struct clk_mux *mux;
+
+	mux = kzalloc(sizeof(*mux), GFP_KERNEL);
+	if (!mux)
+		return ERR_PTR(-ENOMEM);
+
+	mux->reg = reg;
+	mux->shift = shift;
+	mux->mask = (1 << width) - 1;
+	mux->flags = flags;
+	mux->lock = lock;
+	mux->table = table;
+
+	return mux;
+}
+
+static struct clk_divider *_get_cdiv(void __iomem *reg, u8 shift, u8 width,
+				     u32 flags,
+				     const struct clk_div_table *table,
+				     spinlock_t *lock)
+{
+	struct clk_divider *div;
+
+	div = kzalloc(sizeof(*div), GFP_KERNEL);
+
+	if (!div)
+		return ERR_PTR(-ENOMEM);
+
+	div->reg = reg;
+	div->shift = shift;
+	div->width = width;
+	div->flags = flags;
+	div->lock = lock;
+	div->table = table;
+
+	return div;
+}
+
+static struct clk_gate *_get_cgate(void __iomem *reg, u8 bit_idx, u32 flags,
+				   spinlock_t *lock)
+{
+	struct  clk_gate *gate;
+
+	gate = kzalloc(sizeof(*gate), GFP_KERNEL);
+	if (!gate)
+		return ERR_PTR(-ENOMEM);
+
+	gate->reg = reg;
+	gate->bit_idx = bit_idx;
+	gate->flags = flags;
+	gate->lock = lock;
+
+	return gate;
+}
+
+static struct clk_hw *
+clk_stm_register_composite(struct device *dev,
+			   const char *name, const char * const *parent_names,
+			   int num_parents, void __iomem *base,
+			   const struct composite_cfg *cfg,
+			   unsigned long flags, spinlock_t *lock)
+{
+	struct clk_mux *mux = NULL;
+	struct clk_divider *div = NULL;
+	struct clk_gate *gate = NULL;
+	const struct clk_ops *mux_ops, *div_ops, *gate_ops;
+	struct clk_hw *hw;
+	struct clk_hw *mux_hw;
+	struct clk_hw *div_hw;
+	struct clk_hw *gate_hw;
+
+	mux_hw = NULL;
+	div_hw = NULL;
+	gate_hw = NULL;
+	mux_ops = NULL;
+	div_ops = NULL;
+	gate_ops = NULL;
+
+	if (cfg->mux) {
+		mux = _get_cmux(base + cfg->mux->reg_off,
+				cfg->mux->shift,
+				cfg->mux->width,
+				cfg->mux->mux_flags,
+				cfg->mux->table,
+				lock);
+
+		if (!IS_ERR(mux)) {
+			mux_hw = &mux->hw;
+			mux_ops = cfg->mux_ops ?
+				  cfg->mux_ops : &clk_mux_ops;
+		}
+	}
+
+	if (cfg->div) {
+		div = _get_cdiv(base + cfg->div->reg_off,
+				cfg->div->shift,
+				cfg->div->width,
+				cfg->div->div_flags,
+				cfg->div->table,
+				lock);
+
+		if (!IS_ERR(div)) {
+			div_hw = &div->hw;
+			div_ops = cfg->div_ops ?
+				  cfg->div_ops : &clk_divider_ops;
+		}
+	}
+
+	if (cfg->gate) {
+		gate = _get_cgate(base + cfg->gate->reg_off,
+				  cfg->gate->bit_idx,
+				  cfg->gate->gate_flags,
+				  lock);
+
+		if (!IS_ERR(gate)) {
+			gate_hw = &gate->hw;
+			gate_ops = cfg->gate_ops ?
+				   cfg->gate_ops : &clk_gate_ops;
+		}
+	}
+
+	hw = clk_hw_register_composite(dev, name, parent_names, num_parents,
+				       mux_hw, mux_ops, div_hw, div_ops,
+				       gate_hw, gate_ops, flags);
+
+	return hw;
+}
+
 static struct clk_hw *
 _clk_hw_register_gate(struct device *dev,
 		      struct clk_hw_onecell_data *clk_data,
@@ -442,6 +583,17 @@ struct mux_cfg {
 				   mux_cfg->width, mux_cfg->mux_flags, lock);
 }
 
+static struct clk_hw *
+_clk_stm_register_composite(struct device *dev,
+			    struct clk_hw_onecell_data *clk_data,
+			    void __iomem *base, spinlock_t *lock,
+			    const struct clock_config *cfg)
+{
+	return clk_stm_register_composite(dev, cfg->name, cfg->parent_names,
+					  cfg->num_parents, base, cfg->cfg,
+					  cfg->flags, lock);
+}
+
 /* MP1 Gate clock with set & clear registers */
 
 static int mp1_gate_clk_enable(struct clk_hw *hw)
@@ -779,6 +931,76 @@ struct clk_hw *_clk_register_pll(struct device *dev,
 	.func		= _clk_hw_register_mux,\
 }
 
+#define COMPOSITE(_id, _name, _parents, _flags, _cfg)\
+{\
+	.id		= _id,\
+	.name		= _name,\
+	.parent_names	= _parents,\
+	.num_parents	= ARRAY_SIZE(_parents),\
+	.flags		= _flags,\
+	.cfg		= &(struct composite_cfg)_cfg,\
+	.func		= _clk_stm_register_composite,\
+}
+
+#define PARENT(_parent) ((const char *[]) { _parent})
+
+#define _NO_MUX .mux = NULL, .mux_ops = NULL
+#define _NO_DIV .div = NULL, .div_ops = NULL
+#define _NO_GATE .gate = NULL, .gate_ops = NULL
+
+#define _GATE_OPS(_offset, _bit_idx, _gate_flags, _gate_ops) \
+		  .gate = &(struct gate_cfg) {\
+			.reg_off	= _offset,\
+			.bit_idx	= _bit_idx,\
+		 },\
+		 .gate_ops = _gate_ops
+
+#define _GATE(_offset, _bit_idx, _gate_flags)\
+	_GATE_OPS(_offset, _bit_idx, _gate_flags, NULL)
+
+#define _DIV_TABLE_OPS(_offset, _shift, _width, _div_flags, _div_table,\
+		       _div_ops)\
+	.div = &(struct div_cfg) {\
+		.reg_off	= _offset,\
+		.shift		= _shift,\
+		.width		= _width,\
+		.div_flags	= _div_flags,\
+		.table		= _div_table,\
+	},\
+	.div_ops = _div_ops
+
+#define _DIV_TABLE(_offset, _shift, _width, _div_flags, _div_table)\
+		   _DIV_TABLE_OPS(_offset, _shift, _width, _div_flags,\
+				  _div_table, NULL)
+
+#define _DIV_OPS(_offset, _shift, _width, _div_flags, _div_ops)\
+	_DIV_TABLE_OPS(_offset, _shift, _width, _div_flags, NULL, _div_ops)
+
+#define _DIV(_offset, _shift, _width, _div_flags)\
+	_DIV_OPS(_offset, _shift, _width, _div_flags, NULL)
+
+#define _MUX(_offset, _shift, _width, _mux_flags)\
+	.mux = &(struct mux_cfg) {\
+		.reg_off	= _offset,\
+		.shift		= _shift,\
+		.width		= _width,\
+		.mux_flags	= _mux_flags,\
+		.table		= NULL,\
+	},\
+	.mux_ops = NULL
+
+#define _GATEDIV(_gate_offset,\
+		 _bit_idx,\
+		 _div_offset,\
+		 _div_shift,\
+		 _div_width,\
+		 _div_table)\
+{\
+	_DIV_TABLE(_div_offset, _div_shift, _div_width, 0, _div_table),\
+	_GATE(_gate_offset, _bit_idx, 0),\
+	_NO_MUX,\
+}
+
 #define MP1_GATE(_id, _name, _parent, _flags, _offset, _bit_idx, _gate_flags)\
 {\
 	.id		= _id,\
@@ -834,6 +1056,41 @@ struct clk_hw *_clk_register_pll(struct device *dev,
 	PLL(PLL2, "pll2", "ref1", CLK_IGNORE_UNUSED, RCC_PLL2CR),
 	PLL(PLL3, "pll3", "ref3", CLK_IGNORE_UNUSED, RCC_PLL3CR),
 	PLL(PLL4, "pll4", "ref4", CLK_IGNORE_UNUSED, RCC_PLL4CR),
+
+	/* ODF */
+	COMPOSITE(PLL1_P, "pll1_p", PARENT("pll1"), 0,
+		  _GATEDIV(RCC_PLL1CR, 4,
+			   RCC_PLL1CFGR2, 0, 7, NULL)),
+
+	COMPOSITE(PLL2_P, "pll2_p", PARENT("pll2"), 0,
+		  _GATEDIV(RCC_PLL2CR, 4,
+			   RCC_PLL2CFGR2, 0, 7, NULL)),
+	COMPOSITE(PLL2_Q, "pll2_q", PARENT("pll2"), 0,
+		  _GATEDIV(RCC_PLL2CR, 5,
+			   RCC_PLL2CFGR2, 8, 7, NULL)),
+	COMPOSITE(PLL2_R, "pll2_r", PARENT("pll2"), CLK_IS_CRITICAL,
+		  _GATEDIV(RCC_PLL2CR, 6,
+			   RCC_PLL2CFGR2, 16, 7, NULL)),
+
+	COMPOSITE(PLL3_P, "pll3_p", PARENT("pll3"), 0,
+		  _GATEDIV(RCC_PLL3CR, 4,
+			   RCC_PLL3CFGR2, 0, 7, NULL)),
+	COMPOSITE(PLL3_Q, "pll3_q", PARENT("pll3"), 0,
+		  _GATEDIV(RCC_PLL3CR, 5,
+			   RCC_PLL3CFGR2, 8, 7, NULL)),
+	COMPOSITE(PLL3_R, "pll3_r", PARENT("pll3"), 0,
+		  _GATEDIV(RCC_PLL3CR, 6,
+			   RCC_PLL3CFGR2, 16, 7, NULL)),
+
+	COMPOSITE(PLL4_P, "pll4_p", PARENT("pll4"), 0,
+		  _GATEDIV(RCC_PLL4CR, 4,
+			   RCC_PLL4CFGR2, 0, 7, NULL)),
+	COMPOSITE(PLL4_Q, "pll4_q", PARENT("pll4"), 0,
+		  _GATEDIV(RCC_PLL4CR, 5,
+			   RCC_PLL4CFGR2, 8, 7, NULL)),
+	COMPOSITE(PLL4_R, "pll4_r", PARENT("pll4"), 0,
+		  _GATEDIV(RCC_PLL4CR, 6,
+			   RCC_PLL4CFGR2, 16, 7, NULL)),
 };
 
 struct stm32_clock_match_data {
-- 
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] 22+ messages in thread

* [PATCH 08/14] clk: stm32mp1: add Sub System clocks
       [not found] ` <1517580222-23301-1-git-send-email-gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
                     ` (4 preceding siblings ...)
  2018-02-02 14:03   ` [PATCH 07/14] clk: stm32mp1: add Post-dividers for PLL gabriel.fernandez-qxv4g6HH51o
@ 2018-02-02 14:03   ` gabriel.fernandez-qxv4g6HH51o
  2018-02-02 14:03   ` [PATCH 11/14] clk: stm32mp1: add Kernel clocks gabriel.fernandez-qxv4g6HH51o
  2018-02-02 14:03   ` [PATCH 12/14] clk: stm32mp1: add RTC clock gabriel.fernandez-qxv4g6HH51o
  7 siblings, 0 replies; 22+ messages in thread
From: gabriel.fernandez-qxv4g6HH51o @ 2018-02-02 14:03 UTC (permalink / raw)
  To: Rob Herring, Mark Rutland, Lee Jones, Maxime Coquelin,
	Alexandre Torgue, Michael Turquette, Stephen Boyd,
	Gabriel Fernandez
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	gabriel.fernandez.st-Re5JQEeQqe8AvxtiuMwx3w,
	olivier.bideau-qxv4g6HH51o

From: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>

The RCC handles three sub-system clocks: ck_mpuss, ck_axiss and ck_mcuss.
This patch adds also some MUX system and several prescalers.

Signed-off-by: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
---
 drivers/clk/clk-stm32mp1.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 61 insertions(+)

diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
index 15cd488..d85c619 100644
--- a/drivers/clk/clk-stm32mp1.c
+++ b/drivers/clk/clk-stm32mp1.c
@@ -332,6 +332,26 @@
 	"ck_mpu", "ck_axi", "ck_mcu", "pll4_p", "ck_hse", "ck_hsi"
 };
 
+static const struct clk_div_table axi_div_table[] = {
+	{ 0, 1 }, { 1, 2 }, { 2, 3 }, { 3, 4 },
+	{ 4, 4 }, { 5, 4 }, { 6, 4 }, { 7, 4 },
+	{ 0 },
+};
+
+static const struct clk_div_table mcu_div_table[] = {
+	{ 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 },
+	{ 4, 16 }, { 5, 32 }, { 6, 64 }, { 7, 128 },
+	{ 8, 512 }, { 9, 512 }, { 10, 512}, { 11, 512 },
+	{ 12, 512 }, { 13, 512 }, { 14, 512}, { 15, 512 },
+	{ 0 },
+};
+
+static const struct clk_div_table apb_div_table[] = {
+	{ 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 },
+	{ 4, 16 }, { 5, 16 }, { 6, 16 }, { 7, 16 },
+	{ 0 },
+};
+
 struct clock_config {
 	u32 id;
 	const char *name;
@@ -1001,6 +1021,15 @@ struct clk_hw *_clk_register_pll(struct device *dev,
 	_NO_MUX,\
 }
 
+#define _MUXDIV(_mux_offset, _mux_bit, _mux_width,\
+		_div_offset, _div_shift, _div_width,\
+		_div_table)\
+{\
+	_DIV_TABLE(_div_offset, _div_shift, _div_width, 0, _div_table),\
+	_NO_GATE,\
+	_MUX(_mux_offset, _mux_bit, _mux_width, 0),\
+}
+
 #define MP1_GATE(_id, _name, _parent, _flags, _offset, _bit_idx, _gate_flags)\
 {\
 	.id		= _id,\
@@ -1091,6 +1120,38 @@ struct clk_hw *_clk_register_pll(struct device *dev,
 	COMPOSITE(PLL4_R, "pll4_r", PARENT("pll4"), 0,
 		  _GATEDIV(RCC_PLL4CR, 6,
 			   RCC_PLL4CFGR2, 16, 7, NULL)),
+
+	/* MUX system clocks */
+	MUX(CK_PER, "ck_per", per_src, CLK_OPS_PARENT_ENABLE,
+	    RCC_CPERCKSELR, 0, 2, 0),
+
+	MUX(CK_MPU, "ck_mpu", cpu_src, CLK_OPS_PARENT_ENABLE | CLK_IS_CRITICAL,
+	    RCC_MPCKSELR, 0, 2, 0),
+
+	COMPOSITE(CK_AXI, "ck_axi", axi_src, CLK_IS_CRITICAL |
+		  CLK_OPS_PARENT_ENABLE,
+		  _MUXDIV(RCC_ASSCKSELR, 0, 2,
+			  RCC_AXIDIVR, 0, 3, axi_div_table)),
+
+	COMPOSITE(CK_MCU, "ck_mcu", mcu_src, CLK_IS_CRITICAL |
+		  CLK_OPS_PARENT_ENABLE,
+		  _MUXDIV(RCC_MSSCKSELR, 0, 2,
+			  RCC_MCUDIVR, 0, 4, mcu_div_table)),
+
+	DIV_TABLE(NO_ID, "pclk1", "ck_mcu", CLK_IGNORE_UNUSED, RCC_APB1DIVR, 0,
+		  3, CLK_DIVIDER_READ_ONLY, apb_div_table),
+
+	DIV_TABLE(NO_ID, "pclk2", "ck_mcu", CLK_IGNORE_UNUSED, RCC_APB2DIVR, 0,
+		  3, CLK_DIVIDER_READ_ONLY, apb_div_table),
+
+	DIV_TABLE(NO_ID, "pclk3", "ck_mcu", CLK_IGNORE_UNUSED, RCC_APB3DIVR, 0,
+		  3, CLK_DIVIDER_READ_ONLY, apb_div_table),
+
+	DIV_TABLE(NO_ID, "pclk4", "ck_axi", CLK_IGNORE_UNUSED, RCC_APB4DIVR, 0,
+		  3, CLK_DIVIDER_READ_ONLY, apb_div_table),
+
+	DIV_TABLE(NO_ID, "pclk5", "ck_axi", CLK_IGNORE_UNUSED, RCC_APB5DIVR, 0,
+		  3, CLK_DIVIDER_READ_ONLY, apb_div_table),
 };
 
 struct stm32_clock_match_data {
-- 
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] 22+ messages in thread

* [PATCH 09/14] clk: stm32mp1: add Kernel timers
  2018-02-02 14:03 [PATCH 00/14] Introduce STM32MP1 clock driver gabriel.fernandez-qxv4g6HH51o
                   ` (2 preceding siblings ...)
       [not found] ` <1517580222-23301-1-git-send-email-gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
@ 2018-02-02 14:03 ` gabriel.fernandez
  2018-02-02 14:03 ` [PATCH 10/14] clk: stm32mp1: add Peripheral clocks gabriel.fernandez
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 22+ messages in thread
From: gabriel.fernandez @ 2018-02-02 14:03 UTC (permalink / raw)
  To: Rob Herring, Mark Rutland, Lee Jones, Maxime Coquelin,
	Alexandre Torgue, Michael Turquette, Stephen Boyd,
	Gabriel Fernandez
  Cc: devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	gabriel.fernandez.st, olivier.bideau

From: Gabriel Fernandez <gabriel.fernandez@st.com>

This patch adds Kernel timers.
This patch adds timers kernel clock.
Timers are gather into two groups corresponding to the APB bus
they are attached to.
Each group has its own prescaler, managed in this patch.

Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
---
 drivers/clk/clk-stm32mp1.c | 185 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 185 insertions(+)

diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
index d85c619..13d74f3 100644
--- a/drivers/clk/clk-stm32mp1.c
+++ b/drivers/clk/clk-stm32mp1.c
@@ -854,6 +854,138 @@ static struct clk_hw *clk_register_pll(struct device *dev, const char *name,
 	return hw;
 }
 
+/* Kernel Timer */
+struct timer_cker {
+	/* lock the kernel output divider register */
+	spinlock_t *lock;
+	void __iomem *apbdiv;
+	void __iomem *timpre;
+	struct clk_hw hw;
+};
+
+#define to_timer_cker(_hw) container_of(_hw, struct timer_cker, hw)
+
+#define APB_DIV_MASK 0x07
+#define TIM_PRE_MASK 0x01
+
+static unsigned long __bestmult(struct clk_hw *hw, unsigned long rate,
+				unsigned long parent_rate)
+{
+	struct timer_cker *tim_ker = to_timer_cker(hw);
+	u32 prescaler;
+	unsigned int mult = 0;
+
+	prescaler = readl_relaxed(tim_ker->apbdiv) & APB_DIV_MASK;
+	if (prescaler < 2)
+		return 1;
+
+	mult = 2;
+
+	if (rate / parent_rate >= 4)
+		mult = 4;
+
+	return mult;
+}
+
+static long timer_ker_round_rate(struct clk_hw *hw, unsigned long rate,
+				 unsigned long *parent_rate)
+{
+	unsigned long factor = __bestmult(hw, rate, *parent_rate);
+
+	return *parent_rate * factor;
+}
+
+static int timer_ker_set_rate(struct clk_hw *hw, unsigned long rate,
+			      unsigned long parent_rate)
+{
+	struct timer_cker *tim_ker = to_timer_cker(hw);
+	unsigned long flags = 0;
+	unsigned long factor = __bestmult(hw, rate, parent_rate);
+	int ret = 0;
+
+	spin_lock_irqsave(tim_ker->lock, flags);
+
+	switch (factor) {
+	case 1:
+		break;
+	case 2:
+		writel_relaxed(0, tim_ker->timpre);
+		break;
+	case 4:
+		writel_relaxed(1, tim_ker->timpre);
+		break;
+	default:
+		ret = -EINVAL;
+	}
+	spin_unlock_irqrestore(tim_ker->lock, flags);
+
+	return ret;
+}
+
+static unsigned long timer_ker_recalc_rate(struct clk_hw *hw,
+					   unsigned long parent_rate)
+{
+	struct timer_cker *tim_ker = to_timer_cker(hw);
+	u32 prescaler, timpre;
+	u32 mul;
+
+	prescaler = readl_relaxed(tim_ker->apbdiv) & APB_DIV_MASK;
+
+	timpre = readl_relaxed(tim_ker->timpre) & TIM_PRE_MASK;
+
+	if (!prescaler)
+		return parent_rate;
+
+	mul = (timpre + 1) * 2;
+
+	return parent_rate * mul;
+}
+
+static const struct clk_ops timer_ker_ops = {
+	.recalc_rate	= timer_ker_recalc_rate,
+	.round_rate	= timer_ker_round_rate,
+	.set_rate	= timer_ker_set_rate,
+
+};
+
+static struct clk_hw *clk_register_cktim(struct device *dev, const char *name,
+					 const char *parent_name,
+					 unsigned long flags,
+					 void __iomem *apbdiv,
+					 void __iomem *timpre,
+					 spinlock_t *lock)
+{
+	struct timer_cker *tim_ker;
+	struct clk_init_data init;
+	struct clk_hw *hw;
+	int err;
+
+	tim_ker = kzalloc(sizeof(*tim_ker), GFP_KERNEL);
+	if (!tim_ker)
+		return ERR_PTR(-ENOMEM);
+
+	init.name = name;
+	init.ops = &timer_ker_ops;
+	init.flags = flags;
+	init.parent_names = &parent_name;
+	init.num_parents = 1;
+
+	tim_ker->hw.init = &init;
+	tim_ker->lock = lock;
+	tim_ker->apbdiv = apbdiv;
+	tim_ker->timpre = timpre;
+
+	hw = &tim_ker->hw;
+	err = clk_hw_register(dev, hw);
+
+	if (err) {
+		kfree(tim_ker);
+		return ERR_PTR(err);
+	}
+
+	return hw;
+}
+
 static struct clk_hw *
 _clk_register_mp1_gate(struct device *dev,
 		       struct clk_hw_onecell_data *clk_data,
@@ -887,6 +1019,23 @@ struct clk_hw *_clk_register_pll(struct device *dev,
 				base + stm_pll_cfg->offset, cfg->flags, lock);
 }
 
+struct stm32_cktim_cfg {
+	u32 offset_apbdiv;
+	u32 offset_timpre;
+};
+
+static struct clk_hw *_clk_register_cktim(struct device *dev,
+					  struct clk_hw_onecell_data *clk_data,
+					  void __iomem *base, spinlock_t *lock,
+					  const struct clock_config *cfg)
+{
+	struct stm32_cktim_cfg *cktim_cfg = cfg->cfg;
+
+	return clk_register_cktim(dev, cfg->name, cfg->parent_name, cfg->flags,
+				  cktim_cfg->offset_apbdiv + base,
+				  cktim_cfg->offset_timpre + base, lock);
+}
+
 #define GATE(_id, _name, _parent, _flags, _offset, _bit_idx, _gate_flags)\
 {\
 	.id		= _id,\
@@ -1056,6 +1205,23 @@ struct clk_hw *_clk_register_pll(struct device *dev,
 	.func		= _clk_register_pll,\
 }
 
+#define STM32_CKTIM(_name, _parent, _flags, _offset_apbdiv, _offset_timpre)\
+{\
+	.id		= NO_ID,\
+	.name		= _name,\
+	.parent_name	= _parent,\
+	.flags		= _flags,\
+	.cfg		=  &(struct stm32_cktim_cfg) {\
+		.offset_apbdiv = _offset_apbdiv,\
+		.offset_timpre = _offset_timpre,\
+	},\
+	.func		= _clk_register_cktim,\
+}
+
+#define STM32_TIM(_id, _name, _parent, _offset_set, _bit_idx)\
+		  MP1_GATE(_id, _name, _parent, CLK_SET_RATE_PARENT,\
+			   _offset_set, _bit_idx, 0)
+
 static const struct clock_config stm32mp1_clock_cfg[] = {
 	/* Oscillator divider */
 	DIV(NO_ID, "clk-hsi-div", "clk-hsi", 0, RCC_HSICFGR, 0, 2,
@@ -1152,6 +1318,25 @@ struct clk_hw *_clk_register_pll(struct device *dev,
 
 	DIV_TABLE(NO_ID, "pclk5", "ck_axi", CLK_IGNORE_UNUSED, RCC_APB5DIVR, 0,
 		  3, CLK_DIVIDER_READ_ONLY, apb_div_table),
+
+	/* Kernel Timers */
+	STM32_CKTIM("ck1_tim", "pclk1", 0, RCC_APB1DIVR, RCC_TIMG1PRER),
+	STM32_CKTIM("ck2_tim", "pclk2", 0, RCC_APB2DIVR, RCC_TIMG2PRER),
+
+	STM32_TIM(TIM2_K, "tim2_k", "ck1_tim", RCC_APB1ENSETR, 0),
+	STM32_TIM(TIM3_K, "tim3_k", "ck1_tim", RCC_APB1ENSETR, 1),
+	STM32_TIM(TIM4_K, "tim4_k", "ck1_tim", RCC_APB1ENSETR, 2),
+	STM32_TIM(TIM5_K, "tim5_k", "ck1_tim", RCC_APB1ENSETR, 3),
+	STM32_TIM(TIM6_K, "tim6_k", "ck1_tim", RCC_APB1ENSETR, 4),
+	STM32_TIM(TIM7_K, "tim7_k", "ck1_tim", RCC_APB1ENSETR, 5),
+	STM32_TIM(TIM12_K, "tim12_k", "ck1_tim", RCC_APB1ENSETR, 6),
+	STM32_TIM(TIM13_K, "tim13_k", "ck1_tim", RCC_APB1ENSETR, 7),
+	STM32_TIM(TIM14_K, "tim14_k", "ck1_tim", RCC_APB1ENSETR, 8),
+	STM32_TIM(TIM1_K, "tim1_k", "ck2_tim", RCC_APB2ENSETR, 0),
+	STM32_TIM(TIM8_K, "tim8_k", "ck2_tim", RCC_APB2ENSETR, 1),
+	STM32_TIM(TIM15_K, "tim15_k", "ck2_tim", RCC_APB2ENSETR, 2),
+	STM32_TIM(TIM16_K, "tim16_k", "ck2_tim", RCC_APB2ENSETR, 3),
+	STM32_TIM(TIM17_K, "tim17_k", "ck2_tim", RCC_APB2ENSETR, 4),
 };
 
 struct stm32_clock_match_data {
-- 
1.9.1


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

* [PATCH 10/14] clk: stm32mp1: add Peripheral clocks
  2018-02-02 14:03 [PATCH 00/14] Introduce STM32MP1 clock driver gabriel.fernandez-qxv4g6HH51o
                   ` (3 preceding siblings ...)
  2018-02-02 14:03 ` [PATCH 09/14] clk: stm32mp1: add Kernel timers gabriel.fernandez
@ 2018-02-02 14:03 ` gabriel.fernandez
  2018-02-02 14:03 ` [PATCH 13/14] clk: stm32mp1: add MCO clocks gabriel.fernandez
  2018-02-02 14:03 ` [PATCH 14/14] clk: stm32mp1: add Debug clocks gabriel.fernandez
  6 siblings, 0 replies; 22+ messages in thread
From: gabriel.fernandez @ 2018-02-02 14:03 UTC (permalink / raw)
  To: Rob Herring, Mark Rutland, Lee Jones, Maxime Coquelin,
	Alexandre Torgue, Michael Turquette, Stephen Boyd,
	Gabriel Fernandez
  Cc: devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	gabriel.fernandez.st, olivier.bideau

From: Gabriel Fernandez <gabriel.fernandez@st.com>

Each peripheral requires a bus interface clock.

Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
---
 drivers/clk/clk-stm32mp1.c | 114 +++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 114 insertions(+)

diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
index 13d74f3..ea78a6a 100644
--- a/drivers/clk/clk-stm32mp1.c
+++ b/drivers/clk/clk-stm32mp1.c
@@ -1222,6 +1222,10 @@ static struct clk_hw *_clk_register_cktim(struct device *dev,
 		  MP1_GATE(_id, _name, _parent, CLK_SET_RATE_PARENT,\
 			   _offset_set, _bit_idx, 0)
 
+#define PCLK(_reg, _id, _name, _parent, _gate_idx, _flags)\
+	     MP1_GATE(_id, _name, _parent, _flags,\
+		      RCC_##_reg##ENSETR, _gate_idx, 0)
+
 static const struct clock_config stm32mp1_clock_cfg[] = {
 	/* Oscillator divider */
 	DIV(NO_ID, "clk-hsi-div", "clk-hsi", 0, RCC_HSICFGR, 0, 2,
@@ -1337,6 +1341,116 @@ static struct clk_hw *_clk_register_cktim(struct device *dev,
 	STM32_TIM(TIM15_K, "tim15_k", "ck2_tim", RCC_APB2ENSETR, 2),
 	STM32_TIM(TIM16_K, "tim16_k", "ck2_tim", RCC_APB2ENSETR, 3),
 	STM32_TIM(TIM17_K, "tim17_k", "ck2_tim", RCC_APB2ENSETR, 4),
+
+	/* Peripheral clocks */
+	PCLK(APB1, TIM2, "tim2", "pclk1", 0, CLK_IGNORE_UNUSED),
+	PCLK(APB1, TIM3, "tim3", "pclk1", 1, CLK_IGNORE_UNUSED),
+	PCLK(APB1, TIM4, "tim4", "pclk1", 2, CLK_IGNORE_UNUSED),
+	PCLK(APB1, TIM5, "tim5", "pclk1", 3, CLK_IGNORE_UNUSED),
+	PCLK(APB1, TIM6, "tim6", "pclk1", 4, CLK_IGNORE_UNUSED),
+	PCLK(APB1, TIM7, "tim7", "pclk1", 5, CLK_IGNORE_UNUSED),
+	PCLK(APB1, TIM12, "tim12", "pclk1", 6, CLK_IGNORE_UNUSED),
+	PCLK(APB1, TIM13, "tim13", "pclk1", 7, CLK_IGNORE_UNUSED),
+	PCLK(APB1, TIM14, "tim14", "pclk1", 8, CLK_IGNORE_UNUSED),
+	PCLK(APB1, LPTIM1, "lptim1", "pclk1", 9, CLK_IGNORE_UNUSED),
+	PCLK(APB1, SPI2, "spi2", "pclk1", 11, CLK_IGNORE_UNUSED),
+	PCLK(APB1, SPI3, "spi3", "pclk1", 12, CLK_IGNORE_UNUSED),
+	PCLK(APB1, USART2, "usart2", "pclk1", 14, CLK_IGNORE_UNUSED),
+	PCLK(APB1, USART3, "usart3", "pclk1", 15, CLK_IGNORE_UNUSED),
+	PCLK(APB1, UART4, "uart4", "pclk1", 16, CLK_IGNORE_UNUSED),
+	PCLK(APB1, UART5, "uart5", "pclk1", 17, CLK_IGNORE_UNUSED),
+	PCLK(APB1, UART7, "uart7", "pclk1", 18, CLK_IGNORE_UNUSED),
+	PCLK(APB1, UART8, "uart8", "pclk1", 19, CLK_IGNORE_UNUSED),
+	PCLK(APB1, I2C1, "i2c1", "pclk1", 21, CLK_IGNORE_UNUSED),
+	PCLK(APB1, I2C2, "i2c2", "pclk1", 22, CLK_IGNORE_UNUSED),
+	PCLK(APB1, I2C3, "i2c3", "pclk1", 23, CLK_IGNORE_UNUSED),
+	PCLK(APB1, I2C5, "i2c5", "pclk1", 24, CLK_IGNORE_UNUSED),
+	PCLK(APB1, SPDIF, "spdif", "pclk1", 26, CLK_IGNORE_UNUSED),
+	PCLK(APB1, CEC, "cec", "pclk1", 27, CLK_IGNORE_UNUSED),
+	PCLK(APB1, DAC12, "dac12", "pclk1", 29, 0),
+	PCLK(APB1, MDIO, "mdio", "pclk1", 31, 0),
+	PCLK(APB2, TIM1, "tim1", "pclk2", 0, CLK_IGNORE_UNUSED),
+	PCLK(APB2, TIM8, "tim8", "pclk2", 1, CLK_IGNORE_UNUSED),
+	PCLK(APB2, TIM15, "tim15", "pclk2", 2, CLK_IGNORE_UNUSED),
+	PCLK(APB2, TIM16, "tim16", "pclk2", 3, CLK_IGNORE_UNUSED),
+	PCLK(APB2, TIM17, "tim17", "pclk2", 4, CLK_IGNORE_UNUSED),
+	PCLK(APB2, SPI1, "spi1", "pclk2", 8, CLK_IGNORE_UNUSED),
+	PCLK(APB2, SPI4, "spi4", "pclk2", 9, CLK_IGNORE_UNUSED),
+	PCLK(APB2, SPI5, "spi5", "pclk2", 10, CLK_IGNORE_UNUSED),
+	PCLK(APB2, USART6, "usart6", "pclk2", 13, CLK_IGNORE_UNUSED),
+	PCLK(APB2, SAI1, "sai1", "pclk2", 16, CLK_IGNORE_UNUSED),
+	PCLK(APB2, SAI2, "sai2", "pclk2", 17, CLK_IGNORE_UNUSED),
+	PCLK(APB2, SAI3, "sai3", "pclk2", 18, CLK_IGNORE_UNUSED),
+	PCLK(APB2, DFSDM, "dfsdm", "pclk2", 20, CLK_IGNORE_UNUSED),
+	PCLK(APB2, FDCAN, "fdcan", "pclk2", 24, CLK_IGNORE_UNUSED),
+	PCLK(APB3, LPTIM2, "lptim2", "pclk3", 0, CLK_IGNORE_UNUSED),
+	PCLK(APB3, LPTIM3, "lptim3", "pclk3", 1, CLK_IGNORE_UNUSED),
+	PCLK(APB3, LPTIM4, "lptim4", "pclk3", 2, CLK_IGNORE_UNUSED),
+	PCLK(APB3, LPTIM5, "lptim5", "pclk3", 3, CLK_IGNORE_UNUSED),
+	PCLK(APB3, SAI4, "sai4", "pclk3", 8, CLK_IGNORE_UNUSED),
+	PCLK(APB3, SYSCFG, "syscfg", "pclk3", 11, 0),
+	PCLK(APB3, VREF, "vref", "pclk3", 13, 0),
+	PCLK(APB3, TMPSENS, "tmpsens", "pclk3", 16, 0),
+	PCLK(APB3, PMBCTRL, "pmbctrl", "pclk3", 17, 0),
+	PCLK(APB3, HDP, "hdp", "pclk3", 20, 0),
+	PCLK(APB4, LTDC, "ltdc", "pclk4", 0, CLK_IGNORE_UNUSED),
+	PCLK(APB4, DSI, "dsi", "pclk4", 4, CLK_IGNORE_UNUSED),
+	PCLK(APB4, IWDG2, "iwdg2", "pclk4", 15, 0),
+	PCLK(APB4, USBPHY, "usbphy", "pclk4", 16, CLK_IGNORE_UNUSED),
+	PCLK(APB4, STGENRO, "stgenro", "pclk4", 20, 0),
+	PCLK(APB5, SPI6, "spi6", "pclk5", 0, CLK_IGNORE_UNUSED),
+	PCLK(APB5, I2C4, "i2c4", "pclk5", 2, CLK_IGNORE_UNUSED),
+	PCLK(APB5, I2C6, "i2c6", "pclk5", 3, CLK_IGNORE_UNUSED),
+	PCLK(APB5, USART1, "usart1", "pclk5", 4, CLK_IGNORE_UNUSED),
+	PCLK(APB5, RTCAPB, "rtcapb", "pclk5", 8, CLK_IGNORE_UNUSED |
+	     CLK_IS_CRITICAL),
+	PCLK(APB5, TZC, "tzc", "pclk5", 12, CLK_IGNORE_UNUSED),
+	PCLK(APB5, TZPC, "tzpc", "pclk5", 13, CLK_IGNORE_UNUSED),
+	PCLK(APB5, IWDG1, "iwdg1", "pclk5", 15, 0),
+	PCLK(APB5, BSEC, "bsec", "pclk5", 16, CLK_IGNORE_UNUSED),
+	PCLK(APB5, STGEN, "stgen", "pclk5", 20, CLK_IGNORE_UNUSED),
+	PCLK(AHB2, DMA1, "dma1", "ck_mcu", 0, 0),
+	PCLK(AHB2, DMA2, "dma2", "ck_mcu",  1, 0),
+	PCLK(AHB2, DMAMUX, "dmamux", "ck_mcu", 2, 0),
+	PCLK(AHB2, ADC12, "adc12", "ck_mcu", 5, CLK_IGNORE_UNUSED),
+	PCLK(AHB2, USBO, "usbo", "ck_mcu", 8, CLK_IGNORE_UNUSED),
+	PCLK(AHB2, SDMMC3, "sdmmc3", "ck_mcu", 16, CLK_IGNORE_UNUSED),
+	PCLK(AHB3, DCMI, "dcmi", "ck_mcu", 0, 0),
+	PCLK(AHB3, CRYP2, "cryp2", "ck_mcu", 4, 0),
+	PCLK(AHB3, HASH2, "hash2", "ck_mcu", 5, 0),
+	PCLK(AHB3, RNG2, "rng2", "ck_mcu", 6, CLK_IGNORE_UNUSED),
+	PCLK(AHB3, CRC2, "crc2", "ck_mcu", 7, 0),
+	PCLK(AHB3, HSEM, "hsem", "ck_mcu", 11, 0),
+	PCLK(AHB3, IPCC, "ipcc", "ck_mcu", 12, 0),
+	PCLK(AHB4, GPIOA, "gpioa", "ck_mcu", 0, 0),
+	PCLK(AHB4, GPIOB, "gpiob", "ck_mcu", 1, 0),
+	PCLK(AHB4, GPIOC, "gpioc", "ck_mcu", 2, 0),
+	PCLK(AHB4, GPIOD, "gpiod", "ck_mcu", 3, 0),
+	PCLK(AHB4, GPIOE, "gpioe", "ck_mcu", 4, 0),
+	PCLK(AHB4, GPIOF, "gpiof", "ck_mcu", 5, 0),
+	PCLK(AHB4, GPIOG, "gpiog", "ck_mcu", 6, 0),
+	PCLK(AHB4, GPIOH, "gpioh", "ck_mcu", 7, 0),
+	PCLK(AHB4, GPIOI, "gpioi", "ck_mcu", 8, 0),
+	PCLK(AHB4, GPIOJ, "gpioj", "ck_mcu", 9, 0),
+	PCLK(AHB4, GPIOK, "gpiok", "ck_mcu", 10, 0),
+	PCLK(AHB5, GPIOZ, "gpioz", "ck_axi", 0, CLK_IGNORE_UNUSED),
+	PCLK(AHB5, CRYP1, "cryp1", "ck_axi", 4, CLK_IGNORE_UNUSED),
+	PCLK(AHB5, HASH1, "hash1", "ck_axi", 5, CLK_IGNORE_UNUSED),
+	PCLK(AHB5, RNG1, "rng1", "ck_axi",  6, CLK_IGNORE_UNUSED),
+	PCLK(AHB5, BKPSRAM, "bkpsram", "ck_axi", 8, CLK_IGNORE_UNUSED),
+	PCLK(AHB6, MDMA, "mdma", "ck_axi", 0, 0),
+	PCLK(AHB6, GPU, "gpu", "ck_axi", 5, CLK_IGNORE_UNUSED),
+	PCLK(AHB6, ETHCK, "ethck", "ck_axi", 7, 0),
+	PCLK(AHB6, ETHTX, "ethtx", "ck_axi", 8, 0),
+	PCLK(AHB6, ETHRX, "ethrx", "ck_axi", 9, 0),
+	PCLK(AHB6, ETHMAC, "ethmac", "ck_axi", 10, CLK_IGNORE_UNUSED),
+	PCLK(AHB6, FMC, "fmc", "ck_axi", 12, CLK_IGNORE_UNUSED),
+	PCLK(AHB6, QSPI, "qspi", "ck_axi", 14, CLK_IGNORE_UNUSED),
+	PCLK(AHB6, SDMMC1, "sdmmc1", "ck_axi", 16, CLK_IGNORE_UNUSED),
+	PCLK(AHB6, SDMMC2, "sdmmc2", "ck_axi", 17, CLK_IGNORE_UNUSED),
+	PCLK(AHB6, CRC1, "crc1", "ck_axi", 20, 0),
+	PCLK(AHB6, USBH, "usbh", "ck_axi", 24, 0),
+	PCLK(AHB6LP, ETHSTP, "ethstp", "ck_axi", 11, 0),
 };
 
 struct stm32_clock_match_data {
-- 
1.9.1


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

* [PATCH 11/14] clk: stm32mp1: add Kernel clocks
       [not found] ` <1517580222-23301-1-git-send-email-gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
                     ` (5 preceding siblings ...)
  2018-02-02 14:03   ` [PATCH 08/14] clk: stm32mp1: add Sub System clocks gabriel.fernandez-qxv4g6HH51o
@ 2018-02-02 14:03   ` gabriel.fernandez-qxv4g6HH51o
  2018-02-02 14:03   ` [PATCH 12/14] clk: stm32mp1: add RTC clock gabriel.fernandez-qxv4g6HH51o
  7 siblings, 0 replies; 22+ messages in thread
From: gabriel.fernandez-qxv4g6HH51o @ 2018-02-02 14:03 UTC (permalink / raw)
  To: Rob Herring, Mark Rutland, Lee Jones, Maxime Coquelin,
	Alexandre Torgue, Michael Turquette, Stephen Boyd,
	Gabriel Fernandez
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	gabriel.fernandez.st-Re5JQEeQqe8AvxtiuMwx3w,
	olivier.bideau-qxv4g6HH51o

From: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>

Some peripherals need also a dedicated clock for their communication
interface, this clock is generally asynchronous with respect to the bus
interface clock (peripheral clock), and is named kernel clock.

Signed-off-by: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
---
 drivers/clk/clk-stm32mp1.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 75 insertions(+)

diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
index ea78a6a..5a1142c 100644
--- a/drivers/clk/clk-stm32mp1.c
+++ b/drivers/clk/clk-stm32mp1.c
@@ -1179,6 +1179,17 @@ static struct clk_hw *_clk_register_cktim(struct device *dev,
 	_MUX(_mux_offset, _mux_bit, _mux_width, 0),\
 }
 
+#define _MP1_GATE(_gate_offset, _bit_idx, _flags)\
+		  _GATE_OPS(_gate_offset, _bit_idx, _flags, &mp1_gate_clk_ops)
+
+#define _MP1_GATEMUX(_gate_offset, _bit_idx,\
+		     _mux_offset, _mux_bit, _mux_width)\
+{\
+	_NO_DIV,\
+	_MP1_GATE(_gate_offset, _bit_idx, 0),\
+	_MUX(_mux_offset, _mux_bit, _mux_width, 0),\
+}
+
 #define MP1_GATE(_id, _name, _parent, _flags, _offset, _bit_idx, _gate_flags)\
 {\
 	.id		= _id,\
@@ -1226,6 +1237,11 @@ static struct clk_hw *_clk_register_cktim(struct device *dev,
 	     MP1_GATE(_id, _name, _parent, _flags,\
 		      RCC_##_reg##ENSETR, _gate_idx, 0)
 
+#define KCLK(_reg, _id, _bit_idx, _mux_offset, _name, _parents, _flags)\
+	     COMPOSITE(_id, _name, _parents, CLK_OPS_PARENT_ENABLE | _flags,\
+		       _MP1_GATEMUX(RCC_##_reg##ENSETR, _bit_idx,\
+					   _mux_offset, 0, 3))
+
 static const struct clock_config stm32mp1_clock_cfg[] = {
 	/* Oscillator divider */
 	DIV(NO_ID, "clk-hsi-div", "clk-hsi", 0, RCC_HSICFGR, 0, 2,
@@ -1451,6 +1467,65 @@ static struct clk_hw *_clk_register_cktim(struct device *dev,
 	PCLK(AHB6, CRC1, "crc1", "ck_axi", 20, 0),
 	PCLK(AHB6, USBH, "usbh", "ck_axi", 24, 0),
 	PCLK(AHB6LP, ETHSTP, "ethstp", "ck_axi", 11, 0),
+
+	/* Kernel clocks */
+	KCLK(AHB6, SDMMC1_K, 16, RCC_SDMMC12CKSELR, "sdmmc1_k", sdmmc1_src, 0),
+	KCLK(AHB6, SDMMC2_K, 17, RCC_SDMMC12CKSELR, "sdmmc2_k", sdmmc2_src, 0),
+	KCLK(AHB2, SDMMC3_K, 16, RCC_SDMMC3CKSELR, "sdmmc3_k", sdmmc3_src, 0),
+	KCLK(AHB6, FMC_K, 12, RCC_FMCCKSELR, "fmc_k", fmc_src, 0),
+	KCLK(AHB6, QSPI_K, 14, RCC_QSPICKSELR, "qspi_k", qspi_src, 0),
+	KCLK(AHB6, ETHMAC_K, 10, RCC_ETHCKSELR, "ethmac_k", eth_src, 0),
+	KCLK(AHB5, RNG1_K, 6, RCC_RNG1CKSELR, "rng1_k", rng_src, 0),
+	KCLK(AHB3, RNG2_K, 6, RCC_RNG2CKSELR, "rng2_k", rng_src, 0),
+	KCLK(APB4, USBPHY_K, 16, RCC_USBCKSELR, "usbphy_k", usbphy_src, 0),
+	KCLK(APB5, STGEN_K, 20, RCC_STGENCKSELR, "stgen_k",  stgen_src,
+	     CLK_IGNORE_UNUSED),
+	KCLK(APB1, SPDIF_K, 26, RCC_SPDIFCKSELR, "spdif_k",  spdif_src, 0),
+	KCLK(APB2, SPI1_K, 8, RCC_SPI2S1CKSELR, "spi1_k", spi1_src, 0),
+	KCLK(APB1, SPI2_K, 11, RCC_SPI2S23CKSELR, "spi2_k", spi2_src, 0),
+	KCLK(APB1, SPI3_K, 12, RCC_SPI2S23CKSELR, "spi3_k", spi3_src, 0),
+	KCLK(APB2, SPI4_K, 9, RCC_SPI2S45CKSELR, "spi4_k", spi4_src, 0),
+	KCLK(APB2, SPI5_K, 10, RCC_SPI2S45CKSELR, "spi5_k", spi5_src, 0),
+	KCLK(APB5, SPI6_K, 0, RCC_SPI6CKSELR, "spi6_k", spi6_src, 0),
+	KCLK(APB1, CEC_K, 27, RCC_CECCKSELR, "cec_k", cec_src, 0),
+	KCLK(APB1, I2C1_K, 21, RCC_I2C12CKSELR, "i2c1_k", i2c1_src, 0),
+	KCLK(APB1, I2C2_K, 22, RCC_I2C12CKSELR, "i2c2_k", i2c2_src, 0),
+	KCLK(APB1, I2C3_K, 23, RCC_I2C35CKSELR, "i2c3_k", i2c3_src, 0),
+	KCLK(APB5, I2C4_K, 2, RCC_I2C4CKSELR, "i2c4_k", i2c4_src, 0),
+	KCLK(APB1, I2C5_K, 24, RCC_I2C35CKSELR, "i2c5_k", i2c5_src, 0),
+	KCLK(APB5, I2C6_K, 3, RCC_I2C4CKSELR, "i2c6_k", i2c6_src, 0),
+	KCLK(APB1, LPTIM1_K, 9, RCC_LPTIM1CKSELR, "lptim1_k", lptim1_src, 0),
+	KCLK(APB3, LPTIM2_K, 0, RCC_LPTIM23CKSELR, "lptim2_k", lptim2_src, 0),
+	KCLK(APB3, LPTIM3_K, 1, RCC_LPTIM23CKSELR, "lptim3_k", lptim3_src, 0),
+	KCLK(APB3, LPTIM4_K, 2, RCC_LPTIM45CKSELR, "lptim4_k", lptim4_src, 0),
+	KCLK(APB3, LPTIM5_K, 3, RCC_LPTIM45CKSELR, "lptim5_k", lptim5_src, 0),
+	KCLK(APB5, USART1_K, 4, RCC_UART1CKSELR, "usart1_k", usart1_src, 0),
+	KCLK(APB1, USART2_K, 14, RCC_UART24CKSELR, "usart2_k", usart2_src, 0),
+	KCLK(APB1, USART3_K, 15, RCC_UART35CKSELR, "usart3_k", usart3_src, 0),
+	KCLK(APB1, UART4_K, 16, RCC_UART24CKSELR, "uart4_k", uart4_src, 0),
+	KCLK(APB1, UART5_K, 17, RCC_UART35CKSELR, "uart5_k", uart5_src, 0),
+	KCLK(APB2, USART6_K, 13, RCC_UART6CKSELR, "uart6_k", usart6_src, 0),
+	KCLK(APB1, UART7_K, 18, RCC_UART78CKSELR, "uart7_k",  uart7_src, 0),
+	KCLK(APB1, UART8_K, 19, RCC_UART78CKSELR, "uart8_k",  uart8_src, 0),
+	KCLK(APB2, DFSDM_K, 20, RCC_DFSDMCKSELR, "dfsdm_k", dfsdm_src, 0),
+	KCLK(APB2, FDCAN_K, 24, RCC_FDCANCKSELR, "fdcan_k", fdcan_src, 0),
+	KCLK(APB2, SAI1_K, 16, RCC_SAI1CKSELR, "sai1_k", sai_src, 0),
+	KCLK(APB2, SAI2_K, 17, RCC_SAI2CKSELR, "sai2_k", sai2_src, 0),
+	KCLK(APB2, SAI3_K, 18, RCC_SAI3CKSELR, "sai3_k", sai_src, 0),
+	KCLK(APB3, SAI4_K, 8, RCC_SAI4CKSELR, "sai4_k", sai_src, 0),
+	KCLK(AHB2, ADC12_K, 5, RCC_ADCCKSELR, "adc12_k", adc12_src,
+	     CLK_IGNORE_UNUSED),
+	KCLK(APB4, DSI_K, 4, RCC_DSICKSELR, "dsi_k", dsi_src, 0),
+	KCLK(APB2, ADFSDM_K, 21, RCC_SAI1CKSELR, "adfsdm_k", adfsdm_src, 0),
+
+	/* particulary Kernel clocks */
+	COMPOSITE(USBO_K, "usbo_k", usbo_src, CLK_OPS_PARENT_ENABLE,
+		  _MP1_GATEMUX(RCC_AHB2ENSETR, 8, RCC_USBCKSELR, 4, 1)),
+
+	MP1_GATE(LTDC_K, "ltdc_k", "pll4_q", CLK_SET_RATE_PARENT,
+		 RCC_APB4ENSETR, 0, 0),
+
+	MP1_GATE(GPU_K, "gpu_k", "pll2_q", 0, RCC_AHB6ENSETR, 5, 0),
 };
 
 struct stm32_clock_match_data {
-- 
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] 22+ messages in thread

* [PATCH 12/14] clk: stm32mp1: add RTC clock
       [not found] ` <1517580222-23301-1-git-send-email-gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
                     ` (6 preceding siblings ...)
  2018-02-02 14:03   ` [PATCH 11/14] clk: stm32mp1: add Kernel clocks gabriel.fernandez-qxv4g6HH51o
@ 2018-02-02 14:03   ` gabriel.fernandez-qxv4g6HH51o
  7 siblings, 0 replies; 22+ messages in thread
From: gabriel.fernandez-qxv4g6HH51o @ 2018-02-02 14:03 UTC (permalink / raw)
  To: Rob Herring, Mark Rutland, Lee Jones, Maxime Coquelin,
	Alexandre Torgue, Michael Turquette, Stephen Boyd,
	Gabriel Fernandez
  Cc: devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	gabriel.fernandez.st-Re5JQEeQqe8AvxtiuMwx3w,
	olivier.bideau-qxv4g6HH51o

From: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>

This patch adds the RTC clock.

Signed-off-by: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
---
 drivers/clk/clk-stm32mp1.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
index 5a1142c..1cb06b0 100644
--- a/drivers/clk/clk-stm32mp1.c
+++ b/drivers/clk/clk-stm32mp1.c
@@ -1179,6 +1179,15 @@ static struct clk_hw *_clk_register_cktim(struct device *dev,
 	_MUX(_mux_offset, _mux_bit, _mux_width, 0),\
 }
 
+#define _GATEMUX(_gate_offset,\
+		 _bit_idx,\
+		 _mux_offset, _mux_bit, _mux_width)\
+{\
+	_NO_DIV,\
+	_GATE(_gate_offset, _bit_idx, 0),\
+	_MUX(_mux_offset, _mux_bit, _mux_width, 0),\
+}
+
 #define _MP1_GATE(_gate_offset, _bit_idx, _flags)\
 		  _GATE_OPS(_gate_offset, _bit_idx, _flags, &mp1_gate_clk_ops)
 
@@ -1526,6 +1535,14 @@ static struct clk_hw *_clk_register_cktim(struct device *dev,
 		 RCC_APB4ENSETR, 0, 0),
 
 	MP1_GATE(GPU_K, "gpu_k", "pll2_q", 0, RCC_AHB6ENSETR, 5, 0),
+
+	/* RTC clock */
+	DIV(NO_ID, "ck_hse_rtc", "ck_hse", 0, RCC_RTCDIVR, 0, 7,
+	    CLK_DIVIDER_ALLOW_ZERO),
+
+	COMPOSITE(RTC, "ck_rtc", rtc_src, CLK_OPS_PARENT_ENABLE |
+		  CLK_SET_RATE_PARENT,
+		  _GATEMUX(RCC_BDCR, 20, RCC_BDCR, 16, 2)),
 };
 
 struct stm32_clock_match_data {
-- 
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] 22+ messages in thread

* [PATCH 13/14] clk: stm32mp1: add MCO clocks
  2018-02-02 14:03 [PATCH 00/14] Introduce STM32MP1 clock driver gabriel.fernandez-qxv4g6HH51o
                   ` (4 preceding siblings ...)
  2018-02-02 14:03 ` [PATCH 10/14] clk: stm32mp1: add Peripheral clocks gabriel.fernandez
@ 2018-02-02 14:03 ` gabriel.fernandez
  2018-02-02 14:03 ` [PATCH 14/14] clk: stm32mp1: add Debug clocks gabriel.fernandez
  6 siblings, 0 replies; 22+ messages in thread
From: gabriel.fernandez @ 2018-02-02 14:03 UTC (permalink / raw)
  To: Rob Herring, Mark Rutland, Lee Jones, Maxime Coquelin,
	Alexandre Torgue, Michael Turquette, Stephen Boyd,
	Gabriel Fernandez
  Cc: devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	gabriel.fernandez.st, olivier.bideau

From: Gabriel Fernandez <gabriel.fernandez@st.com>

Two micro-controller clock output (MCO) pins are available: MCO1 and MCO2.
For each output, it is possible to select a clock source.
The selected clock can be divided thanks to configurable prescaler.

Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
---
 drivers/clk/clk-stm32mp1.c | 23 +++++++++++++++++++++++
 1 file changed, 23 insertions(+)

diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
index 1cb06b0..0402a0e 100644
--- a/drivers/clk/clk-stm32mp1.c
+++ b/drivers/clk/clk-stm32mp1.c
@@ -1188,6 +1188,16 @@ static struct clk_hw *_clk_register_cktim(struct device *dev,
 	_MUX(_mux_offset, _mux_bit, _mux_width, 0),\
 }
 
+#define _GATEMUXDIV(_gate_offset, _bit_idx,\
+		    _mux_offset, _mux_bit, _mux_width,\
+		    _div_offset, _div_bit, _div_width\
+		)\
+{\
+	_DIV(_div_offset, _div_bit, _div_width, 0),\
+	_GATE(_gate_offset, _bit_idx, 0),\
+	_MUX(_mux_offset, _mux_bit, _mux_width, 0),\
+}
+
 #define _MP1_GATE(_gate_offset, _bit_idx, _flags)\
 		  _GATE_OPS(_gate_offset, _bit_idx, _flags, &mp1_gate_clk_ops)
 
@@ -1543,6 +1553,19 @@ static struct clk_hw *_clk_register_cktim(struct device *dev,
 	COMPOSITE(RTC, "ck_rtc", rtc_src, CLK_OPS_PARENT_ENABLE |
 		  CLK_SET_RATE_PARENT,
 		  _GATEMUX(RCC_BDCR, 20, RCC_BDCR, 16, 2)),
+
+	/* MCO clocks */
+	COMPOSITE(CK_MCO1, "ck_mco1", mco1_src, CLK_OPS_PARENT_ENABLE |
+		  CLK_SET_RATE_NO_REPARENT,
+		  _GATEMUXDIV(RCC_MCO1CFGR, 12,
+			      RCC_MCO1CFGR, 0, 3,
+			      RCC_MCO1CFGR, 4, 4)),
+
+	COMPOSITE(CK_MCO2, "ck_mco2", mco2_src, CLK_OPS_PARENT_ENABLE |
+		  CLK_SET_RATE_NO_REPARENT,
+		  _GATEMUXDIV(RCC_MCO2CFGR, 12,
+			      RCC_MCO2CFGR, 0, 3,
+			      RCC_MCO2CFGR, 4, 4)),
 };
 
 struct stm32_clock_match_data {
-- 
1.9.1


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

* [PATCH 14/14] clk: stm32mp1: add Debug clocks
  2018-02-02 14:03 [PATCH 00/14] Introduce STM32MP1 clock driver gabriel.fernandez-qxv4g6HH51o
                   ` (5 preceding siblings ...)
  2018-02-02 14:03 ` [PATCH 13/14] clk: stm32mp1: add MCO clocks gabriel.fernandez
@ 2018-02-02 14:03 ` gabriel.fernandez
  6 siblings, 0 replies; 22+ messages in thread
From: gabriel.fernandez @ 2018-02-02 14:03 UTC (permalink / raw)
  To: Rob Herring, Mark Rutland, Lee Jones, Maxime Coquelin,
	Alexandre Torgue, Michael Turquette, Stephen Boyd,
	Gabriel Fernandez
  Cc: devicetree, linux-arm-kernel, linux-kernel, linux-clk,
	gabriel.fernandez.st, olivier.bideau

From: Gabriel Fernandez <gabriel.fernandez@st.com>

RCC manages clock for debug and trace.

Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
---
 drivers/clk/clk-stm32mp1.c | 17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff --git a/drivers/clk/clk-stm32mp1.c b/drivers/clk/clk-stm32mp1.c
index 0402a0e..eafc95a 100644
--- a/drivers/clk/clk-stm32mp1.c
+++ b/drivers/clk/clk-stm32mp1.c
@@ -352,6 +352,12 @@
 	{ 0 },
 };
 
+static const struct clk_div_table ck_trace_div_table[] = {
+	{ 0, 1 }, { 1, 2 }, { 2, 4 }, { 3, 8 },
+	{ 4, 16 }, { 5, 16 }, { 6, 16 }, { 7, 16 },
+	{ 0 },
+};
+
 struct clock_config {
 	u32 id;
 	const char *name;
@@ -1566,6 +1572,17 @@ static struct clk_hw *_clk_register_cktim(struct device *dev,
 		  _GATEMUXDIV(RCC_MCO2CFGR, 12,
 			      RCC_MCO2CFGR, 0, 3,
 			      RCC_MCO2CFGR, 4, 4)),
+
+	/* Debug clocks */
+	FIXED_FACTOR(NO_ID, "ck_axi_div2", "ck_axi", 0, 1, 2),
+
+	GATE(DBG, "ck_apb_dbg", "ck_axi_div2", 0, RCC_DBGCFGR, 8, 0),
+
+	GATE(CK_DBG, "ck_sys_dbg", "ck_axi", 0, RCC_DBGCFGR, 8, 0),
+
+	COMPOSITE(CK_TRACE, "ck_trace", ck_trace_src, CLK_OPS_PARENT_ENABLE,
+		  _GATEDIV(RCC_DBGCFGR, 9,
+			   RCC_DBGCFGR, 0, 3, ck_trace_div_table)),
 };
 
 struct stm32_clock_match_data {
-- 
1.9.1


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

* Re: [PATCH 01/14] dt-bindings: Document STM32MP1 Reset Clock Controller (RCC) bindings
  2018-02-02 14:03   ` [PATCH 01/14] dt-bindings: Document STM32MP1 Reset Clock Controller (RCC) bindings gabriel.fernandez-qxv4g6HH51o
@ 2018-02-05  6:09     ` Rob Herring
  2018-02-05  7:01       ` Gabriel FERNANDEZ
  2018-02-05  7:15       ` Gabriel FERNANDEZ
  0 siblings, 2 replies; 22+ messages in thread
From: Rob Herring @ 2018-02-05  6:09 UTC (permalink / raw)
  To: gabriel.fernandez
  Cc: Mark Rutland, Lee Jones, Maxime Coquelin, Alexandre Torgue,
	Michael Turquette, Stephen Boyd, devicetree, linux-arm-kernel,
	linux-kernel, linux-clk, gabriel.fernandez.st, olivier.bideau

On Fri, Feb 02, 2018 at 03:03:29PM +0100, gabriel.fernandez@st.com wrote:
> From: Gabriel Fernandez <gabriel.fernandez@st.com>
> 
> The RCC block is responsible of the management of the clock and reset
> generation for the complete circuit.
> 
> Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
> ---
>  .../devicetree/bindings/mfd/st,stm32-rcc.txt       | 85 ++++++++++++++++++++++
>  1 file changed, 85 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
> 
> diff --git a/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt b/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
> new file mode 100644
> index 0000000..28017a1
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
> @@ -0,0 +1,85 @@
> +STMicroelectronics STM32 Peripheral Reset Clock Controller
> +==========================================================
> +
> +The RCC IP is both a reset and a clock controller.
> +
> +Please also refer to reset.txt for common reset controller binding usage.
> +
> +Please also refer to clock-bindings.txt for common clock controller
> +binding usage.
> +
> +
> +Required properties:
> +- compatible: "simple-mfd", "syscon"


> +- reg: should be register base and length as documented in the datasheet
> +
> +- Sub-nodes:
> +  - compatible: "st,stm32mp1-rcc-clk"
> +	- #clock-cells: 1, device nodes should specify the clock in their
> +	  "clocks" property, containing a phandle to the clock device node,
> +	  an index specifying the clock to use.
> +
> +  - compatible: "st,stm32mp1-rcc-rst"
> +	- #reset-cells: Shall be 1
> +
> +Example:
> +	rcc: rcc@50000000 {
> +		compatible = "syscon", "simple-mfd";
> +		reg = <0x50000000 0x1000>;
> +
> +		rcc_clk: rcc-clk@50000000 {
> +			#clock-cells = <1>;
> +			compatible = "st,stm32mp1-rcc-clk";
> +		};
> +
> +		rcc_rst: rcc-reset@50000000 {

You should not have the same unit-address twice.

IMO, this should just be:

	rcc: rcc@50000000 {
		compatible = "st-stm32mp1-rcc";
		reg = <0x50000000 0x1000>;
		#clock-cells = <1>;
		#reset-cells = <1>;
	};

There's no reason a node can't provide more than 1 function.


> +			#reset-cells = <1>;
> +			compatible = "st,stm32mp1-rcc-rst";
> +		};
> +	};
> +
> +Specifying clocks
> +=================
> +
> +All available clocks are defined as preprocessor macros in
> +dt-bindings/clock/stm32mp1-clks.h header and can be used in device
> +tree sources.
> +
> +Example:
> +
> +	/* Accessing DMA1 clock */
> +	... {
> +		clocks = <&rcc_clk DMA1>
> +	};
> +
> +	/* Accessing SPI6 kernel clock */
> +	... {
> +		clocks = <&rcc_clk SPI6_K>
> +	};

Other than the path to header, the clock binding explains all this. No 
need to duplicate here.

> +
> +Specifying softreset control of devices
> +=======================================
> +
> +Device nodes should specify the reset channel required in their "resets"
> +property, containing a phandle to the reset device node and an index specifying
> +which channel to use.
> +The index is the bit number within the RCC registers bank, starting from RCC
> +base address.
> +It is calculated as: index = register_offset / 4 * 32 + bit_offset.
> +Where bit_offset is the bit offset within the register.
> +
> +For example on STM32MP1, for LTDC reset:
> + ltdc = APB4_RSTSETR_offset / 4 * 32 + LTDC_bit_offset
> +      = 0x180 / 4 * 32 + 0 = 3072
> +
> +The list of valid indices for STM32MP1 is available in:
> +include/dt-bindings/reset-controller/stm32mp1-resets.h
> +
> +This file implements defines like:
> +#define LTDC_R	3072
> +
> +example:
> +
> +	ltdc {
> +		resets = <&rcc_rst LTDC_R>;
> +	};
> -- 
> 1.9.1
> 

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

* Re: [PATCH 02/14] dt-bindings: clock: add STM32MP1 clocks
       [not found]   ` <1517580222-23301-3-git-send-email-gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
@ 2018-02-05  6:09     ` Rob Herring
  2018-02-05  7:02       ` Gabriel FERNANDEZ
  0 siblings, 1 reply; 22+ messages in thread
From: Rob Herring @ 2018-02-05  6:09 UTC (permalink / raw)
  To: gabriel.fernandez-qxv4g6HH51o
  Cc: Mark Rutland, Lee Jones, Maxime Coquelin, Alexandre Torgue,
	Michael Turquette, Stephen Boyd,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	gabriel.fernandez.st-Re5JQEeQqe8AvxtiuMwx3w,
	olivier.bideau-qxv4g6HH51o

On Fri, Feb 02, 2018 at 03:03:30PM +0100, gabriel.fernandez-qxv4g6HH51o@public.gmane.org wrote:
> From: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
> 
> This patch adds the clock binding entry for STM32MP1
> 
> Signed-off-by: Gabriel Fernandez <gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
> ---
>  include/dt-bindings/clock/stm32mp1-clks.h | 248 ++++++++++++++++++++++++++++++
>  1 file changed, 248 insertions(+)
>  create mode 100644 include/dt-bindings/clock/stm32mp1-clks.h

You can squash this into the previous patch.
--
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] 22+ messages in thread

* Re: [PATCH 01/14] dt-bindings: Document STM32MP1 Reset Clock Controller (RCC) bindings
  2018-02-05  6:09     ` Rob Herring
@ 2018-02-05  7:01       ` Gabriel FERNANDEZ
  2018-02-07 18:03         ` Rob Herring
  2018-02-05  7:15       ` Gabriel FERNANDEZ
  1 sibling, 1 reply; 22+ messages in thread
From: Gabriel FERNANDEZ @ 2018-02-05  7:01 UTC (permalink / raw)
  To: Rob Herring
  Cc: Mark Rutland, Lee Jones, Maxime Coquelin, Alexandre TORGUE,
	Michael Turquette, Stephen Boyd, devicetree, linux-arm-kernel,
	linux-kernel, linux-clk, gabriel.fernandez.st, Olivier BIDEAU

Hi Rob,

Thanks for reviewing.


On 02/05/2018 07:09 AM, Rob Herring wrote:
> On Fri, Feb 02, 2018 at 03:03:29PM +0100, gabriel.fernandez@st.com wrote:
>> From: Gabriel Fernandez <gabriel.fernandez@st.com>
>>
>> The RCC block is responsible of the management of the clock and reset
>> generation for the complete circuit.
>>
>> Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
>> ---
>>   .../devicetree/bindings/mfd/st,stm32-rcc.txt       | 85 ++++++++++++++++++++++
>>   1 file changed, 85 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
>>
>> diff --git a/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt b/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
>> new file mode 100644
>> index 0000000..28017a1
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
>> @@ -0,0 +1,85 @@
>> +STMicroelectronics STM32 Peripheral Reset Clock Controller
>> +==========================================================
>> +
>> +The RCC IP is both a reset and a clock controller.
>> +
>> +Please also refer to reset.txt for common reset controller binding usage.
>> +
>> +Please also refer to clock-bindings.txt for common clock controller
>> +binding usage.
>> +
>> +
>> +Required properties:
>> +- compatible: "simple-mfd", "syscon"
>
>> +- reg: should be register base and length as documented in the datasheet
>> +
>> +- Sub-nodes:
>> +  - compatible: "st,stm32mp1-rcc-clk"
>> +	- #clock-cells: 1, device nodes should specify the clock in their
>> +	  "clocks" property, containing a phandle to the clock device node,
>> +	  an index specifying the clock to use.
>> +
>> +  - compatible: "st,stm32mp1-rcc-rst"
>> +	- #reset-cells: Shall be 1
>> +
>> +Example:
>> +	rcc: rcc@50000000 {
>> +		compatible = "syscon", "simple-mfd";
>> +		reg = <0x50000000 0x1000>;
>> +
>> +		rcc_clk: rcc-clk@50000000 {
>> +			#clock-cells = <1>;
>> +			compatible = "st,stm32mp1-rcc-clk";
>> +		};
>> +
>> +		rcc_rst: rcc-reset@50000000 {
> You should not have the same unit-address twice.
>
> IMO, this should just be:
>
> 	rcc: rcc@50000000 {
> 		compatible = "st-stm32mp1-rcc";
> 		reg = <0x50000000 0x1000>;
> 		#clock-cells = <1>;
> 		#reset-cells = <1>;
> 	};
>
> There's no reason a node can't provide more than 1 function.
RCC is an dedicated IP for clocks and resets, but also for power 
management (patches will be sent later)
Then i need to probe 3 drivers with same IP.
It's also a way to avoid use of 'CLK_OF_DECLARE_DRIVER' and i need it to 
probe the 3th driver.

BR
Gabriel

>
>
>> +			#reset-cells = <1>;
>> +			compatible = "st,stm32mp1-rcc-rst";
>> +		};
>> +	};
>> +
>> +Specifying clocks
>> +=================
>> +
>> +All available clocks are defined as preprocessor macros in
>> +dt-bindings/clock/stm32mp1-clks.h header and can be used in device
>> +tree sources.
>> +
>> +Example:
>> +
>> +	/* Accessing DMA1 clock */
>> +	... {
>> +		clocks = <&rcc_clk DMA1>
>> +	};
>> +
>> +	/* Accessing SPI6 kernel clock */
>> +	... {
>> +		clocks = <&rcc_clk SPI6_K>
>> +	};
> Other than the path to header, the clock binding explains all this. No
> need to duplicate here.
ok
>> +
>> +Specifying softreset control of devices
>> +=======================================
>> +
>> +Device nodes should specify the reset channel required in their "resets"
>> +property, containing a phandle to the reset device node and an index specifying
>> +which channel to use.
>> +The index is the bit number within the RCC registers bank, starting from RCC
>> +base address.
>> +It is calculated as: index = register_offset / 4 * 32 + bit_offset.
>> +Where bit_offset is the bit offset within the register.
>> +
>> +For example on STM32MP1, for LTDC reset:
>> + ltdc = APB4_RSTSETR_offset / 4 * 32 + LTDC_bit_offset
>> +      = 0x180 / 4 * 32 + 0 = 3072
>> +
>> +The list of valid indices for STM32MP1 is available in:
>> +include/dt-bindings/reset-controller/stm32mp1-resets.h
>> +
>> +This file implements defines like:
>> +#define LTDC_R	3072
>> +
>> +example:
>> +
>> +	ltdc {
>> +		resets = <&rcc_rst LTDC_R>;
>> +	};
>> -- 
>> 1.9.1
>>

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

* Re: [PATCH 02/14] dt-bindings: clock: add STM32MP1 clocks
  2018-02-05  6:09     ` Rob Herring
@ 2018-02-05  7:02       ` Gabriel FERNANDEZ
  0 siblings, 0 replies; 22+ messages in thread
From: Gabriel FERNANDEZ @ 2018-02-05  7:02 UTC (permalink / raw)
  To: Rob Herring
  Cc: Mark Rutland, devicetree, Alexandre TORGUE, Olivier BIDEAU,
	Michael Turquette, Stephen Boyd, linux-kernel,
	gabriel.fernandez.st, Maxime Coquelin, Lee Jones, linux-clk,
	linux-arm-kernel



On 02/05/2018 07:09 AM, Rob Herring wrote:
> On Fri, Feb 02, 2018 at 03:03:30PM +0100, gabriel.fernandez@st.com wrote:
>> From: Gabriel Fernandez <gabriel.fernandez@st.com>
>>
>> This patch adds the clock binding entry for STM32MP1
>>
>> Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
>> ---
>>   include/dt-bindings/clock/stm32mp1-clks.h | 248 ++++++++++++++++++++++++++++++
>>   1 file changed, 248 insertions(+)
>>   create mode 100644 include/dt-bindings/clock/stm32mp1-clks.h
> You can squash this into the previous patch.
Ok Thanks!

BR
Gabriel

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

* Re: [PATCH 01/14] dt-bindings: Document STM32MP1 Reset Clock Controller (RCC) bindings
  2018-02-05  6:09     ` Rob Herring
  2018-02-05  7:01       ` Gabriel FERNANDEZ
@ 2018-02-05  7:15       ` Gabriel FERNANDEZ
  1 sibling, 0 replies; 22+ messages in thread
From: Gabriel FERNANDEZ @ 2018-02-05  7:15 UTC (permalink / raw)
  To: Rob Herring
  Cc: Mark Rutland, Lee Jones, Maxime Coquelin, Alexandre TORGUE,
	Michael Turquette, Stephen Boyd,
	devicetree-u79uwXL29TY76Z2rM5mHXA,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	linux-clk-u79uwXL29TY76Z2rM5mHXA,
	gabriel.fernandez.st-Re5JQEeQqe8AvxtiuMwx3w, Olivier BIDEAU



On 02/05/2018 07:09 AM, Rob Herring wrote:
> On Fri, Feb 02, 2018 at 03:03:29PM +0100, gabriel.fernandez@st.com wrote:
>> From: Gabriel Fernandez <gabriel.fernandez@st.com>
>>
>> The RCC block is responsible of the management of the clock and reset
>> generation for the complete circuit.
>>
>> Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
>> ---
>>   .../devicetree/bindings/mfd/st,stm32-rcc.txt       | 85 ++++++++++++++++++++++
>>   1 file changed, 85 insertions(+)
>>   create mode 100644 Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
>>
>> diff --git a/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt b/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
>> new file mode 100644
>> index 0000000..28017a1
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
>> @@ -0,0 +1,85 @@
>> +STMicroelectronics STM32 Peripheral Reset Clock Controller
>> +==========================================================
>> +
>> +The RCC IP is both a reset and a clock controller.
>> +
>> +Please also refer to reset.txt for common reset controller binding usage.
>> +
>> +Please also refer to clock-bindings.txt for common clock controller
>> +binding usage.
>> +
>> +
>> +Required properties:
>> +- compatible: "simple-mfd", "syscon"
>
>> +- reg: should be register base and length as documented in the datasheet
>> +
>> +- Sub-nodes:
>> +  - compatible: "st,stm32mp1-rcc-clk"
>> +	- #clock-cells: 1, device nodes should specify the clock in their
>> +	  "clocks" property, containing a phandle to the clock device node,
>> +	  an index specifying the clock to use.
>> +
>> +  - compatible: "st,stm32mp1-rcc-rst"
>> +	- #reset-cells: Shall be 1
>> +
>> +Example:
>> +	rcc: rcc@50000000 {
>> +		compatible = "syscon", "simple-mfd";
>> +		reg = <0x50000000 0x1000>;
>> +
>> +		rcc_clk: rcc-clk@50000000 {
>> +			#clock-cells = <1>;
>> +			compatible = "st,stm32mp1-rcc-clk";
>> +		};
>> +
>> +		rcc_rst: rcc-reset@50000000 {
> You should not have the same unit-address twice.
i can change if you want into:

         rcc: rcc@50000000 {
             compatible = "syscon", "simple-mfd";

             reg = <0x50000000 0x1000>;

             rcc_clk: rcc-clk {
                 #clock-cells = <1>;
                 compatible = "st,stm32mp1-rcc-clk";
             };

             rcc_rst: rcc-reset {
                 #reset-cells = <1>;
                 compatible = "st,stm32mp1-rcc-rst";
             };
BR
Gabriel

> IMO, this should just be:
>
> 	rcc: rcc@50000000 {
> 		compatible = "st-stm32mp1-rcc";
> 		reg = <0x50000000 0x1000>;
> 		#clock-cells = <1>;
> 		#reset-cells = <1>;
> 	};
>
> There's no reason a node can't provide more than 1 function.
>
>
>> +			#reset-cells = <1>;
>> +			compatible = "st,stm32mp1-rcc-rst";
>> +		};
>> +	};
>> +
>> +Specifying clocks
>> +=================
>> +
>> +All available clocks are defined as preprocessor macros in
>> +dt-bindings/clock/stm32mp1-clks.h header and can be used in device
>> +tree sources.
>> +
>> +Example:
>> +
>> +	/* Accessing DMA1 clock */
>> +	... {
>> +		clocks = <&rcc_clk DMA1>
>> +	};
>> +
>> +	/* Accessing SPI6 kernel clock */
>> +	... {
>> +		clocks = <&rcc_clk SPI6_K>
>> +	};
> Other than the path to header, the clock binding explains all this. No
> need to duplicate here.
>
>> +
>> +Specifying softreset control of devices
>> +=======================================
>> +
>> +Device nodes should specify the reset channel required in their "resets"
>> +property, containing a phandle to the reset device node and an index specifying
>> +which channel to use.
>> +The index is the bit number within the RCC registers bank, starting from RCC
>> +base address.
>> +It is calculated as: index = register_offset / 4 * 32 + bit_offset.
>> +Where bit_offset is the bit offset within the register.
>> +
>> +For example on STM32MP1, for LTDC reset:
>> + ltdc = APB4_RSTSETR_offset / 4 * 32 + LTDC_bit_offset
>> +      = 0x180 / 4 * 32 + 0 = 3072
>> +
>> +The list of valid indices for STM32MP1 is available in:
>> +include/dt-bindings/reset-controller/stm32mp1-resets.h
>> +
>> +This file implements defines like:
>> +#define LTDC_R	3072
>> +
>> +example:
>> +
>> +	ltdc {
>> +		resets = <&rcc_rst LTDC_R>;
>> +	};
>> -- 
>> 1.9.1
>>

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

* Re: [PATCH 01/14] dt-bindings: Document STM32MP1 Reset Clock Controller (RCC) bindings
  2018-02-05  7:01       ` Gabriel FERNANDEZ
@ 2018-02-07 18:03         ` Rob Herring
  2018-02-13 14:36           ` Gabriel FERNANDEZ
  0 siblings, 1 reply; 22+ messages in thread
From: Rob Herring @ 2018-02-07 18:03 UTC (permalink / raw)
  To: Gabriel FERNANDEZ
  Cc: Mark Rutland, Lee Jones, Maxime Coquelin, Alexandre TORGUE,
	Michael Turquette, Stephen Boyd, devicetree, linux-arm-kernel,
	linux-kernel, linux-clk, gabriel.fernandez.st, Olivier BIDEAU

On Mon, Feb 5, 2018 at 1:01 AM, Gabriel FERNANDEZ
<gabriel.fernandez@st.com> wrote:
> Hi Rob,
>
> Thanks for reviewing.
>
>
> On 02/05/2018 07:09 AM, Rob Herring wrote:
>> On Fri, Feb 02, 2018 at 03:03:29PM +0100, gabriel.fernandez@st.com wrote:
>>> From: Gabriel Fernandez <gabriel.fernandez@st.com>
>>>
>>> The RCC block is responsible of the management of the clock and reset
>>> generation for the complete circuit.
>>>
>>> Signed-off-by: Gabriel Fernandez <gabriel.fernandez@st.com>
>>> ---
>>>   .../devicetree/bindings/mfd/st,stm32-rcc.txt       | 85 ++++++++++++++++++++++
>>>   1 file changed, 85 insertions(+)
>>>   create mode 100644 Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
>>>
>>> diff --git a/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt b/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
>>> new file mode 100644
>>> index 0000000..28017a1
>>> --- /dev/null
>>> +++ b/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
>>> @@ -0,0 +1,85 @@
>>> +STMicroelectronics STM32 Peripheral Reset Clock Controller
>>> +==========================================================
>>> +
>>> +The RCC IP is both a reset and a clock controller.
>>> +
>>> +Please also refer to reset.txt for common reset controller binding usage.
>>> +
>>> +Please also refer to clock-bindings.txt for common clock controller
>>> +binding usage.
>>> +
>>> +
>>> +Required properties:
>>> +- compatible: "simple-mfd", "syscon"
>>
>>> +- reg: should be register base and length as documented in the datasheet
>>> +
>>> +- Sub-nodes:
>>> +  - compatible: "st,stm32mp1-rcc-clk"
>>> +    - #clock-cells: 1, device nodes should specify the clock in their
>>> +      "clocks" property, containing a phandle to the clock device node,
>>> +      an index specifying the clock to use.
>>> +
>>> +  - compatible: "st,stm32mp1-rcc-rst"
>>> +    - #reset-cells: Shall be 1
>>> +
>>> +Example:
>>> +    rcc: rcc@50000000 {
>>> +            compatible = "syscon", "simple-mfd";
>>> +            reg = <0x50000000 0x1000>;
>>> +
>>> +            rcc_clk: rcc-clk@50000000 {
>>> +                    #clock-cells = <1>;
>>> +                    compatible = "st,stm32mp1-rcc-clk";
>>> +            };
>>> +
>>> +            rcc_rst: rcc-reset@50000000 {
>> You should not have the same unit-address twice.
>>
>> IMO, this should just be:
>>
>>       rcc: rcc@50000000 {
>>               compatible = "st-stm32mp1-rcc";
>>               reg = <0x50000000 0x1000>;
>>               #clock-cells = <1>;
>>               #reset-cells = <1>;
>>       };
>>
>> There's no reason a node can't provide more than 1 function.
> RCC is an dedicated IP for clocks and resets, but also for power
> management (patches will be sent later)

If there's additional functions, they should be part of the binding
now, not later. bindings should not unnecessarily evolve.

> Then i need to probe 3 drivers with same IP.

Drivers and DT nodes don't have to be 1-1. A parent driver can create
additional child devices.

Also, looking at your existing bindings for RCC IP, it is done as I suggested.

> It's also a way to avoid use of 'CLK_OF_DECLARE_DRIVER' and i need it to
> probe the 3th driver.

Sounds like a Linux problem, not a DT issue.

Rob

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

* Re: [PATCH 01/14] dt-bindings: Document STM32MP1 Reset Clock Controller (RCC) bindings
  2018-02-07 18:03         ` Rob Herring
@ 2018-02-13 14:36           ` Gabriel FERNANDEZ
  0 siblings, 0 replies; 22+ messages in thread
From: Gabriel FERNANDEZ @ 2018-02-13 14:36 UTC (permalink / raw)
  To: Rob Herring
  Cc: Mark Rutland, Lee Jones, Maxime Coquelin, Alexandre TORGUE,
	Michael Turquette, Stephen Boyd, devicetree, linux-arm-kernel,
	linux-kernel, linux-clk, gabriel.fernandez.st, Olivier BIDEAU



On 02/07/2018 07:03 PM, Rob Herring wrote:
> On Mon, Feb 5, 2018 at 1:01 AM, Gabriel FERNANDEZ
> <gabriel.fernandez@st.com>  wrote:
>> Hi Rob,
>>
>> Thanks for reviewing.
>>
>>
>> On 02/05/2018 07:09 AM, Rob Herring wrote:
>>> On Fri, Feb 02, 2018 at 03:03:29PM +0100,gabriel.fernandez@st.com  wrote:
>>>> From: Gabriel Fernandez<gabriel.fernandez@st.com>
>>>>
>>>> The RCC block is responsible of the management of the clock and reset
>>>> generation for the complete circuit.
>>>>
>>>> Signed-off-by: Gabriel Fernandez<gabriel.fernandez@st.com>
>>>> ---
>>>>    .../devicetree/bindings/mfd/st,stm32-rcc.txt       | 85 ++++++++++++++++++++++
>>>>    1 file changed, 85 insertions(+)
>>>>    create mode 100644 Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
>>>>
>>>> diff --git a/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt b/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
>>>> new file mode 100644
>>>> index 0000000..28017a1
>>>> --- /dev/null
>>>> +++ b/Documentation/devicetree/bindings/mfd/st,stm32-rcc.txt
>>>> @@ -0,0 +1,85 @@
>>>> +STMicroelectronics STM32 Peripheral Reset Clock Controller
>>>> +==========================================================
>>>> +
>>>> +The RCC IP is both a reset and a clock controller.
>>>> +
>>>> +Please also refer to reset.txt for common reset controller binding usage.
>>>> +
>>>> +Please also refer to clock-bindings.txt for common clock controller
>>>> +binding usage.
>>>> +
>>>> +
>>>> +Required properties:
>>>> +- compatible: "simple-mfd", "syscon"
>>>> +- reg: should be register base and length as documented in the datasheet
>>>> +
>>>> +- Sub-nodes:
>>>> +  - compatible: "st,stm32mp1-rcc-clk"
>>>> +    - #clock-cells: 1, device nodes should specify the clock in their
>>>> +      "clocks" property, containing a phandle to the clock device node,
>>>> +      an index specifying the clock to use.
>>>> +
>>>> +  - compatible: "st,stm32mp1-rcc-rst"
>>>> +    - #reset-cells: Shall be 1
>>>> +
>>>> +Example:
>>>> +    rcc: rcc@50000000 {
>>>> +            compatible = "syscon", "simple-mfd";
>>>> +            reg = <0x50000000 0x1000>;
>>>> +
>>>> +            rcc_clk: rcc-clk@50000000 {
>>>> +                    #clock-cells = <1>;
>>>> +                    compatible = "st,stm32mp1-rcc-clk";
>>>> +            };
>>>> +
>>>> +            rcc_rst: rcc-reset@50000000 {
>>> You should not have the same unit-address twice.
>>>
>>> IMO, this should just be:
>>>
>>>        rcc: rcc@50000000 {
>>>                compatible = "st-stm32mp1-rcc";
>>>                reg = <0x50000000 0x1000>;
>>>                #clock-cells = <1>;
>>>                #reset-cells = <1>;
>>>        };
>>>
>>> There's no reason a node can't provide more than 1 function.
>> RCC is an dedicated IP for clocks and resets, but also for power
>> management (patches will be sent later)
> If there's additional functions, they should be part of the binding
> now, not later. bindings should not unnecessarily evolve.
Yes you're right i will do it.
>> Then i need to probe 3 drivers with same IP.
> Drivers and DT nodes don't have to be 1-1. A parent driver can create
> additional child devices.
>
> Also, looking at your existing bindings for RCC IP, it is done as I suggested.
>
>> It's also a way to avoid use of 'CLK_OF_DECLARE_DRIVER' and i need it to
>> probe the 3th driver.
> Sounds like a Linux problem, not a DT issue.
>
> Rob
RCC is an IP block wich exposed multiple functionalities (clock, reset, 
power management),
mfd should be the best solution to populate each functionality in 
natural way,
and to access to registers ?

Gabriel



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

end of thread, other threads:[~2018-02-13 14:36 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-02-02 14:03 [PATCH 00/14] Introduce STM32MP1 clock driver gabriel.fernandez-qxv4g6HH51o
2018-02-02 14:03 ` [PATCH 02/14] dt-bindings: clock: add STM32MP1 clocks gabriel.fernandez
     [not found]   ` <1517580222-23301-3-git-send-email-gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
2018-02-05  6:09     ` Rob Herring
2018-02-05  7:02       ` Gabriel FERNANDEZ
2018-02-02 14:03 ` [PATCH 04/14] clk: stm32mp1: add MP1 gate for osc hse/hsi/csi oscillators gabriel.fernandez
     [not found] ` <1517580222-23301-1-git-send-email-gabriel.fernandez-qxv4g6HH51o@public.gmane.org>
2018-02-02 14:03   ` [PATCH 01/14] dt-bindings: Document STM32MP1 Reset Clock Controller (RCC) bindings gabriel.fernandez-qxv4g6HH51o
2018-02-05  6:09     ` Rob Herring
2018-02-05  7:01       ` Gabriel FERNANDEZ
2018-02-07 18:03         ` Rob Herring
2018-02-13 14:36           ` Gabriel FERNANDEZ
2018-02-05  7:15       ` Gabriel FERNANDEZ
2018-02-02 14:03   ` [PATCH 03/14] clk: stm32mp1: Introduce STM32MP1 clock driver gabriel.fernandez-qxv4g6HH51o
2018-02-02 14:03   ` [PATCH 05/14] clk: stm32mp1: add Source Clocks for PLLs gabriel.fernandez-qxv4g6HH51o
2018-02-02 14:03   ` [PATCH 06/14] clk: stm32mp1: add PLL clocks gabriel.fernandez-qxv4g6HH51o
2018-02-02 14:03   ` [PATCH 07/14] clk: stm32mp1: add Post-dividers for PLL gabriel.fernandez-qxv4g6HH51o
2018-02-02 14:03   ` [PATCH 08/14] clk: stm32mp1: add Sub System clocks gabriel.fernandez-qxv4g6HH51o
2018-02-02 14:03   ` [PATCH 11/14] clk: stm32mp1: add Kernel clocks gabriel.fernandez-qxv4g6HH51o
2018-02-02 14:03   ` [PATCH 12/14] clk: stm32mp1: add RTC clock gabriel.fernandez-qxv4g6HH51o
2018-02-02 14:03 ` [PATCH 09/14] clk: stm32mp1: add Kernel timers gabriel.fernandez
2018-02-02 14:03 ` [PATCH 10/14] clk: stm32mp1: add Peripheral clocks gabriel.fernandez
2018-02-02 14:03 ` [PATCH 13/14] clk: stm32mp1: add MCO clocks gabriel.fernandez
2018-02-02 14:03 ` [PATCH 14/14] clk: stm32mp1: add Debug clocks gabriel.fernandez

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).