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