diff for duplicates of <20130802234143.6450.39877@quantum> diff --git a/a/1.txt b/N1/1.txt index dd7aa59..9482e2d 100644 --- a/a/1.txt +++ b/N1/1.txt @@ -2,22 +2,19 @@ Quoting Gerhard Sittig (2013-07-22 05:14:44) > this change implements a clock driver for the MPC512x PowerPC platform > which follows the COMMON_CLK approach and uses common clock drivers > shared with other platforms -> = - +> > this driver implements the publicly announced set of clocks (which can > get referenced by means of symbolic identifiers from the dt-bindings > header file), as well as generates additional 'struct clk' items where > the SoC hardware cannot easily get mapped to the common primitives of > the clock API, or requires "intermediate" clock nodes to represent > clocks that have both gates and dividers -> = - +> > the previous PPC_CLOCK implementation is kept in place and remains in > parallel to the common clock implementation for test and comparison > during migration, a compile time option picks one of the two > alternatives (Kconfig switch, common clock used by default) -> = - +> > some of the clock items get pre-enabled in the clock driver to not have > them automatically disabled by the underlying clock subsystem because of > their being unused -- this approach is desirable because @@ -32,8 +29,7 @@ Quoting Gerhard Sittig (2013-07-22 05:14:44) > infrastructure, while more appropriate support for specific hardware > constraints isn't available yet (remaining changes are strictly > internal to the clock driver and won't affect peripheral drivers) -> = - +> > clkdev registration provides "alias names" for few clock items > - to not break those peripheral drivers which encode their component > index into the name that is used for clock lookup (UART, SPI, USB) @@ -41,8 +37,7 @@ Quoting Gerhard Sittig (2013-07-22 05:14:44) > were encoded in the previous PPC_CLOCK implementation (NFC, VIU, CAN) > this workaround will get removed as these drivers get adjusted after > device tree based clock lookup has become available -> = - +> > Signed-off-by: Gerhard Sittig <gsi@denx.de> Hi Gerhard, @@ -57,15 +52,12 @@ Mike > --- > arch/powerpc/platforms/512x/Kconfig | 14 +- > arch/powerpc/platforms/512x/Makefile | 4 +- -> arch/powerpc/platforms/512x/clock-commonclk.c | 786 +++++++++++++++++++= -++++++ +> arch/powerpc/platforms/512x/clock-commonclk.c | 786 +++++++++++++++++++++++++ > include/linux/clk-provider.h | 16 + > 4 files changed, 818 insertions(+), 2 deletions(-) > create mode 100644 arch/powerpc/platforms/512x/clock-commonclk.c -> = - -> diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms= -/512x/Kconfig +> +> diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig > index fc9c1cb..c5fcdd0 100644 > --- a/arch/powerpc/platforms/512x/Kconfig > +++ b/arch/powerpc/platforms/512x/Kconfig @@ -92,8 +84,7 @@ Mike > select PPC_PCI_CHOICE > select FSL_PCI if PCI > select ARCH_WANT_OPTIONAL_GPIOLIB -> diff --git a/arch/powerpc/platforms/512x/Makefile b/arch/powerpc/platform= -s/512x/Makefile +> diff --git a/arch/powerpc/platforms/512x/Makefile b/arch/powerpc/platforms/512x/Makefile > index 72fb934..1e05f9d 100644 > --- a/arch/powerpc/platforms/512x/Makefile > +++ b/arch/powerpc/platforms/512x/Makefile @@ -101,15 +92,14 @@ s/512x/Makefile > # > # Makefile for the Freescale PowerPC 512x linux kernel. > # -> -obj-y +=3D clock.o mpc512x_shared.o -> +obj-$(CONFIG_PPC_CLOCK) +=3D clock.o -> +obj-$(CONFIG_COMMON_CLK) +=3D clock-commonclk.o -> +obj-y +=3D mpc512x_shared.o -> obj-$(CONFIG_MPC5121_ADS) +=3D mpc5121_ads.o mpc5121_ads_cpld.o -> obj-$(CONFIG_MPC512x_GENERIC) +=3D mpc512x_generic.o -> obj-$(CONFIG_PDM360NG) +=3D pdm360ng.o -> diff --git a/arch/powerpc/platforms/512x/clock-commonclk.c b/arch/powerpc= -/platforms/512x/clock-commonclk.c +> -obj-y += clock.o mpc512x_shared.o +> +obj-$(CONFIG_PPC_CLOCK) += clock.o +> +obj-$(CONFIG_COMMON_CLK) += clock-commonclk.o +> +obj-y += mpc512x_shared.o +> obj-$(CONFIG_MPC5121_ADS) += mpc5121_ads.o mpc5121_ads_cpld.o +> obj-$(CONFIG_MPC512x_GENERIC) += mpc512x_generic.o +> obj-$(CONFIG_PDM360NG) += pdm360ng.o +> diff --git a/arch/powerpc/platforms/512x/clock-commonclk.c b/arch/powerpc/platforms/512x/clock-commonclk.c > new file mode 100644 > index 0000000..762ee85 > --- /dev/null @@ -154,11 +144,10 @@ s/512x/Makefile > +#define NR_SPDIFS 1 > +#define NR_MCLKS (NR_PSCS + NR_MSCANS + NR_SPDIFS) > + -> +/* extend the public set of clocks by adding internal slots for manageme= -nt */ +> +/* extend the public set of clocks by adding internal slots for management */ > +enum { > + /* arrange for adjacent numbers after the public set */ -> + MPC512x_CLK_START_PRIVATE =3D MPC512x_CLK_LAST_PUBLIC, +> + MPC512x_CLK_START_PRIVATE = MPC512x_CLK_LAST_PUBLIC, > + /* clocks which aren't announced to the public */ > + MPC512x_CLK_DDR, > + MPC512x_CLK_MEM, @@ -179,7 +168,7 @@ nt */ > + MPC512x_CLK_SPDIF_TX_IN, > + /* intermediates for the mux+gate+div+mux MCLK generation */ > + MPC512x_CLK_MCLKS_FIRST, -> + MPC512x_CLK_MCLKS_LAST =3D MPC512x_CLK_MCLKS_FIRST +> + MPC512x_CLK_MCLKS_LAST = MPC512x_CLK_MCLKS_FIRST > + + NR_MCLKS * MCLK_MAX_IDX, > + /* internal, symbolic spec for the number of slots */ > + MPC512x_CLK_LAST_PRIVATE, @@ -196,8 +185,7 @@ nt */ > +/* convenience wrappers around the common clk API */ > +static inline struct clk *mpc512x_clk_fixed(const char *name, int rate) > +{ -> + return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rat= -e); +> + return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate); > +} > + > +static inline struct clk *mpc512x_clk_factor( @@ -206,9 +194,8 @@ e); > +{ > + int clkflags; > + -> + clkflags =3D CLK_SET_RATE_PARENT; -> + return clk_register_fixed_factor(NULL, name, parent_name, clkflag= -s, +> + clkflags = CLK_SET_RATE_PARENT; +> + return clk_register_fixed_factor(NULL, name, parent_name, clkflags, > + mul, div); > +} > + @@ -227,7 +214,7 @@ s, > +{ > + u8 divflags; > + -> + divflags =3D 0; +> + divflags = 0; > + return clk_register_divider_table(NULL, name, parent_name, 0, > + reg, pos, len, divflags, > + divtab, &clklock); @@ -239,7 +226,7 @@ s, > +{ > + int clkflags; > + -> + clkflags =3D CLK_SET_RATE_PARENT; +> + clkflags = CLK_SET_RATE_PARENT; > + return clk_register_gate(NULL, name, parent_name, clkflags, > + reg, pos, 0, &clklock); > +} @@ -251,35 +238,34 @@ s, > + int clkflags; > + u8 muxflags; > + -> + clkflags =3D CLK_SET_RATE_PARENT; -> + muxflags =3D 0; +> + clkflags = CLK_SET_RATE_PARENT; +> + muxflags = 0; > + return clk_register_mux(NULL, name, > + parent_names, parent_count, clkflags, > + reg, pos, len, muxflags, &clklock); > +} > + > +/* helper to isolate a bit field from a register */ -> +static inline int get_bit_field(uint32_t __iomem *reg, uint8_t pos, uint= -8_t len) +> +static inline int get_bit_field(uint32_t __iomem *reg, uint8_t pos, uint8_t len) > +{ > + uint32_t val; > + -> + val =3D in_be32(reg); -> + val >>=3D pos; -> + val &=3D (1 << len) - 1; +> + val = in_be32(reg); +> + val >>= pos; +> + val &= (1 << len) - 1; > + return val; > +} > + > +/* get the SPMF and translate it into the "sys pll" multiplier */ > +static int get_spmf_mult(void) > +{ -> + static int spmf_to_mult[] =3D { +> + static int spmf_to_mult[] = { > + 68, 1, 12, 16, 20, 24, 28, 32, > + 36, 40, 44, 48, 52, 56, 60, 64, > + }; > + int spmf; > + -> + spmf =3D get_bit_field(&clkregs->spmr, 24, 4); +> + spmf = get_bit_field(&clkregs->spmr, 24, 4); > + return spmf_to_mult[spmf]; > +} > + @@ -291,7 +277,7 @@ s, > + */ > +static int get_sys_div_x2(void) > +{ -> + static int sysdiv_code_to_x2[] =3D { +> + static int sysdiv_code_to_x2[] = { > + 4, 5, 6, 7, 8, 9, 10, 14, > + 12, 16, 18, 22, 20, 24, 26, 30, > + 28, 32, 34, 38, 36, 40, 42, 46, @@ -300,7 +286,7 @@ s, > + }; > + int divcode; > + -> + divcode =3D get_bit_field(&clkregs->scfr2, 26, 6); +> + divcode = get_bit_field(&clkregs->scfr2, 26, 6); > + return sysdiv_code_to_x2[divcode]; > +} > + @@ -312,12 +298,12 @@ s, > + */ > +static int get_cpmf_mult_x2(void) > +{ -> + static int cpmf_to_mult[] =3D { +> + static int cpmf_to_mult[] = { > + 72, 2, 2, 3, 4, 5, 6, 7, > + }; > + int cpmf; > + -> + cpmf =3D get_bit_field(&clkregs->spmr, 16, 4); +> + cpmf = get_bit_field(&clkregs->spmr, 16, 4); > + return cpmf_to_mult[cpmf]; > +} > + @@ -328,21 +314,21 @@ s, > + */ > + > +/* applies to the IPS_DIV, and PCI_DIV values */ -> +static struct clk_div_table divtab_2346[] =3D { -> + { .val =3D 2, .div =3D 2, }, -> + { .val =3D 3, .div =3D 3, }, -> + { .val =3D 4, .div =3D 4, }, -> + { .val =3D 6, .div =3D 6, }, -> + { .div =3D 0, }, +> +static struct clk_div_table divtab_2346[] = { +> + { .val = 2, .div = 2, }, +> + { .val = 3, .div = 3, }, +> + { .val = 4, .div = 4, }, +> + { .val = 6, .div = 6, }, +> + { .div = 0, }, > +}; > + > +/* applies to the MBX_DIV, LPC_DIV, and NFC_DIV values */ -> +static struct clk_div_table divtab_1234[] =3D { -> + { .val =3D 1, .div =3D 1, }, -> + { .val =3D 2, .div =3D 2, }, -> + { .val =3D 3, .div =3D 3, }, -> + { .val =3D 4, .div =3D 4, }, -> + { .div =3D 0, }, +> +static struct clk_div_table divtab_1234[] = { +> + { .val = 1, .div = 1, }, +> + { .val = 2, .div = 2, }, +> + { .val = 3, .div = 3, }, +> + { .val = 4, .div = 4, }, +> + { .div = 0, }, > +}; > + > +static int get_freq_from_dt(char *propname) @@ -351,12 +337,12 @@ s, > + const unsigned int *prop; > + int val; > + -> + val =3D 0; -> + np =3D of_find_compatible_node(NULL, NULL, "fsl,mpc5121-immr"); +> + val = 0; +> + np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-immr"); > + if (np) { -> + prop =3D of_get_property(np, propname, NULL); +> + prop = of_get_property(np, propname, NULL); > + if (prop) -> + val =3D *prop; +> + val = *prop; > + of_node_put(np); > + } > + return val; @@ -366,8 +352,8 @@ s, > +{ > + size_t i; > + -> + for (i =3D 0; i < ARRAY_SIZE(clks); i++) -> + clks[i] =3D ERR_PTR(-ENODEV); +> + for (i = 0; i < ARRAY_SIZE(clks); i++) +> + clks[i] = ERR_PTR(-ENODEV); > +} > + > +/* @@ -391,36 +377,32 @@ s, > + int calc_freq; > + > + /* fetch mul/div factors from the hardware */ -> + *sys_mul =3D get_spmf_mult(); -> + *sys_mul *=3D 2; /* compensate for the fractional divide= -r */ -> + *sys_div =3D get_sys_div_x2(); -> + *ips_div =3D get_bit_field(&clkregs->scfr1, 23, 3); +> + *sys_mul = get_spmf_mult(); +> + *sys_mul *= 2; /* compensate for the fractional divider */ +> + *sys_div = get_sys_div_x2(); +> + *ips_div = get_bit_field(&clkregs->scfr1, 23, 3); > + > + /* lookup the oscillator node */ -> + osc_clk =3D clk_get(NULL, "osc"); +> + osc_clk = clk_get(NULL, "osc"); > + if (osc_clk) { > + /* descend REF directly from OSC, verify the IPS rate */ -> + clks[MPC512x_CLK_REF] =3D mpc512x_clk_factor("ref", "osc"= -, 1, 1); -> + calc_freq =3D clk_get_rate(clks[MPC512x_CLK_REF]); -> + calc_freq *=3D *sys_mul; -> + calc_freq /=3D *sys_div; -> + calc_freq /=3D 2; -> + calc_freq /=3D *ips_div; -> + if (bus_freq && calc_freq !=3D bus_freq) -> + pr_warn("calc rate %d !=3D OF spec %d\n", +> + clks[MPC512x_CLK_REF] = mpc512x_clk_factor("ref", "osc", 1, 1); +> + calc_freq = clk_get_rate(clks[MPC512x_CLK_REF]); +> + calc_freq *= *sys_mul; +> + calc_freq /= *sys_div; +> + calc_freq /= 2; +> + calc_freq /= *ips_div; +> + if (bus_freq && calc_freq != bus_freq) +> + pr_warn("calc rate %d != OF spec %d\n", > + calc_freq, bus_freq); > + } else { -> + /* calculate OSC rate and create REF from the freq value = -*/ -> + calc_freq =3D bus_freq; /* start with IPS */ -> + calc_freq *=3D *ips_div; /* IPS -> CSB */ -> + calc_freq *=3D 2; /* CSB -> SYS */ -> + calc_freq *=3D *sys_div; /* SYS -> PLL out */ -> + calc_freq /=3D *sys_mul; /* PLL out -> REF =3D=3D OSC */ -> + clks[MPC512x_CLK_REF] =3D mpc512x_clk_fixed("ref", calc_f= -req); +> + /* calculate OSC rate and create REF from the freq value */ +> + calc_freq = bus_freq; /* start with IPS */ +> + calc_freq *= *ips_div; /* IPS -> CSB */ +> + calc_freq *= 2; /* CSB -> SYS */ +> + calc_freq *= *sys_div; /* SYS -> PLL out */ +> + calc_freq /= *sys_mul; /* PLL out -> REF == OSC */ +> + clks[MPC512x_CLK_REF] = mpc512x_clk_fixed("ref", calc_freq); > + } > +} > + @@ -457,7 +439,7 @@ req); > + * it's the very data type which <linux/clk-provider.h> expects, > + * making this declaration pass checkpatch will break compilation > + */ -> +static const char *parent_names_mux0[] =3D { +> +static const char *parent_names_mux0[] = { > + "sys", "ref", "psc-mclk-in", "spdif-tx", > +}; > + @@ -513,7 +495,7 @@ req); > + "spdif_mclk", \ > +} > + -> +static struct mclk_setup_data mclk_psc_data[] =3D { +> +static struct mclk_setup_data mclk_psc_data[] = { > + MCLK_SETUP_DATA_PSC(0), > + MCLK_SETUP_DATA_PSC(1), > + MCLK_SETUP_DATA_PSC(2), @@ -528,14 +510,14 @@ req); > + MCLK_SETUP_DATA_PSC(11), > +}; > + -> +static struct mclk_setup_data mclk_mscan_data[] =3D { +> +static struct mclk_setup_data mclk_mscan_data[] = { > + MCLK_SETUP_DATA_MSCAN(0), > + MCLK_SETUP_DATA_MSCAN(1), > + MCLK_SETUP_DATA_MSCAN(2), > + MCLK_SETUP_DATA_MSCAN(3), > +}; > + -> +static struct mclk_setup_data mclk_spdif_data[] =3D { +> +static struct mclk_setup_data mclk_spdif_data[] = { > + MCLK_SETUP_DATA_SPDIF, > +}; > + @@ -544,43 +526,41 @@ req); > +{ > + size_t clks_idx_pub, clks_idx_int; > + u32 __iomem *mccr_reg; /* MCLK control register (mux, en, div) */ -> + u32 __iomem *sccr_reg; /* system clock control register (enable)= - */ +> + u32 __iomem *sccr_reg; /* system clock control register (enable) */ > + int sccr_bit; > + int div; > + > + /* derive a few parameters from the component type and index */ > + switch (entry->type) { > + case MCLK_TYPE_PSC: -> + clks_idx_pub =3D MPC512x_CLK_PSC0_MCLK + entry->comp_idx; -> + clks_idx_int =3D MPC512x_CLK_MCLKS_FIRST +> + clks_idx_pub = MPC512x_CLK_PSC0_MCLK + entry->comp_idx; +> + clks_idx_int = MPC512x_CLK_MCLKS_FIRST > + + (entry->comp_idx) * MCLK_MAX_IDX; -> + mccr_reg =3D &clkregs->psc_ccr[entry->comp_idx]; +> + mccr_reg = &clkregs->psc_ccr[entry->comp_idx]; > + break; > + case MCLK_TYPE_MSCAN: -> + clks_idx_pub =3D MPC512x_CLK_MSCAN0_MCLK + entry->comp_id= -x; -> + clks_idx_int =3D MPC512x_CLK_MCLKS_FIRST +> + clks_idx_pub = MPC512x_CLK_MSCAN0_MCLK + entry->comp_idx; +> + clks_idx_int = MPC512x_CLK_MCLKS_FIRST > + + (NR_PSCS + entry->comp_idx) * MCLK_MAX_IDX; -> + mccr_reg =3D &clkregs->mscan_ccr[entry->comp_idx]; +> + mccr_reg = &clkregs->mscan_ccr[entry->comp_idx]; > + break; > + case MCLK_TYPE_SPDIF: -> + clks_idx_pub =3D MPC512x_CLK_SPDIF_MCLK; -> + clks_idx_int =3D MPC512x_CLK_MCLKS_FIRST +> + clks_idx_pub = MPC512x_CLK_SPDIF_MCLK; +> + clks_idx_int = MPC512x_CLK_MCLKS_FIRST > + + (NR_PSCS + NR_MSCANS) * MCLK_MAX_IDX; -> + mccr_reg =3D &clkregs->spccr; +> + mccr_reg = &clkregs->spccr; > + break; > + default: > + return; > + } -> + if (entry->bit_sccr1 >=3D 0) { -> + sccr_reg =3D &clkregs->sccr1; -> + sccr_bit =3D entry->bit_sccr1; -> + } else if (entry->bit_sccr2 >=3D 0) { -> + sccr_reg =3D &clkregs->sccr2; -> + sccr_bit =3D entry->bit_sccr2; +> + if (entry->bit_sccr1 >= 0) { +> + sccr_reg = &clkregs->sccr1; +> + sccr_bit = entry->bit_sccr1; +> + } else if (entry->bit_sccr2 >= 0) { +> + sccr_reg = &clkregs->sccr2; +> + sccr_bit = entry->bit_sccr2; > + } else { -> + sccr_reg =3D NULL; +> + sccr_reg = NULL; > + } > + > + /* @@ -589,8 +569,8 @@ x; > + * during setup (that's a documented hardware requirement) > + * > + * the PPC_CLOCK implementation might even have violated the -> + * "MCLK <=3D IPS" constraint, the fixed divider value of 1 -> + * results in a divider of 2 and thus MCLK =3D SYS/2 which equals +> + * "MCLK <= IPS" constraint, the fixed divider value of 1 +> + * results in a divider of 2 and thus MCLK = SYS/2 which equals > + * CSB which is greater than IPS; the serial port setup may have > + * adjusted the divider which the clock setup might have left in > + * an undesirable state @@ -601,8 +581,8 @@ x; > + * - MCLK 0 enabled > + * - MCLK 1 from MCLK DIV > + */ -> + div =3D clk_get_rate(clks[MPC512x_CLK_SYS]); -> + div /=3D clk_get_rate(clks[MPC512x_CLK_IPS]); +> + div = clk_get_rate(clks[MPC512x_CLK_SYS]); +> + div /= clk_get_rate(clks[MPC512x_CLK_IPS]); > + out_be32(mccr_reg, (0 << 16)); > + out_be32(mccr_reg, (0 << 16) | ((div - 1) << 17)); > + out_be32(mccr_reg, (1 << 16) | ((div - 1) << 17)); @@ -625,36 +605,34 @@ x; > + * clock items even for those muxers which actually are NOPs > + * (those with two inputs of which one is reserved) > + */ -> + clks[clks_idx_int + MCLK_IDX_MUX0] =3D mpc512x_clk_muxed( +> + clks[clks_idx_int + MCLK_IDX_MUX0] = mpc512x_clk_muxed( > + entry->name_mux0, -> + &parent_names_mux0[0], ARRAY_SIZE(parent_names_mu= -x0), +> + &parent_names_mux0[0], ARRAY_SIZE(parent_names_mux0), > + mccr_reg, 14, 2); -> + clks[clks_idx_int + MCLK_IDX_EN0] =3D mpc512x_clk_gated( +> + clks[clks_idx_int + MCLK_IDX_EN0] = mpc512x_clk_gated( > + entry->name_en0, entry->name_mux0, > + mccr_reg, 16); -> + clks[clks_idx_int + MCLK_IDX_DIV0] =3D mpc512x_clk_divider( +> + clks[clks_idx_int + MCLK_IDX_DIV0] = mpc512x_clk_divider( > + entry->name_div0, > + entry->name_en0, CLK_SET_RATE_GATE, > + mccr_reg, 17, 15, 0); > + if (entry->has_mclk1) { -> + clks[clks_idx_int + MCLK_IDX_MUX1] =3D mpc512x_clk_muxed( +> + clks[clks_idx_int + MCLK_IDX_MUX1] = mpc512x_clk_muxed( > + entry->name_mux1, > + &entry->parent_names_mux1[0], > + ARRAY_SIZE(entry->parent_names_mux1), > + mccr_reg, 7, 1); > + } else { -> + clks[clks_idx_int + MCLK_IDX_MUX1] =3D mpc512x_clk_factor( -> + entry->name_mux1, entry->parent_names_mux= -1[0], +> + clks[clks_idx_int + MCLK_IDX_MUX1] = mpc512x_clk_factor( +> + entry->name_mux1, entry->parent_names_mux1[0], > + 1, 1); > + } > + if (sccr_reg) { -> + clks[clks_idx_pub] =3D mpc512x_clk_gated( +> + clks[clks_idx_pub] = mpc512x_clk_gated( > + entry->name_mclk, > + entry->name_mux1, sccr_reg, sccr_bit); > + } else { -> + clks[clks_idx_pub] =3D mpc512x_clk_factor( +> + clks[clks_idx_pub] = mpc512x_clk_factor( > + entry->name_mclk, > + entry->name_mux1, 1, 1); > + } @@ -671,8 +649,7 @@ x0), > + clk_register_clkdev(clks[clks_idx_pub], entry->name_mclk, NULL); > +} > + -> +static void mpc512x_clk_setup_mclks(struct mclk_setup_data *table, size_= -t count) +> +static void mpc512x_clk_setup_mclks(struct mclk_setup_data *table, size_t count) > +{ > + while (count-- > 0) > + mpc512x_clk_setup_mclk(table++); @@ -702,37 +679,26 @@ t count) > + */ > + > + /* regardless of whether XTAL/OSC exists, have REF created */ -> + mpc512x_clk_setup_ref_clock(busfreq, &sys_mul, &sys_div, &ips_div= -); +> + mpc512x_clk_setup_ref_clock(busfreq, &sys_mul, &sys_div, &ips_div); > + > + /* now setup the REF -> SYS -> CSB -> IPS hierarchy */ -> + clks[MPC512x_CLK_SYS] =3D mpc512x_clk_factor("sys", "ref", +> + clks[MPC512x_CLK_SYS] = mpc512x_clk_factor("sys", "ref", > + sys_mul, sys_div); -> + clks[MPC512x_CLK_CSB] =3D mpc512x_clk_factor("csb", "sys", 1, 2); -> + clks[MPC512x_CLK_IPS] =3D mpc512x_clk_divtable("ips", "csb", -> + &clkregs->scfr1, 23,= - 3, +> + clks[MPC512x_CLK_CSB] = mpc512x_clk_factor("csb", "sys", 1, 2); +> + clks[MPC512x_CLK_IPS] = mpc512x_clk_divtable("ips", "csb", +> + &clkregs->scfr1, 23, 3, > + divtab_2346); > + > + /* now setup anything below SYS and CSB and IPS */ -> + clks[MPC512x_CLK_DDR_UG] =3D mpc512x_clk_factor("ddr-ug", "sys", = -1, 2); -> + clks[MPC512x_CLK_SDHC_x4] =3D mpc512x_clk_factor("sdhc-x4", "csb"= -, 4, 1); -> + clks[MPC512x_CLK_SDHC_UG] =3D mpc512x_clk_divider("sdhc-ug", "sdh= -c-x4", 0, -> + &clkregs->scfr2, = -0, 8, -> + CLK_DIVIDER_ONE_B= -ASED); -> + clks[MPC512x_CLK_DIU_x4] =3D mpc512x_clk_factor("diu-x4", "csb", = -4, 1); -> + clks[MPC512x_CLK_DIU_UG] =3D mpc512x_clk_divider("diu-ug", "diu-x= -4", 0, -> + &clkregs->scfr1, 0= -, 8, -> + CLK_DIVIDER_ONE_BA= -SED); +> + clks[MPC512x_CLK_DDR_UG] = mpc512x_clk_factor("ddr-ug", "sys", 1, 2); +> + clks[MPC512x_CLK_SDHC_x4] = mpc512x_clk_factor("sdhc-x4", "csb", 4, 1); +> + clks[MPC512x_CLK_SDHC_UG] = mpc512x_clk_divider("sdhc-ug", "sdhc-x4", 0, +> + &clkregs->scfr2, 0, 8, +> + CLK_DIVIDER_ONE_BASED); +> + clks[MPC512x_CLK_DIU_x4] = mpc512x_clk_factor("diu-x4", "csb", 4, 1); +> + clks[MPC512x_CLK_DIU_UG] = mpc512x_clk_divider("diu-ug", "diu-x4", 0, +> + &clkregs->scfr1, 0, 8, +> + CLK_DIVIDER_ONE_BASED); > + > + /* > + * the "power architecture PLL" was setup from data which was @@ -741,108 +707,89 @@ SED); > + * longer adjustable, or no longer in need of adjustment), which > + * is why we don't register a PLL here but assume fixed factors > + */ -> + mul =3D get_cpmf_mult_x2(); -> + div =3D 2; /* compensate for the fractional factor */ -> + clks[MPC512x_CLK_E300] =3D mpc512x_clk_factor("e300", "csb", mul,= - div); +> + mul = get_cpmf_mult_x2(); +> + div = 2; /* compensate for the fractional factor */ +> + clks[MPC512x_CLK_E300] = mpc512x_clk_factor("e300", "csb", mul, div); > + -> + clks[MPC512x_CLK_MBX_BUS_UG] =3D mpc512x_clk_factor("mbx-bus-ug",= - "csb", +> + clks[MPC512x_CLK_MBX_BUS_UG] = mpc512x_clk_factor("mbx-bus-ug", "csb", > + 1, 2); -> + clks[MPC512x_CLK_MBX_UG] =3D mpc512x_clk_divtable("mbx-ug", "mbx-= -bus-ug", -> + &clkregs->scfr1, = -14, 3, +> + clks[MPC512x_CLK_MBX_UG] = mpc512x_clk_divtable("mbx-ug", "mbx-bus-ug", +> + &clkregs->scfr1, 14, 3, > + divtab_1234); -> + clks[MPC512x_CLK_MBX_3D_UG] =3D mpc512x_clk_factor("mbx-3d-ug", "= -mbx-ug", +> + clks[MPC512x_CLK_MBX_3D_UG] = mpc512x_clk_factor("mbx-3d-ug", "mbx-ug", > + 1, 1); -> + clks[MPC512x_CLK_PCI_UG] =3D mpc512x_clk_divtable("pci-ug", "csb", -> + &clkregs->scfr1, = -20, 3, +> + clks[MPC512x_CLK_PCI_UG] = mpc512x_clk_divtable("pci-ug", "csb", +> + &clkregs->scfr1, 20, 3, > + divtab_2346); -> + clks[MPC512x_CLK_NFC_UG] =3D mpc512x_clk_divtable("nfc-ug", "ips", -> + &clkregs->scfr1, = -8, 3, +> + clks[MPC512x_CLK_NFC_UG] = mpc512x_clk_divtable("nfc-ug", "ips", +> + &clkregs->scfr1, 8, 3, > + divtab_1234); -> + clks[MPC512x_CLK_LPC_UG] =3D mpc512x_clk_divtable("lpc-ug", "ips", -> + &clkregs->scfr1, = -11, 3, +> + clks[MPC512x_CLK_LPC_UG] = mpc512x_clk_divtable("lpc-ug", "ips", +> + &clkregs->scfr1, 11, 3, > + divtab_1234); > + -> + clks[MPC512x_CLK_LPC] =3D mpc512x_clk_gated("lpc", "lpc-ug", +> + clks[MPC512x_CLK_LPC] = mpc512x_clk_gated("lpc", "lpc-ug", > + &clkregs->sccr1, 30); -> + clks[MPC512x_CLK_NFC] =3D mpc512x_clk_gated("nfc", "nfc-ug", +> + clks[MPC512x_CLK_NFC] = mpc512x_clk_gated("nfc", "nfc-ug", > + &clkregs->sccr1, 29); -> + clks[MPC512x_CLK_PATA] =3D mpc512x_clk_gated("pata", "ips", +> + clks[MPC512x_CLK_PATA] = mpc512x_clk_gated("pata", "ips", > + &clkregs->sccr1, 28); > + mpc512x_clk_setup_mclks(mclk_psc_data, ARRAY_SIZE(mclk_psc_data)); -> + clks[MPC512x_CLK_PSC_FIFO] =3D mpc512x_clk_gated("psc-fifo", "ips= -", -> + &clkregs->sccr1, 1= -5); -> + clks[MPC512x_CLK_SATA] =3D mpc512x_clk_gated("sata", "ips", +> + clks[MPC512x_CLK_PSC_FIFO] = mpc512x_clk_gated("psc-fifo", "ips", +> + &clkregs->sccr1, 15); +> + clks[MPC512x_CLK_SATA] = mpc512x_clk_gated("sata", "ips", > + &clkregs->sccr1, 14); -> + clks[MPC512x_CLK_FEC] =3D mpc512x_clk_gated("fec", "ips", +> + clks[MPC512x_CLK_FEC] = mpc512x_clk_gated("fec", "ips", > + &clkregs->sccr1, 13); -> + clks[MPC512x_CLK_PCI] =3D mpc512x_clk_gated("pci", "pci-ug", +> + clks[MPC512x_CLK_PCI] = mpc512x_clk_gated("pci", "pci-ug", > + &clkregs->sccr1, 11); -> + clks[MPC512x_CLK_DDR] =3D mpc512x_clk_gated("ddr", "ddr-ug", +> + clks[MPC512x_CLK_DDR] = mpc512x_clk_gated("ddr", "ddr-ug", > + &clkregs->sccr1, 10); > + -> + clks[MPC512x_CLK_DIU] =3D mpc512x_clk_gated("diu", "diu-ug", +> + clks[MPC512x_CLK_DIU] = mpc512x_clk_gated("diu", "diu-ug", > + &clkregs->sccr2, 31); -> + clks[MPC512x_CLK_AXE] =3D mpc512x_clk_gated("axe", "csb", +> + clks[MPC512x_CLK_AXE] = mpc512x_clk_gated("axe", "csb", > + &clkregs->sccr2, 30); -> + clks[MPC512x_CLK_MEM] =3D mpc512x_clk_gated("mem", "ips", +> + clks[MPC512x_CLK_MEM] = mpc512x_clk_gated("mem", "ips", > + &clkregs->sccr2, 29); -> + clks[MPC512x_CLK_USB1] =3D mpc512x_clk_gated("usb1", "csb", +> + clks[MPC512x_CLK_USB1] = mpc512x_clk_gated("usb1", "csb", > + &clkregs->sccr2, 28); -> + clks[MPC512x_CLK_USB2] =3D mpc512x_clk_gated("usb2", "csb", +> + clks[MPC512x_CLK_USB2] = mpc512x_clk_gated("usb2", "csb", > + &clkregs->sccr2, 27); -> + clks[MPC512x_CLK_I2C] =3D mpc512x_clk_gated("i2c", "ips", +> + clks[MPC512x_CLK_I2C] = mpc512x_clk_gated("i2c", "ips", > + &clkregs->sccr2, 26); -> + mpc512x_clk_setup_mclks(mclk_mscan_data, ARRAY_SIZE(mclk_mscan_da= -ta)); -> + clks[MPC512x_CLK_SDHC] =3D mpc512x_clk_gated("sdhc", "sdhc-ug", +> + mpc512x_clk_setup_mclks(mclk_mscan_data, ARRAY_SIZE(mclk_mscan_data)); +> + clks[MPC512x_CLK_SDHC] = mpc512x_clk_gated("sdhc", "sdhc-ug", > + &clkregs->sccr2, 24); -> + mpc512x_clk_setup_mclks(mclk_spdif_data, ARRAY_SIZE(mclk_spdif_da= -ta)); -> + clks[MPC512x_CLK_MBX_BUS] =3D mpc512x_clk_gated("mbx-bus", "mbx-b= -us-ug", -> + &clkregs->sccr2, 22= -); -> + clks[MPC512x_CLK_MBX] =3D mpc512x_clk_gated("mbx", "mbx-ug", +> + mpc512x_clk_setup_mclks(mclk_spdif_data, ARRAY_SIZE(mclk_spdif_data)); +> + clks[MPC512x_CLK_MBX_BUS] = mpc512x_clk_gated("mbx-bus", "mbx-bus-ug", +> + &clkregs->sccr2, 22); +> + clks[MPC512x_CLK_MBX] = mpc512x_clk_gated("mbx", "mbx-ug", > + &clkregs->sccr2, 21); -> + clks[MPC512x_CLK_MBX_3D] =3D mpc512x_clk_gated("mbx-3d", "mbx-3d-= -ug", +> + clks[MPC512x_CLK_MBX_3D] = mpc512x_clk_gated("mbx-3d", "mbx-3d-ug", > + &clkregs->sccr2, 20); -> + clks[MPC512x_CLK_IIM] =3D mpc512x_clk_gated("iim", "csb", +> + clks[MPC512x_CLK_IIM] = mpc512x_clk_gated("iim", "csb", > + &clkregs->sccr2, 19); -> + clks[MPC512x_CLK_VIU] =3D mpc512x_clk_gated("viu", "csb", +> + clks[MPC512x_CLK_VIU] = mpc512x_clk_gated("viu", "csb", > + &clkregs->sccr2, 18); -> + clks[MPC512x_CLK_SDHC_2] =3D mpc512x_clk_gated("sdhc-2", "sdhc-ug= -", +> + clks[MPC512x_CLK_SDHC_2] = mpc512x_clk_gated("sdhc-2", "sdhc-ug", > + &clkregs->sccr2, 17); > + > + /* > + * externally provided clocks (when implemented in hardware, > + * device tree may specify values which otherwise were unknown) > + */ -> + freq =3D get_freq_from_dt("psc_mclk_in"); +> + freq = get_freq_from_dt("psc_mclk_in"); > + if (!freq) -> + freq =3D 25000000; -> + clks[MPC512x_CLK_PSC_MCLK_IN] =3D mpc512x_clk_fixed("psc_mclk_in"= -, freq); -> + freq =3D get_freq_from_dt("spdif_tx_in"); -> + clks[MPC512x_CLK_SPDIF_TX_IN] =3D mpc512x_clk_fixed("spdif_tx_in"= -, freq); -> + freq =3D get_freq_from_dt("spdif_rx_in"); -> + clks[MPC512x_CLK_SPDIF_TX_IN] =3D mpc512x_clk_fixed("spdif_rx_in"= -, freq); +> + freq = 25000000; +> + clks[MPC512x_CLK_PSC_MCLK_IN] = mpc512x_clk_fixed("psc_mclk_in", freq); +> + freq = get_freq_from_dt("spdif_tx_in"); +> + clks[MPC512x_CLK_SPDIF_TX_IN] = mpc512x_clk_fixed("spdif_tx_in", freq); +> + freq = get_freq_from_dt("spdif_rx_in"); +> + clks[MPC512x_CLK_SPDIF_TX_IN] = mpc512x_clk_fixed("spdif_rx_in", freq); > + > + /* fixed frequency for AC97, always 24.567MHz */ -> + clks[MPC512x_CLK_AC97] =3D mpc512x_clk_fixed("ac97", 24567000); +> + clks[MPC512x_CLK_AC97] = mpc512x_clk_fixed("ac97", 24567000); > + > + /* clkdev registration for compatibility reasons */ > + clk_register_clkdev(clks[MPC512x_CLK_REF], "ref_clk", NULL); @@ -853,11 +800,11 @@ ug", > + clk_register_clkdev(clks[MPC512x_CLK_USB2], "usb2_clk", NULL); > + > + pr_debug("clock tree setup complete\n"); -> + freq =3D clk_get_rate(clks[MPC512x_CLK_E300]); +> + freq = clk_get_rate(clks[MPC512x_CLK_E300]); > + pr_debug("derived PPC freq [%d]\n", freq); -> + freq =3D clk_get_rate(clks[MPC512x_CLK_IPS]); +> + freq = clk_get_rate(clks[MPC512x_CLK_IPS]); > + pr_debug("derived IPS freq [%d]\n", freq); -> + freq =3D clk_get_rate(clks[MPC512x_CLK_LPC]); +> + freq = clk_get_rate(clks[MPC512x_CLK_LPC]); > + pr_debug("derived LPC freq [%d]\n", freq); > + > + /* enable some of the clocks here unconditionally because ... */ @@ -872,8 +819,7 @@ ug", > + /* some are required yet no dependencies were declared */ > + clk_prepare_enable(clks[MPC512x_CLK_PSC_FIFO]); > + /* some are not yet acquired by their respective drivers */ -> + clk_prepare_enable(clks[MPC512x_CLK_PSC3_MCLK]);/* serial console= - */ +> + clk_prepare_enable(clks[MPC512x_CLK_PSC3_MCLK]);/* serial console */ > + clk_prepare_enable(clks[MPC512x_CLK_FEC]); /* network, NFS */ > + clk_prepare_enable(clks[MPC512x_CLK_DIU]); /* display */ > + clk_prepare_enable(clks[MPC512x_CLK_I2C]); @@ -900,9 +846,8 @@ ug", > + */ > +static void mpc5121_clk_register_of_provider(struct device_node *np) > +{ -> + clk_data.clks =3D clks; -> + clk_data.clk_num =3D MPC512x_CLK_LAST_PUBLIC + 1; /* _not_ ARRAY_= -SIZE() */ +> + clk_data.clks = clks; +> + clk_data.clk_num = MPC512x_CLK_LAST_PUBLIC + 1; /* _not_ ARRAY_SIZE() */ > + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); > +} > + @@ -912,11 +857,10 @@ SIZE() */ > + int busfreq; > + > + /* map the clock control registers */ -> + clk_np =3D of_find_compatible_node(NULL, NULL, "fsl,mpc5121-clock= -"); +> + clk_np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-clock"); > + if (!clk_np) > + return -ENODEV; -> + clkregs =3D of_iomap(clk_np, 0); +> + clkregs = of_iomap(clk_np, 0); > + WARN_ON(!clkregs); > + > + /* invalidate all not yet registered clock slots */ @@ -932,14 +876,14 @@ SIZE() */ > + * add a dummy clock for those situations where a clock spec is > + * required yet no real clock is involved > + */ -> + clks[MPC512x_CLK_DUMMY] =3D mpc512x_clk_fixed("dummy", 0); +> + clks[MPC512x_CLK_DUMMY] = mpc512x_clk_fixed("dummy", 0); > + > + /* > + * have all the real nodes in the clock tree populated from REF > + * down to all leaves, either starting from the OSC node or from > + * a REF root that was created from the IPS bus clock input > + */ -> + busfreq =3D get_freq_from_dt("bus-frequency"); +> + busfreq = get_freq_from_dt("bus-frequency"); > + mpc512x_clk_setup_clock_tree(busfreq); > + > + /* register as an OF clock provider */ @@ -951,12 +895,10 @@ SIZE() */ > index c4f7799..7f8fc64 100644 > --- a/include/linux/clk-provider.h > +++ b/include/linux/clk-provider.h -> @@ -497,6 +497,20 @@ static inline const char *of_clk_get_parent_name(str= -uct device_node *np, +> @@ -497,6 +497,20 @@ static inline const char *of_clk_get_parent_name(struct device_node *np, > * for improved portability across platforms > */ -> = - +> > +#if IS_ENABLED(CONFIG_PPC) > + > +static inline u32 clk_readl(u32 __iomem *reg) @@ -974,16 +916,13 @@ uct device_node *np, > static inline u32 clk_readl(u32 __iomem *reg) > { > return readl(reg); -> @@ -507,5 +521,7 @@ static inline void clk_writel(u32 val, u32 __iomem *r= -eg) +> @@ -507,5 +521,7 @@ static inline void clk_writel(u32 val, u32 __iomem *reg) > writel(val, reg); > } -> = - +> > +#endif /* platform dependent I/O accessors */ > + > #endif /* CONFIG_COMMON_CLK */ > #endif /* CLK_PROVIDER_H */ -> -- = - +> -- > 1.7.10.4 diff --git a/a/content_digest b/N1/content_digest index 1ea7ba6..1e7e48f 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -1,46 +1,29 @@ "ref\01374166855-7280-1-git-send-email-gsi@denx.de\0" "ref\01374495298-22019-1-git-send-email-gsi@denx.de\0" "ref\01374495298-22019-18-git-send-email-gsi@denx.de\0" - "From\0Mike Turquette <mturquette@linaro.org>\0" - "Subject\0Re: [PATCH v3 17/31] clk: mpc512x: introduce COMMON_CLK for MPC512x\0" + "From\0mturquette@linaro.org (Mike Turquette)\0" + "Subject\0[PATCH v3 17/31] clk: mpc512x: introduce COMMON_CLK for MPC512x\0" "Date\0Fri, 02 Aug 2013 16:41:43 -0700\0" - "To\0Gerhard Sittig <gsi@denx.de>" - linuxppc-dev@lists.ozlabs.org - Anatolij Gustschin <agust@denx.de> - linux-arm-kernel@lists.infradead.org - " devicetree-discuss@lists.ozlabs.org\0" - "Cc\0Detlev Zundel <dzu@denx.de>" - Wolfram Sang <wsa@the-dreams.de> - Greg Kroah-Hartman <gregkh@linuxfoundation.org> - Gerhard Sittig <gsi@denx.de> - Rob Herring <rob.herring@calxeda.com> - Mark Brown <broonie@kernel.org> - Marc Kleine-Budde <mkl@pengutronix.de> - David Woodhouse <dwmw2@infradead.org> - Wolfgang Grandegger <wg@grandegger.com> - " Mauro Carvalho Chehab <m.chehab@samsung.com>\0" + "To\0linux-arm-kernel@lists.infradead.org\0" "\00:1\0" "b\0" "Quoting Gerhard Sittig (2013-07-22 05:14:44)\n" "> this change implements a clock driver for the MPC512x PowerPC platform\n" "> which follows the COMMON_CLK approach and uses common clock drivers\n" "> shared with other platforms\n" - "> =\n" - "\n" + "> \n" "> this driver implements the publicly announced set of clocks (which can\n" "> get referenced by means of symbolic identifiers from the dt-bindings\n" "> header file), as well as generates additional 'struct clk' items where\n" "> the SoC hardware cannot easily get mapped to the common primitives of\n" "> the clock API, or requires \"intermediate\" clock nodes to represent\n" "> clocks that have both gates and dividers\n" - "> =\n" - "\n" + "> \n" "> the previous PPC_CLOCK implementation is kept in place and remains in\n" "> parallel to the common clock implementation for test and comparison\n" "> during migration, a compile time option picks one of the two\n" "> alternatives (Kconfig switch, common clock used by default)\n" - "> =\n" - "\n" + "> \n" "> some of the clock items get pre-enabled in the clock driver to not have\n" "> them automatically disabled by the underlying clock subsystem because of\n" "> their being unused -- this approach is desirable because\n" @@ -55,8 +38,7 @@ "> infrastructure, while more appropriate support for specific hardware\n" "> constraints isn't available yet (remaining changes are strictly\n" "> internal to the clock driver and won't affect peripheral drivers)\n" - "> =\n" - "\n" + "> \n" "> clkdev registration provides \"alias names\" for few clock items\n" "> - to not break those peripheral drivers which encode their component\n" "> index into the name that is used for clock lookup (UART, SPI, USB)\n" @@ -64,8 +46,7 @@ "> were encoded in the previous PPC_CLOCK implementation (NFC, VIU, CAN)\n" "> this workaround will get removed as these drivers get adjusted after\n" "> device tree based clock lookup has become available\n" - "> =\n" - "\n" + "> \n" "> Signed-off-by: Gerhard Sittig <gsi@denx.de>\n" "\n" "Hi Gerhard,\n" @@ -80,15 +61,12 @@ "> ---\n" "> arch/powerpc/platforms/512x/Kconfig | 14 +-\n" "> arch/powerpc/platforms/512x/Makefile | 4 +-\n" - "> arch/powerpc/platforms/512x/clock-commonclk.c | 786 +++++++++++++++++++=\n" - "++++++\n" + "> arch/powerpc/platforms/512x/clock-commonclk.c | 786 +++++++++++++++++++++++++\n" "> include/linux/clk-provider.h | 16 +\n" "> 4 files changed, 818 insertions(+), 2 deletions(-)\n" "> create mode 100644 arch/powerpc/platforms/512x/clock-commonclk.c\n" - "> =\n" - "\n" - "> diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms=\n" - "/512x/Kconfig\n" + "> \n" + "> diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig\n" "> index fc9c1cb..c5fcdd0 100644\n" "> --- a/arch/powerpc/platforms/512x/Kconfig\n" "> +++ b/arch/powerpc/platforms/512x/Kconfig\n" @@ -115,8 +93,7 @@ "> select PPC_PCI_CHOICE\n" "> select FSL_PCI if PCI\n" "> select ARCH_WANT_OPTIONAL_GPIOLIB\n" - "> diff --git a/arch/powerpc/platforms/512x/Makefile b/arch/powerpc/platform=\n" - "s/512x/Makefile\n" + "> diff --git a/arch/powerpc/platforms/512x/Makefile b/arch/powerpc/platforms/512x/Makefile\n" "> index 72fb934..1e05f9d 100644\n" "> --- a/arch/powerpc/platforms/512x/Makefile\n" "> +++ b/arch/powerpc/platforms/512x/Makefile\n" @@ -124,15 +101,14 @@ "> #\n" "> # Makefile for the Freescale PowerPC 512x linux kernel.\n" "> #\n" - "> -obj-y +=3D clock.o mpc512x_shared.o\n" - "> +obj-$(CONFIG_PPC_CLOCK) +=3D clock.o\n" - "> +obj-$(CONFIG_COMMON_CLK) +=3D clock-commonclk.o\n" - "> +obj-y +=3D mpc512x_shared.o\n" - "> obj-$(CONFIG_MPC5121_ADS) +=3D mpc5121_ads.o mpc5121_ads_cpld.o\n" - "> obj-$(CONFIG_MPC512x_GENERIC) +=3D mpc512x_generic.o\n" - "> obj-$(CONFIG_PDM360NG) +=3D pdm360ng.o\n" - "> diff --git a/arch/powerpc/platforms/512x/clock-commonclk.c b/arch/powerpc=\n" - "/platforms/512x/clock-commonclk.c\n" + "> -obj-y += clock.o mpc512x_shared.o\n" + "> +obj-$(CONFIG_PPC_CLOCK) += clock.o\n" + "> +obj-$(CONFIG_COMMON_CLK) += clock-commonclk.o\n" + "> +obj-y += mpc512x_shared.o\n" + "> obj-$(CONFIG_MPC5121_ADS) += mpc5121_ads.o mpc5121_ads_cpld.o\n" + "> obj-$(CONFIG_MPC512x_GENERIC) += mpc512x_generic.o\n" + "> obj-$(CONFIG_PDM360NG) += pdm360ng.o\n" + "> diff --git a/arch/powerpc/platforms/512x/clock-commonclk.c b/arch/powerpc/platforms/512x/clock-commonclk.c\n" "> new file mode 100644\n" "> index 0000000..762ee85\n" "> --- /dev/null\n" @@ -177,11 +153,10 @@ "> +#define NR_SPDIFS 1\n" "> +#define NR_MCLKS (NR_PSCS + NR_MSCANS + NR_SPDIFS)\n" "> +\n" - "> +/* extend the public set of clocks by adding internal slots for manageme=\n" - "nt */\n" + "> +/* extend the public set of clocks by adding internal slots for management */\n" "> +enum {\n" "> + /* arrange for adjacent numbers after the public set */\n" - "> + MPC512x_CLK_START_PRIVATE =3D MPC512x_CLK_LAST_PUBLIC,\n" + "> + MPC512x_CLK_START_PRIVATE = MPC512x_CLK_LAST_PUBLIC,\n" "> + /* clocks which aren't announced to the public */\n" "> + MPC512x_CLK_DDR,\n" "> + MPC512x_CLK_MEM,\n" @@ -202,7 +177,7 @@ "> + MPC512x_CLK_SPDIF_TX_IN,\n" "> + /* intermediates for the mux+gate+div+mux MCLK generation */\n" "> + MPC512x_CLK_MCLKS_FIRST,\n" - "> + MPC512x_CLK_MCLKS_LAST =3D MPC512x_CLK_MCLKS_FIRST\n" + "> + MPC512x_CLK_MCLKS_LAST = MPC512x_CLK_MCLKS_FIRST\n" "> + + NR_MCLKS * MCLK_MAX_IDX,\n" "> + /* internal, symbolic spec for the number of slots */\n" "> + MPC512x_CLK_LAST_PRIVATE,\n" @@ -219,8 +194,7 @@ "> +/* convenience wrappers around the common clk API */\n" "> +static inline struct clk *mpc512x_clk_fixed(const char *name, int rate)\n" "> +{\n" - "> + return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rat=\n" - "e);\n" + "> + return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate);\n" "> +}\n" "> +\n" "> +static inline struct clk *mpc512x_clk_factor(\n" @@ -229,9 +203,8 @@ "> +{\n" "> + int clkflags;\n" "> +\n" - "> + clkflags =3D CLK_SET_RATE_PARENT;\n" - "> + return clk_register_fixed_factor(NULL, name, parent_name, clkflag=\n" - "s,\n" + "> + clkflags = CLK_SET_RATE_PARENT;\n" + "> + return clk_register_fixed_factor(NULL, name, parent_name, clkflags,\n" "> + mul, div);\n" "> +}\n" "> +\n" @@ -250,7 +223,7 @@ "> +{\n" "> + u8 divflags;\n" "> +\n" - "> + divflags =3D 0;\n" + "> + divflags = 0;\n" "> + return clk_register_divider_table(NULL, name, parent_name, 0,\n" "> + reg, pos, len, divflags,\n" "> + divtab, &clklock);\n" @@ -262,7 +235,7 @@ "> +{\n" "> + int clkflags;\n" "> +\n" - "> + clkflags =3D CLK_SET_RATE_PARENT;\n" + "> + clkflags = CLK_SET_RATE_PARENT;\n" "> + return clk_register_gate(NULL, name, parent_name, clkflags,\n" "> + reg, pos, 0, &clklock);\n" "> +}\n" @@ -274,35 +247,34 @@ "> + int clkflags;\n" "> + u8 muxflags;\n" "> +\n" - "> + clkflags =3D CLK_SET_RATE_PARENT;\n" - "> + muxflags =3D 0;\n" + "> + clkflags = CLK_SET_RATE_PARENT;\n" + "> + muxflags = 0;\n" "> + return clk_register_mux(NULL, name,\n" "> + parent_names, parent_count, clkflags,\n" "> + reg, pos, len, muxflags, &clklock);\n" "> +}\n" "> +\n" "> +/* helper to isolate a bit field from a register */\n" - "> +static inline int get_bit_field(uint32_t __iomem *reg, uint8_t pos, uint=\n" - "8_t len)\n" + "> +static inline int get_bit_field(uint32_t __iomem *reg, uint8_t pos, uint8_t len)\n" "> +{\n" "> + uint32_t val;\n" "> +\n" - "> + val =3D in_be32(reg);\n" - "> + val >>=3D pos;\n" - "> + val &=3D (1 << len) - 1;\n" + "> + val = in_be32(reg);\n" + "> + val >>= pos;\n" + "> + val &= (1 << len) - 1;\n" "> + return val;\n" "> +}\n" "> +\n" "> +/* get the SPMF and translate it into the \"sys pll\" multiplier */\n" "> +static int get_spmf_mult(void)\n" "> +{\n" - "> + static int spmf_to_mult[] =3D {\n" + "> + static int spmf_to_mult[] = {\n" "> + 68, 1, 12, 16, 20, 24, 28, 32,\n" "> + 36, 40, 44, 48, 52, 56, 60, 64,\n" "> + };\n" "> + int spmf;\n" "> +\n" - "> + spmf =3D get_bit_field(&clkregs->spmr, 24, 4);\n" + "> + spmf = get_bit_field(&clkregs->spmr, 24, 4);\n" "> + return spmf_to_mult[spmf];\n" "> +}\n" "> +\n" @@ -314,7 +286,7 @@ "> + */\n" "> +static int get_sys_div_x2(void)\n" "> +{\n" - "> + static int sysdiv_code_to_x2[] =3D {\n" + "> + static int sysdiv_code_to_x2[] = {\n" "> + 4, 5, 6, 7, 8, 9, 10, 14,\n" "> + 12, 16, 18, 22, 20, 24, 26, 30,\n" "> + 28, 32, 34, 38, 36, 40, 42, 46,\n" @@ -323,7 +295,7 @@ "> + };\n" "> + int divcode;\n" "> +\n" - "> + divcode =3D get_bit_field(&clkregs->scfr2, 26, 6);\n" + "> + divcode = get_bit_field(&clkregs->scfr2, 26, 6);\n" "> + return sysdiv_code_to_x2[divcode];\n" "> +}\n" "> +\n" @@ -335,12 +307,12 @@ "> + */\n" "> +static int get_cpmf_mult_x2(void)\n" "> +{\n" - "> + static int cpmf_to_mult[] =3D {\n" + "> + static int cpmf_to_mult[] = {\n" "> + 72, 2, 2, 3, 4, 5, 6, 7,\n" "> + };\n" "> + int cpmf;\n" "> +\n" - "> + cpmf =3D get_bit_field(&clkregs->spmr, 16, 4);\n" + "> + cpmf = get_bit_field(&clkregs->spmr, 16, 4);\n" "> + return cpmf_to_mult[cpmf];\n" "> +}\n" "> +\n" @@ -351,21 +323,21 @@ "> + */\n" "> +\n" "> +/* applies to the IPS_DIV, and PCI_DIV values */\n" - "> +static struct clk_div_table divtab_2346[] =3D {\n" - "> + { .val =3D 2, .div =3D 2, },\n" - "> + { .val =3D 3, .div =3D 3, },\n" - "> + { .val =3D 4, .div =3D 4, },\n" - "> + { .val =3D 6, .div =3D 6, },\n" - "> + { .div =3D 0, },\n" + "> +static struct clk_div_table divtab_2346[] = {\n" + "> + { .val = 2, .div = 2, },\n" + "> + { .val = 3, .div = 3, },\n" + "> + { .val = 4, .div = 4, },\n" + "> + { .val = 6, .div = 6, },\n" + "> + { .div = 0, },\n" "> +};\n" "> +\n" "> +/* applies to the MBX_DIV, LPC_DIV, and NFC_DIV values */\n" - "> +static struct clk_div_table divtab_1234[] =3D {\n" - "> + { .val =3D 1, .div =3D 1, },\n" - "> + { .val =3D 2, .div =3D 2, },\n" - "> + { .val =3D 3, .div =3D 3, },\n" - "> + { .val =3D 4, .div =3D 4, },\n" - "> + { .div =3D 0, },\n" + "> +static struct clk_div_table divtab_1234[] = {\n" + "> + { .val = 1, .div = 1, },\n" + "> + { .val = 2, .div = 2, },\n" + "> + { .val = 3, .div = 3, },\n" + "> + { .val = 4, .div = 4, },\n" + "> + { .div = 0, },\n" "> +};\n" "> +\n" "> +static int get_freq_from_dt(char *propname)\n" @@ -374,12 +346,12 @@ "> + const unsigned int *prop;\n" "> + int val;\n" "> +\n" - "> + val =3D 0;\n" - "> + np =3D of_find_compatible_node(NULL, NULL, \"fsl,mpc5121-immr\");\n" + "> + val = 0;\n" + "> + np = of_find_compatible_node(NULL, NULL, \"fsl,mpc5121-immr\");\n" "> + if (np) {\n" - "> + prop =3D of_get_property(np, propname, NULL);\n" + "> + prop = of_get_property(np, propname, NULL);\n" "> + if (prop)\n" - "> + val =3D *prop;\n" + "> + val = *prop;\n" "> + of_node_put(np);\n" "> + }\n" "> + return val;\n" @@ -389,8 +361,8 @@ "> +{\n" "> + size_t i;\n" "> +\n" - "> + for (i =3D 0; i < ARRAY_SIZE(clks); i++)\n" - "> + clks[i] =3D ERR_PTR(-ENODEV);\n" + "> + for (i = 0; i < ARRAY_SIZE(clks); i++)\n" + "> + clks[i] = ERR_PTR(-ENODEV);\n" "> +}\n" "> +\n" "> +/*\n" @@ -414,36 +386,32 @@ "> + int calc_freq;\n" "> +\n" "> + /* fetch mul/div factors from the hardware */\n" - "> + *sys_mul =3D get_spmf_mult();\n" - "> + *sys_mul *=3D 2; /* compensate for the fractional divide=\n" - "r */\n" - "> + *sys_div =3D get_sys_div_x2();\n" - "> + *ips_div =3D get_bit_field(&clkregs->scfr1, 23, 3);\n" + "> + *sys_mul = get_spmf_mult();\n" + "> + *sys_mul *= 2; /* compensate for the fractional divider */\n" + "> + *sys_div = get_sys_div_x2();\n" + "> + *ips_div = get_bit_field(&clkregs->scfr1, 23, 3);\n" "> +\n" "> + /* lookup the oscillator node */\n" - "> + osc_clk =3D clk_get(NULL, \"osc\");\n" + "> + osc_clk = clk_get(NULL, \"osc\");\n" "> + if (osc_clk) {\n" "> + /* descend REF directly from OSC, verify the IPS rate */\n" - "> + clks[MPC512x_CLK_REF] =3D mpc512x_clk_factor(\"ref\", \"osc\"=\n" - ", 1, 1);\n" - "> + calc_freq =3D clk_get_rate(clks[MPC512x_CLK_REF]);\n" - "> + calc_freq *=3D *sys_mul;\n" - "> + calc_freq /=3D *sys_div;\n" - "> + calc_freq /=3D 2;\n" - "> + calc_freq /=3D *ips_div;\n" - "> + if (bus_freq && calc_freq !=3D bus_freq)\n" - "> + pr_warn(\"calc rate %d !=3D OF spec %d\\n\",\n" + "> + clks[MPC512x_CLK_REF] = mpc512x_clk_factor(\"ref\", \"osc\", 1, 1);\n" + "> + calc_freq = clk_get_rate(clks[MPC512x_CLK_REF]);\n" + "> + calc_freq *= *sys_mul;\n" + "> + calc_freq /= *sys_div;\n" + "> + calc_freq /= 2;\n" + "> + calc_freq /= *ips_div;\n" + "> + if (bus_freq && calc_freq != bus_freq)\n" + "> + pr_warn(\"calc rate %d != OF spec %d\\n\",\n" "> + calc_freq, bus_freq);\n" "> + } else {\n" - "> + /* calculate OSC rate and create REF from the freq value =\n" - "*/\n" - "> + calc_freq =3D bus_freq; /* start with IPS */\n" - "> + calc_freq *=3D *ips_div; /* IPS -> CSB */\n" - "> + calc_freq *=3D 2; /* CSB -> SYS */\n" - "> + calc_freq *=3D *sys_div; /* SYS -> PLL out */\n" - "> + calc_freq /=3D *sys_mul; /* PLL out -> REF =3D=3D OSC */\n" - "> + clks[MPC512x_CLK_REF] =3D mpc512x_clk_fixed(\"ref\", calc_f=\n" - "req);\n" + "> + /* calculate OSC rate and create REF from the freq value */\n" + "> + calc_freq = bus_freq; /* start with IPS */\n" + "> + calc_freq *= *ips_div; /* IPS -> CSB */\n" + "> + calc_freq *= 2; /* CSB -> SYS */\n" + "> + calc_freq *= *sys_div; /* SYS -> PLL out */\n" + "> + calc_freq /= *sys_mul; /* PLL out -> REF == OSC */\n" + "> + clks[MPC512x_CLK_REF] = mpc512x_clk_fixed(\"ref\", calc_freq);\n" "> + }\n" "> +}\n" "> +\n" @@ -480,7 +448,7 @@ "> + * it's the very data type which <linux/clk-provider.h> expects,\n" "> + * making this declaration pass checkpatch will break compilation\n" "> + */\n" - "> +static const char *parent_names_mux0[] =3D {\n" + "> +static const char *parent_names_mux0[] = {\n" "> + \"sys\", \"ref\", \"psc-mclk-in\", \"spdif-tx\",\n" "> +};\n" "> +\n" @@ -536,7 +504,7 @@ "> + \"spdif_mclk\", \\\n" "> +}\n" "> +\n" - "> +static struct mclk_setup_data mclk_psc_data[] =3D {\n" + "> +static struct mclk_setup_data mclk_psc_data[] = {\n" "> + MCLK_SETUP_DATA_PSC(0),\n" "> + MCLK_SETUP_DATA_PSC(1),\n" "> + MCLK_SETUP_DATA_PSC(2),\n" @@ -551,14 +519,14 @@ "> + MCLK_SETUP_DATA_PSC(11),\n" "> +};\n" "> +\n" - "> +static struct mclk_setup_data mclk_mscan_data[] =3D {\n" + "> +static struct mclk_setup_data mclk_mscan_data[] = {\n" "> + MCLK_SETUP_DATA_MSCAN(0),\n" "> + MCLK_SETUP_DATA_MSCAN(1),\n" "> + MCLK_SETUP_DATA_MSCAN(2),\n" "> + MCLK_SETUP_DATA_MSCAN(3),\n" "> +};\n" "> +\n" - "> +static struct mclk_setup_data mclk_spdif_data[] =3D {\n" + "> +static struct mclk_setup_data mclk_spdif_data[] = {\n" "> + MCLK_SETUP_DATA_SPDIF,\n" "> +};\n" "> +\n" @@ -567,43 +535,41 @@ "> +{\n" "> + size_t clks_idx_pub, clks_idx_int;\n" "> + u32 __iomem *mccr_reg; /* MCLK control register (mux, en, div) */\n" - "> + u32 __iomem *sccr_reg; /* system clock control register (enable)=\n" - " */\n" + "> + u32 __iomem *sccr_reg; /* system clock control register (enable) */\n" "> + int sccr_bit;\n" "> + int div;\n" "> +\n" "> + /* derive a few parameters from the component type and index */\n" "> + switch (entry->type) {\n" "> + case MCLK_TYPE_PSC:\n" - "> + clks_idx_pub =3D MPC512x_CLK_PSC0_MCLK + entry->comp_idx;\n" - "> + clks_idx_int =3D MPC512x_CLK_MCLKS_FIRST\n" + "> + clks_idx_pub = MPC512x_CLK_PSC0_MCLK + entry->comp_idx;\n" + "> + clks_idx_int = MPC512x_CLK_MCLKS_FIRST\n" "> + + (entry->comp_idx) * MCLK_MAX_IDX;\n" - "> + mccr_reg =3D &clkregs->psc_ccr[entry->comp_idx];\n" + "> + mccr_reg = &clkregs->psc_ccr[entry->comp_idx];\n" "> + break;\n" "> + case MCLK_TYPE_MSCAN:\n" - "> + clks_idx_pub =3D MPC512x_CLK_MSCAN0_MCLK + entry->comp_id=\n" - "x;\n" - "> + clks_idx_int =3D MPC512x_CLK_MCLKS_FIRST\n" + "> + clks_idx_pub = MPC512x_CLK_MSCAN0_MCLK + entry->comp_idx;\n" + "> + clks_idx_int = MPC512x_CLK_MCLKS_FIRST\n" "> + + (NR_PSCS + entry->comp_idx) * MCLK_MAX_IDX;\n" - "> + mccr_reg =3D &clkregs->mscan_ccr[entry->comp_idx];\n" + "> + mccr_reg = &clkregs->mscan_ccr[entry->comp_idx];\n" "> + break;\n" "> + case MCLK_TYPE_SPDIF:\n" - "> + clks_idx_pub =3D MPC512x_CLK_SPDIF_MCLK;\n" - "> + clks_idx_int =3D MPC512x_CLK_MCLKS_FIRST\n" + "> + clks_idx_pub = MPC512x_CLK_SPDIF_MCLK;\n" + "> + clks_idx_int = MPC512x_CLK_MCLKS_FIRST\n" "> + + (NR_PSCS + NR_MSCANS) * MCLK_MAX_IDX;\n" - "> + mccr_reg =3D &clkregs->spccr;\n" + "> + mccr_reg = &clkregs->spccr;\n" "> + break;\n" "> + default:\n" "> + return;\n" "> + }\n" - "> + if (entry->bit_sccr1 >=3D 0) {\n" - "> + sccr_reg =3D &clkregs->sccr1;\n" - "> + sccr_bit =3D entry->bit_sccr1;\n" - "> + } else if (entry->bit_sccr2 >=3D 0) {\n" - "> + sccr_reg =3D &clkregs->sccr2;\n" - "> + sccr_bit =3D entry->bit_sccr2;\n" + "> + if (entry->bit_sccr1 >= 0) {\n" + "> + sccr_reg = &clkregs->sccr1;\n" + "> + sccr_bit = entry->bit_sccr1;\n" + "> + } else if (entry->bit_sccr2 >= 0) {\n" + "> + sccr_reg = &clkregs->sccr2;\n" + "> + sccr_bit = entry->bit_sccr2;\n" "> + } else {\n" - "> + sccr_reg =3D NULL;\n" + "> + sccr_reg = NULL;\n" "> + }\n" "> +\n" "> + /*\n" @@ -612,8 +578,8 @@ "> + * during setup (that's a documented hardware requirement)\n" "> + *\n" "> + * the PPC_CLOCK implementation might even have violated the\n" - "> + * \"MCLK <=3D IPS\" constraint, the fixed divider value of 1\n" - "> + * results in a divider of 2 and thus MCLK =3D SYS/2 which equals\n" + "> + * \"MCLK <= IPS\" constraint, the fixed divider value of 1\n" + "> + * results in a divider of 2 and thus MCLK = SYS/2 which equals\n" "> + * CSB which is greater than IPS; the serial port setup may have\n" "> + * adjusted the divider which the clock setup might have left in\n" "> + * an undesirable state\n" @@ -624,8 +590,8 @@ "> + * - MCLK 0 enabled\n" "> + * - MCLK 1 from MCLK DIV\n" "> + */\n" - "> + div =3D clk_get_rate(clks[MPC512x_CLK_SYS]);\n" - "> + div /=3D clk_get_rate(clks[MPC512x_CLK_IPS]);\n" + "> + div = clk_get_rate(clks[MPC512x_CLK_SYS]);\n" + "> + div /= clk_get_rate(clks[MPC512x_CLK_IPS]);\n" "> + out_be32(mccr_reg, (0 << 16));\n" "> + out_be32(mccr_reg, (0 << 16) | ((div - 1) << 17));\n" "> + out_be32(mccr_reg, (1 << 16) | ((div - 1) << 17));\n" @@ -648,36 +614,34 @@ "> + * clock items even for those muxers which actually are NOPs\n" "> + * (those with two inputs of which one is reserved)\n" "> + */\n" - "> + clks[clks_idx_int + MCLK_IDX_MUX0] =3D mpc512x_clk_muxed(\n" + "> + clks[clks_idx_int + MCLK_IDX_MUX0] = mpc512x_clk_muxed(\n" "> + entry->name_mux0,\n" - "> + &parent_names_mux0[0], ARRAY_SIZE(parent_names_mu=\n" - "x0),\n" + "> + &parent_names_mux0[0], ARRAY_SIZE(parent_names_mux0),\n" "> + mccr_reg, 14, 2);\n" - "> + clks[clks_idx_int + MCLK_IDX_EN0] =3D mpc512x_clk_gated(\n" + "> + clks[clks_idx_int + MCLK_IDX_EN0] = mpc512x_clk_gated(\n" "> + entry->name_en0, entry->name_mux0,\n" "> + mccr_reg, 16);\n" - "> + clks[clks_idx_int + MCLK_IDX_DIV0] =3D mpc512x_clk_divider(\n" + "> + clks[clks_idx_int + MCLK_IDX_DIV0] = mpc512x_clk_divider(\n" "> + entry->name_div0,\n" "> + entry->name_en0, CLK_SET_RATE_GATE,\n" "> + mccr_reg, 17, 15, 0);\n" "> + if (entry->has_mclk1) {\n" - "> + clks[clks_idx_int + MCLK_IDX_MUX1] =3D mpc512x_clk_muxed(\n" + "> + clks[clks_idx_int + MCLK_IDX_MUX1] = mpc512x_clk_muxed(\n" "> + entry->name_mux1,\n" "> + &entry->parent_names_mux1[0],\n" "> + ARRAY_SIZE(entry->parent_names_mux1),\n" "> + mccr_reg, 7, 1);\n" "> + } else {\n" - "> + clks[clks_idx_int + MCLK_IDX_MUX1] =3D mpc512x_clk_factor(\n" - "> + entry->name_mux1, entry->parent_names_mux=\n" - "1[0],\n" + "> + clks[clks_idx_int + MCLK_IDX_MUX1] = mpc512x_clk_factor(\n" + "> + entry->name_mux1, entry->parent_names_mux1[0],\n" "> + 1, 1);\n" "> + }\n" "> + if (sccr_reg) {\n" - "> + clks[clks_idx_pub] =3D mpc512x_clk_gated(\n" + "> + clks[clks_idx_pub] = mpc512x_clk_gated(\n" "> + entry->name_mclk,\n" "> + entry->name_mux1, sccr_reg, sccr_bit);\n" "> + } else {\n" - "> + clks[clks_idx_pub] =3D mpc512x_clk_factor(\n" + "> + clks[clks_idx_pub] = mpc512x_clk_factor(\n" "> + entry->name_mclk,\n" "> + entry->name_mux1, 1, 1);\n" "> + }\n" @@ -694,8 +658,7 @@ "> + clk_register_clkdev(clks[clks_idx_pub], entry->name_mclk, NULL);\n" "> +}\n" "> +\n" - "> +static void mpc512x_clk_setup_mclks(struct mclk_setup_data *table, size_=\n" - "t count)\n" + "> +static void mpc512x_clk_setup_mclks(struct mclk_setup_data *table, size_t count)\n" "> +{\n" "> + while (count-- > 0)\n" "> + mpc512x_clk_setup_mclk(table++);\n" @@ -725,37 +688,26 @@ "> + */\n" "> +\n" "> + /* regardless of whether XTAL/OSC exists, have REF created */\n" - "> + mpc512x_clk_setup_ref_clock(busfreq, &sys_mul, &sys_div, &ips_div=\n" - ");\n" + "> + mpc512x_clk_setup_ref_clock(busfreq, &sys_mul, &sys_div, &ips_div);\n" "> +\n" "> + /* now setup the REF -> SYS -> CSB -> IPS hierarchy */\n" - "> + clks[MPC512x_CLK_SYS] =3D mpc512x_clk_factor(\"sys\", \"ref\",\n" + "> + clks[MPC512x_CLK_SYS] = mpc512x_clk_factor(\"sys\", \"ref\",\n" "> + sys_mul, sys_div);\n" - "> + clks[MPC512x_CLK_CSB] =3D mpc512x_clk_factor(\"csb\", \"sys\", 1, 2);\n" - "> + clks[MPC512x_CLK_IPS] =3D mpc512x_clk_divtable(\"ips\", \"csb\",\n" - "> + &clkregs->scfr1, 23,=\n" - " 3,\n" + "> + clks[MPC512x_CLK_CSB] = mpc512x_clk_factor(\"csb\", \"sys\", 1, 2);\n" + "> + clks[MPC512x_CLK_IPS] = mpc512x_clk_divtable(\"ips\", \"csb\",\n" + "> + &clkregs->scfr1, 23, 3,\n" "> + divtab_2346);\n" "> +\n" "> + /* now setup anything below SYS and CSB and IPS */\n" - "> + clks[MPC512x_CLK_DDR_UG] =3D mpc512x_clk_factor(\"ddr-ug\", \"sys\", =\n" - "1, 2);\n" - "> + clks[MPC512x_CLK_SDHC_x4] =3D mpc512x_clk_factor(\"sdhc-x4\", \"csb\"=\n" - ", 4, 1);\n" - "> + clks[MPC512x_CLK_SDHC_UG] =3D mpc512x_clk_divider(\"sdhc-ug\", \"sdh=\n" - "c-x4\", 0,\n" - "> + &clkregs->scfr2, =\n" - "0, 8,\n" - "> + CLK_DIVIDER_ONE_B=\n" - "ASED);\n" - "> + clks[MPC512x_CLK_DIU_x4] =3D mpc512x_clk_factor(\"diu-x4\", \"csb\", =\n" - "4, 1);\n" - "> + clks[MPC512x_CLK_DIU_UG] =3D mpc512x_clk_divider(\"diu-ug\", \"diu-x=\n" - "4\", 0,\n" - "> + &clkregs->scfr1, 0=\n" - ", 8,\n" - "> + CLK_DIVIDER_ONE_BA=\n" - "SED);\n" + "> + clks[MPC512x_CLK_DDR_UG] = mpc512x_clk_factor(\"ddr-ug\", \"sys\", 1, 2);\n" + "> + clks[MPC512x_CLK_SDHC_x4] = mpc512x_clk_factor(\"sdhc-x4\", \"csb\", 4, 1);\n" + "> + clks[MPC512x_CLK_SDHC_UG] = mpc512x_clk_divider(\"sdhc-ug\", \"sdhc-x4\", 0,\n" + "> + &clkregs->scfr2, 0, 8,\n" + "> + CLK_DIVIDER_ONE_BASED);\n" + "> + clks[MPC512x_CLK_DIU_x4] = mpc512x_clk_factor(\"diu-x4\", \"csb\", 4, 1);\n" + "> + clks[MPC512x_CLK_DIU_UG] = mpc512x_clk_divider(\"diu-ug\", \"diu-x4\", 0,\n" + "> + &clkregs->scfr1, 0, 8,\n" + "> + CLK_DIVIDER_ONE_BASED);\n" "> +\n" "> + /*\n" "> + * the \"power architecture PLL\" was setup from data which was\n" @@ -764,108 +716,89 @@ "> + * longer adjustable, or no longer in need of adjustment), which\n" "> + * is why we don't register a PLL here but assume fixed factors\n" "> + */\n" - "> + mul =3D get_cpmf_mult_x2();\n" - "> + div =3D 2; /* compensate for the fractional factor */\n" - "> + clks[MPC512x_CLK_E300] =3D mpc512x_clk_factor(\"e300\", \"csb\", mul,=\n" - " div);\n" + "> + mul = get_cpmf_mult_x2();\n" + "> + div = 2; /* compensate for the fractional factor */\n" + "> + clks[MPC512x_CLK_E300] = mpc512x_clk_factor(\"e300\", \"csb\", mul, div);\n" "> +\n" - "> + clks[MPC512x_CLK_MBX_BUS_UG] =3D mpc512x_clk_factor(\"mbx-bus-ug\",=\n" - " \"csb\",\n" + "> + clks[MPC512x_CLK_MBX_BUS_UG] = mpc512x_clk_factor(\"mbx-bus-ug\", \"csb\",\n" "> + 1, 2);\n" - "> + clks[MPC512x_CLK_MBX_UG] =3D mpc512x_clk_divtable(\"mbx-ug\", \"mbx-=\n" - "bus-ug\",\n" - "> + &clkregs->scfr1, =\n" - "14, 3,\n" + "> + clks[MPC512x_CLK_MBX_UG] = mpc512x_clk_divtable(\"mbx-ug\", \"mbx-bus-ug\",\n" + "> + &clkregs->scfr1, 14, 3,\n" "> + divtab_1234);\n" - "> + clks[MPC512x_CLK_MBX_3D_UG] =3D mpc512x_clk_factor(\"mbx-3d-ug\", \"=\n" - "mbx-ug\",\n" + "> + clks[MPC512x_CLK_MBX_3D_UG] = mpc512x_clk_factor(\"mbx-3d-ug\", \"mbx-ug\",\n" "> + 1, 1);\n" - "> + clks[MPC512x_CLK_PCI_UG] =3D mpc512x_clk_divtable(\"pci-ug\", \"csb\",\n" - "> + &clkregs->scfr1, =\n" - "20, 3,\n" + "> + clks[MPC512x_CLK_PCI_UG] = mpc512x_clk_divtable(\"pci-ug\", \"csb\",\n" + "> + &clkregs->scfr1, 20, 3,\n" "> + divtab_2346);\n" - "> + clks[MPC512x_CLK_NFC_UG] =3D mpc512x_clk_divtable(\"nfc-ug\", \"ips\",\n" - "> + &clkregs->scfr1, =\n" - "8, 3,\n" + "> + clks[MPC512x_CLK_NFC_UG] = mpc512x_clk_divtable(\"nfc-ug\", \"ips\",\n" + "> + &clkregs->scfr1, 8, 3,\n" "> + divtab_1234);\n" - "> + clks[MPC512x_CLK_LPC_UG] =3D mpc512x_clk_divtable(\"lpc-ug\", \"ips\",\n" - "> + &clkregs->scfr1, =\n" - "11, 3,\n" + "> + clks[MPC512x_CLK_LPC_UG] = mpc512x_clk_divtable(\"lpc-ug\", \"ips\",\n" + "> + &clkregs->scfr1, 11, 3,\n" "> + divtab_1234);\n" "> +\n" - "> + clks[MPC512x_CLK_LPC] =3D mpc512x_clk_gated(\"lpc\", \"lpc-ug\",\n" + "> + clks[MPC512x_CLK_LPC] = mpc512x_clk_gated(\"lpc\", \"lpc-ug\",\n" "> + &clkregs->sccr1, 30);\n" - "> + clks[MPC512x_CLK_NFC] =3D mpc512x_clk_gated(\"nfc\", \"nfc-ug\",\n" + "> + clks[MPC512x_CLK_NFC] = mpc512x_clk_gated(\"nfc\", \"nfc-ug\",\n" "> + &clkregs->sccr1, 29);\n" - "> + clks[MPC512x_CLK_PATA] =3D mpc512x_clk_gated(\"pata\", \"ips\",\n" + "> + clks[MPC512x_CLK_PATA] = mpc512x_clk_gated(\"pata\", \"ips\",\n" "> + &clkregs->sccr1, 28);\n" "> + mpc512x_clk_setup_mclks(mclk_psc_data, ARRAY_SIZE(mclk_psc_data));\n" - "> + clks[MPC512x_CLK_PSC_FIFO] =3D mpc512x_clk_gated(\"psc-fifo\", \"ips=\n" - "\",\n" - "> + &clkregs->sccr1, 1=\n" - "5);\n" - "> + clks[MPC512x_CLK_SATA] =3D mpc512x_clk_gated(\"sata\", \"ips\",\n" + "> + clks[MPC512x_CLK_PSC_FIFO] = mpc512x_clk_gated(\"psc-fifo\", \"ips\",\n" + "> + &clkregs->sccr1, 15);\n" + "> + clks[MPC512x_CLK_SATA] = mpc512x_clk_gated(\"sata\", \"ips\",\n" "> + &clkregs->sccr1, 14);\n" - "> + clks[MPC512x_CLK_FEC] =3D mpc512x_clk_gated(\"fec\", \"ips\",\n" + "> + clks[MPC512x_CLK_FEC] = mpc512x_clk_gated(\"fec\", \"ips\",\n" "> + &clkregs->sccr1, 13);\n" - "> + clks[MPC512x_CLK_PCI] =3D mpc512x_clk_gated(\"pci\", \"pci-ug\",\n" + "> + clks[MPC512x_CLK_PCI] = mpc512x_clk_gated(\"pci\", \"pci-ug\",\n" "> + &clkregs->sccr1, 11);\n" - "> + clks[MPC512x_CLK_DDR] =3D mpc512x_clk_gated(\"ddr\", \"ddr-ug\",\n" + "> + clks[MPC512x_CLK_DDR] = mpc512x_clk_gated(\"ddr\", \"ddr-ug\",\n" "> + &clkregs->sccr1, 10);\n" "> +\n" - "> + clks[MPC512x_CLK_DIU] =3D mpc512x_clk_gated(\"diu\", \"diu-ug\",\n" + "> + clks[MPC512x_CLK_DIU] = mpc512x_clk_gated(\"diu\", \"diu-ug\",\n" "> + &clkregs->sccr2, 31);\n" - "> + clks[MPC512x_CLK_AXE] =3D mpc512x_clk_gated(\"axe\", \"csb\",\n" + "> + clks[MPC512x_CLK_AXE] = mpc512x_clk_gated(\"axe\", \"csb\",\n" "> + &clkregs->sccr2, 30);\n" - "> + clks[MPC512x_CLK_MEM] =3D mpc512x_clk_gated(\"mem\", \"ips\",\n" + "> + clks[MPC512x_CLK_MEM] = mpc512x_clk_gated(\"mem\", \"ips\",\n" "> + &clkregs->sccr2, 29);\n" - "> + clks[MPC512x_CLK_USB1] =3D mpc512x_clk_gated(\"usb1\", \"csb\",\n" + "> + clks[MPC512x_CLK_USB1] = mpc512x_clk_gated(\"usb1\", \"csb\",\n" "> + &clkregs->sccr2, 28);\n" - "> + clks[MPC512x_CLK_USB2] =3D mpc512x_clk_gated(\"usb2\", \"csb\",\n" + "> + clks[MPC512x_CLK_USB2] = mpc512x_clk_gated(\"usb2\", \"csb\",\n" "> + &clkregs->sccr2, 27);\n" - "> + clks[MPC512x_CLK_I2C] =3D mpc512x_clk_gated(\"i2c\", \"ips\",\n" + "> + clks[MPC512x_CLK_I2C] = mpc512x_clk_gated(\"i2c\", \"ips\",\n" "> + &clkregs->sccr2, 26);\n" - "> + mpc512x_clk_setup_mclks(mclk_mscan_data, ARRAY_SIZE(mclk_mscan_da=\n" - "ta));\n" - "> + clks[MPC512x_CLK_SDHC] =3D mpc512x_clk_gated(\"sdhc\", \"sdhc-ug\",\n" + "> + mpc512x_clk_setup_mclks(mclk_mscan_data, ARRAY_SIZE(mclk_mscan_data));\n" + "> + clks[MPC512x_CLK_SDHC] = mpc512x_clk_gated(\"sdhc\", \"sdhc-ug\",\n" "> + &clkregs->sccr2, 24);\n" - "> + mpc512x_clk_setup_mclks(mclk_spdif_data, ARRAY_SIZE(mclk_spdif_da=\n" - "ta));\n" - "> + clks[MPC512x_CLK_MBX_BUS] =3D mpc512x_clk_gated(\"mbx-bus\", \"mbx-b=\n" - "us-ug\",\n" - "> + &clkregs->sccr2, 22=\n" - ");\n" - "> + clks[MPC512x_CLK_MBX] =3D mpc512x_clk_gated(\"mbx\", \"mbx-ug\",\n" + "> + mpc512x_clk_setup_mclks(mclk_spdif_data, ARRAY_SIZE(mclk_spdif_data));\n" + "> + clks[MPC512x_CLK_MBX_BUS] = mpc512x_clk_gated(\"mbx-bus\", \"mbx-bus-ug\",\n" + "> + &clkregs->sccr2, 22);\n" + "> + clks[MPC512x_CLK_MBX] = mpc512x_clk_gated(\"mbx\", \"mbx-ug\",\n" "> + &clkregs->sccr2, 21);\n" - "> + clks[MPC512x_CLK_MBX_3D] =3D mpc512x_clk_gated(\"mbx-3d\", \"mbx-3d-=\n" - "ug\",\n" + "> + clks[MPC512x_CLK_MBX_3D] = mpc512x_clk_gated(\"mbx-3d\", \"mbx-3d-ug\",\n" "> + &clkregs->sccr2, 20);\n" - "> + clks[MPC512x_CLK_IIM] =3D mpc512x_clk_gated(\"iim\", \"csb\",\n" + "> + clks[MPC512x_CLK_IIM] = mpc512x_clk_gated(\"iim\", \"csb\",\n" "> + &clkregs->sccr2, 19);\n" - "> + clks[MPC512x_CLK_VIU] =3D mpc512x_clk_gated(\"viu\", \"csb\",\n" + "> + clks[MPC512x_CLK_VIU] = mpc512x_clk_gated(\"viu\", \"csb\",\n" "> + &clkregs->sccr2, 18);\n" - "> + clks[MPC512x_CLK_SDHC_2] =3D mpc512x_clk_gated(\"sdhc-2\", \"sdhc-ug=\n" - "\",\n" + "> + clks[MPC512x_CLK_SDHC_2] = mpc512x_clk_gated(\"sdhc-2\", \"sdhc-ug\",\n" "> + &clkregs->sccr2, 17);\n" "> +\n" "> + /*\n" "> + * externally provided clocks (when implemented in hardware,\n" "> + * device tree may specify values which otherwise were unknown)\n" "> + */\n" - "> + freq =3D get_freq_from_dt(\"psc_mclk_in\");\n" + "> + freq = get_freq_from_dt(\"psc_mclk_in\");\n" "> + if (!freq)\n" - "> + freq =3D 25000000;\n" - "> + clks[MPC512x_CLK_PSC_MCLK_IN] =3D mpc512x_clk_fixed(\"psc_mclk_in\"=\n" - ", freq);\n" - "> + freq =3D get_freq_from_dt(\"spdif_tx_in\");\n" - "> + clks[MPC512x_CLK_SPDIF_TX_IN] =3D mpc512x_clk_fixed(\"spdif_tx_in\"=\n" - ", freq);\n" - "> + freq =3D get_freq_from_dt(\"spdif_rx_in\");\n" - "> + clks[MPC512x_CLK_SPDIF_TX_IN] =3D mpc512x_clk_fixed(\"spdif_rx_in\"=\n" - ", freq);\n" + "> + freq = 25000000;\n" + "> + clks[MPC512x_CLK_PSC_MCLK_IN] = mpc512x_clk_fixed(\"psc_mclk_in\", freq);\n" + "> + freq = get_freq_from_dt(\"spdif_tx_in\");\n" + "> + clks[MPC512x_CLK_SPDIF_TX_IN] = mpc512x_clk_fixed(\"spdif_tx_in\", freq);\n" + "> + freq = get_freq_from_dt(\"spdif_rx_in\");\n" + "> + clks[MPC512x_CLK_SPDIF_TX_IN] = mpc512x_clk_fixed(\"spdif_rx_in\", freq);\n" "> +\n" "> + /* fixed frequency for AC97, always 24.567MHz */\n" - "> + clks[MPC512x_CLK_AC97] =3D mpc512x_clk_fixed(\"ac97\", 24567000);\n" + "> + clks[MPC512x_CLK_AC97] = mpc512x_clk_fixed(\"ac97\", 24567000);\n" "> +\n" "> + /* clkdev registration for compatibility reasons */\n" "> + clk_register_clkdev(clks[MPC512x_CLK_REF], \"ref_clk\", NULL);\n" @@ -876,11 +809,11 @@ "> + clk_register_clkdev(clks[MPC512x_CLK_USB2], \"usb2_clk\", NULL);\n" "> +\n" "> + pr_debug(\"clock tree setup complete\\n\");\n" - "> + freq =3D clk_get_rate(clks[MPC512x_CLK_E300]);\n" + "> + freq = clk_get_rate(clks[MPC512x_CLK_E300]);\n" "> + pr_debug(\"derived PPC freq [%d]\\n\", freq);\n" - "> + freq =3D clk_get_rate(clks[MPC512x_CLK_IPS]);\n" + "> + freq = clk_get_rate(clks[MPC512x_CLK_IPS]);\n" "> + pr_debug(\"derived IPS freq [%d]\\n\", freq);\n" - "> + freq =3D clk_get_rate(clks[MPC512x_CLK_LPC]);\n" + "> + freq = clk_get_rate(clks[MPC512x_CLK_LPC]);\n" "> + pr_debug(\"derived LPC freq [%d]\\n\", freq);\n" "> +\n" "> + /* enable some of the clocks here unconditionally because ... */\n" @@ -895,8 +828,7 @@ "> + /* some are required yet no dependencies were declared */\n" "> + clk_prepare_enable(clks[MPC512x_CLK_PSC_FIFO]);\n" "> + /* some are not yet acquired by their respective drivers */\n" - "> + clk_prepare_enable(clks[MPC512x_CLK_PSC3_MCLK]);/* serial console=\n" - " */\n" + "> + clk_prepare_enable(clks[MPC512x_CLK_PSC3_MCLK]);/* serial console */\n" "> + clk_prepare_enable(clks[MPC512x_CLK_FEC]); /* network, NFS */\n" "> + clk_prepare_enable(clks[MPC512x_CLK_DIU]); /* display */\n" "> + clk_prepare_enable(clks[MPC512x_CLK_I2C]);\n" @@ -923,9 +855,8 @@ "> + */\n" "> +static void mpc5121_clk_register_of_provider(struct device_node *np)\n" "> +{\n" - "> + clk_data.clks =3D clks;\n" - "> + clk_data.clk_num =3D MPC512x_CLK_LAST_PUBLIC + 1; /* _not_ ARRAY_=\n" - "SIZE() */\n" + "> + clk_data.clks = clks;\n" + "> + clk_data.clk_num = MPC512x_CLK_LAST_PUBLIC + 1; /* _not_ ARRAY_SIZE() */\n" "> + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);\n" "> +}\n" "> +\n" @@ -935,11 +866,10 @@ "> + int busfreq;\n" "> +\n" "> + /* map the clock control registers */\n" - "> + clk_np =3D of_find_compatible_node(NULL, NULL, \"fsl,mpc5121-clock=\n" - "\");\n" + "> + clk_np = of_find_compatible_node(NULL, NULL, \"fsl,mpc5121-clock\");\n" "> + if (!clk_np)\n" "> + return -ENODEV;\n" - "> + clkregs =3D of_iomap(clk_np, 0);\n" + "> + clkregs = of_iomap(clk_np, 0);\n" "> + WARN_ON(!clkregs);\n" "> +\n" "> + /* invalidate all not yet registered clock slots */\n" @@ -955,14 +885,14 @@ "> + * add a dummy clock for those situations where a clock spec is\n" "> + * required yet no real clock is involved\n" "> + */\n" - "> + clks[MPC512x_CLK_DUMMY] =3D mpc512x_clk_fixed(\"dummy\", 0);\n" + "> + clks[MPC512x_CLK_DUMMY] = mpc512x_clk_fixed(\"dummy\", 0);\n" "> +\n" "> + /*\n" "> + * have all the real nodes in the clock tree populated from REF\n" "> + * down to all leaves, either starting from the OSC node or from\n" "> + * a REF root that was created from the IPS bus clock input\n" "> + */\n" - "> + busfreq =3D get_freq_from_dt(\"bus-frequency\");\n" + "> + busfreq = get_freq_from_dt(\"bus-frequency\");\n" "> + mpc512x_clk_setup_clock_tree(busfreq);\n" "> +\n" "> + /* register as an OF clock provider */\n" @@ -974,12 +904,10 @@ "> index c4f7799..7f8fc64 100644\n" "> --- a/include/linux/clk-provider.h\n" "> +++ b/include/linux/clk-provider.h\n" - "> @@ -497,6 +497,20 @@ static inline const char *of_clk_get_parent_name(str=\n" - "uct device_node *np,\n" + "> @@ -497,6 +497,20 @@ static inline const char *of_clk_get_parent_name(struct device_node *np,\n" "> * for improved portability across platforms\n" "> */\n" - "> =\n" - "\n" + "> \n" "> +#if IS_ENABLED(CONFIG_PPC)\n" "> +\n" "> +static inline u32 clk_readl(u32 __iomem *reg)\n" @@ -997,18 +925,15 @@ "> static inline u32 clk_readl(u32 __iomem *reg)\n" "> {\n" "> return readl(reg);\n" - "> @@ -507,5 +521,7 @@ static inline void clk_writel(u32 val, u32 __iomem *r=\n" - "eg)\n" + "> @@ -507,5 +521,7 @@ static inline void clk_writel(u32 val, u32 __iomem *reg)\n" "> writel(val, reg);\n" "> }\n" - "> =\n" - "\n" + "> \n" "> +#endif /* platform dependent I/O accessors */\n" "> +\n" "> #endif /* CONFIG_COMMON_CLK */\n" "> #endif /* CLK_PROVIDER_H */\n" - "> -- =\n" - "\n" + "> -- \n" > 1.7.10.4 -0239e9b524e5dd773341f61d998017d552b7527f9815e67de14a18ee03a44213 +562b329b2fff4d4464b5fcecdd99fe111433314b73a3322a38f5d495d422140f
diff --git a/a/1.txt b/N2/1.txt index dd7aa59..9482e2d 100644 --- a/a/1.txt +++ b/N2/1.txt @@ -2,22 +2,19 @@ Quoting Gerhard Sittig (2013-07-22 05:14:44) > this change implements a clock driver for the MPC512x PowerPC platform > which follows the COMMON_CLK approach and uses common clock drivers > shared with other platforms -> = - +> > this driver implements the publicly announced set of clocks (which can > get referenced by means of symbolic identifiers from the dt-bindings > header file), as well as generates additional 'struct clk' items where > the SoC hardware cannot easily get mapped to the common primitives of > the clock API, or requires "intermediate" clock nodes to represent > clocks that have both gates and dividers -> = - +> > the previous PPC_CLOCK implementation is kept in place and remains in > parallel to the common clock implementation for test and comparison > during migration, a compile time option picks one of the two > alternatives (Kconfig switch, common clock used by default) -> = - +> > some of the clock items get pre-enabled in the clock driver to not have > them automatically disabled by the underlying clock subsystem because of > their being unused -- this approach is desirable because @@ -32,8 +29,7 @@ Quoting Gerhard Sittig (2013-07-22 05:14:44) > infrastructure, while more appropriate support for specific hardware > constraints isn't available yet (remaining changes are strictly > internal to the clock driver and won't affect peripheral drivers) -> = - +> > clkdev registration provides "alias names" for few clock items > - to not break those peripheral drivers which encode their component > index into the name that is used for clock lookup (UART, SPI, USB) @@ -41,8 +37,7 @@ Quoting Gerhard Sittig (2013-07-22 05:14:44) > were encoded in the previous PPC_CLOCK implementation (NFC, VIU, CAN) > this workaround will get removed as these drivers get adjusted after > device tree based clock lookup has become available -> = - +> > Signed-off-by: Gerhard Sittig <gsi@denx.de> Hi Gerhard, @@ -57,15 +52,12 @@ Mike > --- > arch/powerpc/platforms/512x/Kconfig | 14 +- > arch/powerpc/platforms/512x/Makefile | 4 +- -> arch/powerpc/platforms/512x/clock-commonclk.c | 786 +++++++++++++++++++= -++++++ +> arch/powerpc/platforms/512x/clock-commonclk.c | 786 +++++++++++++++++++++++++ > include/linux/clk-provider.h | 16 + > 4 files changed, 818 insertions(+), 2 deletions(-) > create mode 100644 arch/powerpc/platforms/512x/clock-commonclk.c -> = - -> diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms= -/512x/Kconfig +> +> diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig > index fc9c1cb..c5fcdd0 100644 > --- a/arch/powerpc/platforms/512x/Kconfig > +++ b/arch/powerpc/platforms/512x/Kconfig @@ -92,8 +84,7 @@ Mike > select PPC_PCI_CHOICE > select FSL_PCI if PCI > select ARCH_WANT_OPTIONAL_GPIOLIB -> diff --git a/arch/powerpc/platforms/512x/Makefile b/arch/powerpc/platform= -s/512x/Makefile +> diff --git a/arch/powerpc/platforms/512x/Makefile b/arch/powerpc/platforms/512x/Makefile > index 72fb934..1e05f9d 100644 > --- a/arch/powerpc/platforms/512x/Makefile > +++ b/arch/powerpc/platforms/512x/Makefile @@ -101,15 +92,14 @@ s/512x/Makefile > # > # Makefile for the Freescale PowerPC 512x linux kernel. > # -> -obj-y +=3D clock.o mpc512x_shared.o -> +obj-$(CONFIG_PPC_CLOCK) +=3D clock.o -> +obj-$(CONFIG_COMMON_CLK) +=3D clock-commonclk.o -> +obj-y +=3D mpc512x_shared.o -> obj-$(CONFIG_MPC5121_ADS) +=3D mpc5121_ads.o mpc5121_ads_cpld.o -> obj-$(CONFIG_MPC512x_GENERIC) +=3D mpc512x_generic.o -> obj-$(CONFIG_PDM360NG) +=3D pdm360ng.o -> diff --git a/arch/powerpc/platforms/512x/clock-commonclk.c b/arch/powerpc= -/platforms/512x/clock-commonclk.c +> -obj-y += clock.o mpc512x_shared.o +> +obj-$(CONFIG_PPC_CLOCK) += clock.o +> +obj-$(CONFIG_COMMON_CLK) += clock-commonclk.o +> +obj-y += mpc512x_shared.o +> obj-$(CONFIG_MPC5121_ADS) += mpc5121_ads.o mpc5121_ads_cpld.o +> obj-$(CONFIG_MPC512x_GENERIC) += mpc512x_generic.o +> obj-$(CONFIG_PDM360NG) += pdm360ng.o +> diff --git a/arch/powerpc/platforms/512x/clock-commonclk.c b/arch/powerpc/platforms/512x/clock-commonclk.c > new file mode 100644 > index 0000000..762ee85 > --- /dev/null @@ -154,11 +144,10 @@ s/512x/Makefile > +#define NR_SPDIFS 1 > +#define NR_MCLKS (NR_PSCS + NR_MSCANS + NR_SPDIFS) > + -> +/* extend the public set of clocks by adding internal slots for manageme= -nt */ +> +/* extend the public set of clocks by adding internal slots for management */ > +enum { > + /* arrange for adjacent numbers after the public set */ -> + MPC512x_CLK_START_PRIVATE =3D MPC512x_CLK_LAST_PUBLIC, +> + MPC512x_CLK_START_PRIVATE = MPC512x_CLK_LAST_PUBLIC, > + /* clocks which aren't announced to the public */ > + MPC512x_CLK_DDR, > + MPC512x_CLK_MEM, @@ -179,7 +168,7 @@ nt */ > + MPC512x_CLK_SPDIF_TX_IN, > + /* intermediates for the mux+gate+div+mux MCLK generation */ > + MPC512x_CLK_MCLKS_FIRST, -> + MPC512x_CLK_MCLKS_LAST =3D MPC512x_CLK_MCLKS_FIRST +> + MPC512x_CLK_MCLKS_LAST = MPC512x_CLK_MCLKS_FIRST > + + NR_MCLKS * MCLK_MAX_IDX, > + /* internal, symbolic spec for the number of slots */ > + MPC512x_CLK_LAST_PRIVATE, @@ -196,8 +185,7 @@ nt */ > +/* convenience wrappers around the common clk API */ > +static inline struct clk *mpc512x_clk_fixed(const char *name, int rate) > +{ -> + return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rat= -e); +> + return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate); > +} > + > +static inline struct clk *mpc512x_clk_factor( @@ -206,9 +194,8 @@ e); > +{ > + int clkflags; > + -> + clkflags =3D CLK_SET_RATE_PARENT; -> + return clk_register_fixed_factor(NULL, name, parent_name, clkflag= -s, +> + clkflags = CLK_SET_RATE_PARENT; +> + return clk_register_fixed_factor(NULL, name, parent_name, clkflags, > + mul, div); > +} > + @@ -227,7 +214,7 @@ s, > +{ > + u8 divflags; > + -> + divflags =3D 0; +> + divflags = 0; > + return clk_register_divider_table(NULL, name, parent_name, 0, > + reg, pos, len, divflags, > + divtab, &clklock); @@ -239,7 +226,7 @@ s, > +{ > + int clkflags; > + -> + clkflags =3D CLK_SET_RATE_PARENT; +> + clkflags = CLK_SET_RATE_PARENT; > + return clk_register_gate(NULL, name, parent_name, clkflags, > + reg, pos, 0, &clklock); > +} @@ -251,35 +238,34 @@ s, > + int clkflags; > + u8 muxflags; > + -> + clkflags =3D CLK_SET_RATE_PARENT; -> + muxflags =3D 0; +> + clkflags = CLK_SET_RATE_PARENT; +> + muxflags = 0; > + return clk_register_mux(NULL, name, > + parent_names, parent_count, clkflags, > + reg, pos, len, muxflags, &clklock); > +} > + > +/* helper to isolate a bit field from a register */ -> +static inline int get_bit_field(uint32_t __iomem *reg, uint8_t pos, uint= -8_t len) +> +static inline int get_bit_field(uint32_t __iomem *reg, uint8_t pos, uint8_t len) > +{ > + uint32_t val; > + -> + val =3D in_be32(reg); -> + val >>=3D pos; -> + val &=3D (1 << len) - 1; +> + val = in_be32(reg); +> + val >>= pos; +> + val &= (1 << len) - 1; > + return val; > +} > + > +/* get the SPMF and translate it into the "sys pll" multiplier */ > +static int get_spmf_mult(void) > +{ -> + static int spmf_to_mult[] =3D { +> + static int spmf_to_mult[] = { > + 68, 1, 12, 16, 20, 24, 28, 32, > + 36, 40, 44, 48, 52, 56, 60, 64, > + }; > + int spmf; > + -> + spmf =3D get_bit_field(&clkregs->spmr, 24, 4); +> + spmf = get_bit_field(&clkregs->spmr, 24, 4); > + return spmf_to_mult[spmf]; > +} > + @@ -291,7 +277,7 @@ s, > + */ > +static int get_sys_div_x2(void) > +{ -> + static int sysdiv_code_to_x2[] =3D { +> + static int sysdiv_code_to_x2[] = { > + 4, 5, 6, 7, 8, 9, 10, 14, > + 12, 16, 18, 22, 20, 24, 26, 30, > + 28, 32, 34, 38, 36, 40, 42, 46, @@ -300,7 +286,7 @@ s, > + }; > + int divcode; > + -> + divcode =3D get_bit_field(&clkregs->scfr2, 26, 6); +> + divcode = get_bit_field(&clkregs->scfr2, 26, 6); > + return sysdiv_code_to_x2[divcode]; > +} > + @@ -312,12 +298,12 @@ s, > + */ > +static int get_cpmf_mult_x2(void) > +{ -> + static int cpmf_to_mult[] =3D { +> + static int cpmf_to_mult[] = { > + 72, 2, 2, 3, 4, 5, 6, 7, > + }; > + int cpmf; > + -> + cpmf =3D get_bit_field(&clkregs->spmr, 16, 4); +> + cpmf = get_bit_field(&clkregs->spmr, 16, 4); > + return cpmf_to_mult[cpmf]; > +} > + @@ -328,21 +314,21 @@ s, > + */ > + > +/* applies to the IPS_DIV, and PCI_DIV values */ -> +static struct clk_div_table divtab_2346[] =3D { -> + { .val =3D 2, .div =3D 2, }, -> + { .val =3D 3, .div =3D 3, }, -> + { .val =3D 4, .div =3D 4, }, -> + { .val =3D 6, .div =3D 6, }, -> + { .div =3D 0, }, +> +static struct clk_div_table divtab_2346[] = { +> + { .val = 2, .div = 2, }, +> + { .val = 3, .div = 3, }, +> + { .val = 4, .div = 4, }, +> + { .val = 6, .div = 6, }, +> + { .div = 0, }, > +}; > + > +/* applies to the MBX_DIV, LPC_DIV, and NFC_DIV values */ -> +static struct clk_div_table divtab_1234[] =3D { -> + { .val =3D 1, .div =3D 1, }, -> + { .val =3D 2, .div =3D 2, }, -> + { .val =3D 3, .div =3D 3, }, -> + { .val =3D 4, .div =3D 4, }, -> + { .div =3D 0, }, +> +static struct clk_div_table divtab_1234[] = { +> + { .val = 1, .div = 1, }, +> + { .val = 2, .div = 2, }, +> + { .val = 3, .div = 3, }, +> + { .val = 4, .div = 4, }, +> + { .div = 0, }, > +}; > + > +static int get_freq_from_dt(char *propname) @@ -351,12 +337,12 @@ s, > + const unsigned int *prop; > + int val; > + -> + val =3D 0; -> + np =3D of_find_compatible_node(NULL, NULL, "fsl,mpc5121-immr"); +> + val = 0; +> + np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-immr"); > + if (np) { -> + prop =3D of_get_property(np, propname, NULL); +> + prop = of_get_property(np, propname, NULL); > + if (prop) -> + val =3D *prop; +> + val = *prop; > + of_node_put(np); > + } > + return val; @@ -366,8 +352,8 @@ s, > +{ > + size_t i; > + -> + for (i =3D 0; i < ARRAY_SIZE(clks); i++) -> + clks[i] =3D ERR_PTR(-ENODEV); +> + for (i = 0; i < ARRAY_SIZE(clks); i++) +> + clks[i] = ERR_PTR(-ENODEV); > +} > + > +/* @@ -391,36 +377,32 @@ s, > + int calc_freq; > + > + /* fetch mul/div factors from the hardware */ -> + *sys_mul =3D get_spmf_mult(); -> + *sys_mul *=3D 2; /* compensate for the fractional divide= -r */ -> + *sys_div =3D get_sys_div_x2(); -> + *ips_div =3D get_bit_field(&clkregs->scfr1, 23, 3); +> + *sys_mul = get_spmf_mult(); +> + *sys_mul *= 2; /* compensate for the fractional divider */ +> + *sys_div = get_sys_div_x2(); +> + *ips_div = get_bit_field(&clkregs->scfr1, 23, 3); > + > + /* lookup the oscillator node */ -> + osc_clk =3D clk_get(NULL, "osc"); +> + osc_clk = clk_get(NULL, "osc"); > + if (osc_clk) { > + /* descend REF directly from OSC, verify the IPS rate */ -> + clks[MPC512x_CLK_REF] =3D mpc512x_clk_factor("ref", "osc"= -, 1, 1); -> + calc_freq =3D clk_get_rate(clks[MPC512x_CLK_REF]); -> + calc_freq *=3D *sys_mul; -> + calc_freq /=3D *sys_div; -> + calc_freq /=3D 2; -> + calc_freq /=3D *ips_div; -> + if (bus_freq && calc_freq !=3D bus_freq) -> + pr_warn("calc rate %d !=3D OF spec %d\n", +> + clks[MPC512x_CLK_REF] = mpc512x_clk_factor("ref", "osc", 1, 1); +> + calc_freq = clk_get_rate(clks[MPC512x_CLK_REF]); +> + calc_freq *= *sys_mul; +> + calc_freq /= *sys_div; +> + calc_freq /= 2; +> + calc_freq /= *ips_div; +> + if (bus_freq && calc_freq != bus_freq) +> + pr_warn("calc rate %d != OF spec %d\n", > + calc_freq, bus_freq); > + } else { -> + /* calculate OSC rate and create REF from the freq value = -*/ -> + calc_freq =3D bus_freq; /* start with IPS */ -> + calc_freq *=3D *ips_div; /* IPS -> CSB */ -> + calc_freq *=3D 2; /* CSB -> SYS */ -> + calc_freq *=3D *sys_div; /* SYS -> PLL out */ -> + calc_freq /=3D *sys_mul; /* PLL out -> REF =3D=3D OSC */ -> + clks[MPC512x_CLK_REF] =3D mpc512x_clk_fixed("ref", calc_f= -req); +> + /* calculate OSC rate and create REF from the freq value */ +> + calc_freq = bus_freq; /* start with IPS */ +> + calc_freq *= *ips_div; /* IPS -> CSB */ +> + calc_freq *= 2; /* CSB -> SYS */ +> + calc_freq *= *sys_div; /* SYS -> PLL out */ +> + calc_freq /= *sys_mul; /* PLL out -> REF == OSC */ +> + clks[MPC512x_CLK_REF] = mpc512x_clk_fixed("ref", calc_freq); > + } > +} > + @@ -457,7 +439,7 @@ req); > + * it's the very data type which <linux/clk-provider.h> expects, > + * making this declaration pass checkpatch will break compilation > + */ -> +static const char *parent_names_mux0[] =3D { +> +static const char *parent_names_mux0[] = { > + "sys", "ref", "psc-mclk-in", "spdif-tx", > +}; > + @@ -513,7 +495,7 @@ req); > + "spdif_mclk", \ > +} > + -> +static struct mclk_setup_data mclk_psc_data[] =3D { +> +static struct mclk_setup_data mclk_psc_data[] = { > + MCLK_SETUP_DATA_PSC(0), > + MCLK_SETUP_DATA_PSC(1), > + MCLK_SETUP_DATA_PSC(2), @@ -528,14 +510,14 @@ req); > + MCLK_SETUP_DATA_PSC(11), > +}; > + -> +static struct mclk_setup_data mclk_mscan_data[] =3D { +> +static struct mclk_setup_data mclk_mscan_data[] = { > + MCLK_SETUP_DATA_MSCAN(0), > + MCLK_SETUP_DATA_MSCAN(1), > + MCLK_SETUP_DATA_MSCAN(2), > + MCLK_SETUP_DATA_MSCAN(3), > +}; > + -> +static struct mclk_setup_data mclk_spdif_data[] =3D { +> +static struct mclk_setup_data mclk_spdif_data[] = { > + MCLK_SETUP_DATA_SPDIF, > +}; > + @@ -544,43 +526,41 @@ req); > +{ > + size_t clks_idx_pub, clks_idx_int; > + u32 __iomem *mccr_reg; /* MCLK control register (mux, en, div) */ -> + u32 __iomem *sccr_reg; /* system clock control register (enable)= - */ +> + u32 __iomem *sccr_reg; /* system clock control register (enable) */ > + int sccr_bit; > + int div; > + > + /* derive a few parameters from the component type and index */ > + switch (entry->type) { > + case MCLK_TYPE_PSC: -> + clks_idx_pub =3D MPC512x_CLK_PSC0_MCLK + entry->comp_idx; -> + clks_idx_int =3D MPC512x_CLK_MCLKS_FIRST +> + clks_idx_pub = MPC512x_CLK_PSC0_MCLK + entry->comp_idx; +> + clks_idx_int = MPC512x_CLK_MCLKS_FIRST > + + (entry->comp_idx) * MCLK_MAX_IDX; -> + mccr_reg =3D &clkregs->psc_ccr[entry->comp_idx]; +> + mccr_reg = &clkregs->psc_ccr[entry->comp_idx]; > + break; > + case MCLK_TYPE_MSCAN: -> + clks_idx_pub =3D MPC512x_CLK_MSCAN0_MCLK + entry->comp_id= -x; -> + clks_idx_int =3D MPC512x_CLK_MCLKS_FIRST +> + clks_idx_pub = MPC512x_CLK_MSCAN0_MCLK + entry->comp_idx; +> + clks_idx_int = MPC512x_CLK_MCLKS_FIRST > + + (NR_PSCS + entry->comp_idx) * MCLK_MAX_IDX; -> + mccr_reg =3D &clkregs->mscan_ccr[entry->comp_idx]; +> + mccr_reg = &clkregs->mscan_ccr[entry->comp_idx]; > + break; > + case MCLK_TYPE_SPDIF: -> + clks_idx_pub =3D MPC512x_CLK_SPDIF_MCLK; -> + clks_idx_int =3D MPC512x_CLK_MCLKS_FIRST +> + clks_idx_pub = MPC512x_CLK_SPDIF_MCLK; +> + clks_idx_int = MPC512x_CLK_MCLKS_FIRST > + + (NR_PSCS + NR_MSCANS) * MCLK_MAX_IDX; -> + mccr_reg =3D &clkregs->spccr; +> + mccr_reg = &clkregs->spccr; > + break; > + default: > + return; > + } -> + if (entry->bit_sccr1 >=3D 0) { -> + sccr_reg =3D &clkregs->sccr1; -> + sccr_bit =3D entry->bit_sccr1; -> + } else if (entry->bit_sccr2 >=3D 0) { -> + sccr_reg =3D &clkregs->sccr2; -> + sccr_bit =3D entry->bit_sccr2; +> + if (entry->bit_sccr1 >= 0) { +> + sccr_reg = &clkregs->sccr1; +> + sccr_bit = entry->bit_sccr1; +> + } else if (entry->bit_sccr2 >= 0) { +> + sccr_reg = &clkregs->sccr2; +> + sccr_bit = entry->bit_sccr2; > + } else { -> + sccr_reg =3D NULL; +> + sccr_reg = NULL; > + } > + > + /* @@ -589,8 +569,8 @@ x; > + * during setup (that's a documented hardware requirement) > + * > + * the PPC_CLOCK implementation might even have violated the -> + * "MCLK <=3D IPS" constraint, the fixed divider value of 1 -> + * results in a divider of 2 and thus MCLK =3D SYS/2 which equals +> + * "MCLK <= IPS" constraint, the fixed divider value of 1 +> + * results in a divider of 2 and thus MCLK = SYS/2 which equals > + * CSB which is greater than IPS; the serial port setup may have > + * adjusted the divider which the clock setup might have left in > + * an undesirable state @@ -601,8 +581,8 @@ x; > + * - MCLK 0 enabled > + * - MCLK 1 from MCLK DIV > + */ -> + div =3D clk_get_rate(clks[MPC512x_CLK_SYS]); -> + div /=3D clk_get_rate(clks[MPC512x_CLK_IPS]); +> + div = clk_get_rate(clks[MPC512x_CLK_SYS]); +> + div /= clk_get_rate(clks[MPC512x_CLK_IPS]); > + out_be32(mccr_reg, (0 << 16)); > + out_be32(mccr_reg, (0 << 16) | ((div - 1) << 17)); > + out_be32(mccr_reg, (1 << 16) | ((div - 1) << 17)); @@ -625,36 +605,34 @@ x; > + * clock items even for those muxers which actually are NOPs > + * (those with two inputs of which one is reserved) > + */ -> + clks[clks_idx_int + MCLK_IDX_MUX0] =3D mpc512x_clk_muxed( +> + clks[clks_idx_int + MCLK_IDX_MUX0] = mpc512x_clk_muxed( > + entry->name_mux0, -> + &parent_names_mux0[0], ARRAY_SIZE(parent_names_mu= -x0), +> + &parent_names_mux0[0], ARRAY_SIZE(parent_names_mux0), > + mccr_reg, 14, 2); -> + clks[clks_idx_int + MCLK_IDX_EN0] =3D mpc512x_clk_gated( +> + clks[clks_idx_int + MCLK_IDX_EN0] = mpc512x_clk_gated( > + entry->name_en0, entry->name_mux0, > + mccr_reg, 16); -> + clks[clks_idx_int + MCLK_IDX_DIV0] =3D mpc512x_clk_divider( +> + clks[clks_idx_int + MCLK_IDX_DIV0] = mpc512x_clk_divider( > + entry->name_div0, > + entry->name_en0, CLK_SET_RATE_GATE, > + mccr_reg, 17, 15, 0); > + if (entry->has_mclk1) { -> + clks[clks_idx_int + MCLK_IDX_MUX1] =3D mpc512x_clk_muxed( +> + clks[clks_idx_int + MCLK_IDX_MUX1] = mpc512x_clk_muxed( > + entry->name_mux1, > + &entry->parent_names_mux1[0], > + ARRAY_SIZE(entry->parent_names_mux1), > + mccr_reg, 7, 1); > + } else { -> + clks[clks_idx_int + MCLK_IDX_MUX1] =3D mpc512x_clk_factor( -> + entry->name_mux1, entry->parent_names_mux= -1[0], +> + clks[clks_idx_int + MCLK_IDX_MUX1] = mpc512x_clk_factor( +> + entry->name_mux1, entry->parent_names_mux1[0], > + 1, 1); > + } > + if (sccr_reg) { -> + clks[clks_idx_pub] =3D mpc512x_clk_gated( +> + clks[clks_idx_pub] = mpc512x_clk_gated( > + entry->name_mclk, > + entry->name_mux1, sccr_reg, sccr_bit); > + } else { -> + clks[clks_idx_pub] =3D mpc512x_clk_factor( +> + clks[clks_idx_pub] = mpc512x_clk_factor( > + entry->name_mclk, > + entry->name_mux1, 1, 1); > + } @@ -671,8 +649,7 @@ x0), > + clk_register_clkdev(clks[clks_idx_pub], entry->name_mclk, NULL); > +} > + -> +static void mpc512x_clk_setup_mclks(struct mclk_setup_data *table, size_= -t count) +> +static void mpc512x_clk_setup_mclks(struct mclk_setup_data *table, size_t count) > +{ > + while (count-- > 0) > + mpc512x_clk_setup_mclk(table++); @@ -702,37 +679,26 @@ t count) > + */ > + > + /* regardless of whether XTAL/OSC exists, have REF created */ -> + mpc512x_clk_setup_ref_clock(busfreq, &sys_mul, &sys_div, &ips_div= -); +> + mpc512x_clk_setup_ref_clock(busfreq, &sys_mul, &sys_div, &ips_div); > + > + /* now setup the REF -> SYS -> CSB -> IPS hierarchy */ -> + clks[MPC512x_CLK_SYS] =3D mpc512x_clk_factor("sys", "ref", +> + clks[MPC512x_CLK_SYS] = mpc512x_clk_factor("sys", "ref", > + sys_mul, sys_div); -> + clks[MPC512x_CLK_CSB] =3D mpc512x_clk_factor("csb", "sys", 1, 2); -> + clks[MPC512x_CLK_IPS] =3D mpc512x_clk_divtable("ips", "csb", -> + &clkregs->scfr1, 23,= - 3, +> + clks[MPC512x_CLK_CSB] = mpc512x_clk_factor("csb", "sys", 1, 2); +> + clks[MPC512x_CLK_IPS] = mpc512x_clk_divtable("ips", "csb", +> + &clkregs->scfr1, 23, 3, > + divtab_2346); > + > + /* now setup anything below SYS and CSB and IPS */ -> + clks[MPC512x_CLK_DDR_UG] =3D mpc512x_clk_factor("ddr-ug", "sys", = -1, 2); -> + clks[MPC512x_CLK_SDHC_x4] =3D mpc512x_clk_factor("sdhc-x4", "csb"= -, 4, 1); -> + clks[MPC512x_CLK_SDHC_UG] =3D mpc512x_clk_divider("sdhc-ug", "sdh= -c-x4", 0, -> + &clkregs->scfr2, = -0, 8, -> + CLK_DIVIDER_ONE_B= -ASED); -> + clks[MPC512x_CLK_DIU_x4] =3D mpc512x_clk_factor("diu-x4", "csb", = -4, 1); -> + clks[MPC512x_CLK_DIU_UG] =3D mpc512x_clk_divider("diu-ug", "diu-x= -4", 0, -> + &clkregs->scfr1, 0= -, 8, -> + CLK_DIVIDER_ONE_BA= -SED); +> + clks[MPC512x_CLK_DDR_UG] = mpc512x_clk_factor("ddr-ug", "sys", 1, 2); +> + clks[MPC512x_CLK_SDHC_x4] = mpc512x_clk_factor("sdhc-x4", "csb", 4, 1); +> + clks[MPC512x_CLK_SDHC_UG] = mpc512x_clk_divider("sdhc-ug", "sdhc-x4", 0, +> + &clkregs->scfr2, 0, 8, +> + CLK_DIVIDER_ONE_BASED); +> + clks[MPC512x_CLK_DIU_x4] = mpc512x_clk_factor("diu-x4", "csb", 4, 1); +> + clks[MPC512x_CLK_DIU_UG] = mpc512x_clk_divider("diu-ug", "diu-x4", 0, +> + &clkregs->scfr1, 0, 8, +> + CLK_DIVIDER_ONE_BASED); > + > + /* > + * the "power architecture PLL" was setup from data which was @@ -741,108 +707,89 @@ SED); > + * longer adjustable, or no longer in need of adjustment), which > + * is why we don't register a PLL here but assume fixed factors > + */ -> + mul =3D get_cpmf_mult_x2(); -> + div =3D 2; /* compensate for the fractional factor */ -> + clks[MPC512x_CLK_E300] =3D mpc512x_clk_factor("e300", "csb", mul,= - div); +> + mul = get_cpmf_mult_x2(); +> + div = 2; /* compensate for the fractional factor */ +> + clks[MPC512x_CLK_E300] = mpc512x_clk_factor("e300", "csb", mul, div); > + -> + clks[MPC512x_CLK_MBX_BUS_UG] =3D mpc512x_clk_factor("mbx-bus-ug",= - "csb", +> + clks[MPC512x_CLK_MBX_BUS_UG] = mpc512x_clk_factor("mbx-bus-ug", "csb", > + 1, 2); -> + clks[MPC512x_CLK_MBX_UG] =3D mpc512x_clk_divtable("mbx-ug", "mbx-= -bus-ug", -> + &clkregs->scfr1, = -14, 3, +> + clks[MPC512x_CLK_MBX_UG] = mpc512x_clk_divtable("mbx-ug", "mbx-bus-ug", +> + &clkregs->scfr1, 14, 3, > + divtab_1234); -> + clks[MPC512x_CLK_MBX_3D_UG] =3D mpc512x_clk_factor("mbx-3d-ug", "= -mbx-ug", +> + clks[MPC512x_CLK_MBX_3D_UG] = mpc512x_clk_factor("mbx-3d-ug", "mbx-ug", > + 1, 1); -> + clks[MPC512x_CLK_PCI_UG] =3D mpc512x_clk_divtable("pci-ug", "csb", -> + &clkregs->scfr1, = -20, 3, +> + clks[MPC512x_CLK_PCI_UG] = mpc512x_clk_divtable("pci-ug", "csb", +> + &clkregs->scfr1, 20, 3, > + divtab_2346); -> + clks[MPC512x_CLK_NFC_UG] =3D mpc512x_clk_divtable("nfc-ug", "ips", -> + &clkregs->scfr1, = -8, 3, +> + clks[MPC512x_CLK_NFC_UG] = mpc512x_clk_divtable("nfc-ug", "ips", +> + &clkregs->scfr1, 8, 3, > + divtab_1234); -> + clks[MPC512x_CLK_LPC_UG] =3D mpc512x_clk_divtable("lpc-ug", "ips", -> + &clkregs->scfr1, = -11, 3, +> + clks[MPC512x_CLK_LPC_UG] = mpc512x_clk_divtable("lpc-ug", "ips", +> + &clkregs->scfr1, 11, 3, > + divtab_1234); > + -> + clks[MPC512x_CLK_LPC] =3D mpc512x_clk_gated("lpc", "lpc-ug", +> + clks[MPC512x_CLK_LPC] = mpc512x_clk_gated("lpc", "lpc-ug", > + &clkregs->sccr1, 30); -> + clks[MPC512x_CLK_NFC] =3D mpc512x_clk_gated("nfc", "nfc-ug", +> + clks[MPC512x_CLK_NFC] = mpc512x_clk_gated("nfc", "nfc-ug", > + &clkregs->sccr1, 29); -> + clks[MPC512x_CLK_PATA] =3D mpc512x_clk_gated("pata", "ips", +> + clks[MPC512x_CLK_PATA] = mpc512x_clk_gated("pata", "ips", > + &clkregs->sccr1, 28); > + mpc512x_clk_setup_mclks(mclk_psc_data, ARRAY_SIZE(mclk_psc_data)); -> + clks[MPC512x_CLK_PSC_FIFO] =3D mpc512x_clk_gated("psc-fifo", "ips= -", -> + &clkregs->sccr1, 1= -5); -> + clks[MPC512x_CLK_SATA] =3D mpc512x_clk_gated("sata", "ips", +> + clks[MPC512x_CLK_PSC_FIFO] = mpc512x_clk_gated("psc-fifo", "ips", +> + &clkregs->sccr1, 15); +> + clks[MPC512x_CLK_SATA] = mpc512x_clk_gated("sata", "ips", > + &clkregs->sccr1, 14); -> + clks[MPC512x_CLK_FEC] =3D mpc512x_clk_gated("fec", "ips", +> + clks[MPC512x_CLK_FEC] = mpc512x_clk_gated("fec", "ips", > + &clkregs->sccr1, 13); -> + clks[MPC512x_CLK_PCI] =3D mpc512x_clk_gated("pci", "pci-ug", +> + clks[MPC512x_CLK_PCI] = mpc512x_clk_gated("pci", "pci-ug", > + &clkregs->sccr1, 11); -> + clks[MPC512x_CLK_DDR] =3D mpc512x_clk_gated("ddr", "ddr-ug", +> + clks[MPC512x_CLK_DDR] = mpc512x_clk_gated("ddr", "ddr-ug", > + &clkregs->sccr1, 10); > + -> + clks[MPC512x_CLK_DIU] =3D mpc512x_clk_gated("diu", "diu-ug", +> + clks[MPC512x_CLK_DIU] = mpc512x_clk_gated("diu", "diu-ug", > + &clkregs->sccr2, 31); -> + clks[MPC512x_CLK_AXE] =3D mpc512x_clk_gated("axe", "csb", +> + clks[MPC512x_CLK_AXE] = mpc512x_clk_gated("axe", "csb", > + &clkregs->sccr2, 30); -> + clks[MPC512x_CLK_MEM] =3D mpc512x_clk_gated("mem", "ips", +> + clks[MPC512x_CLK_MEM] = mpc512x_clk_gated("mem", "ips", > + &clkregs->sccr2, 29); -> + clks[MPC512x_CLK_USB1] =3D mpc512x_clk_gated("usb1", "csb", +> + clks[MPC512x_CLK_USB1] = mpc512x_clk_gated("usb1", "csb", > + &clkregs->sccr2, 28); -> + clks[MPC512x_CLK_USB2] =3D mpc512x_clk_gated("usb2", "csb", +> + clks[MPC512x_CLK_USB2] = mpc512x_clk_gated("usb2", "csb", > + &clkregs->sccr2, 27); -> + clks[MPC512x_CLK_I2C] =3D mpc512x_clk_gated("i2c", "ips", +> + clks[MPC512x_CLK_I2C] = mpc512x_clk_gated("i2c", "ips", > + &clkregs->sccr2, 26); -> + mpc512x_clk_setup_mclks(mclk_mscan_data, ARRAY_SIZE(mclk_mscan_da= -ta)); -> + clks[MPC512x_CLK_SDHC] =3D mpc512x_clk_gated("sdhc", "sdhc-ug", +> + mpc512x_clk_setup_mclks(mclk_mscan_data, ARRAY_SIZE(mclk_mscan_data)); +> + clks[MPC512x_CLK_SDHC] = mpc512x_clk_gated("sdhc", "sdhc-ug", > + &clkregs->sccr2, 24); -> + mpc512x_clk_setup_mclks(mclk_spdif_data, ARRAY_SIZE(mclk_spdif_da= -ta)); -> + clks[MPC512x_CLK_MBX_BUS] =3D mpc512x_clk_gated("mbx-bus", "mbx-b= -us-ug", -> + &clkregs->sccr2, 22= -); -> + clks[MPC512x_CLK_MBX] =3D mpc512x_clk_gated("mbx", "mbx-ug", +> + mpc512x_clk_setup_mclks(mclk_spdif_data, ARRAY_SIZE(mclk_spdif_data)); +> + clks[MPC512x_CLK_MBX_BUS] = mpc512x_clk_gated("mbx-bus", "mbx-bus-ug", +> + &clkregs->sccr2, 22); +> + clks[MPC512x_CLK_MBX] = mpc512x_clk_gated("mbx", "mbx-ug", > + &clkregs->sccr2, 21); -> + clks[MPC512x_CLK_MBX_3D] =3D mpc512x_clk_gated("mbx-3d", "mbx-3d-= -ug", +> + clks[MPC512x_CLK_MBX_3D] = mpc512x_clk_gated("mbx-3d", "mbx-3d-ug", > + &clkregs->sccr2, 20); -> + clks[MPC512x_CLK_IIM] =3D mpc512x_clk_gated("iim", "csb", +> + clks[MPC512x_CLK_IIM] = mpc512x_clk_gated("iim", "csb", > + &clkregs->sccr2, 19); -> + clks[MPC512x_CLK_VIU] =3D mpc512x_clk_gated("viu", "csb", +> + clks[MPC512x_CLK_VIU] = mpc512x_clk_gated("viu", "csb", > + &clkregs->sccr2, 18); -> + clks[MPC512x_CLK_SDHC_2] =3D mpc512x_clk_gated("sdhc-2", "sdhc-ug= -", +> + clks[MPC512x_CLK_SDHC_2] = mpc512x_clk_gated("sdhc-2", "sdhc-ug", > + &clkregs->sccr2, 17); > + > + /* > + * externally provided clocks (when implemented in hardware, > + * device tree may specify values which otherwise were unknown) > + */ -> + freq =3D get_freq_from_dt("psc_mclk_in"); +> + freq = get_freq_from_dt("psc_mclk_in"); > + if (!freq) -> + freq =3D 25000000; -> + clks[MPC512x_CLK_PSC_MCLK_IN] =3D mpc512x_clk_fixed("psc_mclk_in"= -, freq); -> + freq =3D get_freq_from_dt("spdif_tx_in"); -> + clks[MPC512x_CLK_SPDIF_TX_IN] =3D mpc512x_clk_fixed("spdif_tx_in"= -, freq); -> + freq =3D get_freq_from_dt("spdif_rx_in"); -> + clks[MPC512x_CLK_SPDIF_TX_IN] =3D mpc512x_clk_fixed("spdif_rx_in"= -, freq); +> + freq = 25000000; +> + clks[MPC512x_CLK_PSC_MCLK_IN] = mpc512x_clk_fixed("psc_mclk_in", freq); +> + freq = get_freq_from_dt("spdif_tx_in"); +> + clks[MPC512x_CLK_SPDIF_TX_IN] = mpc512x_clk_fixed("spdif_tx_in", freq); +> + freq = get_freq_from_dt("spdif_rx_in"); +> + clks[MPC512x_CLK_SPDIF_TX_IN] = mpc512x_clk_fixed("spdif_rx_in", freq); > + > + /* fixed frequency for AC97, always 24.567MHz */ -> + clks[MPC512x_CLK_AC97] =3D mpc512x_clk_fixed("ac97", 24567000); +> + clks[MPC512x_CLK_AC97] = mpc512x_clk_fixed("ac97", 24567000); > + > + /* clkdev registration for compatibility reasons */ > + clk_register_clkdev(clks[MPC512x_CLK_REF], "ref_clk", NULL); @@ -853,11 +800,11 @@ ug", > + clk_register_clkdev(clks[MPC512x_CLK_USB2], "usb2_clk", NULL); > + > + pr_debug("clock tree setup complete\n"); -> + freq =3D clk_get_rate(clks[MPC512x_CLK_E300]); +> + freq = clk_get_rate(clks[MPC512x_CLK_E300]); > + pr_debug("derived PPC freq [%d]\n", freq); -> + freq =3D clk_get_rate(clks[MPC512x_CLK_IPS]); +> + freq = clk_get_rate(clks[MPC512x_CLK_IPS]); > + pr_debug("derived IPS freq [%d]\n", freq); -> + freq =3D clk_get_rate(clks[MPC512x_CLK_LPC]); +> + freq = clk_get_rate(clks[MPC512x_CLK_LPC]); > + pr_debug("derived LPC freq [%d]\n", freq); > + > + /* enable some of the clocks here unconditionally because ... */ @@ -872,8 +819,7 @@ ug", > + /* some are required yet no dependencies were declared */ > + clk_prepare_enable(clks[MPC512x_CLK_PSC_FIFO]); > + /* some are not yet acquired by their respective drivers */ -> + clk_prepare_enable(clks[MPC512x_CLK_PSC3_MCLK]);/* serial console= - */ +> + clk_prepare_enable(clks[MPC512x_CLK_PSC3_MCLK]);/* serial console */ > + clk_prepare_enable(clks[MPC512x_CLK_FEC]); /* network, NFS */ > + clk_prepare_enable(clks[MPC512x_CLK_DIU]); /* display */ > + clk_prepare_enable(clks[MPC512x_CLK_I2C]); @@ -900,9 +846,8 @@ ug", > + */ > +static void mpc5121_clk_register_of_provider(struct device_node *np) > +{ -> + clk_data.clks =3D clks; -> + clk_data.clk_num =3D MPC512x_CLK_LAST_PUBLIC + 1; /* _not_ ARRAY_= -SIZE() */ +> + clk_data.clks = clks; +> + clk_data.clk_num = MPC512x_CLK_LAST_PUBLIC + 1; /* _not_ ARRAY_SIZE() */ > + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); > +} > + @@ -912,11 +857,10 @@ SIZE() */ > + int busfreq; > + > + /* map the clock control registers */ -> + clk_np =3D of_find_compatible_node(NULL, NULL, "fsl,mpc5121-clock= -"); +> + clk_np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-clock"); > + if (!clk_np) > + return -ENODEV; -> + clkregs =3D of_iomap(clk_np, 0); +> + clkregs = of_iomap(clk_np, 0); > + WARN_ON(!clkregs); > + > + /* invalidate all not yet registered clock slots */ @@ -932,14 +876,14 @@ SIZE() */ > + * add a dummy clock for those situations where a clock spec is > + * required yet no real clock is involved > + */ -> + clks[MPC512x_CLK_DUMMY] =3D mpc512x_clk_fixed("dummy", 0); +> + clks[MPC512x_CLK_DUMMY] = mpc512x_clk_fixed("dummy", 0); > + > + /* > + * have all the real nodes in the clock tree populated from REF > + * down to all leaves, either starting from the OSC node or from > + * a REF root that was created from the IPS bus clock input > + */ -> + busfreq =3D get_freq_from_dt("bus-frequency"); +> + busfreq = get_freq_from_dt("bus-frequency"); > + mpc512x_clk_setup_clock_tree(busfreq); > + > + /* register as an OF clock provider */ @@ -951,12 +895,10 @@ SIZE() */ > index c4f7799..7f8fc64 100644 > --- a/include/linux/clk-provider.h > +++ b/include/linux/clk-provider.h -> @@ -497,6 +497,20 @@ static inline const char *of_clk_get_parent_name(str= -uct device_node *np, +> @@ -497,6 +497,20 @@ static inline const char *of_clk_get_parent_name(struct device_node *np, > * for improved portability across platforms > */ -> = - +> > +#if IS_ENABLED(CONFIG_PPC) > + > +static inline u32 clk_readl(u32 __iomem *reg) @@ -974,16 +916,13 @@ uct device_node *np, > static inline u32 clk_readl(u32 __iomem *reg) > { > return readl(reg); -> @@ -507,5 +521,7 @@ static inline void clk_writel(u32 val, u32 __iomem *r= -eg) +> @@ -507,5 +521,7 @@ static inline void clk_writel(u32 val, u32 __iomem *reg) > writel(val, reg); > } -> = - +> > +#endif /* platform dependent I/O accessors */ > + > #endif /* CONFIG_COMMON_CLK */ > #endif /* CLK_PROVIDER_H */ -> -- = - +> -- > 1.7.10.4 diff --git a/a/content_digest b/N2/content_digest index 1ea7ba6..2a10207 100644 --- a/a/content_digest +++ b/N2/content_digest @@ -4,8 +4,7 @@ "From\0Mike Turquette <mturquette@linaro.org>\0" "Subject\0Re: [PATCH v3 17/31] clk: mpc512x: introduce COMMON_CLK for MPC512x\0" "Date\0Fri, 02 Aug 2013 16:41:43 -0700\0" - "To\0Gerhard Sittig <gsi@denx.de>" - linuxppc-dev@lists.ozlabs.org + "To\0linuxppc-dev@lists.ozlabs.org" Anatolij Gustschin <agust@denx.de> linux-arm-kernel@lists.infradead.org " devicetree-discuss@lists.ozlabs.org\0" @@ -25,22 +24,19 @@ "> this change implements a clock driver for the MPC512x PowerPC platform\n" "> which follows the COMMON_CLK approach and uses common clock drivers\n" "> shared with other platforms\n" - "> =\n" - "\n" + "> \n" "> this driver implements the publicly announced set of clocks (which can\n" "> get referenced by means of symbolic identifiers from the dt-bindings\n" "> header file), as well as generates additional 'struct clk' items where\n" "> the SoC hardware cannot easily get mapped to the common primitives of\n" "> the clock API, or requires \"intermediate\" clock nodes to represent\n" "> clocks that have both gates and dividers\n" - "> =\n" - "\n" + "> \n" "> the previous PPC_CLOCK implementation is kept in place and remains in\n" "> parallel to the common clock implementation for test and comparison\n" "> during migration, a compile time option picks one of the two\n" "> alternatives (Kconfig switch, common clock used by default)\n" - "> =\n" - "\n" + "> \n" "> some of the clock items get pre-enabled in the clock driver to not have\n" "> them automatically disabled by the underlying clock subsystem because of\n" "> their being unused -- this approach is desirable because\n" @@ -55,8 +51,7 @@ "> infrastructure, while more appropriate support for specific hardware\n" "> constraints isn't available yet (remaining changes are strictly\n" "> internal to the clock driver and won't affect peripheral drivers)\n" - "> =\n" - "\n" + "> \n" "> clkdev registration provides \"alias names\" for few clock items\n" "> - to not break those peripheral drivers which encode their component\n" "> index into the name that is used for clock lookup (UART, SPI, USB)\n" @@ -64,8 +59,7 @@ "> were encoded in the previous PPC_CLOCK implementation (NFC, VIU, CAN)\n" "> this workaround will get removed as these drivers get adjusted after\n" "> device tree based clock lookup has become available\n" - "> =\n" - "\n" + "> \n" "> Signed-off-by: Gerhard Sittig <gsi@denx.de>\n" "\n" "Hi Gerhard,\n" @@ -80,15 +74,12 @@ "> ---\n" "> arch/powerpc/platforms/512x/Kconfig | 14 +-\n" "> arch/powerpc/platforms/512x/Makefile | 4 +-\n" - "> arch/powerpc/platforms/512x/clock-commonclk.c | 786 +++++++++++++++++++=\n" - "++++++\n" + "> arch/powerpc/platforms/512x/clock-commonclk.c | 786 +++++++++++++++++++++++++\n" "> include/linux/clk-provider.h | 16 +\n" "> 4 files changed, 818 insertions(+), 2 deletions(-)\n" "> create mode 100644 arch/powerpc/platforms/512x/clock-commonclk.c\n" - "> =\n" - "\n" - "> diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms=\n" - "/512x/Kconfig\n" + "> \n" + "> diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig\n" "> index fc9c1cb..c5fcdd0 100644\n" "> --- a/arch/powerpc/platforms/512x/Kconfig\n" "> +++ b/arch/powerpc/platforms/512x/Kconfig\n" @@ -115,8 +106,7 @@ "> select PPC_PCI_CHOICE\n" "> select FSL_PCI if PCI\n" "> select ARCH_WANT_OPTIONAL_GPIOLIB\n" - "> diff --git a/arch/powerpc/platforms/512x/Makefile b/arch/powerpc/platform=\n" - "s/512x/Makefile\n" + "> diff --git a/arch/powerpc/platforms/512x/Makefile b/arch/powerpc/platforms/512x/Makefile\n" "> index 72fb934..1e05f9d 100644\n" "> --- a/arch/powerpc/platforms/512x/Makefile\n" "> +++ b/arch/powerpc/platforms/512x/Makefile\n" @@ -124,15 +114,14 @@ "> #\n" "> # Makefile for the Freescale PowerPC 512x linux kernel.\n" "> #\n" - "> -obj-y +=3D clock.o mpc512x_shared.o\n" - "> +obj-$(CONFIG_PPC_CLOCK) +=3D clock.o\n" - "> +obj-$(CONFIG_COMMON_CLK) +=3D clock-commonclk.o\n" - "> +obj-y +=3D mpc512x_shared.o\n" - "> obj-$(CONFIG_MPC5121_ADS) +=3D mpc5121_ads.o mpc5121_ads_cpld.o\n" - "> obj-$(CONFIG_MPC512x_GENERIC) +=3D mpc512x_generic.o\n" - "> obj-$(CONFIG_PDM360NG) +=3D pdm360ng.o\n" - "> diff --git a/arch/powerpc/platforms/512x/clock-commonclk.c b/arch/powerpc=\n" - "/platforms/512x/clock-commonclk.c\n" + "> -obj-y += clock.o mpc512x_shared.o\n" + "> +obj-$(CONFIG_PPC_CLOCK) += clock.o\n" + "> +obj-$(CONFIG_COMMON_CLK) += clock-commonclk.o\n" + "> +obj-y += mpc512x_shared.o\n" + "> obj-$(CONFIG_MPC5121_ADS) += mpc5121_ads.o mpc5121_ads_cpld.o\n" + "> obj-$(CONFIG_MPC512x_GENERIC) += mpc512x_generic.o\n" + "> obj-$(CONFIG_PDM360NG) += pdm360ng.o\n" + "> diff --git a/arch/powerpc/platforms/512x/clock-commonclk.c b/arch/powerpc/platforms/512x/clock-commonclk.c\n" "> new file mode 100644\n" "> index 0000000..762ee85\n" "> --- /dev/null\n" @@ -177,11 +166,10 @@ "> +#define NR_SPDIFS 1\n" "> +#define NR_MCLKS (NR_PSCS + NR_MSCANS + NR_SPDIFS)\n" "> +\n" - "> +/* extend the public set of clocks by adding internal slots for manageme=\n" - "nt */\n" + "> +/* extend the public set of clocks by adding internal slots for management */\n" "> +enum {\n" "> + /* arrange for adjacent numbers after the public set */\n" - "> + MPC512x_CLK_START_PRIVATE =3D MPC512x_CLK_LAST_PUBLIC,\n" + "> + MPC512x_CLK_START_PRIVATE = MPC512x_CLK_LAST_PUBLIC,\n" "> + /* clocks which aren't announced to the public */\n" "> + MPC512x_CLK_DDR,\n" "> + MPC512x_CLK_MEM,\n" @@ -202,7 +190,7 @@ "> + MPC512x_CLK_SPDIF_TX_IN,\n" "> + /* intermediates for the mux+gate+div+mux MCLK generation */\n" "> + MPC512x_CLK_MCLKS_FIRST,\n" - "> + MPC512x_CLK_MCLKS_LAST =3D MPC512x_CLK_MCLKS_FIRST\n" + "> + MPC512x_CLK_MCLKS_LAST = MPC512x_CLK_MCLKS_FIRST\n" "> + + NR_MCLKS * MCLK_MAX_IDX,\n" "> + /* internal, symbolic spec for the number of slots */\n" "> + MPC512x_CLK_LAST_PRIVATE,\n" @@ -219,8 +207,7 @@ "> +/* convenience wrappers around the common clk API */\n" "> +static inline struct clk *mpc512x_clk_fixed(const char *name, int rate)\n" "> +{\n" - "> + return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rat=\n" - "e);\n" + "> + return clk_register_fixed_rate(NULL, name, NULL, CLK_IS_ROOT, rate);\n" "> +}\n" "> +\n" "> +static inline struct clk *mpc512x_clk_factor(\n" @@ -229,9 +216,8 @@ "> +{\n" "> + int clkflags;\n" "> +\n" - "> + clkflags =3D CLK_SET_RATE_PARENT;\n" - "> + return clk_register_fixed_factor(NULL, name, parent_name, clkflag=\n" - "s,\n" + "> + clkflags = CLK_SET_RATE_PARENT;\n" + "> + return clk_register_fixed_factor(NULL, name, parent_name, clkflags,\n" "> + mul, div);\n" "> +}\n" "> +\n" @@ -250,7 +236,7 @@ "> +{\n" "> + u8 divflags;\n" "> +\n" - "> + divflags =3D 0;\n" + "> + divflags = 0;\n" "> + return clk_register_divider_table(NULL, name, parent_name, 0,\n" "> + reg, pos, len, divflags,\n" "> + divtab, &clklock);\n" @@ -262,7 +248,7 @@ "> +{\n" "> + int clkflags;\n" "> +\n" - "> + clkflags =3D CLK_SET_RATE_PARENT;\n" + "> + clkflags = CLK_SET_RATE_PARENT;\n" "> + return clk_register_gate(NULL, name, parent_name, clkflags,\n" "> + reg, pos, 0, &clklock);\n" "> +}\n" @@ -274,35 +260,34 @@ "> + int clkflags;\n" "> + u8 muxflags;\n" "> +\n" - "> + clkflags =3D CLK_SET_RATE_PARENT;\n" - "> + muxflags =3D 0;\n" + "> + clkflags = CLK_SET_RATE_PARENT;\n" + "> + muxflags = 0;\n" "> + return clk_register_mux(NULL, name,\n" "> + parent_names, parent_count, clkflags,\n" "> + reg, pos, len, muxflags, &clklock);\n" "> +}\n" "> +\n" "> +/* helper to isolate a bit field from a register */\n" - "> +static inline int get_bit_field(uint32_t __iomem *reg, uint8_t pos, uint=\n" - "8_t len)\n" + "> +static inline int get_bit_field(uint32_t __iomem *reg, uint8_t pos, uint8_t len)\n" "> +{\n" "> + uint32_t val;\n" "> +\n" - "> + val =3D in_be32(reg);\n" - "> + val >>=3D pos;\n" - "> + val &=3D (1 << len) - 1;\n" + "> + val = in_be32(reg);\n" + "> + val >>= pos;\n" + "> + val &= (1 << len) - 1;\n" "> + return val;\n" "> +}\n" "> +\n" "> +/* get the SPMF and translate it into the \"sys pll\" multiplier */\n" "> +static int get_spmf_mult(void)\n" "> +{\n" - "> + static int spmf_to_mult[] =3D {\n" + "> + static int spmf_to_mult[] = {\n" "> + 68, 1, 12, 16, 20, 24, 28, 32,\n" "> + 36, 40, 44, 48, 52, 56, 60, 64,\n" "> + };\n" "> + int spmf;\n" "> +\n" - "> + spmf =3D get_bit_field(&clkregs->spmr, 24, 4);\n" + "> + spmf = get_bit_field(&clkregs->spmr, 24, 4);\n" "> + return spmf_to_mult[spmf];\n" "> +}\n" "> +\n" @@ -314,7 +299,7 @@ "> + */\n" "> +static int get_sys_div_x2(void)\n" "> +{\n" - "> + static int sysdiv_code_to_x2[] =3D {\n" + "> + static int sysdiv_code_to_x2[] = {\n" "> + 4, 5, 6, 7, 8, 9, 10, 14,\n" "> + 12, 16, 18, 22, 20, 24, 26, 30,\n" "> + 28, 32, 34, 38, 36, 40, 42, 46,\n" @@ -323,7 +308,7 @@ "> + };\n" "> + int divcode;\n" "> +\n" - "> + divcode =3D get_bit_field(&clkregs->scfr2, 26, 6);\n" + "> + divcode = get_bit_field(&clkregs->scfr2, 26, 6);\n" "> + return sysdiv_code_to_x2[divcode];\n" "> +}\n" "> +\n" @@ -335,12 +320,12 @@ "> + */\n" "> +static int get_cpmf_mult_x2(void)\n" "> +{\n" - "> + static int cpmf_to_mult[] =3D {\n" + "> + static int cpmf_to_mult[] = {\n" "> + 72, 2, 2, 3, 4, 5, 6, 7,\n" "> + };\n" "> + int cpmf;\n" "> +\n" - "> + cpmf =3D get_bit_field(&clkregs->spmr, 16, 4);\n" + "> + cpmf = get_bit_field(&clkregs->spmr, 16, 4);\n" "> + return cpmf_to_mult[cpmf];\n" "> +}\n" "> +\n" @@ -351,21 +336,21 @@ "> + */\n" "> +\n" "> +/* applies to the IPS_DIV, and PCI_DIV values */\n" - "> +static struct clk_div_table divtab_2346[] =3D {\n" - "> + { .val =3D 2, .div =3D 2, },\n" - "> + { .val =3D 3, .div =3D 3, },\n" - "> + { .val =3D 4, .div =3D 4, },\n" - "> + { .val =3D 6, .div =3D 6, },\n" - "> + { .div =3D 0, },\n" + "> +static struct clk_div_table divtab_2346[] = {\n" + "> + { .val = 2, .div = 2, },\n" + "> + { .val = 3, .div = 3, },\n" + "> + { .val = 4, .div = 4, },\n" + "> + { .val = 6, .div = 6, },\n" + "> + { .div = 0, },\n" "> +};\n" "> +\n" "> +/* applies to the MBX_DIV, LPC_DIV, and NFC_DIV values */\n" - "> +static struct clk_div_table divtab_1234[] =3D {\n" - "> + { .val =3D 1, .div =3D 1, },\n" - "> + { .val =3D 2, .div =3D 2, },\n" - "> + { .val =3D 3, .div =3D 3, },\n" - "> + { .val =3D 4, .div =3D 4, },\n" - "> + { .div =3D 0, },\n" + "> +static struct clk_div_table divtab_1234[] = {\n" + "> + { .val = 1, .div = 1, },\n" + "> + { .val = 2, .div = 2, },\n" + "> + { .val = 3, .div = 3, },\n" + "> + { .val = 4, .div = 4, },\n" + "> + { .div = 0, },\n" "> +};\n" "> +\n" "> +static int get_freq_from_dt(char *propname)\n" @@ -374,12 +359,12 @@ "> + const unsigned int *prop;\n" "> + int val;\n" "> +\n" - "> + val =3D 0;\n" - "> + np =3D of_find_compatible_node(NULL, NULL, \"fsl,mpc5121-immr\");\n" + "> + val = 0;\n" + "> + np = of_find_compatible_node(NULL, NULL, \"fsl,mpc5121-immr\");\n" "> + if (np) {\n" - "> + prop =3D of_get_property(np, propname, NULL);\n" + "> + prop = of_get_property(np, propname, NULL);\n" "> + if (prop)\n" - "> + val =3D *prop;\n" + "> + val = *prop;\n" "> + of_node_put(np);\n" "> + }\n" "> + return val;\n" @@ -389,8 +374,8 @@ "> +{\n" "> + size_t i;\n" "> +\n" - "> + for (i =3D 0; i < ARRAY_SIZE(clks); i++)\n" - "> + clks[i] =3D ERR_PTR(-ENODEV);\n" + "> + for (i = 0; i < ARRAY_SIZE(clks); i++)\n" + "> + clks[i] = ERR_PTR(-ENODEV);\n" "> +}\n" "> +\n" "> +/*\n" @@ -414,36 +399,32 @@ "> + int calc_freq;\n" "> +\n" "> + /* fetch mul/div factors from the hardware */\n" - "> + *sys_mul =3D get_spmf_mult();\n" - "> + *sys_mul *=3D 2; /* compensate for the fractional divide=\n" - "r */\n" - "> + *sys_div =3D get_sys_div_x2();\n" - "> + *ips_div =3D get_bit_field(&clkregs->scfr1, 23, 3);\n" + "> + *sys_mul = get_spmf_mult();\n" + "> + *sys_mul *= 2; /* compensate for the fractional divider */\n" + "> + *sys_div = get_sys_div_x2();\n" + "> + *ips_div = get_bit_field(&clkregs->scfr1, 23, 3);\n" "> +\n" "> + /* lookup the oscillator node */\n" - "> + osc_clk =3D clk_get(NULL, \"osc\");\n" + "> + osc_clk = clk_get(NULL, \"osc\");\n" "> + if (osc_clk) {\n" "> + /* descend REF directly from OSC, verify the IPS rate */\n" - "> + clks[MPC512x_CLK_REF] =3D mpc512x_clk_factor(\"ref\", \"osc\"=\n" - ", 1, 1);\n" - "> + calc_freq =3D clk_get_rate(clks[MPC512x_CLK_REF]);\n" - "> + calc_freq *=3D *sys_mul;\n" - "> + calc_freq /=3D *sys_div;\n" - "> + calc_freq /=3D 2;\n" - "> + calc_freq /=3D *ips_div;\n" - "> + if (bus_freq && calc_freq !=3D bus_freq)\n" - "> + pr_warn(\"calc rate %d !=3D OF spec %d\\n\",\n" + "> + clks[MPC512x_CLK_REF] = mpc512x_clk_factor(\"ref\", \"osc\", 1, 1);\n" + "> + calc_freq = clk_get_rate(clks[MPC512x_CLK_REF]);\n" + "> + calc_freq *= *sys_mul;\n" + "> + calc_freq /= *sys_div;\n" + "> + calc_freq /= 2;\n" + "> + calc_freq /= *ips_div;\n" + "> + if (bus_freq && calc_freq != bus_freq)\n" + "> + pr_warn(\"calc rate %d != OF spec %d\\n\",\n" "> + calc_freq, bus_freq);\n" "> + } else {\n" - "> + /* calculate OSC rate and create REF from the freq value =\n" - "*/\n" - "> + calc_freq =3D bus_freq; /* start with IPS */\n" - "> + calc_freq *=3D *ips_div; /* IPS -> CSB */\n" - "> + calc_freq *=3D 2; /* CSB -> SYS */\n" - "> + calc_freq *=3D *sys_div; /* SYS -> PLL out */\n" - "> + calc_freq /=3D *sys_mul; /* PLL out -> REF =3D=3D OSC */\n" - "> + clks[MPC512x_CLK_REF] =3D mpc512x_clk_fixed(\"ref\", calc_f=\n" - "req);\n" + "> + /* calculate OSC rate and create REF from the freq value */\n" + "> + calc_freq = bus_freq; /* start with IPS */\n" + "> + calc_freq *= *ips_div; /* IPS -> CSB */\n" + "> + calc_freq *= 2; /* CSB -> SYS */\n" + "> + calc_freq *= *sys_div; /* SYS -> PLL out */\n" + "> + calc_freq /= *sys_mul; /* PLL out -> REF == OSC */\n" + "> + clks[MPC512x_CLK_REF] = mpc512x_clk_fixed(\"ref\", calc_freq);\n" "> + }\n" "> +}\n" "> +\n" @@ -480,7 +461,7 @@ "> + * it's the very data type which <linux/clk-provider.h> expects,\n" "> + * making this declaration pass checkpatch will break compilation\n" "> + */\n" - "> +static const char *parent_names_mux0[] =3D {\n" + "> +static const char *parent_names_mux0[] = {\n" "> + \"sys\", \"ref\", \"psc-mclk-in\", \"spdif-tx\",\n" "> +};\n" "> +\n" @@ -536,7 +517,7 @@ "> + \"spdif_mclk\", \\\n" "> +}\n" "> +\n" - "> +static struct mclk_setup_data mclk_psc_data[] =3D {\n" + "> +static struct mclk_setup_data mclk_psc_data[] = {\n" "> + MCLK_SETUP_DATA_PSC(0),\n" "> + MCLK_SETUP_DATA_PSC(1),\n" "> + MCLK_SETUP_DATA_PSC(2),\n" @@ -551,14 +532,14 @@ "> + MCLK_SETUP_DATA_PSC(11),\n" "> +};\n" "> +\n" - "> +static struct mclk_setup_data mclk_mscan_data[] =3D {\n" + "> +static struct mclk_setup_data mclk_mscan_data[] = {\n" "> + MCLK_SETUP_DATA_MSCAN(0),\n" "> + MCLK_SETUP_DATA_MSCAN(1),\n" "> + MCLK_SETUP_DATA_MSCAN(2),\n" "> + MCLK_SETUP_DATA_MSCAN(3),\n" "> +};\n" "> +\n" - "> +static struct mclk_setup_data mclk_spdif_data[] =3D {\n" + "> +static struct mclk_setup_data mclk_spdif_data[] = {\n" "> + MCLK_SETUP_DATA_SPDIF,\n" "> +};\n" "> +\n" @@ -567,43 +548,41 @@ "> +{\n" "> + size_t clks_idx_pub, clks_idx_int;\n" "> + u32 __iomem *mccr_reg; /* MCLK control register (mux, en, div) */\n" - "> + u32 __iomem *sccr_reg; /* system clock control register (enable)=\n" - " */\n" + "> + u32 __iomem *sccr_reg; /* system clock control register (enable) */\n" "> + int sccr_bit;\n" "> + int div;\n" "> +\n" "> + /* derive a few parameters from the component type and index */\n" "> + switch (entry->type) {\n" "> + case MCLK_TYPE_PSC:\n" - "> + clks_idx_pub =3D MPC512x_CLK_PSC0_MCLK + entry->comp_idx;\n" - "> + clks_idx_int =3D MPC512x_CLK_MCLKS_FIRST\n" + "> + clks_idx_pub = MPC512x_CLK_PSC0_MCLK + entry->comp_idx;\n" + "> + clks_idx_int = MPC512x_CLK_MCLKS_FIRST\n" "> + + (entry->comp_idx) * MCLK_MAX_IDX;\n" - "> + mccr_reg =3D &clkregs->psc_ccr[entry->comp_idx];\n" + "> + mccr_reg = &clkregs->psc_ccr[entry->comp_idx];\n" "> + break;\n" "> + case MCLK_TYPE_MSCAN:\n" - "> + clks_idx_pub =3D MPC512x_CLK_MSCAN0_MCLK + entry->comp_id=\n" - "x;\n" - "> + clks_idx_int =3D MPC512x_CLK_MCLKS_FIRST\n" + "> + clks_idx_pub = MPC512x_CLK_MSCAN0_MCLK + entry->comp_idx;\n" + "> + clks_idx_int = MPC512x_CLK_MCLKS_FIRST\n" "> + + (NR_PSCS + entry->comp_idx) * MCLK_MAX_IDX;\n" - "> + mccr_reg =3D &clkregs->mscan_ccr[entry->comp_idx];\n" + "> + mccr_reg = &clkregs->mscan_ccr[entry->comp_idx];\n" "> + break;\n" "> + case MCLK_TYPE_SPDIF:\n" - "> + clks_idx_pub =3D MPC512x_CLK_SPDIF_MCLK;\n" - "> + clks_idx_int =3D MPC512x_CLK_MCLKS_FIRST\n" + "> + clks_idx_pub = MPC512x_CLK_SPDIF_MCLK;\n" + "> + clks_idx_int = MPC512x_CLK_MCLKS_FIRST\n" "> + + (NR_PSCS + NR_MSCANS) * MCLK_MAX_IDX;\n" - "> + mccr_reg =3D &clkregs->spccr;\n" + "> + mccr_reg = &clkregs->spccr;\n" "> + break;\n" "> + default:\n" "> + return;\n" "> + }\n" - "> + if (entry->bit_sccr1 >=3D 0) {\n" - "> + sccr_reg =3D &clkregs->sccr1;\n" - "> + sccr_bit =3D entry->bit_sccr1;\n" - "> + } else if (entry->bit_sccr2 >=3D 0) {\n" - "> + sccr_reg =3D &clkregs->sccr2;\n" - "> + sccr_bit =3D entry->bit_sccr2;\n" + "> + if (entry->bit_sccr1 >= 0) {\n" + "> + sccr_reg = &clkregs->sccr1;\n" + "> + sccr_bit = entry->bit_sccr1;\n" + "> + } else if (entry->bit_sccr2 >= 0) {\n" + "> + sccr_reg = &clkregs->sccr2;\n" + "> + sccr_bit = entry->bit_sccr2;\n" "> + } else {\n" - "> + sccr_reg =3D NULL;\n" + "> + sccr_reg = NULL;\n" "> + }\n" "> +\n" "> + /*\n" @@ -612,8 +591,8 @@ "> + * during setup (that's a documented hardware requirement)\n" "> + *\n" "> + * the PPC_CLOCK implementation might even have violated the\n" - "> + * \"MCLK <=3D IPS\" constraint, the fixed divider value of 1\n" - "> + * results in a divider of 2 and thus MCLK =3D SYS/2 which equals\n" + "> + * \"MCLK <= IPS\" constraint, the fixed divider value of 1\n" + "> + * results in a divider of 2 and thus MCLK = SYS/2 which equals\n" "> + * CSB which is greater than IPS; the serial port setup may have\n" "> + * adjusted the divider which the clock setup might have left in\n" "> + * an undesirable state\n" @@ -624,8 +603,8 @@ "> + * - MCLK 0 enabled\n" "> + * - MCLK 1 from MCLK DIV\n" "> + */\n" - "> + div =3D clk_get_rate(clks[MPC512x_CLK_SYS]);\n" - "> + div /=3D clk_get_rate(clks[MPC512x_CLK_IPS]);\n" + "> + div = clk_get_rate(clks[MPC512x_CLK_SYS]);\n" + "> + div /= clk_get_rate(clks[MPC512x_CLK_IPS]);\n" "> + out_be32(mccr_reg, (0 << 16));\n" "> + out_be32(mccr_reg, (0 << 16) | ((div - 1) << 17));\n" "> + out_be32(mccr_reg, (1 << 16) | ((div - 1) << 17));\n" @@ -648,36 +627,34 @@ "> + * clock items even for those muxers which actually are NOPs\n" "> + * (those with two inputs of which one is reserved)\n" "> + */\n" - "> + clks[clks_idx_int + MCLK_IDX_MUX0] =3D mpc512x_clk_muxed(\n" + "> + clks[clks_idx_int + MCLK_IDX_MUX0] = mpc512x_clk_muxed(\n" "> + entry->name_mux0,\n" - "> + &parent_names_mux0[0], ARRAY_SIZE(parent_names_mu=\n" - "x0),\n" + "> + &parent_names_mux0[0], ARRAY_SIZE(parent_names_mux0),\n" "> + mccr_reg, 14, 2);\n" - "> + clks[clks_idx_int + MCLK_IDX_EN0] =3D mpc512x_clk_gated(\n" + "> + clks[clks_idx_int + MCLK_IDX_EN0] = mpc512x_clk_gated(\n" "> + entry->name_en0, entry->name_mux0,\n" "> + mccr_reg, 16);\n" - "> + clks[clks_idx_int + MCLK_IDX_DIV0] =3D mpc512x_clk_divider(\n" + "> + clks[clks_idx_int + MCLK_IDX_DIV0] = mpc512x_clk_divider(\n" "> + entry->name_div0,\n" "> + entry->name_en0, CLK_SET_RATE_GATE,\n" "> + mccr_reg, 17, 15, 0);\n" "> + if (entry->has_mclk1) {\n" - "> + clks[clks_idx_int + MCLK_IDX_MUX1] =3D mpc512x_clk_muxed(\n" + "> + clks[clks_idx_int + MCLK_IDX_MUX1] = mpc512x_clk_muxed(\n" "> + entry->name_mux1,\n" "> + &entry->parent_names_mux1[0],\n" "> + ARRAY_SIZE(entry->parent_names_mux1),\n" "> + mccr_reg, 7, 1);\n" "> + } else {\n" - "> + clks[clks_idx_int + MCLK_IDX_MUX1] =3D mpc512x_clk_factor(\n" - "> + entry->name_mux1, entry->parent_names_mux=\n" - "1[0],\n" + "> + clks[clks_idx_int + MCLK_IDX_MUX1] = mpc512x_clk_factor(\n" + "> + entry->name_mux1, entry->parent_names_mux1[0],\n" "> + 1, 1);\n" "> + }\n" "> + if (sccr_reg) {\n" - "> + clks[clks_idx_pub] =3D mpc512x_clk_gated(\n" + "> + clks[clks_idx_pub] = mpc512x_clk_gated(\n" "> + entry->name_mclk,\n" "> + entry->name_mux1, sccr_reg, sccr_bit);\n" "> + } else {\n" - "> + clks[clks_idx_pub] =3D mpc512x_clk_factor(\n" + "> + clks[clks_idx_pub] = mpc512x_clk_factor(\n" "> + entry->name_mclk,\n" "> + entry->name_mux1, 1, 1);\n" "> + }\n" @@ -694,8 +671,7 @@ "> + clk_register_clkdev(clks[clks_idx_pub], entry->name_mclk, NULL);\n" "> +}\n" "> +\n" - "> +static void mpc512x_clk_setup_mclks(struct mclk_setup_data *table, size_=\n" - "t count)\n" + "> +static void mpc512x_clk_setup_mclks(struct mclk_setup_data *table, size_t count)\n" "> +{\n" "> + while (count-- > 0)\n" "> + mpc512x_clk_setup_mclk(table++);\n" @@ -725,37 +701,26 @@ "> + */\n" "> +\n" "> + /* regardless of whether XTAL/OSC exists, have REF created */\n" - "> + mpc512x_clk_setup_ref_clock(busfreq, &sys_mul, &sys_div, &ips_div=\n" - ");\n" + "> + mpc512x_clk_setup_ref_clock(busfreq, &sys_mul, &sys_div, &ips_div);\n" "> +\n" "> + /* now setup the REF -> SYS -> CSB -> IPS hierarchy */\n" - "> + clks[MPC512x_CLK_SYS] =3D mpc512x_clk_factor(\"sys\", \"ref\",\n" + "> + clks[MPC512x_CLK_SYS] = mpc512x_clk_factor(\"sys\", \"ref\",\n" "> + sys_mul, sys_div);\n" - "> + clks[MPC512x_CLK_CSB] =3D mpc512x_clk_factor(\"csb\", \"sys\", 1, 2);\n" - "> + clks[MPC512x_CLK_IPS] =3D mpc512x_clk_divtable(\"ips\", \"csb\",\n" - "> + &clkregs->scfr1, 23,=\n" - " 3,\n" + "> + clks[MPC512x_CLK_CSB] = mpc512x_clk_factor(\"csb\", \"sys\", 1, 2);\n" + "> + clks[MPC512x_CLK_IPS] = mpc512x_clk_divtable(\"ips\", \"csb\",\n" + "> + &clkregs->scfr1, 23, 3,\n" "> + divtab_2346);\n" "> +\n" "> + /* now setup anything below SYS and CSB and IPS */\n" - "> + clks[MPC512x_CLK_DDR_UG] =3D mpc512x_clk_factor(\"ddr-ug\", \"sys\", =\n" - "1, 2);\n" - "> + clks[MPC512x_CLK_SDHC_x4] =3D mpc512x_clk_factor(\"sdhc-x4\", \"csb\"=\n" - ", 4, 1);\n" - "> + clks[MPC512x_CLK_SDHC_UG] =3D mpc512x_clk_divider(\"sdhc-ug\", \"sdh=\n" - "c-x4\", 0,\n" - "> + &clkregs->scfr2, =\n" - "0, 8,\n" - "> + CLK_DIVIDER_ONE_B=\n" - "ASED);\n" - "> + clks[MPC512x_CLK_DIU_x4] =3D mpc512x_clk_factor(\"diu-x4\", \"csb\", =\n" - "4, 1);\n" - "> + clks[MPC512x_CLK_DIU_UG] =3D mpc512x_clk_divider(\"diu-ug\", \"diu-x=\n" - "4\", 0,\n" - "> + &clkregs->scfr1, 0=\n" - ", 8,\n" - "> + CLK_DIVIDER_ONE_BA=\n" - "SED);\n" + "> + clks[MPC512x_CLK_DDR_UG] = mpc512x_clk_factor(\"ddr-ug\", \"sys\", 1, 2);\n" + "> + clks[MPC512x_CLK_SDHC_x4] = mpc512x_clk_factor(\"sdhc-x4\", \"csb\", 4, 1);\n" + "> + clks[MPC512x_CLK_SDHC_UG] = mpc512x_clk_divider(\"sdhc-ug\", \"sdhc-x4\", 0,\n" + "> + &clkregs->scfr2, 0, 8,\n" + "> + CLK_DIVIDER_ONE_BASED);\n" + "> + clks[MPC512x_CLK_DIU_x4] = mpc512x_clk_factor(\"diu-x4\", \"csb\", 4, 1);\n" + "> + clks[MPC512x_CLK_DIU_UG] = mpc512x_clk_divider(\"diu-ug\", \"diu-x4\", 0,\n" + "> + &clkregs->scfr1, 0, 8,\n" + "> + CLK_DIVIDER_ONE_BASED);\n" "> +\n" "> + /*\n" "> + * the \"power architecture PLL\" was setup from data which was\n" @@ -764,108 +729,89 @@ "> + * longer adjustable, or no longer in need of adjustment), which\n" "> + * is why we don't register a PLL here but assume fixed factors\n" "> + */\n" - "> + mul =3D get_cpmf_mult_x2();\n" - "> + div =3D 2; /* compensate for the fractional factor */\n" - "> + clks[MPC512x_CLK_E300] =3D mpc512x_clk_factor(\"e300\", \"csb\", mul,=\n" - " div);\n" + "> + mul = get_cpmf_mult_x2();\n" + "> + div = 2; /* compensate for the fractional factor */\n" + "> + clks[MPC512x_CLK_E300] = mpc512x_clk_factor(\"e300\", \"csb\", mul, div);\n" "> +\n" - "> + clks[MPC512x_CLK_MBX_BUS_UG] =3D mpc512x_clk_factor(\"mbx-bus-ug\",=\n" - " \"csb\",\n" + "> + clks[MPC512x_CLK_MBX_BUS_UG] = mpc512x_clk_factor(\"mbx-bus-ug\", \"csb\",\n" "> + 1, 2);\n" - "> + clks[MPC512x_CLK_MBX_UG] =3D mpc512x_clk_divtable(\"mbx-ug\", \"mbx-=\n" - "bus-ug\",\n" - "> + &clkregs->scfr1, =\n" - "14, 3,\n" + "> + clks[MPC512x_CLK_MBX_UG] = mpc512x_clk_divtable(\"mbx-ug\", \"mbx-bus-ug\",\n" + "> + &clkregs->scfr1, 14, 3,\n" "> + divtab_1234);\n" - "> + clks[MPC512x_CLK_MBX_3D_UG] =3D mpc512x_clk_factor(\"mbx-3d-ug\", \"=\n" - "mbx-ug\",\n" + "> + clks[MPC512x_CLK_MBX_3D_UG] = mpc512x_clk_factor(\"mbx-3d-ug\", \"mbx-ug\",\n" "> + 1, 1);\n" - "> + clks[MPC512x_CLK_PCI_UG] =3D mpc512x_clk_divtable(\"pci-ug\", \"csb\",\n" - "> + &clkregs->scfr1, =\n" - "20, 3,\n" + "> + clks[MPC512x_CLK_PCI_UG] = mpc512x_clk_divtable(\"pci-ug\", \"csb\",\n" + "> + &clkregs->scfr1, 20, 3,\n" "> + divtab_2346);\n" - "> + clks[MPC512x_CLK_NFC_UG] =3D mpc512x_clk_divtable(\"nfc-ug\", \"ips\",\n" - "> + &clkregs->scfr1, =\n" - "8, 3,\n" + "> + clks[MPC512x_CLK_NFC_UG] = mpc512x_clk_divtable(\"nfc-ug\", \"ips\",\n" + "> + &clkregs->scfr1, 8, 3,\n" "> + divtab_1234);\n" - "> + clks[MPC512x_CLK_LPC_UG] =3D mpc512x_clk_divtable(\"lpc-ug\", \"ips\",\n" - "> + &clkregs->scfr1, =\n" - "11, 3,\n" + "> + clks[MPC512x_CLK_LPC_UG] = mpc512x_clk_divtable(\"lpc-ug\", \"ips\",\n" + "> + &clkregs->scfr1, 11, 3,\n" "> + divtab_1234);\n" "> +\n" - "> + clks[MPC512x_CLK_LPC] =3D mpc512x_clk_gated(\"lpc\", \"lpc-ug\",\n" + "> + clks[MPC512x_CLK_LPC] = mpc512x_clk_gated(\"lpc\", \"lpc-ug\",\n" "> + &clkregs->sccr1, 30);\n" - "> + clks[MPC512x_CLK_NFC] =3D mpc512x_clk_gated(\"nfc\", \"nfc-ug\",\n" + "> + clks[MPC512x_CLK_NFC] = mpc512x_clk_gated(\"nfc\", \"nfc-ug\",\n" "> + &clkregs->sccr1, 29);\n" - "> + clks[MPC512x_CLK_PATA] =3D mpc512x_clk_gated(\"pata\", \"ips\",\n" + "> + clks[MPC512x_CLK_PATA] = mpc512x_clk_gated(\"pata\", \"ips\",\n" "> + &clkregs->sccr1, 28);\n" "> + mpc512x_clk_setup_mclks(mclk_psc_data, ARRAY_SIZE(mclk_psc_data));\n" - "> + clks[MPC512x_CLK_PSC_FIFO] =3D mpc512x_clk_gated(\"psc-fifo\", \"ips=\n" - "\",\n" - "> + &clkregs->sccr1, 1=\n" - "5);\n" - "> + clks[MPC512x_CLK_SATA] =3D mpc512x_clk_gated(\"sata\", \"ips\",\n" + "> + clks[MPC512x_CLK_PSC_FIFO] = mpc512x_clk_gated(\"psc-fifo\", \"ips\",\n" + "> + &clkregs->sccr1, 15);\n" + "> + clks[MPC512x_CLK_SATA] = mpc512x_clk_gated(\"sata\", \"ips\",\n" "> + &clkregs->sccr1, 14);\n" - "> + clks[MPC512x_CLK_FEC] =3D mpc512x_clk_gated(\"fec\", \"ips\",\n" + "> + clks[MPC512x_CLK_FEC] = mpc512x_clk_gated(\"fec\", \"ips\",\n" "> + &clkregs->sccr1, 13);\n" - "> + clks[MPC512x_CLK_PCI] =3D mpc512x_clk_gated(\"pci\", \"pci-ug\",\n" + "> + clks[MPC512x_CLK_PCI] = mpc512x_clk_gated(\"pci\", \"pci-ug\",\n" "> + &clkregs->sccr1, 11);\n" - "> + clks[MPC512x_CLK_DDR] =3D mpc512x_clk_gated(\"ddr\", \"ddr-ug\",\n" + "> + clks[MPC512x_CLK_DDR] = mpc512x_clk_gated(\"ddr\", \"ddr-ug\",\n" "> + &clkregs->sccr1, 10);\n" "> +\n" - "> + clks[MPC512x_CLK_DIU] =3D mpc512x_clk_gated(\"diu\", \"diu-ug\",\n" + "> + clks[MPC512x_CLK_DIU] = mpc512x_clk_gated(\"diu\", \"diu-ug\",\n" "> + &clkregs->sccr2, 31);\n" - "> + clks[MPC512x_CLK_AXE] =3D mpc512x_clk_gated(\"axe\", \"csb\",\n" + "> + clks[MPC512x_CLK_AXE] = mpc512x_clk_gated(\"axe\", \"csb\",\n" "> + &clkregs->sccr2, 30);\n" - "> + clks[MPC512x_CLK_MEM] =3D mpc512x_clk_gated(\"mem\", \"ips\",\n" + "> + clks[MPC512x_CLK_MEM] = mpc512x_clk_gated(\"mem\", \"ips\",\n" "> + &clkregs->sccr2, 29);\n" - "> + clks[MPC512x_CLK_USB1] =3D mpc512x_clk_gated(\"usb1\", \"csb\",\n" + "> + clks[MPC512x_CLK_USB1] = mpc512x_clk_gated(\"usb1\", \"csb\",\n" "> + &clkregs->sccr2, 28);\n" - "> + clks[MPC512x_CLK_USB2] =3D mpc512x_clk_gated(\"usb2\", \"csb\",\n" + "> + clks[MPC512x_CLK_USB2] = mpc512x_clk_gated(\"usb2\", \"csb\",\n" "> + &clkregs->sccr2, 27);\n" - "> + clks[MPC512x_CLK_I2C] =3D mpc512x_clk_gated(\"i2c\", \"ips\",\n" + "> + clks[MPC512x_CLK_I2C] = mpc512x_clk_gated(\"i2c\", \"ips\",\n" "> + &clkregs->sccr2, 26);\n" - "> + mpc512x_clk_setup_mclks(mclk_mscan_data, ARRAY_SIZE(mclk_mscan_da=\n" - "ta));\n" - "> + clks[MPC512x_CLK_SDHC] =3D mpc512x_clk_gated(\"sdhc\", \"sdhc-ug\",\n" + "> + mpc512x_clk_setup_mclks(mclk_mscan_data, ARRAY_SIZE(mclk_mscan_data));\n" + "> + clks[MPC512x_CLK_SDHC] = mpc512x_clk_gated(\"sdhc\", \"sdhc-ug\",\n" "> + &clkregs->sccr2, 24);\n" - "> + mpc512x_clk_setup_mclks(mclk_spdif_data, ARRAY_SIZE(mclk_spdif_da=\n" - "ta));\n" - "> + clks[MPC512x_CLK_MBX_BUS] =3D mpc512x_clk_gated(\"mbx-bus\", \"mbx-b=\n" - "us-ug\",\n" - "> + &clkregs->sccr2, 22=\n" - ");\n" - "> + clks[MPC512x_CLK_MBX] =3D mpc512x_clk_gated(\"mbx\", \"mbx-ug\",\n" + "> + mpc512x_clk_setup_mclks(mclk_spdif_data, ARRAY_SIZE(mclk_spdif_data));\n" + "> + clks[MPC512x_CLK_MBX_BUS] = mpc512x_clk_gated(\"mbx-bus\", \"mbx-bus-ug\",\n" + "> + &clkregs->sccr2, 22);\n" + "> + clks[MPC512x_CLK_MBX] = mpc512x_clk_gated(\"mbx\", \"mbx-ug\",\n" "> + &clkregs->sccr2, 21);\n" - "> + clks[MPC512x_CLK_MBX_3D] =3D mpc512x_clk_gated(\"mbx-3d\", \"mbx-3d-=\n" - "ug\",\n" + "> + clks[MPC512x_CLK_MBX_3D] = mpc512x_clk_gated(\"mbx-3d\", \"mbx-3d-ug\",\n" "> + &clkregs->sccr2, 20);\n" - "> + clks[MPC512x_CLK_IIM] =3D mpc512x_clk_gated(\"iim\", \"csb\",\n" + "> + clks[MPC512x_CLK_IIM] = mpc512x_clk_gated(\"iim\", \"csb\",\n" "> + &clkregs->sccr2, 19);\n" - "> + clks[MPC512x_CLK_VIU] =3D mpc512x_clk_gated(\"viu\", \"csb\",\n" + "> + clks[MPC512x_CLK_VIU] = mpc512x_clk_gated(\"viu\", \"csb\",\n" "> + &clkregs->sccr2, 18);\n" - "> + clks[MPC512x_CLK_SDHC_2] =3D mpc512x_clk_gated(\"sdhc-2\", \"sdhc-ug=\n" - "\",\n" + "> + clks[MPC512x_CLK_SDHC_2] = mpc512x_clk_gated(\"sdhc-2\", \"sdhc-ug\",\n" "> + &clkregs->sccr2, 17);\n" "> +\n" "> + /*\n" "> + * externally provided clocks (when implemented in hardware,\n" "> + * device tree may specify values which otherwise were unknown)\n" "> + */\n" - "> + freq =3D get_freq_from_dt(\"psc_mclk_in\");\n" + "> + freq = get_freq_from_dt(\"psc_mclk_in\");\n" "> + if (!freq)\n" - "> + freq =3D 25000000;\n" - "> + clks[MPC512x_CLK_PSC_MCLK_IN] =3D mpc512x_clk_fixed(\"psc_mclk_in\"=\n" - ", freq);\n" - "> + freq =3D get_freq_from_dt(\"spdif_tx_in\");\n" - "> + clks[MPC512x_CLK_SPDIF_TX_IN] =3D mpc512x_clk_fixed(\"spdif_tx_in\"=\n" - ", freq);\n" - "> + freq =3D get_freq_from_dt(\"spdif_rx_in\");\n" - "> + clks[MPC512x_CLK_SPDIF_TX_IN] =3D mpc512x_clk_fixed(\"spdif_rx_in\"=\n" - ", freq);\n" + "> + freq = 25000000;\n" + "> + clks[MPC512x_CLK_PSC_MCLK_IN] = mpc512x_clk_fixed(\"psc_mclk_in\", freq);\n" + "> + freq = get_freq_from_dt(\"spdif_tx_in\");\n" + "> + clks[MPC512x_CLK_SPDIF_TX_IN] = mpc512x_clk_fixed(\"spdif_tx_in\", freq);\n" + "> + freq = get_freq_from_dt(\"spdif_rx_in\");\n" + "> + clks[MPC512x_CLK_SPDIF_TX_IN] = mpc512x_clk_fixed(\"spdif_rx_in\", freq);\n" "> +\n" "> + /* fixed frequency for AC97, always 24.567MHz */\n" - "> + clks[MPC512x_CLK_AC97] =3D mpc512x_clk_fixed(\"ac97\", 24567000);\n" + "> + clks[MPC512x_CLK_AC97] = mpc512x_clk_fixed(\"ac97\", 24567000);\n" "> +\n" "> + /* clkdev registration for compatibility reasons */\n" "> + clk_register_clkdev(clks[MPC512x_CLK_REF], \"ref_clk\", NULL);\n" @@ -876,11 +822,11 @@ "> + clk_register_clkdev(clks[MPC512x_CLK_USB2], \"usb2_clk\", NULL);\n" "> +\n" "> + pr_debug(\"clock tree setup complete\\n\");\n" - "> + freq =3D clk_get_rate(clks[MPC512x_CLK_E300]);\n" + "> + freq = clk_get_rate(clks[MPC512x_CLK_E300]);\n" "> + pr_debug(\"derived PPC freq [%d]\\n\", freq);\n" - "> + freq =3D clk_get_rate(clks[MPC512x_CLK_IPS]);\n" + "> + freq = clk_get_rate(clks[MPC512x_CLK_IPS]);\n" "> + pr_debug(\"derived IPS freq [%d]\\n\", freq);\n" - "> + freq =3D clk_get_rate(clks[MPC512x_CLK_LPC]);\n" + "> + freq = clk_get_rate(clks[MPC512x_CLK_LPC]);\n" "> + pr_debug(\"derived LPC freq [%d]\\n\", freq);\n" "> +\n" "> + /* enable some of the clocks here unconditionally because ... */\n" @@ -895,8 +841,7 @@ "> + /* some are required yet no dependencies were declared */\n" "> + clk_prepare_enable(clks[MPC512x_CLK_PSC_FIFO]);\n" "> + /* some are not yet acquired by their respective drivers */\n" - "> + clk_prepare_enable(clks[MPC512x_CLK_PSC3_MCLK]);/* serial console=\n" - " */\n" + "> + clk_prepare_enable(clks[MPC512x_CLK_PSC3_MCLK]);/* serial console */\n" "> + clk_prepare_enable(clks[MPC512x_CLK_FEC]); /* network, NFS */\n" "> + clk_prepare_enable(clks[MPC512x_CLK_DIU]); /* display */\n" "> + clk_prepare_enable(clks[MPC512x_CLK_I2C]);\n" @@ -923,9 +868,8 @@ "> + */\n" "> +static void mpc5121_clk_register_of_provider(struct device_node *np)\n" "> +{\n" - "> + clk_data.clks =3D clks;\n" - "> + clk_data.clk_num =3D MPC512x_CLK_LAST_PUBLIC + 1; /* _not_ ARRAY_=\n" - "SIZE() */\n" + "> + clk_data.clks = clks;\n" + "> + clk_data.clk_num = MPC512x_CLK_LAST_PUBLIC + 1; /* _not_ ARRAY_SIZE() */\n" "> + of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);\n" "> +}\n" "> +\n" @@ -935,11 +879,10 @@ "> + int busfreq;\n" "> +\n" "> + /* map the clock control registers */\n" - "> + clk_np =3D of_find_compatible_node(NULL, NULL, \"fsl,mpc5121-clock=\n" - "\");\n" + "> + clk_np = of_find_compatible_node(NULL, NULL, \"fsl,mpc5121-clock\");\n" "> + if (!clk_np)\n" "> + return -ENODEV;\n" - "> + clkregs =3D of_iomap(clk_np, 0);\n" + "> + clkregs = of_iomap(clk_np, 0);\n" "> + WARN_ON(!clkregs);\n" "> +\n" "> + /* invalidate all not yet registered clock slots */\n" @@ -955,14 +898,14 @@ "> + * add a dummy clock for those situations where a clock spec is\n" "> + * required yet no real clock is involved\n" "> + */\n" - "> + clks[MPC512x_CLK_DUMMY] =3D mpc512x_clk_fixed(\"dummy\", 0);\n" + "> + clks[MPC512x_CLK_DUMMY] = mpc512x_clk_fixed(\"dummy\", 0);\n" "> +\n" "> + /*\n" "> + * have all the real nodes in the clock tree populated from REF\n" "> + * down to all leaves, either starting from the OSC node or from\n" "> + * a REF root that was created from the IPS bus clock input\n" "> + */\n" - "> + busfreq =3D get_freq_from_dt(\"bus-frequency\");\n" + "> + busfreq = get_freq_from_dt(\"bus-frequency\");\n" "> + mpc512x_clk_setup_clock_tree(busfreq);\n" "> +\n" "> + /* register as an OF clock provider */\n" @@ -974,12 +917,10 @@ "> index c4f7799..7f8fc64 100644\n" "> --- a/include/linux/clk-provider.h\n" "> +++ b/include/linux/clk-provider.h\n" - "> @@ -497,6 +497,20 @@ static inline const char *of_clk_get_parent_name(str=\n" - "uct device_node *np,\n" + "> @@ -497,6 +497,20 @@ static inline const char *of_clk_get_parent_name(struct device_node *np,\n" "> * for improved portability across platforms\n" "> */\n" - "> =\n" - "\n" + "> \n" "> +#if IS_ENABLED(CONFIG_PPC)\n" "> +\n" "> +static inline u32 clk_readl(u32 __iomem *reg)\n" @@ -997,18 +938,15 @@ "> static inline u32 clk_readl(u32 __iomem *reg)\n" "> {\n" "> return readl(reg);\n" - "> @@ -507,5 +521,7 @@ static inline void clk_writel(u32 val, u32 __iomem *r=\n" - "eg)\n" + "> @@ -507,5 +521,7 @@ static inline void clk_writel(u32 val, u32 __iomem *reg)\n" "> writel(val, reg);\n" "> }\n" - "> =\n" - "\n" + "> \n" "> +#endif /* platform dependent I/O accessors */\n" "> +\n" "> #endif /* CONFIG_COMMON_CLK */\n" "> #endif /* CLK_PROVIDER_H */\n" - "> -- =\n" - "\n" + "> -- \n" > 1.7.10.4 -0239e9b524e5dd773341f61d998017d552b7527f9815e67de14a18ee03a44213 +3ee17a36debaa2c0f88e647b99ee74deca490e22fa7617c80f40ee3f1c9deef1
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.