Meson clock driver
Subsystems (7)
cover Meson clock driver
Hi,
this is a basic clock driver for u-boot that supports enabling/disabling clock gates and getting their frequency. With this, some hardcoded initializations can be removed from the board code, and drivers can use the information from device tree to initialize clocks.
Beniamino Galvani (4):
ARM: dts: update gxbb-clkc.h from Linux 4.14
ARM: meson: add clock measurement function
clk: add Amlogic meson clock driver
meson: use the clock driver
arch/arm/include/asm/arch-meson/clock.h | 34 ++++++ arch/arm/include/asm/arch-meson/gxbb.h | 10 -- arch/arm/include/asm/arch-meson/i2c.h | 11 -- arch/arm/mach-meson/Kconfig | 2 + arch/arm/mach-meson/Makefile | 2 +- arch/arm/mach-meson/clock.c | 45 ++++++++ board/amlogic/odroid-c2/odroid-c2.c | 4 +- board/amlogic/p212/p212.c | 3 +- drivers/clk/Makefile | 1 + drivers/clk/clk_meson.c | 196 ++++++++++++++++++++++++++++++++ drivers/i2c/meson_i2c.c | 20 +++- include/dt-bindings/clock/gxbb-clkc.h | 75 ++++++++++++ 12 files changed, 373 insertions(+), 30 deletions(-) create mode 100644 arch/arm/include/asm/arch-meson/clock.h delete mode 100644 arch/arm/include/asm/arch-meson/i2c.h create mode 100644 arch/arm/mach-meson/clock.c create mode 100644 drivers/clk/clk_meson.c
Signature · 1 line
2.14.3
PATCH 1/4 ARM: dts: update gxbb-clkc.h from Linux 4.14
Update gxbb-clkc.h from Linux 4.14 as it contains new clock ids.
--- include/dt-bindings/clock/gxbb-clkc.h | 75 +++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+)
include/dt-bindings/clock/gxbb-clkc.h +75 -0
@@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * GXBB clock tree IDs */
@@ -5,37 +6,96 @@#ifndef __GXBB_CLKC_H#define __GXBB_CLKC_H +#define CLKID_SYS_PLL 0#define CLKID_HDMI_PLL 2 +#define CLKID_FIXED_PLL 3#define CLKID_FCLK_DIV2 4#define CLKID_FCLK_DIV3 5#define CLKID_FCLK_DIV4 6 +#define CLKID_FCLK_DIV5 7 +#define CLKID_FCLK_DIV7 8#define CLKID_GP0_PLL 9#define CLKID_CLK81 12 +#define CLKID_MPLL0 13 +#define CLKID_MPLL1 14#define CLKID_MPLL2 15 +#define CLKID_DDR 16 +#define CLKID_DOS 17 +#define CLKID_ISA 18 +#define CLKID_PL301 19 +#define CLKID_PERIPHS 20#define CLKID_SPICC 21#define CLKID_I2C 22#define CLKID_SAR_ADC 23 +#define CLKID_SMART_CARD 24#define CLKID_RNG0 25#define CLKID_UART0 26 +#define CLKID_SDHC 27 +#define CLKID_STREAM 28 +#define CLKID_ASYNC_FIFO 29 +#define CLKID_SDIO 30 +#define CLKID_ABUF 31 +#define CLKID_HIU_IFACE 32 +#define CLKID_ASSIST_MISC 33#define CLKID_SPI 34#define CLKID_ETH 36 +#define CLKID_I2S_SPDIF 35 +#define CLKID_DEMUX 37#define CLKID_AIU_GLUE 38#define CLKID_IEC958 39#define CLKID_I2S_OUT 40 +#define CLKID_AMCLK 41 +#define CLKID_AIFIFO2 42 +#define CLKID_MIXER 43#define CLKID_MIXER_IFACE 44 +#define CLKID_ADC 45 +#define CLKID_BLKMV 46#define CLKID_AIU 47#define CLKID_UART1 48 +#define CLKID_G2D 49#define CLKID_USB0 50#define CLKID_USB1 51 +#define CLKID_RESET 52 +#define CLKID_NAND 53 +#define CLKID_DOS_PARSER 54#define CLKID_USB 55 +#define CLKID_VDIN1 56 +#define CLKID_AHB_ARB0 57 +#define CLKID_EFUSE 58 +#define CLKID_BOOT_ROM 59 +#define CLKID_AHB_DATA_BUS 60 +#define CLKID_AHB_CTRL_BUS 61 +#define CLKID_HDMI_INTR_SYNC 62#define CLKID_HDMI_PCLK 63#define CLKID_USB1_DDR_BRIDGE 64#define CLKID_USB0_DDR_BRIDGE 65 +#define CLKID_MMC_PCLK 66 +#define CLKID_DVIN 67#define CLKID_UART2 68#define CLKID_SANA 69 +#define CLKID_VPU_INTR 70 +#define CLKID_SEC_AHB_AHB3_BRIDGE 71 +#define CLKID_CLK81_A53 72 +#define CLKID_VCLK2_VENCI0 73 +#define CLKID_VCLK2_VENCI1 74 +#define CLKID_VCLK2_VENCP0 75 +#define CLKID_VCLK2_VENCP1 76#define CLKID_GCLK_VENCI_INT0 77 +#define CLKID_GCLK_VENCI_INT 78 +#define CLKID_DAC_CLK 79#define CLKID_AOCLK_GATE 80#define CLKID_IEC958_GATE 81 +#define CLKID_ENC480P 82 +#define CLKID_RNG1 83 +#define CLKID_GCLK_VENCI_INT1 84 +#define CLKID_VCLK2_VENCLMCC 85 +#define CLKID_VCLK2_VENCL 86 +#define CLKID_VCLK_OTHER 87 +#define CLKID_EDP 88 +#define CLKID_AO_MEDIA_CPU 89 +#define CLKID_AO_AHB_SRAM 90 +#define CLKID_AO_AHB_BUS 91 +#define CLKID_AO_IFACE 92#define CLKID_AO_I2C 93#define CLKID_SD_EMMC_A 94#define CLKID_SD_EMMC_B 95
@@ -50,5 +110,20 @@#define CLKID_CTS_AMCLK 107#define CLKID_CTS_MCLK_I958 110#define CLKID_CTS_I958 113 +#define CLKID_32K_CLK 114 +#define CLKID_SD_EMMC_A_CLK0 119 +#define CLKID_SD_EMMC_B_CLK0 122 +#define CLKID_SD_EMMC_C_CLK0 125 +#define CLKID_VPU_0_SEL 126 +#define CLKID_VPU_0 128 +#define CLKID_VPU_1_SEL 129 +#define CLKID_VPU_1 131 +#define CLKID_VPU 132 +#define CLKID_VAPB_0_SEL 133 +#define CLKID_VAPB_0 135 +#define CLKID_VAPB_1_SEL 136 +#define CLKID_VAPB_1 138 +#define CLKID_VAPB_SEL 139 +#define CLKID_VAPB 140#endif /* __GXBB_CLKC_H */
Signature · 1 line
2.14.3
PATCH 1/4 ARM: dts: update gxbb-clkc.h from Linux 4.14
Quoted 125 lines · Beniamino Galvani
Update
gxbb-clkc.hfrom Linux 4.14 as it contains new clock ids.Signed-off-by Beniamino Galvani <[email protected]>--- include/dt-bindings/clock/gxbb-clkc.h | 75 +++++++++++++++++++++++++++++++++++ 1 file changed, 75 insertions(+)include/dt-bindings/clock/gxbb-clkc.h +67
-0@@ -1,3 +1,4 @@ +/* SPDX-License-Identifier: GPL-2.0 */ /* * GXBB clock tree IDs */ @@ -5,37 +6,96 @@#ifndef __GXBB_CLKC_H#define __GXBB_CLKC_H +#define CLKID_SYS_PLL 0#define CLKID_HDMI_PLL 2 +#define CLKID_FIXED_PLL 3#define CLKID_FCLK_DIV2 4#define CLKID_FCLK_DIV3 5#define CLKID_FCLK_DIV4 6 +#define CLKID_FCLK_DIV5 7 +#define CLKID_FCLK_DIV7 8#define CLKID_GP0_PLL 9#define CLKID_CLK81 12 +#define CLKID_MPLL0 13 +#define CLKID_MPLL1 14#define CLKID_MPLL2 15 +#define CLKID_DDR 16 +#define CLKID_DOS 17 +#define CLKID_ISA 18 +#define CLKID_PL301 19 +#define CLKID_PERIPHS 20#define CLKID_SPICC 21#define CLKID_I2C 22#define CLKID_SAR_ADC 23 +#define CLKID_SMART_CARD 24#define CLKID_RNG0 25#define CLKID_UART0 26 +#define CLKID_SDHC 27 +#define CLKID_STREAM 28 +#define CLKID_ASYNC_FIFO 29 +#define CLKID_SDIO 30 +#define CLKID_ABUF 31 +#define CLKID_HIU_IFACE 32 +#define CLKID_ASSIST_MISC 33#define CLKID_SPI 34#define CLKID_ETH 36 +#define CLKID_I2S_SPDIF 35 +#define CLKID_DEMUX 37#define CLKID_AIU_GLUE 38#define CLKID_IEC958 39#define CLKID_I2S_OUT 40 +#define CLKID_AMCLK 41 +#define CLKID_AIFIFO2 42 +#define CLKID_MIXER 43#define CLKID_MIXER_IFACE 44 +#define CLKID_ADC 45 +#define CLKID_BLKMV 46#define CLKID_AIU 47#define CLKID_UART1 48 +#define CLKID_G2D 49#define CLKID_USB0 50#define CLKID_USB1 51 +#define CLKID_RESET 52 +#define CLKID_NAND 53 +#define CLKID_DOS_PARSER 54#define CLKID_USB 55 +#define CLKID_VDIN1 56 +#define CLKID_AHB_ARB0 57 +#define CLKID_EFUSE 58 +#define CLKID_BOOT_ROM 59 +#define CLKID_AHB_DATA_BUS 60 +#define CLKID_AHB_CTRL_BUS 61 +#define CLKID_HDMI_INTR_SYNC 62#define CLKID_HDMI_PCLK 63#define CLKID_USB1_DDR_BRIDGE 64#define CLKID_USB0_DDR_BRIDGE 65 +#define CLKID_MMC_PCLK 66 +#define CLKID_DVIN 67#define CLKID_UART2 68#define CLKID_SANA 69 +#define CLKID_VPU_INTR 70 +#define CLKID_SEC_AHB_AHB3_BRIDGE 71 +#define CLKID_CLK81_A53 72 +#define CLKID_VCLK2_VENCI0 73 +#define CLKID_VCLK2_VENCI1 74 +#define CLKID_VCLK2_VENCP0 75 +#define CLKID_VCLK2_VENCP1 76#define CLKID_GCLK_VENCI_INT0 77 +#define CLKID_GCLK_VENCI_INT 78 +#define CLKID_DAC_CLK 79#define CLKID_AOCLK_GATE 80#define CLKID_IEC958_GATE 81 +#define CLKID_ENC480P 82 +#define CLKID_RNG1 83 +#define CLKID_GCLK_VENCI_INT1 84 +#define CLKID_VCLK2_VENCLMCC 85 +#define CLKID_VCLK2_VENCL 86 +#define CLKID_VCLK_OTHER 87 +#define CLKID_EDP 88 +#define CLKID_AO_MEDIA_CPU 89 +#define CLKID_AO_AHB_SRAM 90 +#define CLKID_AO_AHB_BUS 91 +#define CLKID_AO_IFACE 92#define CLKID_AO_I2C 93#define CLKID_SD_EMMC_A 94#define CLKID_SD_EMMC_B 95@@ -50,5 +110,20 @@#define CLKID_CTS_AMCLK 107#define CLKID_CTS_MCLK_I958 110#define CLKID_CTS_I958 113 +#define CLKID_32K_CLK 114 +#define CLKID_SD_EMMC_A_CLK0 119 +#define CLKID_SD_EMMC_B_CLK0 122 +#define CLKID_SD_EMMC_C_CLK0 125 +#define CLKID_VPU_0_SEL 126 +#define CLKID_VPU_0 128 +#define CLKID_VPU_1_SEL 129
include/dt-bindings/clock/gxbb-clkc.h line 129
Quoted 10 lines
include/dt-bindings/clock/gxbb-clkc.h +8
-0+#define CLKID_VPU_1 131 +#define CLKID_VPU 132 +#define CLKID_VAPB_0_SEL 133 +#define CLKID_VAPB_0 135 +#define CLKID_VAPB_1_SEL 136 +#define CLKID_VAPB_1 138 +#define CLKID_VAPB_SEL 139 +#define CLKID_VAPB 140#endif /* __GXBB_CLKC_H */
PATCH 2/4 ARM: meson: add clock measurement function
In reply to Beniamino GalvaniAdd add a function to measure the current clock rate.
--- arch/arm/include/asm/arch-meson/clock.h | 34 +++++++++++++++++++++++++ arch/arm/mach-meson/Makefile | 2 +- arch/arm/mach-meson/clock.c | 45 +++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 arch/arm/include/asm/arch-meson/clock.h create mode 100644 arch/arm/mach-meson/clock.c
arch/arm/include/asm/arch-meson/clock.h new file +34 -0
@@ -0,0 +1,34 @@ +/* +* Copyright 2017 - Beniamino Galvani <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ +#ifndef _MESON_CLOCK_H_ +#define _MESON_CLOCK_H_ + +/* CBUS clock measure registers */ +#define MSR_CLK_DUTY 0xc1108758 +#define MSR_CLK_REG0 0xc110875c +#define MSR_CLK_REG1 0xc1108760 +#define MSR_CLK_REG2 0xc1108764 + +#define CLK_GP0_PLL 4 +#define CLK_GP1_PLL 5 +#define CLK_81 7 +#define CLK_MMC 23 +#define CLK_MOD_ETH_TX 40 +#define CLK_MOD_ETH_RX_RMII 41 +#define CLK_FCLK_DIV5 43 +#define CLK_SD_EMMC_CLK_C 51 +#define CLK_SD_EMMC_CLK_B 52 + +/* Clock gates */ +#define HHI_GCLK_MPEG0 0x140 +#define HHI_GCLK_MPEG1 0x144 +#define HHI_GCLK_MPEG2 0x148 +#define HHI_GCLK_OTHER 0x150 +#define HHI_GCLK_AO 0x154 + +ulong meson_measure_clk_rate (unsigned int clk); + +#endif
arch/arm/mach-meson/Makefile +1 -1
@@ -4,4 +4,4 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-y += board.o sm.o +obj-y += board.o clock.o sm.o
arch/arm/mach-meson/clock.c new file +45 -0
45 lines not on this page · raw message
Signature · 1 line
2.14.3
PATCH 2/4 ARM: meson: add clock measurement function
Quoted 81 lines · Beniamino Galvani
Add add a function to measure the current clock rate.
Signed-off-by Beniamino Galvani <[email protected]>--- arch/arm/include/asm/arch-meson/clock.h | 34 +++++++++++++++++++++++++ arch/arm/mach-meson/Makefile | 2 +- arch/arm/mach-meson/clock.c | 45 +++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 arch/arm/include/asm/arch-meson/clock.h create mode 100644 arch/arm/mach-meson/clock.carch/arm/include/asm/arch-meson/clock.h new file +34
-0@@ -0,0 +1,34 @@ +/* +* Copyright 2017 - Beniamino Galvani <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ +#ifndef _MESON_CLOCK_H_ +#define _MESON_CLOCK_H_ + +/* CBUS clock measure registers */ +#define MSR_CLK_DUTY 0xc1108758 +#define MSR_CLK_REG0 0xc110875c +#define MSR_CLK_REG1 0xc1108760 +#define MSR_CLK_REG2 0xc1108764 + +#define CLK_GP0_PLL 4 +#define CLK_GP1_PLL 5 +#define CLK_81 7 +#define CLK_MMC 23 +#define CLK_MOD_ETH_TX 40 +#define CLK_MOD_ETH_RX_RMII 41 +#define CLK_FCLK_DIV5 43 +#define CLK_SD_EMMC_CLK_C 51 +#define CLK_SD_EMMC_CLK_B 52 + +/* Clock gates */ +#define HHI_GCLK_MPEG0 0x140 +#define HHI_GCLK_MPEG1 0x144 +#define HHI_GCLK_MPEG2 0x148 +#define HHI_GCLK_OTHER 0x150 +#define HHI_GCLK_AO 0x154 + +ulong meson_measure_clk_rate (unsigned int clk); + +#endif arch/arm/mach-meson/Makefile +1
-1@@ -4,4 +4,4 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-y += board.o sm.o +obj-y += board.o clock.o sm.oarch/arm/mach-meson/clock.c new file +14
-0@@ -0,0 +1,45 @@ +/* +* (C) Copyright 2016 Beniamino Galvani <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +* +* Clock rate measuring. +*/ + +#include <common.h> +#include <asm/arch/clock.h> +#include <asm/io.h> + +ulong meson_measure_clk_rate (unsigned int clk) +{
arch/arm/mach-meson/clock.c line 24
Quoted 10 lines
arch/arm/mach-meson/clock.c new file +10
-0+ulong start; +ulong mhz; + +writel (0 ,MSR_CLK_REG0 ); + +/* Set the measurement gate to 64uS */ +clrsetbits_le32 (MSR_CLK_REG0 ,0xffff ,64 -1 ); +clrbits_le32 (MSR_CLK_REG0 , +BIT (17 ) |/* disable continuous measurement */ +BIT (18 ));/* disable interrupts */
You can maybe document these bits somehow.
arch/arm/mach-meson/clock.c line 30
Quoted 6 lines
arch/arm/mach-meson/clock.c new file +6
-0+clrsetbits_le32 (MSR_CLK_REG0 , +GENMASK (20 ,26 ), + clk <<20 );/* select the clock */ +setbits_le32 (MSR_CLK_REG0 , +BIT (19 ) |/* enable the clock */ +BIT (16 ));/* enable measuring */
Same here.
Quoted 6 lines
arch/arm/mach-meson/clock.c new file +5
-0+ + start =get_timer (0 ); +while (readl (MSR_CLK_REG0 ) &BIT (31 )) { +if (get_timer (start) >100 ) { +debug ("could not measure clk %u rate\n" , clk);
arch/arm/mach-meson/clock.c line 45
Quoted 10 lines
arch/arm/mach-meson/clock.c new file +10
-0+return -ETIMEDOUT ; + } + } + +/* Disable measuring */ +clrbits_le32 (MSR_CLK_REG0 ,BIT (16 )); + + mhz = ((readl (MSR_CLK_REG2 ) +31 ) &0xfffff ) >>6 ; +return mhz *1000000 ; +}
I'm skeptical about this, but it simplifies a lot the clock driver !
Anyway, it can be changed later if we want to control the PLLs and so on.
PATCH 2/4 ARM: meson: add clock measurement function
In reply to Beniamino GalvaniHi Benjamin,
Quoted 30 lines · Beniamino Galvani
Add add a function to measure the current clock rate.
Signed-off-by Beniamino Galvani <[email protected]>--- arch/arm/include/asm/arch-meson/clock.h | 34 +++++++++++++++++++++++++ arch/arm/mach-meson/Makefile | 2 +- arch/arm/mach-meson/clock.c | 45 +++++++++++++++++++++++++++++++++ 3 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 arch/arm/include/asm/arch-meson/clock.h create mode 100644 arch/arm/mach-meson/clock.carch/arm/include/asm/arch-meson/clock.h new file +13
-0@@ -0,0 +1,34 @@ +/* +* Copyright 2017 - Beniamino Galvani <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ +#ifndef _MESON_CLOCK_H_ +#define _MESON_CLOCK_H_ + +/* CBUS clock measure registers */ +#define MSR_CLK_DUTY 0xc1108758 +#define MSR_CLK_REG0 0xc110875c +#define MSR_CLK_REG1 0xc1108760 +#define MSR_CLK_REG2 0xc1108764
arch/arm/include/asm/arch-meson/clock.h line 23
Quoted 10 lines
arch/arm/include/asm/arch-meson/clock.h new file +10
-0+ +#define CLK_GP0_PLL 4 +#define CLK_GP1_PLL 5 +#define CLK_81 7 +#define CLK_MMC 23 +#define CLK_MOD_ETH_TX 40 +#define CLK_MOD_ETH_RX_RMII 41 +#define CLK_FCLK_DIV5 43 +#define CLK_SD_EMMC_CLK_C 51 +#define CLK_SD_EMMC_CLK_B 52
Are these constants in the dt-binding file somewhere?
arch/arm/include/asm/arch-meson/clock.h line 32
Quoted 9 lines
arch/arm/include/asm/arch-meson/clock.h new file +9
-0+ +/* Clock gates */ +#define HHI_GCLK_MPEG0 0x140 +#define HHI_GCLK_MPEG1 0x144 +#define HHI_GCLK_MPEG2 0x148 +#define HHI_GCLK_OTHER 0x150 +#define HHI_GCLK_AO 0x154 + +ulong meson_measure_clk_rate (unsigned int clk);
Please can you add a function comment and mention error-return values also?
Quoted 42 lines
arch/arm/include/asm/arch-meson/clock.h new file +2
-0+ +#endif arch/arm/mach-meson/Makefile +1
-1@@ -4,4 +4,4 @@ # SPDX-License-Identifier: GPL-2.0+ # -obj-y += board.o sm.o +obj-y += board.o clock.o sm.oarch/arm/mach-meson/clock.c new file +24
-0@@ -0,0 +1,45 @@ +/* +* (C) Copyright 2016 Beniamino Galvani <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +* +* Clock rate measuring. +*/ + +#include <common.h> +#include <asm/arch/clock.h> +#include <asm/io.h> + +ulong meson_measure_clk_rate (unsigned int clk) +{ +ulong start; +ulong mhz; + +writel (0 ,MSR_CLK_REG0 ); + +/* Set the measurement gate to 64uS */ +clrsetbits_le32 (MSR_CLK_REG0 ,0xffff ,64 -1 ); +clrbits_le32 (MSR_CLK_REG0 , +BIT (17 ) |/* disable continuous measurement */ +BIT (18 ));/* disable interrupts */
arch/arm/mach-meson/clock.c line 34
Quoted 10 lines
arch/arm/mach-meson/clock.c new file +10
-0+clrsetbits_le32 (MSR_CLK_REG0 , +GENMASK (20 ,26 ), + clk <<20 );/* select the clock */ +setbits_le32 (MSR_CLK_REG0 , +BIT (19 ) |/* enable the clock */ +BIT (16 ));/* enable measuring */ + + start =get_timer (0 ); +while (readl (MSR_CLK_REG0 ) &BIT (31 )) { +if (get_timer (start) >100 ) {
How long does this take to measure? Is it up to 100ms?
Quoted 12 lines
arch/arm/mach-meson/clock.c new file +11
-1+debug ("could not measure clk %u rate\n" , clk); +return -ETIMEDOUT ; + } + } + +/* Disable measuring */ +clrbits_le32 (MSR_CLK_REG0 ,BIT (16 )); + + mhz = ((readl (MSR_CLK_REG2 ) +31 ) &0xfffff ) >>6 ; +return mhz *1000000 ; +} --
Quoted 2 lines
2.14.3
Regards,
Simon
PATCH 3/4 clk: add Amlogic meson clock driver
In reply to Beniamino GalvaniIntroduce a basic clock driver for Amlogic Meson SoCs which supports enabling/disabling clock gates and getting their frequency.
--- arch/arm/mach-meson/Kconfig | 2 + drivers/clk/Makefile | 1 + drivers/clk/clk_meson.c | 196 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 199 insertions(+) create mode 100644 drivers/clk/clk_meson.c
arch/arm/mach-meson/Kconfig +2 -0
@@ -3,6 +3,7 @@ if ARCH_MESON config MESON_GXBB bool "Support Meson GXBaby" select ARM64 + select CLK select DM select DM_SERIAL help
@@ -12,6 +13,7 @@ config MESON_GXBB config MESON_GXL bool "Support Meson GXL" select ARM64 + select CLK select DM select DM_SERIAL help
drivers/clk/Makefile +1 -0
@@ -7,6 +7,7 @@ obj-$(CONFIG_$(SPL_TPL_)CLK) += clk-uclass.o clk_fixed_rate.o obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ +obj-$(CONFIG_ARCH_MESON) += clk_meson.o obj-$(CONFIG_SANDBOX) += clk_sandbox.o obj-$(CONFIG_SANDBOX) += clk_sandbox_test.o obj-$(CONFIG_MACH_PIC32) += clk_pic32.o
drivers/clk/clk_meson.c new file +196 -0
196 lines not on this page · raw message
Signature · 1 line
2.14.3
PATCH 3/4 clk: add Amlogic meson clock driver
Quoted 236 lines · Beniamino Galvani
Introduce a basic clock driver for Amlogic Meson SoCs which supports enabling/disabling clock gates and getting their frequency.
Signed-off-by Beniamino Galvani <[email protected]>--- arch/arm/mach-meson/Kconfig | 2 + drivers/clk/Makefile | 1 + drivers/clk/clk_meson.c | 196 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 199 insertions(+) create mode 100644 drivers/clk/clk_meson.carch/arm/mach-meson/Kconfig +2
-0@@ -3,6 +3,7 @@ if ARCH_MESON config MESON_GXBB bool "Support Meson GXBaby" select ARM64 + select CLK select DM select DM_SERIAL help@@ -12,6 +13,7 @@ config MESON_GXBB config MESON_GXL bool "Support Meson GXL" select ARM64 + select CLK select DM select DM_SERIAL helpdrivers/clk/Makefile +1
-0@@ -7,6 +7,7 @@ obj-$(CONFIG_$(SPL_TPL_)CLK) += clk-uclass.o clk_fixed_rate.o obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ +obj-$(CONFIG_ARCH_MESON) += clk_meson.o obj-$(CONFIG_SANDBOX) += clk_sandbox.o obj-$(CONFIG_SANDBOX) += clk_sandbox_test.o obj-$(CONFIG_MACH_PIC32) += clk_pic32.odrivers/clk/clk_meson.c new file +186
-0@@ -0,0 +1,196 @@ +/* +* (C) Copyright 2017 - Beniamino Galvani <[email protected]> +* +* SPDX-License-Identifier: GPL-2.0+ +*/ + +#include <common.h> +#include <asm/arch/clock.h> +#include <asm/io.h> +#include <clk-uclass.h> +#include <dm.h> +#include <dt-bindings/clock/gxbb-clkc.h> + +struct meson_clk { +void __iomem *addr; +ulong rate; +}; + +struct meson_gate { +unsigned int reg; +unsigned int bit; +}; + +#define MESON_GATE (id, _reg, _bit) \ + [id] = { \ + .reg = (_reg), \ + .bit = (_bit), \ + } + +struct meson_gate gates[] = { +/* Everything Else (EE) domain gates */ +MESON_GATE (CLKID_DDR ,HHI_GCLK_MPEG0 ,0 ), +MESON_GATE (CLKID_DOS ,HHI_GCLK_MPEG0 ,1 ), +MESON_GATE (CLKID_ISA ,HHI_GCLK_MPEG0 ,5 ), +MESON_GATE (CLKID_PL301 ,HHI_GCLK_MPEG0 ,6 ), +MESON_GATE (CLKID_PERIPHS ,HHI_GCLK_MPEG0 ,7 ), +MESON_GATE (CLKID_SPICC ,HHI_GCLK_MPEG0 ,8 ), +MESON_GATE (CLKID_I2C ,HHI_GCLK_MPEG0 ,9 ), +MESON_GATE (CLKID_SAR_ADC ,HHI_GCLK_MPEG0 ,10 ), +MESON_GATE (CLKID_SMART_CARD ,HHI_GCLK_MPEG0 ,11 ), +MESON_GATE (CLKID_RNG0 ,HHI_GCLK_MPEG0 ,12 ), +MESON_GATE (CLKID_UART0 ,HHI_GCLK_MPEG0 ,13 ), +MESON_GATE (CLKID_SDHC ,HHI_GCLK_MPEG0 ,14 ), +MESON_GATE (CLKID_STREAM ,HHI_GCLK_MPEG0 ,15 ), +MESON_GATE (CLKID_ASYNC_FIFO ,HHI_GCLK_MPEG0 ,16 ), +MESON_GATE (CLKID_SDIO ,HHI_GCLK_MPEG0 ,17 ), +MESON_GATE (CLKID_ABUF ,HHI_GCLK_MPEG0 ,18 ), +MESON_GATE (CLKID_HIU_IFACE ,HHI_GCLK_MPEG0 ,19 ), +MESON_GATE (CLKID_ASSIST_MISC ,HHI_GCLK_MPEG0 ,23 ), +MESON_GATE (CLKID_SD_EMMC_A ,HHI_GCLK_MPEG0 ,24 ), +MESON_GATE (CLKID_SD_EMMC_B ,HHI_GCLK_MPEG0 ,25 ), +MESON_GATE (CLKID_SD_EMMC_C ,HHI_GCLK_MPEG0 ,26 ), +MESON_GATE (CLKID_SPI ,HHI_GCLK_MPEG0 ,30 ), + +MESON_GATE (CLKID_I2S_SPDIF ,HHI_GCLK_MPEG1 ,2 ), +MESON_GATE (CLKID_ETH ,HHI_GCLK_MPEG1 ,3 ), +MESON_GATE (CLKID_DEMUX ,HHI_GCLK_MPEG1 ,4 ), +MESON_GATE (CLKID_AIU_GLUE ,HHI_GCLK_MPEG1 ,6 ), +MESON_GATE (CLKID_IEC958 ,HHI_GCLK_MPEG1 ,7 ), +MESON_GATE (CLKID_I2S_OUT ,HHI_GCLK_MPEG1 ,8 ), +MESON_GATE (CLKID_AMCLK ,HHI_GCLK_MPEG1 ,9 ), +MESON_GATE (CLKID_AIFIFO2 ,HHI_GCLK_MPEG1 ,10 ), +MESON_GATE (CLKID_MIXER ,HHI_GCLK_MPEG1 ,11 ), +MESON_GATE (CLKID_MIXER_IFACE ,HHI_GCLK_MPEG1 ,12 ), +MESON_GATE (CLKID_ADC ,HHI_GCLK_MPEG1 ,13 ), +MESON_GATE (CLKID_BLKMV ,HHI_GCLK_MPEG1 ,14 ), +MESON_GATE (CLKID_AIU ,HHI_GCLK_MPEG1 ,15 ), +MESON_GATE (CLKID_UART1 ,HHI_GCLK_MPEG1 ,16 ), +MESON_GATE (CLKID_G2D ,HHI_GCLK_MPEG1 ,20 ), +MESON_GATE (CLKID_USB0 ,HHI_GCLK_MPEG1 ,21 ), +MESON_GATE (CLKID_USB1 ,HHI_GCLK_MPEG1 ,22 ), +MESON_GATE (CLKID_RESET ,HHI_GCLK_MPEG1 ,23 ), +MESON_GATE (CLKID_NAND ,HHI_GCLK_MPEG1 ,24 ), +MESON_GATE (CLKID_DOS_PARSER ,HHI_GCLK_MPEG1 ,25 ), +MESON_GATE (CLKID_USB ,HHI_GCLK_MPEG1 ,26 ), +MESON_GATE (CLKID_VDIN1 ,HHI_GCLK_MPEG1 ,28 ), +MESON_GATE (CLKID_AHB_ARB0 ,HHI_GCLK_MPEG1 ,29 ), +MESON_GATE (CLKID_EFUSE ,HHI_GCLK_MPEG1 ,30 ), +MESON_GATE (CLKID_BOOT_ROM ,HHI_GCLK_MPEG1 ,31 ), + +MESON_GATE (CLKID_AHB_DATA_BUS ,HHI_GCLK_MPEG2 ,1 ), +MESON_GATE (CLKID_AHB_CTRL_BUS ,HHI_GCLK_MPEG2 ,2 ), +MESON_GATE (CLKID_HDMI_INTR_SYNC ,HHI_GCLK_MPEG2 ,3 ), +MESON_GATE (CLKID_HDMI_PCLK ,HHI_GCLK_MPEG2 ,4 ), +MESON_GATE (CLKID_USB1_DDR_BRIDGE ,HHI_GCLK_MPEG2 ,8 ), +MESON_GATE (CLKID_USB0_DDR_BRIDGE ,HHI_GCLK_MPEG2 ,9 ), +MESON_GATE (CLKID_MMC_PCLK ,HHI_GCLK_MPEG2 ,11 ), +MESON_GATE (CLKID_DVIN ,HHI_GCLK_MPEG2 ,12 ), +MESON_GATE (CLKID_UART2 ,HHI_GCLK_MPEG2 ,15 ), +MESON_GATE (CLKID_SANA ,HHI_GCLK_MPEG2 ,22 ), +MESON_GATE (CLKID_VPU_INTR ,HHI_GCLK_MPEG2 ,25 ), +MESON_GATE (CLKID_SEC_AHB_AHB3_BRIDGE ,HHI_GCLK_MPEG2 ,26 ), +MESON_GATE (CLKID_CLK81_A53 ,HHI_GCLK_MPEG2 ,29 ), + +MESON_GATE (CLKID_VCLK2_VENCI0 ,HHI_GCLK_OTHER ,1 ), +MESON_GATE (CLKID_VCLK2_VENCI1 ,HHI_GCLK_OTHER ,2 ), +MESON_GATE (CLKID_VCLK2_VENCP0 ,HHI_GCLK_OTHER ,3 ), +MESON_GATE (CLKID_VCLK2_VENCP1 ,HHI_GCLK_OTHER ,4 ), +MESON_GATE (CLKID_GCLK_VENCI_INT0 ,HHI_GCLK_OTHER ,8 ), +MESON_GATE (CLKID_DAC_CLK ,HHI_GCLK_OTHER ,10 ), +MESON_GATE (CLKID_AOCLK_GATE ,HHI_GCLK_OTHER ,14 ), +MESON_GATE (CLKID_IEC958_GATE ,HHI_GCLK_OTHER ,16 ), +MESON_GATE (CLKID_ENC480P ,HHI_GCLK_OTHER ,20 ), +MESON_GATE (CLKID_RNG1 ,HHI_GCLK_OTHER ,21 ), +MESON_GATE (CLKID_GCLK_VENCI_INT1 ,HHI_GCLK_OTHER ,22 ), +MESON_GATE (CLKID_VCLK2_VENCLMCC ,HHI_GCLK_OTHER ,24 ), +MESON_GATE (CLKID_VCLK2_VENCL ,HHI_GCLK_OTHER ,25 ), +MESON_GATE (CLKID_VCLK_OTHER ,HHI_GCLK_OTHER ,26 ), +MESON_GATE (CLKID_EDP ,HHI_GCLK_OTHER ,31 ), + +/* Always On (AO) domain gates */ +MESON_GATE (CLKID_AO_MEDIA_CPU ,HHI_GCLK_AO ,0 ), +MESON_GATE (CLKID_AO_AHB_SRAM ,HHI_GCLK_AO ,1 ), +MESON_GATE (CLKID_AO_AHB_BUS ,HHI_GCLK_AO ,2 ), +MESON_GATE (CLKID_AO_IFACE ,HHI_GCLK_AO ,3 ), +MESON_GATE (CLKID_AO_I2C ,HHI_GCLK_AO ,4 ), +}; + +static int meson_set_gate (struct clk *clk,bool on) +{ +struct meson_clk *priv =dev_get_priv (clk->dev); +struct meson_gate *gate; + +if (clk->id >=ARRAY_SIZE (gates)) +return -ENOENT ; + + gate = &gates[clk->id]; + +if (gate->reg ==0 ) +return -ENOENT ; + +clrsetbits_le32 (priv->addr + gate->reg, +BIT (gate->bit), on ?BIT (gate->bit) :0 ); +return 0 ; +} + +static int meson_clk_enable (struct clk *clk) +{ +return meson_set_gate (clk, true); +} + +static int meson_clk_disable (struct clk *clk) +{ +return meson_set_gate (clk, false); +} + +static ulong meson_clk_get_rate (struct clk *clk) +{ +struct meson_clk *priv =dev_get_priv (clk->dev); + +if (clk->id !=CLKID_CLK81 ) { +if (clk->id >=ARRAY_SIZE (gates)) +return -ENOENT ; +if (gates[clk->id].reg ==0 ) +return -ENOENT ; + } + +/* Use cached value if available */ +if (priv->rate) +return priv->rate; + + priv->rate =meson_measure_clk_rate (CLK_81 ); + +return priv->rate; +} + +static int meson_clk_probe (struct udevice *dev) +{ +struct meson_clk *priv =dev_get_priv (dev); + + priv->addr =dev_read_addr_ptr (dev); +debug ("meson-clk: probed at addr %p\n" , priv->addr); + +return 0 ; +} + +static struct clk_ops meson_clk_ops = { + .disable = meson_clk_disable, + .enable = meson_clk_enable, + .get_rate = meson_clk_get_rate, +}; + +static const struct udevice_id meson_clk_ids[] = { + { .compatible ="amlogic,gxbb-clkc" }, + { .compatible ="amlogic,gxl-clkc" }, + { }
drivers/clk/clk_meson.c line 196
Quoted 10 lines
drivers/clk/clk_meson.c new file +10
-0+}; + +U_BOOT_DRIVER (meson_clk) = { + .name ="meson_clk" , + .id =UCLASS_CLK , + .of_match = meson_clk_ids, + .priv_auto_alloc_size =sizeof (struct meson_clk ), + .ops = &meson_clk_ops, + .probe = meson_clk_probe, +};
Ok for now to only handle the gates with the clock measure function.
PATCH 3/4 clk: add Amlogic meson clock driver
In reply to Beniamino GalvaniHi Benjamin,
Quoted 10 lines · Beniamino Galvani
Introduce a basic clock driver for Amlogic Meson SoCs which supports enabling/disabling clock gates and getting their frequency.
Signed-off-by Beniamino Galvani <[email protected]>--- arch/arm/mach-meson/Kconfig | 2 + drivers/clk/Makefile | 1 + drivers/clk/clk_meson.c | 196 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 199 insertions(+) create mode 100644 drivers/clk/clk_meson.c
PATCH 3/4 clk: add Amlogic meson clock driver
In reply to Beniamino GalvaniHi Beniamino,
Quoted 15 lines · Beniamino Galvani
Introduce a basic clock driver for Amlogic Meson SoCs which supports enabling/disabling clock gates and getting their frequency.
Signed-off-by Beniamino Galvani <[email protected]>--- arch/arm/mach-meson/Kconfig | 2 + drivers/clk/Makefile | 1 + drivers/clk/clk_meson.c | 196 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 199 insertions(+) create mode 100644 drivers/clk/clk_meson.carch/arm/mach-meson/Kconfig +0
-0
[...]
arch/arm/mach-meson/Kconfig
Quoted 8 lines
arch/arm/mach-meson/Kconfig +8
-0+ +static int meson_set_gate(struct clk *clk, bool on) +{ + struct meson_clk *priv = dev_get_priv(clk->dev); + struct meson_gate *gate; + + if (clk->id >= ARRAY_SIZE(gates)) + return -ENOENT;
This should be -ENOSYS, otherwise it breaks the ethernet driver since it waits -ENOSYS if clock cannot be enabled.
arch/arm/mach-meson/Kconfig
Quoted 5 lines
arch/arm/mach-meson/Kconfig +5
-0+ + gate = &gates[clk->id]; + + if (gate->reg == 0) + return -ENOENT;
Same here -ENOSYS
Quoted 13 lines
arch/arm/mach-meson/Kconfig +13
-0+ + clrsetbits_le32(priv->addr + gate->reg, + BIT(gate->bit), on ? BIT(gate->bit) : 0); + return 0; +} + +static int meson_clk_enable(struct clk *clk) +{ + return meson_set_gate(clk, true); +} + +static int meson_clk_disable(struct clk *clk) +{
arch/arm/mach-meson/Kconfig
Quoted 10 lines
arch/arm/mach-meson/Kconfig +10
-0+ return meson_set_gate(clk, false); +} + +static ulong meson_clk_get_rate(struct clk *clk) +{ + struct meson_clk *priv = dev_get_priv(clk->dev); + + if (clk->id != CLKID_CLK81) { + if (clk->id >= ARRAY_SIZE(gates)) + return -ENOENT;
Same here -ENOSYS
arch/arm/mach-meson/Kconfig
Quoted 2 lines
arch/arm/mach-meson/Kconfig +2
-0+ if (gates[clk->id].reg == 0) + return -ENOENT;
Same here -ENOSYS
arch/arm/mach-meson/Kconfig
Quoted 11 lines
arch/arm/mach-meson/Kconfig +11
-0+ } + + /* Use cached value if available */ + if (priv->rate) + return priv->rate; + + priv->rate = meson_measure_clk_rate(CLK_81); + + return priv->rate; +} +
[...]
Neil
PATCH 3/4 clk: add Amlogic meson clock driver
Hi Neil,
Quoted 20 lines · Neil Armstrong
Hi Beniamino,
Quoted 15 lines · Beniamino Galvani
Introduce a basic clock driver for Amlogic Meson SoCs which supports enabling/disabling clock gates and getting their frequency.
Signed-off-by Beniamino Galvani <[email protected]>--- arch/arm/mach-meson/Kconfig | 2 + drivers/clk/Makefile | 1 + drivers/clk/clk_meson.c | 196 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 199 insertions(+) create mode 100644 drivers/clk/clk_meson.carch/arm/mach-meson/Kconfig +0
-0[...]
Quoted 10 lines
arch/arm/mach-meson/Kconfig
Quoted 8 lines
arch/arm/mach-meson/Kconfig +8
-0+ +static int meson_set_gate(struct clk *clk, bool on) +{ + struct meson_clk *priv = dev_get_priv(clk->dev); + struct meson_gate *gate; + + if (clk->id >= ARRAY_SIZE(gates)) + return -ENOENT;This should be
-ENOSYS, otherwise it breaks the ethernet driver since it waits-ENOSYSif clock cannot be enabled.
Perhaps, but this is a genuine error, so it is OK to break the Ethernet driver, isn't it? We don't want errors to be silently ignored.
Not having a device is one thing, but having a device that does not work is bad.
Also I have tried to keep -ENOSYS for cases where the driver does not support the operation. We should be very clear in clk-uclass.h as to what errors are returned. At present I don't see ENOSYS mentioned. At the very least we should update the docs if certain behaviour is expected. I would also expect us to have a sandbox test for it.
Quoted 54 lines
arch/arm/mach-meson/Kconfig
Quoted 6 lines
arch/arm/mach-meson/Kconfig +5
-0+ + gate = &gates[clk->id]; + + if (gate->reg == 0) + return -ENOENT;Same here
-ENOSYSQuoted 13 lines
arch/arm/mach-meson/Kconfig +13
-0+ + clrsetbits_le32(priv->addr + gate->reg, + BIT(gate->bit), on ? BIT(gate->bit) : 0); + return 0; +} + +static int meson_clk_enable(struct clk *clk) +{ + return meson_set_gate(clk, true); +} + +static int meson_clk_disable(struct clk *clk) +{arch/arm/mach-meson/Kconfig
Quoted 10 lines
arch/arm/mach-meson/Kconfig +10
-0+ return meson_set_gate(clk, false); +} + +static ulong meson_clk_get_rate(struct clk *clk) +{ + struct meson_clk *priv = dev_get_priv(clk->dev); + + if (clk->id != CLKID_CLK81) { + if (clk->id >= ARRAY_SIZE(gates)) + return -ENOENT;Same here
-ENOSYSarch/arm/mach-meson/Kconfig
Quoted 2 lines
arch/arm/mach-meson/Kconfig +2
-0+ if (gates[clk->id].reg == 0) + return -ENOENT;Same here
-ENOSYSQuoted 11 lines
arch/arm/mach-meson/Kconfig +11
-0+ } + + /* Use cached value if available */ + if (priv->rate) + return priv->rate; + + priv->rate = meson_measure_clk_rate(CLK_81); + + return priv->rate; +} +[...]
Quoted 1 line
Neil
Regards,
Simon
PATCH 3/4 clk: add Amlogic meson clock driver
Quoted 34 lines · Simon Glass
Hi Neil,
Quoted 20 lines · Neil Armstrong
Hi Beniamino,
Quoted 15 lines · Beniamino Galvani
Introduce a basic clock driver for Amlogic Meson SoCs which supports enabling/disabling clock gates and getting their frequency.
Signed-off-by Beniamino Galvani <[email protected]>--- arch/arm/mach-meson/Kconfig | 2 + drivers/clk/Makefile | 1 + drivers/clk/clk_meson.c | 196 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 199 insertions(+) create mode 100644 drivers/clk/clk_meson.carch/arm/mach-meson/Kconfig +0
-0[...]
Quoted 10 lines
arch/arm/mach-meson/Kconfig
Quoted 8 lines
arch/arm/mach-meson/Kconfig +8
-0+ +static int meson_set_gate(struct clk *clk, bool on) +{ + struct meson_clk *priv = dev_get_priv(clk->dev); + struct meson_gate *gate; + + if (clk->id >= ARRAY_SIZE(gates)) + return -ENOENT;This should be
-ENOSYS, otherwise it breaks the ethernet driver since it waits-ENOSYSif clock cannot be enabled.
Quoted 6 lines
Perhaps, but this is a genuine error, so it is OK to break the Ethernet driver, isn't it? We don't want errors to be silently ignored.
Not having a device is one thing, but having a device that does not work is bad.
The driver only manages the gates, enabling and disabling them and getting their freq. The missing clocks of the ethernet driver in this case are dividers of the PLL, thus we don't need to enable them, and for now the driver don't need the freq.
Quoted 5 lines
Also I have tried to keep
-ENOSYSfor cases where the driver does not support the operation. We should be very clear inclk-uclass.has to what errors are returned. At present I don't see ENOSYS mentioned. At the very least we should update the docs if certain behaviour is expected. I would also expect us to have a sandbox test for it.
In this case, the driver does not support the operation for these clocks, but maybe it would be better to add them with reg=0 and return -ENOSYS in the following return :
Quoted 9 lines
Quoted 9 lines
arch/arm/mach-meson/Kconfig
Quoted 7 lines
arch/arm/mach-meson/Kconfig +5
-0+ + gate = &gates[clk->id]; + + if (gate->reg == 0) + return -ENOENT;Same here
-ENOSYS
Here thsi means it's not a gate.
Quoted 51 lines
Quoted 46 lines
Quoted 14 lines
arch/arm/mach-meson/Kconfig +13
-0+ + clrsetbits_le32(priv->addr + gate->reg, + BIT(gate->bit), on ? BIT(gate->bit) : 0); + return 0; +} + +static int meson_clk_enable(struct clk *clk) +{ + return meson_set_gate(clk, true); +} + +static int meson_clk_disable(struct clk *clk) +{arch/arm/mach-meson/Kconfig
Quoted 10 lines
arch/arm/mach-meson/Kconfig +10
-0+ return meson_set_gate(clk, false); +} + +static ulong meson_clk_get_rate(struct clk *clk) +{ + struct meson_clk *priv = dev_get_priv(clk->dev); + + if (clk->id != CLKID_CLK81) { + if (clk->id >= ARRAY_SIZE(gates)) + return -ENOENT;Same here
-ENOSYSarch/arm/mach-meson/Kconfig
Quoted 2 lines
arch/arm/mach-meson/Kconfig +2
-0+ if (gates[clk->id].reg == 0) + return -ENOENT;Same here
-ENOSYSQuoted 11 lines
arch/arm/mach-meson/Kconfig +11
-0+ } + + /* Use cached value if available */ + if (priv->rate) + return priv->rate; + + priv->rate = meson_measure_clk_rate(CLK_81); + + return priv->rate; +} +[...]
Quoted 1 line
Neil
Regards,
Simon
PATCH 3/4 clk: add Amlogic meson clock driver
Hi Neil,
Quoted 39 lines · Neil Armstrong
Quoted 38 lines · Simon Glass
Hi Neil,
Quoted 20 lines · Neil Armstrong
Hi Beniamino,
Quoted 15 lines · Beniamino Galvani
Introduce a basic clock driver for Amlogic Meson SoCs which supports enabling/disabling clock gates and getting their frequency.
Signed-off-by Beniamino Galvani <[email protected]>--- arch/arm/mach-meson/Kconfig | 2 + drivers/clk/Makefile | 1 + drivers/clk/clk_meson.c | 196 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 199 insertions(+) create mode 100644 drivers/clk/clk_meson.carch/arm/mach-meson/Kconfig +0
-0[...]
Quoted 10 lines
arch/arm/mach-meson/Kconfig
Quoted 8 lines
arch/arm/mach-meson/Kconfig +8
-0+ +static int meson_set_gate(struct clk *clk, bool on) +{ + struct meson_clk *priv = dev_get_priv(clk->dev); + struct meson_gate *gate; + + if (clk->id >= ARRAY_SIZE(gates)) + return -ENOENT;This should be
-ENOSYS, otherwise it breaks the ethernet driver since it waits-ENOSYSif clock cannot be enabled.Perhaps, but this is a genuine error, so it is OK to break the Ethernet driver, isn't it? We don't want errors to be silently ignored.
Quoted 6 lines
Quoted 2 lines
Not having a device is one thing, but having a device that does not work is bad.
The driver only manages the gates, enabling and disabling them and getting their freq. The missing clocks of the ethernet driver in this case are dividers of the PLL, thus we don't need to enable them, and for now the driver don't need the freq.
Yes but -ENOSYS means that the driver does not support the operation at all. Put it another way: you can't return -ENOSYS for some parameters and not for others.
Quoted 9 lines
Quoted 6 lines
Also I have tried to keep
-ENOSYSfor cases where the driver does not support the operation. We should be very clear inclk-uclass.has to what errors are returned. At present I don't see ENOSYS mentioned. At the very least we should update the docs if certain behaviour is expected. I would also expect us to have a sandbox test for it.In this case, the driver does not support the operation for these clocks, but maybe it would be better to add them with reg=0 and return
-ENOSYSin the following return :
I don't like that - ENOENT seems better.
Quoted 11 lines
Quoted 10 lines
Quoted 10 lines
arch/arm/mach-meson/Kconfig
Quoted 8 lines
arch/arm/mach-meson/Kconfig +5
-0+ + gate = &gates[clk->id]; + + if (gate->reg == 0) + return -ENOENT;Same here
-ENOSYS
Quoted 1 line
Here thsi means it's not a gate.
Yes, but the driver still supports the operation. The problem is that its inputs are invalid. So use -ENOENT to mean that.
Quoted 47 lines
Quoted 47 lines
Quoted 47 lines
Quoted 15 lines
arch/arm/mach-meson/Kconfig +13
-0+ + clrsetbits_le32(priv->addr + gate->reg, + BIT(gate->bit), on ? BIT(gate->bit) : 0); + return 0; +} + +static int meson_clk_enable(struct clk *clk) +{ + return meson_set_gate(clk, true); +} + +static int meson_clk_disable(struct clk *clk) +{arch/arm/mach-meson/Kconfig
Quoted 10 lines
arch/arm/mach-meson/Kconfig +10
-0+ return meson_set_gate(clk, false); +} + +static ulong meson_clk_get_rate(struct clk *clk) +{ + struct meson_clk *priv = dev_get_priv(clk->dev); + + if (clk->id != CLKID_CLK81) { + if (clk->id >= ARRAY_SIZE(gates)) + return -ENOENT;Same here
-ENOSYSarch/arm/mach-meson/Kconfig
Quoted 2 lines
arch/arm/mach-meson/Kconfig +2
-0+ if (gates[clk->id].reg == 0) + return -ENOENT;Same here
-ENOSYSQuoted 11 lines
arch/arm/mach-meson/Kconfig +11
-0+ } + + /* Use cached value if available */ + if (priv->rate) + return priv->rate; + + priv->rate = meson_measure_clk_rate(CLK_81); + + return priv->rate; +} +[...]
Quoted 6 lines
Quoted 5 lines
Quoted 1 line
Neil
Regards,
Simon
Regards,
Simon
PATCH 3/4 clk: add Amlogic meson clock driver
Hi guys,
Am 30.03.2018 um 10:41 schrieb Simon Glass:
Quoted 12 lines · Neil Armstrong
Quoted 11 lines · Simon Glass
Quoted 9 lines · Neil Armstrong
Quoted 8 lines · Beniamino Galvani
drivers/clk/clk_meson.c line 130
Quoted 5 lines
drivers/clk/clk_meson.c new file +5
-0+ + gate = &gates[clk->id]; + +if (gate->reg ==0 ) +return -ENOENT ;Same here
-ENOSYS
Quoted 4 lines
Quoted 1 line
Here thsi means it's not a gate.
Yes, but the driver still supports the operation. The problem is that its inputs are invalid. So use
-ENOENTto mean that.
Isn't that the definition of -EINVAL?
Cheers,
Andreas
Signature · 3 lines
SUSE Linux GmbH, Maxfeldstr. 5, 90409 N?rnberg, Germany GF: Felix Imend?rffer, Jane Smithard, Graham Norton HRB 21284 (AG N?rnberg)
PATCH 3/4 clk: add Amlogic meson clock driver
Hi Andreas,
Quoted 15 lines · Andreas F?rber
Hi guys,
Am 30.03.2018 um 10:41 schrieb Simon Glass:
Quoted 12 lines · Neil Armstrong
Quoted 11 lines · Simon Glass
Quoted 9 lines · Neil Armstrong
Quoted 8 lines · Beniamino Galvani
drivers/clk/clk_meson.c line 130
Quoted 5 lines
drivers/clk/clk_meson.c new file +5
-0+ + gate = &gates[clk->id]; + +if (gate->reg ==0 ) +return -ENOENT ;Same here
-ENOSYS
Quoted 6 lines
Quoted 4 lines
Quoted 1 line
Here thsi means it's not a gate.
Yes, but the driver still supports the operation. The problem is that its inputs are invalid. So use
-ENOENTto mean that.Isn't that the definition of
-EINVAL?
We tend to use that to indicate a failure to read the DT config.
I should probably not have said 'invalid'. The input value is reasonable (it isn't -ve, for example) but the selected item does not exist.
Regards,
Simon
PATCH 4/4 meson: use the clock driver
In reply to Beniamino GalvaniUse the clk framework to initialize clocks from drivers that need them instead of having hardcoded frequencies and initializations from board code.
--- arch/arm/include/asm/arch-meson/gxbb.h | 10 ---------- arch/arm/include/asm/arch-meson/i2c.h | 11 ----------- board/amlogic/odroid-c2/odroid-c2.c | 4 +--- board/amlogic/p212/p212.c | 3 +-- drivers/i2c/meson_i2c.c | 20 +++++++++++++++++--- 5 files changed, 19 insertions(+), 29 deletions(-) delete mode 100644 arch/arm/include/asm/arch-meson/i2c.h
arch/arm/include/asm/arch-meson/gxbb.h +0 -10
@@ -40,14 +40,4 @@/* Ethernet memory power domain */ #define GXBB_MEM_PD_REG_0_ETH_MASK (BIT(2) | BIT(3)) -/* Clock gates */ -#define GXBB_GCLK_MPEG_0 GXBB_HIU_ADDR(0x50) -#define GXBB_GCLK_MPEG_1 GXBB_HIU_ADDR(0x51) -#define GXBB_GCLK_MPEG_2 GXBB_HIU_ADDR(0x52) -#define GXBB_GCLK_MPEG_OTHER GXBB_HIU_ADDR(0x53) -#define GXBB_GCLK_MPEG_AO GXBB_HIU_ADDR(0x54) - -#define GXBB_GCLK_MPEG_0_I2C BIT(9) -#define GXBB_GCLK_MPEG_1_ETH BIT(3) -#endif /* __GXBB_H__ */
arch/arm/include/asm/arch-meson/i2c.h deleted +0 -11
@@ -1,11 +0,0 @@ -/* -* Copyright 2017 - Beniamino Galvani <[email protected]> -* -* SPDX-License-Identifier: GPL-2.0+ -*/ -#ifndef _MESON_I2C_H_ -#define _MESON_I2C_H_ - -#define MESON_I2C_CLK_RATE 167000000 - -#endif
board/amlogic/odroid-c2/odroid-c2.c +1 -3
@@ -34,9 +34,7 @@ int misc_init_r(void)GXBB_ETH_REG_0_PHY_CLK_EN | GXBB_ETH_REG_0_CLK_EN); -/* Enable power and clock gate */ -setbits_le32 (GXBB_GCLK_MPEG_0 ,GXBB_GCLK_MPEG_0_I2C ); -setbits_le32 (GXBB_GCLK_MPEG_1 ,GXBB_GCLK_MPEG_1_ETH ); +/* Enable power */ clrbits_le32 (GXBB_MEM_PD_REG_0 ,GXBB_MEM_PD_REG_0_ETH_MASK );/* Reset PHY on GPIOZ_14 */
board/amlogic/p212/p212.c +1 -2
@@ -36,8 +36,7 @@ int misc_init_r(void)out_le32 (GXBB_ETH_REG_2 ,0x10110181 );out_le32 (GXBB_ETH_REG_3 ,0xe40908ff ); -/* Enable power and clock gate */ -setbits_le32 (GXBB_GCLK_MPEG_1 ,GXBB_GCLK_MPEG_1_ETH ); +/* Enable power */ clrbits_le32 (GXBB_MEM_PD_REG_0 ,GXBB_MEM_PD_REG_0_ETH_MASK );if (!eth_env_get_enetaddr ("ethaddr" , mac_addr)) {
drivers/i2c/meson_i2c.c +17 -3
@@ -4,8 +4,8 @@* SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> -#include <asm/arch/i2c.h> #include <asm/io.h> +#include <clk.h> #include <dm.h> #include <i2c.h>
@@ -43,6 +43,7 @@ struct i2c_regs { };struct meson_i2c { +struct clk clk;struct i2c_regs *regs;struct i2c_msg *msg;bool last;
@@ -209,9 +210,13 @@ static int meson_i2c_xfer(struct udevice *bus, struct i2c_msg *msg,static int meson_i2c_set_bus_speed (struct udevice *bus,unsigned int speed) {struct meson_i2c *i2c =dev_get_priv (bus); -unsigned int clk_rate =MESON_I2C_CLK_RATE ; +ulong clk_rate;unsigned int div; + clk_rate =clk_get_rate (&i2c->clk); +if (IS_ERR_VALUE (clk_rate)) +return -EINVAL ; + div =DIV_ROUND_UP (clk_rate, speed *4 );/* clock divider has 12 bits */
@@ -226,7 +231,7 @@ static int meson_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)clrsetbits_le32 (&i2c->regs->ctrl,REG_CTRL_CLKDIVEXT_MASK , (div >>10 ) <<REG_CTRL_CLKDIVEXT_SHIFT ); -debug ("meson i2c: set clk %u, src %u, div %u\n" , speed, clk_rate, div); +debug ("meson i2c: set clk %u, src %lu, div %u\n" , speed, clk_rate, div);return 0 ; }
@@ -234,6 +239,15 @@ static int meson_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)static int meson_i2c_probe (struct udevice *bus) {struct meson_i2c *i2c =dev_get_priv (bus); +int ret; + + ret =clk_get_by_index (bus,0 , &i2c->clk); +if (ret <0 ) +return ret; + + ret =clk_enable (&i2c->clk); +if (ret) +return ret; i2c->regs =dev_read_addr_ptr (bus);clrbits_le32 (&i2c->regs->ctrl,REG_CTRL_START );
Signature · 1 line
2.14.3
PATCH 4/4 meson: use the clock driver
Quoted 132 lines · Beniamino Galvani
Use the clk framework to initialize clocks from drivers that need them instead of having hardcoded frequencies and initializations from board code.
Signed-off-by Beniamino Galvani <[email protected]>--- arch/arm/include/asm/arch-meson/gxbb.h | 10 ---------- arch/arm/include/asm/arch-meson/i2c.h | 11 ----------- board/amlogic/odroid-c2/odroid-c2.c | 4 +--- board/amlogic/p212/p212.c | 3 +-- drivers/i2c/meson_i2c.c | 20 +++++++++++++++++--- 5 files changed, 19 insertions(+), 29 deletions(-) delete mode 100644 arch/arm/include/asm/arch-meson/i2c.harch/arm/include/asm/arch-meson/gxbb.h +0
-10@@ -40,14 +40,4 @@/* Ethernet memory power domain */ #define GXBB_MEM_PD_REG_0_ETH_MASK (BIT(2) | BIT(3)) -/* Clock gates */ -#define GXBB_GCLK_MPEG_0 GXBB_HIU_ADDR(0x50) -#define GXBB_GCLK_MPEG_1 GXBB_HIU_ADDR(0x51) -#define GXBB_GCLK_MPEG_2 GXBB_HIU_ADDR(0x52) -#define GXBB_GCLK_MPEG_OTHER GXBB_HIU_ADDR(0x53) -#define GXBB_GCLK_MPEG_AO GXBB_HIU_ADDR(0x54) - -#define GXBB_GCLK_MPEG_0_I2C BIT(9) -#define GXBB_GCLK_MPEG_1_ETH BIT(3) -#endif /* __GXBB_H__ */ arch/arm/include/asm/arch-meson/i2c.h deleted +0
-11@@ -1,11 +0,0 @@ -/* -* Copyright 2017 - Beniamino Galvani <[email protected]> -* -* SPDX-License-Identifier: GPL-2.0+ -*/ -#ifndef _MESON_I2C_H_ -#define _MESON_I2C_H_ - -#define MESON_I2C_CLK_RATE 167000000 - -#endif board/amlogic/odroid-c2/odroid-c2.c +1
-3@@ -34,9 +34,7 @@ int misc_init_r(void)GXBB_ETH_REG_0_PHY_CLK_EN | GXBB_ETH_REG_0_CLK_EN); -/* Enable power and clock gate */ -setbits_le32 (GXBB_GCLK_MPEG_0 ,GXBB_GCLK_MPEG_0_I2C ); -setbits_le32 (GXBB_GCLK_MPEG_1 ,GXBB_GCLK_MPEG_1_ETH ); +/* Enable power */ clrbits_le32 (GXBB_MEM_PD_REG_0 ,GXBB_MEM_PD_REG_0_ETH_MASK );/* Reset PHY on GPIOZ_14 */ board/amlogic/p212/p212.c +1
-2@@ -36,8 +36,7 @@ int misc_init_r(void)out_le32 (GXBB_ETH_REG_2 ,0x10110181 );out_le32 (GXBB_ETH_REG_3 ,0xe40908ff ); -/* Enable power and clock gate */ -setbits_le32 (GXBB_GCLK_MPEG_1 ,GXBB_GCLK_MPEG_1_ETH ); +/* Enable power */ clrbits_le32 (GXBB_MEM_PD_REG_0 ,GXBB_MEM_PD_REG_0_ETH_MASK );if (!eth_env_get_enetaddr ("ethaddr" , mac_addr)) {drivers/i2c/meson_i2c.c +10
-3@@ -4,8 +4,8 @@* SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> -#include <asm/arch/i2c.h> #include <asm/io.h> +#include <clk.h> #include <dm.h> #include <i2c.h> @@ -43,6 +43,7 @@ struct i2c_regs { };struct meson_i2c { +struct clk clk;struct i2c_regs *regs;struct i2c_msg *msg;bool last;@@ -209,9 +210,13 @@ static int meson_i2c_xfer(struct udevice *bus, struct i2c_msg *msg,static int meson_i2c_set_bus_speed (struct udevice *bus,unsigned int speed) {struct meson_i2c *i2c =dev_get_priv (bus); -unsigned int clk_rate =MESON_I2C_CLK_RATE ; +ulong clk_rate;unsigned int div; + clk_rate =clk_get_rate (&i2c->clk); +if (IS_ERR_VALUE (clk_rate)) +return -EINVAL ; + div =DIV_ROUND_UP (clk_rate, speed *4 );/* clock divider has 12 bits */ @@ -226,7 +231,7 @@ static int meson_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)clrsetbits_le32 (&i2c->regs->ctrl,REG_CTRL_CLKDIVEXT_MASK , (div >>10 ) <<REG_CTRL_CLKDIVEXT_SHIFT ); -debug ("meson i2c: set clk %u, src %u, div %u\n" , speed, clk_rate, div); +debug ("meson i2c: set clk %u, src %lu, div %u\n" , speed, clk_rate, div);return 0 ; }@@ -234,6 +239,15 @@ static int meson_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)static int meson_i2c_probe (struct udevice *bus) {struct meson_i2c *i2c =dev_get_priv (bus); +int ret; +
drivers/i2c/meson_i2c.c static int meson_i2c_set_bus_speed(struct udevice *bus, unsigned int speed) · line 253
Quoted 10 lines
drivers/i2c/meson_i2c.c +7
-0+ ret =clk_get_by_index (bus,0 , &i2c->clk); +if (ret <0 ) +return ret; + + ret =clk_enable (&i2c->clk); +if (ret) +return ret; i2c->regs =dev_read_addr_ptr (bus);clrbits_le32 (&i2c->regs->ctrl,REG_CTRL_START );
You must now rebase it to master since tom merged the Khadas and LibreTech-CC patches.
Thanks for the patchset, it looks very good.
Neil
PATCH 4/4 meson: use the clock driver
In reply to Beniamino GalvaniQuoted 5 lines · Beniamino Galvani
Use the clk framework to initialize clocks from drivers that need them instead of having hardcoded frequencies and initializations from board code.
Signed-off-by Beniamino Galvani <[email protected]>
Quoted 8 lines
--- arch/arm/include/asm/arch-meson/gxbb.h | 10 ---------- arch/arm/include/asm/arch-meson/i2c.h | 11 ----------- board/amlogic/odroid-c2/odroid-c2.c | 4 +--- board/amlogic/p212/p212.c | 3 +-- drivers/i2c/meson_i2c.c | 20 +++++++++++++++++--- 5 files changed, 19 insertions(+), 29 deletions(-) delete mode 100644 arch/arm/include/asm/arch-meson/i2c.h
PATCH 4/4 meson: use the clock driver
In reply to Beniamino GalvaniQuoted 6 lines · Beniamino Galvani
Use the clk framework to initialize clocks from drivers that need them instead of having hardcoded frequencies and initializations from board code.
Signed-off-by Beniamino Galvani <[email protected]>Reviewed-by Simon Glass <[email protected]>
Quoted 8 lines
--- arch/arm/include/asm/arch-meson/gxbb.h | 10 ---------- arch/arm/include/asm/arch-meson/i2c.h | 11 ----------- board/amlogic/odroid-c2/odroid-c2.c | 4 +--- board/amlogic/p212/p212.c | 3 +-- drivers/i2c/meson_i2c.c | 20 +++++++++++++++++--- 5 files changed, 19 insertions(+), 29 deletions(-) delete mode 100644 arch/arm/include/asm/arch-meson/i2c.h
This fails to apply in non-trivial ways, please update and re-test, thanks!
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: not available URL: <http://lists.infradead.org/pipermail/linux-amlogic/attachments/20171212/5cd90295/attachment.sig>
cover Meson clock driver
In reply to Beniamino GalvaniHi Beniamino,
Quoted 22 lines · Beniamino Galvani
Hi,
this is a basic clock driver for u-boot that supports enabling/disabling clock gates and getting their frequency. With this, some hardcoded initializations can be removed from the board code, and drivers can use the information from device tree to initialize clocks.
Beniamino Galvani (4):
ARM: dts: updategxbb-clkc.hfrom Linux 4.14
ARM: meson: add clock measurement function
clk: add Amlogic meson clock driver
meson: use the clock driverarch/arm/include/asm/arch-meson/clock.h | 34 ++++++ arch/arm/include/asm/arch-meson/gxbb.h | 10 -- arch/arm/include/asm/arch-meson/i2c.h | 11 -- arch/arm/mach-meson/Kconfig | 2 + arch/arm/mach-meson/Makefile | 2 +- arch/arm/mach-meson/clock.c | 45 ++++++++ board/amlogic/odroid-c2/odroid-c2.c | 4 +- board/amlogic/p212/p212.c | 3 +- drivers/clk/Makefile | 1 +
Quoted 9 lines
drivers/clk/clk_meson.c | 196 ++++++++++++++++++++++++++++++++ drivers/i2c/meson_i2c.c | 20 +++- include/dt-bindings/clock/gxbb-clkc.h | 75 ++++++++++++ 12 files changed, 373 insertions(+), 30 deletions(-) create mode 100644 arch/arm/include/asm/arch-meson/clock.h delete mode 100644 arch/arm/include/asm/arch-meson/i2c.h create mode 100644 arch/arm/mach-meson/clock.c create mode 100644 drivers/clk/clk_meson.c
Do you plan to re-send the driver soon ?
Thanks,
Neil
cover Meson clock driver
2018-03-28 10:59 GMT+02:00 Neil Armstrong <[email protected]>:
Quoted 1 line
Do you plan to re-send the driver soon ?
Yes, I plan to submit it again in the next days.
Beniamino
cover Meson clock driver
Quoted 8 lines · Beniamino Galvani
2018-03-28 10:59 GMT+02:00 Neil Armstrong <[email protected]>:
Quoted 1 line
Do you plan to re-send the driver soon ?
Yes, I plan to submit it again in the next days.
Beniamino
Cool ! Thanks !
Can you base it after my "ARM: meson: rename GXBB to GX" patch ?
It will be simpler to merge everything !
Thanks,
Neil