Message ID | 1452867667-2447-6-git-send-email-kernel@martin.sperl.org (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
kernel@martin.sperl.org writes: > From: Martin Sperl <kernel@martin.sperl.org> > > There were 22 HW clocks missing from the clock driver. > > These have been included and int_bits and frac_bits > have been set correctly based on information extracted > from the broadcom videocore headers > (http://www.broadcom.com/docs/support/videocore/Brcm_Android_ICS_Graphics_Stack.tar.gz) > > For an extracted view of the registers please see: > https://github.com/msperl/rpi-registers/blob/master/md/Region_CM.md > > bcm2835_clock_per_parents has been assigned as the parent > clock for all new clocks, but this may not be correct > in all cases - documentation on this is not publicly > available, so some modifications may be needed in the > future. We need the parents to be correct if we're going to land the patch. I'll try to update them. I'm not a fan of this "let's just shove everything we can find in some header file into the .c and hope for the best." Most of these clocks were left out intentionally. > There are a 3 more clocks that possibly could get implemented > as gates instead of clocks: > > > There are comments to indicate those. > > Signed-off-by: Martin Sperl <kernel@martin.sperl.org> > --- > drivers/clk/bcm/clk-bcm2835.c | 260 ++++++++++++++++++++++++++++++++++- > include/dt-bindings/clock/bcm2835.h | 22 +++ > 2 files changed, 276 insertions(+), 6 deletions(-) > > diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c > index 8bc0a76..1640288 100644 > --- a/drivers/clk/bcm/clk-bcm2835.c > +++ b/drivers/clk/bcm/clk-bcm2835.c > @@ -92,8 +92,18 @@ > #define CM_PCMDIV 0x09c > #define CM_PWMCTL 0x0a0 > #define CM_PWMDIV 0x0a4 > +#define CM_SLIMCTL 0x0a8 > +#define CM_SLIMDIV 0x0ac > #define CM_SMICTL 0x0b0 > #define CM_SMIDIV 0x0b4 > +#define CM_TCNTCTL 0x0c0 > +#define CM_TCNTDIV 0x0c4 > +#define CM_TECCTL 0x0c8 > +#define CM_TECDIV 0x0cc > +#define CM_TD0CTL 0x0d0 > +#define CM_TD0DIV 0x0d4 > +#define CM_TD1CTL 0x0d8 > +#define CM_TD1DIV 0x0dc > #define CM_TSENSCTL 0x0e0 > #define CM_TSENSDIV 0x0e4 > #define CM_TIMERCTL 0x0e8 > @@ -107,6 +117,9 @@ > #define CM_SDCCTL 0x1a8 > #define CM_SDCDIV 0x1ac > #define CM_ARMCTL 0x1b0 > +#define CM_ARMDIV 0x1b4 > +#define CM_AVEOCTL 0x1b8 > +#define CM_AVEODIV 0x1bc > #define CM_EMMCCTL 0x1c0 > #define CM_EMMCDIV 0x1c4 > > @@ -829,6 +842,219 @@ static const struct bcm2835_clock_data bcm2835_clock_pcm_data = { > .frac_bits = 12, > }; > > +static const struct bcm2835_clock_data bcm2835_clock_aveo_data = { > + .name = "aveo", > + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), > + .parents = bcm2835_clock_per_parents, > + .ctl_reg = CM_AVEOCTL, > + .div_reg = CM_AVEODIV, > + .int_bits = 4, > + .frac_bits = 12, > +}; AVEO has 0 fractional bits > +static const struct bcm2835_clock_data bcm2835_clock_ccp2_data = { > + /* this is possibly a gate */ > + .name = "ccp2", > + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), > + .parents = bcm2835_clock_per_parents, > + .ctl_reg = CM_CCP2CTL, > + .div_reg = CM_CCP2DIV, > + .int_bits = 1, > + .frac_bits = 0, > +}; CCP2 is a gate from a different clock source, so this won't work. > +static const struct bcm2835_clock_data bcm2835_clock_dsi0p_data = { > + /* this is possibly a gate */ > + .name = "dsi0p", > + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), > + .parents = bcm2835_clock_per_parents, > + .ctl_reg = CM_DSI0PCTL, > + .div_reg = CM_DSI0PDIV, > + .int_bits = 1, > + .frac_bits = 0, > +}; > + > +static const struct bcm2835_clock_data bcm2835_clock_dsi1p_data = { > + /* this is possibly a gate */ > + .name = "dsi1p", > + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), > + .parents = bcm2835_clock_per_parents, > + .ctl_reg = CM_DSI1PCTL, > + .div_reg = CM_DSI1PDIV, > + .int_bits = 1, > + .frac_bits = 0, > +}; DSI0/1 pixel clocks take different clock sources and are gates off of them, so these definitions don't work. > + > +static const struct bcm2835_clock_data bcm2835_clock_gnric_data = { > + .name = "gnric", > + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), > + .parents = bcm2835_clock_per_parents, > + .ctl_reg = CM_GNRICCTL, > + .div_reg = CM_GNRICDIV, > + .int_bits = 12, > + .frac_bits = 12, > +}; GNRIC isn't an actual clock, it's just what's used for describing the overall structure of clocks. > +static const struct bcm2835_clock_data bcm2835_clock_peria_data = { > + .name = "peria", > + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), > + .parents = bcm2835_clock_per_parents, > + .ctl_reg = CM_PERIACTL, > + .div_reg = CM_PERIADIV, > + .int_bits = 12, > + .frac_bits = 12, > +}; This register doesn't do anything, because the debug bit in the power manager is not set. We don't think we should expose a clock gate if it doesn't work, I think. > +static const struct bcm2835_clock_data bcm2835_clock_pulse_data = { > + .name = "pulse", > + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), > + .parents = bcm2835_clock_per_parents, > + .ctl_reg = CM_PULSECTL, > + .div_reg = CM_PULSEDIV, > + .int_bits = 12, > + .frac_bits = 0, > +}; There's some other divider involved in this clock, won't give correct results. > +static const struct bcm2835_clock_data bcm2835_clock_td0_data = { > + .name = "td0", > + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), > + .parents = bcm2835_clock_per_parents, > + .ctl_reg = CM_TD0CTL, > + .div_reg = CM_TD0DIV, > + .int_bits = 12, > + .frac_bits = 12, > +}; > + > +static const struct bcm2835_clock_data bcm2835_clock_td1_data = { > + .name = "td1", > + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), > + .parents = bcm2835_clock_per_parents, > + .ctl_reg = CM_TD1CTL, > + .div_reg = CM_TD1DIV, > + .int_bits = 12, > + .frac_bits = 12, > +}; These are some other clock generator, not the generic or mash ones used elsewhere. I wouldn't enable them without testing. > +static const struct bcm2835_clock_data bcm2835_clock_tec_data = { > + .name = "tec", > + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), > + .parents = bcm2835_clock_per_parents, > + .ctl_reg = CM_TECCTL, > + .div_reg = CM_TECDIV, > + .int_bits = 6, > + .frac_bits = 0, > +}; TEC should be osc parents. > -/* > - * CM_PERIICTL (and CM_PERIACTL, CM_SYSCTL and CM_VPUCTL if > - * you have the debug bit set in the power manager, which we > - * don't bother exposing) are individual gates off of the > - * non-stop vpu clock. > - */ > static const struct bcm2835_gate_data bcm2835_clock_peri_image_data = { > .name = "peri_image", > .parent = "vpu", > .ctl_reg = CM_PERIICTL, > }; > > +static const struct bcm2835_gate_data bcm2835_clock_sys_data = { > + .name = "sys", > + .parent = "vpu", > + .ctl_reg = CM_SYSCTL, > +}; same concern as peria. > + > struct bcm2835_pll { > struct clk_hw hw; > struct bcm2835_cprman *cprman; > @@ -1591,9 +1817,31 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { > [BCM2835_CLOCK_EMMC] = REGISTER_CLK(&bcm2835_clock_emmc_data), > [BCM2835_CLOCK_PWM] = REGISTER_CLK(&bcm2835_clock_pwm_data), > [BCM2835_CLOCK_PCM] = REGISTER_CLK(&bcm2835_clock_pcm_data), > + [BCM2835_CLOCK_AVEO] = REGISTER_CLK(&bcm2835_clock_aveo_data), > + [BCM2835_CLOCK_CAM0] = REGISTER_CLK(&bcm2835_clock_cam0_data), > + [BCM2835_CLOCK_CAM1] = REGISTER_CLK(&bcm2835_clock_cam1_data), > + [BCM2835_CLOCK_CCP2] = REGISTER_CLK(&bcm2835_clock_ccp2_data), > + [BCM2835_CLOCK_DFT] = REGISTER_CLK(&bcm2835_clock_dft_data), > + [BCM2835_CLOCK_DPI] = REGISTER_CLK(&bcm2835_clock_dpi_data), > + [BCM2835_CLOCK_DSI0E] = REGISTER_CLK(&bcm2835_clock_dsi0e_data), > + [BCM2835_CLOCK_DSI0P] = REGISTER_CLK(&bcm2835_clock_dsi0p_data), > + [BCM2835_CLOCK_DSI1E] = REGISTER_CLK(&bcm2835_clock_dsi1e_data), > + [BCM2835_CLOCK_DSI1P] = REGISTER_CLK(&bcm2835_clock_dsi1p_data), > + [BCM2835_CLOCK_GNRIC] = REGISTER_CLK(&bcm2835_clock_gnric_data), > + [BCM2835_CLOCK_GP0] = REGISTER_CLK(&bcm2835_clock_gp0_data), > + [BCM2835_CLOCK_GP1] = REGISTER_CLK(&bcm2835_clock_gp1_data), > + [BCM2835_CLOCK_GP2] = REGISTER_CLK(&bcm2835_clock_gp2_data), > + [BCM2835_CLOCK_PERIA] = REGISTER_CLK(&bcm2835_clock_peria_data), > + [BCM2835_CLOCK_PULSE] = REGISTER_CLK(&bcm2835_clock_pulse_data), > + [BCM2835_CLOCK_SLIM] = REGISTER_CLK(&bcm2835_clock_slim_data), > + [BCM2835_CLOCK_SMI] = REGISTER_CLK(&bcm2835_clock_smi_data), > + [BCM2835_CLOCK_TD0] = REGISTER_CLK(&bcm2835_clock_td0_data), > + [BCM2835_CLOCK_TD1] = REGISTER_CLK(&bcm2835_clock_td1_data), > + [BCM2835_CLOCK_TEC] = REGISTER_CLK(&bcm2835_clock_tec_data), > /* the gates */ > [BCM2835_CLOCK_PERI_IMAGE] = REGISTER_GATE( > &bcm2835_clock_peri_image_data), > + [BCM2835_CLOCK_SYS] = REGISTER_GATE(&bcm2835_clock_sys_data), > }; > > static int bcm2835_clk_probe(struct platform_device *pdev) > diff --git a/include/dt-bindings/clock/bcm2835.h b/include/dt-bindings/clock/bcm2835.h > index 9a7b4a5..d29f181 100644 > --- a/include/dt-bindings/clock/bcm2835.h > +++ b/include/dt-bindings/clock/bcm2835.h > @@ -45,3 +45,25 @@ > #define BCM2835_CLOCK_PERI_IMAGE 29 > #define BCM2835_CLOCK_PWM 30 > #define BCM2835_CLOCK_PCM 31 > +#define BCM2835_CLOCK_AVEO 32 > +#define BCM2835_CLOCK_CAM0 33 > +#define BCM2835_CLOCK_CAM1 34 > +#define BCM2835_CLOCK_CCP2 35 > +#define BCM2835_CLOCK_DFT 36 > +#define BCM2835_CLOCK_DPI 37 > +#define BCM2835_CLOCK_DSI0E 38 > +#define BCM2835_CLOCK_DSI0P 39 > +#define BCM2835_CLOCK_DSI1E 40 > +#define BCM2835_CLOCK_DSI1P 41 > +#define BCM2835_CLOCK_GNRIC 42 > +#define BCM2835_CLOCK_GP0 43 > +#define BCM2835_CLOCK_GP1 44 > +#define BCM2835_CLOCK_GP2 45 > +#define BCM2835_CLOCK_PERIA 46 > +#define BCM2835_CLOCK_PULSE 47 > +#define BCM2835_CLOCK_SLIM 48 > +#define BCM2835_CLOCK_SMI 49 > +#define BCM2835_CLOCK_SYS 50 > +#define BCM2835_CLOCK_TD0 51 > +#define BCM2835_CLOCK_TD1 52 > +#define BCM2835_CLOCK_TEC 53 > -- > 1.7.10.4
On 02.02.2016 02:51, Eric Anholt wrote: > kernel@martin.sperl.org writes: > >> From: Martin Sperl <kernel@martin.sperl.org> >> >> There were 22 HW clocks missing from the clock driver. >> >> These have been included and int_bits and frac_bits >> have been set correctly based on information extracted >> from the broadcom videocore headers >> (http://www.broadcom.com/docs/support/videocore/Brcm_Android_ICS_Graphics_Stack.tar.gz) >> >> For an extracted view of the registers please see: >> https://github.com/msperl/rpi-registers/blob/master/md/Region_CM.md >> >> bcm2835_clock_per_parents has been assigned as the parent >> clock for all new clocks, but this may not be correct >> in all cases - documentation on this is not publicly >> available, so some modifications may be needed in the >> future. > > We need the parents to be correct if we're going to land the patch. > I'll try to update them. > > I'm not a fan of this "let's just shove everything we can find in some > header file into the .c and hope for the best." Most of these clocks > were left out intentionally. Well - I wanted to get them in just in case we need them later. If you have got access to documentation which states the correct parent mux, then please share them so that we can implement them correctly. Also listing all allows us then to expose the values of the registers via debugfs in case we need it - see separate RFC-patch 9 - where we expose the raw register values as well. >> +static const struct bcm2835_clock_data bcm2835_clock_aveo_data = { >> + .name = "aveo", >> + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), >> + .parents = bcm2835_clock_per_parents, >> + .ctl_reg = CM_AVEOCTL, >> + .div_reg = CM_AVEODIV, >> + .int_bits = 4, >> + .frac_bits = 12, >> +}; > > AVEO has 0 fractional bits Correct - my issue (copy paste - I assume). > >> +static const struct bcm2835_clock_data bcm2835_clock_ccp2_data = { >> + /* this is possibly a gate */ >> + .name = "ccp2", >> + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), >> + .parents = bcm2835_clock_per_parents, >> + .ctl_reg = CM_CCP2CTL, >> + .div_reg = CM_CCP2DIV, >> + .int_bits = 1, >> + .frac_bits = 0, >> +}; > > CCP2 is a gate from a different clock source, so this won't work. See comment above: please provide parent clock mux. See also my comment about 3 clock that may be gates - this applies. > >> +static const struct bcm2835_clock_data bcm2835_clock_dsi0p_data = { >> + /* this is possibly a gate */ >> + .name = "dsi0p", >> + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), >> + .parents = bcm2835_clock_per_parents, >> + .ctl_reg = CM_DSI0PCTL, >> + .div_reg = CM_DSI0PDIV, >> + .int_bits = 1, >> + .frac_bits = 0, >> +}; >> + >> +static const struct bcm2835_clock_data bcm2835_clock_dsi1p_data = { >> + /* this is possibly a gate */ >> + .name = "dsi1p", >> + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), >> + .parents = bcm2835_clock_per_parents, >> + .ctl_reg = CM_DSI1PCTL, >> + .div_reg = CM_DSI1PDIV, >> + .int_bits = 1, >> + .frac_bits = 0, >> +}; > > DSI0/1 pixel clocks take different clock sources and are gates off of > them, so these definitions don't work. See comment above: please provide parent clock. See also my comment about 3 clock that may be gates. > >> + >> +static const struct bcm2835_clock_data bcm2835_clock_gnric_data = { >> + .name = "gnric", >> + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), >> + .parents = bcm2835_clock_per_parents, >> + .ctl_reg = CM_GNRICCTL, >> + .div_reg = CM_GNRICDIV, >> + .int_bits = 12, >> + .frac_bits = 12, >> +}; > > GNRIC isn't an actual clock, it's just what's used for describing the > overall structure of clocks. Well - there is the corresponding register at 0x7e101000 which reads as: ctl = 0x0000636d div = 0x0000636d So we could remove this one if this is really the case of a dummy - even though I wonder why there would be space in io-space reserved for this "description" only. > >> +static const struct bcm2835_clock_data bcm2835_clock_peria_data = { >> + .name = "peria", >> + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), >> + .parents = bcm2835_clock_per_parents, >> + .ctl_reg = CM_PERIACTL, >> + .div_reg = CM_PERIADIV, >> + .int_bits = 12, >> + .frac_bits = 12, >> +}; > > This register doesn't do anything, because the debug bit in the power > manager is not set. We don't think we should expose a clock gate if it > doesn't work, I think. maybe we allow setting debug in the PM at a later point in time? > >> +static const struct bcm2835_clock_data bcm2835_clock_pulse_data = { >> + .name = "pulse", >> + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), >> + .parents = bcm2835_clock_per_parents, >> + .ctl_reg = CM_PULSECTL, >> + .div_reg = CM_PULSEDIV, >> + .int_bits = 12, >> + .frac_bits = 0, >> +}; > > There's some other divider involved in this clock, won't give correct results. See comment above: please provide parent clock. > >> +static const struct bcm2835_clock_data bcm2835_clock_td0_data = { >> + .name = "td0", >> + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), >> + .parents = bcm2835_clock_per_parents, >> + .ctl_reg = CM_TD0CTL, >> + .div_reg = CM_TD0DIV, >> + .int_bits = 12, >> + .frac_bits = 12, >> +}; >> + >> +static const struct bcm2835_clock_data bcm2835_clock_td1_data = { >> + .name = "td1", >> + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), >> + .parents = bcm2835_clock_per_parents, >> + .ctl_reg = CM_TD1CTL, >> + .div_reg = CM_TD1DIV, >> + .int_bits = 12, >> + .frac_bits = 12, >> +}; > > These are some other clock generator, not the generic or mash ones used > elsewhere. I wouldn't enable them without testing. As long as they are not referenced in the DT these only are read only and can get read via debugfs - these are disabled anyway: root@raspcm:/build/linux# head /sys/kernel/debug/clk/td*/clk_rate ==> /sys/kernel/debug/clk/td0/clk_rate <== 0 ==> /sys/kernel/debug/clk/td1/clk_rate <== 0 > >> +static const struct bcm2835_clock_data bcm2835_clock_tec_data = { >> + .name = "tec", >> + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), >> + .parents = bcm2835_clock_per_parents, >> + .ctl_reg = CM_TECCTL, >> + .div_reg = CM_TECDIV, >> + .int_bits = 6, >> + .frac_bits = 0, >> +}; > > TEC should be osc parents. I will change that. > >> -/* >> - * CM_PERIICTL (and CM_PERIACTL, CM_SYSCTL and CM_VPUCTL if >> - * you have the debug bit set in the power manager, which we >> - * don't bother exposing) are individual gates off of the >> - * non-stop vpu clock. >> - */ >> static const struct bcm2835_gate_data bcm2835_clock_peri_image_data = { >> .name = "peri_image", >> .parent = "vpu", >> .ctl_reg = CM_PERIICTL, >> }; >> >> +static const struct bcm2835_gate_data bcm2835_clock_sys_data = { >> + .name = "sys", >> + .parent = "vpu", >> + .ctl_reg = CM_SYSCTL, >> +}; > > same concern as peria. maybe we allow setting debug in the PM at a later point in time? Please propose how to continue to get the clocks in. If you want some clocks left out, then that is fine and we can accommodate that and just leave the defines in the bindings header for later use... Just list them. Martin
> On 08.02.2016, at 12:12, Martin Sperl <kernel@martin.sperl.org> wrote: > > > > On 02.02.2016 02:51, Eric Anholt wrote: >> kernel@martin.sperl.org writes: >> >>> From: Martin Sperl <kernel@martin.sperl.org> >>> >>> There were 22 HW clocks missing from the clock driver. >>> >>> These have been included and int_bits and frac_bits >>> have been set correctly based on information extracted >>> from the broadcom videocore headers >>> (http://www.broadcom.com/docs/support/videocore/Brcm_Android_ICS_Graphics_Stack.tar.gz) >>> >>> For an extracted view of the registers please see: >>> https://github.com/msperl/rpi-registers/blob/master/md/Region_CM.md >>> >>> bcm2835_clock_per_parents has been assigned as the parent >>> clock for all new clocks, but this may not be correct >>> in all cases - documentation on this is not publicly >>> available, so some modifications may be needed in the >>> future. >> >> We need the parents to be correct if we're going to land the patch. >> I'll try to update them. >> >> I'm not a fan of this "let's just shove everything we can find in some >> header file into the .c and hope for the best." Most of these clocks >> were left out intentionally. > > Well - I wanted to get them in just in case we need them later. > > If you have got access to documentation which states the correct > parent mux, then please share them so that we can implement them > correctly. > > Also listing all allows us then to expose the values of the registers > via debugfs in case we need it - see separate RFC-patch 9 - where > we expose the raw register values as well. > >>> +static const struct bcm2835_clock_data bcm2835_clock_aveo_data = { >>> + .name = "aveo", >>> + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), >>> + .parents = bcm2835_clock_per_parents, >>> + .ctl_reg = CM_AVEOCTL, >>> + .div_reg = CM_AVEODIV, >>> + .int_bits = 4, >>> + .frac_bits = 12, >>> +}; >> >> AVEO has 0 fractional bits > > Correct - my issue (copy paste - I assume). > >> >>> +static const struct bcm2835_clock_data bcm2835_clock_ccp2_data = { >>> + /* this is possibly a gate */ >>> + .name = "ccp2", >>> + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), >>> + .parents = bcm2835_clock_per_parents, >>> + .ctl_reg = CM_CCP2CTL, >>> + .div_reg = CM_CCP2DIV, >>> + .int_bits = 1, >>> + .frac_bits = 0, >>> +}; >> >> CCP2 is a gate from a different clock source, so this won't work. > See comment above: please provide parent clock mux. > See also my comment about 3 clock that may be gates - this applies. > >> >>> +static const struct bcm2835_clock_data bcm2835_clock_dsi0p_data = { >>> + /* this is possibly a gate */ >>> + .name = "dsi0p", >>> + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), >>> + .parents = bcm2835_clock_per_parents, >>> + .ctl_reg = CM_DSI0PCTL, >>> + .div_reg = CM_DSI0PDIV, >>> + .int_bits = 1, >>> + .frac_bits = 0, >>> +}; >>> + >>> +static const struct bcm2835_clock_data bcm2835_clock_dsi1p_data = { >>> + /* this is possibly a gate */ >>> + .name = "dsi1p", >>> + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), >>> + .parents = bcm2835_clock_per_parents, >>> + .ctl_reg = CM_DSI1PCTL, >>> + .div_reg = CM_DSI1PDIV, >>> + .int_bits = 1, >>> + .frac_bits = 0, >>> +}; >> >> DSI0/1 pixel clocks take different clock sources and are gates off of >> them, so these definitions don't work. > See comment above: please provide parent clock. > See also my comment about 3 clock that may be gates. > >> >>> + >>> +static const struct bcm2835_clock_data bcm2835_clock_gnric_data = { >>> + .name = "gnric", >>> + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), >>> + .parents = bcm2835_clock_per_parents, >>> + .ctl_reg = CM_GNRICCTL, >>> + .div_reg = CM_GNRICDIV, >>> + .int_bits = 12, >>> + .frac_bits = 12, >>> +}; >> >> GNRIC isn't an actual clock, it's just what's used for describing the >> overall structure of clocks. > > Well - there is the corresponding register at 0x7e101000 which reads as: > ctl = 0x0000636d > div = 0x0000636d > > So we could remove this one if this is really the case of a dummy - > even though I wonder why there would be space in io-space reserved for > this "description" only. > >> >>> +static const struct bcm2835_clock_data bcm2835_clock_peria_data = { >>> + .name = "peria", >>> + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), >>> + .parents = bcm2835_clock_per_parents, >>> + .ctl_reg = CM_PERIACTL, >>> + .div_reg = CM_PERIADIV, >>> + .int_bits = 12, >>> + .frac_bits = 12, >>> +}; >> >> This register doesn't do anything, because the debug bit in the power >> manager is not set. We don't think we should expose a clock gate if it >> doesn't work, I think. > maybe we allow setting debug in the PM at a later point in time? > >> >>> +static const struct bcm2835_clock_data bcm2835_clock_pulse_data = { >>> + .name = "pulse", >>> + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), >>> + .parents = bcm2835_clock_per_parents, >>> + .ctl_reg = CM_PULSECTL, >>> + .div_reg = CM_PULSEDIV, >>> + .int_bits = 12, >>> + .frac_bits = 0, >>> +}; >> >> There's some other divider involved in this clock, won't give correct results. > See comment above: please provide parent clock. > >> >>> +static const struct bcm2835_clock_data bcm2835_clock_td0_data = { >>> + .name = "td0", >>> + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), >>> + .parents = bcm2835_clock_per_parents, >>> + .ctl_reg = CM_TD0CTL, >>> + .div_reg = CM_TD0DIV, >>> + .int_bits = 12, >>> + .frac_bits = 12, >>> +}; >>> + >>> +static const struct bcm2835_clock_data bcm2835_clock_td1_data = { >>> + .name = "td1", >>> + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), >>> + .parents = bcm2835_clock_per_parents, >>> + .ctl_reg = CM_TD1CTL, >>> + .div_reg = CM_TD1DIV, >>> + .int_bits = 12, >>> + .frac_bits = 12, >>> +}; >> >> These are some other clock generator, not the generic or mash ones used >> elsewhere. I wouldn't enable them without testing. > > As long as they are not referenced in the DT these only are read only > and can get read via debugfs - these are disabled anyway: > > root@raspcm:/build/linux# head /sys/kernel/debug/clk/td*/clk_rate > ==> /sys/kernel/debug/clk/td0/clk_rate <== > 0 > > ==> /sys/kernel/debug/clk/td1/clk_rate <== > 0 > >> >>> +static const struct bcm2835_clock_data bcm2835_clock_tec_data = { >>> + .name = "tec", >>> + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), >>> + .parents = bcm2835_clock_per_parents, >>> + .ctl_reg = CM_TECCTL, >>> + .div_reg = CM_TECDIV, >>> + .int_bits = 6, >>> + .frac_bits = 0, >>> +}; >> >> TEC should be osc parents. > I will change that. > >> >>> -/* >>> - * CM_PERIICTL (and CM_PERIACTL, CM_SYSCTL and CM_VPUCTL if >>> - * you have the debug bit set in the power manager, which we >>> - * don't bother exposing) are individual gates off of the >>> - * non-stop vpu clock. >>> - */ >>> static const struct bcm2835_gate_data bcm2835_clock_peri_image_data = { >>> .name = "peri_image", >>> .parent = "vpu", >>> .ctl_reg = CM_PERIICTL, >>> }; >>> >>> +static const struct bcm2835_gate_data bcm2835_clock_sys_data = { >>> + .name = "sys", >>> + .parent = "vpu", >>> + .ctl_reg = CM_SYSCTL, >>> +}; >> >> same concern as peria. > maybe we allow setting debug in the PM at a later point in time? > > Please propose how to continue to get the clocks in. > > If you want some clocks left out, then that is fine and we > can accommodate that and just leave the defines in the bindings > header for later use... > > Just list them. > As I am trying to complete the list of clocks here my “best” summary so far of the clock tree for the bcm2835 taken from various sources: * Datasheet * broadcom provided VC4 headers (via https://github.com/msperl/rpi-registers) * mailing list And I have come up with the following description that you can put in graphviz or http://www.webgraphviz.com/ --- cut here --- digraph clocks { graph [ordering="out"]; subgraph cluster_osc { label = "Oscillators"; "GND"; "OSC"; "testdebug0"; "testdebug1"; } subgraph cluster_pll { label = "PLLs"; subgraph cluster_plla { label = "PLLA"; OSC -> PLLA; PLLA -> PLLA_core; PLLA -> PLLA_per; PLLA -> PLLA_dsi0; PLLA -> PLLA_ccp2; } subgraph cluster_pllb { label = "PLLB"; OSC -> PLLB; PLLB -> PLLB_ARM; PLLB -> PLLB_SP0; PLLB -> PLLB_SP1; PLLB -> PLLB_SP2; } subgraph cluster_pllc { label = "PLLC"; OSC -> PLLC; PLLC -> PLLC_core0; PLLC -> PLLC_core1; PLLC -> PLLC_core2; PLLC -> PLLC_per; } subgraph cluster_plld { label = "PLLD"; OSC -> PLLD; PLLD -> PLLD_core; PLLD -> PLLD_per; PLLD -> PLLD_dsi0; PLLD -> PLLD_dsi1; } subgraph cluster_pllh { label = "PLLH"; OSC -> PLLH; PLLH -> PLLH_aux; PLLH -> PLLH_pix; PLLH -> PLLH_rcal; } } subgraph cluster_mux { label = "clocks"; subgraph cluster_vpu_clocks { label = "VPU-clocks"; subgraph cluster_vpu_mux { label = "VPU-mux"; vGND [label="0: GND"]; vOSC [label="1: OSC"]; vtestdebug0 [label="2: testdebug0"]; vtestdebug1 [label="3: testdebug1"]; vPLLA_core [label="4: PLLA_core"]; vPLLC_core0 [label="5: PLLC_core0"]; vPLLD_core [label="6: PLLD_core"]; vPLLH_aux [label="7: PLLH_aux"]; vPLLC_core1 [label="8: PLLC_core1"]; vPLLC_core2 [label="9: PLLC_core2"]; GND -> vGND -> vpu_mux; OSC -> vOSC -> vpu_mux; testdebug0 -> vtestdebug0 -> vpu_mux; testdebug1 -> vtestdebug1 -> vpu_mux; PLLA_core -> vPLLA_core -> vpu_mux; PLLC_core0 -> vPLLC_core1 -> vpu_mux; PLLD_core -> vPLLD_core -> vpu_mux; PLLH_aux -> vPLLH_aux -> vpu_mux; PLLC_core1 -> vPLLC_core1 -> vpu_mux; PLLC_core2 -> vPLLC_core2 -> vpu_mux; } vpu_mux -> vpu; vpu_mux -> v3d; vpu_mux -> isp; vpu_mux -> h264; vpu_mux -> sdram; } subgraph cluster_per_clocks { label = "Periperial-clocks"; subgraph cluster_per_mux { label = "Periperal-mux"; pGND [label="0: GND"]; pOSC [label="1: OSC"]; ptestdebug0 [label="2: testdebug0"]; ptestdebug1 [label="3: testdebug1"]; pPLLA_per [label="4: PLLA_per"]; pPLLC_per [label="5: PLLC_per"]; pPLLD_per [label="5: PLLD_per"]; pPLLH_aux [label="5: PLLH_aux"]; GND -> pGND -> per_mux; OSC -> pOSC -> per_mux; testdebug0 -> ptestdebug0 -> per_mux; testdebug1 -> ptestdebug1 -> per_mux; PLLA_per -> pPLLA_per -> per_mux; PLLC_per -> pPLLC_per -> per_mux; PLLD_per -> pPLLD_per -> per_mux; PLLH_aux -> pPLLH_aux -> per_mux; } per_mux -> vec; per_mux -> uart; per_mux -> hsm; per_mux -> emmc; per_mux -> pwm; per_mux -> pcm; per_mux -> aveo; per_mux -> cam0; per_mux -> cam1; per_mux -> dft; per_mux -> dpi; per_mux -> dsi0e; per_mux -> dsi1e; per_mux -> gp0; per_mux -> gp1; per_mux -> gp2; per_mux -> slim; per_mux -> smi; } subgraph cluster_osc_clocks { label = "osc-clocks"; subgraph cluster_osc_mux { label = "osc-mux"; oGND [label="0: GND"]; oOSC [label="1: OSC"]; otestdebug0 [label="2: testdebug0"]; otestdebug1 [label="3: testdebug1"]; GND -> oGND -> osc_mux; OSC -> oOSC -> osc_mux; testdebug0 -> otestdebug0 -> osc_mux; testdebug1 -> otestdebug1 -> osc_mux; } osc_mux -> tsens; osc_mux -> tec; osc_mux -> otp; } subgraph cluster_unknown_mux_clocks { label = "unknown-parent-mux-clocks"; ukn_mux -> ccp2; ukn_mux -> dsi0pix; ukn_mux -> dsi1pix; ukn_mux -> pulse; ukn_mux -> td0; ukn_mux -> td1; } subgraph cluster_debug_clocks { label = "debug-clocks"; debug_mux -> peria; debug_mux -> sys; } } subgraph cluster_aux { label = “auxiliar-clocks"; vpu -> spi1; vpu -> spi2; vpu -> uart1; } } --- cut here --- I have no idea where we could put this information in the kernel tree - maybe this would help. From this you can see that we have: * PLL that is not configured now: * PLLB * a few more PLL-dividers that are not configured: * PLLB_ARM * PLLB_SP0 * PLLB_SP1 * PLLB_SP2 * PLLD_dsi0 * PLLD_dsi1 * PLLH_rcal * a few clocks which Eric has said are wrong and where the corresponding parents need to get found: * ccp2 (gate) * dsi0pix (gate - maybe PLLD_dis0?) * dis1pix (gate - maybe PLLD_dis1) * pulse (gate) * td0 * td1 * debug clocks that require a running debug power domain: * peria * sys * missing clocks in the current driver: * aveo * cam0 * cam1 * ccp2 (see note above) * dtf * dpi * dsi0e (maybe this also uses a different parent clock mux?) * dsi0pix (maybe this also uses a different parent clock mux?) * dsi1e (maybe this also uses a different parent clock mux?) * dsi1pix (maybe this also uses a different parent clock mux?) * gp0 * gp1 * gp2 * peria (see note above) * pulse (see note above) * slim * smi * td0 (see note above) * td1 (see note above) * td2 (see note above) * tec * sys (see note above) * generic clock that is supposedly not in use I can create a new patch that will include all those missing clocks that are undisputed in their settings (hence without any comments/notes) - I hope this is acceptable. If someone has any ideas about those clocks where we miss the correct parents/mux, then please add your wisdom.
> Martin Sperl <kernel@martin.sperl.org> hat am 17. Februar 2016 um 19:25 > geschrieben: > > As I am trying to complete the list of clocks here my “best” summary > so far of the clock tree for the bcm2835 taken from various sources: > * Datasheet > * broadcom provided VC4 headers (via https://github.com/msperl/rpi-registers) > * mailing list > > And I have come up with the following description that > you can put in graphviz or http://www.webgraphviz.com/ > > --- cut here --- > digraph clocks { > graph [ordering="out"]; > > subgraph cluster_osc { > label = "Oscillators"; > > "GND"; > "OSC"; > "testdebug0"; > "testdebug1"; > } > > subgraph cluster_pll { > label = "PLLs"; > > subgraph cluster_plla { > label = "PLLA"; > > OSC -> PLLA; > > PLLA -> PLLA_core; > PLLA -> PLLA_per; > PLLA -> PLLA_dsi0; > PLLA -> PLLA_ccp2; > } > > subgraph cluster_pllb { > label = "PLLB"; > > OSC -> PLLB; > > PLLB -> PLLB_ARM; > PLLB -> PLLB_SP0; > PLLB -> PLLB_SP1; > PLLB -> PLLB_SP2; > } > > subgraph cluster_pllc { > label = "PLLC"; > > OSC -> PLLC; > > PLLC -> PLLC_core0; > PLLC -> PLLC_core1; > PLLC -> PLLC_core2; > PLLC -> PLLC_per; > } > > subgraph cluster_plld { > label = "PLLD"; > > OSC -> PLLD; > > PLLD -> PLLD_core; > PLLD -> PLLD_per; > PLLD -> PLLD_dsi0; > PLLD -> PLLD_dsi1; > } > > subgraph cluster_pllh { > label = "PLLH"; > > OSC -> PLLH; > > PLLH -> PLLH_aux; > PLLH -> PLLH_pix; > PLLH -> PLLH_rcal; > } > } > > subgraph cluster_mux { > label = "clocks"; > > subgraph cluster_vpu_clocks { > label = "VPU-clocks"; > > subgraph cluster_vpu_mux { > label = "VPU-mux"; > > vGND [label="0: GND"]; > vOSC [label="1: OSC"]; > vtestdebug0 [label="2: testdebug0"]; > vtestdebug1 [label="3: testdebug1"]; > vPLLA_core [label="4: PLLA_core"]; > vPLLC_core0 [label="5: PLLC_core0"]; > vPLLD_core [label="6: PLLD_core"]; > vPLLH_aux [label="7: PLLH_aux"]; > vPLLC_core1 [label="8: PLLC_core1"]; > vPLLC_core2 [label="9: PLLC_core2"]; > > GND -> vGND -> vpu_mux; > OSC -> vOSC -> vpu_mux; > testdebug0 -> vtestdebug0 -> vpu_mux; > testdebug1 -> vtestdebug1 -> vpu_mux; > PLLA_core -> vPLLA_core -> vpu_mux; > PLLC_core0 -> vPLLC_core1 -> vpu_mux; > PLLD_core -> vPLLD_core -> vpu_mux; > PLLH_aux -> vPLLH_aux -> vpu_mux; > PLLC_core1 -> vPLLC_core1 -> vpu_mux; > PLLC_core2 -> vPLLC_core2 -> vpu_mux; > } > > vpu_mux -> vpu; > vpu_mux -> v3d; > vpu_mux -> isp; > vpu_mux -> h264; > vpu_mux -> sdram; > } > > subgraph cluster_per_clocks { > label = "Periperial-clocks"; > > subgraph cluster_per_mux { > label = "Periperal-mux"; > > pGND [label="0: GND"]; > pOSC [label="1: OSC"]; > ptestdebug0 [label="2: testdebug0"]; > ptestdebug1 [label="3: testdebug1"]; > pPLLA_per [label="4: PLLA_per"]; > pPLLC_per [label="5: PLLC_per"]; > pPLLD_per [label="5: PLLD_per"]; > pPLLH_aux [label="5: PLLH_aux"]; > > GND -> pGND -> per_mux; > OSC -> pOSC -> per_mux; > testdebug0 -> ptestdebug0 -> per_mux; > testdebug1 -> ptestdebug1 -> per_mux; > PLLA_per -> pPLLA_per -> per_mux; > PLLC_per -> pPLLC_per -> per_mux; > PLLD_per -> pPLLD_per -> per_mux; > PLLH_aux -> pPLLH_aux -> per_mux; > } > > per_mux -> vec; > per_mux -> uart; > per_mux -> hsm; > per_mux -> emmc; > per_mux -> pwm; > per_mux -> pcm; > per_mux -> aveo; > per_mux -> cam0; > per_mux -> cam1; > per_mux -> dft; > per_mux -> dpi; > per_mux -> dsi0e; > per_mux -> dsi1e; > per_mux -> gp0; > per_mux -> gp1; > per_mux -> gp2; > per_mux -> slim; > per_mux -> smi; > } > > subgraph cluster_osc_clocks { > label = "osc-clocks"; > > subgraph cluster_osc_mux { > label = "osc-mux"; > > oGND [label="0: GND"]; > oOSC [label="1: OSC"]; > otestdebug0 [label="2: testdebug0"]; > otestdebug1 [label="3: testdebug1"]; > > GND -> oGND -> osc_mux; > OSC -> oOSC -> osc_mux; > testdebug0 -> otestdebug0 -> osc_mux; > testdebug1 -> otestdebug1 -> osc_mux; > } > > osc_mux -> tsens; > osc_mux -> tec; > osc_mux -> otp; > } > > subgraph cluster_unknown_mux_clocks { > label = "unknown-parent-mux-clocks"; > > ukn_mux -> ccp2; > ukn_mux -> dsi0pix; > ukn_mux -> dsi1pix; > ukn_mux -> pulse; > ukn_mux -> td0; > ukn_mux -> td1; > } > > subgraph cluster_debug_clocks { > label = "debug-clocks"; > > debug_mux -> peria; > debug_mux -> sys; > } > } > > subgraph cluster_aux { > label = “auxiliar-clocks"; > > vpu -> spi1; > vpu -> spi2; > vpu -> uart1; > } > } > --- cut here --- > > I have no idea where we could put this information > in the kernel tree - maybe this would help. > Documentation/devicetree/bindings/clock/brcm,bcm2835-cprman.txt should be a good place.
diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c index 8bc0a76..1640288 100644 --- a/drivers/clk/bcm/clk-bcm2835.c +++ b/drivers/clk/bcm/clk-bcm2835.c @@ -92,8 +92,18 @@ #define CM_PCMDIV 0x09c #define CM_PWMCTL 0x0a0 #define CM_PWMDIV 0x0a4 +#define CM_SLIMCTL 0x0a8 +#define CM_SLIMDIV 0x0ac #define CM_SMICTL 0x0b0 #define CM_SMIDIV 0x0b4 +#define CM_TCNTCTL 0x0c0 +#define CM_TCNTDIV 0x0c4 +#define CM_TECCTL 0x0c8 +#define CM_TECDIV 0x0cc +#define CM_TD0CTL 0x0d0 +#define CM_TD0DIV 0x0d4 +#define CM_TD1CTL 0x0d8 +#define CM_TD1DIV 0x0dc #define CM_TSENSCTL 0x0e0 #define CM_TSENSDIV 0x0e4 #define CM_TIMERCTL 0x0e8 @@ -107,6 +117,9 @@ #define CM_SDCCTL 0x1a8 #define CM_SDCDIV 0x1ac #define CM_ARMCTL 0x1b0 +#define CM_ARMDIV 0x1b4 +#define CM_AVEOCTL 0x1b8 +#define CM_AVEODIV 0x1bc #define CM_EMMCCTL 0x1c0 #define CM_EMMCDIV 0x1c4 @@ -829,6 +842,219 @@ static const struct bcm2835_clock_data bcm2835_clock_pcm_data = { .frac_bits = 12, }; +static const struct bcm2835_clock_data bcm2835_clock_aveo_data = { + .name = "aveo", + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), + .parents = bcm2835_clock_per_parents, + .ctl_reg = CM_AVEOCTL, + .div_reg = CM_AVEODIV, + .int_bits = 4, + .frac_bits = 12, +}; + +static const struct bcm2835_clock_data bcm2835_clock_cam0_data = { + .name = "cam0", + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), + .parents = bcm2835_clock_per_parents, + .ctl_reg = CM_CAM0CTL, + .div_reg = CM_CAM0DIV, + .int_bits = 4, + .frac_bits = 8, +}; + +static const struct bcm2835_clock_data bcm2835_clock_cam1_data = { + .name = "cam1", + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), + .parents = bcm2835_clock_per_parents, + .ctl_reg = CM_CAM1CTL, + .div_reg = CM_CAM1DIV, + .int_bits = 4, + .frac_bits = 8, +}; + +static const struct bcm2835_clock_data bcm2835_clock_ccp2_data = { + /* this is possibly a gate */ + .name = "ccp2", + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), + .parents = bcm2835_clock_per_parents, + .ctl_reg = CM_CCP2CTL, + .div_reg = CM_CCP2DIV, + .int_bits = 1, + .frac_bits = 0, +}; + +static const struct bcm2835_clock_data bcm2835_clock_dft_data = { + .name = "dft", + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), + .parents = bcm2835_clock_per_parents, + .ctl_reg = CM_DFTCTL, + .div_reg = CM_DFTDIV, + .int_bits = 5, + .frac_bits = 0, +}; + +static const struct bcm2835_clock_data bcm2835_clock_dpi_data = { + .name = "dpi", + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), + .parents = bcm2835_clock_per_parents, + .ctl_reg = CM_DPICTL, + .div_reg = CM_DPIDIV, + .int_bits = 4, + .frac_bits = 8, +}; + +static const struct bcm2835_clock_data bcm2835_clock_dsi0e_data = { + .name = "dsi0e", + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), + .parents = bcm2835_clock_per_parents, + .ctl_reg = CM_DSI0ECTL, + .div_reg = CM_DSI0EDIV, + .int_bits = 4, + .frac_bits = 8, +}; + +static const struct bcm2835_clock_data bcm2835_clock_dsi0p_data = { + /* this is possibly a gate */ + .name = "dsi0p", + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), + .parents = bcm2835_clock_per_parents, + .ctl_reg = CM_DSI0PCTL, + .div_reg = CM_DSI0PDIV, + .int_bits = 1, + .frac_bits = 0, +}; + +static const struct bcm2835_clock_data bcm2835_clock_dsi1e_data = { + .name = "dsi1e", + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), + .parents = bcm2835_clock_per_parents, + .ctl_reg = CM_DSI1ECTL, + .div_reg = CM_DSI1EDIV, + .int_bits = 4, + .frac_bits = 8, +}; + +static const struct bcm2835_clock_data bcm2835_clock_dsi1p_data = { + /* this is possibly a gate */ + .name = "dsi1p", + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), + .parents = bcm2835_clock_per_parents, + .ctl_reg = CM_DSI1PCTL, + .div_reg = CM_DSI1PDIV, + .int_bits = 1, + .frac_bits = 0, +}; + +static const struct bcm2835_clock_data bcm2835_clock_gnric_data = { + .name = "gnric", + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), + .parents = bcm2835_clock_per_parents, + .ctl_reg = CM_GNRICCTL, + .div_reg = CM_GNRICDIV, + .int_bits = 12, + .frac_bits = 12, +}; + +static const struct bcm2835_clock_data bcm2835_clock_gp0_data = { + .name = "gp0", + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), + .parents = bcm2835_clock_per_parents, + .ctl_reg = CM_GP0CTL, + .div_reg = CM_GP0DIV, + .int_bits = 12, + .frac_bits = 12, +}; + +static const struct bcm2835_clock_data bcm2835_clock_gp1_data = { + .name = "gp1", + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), + .parents = bcm2835_clock_per_parents, + .ctl_reg = CM_GP1CTL, + .div_reg = CM_GP1DIV, + .int_bits = 12, + .frac_bits = 12, +}; + +static const struct bcm2835_clock_data bcm2835_clock_gp2_data = { + .name = "gp2", + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), + .parents = bcm2835_clock_per_parents, + .ctl_reg = CM_GP2CTL, + .div_reg = CM_GP2DIV, + .int_bits = 12, + .frac_bits = 12, +}; + +static const struct bcm2835_clock_data bcm2835_clock_peria_data = { + .name = "peria", + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), + .parents = bcm2835_clock_per_parents, + .ctl_reg = CM_PERIACTL, + .div_reg = CM_PERIADIV, + .int_bits = 12, + .frac_bits = 12, +}; + +static const struct bcm2835_clock_data bcm2835_clock_pulse_data = { + .name = "pulse", + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), + .parents = bcm2835_clock_per_parents, + .ctl_reg = CM_PULSECTL, + .div_reg = CM_PULSEDIV, + .int_bits = 12, + .frac_bits = 0, +}; + +static const struct bcm2835_clock_data bcm2835_clock_slim_data = { + .name = "slim", + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), + .parents = bcm2835_clock_per_parents, + .ctl_reg = CM_SLIMCTL, + .div_reg = CM_SLIMDIV, + .int_bits = 12, + .frac_bits = 12, +}; + +static const struct bcm2835_clock_data bcm2835_clock_smi_data = { + .name = "smi", + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), + .parents = bcm2835_clock_per_parents, + .ctl_reg = CM_SMICTL, + .div_reg = CM_SMIDIV, + .int_bits = 4, + .frac_bits = 8, +}; + +static const struct bcm2835_clock_data bcm2835_clock_td0_data = { + .name = "td0", + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), + .parents = bcm2835_clock_per_parents, + .ctl_reg = CM_TD0CTL, + .div_reg = CM_TD0DIV, + .int_bits = 12, + .frac_bits = 12, +}; + +static const struct bcm2835_clock_data bcm2835_clock_td1_data = { + .name = "td1", + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), + .parents = bcm2835_clock_per_parents, + .ctl_reg = CM_TD1CTL, + .div_reg = CM_TD1DIV, + .int_bits = 12, + .frac_bits = 12, +}; + +static const struct bcm2835_clock_data bcm2835_clock_tec_data = { + .name = "tec", + .num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents), + .parents = bcm2835_clock_per_parents, + .ctl_reg = CM_TECCTL, + .div_reg = CM_TECDIV, + .int_bits = 6, + .frac_bits = 0, +}; + struct bcm2835_gate_data { const char *name; const char *parent; @@ -836,18 +1062,18 @@ struct bcm2835_gate_data { u32 ctl_reg; }; -/* - * CM_PERIICTL (and CM_PERIACTL, CM_SYSCTL and CM_VPUCTL if - * you have the debug bit set in the power manager, which we - * don't bother exposing) are individual gates off of the - * non-stop vpu clock. - */ static const struct bcm2835_gate_data bcm2835_clock_peri_image_data = { .name = "peri_image", .parent = "vpu", .ctl_reg = CM_PERIICTL, }; +static const struct bcm2835_gate_data bcm2835_clock_sys_data = { + .name = "sys", + .parent = "vpu", + .ctl_reg = CM_SYSCTL, +}; + struct bcm2835_pll { struct clk_hw hw; struct bcm2835_cprman *cprman; @@ -1591,9 +1817,31 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { [BCM2835_CLOCK_EMMC] = REGISTER_CLK(&bcm2835_clock_emmc_data), [BCM2835_CLOCK_PWM] = REGISTER_CLK(&bcm2835_clock_pwm_data), [BCM2835_CLOCK_PCM] = REGISTER_CLK(&bcm2835_clock_pcm_data), + [BCM2835_CLOCK_AVEO] = REGISTER_CLK(&bcm2835_clock_aveo_data), + [BCM2835_CLOCK_CAM0] = REGISTER_CLK(&bcm2835_clock_cam0_data), + [BCM2835_CLOCK_CAM1] = REGISTER_CLK(&bcm2835_clock_cam1_data), + [BCM2835_CLOCK_CCP2] = REGISTER_CLK(&bcm2835_clock_ccp2_data), + [BCM2835_CLOCK_DFT] = REGISTER_CLK(&bcm2835_clock_dft_data), + [BCM2835_CLOCK_DPI] = REGISTER_CLK(&bcm2835_clock_dpi_data), + [BCM2835_CLOCK_DSI0E] = REGISTER_CLK(&bcm2835_clock_dsi0e_data), + [BCM2835_CLOCK_DSI0P] = REGISTER_CLK(&bcm2835_clock_dsi0p_data), + [BCM2835_CLOCK_DSI1E] = REGISTER_CLK(&bcm2835_clock_dsi1e_data), + [BCM2835_CLOCK_DSI1P] = REGISTER_CLK(&bcm2835_clock_dsi1p_data), + [BCM2835_CLOCK_GNRIC] = REGISTER_CLK(&bcm2835_clock_gnric_data), + [BCM2835_CLOCK_GP0] = REGISTER_CLK(&bcm2835_clock_gp0_data), + [BCM2835_CLOCK_GP1] = REGISTER_CLK(&bcm2835_clock_gp1_data), + [BCM2835_CLOCK_GP2] = REGISTER_CLK(&bcm2835_clock_gp2_data), + [BCM2835_CLOCK_PERIA] = REGISTER_CLK(&bcm2835_clock_peria_data), + [BCM2835_CLOCK_PULSE] = REGISTER_CLK(&bcm2835_clock_pulse_data), + [BCM2835_CLOCK_SLIM] = REGISTER_CLK(&bcm2835_clock_slim_data), + [BCM2835_CLOCK_SMI] = REGISTER_CLK(&bcm2835_clock_smi_data), + [BCM2835_CLOCK_TD0] = REGISTER_CLK(&bcm2835_clock_td0_data), + [BCM2835_CLOCK_TD1] = REGISTER_CLK(&bcm2835_clock_td1_data), + [BCM2835_CLOCK_TEC] = REGISTER_CLK(&bcm2835_clock_tec_data), /* the gates */ [BCM2835_CLOCK_PERI_IMAGE] = REGISTER_GATE( &bcm2835_clock_peri_image_data), + [BCM2835_CLOCK_SYS] = REGISTER_GATE(&bcm2835_clock_sys_data), }; static int bcm2835_clk_probe(struct platform_device *pdev) diff --git a/include/dt-bindings/clock/bcm2835.h b/include/dt-bindings/clock/bcm2835.h index 9a7b4a5..d29f181 100644 --- a/include/dt-bindings/clock/bcm2835.h +++ b/include/dt-bindings/clock/bcm2835.h @@ -45,3 +45,25 @@ #define BCM2835_CLOCK_PERI_IMAGE 29 #define BCM2835_CLOCK_PWM 30 #define BCM2835_CLOCK_PCM 31 +#define BCM2835_CLOCK_AVEO 32 +#define BCM2835_CLOCK_CAM0 33 +#define BCM2835_CLOCK_CAM1 34 +#define BCM2835_CLOCK_CCP2 35 +#define BCM2835_CLOCK_DFT 36 +#define BCM2835_CLOCK_DPI 37 +#define BCM2835_CLOCK_DSI0E 38 +#define BCM2835_CLOCK_DSI0P 39 +#define BCM2835_CLOCK_DSI1E 40 +#define BCM2835_CLOCK_DSI1P 41 +#define BCM2835_CLOCK_GNRIC 42 +#define BCM2835_CLOCK_GP0 43 +#define BCM2835_CLOCK_GP1 44 +#define BCM2835_CLOCK_GP2 45 +#define BCM2835_CLOCK_PERIA 46 +#define BCM2835_CLOCK_PULSE 47 +#define BCM2835_CLOCK_SLIM 48 +#define BCM2835_CLOCK_SMI 49 +#define BCM2835_CLOCK_SYS 50 +#define BCM2835_CLOCK_TD0 51 +#define BCM2835_CLOCK_TD1 52 +#define BCM2835_CLOCK_TEC 53