mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-17 18:36:00 +00:00
Mainly driver updates this time around. There's a single patch to the core clk
framework that simplifies a runtime PM call. Otherwise the majority of the diff falls to a few SoC drivers: Qualcomm, STM32 and MediaTek. Those SoCs gain some new hardware support and what comes along with that is quite a few lines of data and some clk_ops code. Beyond the new hardware support we have the usual pile of driver updates that add missing clks on already supported SoCs or fix up problems like bad clk tree descriptions. It's nice to see that more drivers are moving to clk_hw based APIs too. New Drivers: - Add STM32MP13 RCC driver (Reset Clock Controller) - MediaTek MT8186 SoC clk support - Airoha EN7523 SoC system clocks - Clock driver for exynosautov9 SoC - Renesas R-Car V4H and RZ/V2M SoCs - Renesas RZ/G2UL SoC - LPASS clk driver for Qualcomm sc7280 SoC - GCC clk driver for Qualcomm SC8280XP SoC Updates: - SDCC uses floor clk ops on Qualcomm MSM8976 - Add modem reset and fix RPM clks on Qualcomm MSM8976 - Add the two missing CLKOUT clocks for U8500/DB8500 SoC - Mark some clks critical on Ingenic X1000 - Convert ux500 to clk_hw - Move MediaTek driver to clk_hw provider APIs - Use i2c driver probe_new to avoid id scans - Convert a number of Rockchip dt bindings to YAML - Mark hclk_vo critical on Rockchip rk3568 - Use pm_runtime_resume_and_get to fix pm_runtime_get_sync() usage - Various cleanups like memory allocation error checks and plugged leaks - Allwinner H6 RTC clock support - Allwinner H616 32 kHz clock support - Add the Universal Flash Storage clock on Renesas R-Car S4-8 - Add I2C, SSIF-2 (sound), USB, CANFD, OSTM (timer), WDT, SPI Multi I/O Bus, RSPI, TSU (thermal), and ADC clocks and resets on Renesas RZ/G2UL - Add display clock support on Renesas RZ/G2L - Add RPC (QSPI/HyperFlash) clocks on Renesas R-Car E3 and D3 - Add 27 MHz phy PLL ref clock on i.MX - Add mcore_booted module parameter to tell kernel M core has already booted for i.MX - Remove snvs clock on i.MX because it was for secure world only - Add dt bindings for i.MX8MN GPT - Add DISP2 pixel clock for i.MX8MP - Add clkout1/2 for i.MX8MP - Fix parent clock of ubs_root_clk for i.MX8MP - Implement better RCG parking on Qualcomm SoCs using the shared RCG clk ops - Kerneldoc fixes - Switch Tegra BPMP to determine_rate clk op - Add a pointer to dt schema for generic clock bindings -----BEGIN PGP SIGNATURE----- iQJFBAABCAAvFiEE9L57QeeUxqYDyoaDrQKIl8bklSUFAmKQCksRHHNib3lkQGtl cm5lbC5vcmcACgkQrQKIl8bklSW6NxAA3HZBExSU8gb3XpLWDBcsjFLdR/3Pg2dW GC40IGjX8ZVZ4UOZxwOHXwtycuQcnbfU6bZgw2VHvH1G+xnM9Gyqrk2XfAKhxB8D cvKUhWoQYQBhpjLD8bDfKLb6tCYD/KmGMkkHl0WDUfeV3TlNLhp6mKXLK3buovJ8 XC8BYUK5+8ks4pgGH42PIt33w5yE71AmFpYyyuuprhBvTcwUe8UfhZwI6YFPmwi8 Zbzo0VTGMnCvFFK47zsvsBbwyaEBuNuM2hKcxt2URY2F08W/q5WzduMVUDcMMgWV /X8r+0m+YwQiUCd9qqAQYdIUWODcoaEJoRlv0pr0CKrz4ovzWLBO67G84bRVEHEn LNTfsjH9mJMZMZ89hBy2gbWXa/zKKPcqdtI82/i4LWHP72CcpTQmiyjUsUy+cZ+P usyILn/H3A1rCJ0NTmYeQo2Ja91KVvobuqnWC9euELRLKGeGgmRU6nkVBqIhN8Q+ asJyKcD6yow+2wilYyWtrbV1WYmwZ0zIMEH3kEkitXrqjbSwfZqCcOfwc+1IC/FK /xT7wOBIN/6MB4+O7scWA7RZZyeCJxX7OndIMzxYG2mJLG6rLsWoGZhAqKrHJKV8 D4fHB7FcCyp8Vj01oeKPUanPoqDYCpI3IfpcxnWkl1lU/+xi1WtPV510cTDBYTdY NY4pPKxfA2g= =7lBA -----END PGP SIGNATURE----- Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux Pull clk updates from Stephen Boyd: "Mainly driver updates this time around. There's a single patch to the core clk framework that simplifies a runtime PM call. Otherwise the majority of the diff falls to a few SoC drivers: Qualcomm, STM32 and MediaTek. Those SoCs gain some new hardware support and what comes along with that is quite a few lines of data and some clk_ops code. Beyond the new hardware support we have the usual pile of driver updates that add missing clks on already supported SoCs or fix up problems like bad clk tree descriptions. It's nice to see that more drivers are moving to clk_hw based APIs too. New Drivers: - Add STM32MP13 RCC driver (Reset Clock Controller) - MediaTek MT8186 SoC clk support - Airoha EN7523 SoC system clocks - Clock driver for exynosautov9 SoC - Renesas R-Car V4H and RZ/V2M SoCs - Renesas RZ/G2UL SoC - LPASS clk driver for Qualcomm sc7280 SoC - GCC clk driver for Qualcomm SC8280XP SoC Updates: - SDCC uses floor clk ops on Qualcomm MSM8976 - Add modem reset and fix RPM clks on Qualcomm MSM8976 - Add the two missing CLKOUT clocks for U8500/DB8500 SoC - Mark some clks critical on Ingenic X1000 - Convert ux500 to clk_hw - Move MediaTek driver to clk_hw provider APIs - Use i2c driver probe_new to avoid id scans - Convert a number of Rockchip dt bindings to YAML - Mark hclk_vo critical on Rockchip rk3568 - Use pm_runtime_resume_and_get to fix pm_runtime_get_sync() usage - Various cleanups like memory allocation error checks and plugged leaks - Allwinner H6 RTC clock support - Allwinner H616 32 kHz clock support - Add the Universal Flash Storage clock on Renesas R-Car S4-8 - Add I2C, SSIF-2 (sound), USB, CANFD, OSTM (timer), WDT, SPI Multi I/O Bus, RSPI, TSU (thermal), and ADC clocks and resets on Renesas RZ/G2UL - Add display clock support on Renesas RZ/G2L - Add RPC (QSPI/HyperFlash) clocks on Renesas R-Car E3 and D3 - Add 27 MHz phy PLL ref clock on i.MX - Add mcore_booted module parameter to tell kernel M core has already booted for i.MX - Remove snvs clock on i.MX because it was for secure world only - Add dt bindings for i.MX8MN GPT - Add DISP2 pixel clock for i.MX8MP - Add clkout1/2 for i.MX8MP - Fix parent clock of ubs_root_clk for i.MX8MP - Implement better RCG parking on Qualcomm SoCs using the shared RCG clk ops - Kerneldoc fixes - Switch Tegra BPMP to determine_rate clk op - Add a pointer to dt schema for generic clock bindings" * tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (168 commits) Revert "clk: qcom: regmap-mux: add pipe clk implementation" Revert "clk: qcom: gcc-sc7280: use new clk_regmap_mux_safe_ops for PCIe pipe clocks" Revert "clk: qcom: gcc-sm8450: use new clk_regmap_mux_safe_ops for PCIe pipe clocks" clk: bcm: rpi: Use correct order for the parameters of devm_kcalloc() clk: stm32mp13: add safe mux management clk: stm32mp13: add multi mux function clk: stm32mp13: add all STM32MP13 kernel clocks clk: stm32mp13: add all STM32MP13 peripheral clocks clk: stm32mp13: manage secured clocks clk: stm32mp13: add composite clock clk: stm32mp13: add stm32 divider clock clk: stm32mp13: add stm32_gate management clk: stm32mp13: add stm32_mux clock management clk: stm32: Introduce STM32MP13 RCC drivers (Reset Clock Controller) dt-bindings: rcc: stm32: add new compatible for STM32MP13 SoC clk: ti: clkctrl: replace usage of found with dedicated list iterator variable clk: ti: composite: Prefer kcalloc over open coded arithmetic dt-bindings: clock: exynosautov9: correct count of NR_CLK clk: mediatek: mt8173: Switch to clk_hw provider APIs clk: mediatek: Switch to clk_hw provider APIs ...
This commit is contained in:
commit
6b0e34a030
@ -0,0 +1,56 @@
|
|||||||
|
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: "http://devicetree.org/schemas/arm/mediatek/mediatek,mt8186-clock.yaml#"
|
||||||
|
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
|
||||||
|
|
||||||
|
title: MediaTek Functional Clock Controller for MT8186
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Chun-Jie Chen <chun-jie.chen@mediatek.com>
|
||||||
|
|
||||||
|
description: |
|
||||||
|
The clock architecture in MediaTek like below
|
||||||
|
PLLs -->
|
||||||
|
dividers -->
|
||||||
|
muxes
|
||||||
|
-->
|
||||||
|
clock gate
|
||||||
|
|
||||||
|
The devices provide clock gate control in different IP blocks.
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
items:
|
||||||
|
- enum:
|
||||||
|
- mediatek,mt8186-imp_iic_wrap
|
||||||
|
- mediatek,mt8186-mfgsys
|
||||||
|
- mediatek,mt8186-wpesys
|
||||||
|
- mediatek,mt8186-imgsys1
|
||||||
|
- mediatek,mt8186-imgsys2
|
||||||
|
- mediatek,mt8186-vdecsys
|
||||||
|
- mediatek,mt8186-vencsys
|
||||||
|
- mediatek,mt8186-camsys
|
||||||
|
- mediatek,mt8186-camsys_rawa
|
||||||
|
- mediatek,mt8186-camsys_rawb
|
||||||
|
- mediatek,mt8186-mdpsys
|
||||||
|
- mediatek,mt8186-ipesys
|
||||||
|
reg:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
'#clock-cells':
|
||||||
|
const: 1
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- reg
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
imp_iic_wrap: clock-controller@11017000 {
|
||||||
|
compatible = "mediatek,mt8186-imp_iic_wrap";
|
||||||
|
reg = <0x11017000 0x1000>;
|
||||||
|
#clock-cells = <1>;
|
||||||
|
};
|
@ -0,0 +1,54 @@
|
|||||||
|
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: "http://devicetree.org/schemas/arm/mediatek/mediatek,mt8186-sys-clock.yaml#"
|
||||||
|
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
|
||||||
|
|
||||||
|
title: MediaTek System Clock Controller for MT8186
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Chun-Jie Chen <chun-jie.chen@mediatek.com>
|
||||||
|
|
||||||
|
description: |
|
||||||
|
The clock architecture in MediaTek like below
|
||||||
|
PLLs -->
|
||||||
|
dividers -->
|
||||||
|
muxes
|
||||||
|
-->
|
||||||
|
clock gate
|
||||||
|
|
||||||
|
The apmixedsys provides most of PLLs which generated from SoC 26m.
|
||||||
|
The topckgen provides dividers and muxes which provide the clock source to other IP blocks.
|
||||||
|
The infracfg_ao provides clock gate in peripheral and infrastructure IP blocks.
|
||||||
|
The mcusys provides mux control to select the clock source in AP MCU.
|
||||||
|
The device nodes also provide the system control capacity for configuration.
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
items:
|
||||||
|
- enum:
|
||||||
|
- mediatek,mt8186-mcusys
|
||||||
|
- mediatek,mt8186-topckgen
|
||||||
|
- mediatek,mt8186-infracfg_ao
|
||||||
|
- mediatek,mt8186-apmixedsys
|
||||||
|
- const: syscon
|
||||||
|
|
||||||
|
reg:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
'#clock-cells':
|
||||||
|
const: 1
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- reg
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
topckgen: syscon@10000000 {
|
||||||
|
compatible = "mediatek,mt8186-topckgen", "syscon";
|
||||||
|
reg = <0x10000000 0x1000>;
|
||||||
|
#clock-cells = <1>;
|
||||||
|
};
|
@ -0,0 +1,58 @@
|
|||||||
|
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/clock/airoha,en7523-scu.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: EN7523 Clock Device Tree Bindings
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Felix Fietkau <nbd@nbd.name>
|
||||||
|
- John Crispin <nbd@nbd.name>
|
||||||
|
|
||||||
|
description: |
|
||||||
|
This node defines the System Control Unit of the EN7523 SoC,
|
||||||
|
a collection of registers configuring many different aspects of the SoC.
|
||||||
|
|
||||||
|
The clock driver uses it to read and configure settings of the
|
||||||
|
PLL controller, which provides clocks for the CPU, the bus and
|
||||||
|
other SoC internal peripherals.
|
||||||
|
|
||||||
|
Each clock is assigned an identifier and client nodes use this identifier
|
||||||
|
to specify which clock they consume.
|
||||||
|
|
||||||
|
All these identifiers can be found in:
|
||||||
|
[1]: <include/dt-bindings/clock/en7523-clk.h>.
|
||||||
|
|
||||||
|
The clocks are provided inside a system controller node.
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
items:
|
||||||
|
- const: airoha,en7523-scu
|
||||||
|
|
||||||
|
reg:
|
||||||
|
maxItems: 2
|
||||||
|
|
||||||
|
"#clock-cells":
|
||||||
|
description:
|
||||||
|
The first cell indicates the clock number, see [1] for available
|
||||||
|
clocks.
|
||||||
|
const: 1
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- reg
|
||||||
|
- '#clock-cells'
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
#include <dt-bindings/clock/en7523-clk.h>
|
||||||
|
scu: system-controller@1fa20000 {
|
||||||
|
compatible = "airoha,en7523-scu";
|
||||||
|
reg = <0x1fa20000 0x400>,
|
||||||
|
<0x1fb00000 0x1000>;
|
||||||
|
#clock-cells = <1>;
|
||||||
|
};
|
@ -1,186 +1,2 @@
|
|||||||
This binding is a work-in-progress, and are based on some experimental
|
This file has moved to the clock binding schema:
|
||||||
work by benh[1].
|
https://github.com/devicetree-org/dt-schema/blob/main/dtschema/schemas/clock/clock.yaml
|
||||||
|
|
||||||
Sources of clock signal can be represented by any node in the device
|
|
||||||
tree. Those nodes are designated as clock providers. Clock consumer
|
|
||||||
nodes use a phandle and clock specifier pair to connect clock provider
|
|
||||||
outputs to clock inputs. Similar to the gpio specifiers, a clock
|
|
||||||
specifier is an array of zero, one or more cells identifying the clock
|
|
||||||
output on a device. The length of a clock specifier is defined by the
|
|
||||||
value of a #clock-cells property in the clock provider node.
|
|
||||||
|
|
||||||
[1] https://patchwork.ozlabs.org/patch/31551/
|
|
||||||
|
|
||||||
==Clock providers==
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
#clock-cells: Number of cells in a clock specifier; Typically 0 for nodes
|
|
||||||
with a single clock output and 1 for nodes with multiple
|
|
||||||
clock outputs.
|
|
||||||
|
|
||||||
Optional properties:
|
|
||||||
clock-output-names: Recommended to be a list of strings of clock output signal
|
|
||||||
names indexed by the first cell in the clock specifier.
|
|
||||||
However, the meaning of clock-output-names is domain
|
|
||||||
specific to the clock provider, and is only provided to
|
|
||||||
encourage using the same meaning for the majority of clock
|
|
||||||
providers. This format may not work for clock providers
|
|
||||||
using a complex clock specifier format. In those cases it
|
|
||||||
is recommended to omit this property and create a binding
|
|
||||||
specific names property.
|
|
||||||
|
|
||||||
Clock consumer nodes must never directly reference
|
|
||||||
the provider's clock-output-names property.
|
|
||||||
|
|
||||||
For example:
|
|
||||||
|
|
||||||
oscillator {
|
|
||||||
#clock-cells = <1>;
|
|
||||||
clock-output-names = "ckil", "ckih";
|
|
||||||
};
|
|
||||||
|
|
||||||
- this node defines a device with two clock outputs, the first named
|
|
||||||
"ckil" and the second named "ckih". Consumer nodes always reference
|
|
||||||
clocks by index. The names should reflect the clock output signal
|
|
||||||
names for the device.
|
|
||||||
|
|
||||||
clock-indices: If the identifying number for the clocks in the node
|
|
||||||
is not linear from zero, then this allows the mapping of
|
|
||||||
identifiers into the clock-output-names array.
|
|
||||||
|
|
||||||
For example, if we have two clocks <&oscillator 1> and <&oscillator 3>:
|
|
||||||
|
|
||||||
oscillator {
|
|
||||||
compatible = "myclocktype";
|
|
||||||
#clock-cells = <1>;
|
|
||||||
clock-indices = <1>, <3>;
|
|
||||||
clock-output-names = "clka", "clkb";
|
|
||||||
}
|
|
||||||
|
|
||||||
This ensures we do not have any empty strings in clock-output-names
|
|
||||||
|
|
||||||
|
|
||||||
==Clock consumers==
|
|
||||||
|
|
||||||
Required properties:
|
|
||||||
clocks: List of phandle and clock specifier pairs, one pair
|
|
||||||
for each clock input to the device. Note: if the
|
|
||||||
clock provider specifies '0' for #clock-cells, then
|
|
||||||
only the phandle portion of the pair will appear.
|
|
||||||
|
|
||||||
Optional properties:
|
|
||||||
clock-names: List of clock input name strings sorted in the same
|
|
||||||
order as the clocks property. Consumers drivers
|
|
||||||
will use clock-names to match clock input names
|
|
||||||
with clocks specifiers.
|
|
||||||
clock-ranges: Empty property indicating that child nodes can inherit named
|
|
||||||
clocks from this node. Useful for bus nodes to provide a
|
|
||||||
clock to their children.
|
|
||||||
|
|
||||||
For example:
|
|
||||||
|
|
||||||
device {
|
|
||||||
clocks = <&osc 1>, <&ref 0>;
|
|
||||||
clock-names = "baud", "register";
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
This represents a device with two clock inputs, named "baud" and "register".
|
|
||||||
The baud clock is connected to output 1 of the &osc device, and the register
|
|
||||||
clock is connected to output 0 of the &ref.
|
|
||||||
|
|
||||||
==Example==
|
|
||||||
|
|
||||||
/* external oscillator */
|
|
||||||
osc: oscillator {
|
|
||||||
compatible = "fixed-clock";
|
|
||||||
#clock-cells = <0>;
|
|
||||||
clock-frequency = <32678>;
|
|
||||||
clock-output-names = "osc";
|
|
||||||
};
|
|
||||||
|
|
||||||
/* phase-locked-loop device, generates a higher frequency clock
|
|
||||||
* from the external oscillator reference */
|
|
||||||
pll: pll@4c000 {
|
|
||||||
compatible = "vendor,some-pll-interface"
|
|
||||||
#clock-cells = <1>;
|
|
||||||
clocks = <&osc 0>;
|
|
||||||
clock-names = "ref";
|
|
||||||
reg = <0x4c000 0x1000>;
|
|
||||||
clock-output-names = "pll", "pll-switched";
|
|
||||||
};
|
|
||||||
|
|
||||||
/* UART, using the low frequency oscillator for the baud clock,
|
|
||||||
* and the high frequency switched PLL output for register
|
|
||||||
* clocking */
|
|
||||||
uart@a000 {
|
|
||||||
compatible = "fsl,imx-uart";
|
|
||||||
reg = <0xa000 0x1000>;
|
|
||||||
interrupts = <33>;
|
|
||||||
clocks = <&osc 0>, <&pll 1>;
|
|
||||||
clock-names = "baud", "register";
|
|
||||||
};
|
|
||||||
|
|
||||||
This DT fragment defines three devices: an external oscillator to provide a
|
|
||||||
low-frequency reference clock, a PLL device to generate a higher frequency
|
|
||||||
clock signal, and a UART.
|
|
||||||
|
|
||||||
* The oscillator is fixed-frequency, and provides one clock output, named "osc".
|
|
||||||
* The PLL is both a clock provider and a clock consumer. It uses the clock
|
|
||||||
signal generated by the external oscillator, and provides two output signals
|
|
||||||
("pll" and "pll-switched").
|
|
||||||
* The UART has its baud clock connected the external oscillator and its
|
|
||||||
register clock connected to the PLL clock (the "pll-switched" signal)
|
|
||||||
|
|
||||||
==Assigned clock parents and rates==
|
|
||||||
|
|
||||||
Some platforms may require initial configuration of default parent clocks
|
|
||||||
and clock frequencies. Such a configuration can be specified in a device tree
|
|
||||||
node through assigned-clocks, assigned-clock-parents and assigned-clock-rates
|
|
||||||
properties. The assigned-clock-parents property should contain a list of parent
|
|
||||||
clocks in the form of a phandle and clock specifier pair and the
|
|
||||||
assigned-clock-rates property should contain a list of frequencies in Hz. Both
|
|
||||||
these properties should correspond to the clocks listed in the assigned-clocks
|
|
||||||
property.
|
|
||||||
|
|
||||||
To skip setting parent or rate of a clock its corresponding entry should be
|
|
||||||
set to 0, or can be omitted if it is not followed by any non-zero entry.
|
|
||||||
|
|
||||||
uart@a000 {
|
|
||||||
compatible = "fsl,imx-uart";
|
|
||||||
reg = <0xa000 0x1000>;
|
|
||||||
...
|
|
||||||
clocks = <&osc 0>, <&pll 1>;
|
|
||||||
clock-names = "baud", "register";
|
|
||||||
|
|
||||||
assigned-clocks = <&clkcon 0>, <&pll 2>;
|
|
||||||
assigned-clock-parents = <&pll 2>;
|
|
||||||
assigned-clock-rates = <0>, <460800>;
|
|
||||||
};
|
|
||||||
|
|
||||||
In this example the <&pll 2> clock is set as parent of clock <&clkcon 0> and
|
|
||||||
the <&pll 2> clock is assigned a frequency value of 460800 Hz.
|
|
||||||
|
|
||||||
Configuring a clock's parent and rate through the device node that consumes
|
|
||||||
the clock can be done only for clocks that have a single user. Specifying
|
|
||||||
conflicting parent or rate configuration in multiple consumer nodes for
|
|
||||||
a shared clock is forbidden.
|
|
||||||
|
|
||||||
Configuration of common clocks, which affect multiple consumer devices can
|
|
||||||
be similarly specified in the clock provider node.
|
|
||||||
|
|
||||||
==Protected clocks==
|
|
||||||
|
|
||||||
Some platforms or firmwares may not fully expose all the clocks to the OS, such
|
|
||||||
as in situations where those clks are used by drivers running in ARM secure
|
|
||||||
execution levels. Such a configuration can be specified in device tree with the
|
|
||||||
protected-clocks property in the form of a clock specifier list. This property should
|
|
||||||
only be specified in the node that is providing the clocks being protected:
|
|
||||||
|
|
||||||
clock-controller@a000f000 {
|
|
||||||
compatible = "vendor,clk95;
|
|
||||||
reg = <0xa000f000 0x1000>
|
|
||||||
#clocks-cells = <1>;
|
|
||||||
...
|
|
||||||
protected-clocks = <UART3_CLK>, <SPI5_CLK>;
|
|
||||||
};
|
|
||||||
|
@ -20,12 +20,10 @@ description: |
|
|||||||
See also:
|
See also:
|
||||||
- dt-bindings/clock/qcom,gcc-msm8960.h
|
- dt-bindings/clock/qcom,gcc-msm8960.h
|
||||||
- dt-bindings/reset/qcom,gcc-msm8960.h
|
- dt-bindings/reset/qcom,gcc-msm8960.h
|
||||||
- dt-bindings/clock/qcom,gcc-apq8084.h
|
|
||||||
- dt-bindings/reset/qcom,gcc-apq8084.h
|
|
||||||
|
|
||||||
properties:
|
properties:
|
||||||
compatible:
|
compatible:
|
||||||
const: qcom,gcc-apq8084
|
const: qcom,gcc-apq8064
|
||||||
|
|
||||||
nvmem-cells:
|
nvmem-cells:
|
||||||
minItems: 1
|
minItems: 1
|
||||||
|
@ -0,0 +1,42 @@
|
|||||||
|
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/clock/qcom,gcc-apq8084.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: Qualcomm Global Clock & Reset Controller Binding for APQ8084
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Stephen Boyd <sboyd@kernel.org>
|
||||||
|
- Taniya Das <quic_tdas@quicinc.com>
|
||||||
|
|
||||||
|
description: |
|
||||||
|
Qualcomm global clock control module which supports the clocks, resets and
|
||||||
|
power domains on APQ8084.
|
||||||
|
|
||||||
|
See also::
|
||||||
|
- dt-bindings/clock/qcom,gcc-apq8084.h
|
||||||
|
- dt-bindings/reset/qcom,gcc-apq8084.h
|
||||||
|
|
||||||
|
allOf:
|
||||||
|
- $ref: qcom,gcc.yaml#
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
const: qcom,gcc-apq8084
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
|
||||||
|
unevaluatedProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
clock-controller@fc400000 {
|
||||||
|
compatible = "qcom,gcc-apq8084";
|
||||||
|
reg = <0xfc400000 0x4000>;
|
||||||
|
#clock-cells = <1>;
|
||||||
|
#reset-cells = <1>;
|
||||||
|
#power-domain-cells = <1>;
|
||||||
|
};
|
||||||
|
...
|
128
Documentation/devicetree/bindings/clock/qcom,gcc-sc8280xp.yaml
Normal file
128
Documentation/devicetree/bindings/clock/qcom,gcc-sc8280xp.yaml
Normal file
@ -0,0 +1,128 @@
|
|||||||
|
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/clock/qcom,gcc-sc8280xp.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: Qualcomm Global Clock & Reset Controller Binding for SC8280xp
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Bjorn Andersson <bjorn.andersson@linaro.org>
|
||||||
|
|
||||||
|
description: |
|
||||||
|
Qualcomm global clock control module which supports the clocks, resets and
|
||||||
|
power domains on SC8280xp.
|
||||||
|
|
||||||
|
See also:
|
||||||
|
- include/dt-bindings/clock/qcom,gcc-sc8280xp.h
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
const: qcom,gcc-sc8280xp
|
||||||
|
|
||||||
|
clocks:
|
||||||
|
items:
|
||||||
|
- description: XO reference clock
|
||||||
|
- description: Sleep clock
|
||||||
|
- description: UFS memory first RX symbol clock
|
||||||
|
- description: UFS memory second RX symbol clock
|
||||||
|
- description: UFS memory first TX symbol clock
|
||||||
|
- description: UFS card first RX symbol clock
|
||||||
|
- description: UFS card second RX symbol clock
|
||||||
|
- description: UFS card first TX symbol clock
|
||||||
|
- description: Primary USB SuperSpeed pipe clock
|
||||||
|
- description: USB4 PHY pipegmux clock source
|
||||||
|
- description: USB4 PHY DP gmux clock source
|
||||||
|
- description: USB4 PHY sys piegmux clock source
|
||||||
|
- description: USB4 PHY PCIe pipe clock
|
||||||
|
- description: USB4 PHY router max pipe clock
|
||||||
|
- description: Primary USB4 RX0 clock
|
||||||
|
- description: Primary USB4 RX1 clock
|
||||||
|
- description: Secondary USB SuperSpeed pipe clock
|
||||||
|
- description: Second USB4 PHY pipegmux clock source
|
||||||
|
- description: Second USB4 PHY DP gmux clock source
|
||||||
|
- description: Second USB4 PHY sys pipegmux clock source
|
||||||
|
- description: Second USB4 PHY PCIe pipe clock
|
||||||
|
- description: Second USB4 PHY router max pipe clock
|
||||||
|
- description: Secondary USB4 RX0 clock
|
||||||
|
- description: Secondary USB4 RX1 clock
|
||||||
|
- description: Multiport USB first SupserSpeed pipe clock
|
||||||
|
- description: Multiport USB second SuperSpeed pipe clock
|
||||||
|
- description: PCIe 2a pipe clock
|
||||||
|
- description: PCIe 2b pipe clock
|
||||||
|
- description: PCIe 3a pipe clock
|
||||||
|
- description: PCIe 3b pipe clock
|
||||||
|
- description: PCIe 4 pipe clock
|
||||||
|
- description: First EMAC controller reference clock
|
||||||
|
- description: Second EMAC controller reference clock
|
||||||
|
|
||||||
|
'#clock-cells':
|
||||||
|
const: 1
|
||||||
|
|
||||||
|
'#reset-cells':
|
||||||
|
const: 1
|
||||||
|
|
||||||
|
'#power-domain-cells':
|
||||||
|
const: 1
|
||||||
|
|
||||||
|
reg:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
protected-clocks:
|
||||||
|
maxItems: 389
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- clocks
|
||||||
|
- reg
|
||||||
|
- '#clock-cells'
|
||||||
|
- '#reset-cells'
|
||||||
|
- '#power-domain-cells'
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||||
|
clock-controller@100000 {
|
||||||
|
compatible = "qcom,gcc-sc8280xp";
|
||||||
|
reg = <0x00100000 0x1f0000>;
|
||||||
|
clocks = <&rpmhcc RPMH_CXO_CLK>,
|
||||||
|
<&sleep_clk>,
|
||||||
|
<&ufs_phy_rx_symbol_0_clk>,
|
||||||
|
<&ufs_phy_rx_symbol_1_clk>,
|
||||||
|
<&ufs_phy_tx_symbol_0_clk>,
|
||||||
|
<&ufs_card_rx_symbol_0_clk>,
|
||||||
|
<&ufs_card_rx_symbol_1_clk>,
|
||||||
|
<&ufs_card_tx_symbol_0_clk>,
|
||||||
|
<&usb_0_ssphy>,
|
||||||
|
<&gcc_usb4_phy_pipegmux_clk_src>,
|
||||||
|
<&gcc_usb4_phy_dp_gmux_clk_src>,
|
||||||
|
<&gcc_usb4_phy_sys_pipegmux_clk_src>,
|
||||||
|
<&usb4_phy_gcc_usb4_pcie_pipe_clk>,
|
||||||
|
<&usb4_phy_gcc_usb4rtr_max_pipe_clk>,
|
||||||
|
<&qusb4phy_gcc_usb4_rx0_clk>,
|
||||||
|
<&qusb4phy_gcc_usb4_rx1_clk>,
|
||||||
|
<&usb_1_ssphy>,
|
||||||
|
<&gcc_usb4_1_phy_pipegmux_clk_src>,
|
||||||
|
<&gcc_usb4_1_phy_dp_gmux_clk_src>,
|
||||||
|
<&gcc_usb4_1_phy_sys_pipegmux_clk_src>,
|
||||||
|
<&usb4_1_phy_gcc_usb4_pcie_pipe_clk>,
|
||||||
|
<&usb4_1_phy_gcc_usb4rtr_max_pipe_clk>,
|
||||||
|
<&qusb4phy_1_gcc_usb4_rx0_clk>,
|
||||||
|
<&qusb4phy_1_gcc_usb4_rx1_clk>,
|
||||||
|
<&usb_2_ssphy>,
|
||||||
|
<&usb_3_ssphy>,
|
||||||
|
<&pcie2a_lane>,
|
||||||
|
<&pcie2b_lane>,
|
||||||
|
<&pcie3a_lane>,
|
||||||
|
<&pcie3b_lane>,
|
||||||
|
<&pcie4_lane>,
|
||||||
|
<&rxc0_ref_clk>,
|
||||||
|
<&rxc1_ref_clk>;
|
||||||
|
|
||||||
|
#clock-cells = <1>;
|
||||||
|
#reset-cells = <1>;
|
||||||
|
#power-domain-cells = <1>;
|
||||||
|
};
|
||||||
|
...
|
@ -1,63 +0,0 @@
|
|||||||
Qualcomm RPM Clock Controller Binding
|
|
||||||
------------------------------------------------
|
|
||||||
The RPM is a dedicated hardware engine for managing the shared
|
|
||||||
SoC resources in order to keep the lowest power profile. It
|
|
||||||
communicates with other hardware subsystems via shared memory
|
|
||||||
and accepts clock requests, aggregates the requests and turns
|
|
||||||
the clocks on/off or scales them on demand.
|
|
||||||
|
|
||||||
Required properties :
|
|
||||||
- compatible : shall contain only one of the following. The generic
|
|
||||||
compatible "qcom,rpmcc" should be also included.
|
|
||||||
|
|
||||||
"qcom,rpmcc-mdm9607", "qcom,rpmcc"
|
|
||||||
"qcom,rpmcc-msm8660", "qcom,rpmcc"
|
|
||||||
"qcom,rpmcc-apq8060", "qcom,rpmcc"
|
|
||||||
"qcom,rpmcc-msm8226", "qcom,rpmcc"
|
|
||||||
"qcom,rpmcc-msm8916", "qcom,rpmcc"
|
|
||||||
"qcom,rpmcc-msm8936", "qcom,rpmcc"
|
|
||||||
"qcom,rpmcc-msm8953", "qcom,rpmcc"
|
|
||||||
"qcom,rpmcc-msm8974", "qcom,rpmcc"
|
|
||||||
"qcom,rpmcc-msm8976", "qcom,rpmcc"
|
|
||||||
"qcom,rpmcc-apq8064", "qcom,rpmcc"
|
|
||||||
"qcom,rpmcc-ipq806x", "qcom,rpmcc"
|
|
||||||
"qcom,rpmcc-msm8992",·"qcom,rpmcc"
|
|
||||||
"qcom,rpmcc-msm8994",·"qcom,rpmcc"
|
|
||||||
"qcom,rpmcc-msm8996", "qcom,rpmcc"
|
|
||||||
"qcom,rpmcc-msm8998", "qcom,rpmcc"
|
|
||||||
"qcom,rpmcc-qcm2290", "qcom,rpmcc"
|
|
||||||
"qcom,rpmcc-qcs404", "qcom,rpmcc"
|
|
||||||
"qcom,rpmcc-sdm660", "qcom,rpmcc"
|
|
||||||
"qcom,rpmcc-sm6115", "qcom,rpmcc"
|
|
||||||
"qcom,rpmcc-sm6125", "qcom,rpmcc"
|
|
||||||
|
|
||||||
- #clock-cells : shall contain 1
|
|
||||||
|
|
||||||
The clock enumerators are defined in <dt-bindings/clock/qcom,rpmcc.h>
|
|
||||||
and come in pairs: FOO_CLK followed by FOO_A_CLK. The latter clock
|
|
||||||
is an "active" clock, which means that the consumer only care that the
|
|
||||||
clock is available when the apps CPU subsystem is active, i.e. not
|
|
||||||
suspended or in deep idle. If it is important that the clock keeps running
|
|
||||||
during system suspend, you need to specify the non-active clock, the one
|
|
||||||
not containing *_A_* in the enumerator name.
|
|
||||||
|
|
||||||
Example:
|
|
||||||
smd {
|
|
||||||
compatible = "qcom,smd";
|
|
||||||
|
|
||||||
rpm {
|
|
||||||
interrupts = <0 168 1>;
|
|
||||||
qcom,ipc = <&apcs 8 0>;
|
|
||||||
qcom,smd-edge = <15>;
|
|
||||||
|
|
||||||
rpm_requests {
|
|
||||||
compatible = "qcom,rpm-msm8916";
|
|
||||||
qcom,smd-channels = "rpm_requests";
|
|
||||||
|
|
||||||
rpmcc: clock-controller {
|
|
||||||
compatible = "qcom,rpmcc-msm8916", "qcom,rpmcc";
|
|
||||||
#clock-cells = <1>;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
75
Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml
Normal file
75
Documentation/devicetree/bindings/clock/qcom,rpmcc.yaml
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/clock/qcom,rpmcc.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: Qualcomm RPM Clock Controller
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Bjorn Andersson <bjorn.andersson@linaro.org>
|
||||||
|
- Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
|
||||||
|
|
||||||
|
description: |
|
||||||
|
The clock enumerators are defined in <dt-bindings/clock/qcom,rpmcc.h> and
|
||||||
|
come in pairs:: FOO_CLK followed by FOO_A_CLK. The latter clock is
|
||||||
|
an "active" clock, which means that the consumer only care that the clock is
|
||||||
|
available when the apps CPU subsystem is active, i.e. not suspended or in
|
||||||
|
deep idle. If it is important that the clock keeps running during system
|
||||||
|
suspend, you need to specify the non-active clock, the one not containing
|
||||||
|
*_A_* in the enumerator name.
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
items:
|
||||||
|
- enum:
|
||||||
|
- qcom,rpmcc-apq8060
|
||||||
|
- qcom,rpmcc-apq8064
|
||||||
|
- qcom,rpmcc-ipq806x
|
||||||
|
- qcom,rpmcc-mdm9607
|
||||||
|
- qcom,rpmcc-msm8226
|
||||||
|
- qcom,rpmcc-msm8660
|
||||||
|
- qcom,rpmcc-msm8916
|
||||||
|
- qcom,rpmcc-msm8936
|
||||||
|
- qcom,rpmcc-msm8953
|
||||||
|
- qcom,rpmcc-msm8974
|
||||||
|
- qcom,rpmcc-msm8976
|
||||||
|
- qcom,rpmcc-msm8992
|
||||||
|
- qcom,rpmcc-msm8994
|
||||||
|
- qcom,rpmcc-msm8996
|
||||||
|
- qcom,rpmcc-msm8998
|
||||||
|
- qcom,rpmcc-qcm2290
|
||||||
|
- qcom,rpmcc-qcs404
|
||||||
|
- qcom,rpmcc-sdm660
|
||||||
|
- qcom,rpmcc-sm6115
|
||||||
|
- qcom,rpmcc-sm6125
|
||||||
|
- const: qcom,rpmcc
|
||||||
|
|
||||||
|
'#clock-cells':
|
||||||
|
const: 1
|
||||||
|
|
||||||
|
clocks:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
clock-names:
|
||||||
|
const: xo
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- '#clock-cells'
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
rpm {
|
||||||
|
rpm-requests {
|
||||||
|
compatible = "qcom,rpm-msm8916";
|
||||||
|
qcom,smd-channels = "rpm_requests";
|
||||||
|
|
||||||
|
clock-controller {
|
||||||
|
compatible = "qcom,rpmcc-msm8916", "qcom,rpmcc";
|
||||||
|
#clock-cells = <1>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
@ -49,6 +49,7 @@ properties:
|
|||||||
- renesas,r8a77995-cpg-mssr # R-Car D3
|
- renesas,r8a77995-cpg-mssr # R-Car D3
|
||||||
- renesas,r8a779a0-cpg-mssr # R-Car V3U
|
- renesas,r8a779a0-cpg-mssr # R-Car V3U
|
||||||
- renesas,r8a779f0-cpg-mssr # R-Car S4-8
|
- renesas,r8a779f0-cpg-mssr # R-Car S4-8
|
||||||
|
- renesas,r8a779g0-cpg-mssr # R-Car V4H
|
||||||
|
|
||||||
reg:
|
reg:
|
||||||
maxItems: 1
|
maxItems: 1
|
||||||
|
@ -4,14 +4,15 @@
|
|||||||
$id: "http://devicetree.org/schemas/clock/renesas,rzg2l-cpg.yaml#"
|
$id: "http://devicetree.org/schemas/clock/renesas,rzg2l-cpg.yaml#"
|
||||||
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
|
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
|
||||||
|
|
||||||
title: Renesas RZ/{G2L,V2L} Clock Pulse Generator / Module Standby Mode
|
title: Renesas RZ/{G2L,V2L,V2M} Clock Pulse Generator / Module Standby Mode
|
||||||
|
|
||||||
maintainers:
|
maintainers:
|
||||||
- Geert Uytterhoeven <geert+renesas@glider.be>
|
- Geert Uytterhoeven <geert+renesas@glider.be>
|
||||||
|
|
||||||
description: |
|
description: |
|
||||||
On Renesas RZ/{G2L,V2L} SoC, the CPG (Clock Pulse Generator) and Module
|
On Renesas RZ/{G2L,V2L}-alike SoC's, the CPG (Clock Pulse Generator) and Module
|
||||||
Standby Mode share the same register block.
|
Standby Mode share the same register block. On RZ/V2M, the functionality is
|
||||||
|
similar, but does not have Clock Monitor Registers.
|
||||||
|
|
||||||
They provide the following functionalities:
|
They provide the following functionalities:
|
||||||
- The CPG block generates various core clocks,
|
- The CPG block generates various core clocks,
|
||||||
@ -23,8 +24,10 @@ description: |
|
|||||||
properties:
|
properties:
|
||||||
compatible:
|
compatible:
|
||||||
enum:
|
enum:
|
||||||
- renesas,r9a07g044-cpg # RZ/G2{L,LC}
|
- renesas,r9a07g043-cpg # RZ/G2UL{Type-1,Type-2}
|
||||||
- renesas,r9a07g054-cpg # RZ/V2L
|
- renesas,r9a07g044-cpg # RZ/G2{L,LC}
|
||||||
|
- renesas,r9a07g054-cpg # RZ/V2L
|
||||||
|
- renesas,r9a09g011-cpg # RZ/V2M
|
||||||
|
|
||||||
reg:
|
reg:
|
||||||
maxItems: 1
|
maxItems: 1
|
||||||
@ -42,9 +45,10 @@ properties:
|
|||||||
description: |
|
description: |
|
||||||
- For CPG core clocks, the two clock specifier cells must be "CPG_CORE"
|
- For CPG core clocks, the two clock specifier cells must be "CPG_CORE"
|
||||||
and a core clock reference, as defined in
|
and a core clock reference, as defined in
|
||||||
<dt-bindings/clock/r9a07g*-cpg.h>
|
<dt-bindings/clock/r9a0*-cpg.h>
|
||||||
- For module clocks, the two clock specifier cells must be "CPG_MOD" and
|
- For module clocks, the two clock specifier cells must be "CPG_MOD" and
|
||||||
a module number, as defined in the <dt-bindings/clock/r9a07g0*-cpg.h>.
|
a module number, as defined in the <dt-bindings/clock/r9a07g0*-cpg.h> or
|
||||||
|
<dt-bindings/clock/r9a09g011-cpg.h>.
|
||||||
const: 2
|
const: 2
|
||||||
|
|
||||||
'#power-domain-cells':
|
'#power-domain-cells':
|
||||||
@ -58,7 +62,7 @@ properties:
|
|||||||
'#reset-cells':
|
'#reset-cells':
|
||||||
description:
|
description:
|
||||||
The single reset specifier cell must be the module number, as defined in
|
The single reset specifier cell must be the module number, as defined in
|
||||||
the <dt-bindings/clock/r9a07g0*-cpg.h>.
|
the <dt-bindings/clock/r9a07g0*-cpg.h> or <dt-bindings/clock/r9a09g011-cpg.h>.
|
||||||
const: 1
|
const: 1
|
||||||
|
|
||||||
required:
|
required:
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
* Rockchip PX30 Clock and Reset Unit
|
|
||||||
|
|
||||||
The PX30 clock controller generates and supplies clock to various
|
|
||||||
controllers within the SoC and also implements a reset controller for SoC
|
|
||||||
peripherals.
|
|
||||||
|
|
||||||
Required Properties:
|
|
||||||
|
|
||||||
- compatible: PMU for CRU should be "rockchip,px30-pmu-cru"
|
|
||||||
- compatible: CRU should be "rockchip,px30-cru"
|
|
||||||
- reg: physical base address of the controller and length of memory mapped
|
|
||||||
region.
|
|
||||||
- clocks: A list of phandle + clock-specifier pairs for the clocks listed
|
|
||||||
in clock-names
|
|
||||||
- clock-names: Should contain the following:
|
|
||||||
- "xin24m" for both PMUCRU and CRU
|
|
||||||
- "gpll" for CRU (sourced from PMUCRU)
|
|
||||||
- #clock-cells: should be 1.
|
|
||||||
- #reset-cells: should be 1.
|
|
||||||
|
|
||||||
Optional Properties:
|
|
||||||
|
|
||||||
- rockchip,grf: phandle to the syscon managing the "general register files"
|
|
||||||
If missing, pll rates are not changeable, due to the missing pll lock status.
|
|
||||||
|
|
||||||
Each clock is assigned an identifier and client nodes can use this identifier
|
|
||||||
to specify the clock which they consume. All available clocks are defined as
|
|
||||||
preprocessor macros in the dt-bindings/clock/px30-cru.h headers and can be
|
|
||||||
used in device tree sources. Similar macros exist for the reset sources in
|
|
||||||
these files.
|
|
||||||
|
|
||||||
External clocks:
|
|
||||||
|
|
||||||
There are several clocks that are generated outside the SoC. It is expected
|
|
||||||
that they are defined using standard clock bindings with following
|
|
||||||
clock-output-names:
|
|
||||||
- "xin24m" - crystal input - required,
|
|
||||||
- "xin32k" - rtc clock - optional,
|
|
||||||
- "i2sx_clkin" - external I2S clock - optional,
|
|
||||||
- "gmac_clkin" - external GMAC clock - optional
|
|
||||||
|
|
||||||
Example: Clock controller node:
|
|
||||||
|
|
||||||
pmucru: clock-controller@ff2bc000 {
|
|
||||||
compatible = "rockchip,px30-pmucru";
|
|
||||||
reg = <0x0 0xff2bc000 0x0 0x1000>;
|
|
||||||
#clock-cells = <1>;
|
|
||||||
#reset-cells = <1>;
|
|
||||||
};
|
|
||||||
|
|
||||||
cru: clock-controller@ff2b0000 {
|
|
||||||
compatible = "rockchip,px30-cru";
|
|
||||||
reg = <0x0 0xff2b0000 0x0 0x1000>;
|
|
||||||
rockchip,grf = <&grf>;
|
|
||||||
#clock-cells = <1>;
|
|
||||||
#reset-cells = <1>;
|
|
||||||
};
|
|
||||||
|
|
||||||
Example: UART controller node that consumes the clock generated by the clock
|
|
||||||
controller:
|
|
||||||
|
|
||||||
uart0: serial@ff030000 {
|
|
||||||
compatible = "rockchip,px30-uart", "snps,dw-apb-uart";
|
|
||||||
reg = <0x0 0xff030000 0x0 0x100>;
|
|
||||||
interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
|
|
||||||
clocks = <&pmucru SCLK_UART0_PMU>, <&pmucru PCLK_UART0_PMU>;
|
|
||||||
clock-names = "baudclk", "apb_pclk";
|
|
||||||
reg-shift = <2>;
|
|
||||||
reg-io-width = <4>;
|
|
||||||
};
|
|
119
Documentation/devicetree/bindings/clock/rockchip,px30-cru.yaml
Normal file
119
Documentation/devicetree/bindings/clock/rockchip,px30-cru.yaml
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/clock/rockchip,px30-cru.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: Rockchip PX30 Clock and Reset Unit (CRU)
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Elaine Zhang <zhangqing@rock-chips.com>
|
||||||
|
- Heiko Stuebner <heiko@sntech.de>
|
||||||
|
|
||||||
|
description: |
|
||||||
|
The PX30 clock controller generates and supplies clocks to various
|
||||||
|
controllers within the SoC and also implements a reset controller for SoC
|
||||||
|
peripherals.
|
||||||
|
Each clock is assigned an identifier and client nodes can use this identifier
|
||||||
|
to specify the clock which they consume. All available clocks are defined as
|
||||||
|
preprocessor macros in the dt-bindings/clock/px30-cru.h headers and can be
|
||||||
|
used in device tree sources. Similar macros exist for the reset sources in
|
||||||
|
these files.
|
||||||
|
There are several clocks that are generated outside the SoC. It is expected
|
||||||
|
that they are defined using standard clock bindings with following
|
||||||
|
clock-output-names:
|
||||||
|
- "xin24m" - crystal input - required
|
||||||
|
- "xin32k" - rtc clock - optional
|
||||||
|
- "i2sx_clkin" - external I2S clock - optional
|
||||||
|
- "gmac_clkin" - external GMAC clock - optional
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
enum:
|
||||||
|
- rockchip,px30-cru
|
||||||
|
- rockchip,px30-pmucru
|
||||||
|
|
||||||
|
reg:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
"#clock-cells":
|
||||||
|
const: 1
|
||||||
|
|
||||||
|
"#reset-cells":
|
||||||
|
const: 1
|
||||||
|
|
||||||
|
clocks:
|
||||||
|
minItems: 1
|
||||||
|
items:
|
||||||
|
- description: Clock for both PMUCRU and CRU
|
||||||
|
- description: Clock for CRU (sourced from PMUCRU)
|
||||||
|
|
||||||
|
clock-names:
|
||||||
|
minItems: 1
|
||||||
|
items:
|
||||||
|
- const: xin24m
|
||||||
|
- const: gpll
|
||||||
|
|
||||||
|
rockchip,grf:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/phandle
|
||||||
|
description:
|
||||||
|
Phandle to the syscon managing the "general register files" (GRF),
|
||||||
|
if missing pll rates are not changeable, due to the missing pll
|
||||||
|
lock status.
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- reg
|
||||||
|
- clocks
|
||||||
|
- clock-names
|
||||||
|
- "#clock-cells"
|
||||||
|
- "#reset-cells"
|
||||||
|
|
||||||
|
allOf:
|
||||||
|
- if:
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
contains:
|
||||||
|
const: rockchip,px30-cru
|
||||||
|
|
||||||
|
then:
|
||||||
|
properties:
|
||||||
|
clocks:
|
||||||
|
minItems: 2
|
||||||
|
|
||||||
|
clock-names:
|
||||||
|
minItems: 2
|
||||||
|
|
||||||
|
else:
|
||||||
|
properties:
|
||||||
|
clocks:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
clock-names:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
#include <dt-bindings/clock/px30-cru.h>
|
||||||
|
|
||||||
|
pmucru: clock-controller@ff2bc000 {
|
||||||
|
compatible = "rockchip,px30-pmucru";
|
||||||
|
reg = <0xff2bc000 0x1000>;
|
||||||
|
clocks = <&xin24m>;
|
||||||
|
clock-names = "xin24m";
|
||||||
|
rockchip,grf = <&grf>;
|
||||||
|
#clock-cells = <1>;
|
||||||
|
#reset-cells = <1>;
|
||||||
|
};
|
||||||
|
|
||||||
|
cru: clock-controller@ff2b0000 {
|
||||||
|
compatible = "rockchip,px30-cru";
|
||||||
|
reg = <0xff2b0000 0x1000>;
|
||||||
|
clocks = <&xin24m>, <&pmucru PLL_GPLL>;
|
||||||
|
clock-names = "xin24m", "gpll";
|
||||||
|
rockchip,grf = <&grf>;
|
||||||
|
#clock-cells = <1>;
|
||||||
|
#reset-cells = <1>;
|
||||||
|
};
|
@ -1,56 +0,0 @@
|
|||||||
* Rockchip RK3036 Clock and Reset Unit
|
|
||||||
|
|
||||||
The RK3036 clock controller generates and supplies clock to various
|
|
||||||
controllers within the SoC and also implements a reset controller for SoC
|
|
||||||
peripherals.
|
|
||||||
|
|
||||||
Required Properties:
|
|
||||||
|
|
||||||
- compatible: should be "rockchip,rk3036-cru"
|
|
||||||
- reg: physical base address of the controller and length of memory mapped
|
|
||||||
region.
|
|
||||||
- #clock-cells: should be 1.
|
|
||||||
- #reset-cells: should be 1.
|
|
||||||
|
|
||||||
Optional Properties:
|
|
||||||
|
|
||||||
- rockchip,grf: phandle to the syscon managing the "general register files"
|
|
||||||
If missing pll rates are not changeable, due to the missing pll lock status.
|
|
||||||
|
|
||||||
Each clock is assigned an identifier and client nodes can use this identifier
|
|
||||||
to specify the clock which they consume. All available clocks are defined as
|
|
||||||
preprocessor macros in the dt-bindings/clock/rk3036-cru.h headers and can be
|
|
||||||
used in device tree sources. Similar macros exist for the reset sources in
|
|
||||||
these files.
|
|
||||||
|
|
||||||
External clocks:
|
|
||||||
|
|
||||||
There are several clocks that are generated outside the SoC. It is expected
|
|
||||||
that they are defined using standard clock bindings with following
|
|
||||||
clock-output-names:
|
|
||||||
- "xin24m" - crystal input - required,
|
|
||||||
- "ext_i2s" - external I2S clock - optional,
|
|
||||||
- "rmii_clkin" - external EMAC clock - optional
|
|
||||||
|
|
||||||
Example: Clock controller node:
|
|
||||||
|
|
||||||
cru: cru@20000000 {
|
|
||||||
compatible = "rockchip,rk3036-cru";
|
|
||||||
reg = <0x20000000 0x1000>;
|
|
||||||
rockchip,grf = <&grf>;
|
|
||||||
|
|
||||||
#clock-cells = <1>;
|
|
||||||
#reset-cells = <1>;
|
|
||||||
};
|
|
||||||
|
|
||||||
Example: UART controller node that consumes the clock generated by the clock
|
|
||||||
controller:
|
|
||||||
|
|
||||||
uart0: serial@20060000 {
|
|
||||||
compatible = "snps,dw-apb-uart";
|
|
||||||
reg = <0x20060000 0x100>;
|
|
||||||
interrupts = <GIC_SPI 20 IRQ_TYPE_LEVEL_HIGH>;
|
|
||||||
reg-shift = <2>;
|
|
||||||
reg-io-width = <4>;
|
|
||||||
clocks = <&cru SCLK_UART0>;
|
|
||||||
};
|
|
@ -0,0 +1,72 @@
|
|||||||
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/clock/rockchip,rk3036-cru.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: Rockchip RK3036 Clock and Reset Unit (CRU)
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Elaine Zhang <zhangqing@rock-chips.com>
|
||||||
|
- Heiko Stuebner <heiko@sntech.de>
|
||||||
|
|
||||||
|
description: |
|
||||||
|
The RK3036 clock controller generates and supplies clocks to various
|
||||||
|
controllers within the SoC and also implements a reset controller for SoC
|
||||||
|
peripherals.
|
||||||
|
Each clock is assigned an identifier and client nodes can use this identifier
|
||||||
|
to specify the clock which they consume. All available clocks are defined as
|
||||||
|
preprocessor macros in the dt-bindings/clock/rk3036-cru.h headers and can be
|
||||||
|
used in device tree sources. Similar macros exist for the reset sources in
|
||||||
|
these files.
|
||||||
|
There are several clocks that are generated outside the SoC. It is expected
|
||||||
|
that they are defined using standard clock bindings with following
|
||||||
|
clock-output-names:
|
||||||
|
- "xin24m" - crystal input - required
|
||||||
|
- "ext_i2s" - external I2S clock - optional
|
||||||
|
- "rmii_clkin" - external EMAC clock - optional
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
enum:
|
||||||
|
- rockchip,rk3036-cru
|
||||||
|
|
||||||
|
reg:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
"#clock-cells":
|
||||||
|
const: 1
|
||||||
|
|
||||||
|
"#reset-cells":
|
||||||
|
const: 1
|
||||||
|
|
||||||
|
clocks:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
clock-names:
|
||||||
|
const: xin24m
|
||||||
|
|
||||||
|
rockchip,grf:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/phandle
|
||||||
|
description:
|
||||||
|
Phandle to the syscon managing the "general register files" (GRF),
|
||||||
|
if missing pll rates are not changeable, due to the missing pll
|
||||||
|
lock status.
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- reg
|
||||||
|
- "#clock-cells"
|
||||||
|
- "#reset-cells"
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
cru: clock-controller@20000000 {
|
||||||
|
compatible = "rockchip,rk3036-cru";
|
||||||
|
reg = <0x20000000 0x1000>;
|
||||||
|
rockchip,grf = <&grf>;
|
||||||
|
#clock-cells = <1>;
|
||||||
|
#reset-cells = <1>;
|
||||||
|
};
|
@ -1,61 +0,0 @@
|
|||||||
* Rockchip RK3188/RK3066 Clock and Reset Unit
|
|
||||||
|
|
||||||
The RK3188/RK3066 clock controller generates and supplies clock to various
|
|
||||||
controllers within the SoC and also implements a reset controller for SoC
|
|
||||||
peripherals.
|
|
||||||
|
|
||||||
Required Properties:
|
|
||||||
|
|
||||||
- compatible: should be "rockchip,rk3188-cru", "rockchip,rk3188a-cru" or
|
|
||||||
"rockchip,rk3066a-cru"
|
|
||||||
- reg: physical base address of the controller and length of memory mapped
|
|
||||||
region.
|
|
||||||
- #clock-cells: should be 1.
|
|
||||||
- #reset-cells: should be 1.
|
|
||||||
|
|
||||||
Optional Properties:
|
|
||||||
|
|
||||||
- rockchip,grf: phandle to the syscon managing the "general register files"
|
|
||||||
If missing pll rates are not changeable, due to the missing pll lock status.
|
|
||||||
|
|
||||||
Each clock is assigned an identifier and client nodes can use this identifier
|
|
||||||
to specify the clock which they consume. All available clocks are defined as
|
|
||||||
preprocessor macros in the dt-bindings/clock/rk3188-cru.h and
|
|
||||||
dt-bindings/clock/rk3066-cru.h headers and can be used in device tree sources.
|
|
||||||
Similar macros exist for the reset sources in these files.
|
|
||||||
|
|
||||||
External clocks:
|
|
||||||
|
|
||||||
There are several clocks that are generated outside the SoC. It is expected
|
|
||||||
that they are defined using standard clock bindings with following
|
|
||||||
clock-output-names:
|
|
||||||
- "xin24m" - crystal input - required,
|
|
||||||
- "xin32k" - rtc clock - optional,
|
|
||||||
- "xin27m" - 27mhz crystal input on rk3066 - optional,
|
|
||||||
- "ext_hsadc" - external HSADC clock - optional,
|
|
||||||
- "ext_cif0" - external camera clock - optional,
|
|
||||||
- "ext_rmii" - external RMII clock - optional,
|
|
||||||
- "ext_jtag" - externalJTAG clock - optional
|
|
||||||
|
|
||||||
Example: Clock controller node:
|
|
||||||
|
|
||||||
cru: cru@20000000 {
|
|
||||||
compatible = "rockchip,rk3188-cru";
|
|
||||||
reg = <0x20000000 0x1000>;
|
|
||||||
rockchip,grf = <&grf>;
|
|
||||||
|
|
||||||
#clock-cells = <1>;
|
|
||||||
#reset-cells = <1>;
|
|
||||||
};
|
|
||||||
|
|
||||||
Example: UART controller node that consumes the clock generated by the clock
|
|
||||||
controller:
|
|
||||||
|
|
||||||
uart0: serial@10124000 {
|
|
||||||
compatible = "snps,dw-apb-uart";
|
|
||||||
reg = <0x10124000 0x400>;
|
|
||||||
interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
|
|
||||||
reg-shift = <2>;
|
|
||||||
reg-io-width = <1>;
|
|
||||||
clocks = <&cru SCLK_UART0>;
|
|
||||||
};
|
|
@ -0,0 +1,78 @@
|
|||||||
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/clock/rockchip,rk3188-cru.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: Rockchip RK3188/RK3066 Clock and Reset Unit (CRU)
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Elaine Zhang <zhangqing@rock-chips.com>
|
||||||
|
- Heiko Stuebner <heiko@sntech.de>
|
||||||
|
|
||||||
|
description: |
|
||||||
|
The RK3188/RK3066 clock controller generates and supplies clocks to various
|
||||||
|
controllers within the SoC and also implements a reset controller for SoC
|
||||||
|
peripherals.
|
||||||
|
Each clock is assigned an identifier and client nodes can use this identifier
|
||||||
|
to specify the clock which they consume. All available clocks are defined as
|
||||||
|
preprocessor macros in the dt-bindings/clock/rk3188-cru.h and
|
||||||
|
dt-bindings/clock/rk3066-cru.h headers and can be used in device tree sources.
|
||||||
|
Similar macros exist for the reset sources in these files.
|
||||||
|
There are several clocks that are generated outside the SoC. It is expected
|
||||||
|
that they are defined using standard clock bindings with following
|
||||||
|
clock-output-names:
|
||||||
|
- "xin24m" - crystal input - required
|
||||||
|
- "xin32k" - RTC clock - optional
|
||||||
|
- "xin27m" - 27mhz crystal input on RK3066 - optional
|
||||||
|
- "ext_hsadc" - external HSADC clock - optional
|
||||||
|
- "ext_cif0" - external camera clock - optional
|
||||||
|
- "ext_rmii" - external RMII clock - optional
|
||||||
|
- "ext_jtag" - external JTAG clock - optional
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
enum:
|
||||||
|
- rockchip,rk3066a-cru
|
||||||
|
- rockchip,rk3188-cru
|
||||||
|
- rockchip,rk3188a-cru
|
||||||
|
|
||||||
|
reg:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
"#clock-cells":
|
||||||
|
const: 1
|
||||||
|
|
||||||
|
"#reset-cells":
|
||||||
|
const: 1
|
||||||
|
|
||||||
|
clocks:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
clock-names:
|
||||||
|
const: xin24m
|
||||||
|
|
||||||
|
rockchip,grf:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/phandle
|
||||||
|
description:
|
||||||
|
Phandle to the syscon managing the "general register files" (GRF),
|
||||||
|
if missing pll rates are not changeable, due to the missing pll
|
||||||
|
lock status.
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- reg
|
||||||
|
- "#clock-cells"
|
||||||
|
- "#reset-cells"
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
cru: clock-controller@20000000 {
|
||||||
|
compatible = "rockchip,rk3188-cru";
|
||||||
|
reg = <0x20000000 0x1000>;
|
||||||
|
rockchip,grf = <&grf>;
|
||||||
|
#clock-cells = <1>;
|
||||||
|
#reset-cells = <1>;
|
||||||
|
};
|
@ -1,58 +0,0 @@
|
|||||||
* Rockchip RK3228 Clock and Reset Unit
|
|
||||||
|
|
||||||
The RK3228 clock controller generates and supplies clock to various
|
|
||||||
controllers within the SoC and also implements a reset controller for SoC
|
|
||||||
peripherals.
|
|
||||||
|
|
||||||
Required Properties:
|
|
||||||
|
|
||||||
- compatible: should be "rockchip,rk3228-cru"
|
|
||||||
- reg: physical base address of the controller and length of memory mapped
|
|
||||||
region.
|
|
||||||
- #clock-cells: should be 1.
|
|
||||||
- #reset-cells: should be 1.
|
|
||||||
|
|
||||||
Optional Properties:
|
|
||||||
|
|
||||||
- rockchip,grf: phandle to the syscon managing the "general register files"
|
|
||||||
If missing pll rates are not changeable, due to the missing pll lock status.
|
|
||||||
|
|
||||||
Each clock is assigned an identifier and client nodes can use this identifier
|
|
||||||
to specify the clock which they consume. All available clocks are defined as
|
|
||||||
preprocessor macros in the dt-bindings/clock/rk3228-cru.h headers and can be
|
|
||||||
used in device tree sources. Similar macros exist for the reset sources in
|
|
||||||
these files.
|
|
||||||
|
|
||||||
External clocks:
|
|
||||||
|
|
||||||
There are several clocks that are generated outside the SoC. It is expected
|
|
||||||
that they are defined using standard clock bindings with following
|
|
||||||
clock-output-names:
|
|
||||||
- "xin24m" - crystal input - required,
|
|
||||||
- "ext_i2s" - external I2S clock - optional,
|
|
||||||
- "ext_gmac" - external GMAC clock - optional
|
|
||||||
- "ext_hsadc" - external HSADC clock - optional
|
|
||||||
- "phy_50m_out" - output clock of the pll in the mac phy
|
|
||||||
|
|
||||||
Example: Clock controller node:
|
|
||||||
|
|
||||||
cru: cru@20000000 {
|
|
||||||
compatible = "rockchip,rk3228-cru";
|
|
||||||
reg = <0x20000000 0x1000>;
|
|
||||||
rockchip,grf = <&grf>;
|
|
||||||
|
|
||||||
#clock-cells = <1>;
|
|
||||||
#reset-cells = <1>;
|
|
||||||
};
|
|
||||||
|
|
||||||
Example: UART controller node that consumes the clock generated by the clock
|
|
||||||
controller:
|
|
||||||
|
|
||||||
uart0: serial@10110000 {
|
|
||||||
compatible = "snps,dw-apb-uart";
|
|
||||||
reg = <0x10110000 0x100>;
|
|
||||||
interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>;
|
|
||||||
reg-shift = <2>;
|
|
||||||
reg-io-width = <4>;
|
|
||||||
clocks = <&cru SCLK_UART0>;
|
|
||||||
};
|
|
@ -0,0 +1,74 @@
|
|||||||
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/clock/rockchip,rk3228-cru.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: Rockchip RK3228 Clock and Reset Unit (CRU)
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Elaine Zhang <zhangqing@rock-chips.com>
|
||||||
|
- Heiko Stuebner <heiko@sntech.de>
|
||||||
|
|
||||||
|
description: |
|
||||||
|
The RK3228 clock controller generates and supplies clocks to various
|
||||||
|
controllers within the SoC and also implements a reset controller for SoC
|
||||||
|
peripherals.
|
||||||
|
Each clock is assigned an identifier and client nodes can use this identifier
|
||||||
|
to specify the clock which they consume. All available clocks are defined as
|
||||||
|
preprocessor macros in the dt-bindings/clock/rk3228-cru.h headers and can be
|
||||||
|
used in device tree sources. Similar macros exist for the reset sources in
|
||||||
|
these files.
|
||||||
|
There are several clocks that are generated outside the SoC. It is expected
|
||||||
|
that they are defined using standard clock bindings with following
|
||||||
|
clock-output-names:
|
||||||
|
- "xin24m" - crystal input - required
|
||||||
|
- "ext_i2s" - external I2S clock - optional
|
||||||
|
- "ext_gmac" - external GMAC clock - optional
|
||||||
|
- "ext_hsadc" - external HSADC clock - optional
|
||||||
|
- "phy_50m_out" - output clock of the pll in the mac phy
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
enum:
|
||||||
|
- rockchip,rk3228-cru
|
||||||
|
|
||||||
|
reg:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
"#clock-cells":
|
||||||
|
const: 1
|
||||||
|
|
||||||
|
"#reset-cells":
|
||||||
|
const: 1
|
||||||
|
|
||||||
|
clocks:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
clock-names:
|
||||||
|
const: xin24m
|
||||||
|
|
||||||
|
rockchip,grf:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/phandle
|
||||||
|
description:
|
||||||
|
Phandle to the syscon managing the "general register files" (GRF),
|
||||||
|
if missing pll rates are not changeable, due to the missing pll
|
||||||
|
lock status.
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- reg
|
||||||
|
- "#clock-cells"
|
||||||
|
- "#reset-cells"
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
cru: clock-controller@20000000 {
|
||||||
|
compatible = "rockchip,rk3228-cru";
|
||||||
|
reg = <0x20000000 0x1000>;
|
||||||
|
rockchip,grf = <&grf>;
|
||||||
|
#clock-cells = <1>;
|
||||||
|
#reset-cells = <1>;
|
||||||
|
};
|
@ -1,67 +0,0 @@
|
|||||||
* Rockchip RK3288 Clock and Reset Unit
|
|
||||||
|
|
||||||
The RK3288 clock controller generates and supplies clock to various
|
|
||||||
controllers within the SoC and also implements a reset controller for SoC
|
|
||||||
peripherals.
|
|
||||||
|
|
||||||
A revision of this SoC is available: rk3288w. The clock tree is a bit
|
|
||||||
different so another dt-compatible is available. Noticed that it is only
|
|
||||||
setting the difference but there is no automatic revision detection. This
|
|
||||||
should be performed by bootloaders.
|
|
||||||
|
|
||||||
Required Properties:
|
|
||||||
|
|
||||||
- compatible: should be "rockchip,rk3288-cru" or "rockchip,rk3288w-cru" in
|
|
||||||
case of this revision of Rockchip rk3288.
|
|
||||||
- reg: physical base address of the controller and length of memory mapped
|
|
||||||
region.
|
|
||||||
- #clock-cells: should be 1.
|
|
||||||
- #reset-cells: should be 1.
|
|
||||||
|
|
||||||
Optional Properties:
|
|
||||||
|
|
||||||
- rockchip,grf: phandle to the syscon managing the "general register files"
|
|
||||||
If missing pll rates are not changeable, due to the missing pll lock status.
|
|
||||||
|
|
||||||
Each clock is assigned an identifier and client nodes can use this identifier
|
|
||||||
to specify the clock which they consume. All available clocks are defined as
|
|
||||||
preprocessor macros in the dt-bindings/clock/rk3288-cru.h headers and can be
|
|
||||||
used in device tree sources. Similar macros exist for the reset sources in
|
|
||||||
these files.
|
|
||||||
|
|
||||||
External clocks:
|
|
||||||
|
|
||||||
There are several clocks that are generated outside the SoC. It is expected
|
|
||||||
that they are defined using standard clock bindings with following
|
|
||||||
clock-output-names:
|
|
||||||
- "xin24m" - crystal input - required,
|
|
||||||
- "xin32k" - rtc clock - optional,
|
|
||||||
- "ext_i2s" - external I2S clock - optional,
|
|
||||||
- "ext_hsadc" - external HSADC clock - optional,
|
|
||||||
- "ext_edp_24m" - external display port clock - optional,
|
|
||||||
- "ext_vip" - external VIP clock - optional,
|
|
||||||
- "ext_isp" - external ISP clock - optional,
|
|
||||||
- "ext_jtag" - external JTAG clock - optional
|
|
||||||
|
|
||||||
Example: Clock controller node:
|
|
||||||
|
|
||||||
cru: cru@20000000 {
|
|
||||||
compatible = "rockchip,rk3188-cru";
|
|
||||||
reg = <0x20000000 0x1000>;
|
|
||||||
rockchip,grf = <&grf>;
|
|
||||||
|
|
||||||
#clock-cells = <1>;
|
|
||||||
#reset-cells = <1>;
|
|
||||||
};
|
|
||||||
|
|
||||||
Example: UART controller node that consumes the clock generated by the clock
|
|
||||||
controller:
|
|
||||||
|
|
||||||
uart0: serial@10124000 {
|
|
||||||
compatible = "snps,dw-apb-uart";
|
|
||||||
reg = <0x10124000 0x400>;
|
|
||||||
interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
|
|
||||||
reg-shift = <2>;
|
|
||||||
reg-io-width = <1>;
|
|
||||||
clocks = <&cru SCLK_UART0>;
|
|
||||||
};
|
|
@ -0,0 +1,85 @@
|
|||||||
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/clock/rockchip,rk3288-cru.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: Rockchip RK3288 Clock and Reset Unit (CRU)
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Elaine Zhang <zhangqing@rock-chips.com>
|
||||||
|
- Heiko Stuebner <heiko@sntech.de>
|
||||||
|
|
||||||
|
description: |
|
||||||
|
The RK3288 clock controller generates and supplies clocks to various
|
||||||
|
controllers within the SoC and also implements a reset controller for SoC
|
||||||
|
peripherals.
|
||||||
|
|
||||||
|
A revision of this SoC is available: rk3288w. The clock tree is a bit
|
||||||
|
different so another dt-compatible is available. Noticed that it is only
|
||||||
|
setting the difference but there is no automatic revision detection. This
|
||||||
|
should be performed by boot loaders.
|
||||||
|
|
||||||
|
Each clock is assigned an identifier and client nodes can use this identifier
|
||||||
|
to specify the clock which they consume. All available clocks are defined as
|
||||||
|
preprocessor macros in the dt-bindings/clock/rk3288-cru.h headers and can be
|
||||||
|
used in device tree sources. Similar macros exist for the reset sources in
|
||||||
|
these files.
|
||||||
|
|
||||||
|
There are several clocks that are generated outside the SoC. It is expected
|
||||||
|
that they are defined using standard clock bindings with following
|
||||||
|
clock-output-names:
|
||||||
|
- "xin24m" - crystal input - required,
|
||||||
|
- "xin32k" - rtc clock - optional,
|
||||||
|
- "ext_i2s" - external I2S clock - optional,
|
||||||
|
- "ext_hsadc" - external HSADC clock - optional,
|
||||||
|
- "ext_edp_24m" - external display port clock - optional,
|
||||||
|
- "ext_vip" - external VIP clock - optional,
|
||||||
|
- "ext_isp" - external ISP clock - optional,
|
||||||
|
- "ext_jtag" - external JTAG clock - optional
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
enum:
|
||||||
|
- rockchip,rk3288-cru
|
||||||
|
- rockchip,rk3288w-cru
|
||||||
|
|
||||||
|
reg:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
"#clock-cells":
|
||||||
|
const: 1
|
||||||
|
|
||||||
|
"#reset-cells":
|
||||||
|
const: 1
|
||||||
|
|
||||||
|
clocks:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
clock-names:
|
||||||
|
const: xin24m
|
||||||
|
|
||||||
|
rockchip,grf:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/phandle
|
||||||
|
description:
|
||||||
|
Phandle to the syscon managing the "general register files" (GRF),
|
||||||
|
if missing pll rates are not changeable, due to the missing pll
|
||||||
|
lock status.
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- reg
|
||||||
|
- "#clock-cells"
|
||||||
|
- "#reset-cells"
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
cru: clock-controller@ff760000 {
|
||||||
|
compatible = "rockchip,rk3288-cru";
|
||||||
|
reg = <0xff760000 0x1000>;
|
||||||
|
rockchip,grf = <&grf>;
|
||||||
|
#clock-cells = <1>;
|
||||||
|
#reset-cells = <1>;
|
||||||
|
};
|
@ -1,60 +0,0 @@
|
|||||||
* Rockchip RK3308 Clock and Reset Unit
|
|
||||||
|
|
||||||
The RK3308 clock controller generates and supplies clock to various
|
|
||||||
controllers within the SoC and also implements a reset controller for SoC
|
|
||||||
peripherals.
|
|
||||||
|
|
||||||
Required Properties:
|
|
||||||
|
|
||||||
- compatible: CRU should be "rockchip,rk3308-cru"
|
|
||||||
- reg: physical base address of the controller and length of memory mapped
|
|
||||||
region.
|
|
||||||
- #clock-cells: should be 1.
|
|
||||||
- #reset-cells: should be 1.
|
|
||||||
|
|
||||||
Optional Properties:
|
|
||||||
|
|
||||||
- rockchip,grf: phandle to the syscon managing the "general register files"
|
|
||||||
If missing, pll rates are not changeable, due to the missing pll lock status.
|
|
||||||
|
|
||||||
Each clock is assigned an identifier and client nodes can use this identifier
|
|
||||||
to specify the clock which they consume. All available clocks are defined as
|
|
||||||
preprocessor macros in the dt-bindings/clock/rk3308-cru.h headers and can be
|
|
||||||
used in device tree sources. Similar macros exist for the reset sources in
|
|
||||||
these files.
|
|
||||||
|
|
||||||
External clocks:
|
|
||||||
|
|
||||||
There are several clocks that are generated outside the SoC. It is expected
|
|
||||||
that they are defined using standard clock bindings with following
|
|
||||||
clock-output-names:
|
|
||||||
- "xin24m" - crystal input - required,
|
|
||||||
- "xin32k" - rtc clock - optional,
|
|
||||||
- "mclk_i2s0_8ch_in", "mclk_i2s1_8ch_in", "mclk_i2s2_8ch_in",
|
|
||||||
"mclk_i2s3_8ch_in", "mclk_i2s0_2ch_in",
|
|
||||||
"mclk_i2s1_2ch_in" - external I2S or SPDIF clock - optional,
|
|
||||||
- "mac_clkin" - external MAC clock - optional
|
|
||||||
|
|
||||||
Example: Clock controller node:
|
|
||||||
|
|
||||||
cru: clock-controller@ff500000 {
|
|
||||||
compatible = "rockchip,rk3308-cru";
|
|
||||||
reg = <0x0 0xff500000 0x0 0x1000>;
|
|
||||||
rockchip,grf = <&grf>;
|
|
||||||
#clock-cells = <1>;
|
|
||||||
#reset-cells = <1>;
|
|
||||||
};
|
|
||||||
|
|
||||||
Example: UART controller node that consumes the clock generated by the clock
|
|
||||||
controller:
|
|
||||||
|
|
||||||
uart0: serial@ff0a0000 {
|
|
||||||
compatible = "rockchip,rk3308-uart", "snps,dw-apb-uart";
|
|
||||||
reg = <0x0 0xff0a0000 0x0 0x100>;
|
|
||||||
interrupts = <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>;
|
|
||||||
clocks = <&cru SCLK_UART0>, <&cru PCLK_UART0>;
|
|
||||||
clock-names = "baudclk", "apb_pclk";
|
|
||||||
reg-shift = <2>;
|
|
||||||
reg-io-width = <4>;
|
|
||||||
status = "disabled";
|
|
||||||
};
|
|
@ -0,0 +1,76 @@
|
|||||||
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/clock/rockchip,rk3308-cru.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: Rockchip RK3308 Clock and Reset Unit (CRU)
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Elaine Zhang <zhangqing@rock-chips.com>
|
||||||
|
- Heiko Stuebner <heiko@sntech.de>
|
||||||
|
|
||||||
|
description: |
|
||||||
|
The RK3308 clock controller generates and supplies clocks to various
|
||||||
|
controllers within the SoC and also implements a reset controller for SoC
|
||||||
|
peripherals.
|
||||||
|
Each clock is assigned an identifier and client nodes can use this identifier
|
||||||
|
to specify the clock which they consume. All available clocks are defined as
|
||||||
|
preprocessor macros in the dt-bindings/clock/rk3308-cru.h headers and can be
|
||||||
|
used in device tree sources. Similar macros exist for the reset sources in
|
||||||
|
these files.
|
||||||
|
There are several clocks that are generated outside the SoC. It is expected
|
||||||
|
that they are defined using standard clock bindings with following
|
||||||
|
clock-output-names:
|
||||||
|
- "xin24m" - crystal input - required
|
||||||
|
- "xin32k" - rtc clock - optional
|
||||||
|
- "mclk_i2s0_8ch_in", "mclk_i2s1_8ch_in",
|
||||||
|
"mclk_i2s2_8ch_in", "mclk_i2s3_8ch_in",
|
||||||
|
"mclk_i2s0_2ch_in", "mclk_i2s1_2ch_in" - external I2S or
|
||||||
|
SPDIF clock - optional
|
||||||
|
- "mac_clkin" - external MAC clock - optional
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
enum:
|
||||||
|
- rockchip,rk3308-cru
|
||||||
|
|
||||||
|
reg:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
"#clock-cells":
|
||||||
|
const: 1
|
||||||
|
|
||||||
|
"#reset-cells":
|
||||||
|
const: 1
|
||||||
|
|
||||||
|
clocks:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
clock-names:
|
||||||
|
const: xin24m
|
||||||
|
|
||||||
|
rockchip,grf:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/phandle
|
||||||
|
description:
|
||||||
|
Phandle to the syscon managing the "general register files" (GRF),
|
||||||
|
if missing pll rates are not changeable, due to the missing pll
|
||||||
|
lock status.
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- reg
|
||||||
|
- "#clock-cells"
|
||||||
|
- "#reset-cells"
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
cru: clock-controller@ff500000 {
|
||||||
|
compatible = "rockchip,rk3308-cru";
|
||||||
|
reg = <0xff500000 0x1000>;
|
||||||
|
rockchip,grf = <&grf>;
|
||||||
|
#clock-cells = <1>;
|
||||||
|
#reset-cells = <1>;
|
||||||
|
};
|
@ -1,61 +0,0 @@
|
|||||||
* Rockchip RK3368 Clock and Reset Unit
|
|
||||||
|
|
||||||
The RK3368 clock controller generates and supplies clock to various
|
|
||||||
controllers within the SoC and also implements a reset controller for SoC
|
|
||||||
peripherals.
|
|
||||||
|
|
||||||
Required Properties:
|
|
||||||
|
|
||||||
- compatible: should be "rockchip,rk3368-cru"
|
|
||||||
- reg: physical base address of the controller and length of memory mapped
|
|
||||||
region.
|
|
||||||
- #clock-cells: should be 1.
|
|
||||||
- #reset-cells: should be 1.
|
|
||||||
|
|
||||||
Optional Properties:
|
|
||||||
|
|
||||||
- rockchip,grf: phandle to the syscon managing the "general register files"
|
|
||||||
If missing, pll rates are not changeable, due to the missing pll lock status.
|
|
||||||
|
|
||||||
Each clock is assigned an identifier and client nodes can use this identifier
|
|
||||||
to specify the clock which they consume. All available clocks are defined as
|
|
||||||
preprocessor macros in the dt-bindings/clock/rk3368-cru.h headers and can be
|
|
||||||
used in device tree sources. Similar macros exist for the reset sources in
|
|
||||||
these files.
|
|
||||||
|
|
||||||
External clocks:
|
|
||||||
|
|
||||||
There are several clocks that are generated outside the SoC. It is expected
|
|
||||||
that they are defined using standard clock bindings with following
|
|
||||||
clock-output-names:
|
|
||||||
- "xin24m" - crystal input - required,
|
|
||||||
- "xin32k" - rtc clock - optional,
|
|
||||||
- "ext_i2s" - external I2S clock - optional,
|
|
||||||
- "ext_gmac" - external GMAC clock - optional
|
|
||||||
- "ext_hsadc" - external HSADC clock - optional,
|
|
||||||
- "ext_isp" - external ISP clock - optional,
|
|
||||||
- "ext_jtag" - external JTAG clock - optional
|
|
||||||
- "ext_vip" - external VIP clock - optional,
|
|
||||||
- "usbotg_out" - output clock of the pll in the otg phy
|
|
||||||
|
|
||||||
Example: Clock controller node:
|
|
||||||
|
|
||||||
cru: clock-controller@ff760000 {
|
|
||||||
compatible = "rockchip,rk3368-cru";
|
|
||||||
reg = <0x0 0xff760000 0x0 0x1000>;
|
|
||||||
rockchip,grf = <&grf>;
|
|
||||||
#clock-cells = <1>;
|
|
||||||
#reset-cells = <1>;
|
|
||||||
};
|
|
||||||
|
|
||||||
Example: UART controller node that consumes the clock generated by the clock
|
|
||||||
controller:
|
|
||||||
|
|
||||||
uart0: serial@10124000 {
|
|
||||||
compatible = "snps,dw-apb-uart";
|
|
||||||
reg = <0x10124000 0x400>;
|
|
||||||
interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>;
|
|
||||||
reg-shift = <2>;
|
|
||||||
reg-io-width = <1>;
|
|
||||||
clocks = <&cru SCLK_UART0>;
|
|
||||||
};
|
|
@ -0,0 +1,78 @@
|
|||||||
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/clock/rockchip,rk3368-cru.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: Rockchip RK3368 Clock and Reset Unit (CRU)
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Elaine Zhang <zhangqing@rock-chips.com>
|
||||||
|
- Heiko Stuebner <heiko@sntech.de>
|
||||||
|
|
||||||
|
description: |
|
||||||
|
The RK3368 clock controller generates and supplies clocks to various
|
||||||
|
controllers within the SoC and also implements a reset controller for SoC
|
||||||
|
peripherals.
|
||||||
|
Each clock is assigned an identifier and client nodes can use this identifier
|
||||||
|
to specify the clock which they consume. All available clocks are defined as
|
||||||
|
preprocessor macros in the dt-bindings/clock/rk3368-cru.h headers and can be
|
||||||
|
used in device tree sources. Similar macros exist for the reset sources in
|
||||||
|
these files.
|
||||||
|
There are several clocks that are generated outside the SoC. It is expected
|
||||||
|
that they are defined using standard clock bindings with following
|
||||||
|
clock-output-names:
|
||||||
|
- "xin24m" - crystal input - required
|
||||||
|
- "xin32k" - rtc clock - optional
|
||||||
|
- "ext_i2s" - external I2S clock - optional
|
||||||
|
- "ext_gmac" - external GMAC clock - optional
|
||||||
|
- "ext_hsadc" - external HSADC clock - optional
|
||||||
|
- "ext_isp" - external ISP clock - optional
|
||||||
|
- "ext_jtag" - external JTAG clock - optional
|
||||||
|
- "ext_vip" - external VIP clock - optional
|
||||||
|
- "usbotg_out" - output clock of the pll in the otg phy
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
enum:
|
||||||
|
- rockchip,rk3368-cru
|
||||||
|
|
||||||
|
reg:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
"#clock-cells":
|
||||||
|
const: 1
|
||||||
|
|
||||||
|
"#reset-cells":
|
||||||
|
const: 1
|
||||||
|
|
||||||
|
clocks:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
clock-names:
|
||||||
|
const: xin24m
|
||||||
|
|
||||||
|
rockchip,grf:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/phandle
|
||||||
|
description:
|
||||||
|
Phandle to the syscon managing the "general register files" (GRF),
|
||||||
|
if missing pll rates are not changeable, due to the missing pll
|
||||||
|
lock status.
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- reg
|
||||||
|
- "#clock-cells"
|
||||||
|
- "#reset-cells"
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
cru: clock-controller@ff760000 {
|
||||||
|
compatible = "rockchip,rk3368-cru";
|
||||||
|
reg = <0xff760000 0x1000>;
|
||||||
|
rockchip,grf = <&grf>;
|
||||||
|
#clock-cells = <1>;
|
||||||
|
#reset-cells = <1>;
|
||||||
|
};
|
@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
|||||||
title: Rockchip RK3399 Clock and Reset Unit
|
title: Rockchip RK3399 Clock and Reset Unit
|
||||||
|
|
||||||
maintainers:
|
maintainers:
|
||||||
- Xing Zheng <zhengxing@rock-chips.com>
|
- Elaine Zhang <zhangqing@rock-chips.com>
|
||||||
- Heiko Stuebner <heiko@sntech.de>
|
- Heiko Stuebner <heiko@sntech.de>
|
||||||
|
|
||||||
description: |
|
description: |
|
||||||
@ -22,11 +22,11 @@ description: |
|
|||||||
There are several clocks that are generated outside the SoC. It is expected
|
There are several clocks that are generated outside the SoC. It is expected
|
||||||
that they are defined using standard clock bindings with following
|
that they are defined using standard clock bindings with following
|
||||||
clock-output-names:
|
clock-output-names:
|
||||||
- "xin24m" - crystal input - required,
|
- "xin24m" - crystal input - required,
|
||||||
- "xin32k" - rtc clock - optional,
|
- "xin32k" - rtc clock - optional,
|
||||||
- "clkin_gmac" - external GMAC clock - optional,
|
- "clkin_gmac" - external GMAC clock - optional,
|
||||||
- "clkin_i2s" - external I2S clock - optional,
|
- "clkin_i2s" - external I2S clock - optional,
|
||||||
- "pclkin_cif" - external ISP clock - optional,
|
- "pclkin_cif" - external ISP clock - optional,
|
||||||
- "clk_usbphy0_480m" - output clock of the pll in the usbphy0
|
- "clk_usbphy0_480m" - output clock of the pll in the usbphy0
|
||||||
- "clk_usbphy1_480m" - output clock of the pll in the usbphy1
|
- "clk_usbphy1_480m" - output clock of the pll in the usbphy1
|
||||||
|
|
||||||
@ -46,24 +46,15 @@ properties:
|
|||||||
const: 1
|
const: 1
|
||||||
|
|
||||||
clocks:
|
clocks:
|
||||||
minItems: 1
|
maxItems: 1
|
||||||
|
|
||||||
assigned-clocks:
|
clock-names:
|
||||||
minItems: 1
|
const: xin24m
|
||||||
maxItems: 64
|
|
||||||
|
|
||||||
assigned-clock-parents:
|
|
||||||
minItems: 1
|
|
||||||
maxItems: 64
|
|
||||||
|
|
||||||
assigned-clock-rates:
|
|
||||||
minItems: 1
|
|
||||||
maxItems: 64
|
|
||||||
|
|
||||||
rockchip,grf:
|
rockchip,grf:
|
||||||
$ref: /schemas/types.yaml#/definitions/phandle
|
$ref: /schemas/types.yaml#/definitions/phandle
|
||||||
description: >
|
description:
|
||||||
phandle to the syscon managing the "general register files". It is used
|
Phandle to the syscon managing the "general register files". It is used
|
||||||
for GRF muxes, if missing any muxes present in the GRF will not be
|
for GRF muxes, if missing any muxes present in the GRF will not be
|
||||||
available.
|
available.
|
||||||
|
|
||||||
@ -77,7 +68,7 @@ additionalProperties: false
|
|||||||
|
|
||||||
examples:
|
examples:
|
||||||
- |
|
- |
|
||||||
pmucru: pmu-clock-controller@ff750000 {
|
pmucru: clock-controller@ff750000 {
|
||||||
compatible = "rockchip,rk3399-pmucru";
|
compatible = "rockchip,rk3399-pmucru";
|
||||||
reg = <0xff750000 0x1000>;
|
reg = <0xff750000 0x1000>;
|
||||||
#clock-cells = <1>;
|
#clock-cells = <1>;
|
||||||
|
@ -34,6 +34,19 @@ properties:
|
|||||||
"#reset-cells":
|
"#reset-cells":
|
||||||
const: 1
|
const: 1
|
||||||
|
|
||||||
|
clocks:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
clock-names:
|
||||||
|
const: xin24m
|
||||||
|
|
||||||
|
rockchip,grf:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/phandle
|
||||||
|
description:
|
||||||
|
Phandle to the syscon managing the "general register files" (GRF),
|
||||||
|
if missing pll rates are not changeable, due to the missing pll
|
||||||
|
lock status.
|
||||||
|
|
||||||
required:
|
required:
|
||||||
- compatible
|
- compatible
|
||||||
- reg
|
- reg
|
||||||
|
@ -1,59 +0,0 @@
|
|||||||
* Rockchip RV1108 Clock and Reset Unit
|
|
||||||
|
|
||||||
The RV1108 clock controller generates and supplies clock to various
|
|
||||||
controllers within the SoC and also implements a reset controller for SoC
|
|
||||||
peripherals.
|
|
||||||
|
|
||||||
Required Properties:
|
|
||||||
|
|
||||||
- compatible: should be "rockchip,rv1108-cru"
|
|
||||||
- reg: physical base address of the controller and length of memory mapped
|
|
||||||
region.
|
|
||||||
- #clock-cells: should be 1.
|
|
||||||
- #reset-cells: should be 1.
|
|
||||||
|
|
||||||
Optional Properties:
|
|
||||||
|
|
||||||
- rockchip,grf: phandle to the syscon managing the "general register files"
|
|
||||||
If missing pll rates are not changeable, due to the missing pll lock status.
|
|
||||||
|
|
||||||
Each clock is assigned an identifier and client nodes can use this identifier
|
|
||||||
to specify the clock which they consume. All available clocks are defined as
|
|
||||||
preprocessor macros in the dt-bindings/clock/rv1108-cru.h headers and can be
|
|
||||||
used in device tree sources. Similar macros exist for the reset sources in
|
|
||||||
these files.
|
|
||||||
|
|
||||||
External clocks:
|
|
||||||
|
|
||||||
There are several clocks that are generated outside the SoC. It is expected
|
|
||||||
that they are defined using standard clock bindings with following
|
|
||||||
clock-output-names:
|
|
||||||
- "xin24m" - crystal input - required,
|
|
||||||
- "ext_vip" - external VIP clock - optional
|
|
||||||
- "ext_i2s" - external I2S clock - optional
|
|
||||||
- "ext_gmac" - external GMAC clock - optional
|
|
||||||
- "hdmiphy" - external clock input derived from HDMI PHY - optional
|
|
||||||
- "usbphy" - external clock input derived from USB PHY - optional
|
|
||||||
|
|
||||||
Example: Clock controller node:
|
|
||||||
|
|
||||||
cru: cru@20200000 {
|
|
||||||
compatible = "rockchip,rv1108-cru";
|
|
||||||
reg = <0x20200000 0x1000>;
|
|
||||||
rockchip,grf = <&grf>;
|
|
||||||
|
|
||||||
#clock-cells = <1>;
|
|
||||||
#reset-cells = <1>;
|
|
||||||
};
|
|
||||||
|
|
||||||
Example: UART controller node that consumes the clock generated by the clock
|
|
||||||
controller:
|
|
||||||
|
|
||||||
uart0: serial@10230000 {
|
|
||||||
compatible = "rockchip,rv1108-uart", "snps,dw-apb-uart";
|
|
||||||
reg = <0x10230000 0x100>;
|
|
||||||
interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
|
|
||||||
reg-shift = <2>;
|
|
||||||
reg-io-width = <4>;
|
|
||||||
clocks = <&cru SCLK_UART0>;
|
|
||||||
};
|
|
@ -0,0 +1,75 @@
|
|||||||
|
# SPDX-License-Identifier: GPL-2.0
|
||||||
|
%YAML 1.2
|
||||||
|
---
|
||||||
|
$id: http://devicetree.org/schemas/clock/rockchip,rv1108-cru.yaml#
|
||||||
|
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||||
|
|
||||||
|
title: Rockchip RV1108 Clock and Reset Unit (CRU)
|
||||||
|
|
||||||
|
maintainers:
|
||||||
|
- Elaine Zhang <zhangqing@rock-chips.com>
|
||||||
|
- Heiko Stuebner <heiko@sntech.de>
|
||||||
|
|
||||||
|
description: |
|
||||||
|
The RV1108 clock controller generates and supplies clocks to various
|
||||||
|
controllers within the SoC and also implements a reset controller for SoC
|
||||||
|
peripherals.
|
||||||
|
Each clock is assigned an identifier and client nodes can use this identifier
|
||||||
|
to specify the clock which they consume. All available clocks are defined as
|
||||||
|
preprocessor macros in the dt-bindings/clock/rv1108-cru.h headers and can be
|
||||||
|
used in device tree sources. Similar macros exist for the reset sources in
|
||||||
|
these files.
|
||||||
|
There are several clocks that are generated outside the SoC. It is expected
|
||||||
|
that they are defined using standard clock bindings with following
|
||||||
|
clock-output-names:
|
||||||
|
- "xin24m" - crystal input - required
|
||||||
|
- "ext_vip" - external VIP clock - optional
|
||||||
|
- "ext_i2s" - external I2S clock - optional
|
||||||
|
- "ext_gmac" - external GMAC clock - optional
|
||||||
|
- "hdmiphy" - external clock input derived from HDMI PHY - optional
|
||||||
|
- "usbphy" - external clock input derived from USB PHY - optional
|
||||||
|
|
||||||
|
properties:
|
||||||
|
compatible:
|
||||||
|
enum:
|
||||||
|
- rockchip,rv1108-cru
|
||||||
|
|
||||||
|
reg:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
"#clock-cells":
|
||||||
|
const: 1
|
||||||
|
|
||||||
|
"#reset-cells":
|
||||||
|
const: 1
|
||||||
|
|
||||||
|
clocks:
|
||||||
|
maxItems: 1
|
||||||
|
|
||||||
|
clock-names:
|
||||||
|
const: xin24m
|
||||||
|
|
||||||
|
rockchip,grf:
|
||||||
|
$ref: /schemas/types.yaml#/definitions/phandle
|
||||||
|
description:
|
||||||
|
Phandle to the syscon managing the "general register files" (GRF),
|
||||||
|
if missing pll rates are not changeable, due to the missing pll
|
||||||
|
lock status.
|
||||||
|
|
||||||
|
required:
|
||||||
|
- compatible
|
||||||
|
- reg
|
||||||
|
- "#clock-cells"
|
||||||
|
- "#reset-cells"
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
cru: clock-controller@20200000 {
|
||||||
|
compatible = "rockchip,rv1108-cru";
|
||||||
|
reg = <0x20200000 0x1000>;
|
||||||
|
rockchip,grf = <&grf>;
|
||||||
|
#clock-cells = <1>;
|
||||||
|
#reset-cells = <1>;
|
||||||
|
};
|
@ -41,6 +41,7 @@ description: |
|
|||||||
|
|
||||||
The list of valid indices for STM32MP1 is available in:
|
The list of valid indices for STM32MP1 is available in:
|
||||||
include/dt-bindings/reset-controller/stm32mp1-resets.h
|
include/dt-bindings/reset-controller/stm32mp1-resets.h
|
||||||
|
include/dt-bindings/reset-controller/stm32mp13-resets.h
|
||||||
|
|
||||||
This file implements defines like:
|
This file implements defines like:
|
||||||
#define LTDC_R 3072
|
#define LTDC_R 3072
|
||||||
@ -57,6 +58,7 @@ properties:
|
|||||||
- enum:
|
- enum:
|
||||||
- st,stm32mp1-rcc-secure
|
- st,stm32mp1-rcc-secure
|
||||||
- st,stm32mp1-rcc
|
- st,stm32mp1-rcc
|
||||||
|
- st,stm32mp13-rcc
|
||||||
- const: syscon
|
- const: syscon
|
||||||
clocks: true
|
clocks: true
|
||||||
clock-names: true
|
clock-names: true
|
||||||
|
@ -109,6 +109,25 @@ properties:
|
|||||||
|
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
|
|
||||||
|
clkout-clock:
|
||||||
|
description: A subnode with three clock cells for externally routed clocks,
|
||||||
|
output clocks. These are two PRCMU-internal clocks that can be divided and
|
||||||
|
muxed out on the pads of the DB8500 SoC.
|
||||||
|
type: object
|
||||||
|
|
||||||
|
properties:
|
||||||
|
'#clock-cells':
|
||||||
|
description:
|
||||||
|
The first cell indicates which output clock we are using,
|
||||||
|
possible values are 0 (CLKOUT1) and 1 (CLKOUT2).
|
||||||
|
The second cell indicates which clock we want to use as source,
|
||||||
|
possible values are 0 thru 7, see the defines for the different
|
||||||
|
source clocks.
|
||||||
|
The third cell is a divider, legal values are 1 thru 63.
|
||||||
|
const: 3
|
||||||
|
|
||||||
|
additionalProperties: false
|
||||||
|
|
||||||
required:
|
required:
|
||||||
- compatible
|
- compatible
|
||||||
- reg
|
- reg
|
||||||
@ -119,3 +138,41 @@ required:
|
|||||||
- smp-twd-clock
|
- smp-twd-clock
|
||||||
|
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
|
|
||||||
|
examples:
|
||||||
|
- |
|
||||||
|
#include <dt-bindings/clock/ste-db8500-clkout.h>
|
||||||
|
clocks@8012 {
|
||||||
|
compatible = "stericsson,u8500-clks";
|
||||||
|
reg = <0x8012f000 0x1000>, <0x8011f000 0x1000>,
|
||||||
|
<0x8000f000 0x1000>, <0xa03ff000 0x1000>,
|
||||||
|
<0xa03cf000 0x1000>;
|
||||||
|
|
||||||
|
prcmu_clk: prcmu-clock {
|
||||||
|
#clock-cells = <1>;
|
||||||
|
};
|
||||||
|
|
||||||
|
prcc_pclk: prcc-periph-clock {
|
||||||
|
#clock-cells = <2>;
|
||||||
|
};
|
||||||
|
|
||||||
|
prcc_kclk: prcc-kernel-clock {
|
||||||
|
#clock-cells = <2>;
|
||||||
|
};
|
||||||
|
|
||||||
|
prcc_reset: prcc-reset-controller {
|
||||||
|
#reset-cells = <2>;
|
||||||
|
};
|
||||||
|
|
||||||
|
rtc_clk: rtc32k-clock {
|
||||||
|
#clock-cells = <0>;
|
||||||
|
};
|
||||||
|
|
||||||
|
smp_twd_clk: smp-twd-clock {
|
||||||
|
#clock-cells = <0>;
|
||||||
|
};
|
||||||
|
|
||||||
|
clkout_clk: clkout-clock {
|
||||||
|
#clock-cells = <3>;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
@ -15,6 +15,7 @@ properties:
|
|||||||
- enum:
|
- enum:
|
||||||
- ti,am654-ehrpwm-tbclk
|
- ti,am654-ehrpwm-tbclk
|
||||||
- ti,am64-epwm-tbclk
|
- ti,am64-epwm-tbclk
|
||||||
|
- ti,am62-epwm-tbclk
|
||||||
- const: syscon
|
- const: syscon
|
||||||
|
|
||||||
"#clock-cells":
|
"#clock-cells":
|
||||||
|
@ -47,6 +47,10 @@ properties:
|
|||||||
- qcom,rpm-qcm2290
|
- qcom,rpm-qcm2290
|
||||||
- qcom,rpm-qcs404
|
- qcom,rpm-qcs404
|
||||||
|
|
||||||
|
clock-controller:
|
||||||
|
$ref: /schemas/clock/qcom,rpmcc.yaml#
|
||||||
|
unevaluatedProperties: false
|
||||||
|
|
||||||
qcom,smd-channels:
|
qcom,smd-channels:
|
||||||
$ref: /schemas/types.yaml#/definitions/string-array
|
$ref: /schemas/types.yaml#/definitions/string-array
|
||||||
description: Channel name used for the RPM communication
|
description: Channel name used for the RPM communication
|
||||||
|
@ -131,36 +131,10 @@ static const struct platform_suspend_ops ingenic_pm_ops __maybe_unused = {
|
|||||||
|
|
||||||
static int __init ingenic_pm_init(void)
|
static int __init ingenic_pm_init(void)
|
||||||
{
|
{
|
||||||
struct device_node *cpu_node;
|
|
||||||
struct clk *cpu0_clk;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (boot_cpu_type() == CPU_XBURST) {
|
if (boot_cpu_type() == CPU_XBURST) {
|
||||||
if (IS_ENABLED(CONFIG_PM_SLEEP))
|
if (IS_ENABLED(CONFIG_PM_SLEEP))
|
||||||
suspend_set_ops(&ingenic_pm_ops);
|
suspend_set_ops(&ingenic_pm_ops);
|
||||||
_machine_halt = ingenic_halt;
|
_machine_halt = ingenic_halt;
|
||||||
|
|
||||||
/*
|
|
||||||
* Unconditionally enable the clock for the first CPU.
|
|
||||||
* This makes sure that the PLL that feeds the CPU won't be
|
|
||||||
* stopped while the kernel is running.
|
|
||||||
*/
|
|
||||||
cpu_node = of_get_cpu_node(0, NULL);
|
|
||||||
if (!cpu_node) {
|
|
||||||
pr_err("Unable to get CPU node\n");
|
|
||||||
} else {
|
|
||||||
cpu0_clk = of_clk_get(cpu_node, 0);
|
|
||||||
if (IS_ERR(cpu0_clk)) {
|
|
||||||
pr_err("Unable to get CPU0 clock\n");
|
|
||||||
return PTR_ERR(cpu0_clk);
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = clk_prepare_enable(cpu0_clk);
|
|
||||||
if (ret) {
|
|
||||||
pr_err("Unable to enable CPU0 clock\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -210,6 +210,15 @@ config COMMON_CLK_CS2000_CP
|
|||||||
help
|
help
|
||||||
If you say yes here you get support for the CS2000 clock multiplier.
|
If you say yes here you get support for the CS2000 clock multiplier.
|
||||||
|
|
||||||
|
config COMMON_CLK_EN7523
|
||||||
|
bool "Clock driver for Airoha EN7523 SoC system clocks"
|
||||||
|
depends on OF
|
||||||
|
depends on ARCH_AIROHA || COMPILE_TEST
|
||||||
|
default ARCH_AIROHA
|
||||||
|
help
|
||||||
|
This driver provides the fixed clocks and gates present on Airoha
|
||||||
|
ARM silicon.
|
||||||
|
|
||||||
config COMMON_CLK_FSL_FLEXSPI
|
config COMMON_CLK_FSL_FLEXSPI
|
||||||
tristate "Clock driver for FlexSPI on Layerscape SoCs"
|
tristate "Clock driver for FlexSPI on Layerscape SoCs"
|
||||||
depends on ARCH_LAYERSCAPE || COMPILE_TEST
|
depends on ARCH_LAYERSCAPE || COMPILE_TEST
|
||||||
@ -368,6 +377,11 @@ config COMMON_CLK_VC5
|
|||||||
This driver supports the IDT VersaClock 5 and VersaClock 6
|
This driver supports the IDT VersaClock 5 and VersaClock 6
|
||||||
programmable clock generators.
|
programmable clock generators.
|
||||||
|
|
||||||
|
config COMMON_CLK_STM32MP135
|
||||||
|
def_bool COMMON_CLK && MACH_STM32MP13
|
||||||
|
help
|
||||||
|
Support for stm32mp135 SoC family clocks
|
||||||
|
|
||||||
config COMMON_CLK_STM32MP157
|
config COMMON_CLK_STM32MP157
|
||||||
def_bool COMMON_CLK && MACH_STM32MP157
|
def_bool COMMON_CLK && MACH_STM32MP157
|
||||||
help
|
help
|
||||||
|
@ -30,6 +30,7 @@ obj-$(CONFIG_COMMON_CLK_CDCE925) += clk-cdce925.o
|
|||||||
obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o
|
obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o
|
||||||
obj-$(CONFIG_COMMON_CLK_CS2000_CP) += clk-cs2000-cp.o
|
obj-$(CONFIG_COMMON_CLK_CS2000_CP) += clk-cs2000-cp.o
|
||||||
obj-$(CONFIG_ARCH_SPARX5) += clk-sparx5.o
|
obj-$(CONFIG_ARCH_SPARX5) += clk-sparx5.o
|
||||||
|
obj-$(CONFIG_COMMON_CLK_EN7523) += clk-en7523.o
|
||||||
obj-$(CONFIG_COMMON_CLK_FIXED_MMIO) += clk-fixed-mmio.o
|
obj-$(CONFIG_COMMON_CLK_FIXED_MMIO) += clk-fixed-mmio.o
|
||||||
obj-$(CONFIG_COMMON_CLK_FSL_FLEXSPI) += clk-fsl-flexspi.o
|
obj-$(CONFIG_COMMON_CLK_FSL_FLEXSPI) += clk-fsl-flexspi.o
|
||||||
obj-$(CONFIG_COMMON_CLK_FSL_SAI) += clk-fsl-sai.o
|
obj-$(CONFIG_COMMON_CLK_FSL_SAI) += clk-fsl-sai.o
|
||||||
@ -114,6 +115,7 @@ obj-y += socfpga/
|
|||||||
obj-$(CONFIG_PLAT_SPEAR) += spear/
|
obj-$(CONFIG_PLAT_SPEAR) += spear/
|
||||||
obj-y += sprd/
|
obj-y += sprd/
|
||||||
obj-$(CONFIG_ARCH_STI) += st/
|
obj-$(CONFIG_ARCH_STI) += st/
|
||||||
|
obj-$(CONFIG_ARCH_STM32) += stm32/
|
||||||
obj-$(CONFIG_SOC_STARFIVE) += starfive/
|
obj-$(CONFIG_SOC_STARFIVE) += starfive/
|
||||||
obj-$(CONFIG_ARCH_SUNXI) += sunxi/
|
obj-$(CONFIG_ARCH_SUNXI) += sunxi/
|
||||||
obj-y += sunxi-ng/
|
obj-y += sunxi-ng/
|
||||||
|
@ -25,7 +25,7 @@ static u32 owl_pll_calculate_mul(struct owl_pll_hw *pll_hw, unsigned long rate)
|
|||||||
else if (mul > pll_hw->max_mul)
|
else if (mul > pll_hw->max_mul)
|
||||||
mul = pll_hw->max_mul;
|
mul = pll_hw->max_mul;
|
||||||
|
|
||||||
return mul &= mul_mask(pll_hw);
|
return mul & mul_mask(pll_hw);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned long _get_table_rate(const struct clk_pll_table *table,
|
static unsigned long _get_table_rate(const struct clk_pll_table *table,
|
||||||
|
@ -345,7 +345,7 @@ static int raspberrypi_discover_clocks(struct raspberrypi_clk *rpi,
|
|||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
clks = devm_kcalloc(rpi->dev,
|
clks = devm_kcalloc(rpi->dev,
|
||||||
sizeof(*clks), RPI_FIRMWARE_NUM_CLK_ID,
|
RPI_FIRMWARE_NUM_CLK_ID, sizeof(*clks),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!clks)
|
if (!clks)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
@ -627,8 +627,7 @@ of_clk_cdce_get(struct of_phandle_args *clkspec, void *data)
|
|||||||
return &cdce->clkout[idx].hw;
|
return &cdce->clkout[idx].hw;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cdce706_probe(struct i2c_client *client,
|
static int cdce706_probe(struct i2c_client *client)
|
||||||
const struct i2c_device_id *id)
|
|
||||||
{
|
{
|
||||||
struct i2c_adapter *adapter = client->adapter;
|
struct i2c_adapter *adapter = client->adapter;
|
||||||
struct cdce706_dev_data *cdce;
|
struct cdce706_dev_data *cdce;
|
||||||
@ -692,7 +691,7 @@ static struct i2c_driver cdce706_i2c_driver = {
|
|||||||
.name = "cdce706",
|
.name = "cdce706",
|
||||||
.of_match_table = of_match_ptr(cdce706_dt_match),
|
.of_match_table = of_match_ptr(cdce706_dt_match),
|
||||||
},
|
},
|
||||||
.probe = cdce706_probe,
|
.probe_new = cdce706_probe,
|
||||||
.remove = cdce706_remove,
|
.remove = cdce706_remove,
|
||||||
.id_table = cdce706_id,
|
.id_table = cdce706_id,
|
||||||
};
|
};
|
||||||
|
@ -634,11 +634,20 @@ static struct regmap_bus regmap_cdce925_bus = {
|
|||||||
.read = cdce925_regmap_i2c_read,
|
.read = cdce925_regmap_i2c_read,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int cdce925_probe(struct i2c_client *client,
|
static const struct i2c_device_id cdce925_id[] = {
|
||||||
const struct i2c_device_id *id)
|
{ "cdce913", CDCE913 },
|
||||||
|
{ "cdce925", CDCE925 },
|
||||||
|
{ "cdce937", CDCE937 },
|
||||||
|
{ "cdce949", CDCE949 },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(i2c, cdce925_id);
|
||||||
|
|
||||||
|
static int cdce925_probe(struct i2c_client *client)
|
||||||
{
|
{
|
||||||
struct clk_cdce925_chip *data;
|
struct clk_cdce925_chip *data;
|
||||||
struct device_node *node = client->dev.of_node;
|
struct device_node *node = client->dev.of_node;
|
||||||
|
const struct i2c_device_id *id = i2c_match_id(cdce925_id, client);
|
||||||
const char *parent_name;
|
const char *parent_name;
|
||||||
const char *pll_clk_name[MAX_NUMBER_OF_PLLS] = {NULL,};
|
const char *pll_clk_name[MAX_NUMBER_OF_PLLS] = {NULL,};
|
||||||
struct clk_init_data init;
|
struct clk_init_data init;
|
||||||
@ -814,15 +823,6 @@ error:
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct i2c_device_id cdce925_id[] = {
|
|
||||||
{ "cdce913", CDCE913 },
|
|
||||||
{ "cdce925", CDCE925 },
|
|
||||||
{ "cdce937", CDCE937 },
|
|
||||||
{ "cdce949", CDCE949 },
|
|
||||||
{ }
|
|
||||||
};
|
|
||||||
MODULE_DEVICE_TABLE(i2c, cdce925_id);
|
|
||||||
|
|
||||||
static const struct of_device_id clk_cdce925_of_match[] = {
|
static const struct of_device_id clk_cdce925_of_match[] = {
|
||||||
{ .compatible = "ti,cdce913" },
|
{ .compatible = "ti,cdce913" },
|
||||||
{ .compatible = "ti,cdce925" },
|
{ .compatible = "ti,cdce925" },
|
||||||
@ -837,7 +837,7 @@ static struct i2c_driver cdce925_driver = {
|
|||||||
.name = "cdce925",
|
.name = "cdce925",
|
||||||
.of_match_table = of_match_ptr(clk_cdce925_of_match),
|
.of_match_table = of_match_ptr(clk_cdce925_of_match),
|
||||||
},
|
},
|
||||||
.probe = cdce925_probe,
|
.probe_new = cdce925_probe,
|
||||||
.id_table = cdce925_id,
|
.id_table = cdce925_id,
|
||||||
};
|
};
|
||||||
module_i2c_driver(cdce925_driver);
|
module_i2c_driver(cdce925_driver);
|
||||||
|
@ -570,8 +570,7 @@ static int cs2000_remove(struct i2c_client *client)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cs2000_probe(struct i2c_client *client,
|
static int cs2000_probe(struct i2c_client *client)
|
||||||
const struct i2c_device_id *id)
|
|
||||||
{
|
{
|
||||||
struct cs2000_priv *priv;
|
struct cs2000_priv *priv;
|
||||||
struct device *dev = &client->dev;
|
struct device *dev = &client->dev;
|
||||||
@ -625,7 +624,7 @@ static struct i2c_driver cs2000_driver = {
|
|||||||
.pm = &cs2000_pm_ops,
|
.pm = &cs2000_pm_ops,
|
||||||
.of_match_table = cs2000_of_match,
|
.of_match_table = cs2000_of_match,
|
||||||
},
|
},
|
||||||
.probe = cs2000_probe,
|
.probe_new = cs2000_probe,
|
||||||
.remove = cs2000_remove,
|
.remove = cs2000_remove,
|
||||||
.id_table = cs2000_id,
|
.id_table = cs2000_id,
|
||||||
};
|
};
|
||||||
|
351
drivers/clk/clk-en7523.c
Normal file
351
drivers/clk/clk-en7523.c
Normal file
@ -0,0 +1,351 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0-only
|
||||||
|
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include <linux/clk-provider.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
#include <linux/of_address.h>
|
||||||
|
#include <linux/of_device.h>
|
||||||
|
#include <linux/platform_device.h>
|
||||||
|
#include <dt-bindings/clock/en7523-clk.h>
|
||||||
|
|
||||||
|
#define REG_PCI_CONTROL 0x88
|
||||||
|
#define REG_PCI_CONTROL_PERSTOUT BIT(29)
|
||||||
|
#define REG_PCI_CONTROL_PERSTOUT1 BIT(26)
|
||||||
|
#define REG_PCI_CONTROL_REFCLK_EN1 BIT(22)
|
||||||
|
#define REG_GSW_CLK_DIV_SEL 0x1b4
|
||||||
|
#define REG_EMI_CLK_DIV_SEL 0x1b8
|
||||||
|
#define REG_BUS_CLK_DIV_SEL 0x1bc
|
||||||
|
#define REG_SPI_CLK_DIV_SEL 0x1c4
|
||||||
|
#define REG_SPI_CLK_FREQ_SEL 0x1c8
|
||||||
|
#define REG_NPU_CLK_DIV_SEL 0x1fc
|
||||||
|
#define REG_CRYPTO_CLKSRC 0x200
|
||||||
|
#define REG_RESET_CONTROL 0x834
|
||||||
|
#define REG_RESET_CONTROL_PCIEHB BIT(29)
|
||||||
|
#define REG_RESET_CONTROL_PCIE1 BIT(27)
|
||||||
|
#define REG_RESET_CONTROL_PCIE2 BIT(26)
|
||||||
|
|
||||||
|
struct en_clk_desc {
|
||||||
|
int id;
|
||||||
|
const char *name;
|
||||||
|
u32 base_reg;
|
||||||
|
u8 base_bits;
|
||||||
|
u8 base_shift;
|
||||||
|
union {
|
||||||
|
const unsigned int *base_values;
|
||||||
|
unsigned int base_value;
|
||||||
|
};
|
||||||
|
size_t n_base_values;
|
||||||
|
|
||||||
|
u16 div_reg;
|
||||||
|
u8 div_bits;
|
||||||
|
u8 div_shift;
|
||||||
|
u16 div_val0;
|
||||||
|
u8 div_step;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct en_clk_gate {
|
||||||
|
void __iomem *base;
|
||||||
|
struct clk_hw hw;
|
||||||
|
};
|
||||||
|
|
||||||
|
static const u32 gsw_base[] = { 400000000, 500000000 };
|
||||||
|
static const u32 emi_base[] = { 333000000, 400000000 };
|
||||||
|
static const u32 bus_base[] = { 500000000, 540000000 };
|
||||||
|
static const u32 slic_base[] = { 100000000, 3125000 };
|
||||||
|
static const u32 npu_base[] = { 333000000, 400000000, 500000000 };
|
||||||
|
|
||||||
|
static const struct en_clk_desc en7523_base_clks[] = {
|
||||||
|
{
|
||||||
|
.id = EN7523_CLK_GSW,
|
||||||
|
.name = "gsw",
|
||||||
|
|
||||||
|
.base_reg = REG_GSW_CLK_DIV_SEL,
|
||||||
|
.base_bits = 1,
|
||||||
|
.base_shift = 8,
|
||||||
|
.base_values = gsw_base,
|
||||||
|
.n_base_values = ARRAY_SIZE(gsw_base),
|
||||||
|
|
||||||
|
.div_bits = 3,
|
||||||
|
.div_shift = 0,
|
||||||
|
.div_step = 1,
|
||||||
|
}, {
|
||||||
|
.id = EN7523_CLK_EMI,
|
||||||
|
.name = "emi",
|
||||||
|
|
||||||
|
.base_reg = REG_EMI_CLK_DIV_SEL,
|
||||||
|
.base_bits = 1,
|
||||||
|
.base_shift = 8,
|
||||||
|
.base_values = emi_base,
|
||||||
|
.n_base_values = ARRAY_SIZE(emi_base),
|
||||||
|
|
||||||
|
.div_bits = 3,
|
||||||
|
.div_shift = 0,
|
||||||
|
.div_step = 1,
|
||||||
|
}, {
|
||||||
|
.id = EN7523_CLK_BUS,
|
||||||
|
.name = "bus",
|
||||||
|
|
||||||
|
.base_reg = REG_BUS_CLK_DIV_SEL,
|
||||||
|
.base_bits = 1,
|
||||||
|
.base_shift = 8,
|
||||||
|
.base_values = bus_base,
|
||||||
|
.n_base_values = ARRAY_SIZE(bus_base),
|
||||||
|
|
||||||
|
.div_bits = 3,
|
||||||
|
.div_shift = 0,
|
||||||
|
.div_step = 1,
|
||||||
|
}, {
|
||||||
|
.id = EN7523_CLK_SLIC,
|
||||||
|
.name = "slic",
|
||||||
|
|
||||||
|
.base_reg = REG_SPI_CLK_FREQ_SEL,
|
||||||
|
.base_bits = 1,
|
||||||
|
.base_shift = 0,
|
||||||
|
.base_values = slic_base,
|
||||||
|
.n_base_values = ARRAY_SIZE(slic_base),
|
||||||
|
|
||||||
|
.div_reg = REG_SPI_CLK_DIV_SEL,
|
||||||
|
.div_bits = 5,
|
||||||
|
.div_shift = 24,
|
||||||
|
.div_val0 = 20,
|
||||||
|
.div_step = 2,
|
||||||
|
}, {
|
||||||
|
.id = EN7523_CLK_SPI,
|
||||||
|
.name = "spi",
|
||||||
|
|
||||||
|
.base_reg = REG_SPI_CLK_DIV_SEL,
|
||||||
|
|
||||||
|
.base_value = 400000000,
|
||||||
|
|
||||||
|
.div_bits = 5,
|
||||||
|
.div_shift = 8,
|
||||||
|
.div_val0 = 40,
|
||||||
|
.div_step = 2,
|
||||||
|
}, {
|
||||||
|
.id = EN7523_CLK_NPU,
|
||||||
|
.name = "npu",
|
||||||
|
|
||||||
|
.base_reg = REG_NPU_CLK_DIV_SEL,
|
||||||
|
.base_bits = 2,
|
||||||
|
.base_shift = 8,
|
||||||
|
.base_values = npu_base,
|
||||||
|
.n_base_values = ARRAY_SIZE(npu_base),
|
||||||
|
|
||||||
|
.div_bits = 3,
|
||||||
|
.div_shift = 0,
|
||||||
|
.div_step = 1,
|
||||||
|
}, {
|
||||||
|
.id = EN7523_CLK_CRYPTO,
|
||||||
|
.name = "crypto",
|
||||||
|
|
||||||
|
.base_reg = REG_CRYPTO_CLKSRC,
|
||||||
|
.base_bits = 1,
|
||||||
|
.base_shift = 8,
|
||||||
|
.base_values = emi_base,
|
||||||
|
.n_base_values = ARRAY_SIZE(emi_base),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct of_device_id of_match_clk_en7523[] = {
|
||||||
|
{ .compatible = "airoha,en7523-scu", },
|
||||||
|
{ /* sentinel */ }
|
||||||
|
};
|
||||||
|
|
||||||
|
static unsigned int en7523_get_base_rate(void __iomem *base, unsigned int i)
|
||||||
|
{
|
||||||
|
const struct en_clk_desc *desc = &en7523_base_clks[i];
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
if (!desc->base_bits)
|
||||||
|
return desc->base_value;
|
||||||
|
|
||||||
|
val = readl(base + desc->base_reg);
|
||||||
|
val >>= desc->base_shift;
|
||||||
|
val &= (1 << desc->base_bits) - 1;
|
||||||
|
|
||||||
|
if (val >= desc->n_base_values)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return desc->base_values[val];
|
||||||
|
}
|
||||||
|
|
||||||
|
static u32 en7523_get_div(void __iomem *base, int i)
|
||||||
|
{
|
||||||
|
const struct en_clk_desc *desc = &en7523_base_clks[i];
|
||||||
|
u32 reg, val;
|
||||||
|
|
||||||
|
if (!desc->div_bits)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
reg = desc->div_reg ? desc->div_reg : desc->base_reg;
|
||||||
|
val = readl(base + reg);
|
||||||
|
val >>= desc->div_shift;
|
||||||
|
val &= (1 << desc->div_bits) - 1;
|
||||||
|
|
||||||
|
if (!val && desc->div_val0)
|
||||||
|
return desc->div_val0;
|
||||||
|
|
||||||
|
return (val + 1) * desc->div_step;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int en7523_pci_is_enabled(struct clk_hw *hw)
|
||||||
|
{
|
||||||
|
struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
|
||||||
|
|
||||||
|
return !!(readl(cg->base + REG_PCI_CONTROL) & REG_PCI_CONTROL_REFCLK_EN1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int en7523_pci_prepare(struct clk_hw *hw)
|
||||||
|
{
|
||||||
|
struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
|
||||||
|
void __iomem *np_base = cg->base;
|
||||||
|
u32 val, mask;
|
||||||
|
|
||||||
|
/* Need to pull device low before reset */
|
||||||
|
val = readl(np_base + REG_PCI_CONTROL);
|
||||||
|
val &= ~(REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT);
|
||||||
|
writel(val, np_base + REG_PCI_CONTROL);
|
||||||
|
usleep_range(1000, 2000);
|
||||||
|
|
||||||
|
/* Enable PCIe port 1 */
|
||||||
|
val |= REG_PCI_CONTROL_REFCLK_EN1;
|
||||||
|
writel(val, np_base + REG_PCI_CONTROL);
|
||||||
|
usleep_range(1000, 2000);
|
||||||
|
|
||||||
|
/* Reset to default */
|
||||||
|
val = readl(np_base + REG_RESET_CONTROL);
|
||||||
|
mask = REG_RESET_CONTROL_PCIE1 | REG_RESET_CONTROL_PCIE2 |
|
||||||
|
REG_RESET_CONTROL_PCIEHB;
|
||||||
|
writel(val & ~mask, np_base + REG_RESET_CONTROL);
|
||||||
|
usleep_range(1000, 2000);
|
||||||
|
writel(val | mask, np_base + REG_RESET_CONTROL);
|
||||||
|
msleep(100);
|
||||||
|
writel(val & ~mask, np_base + REG_RESET_CONTROL);
|
||||||
|
usleep_range(5000, 10000);
|
||||||
|
|
||||||
|
/* Release device */
|
||||||
|
mask = REG_PCI_CONTROL_PERSTOUT1 | REG_PCI_CONTROL_PERSTOUT;
|
||||||
|
val = readl(np_base + REG_PCI_CONTROL);
|
||||||
|
writel(val & ~mask, np_base + REG_PCI_CONTROL);
|
||||||
|
usleep_range(1000, 2000);
|
||||||
|
writel(val | mask, np_base + REG_PCI_CONTROL);
|
||||||
|
msleep(250);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void en7523_pci_unprepare(struct clk_hw *hw)
|
||||||
|
{
|
||||||
|
struct en_clk_gate *cg = container_of(hw, struct en_clk_gate, hw);
|
||||||
|
void __iomem *np_base = cg->base;
|
||||||
|
u32 val;
|
||||||
|
|
||||||
|
val = readl(np_base + REG_PCI_CONTROL);
|
||||||
|
val &= ~REG_PCI_CONTROL_REFCLK_EN1;
|
||||||
|
writel(val, np_base + REG_PCI_CONTROL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct clk_hw *en7523_register_pcie_clk(struct device *dev,
|
||||||
|
void __iomem *np_base)
|
||||||
|
{
|
||||||
|
static const struct clk_ops pcie_gate_ops = {
|
||||||
|
.is_enabled = en7523_pci_is_enabled,
|
||||||
|
.prepare = en7523_pci_prepare,
|
||||||
|
.unprepare = en7523_pci_unprepare,
|
||||||
|
};
|
||||||
|
struct clk_init_data init = {
|
||||||
|
.name = "pcie",
|
||||||
|
.ops = &pcie_gate_ops,
|
||||||
|
};
|
||||||
|
struct en_clk_gate *cg;
|
||||||
|
|
||||||
|
cg = devm_kzalloc(dev, sizeof(*cg), GFP_KERNEL);
|
||||||
|
if (!cg)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
cg->base = np_base;
|
||||||
|
cg->hw.init = &init;
|
||||||
|
en7523_pci_unprepare(&cg->hw);
|
||||||
|
|
||||||
|
if (clk_hw_register(dev, &cg->hw))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return &cg->hw;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void en7523_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data,
|
||||||
|
void __iomem *base, void __iomem *np_base)
|
||||||
|
{
|
||||||
|
struct clk_hw *hw;
|
||||||
|
u32 rate;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(en7523_base_clks); i++) {
|
||||||
|
const struct en_clk_desc *desc = &en7523_base_clks[i];
|
||||||
|
|
||||||
|
rate = en7523_get_base_rate(base, i);
|
||||||
|
rate /= en7523_get_div(base, i);
|
||||||
|
|
||||||
|
hw = clk_hw_register_fixed_rate(dev, desc->name, NULL, 0, rate);
|
||||||
|
if (IS_ERR(hw)) {
|
||||||
|
pr_err("Failed to register clk %s: %ld\n",
|
||||||
|
desc->name, PTR_ERR(hw));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
clk_data->hws[desc->id] = hw;
|
||||||
|
}
|
||||||
|
|
||||||
|
hw = en7523_register_pcie_clk(dev, np_base);
|
||||||
|
clk_data->hws[EN7523_CLK_PCIE] = hw;
|
||||||
|
|
||||||
|
clk_data->num = EN7523_NUM_CLOCKS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int en7523_clk_probe(struct platform_device *pdev)
|
||||||
|
{
|
||||||
|
struct device_node *node = pdev->dev.of_node;
|
||||||
|
struct clk_hw_onecell_data *clk_data;
|
||||||
|
void __iomem *base, *np_base;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
base = devm_platform_ioremap_resource(pdev, 0);
|
||||||
|
if (IS_ERR(base))
|
||||||
|
return PTR_ERR(base);
|
||||||
|
|
||||||
|
np_base = devm_platform_ioremap_resource(pdev, 1);
|
||||||
|
if (IS_ERR(np_base))
|
||||||
|
return PTR_ERR(np_base);
|
||||||
|
|
||||||
|
clk_data = devm_kzalloc(&pdev->dev,
|
||||||
|
struct_size(clk_data, hws, EN7523_NUM_CLOCKS),
|
||||||
|
GFP_KERNEL);
|
||||||
|
if (!clk_data)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
en7523_register_clocks(&pdev->dev, clk_data, base, np_base);
|
||||||
|
|
||||||
|
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
|
||||||
|
if (r)
|
||||||
|
dev_err(&pdev->dev,
|
||||||
|
"could not register clock provider: %s: %d\n",
|
||||||
|
pdev->name, r);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct platform_driver clk_en7523_drv = {
|
||||||
|
.probe = en7523_clk_probe,
|
||||||
|
.driver = {
|
||||||
|
.name = "clk-en7523",
|
||||||
|
.of_match_table = of_match_clk_en7523,
|
||||||
|
.suppress_bind_attrs = true,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init clk_en7523_init(void)
|
||||||
|
{
|
||||||
|
return platform_driver_register(&clk_en7523_drv);
|
||||||
|
}
|
||||||
|
|
||||||
|
arch_initcall(clk_en7523_init);
|
@ -87,7 +87,7 @@ struct clk_hw *__clk_hw_register_fixed_rate(struct device *dev,
|
|||||||
hw = &fixed->hw;
|
hw = &fixed->hw;
|
||||||
if (dev || !np)
|
if (dev || !np)
|
||||||
ret = clk_hw_register(dev, hw);
|
ret = clk_hw_register(dev, hw);
|
||||||
else if (np)
|
else
|
||||||
ret = of_clk_hw_register(np, hw);
|
ret = of_clk_hw_register(np, hw);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
kfree(fixed);
|
kfree(fixed);
|
||||||
|
@ -254,8 +254,7 @@ max9485_of_clk_get(struct of_phandle_args *clkspec, void *data)
|
|||||||
return &drvdata->hw[idx].hw;
|
return &drvdata->hw[idx].hw;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int max9485_i2c_probe(struct i2c_client *client,
|
static int max9485_i2c_probe(struct i2c_client *client)
|
||||||
const struct i2c_device_id *id)
|
|
||||||
{
|
{
|
||||||
struct max9485_driver_data *drvdata;
|
struct max9485_driver_data *drvdata;
|
||||||
struct device *dev = &client->dev;
|
struct device *dev = &client->dev;
|
||||||
@ -377,7 +376,7 @@ static struct i2c_driver max9485_driver = {
|
|||||||
.pm = &max9485_pm_ops,
|
.pm = &max9485_pm_ops,
|
||||||
.of_match_table = max9485_dt_ids,
|
.of_match_table = max9485_dt_ids,
|
||||||
},
|
},
|
||||||
.probe = max9485_i2c_probe,
|
.probe_new = max9485_i2c_probe,
|
||||||
.id_table = max9485_i2c_ids,
|
.id_table = max9485_i2c_ids,
|
||||||
};
|
};
|
||||||
module_i2c_driver(max9485_driver);
|
module_i2c_driver(max9485_driver);
|
||||||
|
@ -157,11 +157,11 @@ struct clk_hw *__clk_hw_register_mux(struct device *dev, struct device_node *np,
|
|||||||
struct clk_mux *mux;
|
struct clk_mux *mux;
|
||||||
struct clk_hw *hw;
|
struct clk_hw *hw;
|
||||||
struct clk_init_data init = {};
|
struct clk_init_data init = {};
|
||||||
u8 width = 0;
|
|
||||||
int ret = -EINVAL;
|
int ret = -EINVAL;
|
||||||
|
|
||||||
if (clk_mux_flags & CLK_MUX_HIWORD_MASK) {
|
if (clk_mux_flags & CLK_MUX_HIWORD_MASK) {
|
||||||
width = fls(mask) - ffs(mask) + 1;
|
u8 width = fls(mask) - ffs(mask) + 1;
|
||||||
|
|
||||||
if (width + shift > 16) {
|
if (width + shift > 16) {
|
||||||
pr_err("mux value exceeds LOWORD field\n");
|
pr_err("mux value exceeds LOWORD field\n");
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
|
@ -213,7 +213,7 @@ rs9_of_clk_get(struct of_phandle_args *clkspec, void *data)
|
|||||||
return rs9->clk_dif[idx];
|
return rs9->clk_dif[idx];
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rs9_probe(struct i2c_client *client, const struct i2c_device_id *id)
|
static int rs9_probe(struct i2c_client *client)
|
||||||
{
|
{
|
||||||
unsigned char name[5] = "DIF0";
|
unsigned char name[5] = "DIF0";
|
||||||
struct rs9_driver_data *rs9;
|
struct rs9_driver_data *rs9;
|
||||||
@ -312,7 +312,7 @@ static struct i2c_driver rs9_driver = {
|
|||||||
.pm = &rs9_pm_ops,
|
.pm = &rs9_pm_ops,
|
||||||
.of_match_table = clk_rs9_of_match,
|
.of_match_table = clk_rs9_of_match,
|
||||||
},
|
},
|
||||||
.probe = rs9_probe,
|
.probe_new = rs9_probe,
|
||||||
.id_table = rs9_id,
|
.id_table = rs9_id,
|
||||||
};
|
};
|
||||||
module_i2c_driver(rs9_driver);
|
module_i2c_driver(rs9_driver);
|
||||||
|
@ -327,8 +327,7 @@ static const struct regmap_config si514_regmap_config = {
|
|||||||
.volatile_reg = si514_regmap_is_volatile,
|
.volatile_reg = si514_regmap_is_volatile,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int si514_probe(struct i2c_client *client,
|
static int si514_probe(struct i2c_client *client)
|
||||||
const struct i2c_device_id *id)
|
|
||||||
{
|
{
|
||||||
struct clk_si514 *data;
|
struct clk_si514 *data;
|
||||||
struct clk_init_data init;
|
struct clk_init_data init;
|
||||||
@ -394,7 +393,7 @@ static struct i2c_driver si514_driver = {
|
|||||||
.name = "si514",
|
.name = "si514",
|
||||||
.of_match_table = clk_si514_of_match,
|
.of_match_table = clk_si514_of_match,
|
||||||
},
|
},
|
||||||
.probe = si514_probe,
|
.probe_new = si514_probe,
|
||||||
.remove = si514_remove,
|
.remove = si514_remove,
|
||||||
.id_table = si514_id,
|
.id_table = si514_id,
|
||||||
};
|
};
|
||||||
|
@ -1547,8 +1547,7 @@ static const struct attribute *si5341_attributes[] = {
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
static int si5341_probe(struct i2c_client *client,
|
static int si5341_probe(struct i2c_client *client)
|
||||||
const struct i2c_device_id *id)
|
|
||||||
{
|
{
|
||||||
struct clk_si5341 *data;
|
struct clk_si5341 *data;
|
||||||
struct clk_init_data init;
|
struct clk_init_data init;
|
||||||
@ -1837,7 +1836,7 @@ static struct i2c_driver si5341_driver = {
|
|||||||
.name = "si5341",
|
.name = "si5341",
|
||||||
.of_match_table = clk_si5341_of_match,
|
.of_match_table = clk_si5341_of_match,
|
||||||
},
|
},
|
||||||
.probe = si5341_probe,
|
.probe_new = si5341_probe,
|
||||||
.remove = si5341_remove,
|
.remove = si5341_remove,
|
||||||
.id_table = si5341_id,
|
.id_table = si5341_id,
|
||||||
};
|
};
|
||||||
|
@ -1367,9 +1367,18 @@ si53351_of_clk_get(struct of_phandle_args *clkspec, void *data)
|
|||||||
}
|
}
|
||||||
#endif /* CONFIG_OF */
|
#endif /* CONFIG_OF */
|
||||||
|
|
||||||
static int si5351_i2c_probe(struct i2c_client *client,
|
static const struct i2c_device_id si5351_i2c_ids[] = {
|
||||||
const struct i2c_device_id *id)
|
{ "si5351a", SI5351_VARIANT_A },
|
||||||
|
{ "si5351a-msop", SI5351_VARIANT_A3 },
|
||||||
|
{ "si5351b", SI5351_VARIANT_B },
|
||||||
|
{ "si5351c", SI5351_VARIANT_C },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(i2c, si5351_i2c_ids);
|
||||||
|
|
||||||
|
static int si5351_i2c_probe(struct i2c_client *client)
|
||||||
{
|
{
|
||||||
|
const struct i2c_device_id *id = i2c_match_id(si5351_i2c_ids, client);
|
||||||
enum si5351_variant variant = (enum si5351_variant)id->driver_data;
|
enum si5351_variant variant = (enum si5351_variant)id->driver_data;
|
||||||
struct si5351_platform_data *pdata;
|
struct si5351_platform_data *pdata;
|
||||||
struct si5351_driver_data *drvdata;
|
struct si5351_driver_data *drvdata;
|
||||||
@ -1649,21 +1658,12 @@ static int si5351_i2c_remove(struct i2c_client *client)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct i2c_device_id si5351_i2c_ids[] = {
|
|
||||||
{ "si5351a", SI5351_VARIANT_A },
|
|
||||||
{ "si5351a-msop", SI5351_VARIANT_A3 },
|
|
||||||
{ "si5351b", SI5351_VARIANT_B },
|
|
||||||
{ "si5351c", SI5351_VARIANT_C },
|
|
||||||
{ }
|
|
||||||
};
|
|
||||||
MODULE_DEVICE_TABLE(i2c, si5351_i2c_ids);
|
|
||||||
|
|
||||||
static struct i2c_driver si5351_driver = {
|
static struct i2c_driver si5351_driver = {
|
||||||
.driver = {
|
.driver = {
|
||||||
.name = "si5351",
|
.name = "si5351",
|
||||||
.of_match_table = of_match_ptr(si5351_dt_ids),
|
.of_match_table = of_match_ptr(si5351_dt_ids),
|
||||||
},
|
},
|
||||||
.probe = si5351_i2c_probe,
|
.probe_new = si5351_i2c_probe,
|
||||||
.remove = si5351_i2c_remove,
|
.remove = si5351_i2c_remove,
|
||||||
.id_table = si5351_i2c_ids,
|
.id_table = si5351_i2c_ids,
|
||||||
};
|
};
|
||||||
|
@ -451,11 +451,19 @@ static const struct regmap_config si544_regmap_config = {
|
|||||||
.volatile_reg = si544_regmap_is_volatile,
|
.volatile_reg = si544_regmap_is_volatile,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int si544_probe(struct i2c_client *client,
|
static const struct i2c_device_id si544_id[] = {
|
||||||
const struct i2c_device_id *id)
|
{ "si544a", si544a },
|
||||||
|
{ "si544b", si544b },
|
||||||
|
{ "si544c", si544c },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(i2c, si544_id);
|
||||||
|
|
||||||
|
static int si544_probe(struct i2c_client *client)
|
||||||
{
|
{
|
||||||
struct clk_si544 *data;
|
struct clk_si544 *data;
|
||||||
struct clk_init_data init;
|
struct clk_init_data init;
|
||||||
|
const struct i2c_device_id *id = i2c_match_id(si544_id, client);
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
|
data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
|
||||||
@ -499,14 +507,6 @@ static int si544_probe(struct i2c_client *client,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct i2c_device_id si544_id[] = {
|
|
||||||
{ "si544a", si544a },
|
|
||||||
{ "si544b", si544b },
|
|
||||||
{ "si544c", si544c },
|
|
||||||
{ }
|
|
||||||
};
|
|
||||||
MODULE_DEVICE_TABLE(i2c, si544_id);
|
|
||||||
|
|
||||||
static const struct of_device_id clk_si544_of_match[] = {
|
static const struct of_device_id clk_si544_of_match[] = {
|
||||||
{ .compatible = "silabs,si544a" },
|
{ .compatible = "silabs,si544a" },
|
||||||
{ .compatible = "silabs,si544b" },
|
{ .compatible = "silabs,si544b" },
|
||||||
@ -520,7 +520,7 @@ static struct i2c_driver si544_driver = {
|
|||||||
.name = "si544",
|
.name = "si544",
|
||||||
.of_match_table = clk_si544_of_match,
|
.of_match_table = clk_si544_of_match,
|
||||||
},
|
},
|
||||||
.probe = si544_probe,
|
.probe_new = si544_probe,
|
||||||
.id_table = si544_id,
|
.id_table = si544_id,
|
||||||
};
|
};
|
||||||
module_i2c_driver(si544_driver);
|
module_i2c_driver(si544_driver);
|
||||||
|
@ -398,11 +398,20 @@ static const struct regmap_config si570_regmap_config = {
|
|||||||
.volatile_reg = si570_regmap_is_volatile,
|
.volatile_reg = si570_regmap_is_volatile,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int si570_probe(struct i2c_client *client,
|
static const struct i2c_device_id si570_id[] = {
|
||||||
const struct i2c_device_id *id)
|
{ "si570", si57x },
|
||||||
|
{ "si571", si57x },
|
||||||
|
{ "si598", si59x },
|
||||||
|
{ "si599", si59x },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(i2c, si570_id);
|
||||||
|
|
||||||
|
static int si570_probe(struct i2c_client *client)
|
||||||
{
|
{
|
||||||
struct clk_si570 *data;
|
struct clk_si570 *data;
|
||||||
struct clk_init_data init;
|
struct clk_init_data init;
|
||||||
|
const struct i2c_device_id *id = i2c_match_id(si570_id, client);
|
||||||
u32 initial_fout, factory_fout, stability;
|
u32 initial_fout, factory_fout, stability;
|
||||||
bool skip_recall;
|
bool skip_recall;
|
||||||
int err;
|
int err;
|
||||||
@ -495,15 +504,6 @@ static int si570_remove(struct i2c_client *client)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct i2c_device_id si570_id[] = {
|
|
||||||
{ "si570", si57x },
|
|
||||||
{ "si571", si57x },
|
|
||||||
{ "si598", si59x },
|
|
||||||
{ "si599", si59x },
|
|
||||||
{ }
|
|
||||||
};
|
|
||||||
MODULE_DEVICE_TABLE(i2c, si570_id);
|
|
||||||
|
|
||||||
static const struct of_device_id clk_si570_of_match[] = {
|
static const struct of_device_id clk_si570_of_match[] = {
|
||||||
{ .compatible = "silabs,si570" },
|
{ .compatible = "silabs,si570" },
|
||||||
{ .compatible = "silabs,si571" },
|
{ .compatible = "silabs,si571" },
|
||||||
@ -518,7 +518,7 @@ static struct i2c_driver si570_driver = {
|
|||||||
.name = "si570",
|
.name = "si570",
|
||||||
.of_match_table = clk_si570_of_match,
|
.of_match_table = clk_si570_of_match,
|
||||||
},
|
},
|
||||||
.probe = si570_probe,
|
.probe_new = si570_probe,
|
||||||
.remove = si570_remove,
|
.remove = si570_remove,
|
||||||
.id_table = si570_id,
|
.id_table = si570_id,
|
||||||
};
|
};
|
||||||
|
@ -108,17 +108,10 @@ struct clk {
|
|||||||
/*** runtime pm ***/
|
/*** runtime pm ***/
|
||||||
static int clk_pm_runtime_get(struct clk_core *core)
|
static int clk_pm_runtime_get(struct clk_core *core)
|
||||||
{
|
{
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (!core->rpm_enabled)
|
if (!core->rpm_enabled)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
ret = pm_runtime_get_sync(core->dev);
|
return pm_runtime_resume_and_get(core->dev);
|
||||||
if (ret < 0) {
|
|
||||||
pm_runtime_put_noidle(core->dev);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void clk_pm_runtime_put(struct clk_core *core)
|
static void clk_pm_runtime_put(struct clk_core *core)
|
||||||
|
@ -178,7 +178,7 @@ struct clk_hw *__imx8m_clk_hw_composite(const char *name,
|
|||||||
unsigned long flags)
|
unsigned long flags)
|
||||||
{
|
{
|
||||||
struct clk_hw *hw = ERR_PTR(-ENOMEM), *mux_hw;
|
struct clk_hw *hw = ERR_PTR(-ENOMEM), *mux_hw;
|
||||||
struct clk_hw *div_hw, *gate_hw;
|
struct clk_hw *div_hw, *gate_hw = NULL;
|
||||||
struct clk_divider *div = NULL;
|
struct clk_divider *div = NULL;
|
||||||
struct clk_gate *gate = NULL;
|
struct clk_gate *gate = NULL;
|
||||||
struct clk_mux *mux = NULL;
|
struct clk_mux *mux = NULL;
|
||||||
@ -223,14 +223,17 @@ struct clk_hw *__imx8m_clk_hw_composite(const char *name,
|
|||||||
div->lock = &imx_ccm_lock;
|
div->lock = &imx_ccm_lock;
|
||||||
div->flags = CLK_DIVIDER_ROUND_CLOSEST;
|
div->flags = CLK_DIVIDER_ROUND_CLOSEST;
|
||||||
|
|
||||||
gate = kzalloc(sizeof(*gate), GFP_KERNEL);
|
/* skip registering the gate ops if M4 is enabled */
|
||||||
if (!gate)
|
if (!mcore_booted) {
|
||||||
goto fail;
|
gate = kzalloc(sizeof(*gate), GFP_KERNEL);
|
||||||
|
if (!gate)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
gate_hw = &gate->hw;
|
gate_hw = &gate->hw;
|
||||||
gate->reg = reg;
|
gate->reg = reg;
|
||||||
gate->bit_idx = PCG_CGC_SHIFT;
|
gate->bit_idx = PCG_CGC_SHIFT;
|
||||||
gate->lock = &imx_ccm_lock;
|
gate->lock = &imx_ccm_lock;
|
||||||
|
}
|
||||||
|
|
||||||
hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
|
hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
|
||||||
mux_hw, mux_ops, div_hw,
|
mux_hw, mux_ops, div_hw,
|
||||||
|
@ -782,7 +782,6 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
|
|||||||
hws[IMX7D_DRAM_PHYM_ALT_ROOT_CLK] = imx_clk_hw_gate2_flags("dram_phym_alt_root_clk", "dram_phym_alt_post_div", base + 0x4130, 0, CLK_IS_CRITICAL | CLK_OPS_PARENT_ENABLE);
|
hws[IMX7D_DRAM_PHYM_ALT_ROOT_CLK] = imx_clk_hw_gate2_flags("dram_phym_alt_root_clk", "dram_phym_alt_post_div", base + 0x4130, 0, CLK_IS_CRITICAL | CLK_OPS_PARENT_ENABLE);
|
||||||
hws[IMX7D_DRAM_ALT_ROOT_CLK] = imx_clk_hw_gate2_flags("dram_alt_root_clk", "dram_alt_post_div", base + 0x4130, 0, CLK_IS_CRITICAL | CLK_OPS_PARENT_ENABLE);
|
hws[IMX7D_DRAM_ALT_ROOT_CLK] = imx_clk_hw_gate2_flags("dram_alt_root_clk", "dram_alt_post_div", base + 0x4130, 0, CLK_IS_CRITICAL | CLK_OPS_PARENT_ENABLE);
|
||||||
hws[IMX7D_OCOTP_CLK] = imx_clk_hw_gate4("ocotp_clk", "ipg_root_clk", base + 0x4230, 0);
|
hws[IMX7D_OCOTP_CLK] = imx_clk_hw_gate4("ocotp_clk", "ipg_root_clk", base + 0x4230, 0);
|
||||||
hws[IMX7D_SNVS_CLK] = imx_clk_hw_gate4("snvs_clk", "ipg_root_clk", base + 0x4250, 0);
|
|
||||||
hws[IMX7D_MU_ROOT_CLK] = imx_clk_hw_gate4("mu_root_clk", "ipg_root_clk", base + 0x4270, 0);
|
hws[IMX7D_MU_ROOT_CLK] = imx_clk_hw_gate4("mu_root_clk", "ipg_root_clk", base + 0x4270, 0);
|
||||||
hws[IMX7D_CAAM_CLK] = imx_clk_hw_gate4("caam_clk", "ipg_root_clk", base + 0x4240, 0);
|
hws[IMX7D_CAAM_CLK] = imx_clk_hw_gate4("caam_clk", "ipg_root_clk", base + 0x4240, 0);
|
||||||
hws[IMX7D_USB_HSIC_ROOT_CLK] = imx_clk_hw_gate4("usb_hsic_root_clk", "usb_hsic_post_div", base + 0x4690, 0);
|
hws[IMX7D_USB_HSIC_ROOT_CLK] = imx_clk_hw_gate4("usb_hsic_root_clk", "usb_hsic_post_div", base + 0x4690, 0);
|
||||||
|
@ -560,7 +560,6 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
|
|||||||
hws[IMX8MM_CLK_SAI5_IPG] = imx_clk_hw_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5);
|
hws[IMX8MM_CLK_SAI5_IPG] = imx_clk_hw_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5);
|
||||||
hws[IMX8MM_CLK_SAI6_ROOT] = imx_clk_hw_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6);
|
hws[IMX8MM_CLK_SAI6_ROOT] = imx_clk_hw_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6);
|
||||||
hws[IMX8MM_CLK_SAI6_IPG] = imx_clk_hw_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6);
|
hws[IMX8MM_CLK_SAI6_IPG] = imx_clk_hw_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6);
|
||||||
hws[IMX8MM_CLK_SNVS_ROOT] = imx_clk_hw_gate4("snvs_root_clk", "ipg_root", base + 0x4470, 0);
|
|
||||||
hws[IMX8MM_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", base + 0x4490, 0);
|
hws[IMX8MM_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", base + 0x4490, 0);
|
||||||
hws[IMX8MM_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0);
|
hws[IMX8MM_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0);
|
||||||
hws[IMX8MM_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0);
|
hws[IMX8MM_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0);
|
||||||
@ -639,6 +638,8 @@ static struct platform_driver imx8mm_clk_driver = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
module_platform_driver(imx8mm_clk_driver);
|
module_platform_driver(imx8mm_clk_driver);
|
||||||
|
module_param(mcore_booted, bool, S_IRUGO);
|
||||||
|
MODULE_PARM_DESC(mcore_booted, "See Cortex-M core is booted or not");
|
||||||
|
|
||||||
MODULE_AUTHOR("Bai Ping <ping.bai@nxp.com>");
|
MODULE_AUTHOR("Bai Ping <ping.bai@nxp.com>");
|
||||||
MODULE_DESCRIPTION("NXP i.MX8MM clock driver");
|
MODULE_DESCRIPTION("NXP i.MX8MM clock driver");
|
||||||
|
@ -227,6 +227,30 @@ static const char * const imx8mn_pwm4_sels[] = {"osc_24m", "sys_pll2_100m", "sys
|
|||||||
"sys_pll1_40m", "sys_pll3_out", "clk_ext2",
|
"sys_pll1_40m", "sys_pll3_out", "clk_ext2",
|
||||||
"sys_pll1_80m", "video_pll1_out", };
|
"sys_pll1_80m", "video_pll1_out", };
|
||||||
|
|
||||||
|
static const char * const imx8mn_gpt1_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
|
||||||
|
"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
|
||||||
|
"audio_pll1_out", "clk_ext1", };
|
||||||
|
|
||||||
|
static const char * const imx8mn_gpt2_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
|
||||||
|
"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
|
||||||
|
"audio_pll1_out", "clk_ext1", };
|
||||||
|
|
||||||
|
static const char * const imx8mn_gpt3_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
|
||||||
|
"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
|
||||||
|
"audio_pll1_out", "clk_ext1", };
|
||||||
|
|
||||||
|
static const char * const imx8mn_gpt4_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
|
||||||
|
"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
|
||||||
|
"audio_pll1_out", "clk_ext1", };
|
||||||
|
|
||||||
|
static const char * const imx8mn_gpt5_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
|
||||||
|
"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
|
||||||
|
"audio_pll1_out", "clk_ext1", };
|
||||||
|
|
||||||
|
static const char * const imx8mn_gpt6_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_400m",
|
||||||
|
"sys_pll1_40m", "video_pll1_out", "sys_pll1_80m",
|
||||||
|
"audio_pll1_out", "clk_ext1", };
|
||||||
|
|
||||||
static const char * const imx8mn_wdog_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_160m",
|
static const char * const imx8mn_wdog_sels[] = {"osc_24m", "sys_pll1_133m", "sys_pll1_160m",
|
||||||
"vpu_pll_out", "sys_pll2_125m", "sys_pll3_out",
|
"vpu_pll_out", "sys_pll2_125m", "sys_pll3_out",
|
||||||
"sys_pll1_80m", "sys_pll2_166m", };
|
"sys_pll1_80m", "sys_pll2_166m", };
|
||||||
@ -476,6 +500,12 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
|
|||||||
hws[IMX8MN_CLK_PWM2] = imx8m_clk_hw_composite("pwm2", imx8mn_pwm2_sels, base + 0xb400);
|
hws[IMX8MN_CLK_PWM2] = imx8m_clk_hw_composite("pwm2", imx8mn_pwm2_sels, base + 0xb400);
|
||||||
hws[IMX8MN_CLK_PWM3] = imx8m_clk_hw_composite("pwm3", imx8mn_pwm3_sels, base + 0xb480);
|
hws[IMX8MN_CLK_PWM3] = imx8m_clk_hw_composite("pwm3", imx8mn_pwm3_sels, base + 0xb480);
|
||||||
hws[IMX8MN_CLK_PWM4] = imx8m_clk_hw_composite("pwm4", imx8mn_pwm4_sels, base + 0xb500);
|
hws[IMX8MN_CLK_PWM4] = imx8m_clk_hw_composite("pwm4", imx8mn_pwm4_sels, base + 0xb500);
|
||||||
|
hws[IMX8MN_CLK_GPT1] = imx8m_clk_hw_composite("gpt1", imx8mn_gpt1_sels, base + 0xb580);
|
||||||
|
hws[IMX8MN_CLK_GPT2] = imx8m_clk_hw_composite("gpt2", imx8mn_gpt2_sels, base + 0xb600);
|
||||||
|
hws[IMX8MN_CLK_GPT3] = imx8m_clk_hw_composite("gpt3", imx8mn_gpt3_sels, base + 0xb680);
|
||||||
|
hws[IMX8MN_CLK_GPT4] = imx8m_clk_hw_composite("gpt4", imx8mn_gpt4_sels, base + 0xb700);
|
||||||
|
hws[IMX8MN_CLK_GPT5] = imx8m_clk_hw_composite("gpt5", imx8mn_gpt5_sels, base + 0xb780);
|
||||||
|
hws[IMX8MN_CLK_GPT6] = imx8m_clk_hw_composite("gpt6", imx8mn_gpt6_sels, base + 0xb800);
|
||||||
hws[IMX8MN_CLK_WDOG] = imx8m_clk_hw_composite("wdog", imx8mn_wdog_sels, base + 0xb900);
|
hws[IMX8MN_CLK_WDOG] = imx8m_clk_hw_composite("wdog", imx8mn_wdog_sels, base + 0xb900);
|
||||||
hws[IMX8MN_CLK_WRCLK] = imx8m_clk_hw_composite("wrclk", imx8mn_wrclk_sels, base + 0xb980);
|
hws[IMX8MN_CLK_WRCLK] = imx8m_clk_hw_composite("wrclk", imx8mn_wrclk_sels, base + 0xb980);
|
||||||
hws[IMX8MN_CLK_CLKO1] = imx8m_clk_hw_composite("clko1", imx8mn_clko1_sels, base + 0xba00);
|
hws[IMX8MN_CLK_CLKO1] = imx8m_clk_hw_composite("clko1", imx8mn_clko1_sels, base + 0xba00);
|
||||||
@ -501,6 +531,12 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
|
|||||||
hws[IMX8MN_CLK_GPIO3_ROOT] = imx_clk_hw_gate4("gpio3_root_clk", "ipg_root", base + 0x40d0, 0);
|
hws[IMX8MN_CLK_GPIO3_ROOT] = imx_clk_hw_gate4("gpio3_root_clk", "ipg_root", base + 0x40d0, 0);
|
||||||
hws[IMX8MN_CLK_GPIO4_ROOT] = imx_clk_hw_gate4("gpio4_root_clk", "ipg_root", base + 0x40e0, 0);
|
hws[IMX8MN_CLK_GPIO4_ROOT] = imx_clk_hw_gate4("gpio4_root_clk", "ipg_root", base + 0x40e0, 0);
|
||||||
hws[IMX8MN_CLK_GPIO5_ROOT] = imx_clk_hw_gate4("gpio5_root_clk", "ipg_root", base + 0x40f0, 0);
|
hws[IMX8MN_CLK_GPIO5_ROOT] = imx_clk_hw_gate4("gpio5_root_clk", "ipg_root", base + 0x40f0, 0);
|
||||||
|
hws[IMX8MN_CLK_GPT1_ROOT] = imx_clk_hw_gate4("gpt1_root_clk", "gpt1", base + 0x4100, 0);
|
||||||
|
hws[IMX8MN_CLK_GPT2_ROOT] = imx_clk_hw_gate4("gpt2_root_clk", "gpt2", base + 0x4110, 0);
|
||||||
|
hws[IMX8MN_CLK_GPT3_ROOT] = imx_clk_hw_gate4("gpt3_root_clk", "gpt3", base + 0x4120, 0);
|
||||||
|
hws[IMX8MN_CLK_GPT4_ROOT] = imx_clk_hw_gate4("gpt4_root_clk", "gpt4", base + 0x4130, 0);
|
||||||
|
hws[IMX8MN_CLK_GPT5_ROOT] = imx_clk_hw_gate4("gpt5_root_clk", "gpt5", base + 0x4140, 0);
|
||||||
|
hws[IMX8MN_CLK_GPT6_ROOT] = imx_clk_hw_gate4("gpt6_root_clk", "gpt6", base + 0x4150, 0);
|
||||||
hws[IMX8MN_CLK_I2C1_ROOT] = imx_clk_hw_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0);
|
hws[IMX8MN_CLK_I2C1_ROOT] = imx_clk_hw_gate4("i2c1_root_clk", "i2c1", base + 0x4170, 0);
|
||||||
hws[IMX8MN_CLK_I2C2_ROOT] = imx_clk_hw_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0);
|
hws[IMX8MN_CLK_I2C2_ROOT] = imx_clk_hw_gate4("i2c2_root_clk", "i2c2", base + 0x4180, 0);
|
||||||
hws[IMX8MN_CLK_I2C3_ROOT] = imx_clk_hw_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0);
|
hws[IMX8MN_CLK_I2C3_ROOT] = imx_clk_hw_gate4("i2c3_root_clk", "i2c3", base + 0x4190, 0);
|
||||||
@ -522,7 +558,6 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
|
|||||||
hws[IMX8MN_CLK_SAI5_IPG] = imx_clk_hw_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5);
|
hws[IMX8MN_CLK_SAI5_IPG] = imx_clk_hw_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5);
|
||||||
hws[IMX8MN_CLK_SAI6_ROOT] = imx_clk_hw_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6);
|
hws[IMX8MN_CLK_SAI6_ROOT] = imx_clk_hw_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6);
|
||||||
hws[IMX8MN_CLK_SAI6_IPG] = imx_clk_hw_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6);
|
hws[IMX8MN_CLK_SAI6_IPG] = imx_clk_hw_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6);
|
||||||
hws[IMX8MN_CLK_SNVS_ROOT] = imx_clk_hw_gate4("snvs_root_clk", "ipg_root", base + 0x4470, 0);
|
|
||||||
hws[IMX8MN_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", base + 0x4490, 0);
|
hws[IMX8MN_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", base + 0x4490, 0);
|
||||||
hws[IMX8MN_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0);
|
hws[IMX8MN_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0);
|
||||||
hws[IMX8MN_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0);
|
hws[IMX8MN_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0);
|
||||||
@ -549,6 +584,8 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
|
|||||||
hws[IMX8MN_CLK_SDMA3_ROOT] = imx_clk_hw_gate4("sdma3_clk", "ipg_audio_root", base + 0x45f0, 0);
|
hws[IMX8MN_CLK_SDMA3_ROOT] = imx_clk_hw_gate4("sdma3_clk", "ipg_audio_root", base + 0x45f0, 0);
|
||||||
hws[IMX8MN_CLK_SAI7_ROOT] = imx_clk_hw_gate2_shared2("sai7_root_clk", "sai7", base + 0x4650, 0, &share_count_sai7);
|
hws[IMX8MN_CLK_SAI7_ROOT] = imx_clk_hw_gate2_shared2("sai7_root_clk", "sai7", base + 0x4650, 0, &share_count_sai7);
|
||||||
|
|
||||||
|
hws[IMX8MN_CLK_GPT_3M] = imx_clk_hw_fixed_factor("gpt_3m", "osc_24m", 1, 8);
|
||||||
|
|
||||||
hws[IMX8MN_CLK_DRAM_ALT_ROOT] = imx_clk_hw_fixed_factor("dram_alt_root", "dram_alt", 1, 4);
|
hws[IMX8MN_CLK_DRAM_ALT_ROOT] = imx_clk_hw_fixed_factor("dram_alt_root", "dram_alt", 1, 4);
|
||||||
|
|
||||||
hws[IMX8MN_CLK_ARM] = imx_clk_hw_cpu("arm", "arm_a53_core",
|
hws[IMX8MN_CLK_ARM] = imx_clk_hw_cpu("arm", "arm_a53_core",
|
||||||
@ -594,6 +631,8 @@ static struct platform_driver imx8mn_clk_driver = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
module_platform_driver(imx8mn_clk_driver);
|
module_platform_driver(imx8mn_clk_driver);
|
||||||
|
module_param(mcore_booted, bool, S_IRUGO);
|
||||||
|
MODULE_PARM_DESC(mcore_booted, "See Cortex-M core is booted or not");
|
||||||
|
|
||||||
MODULE_AUTHOR("Anson Huang <Anson.Huang@nxp.com>");
|
MODULE_AUTHOR("Anson Huang <Anson.Huang@nxp.com>");
|
||||||
MODULE_DESCRIPTION("NXP i.MX8MN clock driver");
|
MODULE_DESCRIPTION("NXP i.MX8MN clock driver");
|
||||||
|
@ -358,7 +358,7 @@ static const char * const imx8mp_media_mipi_phy1_ref_sels[] = {"osc_24m", "sys_p
|
|||||||
"clk_ext2", "audio_pll2_out",
|
"clk_ext2", "audio_pll2_out",
|
||||||
"video_pll1_out", };
|
"video_pll1_out", };
|
||||||
|
|
||||||
static const char * const imx8mp_media_disp1_pix_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out",
|
static const char * const imx8mp_media_disp_pix_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out",
|
||||||
"audio_pll1_out", "sys_pll1_800m",
|
"audio_pll1_out", "sys_pll1_800m",
|
||||||
"sys_pll2_1000m", "sys_pll3_out", "clk_ext4", };
|
"sys_pll2_1000m", "sys_pll3_out", "clk_ext4", };
|
||||||
|
|
||||||
@ -399,6 +399,11 @@ static const char * const imx8mp_sai7_sels[] = {"osc_24m", "audio_pll1_out", "au
|
|||||||
|
|
||||||
static const char * const imx8mp_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", };
|
static const char * const imx8mp_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", };
|
||||||
|
|
||||||
|
static const char * const imx8mp_clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll1_out",
|
||||||
|
"dummy", "dummy", "gpu_pll_out", "vpu_pll_out",
|
||||||
|
"arm_pll_out", "sys_pll1", "sys_pll2", "sys_pll3",
|
||||||
|
"dummy", "dummy", "osc_24m", "dummy", "osc_32k"};
|
||||||
|
|
||||||
static struct clk_hw **hws;
|
static struct clk_hw **hws;
|
||||||
static struct clk_hw_onecell_data *clk_hw_data;
|
static struct clk_hw_onecell_data *clk_hw_data;
|
||||||
|
|
||||||
@ -504,6 +509,15 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
|
|||||||
hws[IMX8MP_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2);
|
hws[IMX8MP_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_out", 1, 2);
|
||||||
hws[IMX8MP_SYS_PLL2_1000M] = imx_clk_hw_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
|
hws[IMX8MP_SYS_PLL2_1000M] = imx_clk_hw_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1);
|
||||||
|
|
||||||
|
hws[IMX8MP_CLK_CLKOUT1_SEL] = imx_clk_hw_mux2("clkout1_sel", anatop_base + 0x128, 4, 4,
|
||||||
|
imx8mp_clkout_sels, ARRAY_SIZE(imx8mp_clkout_sels));
|
||||||
|
hws[IMX8MP_CLK_CLKOUT1_DIV] = imx_clk_hw_divider("clkout1_div", "clkout1_sel", anatop_base + 0x128, 0, 4);
|
||||||
|
hws[IMX8MP_CLK_CLKOUT1] = imx_clk_hw_gate("clkout1", "clkout1_div", anatop_base + 0x128, 8);
|
||||||
|
hws[IMX8MP_CLK_CLKOUT2_SEL] = imx_clk_hw_mux2("clkout2_sel", anatop_base + 0x128, 20, 4,
|
||||||
|
imx8mp_clkout_sels, ARRAY_SIZE(imx8mp_clkout_sels));
|
||||||
|
hws[IMX8MP_CLK_CLKOUT2_DIV] = imx_clk_hw_divider("clkout2_div", "clkout2_sel", anatop_base + 0x128, 16, 4);
|
||||||
|
hws[IMX8MP_CLK_CLKOUT2] = imx_clk_hw_gate("clkout2", "clkout2_div", anatop_base + 0x128, 24);
|
||||||
|
|
||||||
hws[IMX8MP_CLK_A53_DIV] = imx8m_clk_hw_composite_core("arm_a53_div", imx8mp_a53_sels, ccm_base + 0x8000);
|
hws[IMX8MP_CLK_A53_DIV] = imx8m_clk_hw_composite_core("arm_a53_div", imx8mp_a53_sels, ccm_base + 0x8000);
|
||||||
hws[IMX8MP_CLK_A53_SRC] = hws[IMX8MP_CLK_A53_DIV];
|
hws[IMX8MP_CLK_A53_SRC] = hws[IMX8MP_CLK_A53_DIV];
|
||||||
hws[IMX8MP_CLK_A53_CG] = hws[IMX8MP_CLK_A53_DIV];
|
hws[IMX8MP_CLK_A53_CG] = hws[IMX8MP_CLK_A53_DIV];
|
||||||
@ -538,6 +552,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
|
|||||||
hws[IMX8MP_CLK_AHB] = imx8m_clk_hw_composite_bus_critical("ahb_root", imx8mp_ahb_sels, ccm_base + 0x9000);
|
hws[IMX8MP_CLK_AHB] = imx8m_clk_hw_composite_bus_critical("ahb_root", imx8mp_ahb_sels, ccm_base + 0x9000);
|
||||||
hws[IMX8MP_CLK_AUDIO_AHB] = imx8m_clk_hw_composite_bus("audio_ahb", imx8mp_audio_ahb_sels, ccm_base + 0x9100);
|
hws[IMX8MP_CLK_AUDIO_AHB] = imx8m_clk_hw_composite_bus("audio_ahb", imx8mp_audio_ahb_sels, ccm_base + 0x9100);
|
||||||
hws[IMX8MP_CLK_MIPI_DSI_ESC_RX] = imx8m_clk_hw_composite_bus("mipi_dsi_esc_rx", imx8mp_mipi_dsi_esc_rx_sels, ccm_base + 0x9200);
|
hws[IMX8MP_CLK_MIPI_DSI_ESC_RX] = imx8m_clk_hw_composite_bus("mipi_dsi_esc_rx", imx8mp_mipi_dsi_esc_rx_sels, ccm_base + 0x9200);
|
||||||
|
hws[IMX8MP_CLK_MEDIA_DISP2_PIX] = imx8m_clk_hw_composite("media_disp2_pix", imx8mp_media_disp_pix_sels, ccm_base + 0x9300);
|
||||||
|
|
||||||
hws[IMX8MP_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb_root", ccm_base + 0x9080, 0, 1);
|
hws[IMX8MP_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb_root", ccm_base + 0x9080, 0, 1);
|
||||||
|
|
||||||
@ -600,7 +615,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
|
|||||||
hws[IMX8MP_CLK_USDHC3] = imx8m_clk_hw_composite("usdhc3", imx8mp_usdhc3_sels, ccm_base + 0xbc80);
|
hws[IMX8MP_CLK_USDHC3] = imx8m_clk_hw_composite("usdhc3", imx8mp_usdhc3_sels, ccm_base + 0xbc80);
|
||||||
hws[IMX8MP_CLK_MEDIA_CAM1_PIX] = imx8m_clk_hw_composite("media_cam1_pix", imx8mp_media_cam1_pix_sels, ccm_base + 0xbd00);
|
hws[IMX8MP_CLK_MEDIA_CAM1_PIX] = imx8m_clk_hw_composite("media_cam1_pix", imx8mp_media_cam1_pix_sels, ccm_base + 0xbd00);
|
||||||
hws[IMX8MP_CLK_MEDIA_MIPI_PHY1_REF] = imx8m_clk_hw_composite("media_mipi_phy1_ref", imx8mp_media_mipi_phy1_ref_sels, ccm_base + 0xbd80);
|
hws[IMX8MP_CLK_MEDIA_MIPI_PHY1_REF] = imx8m_clk_hw_composite("media_mipi_phy1_ref", imx8mp_media_mipi_phy1_ref_sels, ccm_base + 0xbd80);
|
||||||
hws[IMX8MP_CLK_MEDIA_DISP1_PIX] = imx8m_clk_hw_composite("media_disp1_pix", imx8mp_media_disp1_pix_sels, ccm_base + 0xbe00);
|
hws[IMX8MP_CLK_MEDIA_DISP1_PIX] = imx8m_clk_hw_composite("media_disp1_pix", imx8mp_media_disp_pix_sels, ccm_base + 0xbe00);
|
||||||
hws[IMX8MP_CLK_MEDIA_CAM2_PIX] = imx8m_clk_hw_composite("media_cam2_pix", imx8mp_media_cam2_pix_sels, ccm_base + 0xbe80);
|
hws[IMX8MP_CLK_MEDIA_CAM2_PIX] = imx8m_clk_hw_composite("media_cam2_pix", imx8mp_media_cam2_pix_sels, ccm_base + 0xbe80);
|
||||||
hws[IMX8MP_CLK_MEDIA_LDB] = imx8m_clk_hw_composite("media_ldb", imx8mp_media_ldb_sels, ccm_base + 0xbf00);
|
hws[IMX8MP_CLK_MEDIA_LDB] = imx8m_clk_hw_composite("media_ldb", imx8mp_media_ldb_sels, ccm_base + 0xbf00);
|
||||||
hws[IMX8MP_CLK_MEMREPAIR] = imx8m_clk_hw_composite_critical("mem_repair", imx8mp_memrepair_sels, ccm_base + 0xbf80);
|
hws[IMX8MP_CLK_MEMREPAIR] = imx8m_clk_hw_composite_critical("mem_repair", imx8mp_memrepair_sels, ccm_base + 0xbf80);
|
||||||
@ -654,12 +669,11 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
|
|||||||
hws[IMX8MP_CLK_SIM_ENET_ROOT] = imx_clk_hw_gate4("sim_enet_root_clk", "enet_axi", ccm_base + 0x4400, 0);
|
hws[IMX8MP_CLK_SIM_ENET_ROOT] = imx_clk_hw_gate4("sim_enet_root_clk", "enet_axi", ccm_base + 0x4400, 0);
|
||||||
hws[IMX8MP_CLK_GPU2D_ROOT] = imx_clk_hw_gate4("gpu2d_root_clk", "gpu2d_core", ccm_base + 0x4450, 0);
|
hws[IMX8MP_CLK_GPU2D_ROOT] = imx_clk_hw_gate4("gpu2d_root_clk", "gpu2d_core", ccm_base + 0x4450, 0);
|
||||||
hws[IMX8MP_CLK_GPU3D_ROOT] = imx_clk_hw_gate4("gpu3d_root_clk", "gpu3d_core", ccm_base + 0x4460, 0);
|
hws[IMX8MP_CLK_GPU3D_ROOT] = imx_clk_hw_gate4("gpu3d_root_clk", "gpu3d_core", ccm_base + 0x4460, 0);
|
||||||
hws[IMX8MP_CLK_SNVS_ROOT] = imx_clk_hw_gate4("snvs_root_clk", "ipg_root", ccm_base + 0x4470, 0);
|
|
||||||
hws[IMX8MP_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", ccm_base + 0x4490, 0);
|
hws[IMX8MP_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", ccm_base + 0x4490, 0);
|
||||||
hws[IMX8MP_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", ccm_base + 0x44a0, 0);
|
hws[IMX8MP_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", ccm_base + 0x44a0, 0);
|
||||||
hws[IMX8MP_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", ccm_base + 0x44b0, 0);
|
hws[IMX8MP_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", ccm_base + 0x44b0, 0);
|
||||||
hws[IMX8MP_CLK_UART4_ROOT] = imx_clk_hw_gate4("uart4_root_clk", "uart4", ccm_base + 0x44c0, 0);
|
hws[IMX8MP_CLK_UART4_ROOT] = imx_clk_hw_gate4("uart4_root_clk", "uart4", ccm_base + 0x44c0, 0);
|
||||||
hws[IMX8MP_CLK_USB_ROOT] = imx_clk_hw_gate4("usb_root_clk", "osc_32k", ccm_base + 0x44d0, 0);
|
hws[IMX8MP_CLK_USB_ROOT] = imx_clk_hw_gate4("usb_root_clk", "hsio_axi", ccm_base + 0x44d0, 0);
|
||||||
hws[IMX8MP_CLK_USB_PHY_ROOT] = imx_clk_hw_gate4("usb_phy_root_clk", "usb_phy_ref", ccm_base + 0x44f0, 0);
|
hws[IMX8MP_CLK_USB_PHY_ROOT] = imx_clk_hw_gate4("usb_phy_root_clk", "usb_phy_ref", ccm_base + 0x44f0, 0);
|
||||||
hws[IMX8MP_CLK_USDHC1_ROOT] = imx_clk_hw_gate4("usdhc1_root_clk", "usdhc1", ccm_base + 0x4510, 0);
|
hws[IMX8MP_CLK_USDHC1_ROOT] = imx_clk_hw_gate4("usdhc1_root_clk", "usdhc1", ccm_base + 0x4510, 0);
|
||||||
hws[IMX8MP_CLK_USDHC2_ROOT] = imx_clk_hw_gate4("usdhc2_root_clk", "usdhc2", ccm_base + 0x4520, 0);
|
hws[IMX8MP_CLK_USDHC2_ROOT] = imx_clk_hw_gate4("usdhc2_root_clk", "usdhc2", ccm_base + 0x4520, 0);
|
||||||
@ -721,6 +735,8 @@ static struct platform_driver imx8mp_clk_driver = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
module_platform_driver(imx8mp_clk_driver);
|
module_platform_driver(imx8mp_clk_driver);
|
||||||
|
module_param(mcore_booted, bool, S_IRUGO);
|
||||||
|
MODULE_PARM_DESC(mcore_booted, "See Cortex-M core is booted or not");
|
||||||
|
|
||||||
MODULE_AUTHOR("Anson Huang <Anson.Huang@nxp.com>");
|
MODULE_AUTHOR("Anson Huang <Anson.Huang@nxp.com>");
|
||||||
MODULE_DESCRIPTION("NXP i.MX8MP clock driver");
|
MODULE_DESCRIPTION("NXP i.MX8MP clock driver");
|
||||||
|
@ -25,7 +25,7 @@ static u32 share_count_sai6;
|
|||||||
static u32 share_count_dcss;
|
static u32 share_count_dcss;
|
||||||
static u32 share_count_nand;
|
static u32 share_count_nand;
|
||||||
|
|
||||||
static const char * const pll_ref_sels[] = { "osc_25m", "osc_27m", "dummy", "dummy", };
|
static const char * const pll_ref_sels[] = { "osc_25m", "osc_27m", "hdmi_phy_27m", "dummy", };
|
||||||
static const char * const arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", };
|
static const char * const arm_pll_bypass_sels[] = {"arm_pll", "arm_pll_ref_sel", };
|
||||||
static const char * const gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
|
static const char * const gpu_pll_bypass_sels[] = {"gpu_pll", "gpu_pll_ref_sel", };
|
||||||
static const char * const vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", };
|
static const char * const vpu_pll_bypass_sels[] = {"vpu_pll", "vpu_pll_ref_sel", };
|
||||||
@ -557,7 +557,6 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
|
|||||||
hws[IMX8MQ_CLK_SAI5_IPG] = imx_clk_hw_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5);
|
hws[IMX8MQ_CLK_SAI5_IPG] = imx_clk_hw_gate2_shared2("sai5_ipg_clk", "ipg_audio_root", base + 0x4370, 0, &share_count_sai5);
|
||||||
hws[IMX8MQ_CLK_SAI6_ROOT] = imx_clk_hw_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6);
|
hws[IMX8MQ_CLK_SAI6_ROOT] = imx_clk_hw_gate2_shared2("sai6_root_clk", "sai6", base + 0x4380, 0, &share_count_sai6);
|
||||||
hws[IMX8MQ_CLK_SAI6_IPG] = imx_clk_hw_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6);
|
hws[IMX8MQ_CLK_SAI6_IPG] = imx_clk_hw_gate2_shared2("sai6_ipg_clk", "ipg_audio_root", base + 0x4380, 0, &share_count_sai6);
|
||||||
hws[IMX8MQ_CLK_SNVS_ROOT] = imx_clk_hw_gate4("snvs_root_clk", "ipg_root", base + 0x4470, 0);
|
|
||||||
hws[IMX8MQ_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", base + 0x4490, 0);
|
hws[IMX8MQ_CLK_UART1_ROOT] = imx_clk_hw_gate4("uart1_root_clk", "uart1", base + 0x4490, 0);
|
||||||
hws[IMX8MQ_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0);
|
hws[IMX8MQ_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", base + 0x44a0, 0);
|
||||||
hws[IMX8MQ_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0);
|
hws[IMX8MQ_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", base + 0x44b0, 0);
|
||||||
@ -632,6 +631,8 @@ static struct platform_driver imx8mq_clk_driver = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
module_platform_driver(imx8mq_clk_driver);
|
module_platform_driver(imx8mq_clk_driver);
|
||||||
|
module_param(mcore_booted, bool, S_IRUGO);
|
||||||
|
MODULE_PARM_DESC(mcore_booted, "See Cortex-M core is booted or not");
|
||||||
|
|
||||||
MODULE_AUTHOR("Abel Vesa <abel.vesa@nxp.com>");
|
MODULE_AUTHOR("Abel Vesa <abel.vesa@nxp.com>");
|
||||||
MODULE_DESCRIPTION("NXP i.MX8MQ clock driver");
|
MODULE_DESCRIPTION("NXP i.MX8MQ clock driver");
|
||||||
|
@ -528,7 +528,7 @@ static int imx_clk_scu_probe(struct platform_device *pdev)
|
|||||||
pm_runtime_use_autosuspend(&pdev->dev);
|
pm_runtime_use_autosuspend(&pdev->dev);
|
||||||
pm_runtime_enable(dev);
|
pm_runtime_enable(dev);
|
||||||
|
|
||||||
ret = pm_runtime_get_sync(dev);
|
ret = pm_runtime_resume_and_get(dev);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
pm_genpd_remove_device(dev);
|
pm_genpd_remove_device(dev);
|
||||||
pm_runtime_disable(dev);
|
pm_runtime_disable(dev);
|
||||||
@ -837,8 +837,10 @@ struct clk_hw *__imx_clk_gpr_scu(const char *name, const char * const *parent_na
|
|||||||
if (!clk_node)
|
if (!clk_node)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
if (!imx_scu_clk_is_valid(rsrc_id))
|
if (!imx_scu_clk_is_valid(rsrc_id)) {
|
||||||
|
kfree(clk_node);
|
||||||
return ERR_PTR(-EINVAL);
|
return ERR_PTR(-EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
clk = kzalloc(sizeof(*clk), GFP_KERNEL);
|
clk = kzalloc(sizeof(*clk), GFP_KERNEL);
|
||||||
if (!clk) {
|
if (!clk) {
|
||||||
|
@ -17,6 +17,9 @@
|
|||||||
DEFINE_SPINLOCK(imx_ccm_lock);
|
DEFINE_SPINLOCK(imx_ccm_lock);
|
||||||
EXPORT_SYMBOL_GPL(imx_ccm_lock);
|
EXPORT_SYMBOL_GPL(imx_ccm_lock);
|
||||||
|
|
||||||
|
bool mcore_booted;
|
||||||
|
EXPORT_SYMBOL_GPL(mcore_booted);
|
||||||
|
|
||||||
void imx_unregister_clocks(struct clk *clks[], unsigned int count)
|
void imx_unregister_clocks(struct clk *clks[], unsigned int count)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
@ -173,6 +176,8 @@ void imx_register_uart_clocks(unsigned int clk_count)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
imx_uart_clocks = kcalloc(clk_count, sizeof(struct clk *), GFP_KERNEL);
|
imx_uart_clocks = kcalloc(clk_count, sizeof(struct clk *), GFP_KERNEL);
|
||||||
|
if (!imx_uart_clocks)
|
||||||
|
return;
|
||||||
|
|
||||||
if (!of_stdout)
|
if (!of_stdout)
|
||||||
return;
|
return;
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <linux/clk-provider.h>
|
#include <linux/clk-provider.h>
|
||||||
|
|
||||||
extern spinlock_t imx_ccm_lock;
|
extern spinlock_t imx_ccm_lock;
|
||||||
|
extern bool mcore_booted;
|
||||||
|
|
||||||
void imx_check_clocks(struct clk *clks[], unsigned int count);
|
void imx_check_clocks(struct clk *clks[], unsigned int count);
|
||||||
void imx_check_clk_hws(struct clk_hw *clks[], unsigned int count);
|
void imx_check_clk_hws(struct clk_hw *clks[], unsigned int count);
|
||||||
|
@ -660,7 +660,7 @@ static int ingenic_register_clock(struct ingenic_cgu *cgu, unsigned idx)
|
|||||||
ingenic_clk->idx = idx;
|
ingenic_clk->idx = idx;
|
||||||
|
|
||||||
clk_init.name = clk_info->name;
|
clk_init.name = clk_info->name;
|
||||||
clk_init.flags = 0;
|
clk_init.flags = clk_info->flags;
|
||||||
clk_init.parent_names = parent_names;
|
clk_init.parent_names = parent_names;
|
||||||
|
|
||||||
caps = clk_info->type;
|
caps = clk_info->type;
|
||||||
|
@ -136,6 +136,7 @@ struct ingenic_cgu_custom_info {
|
|||||||
* struct ingenic_cgu_clk_info - information about a clock
|
* struct ingenic_cgu_clk_info - information about a clock
|
||||||
* @name: name of the clock
|
* @name: name of the clock
|
||||||
* @type: a bitmask formed from CGU_CLK_* values
|
* @type: a bitmask formed from CGU_CLK_* values
|
||||||
|
* @flags: common clock flags to set on this clock
|
||||||
* @parents: an array of the indices of potential parents of this clock
|
* @parents: an array of the indices of potential parents of this clock
|
||||||
* within the clock_info array of the CGU, or -1 in entries
|
* within the clock_info array of the CGU, or -1 in entries
|
||||||
* which correspond to no valid parent
|
* which correspond to no valid parent
|
||||||
@ -161,6 +162,8 @@ struct ingenic_cgu_clk_info {
|
|||||||
CGU_CLK_CUSTOM = BIT(7),
|
CGU_CLK_CUSTOM = BIT(7),
|
||||||
} type;
|
} type;
|
||||||
|
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
int parents[4];
|
int parents[4];
|
||||||
|
|
||||||
union {
|
union {
|
||||||
|
@ -87,6 +87,11 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = {
|
|||||||
|
|
||||||
[JZ4725B_CLK_CCLK] = {
|
[JZ4725B_CLK_CCLK] = {
|
||||||
"cclk", CGU_CLK_DIV,
|
"cclk", CGU_CLK_DIV,
|
||||||
|
/*
|
||||||
|
* Disabling the CPU clock or any parent clocks will hang the
|
||||||
|
* system; mark it critical.
|
||||||
|
*/
|
||||||
|
.flags = CLK_IS_CRITICAL,
|
||||||
.parents = { JZ4725B_CLK_PLL, -1, -1, -1 },
|
.parents = { JZ4725B_CLK_PLL, -1, -1, -1 },
|
||||||
.div = {
|
.div = {
|
||||||
CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, 0,
|
CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, 0,
|
||||||
@ -114,6 +119,11 @@ static const struct ingenic_cgu_clk_info jz4725b_cgu_clocks[] = {
|
|||||||
|
|
||||||
[JZ4725B_CLK_MCLK] = {
|
[JZ4725B_CLK_MCLK] = {
|
||||||
"mclk", CGU_CLK_DIV,
|
"mclk", CGU_CLK_DIV,
|
||||||
|
/*
|
||||||
|
* Disabling MCLK or its parents will render DRAM
|
||||||
|
* inaccessible; mark it critical.
|
||||||
|
*/
|
||||||
|
.flags = CLK_IS_CRITICAL,
|
||||||
.parents = { JZ4725B_CLK_PLL, -1, -1, -1 },
|
.parents = { JZ4725B_CLK_PLL, -1, -1, -1 },
|
||||||
.div = {
|
.div = {
|
||||||
CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1, 0,
|
CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1, 0,
|
||||||
|
@ -102,6 +102,11 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = {
|
|||||||
|
|
||||||
[JZ4740_CLK_CCLK] = {
|
[JZ4740_CLK_CCLK] = {
|
||||||
"cclk", CGU_CLK_DIV,
|
"cclk", CGU_CLK_DIV,
|
||||||
|
/*
|
||||||
|
* Disabling the CPU clock or any parent clocks will hang the
|
||||||
|
* system; mark it critical.
|
||||||
|
*/
|
||||||
|
.flags = CLK_IS_CRITICAL,
|
||||||
.parents = { JZ4740_CLK_PLL, -1, -1, -1 },
|
.parents = { JZ4740_CLK_PLL, -1, -1, -1 },
|
||||||
.div = {
|
.div = {
|
||||||
CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, 0,
|
CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, 0,
|
||||||
@ -129,6 +134,11 @@ static const struct ingenic_cgu_clk_info jz4740_cgu_clocks[] = {
|
|||||||
|
|
||||||
[JZ4740_CLK_MCLK] = {
|
[JZ4740_CLK_MCLK] = {
|
||||||
"mclk", CGU_CLK_DIV,
|
"mclk", CGU_CLK_DIV,
|
||||||
|
/*
|
||||||
|
* Disabling MCLK or its parents will render DRAM
|
||||||
|
* inaccessible; mark it critical.
|
||||||
|
*/
|
||||||
|
.flags = CLK_IS_CRITICAL,
|
||||||
.parents = { JZ4740_CLK_PLL, -1, -1, -1 },
|
.parents = { JZ4740_CLK_PLL, -1, -1, -1 },
|
||||||
.div = {
|
.div = {
|
||||||
CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1, 0,
|
CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1, 0,
|
||||||
|
@ -143,6 +143,11 @@ static const struct ingenic_cgu_clk_info jz4760_cgu_clocks[] = {
|
|||||||
|
|
||||||
[JZ4760_CLK_CCLK] = {
|
[JZ4760_CLK_CCLK] = {
|
||||||
"cclk", CGU_CLK_DIV,
|
"cclk", CGU_CLK_DIV,
|
||||||
|
/*
|
||||||
|
* Disabling the CPU clock or any parent clocks will hang the
|
||||||
|
* system; mark it critical.
|
||||||
|
*/
|
||||||
|
.flags = CLK_IS_CRITICAL,
|
||||||
.parents = { JZ4760_CLK_PLL0, },
|
.parents = { JZ4760_CLK_PLL0, },
|
||||||
.div = {
|
.div = {
|
||||||
CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, 0,
|
CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, 0,
|
||||||
@ -175,6 +180,11 @@ static const struct ingenic_cgu_clk_info jz4760_cgu_clocks[] = {
|
|||||||
},
|
},
|
||||||
[JZ4760_CLK_MCLK] = {
|
[JZ4760_CLK_MCLK] = {
|
||||||
"mclk", CGU_CLK_DIV,
|
"mclk", CGU_CLK_DIV,
|
||||||
|
/*
|
||||||
|
* Disabling MCLK or its parents will render DRAM
|
||||||
|
* inaccessible; mark it critical.
|
||||||
|
*/
|
||||||
|
.flags = CLK_IS_CRITICAL,
|
||||||
.parents = { JZ4760_CLK_PLL0, },
|
.parents = { JZ4760_CLK_PLL0, },
|
||||||
.div = {
|
.div = {
|
||||||
CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1, 0,
|
CGU_REG_CPCCR, 12, 1, 4, 22, -1, -1, 0,
|
||||||
|
@ -149,6 +149,11 @@ static const struct ingenic_cgu_clk_info jz4770_cgu_clocks[] = {
|
|||||||
|
|
||||||
[JZ4770_CLK_CCLK] = {
|
[JZ4770_CLK_CCLK] = {
|
||||||
"cclk", CGU_CLK_DIV,
|
"cclk", CGU_CLK_DIV,
|
||||||
|
/*
|
||||||
|
* Disabling the CPU clock or any parent clocks will hang the
|
||||||
|
* system; mark it critical.
|
||||||
|
*/
|
||||||
|
.flags = CLK_IS_CRITICAL,
|
||||||
.parents = { JZ4770_CLK_PLL0, },
|
.parents = { JZ4770_CLK_PLL0, },
|
||||||
.div = {
|
.div = {
|
||||||
CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, 0,
|
CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1, 0,
|
||||||
|
@ -341,12 +341,22 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
|
|||||||
|
|
||||||
[JZ4780_CLK_CPU] = {
|
[JZ4780_CLK_CPU] = {
|
||||||
"cpu", CGU_CLK_DIV,
|
"cpu", CGU_CLK_DIV,
|
||||||
|
/*
|
||||||
|
* Disabling the CPU clock or any parent clocks will hang the
|
||||||
|
* system; mark it critical.
|
||||||
|
*/
|
||||||
|
.flags = CLK_IS_CRITICAL,
|
||||||
.parents = { JZ4780_CLK_CPUMUX, -1, -1, -1 },
|
.parents = { JZ4780_CLK_CPUMUX, -1, -1, -1 },
|
||||||
.div = { CGU_REG_CLOCKCONTROL, 0, 1, 4, 22, -1, -1 },
|
.div = { CGU_REG_CLOCKCONTROL, 0, 1, 4, 22, -1, -1 },
|
||||||
},
|
},
|
||||||
|
|
||||||
[JZ4780_CLK_L2CACHE] = {
|
[JZ4780_CLK_L2CACHE] = {
|
||||||
"l2cache", CGU_CLK_DIV,
|
"l2cache", CGU_CLK_DIV,
|
||||||
|
/*
|
||||||
|
* The L2 cache clock is critical if caches are enabled and
|
||||||
|
* disabling it or any parent clocks will hang the system.
|
||||||
|
*/
|
||||||
|
.flags = CLK_IS_CRITICAL,
|
||||||
.parents = { JZ4780_CLK_CPUMUX, -1, -1, -1 },
|
.parents = { JZ4780_CLK_CPUMUX, -1, -1, -1 },
|
||||||
.div = { CGU_REG_CLOCKCONTROL, 4, 1, 4, -1, -1, -1 },
|
.div = { CGU_REG_CLOCKCONTROL, 4, 1, 4, -1, -1, -1 },
|
||||||
},
|
},
|
||||||
@ -380,6 +390,11 @@ static const struct ingenic_cgu_clk_info jz4780_cgu_clocks[] = {
|
|||||||
|
|
||||||
[JZ4780_CLK_DDR] = {
|
[JZ4780_CLK_DDR] = {
|
||||||
"ddr", CGU_CLK_MUX | CGU_CLK_DIV,
|
"ddr", CGU_CLK_MUX | CGU_CLK_DIV,
|
||||||
|
/*
|
||||||
|
* Disabling DDR clock or its parents will render DRAM
|
||||||
|
* inaccessible; mark it critical.
|
||||||
|
*/
|
||||||
|
.flags = CLK_IS_CRITICAL,
|
||||||
.parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1 },
|
.parents = { -1, JZ4780_CLK_SCLKA, JZ4780_CLK_MPLL, -1 },
|
||||||
.mux = { CGU_REG_DDRCDR, 30, 2 },
|
.mux = { CGU_REG_DDRCDR, 30, 2 },
|
||||||
.div = { CGU_REG_DDRCDR, 0, 1, 4, 29, 28, 27 },
|
.div = { CGU_REG_DDRCDR, 0, 1, 4, 29, 28, 27 },
|
||||||
|
@ -31,6 +31,7 @@ struct ingenic_soc_info {
|
|||||||
unsigned int num_channels;
|
unsigned int num_channels;
|
||||||
bool has_ost;
|
bool has_ost;
|
||||||
bool has_tcu_clk;
|
bool has_tcu_clk;
|
||||||
|
bool allow_missing_tcu_clk;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ingenic_tcu_clk_info {
|
struct ingenic_tcu_clk_info {
|
||||||
@ -320,7 +321,8 @@ static const struct ingenic_soc_info jz4770_soc_info = {
|
|||||||
static const struct ingenic_soc_info x1000_soc_info = {
|
static const struct ingenic_soc_info x1000_soc_info = {
|
||||||
.num_channels = 8,
|
.num_channels = 8,
|
||||||
.has_ost = false, /* X1000 has OST, but it not belong TCU */
|
.has_ost = false, /* X1000 has OST, but it not belong TCU */
|
||||||
.has_tcu_clk = false,
|
.has_tcu_clk = true,
|
||||||
|
.allow_missing_tcu_clk = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct of_device_id __maybe_unused ingenic_tcu_of_match[] __initconst = {
|
static const struct of_device_id __maybe_unused ingenic_tcu_of_match[] __initconst = {
|
||||||
@ -355,14 +357,27 @@ static int __init ingenic_tcu_probe(struct device_node *np)
|
|||||||
tcu->clk = of_clk_get_by_name(np, "tcu");
|
tcu->clk = of_clk_get_by_name(np, "tcu");
|
||||||
if (IS_ERR(tcu->clk)) {
|
if (IS_ERR(tcu->clk)) {
|
||||||
ret = PTR_ERR(tcu->clk);
|
ret = PTR_ERR(tcu->clk);
|
||||||
pr_crit("Cannot get TCU clock\n");
|
|
||||||
goto err_free_tcu;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = clk_prepare_enable(tcu->clk);
|
/*
|
||||||
if (ret) {
|
* Old device trees for some SoCs did not include the
|
||||||
pr_crit("Unable to enable TCU clock\n");
|
* TCU clock because this driver (incorrectly) didn't
|
||||||
goto err_put_clk;
|
* use it. In this case we complain loudly and attempt
|
||||||
|
* to continue without the clock, which might work if
|
||||||
|
* booting with workarounds like "clk_ignore_unused".
|
||||||
|
*/
|
||||||
|
if (tcu->soc_info->allow_missing_tcu_clk && ret == -EINVAL) {
|
||||||
|
pr_warn("TCU clock missing from device tree, please update your device tree\n");
|
||||||
|
tcu->clk = NULL;
|
||||||
|
} else {
|
||||||
|
pr_crit("Cannot get TCU clock from device tree\n");
|
||||||
|
goto err_free_tcu;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ret = clk_prepare_enable(tcu->clk);
|
||||||
|
if (ret) {
|
||||||
|
pr_crit("Unable to enable TCU clock\n");
|
||||||
|
goto err_put_clk;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -432,10 +447,10 @@ err_unregister_timer_clocks:
|
|||||||
clk_hw_unregister(tcu->clocks->hws[i]);
|
clk_hw_unregister(tcu->clocks->hws[i]);
|
||||||
kfree(tcu->clocks);
|
kfree(tcu->clocks);
|
||||||
err_clk_disable:
|
err_clk_disable:
|
||||||
if (tcu->soc_info->has_tcu_clk)
|
if (tcu->clk)
|
||||||
clk_disable_unprepare(tcu->clk);
|
clk_disable_unprepare(tcu->clk);
|
||||||
err_put_clk:
|
err_put_clk:
|
||||||
if (tcu->soc_info->has_tcu_clk)
|
if (tcu->clk)
|
||||||
clk_put(tcu->clk);
|
clk_put(tcu->clk);
|
||||||
err_free_tcu:
|
err_free_tcu:
|
||||||
kfree(tcu);
|
kfree(tcu);
|
||||||
|
@ -251,6 +251,11 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
|
|||||||
|
|
||||||
[X1000_CLK_CPU] = {
|
[X1000_CLK_CPU] = {
|
||||||
"cpu", CGU_CLK_DIV | CGU_CLK_GATE,
|
"cpu", CGU_CLK_DIV | CGU_CLK_GATE,
|
||||||
|
/*
|
||||||
|
* Disabling the CPU clock or any parent clocks will hang the
|
||||||
|
* system; mark it critical.
|
||||||
|
*/
|
||||||
|
.flags = CLK_IS_CRITICAL,
|
||||||
.parents = { X1000_CLK_CPUMUX, -1, -1, -1 },
|
.parents = { X1000_CLK_CPUMUX, -1, -1, -1 },
|
||||||
.div = { CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1 },
|
.div = { CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1 },
|
||||||
.gate = { CGU_REG_CLKGR, 30 },
|
.gate = { CGU_REG_CLKGR, 30 },
|
||||||
@ -258,6 +263,11 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
|
|||||||
|
|
||||||
[X1000_CLK_L2CACHE] = {
|
[X1000_CLK_L2CACHE] = {
|
||||||
"l2cache", CGU_CLK_DIV,
|
"l2cache", CGU_CLK_DIV,
|
||||||
|
/*
|
||||||
|
* The L2 cache clock is critical if caches are enabled and
|
||||||
|
* disabling it or any parent clocks will hang the system.
|
||||||
|
*/
|
||||||
|
.flags = CLK_IS_CRITICAL,
|
||||||
.parents = { X1000_CLK_CPUMUX, -1, -1, -1 },
|
.parents = { X1000_CLK_CPUMUX, -1, -1, -1 },
|
||||||
.div = { CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1 },
|
.div = { CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1 },
|
||||||
},
|
},
|
||||||
@ -290,6 +300,11 @@ static const struct ingenic_cgu_clk_info x1000_cgu_clocks[] = {
|
|||||||
|
|
||||||
[X1000_CLK_DDR] = {
|
[X1000_CLK_DDR] = {
|
||||||
"ddr", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
|
"ddr", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
|
||||||
|
/*
|
||||||
|
* Disabling DDR clock or its parents will render DRAM
|
||||||
|
* inaccessible; mark it critical.
|
||||||
|
*/
|
||||||
|
.flags = CLK_IS_CRITICAL,
|
||||||
.parents = { -1, X1000_CLK_SCLKA, X1000_CLK_MPLL, -1 },
|
.parents = { -1, X1000_CLK_SCLKA, X1000_CLK_MPLL, -1 },
|
||||||
.mux = { CGU_REG_DDRCDR, 30, 2 },
|
.mux = { CGU_REG_DDRCDR, 30, 2 },
|
||||||
.div = { CGU_REG_DDRCDR, 0, 1, 4, 29, 28, 27 },
|
.div = { CGU_REG_DDRCDR, 0, 1, 4, 29, 28, 27 },
|
||||||
|
@ -225,6 +225,7 @@ static const struct ingenic_cgu_clk_info x1830_cgu_clocks[] = {
|
|||||||
|
|
||||||
[X1830_CLK_CPU] = {
|
[X1830_CLK_CPU] = {
|
||||||
"cpu", CGU_CLK_DIV | CGU_CLK_GATE,
|
"cpu", CGU_CLK_DIV | CGU_CLK_GATE,
|
||||||
|
.flags = CLK_IS_CRITICAL,
|
||||||
.parents = { X1830_CLK_CPUMUX, -1, -1, -1 },
|
.parents = { X1830_CLK_CPUMUX, -1, -1, -1 },
|
||||||
.div = { CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1 },
|
.div = { CGU_REG_CPCCR, 0, 1, 4, 22, -1, -1 },
|
||||||
.gate = { CGU_REG_CLKGR1, 15 },
|
.gate = { CGU_REG_CLKGR1, 15 },
|
||||||
@ -232,6 +233,11 @@ static const struct ingenic_cgu_clk_info x1830_cgu_clocks[] = {
|
|||||||
|
|
||||||
[X1830_CLK_L2CACHE] = {
|
[X1830_CLK_L2CACHE] = {
|
||||||
"l2cache", CGU_CLK_DIV,
|
"l2cache", CGU_CLK_DIV,
|
||||||
|
/*
|
||||||
|
* The L2 cache clock is critical if caches are enabled and
|
||||||
|
* disabling it or any parent clocks will hang the system.
|
||||||
|
*/
|
||||||
|
.flags = CLK_IS_CRITICAL,
|
||||||
.parents = { X1830_CLK_CPUMUX, -1, -1, -1 },
|
.parents = { X1830_CLK_CPUMUX, -1, -1, -1 },
|
||||||
.div = { CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1 },
|
.div = { CGU_REG_CPCCR, 4, 1, 4, 22, -1, -1 },
|
||||||
},
|
},
|
||||||
@ -264,6 +270,11 @@ static const struct ingenic_cgu_clk_info x1830_cgu_clocks[] = {
|
|||||||
|
|
||||||
[X1830_CLK_DDR] = {
|
[X1830_CLK_DDR] = {
|
||||||
"ddr", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
|
"ddr", CGU_CLK_MUX | CGU_CLK_DIV | CGU_CLK_GATE,
|
||||||
|
/*
|
||||||
|
* Disabling DDR clock or its parents will render DRAM
|
||||||
|
* inaccessible; mark it critical.
|
||||||
|
*/
|
||||||
|
.flags = CLK_IS_CRITICAL,
|
||||||
.parents = { -1, X1830_CLK_SCLKA, X1830_CLK_MPLL, -1 },
|
.parents = { -1, X1830_CLK_SCLKA, X1830_CLK_MPLL, -1 },
|
||||||
.mux = { CGU_REG_DDRCDR, 30, 2 },
|
.mux = { CGU_REG_DDRCDR, 30, 2 },
|
||||||
.div = { CGU_REG_DDRCDR, 0, 1, 4, 29, 28, 27 },
|
.div = { CGU_REG_DDRCDR, 0, 1, 4, 29, 28, 27 },
|
||||||
|
@ -162,6 +162,13 @@ static const struct ti_syscon_gate_clk_data am64_clk_data[] = {
|
|||||||
{ /* Sentinel */ },
|
{ /* Sentinel */ },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct ti_syscon_gate_clk_data am62_clk_data[] = {
|
||||||
|
TI_SYSCON_CLK_GATE("epwm_tbclk0", 0x0, 0),
|
||||||
|
TI_SYSCON_CLK_GATE("epwm_tbclk1", 0x0, 1),
|
||||||
|
TI_SYSCON_CLK_GATE("epwm_tbclk2", 0x0, 2),
|
||||||
|
{ /* Sentinel */ },
|
||||||
|
};
|
||||||
|
|
||||||
static const struct of_device_id ti_syscon_gate_clk_ids[] = {
|
static const struct of_device_id ti_syscon_gate_clk_ids[] = {
|
||||||
{
|
{
|
||||||
.compatible = "ti,am654-ehrpwm-tbclk",
|
.compatible = "ti,am654-ehrpwm-tbclk",
|
||||||
@ -171,6 +178,10 @@ static const struct of_device_id ti_syscon_gate_clk_ids[] = {
|
|||||||
.compatible = "ti,am64-epwm-tbclk",
|
.compatible = "ti,am64-epwm-tbclk",
|
||||||
.data = &am64_clk_data,
|
.data = &am64_clk_data,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.compatible = "ti,am62-epwm-tbclk",
|
||||||
|
.data = &am62_clk_data,
|
||||||
|
},
|
||||||
{ }
|
{ }
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, ti_syscon_gate_clk_ids);
|
MODULE_DEVICE_TABLE(of, ti_syscon_gate_clk_ids);
|
||||||
|
@ -512,6 +512,14 @@ config COMMON_CLK_MT8183_VENCSYS
|
|||||||
help
|
help
|
||||||
This driver supports MediaTek MT8183 vencsys clocks.
|
This driver supports MediaTek MT8183 vencsys clocks.
|
||||||
|
|
||||||
|
config COMMON_CLK_MT8186
|
||||||
|
bool "Clock driver for MediaTek MT8186"
|
||||||
|
depends on ARM64 || COMPILE_TEST
|
||||||
|
select COMMON_CLK_MEDIATEK
|
||||||
|
default ARCH_MEDIATEK
|
||||||
|
help
|
||||||
|
This driver supports MediaTek MT8186 clocks.
|
||||||
|
|
||||||
config COMMON_CLK_MT8192
|
config COMMON_CLK_MT8192
|
||||||
bool "Clock driver for MediaTek MT8192"
|
bool "Clock driver for MediaTek MT8192"
|
||||||
depends on ARM64 || COMPILE_TEST
|
depends on ARM64 || COMPILE_TEST
|
||||||
|
@ -71,6 +71,11 @@ obj-$(CONFIG_COMMON_CLK_MT8183_MFGCFG) += clk-mt8183-mfgcfg.o
|
|||||||
obj-$(CONFIG_COMMON_CLK_MT8183_MMSYS) += clk-mt8183-mm.o
|
obj-$(CONFIG_COMMON_CLK_MT8183_MMSYS) += clk-mt8183-mm.o
|
||||||
obj-$(CONFIG_COMMON_CLK_MT8183_VDECSYS) += clk-mt8183-vdec.o
|
obj-$(CONFIG_COMMON_CLK_MT8183_VDECSYS) += clk-mt8183-vdec.o
|
||||||
obj-$(CONFIG_COMMON_CLK_MT8183_VENCSYS) += clk-mt8183-venc.o
|
obj-$(CONFIG_COMMON_CLK_MT8183_VENCSYS) += clk-mt8183-venc.o
|
||||||
|
obj-$(CONFIG_COMMON_CLK_MT8186) += clk-mt8186-mcu.o clk-mt8186-topckgen.o clk-mt8186-infra_ao.o \
|
||||||
|
clk-mt8186-apmixedsys.o clk-mt8186-imp_iic_wrap.o \
|
||||||
|
clk-mt8186-mfg.o clk-mt8186-mm.o clk-mt8186-wpe.o \
|
||||||
|
clk-mt8186-img.o clk-mt8186-vdec.o clk-mt8186-venc.o \
|
||||||
|
clk-mt8186-cam.o clk-mt8186-mdp.o clk-mt8186-ipe.o
|
||||||
obj-$(CONFIG_COMMON_CLK_MT8192) += clk-mt8192.o
|
obj-$(CONFIG_COMMON_CLK_MT8192) += clk-mt8192.o
|
||||||
obj-$(CONFIG_COMMON_CLK_MT8192_AUDSYS) += clk-mt8192-aud.o
|
obj-$(CONFIG_COMMON_CLK_MT8192_AUDSYS) += clk-mt8192-aud.o
|
||||||
obj-$(CONFIG_COMMON_CLK_MT8192_CAMSYS) += clk-mt8192-cam.o
|
obj-$(CONFIG_COMMON_CLK_MT8192_CAMSYS) += clk-mt8192-cam.o
|
||||||
|
@ -70,12 +70,12 @@ static const struct clk_ops mtk_ref2usb_tx_ops = {
|
|||||||
.unprepare = mtk_ref2usb_tx_unprepare,
|
.unprepare = mtk_ref2usb_tx_unprepare,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct clk * __init mtk_clk_register_ref2usb_tx(const char *name,
|
struct clk_hw * __init mtk_clk_register_ref2usb_tx(const char *name,
|
||||||
const char *parent_name, void __iomem *reg)
|
const char *parent_name, void __iomem *reg)
|
||||||
{
|
{
|
||||||
struct mtk_ref2usb_tx *tx;
|
struct mtk_ref2usb_tx *tx;
|
||||||
struct clk_init_data init = {};
|
struct clk_init_data init = {};
|
||||||
struct clk *clk;
|
int ret;
|
||||||
|
|
||||||
tx = kzalloc(sizeof(*tx), GFP_KERNEL);
|
tx = kzalloc(sizeof(*tx), GFP_KERNEL);
|
||||||
if (!tx)
|
if (!tx)
|
||||||
@ -89,14 +89,14 @@ struct clk * __init mtk_clk_register_ref2usb_tx(const char *name,
|
|||||||
init.parent_names = &parent_name;
|
init.parent_names = &parent_name;
|
||||||
init.num_parents = 1;
|
init.num_parents = 1;
|
||||||
|
|
||||||
clk = clk_register(NULL, &tx->hw);
|
ret = clk_hw_register(NULL, &tx->hw);
|
||||||
|
|
||||||
if (IS_ERR(clk)) {
|
if (ret) {
|
||||||
pr_err("Failed to register clk %s: %pe\n", name, clk);
|
|
||||||
kfree(tx);
|
kfree(tx);
|
||||||
|
return ERR_PTR(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
return clk;
|
return &tx->hw;
|
||||||
}
|
}
|
||||||
|
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
@ -57,12 +57,12 @@ static const struct clk_ops clk_cpumux_ops = {
|
|||||||
.set_parent = clk_cpumux_set_parent,
|
.set_parent = clk_cpumux_set_parent,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk *
|
static struct clk_hw *
|
||||||
mtk_clk_register_cpumux(const struct mtk_composite *mux,
|
mtk_clk_register_cpumux(const struct mtk_composite *mux,
|
||||||
struct regmap *regmap)
|
struct regmap *regmap)
|
||||||
{
|
{
|
||||||
struct mtk_clk_cpumux *cpumux;
|
struct mtk_clk_cpumux *cpumux;
|
||||||
struct clk *clk;
|
int ret;
|
||||||
struct clk_init_data init;
|
struct clk_init_data init;
|
||||||
|
|
||||||
cpumux = kzalloc(sizeof(*cpumux), GFP_KERNEL);
|
cpumux = kzalloc(sizeof(*cpumux), GFP_KERNEL);
|
||||||
@ -81,34 +81,33 @@ mtk_clk_register_cpumux(const struct mtk_composite *mux,
|
|||||||
cpumux->regmap = regmap;
|
cpumux->regmap = regmap;
|
||||||
cpumux->hw.init = &init;
|
cpumux->hw.init = &init;
|
||||||
|
|
||||||
clk = clk_register(NULL, &cpumux->hw);
|
ret = clk_hw_register(NULL, &cpumux->hw);
|
||||||
if (IS_ERR(clk))
|
if (ret) {
|
||||||
kfree(cpumux);
|
kfree(cpumux);
|
||||||
|
return ERR_PTR(ret);
|
||||||
|
}
|
||||||
|
|
||||||
return clk;
|
return &cpumux->hw;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mtk_clk_unregister_cpumux(struct clk *clk)
|
static void mtk_clk_unregister_cpumux(struct clk_hw *hw)
|
||||||
{
|
{
|
||||||
struct mtk_clk_cpumux *cpumux;
|
struct mtk_clk_cpumux *cpumux;
|
||||||
struct clk_hw *hw;
|
|
||||||
|
|
||||||
hw = __clk_get_hw(clk);
|
|
||||||
if (!hw)
|
if (!hw)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cpumux = to_mtk_clk_cpumux(hw);
|
cpumux = to_mtk_clk_cpumux(hw);
|
||||||
|
|
||||||
clk_unregister(clk);
|
clk_hw_unregister(hw);
|
||||||
kfree(cpumux);
|
kfree(cpumux);
|
||||||
}
|
}
|
||||||
|
|
||||||
int mtk_clk_register_cpumuxes(struct device_node *node,
|
int mtk_clk_register_cpumuxes(struct device_node *node,
|
||||||
const struct mtk_composite *clks, int num,
|
const struct mtk_composite *clks, int num,
|
||||||
struct clk_onecell_data *clk_data)
|
struct clk_hw_onecell_data *clk_data)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct clk *clk;
|
struct clk_hw *hw;
|
||||||
struct regmap *regmap;
|
struct regmap *regmap;
|
||||||
|
|
||||||
regmap = device_node_to_regmap(node);
|
regmap = device_node_to_regmap(node);
|
||||||
@ -120,19 +119,20 @@ int mtk_clk_register_cpumuxes(struct device_node *node,
|
|||||||
for (i = 0; i < num; i++) {
|
for (i = 0; i < num; i++) {
|
||||||
const struct mtk_composite *mux = &clks[i];
|
const struct mtk_composite *mux = &clks[i];
|
||||||
|
|
||||||
if (!IS_ERR_OR_NULL(clk_data->clks[mux->id])) {
|
if (!IS_ERR_OR_NULL(clk_data->hws[mux->id])) {
|
||||||
pr_warn("%pOF: Trying to register duplicate clock ID: %d\n",
|
pr_warn("%pOF: Trying to register duplicate clock ID: %d\n",
|
||||||
node, mux->id);
|
node, mux->id);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
clk = mtk_clk_register_cpumux(mux, regmap);
|
hw = mtk_clk_register_cpumux(mux, regmap);
|
||||||
if (IS_ERR(clk)) {
|
if (IS_ERR(hw)) {
|
||||||
pr_err("Failed to register clk %s: %pe\n", mux->name, clk);
|
pr_err("Failed to register clk %s: %pe\n", mux->name,
|
||||||
|
hw);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
clk_data->clks[mux->id] = clk;
|
clk_data->hws[mux->id] = hw;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -141,29 +141,29 @@ err:
|
|||||||
while (--i >= 0) {
|
while (--i >= 0) {
|
||||||
const struct mtk_composite *mux = &clks[i];
|
const struct mtk_composite *mux = &clks[i];
|
||||||
|
|
||||||
if (IS_ERR_OR_NULL(clk_data->clks[mux->id]))
|
if (IS_ERR_OR_NULL(clk_data->hws[mux->id]))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
mtk_clk_unregister_cpumux(clk_data->clks[mux->id]);
|
mtk_clk_unregister_cpumux(clk_data->hws[mux->id]);
|
||||||
clk_data->clks[mux->id] = ERR_PTR(-ENOENT);
|
clk_data->hws[mux->id] = ERR_PTR(-ENOENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
return PTR_ERR(clk);
|
return PTR_ERR(hw);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mtk_clk_unregister_cpumuxes(const struct mtk_composite *clks, int num,
|
void mtk_clk_unregister_cpumuxes(const struct mtk_composite *clks, int num,
|
||||||
struct clk_onecell_data *clk_data)
|
struct clk_hw_onecell_data *clk_data)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = num; i > 0; i--) {
|
for (i = num; i > 0; i--) {
|
||||||
const struct mtk_composite *mux = &clks[i - 1];
|
const struct mtk_composite *mux = &clks[i - 1];
|
||||||
|
|
||||||
if (IS_ERR_OR_NULL(clk_data->clks[mux->id]))
|
if (IS_ERR_OR_NULL(clk_data->hws[mux->id]))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
mtk_clk_unregister_cpumux(clk_data->clks[mux->id]);
|
mtk_clk_unregister_cpumux(clk_data->hws[mux->id]);
|
||||||
clk_data->clks[mux->id] = ERR_PTR(-ENOENT);
|
clk_data->hws[mux->id] = ERR_PTR(-ENOENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,15 +7,15 @@
|
|||||||
#ifndef __DRV_CLK_CPUMUX_H
|
#ifndef __DRV_CLK_CPUMUX_H
|
||||||
#define __DRV_CLK_CPUMUX_H
|
#define __DRV_CLK_CPUMUX_H
|
||||||
|
|
||||||
struct clk_onecell_data;
|
struct clk_hw_onecell_data;
|
||||||
struct device_node;
|
struct device_node;
|
||||||
struct mtk_composite;
|
struct mtk_composite;
|
||||||
|
|
||||||
int mtk_clk_register_cpumuxes(struct device_node *node,
|
int mtk_clk_register_cpumuxes(struct device_node *node,
|
||||||
const struct mtk_composite *clks, int num,
|
const struct mtk_composite *clks, int num,
|
||||||
struct clk_onecell_data *clk_data);
|
struct clk_hw_onecell_data *clk_data);
|
||||||
|
|
||||||
void mtk_clk_unregister_cpumuxes(const struct mtk_composite *clks, int num,
|
void mtk_clk_unregister_cpumuxes(const struct mtk_composite *clks, int num,
|
||||||
struct clk_onecell_data *clk_data);
|
struct clk_hw_onecell_data *clk_data);
|
||||||
|
|
||||||
#endif /* __DRV_CLK_CPUMUX_H */
|
#endif /* __DRV_CLK_CPUMUX_H */
|
||||||
|
@ -152,7 +152,7 @@ const struct clk_ops mtk_clk_gate_ops_no_setclr_inv = {
|
|||||||
};
|
};
|
||||||
EXPORT_SYMBOL_GPL(mtk_clk_gate_ops_no_setclr_inv);
|
EXPORT_SYMBOL_GPL(mtk_clk_gate_ops_no_setclr_inv);
|
||||||
|
|
||||||
static struct clk *mtk_clk_register_gate(const char *name,
|
static struct clk_hw *mtk_clk_register_gate(const char *name,
|
||||||
const char *parent_name,
|
const char *parent_name,
|
||||||
struct regmap *regmap, int set_ofs,
|
struct regmap *regmap, int set_ofs,
|
||||||
int clr_ofs, int sta_ofs, u8 bit,
|
int clr_ofs, int sta_ofs, u8 bit,
|
||||||
@ -160,7 +160,7 @@ static struct clk *mtk_clk_register_gate(const char *name,
|
|||||||
unsigned long flags, struct device *dev)
|
unsigned long flags, struct device *dev)
|
||||||
{
|
{
|
||||||
struct mtk_clk_gate *cg;
|
struct mtk_clk_gate *cg;
|
||||||
struct clk *clk;
|
int ret;
|
||||||
struct clk_init_data init = {};
|
struct clk_init_data init = {};
|
||||||
|
|
||||||
cg = kzalloc(sizeof(*cg), GFP_KERNEL);
|
cg = kzalloc(sizeof(*cg), GFP_KERNEL);
|
||||||
@ -181,35 +181,34 @@ static struct clk *mtk_clk_register_gate(const char *name,
|
|||||||
|
|
||||||
cg->hw.init = &init;
|
cg->hw.init = &init;
|
||||||
|
|
||||||
clk = clk_register(dev, &cg->hw);
|
ret = clk_hw_register(dev, &cg->hw);
|
||||||
if (IS_ERR(clk))
|
if (ret) {
|
||||||
kfree(cg);
|
kfree(cg);
|
||||||
|
return ERR_PTR(ret);
|
||||||
|
}
|
||||||
|
|
||||||
return clk;
|
return &cg->hw;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mtk_clk_unregister_gate(struct clk *clk)
|
static void mtk_clk_unregister_gate(struct clk_hw *hw)
|
||||||
{
|
{
|
||||||
struct mtk_clk_gate *cg;
|
struct mtk_clk_gate *cg;
|
||||||
struct clk_hw *hw;
|
|
||||||
|
|
||||||
hw = __clk_get_hw(clk);
|
|
||||||
if (!hw)
|
if (!hw)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cg = to_mtk_clk_gate(hw);
|
cg = to_mtk_clk_gate(hw);
|
||||||
|
|
||||||
clk_unregister(clk);
|
clk_hw_unregister(hw);
|
||||||
kfree(cg);
|
kfree(cg);
|
||||||
}
|
}
|
||||||
|
|
||||||
int mtk_clk_register_gates_with_dev(struct device_node *node,
|
int mtk_clk_register_gates_with_dev(struct device_node *node,
|
||||||
const struct mtk_gate *clks, int num,
|
const struct mtk_gate *clks, int num,
|
||||||
struct clk_onecell_data *clk_data,
|
struct clk_hw_onecell_data *clk_data,
|
||||||
struct device *dev)
|
struct device *dev)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct clk *clk;
|
struct clk_hw *hw;
|
||||||
struct regmap *regmap;
|
struct regmap *regmap;
|
||||||
|
|
||||||
if (!clk_data)
|
if (!clk_data)
|
||||||
@ -224,13 +223,13 @@ int mtk_clk_register_gates_with_dev(struct device_node *node,
|
|||||||
for (i = 0; i < num; i++) {
|
for (i = 0; i < num; i++) {
|
||||||
const struct mtk_gate *gate = &clks[i];
|
const struct mtk_gate *gate = &clks[i];
|
||||||
|
|
||||||
if (!IS_ERR_OR_NULL(clk_data->clks[gate->id])) {
|
if (!IS_ERR_OR_NULL(clk_data->hws[gate->id])) {
|
||||||
pr_warn("%pOF: Trying to register duplicate clock ID: %d\n",
|
pr_warn("%pOF: Trying to register duplicate clock ID: %d\n",
|
||||||
node, gate->id);
|
node, gate->id);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
clk = mtk_clk_register_gate(gate->name, gate->parent_name,
|
hw = mtk_clk_register_gate(gate->name, gate->parent_name,
|
||||||
regmap,
|
regmap,
|
||||||
gate->regs->set_ofs,
|
gate->regs->set_ofs,
|
||||||
gate->regs->clr_ofs,
|
gate->regs->clr_ofs,
|
||||||
@ -238,12 +237,13 @@ int mtk_clk_register_gates_with_dev(struct device_node *node,
|
|||||||
gate->shift, gate->ops,
|
gate->shift, gate->ops,
|
||||||
gate->flags, dev);
|
gate->flags, dev);
|
||||||
|
|
||||||
if (IS_ERR(clk)) {
|
if (IS_ERR(hw)) {
|
||||||
pr_err("Failed to register clk %s: %pe\n", gate->name, clk);
|
pr_err("Failed to register clk %s: %pe\n", gate->name,
|
||||||
|
hw);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
clk_data->clks[gate->id] = clk;
|
clk_data->hws[gate->id] = hw;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -252,26 +252,26 @@ err:
|
|||||||
while (--i >= 0) {
|
while (--i >= 0) {
|
||||||
const struct mtk_gate *gate = &clks[i];
|
const struct mtk_gate *gate = &clks[i];
|
||||||
|
|
||||||
if (IS_ERR_OR_NULL(clk_data->clks[gate->id]))
|
if (IS_ERR_OR_NULL(clk_data->hws[gate->id]))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
mtk_clk_unregister_gate(clk_data->clks[gate->id]);
|
mtk_clk_unregister_gate(clk_data->hws[gate->id]);
|
||||||
clk_data->clks[gate->id] = ERR_PTR(-ENOENT);
|
clk_data->hws[gate->id] = ERR_PTR(-ENOENT);
|
||||||
}
|
}
|
||||||
|
|
||||||
return PTR_ERR(clk);
|
return PTR_ERR(hw);
|
||||||
}
|
}
|
||||||
|
|
||||||
int mtk_clk_register_gates(struct device_node *node,
|
int mtk_clk_register_gates(struct device_node *node,
|
||||||
const struct mtk_gate *clks, int num,
|
const struct mtk_gate *clks, int num,
|
||||||
struct clk_onecell_data *clk_data)
|
struct clk_hw_onecell_data *clk_data)
|
||||||
{
|
{
|
||||||
return mtk_clk_register_gates_with_dev(node, clks, num, clk_data, NULL);
|
return mtk_clk_register_gates_with_dev(node, clks, num, clk_data, NULL);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(mtk_clk_register_gates);
|
EXPORT_SYMBOL_GPL(mtk_clk_register_gates);
|
||||||
|
|
||||||
void mtk_clk_unregister_gates(const struct mtk_gate *clks, int num,
|
void mtk_clk_unregister_gates(const struct mtk_gate *clks, int num,
|
||||||
struct clk_onecell_data *clk_data)
|
struct clk_hw_onecell_data *clk_data)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@ -281,11 +281,11 @@ void mtk_clk_unregister_gates(const struct mtk_gate *clks, int num,
|
|||||||
for (i = num; i > 0; i--) {
|
for (i = num; i > 0; i--) {
|
||||||
const struct mtk_gate *gate = &clks[i - 1];
|
const struct mtk_gate *gate = &clks[i - 1];
|
||||||
|
|
||||||
if (IS_ERR_OR_NULL(clk_data->clks[gate->id]))
|
if (IS_ERR_OR_NULL(clk_data->hws[gate->id]))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
mtk_clk_unregister_gate(clk_data->clks[gate->id]);
|
mtk_clk_unregister_gate(clk_data->hws[gate->id]);
|
||||||
clk_data->clks[gate->id] = ERR_PTR(-ENOENT);
|
clk_data->hws[gate->id] = ERR_PTR(-ENOENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(mtk_clk_unregister_gates);
|
EXPORT_SYMBOL_GPL(mtk_clk_unregister_gates);
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
struct clk;
|
struct clk;
|
||||||
struct clk_onecell_data;
|
struct clk_hw_onecell_data;
|
||||||
struct clk_ops;
|
struct clk_ops;
|
||||||
struct device;
|
struct device;
|
||||||
struct device_node;
|
struct device_node;
|
||||||
@ -52,14 +52,14 @@ struct mtk_gate {
|
|||||||
|
|
||||||
int mtk_clk_register_gates(struct device_node *node,
|
int mtk_clk_register_gates(struct device_node *node,
|
||||||
const struct mtk_gate *clks, int num,
|
const struct mtk_gate *clks, int num,
|
||||||
struct clk_onecell_data *clk_data);
|
struct clk_hw_onecell_data *clk_data);
|
||||||
|
|
||||||
int mtk_clk_register_gates_with_dev(struct device_node *node,
|
int mtk_clk_register_gates_with_dev(struct device_node *node,
|
||||||
const struct mtk_gate *clks, int num,
|
const struct mtk_gate *clks, int num,
|
||||||
struct clk_onecell_data *clk_data,
|
struct clk_hw_onecell_data *clk_data,
|
||||||
struct device *dev);
|
struct device *dev);
|
||||||
|
|
||||||
void mtk_clk_unregister_gates(const struct mtk_gate *clks, int num,
|
void mtk_clk_unregister_gates(const struct mtk_gate *clks, int num,
|
||||||
struct clk_onecell_data *clk_data);
|
struct clk_hw_onecell_data *clk_data);
|
||||||
|
|
||||||
#endif /* __DRV_CLK_GATE_H */
|
#endif /* __DRV_CLK_GATE_H */
|
||||||
|
@ -145,7 +145,7 @@ static const struct of_device_id of_match_clk_mt2701_aud[] = {
|
|||||||
|
|
||||||
static int clk_mt2701_aud_probe(struct platform_device *pdev)
|
static int clk_mt2701_aud_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct clk_onecell_data *clk_data;
|
struct clk_hw_onecell_data *clk_data;
|
||||||
struct device_node *node = pdev->dev.of_node;
|
struct device_node *node = pdev->dev.of_node;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
@ -154,7 +154,7 @@ static int clk_mt2701_aud_probe(struct platform_device *pdev)
|
|||||||
mtk_clk_register_gates(node, audio_clks, ARRAY_SIZE(audio_clks),
|
mtk_clk_register_gates(node, audio_clks, ARRAY_SIZE(audio_clks),
|
||||||
clk_data);
|
clk_data);
|
||||||
|
|
||||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
|
||||||
if (r) {
|
if (r) {
|
||||||
dev_err(&pdev->dev,
|
dev_err(&pdev->dev,
|
||||||
"could not register clock provider: %s: %d\n",
|
"could not register clock provider: %s: %d\n",
|
||||||
|
@ -101,7 +101,7 @@ static const struct of_device_id of_match_clk_mt2701_bdp[] = {
|
|||||||
|
|
||||||
static int clk_mt2701_bdp_probe(struct platform_device *pdev)
|
static int clk_mt2701_bdp_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct clk_onecell_data *clk_data;
|
struct clk_hw_onecell_data *clk_data;
|
||||||
int r;
|
int r;
|
||||||
struct device_node *node = pdev->dev.of_node;
|
struct device_node *node = pdev->dev.of_node;
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ static int clk_mt2701_bdp_probe(struct platform_device *pdev)
|
|||||||
mtk_clk_register_gates(node, bdp_clks, ARRAY_SIZE(bdp_clks),
|
mtk_clk_register_gates(node, bdp_clks, ARRAY_SIZE(bdp_clks),
|
||||||
clk_data);
|
clk_data);
|
||||||
|
|
||||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
|
||||||
if (r)
|
if (r)
|
||||||
dev_err(&pdev->dev,
|
dev_err(&pdev->dev,
|
||||||
"could not register clock provider: %s: %d\n",
|
"could not register clock provider: %s: %d\n",
|
||||||
|
@ -43,7 +43,7 @@ static const struct of_device_id of_match_clk_mt2701_eth[] = {
|
|||||||
|
|
||||||
static int clk_mt2701_eth_probe(struct platform_device *pdev)
|
static int clk_mt2701_eth_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct clk_onecell_data *clk_data;
|
struct clk_hw_onecell_data *clk_data;
|
||||||
int r;
|
int r;
|
||||||
struct device_node *node = pdev->dev.of_node;
|
struct device_node *node = pdev->dev.of_node;
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ static int clk_mt2701_eth_probe(struct platform_device *pdev)
|
|||||||
mtk_clk_register_gates(node, eth_clks, ARRAY_SIZE(eth_clks),
|
mtk_clk_register_gates(node, eth_clks, ARRAY_SIZE(eth_clks),
|
||||||
clk_data);
|
clk_data);
|
||||||
|
|
||||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
|
||||||
if (r)
|
if (r)
|
||||||
dev_err(&pdev->dev,
|
dev_err(&pdev->dev,
|
||||||
"could not register clock provider: %s: %d\n",
|
"could not register clock provider: %s: %d\n",
|
||||||
|
@ -37,7 +37,7 @@ static const struct mtk_gate g3d_clks[] = {
|
|||||||
|
|
||||||
static int clk_mt2701_g3dsys_init(struct platform_device *pdev)
|
static int clk_mt2701_g3dsys_init(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct clk_onecell_data *clk_data;
|
struct clk_hw_onecell_data *clk_data;
|
||||||
struct device_node *node = pdev->dev.of_node;
|
struct device_node *node = pdev->dev.of_node;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
@ -46,7 +46,7 @@ static int clk_mt2701_g3dsys_init(struct platform_device *pdev)
|
|||||||
mtk_clk_register_gates(node, g3d_clks, ARRAY_SIZE(g3d_clks),
|
mtk_clk_register_gates(node, g3d_clks, ARRAY_SIZE(g3d_clks),
|
||||||
clk_data);
|
clk_data);
|
||||||
|
|
||||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
|
||||||
if (r)
|
if (r)
|
||||||
dev_err(&pdev->dev,
|
dev_err(&pdev->dev,
|
||||||
"could not register clock provider: %s: %d\n",
|
"could not register clock provider: %s: %d\n",
|
||||||
|
@ -40,7 +40,7 @@ static const struct of_device_id of_match_clk_mt2701_hif[] = {
|
|||||||
|
|
||||||
static int clk_mt2701_hif_probe(struct platform_device *pdev)
|
static int clk_mt2701_hif_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct clk_onecell_data *clk_data;
|
struct clk_hw_onecell_data *clk_data;
|
||||||
int r;
|
int r;
|
||||||
struct device_node *node = pdev->dev.of_node;
|
struct device_node *node = pdev->dev.of_node;
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ static int clk_mt2701_hif_probe(struct platform_device *pdev)
|
|||||||
mtk_clk_register_gates(node, hif_clks, ARRAY_SIZE(hif_clks),
|
mtk_clk_register_gates(node, hif_clks, ARRAY_SIZE(hif_clks),
|
||||||
clk_data);
|
clk_data);
|
||||||
|
|
||||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
|
||||||
if (r) {
|
if (r) {
|
||||||
dev_err(&pdev->dev,
|
dev_err(&pdev->dev,
|
||||||
"could not register clock provider: %s: %d\n",
|
"could not register clock provider: %s: %d\n",
|
||||||
|
@ -43,7 +43,7 @@ static const struct of_device_id of_match_clk_mt2701_img[] = {
|
|||||||
|
|
||||||
static int clk_mt2701_img_probe(struct platform_device *pdev)
|
static int clk_mt2701_img_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct clk_onecell_data *clk_data;
|
struct clk_hw_onecell_data *clk_data;
|
||||||
int r;
|
int r;
|
||||||
struct device_node *node = pdev->dev.of_node;
|
struct device_node *node = pdev->dev.of_node;
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ static int clk_mt2701_img_probe(struct platform_device *pdev)
|
|||||||
mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks),
|
mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks),
|
||||||
clk_data);
|
clk_data);
|
||||||
|
|
||||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
|
||||||
if (r)
|
if (r)
|
||||||
dev_err(&pdev->dev,
|
dev_err(&pdev->dev,
|
||||||
"could not register clock provider: %s: %d\n",
|
"could not register clock provider: %s: %d\n",
|
||||||
|
@ -83,7 +83,7 @@ static int clk_mt2701_mm_probe(struct platform_device *pdev)
|
|||||||
{
|
{
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct device_node *node = dev->parent->of_node;
|
struct device_node *node = dev->parent->of_node;
|
||||||
struct clk_onecell_data *clk_data;
|
struct clk_hw_onecell_data *clk_data;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
clk_data = mtk_alloc_clk_data(CLK_MM_NR);
|
clk_data = mtk_alloc_clk_data(CLK_MM_NR);
|
||||||
@ -91,7 +91,7 @@ static int clk_mt2701_mm_probe(struct platform_device *pdev)
|
|||||||
mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks),
|
mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks),
|
||||||
clk_data);
|
clk_data);
|
||||||
|
|
||||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
|
||||||
if (r)
|
if (r)
|
||||||
dev_err(&pdev->dev,
|
dev_err(&pdev->dev,
|
||||||
"could not register clock provider: %s: %d\n",
|
"could not register clock provider: %s: %d\n",
|
||||||
|
@ -54,7 +54,7 @@ static const struct of_device_id of_match_clk_mt2701_vdec[] = {
|
|||||||
|
|
||||||
static int clk_mt2701_vdec_probe(struct platform_device *pdev)
|
static int clk_mt2701_vdec_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct clk_onecell_data *clk_data;
|
struct clk_hw_onecell_data *clk_data;
|
||||||
int r;
|
int r;
|
||||||
struct device_node *node = pdev->dev.of_node;
|
struct device_node *node = pdev->dev.of_node;
|
||||||
|
|
||||||
@ -63,7 +63,7 @@ static int clk_mt2701_vdec_probe(struct platform_device *pdev)
|
|||||||
mtk_clk_register_gates(node, vdec_clks, ARRAY_SIZE(vdec_clks),
|
mtk_clk_register_gates(node, vdec_clks, ARRAY_SIZE(vdec_clks),
|
||||||
clk_data);
|
clk_data);
|
||||||
|
|
||||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
|
||||||
if (r)
|
if (r)
|
||||||
dev_err(&pdev->dev,
|
dev_err(&pdev->dev,
|
||||||
"could not register clock provider: %s: %d\n",
|
"could not register clock provider: %s: %d\n",
|
||||||
|
@ -666,7 +666,7 @@ static const struct mtk_gate top_clks[] = {
|
|||||||
|
|
||||||
static int mtk_topckgen_init(struct platform_device *pdev)
|
static int mtk_topckgen_init(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct clk_onecell_data *clk_data;
|
struct clk_hw_onecell_data *clk_data;
|
||||||
void __iomem *base;
|
void __iomem *base;
|
||||||
struct device_node *node = pdev->dev.of_node;
|
struct device_node *node = pdev->dev.of_node;
|
||||||
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
@ -692,7 +692,7 @@ static int mtk_topckgen_init(struct platform_device *pdev)
|
|||||||
mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks),
|
mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks),
|
||||||
clk_data);
|
clk_data);
|
||||||
|
|
||||||
return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct mtk_gate_regs infra_cg_regs = {
|
static const struct mtk_gate_regs infra_cg_regs = {
|
||||||
@ -735,7 +735,7 @@ static const struct mtk_fixed_factor infra_fixed_divs[] = {
|
|||||||
FACTOR(CLK_INFRA_CLK_13M, "clk13m", "clk26m", 1, 2),
|
FACTOR(CLK_INFRA_CLK_13M, "clk13m", "clk26m", 1, 2),
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct clk_onecell_data *infra_clk_data;
|
static struct clk_hw_onecell_data *infra_clk_data;
|
||||||
|
|
||||||
static void __init mtk_infrasys_init_early(struct device_node *node)
|
static void __init mtk_infrasys_init_early(struct device_node *node)
|
||||||
{
|
{
|
||||||
@ -745,7 +745,7 @@ static void __init mtk_infrasys_init_early(struct device_node *node)
|
|||||||
infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR);
|
infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR);
|
||||||
|
|
||||||
for (i = 0; i < CLK_INFRA_NR; i++)
|
for (i = 0; i < CLK_INFRA_NR; i++)
|
||||||
infra_clk_data->clks[i] = ERR_PTR(-EPROBE_DEFER);
|
infra_clk_data->hws[i] = ERR_PTR(-EPROBE_DEFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs),
|
mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs),
|
||||||
@ -754,7 +754,8 @@ static void __init mtk_infrasys_init_early(struct device_node *node)
|
|||||||
mtk_clk_register_cpumuxes(node, cpu_muxes, ARRAY_SIZE(cpu_muxes),
|
mtk_clk_register_cpumuxes(node, cpu_muxes, ARRAY_SIZE(cpu_muxes),
|
||||||
infra_clk_data);
|
infra_clk_data);
|
||||||
|
|
||||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, infra_clk_data);
|
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get,
|
||||||
|
infra_clk_data);
|
||||||
if (r)
|
if (r)
|
||||||
pr_err("%s(): could not register clock provider: %d\n",
|
pr_err("%s(): could not register clock provider: %d\n",
|
||||||
__func__, r);
|
__func__, r);
|
||||||
@ -771,8 +772,8 @@ static int mtk_infrasys_init(struct platform_device *pdev)
|
|||||||
infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR);
|
infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR);
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < CLK_INFRA_NR; i++) {
|
for (i = 0; i < CLK_INFRA_NR; i++) {
|
||||||
if (infra_clk_data->clks[i] == ERR_PTR(-EPROBE_DEFER))
|
if (infra_clk_data->hws[i] == ERR_PTR(-EPROBE_DEFER))
|
||||||
infra_clk_data->clks[i] = ERR_PTR(-ENOENT);
|
infra_clk_data->hws[i] = ERR_PTR(-ENOENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -781,7 +782,8 @@ static int mtk_infrasys_init(struct platform_device *pdev)
|
|||||||
mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs),
|
mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs),
|
||||||
infra_clk_data);
|
infra_clk_data);
|
||||||
|
|
||||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, infra_clk_data);
|
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get,
|
||||||
|
infra_clk_data);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -886,7 +888,7 @@ static const struct mtk_composite peri_muxs[] = {
|
|||||||
|
|
||||||
static int mtk_pericfg_init(struct platform_device *pdev)
|
static int mtk_pericfg_init(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct clk_onecell_data *clk_data;
|
struct clk_hw_onecell_data *clk_data;
|
||||||
void __iomem *base;
|
void __iomem *base;
|
||||||
int r;
|
int r;
|
||||||
struct device_node *node = pdev->dev.of_node;
|
struct device_node *node = pdev->dev.of_node;
|
||||||
@ -904,7 +906,7 @@ static int mtk_pericfg_init(struct platform_device *pdev)
|
|||||||
mtk_clk_register_composites(peri_muxs, ARRAY_SIZE(peri_muxs), base,
|
mtk_clk_register_composites(peri_muxs, ARRAY_SIZE(peri_muxs), base,
|
||||||
&mt2701_clk_lock, clk_data);
|
&mt2701_clk_lock, clk_data);
|
||||||
|
|
||||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
|
||||||
if (r)
|
if (r)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -935,13 +937,13 @@ static int mtk_pericfg_init(struct platform_device *pdev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const struct mtk_pll_data apmixed_plls[] = {
|
static const struct mtk_pll_data apmixed_plls[] = {
|
||||||
PLL(CLK_APMIXED_ARMPLL, "armpll", 0x200, 0x20c, 0x80000001,
|
PLL(CLK_APMIXED_ARMPLL, "armpll", 0x200, 0x20c, 0x80000000,
|
||||||
PLL_AO, 21, 0x204, 24, 0x0, 0x204, 0),
|
PLL_AO, 21, 0x204, 24, 0x0, 0x204, 0),
|
||||||
PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x210, 0x21c, 0xf0000001,
|
PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x210, 0x21c, 0xf0000000,
|
||||||
HAVE_RST_BAR, 21, 0x210, 4, 0x0, 0x214, 0),
|
HAVE_RST_BAR, 21, 0x210, 4, 0x0, 0x214, 0),
|
||||||
PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x220, 0x22c, 0xf3000001,
|
PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x220, 0x22c, 0xf3000000,
|
||||||
HAVE_RST_BAR, 7, 0x220, 4, 0x0, 0x224, 14),
|
HAVE_RST_BAR, 7, 0x220, 4, 0x0, 0x224, 14),
|
||||||
PLL(CLK_APMIXED_MMPLL, "mmpll", 0x230, 0x23c, 0x00000001, 0,
|
PLL(CLK_APMIXED_MMPLL, "mmpll", 0x230, 0x23c, 0, 0,
|
||||||
21, 0x230, 4, 0x0, 0x234, 0),
|
21, 0x230, 4, 0x0, 0x234, 0),
|
||||||
PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x240, 0x24c, 0x00000001, 0,
|
PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x240, 0x24c, 0x00000001, 0,
|
||||||
21, 0x240, 4, 0x0, 0x244, 0),
|
21, 0x240, 4, 0x0, 0x244, 0),
|
||||||
@ -969,7 +971,7 @@ static const struct mtk_fixed_factor apmixed_fixed_divs[] = {
|
|||||||
|
|
||||||
static int mtk_apmixedsys_init(struct platform_device *pdev)
|
static int mtk_apmixedsys_init(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct clk_onecell_data *clk_data;
|
struct clk_hw_onecell_data *clk_data;
|
||||||
struct device_node *node = pdev->dev.of_node;
|
struct device_node *node = pdev->dev.of_node;
|
||||||
|
|
||||||
clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR);
|
clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR);
|
||||||
@ -981,7 +983,7 @@ static int mtk_apmixedsys_init(struct platform_device *pdev)
|
|||||||
mtk_clk_register_factors(apmixed_fixed_divs, ARRAY_SIZE(apmixed_fixed_divs),
|
mtk_clk_register_factors(apmixed_fixed_divs, ARRAY_SIZE(apmixed_fixed_divs),
|
||||||
clk_data);
|
clk_data);
|
||||||
|
|
||||||
return of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct of_device_id of_match_clk_mt2701[] = {
|
static const struct of_device_id of_match_clk_mt2701[] = {
|
||||||
|
@ -60,7 +60,7 @@ static const struct mtk_gate bdp_clks[] = {
|
|||||||
|
|
||||||
static int clk_mt2712_bdp_probe(struct platform_device *pdev)
|
static int clk_mt2712_bdp_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct clk_onecell_data *clk_data;
|
struct clk_hw_onecell_data *clk_data;
|
||||||
int r;
|
int r;
|
||||||
struct device_node *node = pdev->dev.of_node;
|
struct device_node *node = pdev->dev.of_node;
|
||||||
|
|
||||||
@ -69,7 +69,7 @@ static int clk_mt2712_bdp_probe(struct platform_device *pdev)
|
|||||||
mtk_clk_register_gates(node, bdp_clks, ARRAY_SIZE(bdp_clks),
|
mtk_clk_register_gates(node, bdp_clks, ARRAY_SIZE(bdp_clks),
|
||||||
clk_data);
|
clk_data);
|
||||||
|
|
||||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
|
||||||
|
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
pr_err("%s(): could not register clock provider: %d\n",
|
pr_err("%s(): could not register clock provider: %d\n",
|
||||||
|
@ -38,7 +38,7 @@ static const struct mtk_gate img_clks[] = {
|
|||||||
|
|
||||||
static int clk_mt2712_img_probe(struct platform_device *pdev)
|
static int clk_mt2712_img_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct clk_onecell_data *clk_data;
|
struct clk_hw_onecell_data *clk_data;
|
||||||
int r;
|
int r;
|
||||||
struct device_node *node = pdev->dev.of_node;
|
struct device_node *node = pdev->dev.of_node;
|
||||||
|
|
||||||
@ -47,7 +47,7 @@ static int clk_mt2712_img_probe(struct platform_device *pdev)
|
|||||||
mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks),
|
mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks),
|
||||||
clk_data);
|
clk_data);
|
||||||
|
|
||||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
|
||||||
|
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
pr_err("%s(): could not register clock provider: %d\n",
|
pr_err("%s(): could not register clock provider: %d\n",
|
||||||
|
@ -34,7 +34,7 @@ static const struct mtk_gate jpgdec_clks[] = {
|
|||||||
|
|
||||||
static int clk_mt2712_jpgdec_probe(struct platform_device *pdev)
|
static int clk_mt2712_jpgdec_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct clk_onecell_data *clk_data;
|
struct clk_hw_onecell_data *clk_data;
|
||||||
int r;
|
int r;
|
||||||
struct device_node *node = pdev->dev.of_node;
|
struct device_node *node = pdev->dev.of_node;
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ static int clk_mt2712_jpgdec_probe(struct platform_device *pdev)
|
|||||||
mtk_clk_register_gates(node, jpgdec_clks, ARRAY_SIZE(jpgdec_clks),
|
mtk_clk_register_gates(node, jpgdec_clks, ARRAY_SIZE(jpgdec_clks),
|
||||||
clk_data);
|
clk_data);
|
||||||
|
|
||||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
|
||||||
|
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
pr_err("%s(): could not register clock provider: %d\n",
|
pr_err("%s(): could not register clock provider: %d\n",
|
||||||
|
@ -33,7 +33,7 @@ static const struct mtk_gate mfg_clks[] = {
|
|||||||
|
|
||||||
static int clk_mt2712_mfg_probe(struct platform_device *pdev)
|
static int clk_mt2712_mfg_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct clk_onecell_data *clk_data;
|
struct clk_hw_onecell_data *clk_data;
|
||||||
int r;
|
int r;
|
||||||
struct device_node *node = pdev->dev.of_node;
|
struct device_node *node = pdev->dev.of_node;
|
||||||
|
|
||||||
@ -42,7 +42,7 @@ static int clk_mt2712_mfg_probe(struct platform_device *pdev)
|
|||||||
mtk_clk_register_gates(node, mfg_clks, ARRAY_SIZE(mfg_clks),
|
mtk_clk_register_gates(node, mfg_clks, ARRAY_SIZE(mfg_clks),
|
||||||
clk_data);
|
clk_data);
|
||||||
|
|
||||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
|
||||||
|
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
pr_err("%s(): could not register clock provider: %d\n",
|
pr_err("%s(): could not register clock provider: %d\n",
|
||||||
|
@ -130,7 +130,7 @@ static int clk_mt2712_mm_probe(struct platform_device *pdev)
|
|||||||
{
|
{
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct device_node *node = dev->parent->of_node;
|
struct device_node *node = dev->parent->of_node;
|
||||||
struct clk_onecell_data *clk_data;
|
struct clk_hw_onecell_data *clk_data;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
clk_data = mtk_alloc_clk_data(CLK_MM_NR_CLK);
|
clk_data = mtk_alloc_clk_data(CLK_MM_NR_CLK);
|
||||||
@ -138,7 +138,7 @@ static int clk_mt2712_mm_probe(struct platform_device *pdev)
|
|||||||
mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks),
|
mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks),
|
||||||
clk_data);
|
clk_data);
|
||||||
|
|
||||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
|
||||||
|
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
pr_err("%s(): could not register clock provider: %d\n",
|
pr_err("%s(): could not register clock provider: %d\n",
|
||||||
|
@ -52,7 +52,7 @@ static const struct mtk_gate vdec_clks[] = {
|
|||||||
|
|
||||||
static int clk_mt2712_vdec_probe(struct platform_device *pdev)
|
static int clk_mt2712_vdec_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct clk_onecell_data *clk_data;
|
struct clk_hw_onecell_data *clk_data;
|
||||||
int r;
|
int r;
|
||||||
struct device_node *node = pdev->dev.of_node;
|
struct device_node *node = pdev->dev.of_node;
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ static int clk_mt2712_vdec_probe(struct platform_device *pdev)
|
|||||||
mtk_clk_register_gates(node, vdec_clks, ARRAY_SIZE(vdec_clks),
|
mtk_clk_register_gates(node, vdec_clks, ARRAY_SIZE(vdec_clks),
|
||||||
clk_data);
|
clk_data);
|
||||||
|
|
||||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
|
||||||
|
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
pr_err("%s(): could not register clock provider: %d\n",
|
pr_err("%s(): could not register clock provider: %d\n",
|
||||||
|
@ -35,7 +35,7 @@ static const struct mtk_gate venc_clks[] = {
|
|||||||
|
|
||||||
static int clk_mt2712_venc_probe(struct platform_device *pdev)
|
static int clk_mt2712_venc_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct clk_onecell_data *clk_data;
|
struct clk_hw_onecell_data *clk_data;
|
||||||
int r;
|
int r;
|
||||||
struct device_node *node = pdev->dev.of_node;
|
struct device_node *node = pdev->dev.of_node;
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ static int clk_mt2712_venc_probe(struct platform_device *pdev)
|
|||||||
mtk_clk_register_gates(node, venc_clks, ARRAY_SIZE(venc_clks),
|
mtk_clk_register_gates(node, venc_clks, ARRAY_SIZE(venc_clks),
|
||||||
clk_data);
|
clk_data);
|
||||||
|
|
||||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
|
||||||
|
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
pr_err("%s(): could not register clock provider: %d\n",
|
pr_err("%s(): could not register clock provider: %d\n",
|
||||||
|
@ -1223,44 +1223,44 @@ static const struct mtk_pll_div_table mmpll_div_table[] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static const struct mtk_pll_data plls[] = {
|
static const struct mtk_pll_data plls[] = {
|
||||||
PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x0230, 0x023C, 0xf0000101,
|
PLL(CLK_APMIXED_MAINPLL, "mainpll", 0x0230, 0x023C, 0xf0000100,
|
||||||
HAVE_RST_BAR, 31, 0x0230, 4, 0, 0, 0, 0x0234, 0),
|
HAVE_RST_BAR, 31, 0x0230, 4, 0, 0, 0, 0x0234, 0),
|
||||||
PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x0240, 0x024C, 0xfe000101,
|
PLL(CLK_APMIXED_UNIVPLL, "univpll", 0x0240, 0x024C, 0xfe000100,
|
||||||
HAVE_RST_BAR, 31, 0x0240, 4, 0, 0, 0, 0x0244, 0),
|
HAVE_RST_BAR, 31, 0x0240, 4, 0, 0, 0, 0x0244, 0),
|
||||||
PLL(CLK_APMIXED_VCODECPLL, "vcodecpll", 0x0320, 0x032C, 0xc0000101,
|
PLL(CLK_APMIXED_VCODECPLL, "vcodecpll", 0x0320, 0x032C, 0xc0000100,
|
||||||
0, 31, 0x0320, 4, 0, 0, 0, 0x0324, 0),
|
0, 31, 0x0320, 4, 0, 0, 0, 0x0324, 0),
|
||||||
PLL(CLK_APMIXED_VENCPLL, "vencpll", 0x0280, 0x028C, 0x00000101,
|
PLL(CLK_APMIXED_VENCPLL, "vencpll", 0x0280, 0x028C, 0x00000100,
|
||||||
0, 31, 0x0280, 4, 0, 0, 0, 0x0284, 0),
|
0, 31, 0x0280, 4, 0, 0, 0, 0x0284, 0),
|
||||||
PLL(CLK_APMIXED_APLL1, "apll1", 0x0330, 0x0340, 0x00000101,
|
PLL(CLK_APMIXED_APLL1, "apll1", 0x0330, 0x0340, 0x00000100,
|
||||||
0, 31, 0x0330, 4, 0x0338, 0x0014, 0, 0x0334, 0),
|
0, 31, 0x0330, 4, 0x0338, 0x0014, 0, 0x0334, 0),
|
||||||
PLL(CLK_APMIXED_APLL2, "apll2", 0x0350, 0x0360, 0x00000101,
|
PLL(CLK_APMIXED_APLL2, "apll2", 0x0350, 0x0360, 0x00000100,
|
||||||
0, 31, 0x0350, 4, 0x0358, 0x0014, 1, 0x0354, 0),
|
0, 31, 0x0350, 4, 0x0358, 0x0014, 1, 0x0354, 0),
|
||||||
PLL(CLK_APMIXED_LVDSPLL, "lvdspll", 0x0370, 0x037c, 0x00000101,
|
PLL(CLK_APMIXED_LVDSPLL, "lvdspll", 0x0370, 0x037c, 0x00000100,
|
||||||
0, 31, 0x0370, 4, 0, 0, 0, 0x0374, 0),
|
0, 31, 0x0370, 4, 0, 0, 0, 0x0374, 0),
|
||||||
PLL(CLK_APMIXED_LVDSPLL2, "lvdspll2", 0x0390, 0x039C, 0x00000101,
|
PLL(CLK_APMIXED_LVDSPLL2, "lvdspll2", 0x0390, 0x039C, 0x00000100,
|
||||||
0, 31, 0x0390, 4, 0, 0, 0, 0x0394, 0),
|
0, 31, 0x0390, 4, 0, 0, 0, 0x0394, 0),
|
||||||
PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x0270, 0x027C, 0x00000101,
|
PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x0270, 0x027C, 0x00000100,
|
||||||
0, 31, 0x0270, 4, 0, 0, 0, 0x0274, 0),
|
0, 31, 0x0270, 4, 0, 0, 0, 0x0274, 0),
|
||||||
PLL(CLK_APMIXED_MSDCPLL2, "msdcpll2", 0x0410, 0x041C, 0x00000101,
|
PLL(CLK_APMIXED_MSDCPLL2, "msdcpll2", 0x0410, 0x041C, 0x00000100,
|
||||||
0, 31, 0x0410, 4, 0, 0, 0, 0x0414, 0),
|
0, 31, 0x0410, 4, 0, 0, 0, 0x0414, 0),
|
||||||
PLL(CLK_APMIXED_TVDPLL, "tvdpll", 0x0290, 0x029C, 0xc0000101,
|
PLL(CLK_APMIXED_TVDPLL, "tvdpll", 0x0290, 0x029C, 0xc0000100,
|
||||||
0, 31, 0x0290, 4, 0, 0, 0, 0x0294, 0),
|
0, 31, 0x0290, 4, 0, 0, 0, 0x0294, 0),
|
||||||
PLL_B(CLK_APMIXED_MMPLL, "mmpll", 0x0250, 0x0260, 0x00000101,
|
PLL_B(CLK_APMIXED_MMPLL, "mmpll", 0x0250, 0x0260, 0x00000100,
|
||||||
0, 31, 0x0250, 4, 0, 0, 0, 0x0254, 0,
|
0, 31, 0x0250, 4, 0, 0, 0, 0x0254, 0,
|
||||||
mmpll_div_table),
|
mmpll_div_table),
|
||||||
PLL_B(CLK_APMIXED_ARMCA35PLL, "armca35pll", 0x0100, 0x0110, 0xf0000101,
|
PLL_B(CLK_APMIXED_ARMCA35PLL, "armca35pll", 0x0100, 0x0110, 0xf0000100,
|
||||||
HAVE_RST_BAR, 31, 0x0100, 4, 0, 0, 0, 0x0104, 0,
|
HAVE_RST_BAR, 31, 0x0100, 4, 0, 0, 0, 0x0104, 0,
|
||||||
armca35pll_div_table),
|
armca35pll_div_table),
|
||||||
PLL_B(CLK_APMIXED_ARMCA72PLL, "armca72pll", 0x0210, 0x0220, 0x00000101,
|
PLL_B(CLK_APMIXED_ARMCA72PLL, "armca72pll", 0x0210, 0x0220, 0x00000100,
|
||||||
0, 31, 0x0210, 4, 0, 0, 0, 0x0214, 0,
|
0, 31, 0x0210, 4, 0, 0, 0, 0x0214, 0,
|
||||||
armca72pll_div_table),
|
armca72pll_div_table),
|
||||||
PLL(CLK_APMIXED_ETHERPLL, "etherpll", 0x0300, 0x030C, 0xc0000101,
|
PLL(CLK_APMIXED_ETHERPLL, "etherpll", 0x0300, 0x030C, 0xc0000100,
|
||||||
0, 31, 0x0300, 4, 0, 0, 0, 0x0304, 0),
|
0, 31, 0x0300, 4, 0, 0, 0, 0x0304, 0),
|
||||||
};
|
};
|
||||||
|
|
||||||
static int clk_mt2712_apmixed_probe(struct platform_device *pdev)
|
static int clk_mt2712_apmixed_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct clk_onecell_data *clk_data;
|
struct clk_hw_onecell_data *clk_data;
|
||||||
int r;
|
int r;
|
||||||
struct device_node *node = pdev->dev.of_node;
|
struct device_node *node = pdev->dev.of_node;
|
||||||
|
|
||||||
@ -1268,7 +1268,7 @@ static int clk_mt2712_apmixed_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
|
mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
|
||||||
|
|
||||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
|
||||||
|
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
pr_err("%s(): could not register clock provider: %d\n",
|
pr_err("%s(): could not register clock provider: %d\n",
|
||||||
@ -1277,7 +1277,7 @@ static int clk_mt2712_apmixed_probe(struct platform_device *pdev)
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct clk_onecell_data *top_clk_data;
|
static struct clk_hw_onecell_data *top_clk_data;
|
||||||
|
|
||||||
static void clk_mt2712_top_init_early(struct device_node *node)
|
static void clk_mt2712_top_init_early(struct device_node *node)
|
||||||
{
|
{
|
||||||
@ -1287,13 +1287,13 @@ static void clk_mt2712_top_init_early(struct device_node *node)
|
|||||||
top_clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
|
top_clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
|
||||||
|
|
||||||
for (i = 0; i < CLK_TOP_NR_CLK; i++)
|
for (i = 0; i < CLK_TOP_NR_CLK; i++)
|
||||||
top_clk_data->clks[i] = ERR_PTR(-EPROBE_DEFER);
|
top_clk_data->hws[i] = ERR_PTR(-EPROBE_DEFER);
|
||||||
}
|
}
|
||||||
|
|
||||||
mtk_clk_register_factors(top_early_divs, ARRAY_SIZE(top_early_divs),
|
mtk_clk_register_factors(top_early_divs, ARRAY_SIZE(top_early_divs),
|
||||||
top_clk_data);
|
top_clk_data);
|
||||||
|
|
||||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, top_clk_data);
|
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, top_clk_data);
|
||||||
if (r)
|
if (r)
|
||||||
pr_err("%s(): could not register clock provider: %d\n",
|
pr_err("%s(): could not register clock provider: %d\n",
|
||||||
__func__, r);
|
__func__, r);
|
||||||
@ -1318,8 +1318,8 @@ static int clk_mt2712_top_probe(struct platform_device *pdev)
|
|||||||
top_clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
|
top_clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < CLK_TOP_NR_CLK; i++) {
|
for (i = 0; i < CLK_TOP_NR_CLK; i++) {
|
||||||
if (top_clk_data->clks[i] == ERR_PTR(-EPROBE_DEFER))
|
if (top_clk_data->hws[i] == ERR_PTR(-EPROBE_DEFER))
|
||||||
top_clk_data->clks[i] = ERR_PTR(-ENOENT);
|
top_clk_data->hws[i] = ERR_PTR(-ENOENT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1335,7 +1335,7 @@ static int clk_mt2712_top_probe(struct platform_device *pdev)
|
|||||||
mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks),
|
mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks),
|
||||||
top_clk_data);
|
top_clk_data);
|
||||||
|
|
||||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, top_clk_data);
|
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, top_clk_data);
|
||||||
|
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
pr_err("%s(): could not register clock provider: %d\n",
|
pr_err("%s(): could not register clock provider: %d\n",
|
||||||
@ -1346,7 +1346,7 @@ static int clk_mt2712_top_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
static int clk_mt2712_infra_probe(struct platform_device *pdev)
|
static int clk_mt2712_infra_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct clk_onecell_data *clk_data;
|
struct clk_hw_onecell_data *clk_data;
|
||||||
int r;
|
int r;
|
||||||
struct device_node *node = pdev->dev.of_node;
|
struct device_node *node = pdev->dev.of_node;
|
||||||
|
|
||||||
@ -1355,7 +1355,7 @@ static int clk_mt2712_infra_probe(struct platform_device *pdev)
|
|||||||
mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
|
mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
|
||||||
clk_data);
|
clk_data);
|
||||||
|
|
||||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
|
||||||
|
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
pr_err("%s(): could not register clock provider: %d\n",
|
pr_err("%s(): could not register clock provider: %d\n",
|
||||||
@ -1368,7 +1368,7 @@ static int clk_mt2712_infra_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
static int clk_mt2712_peri_probe(struct platform_device *pdev)
|
static int clk_mt2712_peri_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct clk_onecell_data *clk_data;
|
struct clk_hw_onecell_data *clk_data;
|
||||||
int r;
|
int r;
|
||||||
struct device_node *node = pdev->dev.of_node;
|
struct device_node *node = pdev->dev.of_node;
|
||||||
|
|
||||||
@ -1377,7 +1377,7 @@ static int clk_mt2712_peri_probe(struct platform_device *pdev)
|
|||||||
mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks),
|
mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks),
|
||||||
clk_data);
|
clk_data);
|
||||||
|
|
||||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
|
||||||
|
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
pr_err("%s(): could not register clock provider: %d\n",
|
pr_err("%s(): could not register clock provider: %d\n",
|
||||||
@ -1390,7 +1390,7 @@ static int clk_mt2712_peri_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
static int clk_mt2712_mcu_probe(struct platform_device *pdev)
|
static int clk_mt2712_mcu_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct clk_onecell_data *clk_data;
|
struct clk_hw_onecell_data *clk_data;
|
||||||
int r;
|
int r;
|
||||||
struct device_node *node = pdev->dev.of_node;
|
struct device_node *node = pdev->dev.of_node;
|
||||||
void __iomem *base;
|
void __iomem *base;
|
||||||
@ -1406,7 +1406,7 @@ static int clk_mt2712_mcu_probe(struct platform_device *pdev)
|
|||||||
mtk_clk_register_composites(mcu_muxes, ARRAY_SIZE(mcu_muxes), base,
|
mtk_clk_register_composites(mcu_muxes, ARRAY_SIZE(mcu_muxes), base,
|
||||||
&mt2712_clk_lock, clk_data);
|
&mt2712_clk_lock, clk_data);
|
||||||
|
|
||||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
|
||||||
|
|
||||||
if (r != 0)
|
if (r != 0)
|
||||||
pr_err("%s(): could not register clock provider: %d\n",
|
pr_err("%s(): could not register clock provider: %d\n",
|
||||||
|
@ -66,7 +66,7 @@ static const struct mtk_gate audio_clks[] = {
|
|||||||
|
|
||||||
static int clk_mt6765_audio_probe(struct platform_device *pdev)
|
static int clk_mt6765_audio_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct clk_onecell_data *clk_data;
|
struct clk_hw_onecell_data *clk_data;
|
||||||
int r;
|
int r;
|
||||||
struct device_node *node = pdev->dev.of_node;
|
struct device_node *node = pdev->dev.of_node;
|
||||||
|
|
||||||
@ -75,7 +75,7 @@ static int clk_mt6765_audio_probe(struct platform_device *pdev)
|
|||||||
mtk_clk_register_gates(node, audio_clks,
|
mtk_clk_register_gates(node, audio_clks,
|
||||||
ARRAY_SIZE(audio_clks), clk_data);
|
ARRAY_SIZE(audio_clks), clk_data);
|
||||||
|
|
||||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
|
||||||
|
|
||||||
if (r)
|
if (r)
|
||||||
pr_err("%s(): could not register clock provider: %d\n",
|
pr_err("%s(): could not register clock provider: %d\n",
|
||||||
|
@ -41,7 +41,7 @@ static const struct mtk_gate cam_clks[] = {
|
|||||||
|
|
||||||
static int clk_mt6765_cam_probe(struct platform_device *pdev)
|
static int clk_mt6765_cam_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct clk_onecell_data *clk_data;
|
struct clk_hw_onecell_data *clk_data;
|
||||||
int r;
|
int r;
|
||||||
struct device_node *node = pdev->dev.of_node;
|
struct device_node *node = pdev->dev.of_node;
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ static int clk_mt6765_cam_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
mtk_clk_register_gates(node, cam_clks, ARRAY_SIZE(cam_clks), clk_data);
|
mtk_clk_register_gates(node, cam_clks, ARRAY_SIZE(cam_clks), clk_data);
|
||||||
|
|
||||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
|
||||||
|
|
||||||
if (r)
|
if (r)
|
||||||
pr_err("%s(): could not register clock provider: %d\n",
|
pr_err("%s(): could not register clock provider: %d\n",
|
||||||
|
@ -37,7 +37,7 @@ static const struct mtk_gate img_clks[] = {
|
|||||||
|
|
||||||
static int clk_mt6765_img_probe(struct platform_device *pdev)
|
static int clk_mt6765_img_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct clk_onecell_data *clk_data;
|
struct clk_hw_onecell_data *clk_data;
|
||||||
int r;
|
int r;
|
||||||
struct device_node *node = pdev->dev.of_node;
|
struct device_node *node = pdev->dev.of_node;
|
||||||
|
|
||||||
@ -45,7 +45,7 @@ static int clk_mt6765_img_probe(struct platform_device *pdev)
|
|||||||
|
|
||||||
mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks), clk_data);
|
mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks), clk_data);
|
||||||
|
|
||||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
|
||||||
|
|
||||||
if (r)
|
if (r)
|
||||||
pr_err("%s(): could not register clock provider: %d\n",
|
pr_err("%s(): could not register clock provider: %d\n",
|
||||||
|
@ -34,7 +34,7 @@ static const struct mtk_gate mipi0a_clks[] = {
|
|||||||
|
|
||||||
static int clk_mt6765_mipi0a_probe(struct platform_device *pdev)
|
static int clk_mt6765_mipi0a_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct clk_onecell_data *clk_data;
|
struct clk_hw_onecell_data *clk_data;
|
||||||
int r;
|
int r;
|
||||||
struct device_node *node = pdev->dev.of_node;
|
struct device_node *node = pdev->dev.of_node;
|
||||||
|
|
||||||
@ -43,7 +43,7 @@ static int clk_mt6765_mipi0a_probe(struct platform_device *pdev)
|
|||||||
mtk_clk_register_gates(node, mipi0a_clks,
|
mtk_clk_register_gates(node, mipi0a_clks,
|
||||||
ARRAY_SIZE(mipi0a_clks), clk_data);
|
ARRAY_SIZE(mipi0a_clks), clk_data);
|
||||||
|
|
||||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
|
||||||
|
|
||||||
if (r)
|
if (r)
|
||||||
pr_err("%s(): could not register clock provider: %d\n",
|
pr_err("%s(): could not register clock provider: %d\n",
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user