From d0d268c49029e8a3110ac1db2a03b80f1846efe4 Mon Sep 17 00:00:00 2001 From: Yun Cai Date: Sun, 30 Apr 2017 16:08:56 +0800 Subject: [PATCH] clk: add clk tree for axg PD#142470: add axg basic clk and hifi_pll/pcie_refpll/ mipi_host/vpu/ge2d/sd_emmc clks, add clkmsr Change-Id: I487c6b2792389c5df230df5af7b246e83f37f479 Signed-off-by: Yun Cai --- .../bindings/clock/amlogic,meson-clkc.txt | 1 + arch/arm64/boot/dts/amlogic/mesonaxg.dtsi | 126 ++- drivers/amlogic/clk/Makefile | 16 +- drivers/amlogic/clk/axg/Makefile | 6 + drivers/amlogic/clk/axg/axg.c | 817 ++++++++++++++++++ drivers/amlogic/clk/axg/axg.h | 268 ++++++ drivers/amlogic/clk/axg/axg_clk_media.c | 427 +++++++++ drivers/amlogic/clk/axg/axg_clk_misc.c | 105 +++ drivers/amlogic/clk/axg/axg_clk_sdemmc.c | 169 ++++ drivers/amlogic/clk/clk-mpll.c | 7 + drivers/amlogic/clk/clk_measure.c | 138 ++- drivers/amlogic/clk/clk_test.c | 5 +- drivers/amlogic/clk/clkc.h | 5 + drivers/amlogic/clk/gxl/Makefile | 5 + drivers/amlogic/clk/{ => gxl}/clk_gpu.c | 4 +- drivers/amlogic/clk/{ => gxl}/clk_media.c | 4 +- drivers/amlogic/clk/{ => gxl}/clk_misc.c | 4 +- drivers/amlogic/clk/{ => gxl}/clk_sdemmc.c | 4 +- drivers/amlogic/clk/{ => gxl}/gxl.c | 4 +- drivers/amlogic/clk/{ => gxl}/gxl.h | 2 +- drivers/amlogic/clk/m8b/Makefile | 6 + include/dt-bindings/clock/amlogic,axg-clkc.h | 154 ++++ include/linux/amlogic/cpu_version.h | 6 + 23 files changed, 2240 insertions(+), 43 deletions(-) create mode 100644 drivers/amlogic/clk/axg/Makefile create mode 100644 drivers/amlogic/clk/axg/axg.c create mode 100644 drivers/amlogic/clk/axg/axg.h create mode 100644 drivers/amlogic/clk/axg/axg_clk_media.c create mode 100644 drivers/amlogic/clk/axg/axg_clk_misc.c create mode 100644 drivers/amlogic/clk/axg/axg_clk_sdemmc.c create mode 100644 drivers/amlogic/clk/gxl/Makefile rename drivers/amlogic/clk/{ => gxl}/clk_gpu.c (98%) rename drivers/amlogic/clk/{ => gxl}/clk_media.c (99%) rename drivers/amlogic/clk/{ => gxl}/clk_misc.c (99%) rename drivers/amlogic/clk/{ => gxl}/clk_sdemmc.c (99%) rename drivers/amlogic/clk/{ => gxl}/gxl.c (99%) rename drivers/amlogic/clk/{ => gxl}/gxl.h (99%) create mode 100644 drivers/amlogic/clk/m8b/Makefile create mode 100644 include/dt-bindings/clock/amlogic,axg-clkc.h diff --git a/Documentation/devicetree/bindings/clock/amlogic,meson-clkc.txt b/Documentation/devicetree/bindings/clock/amlogic,meson-clkc.txt index 9027132cca68..bf503d9e12fb 100644 --- a/Documentation/devicetree/bindings/clock/amlogic,meson-clkc.txt +++ b/Documentation/devicetree/bindings/clock/amlogic,meson-clkc.txt @@ -8,6 +8,7 @@ Required Properties: - compatible: Should be one of the following: "amlogic,gxl-aoclkc" - for gxl ao clock "amlogic,gxl-clkc" - for gxl ee clock + "amlogic,axg-clkc" - for axg ee clock - reg: physical base address of the clock controller and length of memory mapped region. diff --git a/arch/arm64/boot/dts/amlogic/mesonaxg.dtsi b/arch/arm64/boot/dts/amlogic/mesonaxg.dtsi index ae42ba9fc5ec..d3059506dd84 100644 --- a/arch/arm64/boot/dts/amlogic/mesonaxg.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesonaxg.dtsi @@ -21,33 +21,64 @@ cpus:cpus { #address-cells = <2>; #size-cells = <0>; - #cooling-cells = <2>; /* min followed by max */ - cpu0:cpu@0 { + cpu-map { + cluster0:cluster0 { + core0 { + cpu = <&CPU0>; + }; + core1 { + cpu = <&CPU1>; + }; + core2 { + cpu = <&CPU2>; + }; + core3 { + cpu = <&CPU3>; + }; + }; + }; + CPU0:cpu@0 { device_type = "cpu"; compatible = "arm,cortex-a53","arm,armv8"; reg = <0x0 0x0>; enable-method = "psci"; + clocks = <&scpi_dvfs 0>; + clock-names = "cpu-cluster.0"; + //cpu-idle-states = <&SYSTEM_SLEEP_0>; + /*cpu-idle-states = <&CPU_SLEEP_0 &SYSTEM_SLEEP_0>;*/ }; - cpu1:cpu@1 { + CPU1:cpu@1 { device_type = "cpu"; compatible = "arm,cortex-a53","arm,armv8"; reg = <0x0 0x1>; enable-method = "psci"; + clocks = <&scpi_dvfs 0>; + clock-names = "cpu-cluster.0"; + //cpu-idle-states = <&SYSTEM_SLEEP_0>; + /*cpu-idle-states = <&CPU_SLEEP_0 &SYSTEM_SLEEP_0>;*/ }; - cpu2:cpu@2 { + CPU2:cpu@2 { device_type = "cpu"; compatible = "arm,cortex-a53","arm,armv8"; reg = <0x0 0x2>; enable-method = "psci"; + clocks = <&scpi_dvfs 0>; + clock-names = "cpu-cluster.0"; + //cpu-idle-states = <&SYSTEM_SLEEP_0>; + /*cpu-idle-states = <&CPU_SLEEP_0 &SYSTEM_SLEEP_0>;*/ }; - cpu3:cpu@3 { + CPU3:cpu@3 { device_type = "cpu"; compatible = "arm,cortex-a53","arm,armv8"; reg = <0x0 0x3>; enable-method = "psci"; + clocks = <&scpi_dvfs 0>; + clock-names = "cpu-cluster.0"; + //cpu-idle-states = <&SYSTEM_SLEEP_0>; + /*cpu-idle-states = <&CPU_SLEEP_0 &SYSTEM_SLEEP_0>;*/ }; }; @@ -90,7 +121,7 @@ }; psci { - compatible = "arm,psci"; + compatible = "arm,psci-0.2"; method = "smc"; }; @@ -102,6 +133,29 @@ reserve_mem_size = <0x00300000>; }; + mailbox: mhu@c883c400 { + compatible = "amlogic, meson_mhu"; + reg = <0x0 0xff63c400 0x0 0x4c>, /* MHU registers */ + <0x0 0xfffd3000 0x0 0x800>; /* Payload area */ + interrupts = <0 209 1>, /* low priority interrupt */ + <0 210 1>; /* high priority interrupt */ + #mbox-cells = <1>; + mbox-names = "cpu_to_scp_low", "cpu_to_scp_high"; + mboxes = <&mailbox 0 &mailbox 1>; + }; + + scpi_clocks { + compatible = "arm, scpi-clks"; + + scpi_dvfs: scpi_clocks@0 { + compatible = "arm, scpi-clk-indexed"; + #clock-cells = <1>; + clock-indices = <0>; + clock-output-names = "vcpu"; + }; + + }; + cpu_iomap { compatible = "amlogic, iomap"; #address-cells=<2>; @@ -133,18 +187,60 @@ status = "okay"; cpuinfo_cmd = <0x82000044>; }; - - - cpu_version { - reg=<0x0 0xff800220 0x0 0x4>; + aml_reboot{ + compatible = "aml, reboot"; + sys_reset = <0x84000009>; + sys_poweroff = <0x84000008>; }; - meson_clk_msr { - compatible = "amlogic, gxl_measure"; - reg = <0x0 0xffd18004 0x0 0x4 - 0x0 0xffd1800c 0x0 0x4>; - }; + soc { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + cbus: cbus@ffd00000 { + compatible = "simple-bus"; + reg = <0x0 0xffd00000 0x0 0x25000>; + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x0 0x0 0x0 0xffd00000 0x0 0x25000>; + + meson_clk_msr { + compatible = "amlogic, gxl_measure"; + reg = <0x0 0x18004 0x0 0x4 + 0x0 0x1800c 0x0 0x4>; + }; + }; /* end of cbus */ + + aobus: aobus@ff800000 { + compatible = "simple-bus"; + reg = <0x0 0xff800000 0x0 0xa000>; + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x0 0x0 0x0 0xff800000 0x0 0xa000>; + + cpu_version { + reg=<0x0 0x220 0x0 0x4>; + }; + };/* end of aobus */ + + hiubus: hiubus@ff600000 { + compatible = "simple-bus"; + reg = <0x0 0xff600000 0x0 0x4c000>; + #address-cells = <2>; + #size-cells = <2>; + ranges = <0x0 0x0 0x0 0xff600000 0x0 0x4c000>; + + clkc: clock-controller@0 { + compatible = "amlogic,axg-clkc"; + #clock-cells = <1>; + reg = <0x0 0x3c000 0x0 0x320>; + }; + };/* end of hiubus*/ + + + }; /* end of soc*/ };/* end of / */ diff --git a/drivers/amlogic/clk/Makefile b/drivers/amlogic/clk/Makefile index e7ba8358c6d8..472c0ebda618 100644 --- a/drivers/amlogic/clk/Makefile +++ b/drivers/amlogic/clk/Makefile @@ -2,19 +2,13 @@ # Makefile for Meson specific clk # -obj-$(CONFIG_AMLOGIC_COMMON_CLK_SCPI) += clk-scpi.o +obj-$(CONFIG_AMLOGIC_COMMON_CLK_SCPI) += clk-scpi.o obj-$(CONFIG_AMLOGIC_RESET) += rstc.o -#obj-$(CONFIG_AMLOGIC_CLK) += clk-pll.o clk-cpu.o \ -# clk_measure.o \ -# clk_sdemmc.o clk_gpu.o clk_media.o clk_misc.o\ -# clk-mux.o - obj-$(CONFIG_AMLOGIC_CLK) += clk-pll.o clk-mux.o clk_measure.o -obj-$(CONFIG_AMLOGIC_GX_CLK) += clk-cpu.o clk-mpll.o \ - clk_sdemmc.o clk_gpu.o clk_media.o clk_misc.o\ - gxl.o +obj-$(CONFIG_AMLOGIC_GX_CLK) += clk-cpu.o clk-mpll.o clk_test.o +obj-$(CONFIG_AMLOGIC_GX_CLK) += gxl/ +obj-$(CONFIG_AMLOGIC_GX_CLK) += axg/ -obj-$(CONFIG_AMLOGIC_M8B_CLK) += m8b/clk-cpu.o m8b/meson8b.o m8b/clk_test.o \ - m8b/clk-mpll.o m8b/clk_gpu.o m8b/clk_media.o m8b/clk_store.o m8b/clk_misc.o +obj-$(CONFIG_AMLOGIC_M8B_CLK) += m8b/ \ No newline at end of file diff --git a/drivers/amlogic/clk/axg/Makefile b/drivers/amlogic/clk/axg/Makefile new file mode 100644 index 000000000000..febce5098eb7 --- /dev/null +++ b/drivers/amlogic/clk/axg/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for Meson AXG clk +# + +obj-$(CONFIG_AMLOGIC_GX_CLK) += axg.o \ + axg_clk_sdemmc.o axg_clk_media.o axg_clk_misc.o diff --git a/drivers/amlogic/clk/axg/axg.c b/drivers/amlogic/clk/axg/axg.c new file mode 100644 index 000000000000..d352d869f8c6 --- /dev/null +++ b/drivers/amlogic/clk/axg/axg.c @@ -0,0 +1,817 @@ +/* + * drivers/amlogic/clk/axg/axg.c + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "../clkc.h" +#include "axg.h" + +static struct clk_onecell_data clk_data; +/* #undef pr_debug */ +/* #define pr_debug pr_info */ + +static const struct clk_div_table cpu_div_table[] = { + { .val = 1, .div = 1 }, + { .val = 2, .div = 2 }, + { .val = 3, .div = 3 }, + { .val = 2, .div = 4 }, + { .val = 3, .div = 6 }, + { .val = 4, .div = 8 }, + { .val = 5, .div = 10 }, + { .val = 6, .div = 12 }, + { .val = 7, .div = 14 }, + { .val = 8, .div = 16 }, + { /* sentinel */ }, +}; + +static struct meson_clk_pll axg_fixed_pll = { + .m = { + .reg_off = HHI_MPLL_CNTL, + .shift = 0, + .width = 9, + }, + .n = { + .reg_off = HHI_MPLL_CNTL, + .shift = 9, + .width = 5, + }, + .od = { + .reg_off = HHI_MPLL_CNTL, + .shift = 16, + .width = 2, + }, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "fixed_pll", + .ops = &meson_clk_pll_ro_ops, + .parent_names = (const char *[]){ "xtal" }, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE, + }, +}; + +static struct meson_clk_pll axg_sys_pll = { + .m = { + .reg_off = HHI_SYS_PLL_CNTL, + .shift = 0, + .width = 9, + }, + .n = { + .reg_off = HHI_SYS_PLL_CNTL, + .shift = 9, + .width = 5, + }, + .od = { + .reg_off = HHI_SYS_PLL_CNTL, + .shift = 10, + .width = 2, + }, + .rate_table = sys_pll_rate_table, + .rate_count = ARRAY_SIZE(sys_pll_rate_table), + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "sys_pll", + .ops = &meson_clk_pll_ops, + .parent_names = (const char *[]){ "xtal" }, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE, + }, +}; + +static struct meson_clk_pll axg_gp0_pll = { + .m = { + .reg_off = HHI_GP0_PLL_CNTL, + .shift = 0, + .width = 9, + }, + .n = { + .reg_off = HHI_GP0_PLL_CNTL, + .shift = 9, + .width = 5, + }, + .od = { + .reg_off = HHI_GP0_PLL_CNTL, + .shift = 16, + .width = 2, + }, + .rate_table = axg_gp0_pll_rate_table, + .rate_count = ARRAY_SIZE(axg_gp0_pll_rate_table), + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "gp0_pll", + .ops = &meson_clk_pll_ops, + .parent_names = (const char *[]){ "xtal" }, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE, + }, +}; + +static struct meson_clk_pll axg_hifi_pll = { + .m = { + .reg_off = HHI_HIFI_PLL_CNTL, + .shift = 0, + .width = 9, + }, + .n = { + .reg_off = HHI_HIFI_PLL_CNTL, + .shift = 9, + .width = 5, + }, + .od = { + .reg_off = HHI_HIFI_PLL_CNTL, + .shift = 16, + .width = 2, + }, + .rate_table = axg_gp0_pll_rate_table, + .rate_count = ARRAY_SIZE(axg_gp0_pll_rate_table), + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "hifi_pll", + .ops = &meson_clk_pll_ops, + .parent_names = (const char *[]){ "xtal" }, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE, + }, +}; + +static struct clk_fixed_factor axg_fclk_div2 = { + .mult = 1, + .div = 2, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div2", + .ops = &clk_fixed_factor_ops, + .parent_names = (const char *[]){ "fixed_pll" }, + .num_parents = 1, + }, +}; + +static struct clk_fixed_factor axg_fclk_div3 = { + .mult = 1, + .div = 3, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div3", + .ops = &clk_fixed_factor_ops, + .parent_names = (const char *[]){ "fixed_pll" }, + .num_parents = 1, + }, +}; + +static struct clk_fixed_factor axg_fclk_div4 = { + .mult = 1, + .div = 4, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div4", + .ops = &clk_fixed_factor_ops, + .parent_names = (const char *[]){ "fixed_pll" }, + .num_parents = 1, + }, +}; + +static struct clk_fixed_factor axg_fclk_div5 = { + .mult = 1, + .div = 5, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div5", + .ops = &clk_fixed_factor_ops, + .parent_names = (const char *[]){ "fixed_pll" }, + .num_parents = 1, + }, +}; + +static struct clk_fixed_factor axg_fclk_div7 = { + .mult = 1, + .div = 7, + .hw.init = &(struct clk_init_data){ + .name = "fclk_div7", + .ops = &clk_fixed_factor_ops, + .parent_names = (const char *[]){ "fixed_pll" }, + .num_parents = 1, + }, +}; + +static struct meson_clk_mpll axg_mpll0 = { + .sdm = { + .reg_off = HHI_MPLL_CNTL7, + .shift = 0, + .width = 14, + }, + .n2 = { + .reg_off = HHI_MPLL_CNTL7, + .shift = 16, + .width = 9, + }, + .sdm_en = 15, + .en_dds = 14, + .top_misc_reg = HHI_PLL_TOP_MISC, + .top_misc_bit = 0, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "mpll0", + .ops = &meson_clk_mpll_ops, + .parent_names = (const char *[]){ "fixed_pll" }, + .num_parents = 1, + }, +}; + +static struct meson_clk_mpll axg_mpll1 = { + .sdm = { + .reg_off = HHI_MPLL_CNTL8, + .shift = 0, + .width = 14, + }, + .n2 = { + .reg_off = HHI_MPLL_CNTL8, + .shift = 16, + .width = 9, + }, + .sdm_en = 15, + .en_dds = 14, + .top_misc_reg = HHI_PLL_TOP_MISC, + .top_misc_bit = 1, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "mpll1", + .ops = &meson_clk_mpll_ops, + .parent_names = (const char *[]){ "fixed_pll" }, + .num_parents = 1, + }, +}; + +static struct meson_clk_mpll axg_mpll2 = { + .sdm = { + .reg_off = HHI_MPLL_CNTL9, + .shift = 0, + .width = 14, + }, + .n2 = { + .reg_off = HHI_MPLL_CNTL9, + .shift = 16, + .width = 9, + }, + .sdm_en = 15, + .en_dds = 14, + .top_misc_reg = HHI_PLL_TOP_MISC, + .top_misc_bit = 2, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "mpll2", + .ops = &meson_clk_mpll_ops, + .parent_names = (const char *[]){ "fixed_pll" }, + .num_parents = 1, + }, +}; + +static struct meson_clk_mpll axg_mpll3 = { + .sdm = { + .reg_off = HHI_MPLL3_CNTL0, + .shift = 12, + .width = 14, + }, + .n2 = { + .reg_off = HHI_MPLL3_CNTL0, + .shift = 2, + .width = 9, + }, + .sdm_en = 11, + .en_dds = 0, + .top_misc_reg = HHI_PLL_TOP_MISC, + .top_misc_bit = 3, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "mpll3", + .ops = &meson_clk_mpll_ops, + .parent_names = (const char *[]){ "fixed_pll" }, + .num_parents = 1, + }, +}; + +static struct meson_clk_pll axg_pcierefpll = { + .m = { + .reg_off = HHI_PCIE_PLL_CNTL, + .shift = 0, + .width = 9, + }, + .n = { + .reg_off = HHI_PCIE_PLL_CNTL, + .shift = 9, + .width = 5, + }, + .od = { + .reg_off = HHI_PCIE_PLL_CNTL, + .shift = 16, + .width = 2, + }, + //.rate_table = axg_gp0_pll_rate_table, + //.rate_count = ARRAY_SIZE(axg_gp0_pll_rate_table), + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "pcierefpll", + .ops = &meson_clk_pll_ops, + .parent_names = (const char *[]){ "mpll3" }, + .num_parents = 1, + .flags = CLK_GET_RATE_NOCACHE, + }, +}; + +/* + * FIXME cpu clocks and the legacy composite clocks (e.g. clk81) are both PLL + * post-dividers and should be modelled with their respective PLLs via the + * forthcoming coordinated clock rates feature + */ +static u32 mux_table_cpu_p00[] = { 0, 1, 2 }; +static struct clk_mux axg_cpu_fixedpll_p00 = { + .reg = (void *)HHI_SYS_CPU_CLK_CNTL0, + .mask = 0x3, + .shift = 0, + .table = mux_table_cpu_p00, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "cpu_fixedpll_p00", + .ops = &meson_clk_cpu_ops, + .parent_names = (const char *[]){ "xtal", "fclk_div2", + "fclk_div3"}, + .num_parents = 3, + .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED), + }, +}; + +static struct clk_divider axg_cpu_fixedpll_p01 = { + .reg = (void *)HHI_SYS_CPU_CLK_CNTL0, + .shift = 4, + .width = 6, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "cpu_fixedpll_p01", + .ops = &clk_divider_ops, + .parent_names = (const char *[]){ "cpu_fixedpll_p00" }, + .num_parents = 1, + .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED), + }, +}; + +static u32 mux_table_cpu_p0[] = { 0, 1 }; +static struct clk_mux axg_cpu_fixedpll_p0 = { + .reg = (void *)HHI_SYS_CPU_CLK_CNTL0, + .mask = 0x1, + .shift = 2, + .table = mux_table_cpu_p0, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "cpu_fixedpll_p0", + .ops = &meson_clk_cpu_ops, + .parent_names = (const char *[]){ "cpu_fixedpll_p00", + "cpu_fixedpll_p01"}, + .num_parents = 2, + .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT + | CLK_IGNORE_UNUSED), + }, +}; + +static u32 mux_table_cpu_p10[] = { 0, 1, 2 }; +static struct clk_mux axg_cpu_fixedpll_p10 = { + .reg = (void *)HHI_SYS_CPU_CLK_CNTL0, + .mask = 0x3, + .shift = 16, + .table = mux_table_cpu_p10, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "cpu_fixedpll_p10", + .ops = &meson_clk_cpu_ops, + .parent_names = (const char *[]){ "xtal", "fclk_div2", + "fclk_div3"}, + .num_parents = 3, + .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED), + }, +}; + +static struct clk_divider axg_cpu_fixedpll_p11 = { + .reg = (void *)HHI_SYS_CPU_CLK_CNTL0, + .shift = 20, + .width = 6, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "cpu_fixedpll_p11", + .ops = &clk_divider_ops, + .parent_names = (const char *[]){ "cpu_fixedpll_p10" }, + .num_parents = 1, + .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED), + }, +}; + +static u32 mux_table_cpu_p1[] = { 0, 1 }; +static struct clk_mux axg_cpu_fixedpll_p1 = { + .reg = (void *)HHI_SYS_CPU_CLK_CNTL0, + .mask = 0x1, + .shift = 18, + .table = mux_table_cpu_p1, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "cpu_fixedpll_p1", + .ops = &meson_clk_cpu_ops, + .parent_names = (const char *[]){ "cpu_fixedpll_p10", + "cpu_fixedpll_p11"}, + .num_parents = 2, + .flags = (CLK_GET_RATE_NOCACHE | CLK_SET_RATE_PARENT + | CLK_IGNORE_UNUSED), + }, +}; + +static u32 mux_table_cpu_p[] = { 0, 1 }; +static struct clk_mux axg_cpu_fixedpll_p = { + .reg = (void *)HHI_SYS_CPU_CLK_CNTL0, + .mask = 0x1, + .shift = 10, + .table = mux_table_cpu_p, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "cpu_fixedpll_p", + .ops = &meson_clk_cpu_ops, + .parent_names = (const char *[]){ "cpu_fixedpll_p0", + "cpu_fixedpll_p1"}, + .num_parents = 2, + .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED), + }, +}; + +static u32 mux_table_cpu_clk[] = { 0, 1 }; +static struct meson_clk_cpu axg_cpu_clk = { + .reg_off = HHI_SYS_CPU_CLK_CNTL0, + .mux.reg = (void *)HHI_SYS_CPU_CLK_CNTL0, + .mux.shift = 11, + .mux.mask = 0x1, + .mux.lock = &clk_lock, + .mux.table = mux_table_cpu_clk, + .mux.hw.init = &(struct clk_init_data){ + .name = "cpu_clk", + .ops = &meson_clk_cpu_ops, + .parent_names = (const char *[]){ "cpu_fixedpll_p", "sys_pll"}, + .num_parents = 2, + .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED), + }, +}; + +static u32 mux_table_clk81[] = { 6, 5, 7 }; + +static struct clk_mux axg_mpeg_clk_sel = { + .reg = (void *)HHI_MPEG_CLK_CNTL, + .mask = 0x7, + .shift = 12, + .flags = CLK_MUX_READ_ONLY, + .table = mux_table_clk81, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "mpeg_clk_sel", + .ops = &clk_mux_ro_ops, + /* + * FIXME bits 14:12 selects from 8 possible parents: + * xtal, 1'b0 (wtf), fclk_div7, mpll_clkout1, mpll_clkout2, + * fclk_div4, fclk_div3, fclk_div5 + */ + .parent_names = (const char *[]){ "fclk_div3", "fclk_div4", + "fclk_div5" }, + .num_parents = 3, + .flags = (CLK_SET_RATE_NO_REPARENT | CLK_IGNORE_UNUSED), + }, +}; + +static struct clk_divider axg_mpeg_clk_div = { + .reg = (void *)HHI_MPEG_CLK_CNTL, + .shift = 0, + .width = 7, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "mpeg_clk_div", + .ops = &clk_divider_ops, + .parent_names = (const char *[]){ "mpeg_clk_sel" }, + .num_parents = 1, + .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), + }, +}; + +/* the mother of dragons^W gates */ +static struct clk_gate axg_clk81 = { + .reg = (void *)HHI_MPEG_CLK_CNTL, + .bit_idx = 7, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "clk81", + .ops = &clk_gate_ops, + .parent_names = (const char *[]){ "mpeg_clk_div" }, + .num_parents = 1, + .flags = (CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED), + }, +}; + +/* Everything Else (EE) domain gates */ +static MESON_GATE(axg_ddr, HHI_GCLK_MPEG0, 0); +static MESON_GATE(axg_audio_locker, HHI_GCLK_MPEG0, 2); +static MESON_GATE(axg_mipi_dsi_host, HHI_GCLK_MPEG0, 3); +static MESON_GATE(axg_isa, HHI_GCLK_MPEG0, 5); +static MESON_GATE(axg_pl301, HHI_GCLK_MPEG0, 6); +static MESON_GATE(axg_periphs, HHI_GCLK_MPEG0, 7); +static MESON_GATE(axg_spicc_0, HHI_GCLK_MPEG0, 8); +static MESON_GATE(axg_i2c, HHI_GCLK_MPEG0, 9); +static MESON_GATE(axg_rng0, HHI_GCLK_MPEG0, 12); +static MESON_GATE(axg_uart0, HHI_GCLK_MPEG0, 13); +static MESON_GATE(axg_mipi_dsi_phy, HHI_GCLK_MPEG0, 14); +static MESON_GATE(axg_spicc_1, HHI_GCLK_MPEG0, 15); +static MESON_GATE(axg_pcie_a, HHI_GCLK_MPEG0, 16); +static MESON_GATE(axg_pcie_b, HHI_GCLK_MPEG0, 17); +static MESON_GATE(axg_hiu_reg, HHI_GCLK_MPEG0, 19); +static MESON_GATE(axg_assist_misc, HHI_GCLK_MPEG0, 23); +static MESON_GATE(axg_emmc_b, HHI_GCLK_MPEG0, 25); +static MESON_GATE(axg_emmc_c, HHI_GCLK_MPEG0, 26); +static MESON_GATE(axg_dma, HHI_GCLK_MPEG0, 27); +static MESON_GATE(axg_spi, HHI_GCLK_MPEG0, 30); + +static MESON_GATE(axg_audio, HHI_GCLK_MPEG1, 0); +static MESON_GATE(axg_eth_core, HHI_GCLK_MPEG1, 3); +static MESON_GATE(axg_uart1, HHI_GCLK_MPEG1, 16); +static MESON_GATE(axg_g2d, HHI_GCLK_MPEG1, 20); +static MESON_GATE(axg_usb0, HHI_GCLK_MPEG1, 21); +static MESON_GATE(axg_usb1, HHI_GCLK_MPEG1, 22); +static MESON_GATE(axg_reset, HHI_GCLK_MPEG1, 23); +static MESON_GATE(axg_usb_general, HHI_GCLK_MPEG1, 26); +static MESON_GATE(axg_ahb_arb0, HHI_GCLK_MPEG1, 29); +static MESON_GATE(axg_efuse, HHI_GCLK_MPEG1, 30); +static MESON_GATE(axg_boot_rom, HHI_GCLK_MPEG1, 31); + +static MESON_GATE(axg_ahb_data_bus, HHI_GCLK_MPEG2, 1); +static MESON_GATE(axg_ahb_ctrl_bus, HHI_GCLK_MPEG2, 2); +static MESON_GATE(axg_usb1_to_ddr, HHI_GCLK_MPEG2, 8); +static MESON_GATE(axg_usb0_to_ddr, HHI_GCLK_MPEG2, 9); +static MESON_GATE(axg_mmc_pclk, HHI_GCLK_MPEG2, 11); +static MESON_GATE(axg_vpu_intr, HHI_GCLK_MPEG2, 25); +static MESON_GATE(axg_sec_ahb_ahb3_bridge, HHI_GCLK_MPEG2, 26); +static MESON_GATE(axg_gic, HHI_GCLK_MPEG2, 30); + +/* Always On (AO) domain gates */ + +static MESON_GATE(axg_ao_media_cpu, HHI_GCLK_AO, 0); +static MESON_GATE(axg_ao_ahb_sram, HHI_GCLK_AO, 1); +static MESON_GATE(axg_ao_ahb_bus, HHI_GCLK_AO, 2); +static MESON_GATE(axg_ao_iface, HHI_GCLK_AO, 3); +static MESON_GATE(axg_ao_i2c, HHI_GCLK_AO, 4); + +/* Array of all clocks provided by this provider */ + +static struct clk_hw *axg_clk_hws[] = { + [CLKID_SYS_PLL] = &axg_sys_pll.hw, + [CLKID_FIXED_PLL] = &axg_fixed_pll.hw, + [CLKID_GP0_PLL] = &axg_gp0_pll.hw, + [CLKID_HIFI_PLL] = &axg_hifi_pll.hw, + [CLKID_FCLK_DIV2] = &axg_fclk_div2.hw, + [CLKID_FCLK_DIV3] = &axg_fclk_div3.hw, + [CLKID_FCLK_DIV4] = &axg_fclk_div4.hw, + [CLKID_FCLK_DIV5] = &axg_fclk_div5.hw, + [CLKID_FCLK_DIV7] = &axg_fclk_div7.hw, + [CLKID_MPEG_SEL] = &axg_mpeg_clk_sel.hw, + [CLKID_MPEG_DIV] = &axg_mpeg_clk_div.hw, + [CLKID_CLK81] = &axg_clk81.hw, + [CLKID_MPLL0] = &axg_mpll0.hw, + [CLKID_MPLL1] = &axg_mpll1.hw, + [CLKID_MPLL2] = &axg_mpll2.hw, + [CLKID_MPLL3] = &axg_mpll3.hw, + [CLKID_DDR] = &axg_ddr.hw, + [CLKID_AUDIO_LOCKER] = &axg_audio_locker.hw, + [CLKID_MIPI_DSI_HOST] = &axg_mipi_dsi_host.hw, + [CLKID_ISA] = &axg_isa.hw, + [CLKID_PL301] = &axg_pl301.hw, + [CLKID_PERIPHS] = &axg_periphs.hw, + [CLKID_SPICC0] = &axg_spicc_0.hw, + [CLKID_I2C] = &axg_i2c.hw, + [CLKID_RNG0] = &axg_rng0.hw, + [CLKID_UART0] = &axg_uart0.hw, + [CLKID_MIPI_DSI_PHY] = &axg_mipi_dsi_phy.hw, + [CLKID_SPICC1] = &axg_spicc_1.hw, + [CLKID_PCIE_A] = &axg_pcie_a.hw, + [CLKID_PCIE_B] = &axg_pcie_b.hw, + [CLKID_HIU_REG] = &axg_hiu_reg.hw, + [CLKID_ASSIST_MISC] = &axg_assist_misc.hw, + [CLKID_SD_EMMC_B] = &axg_emmc_b.hw, + [CLKID_SD_EMMC_C] = &axg_emmc_c.hw, + [CLKID_DMA] = &axg_dma.hw, + [CLKID_SPI] = &axg_spi.hw, + [CLKID_AUDIO] = &axg_audio.hw, + [CLKID_ETH_CORE] = &axg_eth_core.hw, + [CLKID_UART1] = &axg_uart1.hw, + [CLKID_G2D] = &axg_g2d.hw, + [CLKID_USB0] = &axg_usb0.hw, + [CLKID_USB1] = &axg_usb1.hw, + [CLKID_RESET] = &axg_reset.hw, + [CLKID_USB_GENERAL] = &axg_usb_general.hw, + [CLKID_AHB_ARB0] = &axg_ahb_arb0.hw, + [CLKID_EFUSE] = &axg_efuse.hw, + [CLKID_BOOT_ROM] = &axg_boot_rom.hw, + [CLKID_AHB_DATA_BUS] = &axg_ahb_data_bus.hw, + [CLKID_AHB_CTRL_BUS] = &axg_ahb_ctrl_bus.hw, + [CLKID_USB1_TO_DDR] = &axg_usb1_to_ddr.hw, + [CLKID_USB0_TO_DDR] = &axg_usb0_to_ddr.hw, + [CLKID_MMC_PCLK] = &axg_mmc_pclk.hw, + [CLKID_VPU_INTR] = &axg_vpu_intr.hw, + [CLKID_SEC_AHB_AHB3_BRIDGE] = &axg_sec_ahb_ahb3_bridge.hw, + [CLKID_GIC] = &axg_gic.hw, + [CLKID_AO_MEDIA_CPU] = &axg_ao_media_cpu.hw, + [CLKID_AO_AHB_SRAM] = &axg_ao_ahb_sram.hw, + [CLKID_AO_AHB_BUS] = &axg_ao_ahb_bus.hw, + [CLKID_AO_IFACE] = &axg_ao_iface.hw, + [CLKID_AO_I2C] = &axg_ao_i2c.hw, + [CLKID_CPU_FCLK_P00] = &axg_cpu_fixedpll_p00.hw, + [CLKID_CPU_FCLK_P01] = &axg_cpu_fixedpll_p01.hw, + [CLKID_CPU_FCLK_P0] = &axg_cpu_fixedpll_p0.hw, + [CLKID_CPU_FCLK_P10] = &axg_cpu_fixedpll_p10.hw, + [CLKID_CPU_FCLK_P11] = &axg_cpu_fixedpll_p11.hw, + [CLKID_CPU_FCLK_P1] = &axg_cpu_fixedpll_p1.hw, + [CLKID_CPU_FCLK_P] = &axg_cpu_fixedpll_p.hw, + [CLKID_CPU_CLK] = &axg_cpu_clk.mux.hw, + [CLKID_PCIE_REFPLL] = &axg_pcierefpll.hw, +}; +/* Convenience tables to populate base addresses in .probe */ + +static struct meson_clk_pll *const axg_clk_plls[] = { + &axg_fixed_pll, + &axg_sys_pll, + &axg_gp0_pll, + &axg_hifi_pll, + &axg_pcierefpll, +}; + +static struct meson_clk_mpll *const axg_clk_mplls[] = { + &axg_mpll0, + &axg_mpll1, + &axg_mpll2, + &axg_mpll3, +}; + +static struct clk_gate *axg_clk_gates[] = { + &axg_clk81, + &axg_ddr, + &axg_audio_locker, + &axg_mipi_dsi_host, + &axg_isa, + &axg_pl301, + &axg_periphs, + &axg_spicc_0, + &axg_i2c, + &axg_rng0, + &axg_uart0, + &axg_mipi_dsi_phy, + &axg_spicc_1, + &axg_pcie_a, + &axg_pcie_b, + &axg_hiu_reg, + &axg_assist_misc, + &axg_emmc_b, + &axg_emmc_c, + &axg_dma, + &axg_spi, + &axg_audio, + &axg_eth_core, + &axg_uart1, + &axg_g2d, + &axg_usb0, + &axg_usb1, + &axg_reset, + &axg_usb_general, + &axg_ahb_arb0, + &axg_efuse, + &axg_boot_rom, + &axg_ahb_data_bus, + &axg_ahb_ctrl_bus, + &axg_usb1_to_ddr, + &axg_usb0_to_ddr, + &axg_mmc_pclk, + &axg_vpu_intr, + &axg_sec_ahb_ahb3_bridge, + &axg_gic, + &axg_ao_media_cpu, + &axg_ao_ahb_sram, + &axg_ao_ahb_bus, + &axg_ao_iface, + &axg_ao_i2c, +}; + +static void __init axg_clkc_init(struct device_node *np) +{ + int ret, clkid, i; + struct clk_hw *parent_hw; + struct clk *parent_clk; + + /* Generic clocks and PLLs */ + clk_base = of_iomap(np, 0); + if (!clk_base) { + pr_err("%s: Unable to map clk base\n", __func__); + /* return -ENXIO; */ + return; + } + /* pr_debug("%s: iomap clk_base ok!", __func__); */ + /* Populate base address for PLLs */ + for (i = 0; i < ARRAY_SIZE(axg_clk_plls); i++) + axg_clk_plls[i]->base = clk_base; + + /* Populate base address for MPLLs */ + for (i = 0; i < ARRAY_SIZE(axg_clk_mplls); i++) + axg_clk_mplls[i]->base = clk_base; + + /* Populate the base address for CPU clk */ + axg_cpu_clk.mux.reg = clk_base + (u64)axg_cpu_clk.mux.reg; + axg_cpu_fixedpll_p00.reg = clk_base + (u64)axg_cpu_fixedpll_p00.reg; + axg_cpu_fixedpll_p01.reg = clk_base + (u64)axg_cpu_fixedpll_p01.reg; + axg_cpu_fixedpll_p10.reg = clk_base + (u64)axg_cpu_fixedpll_p10.reg; + axg_cpu_fixedpll_p11.reg = clk_base + (u64)axg_cpu_fixedpll_p11.reg; + axg_cpu_fixedpll_p0.reg = clk_base + (u64)axg_cpu_fixedpll_p0.reg; + axg_cpu_fixedpll_p1.reg = clk_base + (u64)axg_cpu_fixedpll_p1.reg; + axg_cpu_fixedpll_p.reg = clk_base + (u64)axg_cpu_fixedpll_p.reg; + + /* Populate the base address for the MPEG clks */ + axg_mpeg_clk_sel.reg = clk_base + (u64)axg_mpeg_clk_sel.reg; + axg_mpeg_clk_div.reg = clk_base + (u64)axg_mpeg_clk_div.reg; + + /* Populate base address for gates */ + for (i = 0; i < ARRAY_SIZE(axg_clk_gates); i++) + axg_clk_gates[i]->reg = clk_base + + (u64)axg_clk_gates[i]->reg; + + clks = kzalloc(NR_CLKS*sizeof(struct clk *), GFP_KERNEL); + if (!clks) { + /* pr_err("%s: alloc clks fail!", __func__); */ + /* return -ENOMEM; */ + return; + } + /* pr_debug("%s: kzalloc clks ok!", __func__); */ + clk_data.clks = clks; + clk_data.clk_num = NR_CLKS; + /* + * register all clks + */ + + for (clkid = 0; clkid < OTHER_BASE; clkid++) { + clks[clkid] = clk_register(NULL, axg_clk_hws[clkid]); + WARN_ON(IS_ERR(clks[clkid])); + } + + axg_amlogic_init_sdemmc(); + axg_amlogic_init_media(); + axg_amlogic_init_misc(); + pr_debug("%s: register all clk ok!", __func__); + /* + * Register CPU clk notifier + * + * FIXME this is wrong for a lot of reasons. First, the muxes should be + * struct clk_hw objects. Second, we shouldn't program the muxes in + * notifier handlers. The tricky programming sequence will be handled + * by the forthcoming coordinated clock rates mechanism once that + * feature is released. + * + * Furthermore, looking up the parent this way is terrible. At some + * point we will stop allocating a default struct clk when registering + * a new clk_hw, and this hack will no longer work. Releasing the ccr + * feature before that time solves the problem :-) + */ + parent_hw = clk_hw_get_parent(&axg_cpu_clk.mux.hw); + parent_clk = parent_hw->clk; + ret = clk_notifier_register(parent_clk, &axg_cpu_clk.clk_nb); + if (ret) { + pr_err("%s: failed to register clock notifier for cpu_clk\n", + __func__); + goto iounmap; + } + pr_debug("%s: cpu clk register notifier ok!", __func__); + + ret = of_clk_add_provider(np, of_clk_src_onecell_get, + &clk_data); + if (ret < 0) + pr_err("%s fail ret: %d\n", __func__, ret); + else + pr_info("%s initialization complete\n", __func__); + return; + +iounmap: + iounmap(clk_base); + pr_info("%s: %d: ret: %d\n", __func__, __LINE__, ret); + /* return; */ +} + +CLK_OF_DECLARE(axg, "amlogic,axg-clkc", axg_clkc_init); + + diff --git a/drivers/amlogic/clk/axg/axg.h b/drivers/amlogic/clk/axg/axg.h new file mode 100644 index 000000000000..a39dfe1a4de7 --- /dev/null +++ b/drivers/amlogic/clk/axg/axg.h @@ -0,0 +1,268 @@ +/* + * drivers/amlogic/clk/axg/axg.h + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef __AXG_H +#define __AXG_H + +/* + * Clock controller register offsets + * + * Register offsets from the data sheet are listed in comment blocks below. + * Those offsets must be multiplied by 4 before adding them to the base address + * to get the right value + */ + +#define HHI_GP0_PLL_CNTL 0x40 /* 0x10 offset in data sheet */ + +#define HHI_HIFI_PLL_CNTL 0x80 /* 0x20 offset in data sheet */ + +#define HHI_PCIE_PLL_CNTL 0xd8 /* 0x36 offset in data sheet */ + +#define HHI_GCLK_MPEG0 0x140 /* 0x50 offset in data sheet */ +#define HHI_GCLK_MPEG1 0x144 /* 0x51 offset in data sheet */ +#define HHI_GCLK_MPEG2 0x148 /* 0x52 offset in data sheet */ + +#define HHI_GCLK_AO 0x154 /* 0x55 offset in data sheet */ + +#define HHI_VID_CLK_DIV 0x164 /* 0x59 offset in data sheet */ +#define HHI_SPICC_HCLK_CNTL 0x168 /* 0x5a offset in data sheet */ + +#define HHI_MPEG_CLK_CNTL 0x174 /* 0x5d offset in data sheet */ +#define HHI_AUD_CLK_CNTL 0x178 /* 0x5e offset in data sheet */ +#define HHI_VID_CLK_CNTL 0x17c /* 0x5f offset in data sheet */ +#define HHI_AUD_CLK_CNTL2 0x190 /* 0x64 offset in data sheet */ +#define HHI_VID_CLK_CNTL2 0x194 /* 0x65 offset in data sheet */ +#define HHI_SYS_CPU_CLK_CNTL0 0x19c /* 0x67 offset in data sheet */ + +#define HHI_VPU_CLK_CNTL 0x1bC /* 0x6f offset in data sheet */ + +#define HHI_VAPBCLK_CNTL 0x1F4 /* 0x7d offset in data sheet */ + +#define HHI_VDIN_MEAS_CLK_CNTL 0x250 /* 0x94 offset in data sheet */ + +#define HHI_NAND_CLK_CNTL 0x25C /* 0x97 offset in data sheet */ +#define HHI_SD_EMMC_CLK_CNTL 0x264 /* 0x99 offset in data sheet */ + +#define HHI_MPLL_CNTL 0x280 /* 0xa0 offset in data sheet */ +#define HHI_MPLL_CNTL2 0x284 /* 0xa1 offset in data sheet */ +#define HHI_MPLL_CNTL3 0x288 /* 0xa2 offset in data sheet */ +#define HHI_MPLL_CNTL4 0x28C /* 0xa3 offset in data sheet */ +#define HHI_MPLL_CNTL5 0x290 /* 0xa4 offset in data sheet */ +#define HHI_MPLL_CNTL6 0x294 /* 0xa5 offset in data sheet */ +#define HHI_MPLL_CNTL7 0x298 /* MP0, 0xa6 offset */ +#define HHI_MPLL_CNTL8 0x29C /* MP1, 0xa7 offset */ +#define HHI_MPLL_CNTL9 0x2A0 /* MP2, 0xa8 offset */ +#define HHI_MPLL_CNTL10 0x2A4 /* MP2, 0xa9 offset */ + +#define HHI_MPLL3_CNTL0 0x2E0 /* 0xb8 offset in data sheet */ +#define HHI_MPLL3_CNTL1 0x2E4 /* 0xb9 offset in data sheet */ +#define HHI_PLL_TOP_MISC 0x2E8 /* 0xba offset in data sheet */ + +#define HHI_SYS_PLL_CNTL 0x300 /* 0xc0 offset in data sheet */ +#define HHI_SYS_PLL_CNTL2 0x304 /* 0xc1 offset in data sheet */ +#define HHI_SYS_PLL_CNTL3 0x308 /* 0xc2 offset in data sheet */ +#define HHI_SYS_PLL_CNTL4 0x30c /* 0xc3 offset in data sheet */ +#define HHI_SYS_PLL_CNTL5 0x310 /* 0xc4 offset in data sheet */ + +static const struct pll_rate_table sys_pll_rate_table[] = { + PLL_RATE(24000000, 56, 1, 2), + PLL_RATE(48000000, 64, 1, 2), + PLL_RATE(72000000, 72, 1, 2), + PLL_RATE(96000000, 64, 1, 2), + PLL_RATE(120000000, 80, 1, 2), + PLL_RATE(144000000, 96, 1, 2), + PLL_RATE(168000000, 56, 1, 1), + PLL_RATE(192000000, 64, 1, 1), + PLL_RATE(216000000, 72, 1, 1), + PLL_RATE(240000000, 80, 1, 1), + PLL_RATE(264000000, 88, 1, 1), + PLL_RATE(288000000, 96, 1, 1), + PLL_RATE(312000000, 52, 1, 2), + PLL_RATE(336000000, 56, 1, 2), + PLL_RATE(360000000, 60, 1, 2), + PLL_RATE(384000000, 64, 1, 2), + PLL_RATE(408000000, 68, 1, 2), + PLL_RATE(432000000, 72, 1, 2), + PLL_RATE(456000000, 76, 1, 2), + PLL_RATE(480000000, 80, 1, 2), + PLL_RATE(504000000, 84, 1, 2), + PLL_RATE(528000000, 88, 1, 2), + PLL_RATE(552000000, 92, 1, 2), + PLL_RATE(576000000, 96, 1, 2), + PLL_RATE(600000000, 50, 1, 1), + PLL_RATE(624000000, 52, 1, 1), + PLL_RATE(648000000, 54, 1, 1), + PLL_RATE(672000000, 56, 1, 1), + PLL_RATE(696000000, 58, 1, 1), + PLL_RATE(720000000, 60, 1, 1), + PLL_RATE(744000000, 62, 1, 1), + PLL_RATE(768000000, 64, 1, 1), + PLL_RATE(792000000, 66, 1, 1), + PLL_RATE(816000000, 68, 1, 1), + PLL_RATE(840000000, 70, 1, 1), + PLL_RATE(864000000, 72, 1, 1), + PLL_RATE(888000000, 74, 1, 1), + PLL_RATE(912000000, 76, 1, 1), + PLL_RATE(936000000, 78, 1, 1), + PLL_RATE(960000000, 80, 1, 1), + PLL_RATE(984000000, 82, 1, 1), + PLL_RATE(1008000000, 84, 1, 1), + PLL_RATE(1032000000, 86, 1, 1), + PLL_RATE(1056000000, 88, 1, 1), + PLL_RATE(1080000000, 90, 1, 1), + PLL_RATE(1104000000, 92, 1, 1), + PLL_RATE(1128000000, 94, 1, 1), + PLL_RATE(1152000000, 96, 1, 1), + PLL_RATE(1176000000, 98, 1, 1), + PLL_RATE(1200000000, 50, 1, 0), + PLL_RATE(1224000000, 51, 1, 0), + PLL_RATE(1248000000, 52, 1, 0), + PLL_RATE(1272000000, 53, 1, 0), + PLL_RATE(1296000000, 54, 1, 0), + PLL_RATE(1320000000, 55, 1, 0), + PLL_RATE(1344000000, 56, 1, 0), + PLL_RATE(1368000000, 57, 1, 0), + PLL_RATE(1392000000, 58, 1, 0), + PLL_RATE(1416000000, 59, 1, 0), + PLL_RATE(1440000000, 60, 1, 0), + PLL_RATE(1464000000, 61, 1, 0), + PLL_RATE(1488000000, 62, 1, 0), + PLL_RATE(1512000000, 63, 1, 0), + PLL_RATE(1536000000, 64, 1, 0), + PLL_RATE(1560000000, 65, 1, 0), + PLL_RATE(1584000000, 66, 1, 0), + PLL_RATE(1608000000, 67, 1, 0), + PLL_RATE(1632000000, 68, 1, 0), + PLL_RATE(1656000000, 68, 1, 0), + PLL_RATE(1680000000, 68, 1, 0), + PLL_RATE(1704000000, 68, 1, 0), + PLL_RATE(1728000000, 69, 1, 0), + PLL_RATE(1752000000, 69, 1, 0), + PLL_RATE(1776000000, 69, 1, 0), + PLL_RATE(1800000000, 69, 1, 0), + PLL_RATE(1824000000, 70, 1, 0), + PLL_RATE(1848000000, 70, 1, 0), + PLL_RATE(1872000000, 70, 1, 0), + PLL_RATE(1896000000, 70, 1, 0), + PLL_RATE(1920000000, 71, 1, 0), + PLL_RATE(1944000000, 71, 1, 0), + PLL_RATE(1968000000, 71, 1, 0), + PLL_RATE(1992000000, 71, 1, 0), + PLL_RATE(2016000000, 72, 1, 0), + PLL_RATE(2040000000, 72, 1, 0), + PLL_RATE(2064000000, 72, 1, 0), + PLL_RATE(2088000000, 72, 1, 0), + PLL_RATE(2112000000, 73, 1, 0), + { /* sentinel */ }, +}; + +/*AXG: gp0_pll: Fdco: 0.96G~1.632G Fdco = 24*(M+frac)/N + *N: recommend is 1 + *gp0_clk_out = Fdco /Fod + *od=0 Fod=1 od=1 Fod=2 od=2 Fod=4 od=3 Fod=4 + */ +static const struct pll_rate_table axg_gp0_pll_rate_table[] = { + PLL_RATE(240000000, 40, 1, 2), + PLL_RATE(246000000, 41, 1, 2), + PLL_RATE(252000000, 42, 1, 2), + PLL_RATE(258000000, 43, 1, 2), + PLL_RATE(264000000, 44, 1, 2), + PLL_RATE(270000000, 45, 1, 2), + PLL_RATE(276000000, 46, 1, 2), + PLL_RATE(282000000, 47, 1, 2), + PLL_RATE(288000000, 48, 1, 2), + PLL_RATE(294000000, 49, 1, 2), + PLL_RATE(300000000, 50, 1, 2), + PLL_RATE(306000000, 51, 1, 2), + PLL_RATE(312000000, 52, 1, 2), + PLL_RATE(318000000, 53, 1, 2), + PLL_RATE(324000000, 54, 1, 2), + PLL_RATE(330000000, 55, 1, 2), + PLL_RATE(336000000, 56, 1, 2), + PLL_RATE(342000000, 57, 1, 2), + PLL_RATE(348000000, 58, 1, 2), + PLL_RATE(354000000, 59, 1, 2), + PLL_RATE(360000000, 60, 1, 2), + PLL_RATE(366000000, 61, 1, 2), + PLL_RATE(372000000, 62, 1, 2), + PLL_RATE(378000000, 63, 1, 2), + PLL_RATE(384000000, 64, 1, 2), + PLL_RATE(390000000, 65, 1, 3), + PLL_RATE(396000000, 66, 1, 3), + PLL_RATE(402000000, 67, 1, 3), + PLL_RATE(408000000, 68, 1, 3), + PLL_RATE(480000000, 40, 1, 1), + PLL_RATE(492000000, 41, 1, 1), + PLL_RATE(504000000, 42, 1, 1), + PLL_RATE(516000000, 43, 1, 1), + PLL_RATE(528000000, 44, 1, 1), + PLL_RATE(540000000, 45, 1, 1), + PLL_RATE(552000000, 46, 1, 1), + PLL_RATE(564000000, 47, 1, 1), + PLL_RATE(576000000, 48, 1, 1), + PLL_RATE(588000000, 49, 1, 1), + PLL_RATE(600000000, 50, 1, 1), + PLL_RATE(612000000, 51, 1, 1), + PLL_RATE(624000000, 52, 1, 1), + PLL_RATE(636000000, 53, 1, 1), + PLL_RATE(648000000, 54, 1, 1), + PLL_RATE(660000000, 55, 1, 1), + PLL_RATE(672000000, 56, 1, 1), + PLL_RATE(684000000, 57, 1, 1), + PLL_RATE(696000000, 58, 1, 1), + PLL_RATE(708000000, 59, 1, 1), + PLL_RATE(720000000, 60, 1, 1), + PLL_RATE(732000000, 61, 1, 1), + PLL_RATE(744000000, 62, 1, 1), + PLL_RATE(756000000, 63, 1, 1), + PLL_RATE(768000000, 64, 1, 1), + PLL_RATE(780000000, 65, 1, 1), + PLL_RATE(792000000, 66, 1, 1), + PLL_RATE(804000000, 67, 1, 1), + PLL_RATE(816000000, 68, 1, 1), + PLL_RATE(960000000, 40, 1, 0), + PLL_RATE(984000000, 41, 1, 0), + PLL_RATE(1008000000, 42, 1, 0), + PLL_RATE(1032000000, 43, 1, 0), + PLL_RATE(1056000000, 44, 1, 0), + PLL_RATE(1080000000, 45, 1, 0), + PLL_RATE(1104000000, 46, 1, 0), + PLL_RATE(1128000000, 47, 1, 0), + PLL_RATE(1152000000, 48, 1, 0), + PLL_RATE(1176000000, 49, 1, 0), + PLL_RATE(1200000000, 50, 1, 0), + PLL_RATE(1224000000, 51, 1, 0), + PLL_RATE(1248000000, 52, 1, 0), + PLL_RATE(1272000000, 53, 1, 0), + PLL_RATE(1296000000, 54, 1, 0), + PLL_RATE(1320000000, 55, 1, 0), + PLL_RATE(1344000000, 56, 1, 0), + PLL_RATE(1368000000, 57, 1, 0), + PLL_RATE(1392000000, 58, 1, 0), + PLL_RATE(1416000000, 59, 1, 0), + PLL_RATE(1440000000, 60, 1, 0), + PLL_RATE(1464000000, 61, 1, 0), + PLL_RATE(1488000000, 62, 1, 0), + PLL_RATE(1512000000, 63, 1, 0), + PLL_RATE(1536000000, 64, 1, 0), + PLL_RATE(1560000000, 65, 1, 0), + PLL_RATE(1584000000, 66, 1, 0), + PLL_RATE(1608000000, 67, 1, 0), + PLL_RATE(1632000000, 68, 1, 0), + { /* sentinel */ }, +}; +#endif /* __AXG_H */ diff --git a/drivers/amlogic/clk/axg/axg_clk_media.c b/drivers/amlogic/clk/axg/axg_clk_media.c new file mode 100644 index 000000000000..f57aba4c01f2 --- /dev/null +++ b/drivers/amlogic/clk/axg/axg_clk_media.c @@ -0,0 +1,427 @@ +/* + * drivers/amlogic/clk/axg/axg_clk_media.c + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "../clkc.h" +#include "axg.h" + +/* cts_dsi_meas_clk */ /*MIPI_HOST*/ +static const char * const meas_parent_names[] = { "xtal", "fclk_div4", + "fclk_div3", "fclk_div5", "null", "null", "fclk_dvi2", "fclk_div7"}; + +/* cts_dsi_meas_clk */ +static struct clk_mux dsi_meas_mux = { + .reg = (void *)HHI_VDIN_MEAS_CLK_CNTL, + .mask = 0x7, + .shift = 21, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "dsi_meas_mux", + .ops = &clk_mux_ops, + .parent_names = meas_parent_names, + .num_parents = 8, + .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED), + }, +}; + +static struct clk_divider dsi_meas_div = { + .reg = (void *)HHI_VDIN_MEAS_CLK_CNTL, + .shift = 12, + .width = 7, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "dsi_meas_div", + .ops = &clk_divider_ops, + .parent_names = (const char *[]){ "dsi_meas_mux" }, + .num_parents = 1, + .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED), + }, +}; + +static struct clk_gate dsi_meas_gate = { + .reg = (void *)HHI_VDIN_MEAS_CLK_CNTL, + .bit_idx = 20, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data) { + .name = "dsi_meas_gate", + .ops = &clk_gate_ops, + .parent_names = (const char *[]){ "dsi_meas_div" }, + .num_parents = 1, + .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED), + }, +}; + +static struct clk_hw *dsi_meas_clk_hws[] = { +[CLKID_DSI_MEAS_MUX - CLKID_DSI_MEAS_MUX] = &dsi_meas_mux.hw, +[CLKID_DSI_MEAS_DIV - CLKID_DSI_MEAS_MUX] = &dsi_meas_div.hw, +[CLKID_DSI_MEAS_GATE - CLKID_DSI_MEAS_MUX] = &dsi_meas_gate.hw, +}; + +static const char * const vpu_parent_names[] = { "fclk_div4", + "fclk_div3", "fclk_div5", "fclk_div7", "mpll1", "null", + "mpll2", "null"}; + +/* cts_vpu_clk */ +static struct clk_mux vpu_p0_mux = { + .reg = (void *)HHI_VPU_CLK_CNTL, + .mask = 0x7, + .shift = 9, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "vpu_p0_mux", + .ops = &clk_mux_ops, + .parent_names = vpu_parent_names, + .num_parents = 8, + .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED), + }, +}; + +static struct clk_divider vpu_p0_div = { + .reg = (void *)HHI_VPU_CLK_CNTL, + .shift = 0, + .width = 7, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "vpu_p0_div", + .ops = &clk_divider_ops, + .parent_names = (const char *[]){ "vpu_p0_mux" }, + .num_parents = 1, + .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED), + }, +}; + +static struct clk_gate vpu_p0_gate = { + .reg = (void *)HHI_VPU_CLK_CNTL, + .bit_idx = 8, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data) { + .name = "vpu_p0_gate", + .ops = &clk_gate_ops, + .parent_names = (const char *[]){ "vpu_p0_div" }, + .num_parents = 1, + .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED), + }, +}; + +static struct clk_mux vpu_p1_mux = { + .reg = (void *)HHI_VPU_CLK_CNTL, + .mask = 0x7, + .shift = 25, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "vpu_p1_mux", + .ops = &clk_mux_ops, + .parent_names = vpu_parent_names, + .num_parents = 8, + .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED), + }, +}; + +static struct clk_divider vpu_p1_div = { + .reg = (void *)HHI_VPU_CLK_CNTL, + .shift = 16, + .width = 7, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "vpu_p1_div", + .ops = &clk_divider_ops, + .parent_names = (const char *[]){ "vpu_p1_mux" }, + .num_parents = 1, + .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED), + }, +}; + +static struct clk_gate vpu_p1_gate = { + .reg = (void *)HHI_VPU_CLK_CNTL, + .bit_idx = 24, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data) { + .name = "vpu_p1_gate", + .ops = &clk_gate_ops, + .parent_names = (const char *[]){ "vpu_p1_div" }, + .num_parents = 1, + .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED), + }, +}; + +static struct clk_mux vpu_mux = { + .reg = (void *)HHI_VPU_CLK_CNTL, + .mask = 0x1, + .shift = 31, + .lock = &clk_lock, + .flags = CLK_PARENT_ALTERNATE, + .hw.init = &(struct clk_init_data){ + .name = "vpu_mux", + .ops = &meson_clk_mux_ops, + .parent_names = (const char *[]){ "vpu_p0_composite", + "vpu_p1_composite"}, + .num_parents = 2, + .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED | + CLK_PARENT_ALTERNATE), + }, +}; + +static struct clk_hw *vpu_clk_hws[] = { + [CLKID_VPU_P0_MUX - CLKID_VPU_P0_MUX] = &vpu_p0_mux.hw, + [CLKID_VPU_P0_DIV - CLKID_VPU_P0_MUX] = &vpu_p0_div.hw, + [CLKID_VPU_P0_GATE - CLKID_VPU_P0_MUX] = &vpu_p0_gate.hw, + [CLKID_VPU_P1_MUX - CLKID_VPU_P0_MUX] = &vpu_p1_mux.hw, + [CLKID_VPU_P1_DIV - CLKID_VPU_P0_MUX] = &vpu_p1_div.hw, + [CLKID_VPU_P1_GATE - CLKID_VPU_P0_MUX] = &vpu_p1_gate.hw, + [CLKID_VPU_MUX - CLKID_VPU_P0_MUX] = &vpu_mux.hw, +}; + +/* cts_vapbclk */ +static struct clk_mux vapb_p0_mux = { + .reg = (void *)HHI_VAPBCLK_CNTL, + .mask = 0x7, + .shift = 9, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "vapb_p0_mux", + .ops = &clk_mux_ops, + .parent_names = vpu_parent_names, + .num_parents = 8, + .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED), + }, +}; + +static struct clk_divider vapb_p0_div = { + .reg = (void *)HHI_VAPBCLK_CNTL, + .shift = 0, + .width = 7, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "vapb_p0_div", + .ops = &clk_divider_ops, + .parent_names = (const char *[]){ "vapb_p0_mux" }, + .num_parents = 1, + .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED), + }, +}; + +static struct clk_gate vapb_p0_gate = { + .reg = (void *)HHI_VAPBCLK_CNTL, + .bit_idx = 8, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data) { + .name = "vapb_p0_gate", + .ops = &clk_gate_ops, + .parent_names = (const char *[]){ "vapb_p0_div" }, + .num_parents = 1, + .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED), + }, +}; + +static struct clk_mux vapb_p1_mux = { + .reg = (void *)HHI_VAPBCLK_CNTL, + .mask = 0x7, + .shift = 25, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "vapb_p1_mux", + .ops = &clk_mux_ops, + .parent_names = vpu_parent_names, + .num_parents = 8, + .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED), + }, +}; + +static struct clk_divider vapb_p1_div = { + .reg = (void *)HHI_VAPBCLK_CNTL, + .shift = 16, + .width = 7, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "vapb_p1_div", + .ops = &clk_divider_ops, + .parent_names = (const char *[]){ "vapb_p1_mux" }, + .num_parents = 1, + .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED), + }, +}; + +static struct clk_gate vapb_p1_gate = { + .reg = (void *)HHI_VAPBCLK_CNTL, + .bit_idx = 24, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data) { + .name = "vapb_p1_gate", + .ops = &clk_gate_ops, + .parent_names = (const char *[]){ "vapb_p1_div" }, + .num_parents = 1, + .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED), + }, +}; + +static struct clk_mux vapb_mux = { + .reg = (void *)HHI_VAPBCLK_CNTL, + .mask = 0x1, + .shift = 31, + .lock = &clk_lock, + .flags = CLK_PARENT_ALTERNATE, + .hw.init = &(struct clk_init_data){ + .name = "vapb_mux", + .ops = &meson_clk_mux_ops, + .parent_names = (const char *[]){ "vapb_p0_composite", + "vapb_p1_composite"}, + .num_parents = 2, + .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED | + CLK_PARENT_ALTERNATE), + }, +}; + +static struct clk_hw *vapb_clk_hws[] = { + [CLKID_VPU_P0_MUX - CLKID_VPU_P0_MUX] = &vapb_p0_mux.hw, + [CLKID_VPU_P0_DIV - CLKID_VPU_P0_MUX] = &vapb_p0_div.hw, + [CLKID_VPU_P0_GATE - CLKID_VPU_P0_MUX] = &vapb_p0_gate.hw, + [CLKID_VPU_P1_MUX - CLKID_VPU_P0_MUX] = &vapb_p1_mux.hw, + [CLKID_VPU_P1_DIV - CLKID_VPU_P0_MUX] = &vapb_p1_div.hw, + [CLKID_VPU_P1_GATE - CLKID_VPU_P0_MUX] = &vapb_p1_gate.hw, + [CLKID_VPU_MUX - CLKID_VPU_P0_MUX] = &vapb_mux.hw, +}; + +static struct clk_gate ge2d_gate = { + .reg = (void *)HHI_VAPBCLK_CNTL, + .bit_idx = 30, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data) { + .name = "ge2d_gate", + .ops = &clk_gate_ops, + .parent_names = (const char *[]){ "vapb_mux" }, + .num_parents = 1, + .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED), + }, +}; + +void axg_amlogic_init_media(void) +{ + /* cts_dsi_meas_clk */ + dsi_meas_mux.reg = clk_base + (u64)(dsi_meas_mux.reg); + dsi_meas_div.reg = clk_base + (u64)(dsi_meas_div.reg); + dsi_meas_gate.reg = clk_base + (u64)(dsi_meas_gate.reg); + + /* cts_vpu_clk */ + vpu_p0_mux.reg = clk_base + (u64)(vpu_p0_mux.reg); + vpu_p0_div.reg = clk_base + (u64)(vpu_p0_div.reg); + vpu_p0_gate.reg = clk_base + (u64)(vpu_p0_gate.reg); + vpu_p1_mux.reg = clk_base + (u64)(vpu_p1_mux.reg); + vpu_p1_div.reg = clk_base + (u64)(vpu_p1_div.reg); + vpu_p1_gate.reg = clk_base + (u64)(vpu_p1_gate.reg); + vpu_mux.reg = clk_base + (u64)(vpu_mux.reg); + /* cts_vapbclk */ + vapb_p0_mux.reg = clk_base + (u64)(vapb_p0_mux.reg); + vapb_p0_div.reg = clk_base + (u64)(vapb_p0_div.reg); + vapb_p0_gate.reg = clk_base + (u64)(vapb_p0_gate.reg); + vapb_p1_mux.reg = clk_base + (u64)(vapb_p1_mux.reg); + vapb_p1_div.reg = clk_base + (u64)(vapb_p1_div.reg); + vapb_p1_gate.reg = clk_base + (u64)(vapb_p1_gate.reg); + vapb_mux.reg = clk_base + (u64)(vapb_mux.reg); + /* cts_ge2d_clk */ + ge2d_gate.reg = clk_base + (u64)(ge2d_gate.reg); + + clks[CLKID_DSI_MEAS_COMP] = clk_register_composite(NULL, + "dsi_meas_composite", + meas_parent_names, 6, + dsi_meas_clk_hws[CLKID_DSI_MEAS_MUX - CLKID_DSI_MEAS_MUX], + &clk_mux_ops, + dsi_meas_clk_hws[CLKID_DSI_MEAS_DIV - CLKID_DSI_MEAS_MUX], + &clk_divider_ops, + dsi_meas_clk_hws[CLKID_DSI_MEAS_GATE - CLKID_DSI_MEAS_MUX], + &clk_gate_ops, 0); + if (IS_ERR(clks[CLKID_DSI_MEAS_COMP])) + pr_err("%s: %d clk_register_composite dsi_meas_composite error\n", + __func__, __LINE__); + + /* cts_vpu_clk */ + clks[CLKID_VPU_P0_COMP] = clk_register_composite(NULL, + "vpu_p0_composite", + vpu_parent_names, 8, + vpu_clk_hws[CLKID_VPU_P0_MUX - CLKID_VPU_P0_MUX], + &clk_mux_ops, + vpu_clk_hws[CLKID_VPU_P0_DIV - CLKID_VPU_P0_MUX], + &clk_divider_ops, + vpu_clk_hws[CLKID_VPU_P0_GATE - CLKID_VPU_P0_MUX], + &clk_gate_ops, 0); + if (IS_ERR(clks[CLKID_VPU_P0_COMP])) + pr_err("%s: %d clk_register_composite vpu_p0_composite error\n", + __func__, __LINE__); + + clks[CLKID_VPU_P1_COMP] = clk_register_composite(NULL, + "vpu_p1_composite", + vpu_parent_names, 8, + vpu_clk_hws[CLKID_VPU_P1_MUX - CLKID_VPU_P0_MUX], + &clk_mux_ops, + vpu_clk_hws[CLKID_VPU_P1_DIV - CLKID_VPU_P0_MUX], + &clk_divider_ops, + vpu_clk_hws[CLKID_VPU_P1_GATE - CLKID_VPU_P0_MUX], + &clk_gate_ops, 0); + if (IS_ERR(clks[CLKID_VPU_P1_COMP])) + pr_err("%s: %d clk_register_composite vpu_p1_composite error\n", + __func__, __LINE__); + + clks[CLKID_VPU_MUX] = clk_register(NULL, + vpu_clk_hws[CLKID_VPU_MUX - CLKID_VPU_P0_MUX]); + WARN_ON(IS_ERR(clks[CLKID_VPU_MUX])); + clk_prepare_enable(clks[CLKID_VPU_MUX]); + + /* cts_vapb_clk */ + clks[CLKID_VAPB_P0_COMP] = clk_register_composite(NULL, + "vapb_p0_composite", + vpu_parent_names, 8, + vapb_clk_hws[CLKID_VAPB_P0_MUX - CLKID_VAPB_P0_MUX], + &clk_mux_ops, + vapb_clk_hws[CLKID_VAPB_P0_DIV - CLKID_VAPB_P0_MUX], + &clk_divider_ops, + vapb_clk_hws[CLKID_VAPB_P0_GATE - CLKID_VAPB_P0_MUX], + &clk_gate_ops, 0); + if (IS_ERR(clks[CLKID_VAPB_P0_COMP])) + pr_err("%s: %d clk_register_composite vapb_p0_composite error\n", + __func__, __LINE__); + + clks[CLKID_VAPB_P1_COMP] = clk_register_composite(NULL, + "vapb_p1_composite", + vpu_parent_names, 8, + vapb_clk_hws[CLKID_VAPB_P1_MUX - CLKID_VAPB_P0_MUX], + &clk_mux_ops, + vapb_clk_hws[CLKID_VAPB_P1_DIV - CLKID_VAPB_P0_MUX], + &clk_divider_ops, + vapb_clk_hws[CLKID_VAPB_P1_GATE - CLKID_VAPB_P0_MUX], + &clk_gate_ops, 0); + if (IS_ERR(clks[CLKID_VAPB_P1_COMP])) + pr_err("%s: %d clk_register_composite vapb_p1_composite error\n", + __func__, __LINE__); + + clks[CLKID_VAPB_MUX] = clk_register(NULL, + vapb_clk_hws[CLKID_VAPB_MUX - CLKID_VAPB_P0_MUX]); + WARN_ON(IS_ERR(clks[CLKID_VAPB_MUX])); + clk_prepare_enable(clks[CLKID_VAPB_MUX]); + + clks[CLKID_GE2D_GATE] = clk_register(NULL, + &ge2d_gate.hw); + WARN_ON(IS_ERR(clks[CLKID_GE2D_GATE])); + + pr_info("%s: register meson media clk\n", __func__); +} + diff --git a/drivers/amlogic/clk/axg/axg_clk_misc.c b/drivers/amlogic/clk/axg/axg_clk_misc.c new file mode 100644 index 000000000000..11b053e8f377 --- /dev/null +++ b/drivers/amlogic/clk/axg/axg_clk_misc.c @@ -0,0 +1,105 @@ +/* + * drivers/amlogic/clk/axg/axg_clk_misc.c + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "../clkc.h" +#include "axg.h" + +static const char * const spicc_parent_names[] = { "fclk_div4", + "fclk_div3", "fclk_div5", "fclk_div7" }; + +static struct clk_mux spicc_mux = { + .reg = (void *)HHI_SPICC_HCLK_CNTL, + .mask = 0x3, + .shift = 8, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "spicc_mux", + .ops = &clk_mux_ops, + .parent_names = spicc_parent_names, + .num_parents = 4, + .flags = (CLK_MUX_ROUND_CLOSEST), + }, +}; + +static struct clk_divider spicc_div = { + .reg = (void *)HHI_SPICC_HCLK_CNTL, + .shift = 0, + .width = 7, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "spicc_div", + .ops = &clk_divider_ops, + .parent_names = (const char *[]){ "spicc_mux" }, + .num_parents = 1, + .flags = (CLK_DIVIDER_ROUND_CLOSEST), + }, +}; + +static struct clk_gate spicc_gate = { + .reg = (void *)HHI_SPICC_HCLK_CNTL, + .bit_idx = 15, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data) { + .name = "spicc_gate", + .ops = &clk_gate_ops, + .parent_names = (const char *[]){ "spicc_div" }, + .num_parents = 1, + .flags = 0, + }, +}; + +static struct clk_hw *misc_clk_hws[] = { + [CLKID_SPICC_MUX - CLKID_SPICC_MUX] + = &spicc_mux.hw, + [CLKID_SPICC_DIV - CLKID_SPICC_MUX] + = &spicc_div.hw, + [CLKID_SPICC_GATE - CLKID_SPICC_MUX] + = &spicc_gate.hw, +}; + +void axg_amlogic_init_misc(void) +{ + /* Populate base address for reg */ + pr_info("%s: register amlogic axg misc clks\n", __func__); + + spicc_mux.reg = clk_base + (u64)(spicc_mux.reg); + spicc_div.reg = clk_base + (u64)(spicc_div.reg); + spicc_gate.reg = clk_base + (u64)(spicc_gate.reg); + + clks[CLKID_SPICC_COMP] = clk_register_composite(NULL, + "spicc_comp", + spicc_parent_names, 4, + misc_clk_hws[CLKID_SPICC_MUX - CLKID_SPICC_MUX], + &clk_mux_ops, + misc_clk_hws[CLKID_SPICC_DIV - CLKID_SPICC_MUX], + &clk_divider_ops, + misc_clk_hws[CLKID_SPICC_GATE - CLKID_SPICC_MUX], + &clk_gate_ops, 0); + if (IS_ERR(clks[CLKID_SPICC_COMP])) + pr_err("%s: %d clk_register_composite spicc_comp error\n", + __func__, __LINE__); + + pr_info("%s: register amlogic sdemmc clk\n", __func__); +} diff --git a/drivers/amlogic/clk/axg/axg_clk_sdemmc.c b/drivers/amlogic/clk/axg/axg_clk_sdemmc.c new file mode 100644 index 000000000000..35438ec36665 --- /dev/null +++ b/drivers/amlogic/clk/axg/axg_clk_sdemmc.c @@ -0,0 +1,169 @@ +/* + * drivers/amlogic/clk/axg/axg_clk_sdemmc.c + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "../clkc.h" +#include "axg.h" + +static const char * const sd_emmc_parent_names[] = { "xtal", "fclk_div2", + "fclk_div3", "fclk_div5", "fclk_div7", "mpll2", "mpll3", "gp0" }; + +static struct clk_mux sd_emmc_p0_mux_B = { + .reg = (void *)HHI_SD_EMMC_CLK_CNTL, + .mask = 0x7, + .shift = 25, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "sd_emmc_p0_mux_B", + .ops = &clk_mux_ops, + .parent_names = sd_emmc_parent_names, + .num_parents = 8, + .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED), + }, +}; + +static struct clk_divider sd_emmc_p0_div_B = { + .reg = (void *)HHI_SD_EMMC_CLK_CNTL, + .shift = 16, + .width = 7, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "sd_emmc_p0_div_B", + .ops = &clk_divider_ops, + .parent_names = (const char *[]){ "sd_emmc_p0_mux_B" }, + .num_parents = 1, + .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED), + }, +}; + +static struct clk_gate sd_emmc_p0_gate_B = { + .reg = (void *)HHI_SD_EMMC_CLK_CNTL, + .bit_idx = 23, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data) { + .name = "sd_emmc_p0_gate_B", + .ops = &clk_gate_ops, + .parent_names = (const char *[]){ "sd_emmc_p0_div_B" }, + .num_parents = 1, + .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED), + }, +}; + +static struct clk_mux sd_emmc_p0_mux_C = { + .reg = (void *)HHI_NAND_CLK_CNTL, + .mask = 0x7, + .shift = 9, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "sd_emmc_p0_mux_C", + .ops = &clk_mux_ops, + .parent_names = sd_emmc_parent_names, + .num_parents = 8, + .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED), + }, +}; + +static struct clk_divider sd_emmc_p0_div_C = { + .reg = (void *)HHI_NAND_CLK_CNTL, + .shift = 0, + .width = 7, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data){ + .name = "sd_emmc_p0_div_C", + .ops = &clk_divider_ops, + .parent_names = (const char *[]){ "sd_emmc_p0_mux_C" }, + .num_parents = 1, + .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED), + }, +}; + +static struct clk_gate sd_emmc_p0_gate_C = { + .reg = (void *)HHI_NAND_CLK_CNTL, + .bit_idx = 7, + .lock = &clk_lock, + .hw.init = &(struct clk_init_data) { + .name = "sd_emmc_p0_gate_C", + .ops = &clk_gate_ops, + .parent_names = (const char *[]){ "sd_emmc_p0_div_C" }, + .num_parents = 1, + .flags = (CLK_GET_RATE_NOCACHE | CLK_IGNORE_UNUSED), + }, +}; + +static struct clk_hw *sd_emmc_clk_hws[] = { + [CLKID_SD_EMMC_B_P0_MUX - CLKID_SD_EMMC_B_P0_MUX] + = &sd_emmc_p0_mux_B.hw, + [CLKID_SD_EMMC_B_P0_DIV - CLKID_SD_EMMC_B_P0_MUX] + = &sd_emmc_p0_div_B.hw, + [CLKID_SD_EMMC_B_P0_GATE - CLKID_SD_EMMC_B_P0_MUX] + = &sd_emmc_p0_gate_B.hw, + [CLKID_SD_EMMC_C_P0_MUX - CLKID_SD_EMMC_B_P0_MUX] + = &sd_emmc_p0_mux_C.hw, + [CLKID_SD_EMMC_C_P0_DIV - CLKID_SD_EMMC_B_P0_MUX] + = &sd_emmc_p0_div_C.hw, + [CLKID_SD_EMMC_C_P0_GATE - CLKID_SD_EMMC_B_P0_MUX] + = &sd_emmc_p0_gate_C.hw, +}; + + +void axg_amlogic_init_sdemmc(void) +{ + /* Populate base address for reg */ + pr_info("%s: register amlogic sdemmc clk\n", __func__); + + sd_emmc_p0_mux_B.reg = clk_base + (u64)(sd_emmc_p0_mux_B.reg); + sd_emmc_p0_div_B.reg = clk_base + (u64)(sd_emmc_p0_div_B.reg); + sd_emmc_p0_gate_B.reg = clk_base + (u64)(sd_emmc_p0_gate_B.reg); + sd_emmc_p0_mux_C.reg = clk_base + (u64)(sd_emmc_p0_mux_C.reg); + sd_emmc_p0_div_C.reg = clk_base + (u64)(sd_emmc_p0_div_C.reg); + sd_emmc_p0_gate_C.reg = clk_base + (u64)(sd_emmc_p0_gate_C.reg); + + clks[CLKID_SD_EMMC_B_P0_COMP] = clk_register_composite(NULL, + "sd_emmc_p0_B_comp", + sd_emmc_parent_names, 8, + sd_emmc_clk_hws[CLKID_SD_EMMC_B_P0_MUX - CLKID_SD_EMMC_B_P0_MUX], + &clk_mux_ops, + sd_emmc_clk_hws[CLKID_SD_EMMC_B_P0_DIV - CLKID_SD_EMMC_B_P0_MUX], + &clk_divider_ops, + sd_emmc_clk_hws[CLKID_SD_EMMC_B_P0_GATE - CLKID_SD_EMMC_B_P0_MUX], + &clk_gate_ops, 0); + if (IS_ERR(clks[CLKID_SD_EMMC_B_P0_COMP])) + pr_err("%s: %d clk_register_composite sd_emmc_p0_B_comp error\n", + __func__, __LINE__); + + clks[CLKID_SD_EMMC_C_P0_COMP] = clk_register_composite(NULL, + "sd_emmc_p0_C_comp", + sd_emmc_parent_names, 8, + sd_emmc_clk_hws[CLKID_SD_EMMC_C_P0_MUX - CLKID_SD_EMMC_B_P0_MUX], + &clk_mux_ops, + sd_emmc_clk_hws[CLKID_SD_EMMC_C_P0_DIV - CLKID_SD_EMMC_B_P0_MUX], + &clk_divider_ops, + sd_emmc_clk_hws[CLKID_SD_EMMC_C_P0_GATE - CLKID_SD_EMMC_B_P0_MUX], + &clk_gate_ops, 0); + if (IS_ERR(clks[CLKID_SD_EMMC_C_P0_COMP])) + pr_err("%s: %d clk_register_composite sd_emmc_p0_C_comp error\n", + __func__, __LINE__); + + pr_info("%s: register amlogic sdemmc clk\n", __func__); +} diff --git a/drivers/amlogic/clk/clk-mpll.c b/drivers/amlogic/clk/clk-mpll.c index 744c1bf93907..042e72517c09 100644 --- a/drivers/amlogic/clk/clk-mpll.c +++ b/drivers/amlogic/clk/clk-mpll.c @@ -122,7 +122,14 @@ static int mpll_set_rate(struct clk_hw *hw, unsigned long rate, writel(readl(mpll->base + p->reg_off - 0x3c) | 0x1<<14, mpll->base + p->reg_off - 0x3c); writel(reg, mpll->base + p->reg_off); + /* mpll top misc for cpu after txlx */ + if (mpll->top_misc_reg) + writel(readl(mpll->base + (u64)(mpll->top_misc_reg)) | + (1<top_misc_bit), + (mpll->base + (u64)(mpll->top_misc_reg))); udelay(100); + pr_debug("%s: mpll->base+mpll->top_misc_reg: 0x%x\n", + __func__, readl(mpll->base+(u64)mpll->top_misc_reg)); } if (mpll->lock) diff --git a/drivers/amlogic/clk/clk_measure.c b/drivers/amlogic/clk/clk_measure.c index 1f9230a857df..1e534adc8d01 100644 --- a/drivers/amlogic/clk/clk_measure.c +++ b/drivers/amlogic/clk/clk_measure.c @@ -399,6 +399,136 @@ int gxm_clk_measure(struct seq_file *s, void *what, unsigned int index) return 0; } +int axg_clk_measure(struct seq_file *s, void *what, unsigned int index) +{ + static const char * const clk_table[] = { + [109] = "audio_locker_in ", + [108] = "audio_locker_out ", + [107] = "pcie_refclk_p ", + [106] = "pcie_refclk_n ", + [105] = "audio_mclk_a ", + [104] = "audio_mclk_b ", + [103] = "audio_mclk_c ", + [102] = "audio_mclk_d ", + [101] = "audio_mclk_e ", + [100] = "audio_mclk_f ", + [99] = "audio_sclk_a ", + [98] = "audio_sclk_b ", + [97] = "audio_sclk_c ", + [96] = "audio_sclk_d ", + [95] = "audio_sclk_e ", + [94] = "audio_sclk_f ", + [93] = "audio_lrclk_a ", + [92] = "audio_lrclk_b ", + [91] = "audio_lrclk_c ", + [90] = "audio_lrclk_d ", + [89] = "audio_lrclk_e ", + [88] = "audio_lrclk_f ", + [87] = "audio_spdifint_clk ", + [86] = "audio_spdifout_clk ", + [85] = "audio_pdm_sysclk ", + [84] = "audio_resample_clk ", + [83] = "0 ", + [82] = "Cts_ge2d_clk ", + [81] = "Cts_vapbclk ", + [80] = "Rng_ring_osc_clk[3]", + [79] = "Rng_ring_osc_clk[2]", + [78] = "Rng_ring_osc_clk[1]", + [77] = "Rng_ring_osc_clk[0]", + [76] = "tdmin_lb_sclk ", + [75] = "tdmin_lb_lrclk ", + [74] = "wifi_beacon ", + [73] = "cts_pwm_C_clk ", + [72] = "cts_pwm_D_clk ", + [71] = "audio_slv_sclk_a ", + [70] = "audio_slv_sclk_b ", + [69] = "audio_slv_sclk_c ", + [68] = "audio_slv_lrclk_a ", + [67] = "audio_slv_lrclk_b ", + [66] = "audio_slv_lrclk_c ", + [65] = "0 ", + [64] = "0 ", + [63] = "0 ", + [62] = "0 ", + [61] = "gpio_clk_msr ", + [60] = "0 ", + [59] = "0 ", + [58] = "0 ", + [57] = "0 ", + [56] = "0 ", + [55] = "0 ", + [54] = "0 ", + [53] = "0 ", + [52] = "sd_emmc_clk_B ", + [51] = "sd_emmc_clk_C ", + [50] = "mp3_clk_out ", + [49] = "mp2_clk_out ", + [48] = "mp1_clk_out ", + [47] = "ddr_dpll_pt_clk ", + [46] = "cts_vpu_clk ", + [45] = "cts_pwm_A_clk ", + [44] = "cts_pwm_B_clk ", + [43] = "fclk_div5 ", + [42] = "mp0_clk_out ", + [41] = "mod_eth_rx_clk_rmii", + [40] = "mod_eth_tx_clk ", + [39] = "0 ", + [38] = "0 ", + [37] = "0 ", + [36] = "0 ", + [35] = "0 ", + [34] = "0 ", + [33] = "0 ", + [32] = "0 ", + [31] = "MPLL_CLK_TEST_OUT ", + [30] = "0 ", + [29] = "0 ", + [28] = "Cts_sar_adc_clk ", + [27] = "0 ", + [26] = "0 ", + [25] = "0 ", + [24] = "0 ", + [23] = "mmc_clk ", + [22] = "0 ", + [21] = "0 ", + [20] = "rtc_osc_clk_out ", + [19] = "0 ", + [18] = "sys_cpu_clk_div16 ", + [17] = "sys_pll_div16 ", + [16] = "0 ", + [15] = "0 ", + [14] = "0 ", + [13] = "0 ", + [12] = "0 ", + [11] = "0 ", + [10] = "0 ", + [9] = "0 ", + [8] = "0 ", + [7] = "clk81 ", + [6] = "0 ", + [5] = "gp1_pll_clk ", + [4] = "gp0_pll_clk ", + [3] = "A53_ring_osc_clk ", + [2] = "am_ring_osc_clk_out_ee[2]", + [1] = "am_ring_osc_clk_out_ee[1]", + [0] = "am_ring_osc_clk_out_ee[0]", + }; + int i; + int len = sizeof(clk_table)/sizeof(char *); + + if (index == 0xff) { + for (i = 0; i < len; i++) + seq_printf(s, "[%2d][%10d]%s\n", + i, gxbb_clk_util_clk_msr(i), + clk_table[i]); + return 0; + } + seq_printf(s, "[%10d]%s\n", gxbb_clk_util_clk_msr(index), + clk_table[index]); + clk_msr_index = 0xff; + return 0; +} + int meson_clk_measure(unsigned int clk_mux) { int clk_val; @@ -406,14 +536,16 @@ int meson_clk_measure(unsigned int clk_mux) switch (get_cpu_type()) { case MESON_CPU_MAJOR_ID_M8B: clk_val = m8b_clk_util_clk_msr(clk_mux); + break; case MESON_CPU_MAJOR_ID_GXL: case MESON_CPU_MAJOR_ID_GXM: + case MESON_CPU_MAJOR_ID_AXG: clk_val = gxbb_clk_util_clk_msr(clk_mux); - break; + break; default: pr_info("Unsupported chip clk measure\n"); clk_val = 0; - break; + break; } return clk_val; @@ -428,6 +560,8 @@ static int dump_clk(struct seq_file *s, void *what) gxl_clk_measure(s, what, clk_msr_index); else if (get_cpu_type() == MESON_CPU_MAJOR_ID_GXM) gxm_clk_measure(s, what, clk_msr_index); + else if (get_cpu_type() == MESON_CPU_MAJOR_ID_AXG) + axg_clk_measure(s, what, clk_msr_index); return 0; } diff --git a/drivers/amlogic/clk/clk_test.c b/drivers/amlogic/clk/clk_test.c index 62ad5e47d0ad..259771e762d7 100644 --- a/drivers/amlogic/clk/clk_test.c +++ b/drivers/amlogic/clk/clk_test.c @@ -25,14 +25,11 @@ #include #include #include -#include #include "clkc.h" -#include "gxl.h" - static struct dentry *debugfs_root; - +#define NR_CLKS 221 void usage(void) { pr_info("\nclk_test:\n"); diff --git a/drivers/amlogic/clk/clkc.h b/drivers/amlogic/clk/clkc.h index 53d7114558ed..d391ba0edeba 100644 --- a/drivers/amlogic/clk/clkc.h +++ b/drivers/amlogic/clk/clkc.h @@ -102,6 +102,8 @@ struct meson_clk_mpll { /* FIXME ssen gate control? */ u8 sdm_en; u8 en_dds; + u16 top_misc_reg; /*after txlx*/ + u16 top_misc_bit; spinlock_t *lock; }; @@ -133,4 +135,7 @@ void amlogic_init_sdemmc(void); void amlogic_init_gpu(void); void amlogic_init_media(void); void amlogic_init_misc(void); +void axg_amlogic_init_sdemmc(void); +void axg_amlogic_init_media(void); +void axg_amlogic_init_misc(void); #endif /* __CLKC_H */ diff --git a/drivers/amlogic/clk/gxl/Makefile b/drivers/amlogic/clk/gxl/Makefile new file mode 100644 index 000000000000..47f30c59bab9 --- /dev/null +++ b/drivers/amlogic/clk/gxl/Makefile @@ -0,0 +1,5 @@ +# +# Makefile for Meson gxl series clk +# + +obj-$(CONFIG_AMLOGIC_GX_CLK) += gxl.o clk_sdemmc.o clk_gpu.o clk_media.o clk_misc.o diff --git a/drivers/amlogic/clk/clk_gpu.c b/drivers/amlogic/clk/gxl/clk_gpu.c similarity index 98% rename from drivers/amlogic/clk/clk_gpu.c rename to drivers/amlogic/clk/gxl/clk_gpu.c index 0765180cc74a..131cf0328d5a 100644 --- a/drivers/amlogic/clk/clk_gpu.c +++ b/drivers/amlogic/clk/gxl/clk_gpu.c @@ -1,5 +1,5 @@ /* - * drivers/amlogic/clk/clk_gpu.c + * drivers/amlogic/clk/gxl/clk_gpu.c * * Copyright (C) 2017 Amlogic, Inc. All rights reserved. * @@ -23,7 +23,7 @@ #include #include -#include "clkc.h" +#include "../clkc.h" #include "gxl.h" const char *gpu_parent_names[] = { "xtal", "gp0", "mpll2", "mpll1", "fclk_div7", diff --git a/drivers/amlogic/clk/clk_media.c b/drivers/amlogic/clk/gxl/clk_media.c similarity index 99% rename from drivers/amlogic/clk/clk_media.c rename to drivers/amlogic/clk/gxl/clk_media.c index 7ba5e2f52ffa..11146e618b72 100644 --- a/drivers/amlogic/clk/clk_media.c +++ b/drivers/amlogic/clk/gxl/clk_media.c @@ -1,5 +1,5 @@ /* - * drivers/amlogic/clk/clk_media.c + * drivers/amlogic/clk/gxl/clk_media.c * * Copyright (C) 2017 Amlogic, Inc. All rights reserved. * @@ -23,7 +23,7 @@ #include #include -#include "clkc.h" +#include "../clkc.h" #include "gxl.h" const char *dec_parent_names[] = { "fclk_div4", "fclk_div3", "fclk_div5", diff --git a/drivers/amlogic/clk/clk_misc.c b/drivers/amlogic/clk/gxl/clk_misc.c similarity index 99% rename from drivers/amlogic/clk/clk_misc.c rename to drivers/amlogic/clk/gxl/clk_misc.c index 2fcd7e34ed49..eb76f8de7df8 100644 --- a/drivers/amlogic/clk/clk_misc.c +++ b/drivers/amlogic/clk/gxl/clk_misc.c @@ -1,5 +1,5 @@ /* - * drivers/amlogic/clk/clk_misc.c + * drivers/amlogic/clk/gxl/clk_misc.c * * Copyright (C) 2017 Amlogic, Inc. All rights reserved. * @@ -23,7 +23,7 @@ #include #include -#include "clkc.h" +#include "../clkc.h" #include "gxl.h" /* cts_vdin_meas_clk */ diff --git a/drivers/amlogic/clk/clk_sdemmc.c b/drivers/amlogic/clk/gxl/clk_sdemmc.c similarity index 99% rename from drivers/amlogic/clk/clk_sdemmc.c rename to drivers/amlogic/clk/gxl/clk_sdemmc.c index 73a05394c144..9e3c11f508fd 100644 --- a/drivers/amlogic/clk/clk_sdemmc.c +++ b/drivers/amlogic/clk/gxl/clk_sdemmc.c @@ -1,5 +1,5 @@ /* - * drivers/amlogic/clk/clk_sdemmc.c + * drivers/amlogic/clk/gxl/clk_sdemmc.c * * Copyright (C) 2017 Amlogic, Inc. All rights reserved. * @@ -23,7 +23,7 @@ #include #include -#include "clkc.h" +#include "../clkc.h" #include "gxl.h" #define to_clk_mux(_hw) container_of(_hw, struct clk_mux, hw) diff --git a/drivers/amlogic/clk/gxl.c b/drivers/amlogic/clk/gxl/gxl.c similarity index 99% rename from drivers/amlogic/clk/gxl.c rename to drivers/amlogic/clk/gxl/gxl.c index c94f58ee7632..d7bd8dc9da7e 100644 --- a/drivers/amlogic/clk/gxl.c +++ b/drivers/amlogic/clk/gxl/gxl.c @@ -1,5 +1,5 @@ /* - * drivers/amlogic/clk/gxl.c + * drivers/amlogic/clk/gxl/gxl.c * * Copyright (C) 2017 Amlogic, Inc. All rights reserved. * @@ -23,7 +23,7 @@ #include #include -#include "clkc.h" +#include "../clkc.h" #include "gxl.h" DEFINE_SPINLOCK(clk_lock); diff --git a/drivers/amlogic/clk/gxl.h b/drivers/amlogic/clk/gxl/gxl.h similarity index 99% rename from drivers/amlogic/clk/gxl.h rename to drivers/amlogic/clk/gxl/gxl.h index 59144b5366f5..eea2ccf9fe7f 100644 --- a/drivers/amlogic/clk/gxl.h +++ b/drivers/amlogic/clk/gxl/gxl.h @@ -1,5 +1,5 @@ /* - * drivers/amlogic/clk/gxl.h + * drivers/amlogic/clk/gxl/gxl.h * * Copyright (C) 2017 Amlogic, Inc. All rights reserved. * diff --git a/drivers/amlogic/clk/m8b/Makefile b/drivers/amlogic/clk/m8b/Makefile new file mode 100644 index 000000000000..74fd25956280 --- /dev/null +++ b/drivers/amlogic/clk/m8b/Makefile @@ -0,0 +1,6 @@ +# +# Makefile for Meson8 baby clk +# + +obj-$(CONFIG_AMLOGIC_M8B_CLK) += clk-cpu.o meson8b.o clk_test.o \ + clk-mpll.o clk_gpu.o clk_media.o clk_store.o clk_misc.o diff --git a/include/dt-bindings/clock/amlogic,axg-clkc.h b/include/dt-bindings/clock/amlogic,axg-clkc.h new file mode 100644 index 000000000000..6b7b5fdc6760 --- /dev/null +++ b/include/dt-bindings/clock/amlogic,axg-clkc.h @@ -0,0 +1,154 @@ +/* + * include/dt-bindings/clock/gxl-clkc.h + * + * Copyright (C) 2017 Amlogic, Inc. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + */ + +#ifndef __GX_CLKC_H +#define __GX_CLKC_H + +/* + * CLKID index values + */ + +#define CLKID_SYS_PLL 0 +#define CLKID_FIXED_PLL 1 +#define CLKID_FCLK_DIV2 2 +#define CLKID_FCLK_DIV3 3 +#define CLKID_FCLK_DIV4 4 +#define CLKID_FCLK_DIV5 5 +#define CLKID_FCLK_DIV7 6 +#define CLKID_GP0_PLL 7 +#define CLKID_HIFI_PLL 8 +#define CLKID_MPEG_SEL 9 +#define CLKID_MPEG_DIV 10 +#define CLKID_CLK81 11 +#define CLKID_MPLL0 12 +#define CLKID_MPLL1 13 +#define CLKID_MPLL2 14 +#define CLKID_MPLL3 15 +#define CLKID_CPU_FCLK_P00 16 +#define CLKID_CPU_FCLK_P01 17 +#define CLKID_CPU_FCLK_P0 18 +#define CLKID_CPU_FCLK_P10 19 +#define CLKID_CPU_FCLK_P11 20 +#define CLKID_CPU_FCLK_P1 21 +#define CLKID_CPU_FCLK_P 22 +#define CLKID_CPU_CLK 23 +#define CLKID_PCIE_REFPLL 24 +/*HHI_GCLK_MPEG0: 0x50*/ +#define GATE_BASE0 25 +#define CLKID_DDR (GATE_BASE0 + 0) +#define CLKID_AUDIO_LOCKER (GATE_BASE0 + 1) +#define CLKID_MIPI_DSI_HOST (GATE_BASE0 + 2) +#define CLKID_ISA (GATE_BASE0 + 3) +#define CLKID_PL301 (GATE_BASE0 + 4) +#define CLKID_PERIPHS (GATE_BASE0 + 5) +#define CLKID_SPICC0 (GATE_BASE0 + 6) +#define CLKID_I2C (GATE_BASE0 + 7) +#define CLKID_RNG0 (GATE_BASE0 + 8) +#define CLKID_UART0 (GATE_BASE0 + 9) +#define CLKID_MIPI_DSI_PHY (GATE_BASE0 + 10) +#define CLKID_SPICC1 (GATE_BASE0 + 11) +#define CLKID_PCIE_A (GATE_BASE0 + 12) +#define CLKID_PCIE_B (GATE_BASE0 + 13) +#define CLKID_HIU_REG (GATE_BASE0 + 14) +#define CLKID_ASSIST_MISC (GATE_BASE0 + 15) +#define CLKID_SD_EMMC_B (GATE_BASE0 + 16) +#define CLKID_SD_EMMC_C (GATE_BASE0 + 17) +#define CLKID_DMA (GATE_BASE0 + 18) +#define CLKID_SPI (GATE_BASE0 + 19) +/*HHI_GCLK_MPEG1: 0x51*/ +#define GATE_BASE1 (GATE_BASE0 + 20) /*25+20*/ +#define CLKID_AUDIO (GATE_BASE1 + 0) +#define CLKID_ETH_CORE (GATE_BASE1 + 1) +#define CLKID_UART1 (GATE_BASE1 + 2) +#define CLKID_G2D (GATE_BASE1 + 3) +#define CLKID_USB0 (GATE_BASE1 + 4) +#define CLKID_USB1 (GATE_BASE1 + 5) +#define CLKID_RESET (GATE_BASE1 + 6) +#define CLKID_USB_GENERAL (GATE_BASE1 + 7) +#define CLKID_AHB_ARB0 (GATE_BASE1 + 8) +#define CLKID_EFUSE (GATE_BASE1 + 9) +#define CLKID_BOOT_ROM (GATE_BASE1 + 10) +/*HHI_GCLK_MPEG2: 0x52*/ +#define GATE_BASE2 (GATE_BASE1 + 11) /*25+20+11*/ +#define CLKID_AHB_DATA_BUS (GATE_BASE2 + 0) +#define CLKID_AHB_CTRL_BUS (GATE_BASE2 + 1) +#define CLKID_USB1_TO_DDR (GATE_BASE2 + 2) +#define CLKID_USB0_TO_DDR (GATE_BASE2 + 3) +#define CLKID_MMC_PCLK (GATE_BASE2 + 4) +#define CLKID_VPU_INTR (GATE_BASE2 + 5) +#define CLKID_SEC_AHB_AHB3_BRIDGE (GATE_BASE2 + 6) +#define CLKID_GIC (GATE_BASE2 + 7) + +#define AO_BASE (GATE_BASE2 + 8) /*25+20+11+8*/ +#define CLKID_AO_MEDIA_CPU (AO_BASE + 0) +#define CLKID_AO_AHB_SRAM (AO_BASE + 1) +#define CLKID_AO_AHB_BUS (AO_BASE + 2) +#define CLKID_AO_IFACE (AO_BASE + 3) +#define CLKID_AO_I2C (AO_BASE + 4) + +#define OTHER_BASE (AO_BASE + 5) /*25+20+11+8+5=69*/ +#define CLKID_SD_EMMC_B_P0_MUX (OTHER_BASE + 0) +#define CLKID_SD_EMMC_B_P0_DIV (OTHER_BASE + 1) +#define CLKID_SD_EMMC_B_P0_GATE (OTHER_BASE + 2) +#define CLKID_SD_EMMC_B_P0_COMP (OTHER_BASE + 3) +#define CLKID_SD_EMMC_C_P0_MUX (OTHER_BASE + 4) +#define CLKID_SD_EMMC_C_P0_DIV (OTHER_BASE + 5) +#define CLKID_SD_EMMC_C_P0_GATE (OTHER_BASE + 6) +#define CLKID_SD_EMMC_C_P0_COMP (OTHER_BASE + 7) +#define CLKID_SD_EMMC_B_MUX (OTHER_BASE + 8) +#define CLKID_SD_EMMC_B_DIV (OTHER_BASE + 9) +#define CLKID_SD_EMMC_B_GATE (OTHER_BASE + 10) +#define CLKID_SD_EMMC_B_COMP (OTHER_BASE + 11) +#define CLKID_SD_EMMC_C_MUX (OTHER_BASE + 12) +#define CLKID_SD_EMMC_C_DIV (OTHER_BASE + 13) +#define CLKID_SD_EMMC_C_GATE (OTHER_BASE + 14) +#define CLKID_SD_EMMC_C_COMP (OTHER_BASE + 15) + +#define CLKID_MEDIA_BASE (OTHER_BASE + 16) /*25+20+11+8+5+16*/ +#define CLKID_VPU_P0_MUX (CLKID_MEDIA_BASE + 0) +#define CLKID_VPU_P0_DIV (CLKID_MEDIA_BASE + 1) +#define CLKID_VPU_P0_GATE (CLKID_MEDIA_BASE + 2) +#define CLKID_VPU_P0_COMP (CLKID_MEDIA_BASE + 3) +#define CLKID_VPU_P1_MUX (CLKID_MEDIA_BASE + 4) +#define CLKID_VPU_P1_DIV (CLKID_MEDIA_BASE + 5) +#define CLKID_VPU_P1_GATE (CLKID_MEDIA_BASE + 6) +#define CLKID_VPU_P1_COMP (CLKID_MEDIA_BASE + 7) +#define CLKID_VPU_MUX (CLKID_MEDIA_BASE + 8) +#define CLKID_VAPB_P0_MUX (CLKID_MEDIA_BASE + 9) +#define CLKID_VAPB_P0_DIV (CLKID_MEDIA_BASE + 10) +#define CLKID_VAPB_P0_GATE (CLKID_MEDIA_BASE + 11) +#define CLKID_VAPB_P0_COMP (CLKID_MEDIA_BASE + 12) +#define CLKID_VAPB_P1_MUX (CLKID_MEDIA_BASE + 13) +#define CLKID_VAPB_P1_DIV (CLKID_MEDIA_BASE + 14) +#define CLKID_VAPB_P1_GATE (CLKID_MEDIA_BASE + 15) +#define CLKID_VAPB_P1_COMP (CLKID_MEDIA_BASE + 16) +#define CLKID_VAPB_MUX (CLKID_MEDIA_BASE + 17) +#define CLKID_GE2D_GATE (CLKID_MEDIA_BASE + 18) +#define CLKID_DSI_MEAS_MUX (CLKID_MEDIA_BASE + 19) +#define CLKID_DSI_MEAS_DIV (CLKID_MEDIA_BASE + 20) +#define CLKID_DSI_MEAS_GATE (CLKID_MEDIA_BASE + 21) +#define CLKID_DSI_MEAS_COMP (CLKID_MEDIA_BASE + 22) + +#define CLKID_MISC_BASE (CLKID_MEDIA_BASE + 23) /*25+20+11+8+5+16+23 = 108*/ +#define CLKID_SPICC_MUX (CLKID_MISC_BASE + 0) +#define CLKID_SPICC_DIV (CLKID_MISC_BASE + 1) +#define CLKID_SPICC_GATE (CLKID_MISC_BASE + 2) +#define CLKID_SPICC_COMP (CLKID_MISC_BASE + 3) + +#define NR_CLKS (OTHER_BASE + 43) + +#endif /* __GX_CLKC_H */ diff --git a/include/linux/amlogic/cpu_version.h b/include/linux/amlogic/cpu_version.h index 5c35a0f1bd2c..5202c22434a9 100644 --- a/include/linux/amlogic/cpu_version.h +++ b/include/linux/amlogic/cpu_version.h @@ -25,6 +25,7 @@ #define MESON_CPU_MAJOR_ID_GXM 0x22 #define MESON_CPU_MAJOR_ID_TXL 0x23 #define MESON_CPU_MAJOR_ID_TXLX 0x24 +#define MESON_CPU_MAJOR_ID_AXG 0x25 #define MESON_CPU_VERSION_LVL_MAJOR 0 #define MESON_CPU_VERSION_LVL_MINOR 1 @@ -136,6 +137,11 @@ static inline bool is_meson_txlx_cpu(void) return get_cpu_type() == MESON_CPU_MAJOR_ID_TXLX; } +static inline bool is_meson_axg_cpu(void) +{ + return get_cpu_type() == MESON_CPU_MAJOR_ID_AXG; +} + static inline bool cpu_after_eq(unsigned int id) { return get_cpu_type() >= id;