From 1a40aab51a1124ee3e4b7cc80c367a6552936c2a Mon Sep 17 00:00:00 2001 From: Uwe Kleine-König Date: Wed, 14 Jun 2017 23:50:09 +0200 Subject: clk: mvebu: Add support for Armada 38x's coreclk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a mixture of the Armada 370 barebox driver and the Armada 38x Linux driver. Signed-off-by: Uwe Kleine-König Signed-off-by: Sascha Hauer --- drivers/clk/mvebu/Makefile | 1 + drivers/clk/mvebu/armada-38x.c | 144 +++++++++++++++++++++++++++++++++++++++++ drivers/clk/mvebu/common.c | 4 ++ drivers/clk/mvebu/common.h | 8 +++ 4 files changed, 157 insertions(+) create mode 100644 drivers/clk/mvebu/armada-38x.c (limited to 'drivers') diff --git a/drivers/clk/mvebu/Makefile b/drivers/clk/mvebu/Makefile index 4b2c3c8431..53c759e4ef 100644 --- a/drivers/clk/mvebu/Makefile +++ b/drivers/clk/mvebu/Makefile @@ -1,5 +1,6 @@ obj-y += common.o obj-$(CONFIG_ARCH_ARMADA_370) += armada-370.o corediv.o obj-$(CONFIG_ARCH_ARMADA_XP) += armada-xp.o corediv.o +obj-$(CONFIG_ARCH_ARMADA_38X) += armada-38x.o corediv.o obj-$(CONFIG_ARCH_DOVE) += dove.o obj-$(CONFIG_ARCH_KIRKWOOD) += kirkwood.o diff --git a/drivers/clk/mvebu/armada-38x.c b/drivers/clk/mvebu/armada-38x.c new file mode 100644 index 0000000000..d2d7c2a225 --- /dev/null +++ b/drivers/clk/mvebu/armada-38x.c @@ -0,0 +1,144 @@ +/* + * Marvell Armada 380/385 SoC clocks + * + * Copyright (C) 2014 Marvell + * + * Gregory CLEMENT + * Sebastian Hesselbarth + * Andrew Lunn + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + */ + +#include +#include + +#include "common.h" + +/* + * Core Clocks + * + * Armada XP Sample At Reset is a 64 bit bitfiled split in two + * register of 32 bits + */ + +#define SAR_A380_TCLK_FREQ_OPT 15 +#define SAR_A380_TCLK_FREQ_OPT_MASK 0x1 +#define SAR_A380_CPU_DDR_L2_FREQ_OPT 10 +#define SAR_A380_CPU_DDR_L2_FREQ_OPT_MASK 0x1f + +/* Armada XP TCLK frequency is fixed to 250MHz */ +static u32 a38x_get_tclk_freq(void __iomem *sar) +{ + if ((readl(sar) >> SAR_A380_TCLK_FREQ_OPT) & SAR_A380_TCLK_FREQ_OPT_MASK) + return 200000000; + else + return 250000000; +} + +static const u32 a38x_cpu_freqs[] = { + 0, 0, 0, 0, + 1666000000, 0, 0, 0, + 1332000000, 0, 0, 0, + 1600000000, +}; + +static u32 a38x_get_cpu_freq(void __iomem *sar) +{ + u32 cpu_freq_select = ((readl(sar) >> SAR_A380_CPU_DDR_L2_FREQ_OPT) & + SAR_A380_CPU_DDR_L2_FREQ_OPT_MASK); + + if (cpu_freq_select >= ARRAY_SIZE(a38x_cpu_freqs)) { + pr_err("CPU freq select unsupported: %d\n", cpu_freq_select); + return 0; + } + + return a38x_cpu_freqs[cpu_freq_select]; +} + +enum { A380_CPU_TO_DDR, A380_CPU_TO_L2 }; + +static const struct coreclk_ratio a38x_coreclk_ratios[] = { + { .id = A380_CPU_TO_L2, .name = "l2clk" }, + { .id = A380_CPU_TO_DDR, .name = "ddrclk" }, +}; + +static const int armada_38x_cpu_l2_ratios[32][2] = { + {0, 1}, {0, 1}, {0, 1}, {0, 1}, + {1, 2}, {0, 1}, {0, 1}, {0, 1}, + {1, 2}, {0, 1}, {0, 1}, {0, 1}, + {1, 2}, {0, 1}, {0, 1}, {0, 1}, + {0, 1}, {0, 1}, {0, 1}, {0, 1}, + {0, 1}, {0, 1}, {0, 1}, {0, 1}, + {0, 1}, {0, 1}, {0, 1}, {0, 1}, + {0, 1}, {0, 1}, {0, 1}, {0, 1}, +}; + +static const int armada_38x_cpu_ddr_ratios[32][2] = { + {0, 1}, {0, 1}, {0, 1}, {0, 1}, + {1, 2}, {0, 1}, {0, 1}, {0, 1}, + {1, 2}, {0, 1}, {0, 1}, {0, 1}, + {1, 2}, {0, 1}, {0, 1}, {0, 1}, + {0, 1}, {0, 1}, {0, 1}, {0, 1}, + {0, 1}, {0, 1}, {0, 1}, {0, 1}, + {0, 1}, {0, 1}, {0, 1}, {0, 1}, + {0, 1}, {0, 1}, {0, 1}, {0, 1}, +}; + +static void a38x_get_clk_ratio( + void __iomem *sar, int id, int *mult, int *div) +{ + u32 opt = ((readl(sar) >> SAR_A380_CPU_DDR_L2_FREQ_OPT) & + SAR_A380_CPU_DDR_L2_FREQ_OPT_MASK); + + switch (id) { + case A380_CPU_TO_L2: + *mult = armada_38x_cpu_l2_ratios[opt][0]; + *div = armada_38x_cpu_l2_ratios[opt][1]; + break; + case A380_CPU_TO_DDR: + *mult = armada_38x_cpu_ddr_ratios[opt][0]; + *div = armada_38x_cpu_ddr_ratios[opt][1]; + break; + } +} + +const struct coreclk_soc_desc armada_38x_coreclks = { + .get_tclk_freq = a38x_get_tclk_freq, + .get_cpu_freq = a38x_get_cpu_freq, + .get_clk_ratio = a38x_get_clk_ratio, + .ratios = a38x_coreclk_ratios, + .num_ratios = ARRAY_SIZE(a38x_coreclk_ratios), +}; + +/* + * Clock Gating Control + */ +const struct clk_gating_soc_desc armada_38x_gating_desc[] = { + { "audio", NULL, 0 }, + { "ge2", NULL, 2 }, + { "ge1", NULL, 3 }, + { "ge0", NULL, 4 }, + { "pex1", NULL, 5 }, + { "pex2", NULL, 6 }, + { "pex3", NULL, 7 }, + { "pex0", NULL, 8 }, + { "usb3h0", NULL, 9 }, + { "usb3h1", NULL, 10 }, + { "usb3d", NULL, 11 }, + { "bm", NULL, 13 }, + { "crypto0z", NULL, 14 }, + { "sata0", NULL, 15 }, + { "crypto1z", NULL, 16 }, + { "sdio", NULL, 17 }, + { "usb2", NULL, 18 }, + { "crypto1", NULL, 21 }, + { "xor0", NULL, 22 }, + { "crypto0", NULL, 23 }, + { "tdm", NULL, 25 }, + { "xor1", NULL, 28 }, + { "sata1", NULL, 30 }, + { } +}; diff --git a/drivers/clk/mvebu/common.c b/drivers/clk/mvebu/common.c index a06b29f4e7..f6f118f0db 100644 --- a/drivers/clk/mvebu/common.c +++ b/drivers/clk/mvebu/common.c @@ -29,6 +29,8 @@ static struct clk_onecell_data clk_data; static struct of_device_id mvebu_coreclk_ids[] = { { .compatible = "marvell,armada-370-core-clock", .data = &armada_370_coreclks }, + { .compatible = "marvell,armada-380-core-clock", + .data = &armada_38x_coreclks }, { .compatible = "marvell,armada-xp-core-clock", .data = &armada_xp_coreclks }, { .compatible = "marvell,dove-core-clock", @@ -144,6 +146,8 @@ static struct of_device_id mvebu_clk_gating_ids[] = { .data = &armada_370_gating_desc }, { .compatible = "marvell,armada-xp-gating-clock", .data = &armada_xp_gating_desc }, + { .compatible = "marvell,armada-380-gating-clock", + .data = &armada_38x_gating_desc }, { .compatible = "marvell,dove-gating-clock", .data = &dove_gating_desc }, { .compatible = "marvell,kirkwood-gating-clock", diff --git a/drivers/clk/mvebu/common.h b/drivers/clk/mvebu/common.h index 522ccdeccd..a3b27247f7 100644 --- a/drivers/clk/mvebu/common.h +++ b/drivers/clk/mvebu/common.h @@ -49,6 +49,14 @@ static const u32 armada_xp_coreclks; static const u32 armada_xp_gating_desc; #endif +#ifdef CONFIG_ARCH_ARMADA_38X +extern const struct coreclk_soc_desc armada_38x_coreclks; +extern const struct clk_gating_soc_desc armada_38x_gating_desc[]; +#else +static const u32 armada_38x_coreclks; +static const u32 armada_38x_gating_desc; +#endif + #ifdef CONFIG_ARCH_DOVE extern const struct coreclk_soc_desc dove_coreclks; extern const struct clk_gating_soc_desc dove_gating_desc[]; -- cgit v1.2.3