linux-clk.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v4 00/42] ep93xx device tree conversion
@ 2023-09-15  8:10 Nikita Shubin via B4 Relay
  2023-09-15  8:10 ` [PATCH v4 03/42] dt-bindings: clock: Add Cirrus EP93xx Nikita Shubin via B4 Relay
                   ` (3 more replies)
  0 siblings, 4 replies; 7+ messages in thread
From: Nikita Shubin via B4 Relay @ 2023-09-15  8:10 UTC (permalink / raw)
  To: Hartley Sweeten, Alexander Sverdlin, Russell King,
	Lukasz Majewski, Linus Walleij, Bartosz Golaszewski,
	Andy Shevchenko, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Nikita Shubin,
	Sebastian Reichel, Daniel Lezcano, Thomas Gleixner,
	Alessandro Zummo, Alexandre Belloni, Wim Van Sebroeck,
	Guenter Roeck, Thierry Reding, Uwe Kleine-König, Mark Brown,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Vinod Koul, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Damien Le Moal, Sergey Shtylyov,
	Dmitry Torokhov, Liam Girdwood, Jaroslav Kysela, Takashi Iwai
  Cc: linux-arm-kernel, linux-kernel, linux-gpio, linux-clk, devicetree,
	linux-pm, linux-rtc, linux-watchdog, linux-pwm, linux-spi, netdev,
	dmaengine, linux-mtd, linux-ide, linux-input, alsa-devel,
	Arnd Bergmann, Bartosz Golaszewski, Krzysztof Kozlowski,
	Andy Shevchenko, Andrew Lunn

This series aims to convert ep93xx from platform to full device tree support.

The main goal is to receive ACK's to take it via Arnd's arm-soc branch.

Major changes:
- drop newline at the end from each YAML files
- rename dma and clk bindings headers to match first compatible
- shrink SoC exported functions number to only 2
- dropped some ep93xx_pata fixes from these series
- dropped m48t86 stuff from these series

Bit thanks to Andy Shevchenko for thorough review.

Some parts are were sent in advance, so these series depends on the
following:

Link: https://lore.kernel.org/all/20230823-m48t86_device_tree-v2-0-21ff275f949d@maquefel.me/
Link: https://lore.kernel.org/all/20230823-ep93xx_pata_fixes-v1-0-d7e7229be148@maquefel.me/

---
Changes in v4:

- gpio: ep93xx: split device in multiple
  - s/generic_handle_irq/generic_handle_domain_irq/
  - s/int offset/irq_hw_number_t offset/ though now it looks a bit odd to me
  - drop i = 0
  - drop 'error'
  - use dev_err_probe withour printing devname once again

dt-bindings: clock: Add Cirrus EP93xx
  - renamed cirrus,ep93xx-clock.h -> cirrus,ep9301-clk.h

clk: ep93xx: add DT support for Cirrus EP93xx
  - drop unused includes
  - use .name only for xtali, pll1, pll2 parents
  - convert // to /*
  - pass clk_parent_data instead of char* clock name

dt-bindings: pinctrl: Add Cirrus EP93xx
  - s/additionalProperties/unevaluatedProperties/

dt-bindings: soc: Add Cirrus EP93xx
  - move syscon to soc directory
  - add vendor prefix
  - make reboot same style as pinctrl, clk
  - use absolute path for ref
  - expand example

soc: Add SoC driver for Cirrus ep93xx
  - s/0xf0000000/GENMASK(31, 28)/
  - s/ret/ep93xx_chip_revision(map)/
  - drop symbol exports
  - convert to platform driver

dt-bindings: rtc: Add Cirrus EP93xx
  - allOf: with $ref to rtc.yaml
  - s/additionalProperties/unevaluatedProperties/

dt-bindings: watchdog: Add Cirrus EP93x
  - drop description
  - reword

power: reset: Add a driver for the ep93xx reset
  - lets use 'GPL-2.0+' instead of '(GPL-2.0)'
  - s/of_device/of/
  - drop mdelay with warning
  - return 0 at the end

net: cirrus: add DT support for Cirrus EP93xx
  - fix leaking np

mtd: nand: add support for ts72xx
  - +bits.h
  - drop comment
  - ok to fwnode_get_next_child_node
  - use goto to put handle and nand and report error

ARM: dts: add Cirrus EP93XX SoC .dtsi
  - add simple-bus for ebi, as we don't require to setup anything
  - add arm,pl011 compatible to uart nodes
  - drop i2c-gpio, as it's isn't used anywhere

ARM: dts: ep93xx: add ts7250 board
  - generic node name for temperature-sensor
  - drop i2c
  - move nand, rtc, watchdog to ebi node
 
- Link to v3: https://lore.kernel.org/r/20230605-ep93xx-v3-0-3d63a5f1103e@maquefel.me

---
Alexander Sverdlin (2):
      ARM: dts: ep93xx: Add EDB9302 DT
      ASoC: cirrus: edb93xx: Delete driver

Nikita Shubin (40):
      gpio: ep93xx: split device in multiple
      ARM: ep93xx: add swlocked prototypes
      dt-bindings: clock: Add Cirrus EP93xx
      clk: ep93xx: add DT support for Cirrus EP93xx
      dt-bindings: pinctrl: Add Cirrus EP93xx
      pinctrl: add a Cirrus ep93xx SoC pin controller
      dt-bindings: power: reset: Add ep93xx reset
      power: reset: Add a driver for the ep93xx reset
      dt-bindings: soc: Add Cirrus EP93xx
      soc: Add SoC driver for Cirrus ep93xx
      dt-bindings: timers: Add Cirrus EP93xx
      clocksource: ep93xx: Add driver for Cirrus Logic EP93xx
      dt-bindings: rtc: Add Cirrus EP93xx
      rtc: ep93xx: add DT support for Cirrus EP93xx
      dt-bindings: watchdog: Add Cirrus EP93x
      watchdog: ep93xx: add DT support for Cirrus EP93xx
      dt-bindings: pwm: Add Cirrus EP93xx
      pwm: ep93xx: add DT support for Cirrus EP93xx
      dt-bindings: spi: Add Cirrus EP93xx
      spi: ep93xx: add DT support for Cirrus EP93xx
      dt-bindings: net: Add Cirrus EP93xx
      net: cirrus: add DT support for Cirrus EP93xx
      dt-bindings: dma: Add Cirrus EP93xx
      dma: cirrus: add DT support for Cirrus EP93xx
      dt-bindings: mtd: Add ts7200 nand-controller
      mtd: nand: add support for ts72xx
      dt-bindings: ata: Add Cirrus EP93xx
      ata: pata_ep93xx: add device tree support
      dt-bindings: input: Add Cirrus EP93xx keypad
      input: keypad: ep93xx: add DT support for Cirrus EP93xx
      dt-bindings: wdt: Add ts72xx
      wdt: ts72xx: add DT support for ts72xx
      gpio: ep93xx: add DT support for gpio-ep93xx
      ARM: dts: add Cirrus EP93XX SoC .dtsi
      ARM: dts: ep93xx: add ts7250 board
      ARM: ep93xx: DT for the Cirrus ep93xx SoC platforms
      pwm: ep93xx: drop legacy pinctrl
      ata: pata_ep93xx: remove legacy pinctrl use
      ARM: ep93xx: delete all boardfiles
      ARM: ep93xx: soc: drop defines

 .../bindings/arm/cirrus/cirrus,ep9301.yaml         |   38 +
 .../bindings/ata/cirrus,ep9312-pata.yaml           |   42 +
 .../bindings/clock/cirrus,ep9301-clk.yaml          |   46 +
 .../bindings/dma/cirrus,ep9301-dma-m2m.yaml        |   69 +
 .../bindings/dma/cirrus,ep9301-dma-m2p.yaml        |  121 ++
 .../bindings/input/cirrus,ep9307-keypad.yaml       |   87 ++
 .../devicetree/bindings/mtd/technologic,nand.yaml  |   45 +
 .../devicetree/bindings/net/cirrus,ep9301-eth.yaml |   59 +
 .../bindings/pinctrl/cirrus,ep9301-pinctrl.yaml    |   57 +
 .../bindings/power/reset/cirrus,ep9301-reboot.yaml |   34 +
 .../devicetree/bindings/pwm/cirrus,ep9301-pwm.yaml |   46 +
 .../devicetree/bindings/rtc/cirrus,ep9301-rtc.yaml |   42 +
 .../bindings/soc/cirrus/cirrus,ep9301-syscon.yaml  |   71 +
 .../devicetree/bindings/spi/cirrus,ep9301-spi.yaml |   61 +
 .../bindings/timer/cirrus,ep9301-timer.yaml        |   49 +
 .../bindings/watchdog/cirrus,ep9301-wdt.yaml       |   42 +
 .../bindings/watchdog/technologic,ts7200-wdt.yaml  |   45 +
 arch/arm/Makefile                                  |    1 -
 arch/arm/boot/dts/cirrus/Makefile                  |    4 +
 arch/arm/boot/dts/cirrus/ep93xx-bk3.dts            |  124 ++
 arch/arm/boot/dts/cirrus/ep93xx-edb9302.dts        |  180 +++
 arch/arm/boot/dts/cirrus/ep93xx-ts7250.dts         |  143 ++
 arch/arm/boot/dts/cirrus/ep93xx.dtsi               |  454 +++++++
 arch/arm/mach-ep93xx/Kconfig                       |   20 +-
 arch/arm/mach-ep93xx/Makefile                      |   11 -
 arch/arm/mach-ep93xx/clock.c                       |  733 ----------
 arch/arm/mach-ep93xx/core.c                        | 1017 --------------
 arch/arm/mach-ep93xx/dma.c                         |  114 --
 arch/arm/mach-ep93xx/edb93xx.c                     |  344 -----
 arch/arm/mach-ep93xx/ep93xx-regs.h                 |   38 -
 arch/arm/mach-ep93xx/gpio-ep93xx.h                 |  111 --
 arch/arm/mach-ep93xx/hardware.h                    |   25 -
 arch/arm/mach-ep93xx/irqs.h                        |   76 --
 arch/arm/mach-ep93xx/platform.h                    |   42 -
 arch/arm/mach-ep93xx/soc.h                         |  212 ---
 arch/arm/mach-ep93xx/ts72xx.c                      |  422 ------
 arch/arm/mach-ep93xx/ts72xx.h                      |   94 --
 arch/arm/mach-ep93xx/vision_ep9307.c               |  311 -----
 drivers/ata/pata_ep93xx.c                          |   33 +-
 drivers/clk/Kconfig                                |    8 +
 drivers/clk/Makefile                               |    1 +
 drivers/clk/clk-ep93xx.c                           |  753 +++++++++++
 drivers/clocksource/Kconfig                        |   11 +
 drivers/clocksource/Makefile                       |    1 +
 .../clocksource}/timer-ep93xx.c                    |  155 ++-
 drivers/dma/ep93xx_dma.c                           |  125 +-
 drivers/gpio/gpio-ep93xx.c                         |  331 ++---
 drivers/input/keyboard/ep93xx_keypad.c             |   74 +-
 drivers/mtd/nand/raw/Kconfig                       |    7 +
 drivers/mtd/nand/raw/Makefile                      |    1 +
 drivers/mtd/nand/raw/technologic-nand-controller.c |  166 +++
 drivers/net/ethernet/cirrus/ep93xx_eth.c           |   63 +-
 drivers/pinctrl/Kconfig                            |    7 +
 drivers/pinctrl/Makefile                           |    1 +
 drivers/pinctrl/pinctrl-ep93xx.c                   | 1429 ++++++++++++++++++++
 drivers/power/reset/Kconfig                        |   10 +
 drivers/power/reset/Makefile                       |    1 +
 drivers/power/reset/ep93xx-restart.c               |   85 ++
 drivers/pwm/pwm-ep93xx.c                           |   26 +-
 drivers/rtc/rtc-ep93xx.c                           |    8 +
 drivers/soc/Kconfig                                |    1 +
 drivers/soc/Makefile                               |    1 +
 drivers/soc/cirrus/Kconfig                         |   12 +
 drivers/soc/cirrus/Makefile                        |    2 +
 drivers/soc/cirrus/soc-ep93xx.c                    |  215 +++
 drivers/spi/spi-ep93xx.c                           |   28 +-
 drivers/watchdog/ep93xx_wdt.c                      |    8 +
 drivers/watchdog/ts72xx_wdt.c                      |    8 +
 include/dt-bindings/clock/cirrus,ep9301-clk.h      |   41 +
 include/dt-bindings/dma/cirrus,ep93xx-dma.h        |   26 +
 include/linux/platform_data/dma-ep93xx.h           |   25 +-
 include/linux/platform_data/eth-ep93xx.h           |   10 -
 include/linux/platform_data/keypad-ep93xx.h        |   32 -
 include/linux/soc/cirrus/ep93xx.h                  |   29 +-
 sound/soc/cirrus/Kconfig                           |    9 -
 sound/soc/cirrus/Makefile                          |    4 -
 sound/soc/cirrus/edb93xx.c                         |  117 --
 77 files changed, 5126 insertions(+), 4168 deletions(-)
---
base-commit: bdc09c8e8b16d494ccd1c56e903e78dd76455a35
change-id: 20230605-ep93xx-01c76317e2d2

Best regards,
-- 
Nikita Shubin <nikita.shubin@maquefel.me>


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

* [PATCH v4 03/42] dt-bindings: clock: Add Cirrus EP93xx
  2023-09-15  8:10 [PATCH v4 00/42] ep93xx device tree conversion Nikita Shubin via B4 Relay
@ 2023-09-15  8:10 ` Nikita Shubin via B4 Relay
  2023-09-15 10:36   ` Krzysztof Kozlowski
  2023-09-15  8:10 ` [PATCH v4 04/42] clk: ep93xx: add DT support for " Nikita Shubin via B4 Relay
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 7+ messages in thread
From: Nikita Shubin via B4 Relay @ 2023-09-15  8:10 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Nikita Shubin, Alexander Sverdlin
  Cc: linux-clk, devicetree, linux-kernel, Arnd Bergmann,
	Alexander Sverdlin

From: Nikita Shubin <nikita.shubin@maquefel.me>

Add device tree bindings for the Cirrus Logic EP93xx clock block
used in these SoCs.

Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me>
---
 .../bindings/clock/cirrus,ep9301-clk.yaml          | 46 ++++++++++++++++++++++
 include/dt-bindings/clock/cirrus,ep9301-clk.h      | 41 +++++++++++++++++++
 2 files changed, 87 insertions(+)

diff --git a/Documentation/devicetree/bindings/clock/cirrus,ep9301-clk.yaml b/Documentation/devicetree/bindings/clock/cirrus,ep9301-clk.yaml
new file mode 100644
index 000000000000..111e016601fb
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/cirrus,ep9301-clk.yaml
@@ -0,0 +1,46 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/clock/cirrus,ep9301-clk.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Cirrus Logic ep93xx SoC's clock controller
+
+maintainers:
+  - Nikita Shubin <nikita.shubin@maquefel.me>
+  - Alexander Sverdlin <alexander.sverdlin@gmail.com>
+
+properties:
+  compatible:
+    oneOf:
+      - const: cirrus,ep9301-clk
+      - items:
+          - enum:
+              - cirrus,ep9302-clk
+              - cirrus,ep9307-clk
+              - cirrus,ep9312-clk
+              - cirrus,ep9315-clk
+          - const: cirrus,ep9301-clk
+
+  "#clock-cells":
+    const: 1
+
+  clocks:
+    items:
+      - description: reference clock
+
+required:
+  - compatible
+  - "#clock-cells"
+  - clocks
+
+additionalProperties: false
+
+examples:
+  - |
+    clock-controller {
+      compatible = "cirrus,ep9301-clk";
+      #clock-cells = <1>;
+      clocks = <&xtali>;
+    };
+...
diff --git a/include/dt-bindings/clock/cirrus,ep9301-clk.h b/include/dt-bindings/clock/cirrus,ep9301-clk.h
new file mode 100644
index 000000000000..3cd053c0fdea
--- /dev/null
+++ b/include/dt-bindings/clock/cirrus,ep9301-clk.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
+#ifndef DT_BINDINGS_CIRRUS_EP93XX_CLOCK_H
+#define DT_BINDINGS_CIRRUS_EP93XX_CLOCK_H
+
+#define EP93XX_CLK_UART1	0
+#define EP93XX_CLK_UART2	1
+#define EP93XX_CLK_UART3	2
+
+#define EP93XX_CLK_ADC		3
+#define EP93XX_CLK_ADC_EN	4
+
+#define EP93XX_CLK_KEYPAD   5
+
+#define EP93XX_CLK_VIDEO	6
+
+#define EP93XX_CLK_I2S_MCLK	7
+#define EP93XX_CLK_I2S_SCLK	8
+#define EP93XX_CLK_I2S_LRCLK	9
+
+#define EP93XX_CLK_UART		10
+#define EP93XX_CLK_SPI		11
+#define EP93XX_CLK_PWM		12
+#define EP93XX_CLK_USB		13
+
+#define EP93XX_CLK_M2M0		14
+#define EP93XX_CLK_M2M1		15
+
+#define EP93XX_CLK_M2P0		16
+#define EP93XX_CLK_M2P1		17
+#define EP93XX_CLK_M2P2		18
+#define EP93XX_CLK_M2P3		19
+#define EP93XX_CLK_M2P4		20
+#define EP93XX_CLK_M2P5		21
+#define EP93XX_CLK_M2P6		22
+#define EP93XX_CLK_M2P7		23
+#define EP93XX_CLK_M2P8		24
+#define EP93XX_CLK_M2P9		25
+
+#define EP93XX_CLK_END      26
+
+#endif /* DT_BINDINGS_CIRRUS_EP93XX_CLOCK_H */

-- 
2.39.2


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

* [PATCH v4 04/42] clk: ep93xx: add DT support for Cirrus EP93xx
  2023-09-15  8:10 [PATCH v4 00/42] ep93xx device tree conversion Nikita Shubin via B4 Relay
  2023-09-15  8:10 ` [PATCH v4 03/42] dt-bindings: clock: Add Cirrus EP93xx Nikita Shubin via B4 Relay
@ 2023-09-15  8:10 ` Nikita Shubin via B4 Relay
  2023-10-24  2:50   ` Stephen Boyd
  2023-09-18  7:39 ` [PATCH v4 00/42] ep93xx device tree conversion Andy Shevchenko
  2023-10-15 21:17 ` (subset) " Alexandre Belloni
  3 siblings, 1 reply; 7+ messages in thread
From: Nikita Shubin via B4 Relay @ 2023-09-15  8:10 UTC (permalink / raw)
  To: Michael Turquette, Stephen Boyd
  Cc: linux-kernel, linux-clk, Arnd Bergmann, Alexander Sverdlin

From: Nikita Shubin <nikita.shubin@maquefel.me>

Rewrite EP93xx clock driver located in arch/arm/mach-ep93xx/clock.c
trying to do everything the device tree way:

- provide clock acces via of
- drop clk_hw_register_clkdev
- drop init code and use builtin_platform_driver_probe

Also moved all clocks not accessed via device tree to syscon.

Co-developed-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
Signed-off-by: Alexander Sverdlin <alexander.sverdlin@gmail.com>
Signed-off-by: Nikita Shubin <nikita.shubin@maquefel.me>
---
 drivers/clk/Kconfig      |   8 +
 drivers/clk/Makefile     |   1 +
 drivers/clk/clk-ep93xx.c | 753 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 762 insertions(+)

diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig
index 6b3b424addab..abd8e04a33aa 100644
--- a/drivers/clk/Kconfig
+++ b/drivers/clk/Kconfig
@@ -218,6 +218,14 @@ config COMMON_CLK_EN7523
 	  This driver provides the fixed clocks and gates present on Airoha
 	  ARM silicon.
 
+config COMMON_CLK_EP93XX
+	bool "Clock driver for Cirrus Logic ep93xx SoC"
+	depends on ARCH_EP93XX || COMPILE_TEST
+	select MFD_SYSCON
+	select REGMAP
+	help
+	  This driver supports the SoC clocks on the Cirrus Logic ep93xx.
+
 config COMMON_CLK_FSL_FLEXSPI
 	tristate "Clock driver for FlexSPI on Layerscape SoCs"
 	depends on ARCH_LAYERSCAPE || COMPILE_TEST
diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile
index 7cb000549b61..6049a2073a25 100644
--- a/drivers/clk/Makefile
+++ b/drivers/clk/Makefile
@@ -29,6 +29,7 @@ obj-$(CONFIG_COMMON_CLK_CDCE706)	+= clk-cdce706.o
 obj-$(CONFIG_COMMON_CLK_CDCE925)	+= clk-cdce925.o
 obj-$(CONFIG_ARCH_CLPS711X)		+= clk-clps711x.o
 obj-$(CONFIG_COMMON_CLK_CS2000_CP)	+= clk-cs2000-cp.o
+obj-$(CONFIG_COMMON_CLK_EP93XX)		+= clk-ep93xx.o
 obj-$(CONFIG_ARCH_SPARX5)		+= clk-sparx5.o
 obj-$(CONFIG_COMMON_CLK_EN7523)		+= clk-en7523.o
 obj-$(CONFIG_COMMON_CLK_FIXED_MMIO)	+= clk-fixed-mmio.o
diff --git a/drivers/clk/clk-ep93xx.c b/drivers/clk/clk-ep93xx.c
new file mode 100644
index 000000000000..e8d3bd595255
--- /dev/null
+++ b/drivers/clk/clk-ep93xx.c
@@ -0,0 +1,753 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Clock control for Cirrus EP93xx chips.
+ * Copyright (C) 2021 Nikita Shubin <nikita.shubin@maquefel.me>
+ *
+ * Based on a rewrite of arch/arm/mach-ep93xx/clock.c:
+ * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
+ */
+#define pr_fmt(fmt) "ep93xx " KBUILD_MODNAME ": " fmt
+
+#include <linux/bits.h>
+#include <linux/clk-provider.h>
+#include <linux/clk.h>
+#include <linux/mfd/syscon.h>
+#include <linux/of_address.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/spinlock.h>
+#include <linux/sys_soc.h>
+
+#include <linux/soc/cirrus/ep93xx.h>
+#include <dt-bindings/clock/cirrus,ep9301-clk.h>
+
+#include <asm/div64.h>
+
+#define EP93XX_EXT_RTC_RATE		32768
+
+#define EP93XX_SYSCON_POWER_STATE	0x00
+#define EP93XX_SYSCON_PWRCNT		0x04
+#define EP93XX_SYSCON_PWRCNT_UARTBAUD	BIT(29)
+#define EP93XX_SYSCON_PWRCNT_USH_EN	28
+#define EP93XX_SYSCON_PWRCNT_DMA_M2M1	27
+#define EP93XX_SYSCON_PWRCNT_DMA_M2M0	26
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P8	25
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P9	24
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P6	23
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P7	22
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P4	21
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P5	20
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P2	19
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P3	18
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P0	17
+#define EP93XX_SYSCON_PWRCNT_DMA_M2P1	16
+#define EP93XX_SYSCON_DEVCFG		0x80
+#define EP93XX_SYSCON_DEVCFG_U3EN	24
+#define EP93XX_SYSCON_DEVCFG_U2EN	20
+#define EP93XX_SYSCON_DEVCFG_U1EN	18
+#define EP93XX_SYSCON_VIDCLKDIV		0x84
+#define EP93XX_SYSCON_CLKDIV_ENABLE	15
+#define EP93XX_SYSCON_CLKDIV_ESEL	BIT(14)
+#define EP93XX_SYSCON_CLKDIV_PSEL	BIT(13)
+#define EP93XX_SYSCON_CLKDIV_MASK	GENMASK(14, 13)
+#define EP93XX_SYSCON_CLKDIV_PDIV_SHIFT	8
+#define EP93XX_SYSCON_I2SCLKDIV		0x8c
+#define EP93XX_SYSCON_I2SCLKDIV_SENA	31
+#define EP93XX_SYSCON_I2SCLKDIV_ORIDE	BIT(29)
+#define EP93XX_SYSCON_I2SCLKDIV_SPOL	BIT(19)
+#define EP93XX_I2SCLKDIV_SDIV		(1 << 16)
+#define EP93XX_I2SCLKDIV_LRDIV32	(0 << 17)
+#define EP93XX_I2SCLKDIV_LRDIV64	(1 << 17)
+#define EP93XX_I2SCLKDIV_LRDIV128	(2 << 17)
+#define EP93XX_I2SCLKDIV_LRDIV_MASK	(3 << 17)
+#define EP93XX_SYSCON_KEYTCHCLKDIV	0x90
+#define EP93XX_SYSCON_KEYTCHCLKDIV_TSEN	31
+#define EP93XX_SYSCON_KEYTCHCLKDIV_ADIV	16
+#define EP93XX_SYSCON_KEYTCHCLKDIV_KEN	15
+#define EP93XX_SYSCON_KEYTCHCLKDIV_KDIV	0
+#define EP93XX_SYSCON_CHIPID		0x94
+#define EP93XX_SYSCON_CHIPID_ID		0x9213
+
+static const char adc_divisors[] = { 16, 4 };
+static const char sclk_divisors[] = { 2, 4 };
+static const char lrclk_divisors[] = { 32, 64, 128 };
+
+static const struct clk_parent_data ep93xx_clk_parents[] = {
+	{ .fw_name = "xtali", .name = "xtali" },
+	{ .index = -1, .name = "pll1" },
+	{ .index = -1, .name = "pll2" },
+};
+
+struct ep93xx_clk {
+	struct clk_hw hw;
+	u16 idx;
+	u16 reg;
+	u32 mask;
+	u8 bit_idx;
+	u8 shift;
+	u8 width;
+	u8 num_div;
+	const char *div;
+};
+
+struct ep93xx_clk_priv {
+	spinlock_t lock;
+	struct device *dev;
+	void __iomem *base;
+	struct regmap *map;
+	struct clk_hw *fixed[16];
+	struct ep93xx_clk reg[];
+};
+
+static struct ep93xx_clk *ep93xx_clk_from(struct clk_hw *hw)
+{
+	return container_of(hw, struct ep93xx_clk, hw);
+}
+
+static struct ep93xx_clk_priv *ep93xx_priv_from(struct ep93xx_clk *clk)
+{
+	return container_of(clk, struct ep93xx_clk_priv, reg[clk->idx]);
+}
+
+static int ep93xx_clk_is_enabled(struct clk_hw *hw)
+{
+	struct ep93xx_clk *clk = ep93xx_clk_from(hw);
+	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
+	u32 val;
+
+	regmap_read(priv->map, clk->reg, &val);
+
+	return !!(val & BIT(clk->bit_idx));
+}
+
+static int ep93xx_clk_enable(struct clk_hw *hw)
+{
+	struct ep93xx_clk *clk = ep93xx_clk_from(hw);
+	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
+	unsigned long flags;
+	u32 val;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	regmap_read(priv->map, clk->reg, &val);
+	val |= BIT(clk->bit_idx);
+
+	ep93xx_regmap_write(priv->map, clk->reg, val);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return 0;
+}
+
+static void ep93xx_clk_disable(struct clk_hw *hw)
+{
+	struct ep93xx_clk *clk = ep93xx_clk_from(hw);
+	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
+	unsigned long flags;
+	u32 val;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	regmap_read(priv->map, clk->reg, &val);
+	val &= ~BIT(clk->bit_idx);
+
+	ep93xx_regmap_write(priv->map, clk->reg, val);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+static const struct clk_ops clk_ep93xx_gate_ops = {
+	.enable = ep93xx_clk_enable,
+	.disable = ep93xx_clk_disable,
+	.is_enabled = ep93xx_clk_is_enabled,
+};
+
+static int ep93xx_clk_register_gate(struct ep93xx_clk *clk,
+					const char *name,
+					struct clk_parent_data *parent_data,
+					unsigned long flags,
+					unsigned int reg,
+					u8 bit_idx)
+{
+	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
+	struct clk_init_data init = { };
+
+	init.name = name;
+	init.ops = &clk_ep93xx_gate_ops;
+	init.flags = flags;
+	init.parent_data = parent_data;
+	init.num_parents = 1;
+
+	clk->reg = reg;
+	clk->bit_idx = bit_idx;
+	clk->hw.init = &init;
+
+	return devm_clk_hw_register(priv->dev, &clk->hw);
+}
+
+static u8 ep93xx_mux_get_parent(struct clk_hw *hw)
+{
+	struct ep93xx_clk *clk = ep93xx_clk_from(hw);
+	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
+	u32 val;
+
+	regmap_read(priv->map, clk->reg, &val);
+
+	val &= EP93XX_SYSCON_CLKDIV_MASK;
+
+	switch (val) {
+	case EP93XX_SYSCON_CLKDIV_ESEL:
+		return 1; /* PLL1 */
+	case EP93XX_SYSCON_CLKDIV_MASK:
+		return 2; /* PLL2 */
+	default:
+		break;
+	};
+
+	return 0; /* XTALI */
+}
+
+static int ep93xx_mux_set_parent_lock(struct clk_hw *hw, u8 index)
+{
+	struct ep93xx_clk *clk = ep93xx_clk_from(hw);
+	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
+	unsigned long flags;
+	u32 val;
+
+	if (index >= ARRAY_SIZE(ep93xx_clk_parents))
+		return -EINVAL;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	regmap_read(priv->map, clk->reg, &val);
+	val &= ~(EP93XX_SYSCON_CLKDIV_MASK);
+	if (index) {
+		val |= EP93XX_SYSCON_CLKDIV_ESEL;
+		val |= (index - 1) ? EP93XX_SYSCON_CLKDIV_PSEL : 0;
+	}
+
+	ep93xx_regmap_write(priv->map, clk->reg, val);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+
+	return 0;
+}
+
+static bool is_best(unsigned long rate, unsigned long now,
+		     unsigned long best)
+{
+	return abs(rate - now) < abs(rate - best);
+}
+
+static int ep93xx_mux_determine_rate(struct clk_hw *hw,
+				struct clk_rate_request *req)
+{
+	unsigned long best_rate = 0, actual_rate, mclk_rate;
+	unsigned long rate = req->rate;
+	struct clk_hw *parent_best = NULL;
+	unsigned long parent_rate_best;
+	unsigned long parent_rate;
+	int div, pdiv;
+	unsigned int i;
+
+	/*
+	 * Try the two pll's and the external clock
+	 * Because the valid predividers are 2, 2.5 and 3, we multiply
+	 * all the clocks by 2 to avoid floating point math.
+	 *
+	 * This is based on the algorithm in the ep93xx raster guide:
+	 * http://be-a-maverick.com/en/pubs/appNote/AN269REV1.pdf
+	 *
+	 */
+	for (i = 0; i < clk_hw_get_num_parents(hw); i++) {
+		struct clk_hw *parent = clk_hw_get_parent_by_index(hw, i);
+
+		parent_rate = clk_hw_get_rate(parent);
+		mclk_rate = parent_rate * 2;
+
+		/* Try each predivider value */
+		for (pdiv = 4; pdiv <= 6; pdiv++) {
+			div = DIV_ROUND_CLOSEST(mclk_rate, rate * pdiv);
+			if (div < 1 || div > 127)
+				continue;
+
+			actual_rate = DIV_ROUND_CLOSEST(mclk_rate, pdiv * div);
+			if (is_best(rate, actual_rate, best_rate)) {
+				best_rate = actual_rate;
+				parent_rate_best = parent_rate;
+				parent_best = parent;
+			}
+		}
+	}
+
+	if (!parent_best)
+		return -EINVAL;
+
+	req->best_parent_rate = parent_rate_best;
+	req->best_parent_hw = parent_best;
+	req->rate = best_rate;
+
+	return 0;
+}
+
+static unsigned long ep93xx_ddiv_recalc_rate(struct clk_hw *hw,
+						unsigned long parent_rate)
+{
+	struct ep93xx_clk *clk = ep93xx_clk_from(hw);
+	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
+	unsigned int pdiv, div;
+	u32 val;
+
+	regmap_read(priv->map, clk->reg, &val);
+	pdiv = ((val >> EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) & 0x03);
+	div = val & GENMASK(6, 0);
+	if (!div)
+		return 0;
+
+	return DIV_ROUND_CLOSEST(parent_rate * 2, (pdiv + 3) * div);
+}
+
+static int ep93xx_ddiv_set_rate(struct clk_hw *hw, unsigned long rate,
+				unsigned long parent_rate)
+{
+	struct ep93xx_clk *clk = ep93xx_clk_from(hw);
+	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
+	int pdiv, div, npdiv, ndiv;
+	unsigned long actual_rate, mclk_rate, rate_err = ULONG_MAX;
+	u32 val;
+
+	regmap_read(priv->map, clk->reg, &val);
+	mclk_rate = parent_rate * 2;
+
+	for (pdiv = 4; pdiv <= 6; pdiv++) {
+		div = DIV_ROUND_CLOSEST(mclk_rate, rate * pdiv);
+		if (div < 1 || div > 127)
+			continue;
+
+		actual_rate = DIV_ROUND_CLOSEST(mclk_rate, pdiv * div);
+		if (abs(actual_rate - rate) < rate_err) {
+			npdiv = pdiv - 3;
+			ndiv = div;
+			rate_err = abs(actual_rate - rate);
+		}
+	}
+
+	if (rate_err == ULONG_MAX)
+		return -EINVAL;
+
+	/* Clear old dividers */
+	val &= ~(GENMASK(9, 0) & ~BIT(7));
+
+	/* Set the new pdiv and div bits for the new clock rate */
+	val |= (npdiv << EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | ndiv;
+
+	ep93xx_regmap_write(priv->map, clk->reg, val);
+
+	return 0;
+}
+
+static const struct clk_ops clk_ddiv_ops = {
+	.enable = ep93xx_clk_enable,
+	.disable = ep93xx_clk_disable,
+	.is_enabled = ep93xx_clk_is_enabled,
+	.get_parent = ep93xx_mux_get_parent,
+	.set_parent = ep93xx_mux_set_parent_lock,
+	.determine_rate = ep93xx_mux_determine_rate,
+	.recalc_rate = ep93xx_ddiv_recalc_rate,
+	.set_rate = ep93xx_ddiv_set_rate,
+};
+
+static int clk_hw_register_ddiv(struct ep93xx_clk *clk,
+						const char *name,
+						unsigned int reg,
+						u8 bit_idx)
+{
+	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
+	struct clk_init_data init = { };
+
+	init.name = name;
+	init.ops = &clk_ddiv_ops;
+	init.flags = 0;
+	init.parent_data = ep93xx_clk_parents;
+	init.num_parents = ARRAY_SIZE(ep93xx_clk_parents);
+
+	clk->reg = reg;
+	clk->bit_idx = bit_idx;
+	clk->hw.init = &init;
+
+	return devm_clk_hw_register(priv->dev, &clk->hw);
+}
+
+static unsigned long ep93xx_div_recalc_rate(struct clk_hw *hw,
+					    unsigned long parent_rate)
+{
+	struct ep93xx_clk *clk = ep93xx_clk_from(hw);
+	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
+	u32 val;
+	u8 index;
+
+	regmap_read(priv->map, clk->reg, &val);
+	index = (val & clk->mask) >> clk->shift;
+	if (index > clk->num_div)
+		return 0;
+
+	return DIV_ROUND_CLOSEST(parent_rate, clk->div[index]);
+}
+
+static long ep93xx_div_round_rate(struct clk_hw *hw, unsigned long rate,
+				   unsigned long *parent_rate)
+{
+	struct ep93xx_clk *clk = ep93xx_clk_from(hw);
+	unsigned long best = 0, now;
+	unsigned int i;
+
+	for (i = 0; i < clk->num_div; i++) {
+		if ((rate * clk->div[i]) == *parent_rate)
+			return rate;
+
+		now = DIV_ROUND_CLOSEST(*parent_rate, clk->div[i]);
+		if (!best || is_best(rate, now, best))
+			best = now;
+	}
+
+	return best;
+}
+
+static int ep93xx_div_set_rate(struct clk_hw *hw, unsigned long rate,
+			       unsigned long parent_rate)
+{
+	struct ep93xx_clk *clk = ep93xx_clk_from(hw);
+	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
+	unsigned int i;
+	u32 val;
+
+	regmap_read(priv->map, clk->reg, &val);
+	val &= ~clk->mask;
+	for (i = 0; i < clk->num_div; i++)
+		if (rate == DIV_ROUND_CLOSEST(parent_rate, clk->div[i])) {
+			val |= i << clk->shift;
+			break;
+		}
+
+	if (i == clk->num_div)
+		return -EINVAL;
+
+	ep93xx_regmap_write(priv->map, clk->reg, val);
+
+	return 0;
+}
+
+static const struct clk_ops ep93xx_div_ops = {
+	.enable = ep93xx_clk_enable,
+	.disable = ep93xx_clk_disable,
+	.is_enabled = ep93xx_clk_is_enabled,
+	.recalc_rate = ep93xx_div_recalc_rate,
+	.round_rate = ep93xx_div_round_rate,
+	.set_rate = ep93xx_div_set_rate,
+};
+
+static int clk_hw_register_div(struct ep93xx_clk *clk,
+					  const char *name,
+					  struct clk_parent_data *parent_data,
+					  // const char *parent_name,
+					  unsigned int reg,
+					  u8 enable_bit,
+					  u8 shift,
+					  u8 width,
+					  const char *clk_divisors,
+					  u8 num_div)
+{
+	struct ep93xx_clk_priv *priv = ep93xx_priv_from(clk);
+	struct clk_init_data init = { };
+
+	init.name = name;
+	init.ops = &ep93xx_div_ops;
+	init.flags = 0;
+	init.parent_data = parent_data;
+	init.num_parents = 1;
+
+	clk->reg = reg;
+	clk->bit_idx = enable_bit;
+	clk->mask = GENMASK(shift + width - 1, shift);
+	clk->shift = shift;
+	clk->div = clk_divisors;
+	clk->num_div = num_div;
+	clk->hw.init = &init;
+
+	return devm_clk_hw_register(priv->dev, &clk->hw);
+}
+
+struct ep93xx_gate {
+	unsigned int idx;
+	unsigned int bit;
+	const char *name;
+};
+
+static const struct ep93xx_gate ep93xx_uarts[] = {
+	{ EP93XX_CLK_UART1, EP93XX_SYSCON_DEVCFG_U1EN, "uart1" },
+	{ EP93XX_CLK_UART2, EP93XX_SYSCON_DEVCFG_U2EN, "uart2" },
+	{ EP93XX_CLK_UART3, EP93XX_SYSCON_DEVCFG_U3EN, "uart3" },
+};
+
+static int ep93xx_uart_clock_init(struct ep93xx_clk_priv *priv)
+{
+	struct clk_parent_data parent_data = { };
+	unsigned int i, ret, clk_uart_div;
+	struct ep93xx_clk *clk;
+	u32 val;
+
+	regmap_read(priv->map, EP93XX_SYSCON_PWRCNT, &val);
+	if (val & EP93XX_SYSCON_PWRCNT_UARTBAUD)
+		clk_uart_div = 1;
+	else
+		clk_uart_div = 2;
+
+	priv->fixed[0] = clk_hw_register_fixed_factor(NULL, "uart", "xtali", 0, 1, clk_uart_div);
+	parent_data.hw = priv->fixed[0];
+
+	/* parenting uart gate clocks to uart clock */
+	for (i = 0; i < ARRAY_SIZE(ep93xx_uarts); i++) {
+		clk = &priv->reg[ep93xx_uarts[i].idx];
+		clk->idx = ep93xx_uarts[i].idx;
+		ret = ep93xx_clk_register_gate(clk,
+					ep93xx_uarts[i].name,
+					&parent_data, CLK_SET_RATE_PARENT,
+					EP93XX_SYSCON_DEVCFG,
+					ep93xx_uarts[i].bit);
+		if (ret)
+			return dev_err_probe(priv->dev, ret, "failed to register dma clock\n");
+	}
+
+	return 0;
+}
+
+static const struct ep93xx_gate ep93xx_dmas[] = {
+	{ EP93XX_CLK_M2M0, EP93XX_SYSCON_PWRCNT_DMA_M2M0, "m2m0" },
+	{ EP93XX_CLK_M2M1, EP93XX_SYSCON_PWRCNT_DMA_M2M1, "m2m1" },
+	{ EP93XX_CLK_M2P0, EP93XX_SYSCON_PWRCNT_DMA_M2P0, "m2p0" },
+	{ EP93XX_CLK_M2P1, EP93XX_SYSCON_PWRCNT_DMA_M2P1, "m2p1" },
+	{ EP93XX_CLK_M2P2, EP93XX_SYSCON_PWRCNT_DMA_M2P2, "m2p2" },
+	{ EP93XX_CLK_M2P3, EP93XX_SYSCON_PWRCNT_DMA_M2P3, "m2p3" },
+	{ EP93XX_CLK_M2P4, EP93XX_SYSCON_PWRCNT_DMA_M2P4, "m2p4" },
+	{ EP93XX_CLK_M2P5, EP93XX_SYSCON_PWRCNT_DMA_M2P5, "m2p5" },
+	{ EP93XX_CLK_M2P6, EP93XX_SYSCON_PWRCNT_DMA_M2P6, "m2p6" },
+	{ EP93XX_CLK_M2P7, EP93XX_SYSCON_PWRCNT_DMA_M2P7, "m2p7" },
+	{ EP93XX_CLK_M2P8, EP93XX_SYSCON_PWRCNT_DMA_M2P8, "m2p8" },
+	{ EP93XX_CLK_M2P9, EP93XX_SYSCON_PWRCNT_DMA_M2P9, "m2p9" },
+};
+
+static int ep93xx_dma_clock_init(struct ep93xx_clk_priv *priv)
+{
+	unsigned int i, idx;
+
+	for (i = 0; i < ARRAY_SIZE(ep93xx_dmas); i++) {
+		idx = ep93xx_dmas[i].idx - EP93XX_CLK_UART;
+		priv->fixed[idx] = devm_clk_hw_register_gate(priv->dev,
+					ep93xx_dmas[i].name,
+					"hclk", 0,
+					priv->base + EP93XX_SYSCON_PWRCNT,
+					ep93xx_dmas[i].bit,
+					0,
+					&priv->lock);
+		if (IS_ERR(priv->fixed[idx]))
+			return PTR_ERR(priv->fixed[idx]);
+	}
+
+	return 0;
+}
+
+static struct clk_hw *ep93xx_clk_get(struct of_phandle_args *clkspec, void *data)
+{
+	struct ep93xx_clk_priv *priv = data;
+	unsigned int idx = clkspec->args[0];
+
+	if (idx < EP93XX_CLK_UART)
+		return &priv->reg[idx].hw;
+
+	if (idx < EP93XX_CLK_END)
+		return priv->fixed[idx - EP93XX_CLK_UART];
+
+	return ERR_PTR(-EINVAL);
+}
+
+static const struct soc_device_attribute ep93xx_soc_table[] = {
+	{ .revision = "E2", .data = (void *)1 },
+	{ /* sentinel */ }
+};
+
+static int ep93xx_clk_probe(struct platform_device *pdev)
+{
+	struct clk_parent_data xtali = { .name = "xtali" };
+	const struct soc_device_attribute *match;
+	struct clk_parent_data pdata = {};
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct ep93xx_clk_priv *priv;
+	struct device_node *parent;
+	struct ep93xx_clk *clk;
+	unsigned long clk_spi_div;
+	int ret;
+	u32 value;
+
+	priv = devm_kzalloc(dev, struct_size(priv, reg, EP93XX_CLK_UART), GFP_KERNEL);
+	if (!priv)
+		return -ENOMEM;
+
+	spin_lock_init(&priv->lock);
+	priv->dev = dev;
+	parent = of_get_parent(np);
+	if (!parent)
+		return dev_err_probe(dev, -EINVAL, "no syscon parent for clk node\n");
+
+	priv->map = syscon_node_to_regmap(parent);
+	if (IS_ERR(priv->map)) {
+		of_node_put(parent);
+		return dev_err_probe(dev, -EINVAL, "no syscon regmap\n");
+	}
+
+	priv->base = devm_of_iomap(dev, parent, 0, NULL);
+	of_node_put(parent);
+	if (IS_ERR(priv->base))
+		return PTR_ERR(priv->base);
+
+	ret = ep93xx_uart_clock_init(priv);
+	if (ret)
+		return ret;
+
+	ret = ep93xx_dma_clock_init(priv);
+	if (ret)
+		return ret;
+
+	/*
+	 * EP93xx SSP clock rate was doubled in version E2. For more information
+	 * see:
+	 *     http://www.cirrus.com/en/pubs/appNote/AN273REV4.pdf
+	 */
+	clk_spi_div = 2;
+	match = soc_device_match(ep93xx_soc_table);
+	if (match)
+		clk_spi_div = (unsigned long)match->data;
+
+	priv->fixed[1] = devm_clk_hw_register_fixed_factor(dev, "ep93xx-spi.0", "xtali",
+							0, 1, clk_spi_div);
+	if (IS_ERR(priv->fixed[1]))
+		return PTR_ERR(priv->fixed[1]);
+
+	/* PWM clock */
+	priv->fixed[2] = devm_clk_hw_register_fixed_factor(dev, "pwm_clk", "xtali", 0, 1, 1);
+	if (IS_ERR(priv->fixed[2]))
+		return PTR_ERR(priv->fixed[2]);
+
+	/* USB clock */
+	priv->fixed[3] = devm_clk_hw_register_gate(priv->dev,
+					"ohci-platform",
+					"usb_clk", 0,
+					priv->base + EP93XX_SYSCON_PWRCNT,
+					EP93XX_SYSCON_PWRCNT_USH_EN,
+					0,
+					&priv->lock);
+	if (IS_ERR(priv->fixed[3]))
+		return PTR_ERR(priv->fixed[3]);
+
+	/* touchscreen/adc clock */
+	clk = &priv->reg[EP93XX_CLK_ADC];
+	clk->idx = EP93XX_CLK_ADC;
+	ret = clk_hw_register_div(clk, "ep93xx-adc", &xtali,
+				EP93XX_SYSCON_KEYTCHCLKDIV,
+				EP93XX_SYSCON_KEYTCHCLKDIV_TSEN,
+				EP93XX_SYSCON_KEYTCHCLKDIV_ADIV,
+				1,
+				adc_divisors,
+				ARRAY_SIZE(adc_divisors));
+
+
+	/* keypad clock */
+	clk = &priv->reg[EP93XX_CLK_KEYPAD];
+	clk->idx = EP93XX_CLK_KEYPAD;
+	ret = clk_hw_register_div(clk, "ep93xx-keypad", &xtali,
+				EP93XX_SYSCON_KEYTCHCLKDIV,
+				EP93XX_SYSCON_KEYTCHCLKDIV_KEN,
+				EP93XX_SYSCON_KEYTCHCLKDIV_KDIV,
+				1,
+				adc_divisors,
+				ARRAY_SIZE(adc_divisors));
+
+	/*
+	 * On reset PDIV and VDIV is set to zero, while PDIV zero
+	 * means clock disable, VDIV shouldn't be zero.
+	 * So i set both dividers to minimum.
+	 */
+	/* ENA - Enable CLK divider. */
+	/* PDIV - 00 - Disable clock */
+	/* VDIV - at least 2 */
+	/* Check and enable video clk registers */
+	regmap_read(priv->map, EP93XX_SYSCON_VIDCLKDIV, &value);
+	value |= BIT(EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | 2;
+	ep93xx_regmap_write(priv->map, EP93XX_SYSCON_VIDCLKDIV, value);
+
+	/* check and enable i2s clk registers */
+	regmap_read(priv->map, EP93XX_SYSCON_I2SCLKDIV, &value);
+	value |= BIT(EP93XX_SYSCON_CLKDIV_PDIV_SHIFT) | 2;
+	/*
+	 * Override the SAI_MSTR_CLK_CFG from the I2S block and use the
+	 * I2SClkDiv Register settings. LRCLK transitions on the falling SCLK
+	 * edge.
+	 */
+	value |= EP93XX_SYSCON_I2SCLKDIV_ORIDE | EP93XX_SYSCON_I2SCLKDIV_SPOL;
+	ep93xx_regmap_write(priv->map, EP93XX_SYSCON_I2SCLKDIV, value);
+
+	/* video clk */
+	clk = &priv->reg[EP93XX_CLK_VIDEO];
+	clk->idx = EP93XX_CLK_VIDEO;
+	ret = clk_hw_register_ddiv(clk, "ep93xx-fb",
+				EP93XX_SYSCON_VIDCLKDIV,
+				EP93XX_SYSCON_CLKDIV_ENABLE);
+
+	/* i2s clk */
+	clk = &priv->reg[EP93XX_CLK_I2S_MCLK];
+	clk->idx = EP93XX_CLK_I2S_MCLK;
+	ret = clk_hw_register_ddiv(clk, "mclk",
+				EP93XX_SYSCON_I2SCLKDIV,
+				EP93XX_SYSCON_CLKDIV_ENABLE);
+
+	/* i2s sclk */
+	clk = &priv->reg[EP93XX_CLK_I2S_SCLK];
+	clk->idx = EP93XX_CLK_I2S_SCLK;
+	pdata.hw = &priv->reg[EP93XX_CLK_I2S_MCLK].hw;
+	ret = clk_hw_register_div(clk, "sclk", &pdata,
+				EP93XX_SYSCON_I2SCLKDIV,
+				EP93XX_SYSCON_I2SCLKDIV_SENA,
+				16, /* EP93XX_I2SCLKDIV_SDIV_SHIFT */
+				1,  /* EP93XX_I2SCLKDIV_SDIV_WIDTH */
+				sclk_divisors,
+				ARRAY_SIZE(sclk_divisors));
+
+	/* i2s lrclk */
+	clk = &priv->reg[EP93XX_CLK_I2S_LRCLK];
+	clk->idx = EP93XX_CLK_I2S_LRCLK;
+	pdata.hw = &priv->reg[EP93XX_CLK_I2S_SCLK].hw;
+	ret = clk_hw_register_div(clk, "lrclk", &pdata,
+				EP93XX_SYSCON_I2SCLKDIV,
+				EP93XX_SYSCON_I2SCLKDIV_SENA,
+				17, /* EP93XX_I2SCLKDIV_LRDIV32_SHIFT */
+				2,  /* EP93XX_I2SCLKDIV_LRDIV32_WIDTH */
+				lrclk_divisors,
+				ARRAY_SIZE(lrclk_divisors));
+
+	/* IrDa clk uses same pattern but no init code presents in original clock driver */
+	return devm_of_clk_add_hw_provider(priv->dev, ep93xx_clk_get, priv);
+}
+
+static const struct of_device_id ep93xx_clk_dt_ids[] = {
+	{ .compatible = "cirrus,ep9301-clk" },
+	{ /* sentinel */ }
+};
+
+static struct platform_driver ep93xx_clk_driver = {
+	.driver = {
+		.name = "ep93xx-clk",
+		.of_match_table = ep93xx_clk_dt_ids,
+		.suppress_bind_attrs = true,
+	},
+};
+builtin_platform_driver_probe(ep93xx_clk_driver, ep93xx_clk_probe);

-- 
2.39.2


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

* Re: [PATCH v4 03/42] dt-bindings: clock: Add Cirrus EP93xx
  2023-09-15  8:10 ` [PATCH v4 03/42] dt-bindings: clock: Add Cirrus EP93xx Nikita Shubin via B4 Relay
@ 2023-09-15 10:36   ` Krzysztof Kozlowski
  0 siblings, 0 replies; 7+ messages in thread
From: Krzysztof Kozlowski @ 2023-09-15 10:36 UTC (permalink / raw)
  To: nikita.shubin, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Alexander Sverdlin
  Cc: linux-clk, devicetree, linux-kernel, Arnd Bergmann

On 15/09/2023 10:10, Nikita Shubin via B4 Relay wrote:
> From: Nikita Shubin <nikita.shubin@maquefel.me>
> 

Thank you for your patch. There is something to discuss/improve.


> diff --git a/include/dt-bindings/clock/cirrus,ep9301-clk.h b/include/dt-bindings/clock/cirrus,ep9301-clk.h
> new file mode 100644
> index 000000000000..3cd053c0fdea
> --- /dev/null
> +++ b/include/dt-bindings/clock/cirrus,ep9301-clk.h
> @@ -0,0 +1,41 @@
> +/* SPDX-License-Identifier: (GPL-2.0 OR MIT) */
> +#ifndef DT_BINDINGS_CIRRUS_EP93XX_CLOCK_H
> +#define DT_BINDINGS_CIRRUS_EP93XX_CLOCK_H
> +
> +#define EP93XX_CLK_UART1	0
> +#define EP93XX_CLK_UART2	1
> +#define EP93XX_CLK_UART3	2
> +
> +#define EP93XX_CLK_ADC		3
> +#define EP93XX_CLK_ADC_EN	4
> +
> +#define EP93XX_CLK_KEYPAD   5

Wrong indentation - use tab instead of spaces, just like in other places.

> +
> +#define EP93XX_CLK_VIDEO	6
> +
> +#define EP93XX_CLK_I2S_MCLK	7
> +#define EP93XX_CLK_I2S_SCLK	8
> +#define EP93XX_CLK_I2S_LRCLK	9
> +
> +#define EP93XX_CLK_UART		10
> +#define EP93XX_CLK_SPI		11
> +#define EP93XX_CLK_PWM		12
> +#define EP93XX_CLK_USB		13
> +
> +#define EP93XX_CLK_M2M0		14
> +#define EP93XX_CLK_M2M1		15
> +
> +#define EP93XX_CLK_M2P0		16
> +#define EP93XX_CLK_M2P1		17
> +#define EP93XX_CLK_M2P2		18
> +#define EP93XX_CLK_M2P3		19
> +#define EP93XX_CLK_M2P4		20
> +#define EP93XX_CLK_M2P5		21
> +#define EP93XX_CLK_M2P6		22
> +#define EP93XX_CLK_M2P7		23
> +#define EP93XX_CLK_M2P8		24
> +#define EP93XX_CLK_M2P9		25
> +
> +#define EP93XX_CLK_END      26

Here as well... except I propose to drop it. Number of clocks should not
be part of bindings, because then you cannot grow it.

With indentation fixed and CLK_END dropped:


Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>

Best regards,
Krzysztof


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

* Re: [PATCH v4 00/42] ep93xx device tree conversion
  2023-09-15  8:10 [PATCH v4 00/42] ep93xx device tree conversion Nikita Shubin via B4 Relay
  2023-09-15  8:10 ` [PATCH v4 03/42] dt-bindings: clock: Add Cirrus EP93xx Nikita Shubin via B4 Relay
  2023-09-15  8:10 ` [PATCH v4 04/42] clk: ep93xx: add DT support for " Nikita Shubin via B4 Relay
@ 2023-09-18  7:39 ` Andy Shevchenko
  2023-10-15 21:17 ` (subset) " Alexandre Belloni
  3 siblings, 0 replies; 7+ messages in thread
From: Andy Shevchenko @ 2023-09-18  7:39 UTC (permalink / raw)
  To: nikita.shubin
  Cc: Hartley Sweeten, Alexander Sverdlin, Russell King,
	Lukasz Majewski, Linus Walleij, Bartosz Golaszewski,
	Michael Turquette, Stephen Boyd, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Sebastian Reichel, Daniel Lezcano, Thomas Gleixner,
	Alessandro Zummo, Alexandre Belloni, Wim Van Sebroeck,
	Guenter Roeck, Thierry Reding, Uwe Kleine-König, Mark Brown,
	David S. Miller, Eric Dumazet, Jakub Kicinski, Paolo Abeni,
	Vinod Koul, Miquel Raynal, Richard Weinberger,
	Vignesh Raghavendra, Damien Le Moal, Sergey Shtylyov,
	Dmitry Torokhov, Liam Girdwood, Jaroslav Kysela, Takashi Iwai,
	linux-arm-kernel, linux-kernel, linux-gpio, linux-clk, devicetree,
	linux-pm, linux-rtc, linux-watchdog, linux-pwm, linux-spi, netdev,
	dmaengine, linux-mtd, linux-ide, linux-input, alsa-devel,
	Arnd Bergmann, Bartosz Golaszewski, Krzysztof Kozlowski,
	Andrew Lunn

On Fri, Sep 15, 2023 at 11:10:42AM +0300, Nikita Shubin via B4 Relay wrote:
> This series aims to convert ep93xx from platform to full device tree support.
> 
> The main goal is to receive ACK's to take it via Arnd's arm-soc branch.
> 
> Major changes:
> - drop newline at the end from each YAML files
> - rename dma and clk bindings headers to match first compatible
> - shrink SoC exported functions number to only 2
> - dropped some ep93xx_pata fixes from these series
> - dropped m48t86 stuff from these series
> 
> Bit thanks to Andy Shevchenko for thorough review.

You are welcome!

Dunno if you have used --patience when formatted the patches, but I think
you should, if hadn't, for the next version. It will help a lot in reviewing
and understanding the changes.

-- 
With Best Regards,
Andy Shevchenko



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

* Re: (subset) [PATCH v4 00/42] ep93xx device tree conversion
  2023-09-15  8:10 [PATCH v4 00/42] ep93xx device tree conversion Nikita Shubin via B4 Relay
                   ` (2 preceding siblings ...)
  2023-09-18  7:39 ` [PATCH v4 00/42] ep93xx device tree conversion Andy Shevchenko
@ 2023-10-15 21:17 ` Alexandre Belloni
  3 siblings, 0 replies; 7+ messages in thread
From: Alexandre Belloni @ 2023-10-15 21:17 UTC (permalink / raw)
  To: Hartley Sweeten, Alexander Sverdlin, Russell King,
	Lukasz Majewski, Linus Walleij, Bartosz Golaszewski,
	Andy Shevchenko, Michael Turquette, Stephen Boyd, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Sebastian Reichel,
	Daniel Lezcano, Thomas Gleixner, Alessandro Zummo,
	Wim Van Sebroeck, Guenter Roeck, Thierry Reding,
	Uwe Kleine-König, Mark Brown, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Vinod Koul, Miquel Raynal,
	Richard Weinberger, Vignesh Raghavendra, Damien Le Moal,
	Sergey Shtylyov, Dmitry Torokhov, Liam Girdwood, Jaroslav Kysela,
	Takashi Iwai, Nikita Shubin
  Cc: linux-arm-kernel, linux-kernel, linux-gpio, linux-clk, devicetree,
	linux-pm, linux-rtc, linux-watchdog, linux-pwm, linux-spi, netdev,
	dmaengine, linux-mtd, linux-ide, linux-input, alsa-devel,
	Arnd Bergmann, Bartosz Golaszewski, Krzysztof Kozlowski,
	Andy Shevchenko, Andrew Lunn


On Fri, 15 Sep 2023 11:10:42 +0300, Nikita Shubin wrote:
> This series aims to convert ep93xx from platform to full device tree support.
> 
> The main goal is to receive ACK's to take it via Arnd's arm-soc branch.
> 
> Major changes:
> - drop newline at the end from each YAML files
> - rename dma and clk bindings headers to match first compatible
> - shrink SoC exported functions number to only 2
> - dropped some ep93xx_pata fixes from these series
> - dropped m48t86 stuff from these series
> 
> [...]

Applied, thanks!

[13/42] dt-bindings: rtc: Add Cirrus EP93xx
        commit: 207bddd97881913bcb8bef84737c0971e712fbee
[14/42] rtc: ep93xx: add DT support for Cirrus EP93xx
        commit: 1d70f9fe5f1c8fbd5d838223b8aec27c69a7e609

Best regards,

-- 
Alexandre Belloni, co-owner and COO, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com

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

* Re: [PATCH v4 04/42] clk: ep93xx: add DT support for Cirrus EP93xx
  2023-09-15  8:10 ` [PATCH v4 04/42] clk: ep93xx: add DT support for " Nikita Shubin via B4 Relay
@ 2023-10-24  2:50   ` Stephen Boyd
  0 siblings, 0 replies; 7+ messages in thread
From: Stephen Boyd @ 2023-10-24  2:50 UTC (permalink / raw)
  To: Michael Turquette, Nikita Shubin via B4 Relay, nikita.shubin
  Cc: linux-kernel, linux-clk, Arnd Bergmann, Alexander Sverdlin

Quoting Nikita Shubin via B4 Relay (2023-09-15 01:10:46)
> diff --git a/drivers/clk/clk-ep93xx.c b/drivers/clk/clk-ep93xx.c
> new file mode 100644
> index 000000000000..e8d3bd595255
> --- /dev/null
> +++ b/drivers/clk/clk-ep93xx.c
> @@ -0,0 +1,753 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Clock control for Cirrus EP93xx chips.
[...]
> +#define EP93XX_SYSCON_KEYTCHCLKDIV_KEN 15
> +#define EP93XX_SYSCON_KEYTCHCLKDIV_KDIV        0
> +#define EP93XX_SYSCON_CHIPID           0x94
> +#define EP93XX_SYSCON_CHIPID_ID                0x9213
> +
> +static const char adc_divisors[] = { 16, 4 };
> +static const char sclk_divisors[] = { 2, 4 };
> +static const char lrclk_divisors[] = { 32, 64, 128 };
> +
> +static const struct clk_parent_data ep93xx_clk_parents[] = {
> +       { .fw_name = "xtali", .name = "xtali" },

Drop name. And please drop fw_name too and set .index to 0 explicitly.

> +       { .index = -1, .name = "pll1" },
> +       { .index = -1, .name = "pll2" },

These two should come from DT via index as well. The binding should be
changed to list the pll. In the previous review you mentioned the SoC
driver was populating these. The answer is yes that you should be
providing an OF clk provider (and updating the binding) to provide those
clks to this device node. Otherwise it won't be possible to describe the
connection besides with the name fallback method, which is not desired.

> +};
> +

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

end of thread, other threads:[~2023-10-24  2:51 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-09-15  8:10 [PATCH v4 00/42] ep93xx device tree conversion Nikita Shubin via B4 Relay
2023-09-15  8:10 ` [PATCH v4 03/42] dt-bindings: clock: Add Cirrus EP93xx Nikita Shubin via B4 Relay
2023-09-15 10:36   ` Krzysztof Kozlowski
2023-09-15  8:10 ` [PATCH v4 04/42] clk: ep93xx: add DT support for " Nikita Shubin via B4 Relay
2023-10-24  2:50   ` Stephen Boyd
2023-09-18  7:39 ` [PATCH v4 00/42] ep93xx device tree conversion Andy Shevchenko
2023-10-15 21:17 ` (subset) " Alexandre Belloni

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).