aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/mvebu/patches-4.14/501-clk-mvebu-armada-37xx-periph-prepare-cpu-clk-to-be-u.patch
diff options
context:
space:
mode:
authorTomasz Maciej Nowak <tomek_n@o2.pl>2018-03-07 22:10:02 +0100
committerHauke Mehrtens <hauke@hauke-m.de>2018-03-10 01:15:22 +0100
commit584d7c53bd2d286a71fe5e8244624f59c529cb26 (patch)
treef03f34a0d88192cd2487791d6bc28e70f0ee50fe /target/linux/mvebu/patches-4.14/501-clk-mvebu-armada-37xx-periph-prepare-cpu-clk-to-be-u.patch
parentbe3da900cdac3640398ed60f62bb445269aa8b50 (diff)
downloadupstream-584d7c53bd2d286a71fe5e8244624f59c529cb26.tar.gz
upstream-584d7c53bd2d286a71fe5e8244624f59c529cb26.tar.bz2
upstream-584d7c53bd2d286a71fe5e8244624f59c529cb26.zip
mvebu: new subtarget cortex A53
This commit introduces new subtarget for Marvell EBU Armada Cortex A53 processor based devices. The first device is Globalscale ESPRESSObin. Some hardware specs: SoC: Marvell Armada 3700LP (88F3720) dual core ARM Cortex A53 processor up to 1.2GHz RAM: 512MB, 1GB or 2GB DDR3 Storage: SATA interface µSD card slot with footprint for an optional 4GB EMMC 4MB SPI NOR flash for bootloader Ethernet: Topaz Networking Switch (88E6341) with 3x GbE ports Connectors: USB 3.0 USB 2.0 µUSB port connected to PL2303SA (USB to serial bridge controller) for UART access Expansion: 2x 46-pin GPIO headers for accessories and shields with I2C, GPIOs, PWM, UART, SPI, MMC, etc MiniPCIe slot Misc: Reset button, JTAG interface Currently booting only from µSD card is supported. The boards depending on date of dispatch can come with various U-Boot versions. For the newest version 2017.03-armada-17.10 no manual intervention should be needed to boot OpenWrt image. For the older ones it's necessary to modify default U-Boot environment: 1. Interrupt boot process to run U-Boot command line, 2. Run following commands: (for version 2017.03-armada-17.06 and 2017.03-armada-17.08) setenv bootcmd "load mmc 0:1 0x4d00000 boot.scr; source 0x4d00000" saveenv (for version 2015.01-armada-17.02 and 2015.01-armada-17.04) setenv bootargs "console=ttyMV0,115200 root=/dev/mmcblk0p2 rw rootwait" setenv bootcmd "ext4load mmc 0:1 ${fdt_addr} armada-3720-espressobin.dtb; ext4load mmc 0:1 ${kernel_addr} Image; booti ${kernel_addr} - ${fdt_addr}" saveenv 3. Poweroff, insert SD card with OpenWrt image, boot and enjoy. Signed-off-by: Tomasz Maciej Nowak <tomek_n@o2.pl>
Diffstat (limited to 'target/linux/mvebu/patches-4.14/501-clk-mvebu-armada-37xx-periph-prepare-cpu-clk-to-be-u.patch')
-rw-r--r--target/linux/mvebu/patches-4.14/501-clk-mvebu-armada-37xx-periph-prepare-cpu-clk-to-be-u.patch178
1 files changed, 178 insertions, 0 deletions
diff --git a/target/linux/mvebu/patches-4.14/501-clk-mvebu-armada-37xx-periph-prepare-cpu-clk-to-be-u.patch b/target/linux/mvebu/patches-4.14/501-clk-mvebu-armada-37xx-periph-prepare-cpu-clk-to-be-u.patch
new file mode 100644
index 0000000000..f9dec9f2ee
--- /dev/null
+++ b/target/linux/mvebu/patches-4.14/501-clk-mvebu-armada-37xx-periph-prepare-cpu-clk-to-be-u.patch
@@ -0,0 +1,178 @@
+From 9818a7a4fd10f72537cdf2a5ec3402f2c245ea24 Mon Sep 17 00:00:00 2001
+From: Gregory CLEMENT <gregory.clement@free-electrons.com>
+Date: Thu, 30 Nov 2017 14:40:28 +0100
+Subject: clk: mvebu: armada-37xx-periph: prepare cpu clk to be
+ used with DVFS
+
+When DVFS will be enabled then the cpu clk will use a different set of
+register at run time. That means that we won't be able to use the common
+callback and need to use our own ones.
+
+This patch prepares this change by switching on our own set of callbacks
+without modifying the behavior of the clocks.
+
+Signed-off-by: Gregory CLEMENT <gregory.clement@free-electrons.com>
+Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
+---
+ drivers/clk/mvebu/armada-37xx-periph.c | 82 ++++++++++++++++++++++++++++++----
+ 1 file changed, 73 insertions(+), 9 deletions(-)
+
+--- a/drivers/clk/mvebu/armada-37xx-periph.c
++++ b/drivers/clk/mvebu/armada-37xx-periph.c
+@@ -46,7 +46,17 @@ struct clk_double_div {
+ u8 shift2;
+ };
+
++struct clk_pm_cpu {
++ struct clk_hw hw;
++ void __iomem *reg_mux;
++ u8 shift_mux;
++ u32 mask_mux;
++ void __iomem *reg_div;
++ u8 shift_div;
++};
++
+ #define to_clk_double_div(_hw) container_of(_hw, struct clk_double_div, hw)
++#define to_clk_pm_cpu(_hw) container_of(_hw, struct clk_pm_cpu, hw)
+
+ struct clk_periph_data {
+ const char *name;
+@@ -55,6 +65,7 @@ struct clk_periph_data {
+ struct clk_hw *mux_hw;
+ struct clk_hw *rate_hw;
+ struct clk_hw *gate_hw;
++ struct clk_hw *muxrate_hw;
+ bool is_double_div;
+ };
+
+@@ -81,6 +92,7 @@ static const struct clk_div_table clk_ta
+ };
+
+ static const struct clk_ops clk_double_div_ops;
++static const struct clk_ops clk_pm_cpu_ops;
+
+ #define PERIPH_GATE(_name, _bit) \
+ struct clk_gate gate_##_name = { \
+@@ -122,6 +134,18 @@ struct clk_divider rate_##_name = { \
+ } \
+ };
+
++#define PERIPH_PM_CPU(_name, _shift1, _reg, _shift2) \
++struct clk_pm_cpu muxrate_##_name = { \
++ .reg_mux = (void *)TBG_SEL, \
++ .mask_mux = 3, \
++ .shift_mux = _shift1, \
++ .reg_div = (void *)_reg, \
++ .shift_div = _shift2, \
++ .hw.init = &(struct clk_init_data){ \
++ .ops = &clk_pm_cpu_ops, \
++ } \
++};
++
+ #define PERIPH_CLK_FULL_DD(_name, _bit, _shift, _reg1, _reg2, _shift1, _shift2)\
+ static PERIPH_GATE(_name, _bit); \
+ static PERIPH_MUX(_name, _shift); \
+@@ -136,10 +160,6 @@ static PERIPH_DIV(_name, _reg, _shift1,
+ static PERIPH_GATE(_name, _bit); \
+ static PERIPH_DIV(_name, _reg, _shift, _table);
+
+-#define PERIPH_CLK_MUX_DIV(_name, _shift, _reg, _shift_div, _table) \
+-static PERIPH_MUX(_name, _shift); \
+-static PERIPH_DIV(_name, _reg, _shift_div, _table);
+-
+ #define PERIPH_CLK_MUX_DD(_name, _shift, _reg1, _reg2, _shift1, _shift2)\
+ static PERIPH_MUX(_name, _shift); \
+ static PERIPH_DOUBLEDIV(_name, _reg1, _reg2, _shift1, _shift2);
+@@ -180,13 +200,12 @@ static PERIPH_DOUBLEDIV(_name, _reg1, _r
+ .rate_hw = &rate_##_name.hw, \
+ }
+
+-#define REF_CLK_MUX_DIV(_name) \
++#define REF_CLK_PM_CPU(_name) \
+ { .name = #_name, \
+ .parent_names = (const char *[]){ "TBG-A-P", \
+ "TBG-B-P", "TBG-A-S", "TBG-B-S"}, \
+ .num_parents = 4, \
+- .mux_hw = &mux_##_name.hw, \
+- .rate_hw = &rate_##_name.hw, \
++ .muxrate_hw = &muxrate_##_name.hw, \
+ }
+
+ #define REF_CLK_MUX_DD(_name) \
+@@ -216,7 +235,7 @@ PERIPH_CLK_FULL_DD(ddr_fclk, 21, 16, DIV
+ PERIPH_CLK_FULL(trace, 22, 18, DIV_SEL0, 20, clk_table6);
+ PERIPH_CLK_FULL(counter, 23, 20, DIV_SEL0, 23, clk_table6);
+ PERIPH_CLK_FULL_DD(eip97, 24, 24, DIV_SEL2, DIV_SEL2, 22, 19);
+-PERIPH_CLK_MUX_DIV(cpu, 22, DIV_SEL0, 28, clk_table6);
++static PERIPH_PM_CPU(cpu, 22, DIV_SEL0, 28);
+
+ static struct clk_periph_data data_nb[] = {
+ REF_CLK_FULL_DD(mmc),
+@@ -235,7 +254,7 @@ static struct clk_periph_data data_nb[]
+ REF_CLK_FULL(trace),
+ REF_CLK_FULL(counter),
+ REF_CLK_FULL_DD(eip97),
+- REF_CLK_MUX_DIV(cpu),
++ REF_CLK_PM_CPU(cpu),
+ { },
+ };
+
+@@ -297,6 +316,37 @@ static const struct clk_ops clk_double_d
+ .recalc_rate = clk_double_div_recalc_rate,
+ };
+
++static u8 clk_pm_cpu_get_parent(struct clk_hw *hw)
++{
++ struct clk_pm_cpu *pm_cpu = to_clk_pm_cpu(hw);
++ int num_parents = clk_hw_get_num_parents(hw);
++ u32 val;
++
++ val = readl(pm_cpu->reg_mux) >> pm_cpu->shift_mux;
++ val &= pm_cpu->mask_mux;
++
++ if (val >= num_parents)
++ return -EINVAL;
++
++ return val;
++}
++
++static unsigned long clk_pm_cpu_recalc_rate(struct clk_hw *hw,
++ unsigned long parent_rate)
++{
++ struct clk_pm_cpu *pm_cpu = to_clk_pm_cpu(hw);
++ unsigned int div;
++
++ div = get_div(pm_cpu->reg_div, pm_cpu->shift_div);
++
++ return DIV_ROUND_UP_ULL((u64)parent_rate, div);
++}
++
++static const struct clk_ops clk_pm_cpu_ops = {
++ .get_parent = clk_pm_cpu_get_parent,
++ .recalc_rate = clk_pm_cpu_recalc_rate,
++};
++
+ static const struct of_device_id armada_3700_periph_clock_of_match[] = {
+ { .compatible = "marvell,armada-3700-periph-clock-nb",
+ .data = data_nb, },
+@@ -356,6 +406,20 @@ static int armada_3700_add_composite_clk
+ }
+ }
+
++ if (data->muxrate_hw) {
++ struct clk_pm_cpu *pmcpu_clk;
++ struct clk_hw *muxrate_hw = data->muxrate_hw;
++
++ pmcpu_clk = to_clk_pm_cpu(muxrate_hw);
++ pmcpu_clk->reg_mux = reg + (u64)pmcpu_clk->reg_mux;
++ pmcpu_clk->reg_div = reg + (u64)pmcpu_clk->reg_div;
++
++ mux_hw = muxrate_hw;
++ rate_hw = muxrate_hw;
++ mux_ops = muxrate_hw->init->ops;
++ rate_ops = muxrate_hw->init->ops;
++ }
++
+ *hw = clk_hw_register_composite(dev, data->name, data->parent_names,
+ data->num_parents, mux_hw,
+ mux_ops, rate_hw, rate_ops,