JH7100 Audio Clocks
Subsystems (3)
Emil Renner Berthing
maintainercover JH7100 Audio Clocks
This series add support for the audio clocks on the StarFive JH7100 RISC-V SoC, although the first two patches are fixes to the original addition of the basic clock driver. At least the first fix may be considered for 5.17.
It turns out the SoC has several memory ranges for different clocks, but they all share the layout of the control registers. This could be modelled in 3 ways:
1) Model all the clocks as a single peripheral with multiple memory ranges and have a single driver for them all.
2) Model each memory range as different, but related peripherals with a single driver handling all of them.
3) Model each memory range as different peripherals with separate drivers that can share most code.
Although the first option would require less code this series implements the 3rd option. The basic clock driver has to be built-in to boot the SoC, so separate drivers for the other registers means less code needs to be built-in and can be left as loadable modules.
Emil Renner Berthing (7):
clk: starfive: jh7100: Don't round divisor up twice
clk: starfive: jh7100: Handle audio_div clock properly
dt-bindings: clock: Add JH7100 audio clock definitions
dt-bindings: clock: Add starfive,jh7100-audclk bindings
clk: starfive: jh7100: Make hw clock implementation reusable
clk: starfive: jh7100: Support more clock types
clk: starfive: Add JH7100 audio clock driver
.../clock/starfive,jh7100-audclk.yaml | 57 ++++++ MAINTAINERS | 8 +- drivers/clk/starfive/Kconfig | 8 + drivers/clk/starfive/Makefile | 1 + .../clk/starfive/clk-starfive-jh7100-audio.c | 170 +++++++++++++++++ drivers/clk/starfive/clk-starfive-jh7100.c | 176 +++++++++--------- drivers/clk/starfive/clk-starfive-jh7100.h | 112 +++++++++++ .../dt-bindings/clock/starfive-jh7100-audio.h | 41 ++++ 8 files changed, 482 insertions(+), 91 deletions(-) create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7100-audclk.yaml create mode 100644 drivers/clk/starfive/clk-starfive-jh7100-audio.c create mode 100644 drivers/clk/starfive/clk-starfive-jh7100.h create mode 100644 include/dt-bindings/clock/starfive-jh7100-audio.h
Signature · 1 line
2.34.1
Emil Renner Berthing
maintainerPATCH 1/7 clk: starfive: jh7100: Don't round divisor up twice
The problem is best illustrated by an example. Suppose a consumer wants a 4MHz clock rate from a divider with a 10MHz parent. It would then call
clk_round_rate(clk, 4000000)
which would call into our determine_rate() callback that correctly rounds up and finds that a divisor of 3 gives the highest possible frequency below the requested 4MHz and returns 10000000 / 3 = 3333333Hz.
However the consumer would then call
clk_set_rate(clk, 3333333)
but since 3333333 doesn't divide 10000000 evenly our set_rate() callback would again round the divisor up and set it to 4 which results in an unnecessarily low rate of 2.5MHz.
Fix it by using DIV_ROUND_CLOSEST in the set_rate() callback.
--- drivers/clk/starfive/clk-starfive-jh7100.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-)
drivers/clk/starfive/clk-starfive-jh7100.c +3 -11
@@ -399,22 +399,13 @@ static unsigned long jh7100_clk_recalc_rate(struct clk_hw *hw,return div ? parent_rate / div :0 ; } -static unsigned long jh7100_clk_bestdiv (struct jh7100_clk *clk, -unsigned long rate,unsigned long parent) -{ -unsigned long max = clk->max_div; -unsigned long div =DIV_ROUND_UP (parent, rate); - -return min (div, max); -} -static int jh7100_clk_determine_rate (struct clk_hw *hw,struct clk_rate_request *req) {struct jh7100_clk *clk =jh7100_clk_from (hw);unsigned long parent = req->best_parent_rate;unsigned long rate =clamp (req->rate, req->min_rate, req->max_rate); -unsigned long div =jh7100_clk_bestdiv (clk, rate, parent); + unsigned long div = min_t(unsigned long, DIV_ROUND_UP(parent, rate), clk->max_div);unsigned long result = parent / div;/*
@@ -442,7 +433,8 @@ static int jh7100_clk_set_rate(struct clk_hw *hw, unsigned long parent_rate) {struct jh7100_clk *clk =jh7100_clk_from (hw); -unsigned long div =jh7100_clk_bestdiv (clk, rate, parent_rate); +unsigned long div =clamp (DIV_ROUND_CLOSEST (parent_rate, rate), +1UL , (unsigned long )clk->max_div);jh7100_clk_reg_rmw (clk,JH7100_CLK_DIV_MASK , div);return 0 ;
Signature · 1 line
2.34.1
Re: [PATCH v1 1/7] clk: starfive: jh7100: Don't round divisor up twice
Quoting Emil Renner Berthing (2022-01-26 09:39:47)
Quoted 18 lines
The problem is best illustrated by an example. Suppose a consumer wants a 4MHz clock rate from a divider with a 10MHz parent. It would then call
clk_round_rate(clk, 4000000)which would call into our
determine_rate()callback that correctly rounds up and finds that a divisor of 3 gives the highest possible frequency below the requested 4MHz and returns 10000000 / 3 = 3333333Hz.However the consumer would then call
clk_set_rate(clk, 3333333)but since 3333333 doesn't divide 10000000 evenly our
set_rate()callback would again round the divisor up and set it to 4 which results in an unnecessarily low rate of 2.5MHz.
Quoted 5 lines
Fix it by using
DIV_ROUND_CLOSESTin theset_rate()callback.Fixes 4210be668a09 ("clk: starfive: Add JH7100 clock generator driver")Signed-off-by Emil Renner Berthing <[email protected]>---
Applied to clk-next
Emil Renner Berthing
maintainerPATCH 2/7 clk: starfive: jh7100: Handle audio_div clock properly
In reply to Emil Renner BerthingIt turns out the audio_div clock is a fractional divider where the lowest byte of the ctrl register is the integer part of the divider and the 2nd byte is the number of 100th added to the divider.
The children of this clock is used by the audio peripherals for their sample rate clock, so round to the closest possible rate rather than always rounding down like regular dividers.
--- drivers/clk/starfive/clk-starfive-jh7100.c | 68 +++++++++++++++++++++- 1 file changed, 67 insertions(+), 1 deletion(-)
drivers/clk/starfive/clk-starfive-jh7100.c +67 -1
@@ -32,6 +32,13 @@#define JH7100_CLK_MUX_MASK GENMASK(27, 24)#define JH7100_CLK_MUX_SHIFT 24#define JH7100_CLK_DIV_MASK GENMASK(23, 0) +#define JH7100_CLK_FRAC_MASK GENMASK(15, 8) +#define JH7100_CLK_FRAC_SHIFT 8 +#define JH7100_CLK_INT_MASK GENMASK(7, 0) + +/* fractional divider min/max */ +#define JH7100_CLK_FRAC_MIN 100UL +#define JH7100_CLK_FRAC_MAX 25599UL/* clock data */ #define JH7100_GATE (_idx, _name, _flags, _parent) [_idx] = { \
@@ -55,6 +62,13 @@ .parents = { [0] = _parent }, \ } +#define JH7100_FDIV (_idx, _name, _parent) [_idx] = { \ + .name = _name, \ + .flags = 0, \ + .max = JH7100_CLK_FRAC_MAX, \ + .parents = { [0] = _parent }, \ +} +#define JH7100__MUX (_idx, _name, _nparents, ...) [_idx] = { \ .name = _name, \ .flags = 0, \
@@ -225,7 +239,7 @@ static const struct {JH7100__MUX (JH7100_CLK_USBPHY_25M ,"usbphy_25m" ,2 ,JH7100_CLK_OSC_SYS ,JH7100_CLK_USBPHY_PLLDIV25M ), -JH7100__DIV (JH7100_CLK_AUDIO_DIV ,"audio_div" ,131072 ,JH7100_CLK_AUDIO_ROOT ), +JH7100_FDIV (JH7100_CLK_AUDIO_DIV ,"audio_div" ,JH7100_CLK_AUDIO_ROOT ),JH7100_GATE (JH7100_CLK_AUDIO_SRC ,"audio_src" ,0 ,JH7100_CLK_AUDIO_DIV ),JH7100_GATE (JH7100_CLK_AUDIO_12288 ,"audio_12288" ,0 ,JH7100_CLK_OSC_AUD ), JH7100_GDIV(JH7100_CLK_VIN_SRC, "vin_src", 0, 4, JH7100_CLK_VIN_ROOT),
@@ -440,6 +454,49 @@ static int jh7100_clk_set_rate(struct clk_hw *hw,return 0 ; } +static unsigned long jh7100_clk_frac_recalc_rate (struct clk_hw *hw, +unsigned long parent_rate) +{ +struct jh7100_clk *clk =jh7100_clk_from (hw); +u32 reg =jh7100_clk_reg_get (clk); +unsigned long div100 =100 * (reg &JH7100_CLK_INT_MASK ) + + ((reg &JH7100_CLK_FRAC_MASK ) >>JH7100_CLK_FRAC_SHIFT ); + +return (div100 >=JH7100_CLK_FRAC_MIN ) ?100 * parent_rate / div100 :0 ; +} + +static int jh7100_clk_frac_determine_rate (struct clk_hw *hw, +struct clk_rate_request *req) +{ +unsigned long parent100 =100 * req->best_parent_rate; +unsigned long rate =clamp (req->rate, req->min_rate, req->max_rate); +unsigned long div100 =clamp (DIV_ROUND_CLOSEST (parent100, rate), +JH7100_CLK_FRAC_MIN ,JH7100_CLK_FRAC_MAX ); +unsigned long result = parent100 / div100; + +/* clamp the result as in jh7100_clk_determine_rate() above */ +if (result > req->max_rate && div100 <JH7100_CLK_FRAC_MAX ) + result = parent100 / (div100 +1 ); +if (result < req->min_rate && div100 >JH7100_CLK_FRAC_MIN ) + result = parent100 / (div100 -1 ); + + req->rate = result; +return 0 ; +} + +static int jh7100_clk_frac_set_rate (struct clk_hw *hw, +unsigned long rate, +unsigned long parent_rate) +{ +struct jh7100_clk *clk =jh7100_clk_from (hw); +unsigned long div100 =clamp (DIV_ROUND_CLOSEST (100 * parent_rate, rate), +JH7100_CLK_FRAC_MIN ,JH7100_CLK_FRAC_MAX ); +u32 value = ((div100 %100 ) <<JH7100_CLK_FRAC_SHIFT ) | (div100 /100 ); + +jh7100_clk_reg_rmw (clk,JH7100_CLK_DIV_MASK , value); +return 0 ; +} +static u8 jh7100_clk_get_parent (struct clk_hw *hw) {struct jh7100_clk *clk =jh7100_clk_from (hw);
@@ -526,6 +583,13 @@ static const struct clk_ops jh7100_clk_div_ops = { .debug_init = jh7100_clk_debug_init, }; +static const struct clk_ops jh7100_clk_fdiv_ops = { + .recalc_rate = jh7100_clk_frac_recalc_rate, + .determine_rate = jh7100_clk_frac_determine_rate, + .set_rate = jh7100_clk_frac_set_rate, + .debug_init = jh7100_clk_debug_init, +}; +static const struct clk_ops jh7100_clk_gdiv_ops = { .enable = jh7100_clk_enable, .disable = jh7100_clk_disable,
@@ -564,6 +628,8 @@ static const struct clk_ops *__init jh7100_clk_ops(u32 max)if (max &JH7100_CLK_DIV_MASK ) {if (max &JH7100_CLK_ENABLE )return &jh7100_clk_gdiv_ops; +if (max ==JH7100_CLK_FRAC_MAX ) +return &jh7100_clk_fdiv_ops;return &jh7100_clk_div_ops; }
Signature · 1 line
2.34.1
Re: [PATCH v1 2/7] clk: starfive: jh7100: Handle audio_div clock properly
Quoting Emil Renner Berthing (2022-01-26 09:39:48)
Quoted 11 lines
It turns out the
audio_divclock is a fractional divider where the lowest byte of the ctrl register is the integer part of the divider and the 2nd byte is the number of 100th added to the divider.The children of this clock is used by the audio peripherals for their sample rate clock, so round to the closest possible rate rather than always rounding down like regular dividers.
Fixes 4210be668a09 ("clk: starfive: Add JH7100 clock generator driver")Signed-off-by Emil Renner Berthing <[email protected]>---
Applied to clk-next
Emil Renner Berthing
maintainerPATCH 3/7 dt-bindings: clock: Add JH7100 audio clock definitions
In reply to Emil Renner BerthingAdd all clock outputs for the StarFive JH7100 audio clock generator.
--- .../dt-bindings/clock/starfive-jh7100-audio.h | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 include/dt-bindings/clock/starfive-jh7100-audio.h
include/dt-bindings/clock/starfive-jh7100-audio.h new file +41 -0
@@ -0,0 +1,41 @@ +/* SPDX-License-Identifier: GPL-2.0 OR MIT */ +/* +* Copyright (C) 2021 Emil Renner Berthing <[email protected]> +*/ + +#ifndef __DT_BINDINGS_CLOCK_STARFIVE_JH7100_AUDIO_H__ +#define __DT_BINDINGS_CLOCK_STARFIVE_JH7100_AUDIO_H__ + +#define JH7100_AUDCLK_ADC_MCLK 0 +#define JH7100_AUDCLK_I2S1_MCLK 1 +#define JH7100_AUDCLK_I2SADC_APB 2 +#define JH7100_AUDCLK_I2SADC_BCLK 3 +#define JH7100_AUDCLK_I2SADC_BCLK_N 4 +#define JH7100_AUDCLK_I2SADC_LRCLK 5 +#define JH7100_AUDCLK_PDM_APB 6 +#define JH7100_AUDCLK_PDM_MCLK 7 +#define JH7100_AUDCLK_I2SVAD_APB 8 +#define JH7100_AUDCLK_SPDIF 9 +#define JH7100_AUDCLK_SPDIF_APB 10 +#define JH7100_AUDCLK_PWMDAC_APB 11 +#define JH7100_AUDCLK_DAC_MCLK 12 +#define JH7100_AUDCLK_I2SDAC_APB 13 +#define JH7100_AUDCLK_I2SDAC_BCLK 14 +#define JH7100_AUDCLK_I2SDAC_BCLK_N 15 +#define JH7100_AUDCLK_I2SDAC_LRCLK 16 +#define JH7100_AUDCLK_I2S1_APB 17 +#define JH7100_AUDCLK_I2S1_BCLK 18 +#define JH7100_AUDCLK_I2S1_BCLK_N 19 +#define JH7100_AUDCLK_I2S1_LRCLK 20 +#define JH7100_AUDCLK_I2SDAC16K_APB 21 +#define JH7100_AUDCLK_APB0_BUS 22 +#define JH7100_AUDCLK_DMA1P_AHB 23 +#define JH7100_AUDCLK_USB_APB 24 +#define JH7100_AUDCLK_USB_LPM 25 +#define JH7100_AUDCLK_USB_STB 26 +#define JH7100_AUDCLK_APB_EN 27 +#define JH7100_AUDCLK_VAD_MEM 28 + +#define JH7100_AUDCLK_END 29 + +#endif /* __DT_BINDINGS_CLOCK_STARFIVE_JH7100_AUDIO_H__ */
Signature · 1 line
2.34.1
Re: [PATCH v1 3/7] dt-bindings: clock: Add JH7100 audio clock definitions
Quoted 8 lines · Emil Renner Berthing
Add all clock outputs for the StarFive JH7100 audio clock generator.
Signed-off-by Emil Renner Berthing <[email protected]>--- .../dt-bindings/clock/starfive-jh7100-audio.h | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 include/dt-bindings/clock/starfive-jh7100-audio.h
Re: [PATCH v1 3/7] dt-bindings: clock: Add JH7100 audio clock definitions
In reply to Emil Renner BerthingQuoting Emil Renner Berthing (2022-01-26 09:39:49)
Quoted 4 lines
Add all clock outputs for the StarFive JH7100 audio clock generator.
Signed-off-by Emil Renner Berthing <[email protected]>---
Applied to clk-next
Emil Renner Berthing
maintainerPATCH 4/7 dt-bindings: clock: Add starfive,jh7100-audclk bindings
In reply to Emil Renner BerthingAdd bindings for the audio clocks on the StarFive JH7100 RISC-V SoC.
--- .../clock/starfive,jh7100-audclk.yaml | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7100-audclk.yaml
Documentation/devicetree/bindings/clock/starfive,jh7100-audclk.yaml new file +57 -0
@@ -0,0 +1,57 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/starfive,jh7100-audclk.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: StarFive JH7100 Audio Clock Generator + +maintainers: + - Emil Renner Berthing <[email protected]> + +properties: + compatible: + const: starfive,jh7100-audclk + + reg: + maxItems: 1 + + clocks: + items: + - description: Audio source clock + - description: External 12.288MHz clock + - description: Domain 7 AHB bus clock + + clock-names: + items: + - const: audio_src + - const: audio_12288 + - const: dom7ahb_bus + + '#clock-cells': + const: 1 + description: + See <dt-bindings/clock/starfive-jh7100-audio.h> for valid indices. + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + +additionalProperties: false + +examples: + - | + #include <dt-bindings/clock/starfive-jh7100.h> + + clock-controller@10480000 { + compatible = "starfive,jh7100-audclk"; + reg = <0x10480000 0x10000>; + clocks = <&clkgen JH7100_CLK_AUDIO_SRC>, + <&clkgen JH7100_CLK_AUDIO_12288>, + <&clkgen JH7100_CLK_DOM7AHB_BUS>; + clock-names = "audio_src", "audio_12288", "dom7ahb_bus"; + #clock-cells = <1>; + };
Signature · 1 line
2.34.1
Re: [PATCH v1 4/7] dt-bindings: clock: Add starfive,jh7100-audclk bindings
Quoted 8 lines · Emil Renner Berthing
Add bindings for the audio clocks on the StarFive JH7100 RISC-V SoC.
Signed-off-by Emil Renner Berthing <[email protected]>--- .../clock/starfive,jh7100-audclk.yaml | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/starfive,jh7100-audclk.yaml
Re: [PATCH v1 4/7] dt-bindings: clock: Add starfive,jh7100-audclk bindings
In reply to Emil Renner BerthingQuoting Emil Renner Berthing (2022-01-26 09:39:50)
Quoted 4 lines
Add bindings for the audio clocks on the StarFive JH7100 RISC-V SoC.
Signed-off-by Emil Renner Berthing <[email protected]>---
Applied to clk-next
Emil Renner Berthing
maintainerPATCH 5/7 clk: starfive: jh7100: Make hw clock implementation reusable
In reply to Emil Renner BerthingThe JH7100 has additional audio and video clocks at different memory ranges, but they use the same register layout. Add a header and export the starfive_jh7100_clk_ops function so the clock implementation can be reused by drivers handling these clocks.
--- drivers/clk/starfive/clk-starfive-jh7100.c | 96 ++------------------- drivers/clk/starfive/clk-starfive-jh7100.h | 97 ++++++++++++++++++++++ 2 files changed, 104 insertions(+), 89 deletions(-) create mode 100644 drivers/clk/starfive/clk-starfive-jh7100.h
drivers/clk/starfive/clk-starfive-jh7100.c +7 -89
@@ -20,83 +20,15 @@#include <dt-bindings/clock/starfive-jh7100.h> +#include "clk-starfive-jh7100.h" +/* external clocks */ #define JH7100_CLK_OSC_SYS (JH7100_CLK_END + 0)#define JH7100_CLK_OSC_AUD (JH7100_CLK_END + 1)#define JH7100_CLK_GMAC_RMII_REF (JH7100_CLK_END + 2)#define JH7100_CLK_GMAC_GR_MII_RX (JH7100_CLK_END + 3) -/* register fields */ -#define JH7100_CLK_ENABLE BIT(31) -#define JH7100_CLK_INVERT BIT(30) -#define JH7100_CLK_MUX_MASK GENMASK(27, 24) -#define JH7100_CLK_MUX_SHIFT 24 -#define JH7100_CLK_DIV_MASK GENMASK(23, 0) -#define JH7100_CLK_FRAC_MASK GENMASK(15, 8) -#define JH7100_CLK_FRAC_SHIFT 8 -#define JH7100_CLK_INT_MASK GENMASK(7, 0) - -/* fractional divider min/max */ -#define JH7100_CLK_FRAC_MIN 100UL -#define JH7100_CLK_FRAC_MAX 25599UL - -/* clock data */ -#define JH7100_GATE (_idx, _name, _flags, _parent) [_idx] = { \ - .name = _name, \ - .flags = CLK_SET_RATE_PARENT | (_flags), \ - .max = JH7100_CLK_ENABLE, \ - .parents = { [0] = _parent }, \ -} - -#define JH7100__DIV (_idx, _name, _max, _parent) [_idx] = { \ - .name = _name, \ - .flags = 0, \ - .max = _max, \ - .parents = { [0] = _parent }, \ -} - -#define JH7100_GDIV (_idx, _name, _flags, _max, _parent) [_idx] = { \ - .name = _name, \ - .flags = _flags, \ - .max = JH7100_CLK_ENABLE | (_max), \ - .parents = { [0] = _parent }, \ -} - -#define JH7100_FDIV (_idx, _name, _parent) [_idx] = { \ - .name = _name, \ - .flags = 0, \ - .max = JH7100_CLK_FRAC_MAX, \ - .parents = { [0] = _parent }, \ -} - -#define JH7100__MUX (_idx, _name, _nparents, ...) [_idx] = { \ - .name = _name, \ - .flags = 0, \ - .max = ((_nparents) - 1) << JH7100_CLK_MUX_SHIFT, \ - .parents = { __VA_ARGS__ }, \ -} - -#define JH7100_GMUX (_idx, _name, _flags, _nparents, ...) [_idx] = { \ - .name = _name, \ - .flags = _flags, \ - .max = JH7100_CLK_ENABLE | \ - (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT), \ - .parents = { __VA_ARGS__ }, \ -} - -#define JH7100__INV (_idx, _name, _parent) [_idx] = { \ - .name = _name, \ - .flags = CLK_SET_RATE_PARENT, \ - .max = JH7100_CLK_INVERT, \ - .parents = { [0] = _parent }, \ -} - -static const struct { -const char *name; -unsigned long flags; -u32 max; -u8 parents[4 ]; -} jh7100_clk_data[]__initconst = { +static const struct jh7100_clk_data jh7100_clk_data[]__initconst = { JH7100__MUX(JH7100_CLK_CPUNDBUS_ROOT, "cpundbus_root", 4, JH7100_CLK_OSC_SYS, JH7100_CLK_PLL0_OUT,
@@ -337,21 +269,6 @@ static const struct { JH7100_GATE(JH7100_CLK_SYSERR_APB, "syserr_apb", 0, JH7100_CLK_APB2_BUS), }; -struct jh7100_clk { -struct clk_hw hw; -unsigned int idx; -unsigned int max_div; -}; - -struct jh7100_clk_priv { -/* protect clk enable and set rate/parent from happening at the same time */ -spinlock_t rmw_lock; -struct device *dev; -void __iomem *base; -struct clk_hw *pll[3 ]; -struct jh7100_clk reg[JH7100_CLK_PLL0_OUT ]; -}; -static struct jh7100_clk *jh7100_clk_from (struct clk_hw *hw) { return container_of(hw, struct jh7100_clk, hw);
@@ -623,7 +540,7 @@ static const struct clk_ops jh7100_clk_inv_ops = { .debug_init = jh7100_clk_debug_init, }; -static const struct clk_ops *__init jh7100_clk_ops (u32 max) +const struct clk_ops *starfive_jh7100_clk_ops (u32 max) {if (max &JH7100_CLK_DIV_MASK ) {if (max &JH7100_CLK_ENABLE )
@@ -644,6 +561,7 @@ static const struct clk_ops *__init jh7100_clk_ops(u32 max)return &jh7100_clk_inv_ops; } +EXPORT_SYMBOL_GPL (starfive_jh7100_clk_ops);static struct clk_hw *jh7100_clk_get (struct of_phandle_args *clkspec,void *data) {
@@ -665,7 +583,7 @@ static int __init clk_starfive_jh7100_probe(struct platform_device *pdev)unsigned int idx;int ret; - priv =devm_kzalloc (&pdev->dev,sizeof (*priv),GFP_KERNEL ); + priv =devm_kzalloc (&pdev->dev,struct_size (priv, reg,JH7100_CLK_PLL0_OUT ),GFP_KERNEL );if (!priv)return -ENOMEM ;
@@ -695,7 +613,7 @@ static int __init clk_starfive_jh7100_probe(struct platform_device *pdev)struct clk_parent_data parents[4 ] = {};struct clk_init_data init = { .name = jh7100_clk_data[idx].name, - .ops =jh7100_clk_ops (max), + .ops =starfive_jh7100_clk_ops (max), .parent_data = parents, .num_parents = ((max &JH7100_CLK_MUX_MASK ) >>JH7100_CLK_MUX_SHIFT ) +1 , .flags = jh7100_clk_data[idx].flags,
drivers/clk/starfive/clk-starfive-jh7100.h new file +97 -0
97 lines not on this page · raw message
Signature · 1 line
2.34.1
Re: [PATCH v1 5/7] clk: starfive: jh7100: Make hw clock implementation reusable
Quoting Emil Renner Berthing (2022-01-26 09:39:51)
Quoted 7 lines
The JH7100 has additional audio and video clocks at different memory ranges, but they use the same register layout. Add a header and export the
starfive_jh7100_clk_opsfunction so the clock implementation can be reused by drivers handling these clocks.Signed-off-by Emil Renner Berthing <[email protected]>---
Applied to clk-next
Emil Renner Berthing
maintainerPATCH 6/7 clk: starfive: jh7100: Support more clock types
In reply to Emil Renner BerthingUnlike the system clocks there are audio clocks that combine both multiplexer/divider and gate/multiplexer/divider, so add support for that.
--- drivers/clk/starfive/clk-starfive-jh7100.c | 26 ++++++++++++++++++++++ drivers/clk/starfive/clk-starfive-jh7100.h | 15 +++++++++++++ 2 files changed, 41 insertions(+)
drivers/clk/starfive/clk-starfive-jh7100.c +26 -0
@@ -534,6 +534,27 @@ static const struct clk_ops jh7100_clk_gmux_ops = { .debug_init = jh7100_clk_debug_init, }; +static const struct clk_ops jh7100_clk_mdiv_ops = { + .recalc_rate = jh7100_clk_recalc_rate, + .determine_rate = jh7100_clk_determine_rate, + .get_parent = jh7100_clk_get_parent, + .set_parent = jh7100_clk_set_parent, + .set_rate = jh7100_clk_set_rate, + .debug_init = jh7100_clk_debug_init, +}; + +static const struct clk_ops jh7100_clk_gmd_ops = { + .enable = jh7100_clk_enable, + .disable = jh7100_clk_disable, + .is_enabled = jh7100_clk_is_enabled, + .recalc_rate = jh7100_clk_recalc_rate, + .determine_rate = jh7100_clk_determine_rate, + .get_parent = jh7100_clk_get_parent, + .set_parent = jh7100_clk_set_parent, + .set_rate = jh7100_clk_set_rate, + .debug_init = jh7100_clk_debug_init, +}; +static const struct clk_ops jh7100_clk_inv_ops = { .get_phase = jh7100_clk_get_phase, .set_phase = jh7100_clk_set_phase,
@@ -543,6 +564,11 @@ static const struct clk_ops jh7100_clk_inv_ops = {const struct clk_ops *starfive_jh7100_clk_ops (u32 max) {if (max &JH7100_CLK_DIV_MASK ) { +if (max &JH7100_CLK_MUX_MASK ) { +if (max &JH7100_CLK_ENABLE ) +return &jh7100_clk_gmd_ops; +return &jh7100_clk_mdiv_ops; + }if (max &JH7100_CLK_ENABLE )return &jh7100_clk_gdiv_ops;if (max ==JH7100_CLK_FRAC_MAX )
drivers/clk/starfive/clk-starfive-jh7100.h +15 -0
@@ -70,6 +70,21 @@ struct jh7100_clk_data { .parents = { __VA_ARGS__ }, \ } +#define JH7100_MDIV (_idx, _name, _max, _nparents, ...) [_idx] = { \ + .name = _name, \ + .flags = 0, \ + .max = (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT) | (_max), \ + .parents = { __VA_ARGS__ }, \ +} + +#define JH7100__GMD (_idx, _name, _flags, _max, _nparents, ...) [_idx] = { \ + .name = _name, \ + .flags = _flags, \ + .max = JH7100_CLK_ENABLE | \ + (((_nparents) - 1) << JH7100_CLK_MUX_SHIFT) | (_max), \ + .parents = { __VA_ARGS__ }, \ +} +#define JH7100__INV (_idx, _name, _parent) [_idx] = { \ .name = _name, \ .flags = CLK_SET_RATE_PARENT, \
Signature · 1 line
2.34.1
Re: [PATCH v1 6/7] clk: starfive: jh7100: Support more clock types
Quoting Emil Renner Berthing (2022-01-26 09:39:52)
Quoted 6 lines
Unlike the system clocks there are audio clocks that combine both multiplexer/divider and gate/multiplexer/divider, so add support for that.
Signed-off-by Emil Renner Berthing <[email protected]>---
Applied to clk-next
Emil Renner Berthing
maintainerPATCH 7/7 clk: starfive: Add JH7100 audio clock driver
In reply to Emil Renner BerthingAdd a driver for the audio clocks on the Starfive JH7100 RISC-V SoC.
--- MAINTAINERS | 8 +- drivers/clk/starfive/Kconfig | 8 + drivers/clk/starfive/Makefile | 1 + .../clk/starfive/clk-starfive-jh7100-audio.c | 170 ++++++++++++++++++ 4 files changed, 183 insertions(+), 4 deletions(-) create mode 100644 drivers/clk/starfive/clk-starfive-jh7100-audio.c
MAINTAINERS +4 -4
@@ -18376,12 +18376,12 @@ M: Ion Badulescu <[email protected]> S: Odd Fixes F: drivers/net/ethernet/adaptec/starfire* -STARFIVE JH7100 CLOCK DRIVER +STARFIVE JH7100 CLOCK DRIVERS M: Emil Renner Berthing <[email protected]> S: Maintained -F: Documentation/devicetree/bindings/clock/starfive,jh7100-clkgen.yaml -F: drivers/clk/starfive/clk-starfive-jh7100.c -F: include/dt-bindings/clock/starfive-jh7100.h +F: Documentation/devicetree/bindings/clock/starfive,jh7100-*.yaml +F: drivers/clk/starfive/clk-starfive-jh7100* +F: include/dt-bindings/clock/starfive-jh7100*.h STARFIVE JH7100 PINCTRL DRIVER M: Emil Renner Berthing <[email protected]>
drivers/clk/starfive/Kconfig +8 -0
@@ -7,3 +7,11 @@ config CLK_STARFIVE_JH7100 help Say yes here to support the clock controller on the StarFive JH7100 SoC. + +config CLK_STARFIVE_JH7100_AUDIO + tristate "StarFive JH7100 audio clock support" + depends on CLK_STARFIVE_JH7100 + default m if SOC_STARFIVE + help + Say Y or M here to support the audio clocks on the StarFive JH7100 + SoC.
drivers/clk/starfive/Makefile +1 -0
@@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 # StarFive Clock obj-$(CONFIG_CLK_STARFIVE_JH7100) += clk-starfive-jh7100.o +obj-$(CONFIG_CLK_STARFIVE_JH7100_AUDIO) += clk-starfive-jh7100-audio.o
drivers/clk/starfive/clk-starfive-jh7100-audio.c new file +170 -0
170 lines not on this page · raw message
Signature · 1 line
2.34.1
Re: [PATCH v1 7/7] clk: starfive: Add JH7100 audio clock driver
Quoting Emil Renner Berthing (2022-01-26 09:39:53)
Quoted 4 lines
Add a driver for the audio clocks on the Starfive JH7100 RISC-V SoC.
Signed-off-by Emil Renner Berthing <[email protected]>---
Applied to clk-next