Merge branches 'clk-amlogic', 'clk-thead', 'clk-mediatek' and 'clk-samsung' into clk-next

* clk-amlogic:
  clk: meson: gxbb: use the existing HHI_HDMI_PLL_CNTL3 macro
  clk: meson: g12a: Limit the HDMI PLL OD to /4
  clk: meson: gxbb: Limit the HDMI PLL OD to /4 on GXL/GXM SoCs
  clk: amlogic: remove potentially unsafe flags from S4 video clocks
  clk: amlogic: add video-related clocks for S4 SoC
  dt-bindings: clock: add video clock indices for Amlogic S4 SoC
  clk: meson: t7: add t7 clock peripherals controller driver
  clk: meson: t7: add support for the T7 SoC PLL clock
  dt-bindings: clock: add Amlogic T7 peripherals clock controller
  dt-bindings: clock: add Amlogic T7 SCMI clock controller
  dt-bindings: clock: add Amlogic T7 PLL clock controller

* clk-thead:
  clk: thead: th1520-ap: Support CPU frequency scaling
  clk: thead: th1520-ap: Add macro to define multiplexers with flags
  clk: thead: th1520-ap: Support setting PLL rates
  clk: thead: th1520-ap: Add C910 bus clock
  clk: thead: th1520-ap: Poll for PLL lock and wait for stability
  dt-bindings: clock: thead,th1520-clk-ap: Add ID for C910 bus clock

* clk-mediatek:
  Revert "clk: Respect CLK_OPS_PARENT_ENABLE during recalc"
  clk: mediatek: Fix error handling in runtime PM setup
  clk: mediatek: don't select clk-mt8192 for all ARM64 builds
  clk: mediatek: Add mfg_eb as parent to mt8196 mfgpll clocks
  clk: mediatek: Refactor pllfh registration to pass device
  clk: mediatek: Pass device to clk_hw_register for PLLs
  clk: mediatek: Refactor pll registration to pass device
  clk: Respect CLK_OPS_PARENT_ENABLE during recalc
  dt-bindings: clock: mediatek,mt7622-pciesys: Remove syscon compatible
  clk: mediatek: Drop __initconst from gates

* clk-samsung:
  clk: samsung: gs101: add support for Display Process Unit (DPU) clocks
  dt-bindings: samsung: exynos-sysreg: add gs101 dpu compatible
  dt-bindings: clock: google,gs101-clock: Add DPU clock management unit
  dt-bindings: clock: google,gs101-clock: fix alphanumeric ordering
  clk: samsung: fix sysreg save/restore when PM is enabled for CMU
  clk: samsung: avoid warning message on legacy Exynos (auto clock gating)
  clk: samsung: gs101: Enable auto_clock_gate mode for each gs101 CMU
  clk: samsung: Implement automatic clock gating mode for CMUs
  dt-bindings: clock: google,gs101-clock: add samsung,sysreg property as required
  clk: samsung: exynosautov920: add clock support
  dt-bindings: clock: exynosautov920: add MFD clock definitions
This commit is contained in:
Stephen Boyd 2026-02-14 10:23:37 -08:00
No known key found for this signature in database
GPG Key ID: AD028897C6E49525
67 changed files with 4426 additions and 145 deletions

View File

@ -0,0 +1,116 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
# Copyright (C) 2024-2025 Amlogic, Inc. All rights reserved
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/amlogic,t7-peripherals-clkc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Amlogic T7 Peripherals Clock Controller
maintainers:
- Neil Armstrong <neil.armstrong@linaro.org>
- Jerome Brunet <jbrunet@baylibre.com>
- Xianwei Zhao <xianwei.zhao@amlogic.com>
- Jian Hu <jian.hu@amlogic.com>
properties:
compatible:
const: amlogic,t7-peripherals-clkc
reg:
maxItems: 1
'#clock-cells':
const: 1
clocks:
minItems: 14
items:
- description: input oscillator
- description: input sys clk
- description: input fixed pll
- description: input fclk div 2
- description: input fclk div 2p5
- description: input fclk div 3
- description: input fclk div 4
- description: input fclk div 5
- description: input fclk div 7
- description: input hifi pll
- description: input gp0 pll
- description: input gp1 pll
- description: input mpll1
- description: input mpll2
- description: external input rmii oscillator (optional)
- description: input video pll0 (optional)
- description: external pad input for rtc (optional)
clock-names:
minItems: 14
items:
- const: xtal
- const: sys
- const: fix
- const: fdiv2
- const: fdiv2p5
- const: fdiv3
- const: fdiv4
- const: fdiv5
- const: fdiv7
- const: hifi
- const: gp0
- const: gp1
- const: mpll1
- const: mpll2
- const: ext_rmii
- const: vid_pll0
- const: ext_rtc
required:
- compatible
- '#clock-cells'
- reg
- clocks
- clock-names
additionalProperties: false
examples:
- |
apb {
#address-cells = <2>;
#size-cells = <2>;
clkc_periphs:clock-controller@0 {
compatible = "amlogic,t7-peripherals-clkc";
reg = <0 0x0 0 0x1c8>;
#clock-cells = <1>;
clocks = <&xtal>,
<&scmi_clk 13>,
<&scmi_clk 16>,
<&scmi_clk 18>,
<&scmi_clk 20>,
<&scmi_clk 22>,
<&scmi_clk 24>,
<&scmi_clk 26>,
<&scmi_clk 28>,
<&hifi 1>,
<&gp0 1>,
<&gp1 1>,
<&mpll 4>,
<&mpll 6>;
clock-names = "xtal",
"sys",
"fix",
"fdiv2",
"fdiv2p5",
"fdiv3",
"fdiv4",
"fdiv5",
"fdiv7",
"hifi",
"gp0",
"gp1",
"mpll1",
"mpll2";
};
};

View File

@ -0,0 +1,114 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
# Copyright (C) 2024-2025 Amlogic, Inc. All rights reserved
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/amlogic,t7-pll-clkc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Amlogic T7 PLL Clock Control Controller
maintainers:
- Neil Armstrong <neil.armstrong@linaro.org>
- Jerome Brunet <jbrunet@baylibre.com>
- Jian Hu <jian.hu@amlogic.com>
- Xianwei Zhao <xianwei.zhao@amlogic.com>
properties:
compatible:
enum:
- amlogic,t7-gp0-pll
- amlogic,t7-gp1-pll
- amlogic,t7-hifi-pll
- amlogic,t7-pcie-pll
- amlogic,t7-mpll
- amlogic,t7-hdmi-pll
- amlogic,t7-mclk-pll
reg:
maxItems: 1
'#clock-cells':
const: 1
clocks:
items:
- description: mclk pll input oscillator gate
- description: oscillator input clock source for mclk_sel_0
- description: fixed input clock source for mclk_sel_0
minItems: 1
clock-names:
items:
- const: in0
- const: in1
- const: in2
minItems: 1
required:
- compatible
- '#clock-cells'
- reg
- clocks
- clock-names
allOf:
- if:
properties:
compatible:
contains:
const: amlogic,t7-mclk-pll
then:
properties:
clocks:
minItems: 3
clock-names:
minItems: 3
- if:
properties:
compatible:
contains:
enum:
- amlogic,t7-gp0-pll
- amlogic,t7-gp1--pll
- amlogic,t7-hifi-pll
- amlogic,t7-pcie-pll
- amlogic,t7-mpll
- amlogic,t7-hdmi-pll
then:
properties:
clocks:
maxItems: 1
clock-names:
maxItems: 1
additionalProperties: false
examples:
- |
apb {
#address-cells = <2>;
#size-cells = <2>;
clock-controller@8080 {
compatible = "amlogic,t7-gp0-pll";
reg = <0 0x8080 0 0x20>;
clocks = <&scmi_clk 2>;
clock-names = "in0";
#clock-cells = <1>;
};
clock-controller@8300 {
compatible = "amlogic,t7-mclk-pll";
reg = <0 0x8300 0 0x18>;
clocks = <&scmi_clk 2>,
<&xtal>,
<&scmi_clk 31>;
clock-names = "in0", "in1", "in2";
#clock-cells = <1>;
};
};

View File

@ -29,9 +29,10 @@ properties:
enum:
- google,gs101-cmu-top
- google,gs101-cmu-apm
- google,gs101-cmu-misc
- google,gs101-cmu-dpu
- google,gs101-cmu-hsi0
- google,gs101-cmu-hsi2
- google,gs101-cmu-misc
- google,gs101-cmu-peric0
- google,gs101-cmu-peric1
@ -52,6 +53,11 @@ properties:
reg:
maxItems: 1
samsung,sysreg:
$ref: /schemas/types.yaml#/definitions/phandle
description:
Phandle to system registers interface.
required:
- compatible
- "#clock-cells"
@ -77,6 +83,24 @@ allOf:
items:
- const: oscclk
- if:
properties:
compatible:
contains:
const: google,gs101-cmu-dpu
then:
properties:
clocks:
items:
- description: External reference clock (24.576 MHz)
- description: DPU bus clock (from CMU_TOP)
clock-names:
items:
- const: oscclk
- const: bus
- if:
properties:
compatible:
@ -166,6 +190,18 @@ allOf:
- const: bus
- const: ip
- if:
properties:
compatible:
contains:
const: google,gs101-cmu-top
then:
properties:
samsung,sysreg: false
else:
required:
- samsung,sysreg
additionalProperties: false
examples:
@ -175,7 +211,7 @@ examples:
cmu_top: clock-controller@1e080000 {
compatible = "google,gs101-cmu-top";
reg = <0x1e080000 0x8000>;
reg = <0x1e080000 0x10000>;
#clock-cells = <1>;
clocks = <&ext_24_5m>;
clock-names = "oscclk";

View File

@ -14,11 +14,9 @@ maintainers:
properties:
compatible:
oneOf:
- items:
- const: mediatek,mt7622-pciesys
- const: syscon
- const: mediatek,mt7629-pciesys
enum:
- mediatek,mt7622-pciesys
- mediatek,mt7629-pciesys
reg:
maxItems: 1
@ -40,7 +38,7 @@ additionalProperties: false
examples:
- |
clock-controller@1a100800 {
compatible = "mediatek,mt7622-pciesys", "syscon";
compatible = "mediatek,mt7622-pciesys";
reg = <0x1a100800 0x1000>;
#clock-cells = <1>;
#reset-cells = <1>;

View File

@ -40,6 +40,7 @@ properties:
- samsung,exynosautov920-cmu-hsi2
- samsung,exynosautov920-cmu-m2m
- samsung,exynosautov920-cmu-mfc
- samsung,exynosautov920-cmu-mfd
- samsung,exynosautov920-cmu-misc
- samsung,exynosautov920-cmu-peric0
- samsung,exynosautov920-cmu-peric1
@ -268,6 +269,24 @@ allOf:
- const: mfc
- const: wfd
- if:
properties:
compatible:
contains:
const: samsung,exynosautov920-cmu-mfd
then:
properties:
clocks:
items:
- description: External reference clock (38.4 MHz)
- description: CMU_MFD NOC clock (from CMU_TOP)
clock-names:
items:
- const: oscclk
- const: noc
required:
- compatible
- "#clock-cells"

View File

@ -15,6 +15,7 @@ properties:
- items:
- enum:
- google,gs101-apm-sysreg
- google,gs101-dpu-sysreg
- google,gs101-hsi0-sysreg
- google,gs101-hsi2-sysreg
- google,gs101-misc-sysreg
@ -92,6 +93,7 @@ allOf:
compatible:
contains:
enum:
- google,gs101-dpu-sysreg
- google,gs101-hsi0-sysreg
- google,gs101-hsi2-sysreg
- google,gs101-misc-sysreg

View File

@ -820,7 +820,7 @@ config COMMON_CLK_MT8192
depends on ARM64 || COMPILE_TEST
select COMMON_CLK_MEDIATEK
select COMMON_CLK_MEDIATEK_FHCTL
default ARM64
default ARM64 && ARCH_MEDIATEK
help
This driver supports MediaTek MT8192 basic clocks.

View File

@ -978,7 +978,7 @@ static int mtk_apmixedsys_init(struct platform_device *pdev)
if (!clk_data)
return -ENOMEM;
mtk_clk_register_plls(node, apmixed_plls, ARRAY_SIZE(apmixed_plls),
mtk_clk_register_plls(&pdev->dev, apmixed_plls, ARRAY_SIZE(apmixed_plls),
clk_data);
mtk_clk_register_factors(apmixed_fixed_divs, ARRAY_SIZE(apmixed_fixed_divs),
clk_data);

View File

@ -119,7 +119,7 @@ static int clk_mt2712_apmixed_probe(struct platform_device *pdev)
if (!clk_data)
return -ENOMEM;
r = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
r = mtk_clk_register_plls(&pdev->dev, plls, ARRAY_SIZE(plls), clk_data);
if (r)
goto free_clk_data;

View File

@ -93,8 +93,8 @@ static int clk_mt6735_apmixed_probe(struct platform_device *pdev)
return -ENOMEM;
platform_set_drvdata(pdev, clk_data);
ret = mtk_clk_register_plls(pdev->dev.of_node, apmixedsys_plls,
ARRAY_SIZE(apmixedsys_plls), clk_data);
ret = mtk_clk_register_plls(&pdev->dev, apmixedsys_plls,
ARRAY_SIZE(apmixedsys_plls), clk_data);
if (ret) {
dev_err(&pdev->dev, "Failed to register PLLs: %d\n", ret);
return ret;

View File

@ -740,7 +740,7 @@ static int clk_mt6765_apmixed_probe(struct platform_device *pdev)
if (!clk_data)
return -ENOMEM;
mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
mtk_clk_register_plls(&pdev->dev, plls, ARRAY_SIZE(plls), clk_data);
mtk_clk_register_gates(&pdev->dev, node, apmixed_clks,
ARRAY_SIZE(apmixed_clks), clk_data);

View File

@ -1220,7 +1220,7 @@ static int clk_mt6779_apmixed_probe(struct platform_device *pdev)
if (!clk_data)
return -ENOMEM;
mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
mtk_clk_register_plls(&pdev->dev, plls, ARRAY_SIZE(plls), clk_data);
mtk_clk_register_gates(&pdev->dev, node, apmixed_clks,
ARRAY_SIZE(apmixed_clks), clk_data);

View File

@ -152,7 +152,7 @@ static int clk_mt6795_apmixed_probe(struct platform_device *pdev)
return -ENOMEM;
fhctl_parse_dt(fhctl_node, pllfhs, ARRAY_SIZE(pllfhs));
ret = mtk_clk_register_pllfhs(node, plls, ARRAY_SIZE(plls),
ret = mtk_clk_register_pllfhs(dev, plls, ARRAY_SIZE(plls),
pllfhs, ARRAY_SIZE(pllfhs), clk_data);
if (ret)
goto free_clk_data;

View File

@ -655,7 +655,7 @@ static int mtk_apmixedsys_init(struct platform_device *pdev)
if (!clk_data)
return -ENOMEM;
mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
mtk_clk_register_plls(&pdev->dev, plls, ARRAY_SIZE(plls), clk_data);
return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
}

View File

@ -96,7 +96,7 @@ static int clk_mt7622_apmixed_probe(struct platform_device *pdev)
if (!clk_data)
return -ENOMEM;
ret = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
ret = mtk_clk_register_plls(dev, plls, ARRAY_SIZE(plls), clk_data);
if (ret)
return ret;

View File

@ -634,7 +634,7 @@ static int mtk_apmixedsys_init(struct platform_device *pdev)
if (!clk_data)
return -ENOMEM;
mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls),
mtk_clk_register_plls(&pdev->dev, plls, ARRAY_SIZE(plls),
clk_data);
mtk_clk_register_gates(&pdev->dev, node, apmixed_clks,

View File

@ -76,7 +76,7 @@ static int clk_mt7981_apmixed_probe(struct platform_device *pdev)
if (!clk_data)
return -ENOMEM;
mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
mtk_clk_register_plls(&pdev->dev, plls, ARRAY_SIZE(plls), clk_data);
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
if (r) {

View File

@ -31,7 +31,7 @@ static const struct mtk_gate_regs sgmii0_cg_regs = {
.ops = &mtk_clk_gate_ops_no_setclr_inv, \
}
static const struct mtk_gate sgmii0_clks[] __initconst = {
static const struct mtk_gate sgmii0_clks[] = {
GATE_SGMII0(CLK_SGM0_TX_EN, "sgm0_tx_en", "usb_tx250m", 2),
GATE_SGMII0(CLK_SGM0_RX_EN, "sgm0_rx_en", "usb_eq_rx250m", 3),
GATE_SGMII0(CLK_SGM0_CK0_EN, "sgm0_ck0_en", "usb_ln0", 4),
@ -53,7 +53,7 @@ static const struct mtk_gate_regs sgmii1_cg_regs = {
.ops = &mtk_clk_gate_ops_no_setclr_inv, \
}
static const struct mtk_gate sgmii1_clks[] __initconst = {
static const struct mtk_gate sgmii1_clks[] = {
GATE_SGMII1(CLK_SGM1_TX_EN, "sgm1_tx_en", "usb_tx250m", 2),
GATE_SGMII1(CLK_SGM1_RX_EN, "sgm1_rx_en", "usb_eq_rx250m", 3),
GATE_SGMII1(CLK_SGM1_CK1_EN, "sgm1_ck1_en", "usb_ln0", 4),
@ -75,7 +75,7 @@ static const struct mtk_gate_regs eth_cg_regs = {
.ops = &mtk_clk_gate_ops_no_setclr_inv, \
}
static const struct mtk_gate eth_clks[] __initconst = {
static const struct mtk_gate eth_clks[] = {
GATE_ETH(CLK_ETH_FE_EN, "eth_fe_en", "netsys_2x", 6),
GATE_ETH(CLK_ETH_GP2_EN, "eth_gp2_en", "sgm_325m", 7),
GATE_ETH(CLK_ETH_GP1_EN, "eth_gp1_en", "sgm_325m", 8),

View File

@ -74,7 +74,7 @@ static int clk_mt7986_apmixed_probe(struct platform_device *pdev)
if (!clk_data)
return -ENOMEM;
mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
mtk_clk_register_plls(&pdev->dev, plls, ARRAY_SIZE(plls), clk_data);
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
if (r) {

View File

@ -86,7 +86,7 @@ static int clk_mt7988_apmixed_probe(struct platform_device *pdev)
if (!clk_data)
return -ENOMEM;
r = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
r = mtk_clk_register_plls(&pdev->dev, plls, ARRAY_SIZE(plls), clk_data);
if (r)
goto free_apmixed_data;

View File

@ -57,7 +57,8 @@ static int clk_mt8135_apmixed_probe(struct platform_device *pdev)
if (!clk_data)
return -ENOMEM;
ret = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
ret = mtk_clk_register_plls(&pdev->dev, plls, ARRAY_SIZE(plls),
clk_data);
if (ret)
goto free_clk_data;

View File

@ -105,7 +105,7 @@ static int clk_mt8167_apmixed_probe(struct platform_device *pdev)
if (!clk_data)
return -ENOMEM;
ret = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
ret = mtk_clk_register_plls(dev, plls, ARRAY_SIZE(plls), clk_data);
if (ret)
return ret;

View File

@ -140,13 +140,13 @@ MODULE_DEVICE_TABLE(of, of_match_clk_mt8173_apmixed);
static int clk_mt8173_apmixed_probe(struct platform_device *pdev)
{
const u8 *fhctl_node = "mediatek,mt8173-fhctl";
struct device_node *node = pdev->dev.of_node;
struct clk_hw_onecell_data *clk_data;
struct device *dev = &pdev->dev;
void __iomem *base;
struct clk_hw *hw;
int r;
base = of_iomap(node, 0);
base = of_iomap(dev->of_node, 0);
if (!base)
return -ENOMEM;
@ -157,25 +157,25 @@ static int clk_mt8173_apmixed_probe(struct platform_device *pdev)
}
fhctl_parse_dt(fhctl_node, pllfhs, ARRAY_SIZE(pllfhs));
r = mtk_clk_register_pllfhs(node, plls, ARRAY_SIZE(plls),
pllfhs, ARRAY_SIZE(pllfhs), clk_data);
r = mtk_clk_register_pllfhs(dev, plls, ARRAY_SIZE(plls), pllfhs,
ARRAY_SIZE(pllfhs), clk_data);
if (r)
goto free_clk_data;
hw = mtk_clk_register_ref2usb_tx("ref2usb_tx", "clk26m", base + REGOFF_REF2USB);
if (IS_ERR(hw)) {
r = PTR_ERR(hw);
dev_err(&pdev->dev, "Failed to register ref2usb_tx: %d\n", r);
dev_err(dev, "Failed to register ref2usb_tx: %d\n", r);
goto unregister_plls;
}
clk_data->hws[CLK_APMIXED_REF2USB_TX] = hw;
hw = devm_clk_hw_register_divider(&pdev->dev, "hdmi_ref", "tvdpll_594m", 0,
hw = devm_clk_hw_register_divider(dev, "hdmi_ref", "tvdpll_594m", 0,
base + REGOFF_HDMI_REF, 16, 3,
CLK_DIVIDER_POWER_OF_TWO, NULL);
clk_data->hws[CLK_APMIXED_HDMI_REF] = hw;
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
r = of_clk_add_hw_provider(dev->of_node, of_clk_hw_onecell_get, clk_data);
if (r)
goto unregister_ref2usb;

View File

@ -155,7 +155,7 @@ static int clk_mt8183_apmixed_probe(struct platform_device *pdev)
if (!clk_data)
return -ENOMEM;
ret = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
ret = mtk_clk_register_plls(dev, plls, ARRAY_SIZE(plls), clk_data);
if (ret)
return ret;

View File

@ -151,7 +151,7 @@ static int clk_mt8186_apmixed_probe(struct platform_device *pdev)
fhctl_parse_dt(fhctl_node, pllfhs, ARRAY_SIZE(pllfhs));
r = mtk_clk_register_pllfhs(node, plls, ARRAY_SIZE(plls),
r = mtk_clk_register_pllfhs(&pdev->dev, plls, ARRAY_SIZE(plls),
pllfhs, ARRAY_SIZE(pllfhs), clk_data);
if (r)
goto free_apmixed_data;

View File

@ -106,7 +106,7 @@ static int clk_mt8188_apmixed_probe(struct platform_device *pdev)
if (!clk_data)
return -ENOMEM;
r = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
r = mtk_clk_register_plls(&pdev->dev, plls, ARRAY_SIZE(plls), clk_data);
if (r)
goto free_apmixed_data;

View File

@ -162,7 +162,7 @@ static int clk_mt8192_apmixed_probe(struct platform_device *pdev)
fhctl_parse_dt(fhctl_node, pllfhs, ARRAY_SIZE(pllfhs));
r = mtk_clk_register_pllfhs(node, plls, ARRAY_SIZE(plls),
r = mtk_clk_register_pllfhs(&pdev->dev, plls, ARRAY_SIZE(plls),
pllfhs, ARRAY_SIZE(pllfhs), clk_data);
if (r)
goto free_clk_data;

View File

@ -181,7 +181,7 @@ static int clk_mt8195_apmixed_probe(struct platform_device *pdev)
fhctl_parse_dt(fhctl_node, pllfhs, ARRAY_SIZE(pllfhs));
r = mtk_clk_register_pllfhs(node, plls, ARRAY_SIZE(plls),
r = mtk_clk_register_pllfhs(&pdev->dev, plls, ARRAY_SIZE(plls),
pllfhs, ARRAY_SIZE(pllfhs), clk_data);
if (r)
goto free_apmixed_data;

View File

@ -66,7 +66,8 @@ static int clk_mt8195_apusys_pll_probe(struct platform_device *pdev)
if (!clk_data)
return -ENOMEM;
r = mtk_clk_register_plls(node, apusys_plls, ARRAY_SIZE(apusys_plls), clk_data);
r = mtk_clk_register_plls(&pdev->dev, apusys_plls,
ARRAY_SIZE(apusys_plls), clk_data);
if (r)
goto free_apusys_pll_data;

View File

@ -152,7 +152,8 @@ static int clk_mt8196_apmixed_probe(struct platform_device *pdev)
if (!clk_data)
return -ENOMEM;
r = mtk_clk_register_plls(node, mcd->clks, mcd->num_clks, clk_data);
r = mtk_clk_register_plls(&pdev->dev, mcd->clks, mcd->num_clks,
clk_data);
if (r)
goto free_apmixed_data;

View File

@ -122,7 +122,7 @@ static int clk_mt8196_mcu_probe(struct platform_device *pdev)
if (!clk_data)
return -ENOMEM;
r = mtk_clk_register_plls(node, plls, num_plls, clk_data);
r = mtk_clk_register_plls(&pdev->dev, plls, num_plls, clk_data);
if (r)
goto free_clk_data;

View File

@ -58,24 +58,25 @@
.pcw_shift = _pcw_shift, \
.pcwbits = _pcwbits, \
.pcwibits = MT8196_INTEGER_BITS, \
.parent_name = "mfg_eb", \
}
static const struct mtk_pll_data mfg_ao_plls[] = {
PLL(CLK_MFG_AO_MFGPLL, "mfgpll", MFGPLL_CON0, MFGPLL_CON0, 0, 0, 0,
BIT(0), MFGPLL_CON1, 24, 0, 0, 0,
PLL(CLK_MFG_AO_MFGPLL, "mfgpll", MFGPLL_CON0, MFGPLL_CON0, 0, 0,
PLL_PARENT_EN, BIT(0), MFGPLL_CON1, 24, 0, 0, 0,
MFGPLL_CON1, 0, 22),
};
static const struct mtk_pll_data mfgsc0_ao_plls[] = {
PLL(CLK_MFGSC0_AO_MFGPLL_SC0, "mfgpll-sc0", MFGPLL_SC0_CON0,
MFGPLL_SC0_CON0, 0, 0, 0, BIT(0), MFGPLL_SC0_CON1, 24, 0, 0, 0,
MFGPLL_SC0_CON1, 0, 22),
MFGPLL_SC0_CON0, 0, 0, PLL_PARENT_EN, BIT(0), MFGPLL_SC0_CON1, 24,
0, 0, 0, MFGPLL_SC0_CON1, 0, 22),
};
static const struct mtk_pll_data mfgsc1_ao_plls[] = {
PLL(CLK_MFGSC1_AO_MFGPLL_SC1, "mfgpll-sc1", MFGPLL_SC1_CON0,
MFGPLL_SC1_CON0, 0, 0, 0, BIT(0), MFGPLL_SC1_CON1, 24, 0, 0, 0,
MFGPLL_SC1_CON1, 0, 22),
MFGPLL_SC1_CON0, 0, 0, PLL_PARENT_EN, BIT(0), MFGPLL_SC1_CON1, 24,
0, 0, 0, MFGPLL_SC1_CON1, 0, 22),
};
static const struct of_device_id of_match_clk_mt8196_mfg[] = {
@ -105,7 +106,7 @@ static int clk_mt8196_mfg_probe(struct platform_device *pdev)
if (!clk_data)
return -ENOMEM;
r = mtk_clk_register_plls(node, plls, num_plls, clk_data);
r = mtk_clk_register_plls(&pdev->dev, plls, num_plls, clk_data);
if (r)
goto free_clk_data;

View File

@ -664,7 +664,7 @@ static int clk_mt8196_vlp_probe(struct platform_device *pdev)
if (r)
goto unregister_factors;
r = mtk_clk_register_plls(node, vlp_plls, ARRAY_SIZE(vlp_plls),
r = mtk_clk_register_plls(dev, vlp_plls, ARRAY_SIZE(vlp_plls),
clk_data);
if (r)
goto unregister_muxes;

View File

@ -133,7 +133,7 @@ static int clk_mt8365_apmixed_probe(struct platform_device *pdev)
return PTR_ERR(hw);
clk_data->hws[CLK_APMIXED_USB20_EN] = hw;
ret = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
ret = mtk_clk_register_plls(dev, plls, ARRAY_SIZE(plls), clk_data);
if (ret)
return ret;

View File

@ -87,7 +87,7 @@ static int clk_mt8516_apmixed_probe(struct platform_device *pdev)
if (!clk_data)
return -ENOMEM;
ret = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
ret = mtk_clk_register_plls(dev, plls, ARRAY_SIZE(plls), clk_data);
if (ret)
return ret;

View File

@ -544,7 +544,7 @@ static const struct mtk_gate_regs top5_cg_regs = {
#define GATE_TOP5(_id, _name, _parent, _shift) \
GATE_MTK(_id, _name, _parent, &top5_cg_regs, _shift, &mtk_clk_gate_ops_setclr)
static const struct mtk_gate top_clks[] __initconst = {
static const struct mtk_gate top_clks[] = {
/* TOP1 */
GATE_TOP1(CLK_TOP_THEM, "them", "ahb_infra_sel", 1),
GATE_TOP1(CLK_TOP_APDMA, "apdma", "ahb_infra_sel", 2),

View File

@ -497,14 +497,16 @@ static int __mtk_clk_simple_probe(struct platform_device *pdev,
if (mcd->need_runtime_pm) {
devm_pm_runtime_enable(&pdev->dev);
r = devm_pm_runtime_enable(&pdev->dev);
if (r)
goto unmap_io;
/*
* Do a pm_runtime_resume_and_get() to workaround a possible
* deadlock between clk_register() and the genpd framework.
*/
r = pm_runtime_resume_and_get(&pdev->dev);
if (r)
return r;
goto unmap_io;
}
/* Calculate how many clk_hw_onecell_data entries to allocate */
@ -618,11 +620,11 @@ static int __mtk_clk_simple_probe(struct platform_device *pdev,
free_data:
mtk_free_clk_data(clk_data);
free_base:
if (mcd->shared_io && base)
iounmap(base);
if (mcd->need_runtime_pm)
pm_runtime_put(&pdev->dev);
unmap_io:
if (mcd->shared_io && base)
iounmap(base);
return r;
}

View File

@ -11,6 +11,7 @@
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of_address.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include "clk-pll.h"
@ -358,6 +359,9 @@ struct clk_hw *mtk_clk_register_pll_ops(struct mtk_clk_pll *pll,
init.name = data->name;
init.flags = (data->flags & PLL_AO) ? CLK_IS_CRITICAL : 0;
if (data->flags & PLL_PARENT_EN)
init.flags |= CLK_OPS_PARENT_ENABLE;
init.ops = pll_ops;
if (data->parent_name)
init.parent_names = &data->parent_name;
@ -365,7 +369,7 @@ struct clk_hw *mtk_clk_register_pll_ops(struct mtk_clk_pll *pll,
init.parent_names = &parent_name;
init.num_parents = 1;
ret = clk_hw_register(NULL, &pll->hw);
ret = clk_hw_register(pll->dev, &pll->hw);
if (ret)
return ERR_PTR(ret);
@ -373,7 +377,8 @@ struct clk_hw *mtk_clk_register_pll_ops(struct mtk_clk_pll *pll,
return &pll->hw;
}
struct clk_hw *mtk_clk_register_pll(const struct mtk_pll_data *data,
struct clk_hw *mtk_clk_register_pll(struct device *dev,
const struct mtk_pll_data *data,
void __iomem *base)
{
struct mtk_clk_pll *pll;
@ -384,6 +389,8 @@ struct clk_hw *mtk_clk_register_pll(const struct mtk_pll_data *data,
if (!pll)
return ERR_PTR(-ENOMEM);
pll->dev = dev;
hw = mtk_clk_register_pll_ops(pll, data, base, pll_ops);
if (IS_ERR(hw))
kfree(pll);
@ -404,7 +411,7 @@ void mtk_clk_unregister_pll(struct clk_hw *hw)
kfree(pll);
}
int mtk_clk_register_plls(struct device_node *node,
int mtk_clk_register_plls(struct device *dev,
const struct mtk_pll_data *plls, int num_plls,
struct clk_hw_onecell_data *clk_data)
{
@ -412,7 +419,7 @@ int mtk_clk_register_plls(struct device_node *node,
int i;
struct clk_hw *hw;
base = of_iomap(node, 0);
base = of_iomap(dev->of_node, 0);
if (!base) {
pr_err("%s(): ioremap failed\n", __func__);
return -EINVAL;
@ -423,11 +430,11 @@ int mtk_clk_register_plls(struct device_node *node,
if (!IS_ERR_OR_NULL(clk_data->hws[pll->id])) {
pr_warn("%pOF: Trying to register duplicate clock ID: %d\n",
node, pll->id);
dev->of_node, pll->id);
continue;
}
hw = mtk_clk_register_pll(pll, base);
hw = mtk_clk_register_pll(dev, pll, base);
if (IS_ERR(hw)) {
pr_err("Failed to register clk %s: %pe\n", pll->name,

View File

@ -10,9 +10,7 @@
#include <linux/clk-provider.h>
#include <linux/types.h>
struct clk_ops;
struct clk_hw_onecell_data;
struct device_node;
struct device;
struct mtk_pll_div_table {
u32 div;
@ -21,6 +19,7 @@ struct mtk_pll_div_table {
#define HAVE_RST_BAR BIT(0)
#define PLL_AO BIT(1)
#define PLL_PARENT_EN BIT(2)
#define POSTDIV_MASK GENMASK(2, 0)
struct mtk_pll_data {
@ -63,6 +62,7 @@ struct mtk_pll_data {
*/
struct mtk_clk_pll {
struct device *dev;
struct clk_hw hw;
void __iomem *base_addr;
void __iomem *pd_addr;
@ -78,9 +78,9 @@ struct mtk_clk_pll {
const struct mtk_pll_data *data;
};
int mtk_clk_register_plls(struct device_node *node,
const struct mtk_pll_data *plls, int num_plls,
struct clk_hw_onecell_data *clk_data);
int mtk_clk_register_plls(struct device *dev, const struct mtk_pll_data *plls,
int num_plls, struct clk_hw_onecell_data *clk_data);
void mtk_clk_unregister_plls(const struct mtk_pll_data *plls, int num_plls,
struct clk_hw_onecell_data *clk_data);
@ -110,7 +110,8 @@ struct clk_hw *mtk_clk_register_pll_ops(struct mtk_clk_pll *pll,
const struct mtk_pll_data *data,
void __iomem *base,
const struct clk_ops *pll_ops);
struct clk_hw *mtk_clk_register_pll(const struct mtk_pll_data *data,
struct clk_hw *mtk_clk_register_pll(struct device *dev,
const struct mtk_pll_data *data,
void __iomem *base);
void mtk_clk_unregister_pll(struct clk_hw *hw);

View File

@ -10,6 +10,7 @@
#include <linux/slab.h>
#include <linux/clkdev.h>
#include <linux/delay.h>
#include <linux/device.h>
#include "clk-mtk.h"
#include "clk-pllfh.h"
@ -149,7 +150,7 @@ static bool fhctl_is_supported_and_enabled(const struct mtk_pllfh_data *pllfh)
}
static struct clk_hw *
mtk_clk_register_pllfh(const struct mtk_pll_data *pll_data,
mtk_clk_register_pllfh(struct device *dev, const struct mtk_pll_data *pll_data,
struct mtk_pllfh_data *pllfh_data, void __iomem *base)
{
struct clk_hw *hw;
@ -166,6 +167,8 @@ mtk_clk_register_pllfh(const struct mtk_pll_data *pll_data,
goto out;
}
fh->clk_pll.dev = dev;
hw = mtk_clk_register_pll_ops(&fh->clk_pll, pll_data, base,
&mtk_pllfh_ops);
@ -194,7 +197,7 @@ static void mtk_clk_unregister_pllfh(struct clk_hw *hw)
kfree(fh);
}
int mtk_clk_register_pllfhs(struct device_node *node,
int mtk_clk_register_pllfhs(struct device *dev,
const struct mtk_pll_data *plls, int num_plls,
struct mtk_pllfh_data *pllfhs, int num_fhs,
struct clk_hw_onecell_data *clk_data)
@ -203,7 +206,7 @@ int mtk_clk_register_pllfhs(struct device_node *node,
int i;
struct clk_hw *hw;
base = of_iomap(node, 0);
base = of_iomap(dev->of_node, 0);
if (!base) {
pr_err("%s(): ioremap failed\n", __func__);
return -EINVAL;
@ -218,9 +221,9 @@ int mtk_clk_register_pllfhs(struct device_node *node,
use_fhctl = fhctl_is_supported_and_enabled(pllfh);
if (use_fhctl)
hw = mtk_clk_register_pllfh(pll, pllfh, base);
hw = mtk_clk_register_pllfh(dev, pll, pllfh, base);
else
hw = mtk_clk_register_pll(pll, base);
hw = mtk_clk_register_pll(dev, pll, base);
if (IS_ERR(hw)) {
pr_err("Failed to register %s clk %s: %ld\n",

View File

@ -68,7 +68,7 @@ struct fh_operation {
int (*ssc_enable)(struct mtk_fh *fh, u32 rate);
};
int mtk_clk_register_pllfhs(struct device_node *node,
int mtk_clk_register_pllfhs(struct device *dev,
const struct mtk_pll_data *plls, int num_plls,
struct mtk_pllfh_data *pllfhs, int num_pllfhs,
struct clk_hw_onecell_data *clk_data);

View File

@ -201,4 +201,32 @@ config COMMON_CLK_S4_PERIPHERALS
help
Support for the peripherals clock controller on Amlogic S805X2 and S905Y4
devices, AKA S4. Say Y if you want S4 peripherals clock controller to work.
config COMMON_CLK_T7_PLL
tristate "Amlogic T7 SoC PLL controller support"
depends on ARM64
default ARCH_MESON
select COMMON_CLK_MESON_REGMAP
select COMMON_CLK_MESON_CLKC_UTILS
select COMMON_CLK_MESON_MPLL
select COMMON_CLK_MESON_PLL
imply COMMON_CLK_SCMI
help
Support for the PLL clock controller on Amlogic A311D2 based
device, AKA T7. PLLs are required by most peripheral to operate.
Say Y if you want T7 PLL clock controller to work.
config COMMON_CLK_T7_PERIPHERALS
tristate "Amlogic T7 SoC peripherals clock controller support"
depends on ARM64
default ARCH_MESON
select COMMON_CLK_MESON_REGMAP
select COMMON_CLK_MESON_CLKC_UTILS
select COMMON_CLK_MESON_DUALDIV
imply COMMON_CLK_SCMI
imply COMMON_CLK_T7_PLL
help
Support for the peripherals clock controller on Amlogic A311D2 based
device, AKA T7. Peripherals are required by most peripheral to operate.
Say Y if you want T7 peripherals clock controller to work.
endmenu

View File

@ -26,3 +26,5 @@ obj-$(CONFIG_COMMON_CLK_G12A) += g12a.o g12a-aoclk.o
obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o meson8-ddr.o
obj-$(CONFIG_COMMON_CLK_S4_PLL) += s4-pll.o
obj-$(CONFIG_COMMON_CLK_S4_PERIPHERALS) += s4-peripherals.o
obj-$(CONFIG_COMMON_CLK_T7_PLL) += t7-pll.o
obj-$(CONFIG_COMMON_CLK_T7_PERIPHERALS) += t7-peripherals.o

View File

@ -777,12 +777,23 @@ static struct clk_regmap g12a_hdmi_pll_dco = {
},
};
/*
* G12/SM1 hdmi OD dividers are POWER_OF_TWO dividers but limited to /4.
* A divider value of 3 should map to /8 but instead map /4 so ignore it.
*/
static const struct clk_div_table g12a_hdmi_pll_od_div_table[] = {
{ .val = 0, .div = 1 },
{ .val = 1, .div = 2 },
{ .val = 2, .div = 4 },
{ /* sentinel */ }
};
static struct clk_regmap g12a_hdmi_pll_od = {
.data = &(struct clk_regmap_div_data){
.offset = HHI_HDMI_PLL_CNTL0,
.shift = 16,
.width = 2,
.flags = CLK_DIVIDER_POWER_OF_TWO,
.table = g12a_hdmi_pll_od_div_table,
},
.hw.init = &(struct clk_init_data){
.name = "hdmi_pll_od",
@ -800,7 +811,7 @@ static struct clk_regmap g12a_hdmi_pll_od2 = {
.offset = HHI_HDMI_PLL_CNTL0,
.shift = 18,
.width = 2,
.flags = CLK_DIVIDER_POWER_OF_TWO,
.table = g12a_hdmi_pll_od_div_table,
},
.hw.init = &(struct clk_init_data){
.name = "hdmi_pll_od2",
@ -818,7 +829,7 @@ static struct clk_regmap g12a_hdmi_pll = {
.offset = HHI_HDMI_PLL_CNTL0,
.shift = 20,
.width = 2,
.flags = CLK_DIVIDER_POWER_OF_TWO,
.table = g12a_hdmi_pll_od_div_table,
},
.hw.init = &(struct clk_init_data){
.name = "hdmi_pll",

View File

@ -349,12 +349,23 @@ static struct clk_regmap gxbb_hdmi_pll = {
},
};
/*
* GXL hdmi OD dividers are POWER_OF_TWO dividers but limited to /4.
* A divider value of 3 should map to /8 but instead map /4 so ignore it.
*/
static const struct clk_div_table gxl_hdmi_pll_od_div_table[] = {
{ .val = 0, .div = 1 },
{ .val = 1, .div = 2 },
{ .val = 2, .div = 4 },
{ /* sentinel */ }
};
static struct clk_regmap gxl_hdmi_pll_od = {
.data = &(struct clk_regmap_div_data){
.offset = HHI_HDMI_PLL_CNTL + 8,
.offset = HHI_HDMI_PLL_CNTL3,
.shift = 21,
.width = 2,
.flags = CLK_DIVIDER_POWER_OF_TWO,
.table = gxl_hdmi_pll_od_div_table,
},
.hw.init = &(struct clk_init_data){
.name = "hdmi_pll_od",
@ -369,10 +380,10 @@ static struct clk_regmap gxl_hdmi_pll_od = {
static struct clk_regmap gxl_hdmi_pll_od2 = {
.data = &(struct clk_regmap_div_data){
.offset = HHI_HDMI_PLL_CNTL + 8,
.offset = HHI_HDMI_PLL_CNTL3,
.shift = 23,
.width = 2,
.flags = CLK_DIVIDER_POWER_OF_TWO,
.table = gxl_hdmi_pll_od_div_table,
},
.hw.init = &(struct clk_init_data){
.name = "hdmi_pll_od2",
@ -387,10 +398,10 @@ static struct clk_regmap gxl_hdmi_pll_od2 = {
static struct clk_regmap gxl_hdmi_pll = {
.data = &(struct clk_regmap_div_data){
.offset = HHI_HDMI_PLL_CNTL + 8,
.offset = HHI_HDMI_PLL_CNTL3,
.shift = 19,
.width = 2,
.flags = CLK_DIVIDER_POWER_OF_TWO,
.table = gxl_hdmi_pll_od_div_table,
},
.hw.init = &(struct clk_init_data){
.name = "hdmi_pll",

View File

@ -44,6 +44,7 @@
#define CLKCTRL_VDIN_MEAS_CLK_CTRL 0x0f8
#define CLKCTRL_VAPBCLK_CTRL 0x0fc
#define CLKCTRL_HDCP22_CTRL 0x100
#define CLKCTRL_CDAC_CLK_CTRL 0x108
#define CLKCTRL_VDEC_CLK_CTRL 0x140
#define CLKCTRL_VDEC2_CLK_CTRL 0x144
#define CLKCTRL_VDEC3_CLK_CTRL 0x148
@ -1106,7 +1107,6 @@ static struct clk_regmap s4_cts_enci_sel = {
.ops = &clk_regmap_mux_ops,
.parent_hws = s4_cts_parents,
.num_parents = ARRAY_SIZE(s4_cts_parents),
.flags = CLK_SET_RATE_PARENT,
},
};
@ -1122,7 +1122,21 @@ static struct clk_regmap s4_cts_encp_sel = {
.ops = &clk_regmap_mux_ops,
.parent_hws = s4_cts_parents,
.num_parents = ARRAY_SIZE(s4_cts_parents),
.flags = CLK_SET_RATE_PARENT,
},
};
static struct clk_regmap s4_cts_encl_sel = {
.data = &(struct clk_regmap_mux_data){
.offset = CLKCTRL_VIID_CLK_DIV,
.mask = 0xf,
.shift = 12,
.table = s4_cts_parents_val_table,
},
.hw.init = &(struct clk_init_data){
.name = "cts_encl_sel",
.ops = &clk_regmap_mux_ops,
.parent_hws = s4_cts_parents,
.num_parents = ARRAY_SIZE(s4_cts_parents),
},
};
@ -1138,7 +1152,6 @@ static struct clk_regmap s4_cts_vdac_sel = {
.ops = &clk_regmap_mux_ops,
.parent_hws = s4_cts_parents,
.num_parents = ARRAY_SIZE(s4_cts_parents),
.flags = CLK_SET_RATE_PARENT,
},
};
@ -1169,7 +1182,6 @@ static struct clk_regmap s4_hdmi_tx_sel = {
.ops = &clk_regmap_mux_ops,
.parent_hws = s4_hdmi_tx_parents,
.num_parents = ARRAY_SIZE(s4_hdmi_tx_parents),
.flags = CLK_SET_RATE_PARENT,
},
};
@ -1205,6 +1217,22 @@ static struct clk_regmap s4_cts_encp = {
},
};
static struct clk_regmap s4_cts_encl = {
.data = &(struct clk_regmap_gate_data){
.offset = CLKCTRL_VID_CLK_CTRL2,
.bit_idx = 3,
},
.hw.init = &(struct clk_init_data) {
.name = "cts_encl",
.ops = &clk_regmap_gate_ops,
.parent_hws = (const struct clk_hw *[]) {
&s4_cts_encl_sel.hw
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
};
static struct clk_regmap s4_cts_vdac = {
.data = &(struct clk_regmap_gate_data){
.offset = CLKCTRL_VID_CLK_CTRL2,
@ -2735,6 +2763,165 @@ static struct clk_regmap s4_gen_clk = {
},
};
/* CVBS DAC */
static struct clk_regmap s4_cdac_sel = {
.data = &(struct clk_regmap_mux_data) {
.offset = CLKCTRL_CDAC_CLK_CTRL,
.mask = 0x3,
.shift = 16,
},
.hw.init = &(struct clk_init_data){
.name = "cdac_sel",
.ops = &clk_regmap_mux_ops,
.parent_data = (const struct clk_parent_data []) {
{ .fw_name = "xtal", },
{ .fw_name = "fclk_div5" },
},
.num_parents = 2,
},
};
static struct clk_regmap s4_cdac_div = {
.data = &(struct clk_regmap_div_data) {
.offset = CLKCTRL_CDAC_CLK_CTRL,
.shift = 0,
.width = 16,
},
.hw.init = &(struct clk_init_data){
.name = "cdac_div",
.ops = &clk_regmap_divider_ops,
.parent_hws = (const struct clk_hw *[]) {
&s4_cdac_sel.hw
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
};
static struct clk_regmap s4_cdac = {
.data = &(struct clk_regmap_gate_data) {
.offset = CLKCTRL_CDAC_CLK_CTRL,
.bit_idx = 20,
},
.hw.init = &(struct clk_init_data){
.name = "cdac",
.ops = &clk_regmap_gate_ops,
.parent_hws = (const struct clk_hw *[]) {
&s4_cdac_div.hw
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
};
static struct clk_regmap s4_demod_core_sel = {
.data = &(struct clk_regmap_mux_data) {
.offset = CLKCTRL_DEMOD_CLK_CTRL,
.mask = 0x3,
.shift = 9,
},
.hw.init = &(struct clk_init_data){
.name = "demod_core_sel",
.ops = &clk_regmap_mux_ops,
.parent_data = (const struct clk_parent_data []) {
{ .fw_name = "xtal" },
{ .fw_name = "fclk_div7" },
{ .fw_name = "fclk_div4" }
},
.num_parents = 3,
},
};
static struct clk_regmap s4_demod_core_div = {
.data = &(struct clk_regmap_div_data) {
.offset = CLKCTRL_DEMOD_CLK_CTRL,
.shift = 0,
.width = 7,
},
.hw.init = &(struct clk_init_data){
.name = "demod_core_div",
.ops = &clk_regmap_divider_ops,
.parent_hws = (const struct clk_hw *[]) {
&s4_demod_core_sel.hw
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
};
static struct clk_regmap s4_demod_core = {
.data = &(struct clk_regmap_gate_data) {
.offset = CLKCTRL_DEMOD_CLK_CTRL,
.bit_idx = 8
},
.hw.init = &(struct clk_init_data){
.name = "demod_core",
.ops = &clk_regmap_gate_ops,
.parent_hws = (const struct clk_hw *[]) {
&s4_demod_core_div.hw
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
};
/* CVBS ADC */
static struct clk_regmap s4_adc_extclk_in_sel = {
.data = &(struct clk_regmap_mux_data) {
.offset = CLKCTRL_DEMOD_CLK_CTRL,
.mask = 0x7,
.shift = 25,
},
.hw.init = &(struct clk_init_data){
.name = "adc_extclk_in_sel",
.ops = &clk_regmap_mux_ops,
.parent_data = (const struct clk_parent_data []) {
{ .fw_name = "xtal" },
{ .fw_name = "fclk_div4" },
{ .fw_name = "fclk_div3" },
{ .fw_name = "fclk_div5" },
{ .fw_name = "fclk_div7" },
{ .fw_name = "mpll2" },
{ .fw_name = "gp0_pll" },
{ .fw_name = "hifi_pll" }
},
.num_parents = 8,
},
};
static struct clk_regmap s4_adc_extclk_in_div = {
.data = &(struct clk_regmap_div_data) {
.offset = CLKCTRL_DEMOD_CLK_CTRL,
.shift = 16,
.width = 7,
},
.hw.init = &(struct clk_init_data){
.name = "adc_extclk_in_div",
.ops = &clk_regmap_divider_ops,
.parent_hws = (const struct clk_hw *[]) {
&s4_adc_extclk_in_sel.hw
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
};
static struct clk_regmap s4_adc_extclk_in = {
.data = &(struct clk_regmap_gate_data) {
.offset = CLKCTRL_DEMOD_CLK_CTRL,
.bit_idx = 24
},
.hw.init = &(struct clk_init_data){
.name = "adc_extclk_in",
.ops = &clk_regmap_gate_ops,
.parent_hws = (const struct clk_hw *[]) {
&s4_adc_extclk_in_div.hw
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
};
static const struct clk_parent_data s4_pclk_parents = { .hw = &s4_sys_clk.hw };
#define S4_PCLK(_name, _reg, _bit, _flags) \
@ -3028,6 +3215,17 @@ static struct clk_hw *s4_peripherals_hw_clks[] = {
[CLKID_HDCP22_SKPCLK_SEL] = &s4_hdcp22_skpclk_sel.hw,
[CLKID_HDCP22_SKPCLK_DIV] = &s4_hdcp22_skpclk_div.hw,
[CLKID_HDCP22_SKPCLK] = &s4_hdcp22_skpclk.hw,
[CLKID_CTS_ENCL_SEL] = &s4_cts_encl_sel.hw,
[CLKID_CTS_ENCL] = &s4_cts_encl.hw,
[CLKID_CDAC_SEL] = &s4_cdac_sel.hw,
[CLKID_CDAC_DIV] = &s4_cdac_div.hw,
[CLKID_CDAC] = &s4_cdac.hw,
[CLKID_DEMOD_CORE_SEL] = &s4_demod_core_sel.hw,
[CLKID_DEMOD_CORE_DIV] = &s4_demod_core_div.hw,
[CLKID_DEMOD_CORE] = &s4_demod_core.hw,
[CLKID_ADC_EXTCLK_IN_SEL] = &s4_adc_extclk_in_sel.hw,
[CLKID_ADC_EXTCLK_IN_DIV] = &s4_adc_extclk_in_div.hw,
[CLKID_ADC_EXTCLK_IN] = &s4_adc_extclk_in.hw,
};
static const struct meson_clkc_data s4_peripherals_clkc_data = {

File diff suppressed because it is too large Load Diff

1074
drivers/clk/meson/t7-pll.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -24,6 +24,16 @@
#define GATE_MANUAL BIT(20)
#define GATE_ENABLE_HWACG BIT(28)
/* Option register bits */
#define OPT_EN_MEM_PWR_GATING BIT(24)
#define OPT_EN_AUTO_GATING BIT(28)
#define OPT_EN_PWR_MANAGEMENT BIT(29)
#define OPT_EN_LAYER2_CTRL BIT(30)
#define OPT_EN_DBG BIT(31)
#define CMU_OPT_GLOBAL_EN_AUTO_GATING (OPT_EN_DBG | OPT_EN_LAYER2_CTRL | \
OPT_EN_PWR_MANAGEMENT | OPT_EN_AUTO_GATING | OPT_EN_MEM_PWR_GATING)
/* PLL_CONx_PLL register offsets range */
#define PLL_CON_OFF_START 0x100
#define PLL_CON_OFF_END 0x600
@ -37,6 +47,8 @@ struct exynos_arm64_cmu_data {
unsigned int nr_clk_save;
const struct samsung_clk_reg_dump *clk_suspend;
unsigned int nr_clk_suspend;
struct samsung_clk_reg_dump *clk_sysreg_save;
unsigned int nr_clk_sysreg;
struct clk *clk;
struct clk **pclks;
@ -76,19 +88,41 @@ static void __init exynos_arm64_init_clocks(struct device_node *np,
const unsigned long *reg_offs = cmu->clk_regs;
size_t reg_offs_len = cmu->nr_clk_regs;
void __iomem *reg_base;
bool init_auto;
size_t i;
reg_base = of_iomap(np, 0);
if (!reg_base)
panic("%s: failed to map registers\n", __func__);
/* ensure compatibility with older DTs */
if (cmu->auto_clock_gate && samsung_is_auto_capable(np))
init_auto = true;
else
init_auto = false;
if (cmu->option_offset && init_auto) {
/*
* Enable the global automatic mode for the entire CMU.
* This overrides the individual HWACG bits in each of the
* individual gate, mux and qch registers.
*/
writel(CMU_OPT_GLOBAL_EN_AUTO_GATING,
reg_base + cmu->option_offset);
}
for (i = 0; i < reg_offs_len; ++i) {
void __iomem *reg = reg_base + reg_offs[i];
u32 val;
if (cmu->manual_plls && is_pll_con1_reg(reg_offs[i])) {
writel(PLL_CON1_MANUAL, reg);
} else if (is_gate_reg(reg_offs[i])) {
} else if (is_gate_reg(reg_offs[i]) && !init_auto) {
/*
* Setting GATE_MANUAL bit (which is described in TRM as
* reserved!) overrides the global CMU automatic mode
* option.
*/
val = readl(reg);
val |= GATE_MANUAL;
val &= ~GATE_ENABLE_HWACG;
@ -140,7 +174,7 @@ static int __init exynos_arm64_cmu_prepare_pm(struct device *dev,
const struct samsung_cmu_info *cmu)
{
struct exynos_arm64_cmu_data *data = dev_get_drvdata(dev);
int i;
int i, ret;
data->clk_save = samsung_clk_alloc_reg_dump(cmu->clk_regs,
cmu->nr_clk_regs);
@ -148,8 +182,22 @@ static int __init exynos_arm64_cmu_prepare_pm(struct device *dev,
return -ENOMEM;
data->nr_clk_save = cmu->nr_clk_regs;
if (cmu->nr_sysreg_clk_regs) {
data->clk_sysreg_save =
samsung_clk_alloc_reg_dump(cmu->sysreg_clk_regs,
cmu->nr_sysreg_clk_regs);
if (!data->clk_sysreg_save) {
ret = -ENOMEM;
goto free_clk_save;
}
data->nr_clk_sysreg = cmu->nr_sysreg_clk_regs;
}
data->clk_suspend = cmu->suspend_regs;
data->nr_clk_suspend = cmu->nr_suspend_regs;
data->nr_pclks = of_clk_get_parent_count(dev->of_node);
if (!data->nr_pclks)
return 0;
@ -157,23 +205,29 @@ static int __init exynos_arm64_cmu_prepare_pm(struct device *dev,
data->pclks = devm_kcalloc(dev, sizeof(struct clk *), data->nr_pclks,
GFP_KERNEL);
if (!data->pclks) {
kfree(data->clk_save);
return -ENOMEM;
ret = -ENOMEM;
goto free_sysreg_save;
}
for (i = 0; i < data->nr_pclks; i++) {
struct clk *clk = of_clk_get(dev->of_node, i);
if (IS_ERR(clk)) {
kfree(data->clk_save);
while (--i >= 0)
clk_put(data->pclks[i]);
return PTR_ERR(clk);
ret = PTR_ERR(clk);
goto free_sysreg_save;
}
data->pclks[i] = clk;
}
return 0;
free_sysreg_save:
kfree(data->clk_sysreg_save);
free_clk_save:
kfree(data->clk_save);
return ret;
}
/**
@ -210,8 +264,8 @@ void __init exynos_arm64_register_cmu(struct device *dev,
/**
* exynos_arm64_register_cmu_pm - Register Exynos CMU domain with PM support
*
* @pdev: Platform device object
* @set_manual: If true, set gate clocks to manual mode
* @pdev: Platform device object
* @init_clk_regs: If true, initialize CMU registers
*
* It's a version of exynos_arm64_register_cmu() with PM support. Should be
* called from probe function of platform driver.
@ -219,7 +273,7 @@ void __init exynos_arm64_register_cmu(struct device *dev,
* Return: 0 on success, or negative error code on error.
*/
int __init exynos_arm64_register_cmu_pm(struct platform_device *pdev,
bool set_manual)
bool init_clk_regs)
{
const struct samsung_cmu_info *cmu;
struct device *dev = &pdev->dev;
@ -249,7 +303,7 @@ int __init exynos_arm64_register_cmu_pm(struct platform_device *pdev,
dev_err(dev, "%s: could not enable bus clock %s; err = %d\n",
__func__, cmu->clk_name, ret);
if (set_manual)
if (init_clk_regs)
exynos_arm64_init_clocks(np, cmu);
reg_base = devm_platform_ioremap_resource(pdev, 0);
@ -268,8 +322,10 @@ int __init exynos_arm64_register_cmu_pm(struct platform_device *pdev,
pm_runtime_set_active(dev);
pm_runtime_enable(dev);
samsung_cmu_register_clocks(data->ctx, cmu);
samsung_cmu_register_clocks(data->ctx, cmu, np);
samsung_clk_of_add_provider(dev->of_node, data->ctx);
/* sysreg DT nodes reference a clock in this CMU */
samsung_en_dyn_root_clk_gating(np, data->ctx, cmu, true);
pm_runtime_put_sync(dev);
return 0;
@ -280,14 +336,17 @@ int exynos_arm64_cmu_suspend(struct device *dev)
struct exynos_arm64_cmu_data *data = dev_get_drvdata(dev);
int i;
samsung_clk_save(data->ctx->reg_base, data->clk_save,
samsung_clk_save(data->ctx->reg_base, NULL, data->clk_save,
data->nr_clk_save);
samsung_clk_save(NULL, data->ctx->sysreg, data->clk_sysreg_save,
data->nr_clk_sysreg);
for (i = 0; i < data->nr_pclks; i++)
clk_prepare_enable(data->pclks[i]);
/* For suspend some registers have to be set to certain values */
samsung_clk_restore(data->ctx->reg_base, data->clk_suspend,
samsung_clk_restore(data->ctx->reg_base, NULL, data->clk_suspend,
data->nr_clk_suspend);
for (i = 0; i < data->nr_pclks; i++)
@ -308,9 +367,14 @@ int exynos_arm64_cmu_resume(struct device *dev)
for (i = 0; i < data->nr_pclks; i++)
clk_prepare_enable(data->pclks[i]);
samsung_clk_restore(data->ctx->reg_base, data->clk_save,
samsung_clk_restore(data->ctx->reg_base, NULL, data->clk_save,
data->nr_clk_save);
if (data->ctx->sysreg)
samsung_clk_restore(NULL, data->ctx->sysreg,
data->clk_sysreg_save,
data->nr_clk_sysreg);
for (i = 0; i < data->nr_pclks; i++)
clk_disable_unprepare(data->pclks[i]);

View File

@ -1361,12 +1361,12 @@ static void __init exynos4_clk_init(struct device_node *np,
ARRAY_SIZE(exynos4x12_plls));
}
samsung_cmu_register_clocks(ctx, &cmu_info_exynos4);
samsung_cmu_register_clocks(ctx, &cmu_info_exynos4, np);
if (exynos4_soc == EXYNOS4210) {
samsung_cmu_register_clocks(ctx, &cmu_info_exynos4210);
samsung_cmu_register_clocks(ctx, &cmu_info_exynos4210, np);
} else {
samsung_cmu_register_clocks(ctx, &cmu_info_exynos4x12);
samsung_cmu_register_clocks(ctx, &cmu_info_exynos4x12, np);
if (soc == EXYNOS4412)
samsung_clk_register_cpu(ctx, exynos4412_cpu_clks,
ARRAY_SIZE(exynos4412_cpu_clks));
@ -1378,15 +1378,15 @@ static void __init exynos4_clk_init(struct device_node *np,
if (soc == EXYNOS4212 || soc == EXYNOS4412)
exynos4x12_core_down_clock();
samsung_clk_extended_sleep_init(reg_base,
samsung_clk_extended_sleep_init(reg_base, NULL,
exynos4_clk_regs, ARRAY_SIZE(exynos4_clk_regs),
src_mask_suspend, ARRAY_SIZE(src_mask_suspend));
if (exynos4_soc == EXYNOS4210)
samsung_clk_extended_sleep_init(reg_base,
samsung_clk_extended_sleep_init(reg_base, NULL,
exynos4210_clk_save, ARRAY_SIZE(exynos4210_clk_save),
src_mask_suspend_e4210, ARRAY_SIZE(src_mask_suspend_e4210));
else
samsung_clk_sleep_init(reg_base, exynos4x12_clk_save,
samsung_clk_sleep_init(reg_base, NULL, exynos4x12_clk_save,
ARRAY_SIZE(exynos4x12_clk_save));
samsung_clk_of_add_provider(np, ctx);

View File

@ -94,7 +94,7 @@ static int __maybe_unused exynos4x12_isp_clk_suspend(struct device *dev)
{
struct samsung_clk_provider *ctx = dev_get_drvdata(dev);
samsung_clk_save(ctx->reg_base, exynos4x12_save_isp,
samsung_clk_save(ctx->reg_base, NULL, exynos4x12_save_isp,
ARRAY_SIZE(exynos4x12_clk_isp_save));
return 0;
}
@ -103,7 +103,7 @@ static int __maybe_unused exynos4x12_isp_clk_resume(struct device *dev)
{
struct samsung_clk_provider *ctx = dev_get_drvdata(dev);
samsung_clk_restore(ctx->reg_base, exynos4x12_save_isp,
samsung_clk_restore(ctx->reg_base, NULL, exynos4x12_save_isp,
ARRAY_SIZE(exynos4x12_clk_isp_save));
return 0;
}

View File

@ -854,7 +854,7 @@ static void __init exynos5250_clk_init(struct device_node *np)
PWR_CTRL2_CORE2_UP_RATIO | PWR_CTRL2_CORE1_UP_RATIO);
__raw_writel(tmp, reg_base + PWR_CTRL2);
samsung_clk_sleep_init(reg_base, exynos5250_clk_regs,
samsung_clk_sleep_init(reg_base, NULL, exynos5250_clk_regs,
ARRAY_SIZE(exynos5250_clk_regs));
exynos5_subcmus_init(ctx, ARRAY_SIZE(exynos5250_subcmus),
exynos5250_subcmus);

View File

@ -1649,12 +1649,12 @@ static void __init exynos5x_clk_init(struct device_node *np,
ARRAY_SIZE(exynos5800_cpu_clks));
}
samsung_clk_extended_sleep_init(reg_base,
samsung_clk_extended_sleep_init(reg_base, NULL,
exynos5x_clk_regs, ARRAY_SIZE(exynos5x_clk_regs),
exynos5420_set_clksrc, ARRAY_SIZE(exynos5420_set_clksrc));
if (soc == EXYNOS5800) {
samsung_clk_sleep_init(reg_base, exynos5800_clk_regs,
samsung_clk_sleep_init(reg_base, NULL, exynos5800_clk_regs,
ARRAY_SIZE(exynos5800_clk_regs));
exynos5_subcmus_init(ctx, ARRAY_SIZE(exynos5800_subcmus),

View File

@ -29,6 +29,7 @@
#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)
#define CLKS_NR_MFD (CLK_DOUT_MFD_NOCP + 1)
/* ---- CMU_TOP ------------------------------------------------------------ */
@ -1905,6 +1906,42 @@ static const struct samsung_cmu_info mfc_cmu_info __initconst = {
.clk_name = "noc",
};
/* ---- CMU_MFD --------------------------------------------------------- */
/* Register Offset definitions for CMU_MFD (0x19e00000) */
#define PLL_CON0_MUX_CLKCMU_MFD_NOC_USER 0x600
#define CLK_CON_DIV_DIV_CLK_MFD_NOCP 0x1800
static const unsigned long mfd_clk_regs[] __initconst = {
PLL_CON0_MUX_CLKCMU_MFD_NOC_USER,
CLK_CON_DIV_DIV_CLK_MFD_NOCP,
};
/* List of parent clocks for Muxes in CMU_MFD */
PNAME(mout_clkcmu_mfd_noc_user_p) = { "oscclk", "dout_clkcmu_mfd_noc" };
static const struct samsung_mux_clock mfd_mux_clks[] __initconst = {
MUX(CLK_MOUT_MFD_NOC_USER, "mout_clkcmu_mfd_noc_user",
mout_clkcmu_mfd_noc_user_p, PLL_CON0_MUX_CLKCMU_MFD_NOC_USER, 4, 1),
};
static const struct samsung_div_clock mfd_div_clks[] __initconst = {
DIV(CLK_DOUT_MFD_NOCP, "dout_mfd_nocp",
"mout_clkcmu_mfd_noc_user", CLK_CON_DIV_DIV_CLK_MFD_NOCP,
0, 3),
};
static const struct samsung_cmu_info mfd_cmu_info __initconst = {
.mux_clks = mfd_mux_clks,
.nr_mux_clks = ARRAY_SIZE(mfd_mux_clks),
.div_clks = mfd_div_clks,
.nr_div_clks = ARRAY_SIZE(mfd_div_clks),
.nr_clk_ids = CLKS_NR_MFD,
.clk_regs = mfd_clk_regs,
.nr_clk_regs = ARRAY_SIZE(mfd_clk_regs),
.clk_name = "noc",
};
static int __init exynosautov920_cmu_probe(struct platform_device *pdev)
{
const struct samsung_cmu_info *info;
@ -1941,6 +1978,9 @@ static const struct of_device_id exynosautov920_cmu_of_match[] = {
}, {
.compatible = "samsung,exynosautov920-cmu-mfc",
.data = &mfc_cmu_info,
}, {
.compatible = "samsung,exynosautov920-cmu-mfd",
.data = &mfd_cmu_info,
},
{ }
};

View File

@ -20,12 +20,17 @@
/* NOTE: Must be equal to the last clock ID increased by one */
#define CLKS_NR_TOP (CLK_GOUT_CMU_TPU_UART + 1)
#define CLKS_NR_APM (CLK_APM_PLL_DIV16_APM + 1)
#define CLKS_NR_DPU (CLK_GOUT_DPU_SYSREG_DPU_PCLK + 1)
#define CLKS_NR_HSI0 (CLK_GOUT_HSI0_XIU_P_HSI0_ACLK + 1)
#define CLKS_NR_HSI2 (CLK_GOUT_HSI2_XIU_P_HSI2_ACLK + 1)
#define CLKS_NR_MISC (CLK_GOUT_MISC_XIU_D_MISC_ACLK + 1)
#define CLKS_NR_PERIC0 (CLK_GOUT_PERIC0_SYSREG_PERIC0_PCLK + 1)
#define CLKS_NR_PERIC1 (CLK_GOUT_PERIC1_SYSREG_PERIC1_PCLK + 1)
#define GS101_GATE_DBG_OFFSET 0x4000
#define GS101_DRCG_EN_OFFSET 0x104
#define GS101_MEMCLK_OFFSET 0x108
/* ---- CMU_TOP ------------------------------------------------------------- */
/* Register Offset definitions for CMU_TOP (0x1e080000) */
@ -1433,6 +1438,9 @@ static const struct samsung_cmu_info top_cmu_info __initconst = {
.nr_clk_ids = CLKS_NR_TOP,
.clk_regs = cmu_top_clk_regs,
.nr_clk_regs = ARRAY_SIZE(cmu_top_clk_regs),
.auto_clock_gate = true,
.gate_dbg_offset = GS101_GATE_DBG_OFFSET,
.option_offset = CMU_CMU_TOP_CONTROLLER_OPTION,
};
static void __init gs101_cmu_top_init(struct device_node *np)
@ -1900,6 +1908,11 @@ static const struct samsung_gate_clock apm_gate_clks[] __initconst = {
CLK_CON_GAT_GOUT_BLK_APM_UID_XIU_DP_APM_IPCLKPORT_ACLK, 21, CLK_IS_CRITICAL, 0),
};
static const unsigned long dcrg_memclk_sysreg[] __initconst = {
GS101_DRCG_EN_OFFSET,
GS101_MEMCLK_OFFSET,
};
static const struct samsung_cmu_info apm_cmu_info __initconst = {
.mux_clks = apm_mux_clks,
.nr_mux_clks = ARRAY_SIZE(apm_mux_clks),
@ -1912,6 +1925,291 @@ static const struct samsung_cmu_info apm_cmu_info __initconst = {
.nr_clk_ids = CLKS_NR_APM,
.clk_regs = apm_clk_regs,
.nr_clk_regs = ARRAY_SIZE(apm_clk_regs),
.sysreg_clk_regs = dcrg_memclk_sysreg,
.nr_sysreg_clk_regs = ARRAY_SIZE(dcrg_memclk_sysreg),
.auto_clock_gate = true,
.gate_dbg_offset = GS101_GATE_DBG_OFFSET,
.drcg_offset = GS101_DRCG_EN_OFFSET,
.memclk_offset = GS101_MEMCLK_OFFSET,
};
/* ---- CMU_DPU ------------------------------------------------------------- */
/* Register Offset definitions for CMU_DPU (0x1c000000) */
#define PLL_CON0_MUX_CLKCMU_DPU_BUS_USER 0x0600
#define PLL_CON1_MUX_CLKCMU_DPU_BUS_USER 0x0604
#define DPU_CMU_DPU_CONTROLLER_OPTION 0x0800
#define CLKOUT_CON_BLK_DPU_CMU_DPU_CLKOUT0 0x0810
#define CLK_CON_DIV_DIV_CLK_DPU_BUSP 0x1800
#define CLK_CON_GAT_CLK_BLK_DPU_UID_DPU_CMU_DPU_IPCLKPORT_PCLK 0x2000
#define CLK_CON_GAT_CLK_BLK_DPU_UID_RSTNSYNC_CLK_DPU_OSCCLK_IPCLKPORT_CLK 0x2004
#define CLK_CON_GAT_GOUT_BLK_DPU_UID_AD_APB_DPU_DMA_IPCLKPORT_PCLKM 0x2008
#define CLK_CON_GAT_GOUT_BLK_DPU_UID_DPUF_IPCLKPORT_ACLK_DMA 0x200c
#define CLK_CON_GAT_GOUT_BLK_DPU_UID_DPUF_IPCLKPORT_ACLK_DPP 0x2010
#define CLK_CON_GAT_GOUT_BLK_DPU_UID_D_TZPC_DPU_IPCLKPORT_PCLK 0x2014
#define CLK_CON_GAT_GOUT_BLK_DPU_UID_GPC_DPU_IPCLKPORT_PCLK 0x2018
#define CLK_CON_GAT_GOUT_BLK_DPU_UID_LHM_AXI_P_DPU_IPCLKPORT_I_CLK 0x201c
#define CLK_CON_GAT_GOUT_BLK_DPU_UID_LHS_AXI_D0_DPU_IPCLKPORT_I_CLK 0x2020
#define CLK_CON_GAT_GOUT_BLK_DPU_UID_LHS_AXI_D1_DPU_IPCLKPORT_I_CLK 0x2024
#define CLK_CON_GAT_GOUT_BLK_DPU_UID_LHS_AXI_D2_DPU_IPCLKPORT_I_CLK 0x2028
#define CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD0_IPCLKPORT_ACLK 0x202c
#define CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD0_IPCLKPORT_PCLK 0x2030
#define CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD1_IPCLKPORT_ACLK 0x2034
#define CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD1_IPCLKPORT_PCLK 0x2038
#define CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD2_IPCLKPORT_ACLK 0x203c
#define CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD2_IPCLKPORT_PCLK 0x2040
#define CLK_CON_GAT_GOUT_BLK_DPU_UID_RSTNSYNC_CLK_DPU_BUSD_IPCLKPORT_CLK 0x2044
#define CLK_CON_GAT_GOUT_BLK_DPU_UID_RSTNSYNC_CLK_DPU_BUSP_IPCLKPORT_CLK 0x2048
#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU0_IPCLKPORT_ACLK 0x204c
#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU0_IPCLKPORT_PCLK 0x2050
#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU1_IPCLKPORT_ACLK 0x2054
#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU1_IPCLKPORT_PCLK 0x2058
#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU2_IPCLKPORT_ACLK 0x205c
#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU2_IPCLKPORT_PCLK 0x2060
#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD0_IPCLKPORT_CLK_S1 0x2064
#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD0_IPCLKPORT_CLK_S2 0x2068
#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD1_IPCLKPORT_CLK_S1 0x206c
#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD1_IPCLKPORT_CLK_S2 0x2070
#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD2_IPCLKPORT_CLK_S1 0x2074
#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD2_IPCLKPORT_CLK_S2 0x2078
#define CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSREG_DPU_IPCLKPORT_PCLK 0x207c
#define PCH_CON_LHM_AXI_P_DPU_PCH 0x3000
#define PCH_CON_LHS_AXI_D0_DPU_PCH 0x3004
#define PCH_CON_LHS_AXI_D1_DPU_PCH 0x3008
#define PCH_CON_LHS_AXI_D2_DPU_PCH 0x300c
#define QCH_CON_DPUF_QCH_DPU_DMA 0x3010
#define QCH_CON_DPUF_QCH_DPU_DPP 0x3014
#define QCH_CON_DPU_CMU_DPU_QCH 0x301c
#define QCH_CON_D_TZPC_DPU_QCH 0x3020
#define QCH_CON_GPC_DPU_QCH 0x3024
#define QCH_CON_LHM_AXI_P_DPU_QCH 0x3028
#define QCH_CON_LHS_AXI_D0_DPU_QCH 0x302c
#define QCH_CON_LHS_AXI_D1_DPU_QCH 0x3030
#define QCH_CON_LHS_AXI_D2_DPU_QCH 0x3034
#define QCH_CON_PPMU_DPUD0_QCH 0x3038
#define QCH_CON_PPMU_DPUD1_QCH 0x303c
#define QCH_CON_PPMU_DPUD2_QCH 0x3040
#define QCH_CON_SSMT_DPU0_QCH 0x3044
#define QCH_CON_SSMT_DPU1_QCH 0x3048
#define QCH_CON_SSMT_DPU2_QCH 0x304c
#define QCH_CON_SYSMMU_DPUD0_QCH_S1 0x3050
#define QCH_CON_SYSMMU_DPUD0_QCH_S2 0x3054
#define QCH_CON_SYSMMU_DPUD1_QCH_S1 0x3058
#define QCH_CON_SYSMMU_DPUD1_QCH_S2 0x305c
#define QCH_CON_SYSMMU_DPUD2_QCH_S1 0x3060
#define QCH_CON_SYSMMU_DPUD2_QCH_S2 0x3064
#define QCH_CON_SYSREG_DPU_QCH 0x3068
#define QUEUE_CTRL_REG_BLK_DPU_CMU_DPU 0x3c00
static const unsigned long dpu_clk_regs[] __initconst = {
PLL_CON0_MUX_CLKCMU_DPU_BUS_USER,
PLL_CON1_MUX_CLKCMU_DPU_BUS_USER,
DPU_CMU_DPU_CONTROLLER_OPTION,
CLKOUT_CON_BLK_DPU_CMU_DPU_CLKOUT0,
CLK_CON_DIV_DIV_CLK_DPU_BUSP,
CLK_CON_GAT_CLK_BLK_DPU_UID_DPU_CMU_DPU_IPCLKPORT_PCLK,
CLK_CON_GAT_CLK_BLK_DPU_UID_RSTNSYNC_CLK_DPU_OSCCLK_IPCLKPORT_CLK,
CLK_CON_GAT_GOUT_BLK_DPU_UID_AD_APB_DPU_DMA_IPCLKPORT_PCLKM,
CLK_CON_GAT_GOUT_BLK_DPU_UID_DPUF_IPCLKPORT_ACLK_DMA,
CLK_CON_GAT_GOUT_BLK_DPU_UID_DPUF_IPCLKPORT_ACLK_DPP,
CLK_CON_GAT_GOUT_BLK_DPU_UID_D_TZPC_DPU_IPCLKPORT_PCLK,
CLK_CON_GAT_GOUT_BLK_DPU_UID_GPC_DPU_IPCLKPORT_PCLK,
CLK_CON_GAT_GOUT_BLK_DPU_UID_LHM_AXI_P_DPU_IPCLKPORT_I_CLK,
CLK_CON_GAT_GOUT_BLK_DPU_UID_LHS_AXI_D0_DPU_IPCLKPORT_I_CLK,
CLK_CON_GAT_GOUT_BLK_DPU_UID_LHS_AXI_D1_DPU_IPCLKPORT_I_CLK,
CLK_CON_GAT_GOUT_BLK_DPU_UID_LHS_AXI_D2_DPU_IPCLKPORT_I_CLK,
CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD0_IPCLKPORT_ACLK,
CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD0_IPCLKPORT_PCLK,
CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD1_IPCLKPORT_ACLK,
CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD1_IPCLKPORT_PCLK,
CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD2_IPCLKPORT_ACLK,
CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD2_IPCLKPORT_PCLK,
CLK_CON_GAT_GOUT_BLK_DPU_UID_RSTNSYNC_CLK_DPU_BUSD_IPCLKPORT_CLK,
CLK_CON_GAT_GOUT_BLK_DPU_UID_RSTNSYNC_CLK_DPU_BUSP_IPCLKPORT_CLK,
CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU0_IPCLKPORT_ACLK,
CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU0_IPCLKPORT_PCLK,
CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU1_IPCLKPORT_ACLK,
CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU1_IPCLKPORT_PCLK,
CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU2_IPCLKPORT_ACLK,
CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU2_IPCLKPORT_PCLK,
CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD0_IPCLKPORT_CLK_S1,
CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD0_IPCLKPORT_CLK_S2,
CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD1_IPCLKPORT_CLK_S1,
CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD1_IPCLKPORT_CLK_S2,
CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD2_IPCLKPORT_CLK_S1,
CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD2_IPCLKPORT_CLK_S2,
CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSREG_DPU_IPCLKPORT_PCLK,
PCH_CON_LHM_AXI_P_DPU_PCH,
PCH_CON_LHS_AXI_D0_DPU_PCH,
PCH_CON_LHS_AXI_D1_DPU_PCH,
PCH_CON_LHS_AXI_D2_DPU_PCH,
QCH_CON_DPUF_QCH_DPU_DMA,
QCH_CON_DPUF_QCH_DPU_DPP,
QCH_CON_DPU_CMU_DPU_QCH,
QCH_CON_D_TZPC_DPU_QCH,
QCH_CON_GPC_DPU_QCH,
QCH_CON_LHM_AXI_P_DPU_QCH,
QCH_CON_LHS_AXI_D0_DPU_QCH,
QCH_CON_LHS_AXI_D1_DPU_QCH,
QCH_CON_LHS_AXI_D2_DPU_QCH,
QCH_CON_PPMU_DPUD0_QCH,
QCH_CON_PPMU_DPUD1_QCH,
QCH_CON_PPMU_DPUD2_QCH,
QCH_CON_SSMT_DPU0_QCH,
QCH_CON_SSMT_DPU1_QCH,
QCH_CON_SSMT_DPU2_QCH,
QCH_CON_SYSMMU_DPUD0_QCH_S1,
QCH_CON_SYSMMU_DPUD0_QCH_S2,
QCH_CON_SYSMMU_DPUD1_QCH_S1,
QCH_CON_SYSMMU_DPUD1_QCH_S2,
QCH_CON_SYSMMU_DPUD2_QCH_S1,
QCH_CON_SYSMMU_DPUD2_QCH_S2,
QCH_CON_SYSREG_DPU_QCH,
QUEUE_CTRL_REG_BLK_DPU_CMU_DPU,
};
/* List of parent clocks for Muxes in CMU_DPU */
PNAME(mout_dpu_bus_user_p) = { "oscclk", "dout_cmu_dpu_bus" };
static const struct samsung_mux_clock dpu_mux_clks[] __initconst = {
MUX(CLK_MOUT_DPU_BUS_USER, "mout_dpu_bus_user",
mout_dpu_bus_user_p, PLL_CON0_MUX_CLKCMU_DPU_BUS_USER, 4, 1),
};
static const struct samsung_div_clock dpu_div_clks[] __initconst = {
DIV(CLK_DOUT_DPU_BUSP, "dout_dpu_busp", "mout_dpu_bus_user",
CLK_CON_DIV_DIV_CLK_DPU_BUSP, 0, 3),
};
static const struct samsung_gate_clock dpu_gate_clks[] __initconst = {
GATE(CLK_GOUT_DPU_PCLK, "gout_dpu_dpu_pclk",
"dout_dpu_busp",
CLK_CON_GAT_CLK_BLK_DPU_UID_DPU_CMU_DPU_IPCLKPORT_PCLK, 21, 0, 0),
GATE(CLK_GOUT_DPU_CLK_DPU_OSCCLK_CLK, "gout_dpu_clk_dpu_oscclk_clk",
"oscclk",
CLK_CON_GAT_CLK_BLK_DPU_UID_RSTNSYNC_CLK_DPU_OSCCLK_IPCLKPORT_CLK,
21, 0, 0),
GATE(CLK_GOUT_DPU_AD_APB_DPU_DMA_PCLKM, "gout_dpu_ad_apb_dpu_dma_pclkm",
"mout_dpu_bus_user",
CLK_CON_GAT_GOUT_BLK_DPU_UID_AD_APB_DPU_DMA_IPCLKPORT_PCLKM,
21, 0, 0),
GATE(CLK_GOUT_DPU_DPUF_ACLK_DMA, "gout_dpu_dpuf_aclk_dma",
"mout_dpu_bus_user",
CLK_CON_GAT_GOUT_BLK_DPU_UID_DPUF_IPCLKPORT_ACLK_DMA, 21, 0, 0),
GATE(CLK_GOUT_DPU_DPUF_ACLK_DPP, "gout_dpu_dpuf_aclk_dpp",
"mout_dpu_bus_user",
CLK_CON_GAT_GOUT_BLK_DPU_UID_DPUF_IPCLKPORT_ACLK_DPP, 21, 0, 0),
GATE(CLK_GOUT_DPU_D_TZPC_DPU_PCLK, "gout_dpu_d_tzpc_dpu_pclk",
"dout_dpu_busp",
CLK_CON_GAT_GOUT_BLK_DPU_UID_D_TZPC_DPU_IPCLKPORT_PCLK, 21, 0, 0),
GATE(CLK_GOUT_DPU_GPC_DPU_PCLK, "gout_dpu_gpc_dpu_pclk",
"dout_dpu_busp",
CLK_CON_GAT_GOUT_BLK_DPU_UID_GPC_DPU_IPCLKPORT_PCLK, 21, 0, 0),
GATE(CLK_GOUT_DPU_LHM_AXI_P_DPU_I_CLK, "gout_dpu_lhm_axi_p_dpu_i_clk",
"dout_dpu_busp",
CLK_CON_GAT_GOUT_BLK_DPU_UID_LHM_AXI_P_DPU_IPCLKPORT_I_CLK,
21, 0, 0),
GATE(CLK_GOUT_DPU_LHS_AXI_D0_DPU_I_CLK, "gout_dpu_lhs_axi_d0_dpu_i_clk",
"mout_dpu_bus_user",
CLK_CON_GAT_GOUT_BLK_DPU_UID_LHS_AXI_D0_DPU_IPCLKPORT_I_CLK,
21, 0, 0),
GATE(CLK_GOUT_DPU_LHS_AXI_D1_DPU_I_CLK, "gout_dpu_lhs_axi_d1_dpu_i_clk",
"mout_dpu_bus_user",
CLK_CON_GAT_GOUT_BLK_DPU_UID_LHS_AXI_D1_DPU_IPCLKPORT_I_CLK,
21, 0, 0),
GATE(CLK_GOUT_DPU_LHS_AXI_D2_DPU_I_CLK, "gout_dpu_lhs_axi_d2_dpu_i_clk",
"mout_dpu_bus_user",
CLK_CON_GAT_GOUT_BLK_DPU_UID_LHS_AXI_D2_DPU_IPCLKPORT_I_CLK,
21, 0, 0),
GATE(CLK_GOUT_DPU_PPMU_DPUD0_ACLK, "gout_dpu_ppmu_dpud0_aclk",
"mout_dpu_bus_user",
CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD0_IPCLKPORT_ACLK, 21, 0, 0),
GATE(CLK_GOUT_DPU_PPMU_DPUD0_PCLK, "gout_dpu_ppmu_dpud0_pclk",
"dout_dpu_busp",
CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD0_IPCLKPORT_PCLK, 21, 0, 0),
GATE(CLK_GOUT_DPU_PPMU_DPUD1_ACLK, "gout_dpu_ppmu_dpud1_aclk",
"mout_dpu_bus_user",
CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD1_IPCLKPORT_ACLK, 21, 0, 0),
GATE(CLK_GOUT_DPU_PPMU_DPUD1_PCLK, "gout_dpu_ppmu_dpud1_pclk",
"dout_dpu_busp",
CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD1_IPCLKPORT_PCLK, 21, 0, 0),
GATE(CLK_GOUT_DPU_PPMU_DPUD2_ACLK, "gout_dpu_ppmu_dpud2_aclk",
"mout_dpu_bus_user",
CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD2_IPCLKPORT_ACLK, 21, 0, 0),
GATE(CLK_GOUT_DPU_PPMU_DPUD2_PCLK, "gout_dpu_ppmu_dpud2_pclk",
"dout_dpu_busp",
CLK_CON_GAT_GOUT_BLK_DPU_UID_PPMU_DPUD2_IPCLKPORT_PCLK, 21, 0, 0),
GATE(CLK_GOUT_DPU_CLK_DPU_BUSD_CLK, "gout_dpu_clk_dpu_busd_clk",
"mout_dpu_bus_user",
CLK_CON_GAT_GOUT_BLK_DPU_UID_RSTNSYNC_CLK_DPU_BUSD_IPCLKPORT_CLK,
21, 0, 0),
GATE(CLK_GOUT_DPU_CLK_DPU_BUSP_CLK, "gout_dpu_clk_dpu_busp_clk",
"dout_dpu_busp",
CLK_CON_GAT_GOUT_BLK_DPU_UID_RSTNSYNC_CLK_DPU_BUSP_IPCLKPORT_CLK,
21, 0, 0),
GATE(CLK_GOUT_DPU_SSMT_DPU0_ACLK, "gout_dpu_ssmt_dpu0_aclk",
"mout_dpu_bus_user",
CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU0_IPCLKPORT_ACLK, 21, 0, 0),
GATE(CLK_GOUT_DPU_SSMT_DPU0_PCLK, "gout_dpu_ssmt_dpu0_pclk",
"dout_dpu_busp",
CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU0_IPCLKPORT_PCLK, 21, 0, 0),
GATE(CLK_GOUT_DPU_SSMT_DPU1_ACLK, "gout_dpu_ssmt_dpu1_aclk",
"mout_dpu_bus_user",
CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU1_IPCLKPORT_ACLK, 21, 0, 0),
GATE(CLK_GOUT_DPU_SSMT_DPU1_PCLK, "gout_dpu_ssmt_dpu1_pclk",
"dout_dpu_busp",
CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU1_IPCLKPORT_PCLK, 21, 0, 0),
GATE(CLK_GOUT_DPU_SSMT_DPU2_ACLK, "gout_dpu_ssmt_dpu2_aclk",
"mout_dpu_bus_user",
CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU2_IPCLKPORT_ACLK, 21, 0, 0),
GATE(CLK_GOUT_DPU_SSMT_DPU2_PCLK, "gout_dpu_ssmt_dpu2_pclk",
"dout_dpu_busp",
CLK_CON_GAT_GOUT_BLK_DPU_UID_SSMT_DPU2_IPCLKPORT_PCLK, 21, 0, 0),
GATE(CLK_GOUT_DPU_SYSMMU_DPUD0_CLK_S1, "gout_dpu_sysmmu_dpud0_clk_s1",
"mout_dpu_bus_user",
CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD0_IPCLKPORT_CLK_S1,
21, 0, 0),
GATE(CLK_GOUT_DPU_SYSMMU_DPUD0_CLK_S2, "gout_dpu_sysmmu_dpud0_clk_s2",
"mout_dpu_bus_user",
CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD0_IPCLKPORT_CLK_S2,
21, 0, 0),
GATE(CLK_GOUT_DPU_SYSMMU_DPUD1_CLK_S1, "gout_dpu_sysmmu_dpud1_clk_s1",
"mout_dpu_bus_user",
CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD1_IPCLKPORT_CLK_S1,
21, 0, 0),
GATE(CLK_GOUT_DPU_SYSMMU_DPUD1_CLK_S2, "gout_dpu_sysmmu_dpud1_clk_s2",
"mout_dpu_bus_user",
CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD1_IPCLKPORT_CLK_S2,
21, 0, 0),
GATE(CLK_GOUT_DPU_SYSMMU_DPUD2_CLK_S1, "gout_dpu_sysmmu_dpud2_clk_s1",
"mout_dpu_bus_user",
CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD2_IPCLKPORT_CLK_S1,
21, 0, 0),
GATE(CLK_GOUT_DPU_SYSMMU_DPUD2_CLK_S2, "gout_dpu_sysmmu_dpud2_clk_s2",
"mout_dpu_bus_user",
CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSMMU_DPUD2_IPCLKPORT_CLK_S2, 21, 0, 0),
GATE(CLK_GOUT_DPU_SYSREG_DPU_PCLK, "gout_dpu_sysreg_dpu_pclk",
"dout_dpu_busp",
CLK_CON_GAT_GOUT_BLK_DPU_UID_SYSREG_DPU_IPCLKPORT_PCLK, 21, 0, 0),
};
static const struct samsung_cmu_info dpu_cmu_info __initconst = {
.mux_clks = dpu_mux_clks,
.nr_mux_clks = ARRAY_SIZE(dpu_mux_clks),
.div_clks = dpu_div_clks,
.nr_div_clks = ARRAY_SIZE(dpu_div_clks),
.gate_clks = dpu_gate_clks,
.nr_gate_clks = ARRAY_SIZE(dpu_gate_clks),
.nr_clk_ids = CLKS_NR_DPU,
.clk_regs = dpu_clk_regs,
.nr_clk_regs = ARRAY_SIZE(dpu_clk_regs),
.sysreg_clk_regs = dcrg_memclk_sysreg,
.nr_sysreg_clk_regs = ARRAY_SIZE(dcrg_memclk_sysreg),
.clk_name = "bus",
.auto_clock_gate = true,
.gate_dbg_offset = GS101_GATE_DBG_OFFSET,
.option_offset = DPU_CMU_DPU_CONTROLLER_OPTION,
.drcg_offset = GS101_DRCG_EN_OFFSET,
};
/* ---- CMU_HSI0 ------------------------------------------------------------ */
@ -2375,7 +2673,14 @@ static const struct samsung_cmu_info hsi0_cmu_info __initconst = {
.nr_clk_ids = CLKS_NR_HSI0,
.clk_regs = hsi0_clk_regs,
.nr_clk_regs = ARRAY_SIZE(hsi0_clk_regs),
.sysreg_clk_regs = dcrg_memclk_sysreg,
.nr_sysreg_clk_regs = ARRAY_SIZE(dcrg_memclk_sysreg),
.clk_name = "bus",
.auto_clock_gate = true,
.gate_dbg_offset = GS101_GATE_DBG_OFFSET,
.option_offset = HSI0_CMU_HSI0_CONTROLLER_OPTION,
.drcg_offset = GS101_DRCG_EN_OFFSET,
.memclk_offset = GS101_MEMCLK_OFFSET,
};
/* ---- CMU_HSI2 ------------------------------------------------------------ */
@ -2863,7 +3168,14 @@ static const struct samsung_cmu_info hsi2_cmu_info __initconst = {
.nr_clk_ids = CLKS_NR_HSI2,
.clk_regs = cmu_hsi2_clk_regs,
.nr_clk_regs = ARRAY_SIZE(cmu_hsi2_clk_regs),
.sysreg_clk_regs = dcrg_memclk_sysreg,
.nr_sysreg_clk_regs = ARRAY_SIZE(dcrg_memclk_sysreg),
.clk_name = "bus",
.auto_clock_gate = true,
.gate_dbg_offset = GS101_GATE_DBG_OFFSET,
.option_offset = HSI2_CMU_HSI2_CONTROLLER_OPTION,
.drcg_offset = GS101_DRCG_EN_OFFSET,
.memclk_offset = GS101_MEMCLK_OFFSET,
};
/* ---- CMU_MISC ------------------------------------------------------------ */
@ -3423,7 +3735,14 @@ static const struct samsung_cmu_info misc_cmu_info __initconst = {
.nr_clk_ids = CLKS_NR_MISC,
.clk_regs = misc_clk_regs,
.nr_clk_regs = ARRAY_SIZE(misc_clk_regs),
.sysreg_clk_regs = dcrg_memclk_sysreg,
.nr_sysreg_clk_regs = ARRAY_SIZE(dcrg_memclk_sysreg),
.clk_name = "bus",
.auto_clock_gate = true,
.gate_dbg_offset = GS101_GATE_DBG_OFFSET,
.option_offset = MISC_CMU_MISC_CONTROLLER_OPTION,
.drcg_offset = GS101_DRCG_EN_OFFSET,
.memclk_offset = GS101_MEMCLK_OFFSET,
};
static void __init gs101_cmu_misc_init(struct device_node *np)
@ -4010,6 +4329,10 @@ static const struct samsung_gate_clock peric0_gate_clks[] __initconst = {
21, 0, 0),
};
static const unsigned long dcrg_sysreg[] __initconst = {
GS101_DRCG_EN_OFFSET,
};
static const struct samsung_cmu_info peric0_cmu_info __initconst = {
.mux_clks = peric0_mux_clks,
.nr_mux_clks = ARRAY_SIZE(peric0_mux_clks),
@ -4020,7 +4343,13 @@ static const struct samsung_cmu_info peric0_cmu_info __initconst = {
.nr_clk_ids = CLKS_NR_PERIC0,
.clk_regs = peric0_clk_regs,
.nr_clk_regs = ARRAY_SIZE(peric0_clk_regs),
.sysreg_clk_regs = dcrg_sysreg,
.nr_sysreg_clk_regs = ARRAY_SIZE(dcrg_sysreg),
.clk_name = "bus",
.auto_clock_gate = true,
.gate_dbg_offset = GS101_GATE_DBG_OFFSET,
.option_offset = PERIC0_CMU_PERIC0_CONTROLLER_OPTION,
.drcg_offset = GS101_DRCG_EN_OFFSET,
};
/* ---- CMU_PERIC1 ---------------------------------------------------------- */
@ -4368,7 +4697,13 @@ static const struct samsung_cmu_info peric1_cmu_info __initconst = {
.nr_clk_ids = CLKS_NR_PERIC1,
.clk_regs = peric1_clk_regs,
.nr_clk_regs = ARRAY_SIZE(peric1_clk_regs),
.sysreg_clk_regs = dcrg_sysreg,
.nr_sysreg_clk_regs = ARRAY_SIZE(dcrg_sysreg),
.clk_name = "bus",
.auto_clock_gate = true,
.gate_dbg_offset = GS101_GATE_DBG_OFFSET,
.option_offset = PERIC1_CMU_PERIC1_CONTROLLER_OPTION,
.drcg_offset = GS101_DRCG_EN_OFFSET,
};
/* ---- platform_driver ----------------------------------------------------- */
@ -4388,6 +4723,9 @@ static const struct of_device_id gs101_cmu_of_match[] = {
{
.compatible = "google,gs101-cmu-apm",
.data = &apm_cmu_info,
}, {
.compatible = "google,gs101-cmu-dpu",
.data = &dpu_cmu_info,
}, {
.compatible = "google,gs101-cmu-hsi0",
.data = &hsi0_cmu_info,

View File

@ -449,10 +449,10 @@ void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f,
samsung_clk_register_alias(ctx, s3c64xx_clock_aliases,
ARRAY_SIZE(s3c64xx_clock_aliases));
samsung_clk_sleep_init(reg_base, s3c64xx_clk_regs,
samsung_clk_sleep_init(reg_base, NULL, s3c64xx_clk_regs,
ARRAY_SIZE(s3c64xx_clk_regs));
if (!is_s3c6400)
samsung_clk_sleep_init(reg_base, s3c6410_clk_regs,
samsung_clk_sleep_init(reg_base, NULL, s3c6410_clk_regs,
ARRAY_SIZE(s3c6410_clk_regs));
samsung_clk_of_add_provider(np, ctx);

View File

@ -782,7 +782,7 @@ static void __init __s5pv210_clk_init(struct device_node *np,
samsung_clk_register_alias(ctx, s5pv210_aliases,
ARRAY_SIZE(s5pv210_aliases));
samsung_clk_sleep_init(reg_base, s5pv210_clk_regs,
samsung_clk_sleep_init(reg_base, NULL, s5pv210_clk_regs,
ARRAY_SIZE(s5pv210_clk_regs));
samsung_clk_of_add_provider(np, ctx);

View File

@ -12,8 +12,10 @@
#include <linux/clkdev.h>
#include <linux/clk-provider.h>
#include <linux/io.h>
#include <linux/mfd/syscon.h>
#include <linux/mod_devicetable.h>
#include <linux/of_address.h>
#include <linux/regmap.h>
#include <linux/syscore_ops.h>
#include "clk.h"
@ -21,19 +23,29 @@
static LIST_HEAD(clock_reg_cache_list);
void samsung_clk_save(void __iomem *base,
struct regmap *regmap,
struct samsung_clk_reg_dump *rd,
unsigned int num_regs)
{
for (; num_regs > 0; --num_regs, ++rd)
rd->value = readl(base + rd->offset);
for (; num_regs > 0; --num_regs, ++rd) {
if (base)
rd->value = readl(base + rd->offset);
else if (regmap)
regmap_read(regmap, rd->offset, &rd->value);
}
}
void samsung_clk_restore(void __iomem *base,
struct regmap *regmap,
const struct samsung_clk_reg_dump *rd,
unsigned int num_regs)
{
for (; num_regs > 0; --num_regs, ++rd)
writel(rd->value, base + rd->offset);
for (; num_regs > 0; --num_regs, ++rd) {
if (base)
writel(rd->value, base + rd->offset);
else if (regmap)
regmap_write(regmap, rd->offset, rd->value);
}
}
struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump(
@ -227,6 +239,103 @@ void __init samsung_clk_register_div(struct samsung_clk_provider *ctx,
}
}
/*
* Some older DT's have an incorrect CMU resource size which is incompatible
* with the auto clock mode feature. In such cases we switch back to manual
* clock gating mode.
*/
bool samsung_is_auto_capable(struct device_node *np)
{
struct resource res;
resource_size_t size;
if (of_address_to_resource(np, 0, &res))
return false;
size = resource_size(&res);
if (size != 0x10000) {
pr_warn("%pOF: incorrect res size for automatic clocks\n", np);
return false;
}
return true;
}
#define ACG_MSK GENMASK(6, 4)
#define CLK_IDLE GENMASK(5, 4)
static int samsung_auto_clk_gate_is_en(struct clk_hw *hw)
{
u32 reg;
struct clk_gate *gate = to_clk_gate(hw);
reg = readl(gate->reg);
return ((reg & ACG_MSK) == CLK_IDLE) ? 0 : 1;
}
/* enable and disable are nops in automatic clock mode */
static int samsung_auto_clk_gate_en(struct clk_hw *hw)
{
return 0;
}
static void samsung_auto_clk_gate_dis(struct clk_hw *hw)
{
}
static const struct clk_ops samsung_auto_clk_gate_ops = {
.enable = samsung_auto_clk_gate_en,
.disable = samsung_auto_clk_gate_dis,
.is_enabled = samsung_auto_clk_gate_is_en,
};
struct clk_hw *samsung_register_auto_gate(struct device *dev,
struct device_node *np, const char *name,
const char *parent_name, const struct clk_hw *parent_hw,
const struct clk_parent_data *parent_data,
unsigned long flags,
void __iomem *reg, u8 bit_idx,
u8 clk_gate_flags, spinlock_t *lock)
{
struct clk_gate *gate;
struct clk_hw *hw;
struct clk_init_data init = {};
int ret = -EINVAL;
/* allocate the gate */
gate = kzalloc(sizeof(*gate), GFP_KERNEL);
if (!gate)
return ERR_PTR(-ENOMEM);
init.name = name;
init.ops = &samsung_auto_clk_gate_ops;
init.flags = flags;
init.parent_names = parent_name ? &parent_name : NULL;
init.parent_hws = parent_hw ? &parent_hw : NULL;
init.parent_data = parent_data;
if (parent_name || parent_hw || parent_data)
init.num_parents = 1;
else
init.num_parents = 0;
/* struct clk_gate assignments */
gate->reg = reg;
gate->bit_idx = bit_idx;
gate->flags = clk_gate_flags;
gate->lock = lock;
gate->hw.init = &init;
hw = &gate->hw;
if (dev || !np)
ret = clk_hw_register(dev, hw);
else if (np)
ret = of_clk_hw_register(np, hw);
if (ret) {
kfree(gate);
hw = ERR_PTR(ret);
}
return hw;
}
/* register a list of gate clocks */
void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx,
const struct samsung_gate_clock *list,
@ -234,14 +343,24 @@ void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx,
{
struct clk_hw *clk_hw;
unsigned int idx;
void __iomem *reg_offs;
for (idx = 0; idx < nr_clk; idx++, list++) {
clk_hw = clk_hw_register_gate(ctx->dev, list->name, list->parent_name,
list->flags, ctx->reg_base + list->offset,
reg_offs = ctx->reg_base + list->offset;
if (ctx->auto_clock_gate && ctx->gate_dbg_offset)
clk_hw = samsung_register_auto_gate(ctx->dev, NULL,
list->name, list->parent_name, NULL, NULL,
list->flags, reg_offs + ctx->gate_dbg_offset,
list->bit_idx, list->gate_flags, &ctx->lock);
else
clk_hw = clk_hw_register_gate(ctx->dev, list->name,
list->parent_name, list->flags,
ctx->reg_base + list->offset, list->bit_idx,
list->gate_flags, &ctx->lock);
if (IS_ERR(clk_hw)) {
pr_err("%s: failed to register clock %s\n", __func__,
list->name);
pr_err("%s: failed to register clock %s: %ld\n", __func__,
list->name, PTR_ERR(clk_hw));
continue;
}
@ -276,10 +395,11 @@ static int samsung_clk_suspend(void *data)
struct samsung_clock_reg_cache *reg_cache;
list_for_each_entry(reg_cache, &clock_reg_cache_list, node) {
samsung_clk_save(reg_cache->reg_base, reg_cache->rdump,
reg_cache->rd_num);
samsung_clk_restore(reg_cache->reg_base, reg_cache->rsuspend,
reg_cache->rsuspend_num);
samsung_clk_save(reg_cache->reg_base, reg_cache->sysreg,
reg_cache->rdump, reg_cache->rd_num);
samsung_clk_restore(reg_cache->reg_base, reg_cache->sysreg,
reg_cache->rsuspend,
reg_cache->rsuspend_num);
}
return 0;
}
@ -289,8 +409,8 @@ static void samsung_clk_resume(void *data)
struct samsung_clock_reg_cache *reg_cache;
list_for_each_entry(reg_cache, &clock_reg_cache_list, node)
samsung_clk_restore(reg_cache->reg_base, reg_cache->rdump,
reg_cache->rd_num);
samsung_clk_restore(reg_cache->reg_base, reg_cache->sysreg,
reg_cache->rdump, reg_cache->rd_num);
}
static const struct syscore_ops samsung_clk_syscore_ops = {
@ -303,6 +423,7 @@ static struct syscore samsung_clk_syscore = {
};
void samsung_clk_extended_sleep_init(void __iomem *reg_base,
struct regmap *sysreg,
const unsigned long *rdump,
unsigned long nr_rdump,
const struct samsung_clk_reg_dump *rsuspend,
@ -323,6 +444,7 @@ void samsung_clk_extended_sleep_init(void __iomem *reg_base,
register_syscore(&samsung_clk_syscore);
reg_cache->reg_base = reg_base;
reg_cache->sysreg = sysreg;
reg_cache->rd_num = nr_rdump;
reg_cache->rsuspend = rsuspend;
reg_cache->rsuspend_num = nr_rsuspend;
@ -334,10 +456,20 @@ void samsung_clk_extended_sleep_init(void __iomem *reg_base,
* samsung_cmu_register_clocks() - Register all clocks provided in CMU object
* @ctx: Clock provider object
* @cmu: CMU object with clocks to register
* @np: CMU device tree node
*/
void __init samsung_cmu_register_clocks(struct samsung_clk_provider *ctx,
const struct samsung_cmu_info *cmu)
const struct samsung_cmu_info *cmu,
struct device_node *np)
{
if (cmu->auto_clock_gate && samsung_is_auto_capable(np))
ctx->auto_clock_gate = cmu->auto_clock_gate;
ctx->gate_dbg_offset = cmu->gate_dbg_offset;
ctx->option_offset = cmu->option_offset;
ctx->drcg_offset = cmu->drcg_offset;
ctx->memclk_offset = cmu->memclk_offset;
if (cmu->pll_clks)
samsung_clk_register_pll(ctx, cmu->pll_clks, cmu->nr_pll_clks);
if (cmu->mux_clks)
@ -357,6 +489,44 @@ void __init samsung_cmu_register_clocks(struct samsung_clk_provider *ctx,
samsung_clk_register_cpu(ctx, cmu->cpu_clks, cmu->nr_cpu_clks);
}
/* Each bit enable/disables DRCG of a bus component */
#define DRCG_EN_MSK GENMASK(31, 0)
#define MEMCLK_EN BIT(0)
/* Enable Dynamic Root Clock Gating (DRCG) of bus components */
void samsung_en_dyn_root_clk_gating(struct device_node *np,
struct samsung_clk_provider *ctx,
const struct samsung_cmu_info *cmu,
bool cmu_has_pm)
{
if (!ctx->auto_clock_gate)
return;
ctx->sysreg = syscon_regmap_lookup_by_phandle(np, "samsung,sysreg");
if (IS_ERR(ctx->sysreg)) {
pr_warn("%pOF: Unable to get CMU sysreg\n", np);
ctx->sysreg = NULL;
} else {
/* Enable DRCG for all bus components */
regmap_write(ctx->sysreg, ctx->drcg_offset, DRCG_EN_MSK);
/* Enable memclk gate (not present on all sysreg) */
if (ctx->memclk_offset)
regmap_write_bits(ctx->sysreg, ctx->memclk_offset,
MEMCLK_EN, 0x0);
if (!cmu_has_pm)
/*
* When a CMU has PM support, clocks are saved/restored
* via its PM handlers, so only register them with the
* syscore suspend / resume paths if PM is not in use.
*/
samsung_clk_extended_sleep_init(NULL, ctx->sysreg,
cmu->sysreg_clk_regs,
cmu->nr_sysreg_clk_regs,
NULL, 0);
}
}
/*
* Common function which registers plls, muxes, dividers and gates
* for each CMU. It also add CMU register list to register cache.
@ -375,14 +545,17 @@ struct samsung_clk_provider * __init samsung_cmu_register_one(
}
ctx = samsung_clk_init(NULL, reg_base, cmu->nr_clk_ids);
samsung_cmu_register_clocks(ctx, cmu);
samsung_cmu_register_clocks(ctx, cmu, np);
if (cmu->clk_regs)
samsung_clk_extended_sleep_init(reg_base,
samsung_clk_extended_sleep_init(reg_base, NULL,
cmu->clk_regs, cmu->nr_clk_regs,
cmu->suspend_regs, cmu->nr_suspend_regs);
samsung_clk_of_add_provider(np, ctx);
/* sysreg DT nodes reference a clock in this CMU */
samsung_en_dyn_root_clk_gating(np, ctx, cmu, false);
return ctx;
}

View File

@ -12,6 +12,7 @@
#include <linux/clk-provider.h>
#include <linux/mod_devicetable.h>
#include <linux/regmap.h>
#include "clk-pll.h"
#include "clk-cpu.h"
@ -19,13 +20,25 @@
* struct samsung_clk_provider - information about clock provider
* @reg_base: virtual address for the register base
* @dev: clock provider device needed for runtime PM
* @sysreg: syscon regmap for clock-provider sysreg controller
* @lock: maintains exclusion between callbacks for a given clock-provider
* @auto_clock_gate: enable auto clk mode for all clocks in clock-provider
* @gate_dbg_offset: gate debug reg offset. Used for all gates in auto clk mode
* @option_offset: option reg offset. Enables auto mode for clock-provider
* @drcg_offset: dynamic root clk gate enable register offset in sysreg
* @memclk_offset: memclk enable register offset in sysreg
* @clk_data: holds clock related data like clk_hw* and number of clocks
*/
struct samsung_clk_provider {
void __iomem *reg_base;
struct device *dev;
struct regmap *sysreg;
spinlock_t lock;
bool auto_clock_gate;
u32 gate_dbg_offset;
u32 option_offset;
u32 drcg_offset;
u32 memclk_offset;
/* clk_data must be the last entry due to variable length 'hws' array */
struct clk_hw_onecell_data clk_data;
};
@ -310,6 +323,7 @@ struct samsung_cpu_clock {
struct samsung_clock_reg_cache {
struct list_head node;
void __iomem *reg_base;
struct regmap *sysreg;
struct samsung_clk_reg_dump *rdump;
unsigned int rd_num;
const struct samsung_clk_reg_dump *rsuspend;
@ -338,7 +352,14 @@ struct samsung_clock_reg_cache {
* @suspend_regs: list of clock registers to set before suspend
* @nr_suspend_regs: count of clock registers in @suspend_regs
* @clk_name: name of the parent clock needed for CMU register access
* @sysreg_clk_regs: list of sysreg clock registers
* @nr_sysreg_clk_regs: count of clock registers in @sysreg_clk_regs
* @manual_plls: Enable manual control for PLL clocks
* @auto_clock_gate: enable auto clock mode for all components in CMU
* @gate_dbg_offset: gate debug reg offset. Used by all gates in auto clk mode
* @option_offset: option reg offset. Enables auto clk mode for entire CMU
* @drcg_offset: dynamic root clk gate enable register offset in sysreg
* @memclk_offset: memclk enable register offset in sysreg
*/
struct samsung_cmu_info {
const struct samsung_pll_clock *pll_clks;
@ -364,8 +385,16 @@ struct samsung_cmu_info {
unsigned int nr_suspend_regs;
const char *clk_name;
const unsigned long *sysreg_clk_regs;
unsigned int nr_sysreg_clk_regs;
/* ARM64 Exynos CMUs */
bool manual_plls;
bool auto_clock_gate;
u32 gate_dbg_offset;
u32 option_offset;
u32 drcg_offset;
u32 memclk_offset;
};
struct samsung_clk_provider *samsung_clk_init(struct device *dev,
@ -408,35 +437,56 @@ void samsung_clk_register_cpu(struct samsung_clk_provider *ctx,
const struct samsung_cpu_clock *list, unsigned int nr_clk);
void samsung_cmu_register_clocks(struct samsung_clk_provider *ctx,
const struct samsung_cmu_info *cmu);
const struct samsung_cmu_info *cmu,
struct device_node *np);
struct samsung_clk_provider *samsung_cmu_register_one(
struct device_node *,
const struct samsung_cmu_info *);
#ifdef CONFIG_PM_SLEEP
void samsung_clk_extended_sleep_init(void __iomem *reg_base,
struct regmap *sysreg,
const unsigned long *rdump,
unsigned long nr_rdump,
const struct samsung_clk_reg_dump *rsuspend,
unsigned long nr_rsuspend);
#else
static inline void samsung_clk_extended_sleep_init(void __iomem *reg_base,
struct regmap *sysreg,
const unsigned long *rdump,
unsigned long nr_rdump,
const struct samsung_clk_reg_dump *rsuspend,
unsigned long nr_rsuspend) {}
#endif
#define samsung_clk_sleep_init(reg_base, rdump, nr_rdump) \
samsung_clk_extended_sleep_init(reg_base, rdump, nr_rdump, NULL, 0)
#define samsung_clk_sleep_init(reg_base, sysreg, rdump, nr_rdump) \
samsung_clk_extended_sleep_init(reg_base, sysreg, rdump, nr_rdump, \
NULL, 0)
void samsung_clk_save(void __iomem *base,
struct regmap *regmap,
struct samsung_clk_reg_dump *rd,
unsigned int num_regs);
void samsung_clk_restore(void __iomem *base,
struct regmap *regmap,
const struct samsung_clk_reg_dump *rd,
unsigned int num_regs);
struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump(
const unsigned long *rdump,
unsigned long nr_rdump);
void samsung_en_dyn_root_clk_gating(struct device_node *np,
struct samsung_clk_provider *ctx,
const struct samsung_cmu_info *cmu,
bool cmu_has_pm);
struct clk_hw *samsung_register_auto_gate(struct device *dev,
struct device_node *np, const char *name,
const char *parent_name, const struct clk_hw *parent_hw,
const struct clk_parent_data *parent_data,
unsigned long flags,
void __iomem *reg, u8 bit_idx,
u8 clk_gate_flags, spinlock_t *lock);
bool samsung_is_auto_capable(struct device_node *np);
#endif /* __SAMSUNG_CLK_H */

View File

@ -7,22 +7,38 @@
#include <dt-bindings/clock/thead,th1520-clk-ap.h>
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/delay.h>
#include <linux/device.h>
#include <linux/minmax.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#define TH1520_PLL_STS 0x80
#define TH1520_PLL_POSTDIV2 GENMASK(26, 24)
#define TH1520_PLL_POSTDIV1 GENMASK(22, 20)
#define TH1520_PLL_FBDIV GENMASK(19, 8)
#define TH1520_PLL_REFDIV GENMASK(5, 0)
#define TH1520_PLL_BYPASS BIT(30)
#define TH1520_PLL_VCO_RST BIT(29)
#define TH1520_PLL_DACPD BIT(25)
#define TH1520_PLL_DSMPD BIT(24)
#define TH1520_PLL_FRAC GENMASK(23, 0)
#define TH1520_PLL_FRAC_BITS 24
/*
* All PLLs in TH1520 take 21250ns at maximum to lock, let's take its double
* for safety.
*/
#define TH1520_PLL_LOCK_TIMEOUT_US 44
#define TH1520_PLL_STABLE_DELAY_US 30
/* c910_bus_clk must be kept below 750MHz for stability */
#define TH1520_C910_BUS_MAX_RATE (750 * 1000 * 1000)
struct ccu_internal {
u8 shift;
u8 width;
@ -62,8 +78,19 @@ struct ccu_div {
struct ccu_common common;
};
struct ccu_pll_cfg {
unsigned long freq;
u32 fbdiv;
u32 frac;
u32 postdiv1;
u32 postdiv2;
};
struct ccu_pll {
struct ccu_common common;
u32 lock_sts_mask;
int cfgnum;
const struct ccu_pll_cfg *cfgs;
};
#define TH_CCU_ARG(_shift, _width) \
@ -79,17 +106,22 @@ struct ccu_pll {
.flags = _flags, \
}
#define TH_CCU_MUX(_name, _parents, _shift, _width) \
#define TH_CCU_MUX_FLAGS(_name, _parents, _shift, _width, _flags, \
_mux_flags) \
{ \
.mask = GENMASK(_width - 1, 0), \
.shift = _shift, \
.flags = _mux_flags, \
.hw.init = CLK_HW_INIT_PARENTS_DATA( \
_name, \
_parents, \
&clk_mux_ops, \
0), \
_flags), \
}
#define TH_CCU_MUX(_name, _parents, _shift, _width) \
TH_CCU_MUX_FLAGS(_name, _parents, _shift, _width, 0, 0)
#define CCU_GATE(_clkid, _struct, _name, _parent, _reg, _bit, _flags) \
struct ccu_gate _struct = { \
.clkid = _clkid, \
@ -299,9 +331,21 @@ static void ccu_pll_disable(struct clk_hw *hw)
static int ccu_pll_enable(struct clk_hw *hw)
{
struct ccu_pll *pll = hw_to_ccu_pll(hw);
u32 reg;
int ret;
return regmap_clear_bits(pll->common.map, pll->common.cfg1,
TH1520_PLL_VCO_RST);
regmap_clear_bits(pll->common.map, pll->common.cfg1,
TH1520_PLL_VCO_RST);
ret = regmap_read_poll_timeout_atomic(pll->common.map, TH1520_PLL_STS,
reg, reg & pll->lock_sts_mask,
5, TH1520_PLL_LOCK_TIMEOUT_US);
if (ret)
return ret;
udelay(TH1520_PLL_STABLE_DELAY_US);
return 0;
}
static int ccu_pll_is_enabled(struct clk_hw *hw)
@ -368,17 +412,168 @@ static unsigned long ccu_pll_recalc_rate(struct clk_hw *hw,
return rate;
}
static const struct ccu_pll_cfg *ccu_pll_lookup_best_cfg(struct ccu_pll *pll,
unsigned long rate)
{
unsigned long best_delta = ULONG_MAX;
const struct ccu_pll_cfg *best_cfg;
int i;
for (i = 0; i < pll->cfgnum; i++) {
const struct ccu_pll_cfg *cfg = &pll->cfgs[i];
unsigned long delta;
delta = abs_diff(cfg->freq, rate);
if (delta < best_delta) {
best_delta = delta;
best_cfg = cfg;
}
}
return best_cfg;
}
static int ccu_pll_determine_rate(struct clk_hw *hw,
struct clk_rate_request *req)
{
struct ccu_pll *pll = hw_to_ccu_pll(hw);
req->rate = ccu_pll_lookup_best_cfg(pll, req->rate)->freq;
return 0;
}
static int ccu_pll_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct ccu_pll *pll = hw_to_ccu_pll(hw);
const struct ccu_pll_cfg *cfg;
cfg = ccu_pll_lookup_best_cfg(pll, rate);
ccu_pll_disable(hw);
regmap_write(pll->common.map, pll->common.cfg0,
FIELD_PREP(TH1520_PLL_REFDIV, 1) |
FIELD_PREP(TH1520_PLL_FBDIV, cfg->fbdiv) |
FIELD_PREP(TH1520_PLL_POSTDIV1, cfg->postdiv1) |
FIELD_PREP(TH1520_PLL_POSTDIV2, cfg->postdiv2));
regmap_update_bits(pll->common.map, pll->common.cfg1,
TH1520_PLL_DACPD | TH1520_PLL_DSMPD |
TH1520_PLL_FRAC,
cfg->frac ? cfg->frac :
TH1520_PLL_DACPD | TH1520_PLL_DSMPD);
return ccu_pll_enable(hw);
}
static const struct clk_ops clk_pll_ops = {
.disable = ccu_pll_disable,
.enable = ccu_pll_enable,
.is_enabled = ccu_pll_is_enabled,
.recalc_rate = ccu_pll_recalc_rate,
.determine_rate = ccu_pll_determine_rate,
.set_rate = ccu_pll_set_rate,
};
/*
* c910_clk could be reparented glitchlessly for DVFS. There are two parents,
* - c910_i0_clk, derived from cpu_pll0_clk or osc_24m.
* - cpu_pll1_clk, which provides the exact same set of rates as cpu_pll0_clk.
*
* During rate setting, always forward the request to the unused parent, and
* then switch c910_clk to it to avoid glitch.
*/
static u8 c910_clk_get_parent(struct clk_hw *hw)
{
return clk_mux_ops.get_parent(hw);
}
static int c910_clk_set_parent(struct clk_hw *hw, u8 index)
{
return clk_mux_ops.set_parent(hw, index);
}
static unsigned long c910_clk_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
return parent_rate;
}
static int c910_clk_determine_rate(struct clk_hw *hw,
struct clk_rate_request *req)
{
u8 alt_parent_index = !c910_clk_get_parent(hw);
struct clk_hw *alt_parent;
alt_parent = clk_hw_get_parent_by_index(hw, alt_parent_index);
req->rate = clk_hw_round_rate(alt_parent, req->rate);
req->best_parent_hw = alt_parent;
req->best_parent_rate = req->rate;
return 0;
}
static int c910_clk_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
return -EOPNOTSUPP;
}
static int c910_clk_set_rate_and_parent(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate, u8 index)
{
struct clk_hw *parent = clk_hw_get_parent_by_index(hw, index);
clk_set_rate(parent->clk, parent_rate);
c910_clk_set_parent(hw, index);
return 0;
}
static const struct clk_ops c910_clk_ops = {
.get_parent = c910_clk_get_parent,
.set_parent = c910_clk_set_parent,
.recalc_rate = c910_clk_recalc_rate,
.determine_rate = c910_clk_determine_rate,
.set_rate = c910_clk_set_rate,
.set_rate_and_parent = c910_clk_set_rate_and_parent,
};
static const struct clk_parent_data osc_24m_clk[] = {
{ .index = 0 }
};
static const struct ccu_pll_cfg cpu_pll_cfgs[] = {
{ 125000000, 125, 0, 6, 4 },
{ 200000000, 125, 0, 5, 3 },
{ 300000000, 125, 0, 5, 2 },
{ 400000000, 100, 0, 3, 2 },
{ 500000000, 125, 0, 6, 1 },
{ 600000000, 125, 0, 5, 1 },
{ 702000000, 117, 0, 4, 1 },
{ 800000000, 100, 0, 3, 1 },
{ 900000000, 75, 0, 2, 1 },
{ 1000000000, 125, 0, 3, 1 },
{ 1104000000, 92, 0, 2, 1 },
{ 1200000000, 100, 0, 2, 1 },
{ 1296000000, 108, 0, 2, 1 },
{ 1404000000, 117, 0, 2, 1 },
{ 1500000000, 125, 0, 2, 1 },
{ 1608000000, 67, 0, 1, 1 },
{ 1704000000, 71, 0, 1, 1 },
{ 1800000000, 75, 0, 1, 1 },
{ 1896000000, 79, 0, 1, 1 },
{ 1992000000, 83, 0, 1, 1 },
{ 2112000000, 88, 0, 1, 1 },
{ 2208000000, 92, 0, 1, 1 },
{ 2304000000, 96, 0, 1, 1 },
{ 2400000000, 100, 0, 1, 1 },
};
static struct ccu_pll cpu_pll0_clk = {
.common = {
.clkid = CLK_CPU_PLL0,
@ -389,6 +584,9 @@ static struct ccu_pll cpu_pll0_clk = {
&clk_pll_ops,
CLK_IS_CRITICAL),
},
.lock_sts_mask = BIT(1),
.cfgnum = ARRAY_SIZE(cpu_pll_cfgs),
.cfgs = cpu_pll_cfgs,
};
static struct ccu_pll cpu_pll1_clk = {
@ -401,6 +599,17 @@ static struct ccu_pll cpu_pll1_clk = {
&clk_pll_ops,
CLK_IS_CRITICAL),
},
.lock_sts_mask = BIT(4),
.cfgnum = ARRAY_SIZE(cpu_pll_cfgs),
.cfgs = cpu_pll_cfgs,
};
static const struct ccu_pll_cfg gmac_pll_cfg = {
.freq = 1000000000,
.fbdiv = 125,
.frac = 0,
.postdiv1 = 3,
.postdiv2 = 1,
};
static struct ccu_pll gmac_pll_clk = {
@ -413,6 +622,9 @@ static struct ccu_pll gmac_pll_clk = {
&clk_pll_ops,
CLK_IS_CRITICAL),
},
.lock_sts_mask = BIT(3),
.cfgnum = 1,
.cfgs = &gmac_pll_cfg,
};
static const struct clk_hw *gmac_pll_clk_parent[] = {
@ -423,6 +635,14 @@ static const struct clk_parent_data gmac_pll_clk_pd[] = {
{ .hw = &gmac_pll_clk.common.hw }
};
static const struct ccu_pll_cfg video_pll_cfg = {
.freq = 792000000,
.fbdiv = 99,
.frac = 0,
.postdiv1 = 3,
.postdiv2 = 1,
};
static struct ccu_pll video_pll_clk = {
.common = {
.clkid = CLK_VIDEO_PLL,
@ -433,6 +653,9 @@ static struct ccu_pll video_pll_clk = {
&clk_pll_ops,
CLK_IS_CRITICAL),
},
.lock_sts_mask = BIT(7),
.cfgnum = 1,
.cfgs = &video_pll_cfg,
};
static const struct clk_hw *video_pll_clk_parent[] = {
@ -443,6 +666,14 @@ static const struct clk_parent_data video_pll_clk_pd[] = {
{ .hw = &video_pll_clk.common.hw }
};
static const struct ccu_pll_cfg dpu_pll_cfg = {
.freq = 1188000000,
.fbdiv = 99,
.frac = 0,
.postdiv1 = 2,
.postdiv2 = 1,
};
static struct ccu_pll dpu0_pll_clk = {
.common = {
.clkid = CLK_DPU0_PLL,
@ -453,6 +684,9 @@ static struct ccu_pll dpu0_pll_clk = {
&clk_pll_ops,
0),
},
.lock_sts_mask = BIT(8),
.cfgnum = 1,
.cfgs = &dpu_pll_cfg,
};
static const struct clk_hw *dpu0_pll_clk_parent[] = {
@ -469,12 +703,23 @@ static struct ccu_pll dpu1_pll_clk = {
&clk_pll_ops,
0),
},
.lock_sts_mask = BIT(9),
.cfgnum = 1,
.cfgs = &dpu_pll_cfg,
};
static const struct clk_hw *dpu1_pll_clk_parent[] = {
&dpu1_pll_clk.common.hw
};
static const struct ccu_pll_cfg tee_pll_cfg = {
.freq = 792000000,
.fbdiv = 99,
.frac = 0,
.postdiv1 = 3,
.postdiv2 = 1,
};
static struct ccu_pll tee_pll_clk = {
.common = {
.clkid = CLK_TEE_PLL,
@ -485,6 +730,9 @@ static struct ccu_pll tee_pll_clk = {
&clk_pll_ops,
CLK_IS_CRITICAL),
},
.lock_sts_mask = BIT(10),
.cfgnum = 1,
.cfgs = &tee_pll_cfg,
};
static const struct clk_parent_data c910_i0_parents[] = {
@ -495,7 +743,8 @@ static const struct clk_parent_data c910_i0_parents[] = {
static struct ccu_mux c910_i0_clk = {
.clkid = CLK_C910_I0,
.reg = 0x100,
.mux = TH_CCU_MUX("c910-i0", c910_i0_parents, 1, 1),
.mux = TH_CCU_MUX_FLAGS("c910-i0", c910_i0_parents, 1, 1,
CLK_SET_RATE_PARENT, CLK_MUX_ROUND_CLOSEST),
};
static const struct clk_parent_data c910_parents[] = {
@ -506,7 +755,28 @@ static const struct clk_parent_data c910_parents[] = {
static struct ccu_mux c910_clk = {
.clkid = CLK_C910,
.reg = 0x100,
.mux = TH_CCU_MUX("c910", c910_parents, 0, 1),
.mux = {
.mask = BIT(0),
.shift = 0,
.hw.init = CLK_HW_INIT_PARENTS_DATA("c910",
c910_parents,
&c910_clk_ops,
CLK_SET_RATE_PARENT),
},
};
static struct ccu_div c910_bus_clk = {
.enable = BIT(7),
.div_en = BIT(11),
.div = TH_CCU_DIV_FLAGS(8, 3, 0),
.common = {
.clkid = CLK_C910_BUS,
.cfg0 = 0x100,
.hw.init = CLK_HW_INIT_HW("c910-bus",
&c910_clk.mux.hw,
&ccu_div_ops,
CLK_IS_CRITICAL),
},
};
static const struct clk_parent_data ahb2_cpusys_parents[] = {
@ -1021,6 +1291,7 @@ static struct ccu_common *th1520_pll_clks[] = {
};
static struct ccu_common *th1520_div_clks[] = {
&c910_bus_clk.common,
&ahb2_cpusys_hclk.common,
&apb3_cpusys_pclk.common,
&axi4_cpusys2_aclk.common,
@ -1164,7 +1435,7 @@ static const struct th1520_plat_data th1520_ap_platdata = {
.th1520_mux_clks = th1520_mux_clks,
.th1520_gate_clks = th1520_gate_clks,
.nr_clks = CLK_UART_SCLK + 1,
.nr_clks = CLK_C910_BUS + 1,
.nr_pll_clks = ARRAY_SIZE(th1520_pll_clks),
.nr_div_clks = ARRAY_SIZE(th1520_div_clks),
@ -1180,11 +1451,69 @@ static const struct th1520_plat_data th1520_vo_platdata = {
.nr_gate_clks = ARRAY_SIZE(th1520_vo_gate_clks),
};
/*
* Maintain clock rate of c910_bus_clk below TH1520_C910_BUS_MAX_RATE (750MHz)
* when its parent, c910_clk, changes the rate.
*
* Additionally, TRM is unclear about c910_bus_clk behavior when the divisor is
* set below 2, thus we should ensure the new divisor stays in (2, MAXDIVISOR).
*/
static unsigned long c910_bus_clk_divisor(struct ccu_div *cd,
unsigned long parent_rate)
{
return clamp(DIV_ROUND_UP(parent_rate, TH1520_C910_BUS_MAX_RATE),
2U, 1U << cd->div.width);
}
static int c910_clk_notifier_cb(struct notifier_block *nb,
unsigned long action, void *data)
{
struct clk_notifier_data *cnd = data;
unsigned long new_divisor, ref_rate;
if (action != PRE_RATE_CHANGE && action != POST_RATE_CHANGE)
return NOTIFY_DONE;
new_divisor = c910_bus_clk_divisor(&c910_bus_clk, cnd->new_rate);
if (cnd->new_rate > cnd->old_rate) {
/*
* Scaling up. Adjust c910_bus_clk divisor
* - before c910_clk rate change to ensure the constraints
* aren't broken after scaling to higher rates,
* - after c910_clk rate change to keep c910_bus_clk as high as
* possible
*/
ref_rate = action == PRE_RATE_CHANGE ?
cnd->old_rate : cnd->new_rate;
clk_set_rate(c910_bus_clk.common.hw.clk,
ref_rate / new_divisor);
} else if (cnd->new_rate < cnd->old_rate &&
action == POST_RATE_CHANGE) {
/*
* Scaling down. Adjust c910_bus_clk divisor only after
* c910_clk rate change to keep c910_bus_clk as high as
* possible, Scaling down never breaks the constraints.
*/
clk_set_rate(c910_bus_clk.common.hw.clk,
cnd->new_rate / new_divisor);
} else {
return NOTIFY_DONE;
}
return NOTIFY_OK;
}
static struct notifier_block c910_clk_notifier = {
.notifier_call = c910_clk_notifier_cb,
};
static int th1520_clk_probe(struct platform_device *pdev)
{
const struct th1520_plat_data *plat_data;
struct device *dev = &pdev->dev;
struct clk_hw_onecell_data *priv;
struct clk *notifier_clk;
struct regmap *map;
void __iomem *base;
@ -1271,6 +1600,13 @@ static int th1520_clk_probe(struct platform_device *pdev)
ret = devm_clk_hw_register(dev, &emmc_sdio_ref_clk.hw);
if (ret)
return ret;
notifier_clk = devm_clk_hw_get_clk(dev, &c910_clk.mux.hw,
"dvfs");
ret = devm_clk_notifier_register(dev, notifier_clk,
&c910_clk_notifier);
if (ret)
return ret;
}
ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, priv);

View File

@ -232,5 +232,16 @@
#define CLKID_HDCP22_SKPCLK_SEL 222
#define CLKID_HDCP22_SKPCLK_DIV 223
#define CLKID_HDCP22_SKPCLK 224
#define CLKID_CTS_ENCL_SEL 225
#define CLKID_CTS_ENCL 226
#define CLKID_CDAC_SEL 227
#define CLKID_CDAC_DIV 228
#define CLKID_CDAC 229
#define CLKID_DEMOD_CORE_SEL 230
#define CLKID_DEMOD_CORE_DIV 231
#define CLKID_DEMOD_CORE 232
#define CLKID_ADC_EXTCLK_IN_SEL 233
#define CLKID_ADC_EXTCLK_IN_DIV 234
#define CLKID_ADC_EXTCLK_IN 235
#endif /* _DT_BINDINGS_CLOCK_AMLOGIC_S4_PERIPHERALS_CLKC_H */

View File

@ -0,0 +1,228 @@
/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
/*
* Copyright (C) 2024-2025 Amlogic, Inc. All rights reserved
*/
#ifndef __T7_PERIPHERALS_CLKC_H
#define __T7_PERIPHERALS_CLKC_H
#define CLKID_RTC_DUALDIV_IN 0
#define CLKID_RTC_DUALDIV_DIV 1
#define CLKID_RTC_DUALDIV_SEL 2
#define CLKID_RTC_DUALDIV 3
#define CLKID_RTC 4
#define CLKID_CECA_DUALDIV_IN 5
#define CLKID_CECA_DUALDIV_DIV 6
#define CLKID_CECA_DUALDIV_SEL 7
#define CLKID_CECA_DUALDIV 8
#define CLKID_CECA 9
#define CLKID_CECB_DUALDIV_IN 10
#define CLKID_CECB_DUALDIV_DIV 11
#define CLKID_CECB_DUALDIV_SEL 12
#define CLKID_CECB_DUALDIV 13
#define CLKID_CECB 14
#define CLKID_SC_SEL 15
#define CLKID_SC_DIV 16
#define CLKID_SC 17
#define CLKID_DSPA_0_SEL 18
#define CLKID_DSPA_0_DIV 19
#define CLKID_DSPA_0 20
#define CLKID_DSPA_1_SEL 21
#define CLKID_DSPA_1_DIV 22
#define CLKID_DSPA_1 23
#define CLKID_DSPA 24
#define CLKID_DSPB_0_SEL 25
#define CLKID_DSPB_0_DIV 26
#define CLKID_DSPB_0 27
#define CLKID_DSPB_1_SEL 28
#define CLKID_DSPB_1_DIV 29
#define CLKID_DSPB_1 30
#define CLKID_DSPB 31
#define CLKID_24M 32
#define CLKID_24M_DIV2 33
#define CLKID_12M 34
#define CLKID_25M_DIV 35
#define CLKID_25M 36
#define CLKID_ANAKIN_0_SEL 37
#define CLKID_ANAKIN_0_DIV 38
#define CLKID_ANAKIN_0 39
#define CLKID_ANAKIN_1_SEL 40
#define CLKID_ANAKIN_1_DIV 41
#define CLKID_ANAKIN_1 42
#define CLKID_ANAKIN_01_SEL 43
#define CLKID_ANAKIN 44
#define CLKID_TS_DIV 45
#define CLKID_TS 46
#define CLKID_MIPI_CSI_PHY_0_SEL 47
#define CLKID_MIPI_CSI_PHY_0_DIV 48
#define CLKID_MIPI_CSI_PHY_0 49
#define CLKID_MIPI_CSI_PHY_1_SEL 50
#define CLKID_MIPI_CSI_PHY_1_DIV 51
#define CLKID_MIPI_CSI_PHY_1 52
#define CLKID_MIPI_CSI_PHY 53
#define CLKID_MIPI_ISP_SEL 54
#define CLKID_MIPI_ISP_DIV 55
#define CLKID_MIPI_ISP 56
#define CLKID_MALI_0_SEL 57
#define CLKID_MALI_0_DIV 58
#define CLKID_MALI_0 59
#define CLKID_MALI_1_SEL 60
#define CLKID_MALI_1_DIV 61
#define CLKID_MALI_1 62
#define CLKID_MALI 63
#define CLKID_ETH_RMII_SEL 64
#define CLKID_ETH_RMII_DIV 65
#define CLKID_ETH_RMII 66
#define CLKID_FCLK_DIV2_DIV8 67
#define CLKID_ETH_125M 68
#define CLKID_SD_EMMC_A_SEL 69
#define CLKID_SD_EMMC_A_DIV 70
#define CLKID_SD_EMMC_A 71
#define CLKID_SD_EMMC_B_SEL 72
#define CLKID_SD_EMMC_B_DIV 73
#define CLKID_SD_EMMC_B 74
#define CLKID_SD_EMMC_C_SEL 75
#define CLKID_SD_EMMC_C_DIV 76
#define CLKID_SD_EMMC_C 77
#define CLKID_SPICC0_SEL 78
#define CLKID_SPICC0_DIV 79
#define CLKID_SPICC0 80
#define CLKID_SPICC1_SEL 81
#define CLKID_SPICC1_DIV 82
#define CLKID_SPICC1 83
#define CLKID_SPICC2_SEL 84
#define CLKID_SPICC2_DIV 85
#define CLKID_SPICC2 86
#define CLKID_SPICC3_SEL 87
#define CLKID_SPICC3_DIV 88
#define CLKID_SPICC3 89
#define CLKID_SPICC4_SEL 90
#define CLKID_SPICC4_DIV 91
#define CLKID_SPICC4 92
#define CLKID_SPICC5_SEL 93
#define CLKID_SPICC5_DIV 94
#define CLKID_SPICC5 95
#define CLKID_SARADC_SEL 96
#define CLKID_SARADC_DIV 97
#define CLKID_SARADC 98
#define CLKID_PWM_A_SEL 99
#define CLKID_PWM_A_DIV 100
#define CLKID_PWM_A 101
#define CLKID_PWM_B_SEL 102
#define CLKID_PWM_B_DIV 103
#define CLKID_PWM_B 104
#define CLKID_PWM_C_SEL 105
#define CLKID_PWM_C_DIV 106
#define CLKID_PWM_C 107
#define CLKID_PWM_D_SEL 108
#define CLKID_PWM_D_DIV 109
#define CLKID_PWM_D 110
#define CLKID_PWM_E_SEL 111
#define CLKID_PWM_E_DIV 112
#define CLKID_PWM_E 113
#define CLKID_PWM_F_SEL 114
#define CLKID_PWM_F_DIV 115
#define CLKID_PWM_F 116
#define CLKID_PWM_AO_A_SEL 117
#define CLKID_PWM_AO_A_DIV 118
#define CLKID_PWM_AO_A 119
#define CLKID_PWM_AO_B_SEL 120
#define CLKID_PWM_AO_B_DIV 121
#define CLKID_PWM_AO_B 122
#define CLKID_PWM_AO_C_SEL 123
#define CLKID_PWM_AO_C_DIV 124
#define CLKID_PWM_AO_C 125
#define CLKID_PWM_AO_D_SEL 126
#define CLKID_PWM_AO_D_DIV 127
#define CLKID_PWM_AO_D 128
#define CLKID_PWM_AO_E_SEL 129
#define CLKID_PWM_AO_E_DIV 130
#define CLKID_PWM_AO_E 131
#define CLKID_PWM_AO_F_SEL 132
#define CLKID_PWM_AO_F_DIV 133
#define CLKID_PWM_AO_F 134
#define CLKID_PWM_AO_G_SEL 135
#define CLKID_PWM_AO_G_DIV 136
#define CLKID_PWM_AO_G 137
#define CLKID_PWM_AO_H_SEL 138
#define CLKID_PWM_AO_H_DIV 139
#define CLKID_PWM_AO_H 140
#define CLKID_SYS_DDR 141
#define CLKID_SYS_DOS 142
#define CLKID_SYS_MIPI_DSI_A 143
#define CLKID_SYS_MIPI_DSI_B 144
#define CLKID_SYS_ETHPHY 145
#define CLKID_SYS_MALI 146
#define CLKID_SYS_AOCPU 147
#define CLKID_SYS_AUCPU 148
#define CLKID_SYS_CEC 149
#define CLKID_SYS_GDC 150
#define CLKID_SYS_DESWARP 151
#define CLKID_SYS_AMPIPE_NAND 152
#define CLKID_SYS_AMPIPE_ETH 153
#define CLKID_SYS_AM2AXI0 154
#define CLKID_SYS_AM2AXI1 155
#define CLKID_SYS_AM2AXI2 156
#define CLKID_SYS_SD_EMMC_A 157
#define CLKID_SYS_SD_EMMC_B 158
#define CLKID_SYS_SD_EMMC_C 159
#define CLKID_SYS_SMARTCARD 160
#define CLKID_SYS_ACODEC 161
#define CLKID_SYS_SPIFC 162
#define CLKID_SYS_MSR_CLK 163
#define CLKID_SYS_IR_CTRL 164
#define CLKID_SYS_AUDIO 165
#define CLKID_SYS_ETH 166
#define CLKID_SYS_UART_A 167
#define CLKID_SYS_UART_B 168
#define CLKID_SYS_UART_C 169
#define CLKID_SYS_UART_D 170
#define CLKID_SYS_UART_E 171
#define CLKID_SYS_UART_F 172
#define CLKID_SYS_AIFIFO 173
#define CLKID_SYS_SPICC2 174
#define CLKID_SYS_SPICC3 175
#define CLKID_SYS_SPICC4 176
#define CLKID_SYS_TS_A73 177
#define CLKID_SYS_TS_A53 178
#define CLKID_SYS_SPICC5 179
#define CLKID_SYS_G2D 180
#define CLKID_SYS_SPICC0 181
#define CLKID_SYS_SPICC1 182
#define CLKID_SYS_PCIE 183
#define CLKID_SYS_USB 184
#define CLKID_SYS_PCIE_PHY 185
#define CLKID_SYS_I2C_AO_A 186
#define CLKID_SYS_I2C_AO_B 187
#define CLKID_SYS_I2C_M_A 188
#define CLKID_SYS_I2C_M_B 189
#define CLKID_SYS_I2C_M_C 190
#define CLKID_SYS_I2C_M_D 191
#define CLKID_SYS_I2C_M_E 192
#define CLKID_SYS_I2C_M_F 193
#define CLKID_SYS_HDMITX_APB 194
#define CLKID_SYS_I2C_S_A 195
#define CLKID_SYS_HDMIRX_PCLK 196
#define CLKID_SYS_MMC_APB 197
#define CLKID_SYS_MIPI_ISP_PCLK 198
#define CLKID_SYS_RSA 199
#define CLKID_SYS_PCLK_SYS_APB 200
#define CLKID_SYS_A73PCLK_APB 201
#define CLKID_SYS_DSPA 202
#define CLKID_SYS_DSPB 203
#define CLKID_SYS_VPU_INTR 204
#define CLKID_SYS_SAR_ADC 205
#define CLKID_SYS_GIC 206
#define CLKID_SYS_TS_GPU 207
#define CLKID_SYS_TS_NNA 208
#define CLKID_SYS_TS_VPU 209
#define CLKID_SYS_TS_HEVC 210
#define CLKID_SYS_PWM_AB 211
#define CLKID_SYS_PWM_CD 212
#define CLKID_SYS_PWM_EF 213
#define CLKID_SYS_PWM_AO_AB 214
#define CLKID_SYS_PWM_AO_CD 215
#define CLKID_SYS_PWM_AO_EF 216
#define CLKID_SYS_PWM_AO_GH 217
#endif /* __T7_PERIPHERALS_CLKC_H */

View File

@ -0,0 +1,56 @@
/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
/*
* Copyright (C) 2024-2025 Amlogic, Inc. All rights reserved
*/
#ifndef __T7_PLL_CLKC_H
#define __T7_PLL_CLKC_H
/* GP0 */
#define CLKID_GP0_PLL_DCO 0
#define CLKID_GP0_PLL 1
/* GP1 */
#define CLKID_GP1_PLL_DCO 0
#define CLKID_GP1_PLL 1
/* HIFI */
#define CLKID_HIFI_PLL_DCO 0
#define CLKID_HIFI_PLL 1
/* PCIE */
#define CLKID_PCIE_PLL_DCO 0
#define CLKID_PCIE_PLL_DCO_DIV2 1
#define CLKID_PCIE_PLL_OD 2
#define CLKID_PCIE_PLL 3
/* MPLL */
#define CLKID_MPLL_PREDIV 0
#define CLKID_MPLL0_DIV 1
#define CLKID_MPLL0 2
#define CLKID_MPLL1_DIV 3
#define CLKID_MPLL1 4
#define CLKID_MPLL2_DIV 5
#define CLKID_MPLL2 6
#define CLKID_MPLL3_DIV 7
#define CLKID_MPLL3 8
/* HDMI */
#define CLKID_HDMI_PLL_DCO 0
#define CLKID_HDMI_PLL_OD 1
#define CLKID_HDMI_PLL 2
/* MCLK */
#define CLKID_MCLK_PLL_DCO 0
#define CLKID_MCLK_PRE 1
#define CLKID_MCLK_PLL 2
#define CLKID_MCLK_0_SEL 3
#define CLKID_MCLK_0_DIV2 4
#define CLKID_MCLK_0_PRE 5
#define CLKID_MCLK_0 6
#define CLKID_MCLK_1_SEL 7
#define CLKID_MCLK_1_DIV2 8
#define CLKID_MCLK_1_PRE 9
#define CLKID_MCLK_1 10
#endif /* __T7_PLL_CLKC_H */

View File

@ -0,0 +1,47 @@
/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
/*
* Copyright (C) 2024-2025 Amlogic, Inc. All rights reserved
*/
#ifndef __T7_SCMI_CLKC_H
#define __T7_SCMI_CLKC_H
#define CLKID_DDR_PLL_OSC 0
#define CLKID_AUD_PLL_OSC 1
#define CLKID_TOP_PLL_OSC 2
#define CLKID_TCON_PLL_OSC 3
#define CLKID_USB_PLL0_OSC 4
#define CLKID_USB_PLL1_OSC 5
#define CLKID_MCLK_PLL_OSC 6
#define CLKID_PCIE_OSC 7
#define CLKID_ETH_PLL_OSC 8
#define CLKID_PCIE_REFCLK_PLL_OSC 9
#define CLKID_EARC_OSC 10
#define CLKID_SYS1_PLL_OSC 11
#define CLKID_HDMI_PLL_OSC 12
#define CLKID_SYS_CLK 13
#define CLKID_AXI_CLK 14
#define CLKID_FIXED_PLL_DCO 15
#define CLKID_FIXED_PLL 16
#define CLKID_FCLK_DIV2_DIV 17
#define CLKID_FCLK_DIV2 18
#define CLKID_FCLK_DIV2P5_DIV 19
#define CLKID_FCLK_DIV2P5 20
#define CLKID_FCLK_DIV3_DIV 21
#define CLKID_FCLK_DIV3 22
#define CLKID_FCLK_DIV4_DIV 23
#define CLKID_FCLK_DIV4 24
#define CLKID_FCLK_DIV5_DIV 25
#define CLKID_FCLK_DIV5 26
#define CLKID_FCLK_DIV7_DIV 27
#define CLKID_FCLK_DIV7 28
#define CLKID_FCLK_50M_DIV 29
#define CLKID_FCLK_50M 30
#define CLKID_CPU_CLK 31
#define CLKID_A73_CLK 32
#define CLKID_CPU_CLK_DIV16_DIV 33
#define CLKID_CPU_CLK_DIV16 34
#define CLKID_A73_CLK_DIV16_DIV 35
#define CLKID_A73_CLK_DIV16 36
#endif /* __T7_SCMI_CLKC_H */

View File

@ -313,6 +313,42 @@
#define CLK_APM_PLL_DIV4_APM 70
#define CLK_APM_PLL_DIV16_APM 71
/* CMU_DPU */
#define CLK_MOUT_DPU_BUS_USER 1
#define CLK_DOUT_DPU_BUSP 2
#define CLK_GOUT_DPU_PCLK 3
#define CLK_GOUT_DPU_CLK_DPU_OSCCLK_CLK 4
#define CLK_GOUT_DPU_AD_APB_DPU_DMA_PCLKM 5
#define CLK_GOUT_DPU_DPUF_ACLK_DMA 6
#define CLK_GOUT_DPU_DPUF_ACLK_DPP 7
#define CLK_GOUT_DPU_D_TZPC_DPU_PCLK 8
#define CLK_GOUT_DPU_GPC_DPU_PCLK 9
#define CLK_GOUT_DPU_LHM_AXI_P_DPU_I_CLK 10
#define CLK_GOUT_DPU_LHS_AXI_D0_DPU_I_CLK 11
#define CLK_GOUT_DPU_LHS_AXI_D1_DPU_I_CLK 12
#define CLK_GOUT_DPU_LHS_AXI_D2_DPU_I_CLK 13
#define CLK_GOUT_DPU_PPMU_DPUD0_ACLK 14
#define CLK_GOUT_DPU_PPMU_DPUD0_PCLK 15
#define CLK_GOUT_DPU_PPMU_DPUD1_ACLK 16
#define CLK_GOUT_DPU_PPMU_DPUD1_PCLK 17
#define CLK_GOUT_DPU_PPMU_DPUD2_ACLK 18
#define CLK_GOUT_DPU_PPMU_DPUD2_PCLK 19
#define CLK_GOUT_DPU_CLK_DPU_BUSD_CLK 20
#define CLK_GOUT_DPU_CLK_DPU_BUSP_CLK 21
#define CLK_GOUT_DPU_SSMT_DPU0_ACLK 22
#define CLK_GOUT_DPU_SSMT_DPU0_PCLK 23
#define CLK_GOUT_DPU_SSMT_DPU1_ACLK 24
#define CLK_GOUT_DPU_SSMT_DPU1_PCLK 25
#define CLK_GOUT_DPU_SSMT_DPU2_ACLK 26
#define CLK_GOUT_DPU_SSMT_DPU2_PCLK 27
#define CLK_GOUT_DPU_SYSMMU_DPUD0_CLK_S1 28
#define CLK_GOUT_DPU_SYSMMU_DPUD0_CLK_S2 29
#define CLK_GOUT_DPU_SYSMMU_DPUD1_CLK_S1 30
#define CLK_GOUT_DPU_SYSMMU_DPUD1_CLK_S2 31
#define CLK_GOUT_DPU_SYSMMU_DPUD2_CLK_S1 32
#define CLK_GOUT_DPU_SYSMMU_DPUD2_CLK_S2 33
#define CLK_GOUT_DPU_SYSREG_DPU_PCLK 34
/* CMU_HSI0 */
#define CLK_FOUT_USB_PLL 1
#define CLK_MOUT_PLL_USB 2

View File

@ -305,4 +305,8 @@
#define CLK_MOUT_MFC_WFD_USER 2
#define CLK_DOUT_MFC_NOCP 3
/* CMU_MFD */
#define CLK_MOUT_MFD_NOC_USER 1
#define CLK_DOUT_MFD_NOCP 2
#endif /* _DT_BINDINGS_CLOCK_EXYNOSAUTOV920_H */

View File

@ -93,6 +93,7 @@
#define CLK_SRAM3 83
#define CLK_PLL_GMAC_100M 84
#define CLK_UART_SCLK 85
#define CLK_C910_BUS 86
/* VO clocks */
#define CLK_AXI4_VO_ACLK 0