diff for duplicates of <87o9zmenon.fsf@free-electrons.com> diff --git a/a/1.txt b/N1/1.txt index 03a10ae..7629707 100644 --- a/a/1.txt +++ b/N1/1.txt @@ -1,7 +1,6 @@ Hi Chris, -=20 - On jeu., d=C3=A9c. 22 2016, Chris Packham <chris.packham@alliedtelesis.co.= -nz> wrote: + + On jeu., d?c. 22 2016, Chris Packham <chris.packham@alliedtelesis.co.nz> wrote: > The 98DX3236, 98DX3336, 98DX4521 and variants have a different TCLK from > the Armada XP (200MHz vs 250MHz). The CPU core clock is fixed at 800MHz. @@ -23,8 +22,7 @@ Gregory > drivers/clk/mvebu/Makefile | 2 +- > drivers/clk/mvebu/armada-xp.c | 42 +++++++ > drivers/clk/mvebu/clk-cpu.c | 33 +++++- -> drivers/clk/mvebu/mv98dx3236-corediv.c | 207 +++++++++++++++++++++++++++= -++++++ +> drivers/clk/mvebu/mv98dx3236-corediv.c | 207 +++++++++++++++++++++++++++++++++ > 4 files changed, 280 insertions(+), 4 deletions(-) > create mode 100644 drivers/clk/mvebu/mv98dx3236-corediv.c > @@ -32,15 +30,15 @@ Gregory > index d9ae97fb43c4..6a3681e3d6db 100644 > --- a/drivers/clk/mvebu/Makefile > +++ b/drivers/clk/mvebu/Makefile -> @@ -9,7 +9,7 @@ obj-$(CONFIG_ARMADA_39X_CLK) +=3D armada-39x.o -> obj-$(CONFIG_ARMADA_37XX_CLK) +=3D armada-37xx-xtal.o -> obj-$(CONFIG_ARMADA_37XX_CLK) +=3D armada-37xx-tbg.o -> obj-$(CONFIG_ARMADA_37XX_CLK) +=3D armada-37xx-periph.o -> -obj-$(CONFIG_ARMADA_XP_CLK) +=3D armada-xp.o -> +obj-$(CONFIG_ARMADA_XP_CLK) +=3D armada-xp.o mv98dx3236-corediv.o -> obj-$(CONFIG_ARMADA_AP806_SYSCON) +=3D ap806-system-controller.o -> obj-$(CONFIG_ARMADA_CP110_SYSCON) +=3D cp110-system-controller.o -> obj-$(CONFIG_DOVE_CLK) +=3D dove.o dove-divider.o +> @@ -9,7 +9,7 @@ obj-$(CONFIG_ARMADA_39X_CLK) += armada-39x.o +> obj-$(CONFIG_ARMADA_37XX_CLK) += armada-37xx-xtal.o +> obj-$(CONFIG_ARMADA_37XX_CLK) += armada-37xx-tbg.o +> obj-$(CONFIG_ARMADA_37XX_CLK) += armada-37xx-periph.o +> -obj-$(CONFIG_ARMADA_XP_CLK) += armada-xp.o +> +obj-$(CONFIG_ARMADA_XP_CLK) += armada-xp.o mv98dx3236-corediv.o +> obj-$(CONFIG_ARMADA_AP806_SYSCON) += ap806-system-controller.o +> obj-$(CONFIG_ARMADA_CP110_SYSCON) += cp110-system-controller.o +> obj-$(CONFIG_DOVE_CLK) += dove.o dove-divider.o > diff --git a/drivers/clk/mvebu/armada-xp.c b/drivers/clk/mvebu/armada-xp.c > index b3094315a3c0..0413bf8284e0 100644 > --- a/drivers/clk/mvebu/armada-xp.c @@ -48,52 +46,49 @@ Gregory > @@ -52,6 +52,12 @@ static u32 __init axp_get_tclk_freq(void __iomem *sar) > return 250000000; > } ->=20=20 +> > +/* MV98DX3236 TCLK frequency is fixed to 200MHz */ > +static u32 __init mv98dx3236_get_tclk_freq(void __iomem *sar) > +{ > + return 200000000; > +} > + -> static const u32 axp_cpu_freqs[] __initconst =3D { +> static const u32 axp_cpu_freqs[] __initconst = { > 1000000000, > 1066000000, > @@ -89,6 +95,12 @@ static u32 __init axp_get_cpu_freq(void __iomem *sar) > return cpu_freq; > } ->=20=20 +> > +/* MV98DX3236 CLK frequency is fixed to 800MHz */ > +static u32 __init mv98dx3236_get_cpu_freq(void __iomem *sar) > +{ > + return 800000000; > +} > + -> static const int axp_nbclk_ratios[32][2] __initconst =3D { +> static const int axp_nbclk_ratios[32][2] __initconst = { > {0, 1}, {1, 2}, {2, 2}, {2, 2}, > {1, 2}, {1, 2}, {1, 1}, {2, 3}, -> @@ -158,6 +170,14 @@ static const struct coreclk_soc_desc axp_coreclks = -=3D { -> .num_ratios =3D ARRAY_SIZE(axp_coreclk_ratios), +> @@ -158,6 +170,14 @@ static const struct coreclk_soc_desc axp_coreclks = { +> .num_ratios = ARRAY_SIZE(axp_coreclk_ratios), > }; ->=20=20 -> +static const struct coreclk_soc_desc mv98dx3236_coreclks =3D { -> + .get_tclk_freq =3D mv98dx3236_get_tclk_freq, -> + .get_cpu_freq =3D mv98dx3236_get_cpu_freq, -> + .get_clk_ratio =3D NULL, -> + .ratios =3D NULL, -> + .num_ratios =3D 0, +> +> +static const struct coreclk_soc_desc mv98dx3236_coreclks = { +> + .get_tclk_freq = mv98dx3236_get_tclk_freq, +> + .get_cpu_freq = mv98dx3236_get_cpu_freq, +> + .get_clk_ratio = NULL, +> + .ratios = NULL, +> + .num_ratios = 0, > +}; > + > /* > * Clock Gating Control > */ -> @@ -195,6 +215,15 @@ static const struct clk_gating_soc_desc axp_gating_d= -esc[] __initconst =3D { +> @@ -195,6 +215,15 @@ static const struct clk_gating_soc_desc axp_gating_desc[] __initconst = { > { } > }; ->=20=20 -> +static const struct clk_gating_soc_desc mv98dx3236_gating_desc[] __initc= -onst =3D { +> +> +static const struct clk_gating_soc_desc mv98dx3236_gating_desc[] __initconst = { > + { "ge1", NULL, 3, 0 }, > + { "ge0", NULL, 4, 0 }, > + { "pex00", NULL, 5, 0 }, @@ -104,16 +99,15 @@ onst =3D { > + > static void __init axp_clk_init(struct device_node *np) > { -> struct device_node *cgnp =3D -> @@ -206,3 +235,16 @@ static void __init axp_clk_init(struct device_node *= -np) +> struct device_node *cgnp = +> @@ -206,3 +235,16 @@ static void __init axp_clk_init(struct device_node *np) > mvebu_clk_gating_setup(cgnp, axp_gating_desc); > } > CLK_OF_DECLARE(axp_clk, "marvell,armada-xp-core-clock", axp_clk_init); > + > +static void __init mv98dx3236_clk_init(struct device_node *np) > +{ -> + struct device_node *cgnp =3D +> + struct device_node *cgnp = > + of_find_compatible_node(NULL, NULL, "marvell,armada-xp-gating-clock"); > + > + mvebu_coreclk_setup(np, &mv98dx3236_coreclks); @@ -127,32 +121,30 @@ np) > index 5837eb8a212f..29f295e7a36b 100644 > --- a/drivers/clk/mvebu/clk-cpu.c > +++ b/drivers/clk/mvebu/clk-cpu.c -> @@ -165,7 +165,9 @@ static const struct clk_ops cpu_ops =3D { -> .set_rate =3D clk_cpu_set_rate, +> @@ -165,7 +165,9 @@ static const struct clk_ops cpu_ops = { +> .set_rate = clk_cpu_set_rate, > }; ->=20=20 +> > -static void __init of_cpu_clk_setup(struct device_node *node) > +/* Add parameter to allow this to support different clock operations. */ > +static void __init _of_cpu_clk_setup(struct device_node *node, > + const struct clk_ops *cpu_clk_ops) > { > struct cpu_clk *cpuclk; -> void __iomem *clock_complex_base =3D of_iomap(node, 0); -> @@ -218,7 +220,7 @@ static void __init of_cpu_clk_setup(struct device_nod= -e *node) -> cpuclk[cpu].hw.init =3D &init; ->=20=20 -> init.name =3D cpuclk[cpu].clk_name; -> - init.ops =3D &cpu_ops; -> + init.ops =3D cpu_clk_ops; -> init.flags =3D 0; -> init.parent_names =3D &cpuclk[cpu].parent_name; -> init.num_parents =3D 1; -> @@ -243,5 +245,30 @@ static void __init of_cpu_clk_setup(struct device_no= -de *node) +> void __iomem *clock_complex_base = of_iomap(node, 0); +> @@ -218,7 +220,7 @@ static void __init of_cpu_clk_setup(struct device_node *node) +> cpuclk[cpu].hw.init = &init; +> +> init.name = cpuclk[cpu].clk_name; +> - init.ops = &cpu_ops; +> + init.ops = cpu_clk_ops; +> init.flags = 0; +> init.parent_names = &cpuclk[cpu].parent_name; +> init.num_parents = 1; +> @@ -243,5 +245,30 @@ static void __init of_cpu_clk_setup(struct device_node *node) > iounmap(clock_complex_base); > } ->=20=20 +> > +/* Use this function to call the generic setup with the correct > + * clock operation > + */ @@ -168,10 +160,10 @@ de *node) > +/* Define the clock and operations for the mv98dx3236 - it cannot perform > + * any operations. > + */ -> +static const struct clk_ops mv98dx3236_cpu_ops =3D { -> + .recalc_rate =3D NULL, -> + .round_rate =3D NULL, -> + .set_rate =3D NULL, +> +static const struct clk_ops mv98dx3236_cpu_ops = { +> + .recalc_rate = NULL, +> + .round_rate = NULL, +> + .set_rate = NULL, > +}; > + > +static void __init of_mv98dx3236_cpu_clk_setup(struct device_node *node) @@ -181,8 +173,7 @@ de *node) > + > +CLK_OF_DECLARE(mv98dx3236_cpu_clock, "marvell,mv98dx3236-cpu-clock", > + of_mv98dx3236_cpu_clk_setup); -> diff --git a/drivers/clk/mvebu/mv98dx3236-corediv.c b/drivers/clk/mvebu/m= -v98dx3236-corediv.c +> diff --git a/drivers/clk/mvebu/mv98dx3236-corediv.c b/drivers/clk/mvebu/mv98dx3236-corediv.c > new file mode 100644 > index 000000000000..3060764a8e5d > --- /dev/null @@ -254,11 +245,11 @@ v98dx3236-corediv.c > +static unsigned long mv98dx3236_corediv_recalc_rate(struct clk_hw *hwclk, > + unsigned long parent_rate) > +{ -> + struct clk_corediv *corediv =3D to_corediv_clk(hwclk); +> + struct clk_corediv *corediv = to_corediv_clk(hwclk); > + u32 reg, div; > + -> + reg =3D readl(corediv->reg + RATIO_REG_OFFSET); -> + div =3D (reg >> CLK_DIV_RATIO_NAND_OFFSET) & CLK_DIV_RATIO_NAND_MASK; +> + reg = readl(corediv->reg + RATIO_REG_OFFSET); +> + div = (reg >> CLK_DIV_RATIO_NAND_OFFSET) & CLK_DIV_RATIO_NAND_MASK; > + return parent_rate / div; > +} > + @@ -268,39 +259,38 @@ v98dx3236-corediv.c > + /* Valid ratio are 1:4, 1:5, 1:6 and 1:8 */ > + u32 div; > + -> + div =3D *parent_rate / rate; +> + div = *parent_rate / rate; > + if (div < 4) -> + div =3D 4; +> + div = 4; > + else if (div > 6) -> + div =3D 8; +> + div = 8; > + > + return *parent_rate / div; > +} > + -> +static int mv98dx3236_corediv_set_rate(struct clk_hw *hwclk, unsigned lo= -ng rate, +> +static int mv98dx3236_corediv_set_rate(struct clk_hw *hwclk, unsigned long rate, > + unsigned long parent_rate) > +{ -> + struct clk_corediv *corediv =3D to_corediv_clk(hwclk); -> + unsigned long flags =3D 0; +> + struct clk_corediv *corediv = to_corediv_clk(hwclk); +> + unsigned long flags = 0; > + u32 reg, div; > + -> + div =3D parent_rate / rate; +> + div = parent_rate / rate; > + > + spin_lock_irqsave(&corediv->lock, flags); > + > + /* Write new divider to the divider ratio register */ -> + reg =3D readl(corediv->reg + RATIO_REG_OFFSET); -> + reg &=3D ~(CLK_DIV_RATIO_NAND_MASK << CLK_DIV_RATIO_NAND_OFFSET); -> + reg |=3D (div & CLK_DIV_RATIO_NAND_MASK) << CLK_DIV_RATIO_NAND_OFFSET; +> + reg = readl(corediv->reg + RATIO_REG_OFFSET); +> + reg &= ~(CLK_DIV_RATIO_NAND_MASK << CLK_DIV_RATIO_NAND_OFFSET); +> + reg |= (div & CLK_DIV_RATIO_NAND_MASK) << CLK_DIV_RATIO_NAND_OFFSET; > + writel(reg, corediv->reg + RATIO_REG_OFFSET); > + > + /* Set reload-force for this clock */ -> + reg =3D readl(corediv->reg) | BIT(CLK_DIV_RATIO_NAND_FORCE_RELOAD_BIT); +> + reg = readl(corediv->reg) | BIT(CLK_DIV_RATIO_NAND_FORCE_RELOAD_BIT); > + writel(reg, corediv->reg); > + > + /* Now trigger the clock update */ -> + reg =3D readl(corediv->reg + RATIO_REG_OFFSET) | RATIO_RELOAD_BIT; +> + reg = readl(corediv->reg + RATIO_REG_OFFSET) | RATIO_RELOAD_BIT; > + writel(reg, corediv->reg + RATIO_REG_OFFSET); > + > + /* @@ -308,7 +298,7 @@ ng rate, > + * ratios request and the reload request. > + */ > + udelay(1000); -> + reg &=3D ~(CORE_CLK_DIV_RATIO_MASK | RATIO_RELOAD_BIT); +> + reg &= ~(CORE_CLK_DIV_RATIO_MASK | RATIO_RELOAD_BIT); > + writel(reg, corediv->reg + RATIO_REG_OFFSET); > + udelay(1000); > + @@ -317,13 +307,13 @@ ng rate, > + return 0; > +} > + -> +static const struct clk_ops ops =3D { -> + .enable =3D mv98dx3236_corediv_enable, -> + .disable =3D mv98dx3236_corediv_disable, -> + .is_enabled =3D mv98dx3236_corediv_is_enabled, -> + .recalc_rate =3D mv98dx3236_corediv_recalc_rate, -> + .round_rate =3D mv98dx3236_corediv_round_rate, -> + .set_rate =3D mv98dx3236_corediv_set_rate, +> +static const struct clk_ops ops = { +> + .enable = mv98dx3236_corediv_enable, +> + .disable = mv98dx3236_corediv_disable, +> + .is_enabled = mv98dx3236_corediv_is_enabled, +> + .recalc_rate = mv98dx3236_corediv_recalc_rate, +> + .round_rate = mv98dx3236_corediv_round_rate, +> + .set_rate = mv98dx3236_corediv_set_rate, > +}; > + > +static void __init mv98dx3236_corediv_clk_init(struct device_node *node) @@ -338,31 +328,31 @@ ng rate, > + int len; > + struct device_node *dfx_node; > + -> + dfx_node =3D of_parse_phandle(node, "base", 0); +> + dfx_node = of_parse_phandle(node, "base", 0); > + if (WARN_ON(!dfx_node)) > + return; > + -> + off =3D of_get_property(node, "reg", &len); +> + off = of_get_property(node, "reg", &len); > + if (WARN_ON(!off)) > + return; > + -> + base =3D of_iomap(dfx_node, 0); +> + base = of_iomap(dfx_node, 0); > + if (WARN_ON(!base)) > + return; > + > + of_node_put(dfx_node); > + -> + parent_name =3D of_clk_get_parent_name(node, 0); +> + parent_name = of_clk_get_parent_name(node, 0); > + -> + clk_data.clk_num =3D 1; +> + clk_data.clk_num = 1; > + > + /* clks holds the clock array */ -> + clks =3D kcalloc(clk_data.clk_num, sizeof(struct clk *), +> + clks = kcalloc(clk_data.clk_num, sizeof(struct clk *), > + GFP_KERNEL); > + if (WARN_ON(!clks)) > + goto err_unmap; > + /* corediv holds the clock specific array */ -> + corediv =3D kcalloc(clk_data.clk_num, sizeof(struct clk_corediv), +> + corediv = kcalloc(clk_data.clk_num, sizeof(struct clk_corediv), > + GFP_KERNEL); > + if (WARN_ON(!corediv)) > + goto err_free_clks; @@ -372,19 +362,19 @@ ng rate, > + of_property_read_string_index(node, "clock-output-names", > + 0, &clk_name); > + -> + init.num_parents =3D 1; -> + init.parent_names =3D &parent_name; -> + init.name =3D clk_name; -> + init.ops =3D &ops; -> + init.flags =3D 0; +> + init.num_parents = 1; +> + init.parent_names = &parent_name; +> + init.name = clk_name; +> + init.ops = &ops; +> + init.flags = 0; > + -> + corediv[0].reg =3D (void *)((int)base + be32_to_cpu(*off)); -> + corediv[0].hw.init =3D &init; +> + corediv[0].reg = (void *)((int)base + be32_to_cpu(*off)); +> + corediv[0].hw.init = &init; > + -> + clks[0] =3D clk_register(NULL, &corediv[0].hw); +> + clks[0] = clk_register(NULL, &corediv[0].hw); > + WARN_ON(IS_ERR(clks[0])); > + -> + clk_data.clks =3D clks; +> + clk_data.clks = clks; > + of_clk_add_provider(node, of_clk_src_onecell_get, &clk_data); > + return; > + @@ -394,14 +384,13 @@ ng rate, > + iounmap(base); > +} > + -> +CLK_OF_DECLARE(mv98dx3236_corediv_clk, "marvell,mv98dx3236-corediv-clock= -", +> +CLK_OF_DECLARE(mv98dx3236_corediv_clk, "marvell,mv98dx3236-corediv-clock", > + mv98dx3236_corediv_clk_init); -> --=20 +> -- > 2.11.0.24.ge6920cf > ---=20 +-- Gregory Clement, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. diff --git a/a/content_digest b/N1/content_digest index d9c26bb..58a1ed3 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -1,22 +1,14 @@ "ref\020161222041328.3303-1-chris.packham@alliedtelesis.co.nz\0" "ref\020161222041328.3303-2-chris.packham@alliedtelesis.co.nz\0" - "From\0Gregory CLEMENT <gregory.clement@free-electrons.com>\0" - "Subject\0Re: [PATCH 1/5] clk: mvebu: support for 98DX3236 SoC\0" + "From\0gregory.clement@free-electrons.com (Gregory CLEMENT)\0" + "Subject\0[PATCH 1/5] clk: mvebu: support for 98DX3236 SoC\0" "Date\0Wed, 04 Jan 2017 18:32:08 +0100\0" - "To\0Chris Packham <chris.packham@alliedtelesis.co.nz>\0" - "Cc\0linux-arm-kernel@lists.infradead.org" - Michael Turquette <mturquette@baylibre.com> - Stephen Boyd <sboyd@codeaurora.org> - Thomas Petazzoni <thomas.petazzoni@free-electrons.com> - Russell King <rmk+kernel@arm.linux.org.uk> - linux-kernel@vger.kernel.org - " linux-clk@vger.kernel.org\0" + "To\0linux-arm-kernel@lists.infradead.org\0" "\00:1\0" "b\0" "Hi Chris,\n" - "=20\n" - " On jeu., d=C3=A9c. 22 2016, Chris Packham <chris.packham@alliedtelesis.co.=\n" - "nz> wrote:\n" + " \n" + " On jeu., d?c. 22 2016, Chris Packham <chris.packham@alliedtelesis.co.nz> wrote:\n" "\n" "> The 98DX3236, 98DX3336, 98DX4521 and variants have a different TCLK from\n" "> the Armada XP (200MHz vs 250MHz). The CPU core clock is fixed at 800MHz.\n" @@ -38,8 +30,7 @@ "> drivers/clk/mvebu/Makefile | 2 +-\n" "> drivers/clk/mvebu/armada-xp.c | 42 +++++++\n" "> drivers/clk/mvebu/clk-cpu.c | 33 +++++-\n" - "> drivers/clk/mvebu/mv98dx3236-corediv.c | 207 +++++++++++++++++++++++++++=\n" - "++++++\n" + "> drivers/clk/mvebu/mv98dx3236-corediv.c | 207 +++++++++++++++++++++++++++++++++\n" "> 4 files changed, 280 insertions(+), 4 deletions(-)\n" "> create mode 100644 drivers/clk/mvebu/mv98dx3236-corediv.c\n" ">\n" @@ -47,15 +38,15 @@ "> index d9ae97fb43c4..6a3681e3d6db 100644\n" "> --- a/drivers/clk/mvebu/Makefile\n" "> +++ b/drivers/clk/mvebu/Makefile\n" - "> @@ -9,7 +9,7 @@ obj-$(CONFIG_ARMADA_39X_CLK)\t+=3D armada-39x.o\n" - "> obj-$(CONFIG_ARMADA_37XX_CLK)\t+=3D armada-37xx-xtal.o\n" - "> obj-$(CONFIG_ARMADA_37XX_CLK)\t+=3D armada-37xx-tbg.o\n" - "> obj-$(CONFIG_ARMADA_37XX_CLK)\t+=3D armada-37xx-periph.o\n" - "> -obj-$(CONFIG_ARMADA_XP_CLK)\t+=3D armada-xp.o\n" - "> +obj-$(CONFIG_ARMADA_XP_CLK)\t+=3D armada-xp.o mv98dx3236-corediv.o\n" - "> obj-$(CONFIG_ARMADA_AP806_SYSCON) +=3D ap806-system-controller.o\n" - "> obj-$(CONFIG_ARMADA_CP110_SYSCON) +=3D cp110-system-controller.o\n" - "> obj-$(CONFIG_DOVE_CLK)\t\t+=3D dove.o dove-divider.o\n" + "> @@ -9,7 +9,7 @@ obj-$(CONFIG_ARMADA_39X_CLK)\t+= armada-39x.o\n" + "> obj-$(CONFIG_ARMADA_37XX_CLK)\t+= armada-37xx-xtal.o\n" + "> obj-$(CONFIG_ARMADA_37XX_CLK)\t+= armada-37xx-tbg.o\n" + "> obj-$(CONFIG_ARMADA_37XX_CLK)\t+= armada-37xx-periph.o\n" + "> -obj-$(CONFIG_ARMADA_XP_CLK)\t+= armada-xp.o\n" + "> +obj-$(CONFIG_ARMADA_XP_CLK)\t+= armada-xp.o mv98dx3236-corediv.o\n" + "> obj-$(CONFIG_ARMADA_AP806_SYSCON) += ap806-system-controller.o\n" + "> obj-$(CONFIG_ARMADA_CP110_SYSCON) += cp110-system-controller.o\n" + "> obj-$(CONFIG_DOVE_CLK)\t\t+= dove.o dove-divider.o\n" "> diff --git a/drivers/clk/mvebu/armada-xp.c b/drivers/clk/mvebu/armada-xp.c\n" "> index b3094315a3c0..0413bf8284e0 100644\n" "> --- a/drivers/clk/mvebu/armada-xp.c\n" @@ -63,52 +54,49 @@ "> @@ -52,6 +52,12 @@ static u32 __init axp_get_tclk_freq(void __iomem *sar)\n" "> \treturn 250000000;\n" "> }\n" - ">=20=20\n" + "> \n" "> +/* MV98DX3236 TCLK frequency is fixed to 200MHz */\n" "> +static u32 __init mv98dx3236_get_tclk_freq(void __iomem *sar)\n" "> +{\n" "> +\treturn 200000000;\n" "> +}\n" "> +\n" - "> static const u32 axp_cpu_freqs[] __initconst =3D {\n" + "> static const u32 axp_cpu_freqs[] __initconst = {\n" "> \t1000000000,\n" "> \t1066000000,\n" "> @@ -89,6 +95,12 @@ static u32 __init axp_get_cpu_freq(void __iomem *sar)\n" "> \treturn cpu_freq;\n" "> }\n" - ">=20=20\n" + "> \n" "> +/* MV98DX3236 CLK frequency is fixed to 800MHz */\n" "> +static u32 __init mv98dx3236_get_cpu_freq(void __iomem *sar)\n" "> +{\n" "> +\treturn 800000000;\n" "> +}\n" "> +\n" - "> static const int axp_nbclk_ratios[32][2] __initconst =3D {\n" + "> static const int axp_nbclk_ratios[32][2] __initconst = {\n" "> \t{0, 1}, {1, 2}, {2, 2}, {2, 2},\n" "> \t{1, 2}, {1, 2}, {1, 1}, {2, 3},\n" - "> @@ -158,6 +170,14 @@ static const struct coreclk_soc_desc axp_coreclks =\n" - "=3D {\n" - "> \t.num_ratios =3D ARRAY_SIZE(axp_coreclk_ratios),\n" + "> @@ -158,6 +170,14 @@ static const struct coreclk_soc_desc axp_coreclks = {\n" + "> \t.num_ratios = ARRAY_SIZE(axp_coreclk_ratios),\n" "> };\n" - ">=20=20\n" - "> +static const struct coreclk_soc_desc mv98dx3236_coreclks =3D {\n" - "> +\t.get_tclk_freq =3D mv98dx3236_get_tclk_freq,\n" - "> +\t.get_cpu_freq =3D mv98dx3236_get_cpu_freq,\n" - "> +\t.get_clk_ratio =3D NULL,\n" - "> +\t.ratios =3D NULL,\n" - "> +\t.num_ratios =3D 0,\n" + "> \n" + "> +static const struct coreclk_soc_desc mv98dx3236_coreclks = {\n" + "> +\t.get_tclk_freq = mv98dx3236_get_tclk_freq,\n" + "> +\t.get_cpu_freq = mv98dx3236_get_cpu_freq,\n" + "> +\t.get_clk_ratio = NULL,\n" + "> +\t.ratios = NULL,\n" + "> +\t.num_ratios = 0,\n" "> +};\n" "> +\n" "> /*\n" "> * Clock Gating Control\n" "> */\n" - "> @@ -195,6 +215,15 @@ static const struct clk_gating_soc_desc axp_gating_d=\n" - "esc[] __initconst =3D {\n" + "> @@ -195,6 +215,15 @@ static const struct clk_gating_soc_desc axp_gating_desc[] __initconst = {\n" "> \t{ }\n" "> };\n" - ">=20=20\n" - "> +static const struct clk_gating_soc_desc mv98dx3236_gating_desc[] __initc=\n" - "onst =3D {\n" + "> \n" + "> +static const struct clk_gating_soc_desc mv98dx3236_gating_desc[] __initconst = {\n" "> +\t{ \"ge1\", NULL, 3, 0 },\n" "> +\t{ \"ge0\", NULL, 4, 0 },\n" "> +\t{ \"pex00\", NULL, 5, 0 },\n" @@ -119,16 +107,15 @@ "> +\n" "> static void __init axp_clk_init(struct device_node *np)\n" "> {\n" - "> \tstruct device_node *cgnp =3D\n" - "> @@ -206,3 +235,16 @@ static void __init axp_clk_init(struct device_node *=\n" - "np)\n" + "> \tstruct device_node *cgnp =\n" + "> @@ -206,3 +235,16 @@ static void __init axp_clk_init(struct device_node *np)\n" "> \t\tmvebu_clk_gating_setup(cgnp, axp_gating_desc);\n" "> }\n" "> CLK_OF_DECLARE(axp_clk, \"marvell,armada-xp-core-clock\", axp_clk_init);\n" "> +\n" "> +static void __init mv98dx3236_clk_init(struct device_node *np)\n" "> +{\n" - "> +\tstruct device_node *cgnp =3D\n" + "> +\tstruct device_node *cgnp =\n" "> +\t\tof_find_compatible_node(NULL, NULL, \"marvell,armada-xp-gating-clock\");\n" "> +\n" "> +\tmvebu_coreclk_setup(np, &mv98dx3236_coreclks);\n" @@ -142,32 +129,30 @@ "> index 5837eb8a212f..29f295e7a36b 100644\n" "> --- a/drivers/clk/mvebu/clk-cpu.c\n" "> +++ b/drivers/clk/mvebu/clk-cpu.c\n" - "> @@ -165,7 +165,9 @@ static const struct clk_ops cpu_ops =3D {\n" - "> \t.set_rate =3D clk_cpu_set_rate,\n" + "> @@ -165,7 +165,9 @@ static const struct clk_ops cpu_ops = {\n" + "> \t.set_rate = clk_cpu_set_rate,\n" "> };\n" - ">=20=20\n" + "> \n" "> -static void __init of_cpu_clk_setup(struct device_node *node)\n" "> +/* Add parameter to allow this to support different clock operations. */\n" "> +static void __init _of_cpu_clk_setup(struct device_node *node,\n" "> +\t\t\tconst struct clk_ops *cpu_clk_ops)\n" "> {\n" "> \tstruct cpu_clk *cpuclk;\n" - "> \tvoid __iomem *clock_complex_base =3D of_iomap(node, 0);\n" - "> @@ -218,7 +220,7 @@ static void __init of_cpu_clk_setup(struct device_nod=\n" - "e *node)\n" - "> \t\tcpuclk[cpu].hw.init =3D &init;\n" - ">=20=20\n" - "> \t\tinit.name =3D cpuclk[cpu].clk_name;\n" - "> -\t\tinit.ops =3D &cpu_ops;\n" - "> +\t\tinit.ops =3D cpu_clk_ops;\n" - "> \t\tinit.flags =3D 0;\n" - "> \t\tinit.parent_names =3D &cpuclk[cpu].parent_name;\n" - "> \t\tinit.num_parents =3D 1;\n" - "> @@ -243,5 +245,30 @@ static void __init of_cpu_clk_setup(struct device_no=\n" - "de *node)\n" + "> \tvoid __iomem *clock_complex_base = of_iomap(node, 0);\n" + "> @@ -218,7 +220,7 @@ static void __init of_cpu_clk_setup(struct device_node *node)\n" + "> \t\tcpuclk[cpu].hw.init = &init;\n" + "> \n" + "> \t\tinit.name = cpuclk[cpu].clk_name;\n" + "> -\t\tinit.ops = &cpu_ops;\n" + "> +\t\tinit.ops = cpu_clk_ops;\n" + "> \t\tinit.flags = 0;\n" + "> \t\tinit.parent_names = &cpuclk[cpu].parent_name;\n" + "> \t\tinit.num_parents = 1;\n" + "> @@ -243,5 +245,30 @@ static void __init of_cpu_clk_setup(struct device_node *node)\n" "> \tiounmap(clock_complex_base);\n" "> }\n" - ">=20=20\n" + "> \n" "> +/* Use this function to call the generic setup with the correct\n" "> + * clock operation\n" "> + */\n" @@ -183,10 +168,10 @@ "> +/* Define the clock and operations for the mv98dx3236 - it cannot perform\n" "> + * any operations.\n" "> + */\n" - "> +static const struct clk_ops mv98dx3236_cpu_ops =3D {\n" - "> +\t.recalc_rate =3D NULL,\n" - "> +\t.round_rate =3D NULL,\n" - "> +\t.set_rate =3D NULL,\n" + "> +static const struct clk_ops mv98dx3236_cpu_ops = {\n" + "> +\t.recalc_rate = NULL,\n" + "> +\t.round_rate = NULL,\n" + "> +\t.set_rate = NULL,\n" "> +};\n" "> +\n" "> +static void __init of_mv98dx3236_cpu_clk_setup(struct device_node *node)\n" @@ -196,8 +181,7 @@ "> +\n" "> +CLK_OF_DECLARE(mv98dx3236_cpu_clock, \"marvell,mv98dx3236-cpu-clock\",\n" "> +\t\t\t\t\t of_mv98dx3236_cpu_clk_setup);\n" - "> diff --git a/drivers/clk/mvebu/mv98dx3236-corediv.c b/drivers/clk/mvebu/m=\n" - "v98dx3236-corediv.c\n" + "> diff --git a/drivers/clk/mvebu/mv98dx3236-corediv.c b/drivers/clk/mvebu/mv98dx3236-corediv.c\n" "> new file mode 100644\n" "> index 000000000000..3060764a8e5d\n" "> --- /dev/null\n" @@ -269,11 +253,11 @@ "> +static unsigned long mv98dx3236_corediv_recalc_rate(struct clk_hw *hwclk,\n" "> +\t\t\t\t\t unsigned long parent_rate)\n" "> +{\n" - "> +\tstruct clk_corediv *corediv =3D to_corediv_clk(hwclk);\n" + "> +\tstruct clk_corediv *corediv = to_corediv_clk(hwclk);\n" "> +\tu32 reg, div;\n" "> +\n" - "> +\treg =3D readl(corediv->reg + RATIO_REG_OFFSET);\n" - "> +\tdiv =3D (reg >> CLK_DIV_RATIO_NAND_OFFSET) & CLK_DIV_RATIO_NAND_MASK;\n" + "> +\treg = readl(corediv->reg + RATIO_REG_OFFSET);\n" + "> +\tdiv = (reg >> CLK_DIV_RATIO_NAND_OFFSET) & CLK_DIV_RATIO_NAND_MASK;\n" "> +\treturn parent_rate / div;\n" "> +}\n" "> +\n" @@ -283,39 +267,38 @@ "> +\t/* Valid ratio are 1:4, 1:5, 1:6 and 1:8 */\n" "> +\tu32 div;\n" "> +\n" - "> +\tdiv =3D *parent_rate / rate;\n" + "> +\tdiv = *parent_rate / rate;\n" "> +\tif (div < 4)\n" - "> +\t\tdiv =3D 4;\n" + "> +\t\tdiv = 4;\n" "> +\telse if (div > 6)\n" - "> +\t\tdiv =3D 8;\n" + "> +\t\tdiv = 8;\n" "> +\n" "> +\treturn *parent_rate / div;\n" "> +}\n" "> +\n" - "> +static int mv98dx3236_corediv_set_rate(struct clk_hw *hwclk, unsigned lo=\n" - "ng rate,\n" + "> +static int mv98dx3236_corediv_set_rate(struct clk_hw *hwclk, unsigned long rate,\n" "> +\t\t\t unsigned long parent_rate)\n" "> +{\n" - "> +\tstruct clk_corediv *corediv =3D to_corediv_clk(hwclk);\n" - "> +\tunsigned long flags =3D 0;\n" + "> +\tstruct clk_corediv *corediv = to_corediv_clk(hwclk);\n" + "> +\tunsigned long flags = 0;\n" "> +\tu32 reg, div;\n" "> +\n" - "> +\tdiv =3D parent_rate / rate;\n" + "> +\tdiv = parent_rate / rate;\n" "> +\n" "> +\tspin_lock_irqsave(&corediv->lock, flags);\n" "> +\n" "> +\t/* Write new divider to the divider ratio register */\n" - "> +\treg =3D readl(corediv->reg + RATIO_REG_OFFSET);\n" - "> +\treg &=3D ~(CLK_DIV_RATIO_NAND_MASK << CLK_DIV_RATIO_NAND_OFFSET);\n" - "> +\treg |=3D (div & CLK_DIV_RATIO_NAND_MASK) << CLK_DIV_RATIO_NAND_OFFSET;\n" + "> +\treg = readl(corediv->reg + RATIO_REG_OFFSET);\n" + "> +\treg &= ~(CLK_DIV_RATIO_NAND_MASK << CLK_DIV_RATIO_NAND_OFFSET);\n" + "> +\treg |= (div & CLK_DIV_RATIO_NAND_MASK) << CLK_DIV_RATIO_NAND_OFFSET;\n" "> +\twritel(reg, corediv->reg + RATIO_REG_OFFSET);\n" "> +\n" "> +\t/* Set reload-force for this clock */\n" - "> +\treg =3D readl(corediv->reg) | BIT(CLK_DIV_RATIO_NAND_FORCE_RELOAD_BIT);\n" + "> +\treg = readl(corediv->reg) | BIT(CLK_DIV_RATIO_NAND_FORCE_RELOAD_BIT);\n" "> +\twritel(reg, corediv->reg);\n" "> +\n" "> +\t/* Now trigger the clock update */\n" - "> +\treg =3D readl(corediv->reg + RATIO_REG_OFFSET) | RATIO_RELOAD_BIT;\n" + "> +\treg = readl(corediv->reg + RATIO_REG_OFFSET) | RATIO_RELOAD_BIT;\n" "> +\twritel(reg, corediv->reg + RATIO_REG_OFFSET);\n" "> +\n" "> +\t/*\n" @@ -323,7 +306,7 @@ "> +\t * ratios request and the reload request.\n" "> +\t */\n" "> +\tudelay(1000);\n" - "> +\treg &=3D ~(CORE_CLK_DIV_RATIO_MASK | RATIO_RELOAD_BIT);\n" + "> +\treg &= ~(CORE_CLK_DIV_RATIO_MASK | RATIO_RELOAD_BIT);\n" "> +\twritel(reg, corediv->reg + RATIO_REG_OFFSET);\n" "> +\tudelay(1000);\n" "> +\n" @@ -332,13 +315,13 @@ "> +\treturn 0;\n" "> +}\n" "> +\n" - "> +static const struct clk_ops ops =3D {\n" - "> +\t.enable =3D mv98dx3236_corediv_enable,\n" - "> +\t.disable =3D mv98dx3236_corediv_disable,\n" - "> +\t.is_enabled =3D mv98dx3236_corediv_is_enabled,\n" - "> +\t.recalc_rate =3D mv98dx3236_corediv_recalc_rate,\n" - "> +\t.round_rate =3D mv98dx3236_corediv_round_rate,\n" - "> +\t.set_rate =3D mv98dx3236_corediv_set_rate,\n" + "> +static const struct clk_ops ops = {\n" + "> +\t.enable = mv98dx3236_corediv_enable,\n" + "> +\t.disable = mv98dx3236_corediv_disable,\n" + "> +\t.is_enabled = mv98dx3236_corediv_is_enabled,\n" + "> +\t.recalc_rate = mv98dx3236_corediv_recalc_rate,\n" + "> +\t.round_rate = mv98dx3236_corediv_round_rate,\n" + "> +\t.set_rate = mv98dx3236_corediv_set_rate,\n" "> +};\n" "> +\n" "> +static void __init mv98dx3236_corediv_clk_init(struct device_node *node)\n" @@ -353,31 +336,31 @@ "> +\tint len;\n" "> +\tstruct device_node *dfx_node;\n" "> +\n" - "> +\tdfx_node =3D of_parse_phandle(node, \"base\", 0);\n" + "> +\tdfx_node = of_parse_phandle(node, \"base\", 0);\n" "> +\tif (WARN_ON(!dfx_node))\n" "> +\t\treturn;\n" "> +\n" - "> +\toff =3D of_get_property(node, \"reg\", &len);\n" + "> +\toff = of_get_property(node, \"reg\", &len);\n" "> +\tif (WARN_ON(!off))\n" "> +\t\treturn;\n" "> +\n" - "> +\tbase =3D of_iomap(dfx_node, 0);\n" + "> +\tbase = of_iomap(dfx_node, 0);\n" "> +\tif (WARN_ON(!base))\n" "> +\t\treturn;\n" "> +\n" "> +\tof_node_put(dfx_node);\n" "> +\n" - "> +\tparent_name =3D of_clk_get_parent_name(node, 0);\n" + "> +\tparent_name = of_clk_get_parent_name(node, 0);\n" "> +\n" - "> +\tclk_data.clk_num =3D 1;\n" + "> +\tclk_data.clk_num = 1;\n" "> +\n" "> +\t/* clks holds the clock array */\n" - "> +\tclks =3D kcalloc(clk_data.clk_num, sizeof(struct clk *),\n" + "> +\tclks = kcalloc(clk_data.clk_num, sizeof(struct clk *),\n" "> +\t\t\t\tGFP_KERNEL);\n" "> +\tif (WARN_ON(!clks))\n" "> +\t\tgoto err_unmap;\n" "> +\t/* corediv holds the clock specific array */\n" - "> +\tcorediv =3D kcalloc(clk_data.clk_num, sizeof(struct clk_corediv),\n" + "> +\tcorediv = kcalloc(clk_data.clk_num, sizeof(struct clk_corediv),\n" "> +\t\t\t\tGFP_KERNEL);\n" "> +\tif (WARN_ON(!corediv))\n" "> +\t\tgoto err_free_clks;\n" @@ -387,19 +370,19 @@ "> +\tof_property_read_string_index(node, \"clock-output-names\",\n" "> +\t\t\t\t\t 0, &clk_name);\n" "> +\n" - "> +\tinit.num_parents =3D 1;\n" - "> +\tinit.parent_names =3D &parent_name;\n" - "> +\tinit.name =3D clk_name;\n" - "> +\tinit.ops =3D &ops;\n" - "> +\tinit.flags =3D 0;\n" + "> +\tinit.num_parents = 1;\n" + "> +\tinit.parent_names = &parent_name;\n" + "> +\tinit.name = clk_name;\n" + "> +\tinit.ops = &ops;\n" + "> +\tinit.flags = 0;\n" "> +\n" - "> +\tcorediv[0].reg =3D (void *)((int)base + be32_to_cpu(*off));\n" - "> +\tcorediv[0].hw.init =3D &init;\n" + "> +\tcorediv[0].reg = (void *)((int)base + be32_to_cpu(*off));\n" + "> +\tcorediv[0].hw.init = &init;\n" "> +\n" - "> +\tclks[0] =3D clk_register(NULL, &corediv[0].hw);\n" + "> +\tclks[0] = clk_register(NULL, &corediv[0].hw);\n" "> +\tWARN_ON(IS_ERR(clks[0]));\n" "> +\n" - "> +\tclk_data.clks =3D clks;\n" + "> +\tclk_data.clks = clks;\n" "> +\tof_clk_add_provider(node, of_clk_src_onecell_get, &clk_data);\n" "> +\treturn;\n" "> +\n" @@ -409,17 +392,16 @@ "> +\tiounmap(base);\n" "> +}\n" "> +\n" - "> +CLK_OF_DECLARE(mv98dx3236_corediv_clk, \"marvell,mv98dx3236-corediv-clock=\n" - "\",\n" + "> +CLK_OF_DECLARE(mv98dx3236_corediv_clk, \"marvell,mv98dx3236-corediv-clock\",\n" "> +\t mv98dx3236_corediv_clk_init);\n" - "> --=20\n" + "> -- \n" "> 2.11.0.24.ge6920cf\n" ">\n" "\n" - "--=20\n" + "-- \n" "Gregory Clement, Free Electrons\n" "Kernel, drivers, real-time and embedded Linux\n" "development, consulting, training and support.\n" http://free-electrons.com -685f45185818579661e3e31d8ea5378eb3bd9bf69dbe1cc8c69a28376dff9640 +d520e1d06e228a778b035c7873ac3b7f08e250c3737a8b2d1ebdcbbbf78192b4
diff --git a/a/1.txt b/N2/1.txt index 03a10ae..0b054e5 100644 --- a/a/1.txt +++ b/N2/1.txt @@ -1,7 +1,6 @@ Hi Chris, -=20 - On jeu., d=C3=A9c. 22 2016, Chris Packham <chris.packham@alliedtelesis.co.= -nz> wrote: + + On jeu., déc. 22 2016, Chris Packham <chris.packham@alliedtelesis.co.nz> wrote: > The 98DX3236, 98DX3336, 98DX4521 and variants have a different TCLK from > the Armada XP (200MHz vs 250MHz). The CPU core clock is fixed at 800MHz. @@ -23,8 +22,7 @@ Gregory > drivers/clk/mvebu/Makefile | 2 +- > drivers/clk/mvebu/armada-xp.c | 42 +++++++ > drivers/clk/mvebu/clk-cpu.c | 33 +++++- -> drivers/clk/mvebu/mv98dx3236-corediv.c | 207 +++++++++++++++++++++++++++= -++++++ +> drivers/clk/mvebu/mv98dx3236-corediv.c | 207 +++++++++++++++++++++++++++++++++ > 4 files changed, 280 insertions(+), 4 deletions(-) > create mode 100644 drivers/clk/mvebu/mv98dx3236-corediv.c > @@ -32,15 +30,15 @@ Gregory > index d9ae97fb43c4..6a3681e3d6db 100644 > --- a/drivers/clk/mvebu/Makefile > +++ b/drivers/clk/mvebu/Makefile -> @@ -9,7 +9,7 @@ obj-$(CONFIG_ARMADA_39X_CLK) +=3D armada-39x.o -> obj-$(CONFIG_ARMADA_37XX_CLK) +=3D armada-37xx-xtal.o -> obj-$(CONFIG_ARMADA_37XX_CLK) +=3D armada-37xx-tbg.o -> obj-$(CONFIG_ARMADA_37XX_CLK) +=3D armada-37xx-periph.o -> -obj-$(CONFIG_ARMADA_XP_CLK) +=3D armada-xp.o -> +obj-$(CONFIG_ARMADA_XP_CLK) +=3D armada-xp.o mv98dx3236-corediv.o -> obj-$(CONFIG_ARMADA_AP806_SYSCON) +=3D ap806-system-controller.o -> obj-$(CONFIG_ARMADA_CP110_SYSCON) +=3D cp110-system-controller.o -> obj-$(CONFIG_DOVE_CLK) +=3D dove.o dove-divider.o +> @@ -9,7 +9,7 @@ obj-$(CONFIG_ARMADA_39X_CLK) += armada-39x.o +> obj-$(CONFIG_ARMADA_37XX_CLK) += armada-37xx-xtal.o +> obj-$(CONFIG_ARMADA_37XX_CLK) += armada-37xx-tbg.o +> obj-$(CONFIG_ARMADA_37XX_CLK) += armada-37xx-periph.o +> -obj-$(CONFIG_ARMADA_XP_CLK) += armada-xp.o +> +obj-$(CONFIG_ARMADA_XP_CLK) += armada-xp.o mv98dx3236-corediv.o +> obj-$(CONFIG_ARMADA_AP806_SYSCON) += ap806-system-controller.o +> obj-$(CONFIG_ARMADA_CP110_SYSCON) += cp110-system-controller.o +> obj-$(CONFIG_DOVE_CLK) += dove.o dove-divider.o > diff --git a/drivers/clk/mvebu/armada-xp.c b/drivers/clk/mvebu/armada-xp.c > index b3094315a3c0..0413bf8284e0 100644 > --- a/drivers/clk/mvebu/armada-xp.c @@ -48,52 +46,49 @@ Gregory > @@ -52,6 +52,12 @@ static u32 __init axp_get_tclk_freq(void __iomem *sar) > return 250000000; > } ->=20=20 +> > +/* MV98DX3236 TCLK frequency is fixed to 200MHz */ > +static u32 __init mv98dx3236_get_tclk_freq(void __iomem *sar) > +{ > + return 200000000; > +} > + -> static const u32 axp_cpu_freqs[] __initconst =3D { +> static const u32 axp_cpu_freqs[] __initconst = { > 1000000000, > 1066000000, > @@ -89,6 +95,12 @@ static u32 __init axp_get_cpu_freq(void __iomem *sar) > return cpu_freq; > } ->=20=20 +> > +/* MV98DX3236 CLK frequency is fixed to 800MHz */ > +static u32 __init mv98dx3236_get_cpu_freq(void __iomem *sar) > +{ > + return 800000000; > +} > + -> static const int axp_nbclk_ratios[32][2] __initconst =3D { +> static const int axp_nbclk_ratios[32][2] __initconst = { > {0, 1}, {1, 2}, {2, 2}, {2, 2}, > {1, 2}, {1, 2}, {1, 1}, {2, 3}, -> @@ -158,6 +170,14 @@ static const struct coreclk_soc_desc axp_coreclks = -=3D { -> .num_ratios =3D ARRAY_SIZE(axp_coreclk_ratios), +> @@ -158,6 +170,14 @@ static const struct coreclk_soc_desc axp_coreclks = { +> .num_ratios = ARRAY_SIZE(axp_coreclk_ratios), > }; ->=20=20 -> +static const struct coreclk_soc_desc mv98dx3236_coreclks =3D { -> + .get_tclk_freq =3D mv98dx3236_get_tclk_freq, -> + .get_cpu_freq =3D mv98dx3236_get_cpu_freq, -> + .get_clk_ratio =3D NULL, -> + .ratios =3D NULL, -> + .num_ratios =3D 0, +> +> +static const struct coreclk_soc_desc mv98dx3236_coreclks = { +> + .get_tclk_freq = mv98dx3236_get_tclk_freq, +> + .get_cpu_freq = mv98dx3236_get_cpu_freq, +> + .get_clk_ratio = NULL, +> + .ratios = NULL, +> + .num_ratios = 0, > +}; > + > /* > * Clock Gating Control > */ -> @@ -195,6 +215,15 @@ static const struct clk_gating_soc_desc axp_gating_d= -esc[] __initconst =3D { +> @@ -195,6 +215,15 @@ static const struct clk_gating_soc_desc axp_gating_desc[] __initconst = { > { } > }; ->=20=20 -> +static const struct clk_gating_soc_desc mv98dx3236_gating_desc[] __initc= -onst =3D { +> +> +static const struct clk_gating_soc_desc mv98dx3236_gating_desc[] __initconst = { > + { "ge1", NULL, 3, 0 }, > + { "ge0", NULL, 4, 0 }, > + { "pex00", NULL, 5, 0 }, @@ -104,16 +99,15 @@ onst =3D { > + > static void __init axp_clk_init(struct device_node *np) > { -> struct device_node *cgnp =3D -> @@ -206,3 +235,16 @@ static void __init axp_clk_init(struct device_node *= -np) +> struct device_node *cgnp = +> @@ -206,3 +235,16 @@ static void __init axp_clk_init(struct device_node *np) > mvebu_clk_gating_setup(cgnp, axp_gating_desc); > } > CLK_OF_DECLARE(axp_clk, "marvell,armada-xp-core-clock", axp_clk_init); > + > +static void __init mv98dx3236_clk_init(struct device_node *np) > +{ -> + struct device_node *cgnp =3D +> + struct device_node *cgnp = > + of_find_compatible_node(NULL, NULL, "marvell,armada-xp-gating-clock"); > + > + mvebu_coreclk_setup(np, &mv98dx3236_coreclks); @@ -127,32 +121,30 @@ np) > index 5837eb8a212f..29f295e7a36b 100644 > --- a/drivers/clk/mvebu/clk-cpu.c > +++ b/drivers/clk/mvebu/clk-cpu.c -> @@ -165,7 +165,9 @@ static const struct clk_ops cpu_ops =3D { -> .set_rate =3D clk_cpu_set_rate, +> @@ -165,7 +165,9 @@ static const struct clk_ops cpu_ops = { +> .set_rate = clk_cpu_set_rate, > }; ->=20=20 +> > -static void __init of_cpu_clk_setup(struct device_node *node) > +/* Add parameter to allow this to support different clock operations. */ > +static void __init _of_cpu_clk_setup(struct device_node *node, > + const struct clk_ops *cpu_clk_ops) > { > struct cpu_clk *cpuclk; -> void __iomem *clock_complex_base =3D of_iomap(node, 0); -> @@ -218,7 +220,7 @@ static void __init of_cpu_clk_setup(struct device_nod= -e *node) -> cpuclk[cpu].hw.init =3D &init; ->=20=20 -> init.name =3D cpuclk[cpu].clk_name; -> - init.ops =3D &cpu_ops; -> + init.ops =3D cpu_clk_ops; -> init.flags =3D 0; -> init.parent_names =3D &cpuclk[cpu].parent_name; -> init.num_parents =3D 1; -> @@ -243,5 +245,30 @@ static void __init of_cpu_clk_setup(struct device_no= -de *node) +> void __iomem *clock_complex_base = of_iomap(node, 0); +> @@ -218,7 +220,7 @@ static void __init of_cpu_clk_setup(struct device_node *node) +> cpuclk[cpu].hw.init = &init; +> +> init.name = cpuclk[cpu].clk_name; +> - init.ops = &cpu_ops; +> + init.ops = cpu_clk_ops; +> init.flags = 0; +> init.parent_names = &cpuclk[cpu].parent_name; +> init.num_parents = 1; +> @@ -243,5 +245,30 @@ static void __init of_cpu_clk_setup(struct device_node *node) > iounmap(clock_complex_base); > } ->=20=20 +> > +/* Use this function to call the generic setup with the correct > + * clock operation > + */ @@ -168,10 +160,10 @@ de *node) > +/* Define the clock and operations for the mv98dx3236 - it cannot perform > + * any operations. > + */ -> +static const struct clk_ops mv98dx3236_cpu_ops =3D { -> + .recalc_rate =3D NULL, -> + .round_rate =3D NULL, -> + .set_rate =3D NULL, +> +static const struct clk_ops mv98dx3236_cpu_ops = { +> + .recalc_rate = NULL, +> + .round_rate = NULL, +> + .set_rate = NULL, > +}; > + > +static void __init of_mv98dx3236_cpu_clk_setup(struct device_node *node) @@ -181,8 +173,7 @@ de *node) > + > +CLK_OF_DECLARE(mv98dx3236_cpu_clock, "marvell,mv98dx3236-cpu-clock", > + of_mv98dx3236_cpu_clk_setup); -> diff --git a/drivers/clk/mvebu/mv98dx3236-corediv.c b/drivers/clk/mvebu/m= -v98dx3236-corediv.c +> diff --git a/drivers/clk/mvebu/mv98dx3236-corediv.c b/drivers/clk/mvebu/mv98dx3236-corediv.c > new file mode 100644 > index 000000000000..3060764a8e5d > --- /dev/null @@ -254,11 +245,11 @@ v98dx3236-corediv.c > +static unsigned long mv98dx3236_corediv_recalc_rate(struct clk_hw *hwclk, > + unsigned long parent_rate) > +{ -> + struct clk_corediv *corediv =3D to_corediv_clk(hwclk); +> + struct clk_corediv *corediv = to_corediv_clk(hwclk); > + u32 reg, div; > + -> + reg =3D readl(corediv->reg + RATIO_REG_OFFSET); -> + div =3D (reg >> CLK_DIV_RATIO_NAND_OFFSET) & CLK_DIV_RATIO_NAND_MASK; +> + reg = readl(corediv->reg + RATIO_REG_OFFSET); +> + div = (reg >> CLK_DIV_RATIO_NAND_OFFSET) & CLK_DIV_RATIO_NAND_MASK; > + return parent_rate / div; > +} > + @@ -268,39 +259,38 @@ v98dx3236-corediv.c > + /* Valid ratio are 1:4, 1:5, 1:6 and 1:8 */ > + u32 div; > + -> + div =3D *parent_rate / rate; +> + div = *parent_rate / rate; > + if (div < 4) -> + div =3D 4; +> + div = 4; > + else if (div > 6) -> + div =3D 8; +> + div = 8; > + > + return *parent_rate / div; > +} > + -> +static int mv98dx3236_corediv_set_rate(struct clk_hw *hwclk, unsigned lo= -ng rate, +> +static int mv98dx3236_corediv_set_rate(struct clk_hw *hwclk, unsigned long rate, > + unsigned long parent_rate) > +{ -> + struct clk_corediv *corediv =3D to_corediv_clk(hwclk); -> + unsigned long flags =3D 0; +> + struct clk_corediv *corediv = to_corediv_clk(hwclk); +> + unsigned long flags = 0; > + u32 reg, div; > + -> + div =3D parent_rate / rate; +> + div = parent_rate / rate; > + > + spin_lock_irqsave(&corediv->lock, flags); > + > + /* Write new divider to the divider ratio register */ -> + reg =3D readl(corediv->reg + RATIO_REG_OFFSET); -> + reg &=3D ~(CLK_DIV_RATIO_NAND_MASK << CLK_DIV_RATIO_NAND_OFFSET); -> + reg |=3D (div & CLK_DIV_RATIO_NAND_MASK) << CLK_DIV_RATIO_NAND_OFFSET; +> + reg = readl(corediv->reg + RATIO_REG_OFFSET); +> + reg &= ~(CLK_DIV_RATIO_NAND_MASK << CLK_DIV_RATIO_NAND_OFFSET); +> + reg |= (div & CLK_DIV_RATIO_NAND_MASK) << CLK_DIV_RATIO_NAND_OFFSET; > + writel(reg, corediv->reg + RATIO_REG_OFFSET); > + > + /* Set reload-force for this clock */ -> + reg =3D readl(corediv->reg) | BIT(CLK_DIV_RATIO_NAND_FORCE_RELOAD_BIT); +> + reg = readl(corediv->reg) | BIT(CLK_DIV_RATIO_NAND_FORCE_RELOAD_BIT); > + writel(reg, corediv->reg); > + > + /* Now trigger the clock update */ -> + reg =3D readl(corediv->reg + RATIO_REG_OFFSET) | RATIO_RELOAD_BIT; +> + reg = readl(corediv->reg + RATIO_REG_OFFSET) | RATIO_RELOAD_BIT; > + writel(reg, corediv->reg + RATIO_REG_OFFSET); > + > + /* @@ -308,7 +298,7 @@ ng rate, > + * ratios request and the reload request. > + */ > + udelay(1000); -> + reg &=3D ~(CORE_CLK_DIV_RATIO_MASK | RATIO_RELOAD_BIT); +> + reg &= ~(CORE_CLK_DIV_RATIO_MASK | RATIO_RELOAD_BIT); > + writel(reg, corediv->reg + RATIO_REG_OFFSET); > + udelay(1000); > + @@ -317,13 +307,13 @@ ng rate, > + return 0; > +} > + -> +static const struct clk_ops ops =3D { -> + .enable =3D mv98dx3236_corediv_enable, -> + .disable =3D mv98dx3236_corediv_disable, -> + .is_enabled =3D mv98dx3236_corediv_is_enabled, -> + .recalc_rate =3D mv98dx3236_corediv_recalc_rate, -> + .round_rate =3D mv98dx3236_corediv_round_rate, -> + .set_rate =3D mv98dx3236_corediv_set_rate, +> +static const struct clk_ops ops = { +> + .enable = mv98dx3236_corediv_enable, +> + .disable = mv98dx3236_corediv_disable, +> + .is_enabled = mv98dx3236_corediv_is_enabled, +> + .recalc_rate = mv98dx3236_corediv_recalc_rate, +> + .round_rate = mv98dx3236_corediv_round_rate, +> + .set_rate = mv98dx3236_corediv_set_rate, > +}; > + > +static void __init mv98dx3236_corediv_clk_init(struct device_node *node) @@ -338,31 +328,31 @@ ng rate, > + int len; > + struct device_node *dfx_node; > + -> + dfx_node =3D of_parse_phandle(node, "base", 0); +> + dfx_node = of_parse_phandle(node, "base", 0); > + if (WARN_ON(!dfx_node)) > + return; > + -> + off =3D of_get_property(node, "reg", &len); +> + off = of_get_property(node, "reg", &len); > + if (WARN_ON(!off)) > + return; > + -> + base =3D of_iomap(dfx_node, 0); +> + base = of_iomap(dfx_node, 0); > + if (WARN_ON(!base)) > + return; > + > + of_node_put(dfx_node); > + -> + parent_name =3D of_clk_get_parent_name(node, 0); +> + parent_name = of_clk_get_parent_name(node, 0); > + -> + clk_data.clk_num =3D 1; +> + clk_data.clk_num = 1; > + > + /* clks holds the clock array */ -> + clks =3D kcalloc(clk_data.clk_num, sizeof(struct clk *), +> + clks = kcalloc(clk_data.clk_num, sizeof(struct clk *), > + GFP_KERNEL); > + if (WARN_ON(!clks)) > + goto err_unmap; > + /* corediv holds the clock specific array */ -> + corediv =3D kcalloc(clk_data.clk_num, sizeof(struct clk_corediv), +> + corediv = kcalloc(clk_data.clk_num, sizeof(struct clk_corediv), > + GFP_KERNEL); > + if (WARN_ON(!corediv)) > + goto err_free_clks; @@ -372,19 +362,19 @@ ng rate, > + of_property_read_string_index(node, "clock-output-names", > + 0, &clk_name); > + -> + init.num_parents =3D 1; -> + init.parent_names =3D &parent_name; -> + init.name =3D clk_name; -> + init.ops =3D &ops; -> + init.flags =3D 0; +> + init.num_parents = 1; +> + init.parent_names = &parent_name; +> + init.name = clk_name; +> + init.ops = &ops; +> + init.flags = 0; > + -> + corediv[0].reg =3D (void *)((int)base + be32_to_cpu(*off)); -> + corediv[0].hw.init =3D &init; +> + corediv[0].reg = (void *)((int)base + be32_to_cpu(*off)); +> + corediv[0].hw.init = &init; > + -> + clks[0] =3D clk_register(NULL, &corediv[0].hw); +> + clks[0] = clk_register(NULL, &corediv[0].hw); > + WARN_ON(IS_ERR(clks[0])); > + -> + clk_data.clks =3D clks; +> + clk_data.clks = clks; > + of_clk_add_provider(node, of_clk_src_onecell_get, &clk_data); > + return; > + @@ -394,14 +384,13 @@ ng rate, > + iounmap(base); > +} > + -> +CLK_OF_DECLARE(mv98dx3236_corediv_clk, "marvell,mv98dx3236-corediv-clock= -", +> +CLK_OF_DECLARE(mv98dx3236_corediv_clk, "marvell,mv98dx3236-corediv-clock", > + mv98dx3236_corediv_clk_init); -> --=20 +> -- > 2.11.0.24.ge6920cf > ---=20 +-- Gregory Clement, Free Electrons Kernel, drivers, real-time and embedded Linux development, consulting, training and support. diff --git a/a/content_digest b/N2/content_digest index d9c26bb..29e0318 100644 --- a/a/content_digest +++ b/N2/content_digest @@ -14,9 +14,8 @@ "\00:1\0" "b\0" "Hi Chris,\n" - "=20\n" - " On jeu., d=C3=A9c. 22 2016, Chris Packham <chris.packham@alliedtelesis.co.=\n" - "nz> wrote:\n" + " \n" + " On jeu., d\303\251c. 22 2016, Chris Packham <chris.packham@alliedtelesis.co.nz> wrote:\n" "\n" "> The 98DX3236, 98DX3336, 98DX4521 and variants have a different TCLK from\n" "> the Armada XP (200MHz vs 250MHz). The CPU core clock is fixed at 800MHz.\n" @@ -38,8 +37,7 @@ "> drivers/clk/mvebu/Makefile | 2 +-\n" "> drivers/clk/mvebu/armada-xp.c | 42 +++++++\n" "> drivers/clk/mvebu/clk-cpu.c | 33 +++++-\n" - "> drivers/clk/mvebu/mv98dx3236-corediv.c | 207 +++++++++++++++++++++++++++=\n" - "++++++\n" + "> drivers/clk/mvebu/mv98dx3236-corediv.c | 207 +++++++++++++++++++++++++++++++++\n" "> 4 files changed, 280 insertions(+), 4 deletions(-)\n" "> create mode 100644 drivers/clk/mvebu/mv98dx3236-corediv.c\n" ">\n" @@ -47,15 +45,15 @@ "> index d9ae97fb43c4..6a3681e3d6db 100644\n" "> --- a/drivers/clk/mvebu/Makefile\n" "> +++ b/drivers/clk/mvebu/Makefile\n" - "> @@ -9,7 +9,7 @@ obj-$(CONFIG_ARMADA_39X_CLK)\t+=3D armada-39x.o\n" - "> obj-$(CONFIG_ARMADA_37XX_CLK)\t+=3D armada-37xx-xtal.o\n" - "> obj-$(CONFIG_ARMADA_37XX_CLK)\t+=3D armada-37xx-tbg.o\n" - "> obj-$(CONFIG_ARMADA_37XX_CLK)\t+=3D armada-37xx-periph.o\n" - "> -obj-$(CONFIG_ARMADA_XP_CLK)\t+=3D armada-xp.o\n" - "> +obj-$(CONFIG_ARMADA_XP_CLK)\t+=3D armada-xp.o mv98dx3236-corediv.o\n" - "> obj-$(CONFIG_ARMADA_AP806_SYSCON) +=3D ap806-system-controller.o\n" - "> obj-$(CONFIG_ARMADA_CP110_SYSCON) +=3D cp110-system-controller.o\n" - "> obj-$(CONFIG_DOVE_CLK)\t\t+=3D dove.o dove-divider.o\n" + "> @@ -9,7 +9,7 @@ obj-$(CONFIG_ARMADA_39X_CLK)\t+= armada-39x.o\n" + "> obj-$(CONFIG_ARMADA_37XX_CLK)\t+= armada-37xx-xtal.o\n" + "> obj-$(CONFIG_ARMADA_37XX_CLK)\t+= armada-37xx-tbg.o\n" + "> obj-$(CONFIG_ARMADA_37XX_CLK)\t+= armada-37xx-periph.o\n" + "> -obj-$(CONFIG_ARMADA_XP_CLK)\t+= armada-xp.o\n" + "> +obj-$(CONFIG_ARMADA_XP_CLK)\t+= armada-xp.o mv98dx3236-corediv.o\n" + "> obj-$(CONFIG_ARMADA_AP806_SYSCON) += ap806-system-controller.o\n" + "> obj-$(CONFIG_ARMADA_CP110_SYSCON) += cp110-system-controller.o\n" + "> obj-$(CONFIG_DOVE_CLK)\t\t+= dove.o dove-divider.o\n" "> diff --git a/drivers/clk/mvebu/armada-xp.c b/drivers/clk/mvebu/armada-xp.c\n" "> index b3094315a3c0..0413bf8284e0 100644\n" "> --- a/drivers/clk/mvebu/armada-xp.c\n" @@ -63,52 +61,49 @@ "> @@ -52,6 +52,12 @@ static u32 __init axp_get_tclk_freq(void __iomem *sar)\n" "> \treturn 250000000;\n" "> }\n" - ">=20=20\n" + "> \n" "> +/* MV98DX3236 TCLK frequency is fixed to 200MHz */\n" "> +static u32 __init mv98dx3236_get_tclk_freq(void __iomem *sar)\n" "> +{\n" "> +\treturn 200000000;\n" "> +}\n" "> +\n" - "> static const u32 axp_cpu_freqs[] __initconst =3D {\n" + "> static const u32 axp_cpu_freqs[] __initconst = {\n" "> \t1000000000,\n" "> \t1066000000,\n" "> @@ -89,6 +95,12 @@ static u32 __init axp_get_cpu_freq(void __iomem *sar)\n" "> \treturn cpu_freq;\n" "> }\n" - ">=20=20\n" + "> \n" "> +/* MV98DX3236 CLK frequency is fixed to 800MHz */\n" "> +static u32 __init mv98dx3236_get_cpu_freq(void __iomem *sar)\n" "> +{\n" "> +\treturn 800000000;\n" "> +}\n" "> +\n" - "> static const int axp_nbclk_ratios[32][2] __initconst =3D {\n" + "> static const int axp_nbclk_ratios[32][2] __initconst = {\n" "> \t{0, 1}, {1, 2}, {2, 2}, {2, 2},\n" "> \t{1, 2}, {1, 2}, {1, 1}, {2, 3},\n" - "> @@ -158,6 +170,14 @@ static const struct coreclk_soc_desc axp_coreclks =\n" - "=3D {\n" - "> \t.num_ratios =3D ARRAY_SIZE(axp_coreclk_ratios),\n" + "> @@ -158,6 +170,14 @@ static const struct coreclk_soc_desc axp_coreclks = {\n" + "> \t.num_ratios = ARRAY_SIZE(axp_coreclk_ratios),\n" "> };\n" - ">=20=20\n" - "> +static const struct coreclk_soc_desc mv98dx3236_coreclks =3D {\n" - "> +\t.get_tclk_freq =3D mv98dx3236_get_tclk_freq,\n" - "> +\t.get_cpu_freq =3D mv98dx3236_get_cpu_freq,\n" - "> +\t.get_clk_ratio =3D NULL,\n" - "> +\t.ratios =3D NULL,\n" - "> +\t.num_ratios =3D 0,\n" + "> \n" + "> +static const struct coreclk_soc_desc mv98dx3236_coreclks = {\n" + "> +\t.get_tclk_freq = mv98dx3236_get_tclk_freq,\n" + "> +\t.get_cpu_freq = mv98dx3236_get_cpu_freq,\n" + "> +\t.get_clk_ratio = NULL,\n" + "> +\t.ratios = NULL,\n" + "> +\t.num_ratios = 0,\n" "> +};\n" "> +\n" "> /*\n" "> * Clock Gating Control\n" "> */\n" - "> @@ -195,6 +215,15 @@ static const struct clk_gating_soc_desc axp_gating_d=\n" - "esc[] __initconst =3D {\n" + "> @@ -195,6 +215,15 @@ static const struct clk_gating_soc_desc axp_gating_desc[] __initconst = {\n" "> \t{ }\n" "> };\n" - ">=20=20\n" - "> +static const struct clk_gating_soc_desc mv98dx3236_gating_desc[] __initc=\n" - "onst =3D {\n" + "> \n" + "> +static const struct clk_gating_soc_desc mv98dx3236_gating_desc[] __initconst = {\n" "> +\t{ \"ge1\", NULL, 3, 0 },\n" "> +\t{ \"ge0\", NULL, 4, 0 },\n" "> +\t{ \"pex00\", NULL, 5, 0 },\n" @@ -119,16 +114,15 @@ "> +\n" "> static void __init axp_clk_init(struct device_node *np)\n" "> {\n" - "> \tstruct device_node *cgnp =3D\n" - "> @@ -206,3 +235,16 @@ static void __init axp_clk_init(struct device_node *=\n" - "np)\n" + "> \tstruct device_node *cgnp =\n" + "> @@ -206,3 +235,16 @@ static void __init axp_clk_init(struct device_node *np)\n" "> \t\tmvebu_clk_gating_setup(cgnp, axp_gating_desc);\n" "> }\n" "> CLK_OF_DECLARE(axp_clk, \"marvell,armada-xp-core-clock\", axp_clk_init);\n" "> +\n" "> +static void __init mv98dx3236_clk_init(struct device_node *np)\n" "> +{\n" - "> +\tstruct device_node *cgnp =3D\n" + "> +\tstruct device_node *cgnp =\n" "> +\t\tof_find_compatible_node(NULL, NULL, \"marvell,armada-xp-gating-clock\");\n" "> +\n" "> +\tmvebu_coreclk_setup(np, &mv98dx3236_coreclks);\n" @@ -142,32 +136,30 @@ "> index 5837eb8a212f..29f295e7a36b 100644\n" "> --- a/drivers/clk/mvebu/clk-cpu.c\n" "> +++ b/drivers/clk/mvebu/clk-cpu.c\n" - "> @@ -165,7 +165,9 @@ static const struct clk_ops cpu_ops =3D {\n" - "> \t.set_rate =3D clk_cpu_set_rate,\n" + "> @@ -165,7 +165,9 @@ static const struct clk_ops cpu_ops = {\n" + "> \t.set_rate = clk_cpu_set_rate,\n" "> };\n" - ">=20=20\n" + "> \n" "> -static void __init of_cpu_clk_setup(struct device_node *node)\n" "> +/* Add parameter to allow this to support different clock operations. */\n" "> +static void __init _of_cpu_clk_setup(struct device_node *node,\n" "> +\t\t\tconst struct clk_ops *cpu_clk_ops)\n" "> {\n" "> \tstruct cpu_clk *cpuclk;\n" - "> \tvoid __iomem *clock_complex_base =3D of_iomap(node, 0);\n" - "> @@ -218,7 +220,7 @@ static void __init of_cpu_clk_setup(struct device_nod=\n" - "e *node)\n" - "> \t\tcpuclk[cpu].hw.init =3D &init;\n" - ">=20=20\n" - "> \t\tinit.name =3D cpuclk[cpu].clk_name;\n" - "> -\t\tinit.ops =3D &cpu_ops;\n" - "> +\t\tinit.ops =3D cpu_clk_ops;\n" - "> \t\tinit.flags =3D 0;\n" - "> \t\tinit.parent_names =3D &cpuclk[cpu].parent_name;\n" - "> \t\tinit.num_parents =3D 1;\n" - "> @@ -243,5 +245,30 @@ static void __init of_cpu_clk_setup(struct device_no=\n" - "de *node)\n" + "> \tvoid __iomem *clock_complex_base = of_iomap(node, 0);\n" + "> @@ -218,7 +220,7 @@ static void __init of_cpu_clk_setup(struct device_node *node)\n" + "> \t\tcpuclk[cpu].hw.init = &init;\n" + "> \n" + "> \t\tinit.name = cpuclk[cpu].clk_name;\n" + "> -\t\tinit.ops = &cpu_ops;\n" + "> +\t\tinit.ops = cpu_clk_ops;\n" + "> \t\tinit.flags = 0;\n" + "> \t\tinit.parent_names = &cpuclk[cpu].parent_name;\n" + "> \t\tinit.num_parents = 1;\n" + "> @@ -243,5 +245,30 @@ static void __init of_cpu_clk_setup(struct device_node *node)\n" "> \tiounmap(clock_complex_base);\n" "> }\n" - ">=20=20\n" + "> \n" "> +/* Use this function to call the generic setup with the correct\n" "> + * clock operation\n" "> + */\n" @@ -183,10 +175,10 @@ "> +/* Define the clock and operations for the mv98dx3236 - it cannot perform\n" "> + * any operations.\n" "> + */\n" - "> +static const struct clk_ops mv98dx3236_cpu_ops =3D {\n" - "> +\t.recalc_rate =3D NULL,\n" - "> +\t.round_rate =3D NULL,\n" - "> +\t.set_rate =3D NULL,\n" + "> +static const struct clk_ops mv98dx3236_cpu_ops = {\n" + "> +\t.recalc_rate = NULL,\n" + "> +\t.round_rate = NULL,\n" + "> +\t.set_rate = NULL,\n" "> +};\n" "> +\n" "> +static void __init of_mv98dx3236_cpu_clk_setup(struct device_node *node)\n" @@ -196,8 +188,7 @@ "> +\n" "> +CLK_OF_DECLARE(mv98dx3236_cpu_clock, \"marvell,mv98dx3236-cpu-clock\",\n" "> +\t\t\t\t\t of_mv98dx3236_cpu_clk_setup);\n" - "> diff --git a/drivers/clk/mvebu/mv98dx3236-corediv.c b/drivers/clk/mvebu/m=\n" - "v98dx3236-corediv.c\n" + "> diff --git a/drivers/clk/mvebu/mv98dx3236-corediv.c b/drivers/clk/mvebu/mv98dx3236-corediv.c\n" "> new file mode 100644\n" "> index 000000000000..3060764a8e5d\n" "> --- /dev/null\n" @@ -269,11 +260,11 @@ "> +static unsigned long mv98dx3236_corediv_recalc_rate(struct clk_hw *hwclk,\n" "> +\t\t\t\t\t unsigned long parent_rate)\n" "> +{\n" - "> +\tstruct clk_corediv *corediv =3D to_corediv_clk(hwclk);\n" + "> +\tstruct clk_corediv *corediv = to_corediv_clk(hwclk);\n" "> +\tu32 reg, div;\n" "> +\n" - "> +\treg =3D readl(corediv->reg + RATIO_REG_OFFSET);\n" - "> +\tdiv =3D (reg >> CLK_DIV_RATIO_NAND_OFFSET) & CLK_DIV_RATIO_NAND_MASK;\n" + "> +\treg = readl(corediv->reg + RATIO_REG_OFFSET);\n" + "> +\tdiv = (reg >> CLK_DIV_RATIO_NAND_OFFSET) & CLK_DIV_RATIO_NAND_MASK;\n" "> +\treturn parent_rate / div;\n" "> +}\n" "> +\n" @@ -283,39 +274,38 @@ "> +\t/* Valid ratio are 1:4, 1:5, 1:6 and 1:8 */\n" "> +\tu32 div;\n" "> +\n" - "> +\tdiv =3D *parent_rate / rate;\n" + "> +\tdiv = *parent_rate / rate;\n" "> +\tif (div < 4)\n" - "> +\t\tdiv =3D 4;\n" + "> +\t\tdiv = 4;\n" "> +\telse if (div > 6)\n" - "> +\t\tdiv =3D 8;\n" + "> +\t\tdiv = 8;\n" "> +\n" "> +\treturn *parent_rate / div;\n" "> +}\n" "> +\n" - "> +static int mv98dx3236_corediv_set_rate(struct clk_hw *hwclk, unsigned lo=\n" - "ng rate,\n" + "> +static int mv98dx3236_corediv_set_rate(struct clk_hw *hwclk, unsigned long rate,\n" "> +\t\t\t unsigned long parent_rate)\n" "> +{\n" - "> +\tstruct clk_corediv *corediv =3D to_corediv_clk(hwclk);\n" - "> +\tunsigned long flags =3D 0;\n" + "> +\tstruct clk_corediv *corediv = to_corediv_clk(hwclk);\n" + "> +\tunsigned long flags = 0;\n" "> +\tu32 reg, div;\n" "> +\n" - "> +\tdiv =3D parent_rate / rate;\n" + "> +\tdiv = parent_rate / rate;\n" "> +\n" "> +\tspin_lock_irqsave(&corediv->lock, flags);\n" "> +\n" "> +\t/* Write new divider to the divider ratio register */\n" - "> +\treg =3D readl(corediv->reg + RATIO_REG_OFFSET);\n" - "> +\treg &=3D ~(CLK_DIV_RATIO_NAND_MASK << CLK_DIV_RATIO_NAND_OFFSET);\n" - "> +\treg |=3D (div & CLK_DIV_RATIO_NAND_MASK) << CLK_DIV_RATIO_NAND_OFFSET;\n" + "> +\treg = readl(corediv->reg + RATIO_REG_OFFSET);\n" + "> +\treg &= ~(CLK_DIV_RATIO_NAND_MASK << CLK_DIV_RATIO_NAND_OFFSET);\n" + "> +\treg |= (div & CLK_DIV_RATIO_NAND_MASK) << CLK_DIV_RATIO_NAND_OFFSET;\n" "> +\twritel(reg, corediv->reg + RATIO_REG_OFFSET);\n" "> +\n" "> +\t/* Set reload-force for this clock */\n" - "> +\treg =3D readl(corediv->reg) | BIT(CLK_DIV_RATIO_NAND_FORCE_RELOAD_BIT);\n" + "> +\treg = readl(corediv->reg) | BIT(CLK_DIV_RATIO_NAND_FORCE_RELOAD_BIT);\n" "> +\twritel(reg, corediv->reg);\n" "> +\n" "> +\t/* Now trigger the clock update */\n" - "> +\treg =3D readl(corediv->reg + RATIO_REG_OFFSET) | RATIO_RELOAD_BIT;\n" + "> +\treg = readl(corediv->reg + RATIO_REG_OFFSET) | RATIO_RELOAD_BIT;\n" "> +\twritel(reg, corediv->reg + RATIO_REG_OFFSET);\n" "> +\n" "> +\t/*\n" @@ -323,7 +313,7 @@ "> +\t * ratios request and the reload request.\n" "> +\t */\n" "> +\tudelay(1000);\n" - "> +\treg &=3D ~(CORE_CLK_DIV_RATIO_MASK | RATIO_RELOAD_BIT);\n" + "> +\treg &= ~(CORE_CLK_DIV_RATIO_MASK | RATIO_RELOAD_BIT);\n" "> +\twritel(reg, corediv->reg + RATIO_REG_OFFSET);\n" "> +\tudelay(1000);\n" "> +\n" @@ -332,13 +322,13 @@ "> +\treturn 0;\n" "> +}\n" "> +\n" - "> +static const struct clk_ops ops =3D {\n" - "> +\t.enable =3D mv98dx3236_corediv_enable,\n" - "> +\t.disable =3D mv98dx3236_corediv_disable,\n" - "> +\t.is_enabled =3D mv98dx3236_corediv_is_enabled,\n" - "> +\t.recalc_rate =3D mv98dx3236_corediv_recalc_rate,\n" - "> +\t.round_rate =3D mv98dx3236_corediv_round_rate,\n" - "> +\t.set_rate =3D mv98dx3236_corediv_set_rate,\n" + "> +static const struct clk_ops ops = {\n" + "> +\t.enable = mv98dx3236_corediv_enable,\n" + "> +\t.disable = mv98dx3236_corediv_disable,\n" + "> +\t.is_enabled = mv98dx3236_corediv_is_enabled,\n" + "> +\t.recalc_rate = mv98dx3236_corediv_recalc_rate,\n" + "> +\t.round_rate = mv98dx3236_corediv_round_rate,\n" + "> +\t.set_rate = mv98dx3236_corediv_set_rate,\n" "> +};\n" "> +\n" "> +static void __init mv98dx3236_corediv_clk_init(struct device_node *node)\n" @@ -353,31 +343,31 @@ "> +\tint len;\n" "> +\tstruct device_node *dfx_node;\n" "> +\n" - "> +\tdfx_node =3D of_parse_phandle(node, \"base\", 0);\n" + "> +\tdfx_node = of_parse_phandle(node, \"base\", 0);\n" "> +\tif (WARN_ON(!dfx_node))\n" "> +\t\treturn;\n" "> +\n" - "> +\toff =3D of_get_property(node, \"reg\", &len);\n" + "> +\toff = of_get_property(node, \"reg\", &len);\n" "> +\tif (WARN_ON(!off))\n" "> +\t\treturn;\n" "> +\n" - "> +\tbase =3D of_iomap(dfx_node, 0);\n" + "> +\tbase = of_iomap(dfx_node, 0);\n" "> +\tif (WARN_ON(!base))\n" "> +\t\treturn;\n" "> +\n" "> +\tof_node_put(dfx_node);\n" "> +\n" - "> +\tparent_name =3D of_clk_get_parent_name(node, 0);\n" + "> +\tparent_name = of_clk_get_parent_name(node, 0);\n" "> +\n" - "> +\tclk_data.clk_num =3D 1;\n" + "> +\tclk_data.clk_num = 1;\n" "> +\n" "> +\t/* clks holds the clock array */\n" - "> +\tclks =3D kcalloc(clk_data.clk_num, sizeof(struct clk *),\n" + "> +\tclks = kcalloc(clk_data.clk_num, sizeof(struct clk *),\n" "> +\t\t\t\tGFP_KERNEL);\n" "> +\tif (WARN_ON(!clks))\n" "> +\t\tgoto err_unmap;\n" "> +\t/* corediv holds the clock specific array */\n" - "> +\tcorediv =3D kcalloc(clk_data.clk_num, sizeof(struct clk_corediv),\n" + "> +\tcorediv = kcalloc(clk_data.clk_num, sizeof(struct clk_corediv),\n" "> +\t\t\t\tGFP_KERNEL);\n" "> +\tif (WARN_ON(!corediv))\n" "> +\t\tgoto err_free_clks;\n" @@ -387,19 +377,19 @@ "> +\tof_property_read_string_index(node, \"clock-output-names\",\n" "> +\t\t\t\t\t 0, &clk_name);\n" "> +\n" - "> +\tinit.num_parents =3D 1;\n" - "> +\tinit.parent_names =3D &parent_name;\n" - "> +\tinit.name =3D clk_name;\n" - "> +\tinit.ops =3D &ops;\n" - "> +\tinit.flags =3D 0;\n" + "> +\tinit.num_parents = 1;\n" + "> +\tinit.parent_names = &parent_name;\n" + "> +\tinit.name = clk_name;\n" + "> +\tinit.ops = &ops;\n" + "> +\tinit.flags = 0;\n" "> +\n" - "> +\tcorediv[0].reg =3D (void *)((int)base + be32_to_cpu(*off));\n" - "> +\tcorediv[0].hw.init =3D &init;\n" + "> +\tcorediv[0].reg = (void *)((int)base + be32_to_cpu(*off));\n" + "> +\tcorediv[0].hw.init = &init;\n" "> +\n" - "> +\tclks[0] =3D clk_register(NULL, &corediv[0].hw);\n" + "> +\tclks[0] = clk_register(NULL, &corediv[0].hw);\n" "> +\tWARN_ON(IS_ERR(clks[0]));\n" "> +\n" - "> +\tclk_data.clks =3D clks;\n" + "> +\tclk_data.clks = clks;\n" "> +\tof_clk_add_provider(node, of_clk_src_onecell_get, &clk_data);\n" "> +\treturn;\n" "> +\n" @@ -409,17 +399,16 @@ "> +\tiounmap(base);\n" "> +}\n" "> +\n" - "> +CLK_OF_DECLARE(mv98dx3236_corediv_clk, \"marvell,mv98dx3236-corediv-clock=\n" - "\",\n" + "> +CLK_OF_DECLARE(mv98dx3236_corediv_clk, \"marvell,mv98dx3236-corediv-clock\",\n" "> +\t mv98dx3236_corediv_clk_init);\n" - "> --=20\n" + "> -- \n" "> 2.11.0.24.ge6920cf\n" ">\n" "\n" - "--=20\n" + "-- \n" "Gregory Clement, Free Electrons\n" "Kernel, drivers, real-time and embedded Linux\n" "development, consulting, training and support.\n" http://free-electrons.com -685f45185818579661e3e31d8ea5378eb3bd9bf69dbe1cc8c69a28376dff9640 +293fd2e2db5c3748e6f4920edecd890aa9724dd21103cfe2c7b8d05650385e1d
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.