Merge branches 'clk-phase-errors', 'clk-amlogic', 'clk-renesas' and 'clk-allwinner' into clk-next
- Don't show clk phase when it is invalid
* clk-phase-errors:
clk: rockchip: fix mmc get phase
clk: Fix phase init check
clk: Bail out when calculating phase fails during clk registration
clk: Move rate and accuracy recalc to mostly consumer APIs
clk: Use 'parent' to shorten lines in __clk_core_init()
clk: Don't cache errors from clk_ops::get_phase()
* clk-amlogic:
clk: meson: meson8b: set audio output clock hierarchy
clk: meson: g12a: add support for the SPICC SCLK Source clocks
dt-bindings: clk: g12a-clkc: add SPICC SCLK Source clock IDs
clk: meson: gxbb: set audio output clock hierarchy
clk: meson: gxbb: add the gxl internal dac gate
dt-bindings: clk: meson: add the gxl internal dac gate
* clk-renesas:
dt-bindings: clock: renesas: cpg-mssr: Convert to json-schema
clk: renesas: rcar-usb2-clock-sel: Add reset_control
clk: renesas: rcar-usb2-clock-sel: Add multiple clocks management
dt-bindings: clock: renesas: rcar-usb2-clock-sel: Add power-domains and resets properties
dt-bindings: clock: renesas: rcar-usb2-clock-sel: Fix clock[-name]s properties
clk: renesas: Remove use of ARCH_R8A7795
clk: renesas: r8a77965: Add RPC clocks
clk: renesas: r8a7796: Add RPC clocks
clk: renesas: r8a7795: Add RPC clocks
clk: renesas: rcar-gen3: Add CCREE clocks
* clk-allwinner:
clk: sunxi-ng: sun8i-de2: Sort structures
clk: sunxi-ng: sun8i-de2: Add R40 specific quirks
clk: sunxi-ng: sun8i-de2: Add rotation core clocks and reset for A83T
clk: sunxi-ng: sun8i-de2: Don't reuse A83T resets
clk: sunxi-ng: sun8i-de2: H6 doesn't have rotate core
clk: sunxi-ng: sun8i-de2: Add rotation core clocks and reset for A64
clk: sunxi-ng: sun8i-de2: Split out H5 definitions
clk: sunxi-ng: a64: Export MBUS clock
diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt
deleted file mode 100644
index f4d153f..0000000
--- a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.txt
+++ /dev/null
@@ -1,100 +0,0 @@
-* Renesas Clock Pulse Generator / Module Standby and Software Reset
-
-On Renesas ARM SoCs (SH/R-Mobile, R-Car, RZ), the CPG (Clock Pulse Generator)
-and MSSR (Module Standby and Software Reset) blocks are intimately connected,
-and share the same register block.
-
-They provide the following functionalities:
- - The CPG block generates various core clocks,
- - The MSSR block provides two functions:
- 1. Module Standby, providing a Clock Domain to control the clock supply
- to individual SoC devices,
- 2. Reset Control, to perform a software reset of individual SoC devices.
-
-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,r8a7744-cpg-mssr" for the r8a7744 SoC (RZ/G1N)
- - "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,r8a774b1-cpg-mssr" for the r8a774b1 SoC (RZ/G2N)
- - "renesas,r8a774c0-cpg-mssr" for the r8a774c0 SoC (RZ/G2E)
- - "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)
- - "renesas,r8a7793-cpg-mssr" for the r8a7793 SoC (R-Car M2-N)
- - "renesas,r8a7794-cpg-mssr" for the r8a7794 SoC (R-Car E2)
- - "renesas,r8a7795-cpg-mssr" for the r8a7795 SoC (R-Car H3)
- - "renesas,r8a7796-cpg-mssr" for the r8a77960 SoC (R-Car M3-W)
- - "renesas,r8a77961-cpg-mssr" for the r8a77961 SoC (R-Car M3-W+)
- - "renesas,r8a77965-cpg-mssr" for the r8a77965 SoC (R-Car M3-N)
- - "renesas,r8a77970-cpg-mssr" for the r8a77970 SoC (R-Car V3M)
- - "renesas,r8a77980-cpg-mssr" for the r8a77980 SoC (R-Car V3H)
- - "renesas,r8a77990-cpg-mssr" for the r8a77990 SoC (R-Car E3)
- - "renesas,r8a77995-cpg-mssr" for the r8a77995 SoC (R-Car D3)
-
- - reg: Base address and length of the memory resource used by the CPG/MSSR
- block
-
- - 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" (r7s9210, r8a7743, r8a7744, r8a7745, r8a77470, r8a774a1,
- r8a774b1, r8a774c0, r8a7790, r8a7791, r8a7792, r8a7793,
- r8a7794, r8a7795, r8a77960, r8a77961, r8a77965, r8a77970,
- r8a77980, r8a77990, r8a77995)
- - "extalr" (r8a774a1, r8a774b1, r8a7795, r8a77960, r8a77961, r8a77965,
- r8a77970, r8a77980)
- - "usb_extal" (r8a7743, r8a7744, r8a7745, r8a77470, r8a7790, r8a7791,
- r8a7793, r8a7794)
-
- - #clock-cells: Must be 2
- - For CPG core clocks, the two clock specifier cells must be "CPG_CORE"
- and a core clock reference, as defined in
- <dt-bindings/clock/*-cpg-mssr.h>.
- - For module clocks, the two clock specifier cells must be "CPG_MOD" and
- a module number, as defined in the datasheet.
-
- - #power-domain-cells: Must be 0
- - SoC devices that are part of the CPG/MSSR Clock Domain and can be
- power-managed through Module Standby should refer to the CPG device
- node in their "power-domains" property, as documented by the generic PM
- Domain bindings in
- Documentation/devicetree/bindings/power/power-domain.yaml.
-
- - #reset-cells: Must be 1
- - The single reset specifier cell must be the module number, as defined
- in the datasheet.
-
-
-Examples
---------
-
- - CPG device node:
-
- cpg: clock-controller@e6150000 {
- compatible = "renesas,r8a7795-cpg-mssr";
- reg = <0 0xe6150000 0 0x1000>;
- clocks = <&extal_clk>, <&extalr_clk>;
- clock-names = "extal", "extalr";
- #clock-cells = <2>;
- #power-domain-cells = <0>;
- #reset-cells = <1>;
- };
-
-
- - CPG/MSSR Clock Domain member device node:
-
- scif2: serial@e6e88000 {
- compatible = "renesas,scif-r8a7795", "renesas,scif";
- reg = <0 0xe6e88000 0 64>;
- interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>;
- clocks = <&cpg CPG_MOD 310>;
- clock-names = "fck";
- dmas = <&dmac1 0x13>, <&dmac1 0x12>;
- dma-names = "tx", "rx";
- power-domains = <&cpg>;
- resets = <&cpg 310>;
- };
diff --git a/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.yaml b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.yaml
new file mode 100644
index 0000000..9cd102e
--- /dev/null
+++ b/Documentation/devicetree/bindings/clock/renesas,cpg-mssr.yaml
@@ -0,0 +1,119 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: "http://devicetree.org/schemas/clock/renesas,cpg-mssr.yaml#"
+$schema: "http://devicetree.org/meta-schemas/core.yaml#"
+
+title: Renesas Clock Pulse Generator / Module Standby and Software Reset
+
+maintainers:
+ - Geert Uytterhoeven <geert+renesas@glider.be>
+
+description: |
+ On Renesas ARM SoCs (SH/R-Mobile, R-Car, RZ), the CPG (Clock Pulse Generator)
+ and MSSR (Module Standby and Software Reset) blocks are intimately connected,
+ and share the same register block.
+
+ They provide the following functionalities:
+ - The CPG block generates various core clocks,
+ - The MSSR block provides two functions:
+ 1. Module Standby, providing a Clock Domain to control the clock supply
+ to individual SoC devices,
+ 2. Reset Control, to perform a software reset of individual SoC devices.
+
+properties:
+ compatible:
+ enum:
+ - renesas,r7s9210-cpg-mssr # RZ/A2
+ - renesas,r8a7743-cpg-mssr # RZ/G1M
+ - renesas,r8a7744-cpg-mssr # RZ/G1N
+ - renesas,r8a7745-cpg-mssr # RZ/G1E
+ - renesas,r8a77470-cpg-mssr # RZ/G1C
+ - renesas,r8a774a1-cpg-mssr # RZ/G2M
+ - renesas,r8a774b1-cpg-mssr # RZ/G2N
+ - renesas,r8a774c0-cpg-mssr # RZ/G2E
+ - renesas,r8a7790-cpg-mssr # R-Car H2
+ - renesas,r8a7791-cpg-mssr # R-Car M2-W
+ - renesas,r8a7792-cpg-mssr # R-Car V2H
+ - renesas,r8a7793-cpg-mssr # R-Car M2-N
+ - renesas,r8a7794-cpg-mssr # R-Car E2
+ - renesas,r8a7795-cpg-mssr # R-Car H3
+ - renesas,r8a7796-cpg-mssr # R-Car M3-W
+ - renesas,r8a77961-cpg-mssr # R-Car M3-W+
+ - renesas,r8a77965-cpg-mssr # R-Car M3-N
+ - renesas,r8a77970-cpg-mssr # R-Car V3M
+ - renesas,r8a77980-cpg-mssr # R-Car V3H
+ - renesas,r8a77990-cpg-mssr # R-Car E3
+ - renesas,r8a77995-cpg-mssr # R-Car D3
+
+ reg:
+ maxItems: 1
+
+ clocks:
+ minItems: 1
+ maxItems: 2
+
+ clock-names:
+ minItems: 1
+ maxItems: 2
+ items:
+ enum:
+ - extal # All
+ - extalr # Most R-Car Gen3 and RZ/G2
+ - usb_extal # Most R-Car Gen2 and RZ/G1
+
+ '#clock-cells':
+ description: |
+ - For CPG core clocks, the two clock specifier cells must be "CPG_CORE"
+ and a core clock reference, as defined in
+ <dt-bindings/clock/*-cpg-mssr.h>
+ - For module clocks, the two clock specifier cells must be "CPG_MOD" and
+ a module number, as defined in the datasheet.
+ const: 2
+
+ '#power-domain-cells':
+ description:
+ SoC devices that are part of the CPG/MSSR Clock Domain and can be
+ power-managed through Module Standby should refer to the CPG device node
+ in their "power-domains" property, as documented by the generic PM Domain
+ bindings in Documentation/devicetree/bindings/power/power-domain.yaml.
+ const: 0
+
+ '#reset-cells':
+ description:
+ The single reset specifier cell must be the module number, as defined in
+ the datasheet.
+ const: 1
+
+if:
+ not:
+ properties:
+ compatible:
+ items:
+ enum:
+ - renesas,r7s9210-cpg-mssr
+then:
+ required:
+ - '#reset-cells'
+
+required:
+ - compatible
+ - reg
+ - clocks
+ - clock-names
+ - '#clock-cells'
+ - '#power-domain-cells'
+
+additionalProperties: false
+
+examples:
+ - |
+ cpg: clock-controller@e6150000 {
+ compatible = "renesas,r8a7795-cpg-mssr";
+ reg = <0xe6150000 0x1000>;
+ clocks = <&extal_clk>, <&extalr_clk>;
+ clock-names = "extal", "extalr";
+ #clock-cells = <2>;
+ #power-domain-cells = <0>;
+ #reset-cells = <1>;
+ };
diff --git a/Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt b/Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt
index 83f6c6a..4bf6f53 100644
--- a/Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt
+++ b/Documentation/devicetree/bindings/clock/renesas,rcar-usb2-clock-sel.txt
@@ -38,10 +38,17 @@
- reg: offset and length of the USB 2.0 clock selector register block.
- clocks: A list of phandles and specifier pairs.
- clock-names: Name of the clocks.
- - The functional clock must be "ehci_ohci"
+ - The functional clock of USB 2.0 host side must be "ehci_ohci"
+ - The functional clock of HS-USB side must be "hs-usb-if"
- The USB_EXTAL clock pin must be "usb_extal"
- The USB_XTAL clock pin must be "usb_xtal"
- #clock-cells: Must be 0
+- power-domains: A phandle and symbolic PM domain specifier.
+ See power/renesas,rcar-sysc.yaml.
+- resets: A list of phandles and specifier pairs.
+- reset-names: Name of the resets.
+ - The reset of USB 2.0 host side must be "ehci_ohci"
+ - The reset of HS-USB side must be "hs-usb-if"
Example (R-Car H3):
@@ -49,7 +56,11 @@
compatible = "renesas,r8a7795-rcar-usb2-clock-sel",
"renesas,rcar-gen3-usb2-clock-sel";
reg = <0 0xe6590630 0 0x02>;
- clocks = <&cpg CPG_MOD 703>, <&usb_extal>, <&usb_xtal>;
- clock-names = "ehci_ohci", "usb_extal", "usb_xtal";
+ clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>,
+ <&usb_extal>, <&usb_xtal>;
+ clock-names = "ehci_ohci", "hs-usb-if", "usb_extal", "usb_xtal";
#clock-cells = <0>;
+ power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
+ resets = <&cpg 703>, <&cpg 704>;
+ reset-names = "ehci_ohci", "hs-usb-if";
};
diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c
index 6e780c2..3c228b0 100644
--- a/drivers/clk/clk-si5341.c
+++ b/drivers/clk/clk-si5341.c
@@ -16,6 +16,8 @@
#include <linux/slab.h>
#include <asm/unaligned.h>
+#define SI5341_NUM_INPUTS 4
+
#define SI5341_MAX_NUM_OUTPUTS 10
#define SI5340_MAX_NUM_OUTPUTS 4
@@ -56,8 +58,8 @@
struct i2c_client *i2c_client;
struct clk_si5341_synth synth[SI5341_NUM_SYNTH];
struct clk_si5341_output clk[SI5341_MAX_NUM_OUTPUTS];
- struct clk *pxtal;
- const char *pxtal_name;
+ struct clk *input_clk[SI5341_NUM_INPUTS];
+ const char *input_clk_name[SI5341_NUM_INPUTS];
const u16 *reg_output_offset;
const u16 *reg_rdiv_offset;
u64 freq_vco; /* 13500–14256 MHz */
@@ -78,10 +80,25 @@
#define SI5341_DEVICE_REV 0x0005
#define SI5341_STATUS 0x000C
#define SI5341_SOFT_RST 0x001C
+#define SI5341_IN_SEL 0x0021
+#define SI5341_XAXB_CFG 0x090E
+#define SI5341_IN_EN 0x0949
+#define SI5341_INX_TO_PFD_EN 0x094A
+
+/* Input selection */
+#define SI5341_IN_SEL_MASK 0x06
+#define SI5341_IN_SEL_SHIFT 1
+#define SI5341_IN_SEL_REGCTRL 0x01
+#define SI5341_INX_TO_PFD_SHIFT 4
+
+/* XTAL config bits */
+#define SI5341_XAXB_CFG_EXTCLK_EN BIT(0)
+#define SI5341_XAXB_CFG_PDNB BIT(1)
/* Input dividers (48-bit) */
#define SI5341_IN_PDIV(x) (0x0208 + ((x) * 10))
#define SI5341_IN_PSET(x) (0x020E + ((x) * 10))
+#define SI5341_PX_UPD 0x0230
/* PLL configuration */
#define SI5341_PLL_M_NUM 0x0235
@@ -120,6 +137,10 @@
u8 value;
};
+static const char * const si5341_input_clock_names[] = {
+ "in0", "in1", "in2", "xtal"
+};
+
/* Output configuration registers 0..9 are not quite logically organized */
static const u16 si5341_reg_output_offset[] = {
0x0108,
@@ -390,7 +411,112 @@
return (unsigned long)res;
}
+static int si5341_clk_get_selected_input(struct clk_si5341 *data)
+{
+ int err;
+ u32 val;
+
+ err = regmap_read(data->regmap, SI5341_IN_SEL, &val);
+ if (err < 0)
+ return err;
+
+ return (val & SI5341_IN_SEL_MASK) >> SI5341_IN_SEL_SHIFT;
+}
+
+static u8 si5341_clk_get_parent(struct clk_hw *hw)
+{
+ struct clk_si5341 *data = to_clk_si5341(hw);
+ int res = si5341_clk_get_selected_input(data);
+
+ if (res < 0)
+ return 0; /* Apparently we cannot report errors */
+
+ return res;
+}
+
+static int si5341_clk_reparent(struct clk_si5341 *data, u8 index)
+{
+ int err;
+ u8 val;
+
+ val = (index << SI5341_IN_SEL_SHIFT) & SI5341_IN_SEL_MASK;
+ /* Enable register-based input selection */
+ val |= SI5341_IN_SEL_REGCTRL;
+
+ err = regmap_update_bits(data->regmap,
+ SI5341_IN_SEL, SI5341_IN_SEL_REGCTRL | SI5341_IN_SEL_MASK, val);
+ if (err < 0)
+ return err;
+
+ if (index < 3) {
+ /* Enable input buffer for selected input */
+ err = regmap_update_bits(data->regmap,
+ SI5341_IN_EN, 0x07, BIT(index));
+ if (err < 0)
+ return err;
+
+ /* Enables the input to phase detector */
+ err = regmap_update_bits(data->regmap, SI5341_INX_TO_PFD_EN,
+ 0x7 << SI5341_INX_TO_PFD_SHIFT,
+ BIT(index + SI5341_INX_TO_PFD_SHIFT));
+ if (err < 0)
+ return err;
+
+ /* Power down XTAL oscillator and buffer */
+ err = regmap_update_bits(data->regmap, SI5341_XAXB_CFG,
+ SI5341_XAXB_CFG_PDNB, 0);
+ if (err < 0)
+ return err;
+
+ /*
+ * Set the P divider to "1". There's no explanation in the
+ * datasheet of these registers, but the clockbuilder software
+ * programs a "1" when the input is being used.
+ */
+ err = regmap_write(data->regmap, SI5341_IN_PDIV(index), 1);
+ if (err < 0)
+ return err;
+
+ err = regmap_write(data->regmap, SI5341_IN_PSET(index), 1);
+ if (err < 0)
+ return err;
+
+ /* Set update PDIV bit */
+ err = regmap_write(data->regmap, SI5341_PX_UPD, BIT(index));
+ if (err < 0)
+ return err;
+ } else {
+ /* Disable all input buffers */
+ err = regmap_update_bits(data->regmap, SI5341_IN_EN, 0x07, 0);
+ if (err < 0)
+ return err;
+
+ /* Disable input to phase detector */
+ err = regmap_update_bits(data->regmap, SI5341_INX_TO_PFD_EN,
+ 0x7 << SI5341_INX_TO_PFD_SHIFT, 0);
+ if (err < 0)
+ return err;
+
+ /* Power up XTAL oscillator and buffer */
+ err = regmap_update_bits(data->regmap, SI5341_XAXB_CFG,
+ SI5341_XAXB_CFG_PDNB, SI5341_XAXB_CFG_PDNB);
+ if (err < 0)
+ return err;
+ }
+
+ return 0;
+}
+
+static int si5341_clk_set_parent(struct clk_hw *hw, u8 index)
+{
+ struct clk_si5341 *data = to_clk_si5341(hw);
+
+ return si5341_clk_reparent(data, index);
+}
+
static const struct clk_ops si5341_clk_ops = {
+ .set_parent = si5341_clk_set_parent,
+ .get_parent = si5341_clk_get_parent,
.recalc_rate = si5341_clk_recalc_rate,
};
@@ -985,7 +1111,8 @@
regmap_reg_range(0x000C, 0x0012), /* Status */
regmap_reg_range(0x001C, 0x001E), /* reset, finc/fdec */
regmap_reg_range(0x00E2, 0x00FE), /* NVM, interrupts, device ready */
- /* Update bits for synth config */
+ /* Update bits for P divider and synth config */
+ regmap_reg_range(SI5341_PX_UPD, SI5341_PX_UPD),
regmap_reg_range(SI5341_SYNTH_N_UPD(0), SI5341_SYNTH_N_UPD(0)),
regmap_reg_range(SI5341_SYNTH_N_UPD(1), SI5341_SYNTH_N_UPD(1)),
regmap_reg_range(SI5341_SYNTH_N_UPD(2), SI5341_SYNTH_N_UPD(2)),
@@ -1122,6 +1249,7 @@
struct device_node *np = data->i2c_client->dev.of_node;
u32 m_num = 0;
u32 m_den = 0;
+ int sel;
if (of_property_read_u32(np, "silabs,pll-m-num", &m_num)) {
dev_err(&data->i2c_client->dev,
@@ -1135,7 +1263,11 @@
if (!m_num || !m_den) {
dev_err(&data->i2c_client->dev,
"PLL configuration invalid, assume 14GHz\n");
- m_den = clk_get_rate(data->pxtal) / 10;
+ sel = si5341_clk_get_selected_input(data);
+ if (sel < 0)
+ return sel;
+
+ m_den = clk_get_rate(data->input_clk[sel]) / 10;
m_num = 1400000000;
}
@@ -1143,11 +1275,52 @@
SI5341_PLL_M_NUM, m_num, m_den);
}
+static int si5341_clk_select_active_input(struct clk_si5341 *data)
+{
+ int res;
+ int err;
+ int i;
+
+ res = si5341_clk_get_selected_input(data);
+ if (res < 0)
+ return res;
+
+ /* If the current register setting is invalid, pick the first input */
+ if (!data->input_clk[res]) {
+ dev_dbg(&data->i2c_client->dev,
+ "Input %d not connected, rerouting\n", res);
+ res = -ENODEV;
+ for (i = 0; i < SI5341_NUM_INPUTS; ++i) {
+ if (data->input_clk[i]) {
+ res = i;
+ break;
+ }
+ }
+ if (res < 0) {
+ dev_err(&data->i2c_client->dev,
+ "No clock input available\n");
+ return res;
+ }
+ }
+
+ /* Make sure the selected clock is also enabled and routed */
+ err = si5341_clk_reparent(data, res);
+ if (err < 0)
+ return err;
+
+ err = clk_prepare_enable(data->input_clk[res]);
+ if (err < 0)
+ return err;
+
+ return res;
+}
+
static int si5341_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct clk_si5341 *data;
struct clk_init_data init;
+ struct clk *input;
const char *root_clock_name;
const char *synth_clock_names[SI5341_NUM_SYNTH];
int err;
@@ -1161,12 +1334,16 @@
data->i2c_client = client;
- data->pxtal = devm_clk_get(&client->dev, "xtal");
- if (IS_ERR(data->pxtal)) {
- if (PTR_ERR(data->pxtal) == -EPROBE_DEFER)
- return -EPROBE_DEFER;
-
- dev_err(&client->dev, "Missing xtal clock input\n");
+ for (i = 0; i < SI5341_NUM_INPUTS; ++i) {
+ input = devm_clk_get(&client->dev, si5341_input_clock_names[i]);
+ if (IS_ERR(input)) {
+ if (PTR_ERR(input) == -EPROBE_DEFER)
+ return -EPROBE_DEFER;
+ data->input_clk_name[i] = si5341_input_clock_names[i];
+ } else {
+ data->input_clk[i] = input;
+ data->input_clk_name[i] = __clk_get_name(input);
+ }
}
err = si5341_dt_parse_dt(client, config);
@@ -1188,9 +1365,6 @@
if (err < 0)
return err;
- /* "Activate" the xtal (usually a fixed clock) */
- clk_prepare_enable(data->pxtal);
-
if (of_property_read_bool(client->dev.of_node, "silabs,reprogram")) {
initialization_required = true;
} else {
@@ -1223,7 +1397,14 @@
ARRAY_SIZE(si5341_reg_defaults));
if (err < 0)
return err;
+ }
+ /* Input must be up and running at this point */
+ err = si5341_clk_select_active_input(data);
+ if (err < 0)
+ return err;
+
+ if (initialization_required) {
/* PLL configuration is required */
err = si5341_initialize_pll(data);
if (err < 0)
@@ -1231,9 +1412,8 @@
}
/* Register the PLL */
- data->pxtal_name = __clk_get_name(data->pxtal);
- init.parent_names = &data->pxtal_name;
- init.num_parents = 1; /* For now, only XTAL input supported */
+ init.parent_names = data->input_clk_name;
+ init.num_parents = SI5341_NUM_INPUTS;
init.ops = &si5341_clk_ops;
init.flags = 0;
data->hw.init = &init;
diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index f0f2b59..766c3e5 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -488,7 +488,7 @@
}
EXPORT_SYMBOL_GPL(clk_hw_get_rate);
-static unsigned long __clk_get_accuracy(struct clk_core *core)
+static unsigned long clk_core_get_accuracy_no_lock(struct clk_core *core)
{
if (!core)
return 0;
@@ -1517,18 +1517,12 @@
__clk_recalc_accuracies(child);
}
-static long clk_core_get_accuracy(struct clk_core *core)
+static long clk_core_get_accuracy_recalc(struct clk_core *core)
{
- unsigned long accuracy;
-
- clk_prepare_lock();
if (core && (core->flags & CLK_GET_ACCURACY_NOCACHE))
__clk_recalc_accuracies(core);
- accuracy = __clk_get_accuracy(core);
- clk_prepare_unlock();
-
- return accuracy;
+ return clk_core_get_accuracy_no_lock(core);
}
/**
@@ -1542,10 +1536,16 @@
*/
long clk_get_accuracy(struct clk *clk)
{
+ long accuracy;
+
if (!clk)
return 0;
- return clk_core_get_accuracy(clk->core);
+ clk_prepare_lock();
+ accuracy = clk_core_get_accuracy_recalc(clk->core);
+ clk_prepare_unlock();
+
+ return accuracy;
}
EXPORT_SYMBOL_GPL(clk_get_accuracy);
@@ -1599,19 +1599,12 @@
__clk_recalc_rates(child, msg);
}
-static unsigned long clk_core_get_rate(struct clk_core *core)
+static unsigned long clk_core_get_rate_recalc(struct clk_core *core)
{
- unsigned long rate;
-
- clk_prepare_lock();
-
if (core && (core->flags & CLK_GET_RATE_NOCACHE))
__clk_recalc_rates(core, 0);
- rate = clk_core_get_rate_nolock(core);
- clk_prepare_unlock();
-
- return rate;
+ return clk_core_get_rate_nolock(core);
}
/**
@@ -1624,10 +1617,16 @@
*/
unsigned long clk_get_rate(struct clk *clk)
{
+ unsigned long rate;
+
if (!clk)
return 0;
- return clk_core_get_rate(clk->core);
+ clk_prepare_lock();
+ rate = clk_core_get_rate_recalc(clk->core);
+ clk_prepare_unlock();
+
+ return rate;
}
EXPORT_SYMBOL_GPL(clk_get_rate);
@@ -2660,12 +2659,14 @@
{
int ret;
- clk_prepare_lock();
+ lockdep_assert_held(&prepare_lock);
+ if (!core->ops->get_phase)
+ return 0;
+
/* Always try to update cached phase if possible */
- if (core->ops->get_phase)
- core->phase = core->ops->get_phase(core->hw);
- ret = core->phase;
- clk_prepare_unlock();
+ ret = core->ops->get_phase(core->hw);
+ if (ret >= 0)
+ core->phase = ret;
return ret;
}
@@ -2679,10 +2680,16 @@
*/
int clk_get_phase(struct clk *clk)
{
+ int ret;
+
if (!clk)
return 0;
- return clk_core_get_phase(clk->core);
+ clk_prepare_lock();
+ ret = clk_core_get_phase(clk->core);
+ clk_prepare_unlock();
+
+ return ret;
}
EXPORT_SYMBOL_GPL(clk_get_phase);
@@ -2896,13 +2903,22 @@
static void clk_summary_show_one(struct seq_file *s, struct clk_core *c,
int level)
{
- seq_printf(s, "%*s%-*s %7d %8d %8d %11lu %10lu %5d %6d\n",
+ int phase;
+
+ seq_printf(s, "%*s%-*s %7d %8d %8d %11lu %10lu ",
level * 3 + 1, "",
30 - level * 3, c->name,
c->enable_count, c->prepare_count, c->protect_count,
- clk_core_get_rate(c), clk_core_get_accuracy(c),
- clk_core_get_phase(c),
- clk_core_get_scaled_duty_cycle(c, 100000));
+ clk_core_get_rate_recalc(c),
+ clk_core_get_accuracy_recalc(c));
+
+ phase = clk_core_get_phase(c);
+ if (phase >= 0)
+ seq_printf(s, "%5d", phase);
+ else
+ seq_puts(s, "-----");
+
+ seq_printf(s, " %6d\n", clk_core_get_scaled_duty_cycle(c, 100000));
}
static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c,
@@ -2939,6 +2955,7 @@
static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level)
{
+ int phase;
unsigned long min_rate, max_rate;
clk_core_get_boundaries(c, &min_rate, &max_rate);
@@ -2948,11 +2965,13 @@
seq_printf(s, "\"enable_count\": %d,", c->enable_count);
seq_printf(s, "\"prepare_count\": %d,", c->prepare_count);
seq_printf(s, "\"protect_count\": %d,", c->protect_count);
- seq_printf(s, "\"rate\": %lu,", clk_core_get_rate(c));
+ seq_printf(s, "\"rate\": %lu,", clk_core_get_rate_recalc(c));
seq_printf(s, "\"min_rate\": %lu,", min_rate);
seq_printf(s, "\"max_rate\": %lu,", max_rate);
- seq_printf(s, "\"accuracy\": %lu,", clk_core_get_accuracy(c));
- seq_printf(s, "\"phase\": %d,", clk_core_get_phase(c));
+ seq_printf(s, "\"accuracy\": %lu,", clk_core_get_accuracy_recalc(c));
+ phase = clk_core_get_phase(c);
+ if (phase >= 0)
+ seq_printf(s, "\"phase\": %d,", phase);
seq_printf(s, "\"duty_cycle\": %u",
clk_core_get_scaled_duty_cycle(c, 100000));
}
@@ -3323,7 +3342,9 @@
static int __clk_core_init(struct clk_core *core)
{
int ret;
+ struct clk_core *parent;
unsigned long rate;
+ int phase;
if (!core)
return -EINVAL;
@@ -3394,7 +3415,7 @@
goto out;
}
- core->parent = __clk_init_parent(core);
+ parent = core->parent = __clk_init_parent(core);
/*
* Populate core->parent if parent has already been clk_core_init'd. If
@@ -3406,10 +3427,9 @@
* clocks and re-parent any that are children of the clock currently
* being clk_init'd.
*/
- if (core->parent) {
- hlist_add_head(&core->child_node,
- &core->parent->children);
- core->orphan = core->parent->orphan;
+ if (parent) {
+ hlist_add_head(&core->child_node, &parent->children);
+ core->orphan = parent->orphan;
} else if (!core->num_parents) {
hlist_add_head(&core->child_node, &clk_root_list);
core->orphan = false;
@@ -3427,21 +3447,24 @@
*/
if (core->ops->recalc_accuracy)
core->accuracy = core->ops->recalc_accuracy(core->hw,
- __clk_get_accuracy(core->parent));
- else if (core->parent)
- core->accuracy = core->parent->accuracy;
+ clk_core_get_accuracy_no_lock(parent));
+ else if (parent)
+ core->accuracy = parent->accuracy;
else
core->accuracy = 0;
/*
- * Set clk's phase.
+ * Set clk's phase by clk_core_get_phase() caching the phase.
* Since a phase is by definition relative to its parent, just
* query the current clock phase, or just assume it's in phase.
*/
- if (core->ops->get_phase)
- core->phase = core->ops->get_phase(core->hw);
- else
- core->phase = 0;
+ phase = clk_core_get_phase(core);
+ if (phase < 0) {
+ ret = phase;
+ pr_warn("%s: Failed to get phase for clk '%s'\n", __func__,
+ core->name);
+ goto out;
+ }
/*
* Set clk's duty cycle.
@@ -3456,9 +3479,9 @@
*/
if (core->ops->recalc_rate)
rate = core->ops->recalc_rate(core->hw,
- clk_core_get_rate_nolock(core->parent));
- else if (core->parent)
- rate = core->parent->rate;
+ clk_core_get_rate_nolock(parent));
+ else if (parent)
+ rate = parent->rate;
else
rate = 0;
core->rate = core->req_rate = rate;
@@ -4865,8 +4888,8 @@
*
* Return: error code or zero on success
*/
-int of_clk_detect_critical(struct device_node *np,
- int index, unsigned long *flags)
+int of_clk_detect_critical(struct device_node *np, int index,
+ unsigned long *flags)
{
struct property *prop;
const __be32 *cur;
diff --git a/drivers/clk/renesas/Kconfig b/drivers/clk/renesas/Kconfig
index 250d816..ac2dd92 100644
--- a/drivers/clk/renesas/Kconfig
+++ b/drivers/clk/renesas/Kconfig
@@ -20,7 +20,7 @@
select CLK_R8A7791 if ARCH_R8A7791 || ARCH_R8A7793
select CLK_R8A7792 if ARCH_R8A7792
select CLK_R8A7794 if ARCH_R8A7794
- select CLK_R8A7795 if ARCH_R8A77950 || ARCH_R8A77951 || ARCH_R8A7795
+ select CLK_R8A7795 if ARCH_R8A77950 || ARCH_R8A77951
select CLK_R8A77960 if ARCH_R8A77960
select CLK_R8A77961 if ARCH_R8A77961
select CLK_R8A77965 if ARCH_R8A77965
@@ -161,6 +161,7 @@
config CLK_RCAR_USB2_CLOCK_SEL
bool "Renesas R-Car USB2 clock selector support"
depends on ARCH_RENESAS || COMPILE_TEST
+ select RESET_CONTROLLER
help
This is a driver for R-Car USB2 clock selector
diff --git a/drivers/clk/renesas/r8a7795-cpg-mssr.c b/drivers/clk/renesas/r8a7795-cpg-mssr.c
index fbc8c75..ff5b3020 100644
--- a/drivers/clk/renesas/r8a7795-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a7795-cpg-mssr.c
@@ -44,6 +44,7 @@
CLK_S3,
CLK_SDSRC,
CLK_SSPSRC,
+ CLK_RPCSRC,
CLK_RINT,
/* Module Clocks */
@@ -70,6 +71,12 @@
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_BASE(".rpcsrc", CLK_RPCSRC, CLK_TYPE_GEN3_RPCSRC, CLK_PLL1),
+
+ DEF_BASE("rpc", R8A7795_CLK_RPC, CLK_TYPE_GEN3_RPC,
+ CLK_RPCSRC),
+ DEF_BASE("rpcd2", R8A7795_CLK_RPCD2, CLK_TYPE_GEN3_RPCD2,
+ R8A7795_CLK_RPC),
DEF_GEN3_OSC(".r", CLK_RINT, CLK_EXTAL, 32),
@@ -242,6 +249,7 @@
DEF_MOD("can-fd", 914, R8A7795_CLK_S3D2),
DEF_MOD("can-if1", 915, R8A7795_CLK_S3D4),
DEF_MOD("can-if0", 916, R8A7795_CLK_S3D4),
+ DEF_MOD("rpc-if", 917, R8A7795_CLK_RPCD2),
DEF_MOD("i2c6", 918, R8A7795_CLK_S0D6),
DEF_MOD("i2c5", 919, R8A7795_CLK_S0D6),
DEF_MOD("i2c-dvfs", 926, R8A7795_CLK_CP),
diff --git a/drivers/clk/renesas/r8a7796-cpg-mssr.c b/drivers/clk/renesas/r8a7796-cpg-mssr.c
index e8420d3..e8d466d 100644
--- a/drivers/clk/renesas/r8a7796-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a7796-cpg-mssr.c
@@ -46,6 +46,7 @@
CLK_S3,
CLK_SDSRC,
CLK_SSPSRC,
+ CLK_RPCSRC,
CLK_RINT,
/* Module Clocks */
@@ -72,6 +73,12 @@
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_BASE(".rpcsrc", CLK_RPCSRC, CLK_TYPE_GEN3_RPCSRC, CLK_PLL1),
+
+ DEF_BASE("rpc", R8A7796_CLK_RPC, CLK_TYPE_GEN3_RPC,
+ CLK_RPCSRC),
+ DEF_BASE("rpcd2", R8A7796_CLK_RPCD2, CLK_TYPE_GEN3_RPCD2,
+ R8A7796_CLK_RPC),
DEF_GEN3_OSC(".r", CLK_RINT, CLK_EXTAL, 32),
@@ -105,6 +112,7 @@
DEF_GEN3_SD("sd3", R8A7796_CLK_SD3, CLK_SDSRC, 0x26c),
DEF_FIXED("cl", R8A7796_CLK_CL, CLK_PLL1_DIV2, 48, 1),
+ DEF_FIXED("cr", R8A7796_CLK_CR, CLK_PLL1_DIV4, 2, 1),
DEF_FIXED("cp", R8A7796_CLK_CP, CLK_EXTAL, 2, 1),
DEF_FIXED("cpex", R8A7796_CLK_CPEX, CLK_EXTAL, 2, 1),
@@ -132,6 +140,7 @@
DEF_MOD("sys-dmac2", 217, R8A7796_CLK_S3D1),
DEF_MOD("sys-dmac1", 218, R8A7796_CLK_S3D1),
DEF_MOD("sys-dmac0", 219, R8A7796_CLK_S0D3),
+ DEF_MOD("sceg-pub", 229, R8A7796_CLK_CR),
DEF_MOD("cmt3", 300, R8A7796_CLK_R),
DEF_MOD("cmt2", 301, R8A7796_CLK_R),
DEF_MOD("cmt1", 302, R8A7796_CLK_R),
@@ -215,6 +224,7 @@
DEF_MOD("can-fd", 914, R8A7796_CLK_S3D2),
DEF_MOD("can-if1", 915, R8A7796_CLK_S3D4),
DEF_MOD("can-if0", 916, R8A7796_CLK_S3D4),
+ DEF_MOD("rpc-if", 917, R8A7796_CLK_RPCD2),
DEF_MOD("i2c6", 918, R8A7796_CLK_S0D6),
DEF_MOD("i2c5", 919, R8A7796_CLK_S0D6),
DEF_MOD("i2c-dvfs", 926, R8A7796_CLK_CP),
diff --git a/drivers/clk/renesas/r8a77965-cpg-mssr.c b/drivers/clk/renesas/r8a77965-cpg-mssr.c
index b3af4da..7a05a2f 100644
--- a/drivers/clk/renesas/r8a77965-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a77965-cpg-mssr.c
@@ -43,6 +43,7 @@
CLK_S3,
CLK_SDSRC,
CLK_SSPSRC,
+ CLK_RPCSRC,
CLK_RINT,
/* Module Clocks */
@@ -68,6 +69,12 @@
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_BASE(".rpcsrc", CLK_RPCSRC, CLK_TYPE_GEN3_RPCSRC, CLK_PLL1),
+
+ DEF_BASE("rpc", R8A77965_CLK_RPC, CLK_TYPE_GEN3_RPC,
+ CLK_RPCSRC),
+ DEF_BASE("rpcd2", R8A77965_CLK_RPCD2, CLK_TYPE_GEN3_RPCD2,
+ R8A77965_CLK_RPC),
DEF_GEN3_OSC(".r", CLK_RINT, CLK_EXTAL, 32),
@@ -99,7 +106,8 @@
DEF_GEN3_SD("sd2", R8A77965_CLK_SD2, CLK_SDSRC, 0x268),
DEF_GEN3_SD("sd3", R8A77965_CLK_SD3, CLK_SDSRC, 0x26c),
- DEF_FIXED("cl", R8A77965_CLK_CL, CLK_PLL1_DIV2, 48, 1),
+ DEF_FIXED("cl", R8A77965_CLK_CL, CLK_PLL1_DIV2, 48, 1),
+ DEF_FIXED("cr", R8A77965_CLK_CR, CLK_PLL1_DIV4, 2, 1),
DEF_FIXED("cp", R8A77965_CLK_CP, CLK_EXTAL, 2, 1),
DEF_FIXED("cpex", R8A77965_CLK_CPEX, CLK_EXTAL, 2, 1),
@@ -127,6 +135,7 @@
DEF_MOD("sys-dmac2", 217, R8A77965_CLK_S3D1),
DEF_MOD("sys-dmac1", 218, R8A77965_CLK_S3D1),
DEF_MOD("sys-dmac0", 219, R8A77965_CLK_S0D3),
+ DEF_MOD("sceg-pub", 229, R8A77965_CLK_CR),
DEF_MOD("cmt3", 300, R8A77965_CLK_R),
DEF_MOD("cmt2", 301, R8A77965_CLK_R),
@@ -215,6 +224,7 @@
DEF_MOD("can-fd", 914, R8A77965_CLK_S3D2),
DEF_MOD("can-if1", 915, R8A77965_CLK_S3D4),
DEF_MOD("can-if0", 916, R8A77965_CLK_S3D4),
+ DEF_MOD("rpc-if", 917, R8A77965_CLK_RPCD2),
DEF_MOD("i2c6", 918, R8A77965_CLK_S0D6),
DEF_MOD("i2c5", 919, R8A77965_CLK_S0D6),
DEF_MOD("i2c-dvfs", 926, R8A77965_CLK_CP),
diff --git a/drivers/clk/renesas/r8a77990-cpg-mssr.c b/drivers/clk/renesas/r8a77990-cpg-mssr.c
index ceabf55c..8eda2e3 100644
--- a/drivers/clk/renesas/r8a77990-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a77990-cpg-mssr.c
@@ -105,6 +105,7 @@
DEF_GEN3_SD("sd3", R8A77990_CLK_SD3, CLK_SDSRC, 0x026c),
DEF_FIXED("cl", R8A77990_CLK_CL, CLK_PLL1, 48, 1),
+ DEF_FIXED("cr", R8A77990_CLK_CR, CLK_PLL1D2, 2, 1),
DEF_FIXED("cp", R8A77990_CLK_CP, CLK_EXTAL, 2, 1),
DEF_FIXED("cpex", R8A77990_CLK_CPEX, CLK_EXTAL, 4, 1),
@@ -135,6 +136,7 @@
DEF_MOD("sys-dmac2", 217, R8A77990_CLK_S3D1),
DEF_MOD("sys-dmac1", 218, R8A77990_CLK_S3D1),
DEF_MOD("sys-dmac0", 219, R8A77990_CLK_S3D1),
+ DEF_MOD("sceg-pub", 229, R8A77990_CLK_CR),
DEF_MOD("cmt3", 300, R8A77990_CLK_R),
DEF_MOD("cmt2", 301, R8A77990_CLK_R),
diff --git a/drivers/clk/renesas/r8a77995-cpg-mssr.c b/drivers/clk/renesas/r8a77995-cpg-mssr.c
index 962bb33..056ebf3 100644
--- a/drivers/clk/renesas/r8a77995-cpg-mssr.c
+++ b/drivers/clk/renesas/r8a77995-cpg-mssr.c
@@ -91,6 +91,7 @@
DEF_FIXED("s3d4", R8A77995_CLK_S3D4, CLK_S3, 4, 1),
DEF_FIXED("cl", R8A77995_CLK_CL, CLK_PLL1, 48, 1),
+ DEF_FIXED("cr", R8A77995_CLK_CR, CLK_PLL1D2, 2, 1),
DEF_FIXED("cp", R8A77995_CLK_CP, CLK_EXTAL, 2, 1),
DEF_FIXED("cpex", R8A77995_CLK_CPEX, CLK_EXTAL, 4, 1),
@@ -122,6 +123,7 @@
DEF_MOD("sys-dmac2", 217, R8A77995_CLK_S3D1),
DEF_MOD("sys-dmac1", 218, R8A77995_CLK_S3D1),
DEF_MOD("sys-dmac0", 219, R8A77995_CLK_S3D1),
+ DEF_MOD("sceg-pub", 229, R8A77995_CLK_CR),
DEF_MOD("cmt3", 300, R8A77995_CLK_R),
DEF_MOD("cmt2", 301, R8A77995_CLK_R),
DEF_MOD("cmt1", 302, R8A77995_CLK_R),
diff --git a/drivers/clk/renesas/rcar-usb2-clock-sel.c b/drivers/clk/renesas/rcar-usb2-clock-sel.c
index b97f5f9..d4c0298 100644
--- a/drivers/clk/renesas/rcar-usb2-clock-sel.c
+++ b/drivers/clk/renesas/rcar-usb2-clock-sel.c
@@ -19,6 +19,7 @@
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
+#include <linux/reset.h>
#include <linux/slab.h>
#define USB20_CLKSET0 0x00
@@ -26,9 +27,16 @@
#define CLKSET0_PRIVATE BIT(0)
#define CLKSET0_EXTAL_ONLY (CLKSET0_INTCLK_EN | CLKSET0_PRIVATE)
+static const struct clk_bulk_data rcar_usb2_clocks[] = {
+ { .id = "ehci_ohci", },
+ { .id = "hs-usb-if", },
+};
+
struct usb2_clock_sel_priv {
void __iomem *base;
struct clk_hw hw;
+ struct clk_bulk_data clks[ARRAY_SIZE(rcar_usb2_clocks)];
+ struct reset_control *rsts;
bool extal;
bool xtal;
};
@@ -53,14 +61,32 @@
static int usb2_clock_sel_enable(struct clk_hw *hw)
{
- usb2_clock_sel_enable_extal_only(to_priv(hw));
+ struct usb2_clock_sel_priv *priv = to_priv(hw);
+ int ret;
+
+ ret = reset_control_deassert(priv->rsts);
+ if (ret)
+ return ret;
+
+ ret = clk_bulk_prepare_enable(ARRAY_SIZE(priv->clks), priv->clks);
+ if (ret) {
+ reset_control_assert(priv->rsts);
+ return ret;
+ }
+
+ usb2_clock_sel_enable_extal_only(priv);
return 0;
}
static void usb2_clock_sel_disable(struct clk_hw *hw)
{
- usb2_clock_sel_disable_extal_only(to_priv(hw));
+ struct usb2_clock_sel_priv *priv = to_priv(hw);
+
+ usb2_clock_sel_disable_extal_only(priv);
+
+ clk_bulk_disable_unprepare(ARRAY_SIZE(priv->clks), priv->clks);
+ reset_control_assert(priv->rsts);
}
/*
@@ -119,6 +145,7 @@
struct usb2_clock_sel_priv *priv;
struct clk *clk;
struct clk_init_data init;
+ int ret;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
@@ -128,6 +155,15 @@
if (IS_ERR(priv->base))
return PTR_ERR(priv->base);
+ memcpy(priv->clks, rcar_usb2_clocks, sizeof(priv->clks));
+ ret = devm_clk_bulk_get(dev, ARRAY_SIZE(priv->clks), priv->clks);
+ if (ret < 0)
+ return ret;
+
+ priv->rsts = devm_reset_control_array_get(dev, true, false);
+ if (IS_ERR(priv->rsts))
+ return PTR_ERR(priv->rsts);
+
pm_runtime_enable(dev);
pm_runtime_get_sync(dev);
diff --git a/drivers/clk/rockchip/clk-mmc-phase.c b/drivers/clk/rockchip/clk-mmc-phase.c
index 4abe7ff..975454a 100644
--- a/drivers/clk/rockchip/clk-mmc-phase.c
+++ b/drivers/clk/rockchip/clk-mmc-phase.c
@@ -51,9 +51,9 @@
u16 degrees;
u32 delay_num = 0;
- /* See the comment for rockchip_mmc_set_phase below */
+ /* Constant signal, no measurable phase shift */
if (!rate)
- return -EINVAL;
+ return 0;
raw_value = readl(mmc_clock->reg) >> (mmc_clock->shift);
diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c
index dad3130..1949ae7 100644
--- a/drivers/clk/samsung/clk.c
+++ b/drivers/clk/samsung/clk.c
@@ -356,10 +356,6 @@
}
ctx = samsung_clk_init(np, reg_base, cmu->nr_clk_ids);
- if (!ctx) {
- panic("%s: unable to allocate ctx\n", __func__);
- return ctx;
- }
if (cmu->pll_clks)
samsung_clk_register_pll(ctx, cmu->pll_clks, cmu->nr_pll_clks,
diff --git a/drivers/clk/socfpga/clk-gate-s10.c b/drivers/clk/socfpga/clk-gate-s10.c
index 54a464f..8be4722 100644
--- a/drivers/clk/socfpga/clk-gate-s10.c
+++ b/drivers/clk/socfpga/clk-gate-s10.c
@@ -65,54 +65,49 @@
.get_parent = socfpga_gate_get_parent,
};
-struct clk *s10_register_gate(const char *name, const char *parent_name,
- const char * const *parent_names,
- u8 num_parents, unsigned long flags,
- void __iomem *regbase, unsigned long gate_reg,
- unsigned long gate_idx, unsigned long div_reg,
- unsigned long div_offset, u8 div_width,
- unsigned long bypass_reg, u8 bypass_shift,
- u8 fixed_div)
+struct clk *s10_register_gate(const struct stratix10_gate_clock *clks, void __iomem *regbase)
{
struct clk *clk;
struct socfpga_gate_clk *socfpga_clk;
struct clk_init_data init;
+ const char * const *parent_names = clks->parent_names;
+ const char *parent_name = clks->parent_name;
socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL);
if (!socfpga_clk)
return NULL;
- socfpga_clk->hw.reg = regbase + gate_reg;
- socfpga_clk->hw.bit_idx = gate_idx;
+ socfpga_clk->hw.reg = regbase + clks->gate_reg;
+ socfpga_clk->hw.bit_idx = clks->gate_idx;
gateclk_ops.enable = clk_gate_ops.enable;
gateclk_ops.disable = clk_gate_ops.disable;
- socfpga_clk->fixed_div = fixed_div;
+ socfpga_clk->fixed_div = clks->fixed_div;
- if (div_reg)
- socfpga_clk->div_reg = regbase + div_reg;
+ if (clks->div_reg)
+ socfpga_clk->div_reg = regbase + clks->div_reg;
else
socfpga_clk->div_reg = NULL;
- socfpga_clk->width = div_width;
- socfpga_clk->shift = div_offset;
+ socfpga_clk->width = clks->div_width;
+ socfpga_clk->shift = clks->div_offset;
- if (bypass_reg)
- socfpga_clk->bypass_reg = regbase + bypass_reg;
+ if (clks->bypass_reg)
+ socfpga_clk->bypass_reg = regbase + clks->bypass_reg;
else
socfpga_clk->bypass_reg = NULL;
- socfpga_clk->bypass_shift = bypass_shift;
+ socfpga_clk->bypass_shift = clks->bypass_shift;
- if (streq(name, "cs_pdbg_clk"))
+ if (streq(clks->name, "cs_pdbg_clk"))
init.ops = &dbgclk_ops;
else
init.ops = &gateclk_ops;
- init.name = name;
- init.flags = flags;
+ init.name = clks->name;
+ init.flags = clks->flags;
- init.num_parents = num_parents;
+ init.num_parents = clks->num_parents;
init.parent_names = parent_names ? parent_names : &parent_name;
socfpga_clk->hw.hw.init = &init;
@@ -121,6 +116,5 @@
kfree(socfpga_clk);
return NULL;
}
-
return clk;
}
diff --git a/drivers/clk/socfpga/clk-periph-s10.c b/drivers/clk/socfpga/clk-periph-s10.c
index 1a191ee..dd6d405 100644
--- a/drivers/clk/socfpga/clk-periph-s10.c
+++ b/drivers/clk/socfpga/clk-periph-s10.c
@@ -73,26 +73,27 @@
.get_parent = clk_periclk_get_parent,
};
-struct clk *s10_register_periph(const char *name, const char *parent_name,
- const char * const *parent_names,
- u8 num_parents, unsigned long flags,
- void __iomem *reg, unsigned long offset)
+struct clk *s10_register_periph(const struct stratix10_perip_c_clock *clks,
+ void __iomem *reg)
{
struct clk *clk;
struct socfpga_periph_clk *periph_clk;
struct clk_init_data init;
+ const char *name = clks->name;
+ const char *parent_name = clks->parent_name;
+ const char * const *parent_names = clks->parent_names;
periph_clk = kzalloc(sizeof(*periph_clk), GFP_KERNEL);
if (WARN_ON(!periph_clk))
return NULL;
- periph_clk->hw.reg = reg + offset;
+ periph_clk->hw.reg = reg + clks->offset;
init.name = name;
init.ops = &peri_c_clk_ops;
- init.flags = flags;
+ init.flags = clks->flags;
- init.num_parents = num_parents;
+ init.num_parents = clks->num_parents;
init.parent_names = parent_names ? parent_names : &parent_name;
periph_clk->hw.hw.init = &init;
@@ -105,38 +106,37 @@
return clk;
}
-struct clk *s10_register_cnt_periph(const char *name, const char *parent_name,
- const char * const *parent_names,
- u8 num_parents, unsigned long flags,
- void __iomem *regbase, unsigned long offset,
- u8 fixed_divider, unsigned long bypass_reg,
- unsigned long bypass_shift)
+struct clk *s10_register_cnt_periph(const struct stratix10_perip_cnt_clock *clks,
+ void __iomem *regbase)
{
struct clk *clk;
struct socfpga_periph_clk *periph_clk;
struct clk_init_data init;
+ const char *name = clks->name;
+ const char *parent_name = clks->parent_name;
+ const char * const *parent_names = clks->parent_names;
periph_clk = kzalloc(sizeof(*periph_clk), GFP_KERNEL);
if (WARN_ON(!periph_clk))
return NULL;
- if (offset)
- periph_clk->hw.reg = regbase + offset;
+ if (clks->offset)
+ periph_clk->hw.reg = regbase + clks->offset;
else
periph_clk->hw.reg = NULL;
- if (bypass_reg)
- periph_clk->bypass_reg = regbase + bypass_reg;
+ if (clks->bypass_reg)
+ periph_clk->bypass_reg = regbase + clks->bypass_reg;
else
periph_clk->bypass_reg = NULL;
- periph_clk->bypass_shift = bypass_shift;
- periph_clk->fixed_div = fixed_divider;
+ periph_clk->bypass_shift = clks->bypass_shift;
+ periph_clk->fixed_div = clks->fixed_divider;
init.name = name;
init.ops = &peri_cnt_clk_ops;
- init.flags = flags;
+ init.flags = clks->flags;
- init.num_parents = num_parents;
+ init.num_parents = clks->num_parents;
init.parent_names = parent_names ? parent_names : &parent_name;
periph_clk->hw.hw.init = &init;
diff --git a/drivers/clk/socfpga/clk-pll-s10.c b/drivers/clk/socfpga/clk-pll-s10.c
index 4705eb5..a301bb2 100644
--- a/drivers/clk/socfpga/clk-pll-s10.c
+++ b/drivers/clk/socfpga/clk-pll-s10.c
@@ -39,7 +39,9 @@
/* read VCO1 reg for numerator and denominator */
reg = readl(socfpgaclk->hw.reg);
refdiv = (reg & SOCFPGA_PLL_REFDIV_MASK) >> SOCFPGA_PLL_REFDIV_SHIFT;
- vco_freq = (unsigned long long)parent_rate / refdiv;
+
+ vco_freq = parent_rate;
+ do_div(vco_freq, refdiv);
/* Read mdiv and fdiv from the fdbck register */
reg = readl(socfpgaclk->hw.reg + 0x4);
@@ -108,19 +110,20 @@
.prepare = clk_pll_prepare,
};
-struct clk *s10_register_pll(const char *name, const char * const *parent_names,
- u8 num_parents, unsigned long flags,
- void __iomem *reg, unsigned long offset)
+struct clk *s10_register_pll(const struct stratix10_pll_clock *clks,
+ void __iomem *reg)
{
struct clk *clk;
struct socfpga_pll *pll_clk;
struct clk_init_data init;
+ const char *name = clks->name;
+ const char * const *parent_names = clks->parent_names;
pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL);
if (WARN_ON(!pll_clk))
return NULL;
- pll_clk->hw.reg = reg + offset;
+ pll_clk->hw.reg = reg + clks->offset;
if (streq(name, SOCFPGA_BOOT_CLK))
init.ops = &clk_boot_ops;
@@ -128,9 +131,9 @@
init.ops = &clk_pll_ops;
init.name = name;
- init.flags = flags;
+ init.flags = clks->flags;
- init.num_parents = num_parents;
+ init.num_parents = clks->num_parents;
init.parent_names = parent_names;
pll_clk->hw.hw.init = &init;
diff --git a/drivers/clk/socfpga/clk-s10.c b/drivers/clk/socfpga/clk-s10.c
index 993f3a7..dea7c6c 100644
--- a/drivers/clk/socfpga/clk-s10.c
+++ b/drivers/clk/socfpga/clk-s10.c
@@ -177,9 +177,7 @@
int i;
for (i = 0; i < nums; i++) {
- clk = s10_register_periph(clks[i].name, clks[i].parent_name,
- clks[i].parent_names, clks[i].num_parents,
- clks[i].flags, base, clks[i].offset);
+ clk = s10_register_periph(&clks[i], base);
if (IS_ERR(clk)) {
pr_err("%s: failed to register clock %s\n",
__func__, clks[i].name);
@@ -198,14 +196,7 @@
int i;
for (i = 0; i < nums; i++) {
- clk = s10_register_cnt_periph(clks[i].name, clks[i].parent_name,
- clks[i].parent_names,
- clks[i].num_parents,
- clks[i].flags, base,
- clks[i].offset,
- clks[i].fixed_divider,
- clks[i].bypass_reg,
- clks[i].bypass_shift);
+ clk = s10_register_cnt_periph(&clks[i], base);
if (IS_ERR(clk)) {
pr_err("%s: failed to register clock %s\n",
__func__, clks[i].name);
@@ -225,16 +216,7 @@
int i;
for (i = 0; i < nums; i++) {
- clk = s10_register_gate(clks[i].name, clks[i].parent_name,
- clks[i].parent_names,
- clks[i].num_parents,
- clks[i].flags, base,
- clks[i].gate_reg,
- clks[i].gate_idx, clks[i].div_reg,
- clks[i].div_offset, clks[i].div_width,
- clks[i].bypass_reg,
- clks[i].bypass_shift,
- clks[i].fixed_div);
+ clk = s10_register_gate(&clks[i], base);
if (IS_ERR(clk)) {
pr_err("%s: failed to register clock %s\n",
__func__, clks[i].name);
@@ -254,10 +236,7 @@
int i;
for (i = 0; i < nums; i++) {
- clk = s10_register_pll(clks[i].name, clks[i].parent_names,
- clks[i].num_parents,
- clks[i].flags, base,
- clks[i].offset);
+ clk = s10_register_pll(&clks[i], base);
if (IS_ERR(clk)) {
pr_err("%s: failed to register clock %s\n",
__func__, clks[i].name);
diff --git a/drivers/clk/socfpga/stratix10-clk.h b/drivers/clk/socfpga/stratix10-clk.h
index e8e1219..fcabef4 100644
--- a/drivers/clk/socfpga/stratix10-clk.h
+++ b/drivers/clk/socfpga/stratix10-clk.h
@@ -60,21 +60,12 @@
u8 fixed_div;
};
-struct clk *s10_register_pll(const char *, const char *const *, u8,
- unsigned long, void __iomem *, unsigned long);
-
-struct clk *s10_register_periph(const char *, const char *,
- const char * const *, u8, unsigned long,
- void __iomem *, unsigned long);
-struct clk *s10_register_cnt_periph(const char *, const char *,
- const char * const *, u8,
- unsigned long, void __iomem *,
- unsigned long, u8, unsigned long,
- unsigned long);
-struct clk *s10_register_gate(const char *, const char *,
- const char * const *, u8,
- unsigned long, void __iomem *,
- unsigned long, unsigned long,
- unsigned long, unsigned long, u8,
- unsigned long, u8, u8);
+struct clk *s10_register_pll(const struct stratix10_pll_clock *,
+ void __iomem *);
+struct clk *s10_register_periph(const struct stratix10_perip_c_clock *,
+ void __iomem *);
+struct clk *s10_register_cnt_periph(const struct stratix10_perip_cnt_clock *,
+ void __iomem *);
+struct clk *s10_register_gate(const struct stratix10_gate_clock *,
+ void __iomem *);
#endif /* __STRATIX10_CLK_H */
diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h
index 116e6f8..54d1f96 100644
--- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h
+++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h
@@ -55,10 +55,6 @@
/* All the DRAM gates are exported */
-/* Some more module clocks are exported */
-
-#define CLK_MBUS 112
-
/* And the DSI and GPU module clock is exported */
#define CLK_NUMBER (CLK_GPU + 1)
diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c
index d966849..524f332 100644
--- a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c
+++ b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c
@@ -50,24 +50,8 @@
CLK_SET_RATE_PARENT);
static SUNXI_CCU_M(wb_div_a83_clk, "wb-div", "pll-de", 0x0c, 8, 4,
CLK_SET_RATE_PARENT);
-
-static struct ccu_common *sun50i_h6_de3_clks[] = {
- &mixer0_clk.common,
- &mixer1_clk.common,
- &wb_clk.common,
-
- &bus_mixer0_clk.common,
- &bus_mixer1_clk.common,
- &bus_wb_clk.common,
-
- &mixer0_div_clk.common,
- &mixer1_div_clk.common,
- &wb_div_clk.common,
-
- &bus_rot_clk.common,
- &rot_clk.common,
- &rot_div_clk.common,
-};
+static SUNXI_CCU_M(rot_div_a83_clk, "rot-div", "pll-de", 0x0c, 0x0c, 4,
+ CLK_SET_RATE_PARENT);
static struct ccu_common *sun8i_a83t_de2_clks[] = {
&mixer0_clk.common,
@@ -81,6 +65,10 @@
&mixer0_div_a83_clk.common,
&mixer1_div_a83_clk.common,
&wb_div_a83_clk.common,
+
+ &bus_rot_clk.common,
+ &rot_clk.common,
+ &rot_div_a83_clk.common,
};
static struct ccu_common *sun8i_h3_de2_clks[] = {
@@ -108,21 +96,42 @@
&wb_div_clk.common,
};
+static struct ccu_common *sun50i_a64_de2_clks[] = {
+ &mixer0_clk.common,
+ &mixer1_clk.common,
+ &wb_clk.common,
+
+ &bus_mixer0_clk.common,
+ &bus_mixer1_clk.common,
+ &bus_wb_clk.common,
+
+ &mixer0_div_clk.common,
+ &mixer1_div_clk.common,
+ &wb_div_clk.common,
+
+ &bus_rot_clk.common,
+ &rot_clk.common,
+ &rot_div_clk.common,
+};
+
static struct clk_hw_onecell_data sun8i_a83t_de2_hw_clks = {
.hws = {
[CLK_MIXER0] = &mixer0_clk.common.hw,
[CLK_MIXER1] = &mixer1_clk.common.hw,
[CLK_WB] = &wb_clk.common.hw,
+ [CLK_ROT] = &rot_clk.common.hw,
[CLK_BUS_MIXER0] = &bus_mixer0_clk.common.hw,
[CLK_BUS_MIXER1] = &bus_mixer1_clk.common.hw,
[CLK_BUS_WB] = &bus_wb_clk.common.hw,
+ [CLK_BUS_ROT] = &bus_rot_clk.common.hw,
[CLK_MIXER0_DIV] = &mixer0_div_a83_clk.common.hw,
[CLK_MIXER1_DIV] = &mixer1_div_a83_clk.common.hw,
[CLK_WB_DIV] = &wb_div_a83_clk.common.hw,
+ [CLK_ROT_DIV] = &rot_div_a83_clk.common.hw,
},
- .num = CLK_NUMBER_WITHOUT_ROT,
+ .num = CLK_NUMBER_WITH_ROT,
};
static struct clk_hw_onecell_data sun8i_h3_de2_hw_clks = {
@@ -156,7 +165,7 @@
.num = CLK_NUMBER_WITHOUT_ROT,
};
-static struct clk_hw_onecell_data sun50i_h6_de3_hw_clks = {
+static struct clk_hw_onecell_data sun50i_a64_de2_hw_clks = {
.hws = {
[CLK_MIXER0] = &mixer0_clk.common.hw,
[CLK_MIXER1] = &mixer1_clk.common.hw,
@@ -179,9 +188,19 @@
static struct ccu_reset_map sun8i_a83t_de2_resets[] = {
[RST_MIXER0] = { 0x08, BIT(0) },
/*
- * For A83T, H3 and R40, mixer1 reset line is shared with wb, so
- * only RST_WB is exported here.
- * For V3s there's just no mixer1, so it also shares this struct.
+ * Mixer1 reset line is shared with wb, so only RST_WB is
+ * exported here.
+ */
+ [RST_WB] = { 0x08, BIT(2) },
+ [RST_ROT] = { 0x08, BIT(3) },
+};
+
+static struct ccu_reset_map sun8i_h3_de2_resets[] = {
+ [RST_MIXER0] = { 0x08, BIT(0) },
+ /*
+ * Mixer1 reset line is shared with wb, so only RST_WB is
+ * exported here.
+ * V3s doesn't have mixer1, so it also shares this struct.
*/
[RST_WB] = { 0x08, BIT(2) },
};
@@ -190,13 +209,13 @@
[RST_MIXER0] = { 0x08, BIT(0) },
[RST_MIXER1] = { 0x08, BIT(1) },
[RST_WB] = { 0x08, BIT(2) },
+ [RST_ROT] = { 0x08, BIT(3) },
};
-static struct ccu_reset_map sun50i_h6_de3_resets[] = {
+static struct ccu_reset_map sun50i_h5_de2_resets[] = {
[RST_MIXER0] = { 0x08, BIT(0) },
[RST_MIXER1] = { 0x08, BIT(1) },
[RST_WB] = { 0x08, BIT(2) },
- [RST_ROT] = { 0x08, BIT(3) },
};
static const struct sunxi_ccu_desc sun8i_a83t_de2_clk_desc = {
@@ -215,30 +234,20 @@
.hw_clks = &sun8i_h3_de2_hw_clks,
+ .resets = sun8i_h3_de2_resets,
+ .num_resets = ARRAY_SIZE(sun8i_h3_de2_resets),
+};
+
+static const struct sunxi_ccu_desc sun8i_r40_de2_clk_desc = {
+ .ccu_clks = sun50i_a64_de2_clks,
+ .num_ccu_clks = ARRAY_SIZE(sun50i_a64_de2_clks),
+
+ .hw_clks = &sun50i_a64_de2_hw_clks,
+
.resets = sun8i_a83t_de2_resets,
.num_resets = ARRAY_SIZE(sun8i_a83t_de2_resets),
};
-static const struct sunxi_ccu_desc sun50i_a64_de2_clk_desc = {
- .ccu_clks = sun8i_h3_de2_clks,
- .num_ccu_clks = ARRAY_SIZE(sun8i_h3_de2_clks),
-
- .hw_clks = &sun8i_h3_de2_hw_clks,
-
- .resets = sun50i_a64_de2_resets,
- .num_resets = ARRAY_SIZE(sun50i_a64_de2_resets),
-};
-
-static const struct sunxi_ccu_desc sun50i_h6_de3_clk_desc = {
- .ccu_clks = sun50i_h6_de3_clks,
- .num_ccu_clks = ARRAY_SIZE(sun50i_h6_de3_clks),
-
- .hw_clks = &sun50i_h6_de3_hw_clks,
-
- .resets = sun50i_h6_de3_resets,
- .num_resets = ARRAY_SIZE(sun50i_h6_de3_resets),
-};
-
static const struct sunxi_ccu_desc sun8i_v3s_de2_clk_desc = {
.ccu_clks = sun8i_v3s_de2_clks,
.num_ccu_clks = ARRAY_SIZE(sun8i_v3s_de2_clks),
@@ -249,6 +258,26 @@
.num_resets = ARRAY_SIZE(sun8i_a83t_de2_resets),
};
+static const struct sunxi_ccu_desc sun50i_a64_de2_clk_desc = {
+ .ccu_clks = sun50i_a64_de2_clks,
+ .num_ccu_clks = ARRAY_SIZE(sun50i_a64_de2_clks),
+
+ .hw_clks = &sun50i_a64_de2_hw_clks,
+
+ .resets = sun50i_a64_de2_resets,
+ .num_resets = ARRAY_SIZE(sun50i_a64_de2_resets),
+};
+
+static const struct sunxi_ccu_desc sun50i_h5_de2_clk_desc = {
+ .ccu_clks = sun8i_h3_de2_clks,
+ .num_ccu_clks = ARRAY_SIZE(sun8i_h3_de2_clks),
+
+ .hw_clks = &sun8i_h3_de2_hw_clks,
+
+ .resets = sun50i_h5_de2_resets,
+ .num_resets = ARRAY_SIZE(sun50i_h5_de2_resets),
+};
+
static int sunxi_de2_clk_probe(struct platform_device *pdev)
{
struct resource *res;
@@ -338,6 +367,10 @@
.data = &sun8i_h3_de2_clk_desc,
},
{
+ .compatible = "allwinner,sun8i-r40-de2-clk",
+ .data = &sun8i_r40_de2_clk_desc,
+ },
+ {
.compatible = "allwinner,sun8i-v3s-de2-clk",
.data = &sun8i_v3s_de2_clk_desc,
},
@@ -347,11 +380,11 @@
},
{
.compatible = "allwinner,sun50i-h5-de2-clk",
- .data = &sun50i_a64_de2_clk_desc,
+ .data = &sun50i_h5_de2_clk_desc,
},
{
.compatible = "allwinner,sun50i-h6-de3-clk",
- .data = &sun50i_h6_de3_clk_desc,
+ .data = &sun50i_h5_de2_clk_desc,
},
{ }
};
diff --git a/include/dt-bindings/clock/sun50i-a64-ccu.h b/include/dt-bindings/clock/sun50i-a64-ccu.h
index e512a1c..318eb15 100644
--- a/include/dt-bindings/clock/sun50i-a64-ccu.h
+++ b/include/dt-bindings/clock/sun50i-a64-ccu.h
@@ -131,7 +131,7 @@
#define CLK_AVS 109
#define CLK_HDMI 110
#define CLK_HDMI_DDC 111
-
+#define CLK_MBUS 112
#define CLK_DSI_DPHY 113
#define CLK_GPU 114