diff options
| -rw-r--r-- | Documentation/devicetree/bindings/clock/st/st,clkgen-divmux.txt | 49 | ||||
| -rw-r--r-- | Documentation/devicetree/bindings/clock/st/st,clkgen-mux.txt | 18 | ||||
| -rw-r--r-- | Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt | 26 | ||||
| -rw-r--r-- | Documentation/devicetree/bindings/clock/st/st,clkgen-prediv.txt | 36 | ||||
| -rw-r--r-- | Documentation/devicetree/bindings/clock/st/st,clkgen-vcc.txt | 61 | ||||
| -rw-r--r-- | Documentation/devicetree/bindings/clock/st/st,clkgen.txt | 54 | ||||
| -rw-r--r-- | Documentation/devicetree/bindings/clock/st/st,quadfs.txt | 27 | ||||
| -rw-r--r-- | drivers/clk/st/clkgen-fsyn.c | 260 | ||||
| -rw-r--r-- | drivers/clk/st/clkgen-mux.c | 726 | ||||
| -rw-r--r-- | drivers/clk/st/clkgen-pll.c | 419 |
10 files changed, 37 insertions, 1639 deletions
diff --git a/Documentation/devicetree/bindings/clock/st/st,clkgen-divmux.txt b/Documentation/devicetree/bindings/clock/st/st,clkgen-divmux.txt deleted file mode 100644 index 6247652044a0..000000000000 --- a/Documentation/devicetree/bindings/clock/st/st,clkgen-divmux.txt +++ /dev/null @@ -1,49 +0,0 @@ -Binding for a ST divider and multiplexer clock driver. - -This binding uses the common clock binding[1]. -Base address is located to the parent node. See clock binding[2] - -[1] Documentation/devicetree/bindings/clock/clock-bindings.txt -[2] Documentation/devicetree/bindings/clock/st/st,clkgen.txt - -Required properties: - -- compatible : shall be: - "st,clkgena-divmux-c65-hs", "st,clkgena-divmux" - "st,clkgena-divmux-c65-ls", "st,clkgena-divmux" - "st,clkgena-divmux-c32-odf0", "st,clkgena-divmux" - "st,clkgena-divmux-c32-odf1", "st,clkgena-divmux" - "st,clkgena-divmux-c32-odf2", "st,clkgena-divmux" - "st,clkgena-divmux-c32-odf3", "st,clkgena-divmux" - -- #clock-cells : From common clock binding; shall be set to 1. - -- clocks : From common clock binding - -- clock-output-names : From common clock binding. - -Example: - - clockgen-a@fd345000 { - reg = <0xfd345000 0xb50>; - - clk_m_a1_div1: clk-m-a1-div1 { - #clock-cells = <1>; - compatible = "st,clkgena-divmux-c32-odf1", - "st,clkgena-divmux"; - - clocks = <&clk_m_a1_osc_prediv>, - <&clk_m_a1_pll0 1>, /* PLL0 PHI1 */ - <&clk_m_a1_pll1 1>; /* PLL1 PHI1 */ - - clock-output-names = "clk-m-rx-icn-ts", - "clk-m-rx-icn-vdp-0", - "", /* unused */ - "clk-m-prv-t1-bus", - "clk-m-icn-reg-12", - "clk-m-icn-reg-10", - "", /* unused */ - "clk-m-icn-st231"; - }; - }; - diff --git a/Documentation/devicetree/bindings/clock/st/st,clkgen-mux.txt b/Documentation/devicetree/bindings/clock/st/st,clkgen-mux.txt index f1fa91c68768..4d277d609b66 100644 --- a/Documentation/devicetree/bindings/clock/st/st,clkgen-mux.txt +++ b/Documentation/devicetree/bindings/clock/st/st,clkgen-mux.txt @@ -10,13 +10,6 @@ This binding uses the common clock binding[1]. Required properties: - compatible : shall be: - "st,stih416-clkgenc-vcc-hd", "st,clkgen-mux" - "st,stih416-clkgenf-vcc-fvdp", "st,clkgen-mux" - "st,stih416-clkgenf-vcc-hva", "st,clkgen-mux" - "st,stih416-clkgenf-vcc-hd", "st,clkgen-mux" - "st,stih416-clkgenf-vcc-sd", "st,clkgen-mux" - "st,stih415-clkgen-a9-mux", "st,clkgen-mux" - "st,stih416-clkgen-a9-mux", "st,clkgen-mux" "st,stih407-clkgen-a9-mux", "st,clkgen-mux" - #clock-cells : from common clock binding; shall be set to 0. @@ -27,10 +20,13 @@ Required properties: Example: - clk_m_hva: clk-m-hva@fd690868 { + clk_m_a9: clk-m-a9@92b0000 { #clock-cells = <0>; - compatible = "st,stih416-clkgenf-vcc-hva", "st,clkgen-mux"; - reg = <0xfd690868 4>; + compatible = "st,stih407-clkgen-a9-mux"; + reg = <0x92b0000 0x10000>; - clocks = <&clockgen_f 1>, <&clk_m_a1_div0 3>; + clocks = <&clockgen_a9_pll 0>, + <&clockgen_a9_pll 0>, + <&clk_s_c0_flexgen 13>, + <&clk_m_a9_ext2f_div2>; }; diff --git a/Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt b/Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt index 844b3a0976bf..c9fd6748f85e 100644 --- a/Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt +++ b/Documentation/devicetree/bindings/clock/st/st,clkgen-pll.txt @@ -9,25 +9,12 @@ Base address is located to the parent node. See clock binding[2] Required properties: - compatible : shall be: - "st,clkgena-prediv-c65", "st,clkgena-prediv" - "st,clkgena-prediv-c32", "st,clkgena-prediv" - - "st,clkgena-plls-c65" - "st,plls-c32-a1x-0", "st,clkgen-plls-c32" - "st,plls-c32-a1x-1", "st,clkgen-plls-c32" - "st,stih415-plls-c32-a9", "st,clkgen-plls-c32" - "st,stih415-plls-c32-ddr", "st,clkgen-plls-c32" - "st,stih416-plls-c32-a9", "st,clkgen-plls-c32" - "st,stih416-plls-c32-ddr", "st,clkgen-plls-c32" "st,stih407-plls-c32-a0", "st,clkgen-plls-c32" "st,stih407-plls-c32-a9", "st,clkgen-plls-c32" "sst,plls-c32-cx_0", "st,clkgen-plls-c32" "sst,plls-c32-cx_1", "st,clkgen-plls-c32" "st,stih418-plls-c28-a9", "st,clkgen-plls-c32" - "st,stih415-gpu-pll-c32", "st,clkgengpu-pll-c32" - "st,stih416-gpu-pll-c32", "st,clkgengpu-pll-c32" - - #clock-cells : From common clock binding; shall be set to 1. - clocks : From common clock binding @@ -36,17 +23,16 @@ Required properties: Example: - clockgen-a@fee62000 { - reg = <0xfee62000 0xb48>; + clockgen-a9@92b0000 { + compatible = "st,clkgen-c32"; + reg = <0x92b0000 0xffff>; - clk_s_a0_pll: clk-s-a0-pll { + clockgen_a9_pll: clockgen-a9-pll { #clock-cells = <1>; - compatible = "st,clkgena-plls-c65"; + compatible = "st,stih407-plls-c32-a9", "st,clkgen-plls-c32"; clocks = <&clk_sysin>; - clock-output-names = "clk-s-a0-pll0-hs", - "clk-s-a0-pll0-ls", - "clk-s-a0-pll1"; + clock-output-names = "clockgen-a9-pll-odf"; }; }; diff --git a/Documentation/devicetree/bindings/clock/st/st,clkgen-prediv.txt b/Documentation/devicetree/bindings/clock/st/st,clkgen-prediv.txt deleted file mode 100644 index 604766c2619e..000000000000 --- a/Documentation/devicetree/bindings/clock/st/st,clkgen-prediv.txt +++ /dev/null @@ -1,36 +0,0 @@ -Binding for a ST pre-divider clock driver. - -This binding uses the common clock binding[1]. -Base address is located to the parent node. See clock binding[2] - -[1] Documentation/devicetree/bindings/clock/clock-bindings.txt -[2] Documentation/devicetree/bindings/clock/st/st,clkgen.txt - -Required properties: - -- compatible : shall be: - "st,clkgena-prediv-c65", "st,clkgena-prediv" - "st,clkgena-prediv-c32", "st,clkgena-prediv" - -- #clock-cells : From common clock binding; shall be set to 0. - -- clocks : From common clock binding - -- clock-output-names : From common clock binding. - -Example: - - clockgen-a@fd345000 { - reg = <0xfd345000 0xb50>; - - clk_m_a2_osc_prediv: clk-m-a2-osc-prediv { - #clock-cells = <0>; - compatible = "st,clkgena-prediv-c32", - "st,clkgena-prediv"; - - clocks = <&clk_sysin>; - - clock-output-names = "clk-m-a2-osc-prediv"; - }; - }; - diff --git a/Documentation/devicetree/bindings/clock/st/st,clkgen-vcc.txt b/Documentation/devicetree/bindings/clock/st/st,clkgen-vcc.txt deleted file mode 100644 index 109b3eddcb17..000000000000 --- a/Documentation/devicetree/bindings/clock/st/st,clkgen-vcc.txt +++ /dev/null @@ -1,61 +0,0 @@ -Binding for a type of STMicroelectronics clock crossbar (VCC). - -The crossbar can take up to 4 input clocks and control up to 16 -output clocks. Not all inputs or outputs have to be in use in a -particular instantiation. Each output can be individually enabled, -select any of the input clocks and apply a divide (by 1,2,4 or 8) to -that selected clock. - -This binding uses the common clock binding[1]. - -[1] Documentation/devicetree/bindings/clock/clock-bindings.txt - -Required properties: - -- compatible : shall be: - "st,stih416-clkgenc", "st,vcc" - "st,stih416-clkgenf", "st,vcc" - -- #clock-cells : from common clock binding; shall be set to 1. - -- reg : A Base address and length of the register set. - -- clocks : from common clock binding - -- clock-output-names : From common clock binding. The block has 16 - clock outputs but not all of them in a specific instance - have to be used in the SoC. If a clock name is left as - an empty string then no clock will be created for the - output associated with that string index. If fewer than - 16 strings are provided then no clocks will be created - for the remaining outputs. - -Example: - - clockgen_c_vcc: clockgen-c-vcc@0xfe8308ac { - #clock-cells = <1>; - compatible = "st,stih416-clkgenc", "st,clkgen-vcc"; - reg = <0xfe8308ac 12>; - - clocks = <&clk_s_vcc_hd>, - <&clockgen_c 1>, - <&clk_s_tmds_fromphy>, - <&clockgen_c 2>; - - clock-output-names = "clk-s-pix-hdmi", - "clk-s-pix-dvo", - "clk-s-out-dvo", - "clk-s-pix-hd", - "clk-s-hddac", - "clk-s-denc", - "clk-s-sddac", - "clk-s-pix-main", - "clk-s-pix-aux", - "clk-s-stfe-frc-0", - "clk-s-ref-mcru", - "clk-s-slave-mcru", - "clk-s-tmds-hdmi", - "clk-s-hdmi-reject-pll", - "clk-s-thsens"; - }; - diff --git a/Documentation/devicetree/bindings/clock/st/st,clkgen.txt b/Documentation/devicetree/bindings/clock/st/st,clkgen.txt index b18bf86f926f..c764d6b4035a 100644 --- a/Documentation/devicetree/bindings/clock/st/st,clkgen.txt +++ b/Documentation/devicetree/bindings/clock/st/st,clkgen.txt @@ -13,14 +13,6 @@ address is common of all subnode. ... }; - prediv_node { - ... - }; - - divmux_node { - ... - }; - quadfs_node { ... }; @@ -29,10 +21,6 @@ address is common of all subnode. ... }; - vcc_node { - ... - }; - flexgen_node { ... }; @@ -43,11 +31,8 @@ This binding uses the common clock binding[1]. Each subnode should use the binding described in [2]..[7] [1] Documentation/devicetree/bindings/clock/clock-bindings.txt -[2] Documentation/devicetree/bindings/clock/st,clkgen-divmux.txt [3] Documentation/devicetree/bindings/clock/st,clkgen-mux.txt [4] Documentation/devicetree/bindings/clock/st,clkgen-pll.txt -[5] Documentation/devicetree/bindings/clock/st,clkgen-prediv.txt -[6] Documentation/devicetree/bindings/clock/st,vcc.txt [7] Documentation/devicetree/bindings/clock/st,quadfs.txt [8] Documentation/devicetree/bindings/clock/st,flexgen.txt @@ -57,44 +42,27 @@ Required properties: Example: - clockgen-a@fee62000 { - - reg = <0xfee62000 0xb48>; + clockgen-a@090ff000 { + compatible = "st,clkgen-c32"; + reg = <0x90ff000 0x1000>; clk_s_a0_pll: clk-s-a0-pll { #clock-cells = <1>; - compatible = "st,clkgena-plls-c65"; - - clocks = <&clk-sysin>; - - clock-output-names = "clk-s-a0-pll0-hs", - "clk-s-a0-pll0-ls", - "clk-s-a0-pll1"; - }; - - clk_s_a0_osc_prediv: clk-s-a0-osc-prediv { - #clock-cells = <0>; - compatible = "st,clkgena-prediv-c65", - "st,clkgena-prediv"; + compatible = "st,stih407-plls-c32-a0", "st,clkgen-plls-c32"; clocks = <&clk_sysin>; - clock-output-names = "clk-s-a0-osc-prediv"; + clock-output-names = "clk-s-a0-pll-ofd-0"; }; - clk_s_a0_hs: clk-s-a0-hs { + clk_s_a0_flexgen: clk-s-a0-flexgen { + compatible = "st,flexgen"; + #clock-cells = <1>; - compatible = "st,clkgena-divmux-c65-hs", - "st,clkgena-divmux"; - clocks = <&clk-s_a0_osc_prediv>, - <&clk-s_a0_pll 0>, /* pll0 hs */ - <&clk-s_a0_pll 2>; /* pll1 */ + clocks = <&clk_s_a0_pll 0>, + <&clk_sysin>; - clock-output-names = "clk-s-fdma-0", - "clk-s-fdma-1", - ""; /* clk-s-jit-sense */ - /* fourth output unused */ + clock-output-names = "clk-ic-lmi0"; }; }; - diff --git a/Documentation/devicetree/bindings/clock/st/st,quadfs.txt b/Documentation/devicetree/bindings/clock/st/st,quadfs.txt index cedeb9cc8208..6d81b11a3d92 100644 --- a/Documentation/devicetree/bindings/clock/st/st,quadfs.txt +++ b/Documentation/devicetree/bindings/clock/st/st,quadfs.txt @@ -11,10 +11,6 @@ This binding uses the common clock binding[1]. Required properties: - compatible : shall be: - "st,stih416-quadfs216", "st,quadfs" - "st,stih416-quadfs432", "st,quadfs" - "st,stih416-quadfs660-E", "st,quadfs" - "st,stih416-quadfs660-F", "st,quadfs" "st,stih407-quadfs660-C", "st,quadfs" "st,stih407-quadfs660-D", "st,quadfs" @@ -35,14 +31,15 @@ Required properties: Example: - clockgen_e: clockgen-e@fd3208bc { - #clock-cells = <1>; - compatible = "st,stih416-quadfs660-E", "st,quadfs"; - reg = <0xfd3208bc 0xB0>; - - clocks = <&clk_sysin>; - clock-output-names = "clk-m-pix-mdtp-0", - "clk-m-pix-mdtp-1", - "clk-m-pix-mdtp-2", - "clk-m-mpelpc"; - }; + clk_s_c0_quadfs: clk-s-c0-quadfs@9103000 { + #clock-cells = <1>; + compatible = "st,stih407-quadfs660-C", "st,quadfs"; + reg = <0x9103000 0x1000>; + + clocks = <&clk_sysin>; + + clock-output-names = "clk-s-c0-fs0-ch0", + "clk-s-c0-fs0-ch1", + "clk-s-c0-fs0-ch2", + "clk-s-c0-fs0-ch3"; + }; diff --git a/drivers/clk/st/clkgen-fsyn.c b/drivers/clk/st/clkgen-fsyn.c index 09afeb85109c..942c18769290 100644 --- a/drivers/clk/st/clkgen-fsyn.c +++ b/drivers/clk/st/clkgen-fsyn.c @@ -42,45 +42,6 @@ struct stm_fs { unsigned long nsdiv; }; -static const struct stm_fs fs216c65_rtbl[] = { - { .mdiv = 0x1f, .pe = 0x0, .sdiv = 0x7, .nsdiv = 0 }, /* 312.5 Khz */ - { .mdiv = 0x17, .pe = 0x25ed, .sdiv = 0x1, .nsdiv = 0 }, /* 27 MHz */ - { .mdiv = 0x1a, .pe = 0x7b36, .sdiv = 0x2, .nsdiv = 1 }, /* 36.87 MHz */ - { .mdiv = 0x13, .pe = 0x0, .sdiv = 0x2, .nsdiv = 1 }, /* 48 MHz */ - { .mdiv = 0x11, .pe = 0x1c72, .sdiv = 0x1, .nsdiv = 1 }, /* 108 MHz */ -}; - -static const struct stm_fs fs432c65_rtbl[] = { - { .mdiv = 0x1f, .pe = 0x0, .sdiv = 0x7, .nsdiv = 0 }, /* 625 Khz */ - { .mdiv = 0x13, .pe = 0x777c, .sdiv = 0x4, .nsdiv = 1 }, /* 25.175 MHz */ - { .mdiv = 0x19, .pe = 0x4d35, .sdiv = 0x2, .nsdiv = 0 }, /* 25.200 MHz */ - { .mdiv = 0x11, .pe = 0x1c72, .sdiv = 0x4, .nsdiv = 1 }, /* 27.000 MHz */ - { .mdiv = 0x17, .pe = 0x28f5, .sdiv = 0x2, .nsdiv = 0 }, /* 27.027 MHz */ - { .mdiv = 0x16, .pe = 0x3359, .sdiv = 0x2, .nsdiv = 0 }, /* 28.320 MHz */ - { .mdiv = 0x1f, .pe = 0x2083, .sdiv = 0x3, .nsdiv = 1 }, /* 30.240 MHz */ - { .mdiv = 0x1e, .pe = 0x430d, .sdiv = 0x3, .nsdiv = 1 }, /* 31.500 MHz */ - { .mdiv = 0x17, .pe = 0x0, .sdiv = 0x3, .nsdiv = 1 }, /* 40.000 MHz */ - { .mdiv = 0x19, .pe = 0x121a, .sdiv = 0x1, .nsdiv = 0 }, /* 49.500 MHz */ - { .mdiv = 0x13, .pe = 0x6667, .sdiv = 0x3, .nsdiv = 1 }, /* 50.000 MHz */ - { .mdiv = 0x10, .pe = 0x1ee6, .sdiv = 0x3, .nsdiv = 1 }, /* 57.284 MHz */ - { .mdiv = 0x1d, .pe = 0x3b14, .sdiv = 0x2, .nsdiv = 1 }, /* 65.000 MHz */ - { .mdiv = 0x12, .pe = 0x7c65, .sdiv = 0x1, .nsdiv = 0 }, /* 71.000 MHz */ - { .mdiv = 0x19, .pe = 0xecd, .sdiv = 0x2, .nsdiv = 1 }, /* 74.176 MHz */ - { .mdiv = 0x19, .pe = 0x121a, .sdiv = 0x2, .nsdiv = 1 }, /* 74.250 MHz */ - { .mdiv = 0x19, .pe = 0x3334, .sdiv = 0x2, .nsdiv = 1 }, /* 75.000 MHz */ - { .mdiv = 0x18, .pe = 0x5138, .sdiv = 0x2, .nsdiv = 1 }, /* 78.800 MHz */ - { .mdiv = 0x1d, .pe = 0x77d, .sdiv = 0x0, .nsdiv = 0 }, /* 85.500 MHz */ - { .mdiv = 0x1c, .pe = 0x13d5, .sdiv = 0x0, .nsdiv = 0 }, /* 88.750 MHz */ - { .mdiv = 0x11, .pe = 0x1c72, .sdiv = 0x2, .nsdiv = 1 }, /* 108.000 MHz */ - { .mdiv = 0x17, .pe = 0x28f5, .sdiv = 0x0, .nsdiv = 0 }, /* 108.108 MHz */ - { .mdiv = 0x10, .pe = 0x6e26, .sdiv = 0x2, .nsdiv = 1 }, /* 118.963 MHz */ - { .mdiv = 0x15, .pe = 0x3e63, .sdiv = 0x0, .nsdiv = 0 }, /* 119.000 MHz */ - { .mdiv = 0x1c, .pe = 0x471d, .sdiv = 0x1, .nsdiv = 1 }, /* 135.000 MHz */ - { .mdiv = 0x19, .pe = 0xecd, .sdiv = 0x1, .nsdiv = 1 }, /* 148.352 MHz */ - { .mdiv = 0x19, .pe = 0x121a, .sdiv = 0x1, .nsdiv = 1 }, /* 148.500 MHz */ - { .mdiv = 0x19, .pe = 0x121a, .sdiv = 0x0, .nsdiv = 1 }, /* 297 MHz */ -}; - static const struct stm_fs fs660c32_rtbl[] = { { .mdiv = 0x14, .pe = 0x376b, .sdiv = 0x4, .nsdiv = 1 }, /* 25.175 MHz */ { .mdiv = 0x14, .pe = 0x30c3, .sdiv = 0x4, .nsdiv = 1 }, /* 25.200 MHz */ @@ -144,168 +105,11 @@ struct clkgen_quadfs_data { unsigned long *); }; -static const struct clk_ops st_quadfs_pll_c65_ops; static const struct clk_ops st_quadfs_pll_c32_ops; -static const struct clk_ops st_quadfs_fs216c65_ops; -static const struct clk_ops st_quadfs_fs432c65_ops; static const struct clk_ops st_quadfs_fs660c32_ops; -static int clk_fs216c65_get_rate(unsigned long, const struct stm_fs *, - unsigned long *); -static int clk_fs432c65_get_rate(unsigned long, const struct stm_fs *, - unsigned long *); static int clk_fs660c32_dig_get_rate(unsigned long, const struct stm_fs *, unsigned long *); -/* - * Values for all of the standalone instances of this clock - * generator found in STiH415 and STiH416 SYSCFG register banks. Note - * that the individual channel standby control bits (nsb) are in the - * first register along with the PLL control bits. - */ -static const struct clkgen_quadfs_data st_fs216c65_416 = { - /* 416 specific */ - .npda = CLKGEN_FIELD(0x0, 0x1, 14), - .nsb = { CLKGEN_FIELD(0x0, 0x1, 10), - CLKGEN_FIELD(0x0, 0x1, 11), - CLKGEN_FIELD(0x0, 0x1, 12), - CLKGEN_FIELD(0x0, 0x1, 13) }, - .nsdiv_present = true, - .nsdiv = { CLKGEN_FIELD(0x0, 0x1, 18), - CLKGEN_FIELD(0x0, 0x1, 19), - CLKGEN_FIELD(0x0, 0x1, 20), - CLKGEN_FIELD(0x0, 0x1, 21) }, - .mdiv = { CLKGEN_FIELD(0x4, 0x1f, 0), - CLKGEN_FIELD(0x14, 0x1f, 0), - CLKGEN_FIELD(0x24, 0x1f, 0), - CLKGEN_FIELD(0x34, 0x1f, 0) }, - .en = { CLKGEN_FIELD(0x10, 0x1, 0), - CLKGEN_FIELD(0x20, 0x1, 0), - CLKGEN_FIELD(0x30, 0x1, 0), - CLKGEN_FIELD(0x40, 0x1, 0) }, - .ndiv = CLKGEN_FIELD(0x0, 0x1, 15), - .bwfilter_present = true, - .ref_bw = CLKGEN_FIELD(0x0, 0x3, 16), - .pe = { CLKGEN_FIELD(0x8, 0xffff, 0), - CLKGEN_FIELD(0x18, 0xffff, 0), - CLKGEN_FIELD(0x28, 0xffff, 0), - CLKGEN_FIELD(0x38, 0xffff, 0) }, - .sdiv = { CLKGEN_FIELD(0xC, 0x7, 0), - CLKGEN_FIELD(0x1C, 0x7, 0), - CLKGEN_FIELD(0x2C, 0x7, 0), - CLKGEN_FIELD(0x3C, 0x7, 0) }, - .pll_ops = &st_quadfs_pll_c65_ops, - .rtbl = fs216c65_rtbl, - .rtbl_cnt = ARRAY_SIZE(fs216c65_rtbl), - .get_rate = clk_fs216c65_get_rate, -}; - -static const struct clkgen_quadfs_data st_fs432c65_416 = { - .npda = CLKGEN_FIELD(0x0, 0x1, 14), - .nsb = { CLKGEN_FIELD(0x0, 0x1, 10), - CLKGEN_FIELD(0x0, 0x1, 11), - CLKGEN_FIELD(0x0, 0x1, 12), - CLKGEN_FIELD(0x0, 0x1, 13) }, - .nsdiv_present = true, - .nsdiv = { CLKGEN_FIELD(0x0, 0x1, 18), - CLKGEN_FIELD(0x0, 0x1, 19), - CLKGEN_FIELD(0x0, 0x1, 20), - CLKGEN_FIELD(0x0, 0x1, 21) }, - .mdiv = { CLKGEN_FIELD(0x4, 0x1f, 0), - CLKGEN_FIELD(0x14, 0x1f, 0), - CLKGEN_FIELD(0x24, 0x1f, 0), - CLKGEN_FIELD(0x34, 0x1f, 0) }, - .en = { CLKGEN_FIELD(0x10, 0x1, 0), - CLKGEN_FIELD(0x20, 0x1, 0), - CLKGEN_FIELD(0x30, 0x1, 0), - CLKGEN_FIELD(0x40, 0x1, 0) }, - .ndiv = CLKGEN_FIELD(0x0, 0x1, 15), - .bwfilter_present = true, - .ref_bw = CLKGEN_FIELD(0x0, 0x3, 16), - .pe = { CLKGEN_FIELD(0x8, 0xffff, 0), - CLKGEN_FIELD(0x18, 0xffff, 0), - CLKGEN_FIELD(0x28, 0xffff, 0), - CLKGEN_FIELD(0x38, 0xffff, 0) }, - .sdiv = { CLKGEN_FIELD(0xC, 0x7, 0), - CLKGEN_FIELD(0x1C, 0x7, 0), - CLKGEN_FIELD(0x2C, 0x7, 0), - CLKGEN_FIELD(0x3C, 0x7, 0) }, - .pll_ops = &st_quadfs_pll_c65_ops, - .rtbl = fs432c65_rtbl, - .rtbl_cnt = ARRAY_SIZE(fs432c65_rtbl), - .get_rate = clk_fs432c65_get_rate, -}; - -static const struct clkgen_quadfs_data st_fs660c32_E_416 = { - .npda = CLKGEN_FIELD(0x0, 0x1, 14), - .nsb = { CLKGEN_FIELD(0x0, 0x1, 10), - CLKGEN_FIELD(0x0, 0x1, 11), - CLKGEN_FIELD(0x0, 0x1, 12), - CLKGEN_FIELD(0x0, 0x1, 13) }, - .nsdiv_present = true, - .nsdiv = { CLKGEN_FIELD(0x0, 0x1, 18), - CLKGEN_FIELD(0x0, 0x1, 19), - CLKGEN_FIELD(0x0, 0x1, 20), - CLKGEN_FIELD(0x0, 0x1, 21) }, - .mdiv = { CLKGEN_FIELD(0x4, 0x1f, 0), - CLKGEN_FIELD(0x14, 0x1f, 0), - CLKGEN_FIELD(0x24, 0x1f, 0), - CLKGEN_FIELD(0x34, 0x1f, 0) }, - .en = { CLKGEN_FIELD(0x10, 0x1, 0), - CLKGEN_FIELD(0x20, 0x1, 0), - CLKGEN_FIELD(0x30, 0x1, 0), - CLKGEN_FIELD(0x40, 0x1, 0) }, - .ndiv = CLKGEN_FIELD(0x0, 0x7, 15), - .pe = { CLKGEN_FIELD(0x8, 0x7fff, 0), - CLKGEN_FIELD(0x18, 0x7fff, 0), - CLKGEN_FIELD(0x28, 0x7fff, 0), - CLKGEN_FIELD(0x38, 0x7fff, 0) }, - .sdiv = { CLKGEN_FIELD(0xC, 0xf, 0), - CLKGEN_FIELD(0x1C, 0xf, 0), - CLKGEN_FIELD(0x2C, 0xf, 0), - CLKGEN_FIELD(0x3C, 0xf, 0) }, - .lockstatus_present = true, - .lock_status = CLKGEN_FIELD(0xAC, 0x1, 0), - .pll_ops = &st_quadfs_pll_c32_ops, - .rtbl = fs660c32_rtbl, - .rtbl_cnt = ARRAY_SIZE(fs660c32_rtbl), - .get_rate = clk_fs660c32_dig_get_rate, -}; - -static const struct clkgen_quadfs_data st_fs660c32_F_416 = { - .npda = CLKGEN_FIELD(0x0, 0x1, 14), - .nsb = { CLKGEN_FIELD(0x0, 0x1, 10), - CLKGEN_FIELD(0x0, 0x1, 11), - CLKGEN_FIELD(0x0, 0x1, 12), - CLKGEN_FIELD(0x0, 0x1, 13) }, - .nsdiv_present = true, - .nsdiv = { CLKGEN_FIELD(0x0, 0x1, 18), - CLKGEN_FIELD(0x0, 0x1, 19), - CLKGEN_FIELD(0x0, 0x1, 20), - CLKGEN_FIELD(0x0, 0x1, 21) }, - .mdiv = { CLKGEN_FIELD(0x4, 0x1f, 0), - CLKGEN_FIELD(0x14, 0x1f, 0), - CLKGEN_FIELD(0x24, 0x1f, 0), - CLKGEN_FIELD(0x34, 0x1f, 0) }, - .en = { CLKGEN_FIELD(0x10, 0x1, 0), - CLKGEN_FIELD(0x20, 0x1, 0), - CLKGEN_FIELD(0x30, 0x1, 0), - CLKGEN_FIELD(0x40, 0x1, 0) }, - .ndiv = CLKGEN_FIELD(0x0, 0x7, 15), - .pe = { CLKGEN_FIELD(0x8, 0x7fff, 0), - CLKGEN_FIELD(0x18, 0x7fff, 0), - CLKGEN_FIELD(0x28, 0x7fff, 0), - CLKGEN_FIELD(0x38, 0x7fff, 0) }, - .sdiv = { CLKGEN_FIELD(0xC, 0xf, 0), - CLKGEN_FIELD(0x1C, 0xf, 0), - CLKGEN_FIELD(0x2C, 0xf, 0), - CLKGEN_FIELD(0x3C, 0xf, 0) }, - .lockstatus_present = true, - .lock_status = CLKGEN_FIELD(0xEC, 0x1, 0), - .pll_ops = &st_quadfs_pll_c32_ops, - .rtbl = fs660c32_rtbl, - .rtbl_cnt = ARRAY_SIZE(fs660c32_rtbl), - .get_rate = clk_fs660c32_dig_get_rate, -}; static const struct clkgen_quadfs_data st_fs660c32_C = { .nrst_present = true, @@ -605,12 +409,6 @@ static int quadfs_pll_fs660c32_set_rate(struct clk_hw *hw, unsigned long rate, return 0; } -static const struct clk_ops st_quadfs_pll_c65_ops = { - .enable = quadfs_pll_enable, - .disable = quadfs_pll_disable, - .is_enabled = quadfs_pll_is_enabled, -}; - static const struct clk_ops st_quadfs_pll_c32_ops = { .enable = quadfs_pll_enable, .disable = quadfs_pll_disable, @@ -797,48 +595,6 @@ static int quadfs_fsynth_is_enabled(struct clk_hw *hw) return fs->data->standby_polarity ? !nsb : !!nsb; } -#define P15 (uint64_t)(1 << 15) - -static int clk_fs216c65_get_rate(unsigned long input, const struct stm_fs *fs, - unsigned long *rate) -{ - uint64_t res; - unsigned long ns; - unsigned long nd = 8; /* ndiv stuck at 0 => val = 8 */ - unsigned long s; - long m; - - m = fs->mdiv - 32; - s = 1 << (fs->sdiv + 1); - ns = (fs->nsdiv ? 1 : 3); - - res = (uint64_t)(s * ns * P15 * (uint64_t)(m + 33)); - res = res - (s * ns * fs->pe); - *rate = div64_u64(P15 * nd * input * 32, res); - - return 0; -} - -static int clk_fs432c65_get_rate(unsigned long input, const struct stm_fs *fs, - unsigned long *rate) -{ - uint64_t res; - unsigned long nd = 16; /* ndiv value; stuck at 0 (30Mhz input) */ - long m; - unsigned long sd; - unsigned long ns; - - m = fs->mdiv - 32; - sd = 1 << (fs->sdiv + 1); - ns = (fs->nsdiv ? 1 : 3); - - res = (uint64_t)(sd * ns * P15 * (uint64_t)(m + 33)); - res = res - (sd * ns * fs->pe); - *rate = div64_u64(P15 * nd * input * 32, res); - - return 0; -} - #define P20 (uint64_t)(1 << 20) static int clk_fs660c32_dig_get_rate(unsigned long input, @@ -1065,22 +821,6 @@ static struct clk * __init st_clk_register_quadfs_fsynth( static const struct of_device_id quadfs_of_match[] = { { - .compatible = "st,stih416-quadfs216", - .data = &st_fs216c65_416 - }, - { - .compatible = "st,stih416-quadfs432", - .data = &st_fs432c65_416 - }, - { - .compatible = "st,stih416-quadfs660-E", - .data = &st_fs660c32_E_416 - }, - { - .compatible = "st,stih416-quadfs660-F", - .data = &st_fs660c32_F_416 - }, - { .compatible = "st,stih407-quadfs660-C", .data = &st_fs660c32_C }, diff --git a/drivers/clk/st/clkgen-mux.c b/drivers/clk/st/clkgen-mux.c index b1e10ffe7a44..6fdb1abcd4c8 100644 --- a/drivers/clk/st/clkgen-mux.c +++ b/drivers/clk/st/clkgen-mux.c @@ -19,9 +19,6 @@ #include <linux/clk-provider.h> #include "clkgen.h" -static DEFINE_SPINLOCK(clkgena_divmux_lock); -static DEFINE_SPINLOCK(clkgenf_lock); - static const char ** __init clkgen_mux_get_parents(struct device_node *np, int *num_parents) { @@ -40,498 +37,6 @@ static const char ** __init clkgen_mux_get_parents(struct device_node *np, return parents; } -/** - * DOC: Clock mux with a programmable divider on each of its three inputs. - * The mux has an input setting which effectively gates its output. - * - * Traits of this clock: - * prepare - clk_(un)prepare only ensures parent is (un)prepared - * enable - clk_enable and clk_disable are functional & control gating - * rate - set rate is supported - * parent - set/get parent - */ - -#define NUM_INPUTS 3 - -struct clkgena_divmux { - struct clk_hw hw; - /* Subclassed mux and divider structures */ - struct clk_mux mux; - struct clk_divider div[NUM_INPUTS]; - /* Enable/running feedback register bits for each input */ - void __iomem *feedback_reg[NUM_INPUTS]; - int feedback_bit_idx; - - u8 muxsel; -}; - -#define to_clkgena_divmux(_hw) container_of(_hw, struct clkgena_divmux, hw) - -struct clkgena_divmux_data { - int num_outputs; - int mux_offset; - int mux_offset2; - int mux_start_bit; - int div_offsets[NUM_INPUTS]; - int fb_offsets[NUM_INPUTS]; - int fb_start_bit_idx; -}; - -#define CKGAX_CLKOPSRC_SWITCH_OFF 0x3 - -static int clkgena_divmux_is_running(struct clkgena_divmux *mux) -{ - u32 regval = readl(mux->feedback_reg[mux->muxsel]); - u32 running = regval & BIT(mux->feedback_bit_idx); - return !!running; -} - -static int clkgena_divmux_enable(struct clk_hw *hw) -{ - struct clkgena_divmux *genamux = to_clkgena_divmux(hw); - struct clk_hw *mux_hw = &genamux->mux.hw; - unsigned long timeout; - int ret = 0; - - __clk_hw_set_clk(mux_hw, hw); - - ret = clk_mux_ops.set_parent(mux_hw, genamux->muxsel); - if (ret) - return ret; - - timeout = jiffies + msecs_to_jiffies(10); - - while (!clkgena_divmux_is_running(genamux)) { - if (time_after(jiffies, timeout)) - return -ETIMEDOUT; - cpu_relax(); - } - - return 0; -} - -static void clkgena_divmux_disable(struct clk_hw *hw) -{ - struct clkgena_divmux *genamux = to_clkgena_divmux(hw); - struct clk_hw *mux_hw = &genamux->mux.hw; - - __clk_hw_set_clk(mux_hw, hw); - - clk_mux_ops.set_parent(mux_hw, CKGAX_CLKOPSRC_SWITCH_OFF); -} - -static int clkgena_divmux_is_enabled(struct clk_hw *hw) -{ - struct clkgena_divmux *genamux = to_clkgena_divmux(hw); - struct clk_hw *mux_hw = &genamux->mux.hw; - - __clk_hw_set_clk(mux_hw, hw); - - return (s8)clk_mux_ops.get_parent(mux_hw) > 0; -} - -static u8 clkgena_divmux_get_parent(struct clk_hw *hw) -{ - struct clkgena_divmux *genamux = to_clkgena_divmux(hw); - struct clk_hw *mux_hw = &genamux->mux.hw; - - __clk_hw_set_clk(mux_hw, hw); - - genamux->muxsel = clk_mux_ops.get_parent(mux_hw); - if ((s8)genamux->muxsel < 0) { - pr_debug("%s: %s: Invalid parent, setting to default.\n", - __func__, clk_hw_get_name(hw)); - genamux->muxsel = 0; - } - - return genamux->muxsel; -} - -static int clkgena_divmux_set_parent(struct clk_hw *hw, u8 index) -{ - struct clkgena_divmux *genamux = to_clkgena_divmux(hw); - - if (index >= CKGAX_CLKOPSRC_SWITCH_OFF) - return -EINVAL; - - genamux->muxsel = index; - - /* - * If the mux is already enabled, call enable directly to set the - * new mux position and wait for it to start running again. Otherwise - * do nothing. - */ - if (clkgena_divmux_is_enabled(hw)) - clkgena_divmux_enable(hw); - - return 0; -} - -static unsigned long clkgena_divmux_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) -{ - struct clkgena_divmux *genamux = to_clkgena_divmux(hw); - struct clk_hw *div_hw = &genamux->div[genamux->muxsel].hw; - - __clk_hw_set_clk(div_hw, hw); - - return clk_divider_ops.recalc_rate(div_hw, parent_rate); -} - -static int clkgena_divmux_set_rate(struct clk_hw *hw, unsigned long rate, - unsigned long parent_rate) -{ - struct clkgena_divmux *genamux = to_clkgena_divmux(hw); - struct clk_hw *div_hw = &genamux->div[genamux->muxsel].hw; - - __clk_hw_set_clk(div_hw, hw); - - return clk_divider_ops.set_rate(div_hw, rate, parent_rate); -} - -static long clkgena_divmux_round_rate(struct clk_hw *hw, unsigned long rate, - unsigned long *prate) -{ - struct clkgena_divmux *genamux = to_clkgena_divmux(hw); - struct clk_hw *div_hw = &genamux->div[genamux->muxsel].hw; - - __clk_hw_set_clk(div_hw, hw); - - return clk_divider_ops.round_rate(div_hw, rate, prate); -} - -static const struct clk_ops clkgena_divmux_ops = { - .enable = clkgena_divmux_enable, - .disable = clkgena_divmux_disable, - .is_enabled = clkgena_divmux_is_enabled, - .get_parent = clkgena_divmux_get_parent, - .set_parent = clkgena_divmux_set_parent, - .round_rate = clkgena_divmux_round_rate, - .recalc_rate = clkgena_divmux_recalc_rate, - .set_rate = clkgena_divmux_set_rate, -}; - -/** - * clk_register_genamux - register a genamux clock with the clock framework - */ -static struct clk * __init clk_register_genamux(const char *name, - const char **parent_names, u8 num_parents, - void __iomem *reg, - const struct clkgena_divmux_data *muxdata, - u32 idx) -{ - /* - * Fixed constants across all ClockgenA variants - */ - const int mux_width = 2; - const int divider_width = 5; - struct clkgena_divmux *genamux; - struct clk *clk; - struct clk_init_data init; - int i; - - genamux = kzalloc(sizeof(*genamux), GFP_KERNEL); - if (!genamux) - return ERR_PTR(-ENOMEM); - - init.name = name; - init.ops = &clkgena_divmux_ops; - init.flags = CLK_IS_BASIC | CLK_GET_RATE_NOCACHE; - init.parent_names = parent_names; - init.num_parents = num_parents; - - genamux->mux.lock = &clkgena_divmux_lock; - genamux->mux.mask = BIT(mux_width) - 1; - genamux->mux.shift = muxdata->mux_start_bit + (idx * mux_width); - if (genamux->mux.shift > 31) { - /* - * We have spilled into the second mux register so - * adjust the register address and the bit shift accordingly - */ - genamux->mux.reg = reg + muxdata->mux_offset2; - genamux->mux.shift -= 32; - } else { - genamux->mux.reg = reg + muxdata->mux_offset; - } - - for (i = 0; i < NUM_INPUTS; i++) { - /* - * Divider config for each input - */ - void __iomem *divbase = reg + muxdata->div_offsets[i]; - genamux->div[i].width = divider_width; - genamux->div[i].reg = divbase + (idx * sizeof(u32)); - - /* - * Mux enabled/running feedback register for each input. - */ - genamux->feedback_reg[i] = reg + muxdata->fb_offsets[i]; - } - - genamux->feedback_bit_idx = muxdata->fb_start_bit_idx + idx; - genamux->hw.init = &init; - - clk = clk_register(NULL, &genamux->hw); - if (IS_ERR(clk)) { - kfree(genamux); - goto err; - } - - pr_debug("%s: parent %s rate %lu\n", - __clk_get_name(clk), - __clk_get_name(clk_get_parent(clk)), - clk_get_rate(clk)); -err: - return clk; -} - -static struct clkgena_divmux_data st_divmux_c65hs = { - .num_outputs = 4, - .mux_offset = 0x14, - .mux_start_bit = 0, - .div_offsets = { 0x800, 0x900, 0xb00 }, - .fb_offsets = { 0x18, 0x1c, 0x20 }, - .fb_start_bit_idx = 0, -}; - -static struct clkgena_divmux_data st_divmux_c65ls = { - .num_outputs = 14, - .mux_offset = 0x14, - .mux_offset2 = 0x24, - .mux_start_bit = 8, - .div_offsets = { 0x810, 0xa10, 0xb10 }, - .fb_offsets = { 0x18, 0x1c, 0x20 }, - .fb_start_bit_idx = 4, -}; - -static struct clkgena_divmux_data st_divmux_c32odf0 = { - .num_outputs = 8, - .mux_offset = 0x1c, - .mux_start_bit = 0, - .div_offsets = { 0x800, 0x900, 0xa60 }, - .fb_offsets = { 0x2c, 0x24, 0x28 }, - .fb_start_bit_idx = 0, -}; - -static struct clkgena_divmux_data st_divmux_c32odf1 = { - .num_outputs = 8, - .mux_offset = 0x1c, |
