This pull request is entirely SoC clk drivers, not for lack of trying to modify
the core clk framework. The majority diff wise is for the new Rockchip and Qualcomm clk drivers which is mostly lines and lines of data structures to describe the clk hardware in these SoCs. Beyond those two, Renesas continues to incrementally add clks to their SoC drivers, causing them to show up higher in the diffstat this time because they added quite a few clks all over the place. Overall it is a semi-quiet release that has some new clk drivers and the usual fixes for clock data that was wrong or missing and non-critical cleanups that plug error paths or fix typos. New Drivers: - Qualcomm IPQ5424 Network Subsystem Clock Controller - Qualcomm SM8750 Video Clock Controller - Rockchip RV1126B and RK3506 clock drivers - i.MX8ULP SIM LPAV clock driver - Samsung ACPM (firmware interface) clock driver - Altera Agilex5 clock driver -----BEGIN PGP SIGNATURE----- iQJIBAABCAAyFiEE9L57QeeUxqYDyoaDrQKIl8bklSUFAmk0uyEUHHN3Ym95ZEBj aHJvbWl1bS5vcmcACgkQrQKIl8bklSXYshAAxzjwN528JN34gU2dpWGtfiCfEG+5 55mymwf+NQwVHnvN2hLfPu8RtwYvLEwCPta5aFyra8syWC+mztI7cmB48mVNuTz1 bzdO2/mnt/Ev4HaDNz3SWIe2C1mArtB1P5gBMjHylFGoZYI9/KP5Spgrxx46Tjvz 4hYYjlPQe7YJFdI7Jv4wEiHb35f37POJXo6IEj2u4yALvd/+bAYB2/mi+9pR3NIG v73rANawaObwtkAXVJPDS89djMUIgMC6//NFaBAVB6B5+R9WNE7sFXcuqmjwFYgg sCJI6k98+/mJkSX2jkY8EjQirXg78oUmcS9yJ+haDn7x1xnZGJG+dRZ1T9c8k4Mv 9YN6plgC42+wHhU1Xe7/hQcX3FfMqfzWPCy0ywVAm+9t+WZuVYgQU4p6kZPVnovx ec/dXYix97TQgjyiaZv+s3/OccrGXzQ+phMmEXHQkOBrcTFH3JHkxGka8Q7YtCXT l3dIxpMPLzceNI8A8pufYKDEGsrpisSIKBTjc7gP20SbNc+e0ble8GTh32rprsmo v5+lL56HwH+Wc6ZAHWbuVPTgsqkVDZKC731JP/DT4ZO/n7laLk7Q+dq2f8n601Mf 6DKqh19NjJcf3wN+YWHZsVzIV6CR3qqdkNyI2gIS/Vqz55xEMZIBC2cDf16j0b2K NTI6yT9y5XxtvWU= =Ivih -----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: "This is entirely SoC clk drivers. The majority diff wise is for the new Rockchip and Qualcomm clk drivers which is mostly lines and lines of data structures to describe the clk hardware in these SoCs. Beyond those two, Renesas continues to incrementally add clks to their SoC drivers, causing them to show up higher in the diffstat this time because they added quite a few clks all over the place. Overall it is a semi-quiet release that has some new clk drivers and the usual fixes for clock data that was wrong or missing and non-critical cleanups that plug error paths or fix typos. New Drivers: - Qualcomm IPQ5424 Network Subsystem Clock Controller - Qualcomm SM8750 Video Clock Controller - Rockchip RV1126B and RK3506 clock drivers - i.MX8ULP SIM LPAV clock driver - Samsung ACPM (firmware interface) clock driver - Altera Agilex5 clock driver" * tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (117 commits) clk: keystone: fix compile testing clk: keystone: syscon-clk: fix regmap leak on probe failure clk: qcom: Mark camcc_sm7150_hws static clk: samsung: exynos-clkout: Assign .num before accessing .hws clk: rockchip: Add clock and reset driver for RK3506 dt-bindings: clock: rockchip: Add RK3506 clock and reset unit clk: actions: Fix discarding const qualifier by 'container_of' macro clk: spacemit: Set clk_hw_onecell_data::num before using flex array clk: visconti: Add VIIF clocks dt-bindings: clock: tmpv770x: Add VIIF clocks dt-bindings: clock: tmpv770x: Remove definition of number of clocks clk: visconti: Do not define number of clocks in bindings clk: rockchip: Add clock controller for the RV1126B dt-bindings: clock, reset: Add support for rv1126b clk: rockchip: Implement rockchip_clk_register_armclk_multi_pll() clk: qcom: x1e80100-dispcc: Add USB4 router link resets dt-bindings: clock: qcom: x1e80100-dispcc: Add USB4 router link resets clk: qcom: videocc-sm8750: Add video clock controller driver for SM8750 dt-bindings: clock: qcom: Add SM8750 video clock controller clk: qcom: branch: Extend invert logic for branch2 mem clocks ...master
commit
ba65a4e712
|
|
@ -64,8 +64,6 @@ allOf:
|
|||
reg:
|
||||
minItems: 2
|
||||
|
||||
'#reset-cells': false
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
|
|
@ -85,6 +83,7 @@ examples:
|
|||
reg = <0x1fa20000 0x400>,
|
||||
<0x1fb00000 0x1000>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
||||
- |
|
||||
|
|
|
|||
|
|
@ -0,0 +1,72 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/fsl,imx8ulp-sim-lpav.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: NXP i.MX8ULP LPAV System Integration Module (SIM)
|
||||
|
||||
maintainers:
|
||||
- Laurentiu Mihalcea <laurentiu.mihalcea@nxp.com>
|
||||
|
||||
description:
|
||||
The i.MX8ULP LPAV subsystem contains a block control module known as
|
||||
SIM LPAV, which offers functionalities such as clock gating or reset
|
||||
line assertion/de-assertion.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: fsl,imx8ulp-sim-lpav
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 3
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: bus
|
||||
- const: core
|
||||
- const: plat
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
|
||||
'#reset-cells':
|
||||
const: 1
|
||||
|
||||
mux-controller:
|
||||
$ref: /schemas/mux/reg-mux.yaml#
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- '#clock-cells'
|
||||
- '#reset-cells'
|
||||
- mux-controller
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/imx8ulp-clock.h>
|
||||
|
||||
clock-controller@2da50000 {
|
||||
compatible = "fsl,imx8ulp-sim-lpav";
|
||||
reg = <0x2da50000 0x10000>;
|
||||
clocks = <&cgc2 IMX8ULP_CLK_LPAV_BUS_DIV>,
|
||||
<&cgc2 IMX8ULP_CLK_HIFI_DIVCORE>,
|
||||
<&cgc2 IMX8ULP_CLK_HIFI_DIVPLAT>;
|
||||
clock-names = "bus", "core", "plat";
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
|
||||
mux-controller {
|
||||
compatible = "reg-mux";
|
||||
#mux-control-cells = <1>;
|
||||
mux-reg-masks = <0x8 0x00000200>;
|
||||
};
|
||||
};
|
||||
|
|
@ -46,6 +46,9 @@ properties:
|
|||
"#clock-cells":
|
||||
const: 1
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
|
|
|
|||
|
|
@ -22,16 +22,23 @@ properties:
|
|||
const: microchip,mpfs-clkcfg
|
||||
|
||||
reg:
|
||||
items:
|
||||
- description: |
|
||||
clock config registers:
|
||||
These registers contain enable, reset & divider tables for the, cpu,
|
||||
axi, ahb and rtc/mtimer reference clocks as well as enable and reset
|
||||
for the peripheral clocks.
|
||||
- description: |
|
||||
mss pll dri registers:
|
||||
Block of registers responsible for dynamic reconfiguration of the mss
|
||||
pll
|
||||
oneOf:
|
||||
- items:
|
||||
- description: |
|
||||
clock config registers:
|
||||
These registers contain enable, reset & divider tables for the, cpu,
|
||||
axi, ahb and rtc/mtimer reference clocks as well as enable and reset
|
||||
for the peripheral clocks.
|
||||
- description: |
|
||||
mss pll dri registers:
|
||||
Block of registers responsible for dynamic reconfiguration of the mss
|
||||
pll
|
||||
deprecated: true
|
||||
- items:
|
||||
- description: |
|
||||
mss pll dri registers:
|
||||
Block of registers responsible for dynamic reconfiguration of the mss
|
||||
pll
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
|
@ -69,11 +76,12 @@ examples:
|
|||
- |
|
||||
#include <dt-bindings/clock/microchip,mpfs-clock.h>
|
||||
soc {
|
||||
#address-cells = <2>;
|
||||
#size-cells = <2>;
|
||||
clkcfg: clock-controller@20002000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
clkcfg: clock-controller@3E001000 {
|
||||
compatible = "microchip,mpfs-clkcfg";
|
||||
reg = <0x0 0x20002000 0x0 0x1000>, <0x0 0x3E001000 0x0 0x1000>;
|
||||
reg = <0x3E001000 0x1000>;
|
||||
clocks = <&ref>;
|
||||
#clock-cells = <1>;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ properties:
|
|||
compatible:
|
||||
enum:
|
||||
- qcom,glymur-rpmh-clk
|
||||
- qcom,kaanapali-rpmh-clk
|
||||
- qcom,milos-rpmh-clk
|
||||
- qcom,qcs615-rpmh-clk
|
||||
- qcom,qdu1000-rpmh-clk
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
|
|||
title: Qualcomm Video Clock & Reset Controller on SM8450
|
||||
|
||||
maintainers:
|
||||
- Taniya Das <quic_tdas@quicinc.com>
|
||||
- Taniya Das <taniya.das@oss.qualcomm.com>
|
||||
- Jagadeesh Kona <quic_jkona@quicinc.com>
|
||||
|
||||
description: |
|
||||
|
|
@ -17,6 +17,7 @@ description: |
|
|||
See also:
|
||||
include/dt-bindings/clock/qcom,sm8450-videocc.h
|
||||
include/dt-bindings/clock/qcom,sm8650-videocc.h
|
||||
include/dt-bindings/clock/qcom,sm8750-videocc.h
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
|
|
@ -25,6 +26,7 @@ properties:
|
|||
- qcom,sm8475-videocc
|
||||
- qcom,sm8550-videocc
|
||||
- qcom,sm8650-videocc
|
||||
- qcom,sm8750-videocc
|
||||
- qcom,x1e80100-videocc
|
||||
|
||||
clocks:
|
||||
|
|
@ -61,6 +63,7 @@ allOf:
|
|||
enum:
|
||||
- qcom,sm8450-videocc
|
||||
- qcom,sm8550-videocc
|
||||
- qcom,sm8750-videocc
|
||||
then:
|
||||
required:
|
||||
- required-opps
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ properties:
|
|||
items:
|
||||
- enum:
|
||||
- qcom,glymur-tcsr
|
||||
- qcom,kaanapali-tcsr
|
||||
- qcom,milos-tcsr
|
||||
- qcom,sar2130p-tcsr
|
||||
- qcom,sm8550-tcsr
|
||||
|
|
|
|||
|
|
@ -13,11 +13,15 @@ description: |
|
|||
Qualcomm global clock control module provides the clocks, resets and power
|
||||
domains on SM8750
|
||||
|
||||
See also: include/dt-bindings/clock/qcom,sm8750-gcc.h
|
||||
See also:
|
||||
include/dt-bindings/clock/qcom,kaanapali-gcc.h
|
||||
include/dt-bindings/clock/qcom,sm8750-gcc.h
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sm8750-gcc
|
||||
enum:
|
||||
- qcom,kaanapali-gcc
|
||||
- qcom,sm8750-gcc
|
||||
|
||||
clocks:
|
||||
items:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,55 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/rockchip,rk3506-cru.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Rockchip RK3506 Clock and Reset Unit (CRU)
|
||||
|
||||
maintainers:
|
||||
- Finley Xiao <finley.xiao@rock-chips.com>
|
||||
- Heiko Stuebner <heiko@sntech.de>
|
||||
|
||||
description:
|
||||
The RK3506 CRU generates the clock and also implements reset for SoC
|
||||
peripherals.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: rockchip,rk3506-cru
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
"#clock-cells":
|
||||
const: 1
|
||||
|
||||
"#reset-cells":
|
||||
const: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
const: xin
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- "#clock-cells"
|
||||
- "#reset-cells"
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
clock-controller@ff9a0000 {
|
||||
compatible = "rockchip,rk3506-cru";
|
||||
reg = <0xff9a0000 0x20000>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
clocks = <&xin24m>;
|
||||
clock-names = "xin";
|
||||
};
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/rockchip,rv1126b-cru.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Rockchip RV1126B Clock and Reset Unit
|
||||
|
||||
maintainers:
|
||||
- Elaine Zhang <zhangqing@rock-chips.com>
|
||||
- Heiko Stuebner <heiko@sntech.de>
|
||||
|
||||
description:
|
||||
The rv1126b clock controller generates the clock and also implements a
|
||||
reset controller for SoC peripherals.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- rockchip,rv1126b-cru
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
"#clock-cells":
|
||||
const: 1
|
||||
|
||||
"#reset-cells":
|
||||
const: 1
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
||||
clock-names:
|
||||
const: xin24m
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- "#clock-cells"
|
||||
- "#reset-cells"
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
clock-controller@20000000 {
|
||||
compatible = "rockchip,rv1126b-cru";
|
||||
reg = <0x20000000 0xc0000>;
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
};
|
||||
|
|
@ -38,6 +38,8 @@ properties:
|
|||
- samsung,exynosautov920-cmu-hsi0
|
||||
- samsung,exynosautov920-cmu-hsi1
|
||||
- samsung,exynosautov920-cmu-hsi2
|
||||
- samsung,exynosautov920-cmu-m2m
|
||||
- samsung,exynosautov920-cmu-mfc
|
||||
- samsung,exynosautov920-cmu-misc
|
||||
- samsung,exynosautov920-cmu-peric0
|
||||
- samsung,exynosautov920-cmu-peric1
|
||||
|
|
@ -226,6 +228,46 @@ allOf:
|
|||
- const: embd
|
||||
- const: ethernet
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: samsung,exynosautov920-cmu-m2m
|
||||
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: External reference clock (38.4 MHz)
|
||||
- description: CMU_M2M NOC clock (from CMU_TOP)
|
||||
- description: CMU_M2M JPEG clock (from CMU_TOP)
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: oscclk
|
||||
- const: noc
|
||||
- const: jpeg
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
contains:
|
||||
const: samsung,exynosautov920-cmu-mfc
|
||||
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: External reference clock (38.4 MHz)
|
||||
- description: CMU_MFC MFC clock (from CMU_TOP)
|
||||
- description: CMU_MFC WFD clock (from CMU_TOP)
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: oscclk
|
||||
- const: mfc
|
||||
- const: wfd
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- "#clock-cells"
|
||||
|
|
|
|||
|
|
@ -10710,7 +10710,7 @@ F: arch/arm64/boot/dts/exynos/google/
|
|||
F: drivers/clk/samsung/clk-gs101.c
|
||||
F: drivers/soc/samsung/gs101-pmu.c
|
||||
F: drivers/phy/samsung/phy-gs101-ufs.c
|
||||
F: include/dt-bindings/clock/google,gs101.h
|
||||
F: include/dt-bindings/clock/google,gs101*
|
||||
K: [gG]oogle.?[tT]ensor
|
||||
|
||||
GPD FAN DRIVER
|
||||
|
|
@ -23137,6 +23137,7 @@ L: linux-kernel@vger.kernel.org
|
|||
L: linux-samsung-soc@vger.kernel.org
|
||||
S: Supported
|
||||
F: Documentation/devicetree/bindings/firmware/google,gs101-acpm-ipc.yaml
|
||||
F: drivers/clk/samsung/clk-acpm.c
|
||||
F: drivers/firmware/samsung/exynos-acpm*
|
||||
F: include/linux/firmware/samsung/exynos-acpm-protocol.h
|
||||
|
||||
|
|
|
|||
|
|
@ -125,8 +125,7 @@ obj-$(CONFIG_ARCH_HISI) += hisilicon/
|
|||
obj-y += imgtec/
|
||||
obj-y += imx/
|
||||
obj-y += ingenic/
|
||||
obj-$(CONFIG_ARCH_K3) += keystone/
|
||||
obj-$(CONFIG_ARCH_KEYSTONE) += keystone/
|
||||
obj-y += keystone/
|
||||
obj-y += mediatek/
|
||||
obj-$(CONFIG_ARCH_MESON) += meson/
|
||||
obj-y += microchip/
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ struct owl_clk_desc {
|
|||
};
|
||||
|
||||
static inline struct owl_clk_common *
|
||||
hw_to_owl_clk_common(const struct clk_hw *hw)
|
||||
hw_to_owl_clk_common(struct clk_hw *hw)
|
||||
{
|
||||
return container_of(hw, struct owl_clk_common, hw);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -108,7 +108,7 @@ struct owl_composite {
|
|||
}, \
|
||||
}
|
||||
|
||||
static inline struct owl_composite *hw_to_owl_comp(const struct clk_hw *hw)
|
||||
static inline struct owl_composite *hw_to_owl_comp(struct clk_hw *hw)
|
||||
{
|
||||
struct owl_clk_common *common = hw_to_owl_clk_common(hw);
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ struct owl_divider {
|
|||
}, \
|
||||
}
|
||||
|
||||
static inline struct owl_divider *hw_to_owl_divider(const struct clk_hw *hw)
|
||||
static inline struct owl_divider *hw_to_owl_divider(struct clk_hw *hw)
|
||||
{
|
||||
struct owl_clk_common *common = hw_to_owl_clk_common(hw);
|
||||
|
||||
|
|
|
|||
|
|
@ -57,7 +57,7 @@ struct owl_factor {
|
|||
|
||||
#define div_mask(d) ((1 << ((d)->width)) - 1)
|
||||
|
||||
static inline struct owl_factor *hw_to_owl_factor(const struct clk_hw *hw)
|
||||
static inline struct owl_factor *hw_to_owl_factor(struct clk_hw *hw)
|
||||
{
|
||||
struct owl_clk_common *common = hw_to_owl_clk_common(hw);
|
||||
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ struct owl_gate {
|
|||
}, \
|
||||
} \
|
||||
|
||||
static inline struct owl_gate *hw_to_owl_gate(const struct clk_hw *hw)
|
||||
static inline struct owl_gate *hw_to_owl_gate(struct clk_hw *hw)
|
||||
{
|
||||
struct owl_clk_common *common = hw_to_owl_clk_common(hw);
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ struct owl_mux {
|
|||
}, \
|
||||
}
|
||||
|
||||
static inline struct owl_mux *hw_to_owl_mux(const struct clk_hw *hw)
|
||||
static inline struct owl_mux *hw_to_owl_mux(struct clk_hw *hw)
|
||||
{
|
||||
struct owl_clk_common *common = hw_to_owl_clk_common(hw);
|
||||
|
||||
|
|
|
|||
|
|
@ -98,7 +98,7 @@ struct owl_pll {
|
|||
|
||||
#define mul_mask(m) ((1 << ((m)->width)) - 1)
|
||||
|
||||
static inline struct owl_pll *hw_to_owl_pll(const struct clk_hw *hw)
|
||||
static inline struct owl_pll *hw_to_owl_pll(struct clk_hw *hw)
|
||||
{
|
||||
struct owl_clk_common *common = hw_to_owl_clk_common(hw);
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
#include <linux/regmap.h>
|
||||
#include <linux/reset-controller.h>
|
||||
#include <dt-bindings/clock/en7523-clk.h>
|
||||
#include <dt-bindings/reset/airoha,en7523-reset.h>
|
||||
#include <dt-bindings/reset/airoha,en7581-reset.h>
|
||||
|
||||
#define RST_NR_PER_BANK 32
|
||||
|
|
@ -299,6 +300,53 @@ static const u16 en7581_rst_ofs[] = {
|
|||
REG_RST_CTRL1,
|
||||
};
|
||||
|
||||
static const u16 en7523_rst_map[] = {
|
||||
/* RST_CTRL2 */
|
||||
[EN7523_XPON_PHY_RST] = 0,
|
||||
[EN7523_XSI_MAC_RST] = 7,
|
||||
[EN7523_XSI_PHY_RST] = 8,
|
||||
[EN7523_NPU_RST] = 9,
|
||||
[EN7523_I2S_RST] = 10,
|
||||
[EN7523_TRNG_RST] = 11,
|
||||
[EN7523_TRNG_MSTART_RST] = 12,
|
||||
[EN7523_DUAL_HSI0_RST] = 13,
|
||||
[EN7523_DUAL_HSI1_RST] = 14,
|
||||
[EN7523_HSI_RST] = 15,
|
||||
[EN7523_DUAL_HSI0_MAC_RST] = 16,
|
||||
[EN7523_DUAL_HSI1_MAC_RST] = 17,
|
||||
[EN7523_HSI_MAC_RST] = 18,
|
||||
[EN7523_WDMA_RST] = 19,
|
||||
[EN7523_WOE0_RST] = 20,
|
||||
[EN7523_WOE1_RST] = 21,
|
||||
[EN7523_HSDMA_RST] = 22,
|
||||
[EN7523_I2C2RBUS_RST] = 23,
|
||||
[EN7523_TDMA_RST] = 24,
|
||||
/* RST_CTRL1 */
|
||||
[EN7523_PCM1_ZSI_ISI_RST] = RST_NR_PER_BANK + 0,
|
||||
[EN7523_FE_PDMA_RST] = RST_NR_PER_BANK + 1,
|
||||
[EN7523_FE_QDMA_RST] = RST_NR_PER_BANK + 2,
|
||||
[EN7523_PCM_SPIWP_RST] = RST_NR_PER_BANK + 4,
|
||||
[EN7523_CRYPTO_RST] = RST_NR_PER_BANK + 6,
|
||||
[EN7523_TIMER_RST] = RST_NR_PER_BANK + 8,
|
||||
[EN7523_PCM1_RST] = RST_NR_PER_BANK + 11,
|
||||
[EN7523_UART_RST] = RST_NR_PER_BANK + 12,
|
||||
[EN7523_GPIO_RST] = RST_NR_PER_BANK + 13,
|
||||
[EN7523_GDMA_RST] = RST_NR_PER_BANK + 14,
|
||||
[EN7523_I2C_MASTER_RST] = RST_NR_PER_BANK + 16,
|
||||
[EN7523_PCM2_ZSI_ISI_RST] = RST_NR_PER_BANK + 17,
|
||||
[EN7523_SFC_RST] = RST_NR_PER_BANK + 18,
|
||||
[EN7523_UART2_RST] = RST_NR_PER_BANK + 19,
|
||||
[EN7523_GDMP_RST] = RST_NR_PER_BANK + 20,
|
||||
[EN7523_FE_RST] = RST_NR_PER_BANK + 21,
|
||||
[EN7523_USB_HOST_P0_RST] = RST_NR_PER_BANK + 22,
|
||||
[EN7523_GSW_RST] = RST_NR_PER_BANK + 23,
|
||||
[EN7523_SFC2_PCM_RST] = RST_NR_PER_BANK + 25,
|
||||
[EN7523_PCIE0_RST] = RST_NR_PER_BANK + 26,
|
||||
[EN7523_PCIE1_RST] = RST_NR_PER_BANK + 27,
|
||||
[EN7523_PCIE_HB_RST] = RST_NR_PER_BANK + 29,
|
||||
[EN7523_XPON_MAC_RST] = RST_NR_PER_BANK + 31,
|
||||
};
|
||||
|
||||
static const u16 en7581_rst_map[] = {
|
||||
/* RST_CTRL2 */
|
||||
[EN7581_XPON_PHY_RST] = 0,
|
||||
|
|
@ -357,6 +405,9 @@ static const u16 en7581_rst_map[] = {
|
|||
[EN7581_XPON_MAC_RST] = RST_NR_PER_BANK + 31,
|
||||
};
|
||||
|
||||
static int en7581_reset_register(struct device *dev, void __iomem *base,
|
||||
const u16 *rst_map, int nr_resets);
|
||||
|
||||
static u32 en7523_get_base_rate(const struct en_clk_desc *desc, u32 val)
|
||||
{
|
||||
if (!desc->base_bits)
|
||||
|
|
@ -552,7 +603,8 @@ static int en7523_clk_hw_init(struct platform_device *pdev,
|
|||
|
||||
en7523_register_clocks(&pdev->dev, clk_data, base, np_base);
|
||||
|
||||
return 0;
|
||||
return en7581_reset_register(&pdev->dev, np_base, en7523_rst_map,
|
||||
ARRAY_SIZE(en7523_rst_map));
|
||||
}
|
||||
|
||||
static void en7581_register_clocks(struct device *dev, struct clk_hw_onecell_data *clk_data,
|
||||
|
|
@ -652,7 +704,8 @@ static const struct reset_control_ops en7581_reset_ops = {
|
|||
.status = en7523_reset_status,
|
||||
};
|
||||
|
||||
static int en7581_reset_register(struct device *dev, void __iomem *base)
|
||||
static int en7581_reset_register(struct device *dev, void __iomem *base,
|
||||
const u16 *rst_map, int nr_resets)
|
||||
{
|
||||
struct en_rst_data *rst_data;
|
||||
|
||||
|
|
@ -661,10 +714,10 @@ static int en7581_reset_register(struct device *dev, void __iomem *base)
|
|||
return -ENOMEM;
|
||||
|
||||
rst_data->bank_ofs = en7581_rst_ofs;
|
||||
rst_data->idx_map = en7581_rst_map;
|
||||
rst_data->idx_map = rst_map;
|
||||
rst_data->base = base;
|
||||
|
||||
rst_data->rcdev.nr_resets = ARRAY_SIZE(en7581_rst_map);
|
||||
rst_data->rcdev.nr_resets = nr_resets;
|
||||
rst_data->rcdev.of_xlate = en7523_reset_xlate;
|
||||
rst_data->rcdev.ops = &en7581_reset_ops;
|
||||
rst_data->rcdev.of_node = dev->of_node;
|
||||
|
|
@ -698,7 +751,8 @@ static int en7581_clk_hw_init(struct platform_device *pdev,
|
|||
val = readl(base + REG_NP_SCU_PCIC);
|
||||
writel(val | 3, base + REG_NP_SCU_PCIC);
|
||||
|
||||
return en7581_reset_register(&pdev->dev, base);
|
||||
return en7581_reset_register(&pdev->dev, base, en7581_rst_map,
|
||||
ARRAY_SIZE(en7581_rst_map));
|
||||
}
|
||||
|
||||
static int en7523_clk_probe(struct platform_device *pdev)
|
||||
|
|
|
|||
|
|
@ -16,8 +16,6 @@
|
|||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <dt-bindings/clock/microchip,lan966x.h>
|
||||
|
||||
#define GCK_ENA BIT(0)
|
||||
#define GCK_SRC_SEL GENMASK(9, 8)
|
||||
#define GCK_PRESCALER GENMASK(23, 16)
|
||||
|
|
|
|||
|
|
@ -105,6 +105,7 @@ config CLK_IMX8ULP
|
|||
tristate "IMX8ULP CCM Clock Driver"
|
||||
depends on ARCH_MXC || COMPILE_TEST
|
||||
select MXC_CLK
|
||||
select AUXILIARY_BUS
|
||||
help
|
||||
Build the driver for i.MX8ULP CCM Clock Driver
|
||||
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@ clk-imx-lpcg-scu-$(CONFIG_CLK_IMX8QXP) += clk-lpcg-scu.o clk-imx8qxp-lpcg.o
|
|||
clk-imx-acm-$(CONFIG_CLK_IMX8QXP) = clk-imx8-acm.o
|
||||
|
||||
obj-$(CONFIG_CLK_IMX8ULP) += clk-imx8ulp.o
|
||||
obj-$(CONFIG_CLK_IMX8ULP) += clk-imx8ulp-sim-lpav.o
|
||||
|
||||
obj-$(CONFIG_CLK_IMX1) += clk-imx1.o
|
||||
obj-$(CONFIG_CLK_IMX25) += clk-imx25.o
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
#include <linux/bits.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/slab.h>
|
||||
|
|
@ -36,6 +37,9 @@ static int pcc_gate_enable(struct clk_hw *hw)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Make sure the IP's clock is ready before release reset */
|
||||
udelay(1);
|
||||
|
||||
spin_lock_irqsave(gate->lock, flags);
|
||||
/*
|
||||
* release the sw reset for peripherals associated with
|
||||
|
|
@ -47,6 +51,15 @@ static int pcc_gate_enable(struct clk_hw *hw)
|
|||
|
||||
spin_unlock_irqrestore(gate->lock, flags);
|
||||
|
||||
/*
|
||||
* Read back the register to make sure the previous write has been
|
||||
* done in the target HW register. For IP like GPU, after deassert
|
||||
* the reset, need to wait for a while to make sure the sync reset
|
||||
* is done
|
||||
*/
|
||||
readl(gate->reg);
|
||||
udelay(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -230,50 +230,19 @@ struct clk_imx8mp_audiomix_priv {
|
|||
|
||||
#if IS_ENABLED(CONFIG_RESET_CONTROLLER)
|
||||
|
||||
static void clk_imx8mp_audiomix_reset_unregister_adev(void *_adev)
|
||||
{
|
||||
struct auxiliary_device *adev = _adev;
|
||||
|
||||
auxiliary_device_delete(adev);
|
||||
auxiliary_device_uninit(adev);
|
||||
}
|
||||
|
||||
static void clk_imx8mp_audiomix_reset_adev_release(struct device *dev)
|
||||
{
|
||||
struct auxiliary_device *adev = to_auxiliary_dev(dev);
|
||||
|
||||
kfree(adev);
|
||||
}
|
||||
|
||||
static int clk_imx8mp_audiomix_reset_controller_register(struct device *dev,
|
||||
struct clk_imx8mp_audiomix_priv *priv)
|
||||
{
|
||||
struct auxiliary_device *adev __free(kfree) = NULL;
|
||||
int ret;
|
||||
struct auxiliary_device *adev;
|
||||
|
||||
if (!of_property_present(dev->of_node, "#reset-cells"))
|
||||
return 0;
|
||||
|
||||
adev = kzalloc(sizeof(*adev), GFP_KERNEL);
|
||||
adev = devm_auxiliary_device_create(dev, "reset", NULL);
|
||||
if (!adev)
|
||||
return -ENOMEM;
|
||||
return -ENODEV;
|
||||
|
||||
adev->name = "reset";
|
||||
adev->dev.parent = dev;
|
||||
adev->dev.release = clk_imx8mp_audiomix_reset_adev_release;
|
||||
|
||||
ret = auxiliary_device_init(adev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = auxiliary_device_add(adev);
|
||||
if (ret) {
|
||||
auxiliary_device_uninit(adev);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return devm_add_action_or_reset(dev, clk_imx8mp_audiomix_reset_unregister_adev,
|
||||
no_free_ptr(adev));
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* !CONFIG_RESET_CONTROLLER */
|
||||
|
|
|
|||
|
|
@ -0,0 +1,156 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright 2025 NXP
|
||||
*/
|
||||
|
||||
#include <dt-bindings/clock/imx8ulp-clock.h>
|
||||
|
||||
#include <linux/auxiliary_bus.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#define SYSCTRL0 0x8
|
||||
|
||||
#define IMX8ULP_HIFI_CLK_GATE(gname, cname, pname, bidx) \
|
||||
{ \
|
||||
.name = gname "_cg", \
|
||||
.id = IMX8ULP_CLK_SIM_LPAV_HIFI_##cname, \
|
||||
.parent = { .fw_name = pname }, \
|
||||
.bit = bidx, \
|
||||
}
|
||||
|
||||
struct clk_imx8ulp_sim_lpav_data {
|
||||
spinlock_t lock; /* shared by MUX, clock gate and reset */
|
||||
unsigned long flags; /* for spinlock usage */
|
||||
struct clk_hw_onecell_data clk_data; /* keep last */
|
||||
};
|
||||
|
||||
struct clk_imx8ulp_sim_lpav_gate {
|
||||
const char *name;
|
||||
int id;
|
||||
const struct clk_parent_data parent;
|
||||
u8 bit;
|
||||
};
|
||||
|
||||
static struct clk_imx8ulp_sim_lpav_gate gates[] = {
|
||||
IMX8ULP_HIFI_CLK_GATE("hifi_core", CORE, "core", 17),
|
||||
IMX8ULP_HIFI_CLK_GATE("hifi_pbclk", PBCLK, "bus", 18),
|
||||
IMX8ULP_HIFI_CLK_GATE("hifi_plat", PLAT, "plat", 19)
|
||||
};
|
||||
|
||||
static void clk_imx8ulp_sim_lpav_lock(void *arg) __acquires(&data->lock)
|
||||
{
|
||||
struct clk_imx8ulp_sim_lpav_data *data = dev_get_drvdata(arg);
|
||||
|
||||
spin_lock_irqsave(&data->lock, data->flags);
|
||||
}
|
||||
|
||||
static void clk_imx8ulp_sim_lpav_unlock(void *arg) __releases(&data->lock)
|
||||
{
|
||||
struct clk_imx8ulp_sim_lpav_data *data = dev_get_drvdata(arg);
|
||||
|
||||
spin_unlock_irqrestore(&data->lock, data->flags);
|
||||
}
|
||||
|
||||
static int clk_imx8ulp_sim_lpav_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct regmap_config regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.val_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.lock = clk_imx8ulp_sim_lpav_lock,
|
||||
.unlock = clk_imx8ulp_sim_lpav_unlock,
|
||||
.lock_arg = &pdev->dev,
|
||||
};
|
||||
struct clk_imx8ulp_sim_lpav_data *data;
|
||||
struct auxiliary_device *adev;
|
||||
struct regmap *regmap;
|
||||
void __iomem *base;
|
||||
struct clk_hw *hw;
|
||||
int i, ret;
|
||||
|
||||
data = devm_kzalloc(&pdev->dev,
|
||||
struct_size(data, clk_data.hws, ARRAY_SIZE(gates)),
|
||||
GFP_KERNEL);
|
||||
if (!data)
|
||||
return -ENOMEM;
|
||||
|
||||
dev_set_drvdata(&pdev->dev, data);
|
||||
|
||||
/*
|
||||
* this lock is used directly by the clock gate and indirectly
|
||||
* by the reset and mux controller via the regmap API
|
||||
*/
|
||||
spin_lock_init(&data->lock);
|
||||
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(base))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(base),
|
||||
"failed to ioremap base\n");
|
||||
/*
|
||||
* although the clock gate doesn't use the regmap API to modify the
|
||||
* registers, we still need the regmap because of the reset auxiliary
|
||||
* driver and the MUX drivers, which use the parent device's regmap
|
||||
*/
|
||||
regmap = devm_regmap_init_mmio(&pdev->dev, base, ®map_config);
|
||||
if (IS_ERR(regmap))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(regmap),
|
||||
"failed to initialize regmap\n");
|
||||
|
||||
data->clk_data.num = ARRAY_SIZE(gates);
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(gates); i++) {
|
||||
hw = devm_clk_hw_register_gate_parent_data(&pdev->dev,
|
||||
gates[i].name,
|
||||
&gates[i].parent,
|
||||
CLK_SET_RATE_PARENT,
|
||||
base + SYSCTRL0,
|
||||
gates[i].bit,
|
||||
0x0, &data->lock);
|
||||
if (IS_ERR(hw))
|
||||
return dev_err_probe(&pdev->dev, PTR_ERR(hw),
|
||||
"failed to register %s gate\n",
|
||||
gates[i].name);
|
||||
|
||||
data->clk_data.hws[i] = hw;
|
||||
}
|
||||
|
||||
adev = devm_auxiliary_device_create(&pdev->dev, "reset", NULL);
|
||||
if (!adev)
|
||||
return dev_err_probe(&pdev->dev, -ENODEV,
|
||||
"failed to register aux reset\n");
|
||||
|
||||
ret = devm_of_clk_add_hw_provider(&pdev->dev,
|
||||
of_clk_hw_onecell_get,
|
||||
&data->clk_data);
|
||||
if (ret)
|
||||
return dev_err_probe(&pdev->dev, ret,
|
||||
"failed to register clk hw provider\n");
|
||||
|
||||
/* used to probe MUX child device */
|
||||
return devm_of_platform_populate(&pdev->dev);
|
||||
}
|
||||
|
||||
static const struct of_device_id clk_imx8ulp_sim_lpav_of_match[] = {
|
||||
{ .compatible = "fsl,imx8ulp-sim-lpav" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, clk_imx8ulp_sim_lpav_of_match);
|
||||
|
||||
static struct platform_driver clk_imx8ulp_sim_lpav_driver = {
|
||||
.probe = clk_imx8ulp_sim_lpav_probe,
|
||||
.driver = {
|
||||
.name = "clk-imx8ulp-sim-lpav",
|
||||
.of_match_table = clk_imx8ulp_sim_lpav_of_match,
|
||||
},
|
||||
};
|
||||
module_platform_driver(clk_imx8ulp_sim_lpav_driver);
|
||||
|
||||
MODULE_LICENSE("GPL");
|
||||
MODULE_DESCRIPTION("i.MX8ULP LPAV System Integration Module (SIM) clock driver");
|
||||
MODULE_AUTHOR("Laurentiu Mihalcea <laurentiu.mihalcea@nxp.com>");
|
||||
|
|
@ -496,8 +496,8 @@ static int ti_sci_scan_clocks_from_fw(struct sci_clk_provider *provider)
|
|||
static int _cmp_sci_clk_list(void *priv, const struct list_head *a,
|
||||
const struct list_head *b)
|
||||
{
|
||||
struct sci_clk *ca = container_of(a, struct sci_clk, node);
|
||||
struct sci_clk *cb = container_of(b, struct sci_clk, node);
|
||||
const struct sci_clk *ca = container_of(a, struct sci_clk, node);
|
||||
const struct sci_clk *cb = container_of(b, struct sci_clk, node);
|
||||
|
||||
return _cmp_sci_clk(ca, &cb);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ static int ti_syscon_gate_clk_probe(struct platform_device *pdev)
|
|||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
regmap = regmap_init_mmio(dev, base, &ti_syscon_regmap_cfg);
|
||||
regmap = devm_regmap_init_mmio(dev, base, &ti_syscon_regmap_cfg);
|
||||
if (IS_ERR(regmap))
|
||||
return dev_err_probe(dev, PTR_ERR(regmap),
|
||||
"failed to get regmap\n");
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ config MCHP_CLK_MPFS
|
|||
bool "Clk driver for PolarFire SoC"
|
||||
depends on ARCH_MICROCHIP_POLARFIRE || COMPILE_TEST
|
||||
default ARCH_MICROCHIP_POLARFIRE
|
||||
depends on MFD_SYSCON
|
||||
select AUXILIARY_BUS
|
||||
select REGMAP_MMIO
|
||||
help
|
||||
Supports Clock Configuration for PolarFire SoC
|
||||
|
|
|
|||
|
|
@ -4,10 +4,13 @@
|
|||
*
|
||||
* Copyright (C) 2020-2022 Microchip Technology Inc. All rights reserved.
|
||||
*/
|
||||
#include <linux/cleanup.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <dt-bindings/clock/microchip,mpfs-clock.h>
|
||||
#include <soc/microchip/mpfs.h>
|
||||
|
||||
|
|
@ -30,6 +33,14 @@
|
|||
#define MSSPLL_POSTDIV_WIDTH 0x07u
|
||||
#define MSSPLL_FIXED_DIV 4u
|
||||
|
||||
static const struct regmap_config mpfs_clk_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.val_format_endian = REGMAP_ENDIAN_LITTLE,
|
||||
.max_register = REG_SUBBLK_RESET_CR,
|
||||
};
|
||||
|
||||
/*
|
||||
* This clock ID is defined here, rather than the binding headers, as it is an
|
||||
* internal clock only, and therefore has no consumers in other peripheral
|
||||
|
|
@ -39,6 +50,7 @@
|
|||
|
||||
struct mpfs_clock_data {
|
||||
struct device *dev;
|
||||
struct regmap *regmap;
|
||||
void __iomem *base;
|
||||
void __iomem *msspll_base;
|
||||
struct clk_hw_onecell_data hw_data;
|
||||
|
|
@ -67,21 +79,39 @@ struct mpfs_msspll_out_hw_clock {
|
|||
|
||||
#define to_mpfs_msspll_out_clk(_hw) container_of(_hw, struct mpfs_msspll_out_hw_clock, hw)
|
||||
|
||||
struct mpfs_cfg_clock {
|
||||
struct regmap *map;
|
||||
const struct clk_div_table *table;
|
||||
u8 map_offset;
|
||||
u8 shift;
|
||||
u8 width;
|
||||
u8 flags;
|
||||
};
|
||||
|
||||
struct mpfs_cfg_hw_clock {
|
||||
struct clk_divider cfg;
|
||||
struct clk_init_data init;
|
||||
struct clk_hw hw;
|
||||
struct mpfs_cfg_clock cfg;
|
||||
unsigned int id;
|
||||
u32 reg_offset;
|
||||
};
|
||||
|
||||
#define to_mpfs_cfg_clk(_hw) container_of(_hw, struct mpfs_cfg_hw_clock, hw)
|
||||
|
||||
struct mpfs_periph_clock {
|
||||
struct regmap *map;
|
||||
u8 map_offset;
|
||||
u8 shift;
|
||||
};
|
||||
|
||||
struct mpfs_periph_hw_clock {
|
||||
struct clk_gate periph;
|
||||
struct clk_hw hw;
|
||||
struct mpfs_periph_clock periph;
|
||||
unsigned int id;
|
||||
};
|
||||
|
||||
#define to_mpfs_periph_clk(_hw) container_of(_hw, struct mpfs_periph_hw_clock, hw)
|
||||
|
||||
/*
|
||||
* mpfs_clk_lock prevents anything else from writing to the
|
||||
* mpfs clk block while a software locked register is being written.
|
||||
* Protects MSSPLL outputs, since there's two to a register
|
||||
*/
|
||||
static DEFINE_SPINLOCK(mpfs_clk_lock);
|
||||
|
||||
|
|
@ -219,16 +249,61 @@ static int mpfs_clk_register_msspll_outs(struct device *dev,
|
|||
/*
|
||||
* "CFG" clocks
|
||||
*/
|
||||
static unsigned long mpfs_cfg_clk_recalc_rate(struct clk_hw *hw, unsigned long prate)
|
||||
{
|
||||
struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw);
|
||||
struct mpfs_cfg_clock *cfg = &cfg_hw->cfg;
|
||||
u32 val;
|
||||
|
||||
#define CLK_CFG(_id, _name, _parent, _shift, _width, _table, _flags, _offset) { \
|
||||
.id = _id, \
|
||||
.cfg.shift = _shift, \
|
||||
.cfg.width = _width, \
|
||||
.cfg.table = _table, \
|
||||
.reg_offset = _offset, \
|
||||
.cfg.flags = _flags, \
|
||||
.cfg.hw.init = CLK_HW_INIT(_name, _parent, &clk_divider_ops, 0), \
|
||||
.cfg.lock = &mpfs_clk_lock, \
|
||||
regmap_read(cfg->map, cfg->map_offset, &val);
|
||||
val >>= cfg->shift;
|
||||
val &= clk_div_mask(cfg->width);
|
||||
|
||||
return divider_recalc_rate(hw, prate, val, cfg->table, cfg->flags, cfg->width);
|
||||
}
|
||||
|
||||
static int mpfs_cfg_clk_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
|
||||
{
|
||||
struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw);
|
||||
struct mpfs_cfg_clock *cfg = &cfg_hw->cfg;
|
||||
|
||||
return divider_determine_rate(hw, req, cfg->table, cfg->width, 0);
|
||||
}
|
||||
|
||||
static int mpfs_cfg_clk_set_rate(struct clk_hw *hw, unsigned long rate, unsigned long prate)
|
||||
{
|
||||
struct mpfs_cfg_hw_clock *cfg_hw = to_mpfs_cfg_clk(hw);
|
||||
struct mpfs_cfg_clock *cfg = &cfg_hw->cfg;
|
||||
int divider_setting;
|
||||
u32 val;
|
||||
u32 mask;
|
||||
|
||||
divider_setting = divider_get_val(rate, prate, cfg->table, cfg->width, 0);
|
||||
|
||||
if (divider_setting < 0)
|
||||
return divider_setting;
|
||||
|
||||
mask = clk_div_mask(cfg->width) << cfg->shift;
|
||||
val = divider_setting << cfg->shift;
|
||||
regmap_update_bits(cfg->map, cfg->map_offset, val, mask);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct clk_ops mpfs_clk_cfg_ops = {
|
||||
.recalc_rate = mpfs_cfg_clk_recalc_rate,
|
||||
.determine_rate = mpfs_cfg_clk_determine_rate,
|
||||
.set_rate = mpfs_cfg_clk_set_rate,
|
||||
};
|
||||
|
||||
#define CLK_CFG(_id, _name, _parent, _shift, _width, _table, _flags, _offset) { \
|
||||
.id = _id, \
|
||||
.cfg.shift = _shift, \
|
||||
.cfg.width = _width, \
|
||||
.cfg.table = _table, \
|
||||
.cfg.map_offset = _offset, \
|
||||
.cfg.flags = _flags, \
|
||||
.hw.init = CLK_HW_INIT(_name, _parent, &mpfs_clk_cfg_ops, 0), \
|
||||
}
|
||||
|
||||
#define CLK_CPU_OFFSET 0u
|
||||
|
|
@ -248,10 +323,10 @@ static struct mpfs_cfg_hw_clock mpfs_cfg_clks[] = {
|
|||
.cfg.shift = 0,
|
||||
.cfg.width = 12,
|
||||
.cfg.table = mpfs_div_rtcref_table,
|
||||
.reg_offset = REG_RTC_CLOCK_CR,
|
||||
.cfg.map_offset = REG_RTC_CLOCK_CR,
|
||||
.cfg.flags = CLK_DIVIDER_ONE_BASED,
|
||||
.cfg.hw.init =
|
||||
CLK_HW_INIT_PARENTS_DATA("clk_rtcref", mpfs_ext_ref, &clk_divider_ops, 0),
|
||||
.hw.init =
|
||||
CLK_HW_INIT_PARENTS_DATA("clk_rtcref", mpfs_ext_ref, &mpfs_clk_cfg_ops, 0),
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -264,14 +339,14 @@ static int mpfs_clk_register_cfgs(struct device *dev, struct mpfs_cfg_hw_clock *
|
|||
for (i = 0; i < num_clks; i++) {
|
||||
struct mpfs_cfg_hw_clock *cfg_hw = &cfg_hws[i];
|
||||
|
||||
cfg_hw->cfg.reg = data->base + cfg_hw->reg_offset;
|
||||
ret = devm_clk_hw_register(dev, &cfg_hw->cfg.hw);
|
||||
cfg_hw->cfg.map = data->regmap;
|
||||
ret = devm_clk_hw_register(dev, &cfg_hw->hw);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed to register clock id: %d\n",
|
||||
cfg_hw->id);
|
||||
|
||||
id = cfg_hw->id;
|
||||
data->hw_data.hws[id] = &cfg_hw->cfg.hw;
|
||||
data->hw_data.hws[id] = &cfg_hw->hw;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
@ -281,15 +356,50 @@ static int mpfs_clk_register_cfgs(struct device *dev, struct mpfs_cfg_hw_clock *
|
|||
* peripheral clocks - devices connected to axi or ahb buses.
|
||||
*/
|
||||
|
||||
#define CLK_PERIPH(_id, _name, _parent, _shift, _flags) { \
|
||||
.id = _id, \
|
||||
.periph.bit_idx = _shift, \
|
||||
.periph.hw.init = CLK_HW_INIT_HW(_name, _parent, &clk_gate_ops, \
|
||||
_flags), \
|
||||
.periph.lock = &mpfs_clk_lock, \
|
||||
static int mpfs_periph_clk_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
|
||||
struct mpfs_periph_clock *periph = &periph_hw->periph;
|
||||
|
||||
regmap_update_bits(periph->map, periph->map_offset,
|
||||
BIT(periph->shift), BIT(periph->shift));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT##_OFFSET].cfg.hw)
|
||||
static void mpfs_periph_clk_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
|
||||
struct mpfs_periph_clock *periph = &periph_hw->periph;
|
||||
|
||||
regmap_update_bits(periph->map, periph->map_offset, BIT(periph->shift), 0);
|
||||
}
|
||||
|
||||
static int mpfs_periph_clk_is_enabled(struct clk_hw *hw)
|
||||
{
|
||||
struct mpfs_periph_hw_clock *periph_hw = to_mpfs_periph_clk(hw);
|
||||
struct mpfs_periph_clock *periph = &periph_hw->periph;
|
||||
u32 val;
|
||||
|
||||
regmap_read(periph->map, periph->map_offset, &val);
|
||||
|
||||
return !!(val & BIT(periph->shift));
|
||||
}
|
||||
|
||||
static const struct clk_ops mpfs_periph_clk_ops = {
|
||||
.enable = mpfs_periph_clk_enable,
|
||||
.disable = mpfs_periph_clk_disable,
|
||||
.is_enabled = mpfs_periph_clk_is_enabled,
|
||||
};
|
||||
|
||||
#define CLK_PERIPH(_id, _name, _parent, _shift, _flags) { \
|
||||
.id = _id, \
|
||||
.periph.map_offset = REG_SUBBLK_CLOCK_CR, \
|
||||
.periph.shift = _shift, \
|
||||
.hw.init = CLK_HW_INIT_HW(_name, _parent, &mpfs_periph_clk_ops, _flags), \
|
||||
}
|
||||
|
||||
#define PARENT_CLK(PARENT) (&mpfs_cfg_clks[CLK_##PARENT##_OFFSET].hw)
|
||||
|
||||
/*
|
||||
* Critical clocks:
|
||||
|
|
@ -346,19 +456,55 @@ static int mpfs_clk_register_periphs(struct device *dev, struct mpfs_periph_hw_c
|
|||
for (i = 0; i < num_clks; i++) {
|
||||
struct mpfs_periph_hw_clock *periph_hw = &periph_hws[i];
|
||||
|
||||
periph_hw->periph.reg = data->base + REG_SUBBLK_CLOCK_CR;
|
||||
ret = devm_clk_hw_register(dev, &periph_hw->periph.hw);
|
||||
periph_hw->periph.map = data->regmap;
|
||||
ret = devm_clk_hw_register(dev, &periph_hw->hw);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "failed to register clock id: %d\n",
|
||||
periph_hw->id);
|
||||
|
||||
id = periph_hws[i].id;
|
||||
data->hw_data.hws[id] = &periph_hw->periph.hw;
|
||||
data->hw_data.hws[id] = &periph_hw->hw;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int mpfs_clk_syscon_probe(struct mpfs_clock_data *clk_data,
|
||||
struct platform_device *pdev)
|
||||
{
|
||||
clk_data->regmap = syscon_regmap_lookup_by_compatible("microchip,mpfs-mss-top-sysreg");
|
||||
if (IS_ERR(clk_data->regmap))
|
||||
return PTR_ERR(clk_data->regmap);
|
||||
|
||||
clk_data->msspll_base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(clk_data->msspll_base))
|
||||
return PTR_ERR(clk_data->msspll_base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int mpfs_clk_old_format_probe(struct mpfs_clock_data *clk_data,
|
||||
struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
|
||||
dev_warn(&pdev->dev, "falling back to old devicetree format");
|
||||
|
||||
clk_data->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(clk_data->base))
|
||||
return PTR_ERR(clk_data->base);
|
||||
|
||||
clk_data->msspll_base = devm_platform_ioremap_resource(pdev, 1);
|
||||
if (IS_ERR(clk_data->msspll_base))
|
||||
return PTR_ERR(clk_data->msspll_base);
|
||||
|
||||
clk_data->regmap = devm_regmap_init_mmio(dev, clk_data->base, &mpfs_clk_regmap_config);
|
||||
if (IS_ERR(clk_data->regmap))
|
||||
return PTR_ERR(clk_data->regmap);
|
||||
|
||||
return mpfs_reset_controller_register(dev, clk_data->regmap);
|
||||
}
|
||||
|
||||
static int mpfs_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
|
|
@ -374,13 +520,12 @@ static int mpfs_clk_probe(struct platform_device *pdev)
|
|||
if (!clk_data)
|
||||
return -ENOMEM;
|
||||
|
||||
clk_data->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(clk_data->base))
|
||||
return PTR_ERR(clk_data->base);
|
||||
|
||||
clk_data->msspll_base = devm_platform_ioremap_resource(pdev, 1);
|
||||
if (IS_ERR(clk_data->msspll_base))
|
||||
return PTR_ERR(clk_data->msspll_base);
|
||||
ret = mpfs_clk_syscon_probe(clk_data, pdev);
|
||||
if (ret) {
|
||||
ret = mpfs_clk_old_format_probe(clk_data, pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
clk_data->hw_data.num = num_clks;
|
||||
clk_data->dev = dev;
|
||||
|
|
@ -406,11 +551,7 @@ static int mpfs_clk_probe(struct platform_device *pdev)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, &clk_data->hw_data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return mpfs_reset_controller_register(dev, clk_data->base + REG_SUBBLK_RESET_CR);
|
||||
return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, &clk_data->hw_data);
|
||||
}
|
||||
|
||||
static const struct of_device_id mpfs_clk_of_match_table[] = {
|
||||
|
|
|
|||
|
|
@ -215,16 +215,16 @@ config IPQ_APSS_PLL
|
|||
devices.
|
||||
|
||||
config IPQ_APSS_5424
|
||||
tristate "IPQ APSS Clock Controller"
|
||||
tristate "IPQ5424 APSS Clock Controller"
|
||||
select IPQ_APSS_PLL
|
||||
default y if IPQ_GCC_5424
|
||||
help
|
||||
Support for APSS Clock controller on Qualcom IPQ5424 platform.
|
||||
Support for APSS Clock controller on Qualcomm IPQ5424 platform.
|
||||
Say Y if you want to support CPU frequency scaling on ipq based
|
||||
devices.
|
||||
|
||||
config IPQ_APSS_6018
|
||||
tristate "IPQ APSS Clock Controller"
|
||||
tristate "IPQ6018 APSS Clock Controller"
|
||||
select IPQ_APSS_PLL
|
||||
depends on QCOM_APCS_IPC || COMPILE_TEST
|
||||
depends on QCOM_SMEM
|
||||
|
|
@ -317,6 +317,17 @@ config IPQ_GCC_9574
|
|||
i2c, USB, SD/eMMC, etc. Select this for the root clock
|
||||
of ipq9574.
|
||||
|
||||
config IPQ_NSSCC_5424
|
||||
tristate "IPQ5424 NSS Clock Controller"
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
depends on IPQ_GCC_5424
|
||||
help
|
||||
Support for NSS clock controller on ipq5424 devices.
|
||||
NSSCC receives the clock sources from GCC, CMN PLL and UNIPHY (PCS).
|
||||
It in turn supplies the clocks and resets to the networking hardware.
|
||||
Say Y or M if you want to enable networking function on the
|
||||
IPQ5424 devices.
|
||||
|
||||
config IPQ_NSSCC_9574
|
||||
tristate "IPQ9574 NSS Clock Controller"
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
|
|
@ -531,6 +542,7 @@ config QCM_DISPCC_2290
|
|||
|
||||
config QCS_DISPCC_615
|
||||
tristate "QCS615 Display Clock Controller"
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
select QCS_GCC_615
|
||||
help
|
||||
Support for the display clock controller on Qualcomm Technologies, Inc
|
||||
|
|
@ -586,6 +598,7 @@ config QCS_GCC_615
|
|||
|
||||
config QCS_GPUCC_615
|
||||
tristate "QCS615 Graphics clock controller"
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
select QCS_GCC_615
|
||||
help
|
||||
Support for the graphics clock controller on QCS615 devices.
|
||||
|
|
@ -594,6 +607,7 @@ config QCS_GPUCC_615
|
|||
|
||||
config QCS_VIDEOCC_615
|
||||
tristate "QCS615 Video Clock Controller"
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
select QCS_GCC_615
|
||||
help
|
||||
Support for the video clock controller on QCS615 devices.
|
||||
|
|
@ -1448,6 +1462,7 @@ config SA_VIDEOCC_8775P
|
|||
|
||||
config SM_VIDEOCC_6350
|
||||
tristate "SM6350 Video Clock Controller"
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
select SM_GCC_6350
|
||||
select QCOM_GDSC
|
||||
help
|
||||
|
|
@ -1516,6 +1531,17 @@ config SM_VIDEOCC_8550
|
|||
Say Y if you want to support video devices and functionality such as
|
||||
video encode/decode.
|
||||
|
||||
config SM_VIDEOCC_8750
|
||||
tristate "SM8750 Video Clock Controller"
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
select SM_GCC_8750
|
||||
select QCOM_GDSC
|
||||
help
|
||||
Support for the video clock controller on Qualcomm Technologies, Inc.
|
||||
SM8750 devices.
|
||||
Say Y if you want to support video devices and functionality such as
|
||||
video encode/decode.
|
||||
|
||||
config SPMI_PMIC_CLKDIV
|
||||
tristate "SPMI PMIC clkdiv Support"
|
||||
depends on SPMI || COMPILE_TEST
|
||||
|
|
|
|||
|
|
@ -43,6 +43,7 @@ obj-$(CONFIG_IPQ_GCC_6018) += gcc-ipq6018.o
|
|||
obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.o
|
||||
obj-$(CONFIG_IPQ_GCC_8074) += gcc-ipq8074.o
|
||||
obj-$(CONFIG_IPQ_GCC_9574) += gcc-ipq9574.o
|
||||
obj-$(CONFIG_IPQ_NSSCC_5424) += nsscc-ipq5424.o
|
||||
obj-$(CONFIG_IPQ_NSSCC_9574) += nsscc-ipq9574.o
|
||||
obj-$(CONFIG_IPQ_LCC_806X) += lcc-ipq806x.o
|
||||
obj-$(CONFIG_IPQ_NSSCC_QCA8K) += nsscc-qca8k.o
|
||||
|
|
@ -184,6 +185,7 @@ obj-$(CONFIG_SM_VIDEOCC_8250) += videocc-sm8250.o
|
|||
obj-$(CONFIG_SM_VIDEOCC_8350) += videocc-sm8350.o
|
||||
obj-$(CONFIG_SM_VIDEOCC_8450) += videocc-sm8450.o
|
||||
obj-$(CONFIG_SM_VIDEOCC_8550) += videocc-sm8550.o
|
||||
obj-$(CONFIG_SM_VIDEOCC_8750) += videocc-sm8750.o
|
||||
obj-$(CONFIG_SM_VIDEOCC_MILOS) += videocc-milos.o
|
||||
obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o
|
||||
obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o
|
||||
|
|
|
|||
|
|
@ -35,13 +35,6 @@ enum {
|
|||
P_L3_PLL,
|
||||
};
|
||||
|
||||
struct apss_clk {
|
||||
struct notifier_block cpu_clk_notifier;
|
||||
struct clk_hw *hw;
|
||||
struct device *dev;
|
||||
struct clk *l3_clk;
|
||||
};
|
||||
|
||||
static const struct alpha_pll_config apss_pll_config = {
|
||||
.l = 0x3b,
|
||||
.config_ctl_val = 0x08200920,
|
||||
|
|
|
|||
|
|
@ -1543,6 +1543,7 @@ static struct gdsc bps_gdsc = {
|
|||
.name = "bps_gdsc",
|
||||
},
|
||||
.flags = HW_CTRL | POLL_CFG_GDSCR,
|
||||
.parent = &titan_top_gdsc.pd,
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
|
|
@ -1552,6 +1553,7 @@ static struct gdsc ipe_0_gdsc = {
|
|||
.name = "ipe_0_gdsc",
|
||||
},
|
||||
.flags = HW_CTRL | POLL_CFG_GDSCR,
|
||||
.parent = &titan_top_gdsc.pd,
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
|
|
@ -1561,6 +1563,7 @@ static struct gdsc ipe_1_gdsc = {
|
|||
.name = "ipe_1_gdsc",
|
||||
},
|
||||
.flags = HW_CTRL | POLL_CFG_GDSCR,
|
||||
.parent = &titan_top_gdsc.pd,
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -145,15 +145,11 @@ static struct clk_alpha_pll_postdiv camcc_pll1_out_even = {
|
|||
static const struct alpha_pll_config camcc_pll2_config = {
|
||||
.l = 0x64,
|
||||
.alpha = 0x0,
|
||||
.post_div_val = 0x3 << 8,
|
||||
.post_div_mask = 0x3 << 8,
|
||||
.aux_output_mask = BIT(1),
|
||||
.main_output_mask = BIT(0),
|
||||
.early_output_mask = BIT(3),
|
||||
.config_ctl_val = 0x20000800,
|
||||
.config_ctl_hi_val = 0x400003d2,
|
||||
.test_ctl_val = 0x04000400,
|
||||
.test_ctl_hi_val = 0x00004000,
|
||||
.user_ctl_val = 0x0000030b,
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll camcc_pll2 = {
|
||||
|
|
@ -1693,6 +1689,8 @@ static struct clk_branch camcc_sys_tmr_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct gdsc titan_top_gdsc;
|
||||
|
||||
static struct gdsc bps_gdsc = {
|
||||
.gdscr = 0x6004,
|
||||
.en_rest_wait_val = 0x2,
|
||||
|
|
@ -1702,6 +1700,7 @@ static struct gdsc bps_gdsc = {
|
|||
.name = "bps_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.parent = &titan_top_gdsc.pd,
|
||||
.flags = VOTABLE,
|
||||
};
|
||||
|
||||
|
|
@ -1714,6 +1713,7 @@ static struct gdsc ipe_0_gdsc = {
|
|||
.name = "ipe_0_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.parent = &titan_top_gdsc.pd,
|
||||
.flags = VOTABLE,
|
||||
};
|
||||
|
||||
|
|
@ -1726,6 +1726,7 @@ static struct gdsc ife_0_gdsc = {
|
|||
.name = "ife_0_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.parent = &titan_top_gdsc.pd,
|
||||
};
|
||||
|
||||
static struct gdsc ife_1_gdsc = {
|
||||
|
|
@ -1737,6 +1738,7 @@ static struct gdsc ife_1_gdsc = {
|
|||
.name = "ife_1_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.parent = &titan_top_gdsc.pd,
|
||||
};
|
||||
|
||||
static struct gdsc ife_2_gdsc = {
|
||||
|
|
@ -1748,6 +1750,7 @@ static struct gdsc ife_2_gdsc = {
|
|||
.name = "ife_2_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.parent = &titan_top_gdsc.pd,
|
||||
};
|
||||
|
||||
static struct gdsc titan_top_gdsc = {
|
||||
|
|
|
|||
|
|
@ -139,13 +139,9 @@ static struct clk_fixed_factor camcc_pll1_out_even = {
|
|||
/* 1920MHz configuration */
|
||||
static const struct alpha_pll_config camcc_pll2_config = {
|
||||
.l = 0x64,
|
||||
.post_div_val = 0x3 << 8,
|
||||
.post_div_mask = 0x3 << 8,
|
||||
.early_output_mask = BIT(3),
|
||||
.aux_output_mask = BIT(1),
|
||||
.main_output_mask = BIT(0),
|
||||
.config_ctl_hi_val = 0x400003d6,
|
||||
.config_ctl_val = 0x20000954,
|
||||
.user_ctl_val = 0x0000030b,
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll camcc_pll2 = {
|
||||
|
|
@ -1846,6 +1842,7 @@ static struct gdsc camcc_bps_gdsc = {
|
|||
.name = "camcc_bps_gdsc",
|
||||
},
|
||||
.flags = HW_CTRL | POLL_CFG_GDSCR,
|
||||
.parent = &camcc_titan_top_gdsc.pd,
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
|
|
@ -1875,6 +1872,7 @@ static struct gdsc camcc_ipe_0_gdsc = {
|
|||
.name = "camcc_ipe_0_gdsc",
|
||||
},
|
||||
.flags = HW_CTRL | POLL_CFG_GDSCR,
|
||||
.parent = &camcc_titan_top_gdsc.pd,
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
|
|
@ -1884,6 +1882,7 @@ static struct gdsc camcc_ipe_1_gdsc = {
|
|||
.name = "camcc_ipe_1_gdsc",
|
||||
},
|
||||
.flags = HW_CTRL | POLL_CFG_GDSCR,
|
||||
.parent = &camcc_titan_top_gdsc.pd,
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
|
|
@ -1896,7 +1895,7 @@ static struct gdsc camcc_titan_top_gdsc = {
|
|||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
struct clk_hw *camcc_sm7150_hws[] = {
|
||||
static struct clk_hw *camcc_sm7150_hws[] = {
|
||||
[CAMCC_PLL0_OUT_EVEN] = &camcc_pll0_out_even.hw,
|
||||
[CAMCC_PLL0_OUT_ODD] = &camcc_pll0_out_odd.hw,
|
||||
[CAMCC_PLL1_OUT_EVEN] = &camcc_pll1_out_even.hw,
|
||||
|
|
|
|||
|
|
@ -2213,6 +2213,7 @@ static struct gdsc bps_gdsc = {
|
|||
.name = "bps_gdsc",
|
||||
},
|
||||
.flags = HW_CTRL | POLL_CFG_GDSCR,
|
||||
.parent = &titan_top_gdsc.pd,
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
|
|
@ -2222,6 +2223,7 @@ static struct gdsc ipe_0_gdsc = {
|
|||
.name = "ipe_0_gdsc",
|
||||
},
|
||||
.flags = HW_CTRL | POLL_CFG_GDSCR,
|
||||
.parent = &titan_top_gdsc.pd,
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
|
|
@ -2231,6 +2233,7 @@ static struct gdsc sbi_gdsc = {
|
|||
.name = "sbi_gdsc",
|
||||
},
|
||||
.flags = HW_CTRL | POLL_CFG_GDSCR,
|
||||
.parent = &titan_top_gdsc.pd,
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2935,6 +2935,7 @@ static struct gdsc bps_gdsc = {
|
|||
.name = "bps_gdsc",
|
||||
},
|
||||
.flags = HW_CTRL | POLL_CFG_GDSCR,
|
||||
.parent = &titan_top_gdsc.pd,
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
|
|
@ -2944,6 +2945,7 @@ static struct gdsc ipe_0_gdsc = {
|
|||
.name = "ipe_0_gdsc",
|
||||
},
|
||||
.flags = HW_CTRL | POLL_CFG_GDSCR,
|
||||
.parent = &titan_top_gdsc.pd,
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
|
|
@ -2953,6 +2955,7 @@ static struct gdsc sbi_gdsc = {
|
|||
.name = "sbi_gdsc",
|
||||
},
|
||||
.flags = POLL_CFG_GDSCR,
|
||||
.parent = &titan_top_gdsc.pd,
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -3204,6 +3204,8 @@ static struct clk_branch cam_cc_sfe_1_fast_ahb_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct gdsc cam_cc_titan_top_gdsc;
|
||||
|
||||
static struct gdsc cam_cc_bps_gdsc = {
|
||||
.gdscr = 0x10004,
|
||||
.en_rest_wait_val = 0x2,
|
||||
|
|
@ -3213,6 +3215,7 @@ static struct gdsc cam_cc_bps_gdsc = {
|
|||
.name = "cam_cc_bps_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.parent = &cam_cc_titan_top_gdsc.pd,
|
||||
.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
|
||||
};
|
||||
|
||||
|
|
@ -3225,6 +3228,7 @@ static struct gdsc cam_cc_ife_0_gdsc = {
|
|||
.name = "cam_cc_ife_0_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.parent = &cam_cc_titan_top_gdsc.pd,
|
||||
.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
|
||||
};
|
||||
|
||||
|
|
@ -3237,6 +3241,7 @@ static struct gdsc cam_cc_ife_1_gdsc = {
|
|||
.name = "cam_cc_ife_1_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.parent = &cam_cc_titan_top_gdsc.pd,
|
||||
.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
|
||||
};
|
||||
|
||||
|
|
@ -3249,6 +3254,7 @@ static struct gdsc cam_cc_ife_2_gdsc = {
|
|||
.name = "cam_cc_ife_2_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.parent = &cam_cc_titan_top_gdsc.pd,
|
||||
.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
|
||||
};
|
||||
|
||||
|
|
@ -3261,6 +3267,7 @@ static struct gdsc cam_cc_ipe_0_gdsc = {
|
|||
.name = "cam_cc_ipe_0_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.parent = &cam_cc_titan_top_gdsc.pd,
|
||||
.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
|
||||
};
|
||||
|
||||
|
|
@ -3273,6 +3280,7 @@ static struct gdsc cam_cc_sbi_gdsc = {
|
|||
.name = "cam_cc_sbi_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.parent = &cam_cc_titan_top_gdsc.pd,
|
||||
.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
|
||||
};
|
||||
|
||||
|
|
@ -3285,6 +3293,7 @@ static struct gdsc cam_cc_sfe_0_gdsc = {
|
|||
.name = "cam_cc_sfe_0_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.parent = &cam_cc_titan_top_gdsc.pd,
|
||||
.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
|
||||
};
|
||||
|
||||
|
|
@ -3297,6 +3306,7 @@ static struct gdsc cam_cc_sfe_1_gdsc = {
|
|||
.name = "cam_cc_sfe_1_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.parent = &cam_cc_titan_top_gdsc.pd,
|
||||
.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -142,8 +142,8 @@ static int clk_branch2_mem_enable(struct clk_hw *hw)
|
|||
u32 val;
|
||||
int ret;
|
||||
|
||||
regmap_update_bits(branch.clkr.regmap, mem_br->mem_enable_reg,
|
||||
mem_br->mem_enable_ack_mask, mem_br->mem_enable_ack_mask);
|
||||
regmap_assign_bits(branch.clkr.regmap, mem_br->mem_enable_reg,
|
||||
mem_br->mem_enable_mask, !mem_br->mem_enable_invert);
|
||||
|
||||
ret = regmap_read_poll_timeout(branch.clkr.regmap, mem_br->mem_ack_reg,
|
||||
val, val & mem_br->mem_enable_ack_mask, 0, 200);
|
||||
|
|
@ -159,8 +159,8 @@ static void clk_branch2_mem_disable(struct clk_hw *hw)
|
|||
{
|
||||
struct clk_mem_branch *mem_br = to_clk_mem_branch(hw);
|
||||
|
||||
regmap_update_bits(mem_br->branch.clkr.regmap, mem_br->mem_enable_reg,
|
||||
mem_br->mem_enable_ack_mask, 0);
|
||||
regmap_assign_bits(mem_br->branch.clkr.regmap, mem_br->mem_enable_reg,
|
||||
mem_br->mem_enable_mask, mem_br->mem_enable_invert);
|
||||
|
||||
return clk_branch2_disable(hw);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -44,6 +44,8 @@ struct clk_branch {
|
|||
* @mem_enable_reg: branch clock memory gating register
|
||||
* @mem_ack_reg: branch clock memory ack register
|
||||
* @mem_enable_ack_mask: branch clock memory enable and ack field in @mem_ack_reg
|
||||
* @mem_enable_mask: branch clock memory enable mask
|
||||
* @mem_enable_invert: branch clock memory enable and disable has invert logic
|
||||
* @branch: branch clock gating handle
|
||||
*
|
||||
* Clock which can gate its memories.
|
||||
|
|
@ -52,6 +54,8 @@ struct clk_mem_branch {
|
|||
u32 mem_enable_reg;
|
||||
u32 mem_ack_reg;
|
||||
u32 mem_enable_ack_mask;
|
||||
u32 mem_enable_mask;
|
||||
bool mem_enable_invert;
|
||||
struct clk_branch branch;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -855,6 +855,7 @@ static struct clk_hw *qcs615_rpmh_clocks[] = {
|
|||
[RPMH_RF_CLK1_A] = &clk_rpmh_rf_clk1_a_ao.hw,
|
||||
[RPMH_RF_CLK2] = &clk_rpmh_rf_clk2_a.hw,
|
||||
[RPMH_RF_CLK2_A] = &clk_rpmh_rf_clk2_a_ao.hw,
|
||||
[RPMH_IPA_CLK] = &clk_rpmh_ipa.hw,
|
||||
};
|
||||
|
||||
static const struct clk_rpmh_desc clk_rpmh_qcs615 = {
|
||||
|
|
|
|||
|
|
@ -679,6 +679,11 @@ static struct clk_branch disp_cc_xo_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static const struct qcom_reset_map disp_cc_sm6350_resets[] = {
|
||||
[DISP_CC_MDSS_CORE_BCR] = { 0x1000 },
|
||||
[DISP_CC_MDSS_RSCC_BCR] = { 0x2000 },
|
||||
};
|
||||
|
||||
static struct gdsc mdss_gdsc = {
|
||||
.gdscr = 0x1004,
|
||||
.en_rest_wait_val = 0x2,
|
||||
|
|
@ -746,6 +751,8 @@ static const struct qcom_cc_desc disp_cc_sm6350_desc = {
|
|||
.num_clks = ARRAY_SIZE(disp_cc_sm6350_clocks),
|
||||
.gdscs = disp_cc_sm6350_gdscs,
|
||||
.num_gdscs = ARRAY_SIZE(disp_cc_sm6350_gdscs),
|
||||
.resets = disp_cc_sm6350_resets,
|
||||
.num_resets = ARRAY_SIZE(disp_cc_sm6350_resets),
|
||||
};
|
||||
|
||||
static const struct of_device_id disp_cc_sm6350_match_table[] = {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include "clk-regmap-divider.h"
|
||||
#include "common.h"
|
||||
#include "gdsc.h"
|
||||
#include "reset.h"
|
||||
|
||||
enum {
|
||||
DT_BI_TCXO,
|
||||
|
|
@ -356,7 +357,7 @@ static struct clk_rcg2 dispcc_mdss_pclk0_clk_src = {
|
|||
.name = "dispcc_mdss_pclk0_clk_src",
|
||||
.parent_data = dispcc_parent_data_4,
|
||||
.num_parents = ARRAY_SIZE(dispcc_parent_data_4),
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
|
||||
.ops = &clk_pixel_ops,
|
||||
},
|
||||
};
|
||||
|
|
@ -951,6 +952,10 @@ static struct gdsc *dispcc_sm7150_gdscs[] = {
|
|||
[MDSS_GDSC] = &mdss_gdsc,
|
||||
};
|
||||
|
||||
static const struct qcom_reset_map dispcc_sm7150_resets[] = {
|
||||
[DISPCC_MDSS_CORE_BCR] = { 0x2000 },
|
||||
};
|
||||
|
||||
static const struct regmap_config dispcc_sm7150_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
|
|
@ -965,6 +970,8 @@ static const struct qcom_cc_desc dispcc_sm7150_desc = {
|
|||
.num_clks = ARRAY_SIZE(dispcc_sm7150_clocks),
|
||||
.gdscs = dispcc_sm7150_gdscs,
|
||||
.num_gdscs = ARRAY_SIZE(dispcc_sm7150_gdscs),
|
||||
.resets = dispcc_sm7150_resets,
|
||||
.num_resets = ARRAY_SIZE(dispcc_sm7150_resets),
|
||||
};
|
||||
|
||||
static const struct of_device_id dispcc_sm7150_match_table[] = {
|
||||
|
|
|
|||
|
|
@ -1618,6 +1618,9 @@ static struct clk_regmap *disp_cc_x1e80100_clocks[] = {
|
|||
|
||||
static const struct qcom_reset_map disp_cc_x1e80100_resets[] = {
|
||||
[DISP_CC_MDSS_CORE_BCR] = { 0x8000 },
|
||||
[DISP_CC_MDSS_DPTX0_USB_ROUTER_LINK_INTF_CLK_ARES] = { .reg = 0x8044, .bit = 2 },
|
||||
[DISP_CC_MDSS_DPTX1_USB_ROUTER_LINK_INTF_CLK_ARES] = { .reg = 0x8068, .bit = 2 },
|
||||
[DISP_CC_MDSS_DPTX2_USB_ROUTER_LINK_INTF_CLK_ARES] = { .reg = 0x8088, .bit = 2 },
|
||||
[DISP_CC_MDSS_CORE_INT2_BCR] = { 0xa000 },
|
||||
[DISP_CC_MDSS_RSCC_BCR] = { 0xc000 },
|
||||
};
|
||||
|
|
|
|||
|
|
@ -920,6 +920,7 @@ static struct clk_branch ecpri_cc_eth_100g_c2c1_udp_fifo_clk = {
|
|||
static struct clk_mem_branch ecpri_cc_eth_100g_c2c_0_hm_ff_0_clk = {
|
||||
.mem_enable_reg = 0x8410,
|
||||
.mem_ack_reg = 0x8424,
|
||||
.mem_enable_mask = BIT(0),
|
||||
.mem_enable_ack_mask = BIT(0),
|
||||
.branch = {
|
||||
.halt_reg = 0x80b4,
|
||||
|
|
@ -943,6 +944,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_c2c_0_hm_ff_0_clk = {
|
|||
static struct clk_mem_branch ecpri_cc_eth_100g_c2c_0_hm_ff_1_clk = {
|
||||
.mem_enable_reg = 0x8410,
|
||||
.mem_ack_reg = 0x8424,
|
||||
.mem_enable_mask = BIT(1),
|
||||
.mem_enable_ack_mask = BIT(1),
|
||||
.branch = {
|
||||
.halt_reg = 0x80bc,
|
||||
|
|
@ -966,6 +968,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_c2c_0_hm_ff_1_clk = {
|
|||
static struct clk_mem_branch ecpri_cc_eth_100g_c2c_hm_macsec_clk = {
|
||||
.mem_enable_reg = 0x8410,
|
||||
.mem_ack_reg = 0x8424,
|
||||
.mem_enable_mask = BIT(4),
|
||||
.mem_enable_ack_mask = BIT(4),
|
||||
.branch = {
|
||||
.halt_reg = 0x80ac,
|
||||
|
|
@ -989,6 +992,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_c2c_hm_macsec_clk = {
|
|||
static struct clk_mem_branch ecpri_cc_eth_100g_dbg_c2c_hm_ff_0_clk = {
|
||||
.mem_enable_reg = 0x8414,
|
||||
.mem_ack_reg = 0x8428,
|
||||
.mem_enable_mask = BIT(0),
|
||||
.mem_enable_ack_mask = BIT(0),
|
||||
.branch = {
|
||||
.halt_reg = 0x80d8,
|
||||
|
|
@ -1012,6 +1016,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_dbg_c2c_hm_ff_0_clk = {
|
|||
static struct clk_mem_branch ecpri_cc_eth_100g_dbg_c2c_hm_ff_1_clk = {
|
||||
.mem_enable_reg = 0x8414,
|
||||
.mem_ack_reg = 0x8428,
|
||||
.mem_enable_mask = BIT(1),
|
||||
.mem_enable_ack_mask = BIT(1),
|
||||
.branch = {
|
||||
.halt_reg = 0x80e0,
|
||||
|
|
@ -1053,6 +1058,7 @@ static struct clk_branch ecpri_cc_eth_100g_dbg_c2c_udp_fifo_clk = {
|
|||
static struct clk_mem_branch ecpri_cc_eth_100g_fh_0_hm_ff_0_clk = {
|
||||
.mem_enable_reg = 0x8404,
|
||||
.mem_ack_reg = 0x8418,
|
||||
.mem_enable_mask = BIT(0),
|
||||
.mem_enable_ack_mask = BIT(0),
|
||||
.branch = {
|
||||
.halt_reg = 0x800c,
|
||||
|
|
@ -1076,6 +1082,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_0_hm_ff_0_clk = {
|
|||
static struct clk_mem_branch ecpri_cc_eth_100g_fh_0_hm_ff_1_clk = {
|
||||
.mem_enable_reg = 0x8404,
|
||||
.mem_ack_reg = 0x8418,
|
||||
.mem_enable_mask = BIT(1),
|
||||
.mem_enable_ack_mask = BIT(1),
|
||||
.branch = {
|
||||
.halt_reg = 0x8014,
|
||||
|
|
@ -1099,6 +1106,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_0_hm_ff_1_clk = {
|
|||
static struct clk_mem_branch ecpri_cc_eth_100g_fh_0_hm_ff_2_clk = {
|
||||
.mem_enable_reg = 0x8404,
|
||||
.mem_ack_reg = 0x8418,
|
||||
.mem_enable_mask = BIT(2),
|
||||
.mem_enable_ack_mask = BIT(2),
|
||||
.branch = {
|
||||
.halt_reg = 0x801c,
|
||||
|
|
@ -1122,6 +1130,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_0_hm_ff_2_clk = {
|
|||
static struct clk_mem_branch ecpri_cc_eth_100g_fh_0_hm_ff_3_clk = {
|
||||
.mem_enable_reg = 0x8404,
|
||||
.mem_ack_reg = 0x8418,
|
||||
.mem_enable_mask = BIT(3),
|
||||
.mem_enable_ack_mask = BIT(3),
|
||||
.branch = {
|
||||
.halt_reg = 0x8024,
|
||||
|
|
@ -1163,6 +1172,7 @@ static struct clk_branch ecpri_cc_eth_100g_fh_0_udp_fifo_clk = {
|
|||
static struct clk_mem_branch ecpri_cc_eth_100g_fh_1_hm_ff_0_clk = {
|
||||
.mem_enable_reg = 0x8408,
|
||||
.mem_ack_reg = 0x841c,
|
||||
.mem_enable_mask = BIT(0),
|
||||
.mem_enable_ack_mask = BIT(0),
|
||||
.branch = {
|
||||
.halt_reg = 0x8044,
|
||||
|
|
@ -1186,6 +1196,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_1_hm_ff_0_clk = {
|
|||
static struct clk_mem_branch ecpri_cc_eth_100g_fh_1_hm_ff_1_clk = {
|
||||
.mem_enable_reg = 0x8408,
|
||||
.mem_ack_reg = 0x841c,
|
||||
.mem_enable_mask = BIT(1),
|
||||
.mem_enable_ack_mask = BIT(1),
|
||||
.branch = {
|
||||
.halt_reg = 0x804c,
|
||||
|
|
@ -1209,6 +1220,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_1_hm_ff_1_clk = {
|
|||
static struct clk_mem_branch ecpri_cc_eth_100g_fh_1_hm_ff_2_clk = {
|
||||
.mem_enable_reg = 0x8408,
|
||||
.mem_ack_reg = 0x841c,
|
||||
.mem_enable_mask = BIT(2),
|
||||
.mem_enable_ack_mask = BIT(2),
|
||||
.branch = {
|
||||
.halt_reg = 0x8054,
|
||||
|
|
@ -1232,6 +1244,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_1_hm_ff_2_clk = {
|
|||
static struct clk_mem_branch ecpri_cc_eth_100g_fh_1_hm_ff_3_clk = {
|
||||
.mem_enable_reg = 0x8408,
|
||||
.mem_ack_reg = 0x841c,
|
||||
.mem_enable_mask = BIT(3),
|
||||
.mem_enable_ack_mask = BIT(3),
|
||||
.branch = {
|
||||
.halt_reg = 0x805c,
|
||||
|
|
@ -1273,6 +1286,7 @@ static struct clk_branch ecpri_cc_eth_100g_fh_1_udp_fifo_clk = {
|
|||
static struct clk_mem_branch ecpri_cc_eth_100g_fh_2_hm_ff_0_clk = {
|
||||
.mem_enable_reg = 0x840c,
|
||||
.mem_ack_reg = 0x8420,
|
||||
.mem_enable_mask = BIT(0),
|
||||
.mem_enable_ack_mask = BIT(0),
|
||||
.branch = {
|
||||
.halt_reg = 0x807c,
|
||||
|
|
@ -1296,6 +1310,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_2_hm_ff_0_clk = {
|
|||
static struct clk_mem_branch ecpri_cc_eth_100g_fh_2_hm_ff_1_clk = {
|
||||
.mem_enable_reg = 0x840c,
|
||||
.mem_ack_reg = 0x8420,
|
||||
.mem_enable_mask = BIT(1),
|
||||
.mem_enable_ack_mask = BIT(1),
|
||||
.branch = {
|
||||
.halt_reg = 0x8084,
|
||||
|
|
@ -1319,6 +1334,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_2_hm_ff_1_clk = {
|
|||
static struct clk_mem_branch ecpri_cc_eth_100g_fh_2_hm_ff_2_clk = {
|
||||
.mem_enable_reg = 0x840c,
|
||||
.mem_ack_reg = 0x8420,
|
||||
.mem_enable_mask = BIT(2),
|
||||
.mem_enable_ack_mask = BIT(2),
|
||||
.branch = {
|
||||
.halt_reg = 0x808c,
|
||||
|
|
@ -1342,6 +1358,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_2_hm_ff_2_clk = {
|
|||
static struct clk_mem_branch ecpri_cc_eth_100g_fh_2_hm_ff_3_clk = {
|
||||
.mem_enable_reg = 0x840c,
|
||||
.mem_ack_reg = 0x8420,
|
||||
.mem_enable_mask = BIT(3),
|
||||
.mem_enable_ack_mask = BIT(3),
|
||||
.branch = {
|
||||
.halt_reg = 0x8094,
|
||||
|
|
@ -1383,6 +1400,7 @@ static struct clk_branch ecpri_cc_eth_100g_fh_2_udp_fifo_clk = {
|
|||
static struct clk_mem_branch ecpri_cc_eth_100g_fh_macsec_0_clk = {
|
||||
.mem_enable_reg = 0x8404,
|
||||
.mem_ack_reg = 0x8418,
|
||||
.mem_enable_mask = BIT(4),
|
||||
.mem_enable_ack_mask = BIT(4),
|
||||
.branch = {
|
||||
.halt_reg = 0x8004,
|
||||
|
|
@ -1406,6 +1424,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_macsec_0_clk = {
|
|||
static struct clk_mem_branch ecpri_cc_eth_100g_fh_macsec_1_clk = {
|
||||
.mem_enable_reg = 0x8408,
|
||||
.mem_ack_reg = 0x841c,
|
||||
.mem_enable_mask = BIT(4),
|
||||
.mem_enable_ack_mask = BIT(4),
|
||||
.branch = {
|
||||
.halt_reg = 0x803c,
|
||||
|
|
@ -1429,6 +1448,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_macsec_1_clk = {
|
|||
static struct clk_mem_branch ecpri_cc_eth_100g_fh_macsec_2_clk = {
|
||||
.mem_enable_reg = 0x840c,
|
||||
.mem_ack_reg = 0x8420,
|
||||
.mem_enable_mask = BIT(4),
|
||||
.mem_enable_ack_mask = BIT(4),
|
||||
.branch = {
|
||||
.halt_reg = 0x8074,
|
||||
|
|
@ -1452,6 +1472,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_fh_macsec_2_clk = {
|
|||
static struct clk_mem_branch ecpri_cc_eth_100g_mac_c2c_hm_ref_clk = {
|
||||
.mem_enable_reg = 0x8410,
|
||||
.mem_ack_reg = 0x8424,
|
||||
.mem_enable_mask = BIT(5),
|
||||
.mem_enable_ack_mask = BIT(5),
|
||||
.branch = {
|
||||
.halt_reg = 0x80c4,
|
||||
|
|
@ -1475,6 +1496,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_mac_c2c_hm_ref_clk = {
|
|||
static struct clk_mem_branch ecpri_cc_eth_100g_mac_dbg_c2c_hm_ref_clk = {
|
||||
.mem_enable_reg = 0x8414,
|
||||
.mem_ack_reg = 0x8428,
|
||||
.mem_enable_mask = BIT(5),
|
||||
.mem_enable_ack_mask = BIT(5),
|
||||
.branch = {
|
||||
.halt_reg = 0x80e8,
|
||||
|
|
@ -1498,6 +1520,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_mac_dbg_c2c_hm_ref_clk = {
|
|||
static struct clk_mem_branch ecpri_cc_eth_100g_mac_fh0_hm_ref_clk = {
|
||||
.mem_enable_reg = 0x8404,
|
||||
.mem_ack_reg = 0x8418,
|
||||
.mem_enable_mask = BIT(5),
|
||||
.mem_enable_ack_mask = BIT(5),
|
||||
.branch = {
|
||||
.halt_reg = 0x802c,
|
||||
|
|
@ -1521,6 +1544,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_mac_fh0_hm_ref_clk = {
|
|||
static struct clk_mem_branch ecpri_cc_eth_100g_mac_fh1_hm_ref_clk = {
|
||||
.mem_enable_reg = 0x8408,
|
||||
.mem_ack_reg = 0x841c,
|
||||
.mem_enable_mask = BIT(5),
|
||||
.mem_enable_ack_mask = BIT(5),
|
||||
.branch = {
|
||||
.halt_reg = 0x8064,
|
||||
|
|
@ -1544,6 +1568,7 @@ static struct clk_mem_branch ecpri_cc_eth_100g_mac_fh1_hm_ref_clk = {
|
|||
static struct clk_mem_branch ecpri_cc_eth_100g_mac_fh2_hm_ref_clk = {
|
||||
.mem_enable_reg = 0x840c,
|
||||
.mem_ack_reg = 0x8420,
|
||||
.mem_enable_mask = BIT(5),
|
||||
.mem_enable_ack_mask = BIT(5),
|
||||
.branch = {
|
||||
.halt_reg = 0x809c,
|
||||
|
|
@ -1603,6 +1628,7 @@ static struct clk_branch ecpri_cc_eth_dbg_noc_axi_clk = {
|
|||
static struct clk_mem_branch ecpri_cc_eth_phy_0_ock_sram_clk = {
|
||||
.mem_enable_reg = 0x8404,
|
||||
.mem_ack_reg = 0x8418,
|
||||
.mem_enable_mask = BIT(6),
|
||||
.mem_enable_ack_mask = BIT(6),
|
||||
.branch = {
|
||||
.halt_reg = 0xd140,
|
||||
|
|
@ -1621,6 +1647,7 @@ static struct clk_mem_branch ecpri_cc_eth_phy_0_ock_sram_clk = {
|
|||
static struct clk_mem_branch ecpri_cc_eth_phy_1_ock_sram_clk = {
|
||||
.mem_enable_reg = 0x8408,
|
||||
.mem_ack_reg = 0x841C,
|
||||
.mem_enable_mask = BIT(6),
|
||||
.mem_enable_ack_mask = BIT(6),
|
||||
.branch = {
|
||||
.halt_reg = 0xd148,
|
||||
|
|
@ -1639,6 +1666,7 @@ static struct clk_mem_branch ecpri_cc_eth_phy_1_ock_sram_clk = {
|
|||
static struct clk_mem_branch ecpri_cc_eth_phy_2_ock_sram_clk = {
|
||||
.mem_enable_reg = 0x840c,
|
||||
.mem_ack_reg = 0x8420,
|
||||
.mem_enable_mask = BIT(6),
|
||||
.mem_enable_ack_mask = BIT(6),
|
||||
.branch = {
|
||||
.halt_reg = 0xd150,
|
||||
|
|
@ -1657,6 +1685,7 @@ static struct clk_mem_branch ecpri_cc_eth_phy_2_ock_sram_clk = {
|
|||
static struct clk_mem_branch ecpri_cc_eth_phy_3_ock_sram_clk = {
|
||||
.mem_enable_reg = 0x8410,
|
||||
.mem_ack_reg = 0x8424,
|
||||
.mem_enable_mask = BIT(6),
|
||||
.mem_enable_ack_mask = BIT(6),
|
||||
.branch = {
|
||||
.halt_reg = 0xd158,
|
||||
|
|
@ -1675,6 +1704,7 @@ static struct clk_mem_branch ecpri_cc_eth_phy_3_ock_sram_clk = {
|
|||
static struct clk_mem_branch ecpri_cc_eth_phy_4_ock_sram_clk = {
|
||||
.mem_enable_reg = 0x8414,
|
||||
.mem_ack_reg = 0x8428,
|
||||
.mem_enable_mask = BIT(6),
|
||||
.mem_enable_ack_mask = BIT(6),
|
||||
.branch = {
|
||||
.halt_reg = 0xd160,
|
||||
|
|
|
|||
|
|
@ -2643,7 +2643,6 @@ static struct clk_rcg2 gcc_usb3_tert_phy_aux_clk_src = {
|
|||
};
|
||||
|
||||
static const struct freq_tbl ftbl_gcc_usb4_0_master_clk_src[] = {
|
||||
F(85714286, P_GCC_GPLL0_OUT_EVEN, 3.5, 0, 0),
|
||||
F(177666750, P_GCC_GPLL8_OUT_MAIN, 4, 0, 0),
|
||||
F(355333500, P_GCC_GPLL8_OUT_MAIN, 2, 0, 0),
|
||||
{ }
|
||||
|
|
@ -6760,7 +6759,7 @@ static struct clk_branch gcc_usb3_prim_phy_com_aux_clk = {
|
|||
|
||||
static struct clk_branch gcc_usb3_prim_phy_pipe_clk = {
|
||||
.halt_reg = 0x3f088,
|
||||
.halt_check = BRANCH_HALT_DELAY,
|
||||
.halt_check = BRANCH_HALT_SKIP,
|
||||
.hwcg_reg = 0x3f088,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
|
|
@ -6816,7 +6815,7 @@ static struct clk_branch gcc_usb3_sec_phy_com_aux_clk = {
|
|||
|
||||
static struct clk_branch gcc_usb3_sec_phy_pipe_clk = {
|
||||
.halt_reg = 0xe2078,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.halt_check = BRANCH_HALT_SKIP,
|
||||
.hwcg_reg = 0xe2078,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
|
|
@ -6872,7 +6871,7 @@ static struct clk_branch gcc_usb3_tert_phy_com_aux_clk = {
|
|||
|
||||
static struct clk_branch gcc_usb3_tert_phy_pipe_clk = {
|
||||
.halt_reg = 0xe1078,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.halt_check = BRANCH_HALT_SKIP,
|
||||
.hwcg_reg = 0xe1078,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
|
|
@ -6961,7 +6960,7 @@ static struct clk_branch gcc_usb4_0_master_clk = {
|
|||
|
||||
static struct clk_branch gcc_usb4_0_phy_p2rr2p_pipe_clk = {
|
||||
.halt_reg = 0x2b0f4,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.halt_check = BRANCH_HALT_SKIP,
|
||||
.clkr = {
|
||||
.enable_reg = 0x2b0f4,
|
||||
.enable_mask = BIT(0),
|
||||
|
|
@ -6979,7 +6978,7 @@ static struct clk_branch gcc_usb4_0_phy_p2rr2p_pipe_clk = {
|
|||
|
||||
static struct clk_branch gcc_usb4_0_phy_pcie_pipe_clk = {
|
||||
.halt_reg = 0x2b04c,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.halt_check = BRANCH_HALT_SKIP,
|
||||
.clkr = {
|
||||
.enable_reg = 0x62010,
|
||||
.enable_mask = BIT(11),
|
||||
|
|
@ -7033,7 +7032,7 @@ static struct clk_branch gcc_usb4_0_phy_rx1_clk = {
|
|||
|
||||
static struct clk_branch gcc_usb4_0_phy_usb_pipe_clk = {
|
||||
.halt_reg = 0x2b0bc,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.halt_check = BRANCH_HALT_SKIP,
|
||||
.hwcg_reg = 0x2b0bc,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
|
|
@ -7196,7 +7195,7 @@ static struct clk_branch gcc_usb4_1_master_clk = {
|
|||
|
||||
static struct clk_branch gcc_usb4_1_phy_p2rr2p_pipe_clk = {
|
||||
.halt_reg = 0x2d118,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.halt_check = BRANCH_HALT_SKIP,
|
||||
.clkr = {
|
||||
.enable_reg = 0x2d118,
|
||||
.enable_mask = BIT(0),
|
||||
|
|
@ -7214,7 +7213,7 @@ static struct clk_branch gcc_usb4_1_phy_p2rr2p_pipe_clk = {
|
|||
|
||||
static struct clk_branch gcc_usb4_1_phy_pcie_pipe_clk = {
|
||||
.halt_reg = 0x2d04c,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.halt_check = BRANCH_HALT_SKIP,
|
||||
.clkr = {
|
||||
.enable_reg = 0x62010,
|
||||
.enable_mask = BIT(12),
|
||||
|
|
@ -7268,7 +7267,7 @@ static struct clk_branch gcc_usb4_1_phy_rx1_clk = {
|
|||
|
||||
static struct clk_branch gcc_usb4_1_phy_usb_pipe_clk = {
|
||||
.halt_reg = 0x2d0e0,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.halt_check = BRANCH_HALT_SKIP,
|
||||
.hwcg_reg = 0x2d0e0,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
|
|
@ -7431,7 +7430,7 @@ static struct clk_branch gcc_usb4_2_master_clk = {
|
|||
|
||||
static struct clk_branch gcc_usb4_2_phy_p2rr2p_pipe_clk = {
|
||||
.halt_reg = 0xe00f8,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.halt_check = BRANCH_HALT_SKIP,
|
||||
.clkr = {
|
||||
.enable_reg = 0xe00f8,
|
||||
.enable_mask = BIT(0),
|
||||
|
|
@ -7449,7 +7448,7 @@ static struct clk_branch gcc_usb4_2_phy_p2rr2p_pipe_clk = {
|
|||
|
||||
static struct clk_branch gcc_usb4_2_phy_pcie_pipe_clk = {
|
||||
.halt_reg = 0xe004c,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.halt_check = BRANCH_HALT_SKIP,
|
||||
.clkr = {
|
||||
.enable_reg = 0x62010,
|
||||
.enable_mask = BIT(13),
|
||||
|
|
@ -7503,7 +7502,7 @@ static struct clk_branch gcc_usb4_2_phy_rx1_clk = {
|
|||
|
||||
static struct clk_branch gcc_usb4_2_phy_usb_pipe_clk = {
|
||||
.halt_reg = 0xe00c0,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.halt_check = BRANCH_HALT_SKIP,
|
||||
.hwcg_reg = 0xe00c0,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2018,2020 The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved.
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
|
|
@ -79,6 +79,20 @@ static struct clk_fixed_factor gpll0_div2 = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll_postdiv gpll0_out_aux = {
|
||||
.offset = 0x20000,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
|
||||
.width = 4,
|
||||
.clkr.hw.init = &(const struct clk_init_data) {
|
||||
.name = "gpll0_out_aux",
|
||||
.parent_hws = (const struct clk_hw *[]) {
|
||||
&gpll0.clkr.hw
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_postdiv_ro_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll gpll2 = {
|
||||
.offset = 0x21000,
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_NSS_HUAYRA],
|
||||
|
|
@ -2934,6 +2948,7 @@ static struct clk_regmap *gcc_ipq5424_clocks[] = {
|
|||
[GPLL2] = &gpll2.clkr,
|
||||
[GPLL2_OUT_MAIN] = &gpll2_out_main.clkr,
|
||||
[GPLL4] = &gpll4.clkr,
|
||||
[GPLL0_OUT_AUX] = &gpll0_out_aux.clkr,
|
||||
};
|
||||
|
||||
static const struct qcom_reset_map gcc_ipq5424_resets[] = {
|
||||
|
|
@ -3250,6 +3265,16 @@ static const struct qcom_icc_hws_data icc_ipq5424_hws[] = {
|
|||
{ MASTER_ANOC_PCIE3, SLAVE_ANOC_PCIE3, GCC_ANOC_PCIE3_2LANE_M_CLK },
|
||||
{ MASTER_CNOC_PCIE3, SLAVE_CNOC_PCIE3, GCC_CNOC_PCIE3_2LANE_S_CLK },
|
||||
{ MASTER_CNOC_USB, SLAVE_CNOC_USB, GCC_CNOC_USB_CLK },
|
||||
{ MASTER_NSSNOC_NSSCC, SLAVE_NSSNOC_NSSCC, GCC_NSSNOC_NSSCC_CLK },
|
||||
{ MASTER_NSSNOC_SNOC_0, SLAVE_NSSNOC_SNOC_0, GCC_NSSNOC_SNOC_CLK },
|
||||
{ MASTER_NSSNOC_SNOC_1, SLAVE_NSSNOC_SNOC_1, GCC_NSSNOC_SNOC_1_CLK },
|
||||
{ MASTER_NSSNOC_PCNOC_1, SLAVE_NSSNOC_PCNOC_1, GCC_NSSNOC_PCNOC_1_CLK },
|
||||
{ MASTER_NSSNOC_QOSGEN_REF, SLAVE_NSSNOC_QOSGEN_REF, GCC_NSSNOC_QOSGEN_REF_CLK },
|
||||
{ MASTER_NSSNOC_TIMEOUT_REF, SLAVE_NSSNOC_TIMEOUT_REF, GCC_NSSNOC_TIMEOUT_REF_CLK },
|
||||
{ MASTER_NSSNOC_XO_DCD, SLAVE_NSSNOC_XO_DCD, GCC_NSSNOC_XO_DCD_CLK },
|
||||
{ MASTER_NSSNOC_ATB, SLAVE_NSSNOC_ATB, GCC_NSSNOC_ATB_CLK },
|
||||
{ MASTER_CNOC_LPASS_CFG, SLAVE_CNOC_LPASS_CFG, GCC_CNOC_LPASS_CFG_CLK },
|
||||
{ MASTER_SNOC_LPASS, SLAVE_SNOC_LPASS, GCC_SNOC_LPASS_CLK },
|
||||
};
|
||||
|
||||
static const struct of_device_id gcc_ipq5424_match_table[] = {
|
||||
|
|
@ -3284,6 +3309,7 @@ static const struct qcom_cc_desc gcc_ipq5424_desc = {
|
|||
.num_clk_hws = ARRAY_SIZE(gcc_ipq5424_hws),
|
||||
.icc_hws = icc_ipq5424_hws,
|
||||
.num_icc_hws = ARRAY_SIZE(icc_ipq5424_hws),
|
||||
.icc_first_node_id = IPQ_APPS_ID,
|
||||
};
|
||||
|
||||
static int gcc_ipq5424_probe(struct platform_device *pdev)
|
||||
|
|
|
|||
|
|
@ -784,7 +784,7 @@ static struct clk_rcg2 gcc_sdcc1_apps_clk_src = {
|
|||
.name = "gcc_sdcc1_apps_clk_src",
|
||||
.parent_data = gcc_parent_data_1,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_1),
|
||||
.ops = &clk_rcg2_floor_ops,
|
||||
.ops = &clk_rcg2_shared_floor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -806,7 +806,7 @@ static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = {
|
|||
.name = "gcc_sdcc1_ice_core_clk_src",
|
||||
.parent_data = gcc_parent_data_0,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_0),
|
||||
.ops = &clk_rcg2_floor_ops,
|
||||
.ops = &clk_rcg2_shared_floor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
@ -830,7 +830,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = {
|
|||
.name = "gcc_sdcc2_apps_clk_src",
|
||||
.parent_data = gcc_parent_data_8,
|
||||
.num_parents = ARRAY_SIZE(gcc_parent_data_8),
|
||||
.ops = &clk_rcg2_floor_ops,
|
||||
.ops = &clk_rcg2_shared_floor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2224,7 +2224,6 @@ static struct clk_rcg2 gcc_usb3_sec_phy_aux_clk_src = {
|
|||
};
|
||||
|
||||
static const struct freq_tbl ftbl_gcc_usb4_1_master_clk_src[] = {
|
||||
F(85714286, P_GCC_GPLL0_OUT_EVEN, 3.5, 0, 0),
|
||||
F(175000000, P_GCC_GPLL8_OUT_MAIN, 4, 0, 0),
|
||||
F(350000000, P_GCC_GPLL8_OUT_MAIN, 2, 0, 0),
|
||||
{ }
|
||||
|
|
|
|||
|
|
@ -1012,6 +1012,7 @@ static struct clk_rcg2 gcc_qupv3_wrap2_s7_clk_src = {
|
|||
static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = {
|
||||
F(400000, P_BI_TCXO, 12, 1, 4),
|
||||
F(25000000, P_GCC_GPLL0_OUT_EVEN, 12, 0, 0),
|
||||
F(37500000, P_GCC_GPLL0_OUT_EVEN, 8, 0, 0),
|
||||
F(50000000, P_GCC_GPLL0_OUT_EVEN, 6, 0, 0),
|
||||
F(100000000, P_GCC_GPLL0_OUT_EVEN, 3, 0, 0),
|
||||
F(202000000, P_GCC_GPLL9_OUT_MAIN, 4, 0, 0),
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -2781,6 +2781,7 @@ static struct gdsc *mmcc_sdm660_gdscs[] = {
|
|||
};
|
||||
|
||||
static const struct qcom_reset_map mmcc_660_resets[] = {
|
||||
[MDSS_BCR] = { 0x2300 },
|
||||
[CAMSS_MICRO_BCR] = { 0x3490 },
|
||||
};
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -28,10 +28,10 @@ enum {
|
|||
};
|
||||
|
||||
static struct clk_branch tcsr_edp_clkref_en = {
|
||||
.halt_reg = 0x1c,
|
||||
.halt_reg = 0x60,
|
||||
.halt_check = BRANCH_HALT_DELAY,
|
||||
.clkr = {
|
||||
.enable_reg = 0x1c,
|
||||
.enable_reg = 0x60,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "tcsr_edp_clkref_en",
|
||||
|
|
@ -45,10 +45,10 @@ static struct clk_branch tcsr_edp_clkref_en = {
|
|||
};
|
||||
|
||||
static struct clk_branch tcsr_pcie_1_clkref_en = {
|
||||
.halt_reg = 0x4,
|
||||
.halt_reg = 0x48,
|
||||
.halt_check = BRANCH_HALT_DELAY,
|
||||
.clkr = {
|
||||
.enable_reg = 0x4,
|
||||
.enable_reg = 0x48,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "tcsr_pcie_1_clkref_en",
|
||||
|
|
@ -62,10 +62,10 @@ static struct clk_branch tcsr_pcie_1_clkref_en = {
|
|||
};
|
||||
|
||||
static struct clk_branch tcsr_pcie_2_clkref_en = {
|
||||
.halt_reg = 0x8,
|
||||
.halt_reg = 0x4c,
|
||||
.halt_check = BRANCH_HALT_DELAY,
|
||||
.clkr = {
|
||||
.enable_reg = 0x8,
|
||||
.enable_reg = 0x4c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "tcsr_pcie_2_clkref_en",
|
||||
|
|
@ -79,10 +79,10 @@ static struct clk_branch tcsr_pcie_2_clkref_en = {
|
|||
};
|
||||
|
||||
static struct clk_branch tcsr_pcie_3_clkref_en = {
|
||||
.halt_reg = 0x10,
|
||||
.halt_reg = 0x54,
|
||||
.halt_check = BRANCH_HALT_DELAY,
|
||||
.clkr = {
|
||||
.enable_reg = 0x10,
|
||||
.enable_reg = 0x54,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "tcsr_pcie_3_clkref_en",
|
||||
|
|
@ -96,10 +96,10 @@ static struct clk_branch tcsr_pcie_3_clkref_en = {
|
|||
};
|
||||
|
||||
static struct clk_branch tcsr_pcie_4_clkref_en = {
|
||||
.halt_reg = 0x14,
|
||||
.halt_reg = 0x58,
|
||||
.halt_check = BRANCH_HALT_DELAY,
|
||||
.clkr = {
|
||||
.enable_reg = 0x14,
|
||||
.enable_reg = 0x58,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "tcsr_pcie_4_clkref_en",
|
||||
|
|
@ -113,10 +113,10 @@ static struct clk_branch tcsr_pcie_4_clkref_en = {
|
|||
};
|
||||
|
||||
static struct clk_branch tcsr_usb2_1_clkref_en = {
|
||||
.halt_reg = 0x28,
|
||||
.halt_reg = 0x6c,
|
||||
.halt_check = BRANCH_HALT_DELAY,
|
||||
.clkr = {
|
||||
.enable_reg = 0x28,
|
||||
.enable_reg = 0x6c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "tcsr_usb2_1_clkref_en",
|
||||
|
|
@ -130,10 +130,10 @@ static struct clk_branch tcsr_usb2_1_clkref_en = {
|
|||
};
|
||||
|
||||
static struct clk_branch tcsr_usb2_2_clkref_en = {
|
||||
.halt_reg = 0x2c,
|
||||
.halt_reg = 0x70,
|
||||
.halt_check = BRANCH_HALT_DELAY,
|
||||
.clkr = {
|
||||
.enable_reg = 0x2c,
|
||||
.enable_reg = 0x70,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "tcsr_usb2_2_clkref_en",
|
||||
|
|
@ -147,10 +147,10 @@ static struct clk_branch tcsr_usb2_2_clkref_en = {
|
|||
};
|
||||
|
||||
static struct clk_branch tcsr_usb2_3_clkref_en = {
|
||||
.halt_reg = 0x30,
|
||||
.halt_reg = 0x74,
|
||||
.halt_check = BRANCH_HALT_DELAY,
|
||||
.clkr = {
|
||||
.enable_reg = 0x30,
|
||||
.enable_reg = 0x74,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "tcsr_usb2_3_clkref_en",
|
||||
|
|
@ -164,10 +164,10 @@ static struct clk_branch tcsr_usb2_3_clkref_en = {
|
|||
};
|
||||
|
||||
static struct clk_branch tcsr_usb2_4_clkref_en = {
|
||||
.halt_reg = 0x44,
|
||||
.halt_reg = 0x88,
|
||||
.halt_check = BRANCH_HALT_DELAY,
|
||||
.clkr = {
|
||||
.enable_reg = 0x44,
|
||||
.enable_reg = 0x88,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "tcsr_usb2_4_clkref_en",
|
||||
|
|
@ -181,10 +181,10 @@ static struct clk_branch tcsr_usb2_4_clkref_en = {
|
|||
};
|
||||
|
||||
static struct clk_branch tcsr_usb3_0_clkref_en = {
|
||||
.halt_reg = 0x20,
|
||||
.halt_reg = 0x64,
|
||||
.halt_check = BRANCH_HALT_DELAY,
|
||||
.clkr = {
|
||||
.enable_reg = 0x20,
|
||||
.enable_reg = 0x64,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "tcsr_usb3_0_clkref_en",
|
||||
|
|
@ -198,10 +198,10 @@ static struct clk_branch tcsr_usb3_0_clkref_en = {
|
|||
};
|
||||
|
||||
static struct clk_branch tcsr_usb3_1_clkref_en = {
|
||||
.halt_reg = 0x24,
|
||||
.halt_reg = 0x68,
|
||||
.halt_check = BRANCH_HALT_DELAY,
|
||||
.clkr = {
|
||||
.enable_reg = 0x24,
|
||||
.enable_reg = 0x68,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "tcsr_usb3_1_clkref_en",
|
||||
|
|
@ -215,10 +215,10 @@ static struct clk_branch tcsr_usb3_1_clkref_en = {
|
|||
};
|
||||
|
||||
static struct clk_branch tcsr_usb4_1_clkref_en = {
|
||||
.halt_reg = 0x0,
|
||||
.halt_reg = 0x44,
|
||||
.halt_check = BRANCH_HALT_DELAY,
|
||||
.clkr = {
|
||||
.enable_reg = 0x0,
|
||||
.enable_reg = 0x44,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "tcsr_usb4_1_clkref_en",
|
||||
|
|
@ -232,10 +232,10 @@ static struct clk_branch tcsr_usb4_1_clkref_en = {
|
|||
};
|
||||
|
||||
static struct clk_branch tcsr_usb4_2_clkref_en = {
|
||||
.halt_reg = 0x18,
|
||||
.halt_reg = 0x5c,
|
||||
.halt_check = BRANCH_HALT_DELAY,
|
||||
.clkr = {
|
||||
.enable_reg = 0x18,
|
||||
.enable_reg = 0x5c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "tcsr_usb4_2_clkref_en",
|
||||
|
|
@ -268,7 +268,7 @@ static const struct regmap_config tcsr_cc_glymur_regmap_config = {
|
|||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0x44,
|
||||
.max_register = 0x94,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,463 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include <dt-bindings/clock/qcom,sm8750-videocc.h>
|
||||
|
||||
#include "clk-alpha-pll.h"
|
||||
#include "clk-branch.h"
|
||||
#include "clk-pll.h"
|
||||
#include "clk-rcg.h"
|
||||
#include "clk-regmap.h"
|
||||
#include "clk-regmap-divider.h"
|
||||
#include "clk-regmap-mux.h"
|
||||
#include "common.h"
|
||||
#include "gdsc.h"
|
||||
#include "reset.h"
|
||||
|
||||
enum {
|
||||
DT_BI_TCXO,
|
||||
DT_BI_TCXO_AO,
|
||||
DT_SLEEP_CLK,
|
||||
};
|
||||
|
||||
enum {
|
||||
P_BI_TCXO,
|
||||
P_SLEEP_CLK,
|
||||
P_VIDEO_CC_PLL0_OUT_MAIN,
|
||||
};
|
||||
|
||||
static const struct pll_vco taycan_elu_vco[] = {
|
||||
{ 249600000, 2500000000, 0 },
|
||||
};
|
||||
|
||||
static const struct alpha_pll_config video_cc_pll0_config = {
|
||||
.l = 0x25,
|
||||
.alpha = 0x8000,
|
||||
.config_ctl_val = 0x19660387,
|
||||
.config_ctl_hi_val = 0x098060a0,
|
||||
.config_ctl_hi1_val = 0xb416cb20,
|
||||
.user_ctl_val = 0x00000000,
|
||||
.user_ctl_hi_val = 0x00000002,
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll video_cc_pll0 = {
|
||||
.offset = 0x0,
|
||||
.config = &video_cc_pll0_config,
|
||||
.vco_table = taycan_elu_vco,
|
||||
.num_vco = ARRAY_SIZE(taycan_elu_vco),
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TAYCAN_ELU],
|
||||
.clkr = {
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "video_cc_pll0",
|
||||
.parent_data = &(const struct clk_parent_data) {
|
||||
.index = DT_BI_TCXO,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_taycan_elu_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static const struct parent_map video_cc_parent_map_0[] = {
|
||||
{ P_BI_TCXO, 0 },
|
||||
};
|
||||
|
||||
static const struct clk_parent_data video_cc_parent_data_0_ao[] = {
|
||||
{ .index = DT_BI_TCXO_AO },
|
||||
};
|
||||
|
||||
static const struct parent_map video_cc_parent_map_1[] = {
|
||||
{ P_BI_TCXO, 0 },
|
||||
{ P_VIDEO_CC_PLL0_OUT_MAIN, 1 },
|
||||
};
|
||||
|
||||
static const struct clk_parent_data video_cc_parent_data_1[] = {
|
||||
{ .index = DT_BI_TCXO },
|
||||
{ .hw = &video_cc_pll0.clkr.hw },
|
||||
};
|
||||
|
||||
static const struct parent_map video_cc_parent_map_2[] = {
|
||||
{ P_SLEEP_CLK, 0 },
|
||||
};
|
||||
|
||||
static const struct clk_parent_data video_cc_parent_data_2_ao[] = {
|
||||
{ .index = DT_SLEEP_CLK },
|
||||
};
|
||||
|
||||
static const struct freq_tbl ftbl_video_cc_ahb_clk_src[] = {
|
||||
F(19200000, P_BI_TCXO, 1, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk_rcg2 video_cc_ahb_clk_src = {
|
||||
.cmd_rcgr = 0x8018,
|
||||
.mnd_width = 0,
|
||||
.hid_width = 5,
|
||||
.parent_map = video_cc_parent_map_0,
|
||||
.freq_tbl = ftbl_video_cc_ahb_clk_src,
|
||||
.clkr.hw.init = &(const struct clk_init_data) {
|
||||
.name = "video_cc_ahb_clk_src",
|
||||
.parent_data = video_cc_parent_data_0_ao,
|
||||
.num_parents = ARRAY_SIZE(video_cc_parent_data_0_ao),
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_rcg2_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct freq_tbl ftbl_video_cc_mvs0_clk_src[] = {
|
||||
F(720000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
|
||||
F(1014000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
|
||||
F(1260000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
|
||||
F(1332000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
|
||||
F(1600000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
|
||||
F(1710000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
|
||||
F(1890000000, P_VIDEO_CC_PLL0_OUT_MAIN, 1, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk_rcg2 video_cc_mvs0_clk_src = {
|
||||
.cmd_rcgr = 0x8000,
|
||||
.mnd_width = 0,
|
||||
.hid_width = 5,
|
||||
.parent_map = video_cc_parent_map_1,
|
||||
.freq_tbl = ftbl_video_cc_mvs0_clk_src,
|
||||
.clkr.hw.init = &(const struct clk_init_data) {
|
||||
.name = "video_cc_mvs0_clk_src",
|
||||
.parent_data = video_cc_parent_data_1,
|
||||
.num_parents = ARRAY_SIZE(video_cc_parent_data_1),
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_rcg2_shared_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct freq_tbl ftbl_video_cc_sleep_clk_src[] = {
|
||||
F(32000, P_SLEEP_CLK, 1, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk_rcg2 video_cc_sleep_clk_src = {
|
||||
.cmd_rcgr = 0x80e0,
|
||||
.mnd_width = 0,
|
||||
.hid_width = 5,
|
||||
.parent_map = video_cc_parent_map_2,
|
||||
.freq_tbl = ftbl_video_cc_sleep_clk_src,
|
||||
.clkr.hw.init = &(const struct clk_init_data) {
|
||||
.name = "video_cc_sleep_clk_src",
|
||||
.parent_data = video_cc_parent_data_2_ao,
|
||||
.num_parents = ARRAY_SIZE(video_cc_parent_data_2_ao),
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_rcg2_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_rcg2 video_cc_xo_clk_src = {
|
||||
.cmd_rcgr = 0x80bc,
|
||||
.mnd_width = 0,
|
||||
.hid_width = 5,
|
||||
.parent_map = video_cc_parent_map_0,
|
||||
.freq_tbl = ftbl_video_cc_ahb_clk_src,
|
||||
.clkr.hw.init = &(const struct clk_init_data) {
|
||||
.name = "video_cc_xo_clk_src",
|
||||
.parent_data = video_cc_parent_data_0_ao,
|
||||
.num_parents = ARRAY_SIZE(video_cc_parent_data_0_ao),
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_rcg2_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap_div video_cc_mvs0_div_clk_src = {
|
||||
.reg = 0x809c,
|
||||
.shift = 0,
|
||||
.width = 4,
|
||||
.clkr.hw.init = &(const struct clk_init_data) {
|
||||
.name = "video_cc_mvs0_div_clk_src",
|
||||
.parent_hws = (const struct clk_hw*[]) {
|
||||
&video_cc_mvs0_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_regmap_div_ro_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap_div video_cc_mvs0c_div2_div_clk_src = {
|
||||
.reg = 0x8060,
|
||||
.shift = 0,
|
||||
.width = 4,
|
||||
.clkr.hw.init = &(const struct clk_init_data) {
|
||||
.name = "video_cc_mvs0c_div2_div_clk_src",
|
||||
.parent_hws = (const struct clk_hw*[]) {
|
||||
&video_cc_mvs0_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_regmap_div_ro_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch video_cc_mvs0_clk = {
|
||||
.halt_reg = 0x807c,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.hwcg_reg = 0x807c,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0x807c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "video_cc_mvs0_clk",
|
||||
.parent_hws = (const struct clk_hw*[]) {
|
||||
&video_cc_mvs0_div_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_mem_branch video_cc_mvs0_freerun_clk = {
|
||||
.mem_enable_reg = 0x8090,
|
||||
.mem_ack_reg = 0x8090,
|
||||
.mem_enable_mask = BIT(3),
|
||||
.mem_enable_ack_mask = GENMASK(11, 10),
|
||||
.mem_enable_invert = true,
|
||||
.branch = {
|
||||
.halt_reg = 0x808c,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x808c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "video_cc_mvs0_freerun_clk",
|
||||
.parent_hws = (const struct clk_hw*[]) {
|
||||
&video_cc_mvs0_div_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_mem_ops,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch video_cc_mvs0_shift_clk = {
|
||||
.halt_reg = 0x80d8,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.hwcg_reg = 0x80d8,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0x80d8,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "video_cc_mvs0_shift_clk",
|
||||
.parent_hws = (const struct clk_hw*[]) {
|
||||
&video_cc_xo_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch video_cc_mvs0c_clk = {
|
||||
.halt_reg = 0x804c,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x804c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "video_cc_mvs0c_clk",
|
||||
.parent_hws = (const struct clk_hw*[]) {
|
||||
&video_cc_mvs0c_div2_div_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch video_cc_mvs0c_freerun_clk = {
|
||||
.halt_reg = 0x805c,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x805c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "video_cc_mvs0c_freerun_clk",
|
||||
.parent_hws = (const struct clk_hw*[]) {
|
||||
&video_cc_mvs0c_div2_div_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch video_cc_mvs0c_shift_clk = {
|
||||
.halt_reg = 0x80dc,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.hwcg_reg = 0x80dc,
|
||||
.hwcg_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0x80dc,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "video_cc_mvs0c_shift_clk",
|
||||
.parent_hws = (const struct clk_hw*[]) {
|
||||
&video_cc_xo_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct gdsc video_cc_mvs0c_gdsc = {
|
||||
.gdscr = 0x8034,
|
||||
.en_rest_wait_val = 0x2,
|
||||
.en_few_wait_val = 0x2,
|
||||
.clk_dis_wait_val = 0x6,
|
||||
.pd = {
|
||||
.name = "video_cc_mvs0c_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE,
|
||||
};
|
||||
|
||||
static struct gdsc video_cc_mvs0_gdsc = {
|
||||
.gdscr = 0x8068,
|
||||
.en_rest_wait_val = 0x2,
|
||||
.en_few_wait_val = 0x2,
|
||||
.clk_dis_wait_val = 0x6,
|
||||
.pd = {
|
||||
.name = "video_cc_mvs0_gdsc",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.parent = &video_cc_mvs0c_gdsc.pd,
|
||||
.flags = POLL_CFG_GDSCR | RETAIN_FF_ENABLE | HW_CTRL_TRIGGER,
|
||||
};
|
||||
|
||||
static struct clk_regmap *video_cc_sm8750_clocks[] = {
|
||||
[VIDEO_CC_AHB_CLK_SRC] = &video_cc_ahb_clk_src.clkr,
|
||||
[VIDEO_CC_MVS0_CLK] = &video_cc_mvs0_clk.clkr,
|
||||
[VIDEO_CC_MVS0_CLK_SRC] = &video_cc_mvs0_clk_src.clkr,
|
||||
[VIDEO_CC_MVS0_DIV_CLK_SRC] = &video_cc_mvs0_div_clk_src.clkr,
|
||||
[VIDEO_CC_MVS0_FREERUN_CLK] = &video_cc_mvs0_freerun_clk.branch.clkr,
|
||||
[VIDEO_CC_MVS0_SHIFT_CLK] = &video_cc_mvs0_shift_clk.clkr,
|
||||
[VIDEO_CC_MVS0C_CLK] = &video_cc_mvs0c_clk.clkr,
|
||||
[VIDEO_CC_MVS0C_DIV2_DIV_CLK_SRC] = &video_cc_mvs0c_div2_div_clk_src.clkr,
|
||||
[VIDEO_CC_MVS0C_FREERUN_CLK] = &video_cc_mvs0c_freerun_clk.clkr,
|
||||
[VIDEO_CC_MVS0C_SHIFT_CLK] = &video_cc_mvs0c_shift_clk.clkr,
|
||||
[VIDEO_CC_PLL0] = &video_cc_pll0.clkr,
|
||||
[VIDEO_CC_SLEEP_CLK_SRC] = &video_cc_sleep_clk_src.clkr,
|
||||
[VIDEO_CC_XO_CLK_SRC] = &video_cc_xo_clk_src.clkr,
|
||||
};
|
||||
|
||||
static struct gdsc *video_cc_sm8750_gdscs[] = {
|
||||
[VIDEO_CC_MVS0_GDSC] = &video_cc_mvs0_gdsc,
|
||||
[VIDEO_CC_MVS0C_GDSC] = &video_cc_mvs0c_gdsc,
|
||||
};
|
||||
|
||||
static const struct qcom_reset_map video_cc_sm8750_resets[] = {
|
||||
[VIDEO_CC_INTERFACE_BCR] = { 0x80a0 },
|
||||
[VIDEO_CC_MVS0_BCR] = { 0x8064 },
|
||||
[VIDEO_CC_MVS0C_CLK_ARES] = { 0x804c, 2 },
|
||||
[VIDEO_CC_MVS0C_BCR] = { 0x8030 },
|
||||
[VIDEO_CC_MVS0_FREERUN_CLK_ARES] = { 0x808c, 2 },
|
||||
[VIDEO_CC_MVS0C_FREERUN_CLK_ARES] = { 0x805c, 2 },
|
||||
[VIDEO_CC_XO_CLK_ARES] = { 0x80d4, 2 },
|
||||
};
|
||||
|
||||
static const struct regmap_config video_cc_sm8750_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0x9f4c,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll *video_cc_sm8750_plls[] = {
|
||||
&video_cc_pll0,
|
||||
};
|
||||
|
||||
static u32 video_cc_sm8750_critical_cbcrs[] = {
|
||||
0x80a4, /* VIDEO_CC_AHB_CLK */
|
||||
0x80f8, /* VIDEO_CC_SLEEP_CLK */
|
||||
0x80d4, /* VIDEO_CC_XO_CLK */
|
||||
};
|
||||
|
||||
static void clk_sm8750_regs_configure(struct device *dev, struct regmap *regmap)
|
||||
{
|
||||
/* Update DLY_ACCU_RED_SHIFTER_DONE to 0xF for mvs0, mvs0c */
|
||||
regmap_update_bits(regmap, 0x8074, GENMASK(25, 21), GENMASK(25, 21));
|
||||
regmap_update_bits(regmap, 0x8040, GENMASK(25, 21), GENMASK(25, 21));
|
||||
|
||||
regmap_update_bits(regmap, 0x9f24, BIT(0), BIT(0));
|
||||
}
|
||||
|
||||
static struct qcom_cc_driver_data video_cc_sm8750_driver_data = {
|
||||
.alpha_plls = video_cc_sm8750_plls,
|
||||
.num_alpha_plls = ARRAY_SIZE(video_cc_sm8750_plls),
|
||||
.clk_cbcrs = video_cc_sm8750_critical_cbcrs,
|
||||
.num_clk_cbcrs = ARRAY_SIZE(video_cc_sm8750_critical_cbcrs),
|
||||
.clk_regs_configure = clk_sm8750_regs_configure,
|
||||
};
|
||||
|
||||
static struct qcom_cc_desc video_cc_sm8750_desc = {
|
||||
.config = &video_cc_sm8750_regmap_config,
|
||||
.clks = video_cc_sm8750_clocks,
|
||||
.num_clks = ARRAY_SIZE(video_cc_sm8750_clocks),
|
||||
.resets = video_cc_sm8750_resets,
|
||||
.num_resets = ARRAY_SIZE(video_cc_sm8750_resets),
|
||||
.gdscs = video_cc_sm8750_gdscs,
|
||||
.num_gdscs = ARRAY_SIZE(video_cc_sm8750_gdscs),
|
||||
.use_rpm = true,
|
||||
.driver_data = &video_cc_sm8750_driver_data,
|
||||
};
|
||||
|
||||
static const struct of_device_id video_cc_sm8750_match_table[] = {
|
||||
{ .compatible = "qcom,sm8750-videocc" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, video_cc_sm8750_match_table);
|
||||
|
||||
static int video_cc_sm8750_probe(struct platform_device *pdev)
|
||||
{
|
||||
return qcom_cc_probe(pdev, &video_cc_sm8750_desc);
|
||||
}
|
||||
|
||||
static struct platform_driver video_cc_sm8750_driver = {
|
||||
.probe = video_cc_sm8750_probe,
|
||||
.driver = {
|
||||
.name = "video_cc-sm8750",
|
||||
.of_match_table = video_cc_sm8750_match_table,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init video_cc_sm8750_init(void)
|
||||
{
|
||||
return platform_driver_register(&video_cc_sm8750_driver);
|
||||
}
|
||||
subsys_initcall(video_cc_sm8750_init);
|
||||
|
||||
static void __exit video_cc_sm8750_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&video_cc_sm8750_driver);
|
||||
}
|
||||
module_exit(video_cc_sm8750_exit);
|
||||
|
||||
MODULE_DESCRIPTION("QTI VIDEO_CC SM8750 Driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
|
||||
enum clk_ids {
|
||||
/* Core Clock Outputs exported to DT */
|
||||
LAST_DT_CORE_CLK = R8A779A0_CLK_OSC,
|
||||
LAST_DT_CORE_CLK = R8A779A0_CLK_ZG,
|
||||
|
||||
/* External Input Clocks */
|
||||
CLK_EXTAL,
|
||||
|
|
@ -39,6 +39,7 @@ enum clk_ids {
|
|||
CLK_PLL21,
|
||||
CLK_PLL30,
|
||||
CLK_PLL31,
|
||||
CLK_PLL4,
|
||||
CLK_PLL5,
|
||||
CLK_PLL1_DIV2,
|
||||
CLK_PLL20_DIV2,
|
||||
|
|
@ -65,6 +66,7 @@ enum clk_ids {
|
|||
#define CPG_PLL21CR 0x0838 /* PLL21 Control Register */
|
||||
#define CPG_PLL30CR 0x083c /* PLL30 Control Register */
|
||||
#define CPG_PLL31CR 0x0840 /* PLL31 Control Register */
|
||||
#define CPG_PLL4CR 0x0844 /* PLL4 Control Register */
|
||||
|
||||
static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = {
|
||||
/* External Clock Inputs */
|
||||
|
|
@ -79,6 +81,7 @@ static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = {
|
|||
DEF_PLL(".pll21", CLK_PLL21, CPG_PLL21CR),
|
||||
DEF_PLL(".pll30", CLK_PLL30, CPG_PLL30CR),
|
||||
DEF_PLL(".pll31", CLK_PLL31, CPG_PLL31CR),
|
||||
DEF_PLL(".pll4", CLK_PLL4, CPG_PLL4CR),
|
||||
|
||||
DEF_FIXED(".pll1_div2", CLK_PLL1_DIV2, CLK_PLL1, 2, 1),
|
||||
DEF_FIXED(".pll20_div2", CLK_PLL20_DIV2, CLK_PLL20, 2, 1),
|
||||
|
|
@ -98,6 +101,7 @@ static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = {
|
|||
/* Core Clock Outputs */
|
||||
DEF_GEN4_Z("z0", R8A779A0_CLK_Z0, CLK_TYPE_GEN4_Z, CLK_PLL20, 2, 0),
|
||||
DEF_GEN4_Z("z1", R8A779A0_CLK_Z1, CLK_TYPE_GEN4_Z, CLK_PLL21, 2, 8),
|
||||
DEF_GEN4_Z("zg", R8A779A0_CLK_ZG, CLK_TYPE_GEN4_Z, CLK_PLL4, 2, 88),
|
||||
DEF_FIXED("zx", R8A779A0_CLK_ZX, CLK_PLL20_DIV2, 2, 1),
|
||||
DEF_FIXED("s1d1", R8A779A0_CLK_S1D1, CLK_S1, 1, 1),
|
||||
DEF_FIXED("s1d2", R8A779A0_CLK_S1D2, CLK_S1, 2, 1),
|
||||
|
|
@ -138,6 +142,7 @@ static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = {
|
|||
};
|
||||
|
||||
static const struct mssr_mod_clk r8a779a0_mod_clks[] __initconst = {
|
||||
DEF_MOD("3dge", 0, R8A779A0_CLK_ZG),
|
||||
DEF_MOD("isp0", 16, R8A779A0_CLK_S1D1),
|
||||
DEF_MOD("isp1", 17, R8A779A0_CLK_S1D1),
|
||||
DEF_MOD("isp2", 18, R8A779A0_CLK_S1D1),
|
||||
|
|
|
|||
|
|
@ -1333,9 +1333,9 @@ static int __init r9a06g032_clocks_probe(struct platform_device *pdev)
|
|||
if (IS_ERR(mclk))
|
||||
return PTR_ERR(mclk);
|
||||
|
||||
clocks->reg = of_iomap(np, 0);
|
||||
if (WARN_ON(!clocks->reg))
|
||||
return -ENOMEM;
|
||||
clocks->reg = devm_of_iomap(dev, np, 0, NULL);
|
||||
if (IS_ERR(clocks->reg))
|
||||
return PTR_ERR(clocks->reg);
|
||||
|
||||
r9a06g032_init_h2mode(clocks);
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
enum clk_ids {
|
||||
/* Core Clock Outputs exported to DT */
|
||||
LAST_DT_CORE_CLK = R9A09G047_USB3_0_CLKCORE,
|
||||
LAST_DT_CORE_CLK = R9A09G047_USB2_0_CLK_CORE1,
|
||||
|
||||
/* External Input Clocks */
|
||||
CLK_AUDIO_EXTAL,
|
||||
|
|
@ -44,6 +44,9 @@ enum clk_ids {
|
|||
CLK_PLLCLN_DIV8,
|
||||
CLK_PLLCLN_DIV16,
|
||||
CLK_PLLCLN_DIV20,
|
||||
CLK_PLLCLN_DIV64,
|
||||
CLK_PLLCLN_DIV256,
|
||||
CLK_PLLCLN_DIV1024,
|
||||
CLK_PLLDTY_ACPU,
|
||||
CLK_PLLDTY_ACPU_DIV2,
|
||||
CLK_PLLDTY_ACPU_DIV4,
|
||||
|
|
@ -142,6 +145,9 @@ static const struct cpg_core_clk r9a09g047_core_clks[] __initconst = {
|
|||
DEF_FIXED(".pllcln_div8", CLK_PLLCLN_DIV8, CLK_PLLCLN, 1, 8),
|
||||
DEF_FIXED(".pllcln_div16", CLK_PLLCLN_DIV16, CLK_PLLCLN, 1, 16),
|
||||
DEF_FIXED(".pllcln_div20", CLK_PLLCLN_DIV20, CLK_PLLCLN, 1, 20),
|
||||
DEF_FIXED(".pllcln_div64", CLK_PLLCLN_DIV64, CLK_PLLCLN, 1, 64),
|
||||
DEF_FIXED(".pllcln_div256", CLK_PLLCLN_DIV256, CLK_PLLCLN, 1, 256),
|
||||
DEF_FIXED(".pllcln_div1024", CLK_PLLCLN_DIV1024, CLK_PLLCLN, 1, 1024),
|
||||
|
||||
DEF_DDIV(".plldty_acpu", CLK_PLLDTY_ACPU, CLK_PLLDTY, CDDIV0_DIVCTL2, dtable_2_64),
|
||||
DEF_FIXED(".plldty_acpu_div2", CLK_PLLDTY_ACPU_DIV2, CLK_PLLDTY_ACPU, 1, 2),
|
||||
|
|
@ -177,6 +183,8 @@ static const struct cpg_core_clk r9a09g047_core_clks[] __initconst = {
|
|||
CDDIV1_DIVCTL3, dtable_1_8),
|
||||
DEF_FIXED("iotop_0_shclk", R9A09G047_IOTOP_0_SHCLK, CLK_PLLCM33_DIV16, 1, 1),
|
||||
DEF_FIXED("spi_clk_spi", R9A09G047_SPI_CLK_SPI, CLK_PLLCM33_XSPI, 1, 2),
|
||||
DEF_FIXED("usb2_0_clk_core0", R9A09G047_USB2_0_CLK_CORE0, CLK_QEXTAL, 1, 1),
|
||||
DEF_FIXED("usb2_0_clk_core1", R9A09G047_USB2_0_CLK_CORE1, CLK_QEXTAL, 1, 1),
|
||||
DEF_FIXED("gbeth_0_clk_ptp_ref_i", R9A09G047_GBETH_0_CLK_PTP_REF_I,
|
||||
CLK_PLLETH_DIV_125_FIX, 1, 1),
|
||||
DEF_FIXED("gbeth_1_clk_ptp_ref_i", R9A09G047_GBETH_1_CLK_PTP_REF_I,
|
||||
|
|
@ -216,6 +224,106 @@ static const struct rzv2h_mod_clk r9a09g047_mod_clks[] __initconst = {
|
|||
BUS_MSTOP(5, BIT(13))),
|
||||
DEF_MOD("wdt_3_clk_loco", CLK_QEXTAL, 5, 2, 2, 18,
|
||||
BUS_MSTOP(5, BIT(13))),
|
||||
DEF_MOD("rsci0_pclk", CLK_PLLCLN_DIV16, 5, 13, 2, 29,
|
||||
BUS_MSTOP(11, BIT(3))),
|
||||
DEF_MOD("rsci0_tclk", CLK_PLLCLN_DIV16, 5, 14, 2, 30,
|
||||
BUS_MSTOP(11, BIT(3))),
|
||||
DEF_MOD("rsci0_ps_ps3_n", CLK_PLLCLN_DIV1024, 5, 15, 2, 31,
|
||||
BUS_MSTOP(11, BIT(3))),
|
||||
DEF_MOD("rsci0_ps_ps2_n", CLK_PLLCLN_DIV256, 6, 0, 3, 0,
|
||||
BUS_MSTOP(11, BIT(3))),
|
||||
DEF_MOD("rsci0_ps_ps1_n", CLK_PLLCLN_DIV64, 6, 1, 3, 1,
|
||||
BUS_MSTOP(11, BIT(3))),
|
||||
DEF_MOD("rsci1_pclk", CLK_PLLCLN_DIV16, 6, 2, 3, 2,
|
||||
BUS_MSTOP(11, BIT(4))),
|
||||
DEF_MOD("rsci1_tclk", CLK_PLLCLN_DIV16, 6, 3, 3, 3,
|
||||
BUS_MSTOP(11, BIT(4))),
|
||||
DEF_MOD("rsci1_ps_ps3_n", CLK_PLLCLN_DIV1024, 6, 4, 3, 4,
|
||||
BUS_MSTOP(11, BIT(4))),
|
||||
DEF_MOD("rsci1_ps_ps2_n", CLK_PLLCLN_DIV256, 6, 5, 3, 5,
|
||||
BUS_MSTOP(11, BIT(4))),
|
||||
DEF_MOD("rsci1_ps_ps1_n", CLK_PLLCLN_DIV64, 6, 6, 3, 6,
|
||||
BUS_MSTOP(11, BIT(4))),
|
||||
DEF_MOD("rsci2_pclk", CLK_PLLCLN_DIV16, 6, 7, 3, 7,
|
||||
BUS_MSTOP(11, BIT(5))),
|
||||
DEF_MOD("rsci2_tclk", CLK_PLLCLN_DIV16, 6, 8, 3, 8,
|
||||
BUS_MSTOP(11, BIT(5))),
|
||||
DEF_MOD("rsci2_ps_ps3_n", CLK_PLLCLN_DIV1024, 6, 9, 3, 9,
|
||||
BUS_MSTOP(11, BIT(5))),
|
||||
DEF_MOD("rsci2_ps_ps2_n", CLK_PLLCLN_DIV256, 6, 10, 3, 10,
|
||||
BUS_MSTOP(11, BIT(5))),
|
||||
DEF_MOD("rsci2_ps_ps1_n", CLK_PLLCLN_DIV64, 6, 11, 3, 11,
|
||||
BUS_MSTOP(11, BIT(5))),
|
||||
DEF_MOD("rsci3_pclk", CLK_PLLCLN_DIV16, 6, 12, 3, 12,
|
||||
BUS_MSTOP(11, BIT(6))),
|
||||
DEF_MOD("rsci3_tclk", CLK_PLLCLN_DIV16, 6, 13, 3, 13,
|
||||
BUS_MSTOP(11, BIT(6))),
|
||||
DEF_MOD("rsci3_ps_ps3_n", CLK_PLLCLN_DIV1024, 6, 14, 3, 14,
|
||||
BUS_MSTOP(11, BIT(6))),
|
||||
DEF_MOD("rsci3_ps_ps2_n", CLK_PLLCLN_DIV256, 6, 15, 3, 15,
|
||||
BUS_MSTOP(11, BIT(6))),
|
||||
DEF_MOD("rsci3_ps_ps1_n", CLK_PLLCLN_DIV64, 7, 0, 3, 16,
|
||||
BUS_MSTOP(11, BIT(6))),
|
||||
DEF_MOD("rsci4_pclk", CLK_PLLCLN_DIV16, 7, 1, 3, 17,
|
||||
BUS_MSTOP(11, BIT(7))),
|
||||
DEF_MOD("rsci4_tclk", CLK_PLLCLN_DIV16, 7, 2, 3, 18,
|
||||
BUS_MSTOP(11, BIT(7))),
|
||||
DEF_MOD("rsci4_ps_ps3_n", CLK_PLLCLN_DIV1024, 7, 3, 3, 19,
|
||||
BUS_MSTOP(11, BIT(7))),
|
||||
DEF_MOD("rsci4_ps_ps2_n", CLK_PLLCLN_DIV256, 7, 4, 3, 20,
|
||||
BUS_MSTOP(11, BIT(7))),
|
||||
DEF_MOD("rsci4_ps_ps1_n", CLK_PLLCLN_DIV64, 7, 5, 3, 21,
|
||||
BUS_MSTOP(11, BIT(7))),
|
||||
DEF_MOD("rsci5_pclk", CLK_PLLCLN_DIV16, 7, 6, 3, 22,
|
||||
BUS_MSTOP(11, BIT(8))),
|
||||
DEF_MOD("rsci5_tclk", CLK_PLLCLN_DIV16, 7, 7, 3, 23,
|
||||
BUS_MSTOP(11, BIT(8))),
|
||||
DEF_MOD("rsci5_ps_ps3_n", CLK_PLLCLN_DIV1024, 7, 8, 3, 24,
|
||||
BUS_MSTOP(11, BIT(8))),
|
||||
DEF_MOD("rsci5_ps_ps2_n", CLK_PLLCLN_DIV256, 7, 9, 3, 25,
|
||||
BUS_MSTOP(11, BIT(8))),
|
||||
DEF_MOD("rsci5_ps_ps1_n", CLK_PLLCLN_DIV64, 7, 10, 3, 26,
|
||||
BUS_MSTOP(11, BIT(8))),
|
||||
DEF_MOD("rsci6_pclk", CLK_PLLCLN_DIV16, 7, 11, 3, 27,
|
||||
BUS_MSTOP(11, BIT(9))),
|
||||
DEF_MOD("rsci6_tclk", CLK_PLLCLN_DIV16, 7, 12, 3, 28,
|
||||
BUS_MSTOP(11, BIT(9))),
|
||||
DEF_MOD("rsci6_ps_ps3_n", CLK_PLLCLN_DIV1024, 7, 13, 3, 29,
|
||||
BUS_MSTOP(11, BIT(9))),
|
||||
DEF_MOD("rsci6_ps_ps2_n", CLK_PLLCLN_DIV256, 7, 14, 3, 30,
|
||||
BUS_MSTOP(11, BIT(9))),
|
||||
DEF_MOD("rsci6_ps_ps1_n", CLK_PLLCLN_DIV64, 7, 15, 3, 31,
|
||||
BUS_MSTOP(11, BIT(9))),
|
||||
DEF_MOD("rsci7_pclk", CLK_PLLCLN_DIV16, 8, 0, 4, 0,
|
||||
BUS_MSTOP(11, BIT(10))),
|
||||
DEF_MOD("rsci7_tclk", CLK_PLLCLN_DIV16, 8, 1, 4, 1,
|
||||
BUS_MSTOP(11, BIT(10))),
|
||||
DEF_MOD("rsci7_ps_ps3_n", CLK_PLLCLN_DIV1024, 8, 2, 4, 2,
|
||||
BUS_MSTOP(11, BIT(10))),
|
||||
DEF_MOD("rsci7_ps_ps2_n", CLK_PLLCLN_DIV256, 8, 3, 4, 3,
|
||||
BUS_MSTOP(11, BIT(10))),
|
||||
DEF_MOD("rsci7_ps_ps1_n", CLK_PLLCLN_DIV64, 8, 4, 4, 4,
|
||||
BUS_MSTOP(11, BIT(10))),
|
||||
DEF_MOD("rsci8_pclk", CLK_PLLCLN_DIV16, 8, 5, 4, 5,
|
||||
BUS_MSTOP(11, BIT(11))),
|
||||
DEF_MOD("rsci8_tclk", CLK_PLLCLN_DIV16, 8, 6, 4, 6,
|
||||
BUS_MSTOP(11, BIT(11))),
|
||||
DEF_MOD("rsci8_ps_ps3_n", CLK_PLLCLN_DIV1024, 8, 7, 4, 7,
|
||||
BUS_MSTOP(11, BIT(11))),
|
||||
DEF_MOD("rsci8_ps_ps2_n", CLK_PLLCLN_DIV256, 8, 8, 4, 8,
|
||||
BUS_MSTOP(11, BIT(11))),
|
||||
DEF_MOD("rsci8_ps_ps1_n", CLK_PLLCLN_DIV64, 8, 9, 4, 9,
|
||||
BUS_MSTOP(11, BIT(11))),
|
||||
DEF_MOD("rsci9_pclk", CLK_PLLCLN_DIV16, 8, 10, 4, 10,
|
||||
BUS_MSTOP(11, BIT(12))),
|
||||
DEF_MOD("rsci9_tclk", CLK_PLLCLN_DIV16, 8, 11, 4, 11,
|
||||
BUS_MSTOP(11, BIT(12))),
|
||||
DEF_MOD("rsci9_ps_ps3_n", CLK_PLLCLN_DIV1024, 8, 12, 4, 12,
|
||||
BUS_MSTOP(11, BIT(12))),
|
||||
DEF_MOD("rsci9_ps_ps2_n", CLK_PLLCLN_DIV256, 8, 13, 4, 13,
|
||||
BUS_MSTOP(11, BIT(12))),
|
||||
DEF_MOD("rsci9_ps_ps1_n", CLK_PLLCLN_DIV64, 8, 14, 4, 14,
|
||||
BUS_MSTOP(11, BIT(12))),
|
||||
DEF_MOD("scif_0_clk_pck", CLK_PLLCM33_DIV16, 8, 15, 4, 15,
|
||||
BUS_MSTOP(3, BIT(14))),
|
||||
DEF_MOD("i3c_0_pclkrw", CLK_PLLCLN_DIV16, 9, 0, 4, 16,
|
||||
|
|
@ -282,6 +390,16 @@ static const struct rzv2h_mod_clk r9a09g047_mod_clks[] __initconst = {
|
|||
BUS_MSTOP(7, BIT(12))),
|
||||
DEF_MOD("usb3_0_pclk_usbtst", CLK_PLLDTY_ACPU_DIV4, 11, 0, 5, 16,
|
||||
BUS_MSTOP(7, BIT(14))),
|
||||
DEF_MOD("usb2_0_u2h0_hclk", CLK_PLLDTY_DIV8, 11, 3, 5, 19,
|
||||
BUS_MSTOP(7, BIT(7))),
|
||||
DEF_MOD("usb2_0_u2h1_hclk", CLK_PLLDTY_DIV8, 11, 4, 5, 20,
|
||||
BUS_MSTOP(7, BIT(8))),
|
||||
DEF_MOD("usb2_0_u2p_exr_cpuclk", CLK_PLLDTY_ACPU_DIV4, 11, 5, 5, 21,
|
||||
BUS_MSTOP(7, BIT(9))),
|
||||
DEF_MOD("usb2_0_pclk_usbtst0", CLK_PLLDTY_ACPU_DIV4, 11, 6, 5, 22,
|
||||
BUS_MSTOP(7, BIT(10))),
|
||||
DEF_MOD("usb2_0_pclk_usbtst1", CLK_PLLDTY_ACPU_DIV4, 11, 7, 5, 23,
|
||||
BUS_MSTOP(7, BIT(11))),
|
||||
DEF_MOD_MUX_EXTERNAL("gbeth_0_clk_tx_i", CLK_SMUX2_GBE0_TXCLK, 11, 8, 5, 24,
|
||||
BUS_MSTOP(8, BIT(5)), 1),
|
||||
DEF_MOD_MUX_EXTERNAL("gbeth_0_clk_rx_i", CLK_SMUX2_GBE0_RXCLK, 11, 9, 5, 25,
|
||||
|
|
@ -339,6 +457,26 @@ static const struct rzv2h_reset r9a09g047_resets[] __initconst = {
|
|||
DEF_RST(7, 6, 3, 7), /* WDT_1_RESET */
|
||||
DEF_RST(7, 7, 3, 8), /* WDT_2_RESET */
|
||||
DEF_RST(7, 8, 3, 9), /* WDT_3_RESET */
|
||||
DEF_RST(8, 1, 3, 18), /* RSCI0_PRESETN */
|
||||
DEF_RST(8, 2, 3, 19), /* RSCI0_TRESETN */
|
||||
DEF_RST(8, 3, 3, 20), /* RSCI1_PRESETN */
|
||||
DEF_RST(8, 4, 3, 21), /* RSCI1_TRESETN */
|
||||
DEF_RST(8, 5, 3, 22), /* RSCI2_PRESETN */
|
||||
DEF_RST(8, 6, 3, 23), /* RSCI2_TRESETN */
|
||||
DEF_RST(8, 7, 3, 24), /* RSCI3_PRESETN */
|
||||
DEF_RST(8, 8, 3, 25), /* RSCI3_TRESETN */
|
||||
DEF_RST(8, 9, 3, 26), /* RSCI4_PRESETN */
|
||||
DEF_RST(8, 10, 3, 27), /* RSCI4_TRESETN */
|
||||
DEF_RST(8, 11, 3, 28), /* RSCI5_PRESETN */
|
||||
DEF_RST(8, 12, 3, 29), /* RSCI5_TRESETN */
|
||||
DEF_RST(8, 13, 3, 30), /* RSCI6_PRESETN */
|
||||
DEF_RST(8, 14, 3, 31), /* RSCI6_TRESETN */
|
||||
DEF_RST(8, 15, 4, 0), /* RSCI7_PRESETN */
|
||||
DEF_RST(9, 0, 4, 1), /* RSCI7_TRESETN */
|
||||
DEF_RST(9, 1, 4, 2), /* RSCI8_PRESETN */
|
||||
DEF_RST(9, 2, 4, 3), /* RSCI8_TRESETN */
|
||||
DEF_RST(9, 3, 4, 4), /* RSCI9_PRESETN */
|
||||
DEF_RST(9, 4, 4, 5), /* RSCI9_TRESETN */
|
||||
DEF_RST(9, 5, 4, 6), /* SCIF_0_RST_SYSTEM_N */
|
||||
DEF_RST(9, 6, 4, 7), /* I3C_0_PRESETN */
|
||||
DEF_RST(9, 7, 4, 8), /* I3C_0_TRESETN */
|
||||
|
|
@ -359,6 +497,10 @@ static const struct rzv2h_reset r9a09g047_resets[] __initconst = {
|
|||
DEF_RST(10, 8, 4, 25), /* SDHI_1_IXRST */
|
||||
DEF_RST(10, 9, 4, 26), /* SDHI_2_IXRST */
|
||||
DEF_RST(10, 10, 4, 27), /* USB3_0_ARESETN */
|
||||
DEF_RST(10, 12, 4, 29), /* USB2_0_U2H0_HRESETN */
|
||||
DEF_RST(10, 13, 4, 30), /* USB2_0_U2H1_HRESETN */
|
||||
DEF_RST(10, 14, 4, 31), /* USB2_0_U2P_EXL_SYSRST */
|
||||
DEF_RST(10, 15, 5, 0), /* USB2_0_PRESETN */
|
||||
DEF_RST(11, 0, 5, 1), /* GBETH_0_ARESETN_I */
|
||||
DEF_RST(11, 1, 5, 2), /* GBETH_1_ARESETN_I */
|
||||
DEF_RST(12, 5, 5, 22), /* CRU_0_PRESETN */
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/clk/renesas.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
|
|
@ -16,7 +17,7 @@
|
|||
|
||||
enum clk_ids {
|
||||
/* Core Clock Outputs exported to DT */
|
||||
LAST_DT_CORE_CLK = R9A09G056_SPI_CLK_SPI,
|
||||
LAST_DT_CORE_CLK = R9A09G056_USB3_0_CLKCORE,
|
||||
|
||||
/* External Input Clocks */
|
||||
CLK_AUDIO_EXTAL,
|
||||
|
|
@ -28,7 +29,9 @@ enum clk_ids {
|
|||
CLK_PLLCLN,
|
||||
CLK_PLLDTY,
|
||||
CLK_PLLCA55,
|
||||
CLK_PLLVDO,
|
||||
CLK_PLLETH,
|
||||
CLK_PLLDSI,
|
||||
CLK_PLLGPU,
|
||||
|
||||
/* Internal Core Clocks */
|
||||
|
|
@ -47,6 +50,10 @@ enum clk_ids {
|
|||
CLK_PLLDTY_ACPU_DIV2,
|
||||
CLK_PLLDTY_ACPU_DIV4,
|
||||
CLK_PLLDTY_DIV8,
|
||||
CLK_PLLDTY_DIV16,
|
||||
CLK_PLLVDO_CRU0,
|
||||
CLK_PLLVDO_CRU1,
|
||||
CLK_PLLVDO_ISP,
|
||||
CLK_PLLETH_DIV_250_FIX,
|
||||
CLK_PLLETH_DIV_125_FIX,
|
||||
CLK_CSDIV_PLLETH_GBE0,
|
||||
|
|
@ -55,6 +62,9 @@ enum clk_ids {
|
|||
CLK_SMUX2_GBE0_RXCLK,
|
||||
CLK_SMUX2_GBE1_TXCLK,
|
||||
CLK_SMUX2_GBE1_RXCLK,
|
||||
CLK_CDIV4_PLLETH_LPCLK,
|
||||
CLK_PLLETH_LPCLK_GEAR,
|
||||
CLK_PLLDSI_GEAR,
|
||||
CLK_PLLGPU_GEAR,
|
||||
|
||||
/* Module Clocks */
|
||||
|
|
@ -69,6 +79,12 @@ static const struct clk_div_table dtable_1_8[] = {
|
|||
{0, 0},
|
||||
};
|
||||
|
||||
static const struct clk_div_table dtable_2_4[] = {
|
||||
{0, 2},
|
||||
{1, 4},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
static const struct clk_div_table dtable_2_16[] = {
|
||||
{0, 2},
|
||||
{1, 4},
|
||||
|
|
@ -77,6 +93,26 @@ static const struct clk_div_table dtable_2_16[] = {
|
|||
{0, 0},
|
||||
};
|
||||
|
||||
static const struct clk_div_table dtable_2_32[] = {
|
||||
{0, 2},
|
||||
{1, 4},
|
||||
{2, 6},
|
||||
{3, 8},
|
||||
{4, 10},
|
||||
{5, 12},
|
||||
{6, 14},
|
||||
{7, 16},
|
||||
{8, 18},
|
||||
{9, 20},
|
||||
{10, 22},
|
||||
{11, 24},
|
||||
{12, 26},
|
||||
{13, 28},
|
||||
{14, 30},
|
||||
{15, 32},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
static const struct clk_div_table dtable_2_64[] = {
|
||||
{0, 2},
|
||||
{1, 4},
|
||||
|
|
@ -93,6 +129,17 @@ static const struct clk_div_table dtable_2_100[] = {
|
|||
{0, 0},
|
||||
};
|
||||
|
||||
static const struct clk_div_table dtable_16_128[] = {
|
||||
{0, 16},
|
||||
{1, 32},
|
||||
{2, 64},
|
||||
{3, 128},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
RZV2H_CPG_PLL_DSI_LIMITS(rzv2n_cpg_pll_dsi_limits);
|
||||
#define PLLDSI PLL_PACK_LIMITS(0xc0, 1, 0, &rzv2n_cpg_pll_dsi_limits)
|
||||
|
||||
/* Mux clock tables */
|
||||
static const char * const smux2_gbe0_rxclk[] = { ".plleth_gbe0", "et0_rxclk" };
|
||||
static const char * const smux2_gbe0_txclk[] = { ".plleth_gbe0", "et0_txclk" };
|
||||
|
|
@ -112,7 +159,9 @@ static const struct cpg_core_clk r9a09g056_core_clks[] __initconst = {
|
|||
DEF_FIXED(".pllcln", CLK_PLLCLN, CLK_QEXTAL, 200, 3),
|
||||
DEF_FIXED(".plldty", CLK_PLLDTY, CLK_QEXTAL, 200, 3),
|
||||
DEF_PLL(".pllca55", CLK_PLLCA55, CLK_QEXTAL, PLLCA55),
|
||||
DEF_FIXED(".pllvdo", CLK_PLLVDO, CLK_QEXTAL, 105, 2),
|
||||
DEF_FIXED(".plleth", CLK_PLLETH, CLK_QEXTAL, 125, 3),
|
||||
DEF_PLLDSI(".plldsi", CLK_PLLDSI, CLK_QEXTAL, PLLDSI),
|
||||
DEF_PLL(".pllgpu", CLK_PLLGPU, CLK_QEXTAL, PLLGPU),
|
||||
|
||||
/* Internal Core Clocks */
|
||||
|
|
@ -134,6 +183,11 @@ static const struct cpg_core_clk r9a09g056_core_clks[] __initconst = {
|
|||
DEF_FIXED(".plldty_acpu_div2", CLK_PLLDTY_ACPU_DIV2, CLK_PLLDTY_ACPU, 1, 2),
|
||||
DEF_FIXED(".plldty_acpu_div4", CLK_PLLDTY_ACPU_DIV4, CLK_PLLDTY_ACPU, 1, 4),
|
||||
DEF_FIXED(".plldty_div8", CLK_PLLDTY_DIV8, CLK_PLLDTY, 1, 8),
|
||||
DEF_FIXED(".plldty_div16", CLK_PLLDTY_DIV16, CLK_PLLDTY, 1, 16),
|
||||
|
||||
DEF_DDIV(".pllvdo_cru0", CLK_PLLVDO_CRU0, CLK_PLLVDO, CDDIV3_DIVCTL3, dtable_2_4),
|
||||
DEF_DDIV(".pllvdo_cru1", CLK_PLLVDO_CRU1, CLK_PLLVDO, CDDIV4_DIVCTL0, dtable_2_4),
|
||||
DEF_DDIV(".pllvdo_isp", CLK_PLLVDO_ISP, CLK_PLLVDO, CDDIV2_DIVCTL3, dtable_2_64),
|
||||
|
||||
DEF_FIXED(".plleth_250_fix", CLK_PLLETH_DIV_250_FIX, CLK_PLLETH, 1, 4),
|
||||
DEF_FIXED(".plleth_125_fix", CLK_PLLETH_DIV_125_FIX, CLK_PLLETH_DIV_250_FIX, 1, 2),
|
||||
|
|
@ -145,6 +199,12 @@ static const struct cpg_core_clk r9a09g056_core_clks[] __initconst = {
|
|||
DEF_SMUX(".smux2_gbe0_rxclk", CLK_SMUX2_GBE0_RXCLK, SSEL0_SELCTL3, smux2_gbe0_rxclk),
|
||||
DEF_SMUX(".smux2_gbe1_txclk", CLK_SMUX2_GBE1_TXCLK, SSEL1_SELCTL0, smux2_gbe1_txclk),
|
||||
DEF_SMUX(".smux2_gbe1_rxclk", CLK_SMUX2_GBE1_RXCLK, SSEL1_SELCTL1, smux2_gbe1_rxclk),
|
||||
DEF_FIXED(".cdiv4_plleth_lpclk", CLK_CDIV4_PLLETH_LPCLK, CLK_PLLETH, 1, 4),
|
||||
DEF_CSDIV(".plleth_lpclk_gear", CLK_PLLETH_LPCLK_GEAR, CLK_CDIV4_PLLETH_LPCLK,
|
||||
CSDIV0_DIVCTL2, dtable_16_128),
|
||||
|
||||
DEF_PLLDSI_DIV(".plldsi_gear", CLK_PLLDSI_GEAR, CLK_PLLDSI,
|
||||
CSDIV1_DIVCTL2, dtable_2_32),
|
||||
|
||||
DEF_DDIV(".pllgpu_gear", CLK_PLLGPU_GEAR, CLK_PLLGPU, CDDIV3_DIVCTL1, dtable_2_64),
|
||||
|
||||
|
|
@ -166,6 +226,8 @@ static const struct cpg_core_clk r9a09g056_core_clks[] __initconst = {
|
|||
CLK_PLLETH_DIV_125_FIX, 1, 1),
|
||||
DEF_FIXED_MOD_STATUS("spi_clk_spi", R9A09G056_SPI_CLK_SPI, CLK_PLLCM33_XSPI, 1, 2,
|
||||
FIXED_MOD_CONF_XSPI),
|
||||
DEF_FIXED("usb3_0_ref_alt_clk_p", R9A09G056_USB3_0_REF_ALT_CLK_P, CLK_QEXTAL, 1, 1),
|
||||
DEF_FIXED("usb3_0_core_clk", R9A09G056_USB3_0_CLKCORE, CLK_QEXTAL, 1, 1),
|
||||
};
|
||||
|
||||
static const struct rzv2h_mod_clk r9a09g056_mod_clks[] __initconst = {
|
||||
|
|
@ -259,6 +321,10 @@ static const struct rzv2h_mod_clk r9a09g056_mod_clks[] __initconst = {
|
|||
BUS_MSTOP(8, BIT(4))),
|
||||
DEF_MOD("sdhi_2_aclk", CLK_PLLDTY_ACPU_DIV4, 10, 14, 5, 14,
|
||||
BUS_MSTOP(8, BIT(4))),
|
||||
DEF_MOD("usb3_0_aclk", CLK_PLLDTY_DIV8, 10, 15, 5, 15,
|
||||
BUS_MSTOP(7, BIT(12))),
|
||||
DEF_MOD("usb3_0_pclk_usbtst", CLK_PLLDTY_ACPU_DIV4, 11, 0, 5, 16,
|
||||
BUS_MSTOP(7, BIT(14))),
|
||||
DEF_MOD("usb2_0_u2h0_hclk", CLK_PLLDTY_DIV8, 11, 3, 5, 19,
|
||||
BUS_MSTOP(7, BIT(7))),
|
||||
DEF_MOD("usb2_0_u2p_exr_cpuclk", CLK_PLLDTY_ACPU_DIV4, 11, 5, 5, 21,
|
||||
|
|
@ -289,6 +355,42 @@ static const struct rzv2h_mod_clk r9a09g056_mod_clks[] __initconst = {
|
|||
BUS_MSTOP(8, BIT(6))),
|
||||
DEF_MOD("gbeth_1_aclk_i", CLK_PLLDTY_DIV8, 12, 3, 6, 3,
|
||||
BUS_MSTOP(8, BIT(6))),
|
||||
DEF_MOD("cru_0_aclk", CLK_PLLDTY_ACPU_DIV2, 13, 2, 6, 18,
|
||||
BUS_MSTOP(9, BIT(4))),
|
||||
DEF_MOD_NO_PM("cru_0_vclk", CLK_PLLVDO_CRU0, 13, 3, 6, 19,
|
||||
BUS_MSTOP(9, BIT(4))),
|
||||
DEF_MOD("cru_0_pclk", CLK_PLLDTY_DIV16, 13, 4, 6, 20,
|
||||
BUS_MSTOP(9, BIT(4))),
|
||||
DEF_MOD("cru_1_aclk", CLK_PLLDTY_ACPU_DIV2, 13, 5, 6, 21,
|
||||
BUS_MSTOP(9, BIT(5))),
|
||||
DEF_MOD_NO_PM("cru_1_vclk", CLK_PLLVDO_CRU1, 13, 6, 6, 22,
|
||||
BUS_MSTOP(9, BIT(5))),
|
||||
DEF_MOD("cru_1_pclk", CLK_PLLDTY_DIV16, 13, 7, 6, 23,
|
||||
BUS_MSTOP(9, BIT(5))),
|
||||
DEF_MOD("isp_0_reg_aclk", CLK_PLLDTY_ACPU_DIV2, 14, 2, 7, 2,
|
||||
BUS_MSTOP(9, BIT(8))),
|
||||
DEF_MOD("isp_0_pclk", CLK_PLLDTY_DIV16, 14, 3, 7, 3,
|
||||
BUS_MSTOP(9, BIT(8))),
|
||||
DEF_MOD("isp_0_vin_aclk", CLK_PLLDTY_ACPU_DIV2, 14, 4, 7, 4,
|
||||
BUS_MSTOP(9, BIT(9))),
|
||||
DEF_MOD("isp_0_isp_sclk", CLK_PLLVDO_ISP, 14, 5, 7, 5,
|
||||
BUS_MSTOP(9, BIT(9))),
|
||||
DEF_MOD("dsi_0_pclk", CLK_PLLDTY_DIV16, 14, 8, 7, 8,
|
||||
BUS_MSTOP(9, BIT(14) | BIT(15))),
|
||||
DEF_MOD("dsi_0_aclk", CLK_PLLDTY_ACPU_DIV2, 14, 9, 7, 9,
|
||||
BUS_MSTOP(9, BIT(14) | BIT(15))),
|
||||
DEF_MOD("dsi_0_vclk1", CLK_PLLDSI_GEAR, 14, 10, 7, 10,
|
||||
BUS_MSTOP(9, BIT(14) | BIT(15))),
|
||||
DEF_MOD("dsi_0_lpclk", CLK_PLLETH_LPCLK_GEAR, 14, 11, 7, 11,
|
||||
BUS_MSTOP(9, BIT(14) | BIT(15))),
|
||||
DEF_MOD("dsi_0_pllref_clk", CLK_QEXTAL, 14, 12, 7, 12,
|
||||
BUS_MSTOP(9, BIT(14) | BIT(15))),
|
||||
DEF_MOD("lcdc_0_clk_a", CLK_PLLDTY_ACPU_DIV2, 14, 13, 7, 13,
|
||||
BUS_MSTOP(10, BIT(1) | BIT(2) | BIT(3))),
|
||||
DEF_MOD("lcdc_0_clk_p", CLK_PLLDTY_DIV16, 14, 14, 7, 14,
|
||||
BUS_MSTOP(10, BIT(1) | BIT(2) | BIT(3))),
|
||||
DEF_MOD("lcdc_0_clk_d", CLK_PLLDSI_GEAR, 14, 15, 7, 15,
|
||||
BUS_MSTOP(10, BIT(1) | BIT(2) | BIT(3))),
|
||||
DEF_MOD("gpu_0_clk", CLK_PLLGPU_GEAR, 15, 0, 7, 16,
|
||||
BUS_MSTOP(3, BIT(4))),
|
||||
DEF_MOD("gpu_0_axi_clk", CLK_PLLDTY_ACPU_DIV2, 15, 1, 7, 17,
|
||||
|
|
@ -330,11 +432,25 @@ static const struct rzv2h_reset r9a09g056_resets[] __initconst = {
|
|||
DEF_RST(10, 7, 4, 24), /* SDHI_0_IXRST */
|
||||
DEF_RST(10, 8, 4, 25), /* SDHI_1_IXRST */
|
||||
DEF_RST(10, 9, 4, 26), /* SDHI_2_IXRST */
|
||||
DEF_RST(10, 10, 4, 27), /* USB3_0_ARESETN */
|
||||
DEF_RST(10, 12, 4, 29), /* USB2_0_U2H0_HRESETN */
|
||||
DEF_RST(10, 14, 4, 31), /* USB2_0_U2P_EXL_SYSRST */
|
||||
DEF_RST(10, 15, 5, 0), /* USB2_0_PRESETN */
|
||||
DEF_RST(11, 0, 5, 1), /* GBETH_0_ARESETN_I */
|
||||
DEF_RST(11, 1, 5, 2), /* GBETH_1_ARESETN_I */
|
||||
DEF_RST(12, 5, 5, 22), /* CRU_0_PRESETN */
|
||||
DEF_RST(12, 6, 5, 23), /* CRU_0_ARESETN */
|
||||
DEF_RST(12, 7, 5, 24), /* CRU_0_S_RESETN */
|
||||
DEF_RST(12, 8, 5, 25), /* CRU_1_PRESETN */
|
||||
DEF_RST(12, 9, 5, 26), /* CRU_1_ARESETN */
|
||||
DEF_RST(12, 10, 5, 27), /* CRU_1_S_RESETN */
|
||||
DEF_RST(13, 1, 6, 2), /* ISP_0_VIN_ARESETN */
|
||||
DEF_RST(13, 2, 6, 3), /* ISP_0_REG_ARESETN */
|
||||
DEF_RST(13, 3, 6, 4), /* ISP_0_ISP_SRESETN */
|
||||
DEF_RST(13, 4, 6, 5), /* ISP_0_PRESETN */
|
||||
DEF_RST(13, 7, 6, 8), /* DSI_0_PRESETN */
|
||||
DEF_RST(13, 8, 6, 9), /* DSI_0_ARESETN */
|
||||
DEF_RST(13, 12, 6, 13), /* LCDC_0_RESET_N */
|
||||
DEF_RST(13, 13, 6, 14), /* GPU_0_RESETN */
|
||||
DEF_RST(13, 14, 6, 15), /* GPU_0_AXI_RESETN */
|
||||
DEF_RST(13, 15, 6, 16), /* GPU_0_ACE_RESETN */
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/clk/renesas.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
|
|
@ -16,7 +17,7 @@
|
|||
|
||||
enum clk_ids {
|
||||
/* Core Clock Outputs exported to DT */
|
||||
LAST_DT_CORE_CLK = R9A09G057_SPI_CLK_SPI,
|
||||
LAST_DT_CORE_CLK = R9A09G057_USB3_1_CLKCORE,
|
||||
|
||||
/* External Input Clocks */
|
||||
CLK_AUDIO_EXTAL,
|
||||
|
|
@ -30,6 +31,7 @@ enum clk_ids {
|
|||
CLK_PLLCA55,
|
||||
CLK_PLLVDO,
|
||||
CLK_PLLETH,
|
||||
CLK_PLLDSI,
|
||||
CLK_PLLGPU,
|
||||
|
||||
/* Internal Core Clocks */
|
||||
|
|
@ -55,6 +57,7 @@ enum clk_ids {
|
|||
CLK_PLLVDO_CRU1,
|
||||
CLK_PLLVDO_CRU2,
|
||||
CLK_PLLVDO_CRU3,
|
||||
CLK_PLLVDO_ISP,
|
||||
CLK_PLLETH_DIV_250_FIX,
|
||||
CLK_PLLETH_DIV_125_FIX,
|
||||
CLK_CSDIV_PLLETH_GBE0,
|
||||
|
|
@ -63,6 +66,9 @@ enum clk_ids {
|
|||
CLK_SMUX2_GBE0_RXCLK,
|
||||
CLK_SMUX2_GBE1_TXCLK,
|
||||
CLK_SMUX2_GBE1_RXCLK,
|
||||
CLK_CDIV4_PLLETH_LPCLK,
|
||||
CLK_PLLETH_LPCLK_GEAR,
|
||||
CLK_PLLDSI_GEAR,
|
||||
CLK_PLLGPU_GEAR,
|
||||
|
||||
/* Module Clocks */
|
||||
|
|
@ -91,6 +97,26 @@ static const struct clk_div_table dtable_2_16[] = {
|
|||
{0, 0},
|
||||
};
|
||||
|
||||
static const struct clk_div_table dtable_2_32[] = {
|
||||
{0, 2},
|
||||
{1, 4},
|
||||
{2, 6},
|
||||
{3, 8},
|
||||
{4, 10},
|
||||
{5, 12},
|
||||
{6, 14},
|
||||
{7, 16},
|
||||
{8, 18},
|
||||
{9, 20},
|
||||
{10, 22},
|
||||
{11, 24},
|
||||
{12, 26},
|
||||
{13, 28},
|
||||
{14, 30},
|
||||
{15, 32},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
static const struct clk_div_table dtable_2_64[] = {
|
||||
{0, 2},
|
||||
{1, 4},
|
||||
|
|
@ -107,6 +133,17 @@ static const struct clk_div_table dtable_2_100[] = {
|
|||
{0, 0},
|
||||
};
|
||||
|
||||
static const struct clk_div_table dtable_16_128[] = {
|
||||
{0, 16},
|
||||
{1, 32},
|
||||
{2, 64},
|
||||
{3, 128},
|
||||
{0, 0},
|
||||
};
|
||||
|
||||
RZV2H_CPG_PLL_DSI_LIMITS(rzv2h_cpg_pll_dsi_limits);
|
||||
#define PLLDSI PLL_PACK_LIMITS(0xc0, 1, 0, &rzv2h_cpg_pll_dsi_limits)
|
||||
|
||||
/* Mux clock tables */
|
||||
static const char * const smux2_gbe0_rxclk[] = { ".plleth_gbe0", "et0_rxclk" };
|
||||
static const char * const smux2_gbe0_txclk[] = { ".plleth_gbe0", "et0_txclk" };
|
||||
|
|
@ -128,6 +165,7 @@ static const struct cpg_core_clk r9a09g057_core_clks[] __initconst = {
|
|||
DEF_PLL(".pllca55", CLK_PLLCA55, CLK_QEXTAL, PLLCA55),
|
||||
DEF_FIXED(".pllvdo", CLK_PLLVDO, CLK_QEXTAL, 105, 2),
|
||||
DEF_FIXED(".plleth", CLK_PLLETH, CLK_QEXTAL, 125, 3),
|
||||
DEF_PLLDSI(".plldsi", CLK_PLLDSI, CLK_QEXTAL, PLLDSI),
|
||||
DEF_PLL(".pllgpu", CLK_PLLGPU, CLK_QEXTAL, PLLGPU),
|
||||
|
||||
/* Internal Core Clocks */
|
||||
|
|
@ -157,6 +195,7 @@ static const struct cpg_core_clk r9a09g057_core_clks[] __initconst = {
|
|||
DEF_DDIV(".pllvdo_cru1", CLK_PLLVDO_CRU1, CLK_PLLVDO, CDDIV4_DIVCTL0, dtable_2_4),
|
||||
DEF_DDIV(".pllvdo_cru2", CLK_PLLVDO_CRU2, CLK_PLLVDO, CDDIV4_DIVCTL1, dtable_2_4),
|
||||
DEF_DDIV(".pllvdo_cru3", CLK_PLLVDO_CRU3, CLK_PLLVDO, CDDIV4_DIVCTL2, dtable_2_4),
|
||||
DEF_DDIV(".pllvdo_isp", CLK_PLLVDO_ISP, CLK_PLLVDO, CDDIV2_DIVCTL3, dtable_2_64),
|
||||
|
||||
DEF_FIXED(".plleth_250_fix", CLK_PLLETH_DIV_250_FIX, CLK_PLLETH, 1, 4),
|
||||
DEF_FIXED(".plleth_125_fix", CLK_PLLETH_DIV_125_FIX, CLK_PLLETH_DIV_250_FIX, 1, 2),
|
||||
|
|
@ -168,6 +207,12 @@ static const struct cpg_core_clk r9a09g057_core_clks[] __initconst = {
|
|||
DEF_SMUX(".smux2_gbe0_rxclk", CLK_SMUX2_GBE0_RXCLK, SSEL0_SELCTL3, smux2_gbe0_rxclk),
|
||||
DEF_SMUX(".smux2_gbe1_txclk", CLK_SMUX2_GBE1_TXCLK, SSEL1_SELCTL0, smux2_gbe1_txclk),
|
||||
DEF_SMUX(".smux2_gbe1_rxclk", CLK_SMUX2_GBE1_RXCLK, SSEL1_SELCTL1, smux2_gbe1_rxclk),
|
||||
DEF_FIXED(".cdiv4_plleth_lpclk", CLK_CDIV4_PLLETH_LPCLK, CLK_PLLETH, 1, 4),
|
||||
DEF_CSDIV(".plleth_lpclk_gear", CLK_PLLETH_LPCLK_GEAR, CLK_CDIV4_PLLETH_LPCLK,
|
||||
CSDIV0_DIVCTL2, dtable_16_128),
|
||||
|
||||
DEF_PLLDSI_DIV(".plldsi_gear", CLK_PLLDSI_GEAR, CLK_PLLDSI,
|
||||
CSDIV1_DIVCTL2, dtable_2_32),
|
||||
|
||||
DEF_DDIV(".pllgpu_gear", CLK_PLLGPU_GEAR, CLK_PLLGPU, CDDIV3_DIVCTL1, dtable_2_64),
|
||||
|
||||
|
|
@ -190,6 +235,10 @@ static const struct cpg_core_clk r9a09g057_core_clks[] __initconst = {
|
|||
CLK_PLLETH_DIV_125_FIX, 1, 1),
|
||||
DEF_FIXED_MOD_STATUS("spi_clk_spi", R9A09G057_SPI_CLK_SPI, CLK_PLLCM33_XSPI, 1, 2,
|
||||
FIXED_MOD_CONF_XSPI),
|
||||
DEF_FIXED("usb3_0_ref_alt_clk_p", R9A09G057_USB3_0_REF_ALT_CLK_P, CLK_QEXTAL, 1, 1),
|
||||
DEF_FIXED("usb3_0_core_clk", R9A09G057_USB3_0_CLKCORE, CLK_QEXTAL, 1, 1),
|
||||
DEF_FIXED("usb3_1_ref_alt_clk_p", R9A09G057_USB3_1_REF_ALT_CLK_P, CLK_QEXTAL, 1, 1),
|
||||
DEF_FIXED("usb3_1_core_clk", R9A09G057_USB3_1_CLKCORE, CLK_QEXTAL, 1, 1),
|
||||
};
|
||||
|
||||
static const struct rzv2h_mod_clk r9a09g057_mod_clks[] __initconst = {
|
||||
|
|
@ -239,6 +288,8 @@ static const struct rzv2h_mod_clk r9a09g057_mod_clks[] __initconst = {
|
|||
BUS_MSTOP(5, BIT(13))),
|
||||
DEF_MOD("wdt_3_clk_loco", CLK_QEXTAL, 5, 2, 2, 18,
|
||||
BUS_MSTOP(5, BIT(13))),
|
||||
DEF_MOD("rtc_0_clk_rtc", CLK_PLLCM33_DIV16, 5, 3, 2, 19,
|
||||
BUS_MSTOP(3, BIT(11) | BIT(12))),
|
||||
DEF_MOD("rspi_0_pclk", CLK_PLLCLN_DIV8, 5, 4, 2, 20,
|
||||
BUS_MSTOP(11, BIT(0))),
|
||||
DEF_MOD("rspi_0_pclk_sfr", CLK_PLLCLN_DIV8, 5, 5, 2, 21,
|
||||
|
|
@ -313,6 +364,14 @@ static const struct rzv2h_mod_clk r9a09g057_mod_clks[] __initconst = {
|
|||
BUS_MSTOP(8, BIT(4))),
|
||||
DEF_MOD("sdhi_2_aclk", CLK_PLLDTY_ACPU_DIV4, 10, 14, 5, 14,
|
||||
BUS_MSTOP(8, BIT(4))),
|
||||
DEF_MOD("usb3_0_aclk", CLK_PLLDTY_DIV8, 10, 15, 5, 15,
|
||||
BUS_MSTOP(7, BIT(12))),
|
||||
DEF_MOD("usb3_0_pclk_usbtst", CLK_PLLDTY_ACPU_DIV4, 11, 0, 5, 16,
|
||||
BUS_MSTOP(7, BIT(14))),
|
||||
DEF_MOD("usb3_1_aclk", CLK_PLLDTY_DIV8, 11, 1, 5, 17,
|
||||
BUS_MSTOP(7, BIT(13))),
|
||||
DEF_MOD("usb3_1_pclk_usbtst", CLK_PLLDTY_ACPU_DIV4, 11, 2, 5, 18,
|
||||
BUS_MSTOP(7, BIT(15))),
|
||||
DEF_MOD("usb2_0_u2h0_hclk", CLK_PLLDTY_DIV8, 11, 3, 5, 19,
|
||||
BUS_MSTOP(7, BIT(7))),
|
||||
DEF_MOD("usb2_0_u2h1_hclk", CLK_PLLDTY_DIV8, 11, 4, 5, 20,
|
||||
|
|
@ -371,12 +430,40 @@ static const struct rzv2h_mod_clk r9a09g057_mod_clks[] __initconst = {
|
|||
BUS_MSTOP(9, BIT(7))),
|
||||
DEF_MOD("cru_3_pclk", CLK_PLLDTY_DIV16, 13, 13, 6, 29,
|
||||
BUS_MSTOP(9, BIT(7))),
|
||||
DEF_MOD("isp_0_reg_aclk", CLK_PLLDTY_ACPU_DIV2, 14, 2, 7, 2,
|
||||
BUS_MSTOP(9, BIT(8))),
|
||||
DEF_MOD("isp_0_pclk", CLK_PLLDTY_DIV16, 14, 3, 7, 3,
|
||||
BUS_MSTOP(9, BIT(8))),
|
||||
DEF_MOD("isp_0_vin_aclk", CLK_PLLDTY_ACPU_DIV2, 14, 4, 7, 4,
|
||||
BUS_MSTOP(9, BIT(9))),
|
||||
DEF_MOD("isp_0_isp_sclk", CLK_PLLVDO_ISP, 14, 5, 7, 5,
|
||||
BUS_MSTOP(9, BIT(9))),
|
||||
DEF_MOD("dsi_0_pclk", CLK_PLLDTY_DIV16, 14, 8, 7, 8,
|
||||
BUS_MSTOP(9, BIT(14) | BIT(15))),
|
||||
DEF_MOD("dsi_0_aclk", CLK_PLLDTY_ACPU_DIV2, 14, 9, 7, 9,
|
||||
BUS_MSTOP(9, BIT(14) | BIT(15))),
|
||||
DEF_MOD("dsi_0_vclk1", CLK_PLLDSI_GEAR, 14, 10, 7, 10,
|
||||
BUS_MSTOP(9, BIT(14) | BIT(15))),
|
||||
DEF_MOD("dsi_0_lpclk", CLK_PLLETH_LPCLK_GEAR, 14, 11, 7, 11,
|
||||
BUS_MSTOP(9, BIT(14) | BIT(15))),
|
||||
DEF_MOD("dsi_0_pllref_clk", CLK_QEXTAL, 14, 12, 7, 12,
|
||||
BUS_MSTOP(9, BIT(14) | BIT(15))),
|
||||
DEF_MOD("lcdc_0_clk_a", CLK_PLLDTY_ACPU_DIV2, 14, 13, 7, 13,
|
||||
BUS_MSTOP(10, BIT(1) | BIT(2) | BIT(3))),
|
||||
DEF_MOD("lcdc_0_clk_p", CLK_PLLDTY_DIV16, 14, 14, 7, 14,
|
||||
BUS_MSTOP(10, BIT(1) | BIT(2) | BIT(3))),
|
||||
DEF_MOD("lcdc_0_clk_d", CLK_PLLDSI_GEAR, 14, 15, 7, 15,
|
||||
BUS_MSTOP(10, BIT(1) | BIT(2) | BIT(3))),
|
||||
DEF_MOD("gpu_0_clk", CLK_PLLGPU_GEAR, 15, 0, 7, 16,
|
||||
BUS_MSTOP(3, BIT(4))),
|
||||
DEF_MOD("gpu_0_axi_clk", CLK_PLLDTY_ACPU_DIV2, 15, 1, 7, 17,
|
||||
BUS_MSTOP(3, BIT(4))),
|
||||
DEF_MOD("gpu_0_ace_clk", CLK_PLLDTY_ACPU_DIV2, 15, 2, 7, 18,
|
||||
BUS_MSTOP(3, BIT(4))),
|
||||
DEF_MOD("tsu_0_pclk", CLK_QEXTAL, 16, 9, 8, 9,
|
||||
BUS_MSTOP(5, BIT(2))),
|
||||
DEF_MOD("tsu_1_pclk", CLK_QEXTAL, 16, 10, 8, 10,
|
||||
BUS_MSTOP(2, BIT(15))),
|
||||
};
|
||||
|
||||
static const struct rzv2h_reset r9a09g057_resets[] __initconst = {
|
||||
|
|
@ -401,6 +488,8 @@ static const struct rzv2h_reset r9a09g057_resets[] __initconst = {
|
|||
DEF_RST(7, 6, 3, 7), /* WDT_1_RESET */
|
||||
DEF_RST(7, 7, 3, 8), /* WDT_2_RESET */
|
||||
DEF_RST(7, 8, 3, 9), /* WDT_3_RESET */
|
||||
DEF_RST(7, 9, 3, 10), /* RTC_0_RST_RTC */
|
||||
DEF_RST(7, 10, 3, 11), /* RTC_0_RST_RTC_V */
|
||||
DEF_RST(7, 11, 3, 12), /* RSPI_0_PRESETN */
|
||||
DEF_RST(7, 12, 3, 13), /* RSPI_0_TRESETN */
|
||||
DEF_RST(7, 13, 3, 14), /* RSPI_1_PRESETN */
|
||||
|
|
@ -424,6 +513,8 @@ static const struct rzv2h_reset r9a09g057_resets[] __initconst = {
|
|||
DEF_RST(10, 7, 4, 24), /* SDHI_0_IXRST */
|
||||
DEF_RST(10, 8, 4, 25), /* SDHI_1_IXRST */
|
||||
DEF_RST(10, 9, 4, 26), /* SDHI_2_IXRST */
|
||||
DEF_RST(10, 10, 4, 27), /* USB3_0_ARESETN */
|
||||
DEF_RST(10, 11, 4, 28), /* USB3_1_ARESETN */
|
||||
DEF_RST(10, 12, 4, 29), /* USB2_0_U2H0_HRESETN */
|
||||
DEF_RST(10, 13, 4, 30), /* USB2_0_U2H1_HRESETN */
|
||||
DEF_RST(10, 14, 4, 31), /* USB2_0_U2P_EXL_SYSRST */
|
||||
|
|
@ -442,9 +533,18 @@ static const struct rzv2h_reset r9a09g057_resets[] __initconst = {
|
|||
DEF_RST(12, 14, 5, 31), /* CRU_3_PRESETN */
|
||||
DEF_RST(12, 15, 6, 0), /* CRU_3_ARESETN */
|
||||
DEF_RST(13, 0, 6, 1), /* CRU_3_S_RESETN */
|
||||
DEF_RST(13, 1, 6, 2), /* ISP_0_VIN_ARESETN */
|
||||
DEF_RST(13, 2, 6, 3), /* ISP_0_REG_ARESETN */
|
||||
DEF_RST(13, 3, 6, 4), /* ISP_0_ISP_SRESETN */
|
||||
DEF_RST(13, 4, 6, 5), /* ISP_0_PRESETN */
|
||||
DEF_RST(13, 7, 6, 8), /* DSI_0_PRESETN */
|
||||
DEF_RST(13, 8, 6, 9), /* DSI_0_ARESETN */
|
||||
DEF_RST(13, 12, 6, 13), /* LCDC_0_RESET_N */
|
||||
DEF_RST(13, 13, 6, 14), /* GPU_0_RESETN */
|
||||
DEF_RST(13, 14, 6, 15), /* GPU_0_AXI_RESETN */
|
||||
DEF_RST(13, 15, 6, 16), /* GPU_0_ACE_RESETN */
|
||||
DEF_RST(15, 7, 7, 8), /* TSU_0_PRESETN */
|
||||
DEF_RST(15, 8, 7, 9), /* TSU_1_PRESETN */
|
||||
};
|
||||
|
||||
const struct rzv2h_cpg_info r9a09g057_cpg_info __initconst = {
|
||||
|
|
|
|||
|
|
@ -46,8 +46,12 @@
|
|||
#define DIVCA55C2 CONF_PACK(SCKCR2, 10, 1)
|
||||
#define DIVCA55C3 CONF_PACK(SCKCR2, 11, 1)
|
||||
#define DIVCA55S CONF_PACK(SCKCR2, 12, 1)
|
||||
#define DIVSPI3ASYNC CONF_PACK(SCKCR2, 16, 2)
|
||||
#define DIVSCI5ASYNC CONF_PACK(SCKCR2, 18, 2)
|
||||
|
||||
#define DIVSPI0ASYNC CONF_PACK(SCKCR3, 0, 2)
|
||||
#define DIVSPI1ASYNC CONF_PACK(SCKCR3, 2, 2)
|
||||
#define DIVSPI2ASYNC CONF_PACK(SCKCR3, 4, 2)
|
||||
#define DIVSCI0ASYNC CONF_PACK(SCKCR3, 6, 2)
|
||||
#define DIVSCI1ASYNC CONF_PACK(SCKCR3, 8, 2)
|
||||
#define DIVSCI2ASYNC CONF_PACK(SCKCR3, 10, 2)
|
||||
|
|
@ -56,7 +60,6 @@
|
|||
|
||||
#define SEL_PLL CONF_PACK(SCKCR, 22, 1)
|
||||
|
||||
|
||||
enum rzt2h_clk_types {
|
||||
CLK_TYPE_RZT2H_DIV = CLK_TYPE_CUSTOM, /* Clock with divider */
|
||||
CLK_TYPE_RZT2H_MUX, /* Clock with clock source selector */
|
||||
|
|
@ -94,6 +97,10 @@ enum clk_ids {
|
|||
CLK_SCI3ASYNC,
|
||||
CLK_SCI4ASYNC,
|
||||
CLK_SCI5ASYNC,
|
||||
CLK_SPI0ASYNC,
|
||||
CLK_SPI1ASYNC,
|
||||
CLK_SPI2ASYNC,
|
||||
CLK_SPI3ASYNC,
|
||||
|
||||
/* Module Clocks */
|
||||
MOD_CLK_BASE,
|
||||
|
|
@ -154,6 +161,15 @@ static const struct cpg_core_clk r9a09g077_core_clks[] __initconst = {
|
|||
DEF_DIV(".sci5async", CLK_SCI5ASYNC, CLK_PLL4D1, DIVSCI5ASYNC,
|
||||
dtable_24_25_30_32),
|
||||
|
||||
DEF_DIV(".spi0async", CLK_SPI0ASYNC, CLK_PLL4D1, DIVSPI0ASYNC,
|
||||
dtable_24_25_30_32),
|
||||
DEF_DIV(".spi1async", CLK_SPI1ASYNC, CLK_PLL4D1, DIVSPI1ASYNC,
|
||||
dtable_24_25_30_32),
|
||||
DEF_DIV(".spi2async", CLK_SPI2ASYNC, CLK_PLL4D1, DIVSPI2ASYNC,
|
||||
dtable_24_25_30_32),
|
||||
DEF_DIV(".spi3async", CLK_SPI3ASYNC, CLK_PLL4D1, DIVSPI3ASYNC,
|
||||
dtable_24_25_30_32),
|
||||
|
||||
/* Core output clk */
|
||||
DEF_DIV("CA55C0", R9A09G077_CLK_CA55C0, CLK_SEL_CLK_PLL0, DIVCA55C0,
|
||||
dtable_1_2),
|
||||
|
|
@ -188,6 +204,13 @@ static const struct mssr_mod_clk r9a09g077_mod_clks[] __initconst = {
|
|||
DEF_MOD("sci4fck", 12, CLK_SCI4ASYNC),
|
||||
DEF_MOD("iic0", 100, R9A09G077_CLK_PCLKL),
|
||||
DEF_MOD("iic1", 101, R9A09G077_CLK_PCLKL),
|
||||
DEF_MOD("spi0", 104, CLK_SPI0ASYNC),
|
||||
DEF_MOD("spi1", 105, CLK_SPI1ASYNC),
|
||||
DEF_MOD("spi2", 106, CLK_SPI2ASYNC),
|
||||
DEF_MOD("adc0", 206, R9A09G077_CLK_PCLKH),
|
||||
DEF_MOD("adc1", 207, R9A09G077_CLK_PCLKH),
|
||||
DEF_MOD("adc2", 225, R9A09G077_CLK_PCLKM),
|
||||
DEF_MOD("tsu", 307, R9A09G077_CLK_PCLKL),
|
||||
DEF_MOD("gmac0", 400, R9A09G077_CLK_PCLKM),
|
||||
DEF_MOD("ethsw", 401, R9A09G077_CLK_PCLKM),
|
||||
DEF_MOD("ethss", 403, R9A09G077_CLK_PCLKM),
|
||||
|
|
@ -196,6 +219,7 @@ static const struct mssr_mod_clk r9a09g077_mod_clks[] __initconst = {
|
|||
DEF_MOD("gmac2", 417, R9A09G077_CLK_PCLKAM),
|
||||
DEF_MOD("sci5fck", 600, CLK_SCI5ASYNC),
|
||||
DEF_MOD("iic2", 601, R9A09G077_CLK_PCLKL),
|
||||
DEF_MOD("spi3", 602, CLK_SPI3ASYNC),
|
||||
DEF_MOD("sdhi0", 1212, R9A09G077_CLK_PCLKAM),
|
||||
DEF_MOD("sdhi1", 1213, R9A09G077_CLK_PCLKAM),
|
||||
};
|
||||
|
|
@ -216,27 +240,28 @@ r9a09g077_cpg_div_clk_register(struct device *dev,
|
|||
parent_name = __clk_get_name(parent);
|
||||
|
||||
if (core->dtable)
|
||||
clk_hw = clk_hw_register_divider_table(dev, core->name,
|
||||
parent_name, 0,
|
||||
addr,
|
||||
GET_SHIFT(core->conf),
|
||||
GET_WIDTH(core->conf),
|
||||
core->flag,
|
||||
core->dtable,
|
||||
&pub->rmw_lock);
|
||||
clk_hw = devm_clk_hw_register_divider_table(dev, core->name,
|
||||
parent_name,
|
||||
CLK_SET_RATE_PARENT,
|
||||
addr,
|
||||
GET_SHIFT(core->conf),
|
||||
GET_WIDTH(core->conf),
|
||||
core->flag,
|
||||
core->dtable,
|
||||
&pub->rmw_lock);
|
||||
else
|
||||
clk_hw = clk_hw_register_divider(dev, core->name,
|
||||
parent_name, 0,
|
||||
addr,
|
||||
GET_SHIFT(core->conf),
|
||||
GET_WIDTH(core->conf),
|
||||
core->flag, &pub->rmw_lock);
|
||||
clk_hw = devm_clk_hw_register_divider(dev, core->name,
|
||||
parent_name,
|
||||
CLK_SET_RATE_PARENT,
|
||||
addr,
|
||||
GET_SHIFT(core->conf),
|
||||
GET_WIDTH(core->conf),
|
||||
core->flag, &pub->rmw_lock);
|
||||
|
||||
if (IS_ERR(clk_hw))
|
||||
return ERR_CAST(clk_hw);
|
||||
|
||||
return clk_hw->clk;
|
||||
|
||||
}
|
||||
|
||||
static struct clk * __init
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ void cpg_reg_modify(void __iomem *reg, u32 clear, u32 set)
|
|||
val |= set;
|
||||
writel(val, reg);
|
||||
spin_unlock_irqrestore(&cpg_lock, flags);
|
||||
};
|
||||
}
|
||||
|
||||
static int cpg_simple_notifier_call(struct notifier_block *nb,
|
||||
unsigned long action, void *data)
|
||||
|
|
|
|||
|
|
@ -257,7 +257,7 @@ static struct clk * __init cpg_pll_clk_register(const char *name,
|
|||
}
|
||||
|
||||
/*
|
||||
* Z0 Clock & Z1 Clock
|
||||
* Z0, Z1 and ZG Clock
|
||||
*/
|
||||
#define CPG_FRQCRB 0x00000804
|
||||
#define CPG_FRQCRB_KICK BIT(31)
|
||||
|
|
@ -386,9 +386,14 @@ static struct clk * __init cpg_z_clk_register(const char *name,
|
|||
|
||||
if (offset < 32) {
|
||||
zclk->reg = reg + CPG_FRQCRC0;
|
||||
} else {
|
||||
} else if (offset < 64) {
|
||||
zclk->reg = reg + CPG_FRQCRC1;
|
||||
offset -= 32;
|
||||
} else if (offset < 96) {
|
||||
zclk->reg = reg + CPG_FRQCRB;
|
||||
offset -= 64;
|
||||
} else {
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
zclk->kick_reg = reg + CPG_FRQCRB;
|
||||
zclk->hw.init = &init;
|
||||
|
|
|
|||
|
|
@ -40,8 +40,10 @@
|
|||
#define WARN_DEBUG(x) do { } while (0)
|
||||
#endif
|
||||
|
||||
#define RZT2H_RESET_REG_READ_COUNT 7
|
||||
|
||||
/*
|
||||
* Module Standby and Software Reset register offets.
|
||||
* Module Standby and Software Reset register offsets.
|
||||
*
|
||||
* If the registers exist, these are valid for SH-Mobile, R-Mobile,
|
||||
* R-Car Gen2, R-Car Gen3, and RZ/G1.
|
||||
|
|
@ -137,6 +139,22 @@ static const u16 srcr_for_gen4[] = {
|
|||
0x2C60, 0x2C64, 0x2C68, 0x2C6C, 0x2C70, 0x2C74,
|
||||
};
|
||||
|
||||
static const u16 mrcr_for_rzt2h[] = {
|
||||
0x240, /* MRCTLA */
|
||||
0x244, /* Reserved */
|
||||
0x248, /* Reserved */
|
||||
0x24C, /* Reserved */
|
||||
0x250, /* MRCTLE */
|
||||
0x254, /* Reserved */
|
||||
0x258, /* Reserved */
|
||||
0x25C, /* Reserved */
|
||||
0x260, /* MRCTLI */
|
||||
0x264, /* Reserved */
|
||||
0x268, /* Reserved */
|
||||
0x26C, /* Reserved */
|
||||
0x270, /* MRCTLM */
|
||||
};
|
||||
|
||||
/*
|
||||
* Software Reset Clearing Register offsets
|
||||
*/
|
||||
|
|
@ -290,10 +308,21 @@ static int cpg_mstp_clock_endisable(struct clk_hw *hw, bool enable)
|
|||
|
||||
spin_unlock_irqrestore(&priv->pub.rmw_lock, flags);
|
||||
|
||||
if (!enable || priv->reg_layout == CLK_REG_LAYOUT_RZ_A ||
|
||||
priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H)
|
||||
if (!enable || priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
|
||||
return 0;
|
||||
|
||||
if (priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H) {
|
||||
/*
|
||||
* For the RZ/T2H case, it is necessary to perform a read-back after
|
||||
* accessing the MSTPCRm register and to dummy-read any register of
|
||||
* the IP at least seven times. Instead of memory-mapping the IP
|
||||
* register, we simply add a delay after the read operation.
|
||||
*/
|
||||
cpg_rzt2h_mstp_read(hw, priv->control_regs[reg]);
|
||||
udelay(10);
|
||||
return 0;
|
||||
}
|
||||
|
||||
error = readl_poll_timeout_atomic(priv->pub.base0 + priv->status_regs[reg],
|
||||
value, !(value & bitmask), 0, 10);
|
||||
if (error)
|
||||
|
|
@ -451,7 +480,7 @@ static void __init cpg_mssr_register_core_clk(const struct cpg_core_clk *core,
|
|||
break;
|
||||
}
|
||||
|
||||
if (IS_ERR_OR_NULL(clk))
|
||||
if (IS_ERR(clk))
|
||||
goto fail;
|
||||
|
||||
dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk));
|
||||
|
|
@ -676,53 +705,56 @@ static int __init cpg_mssr_add_clk_domain(struct device *dev,
|
|||
|
||||
#define rcdev_to_priv(x) container_of(x, struct cpg_mssr_priv, rcdev)
|
||||
|
||||
static int cpg_mssr_reset(struct reset_controller_dev *rcdev,
|
||||
unsigned long id)
|
||||
static int cpg_mssr_reset_operate(struct reset_controller_dev *rcdev,
|
||||
const char *func, bool set, unsigned long id)
|
||||
{
|
||||
struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev);
|
||||
unsigned int reg = id / 32;
|
||||
unsigned int bit = id % 32;
|
||||
const u16 off = set ? priv->reset_regs[reg] : priv->reset_clear_regs[reg];
|
||||
u32 bitmask = BIT(bit);
|
||||
|
||||
dev_dbg(priv->dev, "reset %u%02u\n", reg, bit);
|
||||
if (func)
|
||||
dev_dbg(priv->dev, "%s %u%02u\n", func, reg, bit);
|
||||
|
||||
/* Reset module */
|
||||
writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]);
|
||||
|
||||
/* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */
|
||||
udelay(35);
|
||||
|
||||
/* Release module from reset state */
|
||||
writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]);
|
||||
writel(bitmask, priv->pub.base0 + off);
|
||||
readl(priv->pub.base0 + off);
|
||||
barrier_data(priv->pub.base0 + off);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cpg_mssr_assert(struct reset_controller_dev *rcdev, unsigned long id)
|
||||
static int cpg_mssr_reset(struct reset_controller_dev *rcdev,
|
||||
unsigned long id)
|
||||
{
|
||||
struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev);
|
||||
unsigned int reg = id / 32;
|
||||
unsigned int bit = id % 32;
|
||||
u32 bitmask = BIT(bit);
|
||||
|
||||
dev_dbg(priv->dev, "assert %u%02u\n", reg, bit);
|
||||
/* Reset module */
|
||||
cpg_mssr_reset_operate(rcdev, "reset", true, id);
|
||||
|
||||
writel(bitmask, priv->pub.base0 + priv->reset_regs[reg]);
|
||||
return 0;
|
||||
/*
|
||||
* On R-Car Gen4, delay after SRCR has been written is 1ms.
|
||||
* On older SoCs, delay after SRCR has been written is 35us
|
||||
* (one cycle of the RCLK clock @ ca. 32 kHz).
|
||||
*/
|
||||
if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_GEN4)
|
||||
usleep_range(1000, 2000);
|
||||
else
|
||||
usleep_range(35, 1000);
|
||||
|
||||
/* Release module from reset state */
|
||||
return cpg_mssr_reset_operate(rcdev, NULL, false, id);
|
||||
}
|
||||
|
||||
static int cpg_mssr_assert(struct reset_controller_dev *rcdev, unsigned long id)
|
||||
{
|
||||
return cpg_mssr_reset_operate(rcdev, "assert", true, id);
|
||||
}
|
||||
|
||||
static int cpg_mssr_deassert(struct reset_controller_dev *rcdev,
|
||||
unsigned long id)
|
||||
{
|
||||
struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev);
|
||||
unsigned int reg = id / 32;
|
||||
unsigned int bit = id % 32;
|
||||
u32 bitmask = BIT(bit);
|
||||
|
||||
dev_dbg(priv->dev, "deassert %u%02u\n", reg, bit);
|
||||
|
||||
writel(bitmask, priv->pub.base0 + priv->reset_clear_regs[reg]);
|
||||
return 0;
|
||||
return cpg_mssr_reset_operate(rcdev, "deassert", false, id);
|
||||
}
|
||||
|
||||
static int cpg_mssr_status(struct reset_controller_dev *rcdev,
|
||||
|
|
@ -736,6 +768,72 @@ static int cpg_mssr_status(struct reset_controller_dev *rcdev,
|
|||
return !!(readl(priv->pub.base0 + priv->reset_regs[reg]) & bitmask);
|
||||
}
|
||||
|
||||
static int cpg_mrcr_set_reset_state(struct reset_controller_dev *rcdev,
|
||||
unsigned long id, bool set)
|
||||
{
|
||||
struct cpg_mssr_priv *priv = rcdev_to_priv(rcdev);
|
||||
unsigned int reg = id / 32;
|
||||
unsigned int bit = id % 32;
|
||||
u32 bitmask = BIT(bit);
|
||||
void __iomem *reg_addr;
|
||||
unsigned long flags;
|
||||
unsigned int i;
|
||||
u32 val;
|
||||
|
||||
dev_dbg(priv->dev, "%s %u%02u\n", set ? "assert" : "deassert", reg, bit);
|
||||
|
||||
spin_lock_irqsave(&priv->pub.rmw_lock, flags);
|
||||
|
||||
reg_addr = priv->pub.base0 + priv->reset_regs[reg];
|
||||
/* Read current value and modify */
|
||||
val = readl(reg_addr);
|
||||
if (set)
|
||||
val |= bitmask;
|
||||
else
|
||||
val &= ~bitmask;
|
||||
writel(val, reg_addr);
|
||||
|
||||
/*
|
||||
* For secure processing after release from a module reset, one must
|
||||
* perform multiple dummy reads of the same register.
|
||||
*/
|
||||
for (i = 0; !set && i < RZT2H_RESET_REG_READ_COUNT; i++)
|
||||
readl(reg_addr);
|
||||
|
||||
/* Verify the operation */
|
||||
val = readl(reg_addr);
|
||||
if (set == !(bitmask & val)) {
|
||||
dev_err(priv->dev, "Reset register %u%02u operation failed\n", reg, bit);
|
||||
spin_unlock_irqrestore(&priv->pub.rmw_lock, flags);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
spin_unlock_irqrestore(&priv->pub.rmw_lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cpg_mrcr_reset(struct reset_controller_dev *rcdev, unsigned long id)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = cpg_mrcr_set_reset_state(rcdev, id, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return cpg_mrcr_set_reset_state(rcdev, id, false);
|
||||
}
|
||||
|
||||
static int cpg_mrcr_assert(struct reset_controller_dev *rcdev, unsigned long id)
|
||||
{
|
||||
return cpg_mrcr_set_reset_state(rcdev, id, true);
|
||||
}
|
||||
|
||||
static int cpg_mrcr_deassert(struct reset_controller_dev *rcdev, unsigned long id)
|
||||
{
|
||||
return cpg_mrcr_set_reset_state(rcdev, id, false);
|
||||
}
|
||||
|
||||
static const struct reset_control_ops cpg_mssr_reset_ops = {
|
||||
.reset = cpg_mssr_reset,
|
||||
.assert = cpg_mssr_assert,
|
||||
|
|
@ -743,6 +841,13 @@ static const struct reset_control_ops cpg_mssr_reset_ops = {
|
|||
.status = cpg_mssr_status,
|
||||
};
|
||||
|
||||
static const struct reset_control_ops cpg_mrcr_reset_ops = {
|
||||
.reset = cpg_mrcr_reset,
|
||||
.assert = cpg_mrcr_assert,
|
||||
.deassert = cpg_mrcr_deassert,
|
||||
.status = cpg_mssr_status,
|
||||
};
|
||||
|
||||
static int cpg_mssr_reset_xlate(struct reset_controller_dev *rcdev,
|
||||
const struct of_phandle_args *reset_spec)
|
||||
{
|
||||
|
|
@ -760,11 +865,23 @@ static int cpg_mssr_reset_xlate(struct reset_controller_dev *rcdev,
|
|||
|
||||
static int cpg_mssr_reset_controller_register(struct cpg_mssr_priv *priv)
|
||||
{
|
||||
priv->rcdev.ops = &cpg_mssr_reset_ops;
|
||||
/*
|
||||
* RZ/T2H (and family) has the Module Reset Control Registers
|
||||
* which allows control resets of certain modules.
|
||||
* The number of resets is not equal to the number of module clocks.
|
||||
*/
|
||||
if (priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H) {
|
||||
priv->rcdev.ops = &cpg_mrcr_reset_ops;
|
||||
priv->rcdev.nr_resets = ARRAY_SIZE(mrcr_for_rzt2h) * 32;
|
||||
} else {
|
||||
priv->rcdev.ops = &cpg_mssr_reset_ops;
|
||||
priv->rcdev.nr_resets = priv->num_mod_clks;
|
||||
}
|
||||
|
||||
priv->rcdev.of_node = priv->dev->of_node;
|
||||
priv->rcdev.of_reset_n_cells = 1;
|
||||
priv->rcdev.of_xlate = cpg_mssr_reset_xlate;
|
||||
priv->rcdev.nr_resets = priv->num_mod_clks;
|
||||
|
||||
return devm_reset_controller_register(priv->dev, &priv->rcdev);
|
||||
}
|
||||
|
||||
|
|
@ -1169,6 +1286,7 @@ static int __init cpg_mssr_common_init(struct device *dev,
|
|||
priv->control_regs = stbcr;
|
||||
} else if (priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H) {
|
||||
priv->control_regs = mstpcr_for_rzt2h;
|
||||
priv->reset_regs = mrcr_for_rzt2h;
|
||||
} else if (priv->reg_layout == CLK_REG_LAYOUT_RCAR_GEN4) {
|
||||
priv->status_regs = mstpsr_for_gen4;
|
||||
priv->control_regs = mstpcr_for_gen4;
|
||||
|
|
@ -1265,8 +1383,7 @@ static int __init cpg_mssr_probe(struct platform_device *pdev)
|
|||
goto reserve_exit;
|
||||
|
||||
/* Reset Controller not supported for Standby Control SoCs */
|
||||
if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A ||
|
||||
priv->reg_layout == CLK_REG_LAYOUT_RZ_T2H)
|
||||
if (priv->reg_layout == CLK_REG_LAYOUT_RZ_A)
|
||||
goto reserve_exit;
|
||||
|
||||
error = cpg_mssr_reset_controller_register(priv);
|
||||
|
|
|
|||
|
|
@ -1177,7 +1177,7 @@ rzg2l_cpg_register_core_clk(const struct cpg_core_clk *core,
|
|||
goto fail;
|
||||
}
|
||||
|
||||
if (IS_ERR_OR_NULL(clk))
|
||||
if (IS_ERR(clk))
|
||||
goto fail;
|
||||
|
||||
dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk));
|
||||
|
|
|
|||
|
|
@ -14,9 +14,14 @@
|
|||
#include <linux/bitfield.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/clk/renesas.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/limits.h>
|
||||
#include <linux/math.h>
|
||||
#include <linux/math64.h>
|
||||
#include <linux/minmax.h>
|
||||
#include <linux/mod_devicetable.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
|
|
@ -26,6 +31,7 @@
|
|||
#include <linux/refcount.h>
|
||||
#include <linux/reset-controller.h>
|
||||
#include <linux/string_choices.h>
|
||||
#include <linux/units.h>
|
||||
|
||||
#include <dt-bindings/clock/renesas-cpg-mssr.h>
|
||||
|
||||
|
|
@ -47,13 +53,15 @@
|
|||
|
||||
#define CPG_PLL_STBY(x) ((x))
|
||||
#define CPG_PLL_STBY_RESETB BIT(0)
|
||||
#define CPG_PLL_STBY_SSC_EN BIT(2)
|
||||
#define CPG_PLL_STBY_RESETB_WEN BIT(16)
|
||||
#define CPG_PLL_STBY_SSC_EN_WEN BIT(18)
|
||||
#define CPG_PLL_CLK1(x) ((x) + 0x004)
|
||||
#define CPG_PLL_CLK1_KDIV(x) ((s16)FIELD_GET(GENMASK(31, 16), (x)))
|
||||
#define CPG_PLL_CLK1_MDIV(x) FIELD_GET(GENMASK(15, 6), (x))
|
||||
#define CPG_PLL_CLK1_PDIV(x) FIELD_GET(GENMASK(5, 0), (x))
|
||||
#define CPG_PLL_CLK1_KDIV GENMASK(31, 16)
|
||||
#define CPG_PLL_CLK1_MDIV GENMASK(15, 6)
|
||||
#define CPG_PLL_CLK1_PDIV GENMASK(5, 0)
|
||||
#define CPG_PLL_CLK2(x) ((x) + 0x008)
|
||||
#define CPG_PLL_CLK2_SDIV(x) FIELD_GET(GENMASK(2, 0), (x))
|
||||
#define CPG_PLL_CLK2_SDIV GENMASK(2, 0)
|
||||
#define CPG_PLL_MON(x) ((x) + 0x010)
|
||||
#define CPG_PLL_MON_RESETB BIT(0)
|
||||
#define CPG_PLL_MON_LOCK BIT(4)
|
||||
|
|
@ -65,6 +73,22 @@
|
|||
|
||||
#define CPG_CLKSTATUS0 (0x700)
|
||||
|
||||
/* On RZ/G3E SoC we have two DSI PLLs */
|
||||
#define MAX_CPG_DSI_PLL 2
|
||||
|
||||
/**
|
||||
* struct rzv2h_pll_dsi_info - PLL DSI information, holds the limits and parameters
|
||||
*
|
||||
* @pll_dsi_limits: PLL DSI parameters limits
|
||||
* @pll_dsi_parameters: Calculated PLL DSI parameters
|
||||
* @req_pll_dsi_rate: Requested PLL DSI rate
|
||||
*/
|
||||
struct rzv2h_pll_dsi_info {
|
||||
const struct rzv2h_pll_limits *pll_dsi_limits;
|
||||
struct rzv2h_pll_div_pars pll_dsi_parameters;
|
||||
unsigned long req_pll_dsi_rate;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct rzv2h_cpg_priv - Clock Pulse Generator Private Data
|
||||
*
|
||||
|
|
@ -80,6 +104,7 @@
|
|||
* @ff_mod_status_ops: Fixed Factor Module Status Clock operations
|
||||
* @mstop_count: Array of mstop values
|
||||
* @rcdev: Reset controller entity
|
||||
* @pll_dsi_info: Array of PLL DSI information, holds the limits and parameters
|
||||
*/
|
||||
struct rzv2h_cpg_priv {
|
||||
struct device *dev;
|
||||
|
|
@ -98,6 +123,8 @@ struct rzv2h_cpg_priv {
|
|||
atomic_t *mstop_count;
|
||||
|
||||
struct reset_controller_dev rcdev;
|
||||
|
||||
struct rzv2h_pll_dsi_info pll_dsi_info[MAX_CPG_DSI_PLL];
|
||||
};
|
||||
|
||||
#define rcdev_to_priv(x) container_of(x, struct rzv2h_cpg_priv, rcdev)
|
||||
|
|
@ -168,6 +195,460 @@ struct rzv2h_ff_mod_status_clk {
|
|||
#define to_rzv2h_ff_mod_status_clk(_hw) \
|
||||
container_of(_hw, struct rzv2h_ff_mod_status_clk, fix.hw)
|
||||
|
||||
/**
|
||||
* struct rzv2h_plldsi_div_clk - PLL DSI DDIV clock
|
||||
*
|
||||
* @dtable: divider table
|
||||
* @priv: CPG private data
|
||||
* @hw: divider clk
|
||||
* @ddiv: divider configuration
|
||||
*/
|
||||
struct rzv2h_plldsi_div_clk {
|
||||
const struct clk_div_table *dtable;
|
||||
struct rzv2h_cpg_priv *priv;
|
||||
struct clk_hw hw;
|
||||
struct ddiv ddiv;
|
||||
};
|
||||
|
||||
#define to_plldsi_div_clk(_hw) \
|
||||
container_of(_hw, struct rzv2h_plldsi_div_clk, hw)
|
||||
|
||||
#define RZ_V2H_OSC_CLK_IN_MEGA (24 * MEGA)
|
||||
#define RZV2H_MAX_DIV_TABLES (16)
|
||||
|
||||
/**
|
||||
* rzv2h_get_pll_pars - Finds the best combination of PLL parameters
|
||||
* for a given frequency.
|
||||
*
|
||||
* @limits: Pointer to the structure containing the limits for the PLL parameters
|
||||
* @pars: Pointer to the structure where the best calculated PLL parameters values
|
||||
* will be stored
|
||||
* @freq_millihz: Target output frequency in millihertz
|
||||
*
|
||||
* This function calculates the best set of PLL parameters (M, K, P, S) to achieve
|
||||
* the desired frequency.
|
||||
* There is no direct formula to calculate the PLL parameters, as it's an open
|
||||
* system of equations, therefore this function uses an iterative approach to
|
||||
* determine the best solution. The best solution is one that minimizes the error
|
||||
* (desired frequency - actual frequency).
|
||||
*
|
||||
* Return: true if a valid set of parameters values is found, false otherwise.
|
||||
*/
|
||||
bool rzv2h_get_pll_pars(const struct rzv2h_pll_limits *limits,
|
||||
struct rzv2h_pll_pars *pars, u64 freq_millihz)
|
||||
{
|
||||
u64 fout_min_millihz = mul_u32_u32(limits->fout.min, MILLI);
|
||||
u64 fout_max_millihz = mul_u32_u32(limits->fout.max, MILLI);
|
||||
struct rzv2h_pll_pars p, best;
|
||||
|
||||
if (freq_millihz > fout_max_millihz ||
|
||||
freq_millihz < fout_min_millihz)
|
||||
return false;
|
||||
|
||||
/* Initialize best error to maximum possible value */
|
||||
best.error_millihz = S64_MAX;
|
||||
|
||||
for (p.p = limits->p.min; p.p <= limits->p.max; p.p++) {
|
||||
u32 fref = RZ_V2H_OSC_CLK_IN_MEGA / p.p;
|
||||
u16 divider;
|
||||
|
||||
for (divider = 1 << limits->s.min, p.s = limits->s.min;
|
||||
p.s <= limits->s.max; p.s++, divider <<= 1) {
|
||||
for (p.m = limits->m.min; p.m <= limits->m.max; p.m++) {
|
||||
u64 output_m, output_k_range;
|
||||
s64 pll_k, output_k;
|
||||
u64 fvco, output;
|
||||
|
||||
/*
|
||||
* The frequency generated by the PLL + divider
|
||||
* is calculated as follows:
|
||||
*
|
||||
* With:
|
||||
* Freq = Ffout = Ffvco / 2^(pll_s)
|
||||
* Ffvco = (pll_m + (pll_k / 65536)) * Ffref
|
||||
* Ffref = 24MHz / pll_p
|
||||
*
|
||||
* Freq can also be rewritten as:
|
||||
* Freq = Ffvco / 2^(pll_s)
|
||||
* = ((pll_m + (pll_k / 65536)) * Ffref) / 2^(pll_s)
|
||||
* = (pll_m * Ffref) / 2^(pll_s) + ((pll_k / 65536) * Ffref) / 2^(pll_s)
|
||||
* = output_m + output_k
|
||||
*
|
||||
* Every parameter has been determined at this
|
||||
* point, but pll_k.
|
||||
*
|
||||
* Considering that:
|
||||
* limits->k.min <= pll_k <= limits->k.max
|
||||
* Then:
|
||||
* -0.5 <= (pll_k / 65536) < 0.5
|
||||
* Therefore:
|
||||
* -Ffref / (2 * 2^(pll_s)) <= output_k < Ffref / (2 * 2^(pll_s))
|
||||
*/
|
||||
|
||||
/* Compute output M component (in mHz) */
|
||||
output_m = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(p.m, fref) * MILLI,
|
||||
divider);
|
||||
/* Compute range for output K (in mHz) */
|
||||
output_k_range = DIV_ROUND_CLOSEST_ULL(mul_u32_u32(fref, MILLI),
|
||||
2 * divider);
|
||||
/*
|
||||
* No point in continuing if we can't achieve
|
||||
* the desired frequency
|
||||
*/
|
||||
if (freq_millihz < (output_m - output_k_range) ||
|
||||
freq_millihz >= (output_m + output_k_range)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compute the K component
|
||||
*
|
||||
* Since:
|
||||
* Freq = output_m + output_k
|
||||
* Then:
|
||||
* output_k = Freq - output_m
|
||||
* = ((pll_k / 65536) * Ffref) / 2^(pll_s)
|
||||
* Therefore:
|
||||
* pll_k = (output_k * 65536 * 2^(pll_s)) / Ffref
|
||||
*/
|
||||
output_k = freq_millihz - output_m;
|
||||
pll_k = div_s64(output_k * 65536ULL * divider,
|
||||
fref);
|
||||
pll_k = DIV_S64_ROUND_CLOSEST(pll_k, MILLI);
|
||||
|
||||
/* Validate K value within allowed limits */
|
||||
if (pll_k < limits->k.min ||
|
||||
pll_k > limits->k.max)
|
||||
continue;
|
||||
|
||||
p.k = pll_k;
|
||||
|
||||
/* Compute (Ffvco * 65536) */
|
||||
fvco = mul_u32_u32(p.m * 65536 + p.k, fref);
|
||||
if (fvco < mul_u32_u32(limits->fvco.min, 65536) ||
|
||||
fvco > mul_u32_u32(limits->fvco.max, 65536))
|
||||
continue;
|
||||
|
||||
/* PLL_M component of (output * 65536 * PLL_P) */
|
||||
output = mul_u32_u32(p.m * 65536, RZ_V2H_OSC_CLK_IN_MEGA);
|
||||
/* PLL_K component of (output * 65536 * PLL_P) */
|
||||
output += p.k * RZ_V2H_OSC_CLK_IN_MEGA;
|
||||
/* Make it in mHz */
|
||||
output *= MILLI;
|
||||
output = DIV_U64_ROUND_CLOSEST(output, 65536 * p.p * divider);
|
||||
|
||||
/* Check output frequency against limits */
|
||||
if (output < fout_min_millihz ||
|
||||
output > fout_max_millihz)
|
||||
continue;
|
||||
|
||||
p.error_millihz = freq_millihz - output;
|
||||
p.freq_millihz = output;
|
||||
|
||||
/* If an exact match is found, return immediately */
|
||||
if (p.error_millihz == 0) {
|
||||
*pars = p;
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Update best match if error is smaller */
|
||||
if (abs(best.error_millihz) > abs(p.error_millihz))
|
||||
best = p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* If no valid parameters were found, return false */
|
||||
if (best.error_millihz == S64_MAX)
|
||||
return false;
|
||||
|
||||
*pars = best;
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(rzv2h_get_pll_pars, "RZV2H_CPG");
|
||||
|
||||
/*
|
||||
* rzv2h_get_pll_divs_pars - Finds the best combination of PLL parameters
|
||||
* and divider value for a given frequency.
|
||||
*
|
||||
* @limits: Pointer to the structure containing the limits for the PLL parameters
|
||||
* @pars: Pointer to the structure where the best calculated PLL parameters and
|
||||
* divider values will be stored
|
||||
* @table: Pointer to the array of valid divider values
|
||||
* @table_size: Size of the divider values array
|
||||
* @freq_millihz: Target output frequency in millihertz
|
||||
*
|
||||
* This function calculates the best set of PLL parameters (M, K, P, S) and divider
|
||||
* value to achieve the desired frequency. See rzv2h_get_pll_pars() for more details
|
||||
* on how the PLL parameters are calculated.
|
||||
*
|
||||
* freq_millihz is the desired frequency generated by the PLL followed by a
|
||||
* a gear.
|
||||
*/
|
||||
bool rzv2h_get_pll_divs_pars(const struct rzv2h_pll_limits *limits,
|
||||
struct rzv2h_pll_div_pars *pars,
|
||||
const u8 *table, u8 table_size, u64 freq_millihz)
|
||||
{
|
||||
struct rzv2h_pll_div_pars p, best;
|
||||
|
||||
best.div.error_millihz = S64_MAX;
|
||||
p.div.error_millihz = S64_MAX;
|
||||
for (unsigned int i = 0; i < table_size; i++) {
|
||||
if (!rzv2h_get_pll_pars(limits, &p.pll, freq_millihz * table[i]))
|
||||
continue;
|
||||
|
||||
p.div.divider_value = table[i];
|
||||
p.div.freq_millihz = DIV_U64_ROUND_CLOSEST(p.pll.freq_millihz, table[i]);
|
||||
p.div.error_millihz = freq_millihz - p.div.freq_millihz;
|
||||
|
||||
if (p.div.error_millihz == 0) {
|
||||
*pars = p;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (abs(best.div.error_millihz) > abs(p.div.error_millihz))
|
||||
best = p;
|
||||
}
|
||||
|
||||
if (best.div.error_millihz == S64_MAX)
|
||||
return false;
|
||||
|
||||
*pars = best;
|
||||
return true;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(rzv2h_get_pll_divs_pars, "RZV2H_CPG");
|
||||
|
||||
static unsigned long rzv2h_cpg_plldsi_div_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct rzv2h_plldsi_div_clk *dsi_div = to_plldsi_div_clk(hw);
|
||||
struct rzv2h_cpg_priv *priv = dsi_div->priv;
|
||||
struct ddiv ddiv = dsi_div->ddiv;
|
||||
u32 div;
|
||||
|
||||
div = readl(priv->base + ddiv.offset);
|
||||
div >>= ddiv.shift;
|
||||
div &= clk_div_mask(ddiv.width);
|
||||
div = dsi_div->dtable[div].div;
|
||||
|
||||
return DIV_ROUND_CLOSEST_ULL(parent_rate, div);
|
||||
}
|
||||
|
||||
static int rzv2h_cpg_plldsi_div_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
struct rzv2h_plldsi_div_clk *dsi_div = to_plldsi_div_clk(hw);
|
||||
struct pll_clk *pll_clk = to_pll(clk_hw_get_parent(hw));
|
||||
struct rzv2h_cpg_priv *priv = dsi_div->priv;
|
||||
u8 table[RZV2H_MAX_DIV_TABLES] = { 0 };
|
||||
struct rzv2h_pll_div_pars *dsi_params;
|
||||
struct rzv2h_pll_dsi_info *dsi_info;
|
||||
const struct clk_div_table *div;
|
||||
unsigned int i = 0;
|
||||
u64 rate_millihz;
|
||||
|
||||
dsi_info = &priv->pll_dsi_info[pll_clk->pll.instance];
|
||||
dsi_params = &dsi_info->pll_dsi_parameters;
|
||||
|
||||
rate_millihz = mul_u32_u32(req->rate, MILLI);
|
||||
if (rate_millihz == dsi_params->div.error_millihz + dsi_params->div.freq_millihz)
|
||||
goto exit_determine_rate;
|
||||
|
||||
for (div = dsi_div->dtable; div->div; div++) {
|
||||
if (i >= RZV2H_MAX_DIV_TABLES)
|
||||
return -EINVAL;
|
||||
table[i++] = div->div;
|
||||
}
|
||||
|
||||
if (!rzv2h_get_pll_divs_pars(dsi_info->pll_dsi_limits, dsi_params, table, i,
|
||||
rate_millihz)) {
|
||||
dev_err(priv->dev, "failed to determine rate for req->rate: %lu\n",
|
||||
req->rate);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
exit_determine_rate:
|
||||
req->rate = DIV_ROUND_CLOSEST_ULL(dsi_params->div.freq_millihz, MILLI);
|
||||
req->best_parent_rate = req->rate * dsi_params->div.divider_value;
|
||||
dsi_info->req_pll_dsi_rate = req->best_parent_rate;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rzv2h_cpg_plldsi_div_set_rate(struct clk_hw *hw,
|
||||
unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct rzv2h_plldsi_div_clk *dsi_div = to_plldsi_div_clk(hw);
|
||||
struct pll_clk *pll_clk = to_pll(clk_hw_get_parent(hw));
|
||||
struct rzv2h_cpg_priv *priv = dsi_div->priv;
|
||||
struct rzv2h_pll_div_pars *dsi_params;
|
||||
struct rzv2h_pll_dsi_info *dsi_info;
|
||||
struct ddiv ddiv = dsi_div->ddiv;
|
||||
const struct clk_div_table *clkt;
|
||||
bool divider_found = false;
|
||||
u32 val, shift;
|
||||
|
||||
dsi_info = &priv->pll_dsi_info[pll_clk->pll.instance];
|
||||
dsi_params = &dsi_info->pll_dsi_parameters;
|
||||
|
||||
for (clkt = dsi_div->dtable; clkt->div; clkt++) {
|
||||
if (clkt->div == dsi_params->div.divider_value) {
|
||||
divider_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!divider_found)
|
||||
return -EINVAL;
|
||||
|
||||
shift = ddiv.shift;
|
||||
val = readl(priv->base + ddiv.offset) | DDIV_DIVCTL_WEN(shift);
|
||||
val &= ~(clk_div_mask(ddiv.width) << shift);
|
||||
val |= clkt->val << shift;
|
||||
writel(val, priv->base + ddiv.offset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct clk_ops rzv2h_cpg_plldsi_div_ops = {
|
||||
.recalc_rate = rzv2h_cpg_plldsi_div_recalc_rate,
|
||||
.determine_rate = rzv2h_cpg_plldsi_div_determine_rate,
|
||||
.set_rate = rzv2h_cpg_plldsi_div_set_rate,
|
||||
};
|
||||
|
||||
static struct clk * __init
|
||||
rzv2h_cpg_plldsi_div_clk_register(const struct cpg_core_clk *core,
|
||||
struct rzv2h_cpg_priv *priv)
|
||||
{
|
||||
struct rzv2h_plldsi_div_clk *clk_hw_data;
|
||||
struct clk **clks = priv->clks;
|
||||
struct clk_init_data init;
|
||||
const struct clk *parent;
|
||||
const char *parent_name;
|
||||
struct clk_hw *clk_hw;
|
||||
int ret;
|
||||
|
||||
parent = clks[core->parent];
|
||||
if (IS_ERR(parent))
|
||||
return ERR_CAST(parent);
|
||||
|
||||
clk_hw_data = devm_kzalloc(priv->dev, sizeof(*clk_hw_data), GFP_KERNEL);
|
||||
if (!clk_hw_data)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
clk_hw_data->priv = priv;
|
||||
clk_hw_data->ddiv = core->cfg.ddiv;
|
||||
clk_hw_data->dtable = core->dtable;
|
||||
|
||||
parent_name = __clk_get_name(parent);
|
||||
init.name = core->name;
|
||||
init.ops = &rzv2h_cpg_plldsi_div_ops;
|
||||
init.flags = core->flag;
|
||||
init.parent_names = &parent_name;
|
||||
init.num_parents = 1;
|
||||
|
||||
clk_hw = &clk_hw_data->hw;
|
||||
clk_hw->init = &init;
|
||||
|
||||
ret = devm_clk_hw_register(priv->dev, clk_hw);
|
||||
if (ret)
|
||||
return ERR_PTR(ret);
|
||||
|
||||
return clk_hw->clk;
|
||||
}
|
||||
|
||||
static int rzv2h_cpg_plldsi_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
struct pll_clk *pll_clk = to_pll(hw);
|
||||
struct rzv2h_cpg_priv *priv = pll_clk->priv;
|
||||
struct rzv2h_pll_dsi_info *dsi_info;
|
||||
u64 rate_millihz;
|
||||
|
||||
dsi_info = &priv->pll_dsi_info[pll_clk->pll.instance];
|
||||
/* check if the divider has already invoked the algorithm */
|
||||
if (req->rate == dsi_info->req_pll_dsi_rate)
|
||||
return 0;
|
||||
|
||||
/* If the req->rate doesn't match we do the calculation assuming there is no divider */
|
||||
rate_millihz = mul_u32_u32(req->rate, MILLI);
|
||||
if (!rzv2h_get_pll_pars(dsi_info->pll_dsi_limits,
|
||||
&dsi_info->pll_dsi_parameters.pll, rate_millihz)) {
|
||||
dev_err(priv->dev,
|
||||
"failed to determine rate for req->rate: %lu\n",
|
||||
req->rate);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
req->rate = DIV_ROUND_CLOSEST_ULL(dsi_info->pll_dsi_parameters.pll.freq_millihz, MILLI);
|
||||
dsi_info->req_pll_dsi_rate = req->rate;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rzv2h_cpg_pll_set_rate(struct pll_clk *pll_clk,
|
||||
struct rzv2h_pll_pars *params,
|
||||
bool ssc_disable)
|
||||
{
|
||||
struct rzv2h_cpg_priv *priv = pll_clk->priv;
|
||||
u16 offset = pll_clk->pll.offset;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
/* Put PLL into standby mode */
|
||||
writel(CPG_PLL_STBY_RESETB_WEN, priv->base + CPG_PLL_STBY(offset));
|
||||
ret = readl_poll_timeout_atomic(priv->base + CPG_PLL_MON(offset),
|
||||
val, !(val & CPG_PLL_MON_LOCK),
|
||||
100, 2000);
|
||||
if (ret) {
|
||||
dev_err(priv->dev, "Failed to put PLLDSI into standby mode");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Output clock setting 1 */
|
||||
writel(FIELD_PREP(CPG_PLL_CLK1_KDIV, (u16)params->k) |
|
||||
FIELD_PREP(CPG_PLL_CLK1_MDIV, params->m) |
|
||||
FIELD_PREP(CPG_PLL_CLK1_PDIV, params->p),
|
||||
priv->base + CPG_PLL_CLK1(offset));
|
||||
|
||||
/* Output clock setting 2 */
|
||||
val = readl(priv->base + CPG_PLL_CLK2(offset));
|
||||
writel((val & ~CPG_PLL_CLK2_SDIV) | FIELD_PREP(CPG_PLL_CLK2_SDIV, params->s),
|
||||
priv->base + CPG_PLL_CLK2(offset));
|
||||
|
||||
/* Put PLL to normal mode */
|
||||
if (ssc_disable)
|
||||
val = CPG_PLL_STBY_SSC_EN_WEN;
|
||||
else
|
||||
val = CPG_PLL_STBY_SSC_EN_WEN | CPG_PLL_STBY_SSC_EN;
|
||||
writel(val | CPG_PLL_STBY_RESETB_WEN | CPG_PLL_STBY_RESETB,
|
||||
priv->base + CPG_PLL_STBY(offset));
|
||||
|
||||
/* PLL normal mode transition, output clock stability check */
|
||||
ret = readl_poll_timeout_atomic(priv->base + CPG_PLL_MON(offset),
|
||||
val, (val & CPG_PLL_MON_LOCK),
|
||||
100, 2000);
|
||||
if (ret) {
|
||||
dev_err(priv->dev, "Failed to put PLLDSI into normal mode");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rzv2h_cpg_plldsi_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct pll_clk *pll_clk = to_pll(hw);
|
||||
struct rzv2h_pll_dsi_info *dsi_info;
|
||||
struct rzv2h_cpg_priv *priv = pll_clk->priv;
|
||||
|
||||
dsi_info = &priv->pll_dsi_info[pll_clk->pll.instance];
|
||||
|
||||
return rzv2h_cpg_pll_set_rate(pll_clk, &dsi_info->pll_dsi_parameters.pll, true);
|
||||
}
|
||||
|
||||
static int rzv2h_cpg_pll_clk_is_enabled(struct clk_hw *hw)
|
||||
{
|
||||
struct pll_clk *pll_clk = to_pll(hw);
|
||||
|
|
@ -231,12 +712,19 @@ static unsigned long rzv2h_cpg_pll_clk_recalc_rate(struct clk_hw *hw,
|
|||
clk1 = readl(priv->base + CPG_PLL_CLK1(pll.offset));
|
||||
clk2 = readl(priv->base + CPG_PLL_CLK2(pll.offset));
|
||||
|
||||
rate = mul_u64_u32_shr(parent_rate, (CPG_PLL_CLK1_MDIV(clk1) << 16) +
|
||||
CPG_PLL_CLK1_KDIV(clk1), 16 + CPG_PLL_CLK2_SDIV(clk2));
|
||||
rate = mul_u64_u32_shr(parent_rate, (FIELD_GET(CPG_PLL_CLK1_MDIV, clk1) << 16) +
|
||||
(s16)FIELD_GET(CPG_PLL_CLK1_KDIV, clk1),
|
||||
16 + FIELD_GET(CPG_PLL_CLK2_SDIV, clk2));
|
||||
|
||||
return DIV_ROUND_CLOSEST_ULL(rate, CPG_PLL_CLK1_PDIV(clk1));
|
||||
return DIV_ROUND_CLOSEST_ULL(rate, FIELD_GET(CPG_PLL_CLK1_PDIV, clk1));
|
||||
}
|
||||
|
||||
static const struct clk_ops rzv2h_cpg_plldsi_ops = {
|
||||
.recalc_rate = rzv2h_cpg_pll_clk_recalc_rate,
|
||||
.determine_rate = rzv2h_cpg_plldsi_determine_rate,
|
||||
.set_rate = rzv2h_cpg_plldsi_set_rate,
|
||||
};
|
||||
|
||||
static const struct clk_ops rzv2h_cpg_pll_ops = {
|
||||
.is_enabled = rzv2h_cpg_pll_clk_is_enabled,
|
||||
.enable = rzv2h_cpg_pll_clk_enable,
|
||||
|
|
@ -263,6 +751,10 @@ rzv2h_cpg_pll_clk_register(const struct cpg_core_clk *core,
|
|||
if (!pll_clk)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
if (core->type == CLK_TYPE_PLLDSI)
|
||||
priv->pll_dsi_info[core->cfg.pll.instance].pll_dsi_limits =
|
||||
core->cfg.pll.limits;
|
||||
|
||||
parent_name = __clk_get_name(parent);
|
||||
init.name = core->name;
|
||||
init.ops = ops;
|
||||
|
|
@ -587,11 +1079,17 @@ rzv2h_cpg_register_core_clk(const struct cpg_core_clk *core,
|
|||
case CLK_TYPE_SMUX:
|
||||
clk = rzv2h_cpg_mux_clk_register(core, priv);
|
||||
break;
|
||||
case CLK_TYPE_PLLDSI:
|
||||
clk = rzv2h_cpg_pll_clk_register(core, priv, &rzv2h_cpg_plldsi_ops);
|
||||
break;
|
||||
case CLK_TYPE_PLLDSI_DIV:
|
||||
clk = rzv2h_cpg_plldsi_div_clk_register(core, priv);
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (IS_ERR_OR_NULL(clk))
|
||||
if (IS_ERR(clk))
|
||||
goto fail;
|
||||
|
||||
dev_dbg(dev, "Core clock %pC at %lu Hz\n", clk, clk_get_rate(clk));
|
||||
|
|
|
|||
|
|
@ -16,20 +16,28 @@
|
|||
*
|
||||
* @offset: STBY register offset
|
||||
* @has_clkn: Flag to indicate if CLK1/2 are accessible or not
|
||||
* @instance: PLL instance number
|
||||
*/
|
||||
struct pll {
|
||||
unsigned int offset:9;
|
||||
unsigned int has_clkn:1;
|
||||
unsigned int instance:2;
|
||||
const struct rzv2h_pll_limits *limits;
|
||||
};
|
||||
|
||||
#define PLL_PACK(_offset, _has_clkn) \
|
||||
#define PLL_PACK_LIMITS(_offset, _has_clkn, _instance, _limits) \
|
||||
((struct pll){ \
|
||||
.offset = _offset, \
|
||||
.has_clkn = _has_clkn \
|
||||
.has_clkn = _has_clkn, \
|
||||
.instance = _instance, \
|
||||
.limits = _limits \
|
||||
})
|
||||
|
||||
#define PLLCA55 PLL_PACK(0x60, 1)
|
||||
#define PLLGPU PLL_PACK(0x120, 1)
|
||||
#define PLL_PACK(_offset, _has_clkn, _instance) \
|
||||
PLL_PACK_LIMITS(_offset, _has_clkn, _instance, NULL)
|
||||
|
||||
#define PLLCA55 PLL_PACK(0x60, 1, 0)
|
||||
#define PLLGPU PLL_PACK(0x120, 1, 0)
|
||||
|
||||
/**
|
||||
* struct ddiv - Structure for dynamic switching divider
|
||||
|
|
@ -115,9 +123,11 @@ struct fixed_mod_conf {
|
|||
#define CPG_SSEL1 (0x304)
|
||||
#define CPG_CDDIV0 (0x400)
|
||||
#define CPG_CDDIV1 (0x404)
|
||||
#define CPG_CDDIV2 (0x408)
|
||||
#define CPG_CDDIV3 (0x40C)
|
||||
#define CPG_CDDIV4 (0x410)
|
||||
#define CPG_CSDIV0 (0x500)
|
||||
#define CPG_CSDIV1 (0x504)
|
||||
|
||||
#define CDDIV0_DIVCTL1 DDIV_PACK(CPG_CDDIV0, 4, 3, 1)
|
||||
#define CDDIV0_DIVCTL2 DDIV_PACK(CPG_CDDIV0, 8, 3, 2)
|
||||
|
|
@ -125,6 +135,7 @@ struct fixed_mod_conf {
|
|||
#define CDDIV1_DIVCTL1 DDIV_PACK(CPG_CDDIV1, 4, 2, 5)
|
||||
#define CDDIV1_DIVCTL2 DDIV_PACK(CPG_CDDIV1, 8, 2, 6)
|
||||
#define CDDIV1_DIVCTL3 DDIV_PACK(CPG_CDDIV1, 12, 2, 7)
|
||||
#define CDDIV2_DIVCTL3 DDIV_PACK(CPG_CDDIV2, 12, 3, 11)
|
||||
#define CDDIV3_DIVCTL1 DDIV_PACK(CPG_CDDIV3, 4, 3, 13)
|
||||
#define CDDIV3_DIVCTL2 DDIV_PACK(CPG_CDDIV3, 8, 3, 14)
|
||||
#define CDDIV3_DIVCTL3 DDIV_PACK(CPG_CDDIV3, 12, 1, 15)
|
||||
|
|
@ -134,7 +145,9 @@ struct fixed_mod_conf {
|
|||
|
||||
#define CSDIV0_DIVCTL0 DDIV_PACK(CPG_CSDIV0, 0, 2, CSDIV_NO_MON)
|
||||
#define CSDIV0_DIVCTL1 DDIV_PACK(CPG_CSDIV0, 4, 2, CSDIV_NO_MON)
|
||||
#define CSDIV0_DIVCTL2 DDIV_PACK(CPG_CSDIV0, 8, 2, CSDIV_NO_MON)
|
||||
#define CSDIV0_DIVCTL3 DDIV_PACK_NO_RMW(CPG_CSDIV0, 12, 2, CSDIV_NO_MON)
|
||||
#define CSDIV1_DIVCTL2 DDIV_PACK(CPG_CSDIV1, 8, 4, CSDIV_NO_MON)
|
||||
|
||||
#define SSEL0_SELCTL2 SMUX_PACK(CPG_SSEL0, 8, 1)
|
||||
#define SSEL0_SELCTL3 SMUX_PACK(CPG_SSEL0, 12, 1)
|
||||
|
|
@ -188,6 +201,8 @@ enum clk_types {
|
|||
CLK_TYPE_PLL,
|
||||
CLK_TYPE_DDIV, /* Dynamic Switching Divider */
|
||||
CLK_TYPE_SMUX, /* Static Mux */
|
||||
CLK_TYPE_PLLDSI, /* PLLDSI */
|
||||
CLK_TYPE_PLLDSI_DIV, /* PLLDSI divider */
|
||||
};
|
||||
|
||||
#define DEF_TYPE(_name, _id, _type...) \
|
||||
|
|
@ -218,6 +233,14 @@ enum clk_types {
|
|||
.num_parents = ARRAY_SIZE(_parent_names), \
|
||||
.flag = CLK_SET_RATE_PARENT, \
|
||||
.mux_flags = CLK_MUX_HIWORD_MASK)
|
||||
#define DEF_PLLDSI(_name, _id, _parent, _pll_packed) \
|
||||
DEF_TYPE(_name, _id, CLK_TYPE_PLLDSI, .parent = _parent, .cfg.pll = _pll_packed)
|
||||
#define DEF_PLLDSI_DIV(_name, _id, _parent, _ddiv_packed, _dtable) \
|
||||
DEF_TYPE(_name, _id, CLK_TYPE_PLLDSI_DIV, \
|
||||
.cfg.ddiv = _ddiv_packed, \
|
||||
.dtable = _dtable, \
|
||||
.parent = _parent, \
|
||||
.flag = CLK_SET_RATE_PARENT)
|
||||
|
||||
/**
|
||||
* struct rzv2h_mod_clk - Module Clocks definitions
|
||||
|
|
|
|||
|
|
@ -30,6 +30,13 @@ config CLK_RV1126
|
|||
help
|
||||
Build the driver for RV1126 Clock Driver.
|
||||
|
||||
config CLK_RV1126B
|
||||
bool "Rockchip RV1126B clock controller support"
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
default y
|
||||
help
|
||||
Build the driver for RV1126B Clock Driver.
|
||||
|
||||
config CLK_RK3036
|
||||
bool "Rockchip RK3036 clock controller support"
|
||||
depends on ARM || COMPILE_TEST
|
||||
|
|
@ -93,6 +100,13 @@ config CLK_RK3399
|
|||
help
|
||||
Build the driver for RK3399 Clock Driver.
|
||||
|
||||
config CLK_RK3506
|
||||
bool "Rockchip RK3506 clock controller support"
|
||||
depends on ARM || COMPILE_TEST
|
||||
default y
|
||||
help
|
||||
Build the driver for RK3506 Clock Driver.
|
||||
|
||||
config CLK_RK3528
|
||||
bool "Rockchip RK3528 clock controller support"
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ clk-rockchip-$(CONFIG_RESET_CONTROLLER) += softrst.o
|
|||
obj-$(CONFIG_CLK_PX30) += clk-px30.o
|
||||
obj-$(CONFIG_CLK_RV110X) += clk-rv1108.o
|
||||
obj-$(CONFIG_CLK_RV1126) += clk-rv1126.o
|
||||
obj-$(CONFIG_CLK_RV1126B) += clk-rv1126b.o rst-rv1126b.o
|
||||
obj-$(CONFIG_CLK_RK3036) += clk-rk3036.o
|
||||
obj-$(CONFIG_CLK_RK312X) += clk-rk3128.o
|
||||
obj-$(CONFIG_CLK_RK3188) += clk-rk3188.o
|
||||
|
|
@ -29,6 +30,7 @@ obj-$(CONFIG_CLK_RK3308) += clk-rk3308.o
|
|||
obj-$(CONFIG_CLK_RK3328) += clk-rk3328.o
|
||||
obj-$(CONFIG_CLK_RK3368) += clk-rk3368.o
|
||||
obj-$(CONFIG_CLK_RK3399) += clk-rk3399.o
|
||||
obj-$(CONFIG_CLK_RK3506) += clk-rk3506.o rst-rk3506.o
|
||||
obj-$(CONFIG_CLK_RK3528) += clk-rk3528.o rst-rk3528.o
|
||||
obj-$(CONFIG_CLK_RK3562) += clk-rk3562.o rst-rk3562.o
|
||||
obj-$(CONFIG_CLK_RK3568) += clk-rk3568.o
|
||||
|
|
|
|||
|
|
@ -396,3 +396,168 @@ free_cpuclk:
|
|||
kfree(cpuclk);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
||||
static int rockchip_cpuclk_multi_pll_pre_rate_change(struct rockchip_cpuclk *cpuclk,
|
||||
struct clk_notifier_data *ndata)
|
||||
{
|
||||
unsigned long new_rate = roundup(ndata->new_rate, 1000);
|
||||
const struct rockchip_cpuclk_rate_table *rate;
|
||||
unsigned long flags;
|
||||
|
||||
rate = rockchip_get_cpuclk_settings(cpuclk, new_rate);
|
||||
if (!rate) {
|
||||
pr_err("%s: Invalid rate : %lu for cpuclk\n",
|
||||
__func__, new_rate);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (new_rate > ndata->old_rate) {
|
||||
spin_lock_irqsave(cpuclk->lock, flags);
|
||||
rockchip_cpuclk_set_dividers(cpuclk, rate);
|
||||
spin_unlock_irqrestore(cpuclk->lock, flags);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rockchip_cpuclk_multi_pll_post_rate_change(struct rockchip_cpuclk *cpuclk,
|
||||
struct clk_notifier_data *ndata)
|
||||
{
|
||||
unsigned long new_rate = roundup(ndata->new_rate, 1000);
|
||||
const struct rockchip_cpuclk_rate_table *rate;
|
||||
unsigned long flags;
|
||||
|
||||
rate = rockchip_get_cpuclk_settings(cpuclk, new_rate);
|
||||
if (!rate) {
|
||||
pr_err("%s: Invalid rate : %lu for cpuclk\n",
|
||||
__func__, new_rate);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (new_rate < ndata->old_rate) {
|
||||
spin_lock_irqsave(cpuclk->lock, flags);
|
||||
rockchip_cpuclk_set_dividers(cpuclk, rate);
|
||||
spin_unlock_irqrestore(cpuclk->lock, flags);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rockchip_cpuclk_multi_pll_notifier_cb(struct notifier_block *nb,
|
||||
unsigned long event, void *data)
|
||||
{
|
||||
struct clk_notifier_data *ndata = data;
|
||||
struct rockchip_cpuclk *cpuclk = to_rockchip_cpuclk_nb(nb);
|
||||
int ret = 0;
|
||||
|
||||
pr_debug("%s: event %lu, old_rate %lu, new_rate: %lu\n",
|
||||
__func__, event, ndata->old_rate, ndata->new_rate);
|
||||
if (event == PRE_RATE_CHANGE)
|
||||
ret = rockchip_cpuclk_multi_pll_pre_rate_change(cpuclk, ndata);
|
||||
else if (event == POST_RATE_CHANGE)
|
||||
ret = rockchip_cpuclk_multi_pll_post_rate_change(cpuclk, ndata);
|
||||
|
||||
return notifier_from_errno(ret);
|
||||
}
|
||||
|
||||
struct clk *rockchip_clk_register_cpuclk_multi_pll(const char *name,
|
||||
const char *const *parent_names,
|
||||
u8 num_parents, void __iomem *base,
|
||||
int muxdiv_offset, u8 mux_shift,
|
||||
u8 mux_width, u8 mux_flags,
|
||||
int div_offset, u8 div_shift,
|
||||
u8 div_width, u8 div_flags,
|
||||
unsigned long flags, spinlock_t *lock,
|
||||
const struct rockchip_cpuclk_rate_table *rates,
|
||||
int nrates)
|
||||
{
|
||||
struct rockchip_cpuclk *cpuclk;
|
||||
struct clk_hw *hw;
|
||||
struct clk_mux *mux = NULL;
|
||||
struct clk_divider *div = NULL;
|
||||
const struct clk_ops *mux_ops = NULL, *div_ops = NULL;
|
||||
int ret;
|
||||
|
||||
if (num_parents > 1) {
|
||||
mux = kzalloc(sizeof(*mux), GFP_KERNEL);
|
||||
if (!mux)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
mux->reg = base + muxdiv_offset;
|
||||
mux->shift = mux_shift;
|
||||
mux->mask = BIT(mux_width) - 1;
|
||||
mux->flags = mux_flags;
|
||||
mux->lock = lock;
|
||||
mux_ops = (mux_flags & CLK_MUX_READ_ONLY) ? &clk_mux_ro_ops
|
||||
: &clk_mux_ops;
|
||||
}
|
||||
|
||||
if (div_width > 0) {
|
||||
div = kzalloc(sizeof(*div), GFP_KERNEL);
|
||||
if (!div) {
|
||||
ret = -ENOMEM;
|
||||
goto free_mux;
|
||||
}
|
||||
|
||||
div->flags = div_flags;
|
||||
if (div_offset)
|
||||
div->reg = base + div_offset;
|
||||
else
|
||||
div->reg = base + muxdiv_offset;
|
||||
div->shift = div_shift;
|
||||
div->width = div_width;
|
||||
div->lock = lock;
|
||||
div_ops = (div_flags & CLK_DIVIDER_READ_ONLY)
|
||||
? &clk_divider_ro_ops
|
||||
: &clk_divider_ops;
|
||||
}
|
||||
|
||||
hw = clk_hw_register_composite(NULL, name, parent_names, num_parents,
|
||||
mux ? &mux->hw : NULL, mux_ops,
|
||||
div ? &div->hw : NULL, div_ops,
|
||||
NULL, NULL, flags);
|
||||
if (IS_ERR(hw)) {
|
||||
ret = PTR_ERR(hw);
|
||||
goto free_div;
|
||||
}
|
||||
|
||||
cpuclk = kzalloc(sizeof(*cpuclk), GFP_KERNEL);
|
||||
if (!cpuclk) {
|
||||
ret = -ENOMEM;
|
||||
goto unregister_clk;
|
||||
}
|
||||
|
||||
cpuclk->reg_base = base;
|
||||
cpuclk->lock = lock;
|
||||
cpuclk->clk_nb.notifier_call = rockchip_cpuclk_multi_pll_notifier_cb;
|
||||
ret = clk_notifier_register(hw->clk, &cpuclk->clk_nb);
|
||||
if (ret) {
|
||||
pr_err("%s: failed to register clock notifier for %s\n",
|
||||
__func__, name);
|
||||
goto free_cpuclk;
|
||||
}
|
||||
|
||||
if (nrates > 0) {
|
||||
cpuclk->rate_count = nrates;
|
||||
cpuclk->rate_table = kmemdup(rates,
|
||||
sizeof(*rates) * nrates,
|
||||
GFP_KERNEL);
|
||||
if (!cpuclk->rate_table) {
|
||||
ret = -ENOMEM;
|
||||
goto free_cpuclk;
|
||||
}
|
||||
}
|
||||
|
||||
return hw->clk;
|
||||
|
||||
free_cpuclk:
|
||||
kfree(cpuclk);
|
||||
unregister_clk:
|
||||
clk_hw_unregister_composite(hw);
|
||||
free_div:
|
||||
kfree(div);
|
||||
free_mux:
|
||||
kfree(mux);
|
||||
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,869 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2023-2025 Rockchip Electronics Co., Ltd.
|
||||
* Author: Finley Xiao <finley.xiao@rock-chips.com>
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/syscore_ops.h>
|
||||
#include <dt-bindings/clock/rockchip,rk3506-cru.h>
|
||||
#include "clk.h"
|
||||
|
||||
#define PVTPLL_SRC_SEL_PVTPLL (BIT(7) | BIT(23))
|
||||
|
||||
enum rk3506_plls {
|
||||
gpll, v0pll, v1pll,
|
||||
};
|
||||
|
||||
/*
|
||||
* [FRAC PLL]: GPLL, V0PLL, V1PLL
|
||||
* - VCO Frequency: 950MHz to 3800MHZ
|
||||
* - Output Frequency: 19MHz to 3800MHZ
|
||||
* - refdiv: 1 to 63 (Int Mode), 1 to 2 (Frac Mode)
|
||||
* - fbdiv: 16 to 3800 (Int Mode), 20 to 380 (Frac Mode)
|
||||
* - post1div: 1 to 7
|
||||
* - post2div: 1 to 7
|
||||
*/
|
||||
static struct rockchip_pll_rate_table rk3506_pll_rates[] = {
|
||||
/* _mhz, _refdiv, _fbdiv, _postdiv1, _postdiv2, _dsmpd, _frac */
|
||||
RK3036_PLL_RATE(1896000000, 1, 79, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1800000000, 1, 75, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1704000000, 1, 71, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1608000000, 1, 67, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1512000000, 1, 63, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1416000000, 1, 59, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1350000000, 4, 225, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1296000000, 1, 54, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1200000000, 1, 50, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1188000000, 1, 99, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1179648000, 1, 49, 1, 1, 0, 2550137),
|
||||
RK3036_PLL_RATE(1008000000, 1, 84, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE(1000000000, 3, 125, 1, 1, 1, 0),
|
||||
RK3036_PLL_RATE(993484800, 1, 41, 1, 1, 0, 6630355),
|
||||
RK3036_PLL_RATE(983040000, 1, 40, 1, 1, 0, 16106127),
|
||||
RK3036_PLL_RATE(960000000, 1, 80, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE(912000000, 1, 76, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE(903168000, 1, 75, 2, 1, 0, 4429185),
|
||||
RK3036_PLL_RATE(816000000, 1, 68, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE(800000000, 3, 200, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE(600000000, 1, 50, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE(594000000, 2, 99, 2, 1, 1, 0),
|
||||
RK3036_PLL_RATE(408000000, 1, 68, 2, 2, 1, 0),
|
||||
RK3036_PLL_RATE(312000000, 1, 78, 6, 1, 1, 0),
|
||||
RK3036_PLL_RATE(216000000, 1, 72, 4, 2, 1, 0),
|
||||
RK3036_PLL_RATE(96000000, 1, 48, 6, 2, 1, 0),
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
#define RK3506_DIV_ACLK_CORE_MASK 0xf
|
||||
#define RK3506_DIV_ACLK_CORE_SHIFT 9
|
||||
#define RK3506_DIV_PCLK_CORE_MASK 0xf
|
||||
#define RK3506_DIV_PCLK_CORE_SHIFT 0
|
||||
|
||||
#define RK3506_CLKSEL15(_aclk_core_div) \
|
||||
{ \
|
||||
.reg = RK3506_CLKSEL_CON(15), \
|
||||
.val = HIWORD_UPDATE(_aclk_core_div, RK3506_DIV_ACLK_CORE_MASK, \
|
||||
RK3506_DIV_ACLK_CORE_SHIFT), \
|
||||
}
|
||||
|
||||
#define RK3506_CLKSEL16(_pclk_core_div) \
|
||||
{ \
|
||||
.reg = RK3506_CLKSEL_CON(16), \
|
||||
.val = HIWORD_UPDATE(_pclk_core_div, RK3506_DIV_PCLK_CORE_MASK, \
|
||||
RK3506_DIV_PCLK_CORE_SHIFT), \
|
||||
}
|
||||
|
||||
/* SIGN-OFF: aclk_core: 500M, pclk_core: 125M, */
|
||||
#define RK3506_CPUCLK_RATE(_prate, _aclk_core_div, _pclk_core_div) \
|
||||
{ \
|
||||
.prate = _prate, \
|
||||
.divs = { \
|
||||
RK3506_CLKSEL15(_aclk_core_div), \
|
||||
RK3506_CLKSEL16(_pclk_core_div), \
|
||||
}, \
|
||||
}
|
||||
|
||||
static struct rockchip_cpuclk_rate_table rk3506_cpuclk_rates[] __initdata = {
|
||||
RK3506_CPUCLK_RATE(1608000000, 3, 12),
|
||||
RK3506_CPUCLK_RATE(1512000000, 3, 12),
|
||||
RK3506_CPUCLK_RATE(1416000000, 2, 11),
|
||||
RK3506_CPUCLK_RATE(1296000000, 2, 10),
|
||||
RK3506_CPUCLK_RATE(1200000000, 2, 9),
|
||||
RK3506_CPUCLK_RATE(1179648000, 2, 9),
|
||||
RK3506_CPUCLK_RATE(1008000000, 1, 7),
|
||||
RK3506_CPUCLK_RATE(903168000, 1, 7),
|
||||
RK3506_CPUCLK_RATE(800000000, 1, 6),
|
||||
RK3506_CPUCLK_RATE(750000000, 1, 5),
|
||||
RK3506_CPUCLK_RATE(589824000, 1, 4),
|
||||
RK3506_CPUCLK_RATE(400000000, 1, 3),
|
||||
RK3506_CPUCLK_RATE(200000000, 1, 1),
|
||||
};
|
||||
|
||||
PNAME(mux_pll_p) = { "xin24m" };
|
||||
PNAME(gpll_v0pll_v1pll_parents_p) = { "gpll", "v0pll", "v1pll" };
|
||||
PNAME(gpll_v0pll_v1pll_g_parents_p) = { "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate" };
|
||||
PNAME(gpll_v0pll_v1pll_div_parents_p) = { "clk_gpll_div", "clk_v0pll_div", "clk_v1pll_div" };
|
||||
PNAME(xin24m_gpll_v0pll_v1pll_g_parents_p) = { "xin24m", "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate" };
|
||||
PNAME(xin24m_g_gpll_v0pll_v1pll_g_parents_p) = { "xin24m_gate", "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate" };
|
||||
PNAME(xin24m_g_gpll_v0pll_v1pll_div_parents_p) = { "xin24m_gate", "clk_gpll_div", "clk_v0pll_div", "clk_v1pll_div" };
|
||||
PNAME(xin24m_400k_32k_parents_p) = { "xin24m", "clk_rc", "clk_32k" };
|
||||
PNAME(clk_frac_uart_matrix0_mux_parents_p) = { "xin24m", "gpll", "clk_v0pll_gate", "clk_v1pll_gate" };
|
||||
PNAME(clk_timer0_parents_p) = { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "sai0_mclk_in", "sai0_sclk_in" };
|
||||
PNAME(clk_timer1_parents_p) = { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "sai1_mclk_in", "sai1_sclk_in" };
|
||||
PNAME(clk_timer2_parents_p) = { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "sai2_mclk_in", "sai2_sclk_in" };
|
||||
PNAME(clk_timer3_parents_p) = { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "sai3_mclk_in", "sai3_sclk_in" };
|
||||
PNAME(clk_timer4_parents_p) = { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "mclk_asrc0" };
|
||||
PNAME(clk_timer5_parents_p) = { "xin24m", "clk_gpll_div_100m", "clk_32k", "clk_core_pvtpll", "mclk_asrc1" };
|
||||
PNAME(sclk_uart_parents_p) = { "xin24m", "clk_gpll_gate", "clk_v0pll_gate", "clk_frac_uart_matrix0", "clk_frac_uart_matrix1",
|
||||
"clk_frac_common_matrix0", "clk_frac_common_matrix1", "clk_frac_common_matrix2" };
|
||||
PNAME(clk_mac_ptp_root_parents_p) = { "gpll", "v0pll", "v1pll" };
|
||||
PNAME(clk_pwm_parents_p) = { "clk_rc", "sai0_mclk_in", "sai1_mclk_in", "sai2_mclk_in", "sai3_mclk_in", "sai0_sclk_in", "sai1_sclk_in",
|
||||
"sai2_sclk_in", "sai3_sclk_in", "mclk_asrc0", "mclk_asrc1" };
|
||||
PNAME(clk_can_parents_p) = { "xin24m", "gpll", "clk_v0pll_gate", "clk_v1pll_gate", "clk_frac_voice_matrix1",
|
||||
"clk_frac_common_matrix0", "clk_frac_common_matrix1", "clk_frac_common_matrix2" };
|
||||
PNAME(clk_pdm_parents_p) = { "xin24m_gate", "clk_int_voice_matrix0", "clk_int_voice_matrix1", "clk_int_voice_matrix2",
|
||||
"clk_frac_voice_matrix0", "clk_frac_voice_matrix1", "clk_frac_common_matrix0", "clk_frac_common_matrix1",
|
||||
"clk_frac_common_matrix2", "sai0_mclk_in", "sai1_mclk_in", "sai2_mclk_in", "sai3_mclk_in", "clk_gpll_div" };
|
||||
PNAME(mclk_sai_asrc_parents_p) = { "xin24m_gate", "clk_int_voice_matrix0", "clk_int_voice_matrix1", "clk_int_voice_matrix2",
|
||||
"clk_frac_voice_matrix0", "clk_frac_voice_matrix1", "clk_frac_common_matrix0", "clk_frac_common_matrix1",
|
||||
"clk_frac_common_matrix2", "sai0_mclk_in", "sai1_mclk_in", "sai2_mclk_in", "sai3_mclk_in" };
|
||||
PNAME(lrck_asrc_parents_p) = { "mclk_asrc0", "mclk_asrc1", "mclk_asrc2", "mclk_asrc3", "mclk_spdiftx", "clk_spdifrx_to_asrc", "clkout_pdm",
|
||||
"sai0_fs", "sai1_fs", "sai2_fs", "sai3_fs", "sai4_fs" };
|
||||
PNAME(cclk_src_sdmmc_parents_p) = { "xin24m_gate", "gpll", "clk_v0pll_gate", "clk_v1pll_gate" };
|
||||
PNAME(dclk_vop_parents_p) = { "xin24m_gate", "clk_gpll_gate", "clk_v0pll_gate", "clk_v1pll_gate", "dummy_vop_dclk",
|
||||
"dummy_vop_dclk", "dummy_vop_dclk", "dummy_vop_dclk" };
|
||||
PNAME(dbclk_gpio0_parents_p) = { "xin24m", "clk_rc", "clk_32k_pmu" };
|
||||
PNAME(clk_pmu_hp_timer_parents_p) = { "xin24m", "gpll_div_100m", "clk_core_pvtpll" };
|
||||
PNAME(clk_ref_out_parents_p) = { "xin24m", "gpll", "v0pll", "v1pll" };
|
||||
PNAME(clk_32k_frac_parents_p) = { "xin24m", "v0pll", "v1pll", "clk_rc" };
|
||||
PNAME(clk_32k_parents_p) = { "xin32k", "clk_32k_rc", "clk_32k_frac" };
|
||||
PNAME(clk_ref_phy_pmu_mux_parents_p) = { "xin24m", "clk_ref_phy_pll" };
|
||||
PNAME(clk_vpll_ref_parents_p) = { "xin24m", "clk_pll_ref_io" };
|
||||
PNAME(mux_armclk_p) = { "armclk_pll", "clk_core_pvtpll" };
|
||||
|
||||
#define MFLAGS CLK_MUX_HIWORD_MASK
|
||||
#define DFLAGS CLK_DIVIDER_HIWORD_MASK
|
||||
#define GFLAGS (CLK_GATE_HIWORD_MASK | CLK_GATE_SET_TO_DISABLE)
|
||||
|
||||
static struct rockchip_pll_clock rk3506_pll_clks[] __initdata = {
|
||||
[gpll] = PLL(pll_rk3328, PLL_GPLL, "gpll", mux_pll_p,
|
||||
CLK_IS_CRITICAL, RK3506_PLL_CON(0),
|
||||
RK3506_MODE_CON, 0, 2, 0, rk3506_pll_rates),
|
||||
[v0pll] = PLL(pll_rk3328, PLL_V0PLL, "v0pll", mux_pll_p,
|
||||
CLK_IS_CRITICAL, RK3506_PLL_CON(8),
|
||||
RK3506_MODE_CON, 2, 0, 0, rk3506_pll_rates),
|
||||
[v1pll] = PLL(pll_rk3328, PLL_V1PLL, "v1pll", mux_pll_p,
|
||||
CLK_IS_CRITICAL, RK3506_PLL_CON(16),
|
||||
RK3506_MODE_CON, 4, 1, 0, rk3506_pll_rates),
|
||||
};
|
||||
|
||||
static struct rockchip_clk_branch rk3506_armclk __initdata =
|
||||
MUX(ARMCLK, "armclk", mux_armclk_p, CLK_IS_CRITICAL | CLK_SET_RATE_PARENT,
|
||||
RK3506_CLKSEL_CON(15), 8, 1, MFLAGS);
|
||||
|
||||
static struct rockchip_clk_branch rk3506_clk_branches[] __initdata = {
|
||||
/*
|
||||
* CRU Clock-Architecture
|
||||
*/
|
||||
/* top */
|
||||
GATE(XIN24M_GATE, "xin24m_gate", "xin24m", CLK_IS_CRITICAL,
|
||||
RK3506_CLKGATE_CON(0), 1, GFLAGS),
|
||||
GATE(CLK_GPLL_GATE, "clk_gpll_gate", "gpll", CLK_IS_CRITICAL,
|
||||
RK3506_CLKGATE_CON(0), 2, GFLAGS),
|
||||
GATE(CLK_V0PLL_GATE, "clk_v0pll_gate", "v0pll", CLK_IS_CRITICAL,
|
||||
RK3506_CLKGATE_CON(0), 3, GFLAGS),
|
||||
GATE(CLK_V1PLL_GATE, "clk_v1pll_gate", "v1pll", 0,
|
||||
RK3506_CLKGATE_CON(0), 4, GFLAGS),
|
||||
COMPOSITE_NOMUX(CLK_GPLL_DIV, "clk_gpll_div", "clk_gpll_gate", CLK_IS_CRITICAL,
|
||||
RK3506_CLKSEL_CON(0), 6, 4, DFLAGS,
|
||||
RK3506_CLKGATE_CON(0), 5, GFLAGS),
|
||||
COMPOSITE_NOMUX(CLK_GPLL_DIV_100M, "clk_gpll_div_100m", "clk_gpll_div", 0,
|
||||
RK3506_CLKSEL_CON(0), 10, 4, DFLAGS,
|
||||
RK3506_CLKGATE_CON(0), 6, GFLAGS),
|
||||
COMPOSITE_NOMUX(CLK_V0PLL_DIV, "clk_v0pll_div", "clk_v0pll_gate", CLK_IS_CRITICAL,
|
||||
RK3506_CLKSEL_CON(1), 0, 4, DFLAGS,
|
||||
RK3506_CLKGATE_CON(0), 7, GFLAGS),
|
||||
COMPOSITE_NOMUX(CLK_V1PLL_DIV, "clk_v1pll_div", "clk_v1pll_gate", 0,
|
||||
RK3506_CLKSEL_CON(1), 4, 4, DFLAGS,
|
||||
RK3506_CLKGATE_CON(0), 8, GFLAGS),
|
||||
COMPOSITE_NOMUX(CLK_INT_VOICE_MATRIX0, "clk_int_voice_matrix0", "clk_v0pll_gate", 0,
|
||||
RK3506_CLKSEL_CON(1), 8, 5, DFLAGS,
|
||||
RK3506_CLKGATE_CON(0), 9, GFLAGS),
|
||||
COMPOSITE_NOMUX(CLK_INT_VOICE_MATRIX1, "clk_int_voice_matrix1", "clk_v1pll_gate", 0,
|
||||
RK3506_CLKSEL_CON(2), 0, 5, DFLAGS,
|
||||
RK3506_CLKGATE_CON(0), 10, GFLAGS),
|
||||
COMPOSITE_NOMUX(CLK_INT_VOICE_MATRIX2, "clk_int_voice_matrix2", "clk_v0pll_gate", 0,
|
||||
RK3506_CLKSEL_CON(2), 5, 5, DFLAGS,
|
||||
RK3506_CLKGATE_CON(0), 11, GFLAGS),
|
||||
MUX(CLK_FRAC_UART_MATRIX0_MUX, "clk_frac_uart_matrix0_mux", clk_frac_uart_matrix0_mux_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(3), 9, 2, MFLAGS),
|
||||
MUX(CLK_FRAC_UART_MATRIX1_MUX, "clk_frac_uart_matrix1_mux", xin24m_gpll_v0pll_v1pll_g_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(3), 11, 2, MFLAGS),
|
||||
MUX(CLK_FRAC_VOICE_MATRIX0_MUX, "clk_frac_voice_matrix0_mux", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(3), 13, 2, MFLAGS),
|
||||
MUX(CLK_FRAC_VOICE_MATRIX1_MUX, "clk_frac_voice_matrix1_mux", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(4), 0, 2, MFLAGS),
|
||||
MUX(CLK_FRAC_COMMON_MATRIX0_MUX, "clk_frac_common_matrix0_mux", xin24m_gpll_v0pll_v1pll_g_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(4), 2, 2, MFLAGS),
|
||||
MUX(CLK_FRAC_COMMON_MATRIX1_MUX, "clk_frac_common_matrix1_mux", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(4), 4, 2, MFLAGS),
|
||||
MUX(CLK_FRAC_COMMON_MATRIX2_MUX, "clk_frac_common_matrix2_mux", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(4), 6, 2, MFLAGS),
|
||||
COMPOSITE_FRAC(CLK_FRAC_UART_MATRIX0, "clk_frac_uart_matrix0", "clk_frac_uart_matrix0_mux", 0,
|
||||
RK3506_CLKSEL_CON(5), 0,
|
||||
RK3506_CLKGATE_CON(0), 13, GFLAGS),
|
||||
COMPOSITE_FRAC(CLK_FRAC_UART_MATRIX1, "clk_frac_uart_matrix1", "clk_frac_uart_matrix1_mux", 0,
|
||||
RK3506_CLKSEL_CON(6), 0,
|
||||
RK3506_CLKGATE_CON(0), 14, GFLAGS),
|
||||
COMPOSITE_FRAC(CLK_FRAC_VOICE_MATRIX0, "clk_frac_voice_matrix0", "clk_frac_voice_matrix0_mux", 0,
|
||||
RK3506_CLKSEL_CON(7), 0,
|
||||
RK3506_CLKGATE_CON(0), 15, GFLAGS),
|
||||
COMPOSITE_FRAC(CLK_FRAC_VOICE_MATRIX1, "clk_frac_voice_matrix1", "clk_frac_voice_matrix1_mux", 0,
|
||||
RK3506_CLKSEL_CON(9), 0,
|
||||
RK3506_CLKGATE_CON(1), 0, GFLAGS),
|
||||
COMPOSITE_FRAC(CLK_FRAC_COMMON_MATRIX0, "clk_frac_common_matrix0", "clk_frac_common_matrix0_mux", 0,
|
||||
RK3506_CLKSEL_CON(11), 0,
|
||||
RK3506_CLKGATE_CON(1), 1, GFLAGS),
|
||||
COMPOSITE_FRAC(CLK_FRAC_COMMON_MATRIX1, "clk_frac_common_matrix1", "clk_frac_common_matrix1_mux", 0,
|
||||
RK3506_CLKSEL_CON(12), 0,
|
||||
RK3506_CLKGATE_CON(1), 2, GFLAGS),
|
||||
COMPOSITE_FRAC(CLK_FRAC_COMMON_MATRIX2, "clk_frac_common_matrix2", "clk_frac_common_matrix2_mux", 0,
|
||||
RK3506_CLKSEL_CON(13), 0,
|
||||
RK3506_CLKGATE_CON(1), 3, GFLAGS),
|
||||
GATE(CLK_REF_USBPHY_TOP, "clk_ref_usbphy_top", "xin24m", 0,
|
||||
RK3506_CLKGATE_CON(1), 4, GFLAGS),
|
||||
GATE(CLK_REF_DPHY_TOP, "clk_ref_dphy_top", "xin24m", 0,
|
||||
RK3506_CLKGATE_CON(1), 5, GFLAGS),
|
||||
|
||||
/* core */
|
||||
COMPOSITE_NOGATE(0, "armclk_pll", gpll_v0pll_v1pll_parents_p, CLK_IS_CRITICAL,
|
||||
RK3506_CLKSEL_CON(15), 5, 2, MFLAGS, 0, 5, DFLAGS),
|
||||
COMPOSITE_NOMUX(ACLK_CORE_ROOT, "aclk_core_root", "armclk", CLK_IGNORE_UNUSED,
|
||||
RK3506_CLKSEL_CON(15), 9, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
|
||||
RK3506_CLKGATE_CON(2), 11, GFLAGS),
|
||||
COMPOSITE_NOMUX(PCLK_CORE_ROOT, "pclk_core_root", "armclk", CLK_IGNORE_UNUSED,
|
||||
RK3506_CLKSEL_CON(16), 0, 4, DFLAGS | CLK_DIVIDER_READ_ONLY,
|
||||
RK3506_CLKGATE_CON(2), 12, GFLAGS),
|
||||
GATE(PCLK_DBG, "pclk_dbg", "pclk_core_root", CLK_IGNORE_UNUSED,
|
||||
RK3506_CLKGATE_CON(3), 1, GFLAGS),
|
||||
GATE(PCLK_CORE_GRF, "pclk_core_grf", "pclk_core_root", CLK_IGNORE_UNUSED,
|
||||
RK3506_CLKGATE_CON(3), 4, GFLAGS),
|
||||
GATE(PCLK_CORE_CRU, "pclk_core_cru", "pclk_core_root", CLK_IGNORE_UNUSED,
|
||||
RK3506_CLKGATE_CON(3), 5, GFLAGS),
|
||||
GATE(CLK_CORE_EMA_DETECT, "clk_core_ema_detect", "xin24m_gate", CLK_IGNORE_UNUSED,
|
||||
RK3506_CLKGATE_CON(3), 6, GFLAGS),
|
||||
GATE(PCLK_GPIO1, "pclk_gpio1", "aclk_core_root", 0,
|
||||
RK3506_CLKGATE_CON(3), 8, GFLAGS),
|
||||
GATE(DBCLK_GPIO1, "dbclk_gpio1", "xin24m_gate", 0,
|
||||
RK3506_CLKGATE_CON(3), 9, GFLAGS),
|
||||
|
||||
/* core peri */
|
||||
COMPOSITE(ACLK_CORE_PERI_ROOT, "aclk_core_peri_root", gpll_v0pll_v1pll_g_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(18), 5, 2, MFLAGS, 0, 5, DFLAGS,
|
||||
RK3506_CLKGATE_CON(4), 0, GFLAGS),
|
||||
GATE(HCLK_CORE_PERI_ROOT, "hclk_core_peri_root", "aclk_core_peri_root", 0,
|
||||
RK3506_CLKGATE_CON(4), 1, GFLAGS),
|
||||
GATE(PCLK_CORE_PERI_ROOT, "pclk_core_peri_root", "aclk_core_peri_root", 0,
|
||||
RK3506_CLKGATE_CON(4), 2, GFLAGS),
|
||||
COMPOSITE(CLK_DSMC, "clk_dsmc", xin24m_gpll_v0pll_v1pll_g_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(18), 12, 2, MFLAGS, 7, 5, DFLAGS,
|
||||
RK3506_CLKGATE_CON(4), 4, GFLAGS),
|
||||
GATE(ACLK_DSMC, "aclk_dsmc", "aclk_core_peri_root", 0,
|
||||
RK3506_CLKGATE_CON(4), 5, GFLAGS),
|
||||
GATE(PCLK_DSMC, "pclk_dsmc", "pclk_core_peri_root", 0,
|
||||
RK3506_CLKGATE_CON(4), 6, GFLAGS),
|
||||
COMPOSITE(CLK_FLEXBUS_TX, "clk_flexbus_tx", xin24m_gpll_v0pll_v1pll_g_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(19), 5, 2, MFLAGS, 0, 5, DFLAGS,
|
||||
RK3506_CLKGATE_CON(4), 7, GFLAGS),
|
||||
COMPOSITE(CLK_FLEXBUS_RX, "clk_flexbus_rx", xin24m_gpll_v0pll_v1pll_g_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(19), 12, 2, MFLAGS, 7, 5, DFLAGS,
|
||||
RK3506_CLKGATE_CON(4), 8, GFLAGS),
|
||||
GATE(ACLK_FLEXBUS, "aclk_flexbus", "aclk_core_peri_root", 0,
|
||||
RK3506_CLKGATE_CON(4), 9, GFLAGS),
|
||||
GATE(HCLK_FLEXBUS, "hclk_flexbus", "hclk_core_peri_root", 0,
|
||||
RK3506_CLKGATE_CON(4), 10, GFLAGS),
|
||||
GATE(ACLK_DSMC_SLV, "aclk_dsmc_slv", "aclk_core_peri_root", 0,
|
||||
RK3506_CLKGATE_CON(4), 11, GFLAGS),
|
||||
GATE(HCLK_DSMC_SLV, "hclk_dsmc_slv", "hclk_core_peri_root", 0,
|
||||
RK3506_CLKGATE_CON(4), 12, GFLAGS),
|
||||
|
||||
/* bus */
|
||||
COMPOSITE(ACLK_BUS_ROOT, "aclk_bus_root", gpll_v0pll_v1pll_div_parents_p, CLK_IS_CRITICAL,
|
||||
RK3506_CLKSEL_CON(21), 5, 2, MFLAGS, 0, 5, DFLAGS,
|
||||
RK3506_CLKGATE_CON(5), 0, GFLAGS),
|
||||
COMPOSITE(HCLK_BUS_ROOT, "hclk_bus_root", gpll_v0pll_v1pll_div_parents_p, CLK_IS_CRITICAL,
|
||||
RK3506_CLKSEL_CON(21), 12, 2, MFLAGS, 7, 5, DFLAGS,
|
||||
RK3506_CLKGATE_CON(5), 1, GFLAGS),
|
||||
COMPOSITE(PCLK_BUS_ROOT, "pclk_bus_root", gpll_v0pll_v1pll_div_parents_p, CLK_IS_CRITICAL,
|
||||
RK3506_CLKSEL_CON(22), 5, 2, MFLAGS, 0, 5, DFLAGS,
|
||||
RK3506_CLKGATE_CON(5), 2, GFLAGS),
|
||||
GATE(ACLK_SYSRAM, "aclk_sysram", "aclk_bus_root", CLK_IGNORE_UNUSED,
|
||||
RK3506_CLKGATE_CON(5), 6, GFLAGS),
|
||||
GATE(HCLK_SYSRAM, "hclk_sysram", "aclk_bus_root", CLK_IGNORE_UNUSED,
|
||||
RK3506_CLKGATE_CON(5), 7, GFLAGS),
|
||||
GATE(ACLK_DMAC0, "aclk_dmac0", "aclk_bus_root", 0,
|
||||
RK3506_CLKGATE_CON(5), 8, GFLAGS),
|
||||
GATE(ACLK_DMAC1, "aclk_dmac1", "aclk_bus_root", 0,
|
||||
RK3506_CLKGATE_CON(5), 9, GFLAGS),
|
||||
GATE(HCLK_M0, "hclk_m0", "aclk_bus_root", 0,
|
||||
RK3506_CLKGATE_CON(5), 10, GFLAGS),
|
||||
GATE(ACLK_CRYPTO_NS, "aclk_crypto_ns", "aclk_bus_root", 0,
|
||||
RK3506_CLKGATE_CON(5), 14, GFLAGS),
|
||||
GATE(HCLK_CRYPTO_NS, "hclk_crypto_ns", "hclk_bus_root", 0,
|
||||
RK3506_CLKGATE_CON(5), 15, GFLAGS),
|
||||
GATE(HCLK_RNG, "hclk_rng", "hclk_bus_root", 0,
|
||||
RK3506_CLKGATE_CON(6), 0, GFLAGS),
|
||||
GATE(PCLK_BUS_GRF, "pclk_bus_grf", "pclk_bus_root", CLK_IGNORE_UNUSED,
|
||||
RK3506_CLKGATE_CON(6), 1, GFLAGS),
|
||||
GATE(PCLK_TIMER, "pclk_timer", "pclk_bus_root", 0,
|
||||
RK3506_CLKGATE_CON(6), 2, GFLAGS),
|
||||
COMPOSITE_NODIV(CLK_TIMER0_CH0, "clk_timer0_ch0", clk_timer0_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(22), 7, 3, MFLAGS,
|
||||
RK3506_CLKGATE_CON(6), 3, GFLAGS),
|
||||
COMPOSITE_NODIV(CLK_TIMER0_CH1, "clk_timer0_ch1", clk_timer1_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(22), 10, 3, MFLAGS,
|
||||
RK3506_CLKGATE_CON(6), 4, GFLAGS),
|
||||
COMPOSITE_NODIV(CLK_TIMER0_CH2, "clk_timer0_ch2", clk_timer2_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(22), 13, 3, MFLAGS,
|
||||
RK3506_CLKGATE_CON(6), 5, GFLAGS),
|
||||
COMPOSITE_NODIV(CLK_TIMER0_CH3, "clk_timer0_ch3", clk_timer3_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(23), 0, 3, MFLAGS,
|
||||
RK3506_CLKGATE_CON(6), 6, GFLAGS),
|
||||
COMPOSITE_NODIV(CLK_TIMER0_CH4, "clk_timer0_ch4", clk_timer4_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(23), 3, 3, MFLAGS,
|
||||
RK3506_CLKGATE_CON(6), 7, GFLAGS),
|
||||
COMPOSITE_NODIV(CLK_TIMER0_CH5, "clk_timer0_ch5", clk_timer5_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(23), 6, 3, MFLAGS,
|
||||
RK3506_CLKGATE_CON(6), 8, GFLAGS),
|
||||
GATE(PCLK_WDT0, "pclk_wdt0", "pclk_bus_root", 0,
|
||||
RK3506_CLKGATE_CON(6), 9, GFLAGS),
|
||||
GATE(TCLK_WDT0, "tclk_wdt0", "xin24m_gate", 0,
|
||||
RK3506_CLKGATE_CON(6), 10, GFLAGS),
|
||||
GATE(PCLK_WDT1, "pclk_wdt1", "pclk_bus_root", 0,
|
||||
RK3506_CLKGATE_CON(6), 11, GFLAGS),
|
||||
GATE(TCLK_WDT1, "tclk_wdt1", "xin24m_gate", 0,
|
||||
RK3506_CLKGATE_CON(6), 12, GFLAGS),
|
||||
GATE(PCLK_MAILBOX, "pclk_mailbox", "pclk_bus_root", 0,
|
||||
RK3506_CLKGATE_CON(6), 13, GFLAGS),
|
||||
GATE(PCLK_INTMUX, "pclk_intmux", "pclk_bus_root", 0,
|
||||
RK3506_CLKGATE_CON(6), 14, GFLAGS),
|
||||
GATE(PCLK_SPINLOCK, "pclk_spinlock", "pclk_bus_root", 0,
|
||||
RK3506_CLKGATE_CON(6), 15, GFLAGS),
|
||||
GATE(PCLK_DDRC, "pclk_ddrc", "pclk_bus_root", CLK_IGNORE_UNUSED,
|
||||
RK3506_CLKGATE_CON(7), 0, GFLAGS),
|
||||
GATE(HCLK_DDRPHY, "hclk_ddrphy", "hclk_bus_root", CLK_IGNORE_UNUSED,
|
||||
RK3506_CLKGATE_CON(7), 1, GFLAGS),
|
||||
GATE(PCLK_DDRMON, "pclk_ddrmon", "pclk_bus_root", CLK_IGNORE_UNUSED,
|
||||
RK3506_CLKGATE_CON(7), 2, GFLAGS),
|
||||
GATE(CLK_DDRMON_OSC, "clk_ddrmon_osc", "xin24m_gate", CLK_IGNORE_UNUSED,
|
||||
RK3506_CLKGATE_CON(7), 3, GFLAGS),
|
||||
GATE(PCLK_STDBY, "pclk_stdby", "pclk_bus_root", CLK_IGNORE_UNUSED,
|
||||
RK3506_CLKGATE_CON(7), 4, GFLAGS),
|
||||
GATE(HCLK_USBOTG0, "hclk_usbotg0", "hclk_bus_root", 0,
|
||||
RK3506_CLKGATE_CON(7), 5, GFLAGS),
|
||||
GATE(HCLK_USBOTG0_PMU, "hclk_usbotg0_pmu", "hclk_bus_root", 0,
|
||||
RK3506_CLKGATE_CON(7), 6, GFLAGS),
|
||||
GATE(CLK_USBOTG0_ADP, "clk_usbotg0_adp", "clk_32k", 0,
|
||||
RK3506_CLKGATE_CON(7), 7, GFLAGS),
|
||||
GATE(HCLK_USBOTG1, "hclk_usbotg1", "hclk_bus_root", 0,
|
||||
RK3506_CLKGATE_CON(7), 8, GFLAGS),
|
||||
GATE(HCLK_USBOTG1_PMU, "hclk_usbotg1_pmu", "hclk_bus_root", 0,
|
||||
RK3506_CLKGATE_CON(7), 9, GFLAGS),
|
||||
GATE(CLK_USBOTG1_ADP, "clk_usbotg1_adp", "clk_32k", 0,
|
||||
RK3506_CLKGATE_CON(7), 10, GFLAGS),
|
||||
GATE(PCLK_USBPHY, "pclk_usbphy", "pclk_bus_root", 0,
|
||||
RK3506_CLKGATE_CON(7), 11, GFLAGS),
|
||||
GATE(ACLK_DMA2DDR, "aclk_dma2ddr", "aclk_bus_root", CLK_IGNORE_UNUSED,
|
||||
RK3506_CLKGATE_CON(8), 0, GFLAGS),
|
||||
GATE(PCLK_DMA2DDR, "pclk_dma2ddr", "pclk_bus_root", CLK_IGNORE_UNUSED,
|
||||
RK3506_CLKGATE_CON(8), 1, GFLAGS),
|
||||
COMPOSITE_NOMUX(STCLK_M0, "stclk_m0", "xin24m_gate", 0,
|
||||
RK3506_CLKSEL_CON(23), 9, 6, DFLAGS,
|
||||
RK3506_CLKGATE_CON(8), 2, GFLAGS),
|
||||
COMPOSITE(CLK_DDRPHY, "clk_ddrphy", gpll_v0pll_v1pll_parents_p, CLK_IGNORE_UNUSED,
|
||||
RK3506_PMU_CLKSEL_CON(4), 4, 2, MFLAGS, 0, 4, DFLAGS,
|
||||
RK3506_PMU_CLKGATE_CON(1), 10, GFLAGS),
|
||||
FACTOR(CLK_DDRC_SRC, "clk_ddrc_src", "clk_ddrphy", 0, 1, 4),
|
||||
GATE(ACLK_DDRC_0, "aclk_ddrc_0", "clk_ddrc_src", CLK_IGNORE_UNUSED,
|
||||
RK3506_CLKGATE_CON(10), 0, GFLAGS),
|
||||
GATE(ACLK_DDRC_1, "aclk_ddrc_1", "clk_ddrc_src", CLK_IGNORE_UNUSED,
|
||||
RK3506_CLKGATE_CON(10), 1, GFLAGS),
|
||||
GATE(CLK_DDRC, "clk_ddrc", "clk_ddrc_src", CLK_IS_CRITICAL,
|
||||
RK3506_CLKGATE_CON(10), 3, GFLAGS),
|
||||
GATE(CLK_DDRMON, "clk_ddrmon", "clk_ddrc_src", CLK_IGNORE_UNUSED,
|
||||
RK3506_CLKGATE_CON(10), 4, GFLAGS),
|
||||
|
||||
/* ls peri */
|
||||
COMPOSITE(HCLK_LSPERI_ROOT, "hclk_lsperi_root", gpll_v0pll_v1pll_div_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(29), 5, 2, MFLAGS, 0, 5, DFLAGS,
|
||||
RK3506_CLKGATE_CON(11), 0, GFLAGS),
|
||||
GATE(PCLK_LSPERI_ROOT, "pclk_lsperi_root", "hclk_lsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(11), 1, GFLAGS),
|
||||
GATE(PCLK_UART0, "pclk_uart0", "pclk_lsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(11), 4, GFLAGS),
|
||||
GATE(PCLK_UART1, "pclk_uart1", "pclk_lsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(11), 5, GFLAGS),
|
||||
GATE(PCLK_UART2, "pclk_uart2", "pclk_lsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(11), 6, GFLAGS),
|
||||
GATE(PCLK_UART3, "pclk_uart3", "pclk_lsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(11), 7, GFLAGS),
|
||||
GATE(PCLK_UART4, "pclk_uart4", "pclk_lsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(11), 8, GFLAGS),
|
||||
COMPOSITE(SCLK_UART0, "sclk_uart0", sclk_uart_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(29), 12, 3, MFLAGS, 7, 5, DFLAGS,
|
||||
RK3506_CLKGATE_CON(11), 9, GFLAGS),
|
||||
COMPOSITE(SCLK_UART1, "sclk_uart1", sclk_uart_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(30), 5, 3, MFLAGS, 0, 5, DFLAGS,
|
||||
RK3506_CLKGATE_CON(11), 10, GFLAGS),
|
||||
COMPOSITE(SCLK_UART2, "sclk_uart2", sclk_uart_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(30), 13, 3, MFLAGS, 8, 5, DFLAGS,
|
||||
RK3506_CLKGATE_CON(11), 11, GFLAGS),
|
||||
COMPOSITE(SCLK_UART3, "sclk_uart3", sclk_uart_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(31), 5, 3, MFLAGS, 0, 5, DFLAGS,
|
||||
RK3506_CLKGATE_CON(11), 12, GFLAGS),
|
||||
COMPOSITE(SCLK_UART4, "sclk_uart4", sclk_uart_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(31), 13, 3, MFLAGS, 8, 5, DFLAGS,
|
||||
RK3506_CLKGATE_CON(11), 13, GFLAGS),
|
||||
GATE(PCLK_I2C0, "pclk_i2c0", "pclk_lsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(11), 14, GFLAGS),
|
||||
COMPOSITE(CLK_I2C0, "clk_i2c0", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(32), 4, 2, MFLAGS, 0, 4, DFLAGS,
|
||||
RK3506_CLKGATE_CON(11), 15, GFLAGS),
|
||||
GATE(PCLK_I2C1, "pclk_i2c1", "pclk_lsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(12), 0, GFLAGS),
|
||||
COMPOSITE(CLK_I2C1, "clk_i2c1", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(32), 10, 2, MFLAGS, 6, 4, DFLAGS,
|
||||
RK3506_CLKGATE_CON(12), 1, GFLAGS),
|
||||
GATE(PCLK_I2C2, "pclk_i2c2", "pclk_lsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(12), 2, GFLAGS),
|
||||
COMPOSITE(CLK_I2C2, "clk_i2c2", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(33), 4, 2, MFLAGS, 0, 4, DFLAGS,
|
||||
RK3506_CLKGATE_CON(12), 3, GFLAGS),
|
||||
GATE(PCLK_PWM1, "pclk_pwm1", "pclk_lsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(12), 4, GFLAGS),
|
||||
COMPOSITE(CLK_PWM1, "clk_pwm1", gpll_v0pll_v1pll_div_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(33), 10, 2, MFLAGS, 6, 4, DFLAGS,
|
||||
RK3506_CLKGATE_CON(12), 5, GFLAGS),
|
||||
GATE(CLK_OSC_PWM1, "clk_osc_pwm1", "xin24m", 0,
|
||||
RK3506_CLKGATE_CON(12), 6, GFLAGS),
|
||||
GATE(CLK_RC_PWM1, "clk_rc_pwm1", "clk_rc", 0,
|
||||
RK3506_CLKGATE_CON(12), 7, GFLAGS),
|
||||
COMPOSITE_NODIV(CLK_FREQ_PWM1, "clk_freq_pwm1", clk_pwm_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(33), 12, 4, MFLAGS,
|
||||
RK3506_CLKGATE_CON(12), 8, GFLAGS),
|
||||
COMPOSITE_NODIV(CLK_COUNTER_PWM1, "clk_counter_pwm1", clk_pwm_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(34), 0, 4, MFLAGS,
|
||||
RK3506_CLKGATE_CON(12), 9, GFLAGS),
|
||||
GATE(PCLK_SPI0, "pclk_spi0", "pclk_lsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(12), 10, GFLAGS),
|
||||
COMPOSITE(CLK_SPI0, "clk_spi0", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(34), 8, 2, MFLAGS, 4, 4, DFLAGS,
|
||||
RK3506_CLKGATE_CON(12), 11, GFLAGS),
|
||||
GATE(PCLK_SPI1, "pclk_spi1", "pclk_lsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(12), 12, GFLAGS),
|
||||
COMPOSITE(CLK_SPI1, "clk_spi1", xin24m_g_gpll_v0pll_v1pll_div_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(34), 14, 2, MFLAGS, 10, 4, DFLAGS,
|
||||
RK3506_CLKGATE_CON(12), 13, GFLAGS),
|
||||
GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_lsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(12), 14, GFLAGS),
|
||||
COMPOSITE_NODIV(DBCLK_GPIO2, "dbclk_gpio2", xin24m_400k_32k_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(35), 0, 2, MFLAGS,
|
||||
RK3506_CLKGATE_CON(12), 15, GFLAGS),
|
||||
GATE(PCLK_GPIO3, "pclk_gpio3", "pclk_lsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(13), 0, GFLAGS),
|
||||
COMPOSITE_NODIV(DBCLK_GPIO3, "dbclk_gpio3", xin24m_400k_32k_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(35), 2, 2, MFLAGS,
|
||||
RK3506_CLKGATE_CON(13), 1, GFLAGS),
|
||||
GATE(PCLK_GPIO4, "pclk_gpio4", "pclk_lsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(13), 2, GFLAGS),
|
||||
COMPOSITE_NODIV(DBCLK_GPIO4, "dbclk_gpio4", xin24m_400k_32k_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(35), 4, 2, MFLAGS,
|
||||
RK3506_CLKGATE_CON(13), 3, GFLAGS),
|
||||
GATE(HCLK_CAN0, "hclk_can0", "hclk_lsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(13), 4, GFLAGS),
|
||||
COMPOSITE(CLK_CAN0, "clk_can0", clk_can_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(35), 11, 3, MFLAGS, 6, 5, DFLAGS,
|
||||
RK3506_CLKGATE_CON(13), 5, GFLAGS),
|
||||
GATE(HCLK_CAN1, "hclk_can1", "hclk_lsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(13), 6, GFLAGS),
|
||||
COMPOSITE(CLK_CAN1, "clk_can1", clk_can_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(36), 5, 3, MFLAGS, 0, 5, DFLAGS,
|
||||
RK3506_CLKGATE_CON(13), 7, GFLAGS),
|
||||
GATE(HCLK_PDM, "hclk_pdm", "hclk_lsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(13), 8, GFLAGS),
|
||||
COMPOSITE(MCLK_PDM, "mclk_pdm", clk_pdm_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(37), 5, 4, MFLAGS, 0, 5, DFLAGS,
|
||||
RK3506_CLKGATE_CON(13), 9, GFLAGS),
|
||||
COMPOSITE(CLKOUT_PDM, "clkout_pdm", clk_pdm_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(38), 10, 4, MFLAGS, 0, 10, DFLAGS,
|
||||
RK3506_CLKGATE_CON(13), 10, GFLAGS),
|
||||
COMPOSITE(MCLK_SPDIFTX, "mclk_spdiftx", mclk_sai_asrc_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(39), 5, 4, MFLAGS, 0, 5, DFLAGS,
|
||||
RK3506_CLKGATE_CON(13), 11, GFLAGS),
|
||||
GATE(HCLK_SPDIFTX, "hclk_spdiftx", "hclk_lsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(13), 12, GFLAGS),
|
||||
GATE(HCLK_SPDIFRX, "hclk_spdifrx", "hclk_lsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(13), 13, GFLAGS),
|
||||
COMPOSITE(MCLK_SPDIFRX, "mclk_spdifrx", gpll_v0pll_v1pll_g_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(39), 14, 2, MFLAGS, 9, 5, DFLAGS,
|
||||
RK3506_CLKGATE_CON(13), 14, GFLAGS),
|
||||
COMPOSITE(MCLK_SAI0, "mclk_sai0", mclk_sai_asrc_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(40), 8, 4, MFLAGS, 0, 8, DFLAGS,
|
||||
RK3506_CLKGATE_CON(13), 15, GFLAGS),
|
||||
GATE(HCLK_SAI0, "hclk_sai0", "hclk_lsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(14), 0, GFLAGS),
|
||||
GATE(MCLK_OUT_SAI0, "mclk_out_sai0", "mclk_sai0", 0,
|
||||
RK3506_CLKGATE_CON(14), 1, GFLAGS),
|
||||
COMPOSITE(MCLK_SAI1, "mclk_sai1", mclk_sai_asrc_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(41), 8, 4, MFLAGS, 0, 8, DFLAGS,
|
||||
RK3506_CLKGATE_CON(14), 2, GFLAGS),
|
||||
GATE(HCLK_SAI1, "hclk_sai1", "hclk_lsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(14), 3, GFLAGS),
|
||||
GATE(MCLK_OUT_SAI1, "mclk_out_sai1", "mclk_sai1", 0,
|
||||
RK3506_CLKGATE_CON(14), 4, GFLAGS),
|
||||
GATE(HCLK_ASRC0, "hclk_asrc0", "hclk_lsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(14), 5, GFLAGS),
|
||||
COMPOSITE(CLK_ASRC0, "clk_asrc0", gpll_v0pll_v1pll_g_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(42), 5, 2, MFLAGS, 0, 5, DFLAGS,
|
||||
RK3506_CLKGATE_CON(14), 6, GFLAGS),
|
||||
GATE(HCLK_ASRC1, "hclk_asrc1", "hclk_lsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(14), 7, GFLAGS),
|
||||
COMPOSITE(CLK_ASRC1, "clk_asrc1", gpll_v0pll_v1pll_g_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(42), 12, 2, MFLAGS, 7, 5, DFLAGS,
|
||||
RK3506_CLKGATE_CON(14), 8, GFLAGS),
|
||||
GATE(PCLK_CRU, "pclk_cru", "pclk_lsperi_root", CLK_IS_CRITICAL,
|
||||
RK3506_CLKGATE_CON(14), 9, GFLAGS),
|
||||
GATE(PCLK_PMU_ROOT, "pclk_pmu_root", "pclk_lsperi_root", CLK_IS_CRITICAL,
|
||||
RK3506_CLKGATE_CON(14), 10, GFLAGS),
|
||||
COMPOSITE_NODIV(MCLK_ASRC0, "mclk_asrc0", mclk_sai_asrc_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(46), 0, 4, MFLAGS,
|
||||
RK3506_CLKGATE_CON(16), 0, GFLAGS),
|
||||
COMPOSITE_NODIV(MCLK_ASRC1, "mclk_asrc1", mclk_sai_asrc_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(46), 4, 4, MFLAGS,
|
||||
RK3506_CLKGATE_CON(16), 1, GFLAGS),
|
||||
COMPOSITE_NODIV(MCLK_ASRC2, "mclk_asrc2", mclk_sai_asrc_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(46), 8, 4, MFLAGS,
|
||||
RK3506_CLKGATE_CON(16), 2, GFLAGS),
|
||||
COMPOSITE_NODIV(MCLK_ASRC3, "mclk_asrc3", mclk_sai_asrc_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(46), 12, 4, MFLAGS,
|
||||
RK3506_CLKGATE_CON(16), 3, GFLAGS),
|
||||
COMPOSITE_NODIV(LRCK_ASRC0_SRC, "lrck_asrc0_src", lrck_asrc_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(47), 0, 4, MFLAGS,
|
||||
RK3506_CLKGATE_CON(16), 4, GFLAGS),
|
||||
COMPOSITE_NODIV(LRCK_ASRC0_DST, "lrck_asrc0_dst", lrck_asrc_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(47), 4, 4, MFLAGS,
|
||||
RK3506_CLKGATE_CON(16), 5, GFLAGS),
|
||||
COMPOSITE_NODIV(LRCK_ASRC1_SRC, "lrck_asrc1_src", lrck_asrc_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(47), 8, 4, MFLAGS,
|
||||
RK3506_CLKGATE_CON(16), 6, GFLAGS),
|
||||
COMPOSITE_NODIV(LRCK_ASRC1_DST, "lrck_asrc1_dst", lrck_asrc_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(47), 12, 4, MFLAGS,
|
||||
RK3506_CLKGATE_CON(16), 7, GFLAGS),
|
||||
|
||||
/* hs peri */
|
||||
COMPOSITE(ACLK_HSPERI_ROOT, "aclk_hsperi_root", gpll_v0pll_v1pll_div_parents_p, CLK_IS_CRITICAL,
|
||||
RK3506_CLKSEL_CON(49), 5, 2, MFLAGS, 0, 5, DFLAGS,
|
||||
RK3506_CLKGATE_CON(17), 0, GFLAGS),
|
||||
GATE(HCLK_HSPERI_ROOT, "hclk_hsperi_root", "aclk_hsperi_root", CLK_IS_CRITICAL,
|
||||
RK3506_CLKGATE_CON(17), 1, GFLAGS),
|
||||
GATE(PCLK_HSPERI_ROOT, "pclk_hsperi_root", "hclk_hsperi_root", CLK_IS_CRITICAL,
|
||||
RK3506_CLKGATE_CON(17), 2, GFLAGS),
|
||||
COMPOSITE(CCLK_SRC_SDMMC, "cclk_src_sdmmc", cclk_src_sdmmc_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(49), 13, 2, MFLAGS, 7, 6, DFLAGS,
|
||||
RK3506_CLKGATE_CON(17), 6, GFLAGS),
|
||||
GATE(HCLK_SDMMC, "hclk_sdmmc", "hclk_hsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(17), 7, GFLAGS),
|
||||
GATE(HCLK_FSPI, "hclk_fspi", "hclk_hsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(17), 8, GFLAGS),
|
||||
COMPOSITE(SCLK_FSPI, "sclk_fspi", xin24m_g_gpll_v0pll_v1pll_g_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(50), 5, 2, MFLAGS, 0, 5, DFLAGS,
|
||||
RK3506_CLKGATE_CON(17), 9, GFLAGS),
|
||||
GATE(PCLK_SPI2, "pclk_spi2", "pclk_hsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(17), 10, GFLAGS),
|
||||
GATE(ACLK_MAC0, "aclk_mac0", "aclk_hsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(17), 11, GFLAGS),
|
||||
GATE(ACLK_MAC1, "aclk_mac1", "aclk_hsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(17), 12, GFLAGS),
|
||||
GATE(PCLK_MAC0, "pclk_mac0", "pclk_hsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(17), 13, GFLAGS),
|
||||
GATE(PCLK_MAC1, "pclk_mac1", "pclk_hsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(17), 14, GFLAGS),
|
||||
COMPOSITE_NOMUX(CLK_MAC_ROOT, "clk_mac_root", "gpll", 0,
|
||||
RK3506_CLKSEL_CON(50), 7, 5, DFLAGS,
|
||||
RK3506_CLKGATE_CON(17), 15, GFLAGS),
|
||||
GATE(CLK_MAC0, "clk_mac0", "clk_mac_root", 0,
|
||||
RK3506_CLKGATE_CON(18), 0, GFLAGS),
|
||||
GATE(CLK_MAC1, "clk_mac1", "clk_mac_root", 0,
|
||||
RK3506_CLKGATE_CON(18), 1, GFLAGS),
|
||||
COMPOSITE(MCLK_SAI2, "mclk_sai2", mclk_sai_asrc_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(51), 8, 4, MFLAGS, 0, 8, DFLAGS,
|
||||
RK3506_CLKGATE_CON(18), 2, GFLAGS),
|
||||
GATE(HCLK_SAI2, "hclk_sai2", "hclk_hsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(18), 3, GFLAGS),
|
||||
GATE(MCLK_OUT_SAI2, "mclk_out_sai2", "mclk_sai2", 0,
|
||||
RK3506_CLKGATE_CON(18), 4, GFLAGS),
|
||||
COMPOSITE(MCLK_SAI3_SRC, "mclk_sai3_src", mclk_sai_asrc_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(52), 8, 4, MFLAGS, 0, 8, DFLAGS,
|
||||
RK3506_CLKGATE_CON(18), 5, GFLAGS),
|
||||
GATE(HCLK_SAI3, "hclk_sai3", "hclk_hsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(18), 6, GFLAGS),
|
||||
GATE(MCLK_SAI3, "mclk_sai3", "mclk_sai3_src", 0,
|
||||
RK3506_CLKGATE_CON(18), 7, GFLAGS),
|
||||
GATE(MCLK_OUT_SAI3, "mclk_out_sai3", "mclk_sai3_src", 0,
|
||||
RK3506_CLKGATE_CON(18), 8, GFLAGS),
|
||||
COMPOSITE(MCLK_SAI4_SRC, "mclk_sai4_src", mclk_sai_asrc_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(53), 8, 4, MFLAGS, 0, 8, DFLAGS,
|
||||
RK3506_CLKGATE_CON(18), 9, GFLAGS),
|
||||
GATE(HCLK_SAI4, "hclk_sai4", "hclk_hsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(18), 10, GFLAGS),
|
||||
GATE(MCLK_SAI4, "mclk_sai4", "mclk_sai4_src", 0,
|
||||
RK3506_CLKGATE_CON(18), 11, GFLAGS),
|
||||
GATE(HCLK_DSM, "hclk_dsm", "hclk_hsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(18), 12, GFLAGS),
|
||||
GATE(MCLK_DSM, "mclk_dsm", "mclk_sai3_src", 0,
|
||||
RK3506_CLKGATE_CON(18), 13, GFLAGS),
|
||||
GATE(PCLK_AUDIO_ADC, "pclk_audio_adc", "pclk_hsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(18), 14, GFLAGS),
|
||||
GATE(MCLK_AUDIO_ADC, "mclk_audio_adc", "mclk_sai4_src", 0,
|
||||
RK3506_CLKGATE_CON(18), 15, GFLAGS),
|
||||
FACTOR(MCLK_AUDIO_ADC_DIV4, "mclk_audio_adc_div4", "mclk_audio_adc", 0, 1, 4),
|
||||
GATE(PCLK_SARADC, "pclk_saradc", "pclk_hsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(19), 0, GFLAGS),
|
||||
COMPOSITE(CLK_SARADC, "clk_saradc", xin24m_400k_32k_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(54), 4, 2, MFLAGS, 0, 4, DFLAGS,
|
||||
RK3506_CLKGATE_CON(19), 1, GFLAGS),
|
||||
GATE(PCLK_OTPC_NS, "pclk_otpc_ns", "pclk_hsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(19), 3, GFLAGS),
|
||||
GATE(CLK_SBPI_OTPC_NS, "clk_sbpi_otpc_ns", "xin24m_gate", 0,
|
||||
RK3506_CLKGATE_CON(19), 4, GFLAGS),
|
||||
FACTOR(CLK_USER_OTPC_NS, "clk_user_otpc_ns", "clk_sbpi_otpc_ns", 0, 1, 2),
|
||||
GATE(PCLK_UART5, "pclk_uart5", "pclk_hsperi_root", 0,
|
||||
RK3506_CLKGATE_CON(19), 6, GFLAGS),
|
||||
COMPOSITE(SCLK_UART5, "sclk_uart5", sclk_uart_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(54), 11, 3, MFLAGS, 6, 5, DFLAGS,
|
||||
RK3506_CLKGATE_CON(19), 7, GFLAGS),
|
||||
GATE(PCLK_GPIO234_IOC, "pclk_gpio234_ioc", "pclk_hsperi_root", CLK_IS_CRITICAL,
|
||||
RK3506_CLKGATE_CON(19), 8, GFLAGS),
|
||||
COMPOSITE(CLK_MAC_PTP_ROOT, "clk_mac_ptp_root", clk_mac_ptp_root_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(55), 5, 2, MFLAGS, 0, 5, DFLAGS,
|
||||
RK3506_CLKGATE_CON(19), 9, GFLAGS),
|
||||
GATE(CLK_MAC0_PTP, "clk_mac0_ptp", "clk_mac_ptp_root", 0,
|
||||
RK3506_CLKGATE_CON(19), 10, GFLAGS),
|
||||
GATE(CLK_MAC1_PTP, "clk_mac1_ptp", "clk_mac_ptp_root", 0,
|
||||
RK3506_CLKGATE_CON(19), 11, GFLAGS),
|
||||
COMPOSITE(ACLK_VIO_ROOT, "aclk_vio_root", gpll_v0pll_v1pll_g_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(58), 5, 2, MFLAGS, 0, 5, DFLAGS,
|
||||
RK3506_CLKGATE_CON(21), 0, GFLAGS),
|
||||
COMPOSITE(HCLK_VIO_ROOT, "hclk_vio_root", gpll_v0pll_v1pll_div_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(58), 12, 2, MFLAGS, 7, 5, DFLAGS,
|
||||
RK3506_CLKGATE_CON(21), 1, GFLAGS),
|
||||
GATE(PCLK_VIO_ROOT, "pclk_vio_root", "hclk_vio_root", 0,
|
||||
RK3506_CLKGATE_CON(21), 2, GFLAGS),
|
||||
GATE(HCLK_RGA, "hclk_rga", "hclk_vio_root", 0,
|
||||
RK3506_CLKGATE_CON(21), 6, GFLAGS),
|
||||
GATE(ACLK_RGA, "aclk_rga", "aclk_vio_root", 0,
|
||||
RK3506_CLKGATE_CON(21), 7, GFLAGS),
|
||||
COMPOSITE(CLK_CORE_RGA, "clk_core_rga", gpll_v0pll_v1pll_g_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(59), 5, 2, MFLAGS, 0, 5, DFLAGS,
|
||||
RK3506_CLKGATE_CON(21), 8, GFLAGS),
|
||||
GATE(ACLK_VOP, "aclk_vop", "aclk_vio_root", 0,
|
||||
RK3506_CLKGATE_CON(21), 9, GFLAGS),
|
||||
GATE(HCLK_VOP, "hclk_vop", "hclk_vio_root", 0,
|
||||
RK3506_CLKGATE_CON(21), 10, GFLAGS),
|
||||
COMPOSITE(DCLK_VOP, "dclk_vop", dclk_vop_parents_p, 0,
|
||||
RK3506_CLKSEL_CON(60), 8, 3, MFLAGS, 0, 8, DFLAGS,
|
||||
RK3506_CLKGATE_CON(21), 11, GFLAGS),
|
||||
GATE(PCLK_DPHY, "pclk_dphy", "pclk_vio_root", 0,
|
||||
RK3506_CLKGATE_CON(21), 12, GFLAGS),
|
||||
GATE(PCLK_DSI_HOST, "pclk_dsi_host", "pclk_vio_root", 0,
|
||||
RK3506_CLKGATE_CON(21), 13, GFLAGS),
|
||||
GATE(PCLK_TSADC, "pclk_tsadc", "pclk_vio_root", 0,
|
||||
RK3506_CLKGATE_CON(21), 14, GFLAGS),
|
||||
COMPOSITE_NOMUX(CLK_TSADC, "clk_tsadc", "xin24m_gate", 0,
|
||||
RK3506_CLKSEL_CON(61), 0, 8, DFLAGS,
|
||||
RK3506_CLKGATE_CON(21), 15, GFLAGS),
|
||||
COMPOSITE_NOMUX(CLK_TSADC_TSEN, "clk_tsadc_tsen", "xin24m_gate", 0,
|
||||
RK3506_CLKSEL_CON(61), 8, 3, DFLAGS,
|
||||
RK3506_CLKGATE_CON(22), 0, GFLAGS),
|
||||
GATE(PCLK_GPIO1_IOC, "pclk_gpio1_ioc", "pclk_vio_root", CLK_IS_CRITICAL,
|
||||
RK3506_CLKGATE_CON(22), 1, GFLAGS),
|
||||
|
||||
/* pmu */
|
||||
GATE(CLK_PMU, "clk_pmu", "xin24m", CLK_IGNORE_UNUSED,
|
||||
RK3506_PMU_CLKGATE_CON(0), 1, GFLAGS),
|
||||
GATE(PCLK_PMU, "pclk_pmu", "pclk_pmu_root", CLK_IGNORE_UNUSED,
|
||||
RK3506_PMU_CLKGATE_CON(0), 2, GFLAGS),
|
||||
GATE(PCLK_PMU_CRU, "pclk_pmu_cru", "pclk_pmu_root", CLK_IGNORE_UNUSED,
|
||||
RK3506_PMU_CLKGATE_CON(0), 4, GFLAGS),
|
||||
GATE(PCLK_PMU_GRF, "pclk_pmu_grf", "pclk_pmu_root", CLK_IGNORE_UNUSED,
|
||||
RK3506_PMU_CLKGATE_CON(0), 5, GFLAGS),
|
||||
GATE(PCLK_GPIO0_IOC, "pclk_gpio0_ioc", "pclk_pmu_root", CLK_IS_CRITICAL,
|
||||
RK3506_PMU_CLKGATE_CON(0), 7, GFLAGS),
|
||||
GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_pmu_root", 0,
|
||||
RK3506_PMU_CLKGATE_CON(0), 8, GFLAGS),
|
||||
COMPOSITE_NODIV(DBCLK_GPIO0, "dbclk_gpio0", dbclk_gpio0_parents_p, 0,
|
||||
RK3506_PMU_CLKSEL_CON(0), 0, 2, MFLAGS,
|
||||
RK3506_PMU_CLKGATE_CON(0), 9, GFLAGS),
|
||||
GATE(PCLK_GPIO1_SHADOW, "pclk_gpio1_shadow", "pclk_pmu_root", 0,
|
||||
RK3506_PMU_CLKGATE_CON(0), 10, GFLAGS),
|
||||
COMPOSITE_NODIV(DBCLK_GPIO1_SHADOW, "dbclk_gpio1_shadow", dbclk_gpio0_parents_p, 0,
|
||||
RK3506_PMU_CLKSEL_CON(0), 2, 2, MFLAGS,
|
||||
RK3506_PMU_CLKGATE_CON(0), 11, GFLAGS),
|
||||
GATE(PCLK_PMU_HP_TIMER, "pclk_pmu_hp_timer", "pclk_pmu_root", CLK_IGNORE_UNUSED,
|
||||
RK3506_PMU_CLKGATE_CON(0), 12, GFLAGS),
|
||||
MUX(CLK_PMU_HP_TIMER, "clk_pmu_hp_timer", clk_pmu_hp_timer_parents_p, CLK_IGNORE_UNUSED,
|
||||
RK3506_PMU_CLKSEL_CON(0), 4, 2, MFLAGS),
|
||||
GATE(PCLK_PWM0, "pclk_pwm0", "pclk_pmu_root", 0,
|
||||
RK3506_PMU_CLKGATE_CON(0), 15, GFLAGS),
|
||||
COMPOSITE_NOMUX(CLK_PWM0, "clk_pwm0", "clk_gpll_div_100m", 0,
|
||||
RK3506_PMU_CLKSEL_CON(0), 6, 4, DFLAGS,
|
||||
RK3506_PMU_CLKGATE_CON(1), 0, GFLAGS),
|
||||
GATE(CLK_OSC_PWM0, "clk_osc_pwm0", "xin24m", 0,
|
||||
RK3506_PMU_CLKGATE_CON(1), 1, GFLAGS),
|
||||
GATE(CLK_RC_PWM0, "clk_rc_pwm0", "clk_rc", 0,
|
||||
RK3506_PMU_CLKGATE_CON(1), 2, GFLAGS),
|
||||
COMPOSITE_NOMUX(CLK_MAC_OUT, "clk_mac_out", "gpll", 0,
|
||||
RK3506_PMU_CLKSEL_CON(0), 10, 6, DFLAGS,
|
||||
RK3506_PMU_CLKGATE_CON(1), 3, GFLAGS),
|
||||
COMPOSITE(CLK_REF_OUT0, "clk_ref_out0", clk_ref_out_parents_p, 0,
|
||||
RK3506_PMU_CLKSEL_CON(1), 6, 2, MFLAGS, 0, 6, DFLAGS,
|
||||
RK3506_PMU_CLKGATE_CON(1), 4, GFLAGS),
|
||||
COMPOSITE(CLK_REF_OUT1, "clk_ref_out1", clk_ref_out_parents_p, 0,
|
||||
RK3506_PMU_CLKSEL_CON(1), 14, 2, MFLAGS, 8, 6, DFLAGS,
|
||||
RK3506_PMU_CLKGATE_CON(1), 5, GFLAGS),
|
||||
MUX(CLK_32K_FRAC_MUX, "clk_32k_frac_mux", clk_32k_frac_parents_p, 0,
|
||||
RK3506_PMU_CLKSEL_CON(3), 0, 2, MFLAGS),
|
||||
COMPOSITE_FRAC(CLK_32K_FRAC, "clk_32k_frac", "clk_32k_frac_mux", 0,
|
||||
RK3506_PMU_CLKSEL_CON(2), 0,
|
||||
RK3506_PMU_CLKGATE_CON(1), 6, GFLAGS),
|
||||
COMPOSITE_NOMUX(CLK_32K_RC, "clk_32k_rc", "clk_rc", CLK_IS_CRITICAL,
|
||||
RK3506_PMU_CLKSEL_CON(3), 2, 5, DFLAGS,
|
||||
RK3506_PMU_CLKGATE_CON(1), 7, GFLAGS),
|
||||
COMPOSITE_NODIV(CLK_32K, "clk_32k", clk_32k_parents_p, CLK_IS_CRITICAL,
|
||||
RK3506_PMU_CLKSEL_CON(3), 7, 2, MFLAGS,
|
||||
RK3506_PMU_CLKGATE_CON(1), 8, GFLAGS),
|
||||
COMPOSITE_NODIV(CLK_32K_PMU, "clk_32k_pmu", clk_32k_parents_p, CLK_IS_CRITICAL,
|
||||
RK3506_PMU_CLKSEL_CON(3), 9, 2, MFLAGS,
|
||||
RK3506_PMU_CLKGATE_CON(1), 9, GFLAGS),
|
||||
GATE(CLK_PMU_32K, "clk_pmu_32k", "clk_32k_pmu", CLK_IGNORE_UNUSED,
|
||||
RK3506_PMU_CLKGATE_CON(0), 3, GFLAGS),
|
||||
GATE(CLK_PMU_HP_TIMER_32K, "clk_pmu_hp_timer_32k", "clk_32k_pmu", CLK_IGNORE_UNUSED,
|
||||
RK3506_PMU_CLKGATE_CON(0), 14, GFLAGS),
|
||||
GATE(PCLK_TOUCH_KEY, "pclk_touch_key", "pclk_pmu_root", CLK_IGNORE_UNUSED,
|
||||
RK3506_PMU_CLKGATE_CON(1), 12, GFLAGS),
|
||||
GATE(CLK_TOUCH_KEY, "clk_touch_key", "xin24m", CLK_IGNORE_UNUSED,
|
||||
RK3506_PMU_CLKGATE_CON(1), 13, GFLAGS),
|
||||
COMPOSITE(CLK_REF_PHY_PLL, "clk_ref_phy_pll", gpll_v0pll_v1pll_parents_p, 0,
|
||||
RK3506_PMU_CLKSEL_CON(4), 13, 2, MFLAGS, 6, 7, DFLAGS,
|
||||
RK3506_PMU_CLKGATE_CON(1), 14, GFLAGS),
|
||||
MUX(CLK_REF_PHY_PMU_MUX, "clk_ref_phy_pmu_mux", clk_ref_phy_pmu_mux_parents_p, 0,
|
||||
RK3506_PMU_CLKSEL_CON(4), 15, 1, MFLAGS),
|
||||
GATE(CLK_WIFI_OUT, "clk_wifi_out", "xin24m", 0,
|
||||
RK3506_PMU_CLKGATE_CON(2), 0, GFLAGS),
|
||||
MUX(CLK_V0PLL_REF, "clk_v0pll_ref", clk_vpll_ref_parents_p, CLK_IGNORE_UNUSED,
|
||||
RK3506_PMU_CLKSEL_CON(6), 0, 1, MFLAGS),
|
||||
MUX(CLK_V1PLL_REF, "clk_v1pll_ref", clk_vpll_ref_parents_p, CLK_IGNORE_UNUSED,
|
||||
RK3506_PMU_CLKSEL_CON(6), 1, 1, MFLAGS),
|
||||
|
||||
/* secure ns */
|
||||
GATE(CLK_CORE_CRYPTO_NS, "clk_core_crypto_ns", "clk_core_crypto", 0,
|
||||
RK3506_CLKGATE_CON(5), 12, GFLAGS),
|
||||
GATE(CLK_PKA_CRYPTO_NS, "clk_pka_crypto_ns", "clk_pka_crypto", 0,
|
||||
RK3506_CLKGATE_CON(5), 13, GFLAGS),
|
||||
|
||||
/* io */
|
||||
GATE(CLK_SPI2, "clk_spi2", "clk_spi2_io", 0,
|
||||
RK3506_CLKGATE_CON(20), 0, GFLAGS),
|
||||
};
|
||||
|
||||
static void __init rk3506_clk_init(struct device_node *np)
|
||||
{
|
||||
struct rockchip_clk_provider *ctx;
|
||||
unsigned long clk_nr_clks;
|
||||
void __iomem *reg_base;
|
||||
|
||||
clk_nr_clks = rockchip_clk_find_max_clk_id(rk3506_clk_branches,
|
||||
ARRAY_SIZE(rk3506_clk_branches)) + 1;
|
||||
|
||||
reg_base = of_iomap(np, 0);
|
||||
if (!reg_base) {
|
||||
pr_err("%s: could not map cru region\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
ctx = rockchip_clk_init(np, reg_base, clk_nr_clks);
|
||||
if (IS_ERR(ctx)) {
|
||||
pr_err("%s: rockchip clk init failed\n", __func__);
|
||||
iounmap(reg_base);
|
||||
return;
|
||||
}
|
||||
|
||||
rockchip_clk_register_plls(ctx, rk3506_pll_clks,
|
||||
ARRAY_SIZE(rk3506_pll_clks),
|
||||
0);
|
||||
|
||||
rockchip_clk_register_armclk_multi_pll(ctx, &rk3506_armclk,
|
||||
rk3506_cpuclk_rates,
|
||||
ARRAY_SIZE(rk3506_cpuclk_rates));
|
||||
|
||||
rockchip_clk_register_branches(ctx, rk3506_clk_branches,
|
||||
ARRAY_SIZE(rk3506_clk_branches));
|
||||
|
||||
rk3506_rst_init(np, reg_base);
|
||||
|
||||
rockchip_register_restart_notifier(ctx, RK3506_GLB_SRST_FST, NULL);
|
||||
|
||||
rockchip_clk_of_add_provider(np, ctx);
|
||||
|
||||
/* pvtpll src init */
|
||||
writel_relaxed(PVTPLL_SRC_SEL_PVTPLL, reg_base + RK3506_CLKSEL_CON(15));
|
||||
}
|
||||
|
||||
CLK_OF_DECLARE(rk3506_cru, "rockchip,rk3506-cru", rk3506_clk_init);
|
||||
|
||||
struct clk_rk3506_inits {
|
||||
void (*inits)(struct device_node *np);
|
||||
};
|
||||
|
||||
static const struct clk_rk3506_inits clk_rk3506_cru_init = {
|
||||
.inits = rk3506_clk_init,
|
||||
};
|
||||
|
||||
static const struct of_device_id clk_rk3506_match_table[] = {
|
||||
{
|
||||
.compatible = "rockchip,rk3506-cru",
|
||||
.data = &clk_rk3506_cru_init,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
||||
static int clk_rk3506_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct clk_rk3506_inits *init_data;
|
||||
struct device *dev = &pdev->dev;
|
||||
|
||||
init_data = device_get_match_data(dev);
|
||||
if (!init_data)
|
||||
return -EINVAL;
|
||||
|
||||
if (init_data->inits)
|
||||
init_data->inits(dev->of_node);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver clk_rk3506_driver = {
|
||||
.probe = clk_rk3506_probe,
|
||||
.driver = {
|
||||
.name = "clk-rk3506",
|
||||
.of_match_table = clk_rk3506_match_table,
|
||||
.suppress_bind_attrs = true,
|
||||
},
|
||||
};
|
||||
builtin_platform_driver_probe(clk_rk3506_driver, clk_rk3506_probe);
|
||||
|
|
@ -1652,6 +1652,7 @@ CLK_OF_DECLARE(rk3568_cru_pmu, "rockchip,rk3568-pmucru", rk3568_pmu_clk_init);
|
|||
static void __init rk3568_clk_init(struct device_node *np)
|
||||
{
|
||||
struct rockchip_clk_provider *ctx;
|
||||
unsigned long clk_nr_clks;
|
||||
void __iomem *reg_base;
|
||||
|
||||
reg_base = of_iomap(np, 0);
|
||||
|
|
@ -1660,7 +1661,9 @@ static void __init rk3568_clk_init(struct device_node *np)
|
|||
return;
|
||||
}
|
||||
|
||||
ctx = rockchip_clk_init(np, reg_base, CLK_NR_CLKS);
|
||||
clk_nr_clks = rockchip_clk_find_max_clk_id(rk3568_clk_branches,
|
||||
ARRAY_SIZE(rk3568_clk_branches)) + 1;
|
||||
ctx = rockchip_clk_init(np, reg_base, clk_nr_clks);
|
||||
if (IS_ERR(ctx)) {
|
||||
pr_err("%s: rockchip clk init failed\n", __func__);
|
||||
iounmap(reg_base);
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -722,6 +722,30 @@ void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx,
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(rockchip_clk_register_armclk);
|
||||
|
||||
void rockchip_clk_register_armclk_multi_pll(struct rockchip_clk_provider *ctx,
|
||||
struct rockchip_clk_branch *list,
|
||||
const struct rockchip_cpuclk_rate_table *rates,
|
||||
int nrates)
|
||||
{
|
||||
struct clk *clk;
|
||||
|
||||
clk = rockchip_clk_register_cpuclk_multi_pll(list->name, list->parent_names,
|
||||
list->num_parents, ctx->reg_base,
|
||||
list->muxdiv_offset, list->mux_shift,
|
||||
list->mux_width, list->mux_flags,
|
||||
list->div_offset, list->div_shift,
|
||||
list->div_width, list->div_flags,
|
||||
list->flags, &ctx->lock, rates, nrates);
|
||||
if (IS_ERR(clk)) {
|
||||
pr_err("%s: failed to register clock %s: %ld\n",
|
||||
__func__, list->name, PTR_ERR(clk));
|
||||
return;
|
||||
}
|
||||
|
||||
rockchip_clk_set_lookup(ctx, clk, list->id);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(rockchip_clk_register_armclk_multi_pll);
|
||||
|
||||
void rockchip_clk_protect_critical(const char *const clocks[],
|
||||
int nclocks)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -99,6 +99,73 @@ struct clk;
|
|||
#define RV1126_EMMC_CON0 0x450
|
||||
#define RV1126_EMMC_CON1 0x454
|
||||
|
||||
#define RV1126B_TOPCRU_BASE 0x0
|
||||
#define RV1126B_BUSCRU_BASE 0x10000
|
||||
#define RV1126B_PERICRU_BASE 0x20000
|
||||
#define RV1126B_CORECRU_BASE 0x30000
|
||||
#define RV1126B_PMUCRU_BASE 0x40000
|
||||
#define RV1126B_PMU1CRU_BASE 0x50000
|
||||
#define RV1126B_DDRCRU_BASE 0x60000
|
||||
#define RV1126B_SUBDDRCRU_BASE 0x68000
|
||||
#define RV1126B_VICRU_BASE 0x70000
|
||||
#define RV1126B_VEPUCRU_BASE 0x80000
|
||||
#define RV1126B_NPUCRU_BASE 0x90000
|
||||
#define RV1126B_VDOCRU_BASE 0xA0000
|
||||
#define RV1126B_VCPCRU_BASE 0xB0000
|
||||
|
||||
#define RV1126B_PLL_CON(x) ((x) * 0x4 + RV1126B_TOPCRU_BASE)
|
||||
#define RV1126B_MODE_CON (0x280 + RV1126B_TOPCRU_BASE)
|
||||
#define RV1126B_CLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_TOPCRU_BASE)
|
||||
#define RV1126B_CLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_TOPCRU_BASE)
|
||||
#define RV1126B_SOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_TOPCRU_BASE)
|
||||
#define RV1126B_GLB_SRST_FST (0xc08 + RV1126B_TOPCRU_BASE)
|
||||
#define RV1126B_GLB_SRST_SND (0xc0c + RV1126B_TOPCRU_BASE)
|
||||
#define RV1126B_CLK_CM_FRAC0_DIV_H (0xcc0 + RV1126B_TOPCRU_BASE)
|
||||
#define RV1126B_CLK_CM_FRAC1_DIV_H (0xcc4 + RV1126B_TOPCRU_BASE)
|
||||
#define RV1126B_CLK_CM_FRAC2_DIV_H (0xcc8 + RV1126B_TOPCRU_BASE)
|
||||
#define RV1126B_CLK_UART_FRAC0_DIV_H (0xccc + RV1126B_TOPCRU_BASE)
|
||||
#define RV1126B_CLK_UART_FRAC1_DIV_H (0xcd0 + RV1126B_TOPCRU_BASE)
|
||||
#define RV1126B_CLK_AUDIO_FRAC0_DIV_H (0xcd4 + RV1126B_TOPCRU_BASE)
|
||||
#define RV1126B_CLK_AUDIO_FRAC1_DIV_H (0xcd8 + RV1126B_TOPCRU_BASE)
|
||||
#define RV1126B_BUSCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_BUSCRU_BASE)
|
||||
#define RV1126B_BUSCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_BUSCRU_BASE)
|
||||
#define RV1126B_BUSSOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_BUSCRU_BASE)
|
||||
#define RV1126B_PERIPLL_CON(x) ((x) * 0x4 + RV1126B_PERICRU_BASE)
|
||||
#define RV1126B_PERICLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_PERICRU_BASE)
|
||||
#define RV1126B_PERICLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_PERICRU_BASE)
|
||||
#define RV1126B_PERISOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_PERICRU_BASE)
|
||||
#define RV1126B_CORECLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_CORECRU_BASE)
|
||||
#define RV1126B_CORECLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_CORECRU_BASE)
|
||||
#define RV1126B_CORESOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_CORECRU_BASE)
|
||||
#define RV1126B_PMUCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_PMUCRU_BASE)
|
||||
#define RV1126B_PMUCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_PMUCRU_BASE)
|
||||
#define RV1126B_PMUSOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_PMUCRU_BASE)
|
||||
#define RV1126B_PMU1CLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_PMU1CRU_BASE)
|
||||
#define RV1126B_PMU1CLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_PMU1CRU_BASE)
|
||||
#define RV1126B_PMU1SOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_PMU1CRU_BASE)
|
||||
#define RV1126B_DDRCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_DDRCRU_BASE)
|
||||
#define RV1126B_DDRCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_DDRCRU_BASE)
|
||||
#define RV1126B_DDRSOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_DDRCRU_BASE)
|
||||
#define RV1126B_SUBDDRPLL_CON(x) ((x) * 0x4 + RV1126B_SUBDDRCRU_BASE)
|
||||
#define RV1126B_SUBDDRCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_SUBDDRCRU_BASE)
|
||||
#define RV1126B_SUBDDRCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_SUBDDRCRU_BASE)
|
||||
#define RV1126B_SUBDDRSOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_SUBDDRCRU_BASE)
|
||||
#define RV1126B_VICLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_VICRU_BASE)
|
||||
#define RV1126B_VICLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_VICRU_BASE)
|
||||
#define RV1126B_VISOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_VICRU_BASE)
|
||||
#define RV1126B_VEPUCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_VEPUCRU_BASE)
|
||||
#define RV1126B_VEPUCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_VEPUCRU_BASE)
|
||||
#define RV1126B_VEPUSOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_VEPUCRU_BASE)
|
||||
#define RV1126B_NPUCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_NPUCRU_BASE)
|
||||
#define RV1126B_NPUCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_NPUCRU_BASE)
|
||||
#define RV1126B_NPUSOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_NPUCRU_BASE)
|
||||
#define RV1126B_VDOCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_VDOCRU_BASE)
|
||||
#define RV1126B_VDOCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_VDOCRU_BASE)
|
||||
#define RV1126B_VDOSOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_VDOCRU_BASE)
|
||||
#define RV1126B_VCPCLKSEL_CON(x) ((x) * 0x4 + 0x300 + RV1126B_VCPCRU_BASE)
|
||||
#define RV1126B_VCPCLKGATE_CON(x) ((x) * 0x4 + 0x800 + RV1126B_VCPCRU_BASE)
|
||||
#define RV1126B_VCPSOFTRST_CON(x) ((x) * 0x4 + 0xa00 + RV1126B_VCPCRU_BASE)
|
||||
|
||||
#define RK2928_PLL_CON(x) ((x) * 0x4)
|
||||
#define RK2928_MODE_CON 0x40
|
||||
#define RK2928_CLKSEL_CON(x) ((x) * 0x4 + 0x44)
|
||||
|
|
@ -208,6 +275,18 @@ struct clk;
|
|||
#define RK3399_PMU_CLKGATE_CON(x) ((x) * 0x4 + 0x100)
|
||||
#define RK3399_PMU_SOFTRST_CON(x) ((x) * 0x4 + 0x110)
|
||||
|
||||
#define RK3506_PMU_CRU_BASE 0x10000
|
||||
#define RK3506_PLL_CON(x) ((x) * 0x4 + RK3506_PMU_CRU_BASE)
|
||||
#define RK3506_CLKSEL_CON(x) ((x) * 0x4 + 0x300)
|
||||
#define RK3506_CLKGATE_CON(x) ((x) * 0x4 + 0x800)
|
||||
#define RK3506_SOFTRST_CON(x) ((x) * 0x4 + 0xa00)
|
||||
#define RK3506_PMU_CLKSEL_CON(x) ((x) * 0x4 + 0x300 + RK3506_PMU_CRU_BASE)
|
||||
#define RK3506_PMU_CLKGATE_CON(x) ((x) * 0x4 + 0x800 + RK3506_PMU_CRU_BASE)
|
||||
#define RK3506_MODE_CON 0x280
|
||||
#define RK3506_GLB_CNT_TH 0xc00
|
||||
#define RK3506_GLB_SRST_FST 0xc08
|
||||
#define RK3506_GLB_SRST_SND 0xc0c
|
||||
|
||||
#define RK3528_PMU_CRU_BASE 0x10000
|
||||
#define RK3528_PCIE_CRU_BASE 0x20000
|
||||
#define RK3528_DDRPHY_CRU_BASE 0x28000
|
||||
|
|
@ -622,6 +701,17 @@ struct clk *rockchip_clk_register_cpuclk(const char *name,
|
|||
const struct rockchip_cpuclk_rate_table *rates,
|
||||
int nrates, void __iomem *reg_base, spinlock_t *lock);
|
||||
|
||||
struct clk *rockchip_clk_register_cpuclk_multi_pll(const char *name,
|
||||
const char *const *parent_names,
|
||||
u8 num_parents, void __iomem *base,
|
||||
int muxdiv_offset, u8 mux_shift,
|
||||
u8 mux_width, u8 mux_flags,
|
||||
int div_offset, u8 div_shift,
|
||||
u8 div_width, u8 div_flags,
|
||||
unsigned long flags, spinlock_t *lock,
|
||||
const struct rockchip_cpuclk_rate_table *rates,
|
||||
int nrates);
|
||||
|
||||
struct clk *rockchip_clk_register_mmc(const char *name,
|
||||
const char *const *parent_names, u8 num_parents,
|
||||
void __iomem *reg,
|
||||
|
|
@ -1208,6 +1298,10 @@ void rockchip_clk_register_armclk(struct rockchip_clk_provider *ctx,
|
|||
const struct rockchip_cpuclk_reg_data *reg_data,
|
||||
const struct rockchip_cpuclk_rate_table *rates,
|
||||
int nrates);
|
||||
void rockchip_clk_register_armclk_multi_pll(struct rockchip_clk_provider *ctx,
|
||||
struct rockchip_clk_branch *list,
|
||||
const struct rockchip_cpuclk_rate_table *rates,
|
||||
int nrates);
|
||||
void rockchip_clk_protect_critical(const char *const clocks[], int nclocks);
|
||||
void rockchip_register_restart_notifier(struct rockchip_clk_provider *ctx,
|
||||
unsigned int reg, void (*cb)(void));
|
||||
|
|
@ -1246,6 +1340,8 @@ static inline void rockchip_register_softrst(struct device_node *np,
|
|||
return rockchip_register_softrst_lut(np, NULL, num_regs, base, flags);
|
||||
}
|
||||
|
||||
void rv1126b_rst_init(struct device_node *np, void __iomem *reg_base);
|
||||
void rk3506_rst_init(struct device_node *np, void __iomem *reg_base);
|
||||
void rk3528_rst_init(struct device_node *np, void __iomem *reg_base);
|
||||
void rk3562_rst_init(struct device_node *np, void __iomem *reg_base);
|
||||
void rk3576_rst_init(struct device_node *np, void __iomem *reg_base);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,226 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
|
||||
* Author: Finley Xiao <finley.xiao@rock-chips.com>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <dt-bindings/reset/rockchip,rk3506-cru.h>
|
||||
#include "clk.h"
|
||||
|
||||
/* 0xFF9A0000 + 0x0A00 */
|
||||
#define RK3506_CRU_RESET_OFFSET(id, reg, bit) [id] = (0 + reg * 16 + bit)
|
||||
|
||||
/* mapping table for reset ID to register offset */
|
||||
static const int rk3506_register_offset[] = {
|
||||
/* CRU-->SOFTRST_CON00 */
|
||||
RK3506_CRU_RESET_OFFSET(SRST_NCOREPORESET0_AC, 0, 0),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_NCOREPORESET1_AC, 0, 1),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_NCOREPORESET2_AC, 0, 2),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_NCORESET0_AC, 0, 4),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_NCORESET1_AC, 0, 5),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_NCORESET2_AC, 0, 6),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_NL2RESET_AC, 0, 8),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_A_CORE_BIU_AC, 0, 9),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_H_M0_AC, 0, 10),
|
||||
|
||||
/* CRU-->SOFTRST_CON02 */
|
||||
RK3506_CRU_RESET_OFFSET(SRST_NDBGRESET, 2, 10),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_CORE_BIU, 2, 14),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_PMU, 2, 15),
|
||||
|
||||
/* CRU-->SOFTRST_CON03 */
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_DBG, 3, 1),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_POT_DBG, 3, 2),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_CORE_GRF, 3, 4),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_CORE_EMA_DETECT, 3, 6),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_REF_PVTPLL_CORE, 3, 7),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_GPIO1, 3, 8),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_DB_GPIO1, 3, 9),
|
||||
|
||||
/* CRU-->SOFTRST_CON04 */
|
||||
RK3506_CRU_RESET_OFFSET(SRST_A_CORE_PERI_BIU, 4, 3),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_A_DSMC, 4, 5),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_DSMC, 4, 6),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_FLEXBUS, 4, 7),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_A_FLEXBUS, 4, 9),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_H_FLEXBUS, 4, 10),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_A_DSMC_SLV, 4, 11),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_H_DSMC_SLV, 4, 12),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_DSMC_SLV, 4, 13),
|
||||
|
||||
/* CRU-->SOFTRST_CON05 */
|
||||
RK3506_CRU_RESET_OFFSET(SRST_A_BUS_BIU, 5, 3),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_H_BUS_BIU, 5, 4),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_BUS_BIU, 5, 5),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_A_SYSRAM, 5, 6),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_H_SYSRAM, 5, 7),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_A_DMAC0, 5, 8),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_A_DMAC1, 5, 9),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_H_M0, 5, 10),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_M0_JTAG, 5, 11),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_H_CRYPTO, 5, 15),
|
||||
|
||||
/* CRU-->SOFTRST_CON06 */
|
||||
RK3506_CRU_RESET_OFFSET(SRST_H_RNG, 6, 0),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_BUS_GRF, 6, 1),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_TIMER0, 6, 2),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH0, 6, 3),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH1, 6, 4),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH2, 6, 5),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH3, 6, 6),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH4, 6, 7),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_TIMER0_CH5, 6, 8),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_WDT0, 6, 9),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_T_WDT0, 6, 10),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_WDT1, 6, 11),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_T_WDT1, 6, 12),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_MAILBOX, 6, 13),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_INTMUX, 6, 14),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_SPINLOCK, 6, 15),
|
||||
|
||||
/* CRU-->SOFTRST_CON07 */
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_DDRC, 7, 0),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_H_DDRPHY, 7, 1),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_DDRMON, 7, 2),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_DDRMON_OSC, 7, 3),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_DDR_LPC, 7, 4),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_H_USBOTG0, 7, 5),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_USBOTG0_ADP, 7, 7),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_H_USBOTG1, 7, 8),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_USBOTG1_ADP, 7, 10),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_USBPHY, 7, 11),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_USBPHY_POR, 7, 12),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_USBPHY_OTG0, 7, 13),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_USBPHY_OTG1, 7, 14),
|
||||
|
||||
/* CRU-->SOFTRST_CON08 */
|
||||
RK3506_CRU_RESET_OFFSET(SRST_A_DMA2DDR, 8, 0),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_DMA2DDR, 8, 1),
|
||||
|
||||
/* CRU-->SOFTRST_CON09 */
|
||||
RK3506_CRU_RESET_OFFSET(SRST_USBOTG0_UTMI, 9, 0),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_USBOTG1_UTMI, 9, 1),
|
||||
|
||||
/* CRU-->SOFTRST_CON10 */
|
||||
RK3506_CRU_RESET_OFFSET(SRST_A_DDRC_0, 10, 0),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_A_DDRC_1, 10, 1),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_A_DDR_BIU, 10, 2),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_DDRC, 10, 3),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_DDRMON, 10, 4),
|
||||
|
||||
/* CRU-->SOFTRST_CON11 */
|
||||
RK3506_CRU_RESET_OFFSET(SRST_H_LSPERI_BIU, 11, 2),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_UART0, 11, 4),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_UART1, 11, 5),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_UART2, 11, 6),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_UART3, 11, 7),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_UART4, 11, 8),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_UART0, 11, 9),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_UART1, 11, 10),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_UART2, 11, 11),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_UART3, 11, 12),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_UART4, 11, 13),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_I2C0, 11, 14),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_I2C0, 11, 15),
|
||||
|
||||
/* CRU-->SOFTRST_CON12 */
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_I2C1, 12, 0),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_I2C1, 12, 1),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_I2C2, 12, 2),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_I2C2, 12, 3),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_PWM1, 12, 4),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_PWM1, 12, 5),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_SPI0, 12, 10),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_SPI0, 12, 11),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_SPI1, 12, 12),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_SPI1, 12, 13),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_GPIO2, 12, 14),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_DB_GPIO2, 12, 15),
|
||||
|
||||
/* CRU-->SOFTRST_CON13 */
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_GPIO3, 13, 0),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_DB_GPIO3, 13, 1),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_GPIO4, 13, 2),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_DB_GPIO4, 13, 3),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_H_CAN0, 13, 4),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_CAN0, 13, 5),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_H_CAN1, 13, 6),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_CAN1, 13, 7),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_H_PDM, 13, 8),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_M_PDM, 13, 9),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_PDM, 13, 10),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_SPDIFTX, 13, 11),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_H_SPDIFTX, 13, 12),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_H_SPDIFRX, 13, 13),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_SPDIFRX, 13, 14),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_M_SAI0, 13, 15),
|
||||
|
||||
/* CRU-->SOFTRST_CON14 */
|
||||
RK3506_CRU_RESET_OFFSET(SRST_H_SAI0, 14, 0),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_M_SAI1, 14, 2),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_H_SAI1, 14, 3),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_H_ASRC0, 14, 5),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_ASRC0, 14, 6),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_H_ASRC1, 14, 7),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_ASRC1, 14, 8),
|
||||
|
||||
/* CRU-->SOFTRST_CON17 */
|
||||
RK3506_CRU_RESET_OFFSET(SRST_H_HSPERI_BIU, 17, 4),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_H_SDMMC, 17, 7),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_H_FSPI, 17, 8),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_S_FSPI, 17, 9),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_SPI2, 17, 10),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_A_MAC0, 17, 11),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_A_MAC1, 17, 12),
|
||||
|
||||
/* CRU-->SOFTRST_CON18 */
|
||||
RK3506_CRU_RESET_OFFSET(SRST_M_SAI2, 18, 2),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_H_SAI2, 18, 3),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_H_SAI3, 18, 6),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_M_SAI3, 18, 7),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_H_SAI4, 18, 10),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_M_SAI4, 18, 11),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_H_DSM, 18, 12),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_M_DSM, 18, 13),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_AUDIO_ADC, 18, 14),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_M_AUDIO_ADC, 18, 15),
|
||||
|
||||
/* CRU-->SOFTRST_CON19 */
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_SARADC, 19, 0),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_SARADC, 19, 1),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_SARADC_PHY, 19, 2),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_OTPC_NS, 19, 3),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_SBPI_OTPC_NS, 19, 4),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_USER_OTPC_NS, 19, 5),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_UART5, 19, 6),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_UART5, 19, 7),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_GPIO234_IOC, 19, 8),
|
||||
|
||||
/* CRU-->SOFTRST_CON21 */
|
||||
RK3506_CRU_RESET_OFFSET(SRST_A_VIO_BIU, 21, 3),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_H_VIO_BIU, 21, 4),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_H_RGA, 21, 6),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_A_RGA, 21, 7),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_CORE_RGA, 21, 8),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_A_VOP, 21, 9),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_H_VOP, 21, 10),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_VOP, 21, 11),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_DPHY, 21, 12),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_DSI_HOST, 21, 13),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_TSADC, 21, 14),
|
||||
RK3506_CRU_RESET_OFFSET(SRST_TSADC, 21, 15),
|
||||
|
||||
/* CRU-->SOFTRST_CON22 */
|
||||
RK3506_CRU_RESET_OFFSET(SRST_P_GPIO1_IOC, 22, 1),
|
||||
};
|
||||
|
||||
void rk3506_rst_init(struct device_node *np, void __iomem *reg_base)
|
||||
{
|
||||
rockchip_register_softrst_lut(np,
|
||||
rk3506_register_offset,
|
||||
ARRAY_SIZE(rk3506_register_offset),
|
||||
reg_base + RK3506_SOFTRST_CON(0),
|
||||
ROCKCHIP_SOFTRST_HIWORD_MASK);
|
||||
}
|
||||
|
|
@ -0,0 +1,443 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (c) 2025 Rockchip Electronics Co., Ltd.
|
||||
* Author: Elaine Zhang <zhangqing@rock-chips.com>
|
||||
*/
|
||||
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <dt-bindings/reset/rockchip,rv1126b-cru.h>
|
||||
#include "clk.h"
|
||||
|
||||
/* 0x20000000 + 0x0A00 */
|
||||
#define TOPCRU_RESET_OFFSET(id, reg, bit) [id] = (0x0 * 4 + reg * 16 + bit)
|
||||
/* 0x20010000 + 0x0A00 */
|
||||
#define BUSCRU_RESET_OFFSET(id, reg, bit) [id] = (0x10000 * 4 + reg * 16 + bit)
|
||||
/* 0x20020000 + 0x0A00 */
|
||||
#define PERICRU_RESET_OFFSET(id, reg, bit) [id] = (0x20000 * 4 + reg * 16 + bit)
|
||||
/* 0x20030000 + 0x0A00 */
|
||||
#define CORECRU_RESET_OFFSET(id, reg, bit) [id] = (0x30000 * 4 + reg * 16 + bit)
|
||||
/* 0x20040000 + 0x0A00 */
|
||||
#define PMUCRU_RESET_OFFSET(id, reg, bit) [id] = (0x40000 * 4 + reg * 16 + bit)
|
||||
/* 0x20050000 + 0x0A00 */
|
||||
#define PMU1CRU_RESET_OFFSET(id, reg, bit) [id] = (0x50000 * 4 + reg * 16 + bit)
|
||||
/* 0x20060000 + 0x0A00 */
|
||||
#define DDRCRU_RESET_OFFSET(id, reg, bit) [id] = (0x60000 * 4 + reg * 16 + bit)
|
||||
/* 0x20068000 + 0x0A00 */
|
||||
#define SUBDDRCRU_RESET_OFFSET(id, reg, bit) [id] = (0x68000 * 4 + reg * 16 + bit)
|
||||
/* 0x20070000 + 0x0A00 */
|
||||
#define VICRU_RESET_OFFSET(id, reg, bit) [id] = (0x70000 * 4 + reg * 16 + bit)
|
||||
/* 0x20080000 + 0x0A00 */
|
||||
#define VEPUCRU_RESET_OFFSET(id, reg, bit) [id] = (0x80000 * 4 + reg * 16 + bit)
|
||||
/* 0x20090000 + 0x0A00 */
|
||||
#define NPUCRU_RESET_OFFSET(id, reg, bit) [id] = (0x90000 * 4 + reg * 16 + bit)
|
||||
/* 0x200A0000 + 0x0A00 */
|
||||
#define VDOCRU_RESET_OFFSET(id, reg, bit) [id] = (0xA0000 * 4 + reg * 16 + bit)
|
||||
/* 0x200B0000 + 0x0A00 */
|
||||
#define VCPCRU_RESET_OFFSET(id, reg, bit) [id] = (0xB0000 * 4 + reg * 16 + bit)
|
||||
|
||||
/* =================mapping table for reset ID to register offset================== */
|
||||
static const int rv1126b_register_offset[] = {
|
||||
/* TOPCRU-->SOFTRST_CON00 */
|
||||
|
||||
/* TOPCRU-->SOFTRST_CON15 */
|
||||
TOPCRU_RESET_OFFSET(SRST_P_CRU, 15, 1),
|
||||
TOPCRU_RESET_OFFSET(SRST_P_CRU_BIU, 15, 2),
|
||||
|
||||
/* BUSCRU-->SOFTRST_CON00 */
|
||||
BUSCRU_RESET_OFFSET(SRST_A_TOP_BIU, 0, 0),
|
||||
BUSCRU_RESET_OFFSET(SRST_A_RKCE_BIU, 0, 1),
|
||||
BUSCRU_RESET_OFFSET(SRST_A_BUS_BIU, 0, 2),
|
||||
BUSCRU_RESET_OFFSET(SRST_H_BUS_BIU, 0, 3),
|
||||
BUSCRU_RESET_OFFSET(SRST_P_BUS_BIU, 0, 4),
|
||||
BUSCRU_RESET_OFFSET(SRST_P_CRU_BUS, 0, 5),
|
||||
BUSCRU_RESET_OFFSET(SRST_P_SYS_GRF, 0, 6),
|
||||
BUSCRU_RESET_OFFSET(SRST_H_BOOTROM, 0, 7),
|
||||
BUSCRU_RESET_OFFSET(SRST_A_GIC400, 0, 8),
|
||||
BUSCRU_RESET_OFFSET(SRST_A_SPINLOCK, 0, 9),
|
||||
BUSCRU_RESET_OFFSET(SRST_P_WDT_NS, 0, 10),
|
||||
BUSCRU_RESET_OFFSET(SRST_T_WDT_NS, 0, 11),
|
||||
|
||||
/* BUSCRU-->SOFTRST_CON01 */
|
||||
BUSCRU_RESET_OFFSET(SRST_P_WDT_HPMCU, 1, 0),
|
||||
BUSCRU_RESET_OFFSET(SRST_T_WDT_HPMCU, 1, 1),
|
||||
BUSCRU_RESET_OFFSET(SRST_H_CACHE, 1, 2),
|
||||
BUSCRU_RESET_OFFSET(SRST_P_HPMCU_MAILBOX, 1, 3),
|
||||
BUSCRU_RESET_OFFSET(SRST_P_HPMCU_INTMUX, 1, 4),
|
||||
BUSCRU_RESET_OFFSET(SRST_HPMCU_FULL_CLUSTER, 1, 5),
|
||||
BUSCRU_RESET_OFFSET(SRST_HPMCU_PWUP, 1, 6),
|
||||
BUSCRU_RESET_OFFSET(SRST_HPMCU_ONLY_CORE, 1, 7),
|
||||
BUSCRU_RESET_OFFSET(SRST_T_HPMCU_JTAG, 1, 8),
|
||||
BUSCRU_RESET_OFFSET(SRST_P_RKDMA, 1, 11),
|
||||
BUSCRU_RESET_OFFSET(SRST_A_RKDMA, 1, 12),
|
||||
|
||||
/* BUSCRU-->SOFTRST_CON02 */
|
||||
BUSCRU_RESET_OFFSET(SRST_P_DCF, 2, 0),
|
||||
BUSCRU_RESET_OFFSET(SRST_A_DCF, 2, 1),
|
||||
BUSCRU_RESET_OFFSET(SRST_H_RGA, 2, 2),
|
||||
BUSCRU_RESET_OFFSET(SRST_A_RGA, 2, 3),
|
||||
BUSCRU_RESET_OFFSET(SRST_CORE_RGA, 2, 4),
|
||||
BUSCRU_RESET_OFFSET(SRST_P_TIMER, 2, 5),
|
||||
BUSCRU_RESET_OFFSET(SRST_TIMER0, 2, 6),
|
||||
BUSCRU_RESET_OFFSET(SRST_TIMER1, 2, 7),
|
||||
BUSCRU_RESET_OFFSET(SRST_TIMER2, 2, 8),
|
||||
BUSCRU_RESET_OFFSET(SRST_TIMER3, 2, 9),
|
||||
BUSCRU_RESET_OFFSET(SRST_TIMER4, 2, 10),
|
||||
BUSCRU_RESET_OFFSET(SRST_TIMER5, 2, 11),
|
||||
BUSCRU_RESET_OFFSET(SRST_A_RKCE, 2, 12),
|
||||
BUSCRU_RESET_OFFSET(SRST_PKA_RKCE, 2, 13),
|
||||
BUSCRU_RESET_OFFSET(SRST_H_RKRNG_S, 2, 14),
|
||||
BUSCRU_RESET_OFFSET(SRST_H_RKRNG_NS, 2, 15),
|
||||
|
||||
/* BUSCRU-->SOFTRST_CON03 */
|
||||
BUSCRU_RESET_OFFSET(SRST_P_I2C0, 3, 0),
|
||||
BUSCRU_RESET_OFFSET(SRST_I2C0, 3, 1),
|
||||
BUSCRU_RESET_OFFSET(SRST_P_I2C1, 3, 2),
|
||||
BUSCRU_RESET_OFFSET(SRST_I2C1, 3, 3),
|
||||
BUSCRU_RESET_OFFSET(SRST_P_I2C3, 3, 4),
|
||||
BUSCRU_RESET_OFFSET(SRST_I2C3, 3, 5),
|
||||
BUSCRU_RESET_OFFSET(SRST_P_I2C4, 3, 6),
|
||||
BUSCRU_RESET_OFFSET(SRST_I2C4, 3, 7),
|
||||
BUSCRU_RESET_OFFSET(SRST_P_I2C5, 3, 8),
|
||||
BUSCRU_RESET_OFFSET(SRST_I2C5, 3, 9),
|
||||
BUSCRU_RESET_OFFSET(SRST_P_SPI0, 3, 10),
|
||||
BUSCRU_RESET_OFFSET(SRST_SPI0, 3, 11),
|
||||
BUSCRU_RESET_OFFSET(SRST_P_SPI1, 3, 12),
|
||||
BUSCRU_RESET_OFFSET(SRST_SPI1, 3, 13),
|
||||
|
||||
/* BUSCRU-->SOFTRST_CON04 */
|
||||
BUSCRU_RESET_OFFSET(SRST_P_PWM0, 4, 0),
|
||||
BUSCRU_RESET_OFFSET(SRST_PWM0, 4, 1),
|
||||
BUSCRU_RESET_OFFSET(SRST_P_PWM2, 4, 4),
|
||||
BUSCRU_RESET_OFFSET(SRST_PWM2, 4, 5),
|
||||
BUSCRU_RESET_OFFSET(SRST_P_PWM3, 4, 8),
|
||||
BUSCRU_RESET_OFFSET(SRST_PWM3, 4, 9),
|
||||
|
||||
/* BUSCRU-->SOFTRST_CON05 */
|
||||
BUSCRU_RESET_OFFSET(SRST_P_UART1, 5, 0),
|
||||
BUSCRU_RESET_OFFSET(SRST_S_UART1, 5, 1),
|
||||
BUSCRU_RESET_OFFSET(SRST_P_UART2, 5, 2),
|
||||
BUSCRU_RESET_OFFSET(SRST_S_UART2, 5, 3),
|
||||
BUSCRU_RESET_OFFSET(SRST_P_UART3, 5, 4),
|
||||
BUSCRU_RESET_OFFSET(SRST_S_UART3, 5, 5),
|
||||
BUSCRU_RESET_OFFSET(SRST_P_UART4, 5, 6),
|
||||
BUSCRU_RESET_OFFSET(SRST_S_UART4, 5, 7),
|
||||
BUSCRU_RESET_OFFSET(SRST_P_UART5, 5, 8),
|
||||
BUSCRU_RESET_OFFSET(SRST_S_UART5, 5, 9),
|
||||
BUSCRU_RESET_OFFSET(SRST_P_UART6, 5, 10),
|
||||
BUSCRU_RESET_OFFSET(SRST_S_UART6, 5, 11),
|
||||
BUSCRU_RESET_OFFSET(SRST_P_UART7, 5, 12),
|
||||
BUSCRU_RESET_OFFSET(SRST_S_UART7, 5, 13),
|
||||
|
||||
/* BUSCRU-->SOFTRST_CON06 */
|
||||
BUSCRU_RESET_OFFSET(SRST_P_TSADC, 6, 0),
|
||||
BUSCRU_RESET_OFFSET(SRST_TSADC, 6, 1),
|
||||
BUSCRU_RESET_OFFSET(SRST_H_SAI0, 6, 2),
|
||||
BUSCRU_RESET_OFFSET(SRST_M_SAI0, 6, 3),
|
||||
BUSCRU_RESET_OFFSET(SRST_H_SAI1, 6, 4),
|
||||
BUSCRU_RESET_OFFSET(SRST_M_SAI1, 6, 5),
|
||||
BUSCRU_RESET_OFFSET(SRST_H_SAI2, 6, 6),
|
||||
BUSCRU_RESET_OFFSET(SRST_M_SAI2, 6, 7),
|
||||
BUSCRU_RESET_OFFSET(SRST_H_RKDSM, 6, 8),
|
||||
BUSCRU_RESET_OFFSET(SRST_M_RKDSM, 6, 9),
|
||||
BUSCRU_RESET_OFFSET(SRST_H_PDM, 6, 10),
|
||||
BUSCRU_RESET_OFFSET(SRST_M_PDM, 6, 11),
|
||||
BUSCRU_RESET_OFFSET(SRST_PDM, 6, 12),
|
||||
|
||||
/* BUSCRU-->SOFTRST_CON07 */
|
||||
BUSCRU_RESET_OFFSET(SRST_H_ASRC0, 7, 0),
|
||||
BUSCRU_RESET_OFFSET(SRST_ASRC0, 7, 1),
|
||||
BUSCRU_RESET_OFFSET(SRST_H_ASRC1, 7, 2),
|
||||
BUSCRU_RESET_OFFSET(SRST_ASRC1, 7, 3),
|
||||
BUSCRU_RESET_OFFSET(SRST_P_AUDIO_ADC_BUS, 7, 4),
|
||||
BUSCRU_RESET_OFFSET(SRST_M_AUDIO_ADC_BUS, 7, 5),
|
||||
BUSCRU_RESET_OFFSET(SRST_P_RKCE, 7, 6),
|
||||
BUSCRU_RESET_OFFSET(SRST_H_NS_RKCE, 7, 7),
|
||||
BUSCRU_RESET_OFFSET(SRST_P_OTPC_NS, 7, 8),
|
||||
BUSCRU_RESET_OFFSET(SRST_SBPI_OTPC_NS, 7, 9),
|
||||
BUSCRU_RESET_OFFSET(SRST_USER_OTPC_NS, 7, 10),
|
||||
BUSCRU_RESET_OFFSET(SRST_OTPC_ARB, 7, 11),
|
||||
BUSCRU_RESET_OFFSET(SRST_P_OTP_MASK, 7, 12),
|
||||
|
||||
/* PERICRU-->SOFTRST_CON00 */
|
||||
PERICRU_RESET_OFFSET(SRST_A_PERI_BIU, 0, 0),
|
||||
PERICRU_RESET_OFFSET(SRST_P_PERI_BIU, 0, 1),
|
||||
PERICRU_RESET_OFFSET(SRST_P_RTC_BIU, 0, 2),
|
||||
PERICRU_RESET_OFFSET(SRST_P_CRU_PERI, 0, 3),
|
||||
PERICRU_RESET_OFFSET(SRST_P_PERI_GRF, 0, 4),
|
||||
PERICRU_RESET_OFFSET(SRST_P_GPIO1, 0, 5),
|
||||
PERICRU_RESET_OFFSET(SRST_DB_GPIO1, 0, 6),
|
||||
PERICRU_RESET_OFFSET(SRST_P_IOC_VCCIO1, 0, 7),
|
||||
PERICRU_RESET_OFFSET(SRST_A_USB3OTG, 0, 8),
|
||||
PERICRU_RESET_OFFSET(SRST_H_USB2HOST, 0, 11),
|
||||
PERICRU_RESET_OFFSET(SRST_H_ARB_USB2HOST, 0, 12),
|
||||
PERICRU_RESET_OFFSET(SRST_P_RTC_TEST, 0, 13),
|
||||
|
||||
/* PERICRU-->SOFTRST_CON01 */
|
||||
PERICRU_RESET_OFFSET(SRST_H_EMMC, 1, 0),
|
||||
PERICRU_RESET_OFFSET(SRST_H_FSPI0, 1, 1),
|
||||
PERICRU_RESET_OFFSET(SRST_H_XIP_FSPI0, 1, 2),
|
||||
PERICRU_RESET_OFFSET(SRST_S_2X_FSPI0, 1, 3),
|
||||
PERICRU_RESET_OFFSET(SRST_UTMI_USB2HOST, 1, 5),
|
||||
PERICRU_RESET_OFFSET(SRST_REF_PIPEPHY, 1, 7),
|
||||
PERICRU_RESET_OFFSET(SRST_P_PIPEPHY, 1, 8),
|
||||
PERICRU_RESET_OFFSET(SRST_P_PIPEPHY_GRF, 1, 9),
|
||||
PERICRU_RESET_OFFSET(SRST_P_USB2PHY, 1, 10),
|
||||
PERICRU_RESET_OFFSET(SRST_POR_USB2PHY, 1, 11),
|
||||
PERICRU_RESET_OFFSET(SRST_OTG_USB2PHY, 1, 12),
|
||||
PERICRU_RESET_OFFSET(SRST_HOST_USB2PHY, 1, 13),
|
||||
|
||||
/* CORECRU-->SOFTRST_CON00 */
|
||||
CORECRU_RESET_OFFSET(SRST_REF_PVTPLL_CORE, 0, 0),
|
||||
CORECRU_RESET_OFFSET(SRST_NCOREPORESET0, 0, 1),
|
||||
CORECRU_RESET_OFFSET(SRST_NCORESET0, 0, 2),
|
||||
CORECRU_RESET_OFFSET(SRST_NCOREPORESET1, 0, 3),
|
||||
CORECRU_RESET_OFFSET(SRST_NCORESET1, 0, 4),
|
||||
CORECRU_RESET_OFFSET(SRST_NCOREPORESET2, 0, 5),
|
||||
CORECRU_RESET_OFFSET(SRST_NCORESET2, 0, 6),
|
||||
CORECRU_RESET_OFFSET(SRST_NCOREPORESET3, 0, 7),
|
||||
CORECRU_RESET_OFFSET(SRST_NCORESET3, 0, 8),
|
||||
CORECRU_RESET_OFFSET(SRST_NDBGRESET, 0, 9),
|
||||
CORECRU_RESET_OFFSET(SRST_NL2RESET, 0, 10),
|
||||
|
||||
/* CORECRU-->SOFTRST_CON01 */
|
||||
CORECRU_RESET_OFFSET(SRST_A_CORE_BIU, 1, 0),
|
||||
CORECRU_RESET_OFFSET(SRST_P_CORE_BIU, 1, 1),
|
||||
CORECRU_RESET_OFFSET(SRST_H_CORE_BIU, 1, 2),
|
||||
CORECRU_RESET_OFFSET(SRST_P_DBG, 1, 3),
|
||||
CORECRU_RESET_OFFSET(SRST_POT_DBG, 1, 4),
|
||||
CORECRU_RESET_OFFSET(SRST_NT_DBG, 1, 5),
|
||||
CORECRU_RESET_OFFSET(SRST_P_CORE_PVTPLL, 1, 6),
|
||||
CORECRU_RESET_OFFSET(SRST_P_CRU_CORE, 1, 7),
|
||||
CORECRU_RESET_OFFSET(SRST_P_CORE_GRF, 1, 8),
|
||||
CORECRU_RESET_OFFSET(SRST_P_DFT2APB, 1, 10),
|
||||
|
||||
/* PMUCRU-->SOFTRST_CON00 */
|
||||
PMUCRU_RESET_OFFSET(SRST_H_PMU_BIU, 0, 0),
|
||||
PMUCRU_RESET_OFFSET(SRST_P_PMU_GPIO0, 0, 7),
|
||||
PMUCRU_RESET_OFFSET(SRST_DB_PMU_GPIO0, 0, 8),
|
||||
PMUCRU_RESET_OFFSET(SRST_P_PMU_HP_TIMER, 0, 10),
|
||||
PMUCRU_RESET_OFFSET(SRST_PMU_HP_TIMER, 0, 11),
|
||||
PMUCRU_RESET_OFFSET(SRST_PMU_32K_HP_TIMER, 0, 12),
|
||||
|
||||
/* PMUCRU-->SOFTRST_CON01 */
|
||||
PMUCRU_RESET_OFFSET(SRST_P_PWM1, 1, 0),
|
||||
PMUCRU_RESET_OFFSET(SRST_PWM1, 1, 1),
|
||||
PMUCRU_RESET_OFFSET(SRST_P_I2C2, 1, 2),
|
||||
PMUCRU_RESET_OFFSET(SRST_I2C2, 1, 3),
|
||||
PMUCRU_RESET_OFFSET(SRST_P_UART0, 1, 4),
|
||||
PMUCRU_RESET_OFFSET(SRST_S_UART0, 1, 5),
|
||||
|
||||
/* PMUCRU-->SOFTRST_CON02 */
|
||||
PMUCRU_RESET_OFFSET(SRST_P_RCOSC_CTRL, 2, 0),
|
||||
PMUCRU_RESET_OFFSET(SRST_REF_RCOSC_CTRL, 2, 2),
|
||||
PMUCRU_RESET_OFFSET(SRST_P_IOC_PMUIO0, 2, 3),
|
||||
PMUCRU_RESET_OFFSET(SRST_P_CRU_PMU, 2, 4),
|
||||
PMUCRU_RESET_OFFSET(SRST_P_PMU_GRF, 2, 5),
|
||||
PMUCRU_RESET_OFFSET(SRST_PREROLL, 2, 7),
|
||||
PMUCRU_RESET_OFFSET(SRST_PREROLL_32K, 2, 8),
|
||||
PMUCRU_RESET_OFFSET(SRST_H_PMU_SRAM, 2, 9),
|
||||
|
||||
/* PMUCRU-->SOFTRST_CON03 */
|
||||
PMUCRU_RESET_OFFSET(SRST_P_WDT_LPMCU, 3, 0),
|
||||
PMUCRU_RESET_OFFSET(SRST_T_WDT_LPMCU, 3, 1),
|
||||
PMUCRU_RESET_OFFSET(SRST_LPMCU_FULL_CLUSTER, 3, 2),
|
||||
PMUCRU_RESET_OFFSET(SRST_LPMCU_PWUP, 3, 3),
|
||||
PMUCRU_RESET_OFFSET(SRST_LPMCU_ONLY_CORE, 3, 4),
|
||||
PMUCRU_RESET_OFFSET(SRST_T_LPMCU_JTAG, 3, 5),
|
||||
PMUCRU_RESET_OFFSET(SRST_P_LPMCU_MAILBOX, 3, 6),
|
||||
|
||||
/* PMU1CRU-->SOFTRST_CON00 */
|
||||
PMU1CRU_RESET_OFFSET(SRST_P_SPI2AHB, 0, 0),
|
||||
PMU1CRU_RESET_OFFSET(SRST_H_SPI2AHB, 0, 1),
|
||||
PMU1CRU_RESET_OFFSET(SRST_H_FSPI1, 0, 2),
|
||||
PMU1CRU_RESET_OFFSET(SRST_H_XIP_FSPI1, 0, 3),
|
||||
PMU1CRU_RESET_OFFSET(SRST_S_1X_FSPI1, 0, 4),
|
||||
PMU1CRU_RESET_OFFSET(SRST_P_IOC_PMUIO1, 0, 5),
|
||||
PMU1CRU_RESET_OFFSET(SRST_P_CRU_PMU1, 0, 6),
|
||||
PMU1CRU_RESET_OFFSET(SRST_P_AUDIO_ADC_PMU, 0, 7),
|
||||
PMU1CRU_RESET_OFFSET(SRST_M_AUDIO_ADC_PMU, 0, 8),
|
||||
PMU1CRU_RESET_OFFSET(SRST_H_PMU1_BIU, 0, 9),
|
||||
|
||||
/* PMU1CRU-->SOFTRST_CON01 */
|
||||
PMU1CRU_RESET_OFFSET(SRST_P_LPDMA, 1, 0),
|
||||
PMU1CRU_RESET_OFFSET(SRST_A_LPDMA, 1, 1),
|
||||
PMU1CRU_RESET_OFFSET(SRST_H_LPSAI, 1, 2),
|
||||
PMU1CRU_RESET_OFFSET(SRST_M_LPSAI, 1, 3),
|
||||
PMU1CRU_RESET_OFFSET(SRST_P_AOA_TDD, 1, 4),
|
||||
PMU1CRU_RESET_OFFSET(SRST_P_AOA_FE, 1, 5),
|
||||
PMU1CRU_RESET_OFFSET(SRST_P_AOA_AAD, 1, 6),
|
||||
PMU1CRU_RESET_OFFSET(SRST_P_AOA_APB, 1, 7),
|
||||
PMU1CRU_RESET_OFFSET(SRST_P_AOA_SRAM, 1, 8),
|
||||
|
||||
/* DDRCRU-->SOFTRST_CON00 */
|
||||
DDRCRU_RESET_OFFSET(SRST_P_DDR_BIU, 0, 1),
|
||||
DDRCRU_RESET_OFFSET(SRST_P_DDRC, 0, 2),
|
||||
DDRCRU_RESET_OFFSET(SRST_P_DDRMON, 0, 3),
|
||||
DDRCRU_RESET_OFFSET(SRST_TIMER_DDRMON, 0, 4),
|
||||
DDRCRU_RESET_OFFSET(SRST_P_DFICTRL, 0, 5),
|
||||
DDRCRU_RESET_OFFSET(SRST_P_DDR_GRF, 0, 6),
|
||||
DDRCRU_RESET_OFFSET(SRST_P_CRU_DDR, 0, 7),
|
||||
DDRCRU_RESET_OFFSET(SRST_P_DDRPHY, 0, 8),
|
||||
DDRCRU_RESET_OFFSET(SRST_P_DMA2DDR, 0, 9),
|
||||
|
||||
/* SUBDDRCRU-->SOFTRST_CON00 */
|
||||
SUBDDRCRU_RESET_OFFSET(SRST_A_SYSMEM_BIU, 0, 0),
|
||||
SUBDDRCRU_RESET_OFFSET(SRST_A_SYSMEM, 0, 1),
|
||||
SUBDDRCRU_RESET_OFFSET(SRST_A_DDR_BIU, 0, 2),
|
||||
SUBDDRCRU_RESET_OFFSET(SRST_A_DDRSCH0_CPU, 0, 3),
|
||||
SUBDDRCRU_RESET_OFFSET(SRST_A_DDRSCH1_NPU, 0, 4),
|
||||
SUBDDRCRU_RESET_OFFSET(SRST_A_DDRSCH2_POE, 0, 5),
|
||||
SUBDDRCRU_RESET_OFFSET(SRST_A_DDRSCH3_VI, 0, 6),
|
||||
SUBDDRCRU_RESET_OFFSET(SRST_CORE_DDRC, 0, 7),
|
||||
SUBDDRCRU_RESET_OFFSET(SRST_DDRMON, 0, 8),
|
||||
SUBDDRCRU_RESET_OFFSET(SRST_DFICTRL, 0, 9),
|
||||
SUBDDRCRU_RESET_OFFSET(SRST_RS, 0, 11),
|
||||
SUBDDRCRU_RESET_OFFSET(SRST_A_DMA2DDR, 0, 12),
|
||||
SUBDDRCRU_RESET_OFFSET(SRST_DDRPHY, 0, 13),
|
||||
|
||||
/* VICRU-->SOFTRST_CON00 */
|
||||
VICRU_RESET_OFFSET(SRST_REF_PVTPLL_ISP, 0, 0),
|
||||
VICRU_RESET_OFFSET(SRST_A_GMAC_BIU, 0, 1),
|
||||
VICRU_RESET_OFFSET(SRST_A_VI_BIU, 0, 2),
|
||||
VICRU_RESET_OFFSET(SRST_H_VI_BIU, 0, 3),
|
||||
VICRU_RESET_OFFSET(SRST_P_VI_BIU, 0, 4),
|
||||
VICRU_RESET_OFFSET(SRST_P_CRU_VI, 0, 5),
|
||||
VICRU_RESET_OFFSET(SRST_P_VI_GRF, 0, 6),
|
||||
VICRU_RESET_OFFSET(SRST_P_VI_PVTPLL, 0, 7),
|
||||
VICRU_RESET_OFFSET(SRST_P_DSMC, 0, 8),
|
||||
VICRU_RESET_OFFSET(SRST_A_DSMC, 0, 9),
|
||||
VICRU_RESET_OFFSET(SRST_H_CAN0, 0, 10),
|
||||
VICRU_RESET_OFFSET(SRST_CAN0, 0, 11),
|
||||
VICRU_RESET_OFFSET(SRST_H_CAN1, 0, 12),
|
||||
VICRU_RESET_OFFSET(SRST_CAN1, 0, 13),
|
||||
|
||||
/* VICRU-->SOFTRST_CON01 */
|
||||
VICRU_RESET_OFFSET(SRST_P_GPIO2, 1, 0),
|
||||
VICRU_RESET_OFFSET(SRST_DB_GPIO2, 1, 1),
|
||||
VICRU_RESET_OFFSET(SRST_P_GPIO4, 1, 2),
|
||||
VICRU_RESET_OFFSET(SRST_DB_GPIO4, 1, 3),
|
||||
VICRU_RESET_OFFSET(SRST_P_GPIO5, 1, 4),
|
||||
VICRU_RESET_OFFSET(SRST_DB_GPIO5, 1, 5),
|
||||
VICRU_RESET_OFFSET(SRST_P_GPIO6, 1, 6),
|
||||
VICRU_RESET_OFFSET(SRST_DB_GPIO6, 1, 7),
|
||||
VICRU_RESET_OFFSET(SRST_P_GPIO7, 1, 8),
|
||||
VICRU_RESET_OFFSET(SRST_DB_GPIO7, 1, 9),
|
||||
VICRU_RESET_OFFSET(SRST_P_IOC_VCCIO2, 1, 10),
|
||||
VICRU_RESET_OFFSET(SRST_P_IOC_VCCIO4, 1, 11),
|
||||
VICRU_RESET_OFFSET(SRST_P_IOC_VCCIO5, 1, 12),
|
||||
VICRU_RESET_OFFSET(SRST_P_IOC_VCCIO6, 1, 13),
|
||||
VICRU_RESET_OFFSET(SRST_P_IOC_VCCIO7, 1, 14),
|
||||
|
||||
/* VICRU-->SOFTRST_CON02 */
|
||||
VICRU_RESET_OFFSET(SRST_CORE_ISP, 2, 0),
|
||||
VICRU_RESET_OFFSET(SRST_H_VICAP, 2, 1),
|
||||
VICRU_RESET_OFFSET(SRST_A_VICAP, 2, 2),
|
||||
VICRU_RESET_OFFSET(SRST_D_VICAP, 2, 3),
|
||||
VICRU_RESET_OFFSET(SRST_ISP0_VICAP, 2, 4),
|
||||
VICRU_RESET_OFFSET(SRST_CORE_VPSS, 2, 5),
|
||||
VICRU_RESET_OFFSET(SRST_CORE_VPSL, 2, 6),
|
||||
VICRU_RESET_OFFSET(SRST_P_CSI2HOST0, 2, 7),
|
||||
VICRU_RESET_OFFSET(SRST_P_CSI2HOST1, 2, 8),
|
||||
VICRU_RESET_OFFSET(SRST_P_CSI2HOST2, 2, 9),
|
||||
VICRU_RESET_OFFSET(SRST_P_CSI2HOST3, 2, 10),
|
||||
VICRU_RESET_OFFSET(SRST_H_SDMMC0, 2, 11),
|
||||
VICRU_RESET_OFFSET(SRST_A_GMAC, 2, 12),
|
||||
VICRU_RESET_OFFSET(SRST_P_CSIPHY0, 2, 13),
|
||||
VICRU_RESET_OFFSET(SRST_P_CSIPHY1, 2, 14),
|
||||
|
||||
/* VICRU-->SOFTRST_CON03 */
|
||||
VICRU_RESET_OFFSET(SRST_P_MACPHY, 3, 0),
|
||||
VICRU_RESET_OFFSET(SRST_MACPHY, 3, 1),
|
||||
VICRU_RESET_OFFSET(SRST_P_SARADC1, 3, 2),
|
||||
VICRU_RESET_OFFSET(SRST_SARADC1, 3, 3),
|
||||
VICRU_RESET_OFFSET(SRST_P_SARADC2, 3, 5),
|
||||
VICRU_RESET_OFFSET(SRST_SARADC2, 3, 6),
|
||||
|
||||
/* VEPUCRU-->SOFTRST_CON00 */
|
||||
VEPUCRU_RESET_OFFSET(SRST_REF_PVTPLL_VEPU, 0, 0),
|
||||
VEPUCRU_RESET_OFFSET(SRST_A_VEPU_BIU, 0, 1),
|
||||
VEPUCRU_RESET_OFFSET(SRST_H_VEPU_BIU, 0, 2),
|
||||
VEPUCRU_RESET_OFFSET(SRST_P_VEPU_BIU, 0, 3),
|
||||
VEPUCRU_RESET_OFFSET(SRST_P_CRU_VEPU, 0, 4),
|
||||
VEPUCRU_RESET_OFFSET(SRST_P_VEPU_GRF, 0, 5),
|
||||
VEPUCRU_RESET_OFFSET(SRST_P_GPIO3, 0, 7),
|
||||
VEPUCRU_RESET_OFFSET(SRST_DB_GPIO3, 0, 8),
|
||||
VEPUCRU_RESET_OFFSET(SRST_P_IOC_VCCIO3, 0, 9),
|
||||
VEPUCRU_RESET_OFFSET(SRST_P_SARADC0, 0, 10),
|
||||
VEPUCRU_RESET_OFFSET(SRST_SARADC0, 0, 11),
|
||||
VEPUCRU_RESET_OFFSET(SRST_H_SDMMC1, 0, 13),
|
||||
|
||||
/* VEPUCRU-->SOFTRST_CON01 */
|
||||
VEPUCRU_RESET_OFFSET(SRST_P_VEPU_PVTPLL, 1, 0),
|
||||
VEPUCRU_RESET_OFFSET(SRST_H_VEPU, 1, 1),
|
||||
VEPUCRU_RESET_OFFSET(SRST_A_VEPU, 1, 2),
|
||||
VEPUCRU_RESET_OFFSET(SRST_CORE_VEPU, 1, 3),
|
||||
|
||||
/* NPUCRU-->SOFTRST_CON00 */
|
||||
NPUCRU_RESET_OFFSET(SRST_REF_PVTPLL_NPU, 0, 0),
|
||||
NPUCRU_RESET_OFFSET(SRST_A_NPU_BIU, 0, 2),
|
||||
NPUCRU_RESET_OFFSET(SRST_H_NPU_BIU, 0, 3),
|
||||
NPUCRU_RESET_OFFSET(SRST_P_NPU_BIU, 0, 4),
|
||||
NPUCRU_RESET_OFFSET(SRST_P_CRU_NPU, 0, 5),
|
||||
NPUCRU_RESET_OFFSET(SRST_P_NPU_GRF, 0, 6),
|
||||
NPUCRU_RESET_OFFSET(SRST_P_NPU_PVTPLL, 0, 8),
|
||||
NPUCRU_RESET_OFFSET(SRST_H_RKNN, 0, 9),
|
||||
NPUCRU_RESET_OFFSET(SRST_A_RKNN, 0, 10),
|
||||
|
||||
/* VDOCRU-->SOFTRST_CON00 */
|
||||
VDOCRU_RESET_OFFSET(SRST_A_RKVDEC_BIU, 0, 0),
|
||||
VDOCRU_RESET_OFFSET(SRST_A_VDO_BIU, 0, 1),
|
||||
VDOCRU_RESET_OFFSET(SRST_H_VDO_BIU, 0, 3),
|
||||
VDOCRU_RESET_OFFSET(SRST_P_VDO_BIU, 0, 4),
|
||||
VDOCRU_RESET_OFFSET(SRST_P_CRU_VDO, 0, 5),
|
||||
VDOCRU_RESET_OFFSET(SRST_P_VDO_GRF, 0, 6),
|
||||
VDOCRU_RESET_OFFSET(SRST_A_RKVDEC, 0, 7),
|
||||
VDOCRU_RESET_OFFSET(SRST_H_RKVDEC, 0, 8),
|
||||
VDOCRU_RESET_OFFSET(SRST_HEVC_CA_RKVDEC, 0, 9),
|
||||
VDOCRU_RESET_OFFSET(SRST_A_VOP, 0, 10),
|
||||
VDOCRU_RESET_OFFSET(SRST_H_VOP, 0, 11),
|
||||
VDOCRU_RESET_OFFSET(SRST_D_VOP, 0, 12),
|
||||
VDOCRU_RESET_OFFSET(SRST_A_OOC, 0, 13),
|
||||
VDOCRU_RESET_OFFSET(SRST_H_OOC, 0, 14),
|
||||
VDOCRU_RESET_OFFSET(SRST_D_OOC, 0, 15),
|
||||
|
||||
/* VDOCRU-->SOFTRST_CON01 */
|
||||
VDOCRU_RESET_OFFSET(SRST_H_RKJPEG, 1, 3),
|
||||
VDOCRU_RESET_OFFSET(SRST_A_RKJPEG, 1, 4),
|
||||
VDOCRU_RESET_OFFSET(SRST_A_RKMMU_DECOM, 1, 5),
|
||||
VDOCRU_RESET_OFFSET(SRST_H_RKMMU_DECOM, 1, 6),
|
||||
VDOCRU_RESET_OFFSET(SRST_D_DECOM, 1, 8),
|
||||
VDOCRU_RESET_OFFSET(SRST_A_DECOM, 1, 9),
|
||||
VDOCRU_RESET_OFFSET(SRST_P_DECOM, 1, 10),
|
||||
VDOCRU_RESET_OFFSET(SRST_P_MIPI_DSI, 1, 12),
|
||||
VDOCRU_RESET_OFFSET(SRST_P_DSIPHY, 1, 13),
|
||||
|
||||
/* VCPCRU-->SOFTRST_CON00 */
|
||||
VCPCRU_RESET_OFFSET(SRST_REF_PVTPLL_VCP, 0, 0),
|
||||
VCPCRU_RESET_OFFSET(SRST_A_VCP_BIU, 0, 1),
|
||||
VCPCRU_RESET_OFFSET(SRST_H_VCP_BIU, 0, 2),
|
||||
VCPCRU_RESET_OFFSET(SRST_P_VCP_BIU, 0, 3),
|
||||
VCPCRU_RESET_OFFSET(SRST_P_CRU_VCP, 0, 4),
|
||||
VCPCRU_RESET_OFFSET(SRST_P_VCP_GRF, 0, 5),
|
||||
VCPCRU_RESET_OFFSET(SRST_P_VCP_PVTPLL, 0, 7),
|
||||
VCPCRU_RESET_OFFSET(SRST_A_AISP_BIU, 0, 8),
|
||||
VCPCRU_RESET_OFFSET(SRST_H_AISP_BIU, 0, 9),
|
||||
VCPCRU_RESET_OFFSET(SRST_CORE_AISP, 0, 13),
|
||||
|
||||
/* VCPCRU-->SOFTRST_CON01 */
|
||||
VCPCRU_RESET_OFFSET(SRST_H_FEC, 1, 0),
|
||||
VCPCRU_RESET_OFFSET(SRST_A_FEC, 1, 1),
|
||||
VCPCRU_RESET_OFFSET(SRST_CORE_FEC, 1, 2),
|
||||
VCPCRU_RESET_OFFSET(SRST_H_AVSP, 1, 3),
|
||||
VCPCRU_RESET_OFFSET(SRST_A_AVSP, 1, 4),
|
||||
};
|
||||
|
||||
void rv1126b_rst_init(struct device_node *np, void __iomem *reg_base)
|
||||
{
|
||||
rockchip_register_softrst_lut(np,
|
||||
rv1126b_register_offset,
|
||||
ARRAY_SIZE(rv1126b_register_offset),
|
||||
reg_base + RV1126B_SOFTRST_CON(0),
|
||||
ROCKCHIP_SOFTRST_HIWORD_MASK);
|
||||
}
|
||||
|
|
@ -95,6 +95,16 @@ config EXYNOS_CLKOUT
|
|||
status of the certains clocks from SoC, but it could also be tied to
|
||||
other devices as an input clock.
|
||||
|
||||
config EXYNOS_ACPM_CLK
|
||||
tristate "Clock driver controlled via ACPM interface"
|
||||
depends on EXYNOS_ACPM_PROTOCOL || (COMPILE_TEST && !EXYNOS_ACPM_PROTOCOL)
|
||||
help
|
||||
This driver provides support for clocks that are controlled by
|
||||
firmware that implements the ACPM interface.
|
||||
|
||||
This driver uses the ACPM interface to interact with the firmware
|
||||
providing all the clock controlls.
|
||||
|
||||
config TESLA_FSD_COMMON_CLK
|
||||
bool "Tesla FSD clock controller support" if COMPILE_TEST
|
||||
depends on COMMON_CLK_SAMSUNG
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos990.o
|
|||
obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynosautov9.o
|
||||
obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynosautov920.o
|
||||
obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-gs101.o
|
||||
obj-$(CONFIG_EXYNOS_ACPM_CLK) += clk-acpm.o
|
||||
obj-$(CONFIG_S3C64XX_COMMON_CLK) += clk-s3c64xx.o
|
||||
obj-$(CONFIG_S5PV210_COMMON_CLK) += clk-s5pv210.o clk-s5pv210-audss.o
|
||||
obj-$(CONFIG_TESLA_FSD_COMMON_CLK) += clk-fsd.o
|
||||
|
|
|
|||
|
|
@ -0,0 +1,185 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Samsung Exynos ACPM protocol based clock driver.
|
||||
*
|
||||
* Copyright 2025 Linaro Ltd.
|
||||
*/
|
||||
|
||||
#include <linux/array_size.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/container_of.h>
|
||||
#include <linux/device/devres.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/firmware/samsung/exynos-acpm-protocol.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
struct acpm_clk {
|
||||
u32 id;
|
||||
struct clk_hw hw;
|
||||
unsigned int mbox_chan_id;
|
||||
const struct acpm_handle *handle;
|
||||
};
|
||||
|
||||
struct acpm_clk_variant {
|
||||
const char *name;
|
||||
};
|
||||
|
||||
struct acpm_clk_driver_data {
|
||||
const struct acpm_clk_variant *clks;
|
||||
unsigned int nr_clks;
|
||||
unsigned int mbox_chan_id;
|
||||
};
|
||||
|
||||
#define to_acpm_clk(clk) container_of(clk, struct acpm_clk, hw)
|
||||
|
||||
#define ACPM_CLK(cname) \
|
||||
{ \
|
||||
.name = cname, \
|
||||
}
|
||||
|
||||
static const struct acpm_clk_variant gs101_acpm_clks[] = {
|
||||
ACPM_CLK("mif"),
|
||||
ACPM_CLK("int"),
|
||||
ACPM_CLK("cpucl0"),
|
||||
ACPM_CLK("cpucl1"),
|
||||
ACPM_CLK("cpucl2"),
|
||||
ACPM_CLK("g3d"),
|
||||
ACPM_CLK("g3dl2"),
|
||||
ACPM_CLK("tpu"),
|
||||
ACPM_CLK("intcam"),
|
||||
ACPM_CLK("tnr"),
|
||||
ACPM_CLK("cam"),
|
||||
ACPM_CLK("mfc"),
|
||||
ACPM_CLK("disp"),
|
||||
ACPM_CLK("bo"),
|
||||
};
|
||||
|
||||
static const struct acpm_clk_driver_data acpm_clk_gs101 = {
|
||||
.clks = gs101_acpm_clks,
|
||||
.nr_clks = ARRAY_SIZE(gs101_acpm_clks),
|
||||
.mbox_chan_id = 0,
|
||||
};
|
||||
|
||||
static unsigned long acpm_clk_recalc_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct acpm_clk *clk = to_acpm_clk(hw);
|
||||
|
||||
return clk->handle->ops.dvfs_ops.get_rate(clk->handle,
|
||||
clk->mbox_chan_id, clk->id);
|
||||
}
|
||||
|
||||
static int acpm_clk_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
/*
|
||||
* We can't figure out what rate it will be, so just return the
|
||||
* rate back to the caller. acpm_clk_recalc_rate() will be called
|
||||
* after the rate is set and we'll know what rate the clock is
|
||||
* running at then.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int acpm_clk_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct acpm_clk *clk = to_acpm_clk(hw);
|
||||
|
||||
return clk->handle->ops.dvfs_ops.set_rate(clk->handle,
|
||||
clk->mbox_chan_id, clk->id, rate);
|
||||
}
|
||||
|
||||
static const struct clk_ops acpm_clk_ops = {
|
||||
.recalc_rate = acpm_clk_recalc_rate,
|
||||
.determine_rate = acpm_clk_determine_rate,
|
||||
.set_rate = acpm_clk_set_rate,
|
||||
};
|
||||
|
||||
static int acpm_clk_register(struct device *dev, struct acpm_clk *aclk,
|
||||
const char *name)
|
||||
{
|
||||
struct clk_init_data init = {};
|
||||
|
||||
init.name = name;
|
||||
init.ops = &acpm_clk_ops;
|
||||
aclk->hw.init = &init;
|
||||
|
||||
return devm_clk_hw_register(dev, &aclk->hw);
|
||||
}
|
||||
|
||||
static int acpm_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct acpm_handle *acpm_handle;
|
||||
struct clk_hw_onecell_data *clk_data;
|
||||
struct clk_hw **hws;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct acpm_clk *aclks;
|
||||
unsigned int mbox_chan_id;
|
||||
int i, err, count;
|
||||
|
||||
acpm_handle = devm_acpm_get_by_node(dev, dev->parent->of_node);
|
||||
if (IS_ERR(acpm_handle))
|
||||
return dev_err_probe(dev, PTR_ERR(acpm_handle),
|
||||
"Failed to get acpm handle\n");
|
||||
|
||||
count = acpm_clk_gs101.nr_clks;
|
||||
mbox_chan_id = acpm_clk_gs101.mbox_chan_id;
|
||||
|
||||
clk_data = devm_kzalloc(dev, struct_size(clk_data, hws, count),
|
||||
GFP_KERNEL);
|
||||
if (!clk_data)
|
||||
return -ENOMEM;
|
||||
|
||||
clk_data->num = count;
|
||||
hws = clk_data->hws;
|
||||
|
||||
aclks = devm_kcalloc(dev, count, sizeof(*aclks), GFP_KERNEL);
|
||||
if (!aclks)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
struct acpm_clk *aclk = &aclks[i];
|
||||
|
||||
/*
|
||||
* The code assumes the clock IDs start from zero,
|
||||
* are sequential and do not have gaps.
|
||||
*/
|
||||
aclk->id = i;
|
||||
aclk->handle = acpm_handle;
|
||||
aclk->mbox_chan_id = mbox_chan_id;
|
||||
|
||||
hws[i] = &aclk->hw;
|
||||
|
||||
err = acpm_clk_register(dev, aclk,
|
||||
acpm_clk_gs101.clks[i].name);
|
||||
if (err)
|
||||
return dev_err_probe(dev, err,
|
||||
"Failed to register clock\n");
|
||||
}
|
||||
|
||||
return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
|
||||
clk_data);
|
||||
}
|
||||
|
||||
static const struct platform_device_id acpm_clk_id[] = {
|
||||
{ "gs101-acpm-clk" },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(platform, acpm_clk_id);
|
||||
|
||||
static struct platform_driver acpm_clk_driver = {
|
||||
.driver = {
|
||||
.name = "acpm-clocks",
|
||||
},
|
||||
.probe = acpm_clk_probe,
|
||||
.id_table = acpm_clk_id,
|
||||
};
|
||||
module_platform_driver(acpm_clk_driver);
|
||||
|
||||
MODULE_AUTHOR("Tudor Ambarus <tudor.ambarus@linaro.org>");
|
||||
MODULE_DESCRIPTION("Samsung Exynos ACPM clock driver");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
@ -175,6 +175,7 @@ static int exynos_clkout_probe(struct platform_device *pdev)
|
|||
clkout->mux.shift = EXYNOS_CLKOUT_MUX_SHIFT;
|
||||
clkout->mux.lock = &clkout->slock;
|
||||
|
||||
clkout->data.num = EXYNOS_CLKOUT_NR_CLKS;
|
||||
clkout->data.hws[0] = clk_hw_register_composite(NULL, "clkout",
|
||||
parent_names, parent_count, &clkout->mux.hw,
|
||||
&clk_mux_ops, NULL, NULL, &clkout->gate.hw,
|
||||
|
|
@ -185,7 +186,6 @@ static int exynos_clkout_probe(struct platform_device *pdev)
|
|||
goto err_unmap;
|
||||
}
|
||||
|
||||
clkout->data.num = EXYNOS_CLKOUT_NR_CLKS;
|
||||
ret = of_clk_add_hw_provider(clkout->np, of_clk_hw_onecell_get, &clkout->data);
|
||||
if (ret)
|
||||
goto err_clk_unreg;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@
|
|||
#define CLKS_NR_HSI0 (CLK_DOUT_HSI0_PCIE_APB + 1)
|
||||
#define CLKS_NR_HSI1 (CLK_MOUT_HSI1_USBDRD + 1)
|
||||
#define CLKS_NR_HSI2 (CLK_DOUT_HSI2_ETHERNET_PTP + 1)
|
||||
#define CLKS_NR_M2M (CLK_DOUT_M2M_NOCP + 1)
|
||||
#define CLKS_NR_MFC (CLK_DOUT_MFC_NOCP + 1)
|
||||
|
||||
/* ---- CMU_TOP ------------------------------------------------------------ */
|
||||
|
||||
|
|
@ -1821,6 +1823,88 @@ static const struct samsung_cmu_info hsi2_cmu_info __initconst = {
|
|||
.clk_name = "noc",
|
||||
};
|
||||
|
||||
/* ---- CMU_M2M --------------------------------------------------------- */
|
||||
|
||||
/* Register Offset definitions for CMU_M2M (0x1a800000) */
|
||||
#define PLL_CON0_MUX_CLKCMU_M2M_JPEG_USER 0x600
|
||||
#define PLL_CON0_MUX_CLKCMU_M2M_NOC_USER 0x610
|
||||
#define CLK_CON_DIV_DIV_CLK_M2M_NOCP 0x1800
|
||||
|
||||
static const unsigned long m2m_clk_regs[] __initconst = {
|
||||
PLL_CON0_MUX_CLKCMU_M2M_JPEG_USER,
|
||||
PLL_CON0_MUX_CLKCMU_M2M_NOC_USER,
|
||||
CLK_CON_DIV_DIV_CLK_M2M_NOCP,
|
||||
};
|
||||
|
||||
/* List of parent clocks for Muxes in CMU_M2M */
|
||||
PNAME(mout_clkcmu_m2m_noc_user_p) = { "oscclk", "dout_clkcmu_m2m_noc" };
|
||||
PNAME(mout_clkcmu_m2m_jpeg_user_p) = { "oscclk", "dout_clkcmu_m2m_jpeg" };
|
||||
|
||||
static const struct samsung_mux_clock m2m_mux_clks[] __initconst = {
|
||||
MUX(CLK_MOUT_M2M_JPEG_USER, "mout_clkcmu_m2m_jpeg_user",
|
||||
mout_clkcmu_m2m_jpeg_user_p, PLL_CON0_MUX_CLKCMU_M2M_JPEG_USER, 4, 1),
|
||||
MUX(CLK_MOUT_M2M_NOC_USER, "mout_clkcmu_m2m_noc_user",
|
||||
mout_clkcmu_m2m_noc_user_p, PLL_CON0_MUX_CLKCMU_M2M_NOC_USER, 4, 1),
|
||||
};
|
||||
|
||||
static const struct samsung_div_clock m2m_div_clks[] __initconst = {
|
||||
DIV(CLK_DOUT_M2M_NOCP, "dout_m2m_nocp",
|
||||
"mout_clkcmu_m2m_noc_user", CLK_CON_DIV_DIV_CLK_M2M_NOCP,
|
||||
0, 3),
|
||||
};
|
||||
|
||||
static const struct samsung_cmu_info m2m_cmu_info __initconst = {
|
||||
.mux_clks = m2m_mux_clks,
|
||||
.nr_mux_clks = ARRAY_SIZE(m2m_mux_clks),
|
||||
.div_clks = m2m_div_clks,
|
||||
.nr_div_clks = ARRAY_SIZE(m2m_div_clks),
|
||||
.nr_clk_ids = CLKS_NR_M2M,
|
||||
.clk_regs = m2m_clk_regs,
|
||||
.nr_clk_regs = ARRAY_SIZE(m2m_clk_regs),
|
||||
.clk_name = "noc",
|
||||
};
|
||||
|
||||
/* ---- CMU_MFC --------------------------------------------------------- */
|
||||
|
||||
/* Register Offset definitions for CMU_MFC (0x19c00000) */
|
||||
#define PLL_CON0_MUX_CLKCMU_MFC_MFC_USER 0x600
|
||||
#define PLL_CON0_MUX_CLKCMU_MFC_WFD_USER 0x610
|
||||
#define CLK_CON_DIV_DIV_CLK_MFC_NOCP 0x1800
|
||||
|
||||
static const unsigned long mfc_clk_regs[] __initconst = {
|
||||
PLL_CON0_MUX_CLKCMU_MFC_MFC_USER,
|
||||
PLL_CON0_MUX_CLKCMU_MFC_WFD_USER,
|
||||
CLK_CON_DIV_DIV_CLK_MFC_NOCP,
|
||||
};
|
||||
|
||||
/* List of parent clocks for Muxes in CMU_MFC */
|
||||
PNAME(mout_clkcmu_mfc_mfc_user_p) = { "oscclk", "dout_clkcmu_mfc_mfc" };
|
||||
PNAME(mout_clkcmu_mfc_wfd_user_p) = { "oscclk", "dout_clkcmu_mfc_wfd" };
|
||||
|
||||
static const struct samsung_mux_clock mfc_mux_clks[] __initconst = {
|
||||
MUX(CLK_MOUT_MFC_MFC_USER, "mout_clkcmu_mfc_mfc_user",
|
||||
mout_clkcmu_mfc_mfc_user_p, PLL_CON0_MUX_CLKCMU_MFC_MFC_USER, 4, 1),
|
||||
MUX(CLK_MOUT_MFC_WFD_USER, "mout_clkcmu_mfc_wfd_user",
|
||||
mout_clkcmu_mfc_wfd_user_p, PLL_CON0_MUX_CLKCMU_MFC_WFD_USER, 4, 1),
|
||||
};
|
||||
|
||||
static const struct samsung_div_clock mfc_div_clks[] __initconst = {
|
||||
DIV(CLK_DOUT_MFC_NOCP, "dout_mfc_nocp",
|
||||
"mout_clkcmu_mfc_mfc_user", CLK_CON_DIV_DIV_CLK_MFC_NOCP,
|
||||
0, 3),
|
||||
};
|
||||
|
||||
static const struct samsung_cmu_info mfc_cmu_info __initconst = {
|
||||
.mux_clks = mfc_mux_clks,
|
||||
.nr_mux_clks = ARRAY_SIZE(mfc_mux_clks),
|
||||
.div_clks = mfc_div_clks,
|
||||
.nr_div_clks = ARRAY_SIZE(mfc_div_clks),
|
||||
.nr_clk_ids = CLKS_NR_MFC,
|
||||
.clk_regs = mfc_clk_regs,
|
||||
.nr_clk_regs = ARRAY_SIZE(mfc_clk_regs),
|
||||
.clk_name = "noc",
|
||||
};
|
||||
|
||||
static int __init exynosautov920_cmu_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct samsung_cmu_info *info;
|
||||
|
|
@ -1851,6 +1935,12 @@ static const struct of_device_id exynosautov920_cmu_of_match[] = {
|
|||
}, {
|
||||
.compatible = "samsung,exynosautov920-cmu-hsi2",
|
||||
.data = &hsi2_cmu_info,
|
||||
}, {
|
||||
.compatible = "samsung,exynosautov920-cmu-m2m",
|
||||
.data = &m2m_cmu_info,
|
||||
}, {
|
||||
.compatible = "samsung,exynosautov920-cmu-mfc",
|
||||
.data = &mfc_cmu_info,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -11,14 +11,12 @@
|
|||
#include <linux/iopoll.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/timekeeping.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/io.h>
|
||||
#include "clk.h"
|
||||
#include "clk-pll.h"
|
||||
|
||||
#define PLL_TIMEOUT_US 20000U
|
||||
#define PLL_TIMEOUT_LOOPS 1000000U
|
||||
#define PLL_TIMEOUT_LOOPS 20000U
|
||||
|
||||
struct samsung_clk_pll {
|
||||
struct clk_hw hw;
|
||||
|
|
@ -71,20 +69,11 @@ static int samsung_pll_determine_rate(struct clk_hw *hw,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool pll_early_timeout = true;
|
||||
|
||||
static int __init samsung_pll_disable_early_timeout(void)
|
||||
{
|
||||
pll_early_timeout = false;
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(samsung_pll_disable_early_timeout);
|
||||
|
||||
/* Wait until the PLL is locked */
|
||||
static int samsung_pll_lock_wait(struct samsung_clk_pll *pll,
|
||||
unsigned int reg_mask)
|
||||
{
|
||||
int i, ret;
|
||||
int ret;
|
||||
u32 val;
|
||||
|
||||
/*
|
||||
|
|
@ -93,25 +82,15 @@ static int samsung_pll_lock_wait(struct samsung_clk_pll *pll,
|
|||
* initialized, another when the timekeeping is suspended. udelay() also
|
||||
* cannot be used when the clocksource is not running on arm64, since
|
||||
* the current timer is used as cycle counter. So a simple busy loop
|
||||
* is used here in that special cases. The limit of iterations has been
|
||||
* derived from experimental measurements of various PLLs on multiple
|
||||
* Exynos SoC variants. Single register read time was usually in range
|
||||
* 0.4...1.5 us, never less than 0.4 us.
|
||||
* is used here.
|
||||
* The limit of iterations has been derived from experimental
|
||||
* measurements of various PLLs on multiple Exynos SoC variants. Single
|
||||
* register read time was usually in range 0.4...1.5 us, never less than
|
||||
* 0.4 us.
|
||||
*/
|
||||
if (pll_early_timeout || timekeeping_suspended) {
|
||||
i = PLL_TIMEOUT_LOOPS;
|
||||
while (i-- > 0) {
|
||||
if (readl_relaxed(pll->con_reg) & reg_mask)
|
||||
return 0;
|
||||
|
||||
cpu_relax();
|
||||
}
|
||||
ret = -ETIMEDOUT;
|
||||
} else {
|
||||
ret = readl_relaxed_poll_timeout_atomic(pll->con_reg, val,
|
||||
val & reg_mask, 0, PLL_TIMEOUT_US);
|
||||
}
|
||||
|
||||
ret = readl_relaxed_poll_timeout_atomic(pll->con_reg, val,
|
||||
val & reg_mask, 0,
|
||||
PLL_TIMEOUT_LOOPS);
|
||||
if (ret < 0)
|
||||
pr_err("Could not lock PLL %s\n", clk_hw_get_name(&pll->hw));
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ config CLK_INTEL_SOCFPGA32
|
|||
default ARM && ARCH_INTEL_SOCFPGA
|
||||
|
||||
config CLK_INTEL_SOCFPGA64
|
||||
bool "Intel Stratix / Agilex / N5X clock controller support" if COMPILE_TEST && (!ARM64 || !ARCH_INTEL_SOCFPGA)
|
||||
bool "Intel Stratix / Agilex / N5X / Agilex5 clock controller support" if COMPILE_TEST && (!ARM64 || !ARCH_INTEL_SOCFPGA)
|
||||
default ARM64 && ARCH_INTEL_SOCFPGA
|
||||
|
||||
endif # CLK_INTEL_SOCFPGA
|
||||
|
|
|
|||
|
|
@ -3,4 +3,4 @@ obj-$(CONFIG_CLK_INTEL_SOCFPGA32) += clk.o clk-gate.o clk-pll.o clk-periph.o \
|
|||
clk-pll-a10.o clk-periph-a10.o clk-gate-a10.o
|
||||
obj-$(CONFIG_CLK_INTEL_SOCFPGA64) += clk-s10.o \
|
||||
clk-pll-s10.o clk-periph-s10.o clk-gate-s10.o \
|
||||
clk-agilex.o
|
||||
clk-agilex.o clk-agilex5.o
|
||||
|
|
|
|||
|
|
@ -0,0 +1,561 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2022-2024, Intel Corporation
|
||||
* Copyright (C) 2025, Altera Corporation
|
||||
*/
|
||||
#include <linux/slab.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <dt-bindings/clock/intel,agilex5-clkmgr.h>
|
||||
#include "stratix10-clk.h"
|
||||
#include "clk.h"
|
||||
|
||||
/* External parent clocks come from DT via fw_name */
|
||||
static const char * const boot_pll_parents[] = {
|
||||
"osc1",
|
||||
"cb-intosc-hs-div2-clk",
|
||||
};
|
||||
|
||||
static const char * const main_pll_parents[] = {
|
||||
"osc1",
|
||||
"cb-intosc-hs-div2-clk",
|
||||
"f2s-free-clk",
|
||||
};
|
||||
|
||||
static const char * const periph_pll_parents[] = {
|
||||
"osc1",
|
||||
"cb-intosc-hs-div2-clk",
|
||||
};
|
||||
|
||||
/* Core free muxes */
|
||||
static const char * const core0_free_mux[] = {
|
||||
"main_pll_c1",
|
||||
"peri_pll_c0",
|
||||
"osc1",
|
||||
"cb-intosc-hs-div2-clk",
|
||||
"f2s-free-clk",
|
||||
};
|
||||
|
||||
static const char * const core1_free_mux[] = {
|
||||
"main_pll_c1",
|
||||
"peri_pll_c0",
|
||||
"osc1",
|
||||
"cb-intosc-hs-div2-clk",
|
||||
"f2s-free-clk",
|
||||
};
|
||||
|
||||
static const char * const core2_free_mux[] = {
|
||||
"main_pll_c0",
|
||||
"osc1",
|
||||
"cb-intosc-hs-div2-clk",
|
||||
"f2s-free-clk",
|
||||
};
|
||||
|
||||
static const char * const core3_free_mux[] = {
|
||||
"main_pll_c0",
|
||||
"osc1",
|
||||
"cb-intosc-hs-div2-clk",
|
||||
"f2s-free-clk",
|
||||
};
|
||||
|
||||
static const char * const dsu_free_mux[] = {
|
||||
"main_pll_c2",
|
||||
"peri_pll_c0",
|
||||
"osc1",
|
||||
"cb-intosc-hs-div2-clk",
|
||||
"f2s-free-clk",
|
||||
};
|
||||
|
||||
static const char * const noc_free_mux[] = {
|
||||
"main_pll_c3",
|
||||
"peri_pll_c1",
|
||||
"osc1",
|
||||
"cb-intosc-hs-div2-clk",
|
||||
"f2s-free-clk",
|
||||
};
|
||||
|
||||
static const char * const emac_ptp_free_mux[] = {
|
||||
"main_pll_c3",
|
||||
"peri_pll_c3",
|
||||
"osc1",
|
||||
"cb-intosc-hs-div2-clk",
|
||||
"f2s-free-clk",
|
||||
};
|
||||
|
||||
static const char * const emaca_free_mux[] = {
|
||||
"main_pll_c2",
|
||||
"peri_pll_c3",
|
||||
"osc1",
|
||||
"cb-intosc-hs-div2-clk",
|
||||
"f2s-free-clk",
|
||||
};
|
||||
|
||||
static const char * const emacb_free_mux[] = {
|
||||
"main_pll_c3",
|
||||
"peri_pll_c3",
|
||||
"osc1",
|
||||
"cb-intosc-hs-div2-clk",
|
||||
"f2s-free-clk",
|
||||
};
|
||||
|
||||
static const char * const gpio_db_free_mux[] = {
|
||||
"main_pll_c3",
|
||||
"peri_pll_c1",
|
||||
"osc1",
|
||||
"cb-intosc-hs-div2-clk",
|
||||
"f2s-free-clk",
|
||||
};
|
||||
|
||||
static const char * const psi_ref_free_mux[] = {
|
||||
"main_pll_c1",
|
||||
"peri_pll_c3",
|
||||
"osc1",
|
||||
"cb-intosc-hs-div2-clk",
|
||||
"f2s-free-clk",
|
||||
};
|
||||
|
||||
static const char * const usb31_free_mux[] = {
|
||||
"main_pll_c3",
|
||||
"peri_pll_c2",
|
||||
"osc1",
|
||||
"cb-intosc-hs-div2-clk",
|
||||
"f2s-free-clk",
|
||||
};
|
||||
|
||||
static const char * const s2f_user0_free_mux[] = {
|
||||
"main_pll_c1",
|
||||
"peri_pll_c3",
|
||||
"osc1",
|
||||
"cb-intosc-hs-div2-clk",
|
||||
"f2s-free-clk",
|
||||
};
|
||||
|
||||
static const char * const s2f_user1_free_mux[] = {
|
||||
"main_pll_c1",
|
||||
"peri_pll_c3",
|
||||
"osc1",
|
||||
"cb-intosc-hs-div2-clk",
|
||||
"f2s-free-clk",
|
||||
};
|
||||
|
||||
/* Secondary muxes between free_clk and boot_clk */
|
||||
static const char * const core0_mux[] = {
|
||||
"core0_free_clk",
|
||||
"boot_clk",
|
||||
};
|
||||
|
||||
static const char * const core1_mux[] = {
|
||||
"core1_free_clk",
|
||||
"boot_clk",
|
||||
};
|
||||
|
||||
static const char * const core2_mux[] = {
|
||||
"core2_free_clk",
|
||||
"boot_clk",
|
||||
};
|
||||
|
||||
static const char * const core3_mux[] = {
|
||||
"core3_free_clk",
|
||||
"boot_clk",
|
||||
};
|
||||
|
||||
static const char * const dsu_mux[] = {
|
||||
"dsu_free_clk",
|
||||
"boot_clk",
|
||||
};
|
||||
|
||||
static const char * const noc_mux[] = {
|
||||
"noc_free_clk",
|
||||
"boot_clk",
|
||||
};
|
||||
|
||||
static const char * const emac_mux[] = {
|
||||
"emaca_free_clk",
|
||||
"emacb_free_clk",
|
||||
"boot_clk",
|
||||
};
|
||||
|
||||
static const char * const s2f_user0_mux[] = {
|
||||
"s2f_user0_free_clk",
|
||||
"boot_clk",
|
||||
};
|
||||
|
||||
static const char * const s2f_user1_mux[] = {
|
||||
"s2f_user1_free_clk",
|
||||
"boot_clk",
|
||||
};
|
||||
|
||||
static const char * const psi_mux[] = {
|
||||
"psi_ref_free_clk",
|
||||
"boot_clk",
|
||||
};
|
||||
|
||||
static const char * const gpio_db_mux[] = {
|
||||
"gpio_db_free_clk",
|
||||
"boot_clk",
|
||||
};
|
||||
|
||||
static const char * const emac_ptp_mux[] = {
|
||||
"emac_ptp_free_clk",
|
||||
"boot_clk",
|
||||
};
|
||||
|
||||
static const char * const usb31_mux[] = {
|
||||
"usb31_free_clk",
|
||||
"boot_clk",
|
||||
};
|
||||
|
||||
static const struct agilex5_pll_clock agilex5_pll_clks[] = {
|
||||
{
|
||||
.id = AGILEX5_BOOT_CLK,
|
||||
.name = "boot_clk",
|
||||
.parent_names = boot_pll_parents,
|
||||
.num_parents = ARRAY_SIZE(boot_pll_parents),
|
||||
.flags = 0,
|
||||
.offset = 0x0,
|
||||
},
|
||||
{
|
||||
.id = AGILEX5_MAIN_PLL_CLK,
|
||||
.name = "main_pll",
|
||||
.parent_names = main_pll_parents,
|
||||
.num_parents = ARRAY_SIZE(main_pll_parents),
|
||||
.flags = 0,
|
||||
.offset = 0x48,
|
||||
},
|
||||
{
|
||||
.id = AGILEX5_PERIPH_PLL_CLK,
|
||||
.name = "periph_pll",
|
||||
.parent_names = periph_pll_parents,
|
||||
.num_parents = ARRAY_SIZE(periph_pll_parents),
|
||||
.flags = 0,
|
||||
.offset = 0x9C,
|
||||
},
|
||||
};
|
||||
|
||||
/* Main PLL C0, C1, C2, C3 and Peri PLL C0, C1, C2, C3. With ping-pong counter. */
|
||||
static const struct stratix10_perip_c_clock agilex5_main_perip_c_clks[] = {
|
||||
{ AGILEX5_MAIN_PLL_C0_CLK, "main_pll_c0", "main_pll", NULL, 1, 0,
|
||||
0x5C },
|
||||
{ AGILEX5_MAIN_PLL_C1_CLK, "main_pll_c1", "main_pll", NULL, 1, 0,
|
||||
0x60 },
|
||||
{ AGILEX5_MAIN_PLL_C2_CLK, "main_pll_c2", "main_pll", NULL, 1, 0,
|
||||
0x64 },
|
||||
{ AGILEX5_MAIN_PLL_C3_CLK, "main_pll_c3", "main_pll", NULL, 1, 0,
|
||||
0x68 },
|
||||
{ AGILEX5_PERIPH_PLL_C0_CLK, "peri_pll_c0", "periph_pll", NULL, 1, 0,
|
||||
0xB0 },
|
||||
{ AGILEX5_PERIPH_PLL_C1_CLK, "peri_pll_c1", "periph_pll", NULL, 1, 0,
|
||||
0xB4 },
|
||||
{ AGILEX5_PERIPH_PLL_C2_CLK, "peri_pll_c2", "periph_pll", NULL, 1, 0,
|
||||
0xB8 },
|
||||
{ AGILEX5_PERIPH_PLL_C3_CLK, "peri_pll_c3", "periph_pll", NULL, 1, 0,
|
||||
0xBC },
|
||||
};
|
||||
|
||||
/* Non-SW clock-gated enabled clocks */
|
||||
static const struct agilex5_perip_cnt_clock agilex5_main_perip_cnt_clks[] = {
|
||||
{ AGILEX5_CORE0_FREE_CLK, "core0_free_clk", core0_free_mux,
|
||||
ARRAY_SIZE(core0_free_mux), 0, 0x0100, 0, 0, 0},
|
||||
{ AGILEX5_CORE1_FREE_CLK, "core1_free_clk", core1_free_mux,
|
||||
ARRAY_SIZE(core1_free_mux), 0, 0x0104, 0, 0, 0},
|
||||
{ AGILEX5_CORE2_FREE_CLK, "core2_free_clk", core2_free_mux,
|
||||
ARRAY_SIZE(core2_free_mux), 0, 0x010C, 0, 0, 0},
|
||||
{ AGILEX5_CORE3_FREE_CLK, "core3_free_clk", core3_free_mux,
|
||||
ARRAY_SIZE(core3_free_mux), 0, 0x0110, 0, 0, 0},
|
||||
{ AGILEX5_DSU_FREE_CLK, "dsu_free_clk", dsu_free_mux,
|
||||
ARRAY_SIZE(dsu_free_mux), 0, 0xfc, 0, 0, 0},
|
||||
{ AGILEX5_NOC_FREE_CLK, "noc_free_clk", noc_free_mux,
|
||||
ARRAY_SIZE(noc_free_mux), 0, 0x40, 0, 0, 0 },
|
||||
{ AGILEX5_EMAC_A_FREE_CLK, "emaca_free_clk", emaca_free_mux,
|
||||
ARRAY_SIZE(emaca_free_mux), 0, 0xD4, 0, 0x88, 0 },
|
||||
{ AGILEX5_EMAC_B_FREE_CLK, "emacb_free_clk", emacb_free_mux,
|
||||
ARRAY_SIZE(emacb_free_mux), 0, 0xD8, 0, 0x88, 1 },
|
||||
{ AGILEX5_EMAC_PTP_FREE_CLK, "emac_ptp_free_clk", emac_ptp_free_mux,
|
||||
ARRAY_SIZE(emac_ptp_free_mux), 0, 0xDC, 0, 0x88, 2 },
|
||||
{ AGILEX5_GPIO_DB_FREE_CLK, "gpio_db_free_clk", gpio_db_free_mux,
|
||||
ARRAY_SIZE(gpio_db_free_mux), 0, 0xE0, 0, 0x88, 3 },
|
||||
{ AGILEX5_S2F_USER0_FREE_CLK, "s2f_user0_free_clk", s2f_user0_free_mux,
|
||||
ARRAY_SIZE(s2f_user0_free_mux), 0, 0xE8, 0, 0x30, 2 },
|
||||
{ AGILEX5_S2F_USER1_FREE_CLK, "s2f_user1_free_clk", s2f_user1_free_mux,
|
||||
ARRAY_SIZE(s2f_user1_free_mux), 0, 0xEC, 0, 0x88, 5 },
|
||||
{ AGILEX5_PSI_REF_FREE_CLK, "psi_ref_free_clk", psi_ref_free_mux,
|
||||
ARRAY_SIZE(psi_ref_free_mux), 0, 0xF0, 0, 0x88, 6 },
|
||||
{ AGILEX5_USB31_FREE_CLK, "usb31_free_clk", usb31_free_mux,
|
||||
ARRAY_SIZE(usb31_free_mux), 0, 0xF8, 0, 0x88, 7},
|
||||
};
|
||||
|
||||
static const char * const cs_pdbg_parents[] = { "cs_at_clk" };
|
||||
static const char * const usb31_bus_clk_early_parents[] = { "l4_main_clk" };
|
||||
static const char * const l4_mp_clk_parent[] = { "l4_mp_clk" };
|
||||
static const char * const l4_sp_clk_parent[] = { "l4_sp_clk" };
|
||||
static const char * const dfi_clk_parent[] = { "dfi_clk" };
|
||||
|
||||
/* SW Clock gate enabled clocks */
|
||||
static const struct agilex5_gate_clock agilex5_gate_clks[] = {
|
||||
{ AGILEX5_CORE0_CLK, "core0_clk", core0_mux,
|
||||
ARRAY_SIZE(core0_mux), 0, 0x24, 8, 0, 0, 0, 0x30, 5, 0 },
|
||||
{ AGILEX5_CORE1_CLK, "core1_clk", core1_mux,
|
||||
ARRAY_SIZE(core1_mux), 0, 0x24, 9, 0, 0, 0, 0x30, 5, 0 },
|
||||
{ AGILEX5_CORE2_CLK, "core2_clk", core2_mux,
|
||||
ARRAY_SIZE(core2_mux), 0, 0x24, 10, 0, 0, 0, 0x30, 6, 0 },
|
||||
{ AGILEX5_CORE3_CLK, "core3_clk", core3_mux,
|
||||
ARRAY_SIZE(core3_mux), 0, 0x24, 11, 0, 0, 0, 0x30, 7, 0 },
|
||||
{ AGILEX5_MPU_CLK, "dsu_clk", dsu_mux, ARRAY_SIZE(dsu_mux), 0, 0, 0,
|
||||
0, 0, 0, 0x34, 4, 0 },
|
||||
{ AGILEX5_MPU_PERIPH_CLK, "mpu_periph_clk", dsu_mux,
|
||||
ARRAY_SIZE(dsu_mux), 0, 0, 0, 0x44, 20, 2, 0x34, 4, 0 },
|
||||
{ AGILEX5_MPU_CCU_CLK, "mpu_ccu_clk", dsu_mux,
|
||||
ARRAY_SIZE(dsu_mux), 0, 0, 0, 0x44, 18, 2, 0x34, 4, 0 },
|
||||
{ AGILEX5_L4_MAIN_CLK, "l4_main_clk", noc_mux, ARRAY_SIZE(noc_mux),
|
||||
CLK_IS_CRITICAL, 0x24, 1, 0, 0, 0, 0, 0, 0 },
|
||||
{ AGILEX5_L4_MP_CLK, "l4_mp_clk", noc_mux, ARRAY_SIZE(noc_mux), 0,
|
||||
0x24, 2, 0x44, 4, 2, 0x30, 1, 0 },
|
||||
{ AGILEX5_L4_SYS_FREE_CLK, "l4_sys_free_clk", noc_mux,
|
||||
ARRAY_SIZE(noc_mux), 0, 0, 0, 0x44, 2, 2, 0x30, 1, 0 },
|
||||
{ AGILEX5_L4_SP_CLK, "l4_sp_clk", noc_mux, ARRAY_SIZE(noc_mux),
|
||||
CLK_IS_CRITICAL, 0x24, 3, 0x44, 6, 2, 0x30, 1, 0 },
|
||||
|
||||
/* Core sight clocks*/
|
||||
{ AGILEX5_CS_AT_CLK, "cs_at_clk", noc_mux, ARRAY_SIZE(noc_mux), 0,
|
||||
0x24, 4, 0x44, 24, 2, 0x30, 1, 0 },
|
||||
{ AGILEX5_CS_TRACE_CLK, "cs_trace_clk", noc_mux,
|
||||
ARRAY_SIZE(noc_mux), 0, 0x24, 4, 0x44, 26, 2, 0x30, 1, 0 },
|
||||
{ AGILEX5_CS_PDBG_CLK, "cs_pdbg_clk", cs_pdbg_parents, 1, 0, 0x24, 4,
|
||||
0x44, 28, 1, 0, 0, 0 },
|
||||
|
||||
/* Main Peripheral PLL1 Begin */
|
||||
{ AGILEX5_EMAC0_CLK, "emac0_clk", emac_mux, ARRAY_SIZE(emac_mux),
|
||||
0, 0x7C, 0, 0, 0, 0, 0x94, 26, 0 },
|
||||
{ AGILEX5_EMAC1_CLK, "emac1_clk", emac_mux, ARRAY_SIZE(emac_mux),
|
||||
0, 0x7C, 1, 0, 0, 0, 0x94, 27, 0 },
|
||||
{ AGILEX5_EMAC2_CLK, "emac2_clk", emac_mux, ARRAY_SIZE(emac_mux),
|
||||
0, 0x7C, 2, 0, 0, 0, 0x94, 28, 0 },
|
||||
{ AGILEX5_EMAC_PTP_CLK, "emac_ptp_clk", emac_ptp_mux,
|
||||
ARRAY_SIZE(emac_ptp_mux), 0, 0x7C, 3, 0, 0, 0, 0x88, 2, 0 },
|
||||
{ AGILEX5_GPIO_DB_CLK, "gpio_db_clk", gpio_db_mux,
|
||||
ARRAY_SIZE(gpio_db_mux), 0, 0x7C, 4, 0x98, 0, 16, 0x88, 3, 1 },
|
||||
/* Main Peripheral PLL1 End */
|
||||
|
||||
/* Peripheral clocks */
|
||||
{ AGILEX5_S2F_USER0_CLK, "s2f_user0_clk", s2f_user0_mux,
|
||||
ARRAY_SIZE(s2f_user0_mux), 0, 0x24, 6, 0, 0, 0, 0x30, 2, 0 },
|
||||
{ AGILEX5_S2F_USER1_CLK, "s2f_user1_clk", s2f_user1_mux,
|
||||
ARRAY_SIZE(s2f_user1_mux), 0, 0x7C, 6, 0, 0, 0, 0x88, 5, 0 },
|
||||
{ AGILEX5_PSI_REF_CLK, "psi_ref_clk", psi_mux,
|
||||
ARRAY_SIZE(psi_mux), 0, 0x7C, 7, 0, 0, 0, 0x88, 6, 0 },
|
||||
{ AGILEX5_USB31_SUSPEND_CLK, "usb31_suspend_clk", usb31_mux,
|
||||
ARRAY_SIZE(usb31_mux), 0, 0x7C, 25, 0, 0, 0, 0x88, 7, 0 },
|
||||
{ AGILEX5_USB31_BUS_CLK_EARLY, "usb31_bus_clk_early", usb31_bus_clk_early_parents,
|
||||
1, 0, 0x7C, 25, 0, 0, 0, 0, 0, 0 },
|
||||
{ AGILEX5_USB2OTG_HCLK, "usb2otg_hclk", l4_mp_clk_parent, 1, 0, 0x7C,
|
||||
8, 0, 0, 0, 0, 0, 0 },
|
||||
{ AGILEX5_SPIM_0_CLK, "spim_0_clk", l4_mp_clk_parent, 1, 0, 0x7C, 9,
|
||||
0, 0, 0, 0, 0, 0 },
|
||||
{ AGILEX5_SPIM_1_CLK, "spim_1_clk", l4_mp_clk_parent, 1, 0, 0x7C, 11,
|
||||
0, 0, 0, 0, 0, 0 },
|
||||
{ AGILEX5_SPIS_0_CLK, "spis_0_clk", l4_sp_clk_parent, 1, 0, 0x7C, 12,
|
||||
0, 0, 0, 0, 0, 0 },
|
||||
{ AGILEX5_SPIS_1_CLK, "spis_1_clk", l4_sp_clk_parent, 1, 0, 0x7C, 13,
|
||||
0, 0, 0, 0, 0, 0 },
|
||||
{ AGILEX5_DMA_CORE_CLK, "dma_core_clk", l4_mp_clk_parent, 1, 0, 0x7C,
|
||||
14, 0, 0, 0, 0, 0, 0 },
|
||||
{ AGILEX5_DMA_HS_CLK, "dma_hs_clk", l4_mp_clk_parent, 1, 0, 0x7C, 14,
|
||||
0, 0, 0, 0, 0, 0 },
|
||||
{ AGILEX5_I3C_0_CORE_CLK, "i3c_0_core_clk", l4_mp_clk_parent, 1, 0,
|
||||
0x7C, 18, 0, 0, 0, 0, 0, 0 },
|
||||
{ AGILEX5_I3C_1_CORE_CLK, "i3c_1_core_clk", l4_mp_clk_parent, 1, 0,
|
||||
0x7C, 19, 0, 0, 0, 0, 0, 0 },
|
||||
{ AGILEX5_I2C_0_PCLK, "i2c_0_pclk", l4_sp_clk_parent, 1, 0, 0x7C, 15,
|
||||
0, 0, 0, 0, 0, 0 },
|
||||
{ AGILEX5_I2C_1_PCLK, "i2c_1_pclk", l4_sp_clk_parent, 1, 0, 0x7C, 16,
|
||||
0, 0, 0, 0, 0, 0 },
|
||||
{ AGILEX5_I2C_EMAC0_PCLK, "i2c_emac0_pclk", l4_sp_clk_parent, 1, 0,
|
||||
0x7C, 17, 0, 0, 0, 0, 0, 0 },
|
||||
{ AGILEX5_I2C_EMAC1_PCLK, "i2c_emac1_pclk", l4_sp_clk_parent, 1, 0,
|
||||
0x7C, 22, 0, 0, 0, 0, 0, 0 },
|
||||
{ AGILEX5_I2C_EMAC2_PCLK, "i2c_emac2_pclk", l4_sp_clk_parent, 1, 0,
|
||||
0x7C, 27, 0, 0, 0, 0, 0, 0 },
|
||||
{ AGILEX5_UART_0_PCLK, "uart_0_pclk", l4_sp_clk_parent, 1, 0, 0x7C, 20,
|
||||
0, 0, 0, 0, 0, 0 },
|
||||
{ AGILEX5_UART_1_PCLK, "uart_1_pclk", l4_sp_clk_parent, 1, 0, 0x7C, 21,
|
||||
0, 0, 0, 0, 0, 0 },
|
||||
{ AGILEX5_SPTIMER_0_PCLK, "sptimer_0_pclk", l4_sp_clk_parent, 1, 0,
|
||||
0x7C, 23, 0, 0, 0, 0, 0, 0 },
|
||||
{ AGILEX5_SPTIMER_1_PCLK, "sptimer_1_pclk", l4_sp_clk_parent, 1, 0,
|
||||
0x7C, 24, 0, 0, 0, 0, 0, 0 },
|
||||
|
||||
/*NAND, SD/MMC and SoftPHY overall clocking*/
|
||||
{ AGILEX5_DFI_CLK, "dfi_clk", l4_mp_clk_parent, 1, 0, 0, 0, 0x44, 16,
|
||||
2, 0, 0, 0 },
|
||||
{ AGILEX5_NAND_NF_CLK, "nand_nf_clk", dfi_clk_parent, 1, 0, 0x7C, 10,
|
||||
0, 0, 0, 0, 0, 0 },
|
||||
{ AGILEX5_NAND_BCH_CLK, "nand_bch_clk", l4_mp_clk_parent, 1, 0, 0x7C,
|
||||
10, 0, 0, 0, 0, 0, 0 },
|
||||
{ AGILEX5_SDMMC_SDPHY_REG_CLK, "sdmmc_sdphy_reg_clk", l4_mp_clk_parent,
|
||||
1, 0, 0x7C, 5, 0, 0, 0, 0, 0, 0 },
|
||||
{ AGILEX5_SDMCLK, "sdmclk", dfi_clk_parent, 1, 0, 0x7C, 5, 0, 0, 0,
|
||||
0, 0, 0 },
|
||||
{ AGILEX5_SOFTPHY_REG_PCLK, "softphy_reg_pclk", l4_mp_clk_parent, 1, 0,
|
||||
0x7C, 26, 0, 0, 0, 0, 0, 0 },
|
||||
{ AGILEX5_SOFTPHY_PHY_CLK, "softphy_phy_clk", l4_mp_clk_parent, 1, 0,
|
||||
0x7C, 26, 0x44, 16, 2, 0, 0, 0 },
|
||||
{ AGILEX5_SOFTPHY_CTRL_CLK, "softphy_ctrl_clk", dfi_clk_parent, 1, 0,
|
||||
0x7C, 26, 0, 0, 0, 0, 0, 0 },
|
||||
};
|
||||
|
||||
static int
|
||||
agilex5_clk_register_c_perip(const struct stratix10_perip_c_clock *clks,
|
||||
int nums, struct stratix10_clock_data *data)
|
||||
{
|
||||
struct clk_hw *hw_clk;
|
||||
void __iomem *base = data->base;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nums; i++) {
|
||||
hw_clk = s10_register_periph(&clks[i], base);
|
||||
if (IS_ERR(hw_clk)) {
|
||||
pr_err("%s: failed to register clock %s\n", __func__,
|
||||
clks[i].name);
|
||||
continue;
|
||||
}
|
||||
data->clk_data.hws[clks[i].id] = hw_clk;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
agilex5_clk_register_cnt_perip(const struct agilex5_perip_cnt_clock *clks,
|
||||
int nums, struct stratix10_clock_data *data)
|
||||
{
|
||||
struct clk_hw *hw_clk;
|
||||
void __iomem *base = data->base;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nums; i++) {
|
||||
hw_clk = agilex5_register_cnt_periph(&clks[i], base);
|
||||
if (IS_ERR(hw_clk)) {
|
||||
pr_err("%s: failed to register clock %s\n", __func__,
|
||||
clks[i].name);
|
||||
continue;
|
||||
}
|
||||
data->clk_data.hws[clks[i].id] = hw_clk;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int agilex5_clk_register_gate(const struct agilex5_gate_clock *clks,
|
||||
int nums,
|
||||
struct stratix10_clock_data *data)
|
||||
{
|
||||
struct clk_hw *hw_clk;
|
||||
void __iomem *base = data->base;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nums; i++) {
|
||||
hw_clk = agilex5_register_gate(&clks[i], base);
|
||||
if (IS_ERR(hw_clk)) {
|
||||
pr_err("%s: failed to register clock %s\n", __func__,
|
||||
clks[i].name);
|
||||
continue;
|
||||
}
|
||||
data->clk_data.hws[clks[i].id] = hw_clk;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int agilex5_clk_register_pll(const struct agilex5_pll_clock *clks,
|
||||
int nums, struct stratix10_clock_data *data)
|
||||
{
|
||||
struct clk_hw *hw_clk;
|
||||
void __iomem *base = data->base;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < nums; i++) {
|
||||
hw_clk = agilex5_register_pll(&clks[i], base);
|
||||
if (IS_ERR(hw_clk)) {
|
||||
pr_err("%s: failed to register clock %s\n", __func__,
|
||||
clks[i].name);
|
||||
continue;
|
||||
}
|
||||
data->clk_data.hws[clks[i].id] = hw_clk;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int agilex5_clkmgr_init(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct stratix10_clock_data *clk_data;
|
||||
void __iomem *base;
|
||||
int i, num_clks;
|
||||
|
||||
base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(base))
|
||||
return PTR_ERR(base);
|
||||
|
||||
num_clks = AGILEX5_NUM_CLKS;
|
||||
|
||||
clk_data = devm_kzalloc(dev, struct_size(clk_data, clk_data.hws,
|
||||
num_clks), GFP_KERNEL);
|
||||
if (!clk_data)
|
||||
return -ENOMEM;
|
||||
|
||||
clk_data->base = base;
|
||||
clk_data->clk_data.num = num_clks;
|
||||
|
||||
for (i = 0; i < num_clks; i++)
|
||||
clk_data->clk_data.hws[i] = ERR_PTR(-ENOENT);
|
||||
|
||||
agilex5_clk_register_pll(agilex5_pll_clks, ARRAY_SIZE(agilex5_pll_clks),
|
||||
clk_data);
|
||||
|
||||
/* mainPLL C0, C1, C2, C3 and periph PLL C0, C1, C2, C3*/
|
||||
agilex5_clk_register_c_perip(agilex5_main_perip_c_clks,
|
||||
ARRAY_SIZE(agilex5_main_perip_c_clks),
|
||||
clk_data);
|
||||
|
||||
agilex5_clk_register_cnt_perip(agilex5_main_perip_cnt_clks,
|
||||
ARRAY_SIZE(agilex5_main_perip_cnt_clks),
|
||||
clk_data);
|
||||
|
||||
agilex5_clk_register_gate(agilex5_gate_clks,
|
||||
ARRAY_SIZE(agilex5_gate_clks), clk_data);
|
||||
|
||||
of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &clk_data->clk_data);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int agilex5_clkmgr_probe(struct platform_device *pdev)
|
||||
{
|
||||
int (*probe_func)(struct platform_device *init_func);
|
||||
|
||||
probe_func = of_device_get_match_data(&pdev->dev);
|
||||
if (!probe_func)
|
||||
return -ENODEV;
|
||||
return probe_func(pdev);
|
||||
}
|
||||
|
||||
static const struct of_device_id agilex5_clkmgr_match_table[] = {
|
||||
{ .compatible = "intel,agilex5-clkmgr", .data = agilex5_clkmgr_init },
|
||||
{}
|
||||
};
|
||||
|
||||
static struct platform_driver agilex5_clkmgr_driver = {
|
||||
.probe = agilex5_clkmgr_probe,
|
||||
.driver = {
|
||||
.name = "agilex5-clkmgr",
|
||||
.suppress_bind_attrs = true,
|
||||
.of_match_table = agilex5_clkmgr_match_table,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init agilex5_clk_init(void)
|
||||
{
|
||||
return platform_driver_register(&agilex5_clkmgr_driver);
|
||||
}
|
||||
core_initcall(agilex5_clk_init);
|
||||
|
|
@ -239,3 +239,56 @@ struct clk_hw *agilex_register_gate(const struct stratix10_gate_clock *clks, voi
|
|||
}
|
||||
return hw_clk;
|
||||
}
|
||||
|
||||
struct clk_hw *agilex5_register_gate(const struct agilex5_gate_clock *clks, void __iomem *regbase)
|
||||
{
|
||||
struct clk_hw *hw_clk;
|
||||
struct socfpga_gate_clk *socfpga_clk;
|
||||
struct clk_init_data init;
|
||||
int ret;
|
||||
|
||||
socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL);
|
||||
if (!socfpga_clk)
|
||||
return NULL;
|
||||
|
||||
socfpga_clk->hw.reg = regbase + clks->gate_reg;
|
||||
socfpga_clk->hw.bit_idx = clks->gate_idx;
|
||||
|
||||
gateclk_ops.enable = clk_gate_ops.enable;
|
||||
gateclk_ops.disable = clk_gate_ops.disable;
|
||||
|
||||
socfpga_clk->fixed_div = clks->fixed_div;
|
||||
|
||||
if (clks->div_reg)
|
||||
socfpga_clk->div_reg = regbase + clks->div_reg;
|
||||
else
|
||||
socfpga_clk->div_reg = NULL;
|
||||
|
||||
socfpga_clk->width = clks->div_width;
|
||||
socfpga_clk->shift = clks->div_offset;
|
||||
|
||||
if (clks->bypass_reg)
|
||||
socfpga_clk->bypass_reg = regbase + clks->bypass_reg;
|
||||
else
|
||||
socfpga_clk->bypass_reg = NULL;
|
||||
socfpga_clk->bypass_shift = clks->bypass_shift;
|
||||
|
||||
if (streq(clks->name, "cs_pdbg_clk"))
|
||||
init.ops = &dbgclk_ops;
|
||||
else
|
||||
init.ops = &agilex_gateclk_ops;
|
||||
|
||||
init.name = clks->name;
|
||||
init.flags = clks->flags;
|
||||
init.num_parents = clks->num_parents;
|
||||
init.parent_names = clks->parent_names;
|
||||
socfpga_clk->hw.hw.init = &init;
|
||||
hw_clk = &socfpga_clk->hw.hw;
|
||||
|
||||
ret = clk_hw_register(NULL, &socfpga_clk->hw.hw);
|
||||
if (ret) {
|
||||
kfree(socfpga_clk);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
return hw_clk;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -214,3 +214,44 @@ struct clk_hw *s10_register_cnt_periph(const struct stratix10_perip_cnt_clock *c
|
|||
}
|
||||
return hw_clk;
|
||||
}
|
||||
|
||||
struct clk_hw *agilex5_register_cnt_periph(const struct agilex5_perip_cnt_clock *clks,
|
||||
void __iomem *regbase)
|
||||
{
|
||||
struct clk_hw *hw_clk;
|
||||
struct socfpga_periph_clk *periph_clk;
|
||||
struct clk_init_data init;
|
||||
const char *name = clks->name;
|
||||
int ret;
|
||||
|
||||
periph_clk = kzalloc(sizeof(*periph_clk), GFP_KERNEL);
|
||||
if (WARN_ON(!periph_clk))
|
||||
return NULL;
|
||||
|
||||
if (clks->offset)
|
||||
periph_clk->hw.reg = regbase + clks->offset;
|
||||
else
|
||||
periph_clk->hw.reg = NULL;
|
||||
|
||||
if (clks->bypass_reg)
|
||||
periph_clk->bypass_reg = regbase + clks->bypass_reg;
|
||||
else
|
||||
periph_clk->bypass_reg = NULL;
|
||||
periph_clk->bypass_shift = clks->bypass_shift;
|
||||
periph_clk->fixed_div = clks->fixed_divider;
|
||||
|
||||
init.name = name;
|
||||
init.ops = &peri_cnt_clk_ops;
|
||||
init.flags = clks->flags;
|
||||
init.num_parents = clks->num_parents;
|
||||
init.parent_names = clks->parent_names;
|
||||
periph_clk->hw.hw.init = &init;
|
||||
hw_clk = &periph_clk->hw.hw;
|
||||
|
||||
ret = clk_hw_register(NULL, hw_clk);
|
||||
if (ret) {
|
||||
kfree(periph_clk);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
return hw_clk;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -304,3 +304,39 @@ struct clk_hw *n5x_register_pll(const struct stratix10_pll_clock *clks,
|
|||
}
|
||||
return hw_clk;
|
||||
}
|
||||
|
||||
struct clk_hw *agilex5_register_pll(const struct agilex5_pll_clock *clks,
|
||||
void __iomem *reg)
|
||||
{
|
||||
struct clk_hw *hw_clk;
|
||||
struct socfpga_pll *pll_clk;
|
||||
struct clk_init_data init;
|
||||
const char *name = clks->name;
|
||||
int ret;
|
||||
|
||||
pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL);
|
||||
if (WARN_ON(!pll_clk))
|
||||
return NULL;
|
||||
|
||||
pll_clk->hw.reg = reg + clks->offset;
|
||||
|
||||
if (streq(name, SOCFPGA_BOOT_CLK))
|
||||
init.ops = &clk_boot_ops;
|
||||
else
|
||||
init.ops = &agilex_clk_pll_ops;
|
||||
|
||||
init.name = name;
|
||||
init.flags = clks->flags;
|
||||
init.num_parents = clks->num_parents;
|
||||
init.parent_names = clks->parent_names;
|
||||
pll_clk->hw.hw.init = &init;
|
||||
pll_clk->hw.bit_idx = SOCFPGA_PLL_POWER;
|
||||
hw_clk = &pll_clk->hw.hw;
|
||||
|
||||
ret = clk_hw_register(NULL, hw_clk);
|
||||
if (ret) {
|
||||
kfree(pll_clk);
|
||||
return ERR_PTR(ret);
|
||||
}
|
||||
return hw_clk;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -73,12 +73,55 @@ struct stratix10_gate_clock {
|
|||
u8 fixed_div;
|
||||
};
|
||||
|
||||
struct agilex5_pll_clock {
|
||||
unsigned int id;
|
||||
const char *name;
|
||||
const char * const *parent_names;
|
||||
u8 num_parents;
|
||||
unsigned long flags;
|
||||
unsigned long offset;
|
||||
};
|
||||
|
||||
struct agilex5_perip_cnt_clock {
|
||||
unsigned int id;
|
||||
const char *name;
|
||||
const char * const *parent_names;
|
||||
u8 num_parents;
|
||||
unsigned long flags;
|
||||
unsigned long offset;
|
||||
u8 fixed_divider;
|
||||
unsigned long bypass_reg;
|
||||
unsigned long bypass_shift;
|
||||
};
|
||||
|
||||
struct agilex5_gate_clock {
|
||||
unsigned int id;
|
||||
const char *name;
|
||||
const char * const *parent_names;
|
||||
u8 num_parents;
|
||||
unsigned long flags;
|
||||
unsigned long gate_reg;
|
||||
u8 gate_idx;
|
||||
unsigned long div_reg;
|
||||
u8 div_offset;
|
||||
u8 div_width;
|
||||
unsigned long bypass_reg;
|
||||
u8 bypass_shift;
|
||||
u8 fixed_div;
|
||||
};
|
||||
|
||||
struct clk_hw *s10_register_pll(const struct stratix10_pll_clock *clks,
|
||||
void __iomem *reg);
|
||||
struct clk_hw *agilex_register_pll(const struct stratix10_pll_clock *clks,
|
||||
void __iomem *reg);
|
||||
struct clk_hw *n5x_register_pll(const struct stratix10_pll_clock *clks,
|
||||
void __iomem *reg);
|
||||
struct clk_hw *agilex5_register_pll(const struct agilex5_pll_clock *clks,
|
||||
void __iomem *reg);
|
||||
struct clk_hw *agilex5_register_cnt_periph(const struct agilex5_perip_cnt_clock *clks,
|
||||
void __iomem *regbase);
|
||||
struct clk_hw *agilex5_register_gate(const struct agilex5_gate_clock *clks,
|
||||
void __iomem *regbase);
|
||||
struct clk_hw *s10_register_periph(const struct stratix10_perip_c_clock *clks,
|
||||
void __iomem *reg);
|
||||
struct clk_hw *n5x_register_periph(const struct n5x_perip_c_clock *clks,
|
||||
|
|
|
|||
|
|
@ -1018,6 +1018,8 @@ static int spacemit_ccu_register(struct device *dev,
|
|||
if (!clk_data)
|
||||
return -ENOMEM;
|
||||
|
||||
clk_data->num = data->num;
|
||||
|
||||
for (i = 0; i < data->num; i++) {
|
||||
struct clk_hw *hw = data->hws[i];
|
||||
struct ccu_common *common;
|
||||
|
|
@ -1044,8 +1046,6 @@ static int spacemit_ccu_register(struct device *dev,
|
|||
clk_data->hws[i] = hw;
|
||||
}
|
||||
|
||||
clk_data->num = data->num;
|
||||
|
||||
ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_data);
|
||||
if (ret)
|
||||
dev_err(dev, "failed to add clock hardware provider (%d)\n", ret);
|
||||
|
|
|
|||
|
|
@ -220,4 +220,4 @@ extern const struct clk_ops spacemit_ccu_div_gate_ops;
|
|||
extern const struct clk_ops spacemit_ccu_mux_gate_ops;
|
||||
extern const struct clk_ops spacemit_ccu_mux_div_ops;
|
||||
extern const struct clk_ops spacemit_ccu_mux_div_gate_ops;
|
||||
#endif /* _CCU_DIV_H_ */
|
||||
#endif /* _CCU_MIX_H_ */
|
||||
|
|
|
|||
|
|
@ -2021,17 +2021,13 @@ MODULE_DEVICE_TABLE(of, sprd_sc9860_clk_ids);
|
|||
|
||||
static int sc9860_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct of_device_id *match;
|
||||
const struct sprd_clk_desc *desc;
|
||||
int ret;
|
||||
|
||||
match = of_match_node(sprd_sc9860_clk_ids, pdev->dev.of_node);
|
||||
if (!match) {
|
||||
pr_err("%s: of_match_node() failed", __func__);
|
||||
desc = device_get_match_data(&pdev->dev);
|
||||
if (!desc)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
desc = match->data;
|
||||
ret = sprd_clk_regmap_init(pdev, desc);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,10 @@
|
|||
#include "clkc.h"
|
||||
#include "reset.h"
|
||||
|
||||
/* Must be equal to the last clock/reset ID increased by one */
|
||||
#define CLKS_NR (TMPV770X_CLK_VIIFBS1_PROC + 1)
|
||||
#define RESETS_NR (TMPV770X_RESET_VIIFBS1_L1ISP + 1)
|
||||
|
||||
static DEFINE_SPINLOCK(tmpv770x_clk_lock);
|
||||
static DEFINE_SPINLOCK(tmpv770x_rst_lock);
|
||||
|
||||
|
|
@ -28,6 +32,10 @@ static const struct clk_parent_data pietherplls_parent_data[] = {
|
|||
{ .fw_name = "pietherpll", .name = "pietherpll", },
|
||||
};
|
||||
|
||||
static const struct clk_parent_data pidnnplls_parent_data[] = {
|
||||
{ .fw_name = "pidnnpll", .name = "pidnnpll", },
|
||||
};
|
||||
|
||||
static const struct visconti_fixed_clk fixed_clk_tables[] = {
|
||||
/* PLL1 */
|
||||
/* PICMPT0/1, PITSC, PIUWDT, PISWDT, PISBUS, PIPMU, PIGPMU, PITMU */
|
||||
|
|
@ -64,6 +72,41 @@ static const struct visconti_clk_gate_table pietherpll_clk_gate_tables[] = {
|
|||
TMPV770X_RESET_PIETHER_125M, },
|
||||
};
|
||||
|
||||
static const struct visconti_clk_gate_table pidnnpll_clk_gate_tables[] = {
|
||||
{ TMPV770X_CLK_VIIFBS0, "viifbs0",
|
||||
pidnnplls_parent_data, ARRAY_SIZE(pidnnplls_parent_data),
|
||||
0, 0x58, 0x158, 1, 1,
|
||||
NO_RESET, },
|
||||
{ TMPV770X_CLK_VIIFBS0_PROC, "viifbs0_proc",
|
||||
pidnnplls_parent_data, ARRAY_SIZE(pidnnplls_parent_data),
|
||||
0, 0x58, 0x158, 18, 1,
|
||||
NO_RESET, },
|
||||
{ TMPV770X_CLK_VIIFBS0_L1ISP, "viifbs0_l1isp",
|
||||
pidnnplls_parent_data, ARRAY_SIZE(pidnnplls_parent_data),
|
||||
0, 0x58, 0x158, 17, 1,
|
||||
NO_RESET, },
|
||||
{ TMPV770X_CLK_VIIFBS0_L2ISP, "viifbs0_l2isp",
|
||||
pidnnplls_parent_data, ARRAY_SIZE(pidnnplls_parent_data),
|
||||
0, 0x58, 0x158, 16, 1,
|
||||
NO_RESET, },
|
||||
{ TMPV770X_CLK_VIIFBS1, "viifbs1",
|
||||
pidnnplls_parent_data, ARRAY_SIZE(pidnnplls_parent_data),
|
||||
0, 0x58, 0x158, 5, 1,
|
||||
NO_RESET, },
|
||||
{ TMPV770X_CLK_VIIFBS1_PROC, "viifbs1_proc",
|
||||
pidnnplls_parent_data, ARRAY_SIZE(pidnnplls_parent_data),
|
||||
0, 0x58, 0x158, 22, 1,
|
||||
NO_RESET, },
|
||||
{ TMPV770X_CLK_VIIFBS1_L1ISP, "viifbs1_l1isp",
|
||||
pidnnplls_parent_data, ARRAY_SIZE(pidnnplls_parent_data),
|
||||
0, 0x58, 0x158, 21, 1,
|
||||
NO_RESET, },
|
||||
{ TMPV770X_CLK_VIIFBS1_L2ISP, "viifbs1_l2isp",
|
||||
pidnnplls_parent_data, ARRAY_SIZE(pidnnplls_parent_data),
|
||||
0, 0x58, 0x158, 20, 1,
|
||||
NO_RESET, },
|
||||
};
|
||||
|
||||
static const struct visconti_clk_gate_table clk_gate_tables[] = {
|
||||
{ TMPV770X_CLK_HOX, "hox",
|
||||
clks_parent_data, ARRAY_SIZE(clks_parent_data),
|
||||
|
|
@ -185,6 +228,22 @@ static const struct visconti_clk_gate_table clk_gate_tables[] = {
|
|||
clks_parent_data, ARRAY_SIZE(clks_parent_data),
|
||||
0, 0x14, 0x114, 0, 4,
|
||||
TMPV770X_RESET_SBUSCLK, },
|
||||
{ TMPV770X_CLK_VIIF0_CFGCLK, "csi2rx0cfg",
|
||||
clks_parent_data, ARRAY_SIZE(clks_parent_data),
|
||||
0, 0x58, 0x158, 0, 24,
|
||||
NO_RESET, },
|
||||
{ TMPV770X_CLK_VIIF0_APBCLK, "csi2rx0apb",
|
||||
clks_parent_data, ARRAY_SIZE(clks_parent_data),
|
||||
0, 0x58, 0x158, 2, 4,
|
||||
NO_RESET, },
|
||||
{ TMPV770X_CLK_VIIF1_CFGCLK, "csi2rx1cfg",
|
||||
clks_parent_data, ARRAY_SIZE(clks_parent_data),
|
||||
0, 0x58, 0x158, 4, 24,
|
||||
NO_RESET, },
|
||||
{ TMPV770X_CLK_VIIF1_APBCLK, "csi2rx1apb",
|
||||
clks_parent_data, ARRAY_SIZE(clks_parent_data),
|
||||
0, 0x58, 0x158, 6, 4,
|
||||
NO_RESET, },
|
||||
};
|
||||
|
||||
static const struct visconti_reset_data clk_reset_data[] = {
|
||||
|
|
@ -220,6 +279,14 @@ static const struct visconti_reset_data clk_reset_data[] = {
|
|||
[TMPV770X_RESET_PIPCMIF] = { 0x464, 0x564, 0, },
|
||||
[TMPV770X_RESET_PICKMON] = { 0x410, 0x510, 8, },
|
||||
[TMPV770X_RESET_SBUSCLK] = { 0x414, 0x514, 0, },
|
||||
[TMPV770X_RESET_VIIFBS0] = { 0x458, 0x558, 0, },
|
||||
[TMPV770X_RESET_VIIFBS0_APB] = { 0x458, 0x558, 1, },
|
||||
[TMPV770X_RESET_VIIFBS0_L2ISP] = { 0x458, 0x558, 16, },
|
||||
[TMPV770X_RESET_VIIFBS0_L1ISP] = { 0x458, 0x558, 17, },
|
||||
[TMPV770X_RESET_VIIFBS1] = { 0x458, 0x558, 4, },
|
||||
[TMPV770X_RESET_VIIFBS1_APB] = { 0x458, 0x558, 5, },
|
||||
[TMPV770X_RESET_VIIFBS1_L2ISP] = { 0x458, 0x558, 20, },
|
||||
[TMPV770X_RESET_VIIFBS1_L1ISP] = { 0x458, 0x558, 21, },
|
||||
};
|
||||
|
||||
static int visconti_clk_probe(struct platform_device *pdev)
|
||||
|
|
@ -234,12 +301,12 @@ static int visconti_clk_probe(struct platform_device *pdev)
|
|||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
|
||||
ctx = visconti_init_clk(dev, regmap, TMPV770X_NR_CLK);
|
||||
ctx = visconti_init_clk(dev, regmap, CLKS_NR);
|
||||
if (IS_ERR(ctx))
|
||||
return PTR_ERR(ctx);
|
||||
|
||||
ret = visconti_register_reset_controller(dev, regmap, clk_reset_data,
|
||||
TMPV770X_NR_RESET,
|
||||
RESETS_NR,
|
||||
&visconti_reset_ops,
|
||||
&tmpv770x_rst_lock);
|
||||
if (ret) {
|
||||
|
|
@ -272,6 +339,14 @@ static int visconti_clk_probe(struct platform_device *pdev)
|
|||
return ret;
|
||||
}
|
||||
|
||||
ret = visconti_clk_register_gates(ctx, pidnnpll_clk_gate_tables,
|
||||
ARRAY_SIZE(pidnnpll_clk_gate_tables),
|
||||
clk_reset_data, &tmpv770x_clk_lock);
|
||||
if (ret) {
|
||||
dev_err(dev, "Failed to register pidnnpll clock gate: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return of_clk_add_hw_provider(np, of_clk_hw_onecell_get, &ctx->clk_data);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@
|
|||
|
||||
#include "pll.h"
|
||||
|
||||
/* Must be equal to the last pll ID increased by one */
|
||||
#define PLLS_NR (TMPV770X_PLL_PIIMGERPLL + 1)
|
||||
|
||||
static DEFINE_SPINLOCK(tmpv770x_pll_lock);
|
||||
|
||||
static const struct visconti_pll_rate_table pipll0_rates[] __initconst = {
|
||||
|
|
@ -66,7 +69,7 @@ static void __init tmpv770x_setup_plls(struct device_node *np)
|
|||
if (!reg_base)
|
||||
return;
|
||||
|
||||
ctx = visconti_init_pll(np, reg_base, TMPV770X_NR_PLL);
|
||||
ctx = visconti_init_pll(np, reg_base, PLLS_NR);
|
||||
if (IS_ERR(ctx)) {
|
||||
iounmap(reg_base);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,6 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
|
||||
acpm-protocol-objs := exynos-acpm.o exynos-acpm-pmic.o
|
||||
acpm-protocol-objs := exynos-acpm.o
|
||||
acpm-protocol-objs += exynos-acpm-pmic.o
|
||||
acpm-protocol-objs += exynos-acpm-dvfs.o
|
||||
obj-$(CONFIG_EXYNOS_ACPM_PROTOCOL) += acpm-protocol.o
|
||||
|
|
|
|||
|
|
@ -0,0 +1,80 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright 2020 Samsung Electronics Co., Ltd.
|
||||
* Copyright 2020 Google LLC.
|
||||
* Copyright 2025 Linaro Ltd.
|
||||
*/
|
||||
|
||||
#include <linux/bitfield.h>
|
||||
#include <linux/firmware/samsung/exynos-acpm-protocol.h>
|
||||
#include <linux/ktime.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/units.h>
|
||||
|
||||
#include "exynos-acpm.h"
|
||||
#include "exynos-acpm-dvfs.h"
|
||||
|
||||
#define ACPM_DVFS_ID GENMASK(11, 0)
|
||||
#define ACPM_DVFS_REQ_TYPE GENMASK(15, 0)
|
||||
|
||||
#define ACPM_DVFS_FREQ_REQ 0
|
||||
#define ACPM_DVFS_FREQ_GET 1
|
||||
|
||||
static void acpm_dvfs_set_xfer(struct acpm_xfer *xfer, u32 *cmd, size_t cmdlen,
|
||||
unsigned int acpm_chan_id, bool response)
|
||||
{
|
||||
xfer->acpm_chan_id = acpm_chan_id;
|
||||
xfer->txd = cmd;
|
||||
xfer->txlen = cmdlen;
|
||||
|
||||
if (response) {
|
||||
xfer->rxd = cmd;
|
||||
xfer->rxlen = cmdlen;
|
||||
}
|
||||
}
|
||||
|
||||
static void acpm_dvfs_init_set_rate_cmd(u32 cmd[4], unsigned int clk_id,
|
||||
unsigned long rate)
|
||||
{
|
||||
cmd[0] = FIELD_PREP(ACPM_DVFS_ID, clk_id);
|
||||
cmd[1] = rate / HZ_PER_KHZ;
|
||||
cmd[2] = FIELD_PREP(ACPM_DVFS_REQ_TYPE, ACPM_DVFS_FREQ_REQ);
|
||||
cmd[3] = ktime_to_ms(ktime_get());
|
||||
}
|
||||
|
||||
int acpm_dvfs_set_rate(const struct acpm_handle *handle,
|
||||
unsigned int acpm_chan_id, unsigned int clk_id,
|
||||
unsigned long rate)
|
||||
{
|
||||
struct acpm_xfer xfer = {0};
|
||||
u32 cmd[4];
|
||||
|
||||
acpm_dvfs_init_set_rate_cmd(cmd, clk_id, rate);
|
||||
acpm_dvfs_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id, false);
|
||||
|
||||
return acpm_do_xfer(handle, &xfer);
|
||||
}
|
||||
|
||||
static void acpm_dvfs_init_get_rate_cmd(u32 cmd[4], unsigned int clk_id)
|
||||
{
|
||||
cmd[0] = FIELD_PREP(ACPM_DVFS_ID, clk_id);
|
||||
cmd[2] = FIELD_PREP(ACPM_DVFS_REQ_TYPE, ACPM_DVFS_FREQ_GET);
|
||||
cmd[3] = ktime_to_ms(ktime_get());
|
||||
}
|
||||
|
||||
unsigned long acpm_dvfs_get_rate(const struct acpm_handle *handle,
|
||||
unsigned int acpm_chan_id, unsigned int clk_id)
|
||||
{
|
||||
struct acpm_xfer xfer;
|
||||
unsigned int cmd[4] = {0};
|
||||
int ret;
|
||||
|
||||
acpm_dvfs_init_get_rate_cmd(cmd, clk_id);
|
||||
acpm_dvfs_set_xfer(&xfer, cmd, sizeof(cmd), acpm_chan_id, true);
|
||||
|
||||
ret = acpm_do_xfer(handle, &xfer);
|
||||
if (ret)
|
||||
return 0;
|
||||
|
||||
return xfer.rxd[1] * HZ_PER_KHZ;
|
||||
}
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright 2020 Samsung Electronics Co., Ltd.
|
||||
* Copyright 2020 Google LLC.
|
||||
* Copyright 2025 Linaro Ltd.
|
||||
*/
|
||||
#ifndef __EXYNOS_ACPM_DVFS_H__
|
||||
#define __EXYNOS_ACPM_DVFS_H__
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
struct acpm_handle;
|
||||
|
||||
int acpm_dvfs_set_rate(const struct acpm_handle *handle,
|
||||
unsigned int acpm_chan_id, unsigned int id,
|
||||
unsigned long rate);
|
||||
unsigned long acpm_dvfs_get_rate(const struct acpm_handle *handle,
|
||||
unsigned int acpm_chan_id,
|
||||
unsigned int clk_id);
|
||||
|
||||
#endif /* __EXYNOS_ACPM_DVFS_H__ */
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue