From 0d2602d750152f9fcf3d9af9466f3d67b60aa646 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Wed, 11 Jul 2018 13:47:28 +0200 Subject: clk: renesas: cpg-mssr: Add support for fixed rate clocks Add support for defining fixed rate clocks, to be used for on-chip oscillators. Signed-off-by: Geert Uytterhoeven Reviewed-by: Simon Horman --- drivers/clk/renesas/renesas-cpg-mssr.h | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers/clk/renesas/renesas-cpg-mssr.h') diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h index 642f720b9b05..87bb8f368d4e 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.h +++ b/drivers/clk/renesas/renesas-cpg-mssr.h @@ -38,6 +38,7 @@ enum clk_types { CLK_TYPE_FF, /* Fixed Factor Clock */ CLK_TYPE_DIV6P1, /* DIV6 Clock with 1 parent clock */ CLK_TYPE_DIV6_RO, /* DIV6 Clock read only with extra divisor */ + CLK_TYPE_FR, /* Fixed Rate Clock */ /* Custom definitions start here */ CLK_TYPE_CUSTOM, @@ -56,6 +57,8 @@ enum clk_types { DEF_BASE(_name, _id, CLK_TYPE_DIV6P1, _parent, .offset = _offset) #define DEF_DIV6_RO(_name, _id, _parent, _offset, _div) \ DEF_BASE(_name, _id, CLK_TYPE_DIV6_RO, _parent, .offset = _offset, .div = _div, .mult = 1) +#define DEF_RATE(_name, _id, _rate) \ + DEF_TYPE(_name, _id, CLK_TYPE_FR, .mult = _rate) /* * Definitions of Module Clocks -- cgit v1.2.3 From 331a53e05b67b40a107e7e2597d22b4f8a2ca0d2 Mon Sep 17 00:00:00 2001 From: Biju Das Date: Thu, 2 Aug 2018 15:57:51 +0100 Subject: clk: renesas: cpg-mssr: Add r8a774a1 support Add RZ/G2M (R8A774A1) Clock Pulse Generator / Module Standby and Software Reset support. Based on the Table 8.2b of "RZ/G Series, 2nd Generation User's Manual: Hardware ((Rev. 0.61, June 12, 2018)". Signed-off-by: Biju Das Reviewed-by: Fabrizio Castro Signed-off-by: Geert Uytterhoeven --- .../devicetree/bindings/clock/renesas,cpg-mssr.txt | 9 +- drivers/clk/renesas/Kconfig | 5 + drivers/clk/renesas/Makefile | 1 + drivers/clk/renesas/r8a774a1-cpg-mssr.c | 323 +++++++++++++++++++++ drivers/clk/renesas/renesas-cpg-mssr.c | 6 + drivers/clk/renesas/renesas-cpg-mssr.h | 1 + 6 files changed, 341 insertions(+), 4 deletions(-) create mode 100644 drivers/clk/renesas/r8a774a1-cpg-mssr.c (limited to 'drivers/clk/renesas/renesas-cpg-mssr.h') diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt index db542abadb75..42d0f83d812b 100644 --- a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt @@ -16,6 +16,7 @@ Required Properties: - "renesas,r8a7743-cpg-mssr" for the r8a7743 SoC (RZ/G1M) - "renesas,r8a7745-cpg-mssr" for the r8a7745 SoC (RZ/G1E) - "renesas,r8a77470-cpg-mssr" for the r8a77470 SoC (RZ/G1C) + - "renesas,r8a774a1-cpg-mssr" for the r8a774a1 SoC (RZ/G2M) - "renesas,r8a7790-cpg-mssr" for the r8a7790 SoC (R-Car H2) - "renesas,r8a7791-cpg-mssr" for the r8a7791 SoC (R-Car M2-W) - "renesas,r8a7792-cpg-mssr" for the r8a7792 SoC (R-Car V2H) @@ -35,10 +36,10 @@ Required Properties: - clocks: References to external parent clocks, one entry for each entry in clock-names - clock-names: List of external parent clock names. Valid names are: - - "extal" (r8a7743, r8a7745, r8a77470, r8a7790, r8a7791, r8a7792, - r8a7793, r8a7794, r8a7795, r8a7796, r8a77965, r8a77970, - r8a77980, r8a77990, r8a77995) - - "extalr" (r8a7795, r8a7796, r8a77965, r8a77970, r8a77980) + - "extal" (r8a7743, r8a7745, r8a77470, r8a774a1, r8a7790, r8a7791, + r8a7792, r8a7793, r8a7794, r8a7795, r8a7796, r8a77965, + r8a77970, r8a77980, r8a77990, r8a77995) + - "extalr" (r8a774a1, r8a7795, r8a7796, r8a77965, r8a77970, r8a77980) - "usb_extal" (r8a7743, r8a7745, r8a77470, r8a7790, r8a7791, r8a7793, r8a7794) diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index 9022bbe1297e..f998a7333acb 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -8,6 +8,7 @@ config CLK_RENESAS select CLK_R8A7743 if ARCH_R8A7743 select CLK_R8A7745 if ARCH_R8A7745 select CLK_R8A77470 if ARCH_R8A77470 + select CLK_R8A774A1 if ARCH_R8A774A1 select CLK_R8A7778 if ARCH_R8A7778 select CLK_R8A7779 if ARCH_R8A7779 select CLK_R8A7790 if ARCH_R8A7790 @@ -67,6 +68,10 @@ config CLK_R8A77470 bool "RZ/G1C clock support" if COMPILE_TEST select CLK_RCAR_GEN2_CPG +config CLK_R8A774A1 + bool "RZ/G2M clock support" if COMPILE_TEST + select CLK_RCAR_GEN3_CPG + config CLK_R8A7778 bool "R-Car M1A clock support" if COMPILE_TEST select CLK_RENESAS_CPG_MSTP diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index e4aa3d6143d2..71d4cafe15c0 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_CLK_R8A7740) += clk-r8a7740.o obj-$(CONFIG_CLK_R8A7743) += r8a7743-cpg-mssr.o obj-$(CONFIG_CLK_R8A7745) += r8a7745-cpg-mssr.o obj-$(CONFIG_CLK_R8A77470) += r8a77470-cpg-mssr.o +obj-$(CONFIG_CLK_R8A774A1) += r8a774a1-cpg-mssr.o obj-$(CONFIG_CLK_R8A7778) += clk-r8a7778.o obj-$(CONFIG_CLK_R8A7779) += clk-r8a7779.o obj-$(CONFIG_CLK_R8A7790) += r8a7790-cpg-mssr.o diff --git a/drivers/clk/renesas/r8a774a1-cpg-mssr.c b/drivers/clk/renesas/r8a774a1-cpg-mssr.c new file mode 100644 index 000000000000..b0da34217bdf --- /dev/null +++ b/drivers/clk/renesas/r8a774a1-cpg-mssr.c @@ -0,0 +1,323 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * r8a774a1 Clock Pulse Generator / Module Standby and Software Reset + * + * Copyright (C) 2018 Renesas Electronics Corp. + * + * Based on r8a7796-cpg-mssr.c + * + * Copyright (C) 2016 Glider bvba + */ + +#include +#include +#include +#include + +#include + +#include "renesas-cpg-mssr.h" +#include "rcar-gen3-cpg.h" + +enum clk_ids { + /* Core Clock Outputs exported to DT */ + LAST_DT_CORE_CLK = R8A774A1_CLK_OSC, + + /* External Input Clocks */ + CLK_EXTAL, + CLK_EXTALR, + + /* Internal Core Clocks */ + CLK_MAIN, + CLK_PLL0, + CLK_PLL1, + CLK_PLL2, + CLK_PLL3, + CLK_PLL4, + CLK_PLL1_DIV2, + CLK_PLL1_DIV4, + CLK_S0, + CLK_S1, + CLK_S2, + CLK_S3, + CLK_SDSRC, + CLK_RINT, + + /* Module Clocks */ + MOD_CLK_BASE +}; + +static const struct cpg_core_clk r8a774a1_core_clks[] __initconst = { + /* External Clock Inputs */ + DEF_INPUT("extal", CLK_EXTAL), + DEF_INPUT("extalr", CLK_EXTALR), + + /* Internal Core Clocks */ + DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL), + DEF_BASE(".pll0", CLK_PLL0, CLK_TYPE_GEN3_PLL0, CLK_MAIN), + DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN), + DEF_BASE(".pll2", CLK_PLL2, CLK_TYPE_GEN3_PLL2, CLK_MAIN), + DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN), + DEF_BASE(".pll4", CLK_PLL4, CLK_TYPE_GEN3_PLL4, CLK_MAIN), + + DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1), + DEF_FIXED(".pll1_div4", CLK_PLL1_DIV4, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED(".s0", CLK_S0, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED(".s1", CLK_S1, CLK_PLL1_DIV2, 3, 1), + DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1), + DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1), + DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1), + + DEF_GEN3_OSC(".r", CLK_RINT, CLK_EXTAL, 32), + + /* Core Clock Outputs */ + DEF_BASE("z", R8A774A1_CLK_Z, CLK_TYPE_GEN3_Z, CLK_PLL0), + DEF_BASE("z2", R8A774A1_CLK_Z2, CLK_TYPE_GEN3_Z2, CLK_PLL2), + DEF_FIXED("ztr", R8A774A1_CLK_ZTR, CLK_PLL1_DIV2, 6, 1), + DEF_FIXED("ztrd2", R8A774A1_CLK_ZTRD2, CLK_PLL1_DIV2, 12, 1), + DEF_FIXED("zt", R8A774A1_CLK_ZT, CLK_PLL1_DIV2, 4, 1), + DEF_FIXED("zx", R8A774A1_CLK_ZX, CLK_PLL1_DIV2, 2, 1), + DEF_FIXED("s0d1", R8A774A1_CLK_S0D1, CLK_S0, 1, 1), + DEF_FIXED("s0d2", R8A774A1_CLK_S0D2, CLK_S0, 2, 1), + DEF_FIXED("s0d3", R8A774A1_CLK_S0D3, CLK_S0, 3, 1), + DEF_FIXED("s0d4", R8A774A1_CLK_S0D4, CLK_S0, 4, 1), + DEF_FIXED("s0d6", R8A774A1_CLK_S0D6, CLK_S0, 6, 1), + DEF_FIXED("s0d8", R8A774A1_CLK_S0D8, CLK_S0, 8, 1), + DEF_FIXED("s0d12", R8A774A1_CLK_S0D12, CLK_S0, 12, 1), + DEF_FIXED("s1d2", R8A774A1_CLK_S1D2, CLK_S1, 2, 1), + DEF_FIXED("s1d4", R8A774A1_CLK_S1D4, CLK_S1, 4, 1), + DEF_FIXED("s2d1", R8A774A1_CLK_S2D1, CLK_S2, 1, 1), + DEF_FIXED("s2d2", R8A774A1_CLK_S2D2, CLK_S2, 2, 1), + DEF_FIXED("s2d4", R8A774A1_CLK_S2D4, CLK_S2, 4, 1), + DEF_FIXED("s3d1", R8A774A1_CLK_S3D1, CLK_S3, 1, 1), + DEF_FIXED("s3d2", R8A774A1_CLK_S3D2, CLK_S3, 2, 1), + DEF_FIXED("s3d4", R8A774A1_CLK_S3D4, CLK_S3, 4, 1), + + DEF_GEN3_SD("sd0", R8A774A1_CLK_SD0, CLK_SDSRC, 0x074), + DEF_GEN3_SD("sd1", R8A774A1_CLK_SD1, CLK_SDSRC, 0x078), + DEF_GEN3_SD("sd2", R8A774A1_CLK_SD2, CLK_SDSRC, 0x268), + DEF_GEN3_SD("sd3", R8A774A1_CLK_SD3, CLK_SDSRC, 0x26c), + + DEF_FIXED("cl", R8A774A1_CLK_CL, CLK_PLL1_DIV2, 48, 1), + DEF_FIXED("cp", R8A774A1_CLK_CP, CLK_EXTAL, 2, 1), + + DEF_DIV6P1("csi0", R8A774A1_CLK_CSI0, CLK_PLL1_DIV4, 0x00c), + DEF_DIV6P1("mso", R8A774A1_CLK_MSO, CLK_PLL1_DIV4, 0x014), + DEF_DIV6P1("hdmi", R8A774A1_CLK_HDMI, CLK_PLL1_DIV4, 0x250), + + DEF_GEN3_OSC("osc", R8A774A1_CLK_OSC, CLK_EXTAL, 8), + + DEF_BASE("r", R8A774A1_CLK_R, CLK_TYPE_GEN3_R, CLK_RINT), +}; + +static const struct mssr_mod_clk r8a774a1_mod_clks[] __initconst = { + DEF_MOD("fdp1-0", 119, R8A774A1_CLK_S0D1), + DEF_MOD("scif5", 202, R8A774A1_CLK_S3D4), + DEF_MOD("scif4", 203, R8A774A1_CLK_S3D4), + DEF_MOD("scif3", 204, R8A774A1_CLK_S3D4), + DEF_MOD("scif1", 206, R8A774A1_CLK_S3D4), + DEF_MOD("scif0", 207, R8A774A1_CLK_S3D4), + DEF_MOD("msiof3", 208, R8A774A1_CLK_MSO), + DEF_MOD("msiof2", 209, R8A774A1_CLK_MSO), + DEF_MOD("msiof1", 210, R8A774A1_CLK_MSO), + DEF_MOD("msiof0", 211, R8A774A1_CLK_MSO), + DEF_MOD("sys-dmac2", 217, R8A774A1_CLK_S0D3), + DEF_MOD("sys-dmac1", 218, R8A774A1_CLK_S0D3), + DEF_MOD("sys-dmac0", 219, R8A774A1_CLK_S0D3), + DEF_MOD("cmt3", 300, R8A774A1_CLK_R), + DEF_MOD("cmt2", 301, R8A774A1_CLK_R), + DEF_MOD("cmt1", 302, R8A774A1_CLK_R), + DEF_MOD("cmt0", 303, R8A774A1_CLK_R), + DEF_MOD("scif2", 310, R8A774A1_CLK_S3D4), + DEF_MOD("sdif3", 311, R8A774A1_CLK_SD3), + DEF_MOD("sdif2", 312, R8A774A1_CLK_SD2), + DEF_MOD("sdif1", 313, R8A774A1_CLK_SD1), + DEF_MOD("sdif0", 314, R8A774A1_CLK_SD0), + DEF_MOD("pcie1", 318, R8A774A1_CLK_S3D1), + DEF_MOD("pcie0", 319, R8A774A1_CLK_S3D1), + DEF_MOD("usb3-if0", 328, R8A774A1_CLK_S3D1), + DEF_MOD("usb-dmac0", 330, R8A774A1_CLK_S3D1), + DEF_MOD("usb-dmac1", 331, R8A774A1_CLK_S3D1), + DEF_MOD("rwdt", 402, R8A774A1_CLK_R), + DEF_MOD("intc-ex", 407, R8A774A1_CLK_CP), + DEF_MOD("intc-ap", 408, R8A774A1_CLK_S0D3), + DEF_MOD("audmac1", 501, R8A774A1_CLK_S0D3), + DEF_MOD("audmac0", 502, R8A774A1_CLK_S0D3), + DEF_MOD("hscif4", 516, R8A774A1_CLK_S3D1), + DEF_MOD("hscif3", 517, R8A774A1_CLK_S3D1), + DEF_MOD("hscif2", 518, R8A774A1_CLK_S3D1), + DEF_MOD("hscif1", 519, R8A774A1_CLK_S3D1), + DEF_MOD("hscif0", 520, R8A774A1_CLK_S3D1), + DEF_MOD("thermal", 522, R8A774A1_CLK_CP), + DEF_MOD("pwm", 523, R8A774A1_CLK_S0D12), + DEF_MOD("fcpvd2", 601, R8A774A1_CLK_S0D2), + DEF_MOD("fcpvd1", 602, R8A774A1_CLK_S0D2), + DEF_MOD("fcpvd0", 603, R8A774A1_CLK_S0D2), + DEF_MOD("fcpvb0", 607, R8A774A1_CLK_S0D1), + DEF_MOD("fcpvi0", 611, R8A774A1_CLK_S0D1), + DEF_MOD("fcpf0", 615, R8A774A1_CLK_S0D1), + DEF_MOD("fcpci0", 617, R8A774A1_CLK_S0D2), + DEF_MOD("fcpcs", 619, R8A774A1_CLK_S0D2), + DEF_MOD("vspd2", 621, R8A774A1_CLK_S0D2), + DEF_MOD("vspd1", 622, R8A774A1_CLK_S0D2), + DEF_MOD("vspd0", 623, R8A774A1_CLK_S0D2), + DEF_MOD("vspb", 626, R8A774A1_CLK_S0D1), + DEF_MOD("vspi0", 631, R8A774A1_CLK_S0D1), + DEF_MOD("ehci1", 702, R8A774A1_CLK_S3D4), + DEF_MOD("ehci0", 703, R8A774A1_CLK_S3D4), + DEF_MOD("hsusb", 704, R8A774A1_CLK_S3D4), + DEF_MOD("csi20", 714, R8A774A1_CLK_CSI0), + DEF_MOD("csi40", 716, R8A774A1_CLK_CSI0), + DEF_MOD("du2", 722, R8A774A1_CLK_S2D1), + DEF_MOD("du1", 723, R8A774A1_CLK_S2D1), + DEF_MOD("du0", 724, R8A774A1_CLK_S2D1), + DEF_MOD("lvds", 727, R8A774A1_CLK_S2D1), + DEF_MOD("hdmi0", 729, R8A774A1_CLK_HDMI), + DEF_MOD("vin7", 804, R8A774A1_CLK_S0D2), + DEF_MOD("vin6", 805, R8A774A1_CLK_S0D2), + DEF_MOD("vin5", 806, R8A774A1_CLK_S0D2), + DEF_MOD("vin4", 807, R8A774A1_CLK_S0D2), + DEF_MOD("vin3", 808, R8A774A1_CLK_S0D2), + DEF_MOD("vin2", 809, R8A774A1_CLK_S0D2), + DEF_MOD("vin1", 810, R8A774A1_CLK_S0D2), + DEF_MOD("vin0", 811, R8A774A1_CLK_S0D2), + DEF_MOD("etheravb", 812, R8A774A1_CLK_S0D6), + DEF_MOD("gpio7", 905, R8A774A1_CLK_S3D4), + DEF_MOD("gpio6", 906, R8A774A1_CLK_S3D4), + DEF_MOD("gpio5", 907, R8A774A1_CLK_S3D4), + DEF_MOD("gpio4", 908, R8A774A1_CLK_S3D4), + DEF_MOD("gpio3", 909, R8A774A1_CLK_S3D4), + DEF_MOD("gpio2", 910, R8A774A1_CLK_S3D4), + DEF_MOD("gpio1", 911, R8A774A1_CLK_S3D4), + DEF_MOD("gpio0", 912, R8A774A1_CLK_S3D4), + DEF_MOD("can-if1", 915, R8A774A1_CLK_S3D4), + DEF_MOD("can-if0", 916, R8A774A1_CLK_S3D4), + DEF_MOD("i2c6", 918, R8A774A1_CLK_S0D6), + DEF_MOD("i2c5", 919, R8A774A1_CLK_S0D6), + DEF_MOD("i2c-dvfs", 926, R8A774A1_CLK_CP), + DEF_MOD("i2c4", 927, R8A774A1_CLK_S0D6), + DEF_MOD("i2c3", 928, R8A774A1_CLK_S0D6), + DEF_MOD("i2c2", 929, R8A774A1_CLK_S3D2), + DEF_MOD("i2c1", 930, R8A774A1_CLK_S3D2), + DEF_MOD("i2c0", 931, R8A774A1_CLK_S3D2), + DEF_MOD("ssi-all", 1005, R8A774A1_CLK_S3D4), + DEF_MOD("ssi9", 1006, MOD_CLK_ID(1005)), + DEF_MOD("ssi8", 1007, MOD_CLK_ID(1005)), + DEF_MOD("ssi7", 1008, MOD_CLK_ID(1005)), + DEF_MOD("ssi6", 1009, MOD_CLK_ID(1005)), + DEF_MOD("ssi5", 1010, MOD_CLK_ID(1005)), + DEF_MOD("ssi4", 1011, MOD_CLK_ID(1005)), + DEF_MOD("ssi3", 1012, MOD_CLK_ID(1005)), + DEF_MOD("ssi2", 1013, MOD_CLK_ID(1005)), + DEF_MOD("ssi1", 1014, MOD_CLK_ID(1005)), + DEF_MOD("ssi0", 1015, MOD_CLK_ID(1005)), + DEF_MOD("scu-all", 1017, R8A774A1_CLK_S3D4), + DEF_MOD("scu-dvc1", 1018, MOD_CLK_ID(1017)), + DEF_MOD("scu-dvc0", 1019, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu1-mix1", 1020, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu0-mix0", 1021, MOD_CLK_ID(1017)), + DEF_MOD("scu-src9", 1022, MOD_CLK_ID(1017)), + DEF_MOD("scu-src8", 1023, MOD_CLK_ID(1017)), + DEF_MOD("scu-src7", 1024, MOD_CLK_ID(1017)), + DEF_MOD("scu-src6", 1025, MOD_CLK_ID(1017)), + DEF_MOD("scu-src5", 1026, MOD_CLK_ID(1017)), + DEF_MOD("scu-src4", 1027, MOD_CLK_ID(1017)), + DEF_MOD("scu-src3", 1028, MOD_CLK_ID(1017)), + DEF_MOD("scu-src2", 1029, MOD_CLK_ID(1017)), + DEF_MOD("scu-src1", 1030, MOD_CLK_ID(1017)), + DEF_MOD("scu-src0", 1031, MOD_CLK_ID(1017)), +}; + +static const unsigned int r8a774a1_crit_mod_clks[] __initconst = { + MOD_CLK_ID(408), /* INTC-AP (GIC) */ +}; + +/* + * CPG Clock Data + */ + +/* + * MD EXTAL PLL0 PLL1 PLL2 PLL3 PLL4 OSC + * 14 13 19 17 (MHz) + *------------------------------------------------------------------------- + * 0 0 0 0 16.66 x 1 x180 x192 x144 x192 x144 /16 + * 0 0 0 1 16.66 x 1 x180 x192 x144 x128 x144 /16 + * 0 0 1 0 Prohibited setting + * 0 0 1 1 16.66 x 1 x180 x192 x144 x192 x144 /16 + * 0 1 0 0 20 x 1 x150 x160 x120 x160 x120 /19 + * 0 1 0 1 20 x 1 x150 x160 x120 x106 x120 /19 + * 0 1 1 0 Prohibited setting + * 0 1 1 1 20 x 1 x150 x160 x120 x160 x120 /19 + * 1 0 0 0 25 x 1 x120 x128 x96 x128 x96 /24 + * 1 0 0 1 25 x 1 x120 x128 x96 x84 x96 /24 + * 1 0 1 0 Prohibited setting + * 1 0 1 1 25 x 1 x120 x128 x96 x128 x96 /24 + * 1 1 0 0 33.33 / 2 x180 x192 x144 x192 x144 /32 + * 1 1 0 1 33.33 / 2 x180 x192 x144 x128 x144 /32 + * 1 1 1 0 Prohibited setting + * 1 1 1 1 33.33 / 2 x180 x192 x144 x192 x144 /32 + */ +#define CPG_PLL_CONFIG_INDEX(md) ((((md) & BIT(14)) >> 11) | \ + (((md) & BIT(13)) >> 11) | \ + (((md) & BIT(19)) >> 18) | \ + (((md) & BIT(17)) >> 17)) + +static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[16] __initconst = { + /* EXTAL div PLL1 mult/div PLL3 mult/div OSC prediv */ + { 1, 192, 1, 192, 1, 16, }, + { 1, 192, 1, 128, 1, 16, }, + { 0, /* Prohibited setting */ }, + { 1, 192, 1, 192, 1, 16, }, + { 1, 160, 1, 160, 1, 19, }, + { 1, 160, 1, 106, 1, 19, }, + { 0, /* Prohibited setting */ }, + { 1, 160, 1, 160, 1, 19, }, + { 1, 128, 1, 128, 1, 24, }, + { 1, 128, 1, 84, 1, 24, }, + { 0, /* Prohibited setting */ }, + { 1, 128, 1, 128, 1, 24, }, + { 2, 192, 1, 192, 1, 32, }, + { 2, 192, 1, 128, 1, 32, }, + { 0, /* Prohibited setting */ }, + { 2, 192, 1, 192, 1, 32, }, +}; + +static int __init r8a774a1_cpg_mssr_init(struct device *dev) +{ + const struct rcar_gen3_cpg_pll_config *cpg_pll_config; + u32 cpg_mode; + int error; + + error = rcar_rst_read_mode_pins(&cpg_mode); + if (error) + return error; + + cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; + if (!cpg_pll_config->extal_div) { + dev_err(dev, "Prohibited setting (cpg_mode=0x%x)\n", cpg_mode); + return -EINVAL; + } + + return rcar_gen3_cpg_init(cpg_pll_config, CLK_EXTALR, cpg_mode); +} + +const struct cpg_mssr_info r8a774a1_cpg_mssr_info __initconst = { + /* Core Clocks */ + .core_clks = r8a774a1_core_clks, + .num_core_clks = ARRAY_SIZE(r8a774a1_core_clks), + .last_dt_core_clk = LAST_DT_CORE_CLK, + .num_total_core_clks = MOD_CLK_BASE, + + /* Module Clocks */ + .mod_clks = r8a774a1_mod_clks, + .num_mod_clks = ARRAY_SIZE(r8a774a1_mod_clks), + .num_hw_mod_clks = 12 * 32, + + /* Critical Module Clocks */ + .crit_mod_clks = r8a774a1_crit_mod_clks, + .num_crit_mod_clks = ARRAY_SIZE(r8a774a1_crit_mod_clks), + + /* Callbacks */ + .init = r8a774a1_cpg_mssr_init, + .cpg_clk_register = rcar_gen3_cpg_clk_register, +}; diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index e04338932786..f90b0d0ba46a 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -664,6 +664,12 @@ static const struct of_device_id cpg_mssr_match[] = { .data = &r8a77470_cpg_mssr_info, }, #endif +#ifdef CONFIG_CLK_R8A774A1 + { + .compatible = "renesas,r8a774a1-cpg-mssr", + .data = &r8a774a1_cpg_mssr_info, + }, +#endif #ifdef CONFIG_CLK_R8A7790 { .compatible = "renesas,r8a7790-cpg-mssr", diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h index 87bb8f368d4e..2e1730bc5ef2 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.h +++ b/drivers/clk/renesas/renesas-cpg-mssr.h @@ -137,6 +137,7 @@ struct cpg_mssr_info { extern const struct cpg_mssr_info r8a7743_cpg_mssr_info; extern const struct cpg_mssr_info r8a7745_cpg_mssr_info; extern const struct cpg_mssr_info r8a77470_cpg_mssr_info; +extern const struct cpg_mssr_info r8a774a1_cpg_mssr_info; extern const struct cpg_mssr_info r8a7790_cpg_mssr_info; extern const struct cpg_mssr_info r8a7791_cpg_mssr_info; extern const struct cpg_mssr_info r8a7792_cpg_mssr_info; -- cgit v1.2.3 From fde35c9c7db5732cc1fbd89fa5eba5a9e0b25f6e Mon Sep 17 00:00:00 2001 From: Chris Brandt Date: Fri, 7 Sep 2018 11:58:49 -0500 Subject: clk: renesas: cpg-mssr: Add R7S9210 support Add support for the R7S9210 (RZ/A2) Clock Pulse Generator and Module Standby. The Module Standby HW in the RZ/A series is very close to R-Car HW, except for how the registers are laid out. The MSTP registers are only 8-bits wide, there are no status registers (MSTPSR), and the register offsets are a little different. Since the RZ/A hardware manuals refer to these registers as the Standby Control Registers, we'll use that name to distinguish the RZ/A type from the R-Car type. Signed-off-by: Chris Brandt Acked-by: Rob Herring # DT bits Signed-off-by: Geert Uytterhoeven --- .../devicetree/bindings/clock/renesas,cpg-mssr.txt | 5 +- drivers/clk/renesas/Kconfig | 5 + drivers/clk/renesas/Makefile | 1 + drivers/clk/renesas/r7s9210-cpg-mssr.c | 189 +++++++++++++++++++++ drivers/clk/renesas/renesas-cpg-mssr.c | 81 +++++++-- drivers/clk/renesas/renesas-cpg-mssr.h | 13 ++ include/dt-bindings/clock/r7s9210-cpg-mssr.h | 20 +++ 7 files changed, 300 insertions(+), 14 deletions(-) create mode 100644 drivers/clk/renesas/r7s9210-cpg-mssr.c create mode 100644 include/dt-bindings/clock/r7s9210-cpg-mssr.h (limited to 'drivers/clk/renesas/renesas-cpg-mssr.h') diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt index 42d0f83d812b..5e46e6be789b 100644 --- a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt +++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt @@ -13,6 +13,7 @@ They provide the following functionalities: Required Properties: - compatible: Must be one of: + - "renesas,r7s9210-cpg-mssr" for the r7s9210 SoC (RZ/A2) - "renesas,r8a7743-cpg-mssr" for the r8a7743 SoC (RZ/G1M) - "renesas,r8a7745-cpg-mssr" for the r8a7745 SoC (RZ/G1E) - "renesas,r8a77470-cpg-mssr" for the r8a77470 SoC (RZ/G1C) @@ -36,8 +37,8 @@ Required Properties: - clocks: References to external parent clocks, one entry for each entry in clock-names - clock-names: List of external parent clock names. Valid names are: - - "extal" (r8a7743, r8a7745, r8a77470, r8a774a1, r8a7790, r8a7791, - r8a7792, r8a7793, r8a7794, r8a7795, r8a7796, r8a77965, + - "extal" (r7s9210, r8a7743, r8a7745, r8a77470, r8a774a1, r8a7790, + r8a7791, r8a7792, r8a7793, r8a7794, r8a7795, r8a7796, r8a77965, r8a77970, r8a77980, r8a77990, r8a77995) - "extalr" (r8a774a1, r8a7795, r8a7796, r8a77965, r8a77970, r8a77980) - "usb_extal" (r8a7743, r8a7745, r8a77470, r8a7790, r8a7791, r8a7793, diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index f998a7333acb..2edcb1bdb487 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -3,6 +3,7 @@ config CLK_RENESAS default y if ARCH_RENESAS select CLK_EMEV2 if ARCH_EMEV2 select CLK_RZA1 if ARCH_R7S72100 + select CLK_R7S9210 if ARCH_R7S9210 select CLK_R8A73A4 if ARCH_R8A73A4 select CLK_R8A7740 if ARCH_R8A7740 select CLK_R8A7743 if ARCH_R8A7743 @@ -46,6 +47,10 @@ config CLK_RZA1 bool "RZ/A1H clock support" if COMPILE_TEST select CLK_RENESAS_CPG_MSTP +config CLK_R7S9210 + bool "RZ/A2 clock support" if COMPILE_TEST + select CLK_RENESAS_CPG_MSSR + config CLK_R8A73A4 bool "R-Mobile APE6 clock support" if COMPILE_TEST select CLK_RENESAS_CPG_MSTP diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index 71d4cafe15c0..dbbfd0b0742b 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -2,6 +2,7 @@ # SoC obj-$(CONFIG_CLK_EMEV2) += clk-emev2.o obj-$(CONFIG_CLK_RZA1) += clk-rz.o +obj-$(CONFIG_CLK_R7S9210) += r7s9210-cpg-mssr.o obj-$(CONFIG_CLK_R8A73A4) += clk-r8a73a4.o obj-$(CONFIG_CLK_R8A7740) += clk-r8a7740.o obj-$(CONFIG_CLK_R8A7743) += r8a7743-cpg-mssr.o diff --git a/drivers/clk/renesas/r7s9210-cpg-mssr.c b/drivers/clk/renesas/r7s9210-cpg-mssr.c new file mode 100644 index 000000000000..bd1dd4ff2051 --- /dev/null +++ b/drivers/clk/renesas/r7s9210-cpg-mssr.c @@ -0,0 +1,189 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * R7S9210 Clock Pulse Generator / Module Standby + * + * Based on r8a7795-cpg-mssr.c + * + * Copyright (C) 2018 Chris Brandt + * Copyright (C) 2018 Renesas Electronics Corp. + * + */ + +#include +#include +#include +#include "renesas-cpg-mssr.h" + +#define CPG_FRQCR 0x00 + +static u8 cpg_mode; + +/* Internal Clock ratio table */ +static const struct { + unsigned int i; + unsigned int g; + unsigned int b; + unsigned int p1; + /* p0 is always 32 */; +} ratio_tab[5] = { /* I, G, B, P1 */ + { 2, 4, 8, 16}, /* FRQCR = 0x012 */ + { 4, 4, 8, 16}, /* FRQCR = 0x112 */ + { 8, 4, 8, 16}, /* FRQCR = 0x212 */ + { 16, 8, 16, 16}, /* FRQCR = 0x322 */ + { 16, 16, 32, 32}, /* FRQCR = 0x333 */ + }; + +enum rz_clk_types { + CLK_TYPE_RZA_MAIN = CLK_TYPE_CUSTOM, + CLK_TYPE_RZA_PLL, +}; + +enum clk_ids { + /* Core Clock Outputs exported to DT */ + LAST_DT_CORE_CLK = R7S9210_CLK_P0, + + /* External Input Clocks */ + CLK_EXTAL, + + /* Internal Core Clocks */ + CLK_MAIN, + CLK_PLL, + + /* Module Clocks */ + MOD_CLK_BASE +}; + +static struct cpg_core_clk r7s9210_core_clks[] = { + /* External Clock Inputs */ + DEF_INPUT("extal", CLK_EXTAL), + + /* Internal Core Clocks */ + DEF_BASE(".main", CLK_MAIN, CLK_TYPE_RZA_MAIN, CLK_EXTAL), + DEF_BASE(".pll", CLK_PLL, CLK_TYPE_RZA_PLL, CLK_MAIN), + + /* Core Clock Outputs */ + DEF_FIXED("i", R7S9210_CLK_I, CLK_PLL, 2, 1), + DEF_FIXED("g", R7S9210_CLK_G, CLK_PLL, 4, 1), + DEF_FIXED("b", R7S9210_CLK_B, CLK_PLL, 8, 1), + DEF_FIXED("p1", R7S9210_CLK_P1, CLK_PLL, 16, 1), + DEF_FIXED("p1c", R7S9210_CLK_P1C, CLK_PLL, 16, 1), + DEF_FIXED("p0", R7S9210_CLK_P0, CLK_PLL, 32, 1), +}; + +static const struct mssr_mod_clk r7s9210_mod_clks[] __initconst = { + DEF_MOD_STB("ostm2", 34, R7S9210_CLK_P1C), + DEF_MOD_STB("ostm1", 35, R7S9210_CLK_P1C), + DEF_MOD_STB("ostm0", 36, R7S9210_CLK_P1C), + + DEF_MOD_STB("scif4", 43, R7S9210_CLK_P1C), + DEF_MOD_STB("scif3", 44, R7S9210_CLK_P1C), + DEF_MOD_STB("scif2", 45, R7S9210_CLK_P1C), + DEF_MOD_STB("scif1", 46, R7S9210_CLK_P1C), + DEF_MOD_STB("scif0", 47, R7S9210_CLK_P1C), + + DEF_MOD_STB("ether1", 64, R7S9210_CLK_B), + DEF_MOD_STB("ether0", 65, R7S9210_CLK_B), + + DEF_MOD_STB("i2c3", 84, R7S9210_CLK_P1), + DEF_MOD_STB("i2c2", 85, R7S9210_CLK_P1), + DEF_MOD_STB("i2c1", 86, R7S9210_CLK_P1), + DEF_MOD_STB("i2c0", 87, R7S9210_CLK_P1), + +}; + +struct clk * __init rza2_cpg_clk_register(struct device *dev, + const struct cpg_core_clk *core, const struct cpg_mssr_info *info, + struct clk **clks, void __iomem *base, + struct raw_notifier_head *notifiers) +{ + struct clk *parent; + unsigned int mult = 1; + unsigned int div = 1; + u16 frqcr; + u8 index; + int i; + + parent = clks[core->parent]; + if (IS_ERR(parent)) + return ERR_CAST(parent); + + switch (core->id) { + case CLK_MAIN: + break; + + case CLK_PLL: + if (cpg_mode) + mult = 44; /* Divider 1 is 1/2 */ + else + mult = 88; /* Divider 1 is 1 */ + break; + + default: + return ERR_PTR(-EINVAL); + } + + /* Adjust the dividers based on the current FRQCR setting */ + if (core->id == CLK_MAIN) { + + /* If EXTAL is above 12MHz, then we know it is Mode 1 */ + if (clk_get_rate(parent) > 12000000) + cpg_mode = 1; + + frqcr = clk_readl(base + CPG_FRQCR) & 0xFFF; + if (frqcr == 0x012) + index = 0; + else if (frqcr == 0x112) + index = 1; + else if (frqcr == 0x212) + index = 2; + else if (frqcr == 0x322) + index = 3; + else if (frqcr == 0x333) + index = 4; + else + BUG_ON(1); /* Illegal FRQCR value */ + + for (i = 0; i < ARRAY_SIZE(r7s9210_core_clks); i++) { + switch (r7s9210_core_clks[i].id) { + case R7S9210_CLK_I: + r7s9210_core_clks[i].div = ratio_tab[index].i; + break; + case R7S9210_CLK_G: + r7s9210_core_clks[i].div = ratio_tab[index].g; + break; + case R7S9210_CLK_B: + r7s9210_core_clks[i].div = ratio_tab[index].b; + break; + case R7S9210_CLK_P1: + case R7S9210_CLK_P1C: + r7s9210_core_clks[i].div = ratio_tab[index].p1; + break; + case R7S9210_CLK_P0: + r7s9210_core_clks[i].div = 32; + break; + } + } + } + + return clk_register_fixed_factor(NULL, core->name, + __clk_get_name(parent), 0, mult, div); +} + +const struct cpg_mssr_info r7s9210_cpg_mssr_info __initconst = { + /* Core Clocks */ + .core_clks = r7s9210_core_clks, + .num_core_clks = ARRAY_SIZE(r7s9210_core_clks), + .last_dt_core_clk = LAST_DT_CORE_CLK, + .num_total_core_clks = MOD_CLK_BASE, + + /* Module Clocks */ + .mod_clks = r7s9210_mod_clks, + .num_mod_clks = ARRAY_SIZE(r7s9210_mod_clks), + .num_hw_mod_clks = 11 * 32, /* includes STBCR0 which doesn't exist */ + + /* Callbacks */ + .cpg_clk_register = rza2_cpg_clk_register, + + /* RZ/A2 has Standby Control Registers */ + .stbyctrl = true, +}; diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index f90b0d0ba46a..b97e0e3ff0b1 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -73,6 +73,17 @@ static const u16 smstpcr[] = { #define SMSTPCR(i) smstpcr[i] +/* + * Standby Control Register offsets (RZ/A) + * Base address is FRQCR register + */ + +static const u16 stbcr[] = { + 0xFFFF/*dummy*/, 0x010, 0x014, 0x410, 0x414, 0x418, 0x41C, 0x420, + 0x424, 0x428, 0x42C, +}; + +#define STBCR(i) stbcr[i] /* * Software Reset Register offsets @@ -110,6 +121,7 @@ static const u16 srcr[] = { * @notifiers: Notifier chain to save/restore clock state for system resume * @smstpcr_saved[].mask: Mask of SMSTPCR[] bits under our control * @smstpcr_saved[].val: Saved values of SMSTPCR[] + * @stbyctrl: This device has Standby Control Registers */ struct cpg_mssr_priv { #ifdef CONFIG_RESET_CONTROLLER @@ -123,6 +135,7 @@ struct cpg_mssr_priv { unsigned int num_core_clks; unsigned int num_mod_clks; unsigned int last_dt_core_clk; + bool stbyctrl; struct raw_notifier_head notifiers; struct { @@ -162,16 +175,29 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable) enable ? "ON" : "OFF"); spin_lock_irqsave(&priv->rmw_lock, flags); - value = readl(priv->base + SMSTPCR(reg)); - if (enable) - value &= ~bitmask; - else - value |= bitmask; - writel(value, priv->base + SMSTPCR(reg)); + if (priv->stbyctrl) { + value = readb(priv->base + STBCR(reg)); + if (enable) + value &= ~bitmask; + else + value |= bitmask; + writeb(value, priv->base + STBCR(reg)); + + /* dummy read to ensure write has completed */ + readb(priv->base + STBCR(reg)); + barrier_data(priv->base + STBCR(reg)); + } else { + value = readl(priv->base + SMSTPCR(reg)); + if (enable) + value &= ~bitmask; + else + value |= bitmask; + writel(value, priv->base + SMSTPCR(reg)); + } spin_unlock_irqrestore(&priv->rmw_lock, flags); - if (!enable) + if (!enable || priv->stbyctrl) return 0; for (i = 1000; i > 0; --i) { @@ -205,7 +231,10 @@ static int cpg_mstp_clock_is_enabled(struct clk_hw *hw) struct cpg_mssr_priv *priv = clock->priv; u32 value; - value = readl(priv->base + MSTPSR(clock->index / 32)); + if (priv->stbyctrl) + value = readb(priv->base + STBCR(clock->index / 32)); + else + value = readl(priv->base + MSTPSR(clock->index / 32)); return !(value & BIT(clock->index % 32)); } @@ -226,6 +255,7 @@ struct clk *cpg_mssr_clk_src_twocell_get(struct of_phandle_args *clkspec, unsigned int idx; const char *type; struct clk *clk; + int range_check; switch (clkspec->args[0]) { case CPG_CORE: @@ -240,8 +270,14 @@ struct clk *cpg_mssr_clk_src_twocell_get(struct of_phandle_args *clkspec, case CPG_MOD: type = "module"; - idx = MOD_CLK_PACK(clkidx); - if (clkidx % 100 > 31 || idx >= priv->num_mod_clks) { + if (priv->stbyctrl) { + idx = MOD_CLK_PACK_10(clkidx); + range_check = 7 - (clkidx % 10); + } else { + idx = MOD_CLK_PACK(clkidx); + range_check = 31 - (clkidx % 100); + } + if (range_check < 0 || idx >= priv->num_mod_clks) { dev_err(dev, "Invalid %s clock index %u\n", type, clkidx); return ERR_PTR(-EINVAL); @@ -646,6 +682,12 @@ static inline int cpg_mssr_reset_controller_register(struct cpg_mssr_priv *priv) static const struct of_device_id cpg_mssr_match[] = { +#ifdef CONFIG_CLK_R7S9210 + { + .compatible = "renesas,r7s9210-cpg-mssr", + .data = &r7s9210_cpg_mssr_info, + }, +#endif #ifdef CONFIG_CLK_R8A7743 { .compatible = "renesas,r8a7743-cpg-mssr", @@ -791,13 +833,23 @@ static int cpg_mssr_resume_noirq(struct device *dev) if (!mask) continue; - oldval = readl(priv->base + SMSTPCR(reg)); + if (priv->stbyctrl) + oldval = readb(priv->base + STBCR(reg)); + else + oldval = readl(priv->base + SMSTPCR(reg)); newval = oldval & ~mask; newval |= priv->smstpcr_saved[reg].val & mask; if (newval == oldval) continue; - writel(newval, priv->base + SMSTPCR(reg)); + if (priv->stbyctrl) { + writeb(newval, priv->base + STBCR(reg)); + /* dummy read to ensure write has completed */ + readb(priv->base + STBCR(reg)); + barrier_data(priv->base + STBCR(reg)); + continue; + } else + writel(newval, priv->base + SMSTPCR(reg)); /* Wait until enabled clocks are really enabled */ mask &= ~priv->smstpcr_saved[reg].val; @@ -869,6 +921,7 @@ static int __init cpg_mssr_probe(struct platform_device *pdev) priv->num_mod_clks = info->num_hw_mod_clks; priv->last_dt_core_clk = info->last_dt_core_clk; RAW_INIT_NOTIFIER_HEAD(&priv->notifiers); + priv->stbyctrl = info->stbyctrl; for (i = 0; i < nclks; i++) clks[i] = ERR_PTR(-ENOENT); @@ -894,6 +947,10 @@ static int __init cpg_mssr_probe(struct platform_device *pdev) if (error) return error; + /* Reset Controller not supported for Standby Control SoCs */ + if (info->stbyctrl) + return 0; + error = cpg_mssr_reset_controller_register(priv); if (error) return error; diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h index 2e1730bc5ef2..35f60b3d0e09 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.h +++ b/drivers/clk/renesas/renesas-cpg-mssr.h @@ -78,6 +78,13 @@ struct mssr_mod_clk { #define DEF_MOD(_name, _mod, _parent...) \ { .name = _name, .id = MOD_CLK_ID(_mod), .parent = _parent } +/* Convert from sparse base-10 to packed index space */ +#define MOD_CLK_PACK_10(x) ((x / 10) * 32 + (x % 10)) + +#define MOD_CLK_ID_10(x) (MOD_CLK_BASE + MOD_CLK_PACK_10(x)) + +#define DEF_MOD_STB(_name, _mod, _parent...) \ + { .name = _name, .id = MOD_CLK_ID_10(_mod), .parent = _parent } struct device_node; @@ -103,6 +110,10 @@ struct device_node; * * @init: Optional callback to perform SoC-specific initialization * @cpg_clk_register: Optional callback to handle special Core Clock types + * + * @stbyctrl: This device has Standby Control Registers which are 8-bits + * wide, no status registers (MSTPSR) and have different address + * offsets. */ struct cpg_mssr_info { @@ -111,6 +122,7 @@ struct cpg_mssr_info { unsigned int num_core_clks; unsigned int last_dt_core_clk; unsigned int num_total_core_clks; + bool stbyctrl; /* Module Clocks */ const struct mssr_mod_clk *mod_clks; @@ -134,6 +146,7 @@ struct cpg_mssr_info { struct raw_notifier_head *notifiers); }; +extern const struct cpg_mssr_info r7s9210_cpg_mssr_info; extern const struct cpg_mssr_info r8a7743_cpg_mssr_info; extern const struct cpg_mssr_info r8a7745_cpg_mssr_info; extern const struct cpg_mssr_info r8a77470_cpg_mssr_info; diff --git a/include/dt-bindings/clock/r7s9210-cpg-mssr.h b/include/dt-bindings/clock/r7s9210-cpg-mssr.h new file mode 100644 index 000000000000..b6f85ca149aa --- /dev/null +++ b/include/dt-bindings/clock/r7s9210-cpg-mssr.h @@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0 + * + * Copyright (C) 2018 Renesas Electronics Corp. + * + */ + +#ifndef __DT_BINDINGS_CLOCK_R7S9210_CPG_MSSR_H__ +#define __DT_BINDINGS_CLOCK_R7S9210_CPG_MSSR_H__ + +#include + +/* R7S9210 CPG Core Clocks */ +#define R7S9210_CLK_I 0 +#define R7S9210_CLK_G 1 +#define R7S9210_CLK_B 2 +#define R7S9210_CLK_P1 3 +#define R7S9210_CLK_P1C 4 +#define R7S9210_CLK_P0 5 + +#endif /* __DT_BINDINGS_CLOCK_R7S9210_CPG_MSSR_H__ */ -- cgit v1.2.3 From 906e0a4a6d1ef2d3940cd7f17287b111730382da Mon Sep 17 00:00:00 2001 From: Fabrizio Castro Date: Wed, 12 Sep 2018 11:41:53 +0100 Subject: clk: renesas: cpg-mssr: Add r8a774c0 support Add RZ/G2E (R8A774C0) Clock Pulse Generator / Module Standby and Software Reset support. Based on Table 8.2g of "RZ/G Series, 2nd Generation User's Manual: Hardware (Rev. 0.61, June 12, 2018)". Signed-off-by: Fabrizio Castro Reviewed-by: Biju Das Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/Kconfig | 5 + drivers/clk/renesas/Makefile | 1 + drivers/clk/renesas/r8a774c0-cpg-mssr.c | 286 ++++++++++++++++++++++++++++++++ drivers/clk/renesas/renesas-cpg-mssr.c | 6 + drivers/clk/renesas/renesas-cpg-mssr.h | 1 + 5 files changed, 299 insertions(+) create mode 100644 drivers/clk/renesas/r8a774c0-cpg-mssr.c (limited to 'drivers/clk/renesas/renesas-cpg-mssr.h') diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig index 7a6ceecc213e..8d5a6fbef7e9 100644 --- a/drivers/clk/renesas/Kconfig +++ b/drivers/clk/renesas/Kconfig @@ -10,6 +10,7 @@ config CLK_RENESAS select CLK_R8A7745 if ARCH_R8A7745 select CLK_R8A77470 if ARCH_R8A77470 select CLK_R8A774A1 if ARCH_R8A774A1 + select CLK_R8A774C0 if ARCH_R8A774C0 select CLK_R8A7778 if ARCH_R8A7778 select CLK_R8A7779 if ARCH_R8A7779 select CLK_R8A7790 if ARCH_R8A7790 @@ -77,6 +78,10 @@ config CLK_R8A774A1 bool "RZ/G2M clock support" if COMPILE_TEST select CLK_RCAR_GEN3_CPG +config CLK_R8A774C0 + bool "RZ/G2E clock support" if COMPILE_TEST + select CLK_RCAR_GEN3_CPG + config CLK_R8A7778 bool "R-Car M1A clock support" if COMPILE_TEST select CLK_RENESAS_CPG_MSTP diff --git a/drivers/clk/renesas/Makefile b/drivers/clk/renesas/Makefile index dbbfd0b0742b..c793e3cc9452 100644 --- a/drivers/clk/renesas/Makefile +++ b/drivers/clk/renesas/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_CLK_R8A7743) += r8a7743-cpg-mssr.o obj-$(CONFIG_CLK_R8A7745) += r8a7745-cpg-mssr.o obj-$(CONFIG_CLK_R8A77470) += r8a77470-cpg-mssr.o obj-$(CONFIG_CLK_R8A774A1) += r8a774a1-cpg-mssr.o +obj-$(CONFIG_CLK_R8A774C0) += r8a774c0-cpg-mssr.o obj-$(CONFIG_CLK_R8A7778) += clk-r8a7778.o obj-$(CONFIG_CLK_R8A7779) += clk-r8a7779.o obj-$(CONFIG_CLK_R8A7790) += r8a7790-cpg-mssr.o diff --git a/drivers/clk/renesas/r8a774c0-cpg-mssr.c b/drivers/clk/renesas/r8a774c0-cpg-mssr.c new file mode 100644 index 000000000000..10b96895d452 --- /dev/null +++ b/drivers/clk/renesas/r8a774c0-cpg-mssr.c @@ -0,0 +1,286 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * r8a774c0 Clock Pulse Generator / Module Standby and Software Reset + * + * Copyright (C) 2018 Renesas Electronics Corp. + * + * Based on r8a77990-cpg-mssr.c + * + * Copyright (C) 2015 Glider bvba + * Copyright (C) 2015 Renesas Electronics Corp. + */ + +#include +#include +#include +#include + +#include + +#include "renesas-cpg-mssr.h" +#include "rcar-gen3-cpg.h" + +enum clk_ids { + /* Core Clock Outputs exported to DT */ + LAST_DT_CORE_CLK = R8A774C0_CLK_CPEX, + + /* External Input Clocks */ + CLK_EXTAL, + + /* Internal Core Clocks */ + CLK_MAIN, + CLK_PLL0, + CLK_PLL1, + CLK_PLL3, + CLK_PLL0D4, + CLK_PLL0D8, + CLK_PLL0D20, + CLK_PLL0D24, + CLK_PLL1D2, + CLK_PE, + CLK_S0, + CLK_S1, + CLK_S2, + CLK_S3, + CLK_SDSRC, + CLK_RINT, + CLK_OCO, + + /* Module Clocks */ + MOD_CLK_BASE +}; + +static const struct cpg_core_clk r8a774c0_core_clks[] __initconst = { + /* External Clock Inputs */ + DEF_INPUT("extal", CLK_EXTAL), + + /* Internal Core Clocks */ + DEF_BASE(".main", CLK_MAIN, CLK_TYPE_GEN3_MAIN, CLK_EXTAL), + DEF_BASE(".pll1", CLK_PLL1, CLK_TYPE_GEN3_PLL1, CLK_MAIN), + DEF_BASE(".pll3", CLK_PLL3, CLK_TYPE_GEN3_PLL3, CLK_MAIN), + + DEF_FIXED(".pll0", CLK_PLL0, CLK_MAIN, 1, 100), + DEF_FIXED(".pll0d4", CLK_PLL0D4, CLK_PLL0, 4, 1), + DEF_FIXED(".pll0d8", CLK_PLL0D8, CLK_PLL0, 8, 1), + DEF_FIXED(".pll0d20", CLK_PLL0D20, CLK_PLL0, 20, 1), + DEF_FIXED(".pll0d24", CLK_PLL0D24, CLK_PLL0, 24, 1), + DEF_FIXED(".pll1d2", CLK_PLL1D2, CLK_PLL1, 2, 1), + DEF_FIXED(".pe", CLK_PE, CLK_PLL0D20, 1, 1), + DEF_FIXED(".s0", CLK_S0, CLK_PLL1, 2, 1), + DEF_FIXED(".s1", CLK_S1, CLK_PLL1, 3, 1), + DEF_FIXED(".s2", CLK_S2, CLK_PLL1, 4, 1), + DEF_FIXED(".s3", CLK_S3, CLK_PLL1, 6, 1), + DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1, 2, 1), + + DEF_DIV6_RO(".r", CLK_RINT, CLK_EXTAL, CPG_RCKCR, 32), + + DEF_RATE(".oco", CLK_OCO, 8 * 1000 * 1000), + + /* Core Clock Outputs */ + DEF_FIXED("za2", R8A774C0_CLK_ZA2, CLK_PLL0D24, 1, 1), + DEF_FIXED("za8", R8A774C0_CLK_ZA8, CLK_PLL0D8, 1, 1), + DEF_FIXED("ztr", R8A774C0_CLK_ZTR, CLK_PLL1, 6, 1), + DEF_FIXED("zt", R8A774C0_CLK_ZT, CLK_PLL1, 4, 1), + DEF_FIXED("zx", R8A774C0_CLK_ZX, CLK_PLL1, 3, 1), + DEF_FIXED("s0d1", R8A774C0_CLK_S0D1, CLK_S0, 1, 1), + DEF_FIXED("s0d3", R8A774C0_CLK_S0D3, CLK_S0, 3, 1), + DEF_FIXED("s0d6", R8A774C0_CLK_S0D6, CLK_S0, 6, 1), + DEF_FIXED("s0d12", R8A774C0_CLK_S0D12, CLK_S0, 12, 1), + DEF_FIXED("s0d24", R8A774C0_CLK_S0D24, CLK_S0, 24, 1), + DEF_FIXED("s1d1", R8A774C0_CLK_S1D1, CLK_S1, 1, 1), + DEF_FIXED("s1d2", R8A774C0_CLK_S1D2, CLK_S1, 2, 1), + DEF_FIXED("s1d4", R8A774C0_CLK_S1D4, CLK_S1, 4, 1), + DEF_FIXED("s2d1", R8A774C0_CLK_S2D1, CLK_S2, 1, 1), + DEF_FIXED("s2d2", R8A774C0_CLK_S2D2, CLK_S2, 2, 1), + DEF_FIXED("s2d4", R8A774C0_CLK_S2D4, CLK_S2, 4, 1), + DEF_FIXED("s3d1", R8A774C0_CLK_S3D1, CLK_S3, 1, 1), + DEF_FIXED("s3d2", R8A774C0_CLK_S3D2, CLK_S3, 2, 1), + DEF_FIXED("s3d4", R8A774C0_CLK_S3D4, CLK_S3, 4, 1), + + DEF_GEN3_SD("sd0", R8A774C0_CLK_SD0, CLK_SDSRC, 0x0074), + DEF_GEN3_SD("sd1", R8A774C0_CLK_SD1, CLK_SDSRC, 0x0078), + DEF_GEN3_SD("sd3", R8A774C0_CLK_SD3, CLK_SDSRC, 0x026c), + + DEF_FIXED("cl", R8A774C0_CLK_CL, CLK_PLL1, 48, 1), + DEF_FIXED("cp", R8A774C0_CLK_CP, CLK_EXTAL, 2, 1), + DEF_FIXED("cpex", R8A774C0_CLK_CPEX, CLK_EXTAL, 4, 1), + + DEF_DIV6_RO("osc", R8A774C0_CLK_OSC, CLK_EXTAL, CPG_RCKCR, 8), + + DEF_GEN3_PE("s0d6c", R8A774C0_CLK_S0D6C, CLK_S0, 6, CLK_PE, 2), + DEF_GEN3_PE("s3d1c", R8A774C0_CLK_S3D1C, CLK_S3, 1, CLK_PE, 1), + DEF_GEN3_PE("s3d2c", R8A774C0_CLK_S3D2C, CLK_S3, 2, CLK_PE, 2), + DEF_GEN3_PE("s3d4c", R8A774C0_CLK_S3D4C, CLK_S3, 4, CLK_PE, 4), + + DEF_DIV6P1("csi0", R8A774C0_CLK_CSI0, CLK_PLL1D2, 0x00c), + DEF_DIV6P1("mso", R8A774C0_CLK_MSO, CLK_PLL1D2, 0x014), + + DEF_GEN3_RCKSEL("r", R8A774C0_CLK_R, CLK_RINT, 1, CLK_OCO, 61 * 4), +}; + +static const struct mssr_mod_clk r8a774c0_mod_clks[] __initconst = { + DEF_MOD("scif5", 202, R8A774C0_CLK_S3D4C), + DEF_MOD("scif4", 203, R8A774C0_CLK_S3D4C), + DEF_MOD("scif3", 204, R8A774C0_CLK_S3D4C), + DEF_MOD("scif1", 206, R8A774C0_CLK_S3D4C), + DEF_MOD("scif0", 207, R8A774C0_CLK_S3D4C), + DEF_MOD("msiof3", 208, R8A774C0_CLK_MSO), + DEF_MOD("msiof2", 209, R8A774C0_CLK_MSO), + DEF_MOD("msiof1", 210, R8A774C0_CLK_MSO), + DEF_MOD("msiof0", 211, R8A774C0_CLK_MSO), + DEF_MOD("sys-dmac2", 217, R8A774C0_CLK_S3D1), + DEF_MOD("sys-dmac1", 218, R8A774C0_CLK_S3D1), + DEF_MOD("sys-dmac0", 219, R8A774C0_CLK_S3D1), + + DEF_MOD("cmt3", 300, R8A774C0_CLK_R), + DEF_MOD("cmt2", 301, R8A774C0_CLK_R), + DEF_MOD("cmt1", 302, R8A774C0_CLK_R), + DEF_MOD("cmt0", 303, R8A774C0_CLK_R), + DEF_MOD("scif2", 310, R8A774C0_CLK_S3D4C), + DEF_MOD("sdif3", 311, R8A774C0_CLK_SD3), + DEF_MOD("sdif1", 313, R8A774C0_CLK_SD1), + DEF_MOD("sdif0", 314, R8A774C0_CLK_SD0), + DEF_MOD("pcie0", 319, R8A774C0_CLK_S3D1), + DEF_MOD("usb3-if0", 328, R8A774C0_CLK_S3D1), + DEF_MOD("usb-dmac0", 330, R8A774C0_CLK_S3D1), + DEF_MOD("usb-dmac1", 331, R8A774C0_CLK_S3D1), + + DEF_MOD("rwdt", 402, R8A774C0_CLK_R), + DEF_MOD("intc-ex", 407, R8A774C0_CLK_CP), + DEF_MOD("intc-ap", 408, R8A774C0_CLK_S0D3), + + DEF_MOD("audmac0", 502, R8A774C0_CLK_S3D4), + DEF_MOD("hscif4", 516, R8A774C0_CLK_S3D1C), + DEF_MOD("hscif3", 517, R8A774C0_CLK_S3D1C), + DEF_MOD("hscif2", 518, R8A774C0_CLK_S3D1C), + DEF_MOD("hscif1", 519, R8A774C0_CLK_S3D1C), + DEF_MOD("hscif0", 520, R8A774C0_CLK_S3D1C), + DEF_MOD("thermal", 522, R8A774C0_CLK_CP), + DEF_MOD("pwm", 523, R8A774C0_CLK_S3D4C), + + DEF_MOD("fcpvd1", 602, R8A774C0_CLK_S1D2), + DEF_MOD("fcpvd0", 603, R8A774C0_CLK_S1D2), + DEF_MOD("fcpvb0", 607, R8A774C0_CLK_S0D1), + DEF_MOD("fcpvi0", 611, R8A774C0_CLK_S0D1), + DEF_MOD("fcpf0", 615, R8A774C0_CLK_S0D1), + DEF_MOD("fcpcs", 619, R8A774C0_CLK_S0D1), + DEF_MOD("vspd1", 622, R8A774C0_CLK_S1D2), + DEF_MOD("vspd0", 623, R8A774C0_CLK_S1D2), + DEF_MOD("vspb", 626, R8A774C0_CLK_S0D1), + DEF_MOD("vspi0", 631, R8A774C0_CLK_S0D1), + + DEF_MOD("ehci0", 703, R8A774C0_CLK_S3D4), + DEF_MOD("hsusb", 704, R8A774C0_CLK_S3D4), + DEF_MOD("csi40", 716, R8A774C0_CLK_CSI0), + DEF_MOD("du1", 723, R8A774C0_CLK_S2D1), + DEF_MOD("du0", 724, R8A774C0_CLK_S2D1), + DEF_MOD("lvds", 727, R8A774C0_CLK_S2D1), + + DEF_MOD("vin5", 806, R8A774C0_CLK_S1D2), + DEF_MOD("vin4", 807, R8A774C0_CLK_S1D2), + DEF_MOD("etheravb", 812, R8A774C0_CLK_S3D2), + + DEF_MOD("gpio6", 906, R8A774C0_CLK_S3D4), + DEF_MOD("gpio5", 907, R8A774C0_CLK_S3D4), + DEF_MOD("gpio4", 908, R8A774C0_CLK_S3D4), + DEF_MOD("gpio3", 909, R8A774C0_CLK_S3D4), + DEF_MOD("gpio2", 910, R8A774C0_CLK_S3D4), + DEF_MOD("gpio1", 911, R8A774C0_CLK_S3D4), + DEF_MOD("gpio0", 912, R8A774C0_CLK_S3D4), + DEF_MOD("can-if1", 915, R8A774C0_CLK_S3D4), + DEF_MOD("can-if0", 916, R8A774C0_CLK_S3D4), + DEF_MOD("i2c6", 918, R8A774C0_CLK_S3D2), + DEF_MOD("i2c5", 919, R8A774C0_CLK_S3D2), + DEF_MOD("i2c-dvfs", 926, R8A774C0_CLK_CP), + DEF_MOD("i2c4", 927, R8A774C0_CLK_S3D2), + DEF_MOD("i2c3", 928, R8A774C0_CLK_S3D2), + DEF_MOD("i2c2", 929, R8A774C0_CLK_S3D2), + DEF_MOD("i2c1", 930, R8A774C0_CLK_S3D2), + DEF_MOD("i2c0", 931, R8A774C0_CLK_S3D2), + + DEF_MOD("i2c7", 1003, R8A774C0_CLK_S3D2), + DEF_MOD("ssi-all", 1005, R8A774C0_CLK_S3D4), + DEF_MOD("ssi9", 1006, MOD_CLK_ID(1005)), + DEF_MOD("ssi8", 1007, MOD_CLK_ID(1005)), + DEF_MOD("ssi7", 1008, MOD_CLK_ID(1005)), + DEF_MOD("ssi6", 1009, MOD_CLK_ID(1005)), + DEF_MOD("ssi5", 1010, MOD_CLK_ID(1005)), + DEF_MOD("ssi4", 1011, MOD_CLK_ID(1005)), + DEF_MOD("ssi3", 1012, MOD_CLK_ID(1005)), + DEF_MOD("ssi2", 1013, MOD_CLK_ID(1005)), + DEF_MOD("ssi1", 1014, MOD_CLK_ID(1005)), + DEF_MOD("ssi0", 1015, MOD_CLK_ID(1005)), + DEF_MOD("scu-all", 1017, R8A774C0_CLK_S3D4), + DEF_MOD("scu-dvc1", 1018, MOD_CLK_ID(1017)), + DEF_MOD("scu-dvc0", 1019, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu1-mix1", 1020, MOD_CLK_ID(1017)), + DEF_MOD("scu-ctu0-mix0", 1021, MOD_CLK_ID(1017)), + DEF_MOD("scu-src9", 1022, MOD_CLK_ID(1017)), + DEF_MOD("scu-src8", 1023, MOD_CLK_ID(1017)), + DEF_MOD("scu-src7", 1024, MOD_CLK_ID(1017)), + DEF_MOD("scu-src6", 1025, MOD_CLK_ID(1017)), + DEF_MOD("scu-src5", 1026, MOD_CLK_ID(1017)), + DEF_MOD("scu-src4", 1027, MOD_CLK_ID(1017)), + DEF_MOD("scu-src3", 1028, MOD_CLK_ID(1017)), + DEF_MOD("scu-src2", 1029, MOD_CLK_ID(1017)), + DEF_MOD("scu-src1", 1030, MOD_CLK_ID(1017)), + DEF_MOD("scu-src0", 1031, MOD_CLK_ID(1017)), +}; + +static const unsigned int r8a774c0_crit_mod_clks[] __initconst = { + MOD_CLK_ID(408), /* INTC-AP (GIC) */ +}; + +/* + * CPG Clock Data + */ + +/* + * MD19 EXTAL (MHz) PLL0 PLL1 PLL3 + *-------------------------------------------------------------------- + * 0 48 x 1 x100/1 x100/3 x100/3 + * 1 48 x 1 x100/1 x100/3 x58/3 + */ +#define CPG_PLL_CONFIG_INDEX(md) (((md) & BIT(19)) >> 19) + +static const struct rcar_gen3_cpg_pll_config cpg_pll_configs[2] __initconst = { + /* EXTAL div PLL1 mult/div PLL3 mult/div */ + { 1, 100, 3, 100, 3, }, + { 1, 100, 3, 58, 3, }, +}; + +static int __init r8a774c0_cpg_mssr_init(struct device *dev) +{ + const struct rcar_gen3_cpg_pll_config *cpg_pll_config; + u32 cpg_mode; + int error; + + error = rcar_rst_read_mode_pins(&cpg_mode); + if (error) + return error; + + cpg_pll_config = &cpg_pll_configs[CPG_PLL_CONFIG_INDEX(cpg_mode)]; + + return rcar_gen3_cpg_init(cpg_pll_config, 0, cpg_mode); +} + +const struct cpg_mssr_info r8a774c0_cpg_mssr_info __initconst = { + /* Core Clocks */ + .core_clks = r8a774c0_core_clks, + .num_core_clks = ARRAY_SIZE(r8a774c0_core_clks), + .last_dt_core_clk = LAST_DT_CORE_CLK, + .num_total_core_clks = MOD_CLK_BASE, + + /* Module Clocks */ + .mod_clks = r8a774c0_mod_clks, + .num_mod_clks = ARRAY_SIZE(r8a774c0_mod_clks), + .num_hw_mod_clks = 12 * 32, + + /* Critical Module Clocks */ + .crit_mod_clks = r8a774c0_crit_mod_clks, + .num_crit_mod_clks = ARRAY_SIZE(r8a774c0_crit_mod_clks), + + /* Callbacks */ + .init = r8a774c0_cpg_mssr_init, + .cpg_clk_register = rcar_gen3_cpg_clk_register, +}; diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index c4beec7b563f..e0c11a5b1761 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -717,6 +717,12 @@ static const struct of_device_id cpg_mssr_match[] = { .data = &r8a774a1_cpg_mssr_info, }, #endif +#ifdef CONFIG_CLK_R8A774C0 + { + .compatible = "renesas,r8a774c0-cpg-mssr", + .data = &r8a774c0_cpg_mssr_info, + }, +#endif #ifdef CONFIG_CLK_R8A7790 { .compatible = "renesas,r8a7790-cpg-mssr", diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h index 35f60b3d0e09..d43d00351638 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.h +++ b/drivers/clk/renesas/renesas-cpg-mssr.h @@ -151,6 +151,7 @@ extern const struct cpg_mssr_info r8a7743_cpg_mssr_info; extern const struct cpg_mssr_info r8a7745_cpg_mssr_info; extern const struct cpg_mssr_info r8a77470_cpg_mssr_info; extern const struct cpg_mssr_info r8a774a1_cpg_mssr_info; +extern const struct cpg_mssr_info r8a774c0_cpg_mssr_info; extern const struct cpg_mssr_info r8a7790_cpg_mssr_info; extern const struct cpg_mssr_info r8a7791_cpg_mssr_info; extern const struct cpg_mssr_info r8a7792_cpg_mssr_info; -- cgit v1.2.3 From 1f7db7bbf031828178216527523b29cb6001f86f Mon Sep 17 00:00:00 2001 From: Chris Brandt Date: Mon, 24 Sep 2018 11:49:35 -0500 Subject: clk: renesas: cpg-mssr: Add early clock support Add support for SoCs that need to register core and module clocks early in order to use OF drivers that exclusively use macros such as TIMER_OF_DECLARE. Signed-off-by: Chris Brandt Signed-off-by: Geert Uytterhoeven --- drivers/clk/renesas/renesas-cpg-mssr.c | 97 ++++++++++++++++++++++++++-------- drivers/clk/renesas/renesas-cpg-mssr.h | 13 +++++ 2 files changed, 89 insertions(+), 21 deletions(-) (limited to 'drivers/clk/renesas/renesas-cpg-mssr.h') diff --git a/drivers/clk/renesas/renesas-cpg-mssr.c b/drivers/clk/renesas/renesas-cpg-mssr.c index e0c11a5b1761..394a7d10392a 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.c +++ b/drivers/clk/renesas/renesas-cpg-mssr.c @@ -130,6 +130,7 @@ struct cpg_mssr_priv { struct device *dev; void __iomem *base; spinlock_t rmw_lock; + struct device_node *np; struct clk **clks; unsigned int num_core_clks; @@ -144,6 +145,7 @@ struct cpg_mssr_priv { } smstpcr_saved[ARRAY_SIZE(smstpcr)]; }; +static struct cpg_mssr_priv *cpg_mssr_priv; /** * struct mstp_clock - MSTP gating clock @@ -319,7 +321,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core, switch (core->type) { case CLK_TYPE_IN: - clk = of_clk_get_by_name(priv->dev->of_node, core->name); + clk = of_clk_get_by_name(priv->np, core->name); break; case CLK_TYPE_FF: @@ -891,42 +893,43 @@ static const struct dev_pm_ops cpg_mssr_pm = { #define DEV_PM_OPS NULL #endif /* CONFIG_PM_SLEEP && CONFIG_ARM_PSCI_FW */ -static int __init cpg_mssr_probe(struct platform_device *pdev) +static int __init cpg_mssr_common_init(struct device *dev, + struct device_node *np, + const struct cpg_mssr_info *info) { - struct device *dev = &pdev->dev; - struct device_node *np = dev->of_node; - const struct cpg_mssr_info *info; struct cpg_mssr_priv *priv; + struct clk **clks = NULL; unsigned int nclks, i; - struct resource *res; - struct clk **clks; int error; - info = of_device_get_match_data(dev); if (info->init) { error = info->init(dev); if (error) return error; } - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + priv = kzalloc(sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; + priv->np = np; priv->dev = dev; spin_lock_init(&priv->rmw_lock); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - priv->base = devm_ioremap_resource(dev, res); - if (IS_ERR(priv->base)) - return PTR_ERR(priv->base); + priv->base = of_iomap(np, 0); + if (!priv->base) { + error = -ENOMEM; + goto out_err; + } nclks = info->num_total_core_clks + info->num_hw_mod_clks; - clks = devm_kmalloc_array(dev, nclks, sizeof(*clks), GFP_KERNEL); - if (!clks) - return -ENOMEM; + clks = kmalloc_array(nclks, sizeof(*clks), GFP_KERNEL); + if (!clks) { + error = -ENOMEM; + goto out_err; + } - dev_set_drvdata(dev, priv); + cpg_mssr_priv = priv; priv->clks = clks; priv->num_core_clks = info->num_total_core_clks; priv->num_mod_clks = info->num_hw_mod_clks; @@ -937,16 +940,68 @@ static int __init cpg_mssr_probe(struct platform_device *pdev) for (i = 0; i < nclks; i++) clks[i] = ERR_PTR(-ENOENT); + error = of_clk_add_provider(np, cpg_mssr_clk_src_twocell_get, priv); + if (error) + goto out_err; + + return 0; + +out_err: + kfree(clks); + if (priv->base) + iounmap(priv->base); + kfree(priv); + + return error; +} + +void __init cpg_mssr_early_init(struct device_node *np, + const struct cpg_mssr_info *info) +{ + int error; + int i; + + error = cpg_mssr_common_init(NULL, np, info); + if (error) + return; + + for (i = 0; i < info->num_early_core_clks; i++) + cpg_mssr_register_core_clk(&info->early_core_clks[i], info, + cpg_mssr_priv); + + for (i = 0; i < info->num_early_mod_clks; i++) + cpg_mssr_register_mod_clk(&info->early_mod_clks[i], info, + cpg_mssr_priv); + +} + +static int __init cpg_mssr_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + const struct cpg_mssr_info *info; + struct cpg_mssr_priv *priv; + unsigned int i; + int error; + + info = of_device_get_match_data(dev); + + if (!cpg_mssr_priv) { + error = cpg_mssr_common_init(dev, dev->of_node, info); + if (error) + return error; + } + + priv = cpg_mssr_priv; + priv->dev = dev; + dev_set_drvdata(dev, priv); + for (i = 0; i < info->num_core_clks; i++) cpg_mssr_register_core_clk(&info->core_clks[i], info, priv); for (i = 0; i < info->num_mod_clks; i++) cpg_mssr_register_mod_clk(&info->mod_clks[i], info, priv); - error = of_clk_add_provider(np, cpg_mssr_clk_src_twocell_get, priv); - if (error) - return error; - error = devm_add_action_or_reset(dev, cpg_mssr_del_clk_provider, np); diff --git a/drivers/clk/renesas/renesas-cpg-mssr.h b/drivers/clk/renesas/renesas-cpg-mssr.h index d43d00351638..4e639fb8da9a 100644 --- a/drivers/clk/renesas/renesas-cpg-mssr.h +++ b/drivers/clk/renesas/renesas-cpg-mssr.h @@ -91,6 +91,11 @@ struct device_node; /** * SoC-specific CPG/MSSR Description * + * @early_core_clks: Array of Early Core Clock definitions + * @num_early_core_clks: Number of entries in early_core_clks[] + * @early_mod_clks: Array of Early Module Clock definitions + * @num_early_mod_clks: Number of entries in early_mod_clks[] + * * @core_clks: Array of Core Clock definitions * @num_core_clks: Number of entries in core_clks[] * @last_dt_core_clk: ID of the last Core Clock exported to DT @@ -117,6 +122,12 @@ struct device_node; */ struct cpg_mssr_info { + /* Early Clocks */ + const struct cpg_core_clk *early_core_clks; + unsigned int num_early_core_clks; + const struct mssr_mod_clk *early_mod_clks; + unsigned int num_early_mod_clks; + /* Core Clocks */ const struct cpg_core_clk *core_clks; unsigned int num_core_clks; @@ -164,6 +175,8 @@ extern const struct cpg_mssr_info r8a77980_cpg_mssr_info; extern const struct cpg_mssr_info r8a77990_cpg_mssr_info; extern const struct cpg_mssr_info r8a77995_cpg_mssr_info; +void __init cpg_mssr_early_init(struct device_node *np, + const struct cpg_mssr_info *info); /* * Helpers for fixing up clock tables depending on SoC revision -- cgit v1.2.3