This pull request contains zero diff to the core framework. It is a collection
of various clk driver updates. The biggest driver updates in terms of lines of code is the Allwinner driver, closely followed by the Qualcomm and Mediatek drivers. All of those hit high because we add so many lines of clk data. Coming in fourth place is i.MX which also adds a bunch of clk data. This accounts for the new driver additions this time around. Otherwise the patches are lots of little cleanups and fixes for various clk drivers that have baked in linux-next for a while. I suppose one highlight or theme is that more clk drivers are being updated to work as modules, which is interesting to see such critical SoC infrastructure work as a loadable module. New Drivers: - Support qcom SM8150/SM8250 video and display clks - Support Mediatek MT8167 clks - Add clock for CRC block found on vf610 SoCs - Add support for the Renesas R-Car V3U (R8A779A0) SoC - Add support for the VSP for Resizing clock on Renesas RZ/G1H - Support Allwinner A100 SoC clks Removed Drivers: - Remove i.MX21 clock driver, as i.MX21 platform support is being dropped Updates: - Change how qcom's display port clks work - Small non-critical fixes for TI clk driver - Remove various unused variables in clk drivers - Allow Rockchip clk driver to be a module - Remove most __clk_lookup() calls in Samsung drivers (yay!) - Support building i.MX ARMv8 platforms clock driver as module - Some kerneldoc fixes here and there - A couple of minor i.MX clk data corrections - Update audio clock inverter and fdiv2 flag on Amlogic g12 - Make amlogic clk drivers configurable in Kconfig - Fix Renesas VSP clock names to match corrected hardware documentation - Sigma-delta modulation on Allwinner R40 - Various fixes for at91 clk driver - Use semicolons instead of commas in some places - Mark some variables const so they can move to RO memory -----BEGIN PGP SIGNATURE----- iQJFBAABCAAvFiEE9L57QeeUxqYDyoaDrQKIl8bklSUFAl+R0K0RHHNib3lkQGtl cm5lbC5vcmcACgkQrQKIl8bklSU9xw/+KRDZ/xo7GKeC7QrRt4q5eWIW4l/HzjYH yeht/i7cEXy+jSJuOTBj4sIpOdvzdBQfsqMiNg7RKdtYs0HbYFywxWtnvetptuM1 BCgSMDHHJ59EJSPEWAvE6bsl9xaVl4o0XEI2+qAoJ4OIcJVzVz+vRGQ7pDyEk2XT zTXRw4W+HftZXFB8Nw0JTj9YzBoZJzpnAB/vu2HzMYVAvoeQ8RhcdbipdSTjI+zY ++zkt8cmGP0iKloHbi3rk1A7w/ORJ//UjT24xmkwAO6t1CWEErVzXBtGkQ9K4ijy F2w5CzJb/szGCfnGlcchQ5kjB/FfgIKuLNlhTiptY+UZGIvSAbndhMSS3JFsqGbl aYUk5fpjdpneSsIPvHnnz1jIaK6OmHSoxmq7FgwaU+YDX6ZK6UKalMHbHUEpiNX+ 3a+FeKe2IVMZ0uVqpJGnd/o4Kud2CeRM1ufqu15ygbujfSH6xcO7fbUi/C8XJLMX 7PR0Ze0PhwkMezdlxb3WpK+4MrOny3JT0DTAbAQDdAwsKFP/Sex4QMWP8PUdTmGY dQcrgvuXYC1hufOaY1JzxjfGrhEBuJAr7BsjBI+etUpnJ9Z5Uhguti/lnKm7oAlI EceBJ4B5M1iUYTkKXYxLWWzUlkIKNzgHvjRM2Q6Nn5LbyVlzM4i284C/E4M8AmVB nSXy1nWkSAU= =sKI8 -----END PGP SIGNATURE----- Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux Pull clk updates from Stephen Boyd: "This contains no changes to the core framework. It is a collection of various clk driver updates. The biggest driver updates in terms of lines of code is the Allwinner driver, closely followed by the Qualcomm and Mediatek drivers. All of those hit high because we add so many lines of clk data. Coming in fourth place is i.MX which also adds a bunch of clk data. This accounts for the new driver additions this time around. Otherwise the patches are lots of little cleanups and fixes for various clk drivers that have baked in linux-next for a while. I suppose one highlight or theme is that more clk drivers are being updated to work as modules, which is interesting to see such critical SoC infrastructure work as a loadable module. New Drivers: - Support qcom SM8150/SM8250 video and display clks - Support Mediatek MT8167 clks - Add clock for CRC block found on vf610 SoCs - Add support for the Renesas R-Car V3U (R8A779A0) SoC - Add support for the VSP for Resizing clock on Renesas RZ/G1H - Support Allwinner A100 SoC clks Removed Drivers: - Remove i.MX21 clock driver, as i.MX21 platform support is being dropped Updates: - Change how qcom's display port clks work - Small non-critical fixes for TI clk driver - Remove various unused variables in clk drivers - Allow Rockchip clk driver to be a module - Remove most __clk_lookup() calls in Samsung drivers (yay!) - Support building i.MX ARMv8 platforms clock driver as module - Some kerneldoc fixes here and there - A couple of minor i.MX clk data corrections - Update audio clock inverter and fdiv2 flag on Amlogic g12 - Make amlogic clk drivers configurable in Kconfig - Fix Renesas VSP clock names to match corrected hardware documentation - Sigma-delta modulation on Allwinner R40 - Various fixes for at91 clk driver - Use semicolons instead of commas in some places - Mark some variables const so they can move to RO memory" * tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (102 commits) clk: imx8mq: Fix usdhc parents order clk: qcom: gdsc: Keep RETAIN_FF bit set if gdsc is already on clk: Restrict CLK_HSDK to ARC_SOC_HSDK clk: at91: sam9x60: support only two programmable clocks clk: ingenic: Respect CLK_SET_RATE_PARENT in .round_rate clk: ingenic: Don't tag custom clocks with CLK_SET_RATE_PARENT clk: ingenic: Don't use CLK_SET_RATE_GATE for PLL clk: ingenic: Use readl_poll_timeout instead of custom loop clk: ingenic: Use to_clk_info() macro for all clocks clk: bcm2835: add missing release if devm_clk_hw_register fails clk: at91: clk-sam9x60-pll: remove unused variable clk: at91: clk-main: update key before writing AT91_CKGR_MOR clk: at91: remove the checking of parent_name clk: clk-prima2: fix return value check in prima2_clk_init() clk: mmp2: Fix the display clock divider base clk: pxa: Constify static struct clk_ops clk: baikal-t1: Mark Ethernet PLL as critical clk: qoriq: modify MAX_PLL_DIV to 32 clk: axi-clkgen: Set power bits for fractional mode clk: axi-clkgen: Add support for fractional dividers ...
This commit is contained in:
commit
3fec0eaaf0
|
@ -15,6 +15,7 @@ Required Properties:
|
|||
- "mediatek,mt7623-apmixedsys", "mediatek,mt2701-apmixedsys"
|
||||
- "mediatek,mt7629-apmixedsys"
|
||||
- "mediatek,mt8135-apmixedsys"
|
||||
- "mediatek,mt8167-apmixedsys", "syscon"
|
||||
- "mediatek,mt8173-apmixedsys"
|
||||
- "mediatek,mt8183-apmixedsys", "syscon"
|
||||
- "mediatek,mt8516-apmixedsys"
|
||||
|
|
|
@ -11,6 +11,7 @@ Required Properties:
|
|||
- "mediatek,mt6779-audio", "syscon"
|
||||
- "mediatek,mt7622-audsys", "syscon"
|
||||
- "mediatek,mt7623-audsys", "mediatek,mt2701-audsys", "syscon"
|
||||
- "mediatek,mt8167-audiosys", "syscon"
|
||||
- "mediatek,mt8183-audiosys", "syscon"
|
||||
- "mediatek,mt8516-audsys", "syscon"
|
||||
- #clock-cells: Must be 1
|
||||
|
|
|
@ -12,6 +12,7 @@ Required Properties:
|
|||
- "mediatek,mt6779-imgsys", "syscon"
|
||||
- "mediatek,mt6797-imgsys", "syscon"
|
||||
- "mediatek,mt7623-imgsys", "mediatek,mt2701-imgsys", "syscon"
|
||||
- "mediatek,mt8167-imgsys", "syscon"
|
||||
- "mediatek,mt8173-imgsys", "syscon"
|
||||
- "mediatek,mt8183-imgsys", "syscon"
|
||||
- #clock-cells: Must be 1
|
||||
|
|
|
@ -16,6 +16,7 @@ Required Properties:
|
|||
- "mediatek,mt7623-infracfg", "mediatek,mt2701-infracfg", "syscon"
|
||||
- "mediatek,mt7629-infracfg", "syscon"
|
||||
- "mediatek,mt8135-infracfg", "syscon"
|
||||
- "mediatek,mt8167-infracfg", "syscon"
|
||||
- "mediatek,mt8173-infracfg", "syscon"
|
||||
- "mediatek,mt8183-infracfg", "syscon"
|
||||
- "mediatek,mt8516-infracfg", "syscon"
|
||||
|
|
|
@ -8,6 +8,7 @@ Required Properties:
|
|||
- compatible: Should be one of:
|
||||
- "mediatek,mt2712-mfgcfg", "syscon"
|
||||
- "mediatek,mt6779-mfgcfg", "syscon"
|
||||
- "mediatek,mt8167-mfgcfg", "syscon"
|
||||
- "mediatek,mt8183-mfgcfg", "syscon"
|
||||
- #clock-cells: Must be 1
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ Required Properties:
|
|||
- "mediatek,mt7623-topckgen", "mediatek,mt2701-topckgen"
|
||||
- "mediatek,mt7629-topckgen"
|
||||
- "mediatek,mt8135-topckgen"
|
||||
- "mediatek,mt8167-topckgen", "syscon"
|
||||
- "mediatek,mt8173-topckgen"
|
||||
- "mediatek,mt8183-topckgen", "syscon"
|
||||
- "mediatek,mt8516-topckgen"
|
||||
|
|
|
@ -11,6 +11,7 @@ Required Properties:
|
|||
- "mediatek,mt6779-vdecsys", "syscon"
|
||||
- "mediatek,mt6797-vdecsys", "syscon"
|
||||
- "mediatek,mt7623-vdecsys", "mediatek,mt2701-vdecsys", "syscon"
|
||||
- "mediatek,mt8167-vdecsys", "syscon"
|
||||
- "mediatek,mt8173-vdecsys", "syscon"
|
||||
- "mediatek,mt8183-vdecsys", "syscon"
|
||||
- #clock-cells: Must be 1
|
||||
|
|
|
@ -36,6 +36,8 @@ properties:
|
|||
- allwinner,sun9i-a80-ccu
|
||||
- allwinner,sun50i-a64-ccu
|
||||
- allwinner,sun50i-a64-r-ccu
|
||||
- allwinner,sun50i-a100-ccu
|
||||
- allwinner,sun50i-a100-r-ccu
|
||||
- allwinner,sun50i-h5-ccu
|
||||
- allwinner,sun50i-h6-ccu
|
||||
- allwinner,sun50i-h6-r-ccu
|
||||
|
@ -78,6 +80,7 @@ if:
|
|||
- allwinner,sun8i-a83t-r-ccu
|
||||
- allwinner,sun8i-h3-r-ccu
|
||||
- allwinner,sun50i-a64-r-ccu
|
||||
- allwinner,sun50i-a100-r-ccu
|
||||
- allwinner,sun50i-h6-r-ccu
|
||||
|
||||
then:
|
||||
|
@ -94,7 +97,9 @@ else:
|
|||
if:
|
||||
properties:
|
||||
compatible:
|
||||
const: allwinner,sun50i-h6-ccu
|
||||
enum:
|
||||
- allwinner,sun50i-a100-ccu
|
||||
- allwinner,sun50i-h6-ccu
|
||||
|
||||
then:
|
||||
properties:
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/qcom,dispcc-sm8x50.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Display Clock & Reset Controller Binding for SM8150/SM8250
|
||||
|
||||
maintainers:
|
||||
- Jonathan Marek <jonathan@marek.ca>
|
||||
|
||||
description: |
|
||||
Qualcomm display clock control module which supports the clocks, resets and
|
||||
power domains on SM8150 and SM8250.
|
||||
|
||||
See also:
|
||||
dt-bindings/clock/qcom,dispcc-sm8150.h
|
||||
dt-bindings/clock/qcom,dispcc-sm8250.h
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,sm8150-dispcc
|
||||
- qcom,sm8250-dispcc
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Board XO source
|
||||
- description: Byte clock from DSI PHY0
|
||||
- description: Pixel clock from DSI PHY0
|
||||
- description: Byte clock from DSI PHY1
|
||||
- description: Pixel clock from DSI PHY1
|
||||
- description: Link clock from DP PHY
|
||||
- description: VCO DIV clock from DP PHY
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: bi_tcxo
|
||||
- const: dsi0_phy_pll_out_byteclk
|
||||
- const: dsi0_phy_pll_out_dsiclk
|
||||
- const: dsi1_phy_pll_out_byteclk
|
||||
- const: dsi1_phy_pll_out_dsiclk
|
||||
- const: dp_phy_pll_link_clk
|
||||
- const: dp_phy_pll_vco_div_clk
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
|
||||
'#reset-cells':
|
||||
const: 1
|
||||
|
||||
'#power-domain-cells':
|
||||
const: 1
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- '#clock-cells'
|
||||
- '#reset-cells'
|
||||
- '#power-domain-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||
clock-controller@af00000 {
|
||||
compatible = "qcom,sm8250-dispcc";
|
||||
reg = <0x0af00000 0x10000>;
|
||||
clocks = <&rpmhcc RPMH_CXO_CLK>,
|
||||
<&dsi0_phy 0>,
|
||||
<&dsi0_phy 1>,
|
||||
<&dsi1_phy 0>,
|
||||
<&dsi1_phy 1>,
|
||||
<&dp_phy 0>,
|
||||
<&dp_phy 1>;
|
||||
clock-names = "bi_tcxo",
|
||||
"dsi0_phy_pll_out_byteclk",
|
||||
"dsi0_phy_pll_out_dsiclk",
|
||||
"dsi1_phy_pll_out_byteclk",
|
||||
"dsi1_phy_pll_out_dsiclk",
|
||||
"dp_phy_pll_link_clk",
|
||||
"dp_phy_pll_vco_div_clk";
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
#power-domain-cells = <1>;
|
||||
};
|
||||
...
|
|
@ -1,65 +0,0 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/qcom,sc7180-videocc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Video Clock & Reset Controller Binding for SC7180
|
||||
|
||||
maintainers:
|
||||
- Taniya Das <tdas@codeaurora.org>
|
||||
|
||||
description: |
|
||||
Qualcomm video clock control module which supports the clocks, resets and
|
||||
power domains on SC7180.
|
||||
|
||||
See also dt-bindings/clock/qcom,videocc-sc7180.h.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sc7180-videocc
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Board XO source
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: bi_tcxo
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
|
||||
'#reset-cells':
|
||||
const: 1
|
||||
|
||||
'#power-domain-cells':
|
||||
const: 1
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- '#clock-cells'
|
||||
- '#reset-cells'
|
||||
- '#power-domain-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||
clock-controller@ab00000 {
|
||||
compatible = "qcom,sc7180-videocc";
|
||||
reg = <0x0ab00000 0x10000>;
|
||||
clocks = <&rpmhcc RPMH_CXO_CLK>;
|
||||
clock-names = "bi_tcxo";
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
#power-domain-cells = <1>;
|
||||
};
|
||||
...
|
|
@ -1,23 +1,31 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/qcom,sdm845-videocc.yaml#
|
||||
$id: http://devicetree.org/schemas/clock/qcom,videocc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Video Clock & Reset Controller Binding for SDM845
|
||||
title: Qualcomm Video Clock & Reset Controller Binding
|
||||
|
||||
maintainers:
|
||||
- Taniya Das <tdas@codeaurora.org>
|
||||
|
||||
description: |
|
||||
Qualcomm video clock control module which supports the clocks, resets and
|
||||
power domains on SDM845.
|
||||
power domains on SDM845/SC7180/SM8150/SM8250.
|
||||
|
||||
See also dt-bindings/clock/qcom,videocc-sdm845.h.
|
||||
See also:
|
||||
dt-bindings/clock/qcom,videocc-sc7180.h
|
||||
dt-bindings/clock/qcom,videocc-sdm845.h
|
||||
dt-bindings/clock/qcom,videocc-sm8150.h
|
||||
dt-bindings/clock/qcom,videocc-sm8250.h
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sdm845-videocc
|
||||
enum:
|
||||
- qcom,sc7180-videocc
|
||||
- qcom,sdm845-videocc
|
||||
- qcom,sm8150-videocc
|
||||
- qcom,sm8250-videocc
|
||||
|
||||
clocks:
|
||||
items:
|
|
@ -47,6 +47,7 @@ properties:
|
|||
- renesas,r8a77980-cpg-mssr # R-Car V3H
|
||||
- renesas,r8a77990-cpg-mssr # R-Car E3
|
||||
- renesas,r8a77995-cpg-mssr # R-Car D3
|
||||
- renesas,r8a779a0-cpg-mssr # R-Car V3U
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
|
|
@ -49,7 +49,7 @@ source "drivers/clk/versatile/Kconfig"
|
|||
|
||||
config CLK_HSDK
|
||||
bool "PLL Driver for HSDK platform"
|
||||
depends on OF || COMPILE_TEST
|
||||
depends on ARC_SOC_HSDK || COMPILE_TEST
|
||||
depends on HAS_IOMEM
|
||||
help
|
||||
This driver supports the HSDK core, system, ddr, tunnel and hdmi PLLs
|
||||
|
@ -373,6 +373,7 @@ source "drivers/clk/meson/Kconfig"
|
|||
source "drivers/clk/mvebu/Kconfig"
|
||||
source "drivers/clk/qcom/Kconfig"
|
||||
source "drivers/clk/renesas/Kconfig"
|
||||
source "drivers/clk/rockchip/Kconfig"
|
||||
source "drivers/clk/samsung/Kconfig"
|
||||
source "drivers/clk/sifive/Kconfig"
|
||||
source "drivers/clk/sprd/Kconfig"
|
||||
|
|
|
@ -46,13 +46,6 @@ static const struct {
|
|||
{ .n = "pck1", .p = "prog1", .id = 9 },
|
||||
};
|
||||
|
||||
static const struct clk_pcr_layout at91sam9g45_pcr_layout = {
|
||||
.offset = 0x10c,
|
||||
.cmd = BIT(12),
|
||||
.pid_mask = GENMASK(5, 0),
|
||||
.div_mask = GENMASK(17, 16),
|
||||
};
|
||||
|
||||
struct pck {
|
||||
char *n;
|
||||
u8 id;
|
||||
|
|
|
@ -437,12 +437,17 @@ static int clk_sam9x5_main_set_parent(struct clk_hw *hw, u8 index)
|
|||
return -EINVAL;
|
||||
|
||||
regmap_read(regmap, AT91_CKGR_MOR, &tmp);
|
||||
tmp &= ~MOR_KEY_MASK;
|
||||
|
||||
if (index && !(tmp & AT91_PMC_MOSCSEL))
|
||||
regmap_write(regmap, AT91_CKGR_MOR, tmp | AT91_PMC_MOSCSEL);
|
||||
tmp = AT91_PMC_MOSCSEL;
|
||||
else if (!index && (tmp & AT91_PMC_MOSCSEL))
|
||||
regmap_write(regmap, AT91_CKGR_MOR, tmp & ~AT91_PMC_MOSCSEL);
|
||||
tmp = 0;
|
||||
else
|
||||
return 0;
|
||||
|
||||
regmap_update_bits(regmap, AT91_CKGR_MOR,
|
||||
AT91_PMC_MOSCSEL | MOR_KEY_MASK,
|
||||
tmp | AT91_PMC_KEY);
|
||||
|
||||
while (!clk_sam9x5_main_ready(regmap))
|
||||
cpu_relax();
|
||||
|
|
|
@ -112,8 +112,8 @@ at91_clk_register_peripheral(struct regmap *regmap, const char *name,
|
|||
|
||||
init.name = name;
|
||||
init.ops = &peripheral_ops;
|
||||
init.parent_names = (parent_name ? &parent_name : NULL);
|
||||
init.num_parents = (parent_name ? 1 : 0);
|
||||
init.parent_names = &parent_name;
|
||||
init.num_parents = 1;
|
||||
init.flags = 0;
|
||||
|
||||
periph->id = id;
|
||||
|
|
|
@ -331,7 +331,7 @@ static long sam9x60_div_pll_compute_div(struct sam9x60_pll_core *core,
|
|||
struct clk_hw *parent = clk_hw_get_parent(&core->hw);
|
||||
unsigned long tmp_rate, tmp_parent_rate, tmp_diff;
|
||||
long best_diff = -1, best_rate = -EINVAL;
|
||||
u32 divid, best_div;
|
||||
u32 divid;
|
||||
|
||||
if (!rate)
|
||||
return 0;
|
||||
|
@ -352,7 +352,6 @@ static long sam9x60_div_pll_compute_div(struct sam9x60_pll_core *core,
|
|||
*parent_rate = tmp_parent_rate;
|
||||
best_rate = tmp_rate;
|
||||
best_diff = tmp_diff;
|
||||
best_div = divid;
|
||||
}
|
||||
|
||||
if (!best_diff)
|
||||
|
|
|
@ -279,7 +279,7 @@ static void __init sam9x60_pmc_setup(struct device_node *np)
|
|||
parent_names[3] = "masterck";
|
||||
parent_names[4] = "pllack_divck";
|
||||
parent_names[5] = "upllck_divck";
|
||||
for (i = 0; i < 8; i++) {
|
||||
for (i = 0; i < 2; i++) {
|
||||
char name[6];
|
||||
|
||||
snprintf(name, sizeof(name), "prog%d", i);
|
||||
|
|
|
@ -51,11 +51,13 @@ struct ccu_pll_info {
|
|||
};
|
||||
|
||||
/*
|
||||
* Mark as critical all PLLs except Ethernet one. CPU and DDR PLLs are sources
|
||||
* of CPU cores and DDR controller reference clocks, due to which they
|
||||
* obviously shouldn't be ever gated. SATA and PCIe PLLs are the parents of
|
||||
* APB-bus and DDR controller AXI-bus clocks. If they are gated the system will
|
||||
* be unusable.
|
||||
* Alas we have to mark all PLLs as critical. CPU and DDR PLLs are sources of
|
||||
* CPU cores and DDR controller reference clocks, due to which they obviously
|
||||
* shouldn't be ever gated. SATA and PCIe PLLs are the parents of APB-bus and
|
||||
* DDR controller AXI-bus clocks. If they are gated the system will be
|
||||
* unusable. Moreover disabling SATA and Ethernet PLLs causes automatic reset
|
||||
* of the corresponding subsystems. So until we aren't ready to re-initialize
|
||||
* all the devices consuming those PLLs, they will be marked as critical too.
|
||||
*/
|
||||
static const struct ccu_pll_info pll_info[] = {
|
||||
CCU_PLL_INFO(CCU_CPU_PLL, "cpu_pll", "ref_clk", CCU_CPU_PLL_BASE,
|
||||
|
@ -67,7 +69,7 @@ static const struct ccu_pll_info pll_info[] = {
|
|||
CCU_PLL_INFO(CCU_PCIE_PLL, "pcie_pll", "ref_clk", CCU_PCIE_PLL_BASE,
|
||||
CLK_IS_CRITICAL),
|
||||
CCU_PLL_INFO(CCU_ETH_PLL, "eth_pll", "ref_clk", CCU_ETH_PLL_BASE,
|
||||
CLK_SET_RATE_GATE)
|
||||
CLK_IS_CRITICAL | CLK_SET_RATE_GATE)
|
||||
};
|
||||
|
||||
struct ccu_pll_data {
|
||||
|
|
|
@ -1338,8 +1338,10 @@ static struct clk_hw *bcm2835_register_pll(struct bcm2835_cprman *cprman,
|
|||
pll->hw.init = &init;
|
||||
|
||||
ret = devm_clk_hw_register(cprman->dev, &pll->hw);
|
||||
if (ret)
|
||||
if (ret) {
|
||||
kfree(pll);
|
||||
return NULL;
|
||||
}
|
||||
return &pll->hw;
|
||||
}
|
||||
|
||||
|
|
|
@ -271,6 +271,7 @@ static int raspberrypi_discover_clocks(struct raspberrypi_clk *rpi,
|
|||
case RPI_FIRMWARE_CORE_CLK_ID:
|
||||
case RPI_FIRMWARE_M2MC_CLK_ID:
|
||||
case RPI_FIRMWARE_V3D_CLK_ID:
|
||||
case RPI_FIRMWARE_PIXEL_BVB_CLK_ID:
|
||||
hw = raspberrypi_clk_register(rpi, clks->parent,
|
||||
clks->id);
|
||||
if (IS_ERR(hw))
|
||||
|
|
|
@ -27,19 +27,23 @@
|
|||
|
||||
#define AXI_CLKGEN_V2_DRP_STATUS_BUSY BIT(16)
|
||||
|
||||
#define MMCM_REG_CLKOUT5_2 0x07
|
||||
#define MMCM_REG_CLKOUT0_1 0x08
|
||||
#define MMCM_REG_CLKOUT0_2 0x09
|
||||
#define MMCM_REG_CLKOUT6_2 0x13
|
||||
#define MMCM_REG_CLK_FB1 0x14
|
||||
#define MMCM_REG_CLK_FB2 0x15
|
||||
#define MMCM_REG_CLK_DIV 0x16
|
||||
#define MMCM_REG_LOCK1 0x18
|
||||
#define MMCM_REG_LOCK2 0x19
|
||||
#define MMCM_REG_LOCK3 0x1a
|
||||
#define MMCM_REG_POWER 0x28
|
||||
#define MMCM_REG_FILTER1 0x4e
|
||||
#define MMCM_REG_FILTER2 0x4f
|
||||
|
||||
#define MMCM_CLKOUT_NOCOUNT BIT(6)
|
||||
|
||||
#define MMCM_CLK_DIV_DIVIDE BIT(11)
|
||||
#define MMCM_CLK_DIV_NOCOUNT BIT(12)
|
||||
|
||||
struct axi_clkgen {
|
||||
|
@ -107,6 +111,8 @@ static void axi_clkgen_calc_params(unsigned long fin, unsigned long fout,
|
|||
unsigned long d, d_min, d_max, _d_min, _d_max;
|
||||
unsigned long m, m_min, m_max;
|
||||
unsigned long f, dout, best_f, fvco;
|
||||
unsigned long fract_shift = 0;
|
||||
unsigned long fvco_min_fract, fvco_max_fract;
|
||||
|
||||
fin /= 1000;
|
||||
fout /= 1000;
|
||||
|
@ -119,42 +125,89 @@ static void axi_clkgen_calc_params(unsigned long fin, unsigned long fout,
|
|||
d_min = max_t(unsigned long, DIV_ROUND_UP(fin, fpfd_max), 1);
|
||||
d_max = min_t(unsigned long, fin / fpfd_min, 80);
|
||||
|
||||
m_min = max_t(unsigned long, DIV_ROUND_UP(fvco_min, fin) * d_min, 1);
|
||||
m_max = min_t(unsigned long, fvco_max * d_max / fin, 64);
|
||||
again:
|
||||
fvco_min_fract = fvco_min << fract_shift;
|
||||
fvco_max_fract = fvco_max << fract_shift;
|
||||
|
||||
m_min = max_t(unsigned long, DIV_ROUND_UP(fvco_min_fract, fin) * d_min, 1);
|
||||
m_max = min_t(unsigned long, fvco_max_fract * d_max / fin, 64 << fract_shift);
|
||||
|
||||
for (m = m_min; m <= m_max; m++) {
|
||||
_d_min = max(d_min, DIV_ROUND_UP(fin * m, fvco_max));
|
||||
_d_max = min(d_max, fin * m / fvco_min);
|
||||
_d_min = max(d_min, DIV_ROUND_UP(fin * m, fvco_max_fract));
|
||||
_d_max = min(d_max, fin * m / fvco_min_fract);
|
||||
|
||||
for (d = _d_min; d <= _d_max; d++) {
|
||||
fvco = fin * m / d;
|
||||
|
||||
dout = DIV_ROUND_CLOSEST(fvco, fout);
|
||||
dout = clamp_t(unsigned long, dout, 1, 128);
|
||||
dout = clamp_t(unsigned long, dout, 1, 128 << fract_shift);
|
||||
f = fvco / dout;
|
||||
if (abs(f - fout) < abs(best_f - fout)) {
|
||||
best_f = f;
|
||||
*best_d = d;
|
||||
*best_m = m;
|
||||
*best_dout = dout;
|
||||
*best_m = m << (3 - fract_shift);
|
||||
*best_dout = dout << (3 - fract_shift);
|
||||
if (best_f == fout)
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Lets see if we find a better setting in fractional mode */
|
||||
if (fract_shift == 0) {
|
||||
fract_shift = 3;
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
|
||||
static void axi_clkgen_calc_clk_params(unsigned int divider, unsigned int *low,
|
||||
unsigned int *high, unsigned int *edge, unsigned int *nocount)
|
||||
{
|
||||
if (divider == 1)
|
||||
*nocount = 1;
|
||||
else
|
||||
*nocount = 0;
|
||||
struct axi_clkgen_div_params {
|
||||
unsigned int low;
|
||||
unsigned int high;
|
||||
unsigned int edge;
|
||||
unsigned int nocount;
|
||||
unsigned int frac_en;
|
||||
unsigned int frac;
|
||||
unsigned int frac_wf_f;
|
||||
unsigned int frac_wf_r;
|
||||
unsigned int frac_phase;
|
||||
};
|
||||
|
||||
*high = divider / 2;
|
||||
*edge = divider % 2;
|
||||
*low = divider - *high;
|
||||
static void axi_clkgen_calc_clk_params(unsigned int divider,
|
||||
unsigned int frac_divider, struct axi_clkgen_div_params *params)
|
||||
{
|
||||
|
||||
memset(params, 0x0, sizeof(*params));
|
||||
|
||||
if (divider == 1) {
|
||||
params->nocount = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
if (frac_divider == 0) {
|
||||
params->high = divider / 2;
|
||||
params->edge = divider % 2;
|
||||
params->low = divider - params->high;
|
||||
} else {
|
||||
params->frac_en = 1;
|
||||
params->frac = frac_divider;
|
||||
|
||||
params->high = divider / 2;
|
||||
params->edge = divider % 2;
|
||||
params->low = params->high;
|
||||
|
||||
if (params->edge == 0) {
|
||||
params->high--;
|
||||
params->frac_wf_r = 1;
|
||||
}
|
||||
|
||||
if (params->edge == 0 || frac_divider == 1)
|
||||
params->low--;
|
||||
if (((params->edge == 0) ^ (frac_divider == 1)) ||
|
||||
(divider == 2 && frac_divider == 1))
|
||||
params->frac_wf_f = 1;
|
||||
|
||||
params->frac_phase = params->edge * 4 + frac_divider / 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void axi_clkgen_write(struct axi_clkgen *axi_clkgen,
|
||||
|
@ -246,15 +299,29 @@ static struct axi_clkgen *clk_hw_to_axi_clkgen(struct clk_hw *clk_hw)
|
|||
return container_of(clk_hw, struct axi_clkgen, clk_hw);
|
||||
}
|
||||
|
||||
static void axi_clkgen_set_div(struct axi_clkgen *axi_clkgen,
|
||||
unsigned int reg1, unsigned int reg2, unsigned int reg3,
|
||||
struct axi_clkgen_div_params *params)
|
||||
{
|
||||
axi_clkgen_mmcm_write(axi_clkgen, reg1,
|
||||
(params->high << 6) | params->low, 0xefff);
|
||||
axi_clkgen_mmcm_write(axi_clkgen, reg2,
|
||||
(params->frac << 12) | (params->frac_en << 11) |
|
||||
(params->frac_wf_r << 10) | (params->edge << 7) |
|
||||
(params->nocount << 6), 0x7fff);
|
||||
if (reg3 != 0) {
|
||||
axi_clkgen_mmcm_write(axi_clkgen, reg3,
|
||||
(params->frac_phase << 11) | (params->frac_wf_f << 10), 0x3c00);
|
||||
}
|
||||
}
|
||||
|
||||
static int axi_clkgen_set_rate(struct clk_hw *clk_hw,
|
||||
unsigned long rate, unsigned long parent_rate)
|
||||
{
|
||||
struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw);
|
||||
unsigned int d, m, dout;
|
||||
unsigned int nocount;
|
||||
unsigned int high;
|
||||
unsigned int edge;
|
||||
unsigned int low;
|
||||
struct axi_clkgen_div_params params;
|
||||
uint32_t power = 0;
|
||||
uint32_t filter;
|
||||
uint32_t lock;
|
||||
|
||||
|
@ -266,24 +333,26 @@ static int axi_clkgen_set_rate(struct clk_hw *clk_hw,
|
|||
if (d == 0 || dout == 0 || m == 0)
|
||||
return -EINVAL;
|
||||
|
||||
if ((dout & 0x7) != 0 || (m & 0x7) != 0)
|
||||
power |= 0x9800;
|
||||
|
||||
axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_POWER, power, 0x9800);
|
||||
|
||||
filter = axi_clkgen_lookup_filter(m - 1);
|
||||
lock = axi_clkgen_lookup_lock(m - 1);
|
||||
|
||||
axi_clkgen_calc_clk_params(dout, &low, &high, &edge, &nocount);
|
||||
axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_CLKOUT0_1,
|
||||
(high << 6) | low, 0xefff);
|
||||
axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_CLKOUT0_2,
|
||||
(edge << 7) | (nocount << 6), 0x03ff);
|
||||
axi_clkgen_calc_clk_params(dout >> 3, dout & 0x7, ¶ms);
|
||||
axi_clkgen_set_div(axi_clkgen, MMCM_REG_CLKOUT0_1, MMCM_REG_CLKOUT0_2,
|
||||
MMCM_REG_CLKOUT5_2, ¶ms);
|
||||
|
||||
axi_clkgen_calc_clk_params(d, &low, &high, &edge, &nocount);
|
||||
axi_clkgen_calc_clk_params(d, 0, ¶ms);
|
||||
axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_CLK_DIV,
|
||||
(edge << 13) | (nocount << 12) | (high << 6) | low, 0x3fff);
|
||||
(params.edge << 13) | (params.nocount << 12) |
|
||||
(params.high << 6) | params.low, 0x3fff);
|
||||
|
||||
axi_clkgen_calc_clk_params(m, &low, &high, &edge, &nocount);
|
||||
axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_CLK_FB1,
|
||||
(high << 6) | low, 0xefff);
|
||||
axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_CLK_FB2,
|
||||
(edge << 7) | (nocount << 6), 0x03ff);
|
||||
axi_clkgen_calc_clk_params(m >> 3, m & 0x7, ¶ms);
|
||||
axi_clkgen_set_div(axi_clkgen, MMCM_REG_CLK_FB1, MMCM_REG_CLK_FB2,
|
||||
MMCM_REG_CLKOUT6_2, ¶ms);
|
||||
|
||||
axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_LOCK1, lock & 0x3ff, 0x3ff);
|
||||
axi_clkgen_mmcm_write(axi_clkgen, MMCM_REG_LOCK2,
|
||||
|
@ -313,35 +382,51 @@ static long axi_clkgen_round_rate(struct clk_hw *hw, unsigned long rate,
|
|||
return min_t(unsigned long long, tmp, LONG_MAX);
|
||||
}
|
||||
|
||||
static unsigned int axi_clkgen_get_div(struct axi_clkgen *axi_clkgen,
|
||||
unsigned int reg1, unsigned int reg2)
|
||||
{
|
||||
unsigned int val1, val2;
|
||||
unsigned int div;
|
||||
|
||||
axi_clkgen_mmcm_read(axi_clkgen, reg2, &val2);
|
||||
if (val2 & MMCM_CLKOUT_NOCOUNT)
|
||||
return 8;
|
||||
|
||||
axi_clkgen_mmcm_read(axi_clkgen, reg1, &val1);
|
||||
|
||||
div = (val1 & 0x3f) + ((val1 >> 6) & 0x3f);
|
||||
div <<= 3;
|
||||
|
||||
if (val2 & MMCM_CLK_DIV_DIVIDE) {
|
||||
if ((val2 & BIT(7)) && (val2 & 0x7000) != 0x1000)
|
||||
div += 8;
|
||||
else
|
||||
div += 16;
|
||||
|
||||
div += (val2 >> 12) & 0x7;
|
||||
}
|
||||
|
||||
return div;
|
||||
}
|
||||
|
||||
static unsigned long axi_clkgen_recalc_rate(struct clk_hw *clk_hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct axi_clkgen *axi_clkgen = clk_hw_to_axi_clkgen(clk_hw);
|
||||
unsigned int d, m, dout;
|
||||
unsigned int reg;
|
||||
unsigned long long tmp;
|
||||
unsigned int val;
|
||||
|
||||
axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLKOUT0_2, ®);
|
||||
if (reg & MMCM_CLKOUT_NOCOUNT) {
|
||||
dout = 1;
|
||||
} else {
|
||||
axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLKOUT0_1, ®);
|
||||
dout = (reg & 0x3f) + ((reg >> 6) & 0x3f);
|
||||
}
|
||||
dout = axi_clkgen_get_div(axi_clkgen, MMCM_REG_CLKOUT0_1,
|
||||
MMCM_REG_CLKOUT0_2);
|
||||
m = axi_clkgen_get_div(axi_clkgen, MMCM_REG_CLK_FB1,
|
||||
MMCM_REG_CLK_FB2);
|
||||
|
||||
axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_DIV, ®);
|
||||
if (reg & MMCM_CLK_DIV_NOCOUNT)
|
||||
axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_DIV, &val);
|
||||
if (val & MMCM_CLK_DIV_NOCOUNT)
|
||||
d = 1;
|
||||
else
|
||||
d = (reg & 0x3f) + ((reg >> 6) & 0x3f);
|
||||
|
||||
axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_FB2, ®);
|
||||
if (reg & MMCM_CLKOUT_NOCOUNT) {
|
||||
m = 1;
|
||||
} else {
|
||||
axi_clkgen_mmcm_read(axi_clkgen, MMCM_REG_CLK_FB1, ®);
|
||||
m = (reg & 0x3f) + ((reg >> 6) & 0x3f);
|
||||
}
|
||||
d = (val & 0x3f) + ((val >> 6) & 0x3f);
|
||||
|
||||
if (d == 0 || dout == 0)
|
||||
return 0;
|
||||
|
|
|
@ -328,6 +328,7 @@ struct clk_hw *clk_hw_register_composite(struct device *dev, const char *name,
|
|||
rate_hw, rate_ops, gate_hw,
|
||||
gate_ops, flags);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_hw_register_composite);
|
||||
|
||||
struct clk_hw *clk_hw_register_composite_pdata(struct device *dev,
|
||||
const char *name,
|
||||
|
|
|
@ -206,6 +206,7 @@ static struct clk_hw *_of_fixed_factor_clk_setup(struct device_node *node)
|
|||
|
||||
/**
|
||||
* of_fixed_factor_clk_setup() - Setup function for simple fixed factor clock
|
||||
* @node: device node for the clock
|
||||
*/
|
||||
void __init of_fixed_factor_clk_setup(struct device_node *node)
|
||||
{
|
||||
|
|
|
@ -168,6 +168,7 @@ static struct clk_hw *_of_fixed_clk_setup(struct device_node *node)
|
|||
|
||||
/**
|
||||
* of_fixed_clk_setup() - Setup function for simple fixed rate clock
|
||||
* @node: device node for the clock
|
||||
*/
|
||||
void __init of_fixed_clk_setup(struct device_node *node)
|
||||
{
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
#define CGA_PLL4 4 /* only on clockgen-1.0, which lacks CGB */
|
||||
#define CGB_PLL1 4
|
||||
#define CGB_PLL2 5
|
||||
#define MAX_PLL_DIV 16
|
||||
#define MAX_PLL_DIV 32
|
||||
|
||||
struct clockgen_pll_div {
|
||||
struct clk *clk;
|
||||
|
|
|
@ -267,18 +267,7 @@ static struct platform_driver s2mps11_clk_driver = {
|
|||
.remove = s2mps11_clk_remove,
|
||||
.id_table = s2mps11_clk_id,
|
||||
};
|
||||
|
||||
static int __init s2mps11_clk_init(void)
|
||||
{
|
||||
return platform_driver_register(&s2mps11_clk_driver);
|
||||
}
|
||||
subsys_initcall(s2mps11_clk_init);
|
||||
|
||||
static void __exit s2mps11_clk_cleanup(void)
|
||||
{
|
||||
platform_driver_unregister(&s2mps11_clk_driver);
|
||||
}
|
||||
module_exit(s2mps11_clk_cleanup);
|
||||
module_platform_driver(s2mps11_clk_driver);
|
||||
|
||||
MODULE_DESCRIPTION("S2MPS11 Clock Driver");
|
||||
MODULE_AUTHOR("Yadwinder Singh Brar <yadi.brar@samsung.com>");
|
||||
|
|
|
@ -883,11 +883,9 @@ static int si5341_output_set_parent(struct clk_hw *hw, u8 index)
|
|||
static u8 si5341_output_get_parent(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_si5341_output *output = to_clk_si5341_output(hw);
|
||||
int err;
|
||||
u32 val;
|
||||
|
||||
err = regmap_read(output->data->regmap,
|
||||
SI5341_OUT_MUX_SEL(output), &val);
|
||||
regmap_read(output->data->regmap, SI5341_OUT_MUX_SEL(output), &val);
|
||||
|
||||
return val & 0x7;
|
||||
}
|
||||
|
|
|
@ -571,6 +571,7 @@ static const struct clk_ops da8xx_usb1_clk48_ops = {
|
|||
|
||||
/**
|
||||
* da8xx_cfgchip_register_usb1_clk48 - Register a new USB 1.1 PHY clock
|
||||
* @dev: The device
|
||||
* @regmap: The CFGCHIP regmap
|
||||
*/
|
||||
static struct da8xx_usb1_clk48 *
|
||||
|
|
|
@ -1,40 +1,102 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
# common clock support for NXP i.MX SoC family.
|
||||
config MXC_CLK
|
||||
bool
|
||||
def_bool ARCH_MXC
|
||||
tristate "IMX clock"
|
||||
depends on ARCH_MXC || COMPILE_TEST
|
||||
|
||||
config MXC_CLK_SCU
|
||||
bool
|
||||
depends on IMX_SCU
|
||||
tristate "IMX SCU clock"
|
||||
depends on ARCH_MXC || COMPILE_TEST
|
||||
depends on IMX_SCU && HAVE_ARM_SMCCC
|
||||
|
||||
config CLK_IMX1
|
||||
def_bool SOC_IMX1
|
||||
select MXC_CLK
|
||||
|
||||
config CLK_IMX25
|
||||
def_bool SOC_IMX25
|
||||
select MXC_CLK
|
||||
|
||||
config CLK_IMX27
|
||||
def_bool SOC_IMX27
|
||||
select MXC_CLK
|
||||
|
||||
config CLK_IMX31
|
||||
def_bool SOC_IMX31
|
||||
select MXC_CLK
|
||||
|
||||
config CLK_IMX35
|
||||
def_bool SOC_IMX35
|
||||
select MXC_CLK
|
||||
|
||||
config CLK_IMX5
|
||||
def_bool SOC_IMX5
|
||||
select MXC_CLK
|
||||
|
||||
config CLK_IMX6Q
|
||||
def_bool SOC_IMX6Q
|
||||
select MXC_CLK
|
||||
|
||||
config CLK_IMX6SL
|
||||
def_bool SOC_IMX6SL
|
||||
select MXC_CLK
|
||||
|
||||
config CLK_IMX6SLL
|
||||
def_bool SOC_IMX6SLL
|
||||
select MXC_CLK
|
||||
|
||||
config CLK_IMX6SX
|
||||
def_bool SOC_IMX6SX
|
||||
select MXC_CLK
|
||||
|
||||
config CLK_IMX6UL
|
||||
def_bool SOC_IMX6UL
|
||||
select MXC_CLK
|
||||
|
||||
config CLK_IMX7D
|
||||
def_bool SOC_IMX7D
|
||||
select MXC_CLK
|
||||
|
||||
config CLK_IMX7ULP
|
||||
def_bool SOC_IMX7ULP
|
||||
select MXC_CLK
|
||||
|
||||
config CLK_VF610
|
||||
def_bool SOC_VF610
|
||||
select MXC_CLK
|
||||
|
||||
config CLK_IMX8MM
|
||||
bool "IMX8MM CCM Clock Driver"
|
||||
depends on ARCH_MXC
|
||||
tristate "IMX8MM CCM Clock Driver"
|
||||
depends on ARCH_MXC || COMPILE_TEST
|
||||
select MXC_CLK
|
||||
help
|
||||
Build the driver for i.MX8MM CCM Clock Driver
|
||||
|
||||
config CLK_IMX8MN
|
||||
bool "IMX8MN CCM Clock Driver"
|
||||
depends on ARCH_MXC
|
||||
tristate "IMX8MN CCM Clock Driver"
|
||||
depends on ARCH_MXC || COMPILE_TEST
|
||||
select MXC_CLK
|
||||
help
|
||||
Build the driver for i.MX8MN CCM Clock Driver
|
||||
|
||||
config CLK_IMX8MP
|
||||
bool "IMX8MP CCM Clock Driver"
|
||||
depends on ARCH_MXC
|
||||
tristate "IMX8MP CCM Clock Driver"
|
||||
depends on ARCH_MXC || COMPILE_TEST
|
||||
select MXC_CLK
|
||||
help
|
||||
Build the driver for i.MX8MP CCM Clock Driver
|
||||
|
||||
config CLK_IMX8MQ
|
||||
bool "IMX8MQ CCM Clock Driver"
|
||||
depends on ARCH_MXC
|
||||
tristate "IMX8MQ CCM Clock Driver"
|
||||
depends on ARCH_MXC || COMPILE_TEST
|
||||
select MXC_CLK
|
||||
help
|
||||
Build the driver for i.MX8MQ CCM Clock Driver
|
||||
|
||||
config CLK_IMX8QXP
|
||||
bool "IMX8QXP SCU Clock"
|
||||
depends on ARCH_MXC && IMX_SCU && ARM64
|
||||
tristate "IMX8QXP SCU Clock"
|
||||
depends on (ARCH_MXC && ARM64) || COMPILE_TEST
|
||||
depends on IMX_SCU && HAVE_ARM_SMCCC
|
||||
select MXC_CLK_SCU
|
||||
help
|
||||
Build the driver for IMX8QXP SCU based clocks.
|
||||
|
|
|
@ -1,48 +1,46 @@
|
|||
# SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
obj-$(CONFIG_MXC_CLK) += \
|
||||
clk.o \
|
||||
clk-busy.o \
|
||||
clk-composite-8m.o \
|
||||
clk-cpu.o \
|
||||
clk-composite-7ulp.o \
|
||||
clk-divider-gate.o \
|
||||
clk-fixup-div.o \
|
||||
clk-fixup-mux.o \
|
||||
clk-frac-pll.o \
|
||||
clk-gate-exclusive.o \
|
||||
clk-gate2.o \
|
||||
clk-pfd.o \
|
||||
clk-pfdv2.o \
|
||||
clk-pllv1.o \
|
||||
clk-pllv2.o \
|
||||
clk-pllv3.o \
|
||||
clk-pllv4.o \
|
||||
clk-sscg-pll.o \
|
||||
clk-pll14xx.o
|
||||
|
||||
obj-$(CONFIG_MXC_CLK_SCU) += \
|
||||
clk-scu.o \
|
||||
clk-lpcg-scu.o
|
||||
mxc-clk-objs += clk.o
|
||||
mxc-clk-objs += clk-busy.o
|
||||
mxc-clk-objs += clk-composite-7ulp.o
|
||||
mxc-clk-objs += clk-composite-8m.o
|
||||
mxc-clk-objs += clk-cpu.o
|
||||
mxc-clk-objs += clk-divider-gate.o
|
||||
mxc-clk-objs += clk-fixup-div.o
|
||||
mxc-clk-objs += clk-fixup-mux.o
|
||||
mxc-clk-objs += clk-frac-pll.o
|
||||
mxc-clk-objs += clk-gate2.o
|
||||
mxc-clk-objs += clk-gate-exclusive.o
|
||||
mxc-clk-objs += clk-pfd.o
|
||||
mxc-clk-objs += clk-pfdv2.o
|
||||
mxc-clk-objs += clk-pllv1.o
|
||||
mxc-clk-objs += clk-pllv2.o
|
||||
mxc-clk-objs += clk-pllv3.o
|
||||
mxc-clk-objs += clk-pllv4.o
|
||||
mxc-clk-objs += clk-pll14xx.o
|
||||
mxc-clk-objs += clk-sscg-pll.o
|
||||
obj-$(CONFIG_MXC_CLK) += mxc-clk.o
|
||||
|
||||
obj-$(CONFIG_CLK_IMX8MM) += clk-imx8mm.o
|
||||
obj-$(CONFIG_CLK_IMX8MN) += clk-imx8mn.o
|
||||
obj-$(CONFIG_CLK_IMX8MP) += clk-imx8mp.o
|
||||
obj-$(CONFIG_CLK_IMX8MQ) += clk-imx8mq.o
|
||||
obj-$(CONFIG_CLK_IMX8QXP) += clk-imx8qxp.o clk-imx8qxp-lpcg.o
|
||||
|
||||
obj-$(CONFIG_SOC_IMX1) += clk-imx1.o
|
||||
obj-$(CONFIG_SOC_IMX21) += clk-imx21.o
|
||||
obj-$(CONFIG_SOC_IMX25) += clk-imx25.o
|
||||
obj-$(CONFIG_SOC_IMX27) += clk-imx27.o
|
||||
obj-$(CONFIG_SOC_IMX31) += clk-imx31.o
|
||||
obj-$(CONFIG_SOC_IMX35) += clk-imx35.o
|
||||
obj-$(CONFIG_SOC_IMX5) += clk-imx5.o
|
||||
obj-$(CONFIG_SOC_IMX6Q) += clk-imx6q.o
|
||||
obj-$(CONFIG_SOC_IMX6SL) += clk-imx6sl.o
|
||||
obj-$(CONFIG_SOC_IMX6SLL) += clk-imx6sll.o
|
||||
obj-$(CONFIG_SOC_IMX6SX) += clk-imx6sx.o
|
||||
obj-$(CONFIG_SOC_IMX6UL) += clk-imx6ul.o
|
||||
obj-$(CONFIG_SOC_IMX7D) += clk-imx7d.o
|
||||
obj-$(CONFIG_SOC_IMX7ULP) += clk-imx7ulp.o
|
||||
obj-$(CONFIG_SOC_VF610) += clk-vf610.o
|
||||
obj-$(CONFIG_MXC_CLK_SCU) += clk-imx-scu.o clk-imx-lpcg-scu.o
|
||||
clk-imx-scu-$(CONFIG_CLK_IMX8QXP) += clk-scu.o clk-imx8qxp.o
|
||||
clk-imx-lpcg-scu-$(CONFIG_CLK_IMX8QXP) += clk-lpcg-scu.o clk-imx8qxp-lpcg.o
|
||||
|
||||
obj-$(CONFIG_CLK_IMX1) += clk-imx1.o
|
||||
obj-$(CONFIG_CLK_IMX25) += clk-imx25.o
|
||||
obj-$(CONFIG_CLK_IMX27) += clk-imx27.o
|
||||
obj-$(CONFIG_CLK_IMX31) += clk-imx31.o
|
||||
obj-$(CONFIG_CLK_IMX35) += clk-imx35.o
|
||||
obj-$(CONFIG_CLK_IMX5) += clk-imx5.o
|
||||
obj-$(CONFIG_CLK_IMX6Q) += clk-imx6q.o
|
||||
obj-$(CONFIG_CLK_IMX6SL) += clk-imx6sl.o
|
||||
obj-$(CONFIG_CLK_IMX6SLL) += clk-imx6sll.o
|
||||
obj-$(CONFIG_CLK_IMX6SX) += clk-imx6sx.o
|
||||
obj-$(CONFIG_CLK_IMX6UL) += clk-imx6ul.o
|
||||
obj-$(CONFIG_CLK_IMX7D) += clk-imx7d.o
|
||||
obj-$(CONFIG_CLK_IMX7ULP) += clk-imx7ulp.o
|
||||
obj-$(CONFIG_CLK_VF610) += clk-vf610.o
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* Copyright 2012 Linaro Ltd.
|
||||
*/
|
||||
|
||||
#include <linux/bits.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/io.h>
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <linux/bits.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/slab.h>
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
|
@ -215,6 +216,7 @@ struct clk_hw *imx8m_clk_hw_composite_flags(const char *name,
|
|||
div->width = PCG_PREDIV_WIDTH;
|
||||
divider_ops = &imx8m_clk_composite_divider_ops;
|
||||
mux_ops = &clk_mux_ops;
|
||||
flags |= CLK_SET_PARENT_GATE;
|
||||
}
|
||||
|
||||
div->lock = &imx_ccm_lock;
|
||||
|
@ -243,3 +245,4 @@ fail:
|
|||
kfree(mux);
|
||||
return ERR_CAST(hw);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(imx8m_clk_hw_composite_flags);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/slab.h>
|
||||
#include "clk.h"
|
||||
|
||||
|
@ -104,3 +105,4 @@ struct clk_hw *imx_clk_hw_cpu(const char *name, const char *parent_name,
|
|||
|
||||
return hw;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(imx_clk_hw_cpu);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* Copyright (C) 2013 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <linux/bits.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/slab.h>
|
||||
|
@ -233,3 +234,4 @@ struct clk_hw *imx_clk_hw_frac_pll(const char *name,
|
|||
|
||||
return hw;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(imx_clk_hw_frac_pll);
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/io.h>
|
||||
|
@ -15,7 +16,7 @@
|
|||
#include "clk.h"
|
||||
|
||||
/**
|
||||
* DOC: basic gatable clock which can gate and ungate it's ouput
|
||||
* DOC: basic gateable clock which can gate and ungate its output
|
||||
*
|
||||
* Traits of this clock:
|
||||
* prepare - clk_(un)prepare only ensures parent is (un)prepared
|
||||
|
@ -177,3 +178,4 @@ struct clk_hw *clk_hw_register_gate2(struct device *dev, const char *name,
|
|||
|
||||
return hw;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_hw_register_gate2);
|
||||
|
|
|
@ -1,171 +0,0 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright 2004-2007 Freescale Semiconductor, Inc. All Rights Reserved.
|
||||
* Copyright 2008 Juergen Beisert, kernel@pengutronix.de
|
||||
* Copyright 2008 Martin Fuzzey, mfuzzey@gmail.com
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <dt-bindings/clock/imx21-clock.h>
|
||||
#include <soc/imx/timer.h>
|
||||
#include <asm/irq.h>
|
||||
|
||||
#include "clk.h"
|
||||
|
||||
#define MX21_CCM_BASE_ADDR 0x10027000
|
||||
#define MX21_GPT1_BASE_ADDR 0x10003000
|
||||
#define MX21_INT_GPT1 (NR_IRQS_LEGACY + 26)
|
||||
|
||||
static void __iomem *ccm __initdata;
|
||||
|
||||
/* Register offsets */
|
||||
#define CCM_CSCR (ccm + 0x00)
|
||||
#define CCM_MPCTL0 (ccm + 0x04)
|
||||
#define CCM_SPCTL0 (ccm + 0x0c)
|
||||
#define CCM_PCDR0 (ccm + 0x18)
|
||||
#define CCM_PCDR1 (ccm + 0x1c)
|
||||
#define CCM_PCCR0 (ccm + 0x20)
|
||||
#define CCM_PCCR1 (ccm + 0x24)
|
||||
|
||||
static const char *mpll_osc_sel_clks[] = { "ckih_gate", "ckih_div1p5", };
|
||||
static const char *mpll_sel_clks[] = { "fpm_gate", "mpll_osc_sel", };
|
||||
static const char *spll_sel_clks[] = { "fpm_gate", "mpll_osc_sel", };
|
||||
static const char *ssi_sel_clks[] = { "spll_gate", "mpll_gate", };
|
||||
|
||||
static struct clk *clk[IMX21_CLK_MAX];
|
||||
static struct clk_onecell_data clk_data;
|
||||
|
||||
static void __init _mx21_clocks_init(unsigned long lref, unsigned long href)
|
||||
{
|
||||
BUG_ON(!ccm);
|
||||
|
||||
clk[IMX21_CLK_DUMMY] = imx_clk_fixed("dummy", 0);
|
||||
clk[IMX21_CLK_CKIL] = imx_obtain_fixed_clock("ckil", lref);
|
||||
clk[IMX21_CLK_CKIH] = imx_obtain_fixed_clock("ckih", href);
|
||||
clk[IMX21_CLK_FPM] = imx_clk_fixed_factor("fpm", "ckil", 512, 1);
|
||||
clk[IMX21_CLK_CKIH_DIV1P5] = imx_clk_fixed_factor("ckih_div1p5", "ckih_gate", 2, 3);
|
||||
|
||||
clk[IMX21_CLK_MPLL_GATE] = imx_clk_gate("mpll_gate", "mpll", CCM_CSCR, 0);
|
||||
clk[IMX21_CLK_SPLL_GATE] = imx_clk_gate("spll_gate", "spll", CCM_CSCR, 1);
|
||||
clk[IMX21_CLK_FPM_GATE] = imx_clk_gate("fpm_gate", "fpm", CCM_CSCR, 2);
|
||||
clk[IMX21_CLK_CKIH_GATE] = imx_clk_gate_dis("ckih_gate", "ckih", CCM_CSCR, 3);
|
||||
clk[IMX21_CLK_MPLL_OSC_SEL] = imx_clk_mux("mpll_osc_sel", CCM_CSCR, 4, 1, mpll_osc_sel_clks, ARRAY_SIZE(mpll_osc_sel_clks));
|
||||
clk[IMX21_CLK_IPG] = imx_clk_divider("ipg", "hclk", CCM_CSCR, 9, 1);
|
||||
clk[IMX21_CLK_HCLK] = imx_clk_divider("hclk", "fclk", CCM_CSCR, 10, 4);
|
||||
clk[IMX21_CLK_MPLL_SEL] = imx_clk_mux("mpll_sel", CCM_CSCR, 16, 1, mpll_sel_clks, ARRAY_SIZE(mpll_sel_clks));
|
||||
clk[IMX21_CLK_SPLL_SEL] = imx_clk_mux("spll_sel", CCM_CSCR, 17, 1, spll_sel_clks, ARRAY_SIZE(spll_sel_clks));
|
||||
clk[IMX21_CLK_SSI1_SEL] = imx_clk_mux("ssi1_sel", CCM_CSCR, 19, 1, ssi_sel_clks, ARRAY_SIZE(ssi_sel_clks));
|
||||
clk[IMX21_CLK_SSI2_SEL] = imx_clk_mux("ssi2_sel", CCM_CSCR, 20, 1, ssi_sel_clks, ARRAY_SIZE(ssi_sel_clks));
|
||||
clk[IMX21_CLK_USB_DIV] = imx_clk_divider("usb_div", "spll_gate", CCM_CSCR, 26, 3);
|
||||
clk[IMX21_CLK_FCLK] = imx_clk_divider("fclk", "mpll_gate", CCM_CSCR, 29, 3);
|
||||
|
||||
clk[IMX21_CLK_MPLL] = imx_clk_pllv1(IMX_PLLV1_IMX21, "mpll", "mpll_sel", CCM_MPCTL0);
|
||||
|
||||
clk[IMX21_CLK_SPLL] = imx_clk_pllv1(IMX_PLLV1_IMX21, "spll", "spll_sel", CCM_SPCTL0);
|
||||
|
||||
clk[IMX21_CLK_NFC_DIV] = imx_clk_divider("nfc_div", "fclk", CCM_PCDR0, 12, 4);
|
||||
clk[IMX21_CLK_SSI1_DIV] = imx_clk_divider("ssi1_div", "ssi1_sel", CCM_PCDR0, 16, 6);
|
||||
clk[IMX21_CLK_SSI2_DIV] = imx_clk_divider("ssi2_div", "ssi2_sel", CCM_PCDR0, 26, 6);
|
||||
|
||||
clk[IMX21_CLK_PER1] = imx_clk_divider("per1", "mpll_gate", CCM_PCDR1, 0, 6);
|
||||
clk[IMX21_CLK_PER2] = imx_clk_divider("per2", "mpll_gate", CCM_PCDR1, 8, 6);
|
||||
clk[IMX21_CLK_PER3] = imx_clk_divider("per3", "mpll_gate", CCM_PCDR1, 16, 6);
|
||||
clk[IMX21_CLK_PER4] = imx_clk_divider("per4", "mpll_gate", CCM_PCDR1, 24, 6);
|
||||
|
||||
clk[IMX21_CLK_UART1_IPG_GATE] = imx_clk_gate("uart1_ipg_gate", "ipg", CCM_PCCR0, 0);
|
||||
clk[IMX21_CLK_UART2_IPG_GATE] = imx_clk_gate("uart2_ipg_gate", "ipg", CCM_PCCR0, 1);
|
||||
clk[IMX21_CLK_UART3_IPG_GATE] = imx_clk_gate("uart3_ipg_gate", "ipg", CCM_PCCR0, 2);
|
||||
clk[IMX21_CLK_UART4_IPG_GATE] = imx_clk_gate("uart4_ipg_gate", "ipg", CCM_PCCR0, 3);
|
||||
clk[IMX21_CLK_CSPI1_IPG_GATE] = imx_clk_gate("cspi1_ipg_gate", "ipg", CCM_PCCR0, 4);
|
||||
clk[IMX21_CLK_CSPI2_IPG_GATE] = imx_clk_gate("cspi2_ipg_gate", "ipg", CCM_PCCR0, 5);
|
||||
clk[IMX21_CLK_SSI1_GATE] = imx_clk_gate("ssi1_gate", "ipg", CCM_PCCR0, 6);
|
||||
clk[IMX21_CLK_SSI2_GATE] = imx_clk_gate("ssi2_gate", "ipg", CCM_PCCR0, 7);
|
||||
clk[IMX21_CLK_SDHC1_IPG_GATE] = imx_clk_gate("sdhc1_ipg_gate", "ipg", CCM_PCCR0, 9);
|
||||
clk[IMX21_CLK_SDHC2_IPG_GATE] = imx_clk_gate("sdhc2_ipg_gate", "ipg", CCM_PCCR0, 10);
|
||||
clk[IMX21_CLK_GPIO_GATE] = imx_clk_gate("gpio_gate", "ipg", CCM_PCCR0, 11);
|
||||
clk[IMX21_CLK_I2C_GATE] = imx_clk_gate("i2c_gate", "ipg", CCM_PCCR0, 12);
|
||||
clk[IMX21_CLK_DMA_GATE] = imx_clk_gate("dma_gate", "ipg", CCM_PCCR0, 13);
|
||||
clk[IMX21_CLK_USB_GATE] = imx_clk_gate("usb_gate", "usb_div", CCM_PCCR0, 14);
|
||||
clk[IMX21_CLK_EMMA_GATE] = imx_clk_gate("emma_gate", "ipg", CCM_PCCR0, 15);
|
||||
clk[IMX21_CLK_SSI2_BAUD_GATE] = imx_clk_gate("ssi2_baud_gate", "ipg", CCM_PCCR0, 16);
|
||||
clk[IMX21_CLK_SSI1_BAUD_GATE] = imx_clk_gate("ssi1_baud_gate", "ipg", CCM_PCCR0, 17);
|
||||
clk[IMX21_CLK_LCDC_IPG_GATE] = imx_clk_gate("lcdc_ipg_gate", "ipg", CCM_PCCR0, 18);
|
||||
clk[IMX21_CLK_NFC_GATE] = imx_clk_gate("nfc_gate", "nfc_div", CCM_PCCR0, 19);
|
||||
clk[IMX21_CLK_SLCDC_HCLK_GATE] = imx_clk_gate("slcdc_hclk_gate", "hclk", CCM_PCCR0, 21);
|
||||
clk[IMX21_CLK_PER4_GATE] = imx_clk_gate("per4_gate", "per4", CCM_PCCR0, 22);
|
||||
clk[IMX21_CLK_BMI_GATE] = imx_clk_gate("bmi_gate", "hclk", CCM_PCCR0, 23);
|
||||
clk[IMX21_CLK_USB_HCLK_GATE] = imx_clk_gate("usb_hclk_gate", "hclk", CCM_PCCR0, 24);
|
||||
clk[IMX21_CLK_SLCDC_GATE] = imx_clk_gate("slcdc_gate", "hclk", CCM_PCCR0, 25);
|
||||
clk[IMX21_CLK_LCDC_HCLK_GATE] = imx_clk_gate("lcdc_hclk_gate", "hclk", CCM_PCCR0, 26);
|
||||
clk[IMX21_CLK_EMMA_HCLK_GATE] = imx_clk_gate("emma_hclk_gate", "hclk", CCM_PCCR0, 27);
|
||||
clk[IMX21_CLK_BROM_GATE] = imx_clk_gate("brom_gate", "hclk", CCM_PCCR0, 28);
|
||||
clk[IMX21_CLK_DMA_HCLK_GATE] = imx_clk_gate("dma_hclk_gate", "hclk", CCM_PCCR0, 30);
|
||||
clk[IMX21_CLK_CSI_HCLK_GATE] = imx_clk_gate("csi_hclk_gate", "hclk", CCM_PCCR0, 31);
|
||||
|
||||
clk[IMX21_CLK_CSPI3_IPG_GATE] = imx_clk_gate("cspi3_ipg_gate", "ipg", CCM_PCCR1, 23);
|
||||
clk[IMX21_CLK_WDOG_GATE] = imx_clk_gate("wdog_gate", "ipg", CCM_PCCR1, 24);
|
||||
clk[IMX21_CLK_GPT1_IPG_GATE] = imx_clk_gate("gpt1_ipg_gate", "ipg", CCM_PCCR1, 25);
|
||||
clk[IMX21_CLK_GPT2_IPG_GATE] = imx_clk_gate("gpt2_ipg_gate", "ipg", CCM_PCCR1, 26);
|
||||
clk[IMX21_CLK_GPT3_IPG_GATE] = imx_clk_gate("gpt3_ipg_gate", "ipg", CCM_PCCR1, 27);
|
||||
clk[IMX21_CLK_PWM_IPG_GATE] = imx_clk_gate("pwm_ipg_gate", "ipg", CCM_PCCR1, 28);
|
||||
clk[IMX21_CLK_RTC_GATE] = imx_clk_gate("rtc_gate", "ipg", CCM_PCCR1, 29);
|
||||
clk[IMX21_CLK_KPP_GATE] = imx_clk_gate("kpp_gate", "ipg", CCM_PCCR1, 30);
|
||||
clk[IMX21_CLK_OWIRE_GATE] = imx_clk_gate("owire_gate", "ipg", CCM_PCCR1, 31);
|
||||
|
||||
imx_check_clocks(clk, ARRAY_SIZE(clk));
|
||||
}
|
||||
|
||||
int __init mx21_clocks_init(unsigned long lref, unsigned long href)
|
||||
{
|
||||
ccm = ioremap(MX21_CCM_BASE_ADDR, SZ_2K);
|
||||
|
||||
_mx21_clocks_init(lref, href);
|
||||
|
||||
clk_register_clkdev(clk[IMX21_CLK_PER1], "per", "imx21-uart.0");
|
||||
clk_register_clkdev(clk[IMX21_CLK_UART1_IPG_GATE], "ipg", "imx21-uart.0");
|
||||
clk_register_clkdev(clk[IMX21_CLK_PER1], "per", "imx21-uart.1");
|
||||
clk_register_clkdev(clk[IMX21_CLK_UART2_IPG_GATE], "ipg", "imx21-uart.1");
|
||||
clk_register_clkdev(clk[IMX21_CLK_PER1], "per", "imx21-uart.2");
|
||||
clk_register_clkdev(clk[IMX21_CLK_UART3_IPG_GATE], "ipg", "imx21-uart.2");
|
||||
clk_register_clkdev(clk[IMX21_CLK_PER1], "per", "imx21-uart.3");
|
||||
clk_register_clkdev(clk[IMX21_CLK_UART4_IPG_GATE], "ipg", "imx21-uart.3");
|
||||
clk_register_clkdev(clk[IMX21_CLK_GPT1_IPG_GATE], "ipg", "imx-gpt.0");
|
||||
clk_register_clkdev(clk[IMX21_CLK_PER1], "per", "imx-gpt.0");
|
||||
clk_register_clkdev(clk[IMX21_CLK_PER2], "per", "imx21-cspi.0");
|
||||
clk_register_clkdev(clk[IMX21_CLK_CSPI1_IPG_GATE], "ipg", "imx21-cspi.0");
|
||||
clk_register_clkdev(clk[IMX21_CLK_PER2], "per", "imx21-cspi.1");
|
||||
clk_register_clkdev(clk[IMX21_CLK_CSPI2_IPG_GATE], "ipg", "imx21-cspi.1");
|
||||
clk_register_clkdev(clk[IMX21_CLK_PER2], "per", "imx21-cspi.2");
|
||||
clk_register_clkdev(clk[IMX21_CLK_CSPI3_IPG_GATE], "ipg", "imx21-cspi.2");
|
||||
clk_register_clkdev(clk[IMX21_CLK_PER3], "per", "imx21-fb.0");
|
||||
clk_register_clkdev(clk[IMX21_CLK_LCDC_IPG_GATE], "ipg", "imx21-fb.0");
|
||||
clk_register_clkdev(clk[IMX21_CLK_LCDC_HCLK_GATE], "ahb", "imx21-fb.0");
|
||||
clk_register_clkdev(clk[IMX21_CLK_USB_GATE], "per", "imx21-hcd.0");
|
||||
clk_register_clkdev(clk[IMX21_CLK_USB_HCLK_GATE], "ahb", "imx21-hcd.0");
|
||||
clk_register_clkdev(clk[IMX21_CLK_NFC_GATE], NULL, "imx21-nand.0");
|
||||
clk_register_clkdev(clk[IMX21_CLK_DMA_HCLK_GATE], "ahb", "imx21-dma");
|
||||
clk_register_clkdev(clk[IMX21_CLK_DMA_GATE], "ipg", "imx21-dma");
|
||||
clk_register_clkdev(clk[IMX21_CLK_WDOG_GATE], NULL, "imx2-wdt.0");
|
||||
clk_register_clkdev(clk[IMX21_CLK_I2C_GATE], NULL, "imx21-i2c.0");
|
||||
clk_register_clkdev(clk[IMX21_CLK_OWIRE_GATE], NULL, "mxc_w1.0");
|
||||
|
||||
mxc_timer_init(MX21_GPT1_BASE_ADDR, MX21_INT_GPT1, GPT_TYPE_IMX21);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __init mx21_clocks_init_dt(struct device_node *np)
|
||||
{
|
||||
ccm = of_iomap(np, 0);
|
||||
|
||||
_mx21_clocks_init(32768, 26000000);
|
||||
|
||||
clk_data.clks = clk;
|
||||
clk_data.clk_num = ARRAY_SIZE(clk);
|
||||
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
|
||||
}
|
||||
CLK_OF_DECLARE(imx27_ccm, "fsl,imx21-ccm", mx21_clocks_init_dt);
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <linux/init.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/bits.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/clk-provider.h>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
* Copyright 2013-2014 Freescale Semiconductor, Inc.
|
||||
*/
|
||||
|
||||
#include <linux/bits.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/err.h>
|
||||
|
@ -14,19 +15,19 @@
|
|||
#include "clk.h"
|
||||
|
||||
#define CCSR 0xc
|
||||
#define BM_CCSR_PLL1_SW_CLK_SEL (1 << 2)
|
||||
#define BM_CCSR_PLL1_SW_CLK_SEL BIT(2)
|
||||
#define CACRR 0x10
|
||||
#define CDHIPR 0x48
|
||||
#define BM_CDHIPR_ARM_PODF_BUSY (1 << 16)
|
||||
#define BM_CDHIPR_ARM_PODF_BUSY BIT(16)
|
||||
#define ARM_WAIT_DIV_396M 2
|
||||
#define ARM_WAIT_DIV_792M 4
|
||||
#define ARM_WAIT_DIV_996M 6
|
||||
|
||||
#define PLL_ARM 0x0
|
||||
#define BM_PLL_ARM_DIV_SELECT (0x7f << 0)
|
||||
#define BM_PLL_ARM_POWERDOWN (1 << 12)
|
||||
#define BM_PLL_ARM_ENABLE (1 << 13)
|
||||
#define BM_PLL_ARM_LOCK (1 << 31)
|
||||
#define BM_PLL_ARM_DIV_SELECT 0x7f
|
||||
#define BM_PLL_ARM_POWERDOWN BIT(12)
|
||||
#define BM_PLL_ARM_ENABLE BIT(13)
|
||||
#define BM_PLL_ARM_LOCK BIT(31)
|
||||
#define PLL_ARM_DIV_792M 66
|
||||
|
||||
static const char *step_sels[] = { "osc", "pll2_pfd2", };
|
||||
|
@ -145,7 +146,7 @@ static void imx6sl_enable_pll_arm(bool enable)
|
|||
val |= BM_PLL_ARM_ENABLE;
|
||||
val &= ~BM_PLL_ARM_POWERDOWN;
|
||||
writel_relaxed(val, anatop_base + PLL_ARM);
|
||||
while (!(__raw_readl(anatop_base + PLL_ARM) & BM_PLL_ARM_LOCK))
|
||||
while (!(readl_relaxed(anatop_base + PLL_ARM) & BM_PLL_ARM_LOCK))
|
||||
;
|
||||
} else {
|
||||
writel_relaxed(saved_pll_arm, anatop_base + PLL_ARM);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
|
||||
#include <dt-bindings/clock/imx6sx-clock.h>
|
||||
#include <linux/bits.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/clk-provider.h>
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
|
||||
#include <dt-bindings/clock/imx7d-clock.h>
|
||||
#include <linux/bits.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/clk-provider.h>
|
||||
|
@ -505,72 +506,73 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
|
|||
hws[IMX7D_ARM_M4_ROOT_SRC] = imx_clk_hw_mux2("arm_m4_src", base + 0x8080, 24, 3, arm_m4_sel, ARRAY_SIZE(arm_m4_sel));
|
||||
hws[IMX7D_MAIN_AXI_ROOT_SRC] = imx_clk_hw_mux2("axi_src", base + 0x8800, 24, 3, axi_sel, ARRAY_SIZE(axi_sel));
|
||||
hws[IMX7D_DISP_AXI_ROOT_SRC] = imx_clk_hw_mux2("disp_axi_src", base + 0x8880, 24, 3, disp_axi_sel, ARRAY_SIZE(disp_axi_sel));
|
||||
hws[IMX7D_ENET_AXI_ROOT_SRC] = imx_clk_hw_mux2("enet_axi_src", base + 0x8900, 24, 3, enet_axi_sel, ARRAY_SIZE(enet_axi_sel));
|
||||
hws[IMX7D_NAND_USDHC_BUS_ROOT_SRC] = imx_clk_hw_mux2("nand_usdhc_src", base + 0x8980, 24, 3, nand_usdhc_bus_sel, ARRAY_SIZE(nand_usdhc_bus_sel));
|
||||
hws[IMX7D_AHB_CHANNEL_ROOT_SRC] = imx_clk_hw_mux2("ahb_src", base + 0x9000, 24, 3, ahb_channel_sel, ARRAY_SIZE(ahb_channel_sel));
|
||||
hws[IMX7D_DRAM_PHYM_ROOT_SRC] = imx_clk_hw_mux2("dram_phym_src", base + 0x9800, 24, 1, dram_phym_sel, ARRAY_SIZE(dram_phym_sel));
|
||||
hws[IMX7D_DRAM_ROOT_SRC] = imx_clk_hw_mux2("dram_src", base + 0x9880, 24, 1, dram_sel, ARRAY_SIZE(dram_sel));
|
||||
hws[IMX7D_DRAM_PHYM_ALT_ROOT_SRC] = imx_clk_hw_mux2("dram_phym_alt_src", base + 0xa000, 24, 3, dram_phym_alt_sel, ARRAY_SIZE(dram_phym_alt_sel));
|
||||
hws[IMX7D_DRAM_ALT_ROOT_SRC] = imx_clk_hw_mux2("dram_alt_src", base + 0xa080, 24, 3, dram_alt_sel, ARRAY_SIZE(dram_alt_sel));
|
||||
hws[IMX7D_USB_HSIC_ROOT_SRC] = imx_clk_hw_mux2("usb_hsic_src", base + 0xa100, 24, 3, usb_hsic_sel, ARRAY_SIZE(usb_hsic_sel));
|
||||
hws[IMX7D_PCIE_CTRL_ROOT_SRC] = imx_clk_hw_mux2("pcie_ctrl_src", base + 0xa180, 24, 3, pcie_ctrl_sel, ARRAY_SIZE(pcie_ctrl_sel));
|
||||
hws[IMX7D_PCIE_PHY_ROOT_SRC] = imx_clk_hw_mux2("pcie_phy_src", base + 0xa200, 24, 3, pcie_phy_sel, ARRAY_SIZE(pcie_phy_sel));
|
||||
hws[IMX7D_EPDC_PIXEL_ROOT_SRC] = imx_clk_hw_mux2("epdc_pixel_src", base + 0xa280, 24, 3, epdc_pixel_sel, ARRAY_SIZE(epdc_pixel_sel));
|
||||
hws[IMX7D_LCDIF_PIXEL_ROOT_SRC] = imx_clk_hw_mux2("lcdif_pixel_src", base + 0xa300, 24, 3, lcdif_pixel_sel, ARRAY_SIZE(lcdif_pixel_sel));
|
||||
hws[IMX7D_MIPI_DSI_ROOT_SRC] = imx_clk_hw_mux2("mipi_dsi_src", base + 0xa380, 24, 3, mipi_dsi_sel, ARRAY_SIZE(mipi_dsi_sel));
|
||||
hws[IMX7D_MIPI_CSI_ROOT_SRC] = imx_clk_hw_mux2("mipi_csi_src", base + 0xa400, 24, 3, mipi_csi_sel, ARRAY_SIZE(mipi_csi_sel));
|
||||
hws[IMX7D_MIPI_DPHY_ROOT_SRC] = imx_clk_hw_mux2("mipi_dphy_src", base + 0xa480, 24, 3, mipi_dphy_sel, ARRAY_SIZE(mipi_dphy_sel));
|
||||
hws[IMX7D_SAI1_ROOT_SRC] = imx_clk_hw_mux2("sai1_src", base + 0xa500, 24, 3, sai1_sel, ARRAY_SIZE(sai1_sel));
|
||||
hws[IMX7D_SAI2_ROOT_SRC] = imx_clk_hw_mux2("sai2_src", base + 0xa580, 24, 3, sai2_sel, ARRAY_SIZE(sai2_sel));
|
||||
hws[IMX7D_SAI3_ROOT_SRC] = imx_clk_hw_mux2("sai3_src", base + 0xa600, 24, 3, sai3_sel, ARRAY_SIZE(sai3_sel));
|
||||
hws[IMX7D_SPDIF_ROOT_SRC] = imx_clk_hw_mux2("spdif_src", base + 0xa680, 24, 3, spdif_sel, ARRAY_SIZE(spdif_sel));
|
||||
hws[IMX7D_ENET1_REF_ROOT_SRC] = imx_clk_hw_mux2("enet1_ref_src", base + 0xa700, 24, 3, enet1_ref_sel, ARRAY_SIZE(enet1_ref_sel));
|
||||
hws[IMX7D_ENET1_TIME_ROOT_SRC] = imx_clk_hw_mux2("enet1_time_src", base + 0xa780, 24, 3, enet1_time_sel, ARRAY_SIZE(enet1_time_sel));
|
||||
hws[IMX7D_ENET2_REF_ROOT_SRC] = imx_clk_hw_mux2("enet2_ref_src", base + 0xa800, 24, 3, enet2_ref_sel, ARRAY_SIZE(enet2_ref_sel));
|
||||
hws[IMX7D_ENET2_TIME_ROOT_SRC] = imx_clk_hw_mux2("enet2_time_src", base + 0xa880, 24, 3, enet2_time_sel, ARRAY_SIZE(enet2_time_sel));
|
||||
hws[IMX7D_ENET_PHY_REF_ROOT_SRC] = imx_clk_hw_mux2("enet_phy_ref_src", base + 0xa900, 24, 3, enet_phy_ref_sel, ARRAY_SIZE(enet_phy_ref_sel));
|
||||
hws[IMX7D_EIM_ROOT_SRC] = imx_clk_hw_mux2("eim_src", base + 0xa980, 24, 3, eim_sel, ARRAY_SIZE(eim_sel));
|
||||
hws[IMX7D_NAND_ROOT_SRC] = imx_clk_hw_mux2("nand_src", base + 0xaa00, 24, 3, nand_sel, ARRAY_SIZE(nand_sel));
|
||||
hws[IMX7D_QSPI_ROOT_SRC] = imx_clk_hw_mux2("qspi_src", base + 0xaa80, 24, 3, qspi_sel, ARRAY_SIZE(qspi_sel));
|
||||
hws[IMX7D_USDHC1_ROOT_SRC] = imx_clk_hw_mux2("usdhc1_src", base + 0xab00, 24, 3, usdhc1_sel, ARRAY_SIZE(usdhc1_sel));
|
||||
hws[IMX7D_USDHC2_ROOT_SRC] = imx_clk_hw_mux2("usdhc2_src", base + 0xab80, 24, 3, usdhc2_sel, ARRAY_SIZE(usdhc2_sel));
|
||||
hws[IMX7D_USDHC3_ROOT_SRC] = imx_clk_hw_mux2("usdhc3_src", base + 0xac00, 24, 3, usdhc3_sel, ARRAY_SIZE(usdhc3_sel));
|
||||
hws[IMX7D_CAN1_ROOT_SRC] = imx_clk_hw_mux2("can1_src", base + 0xac80, 24, 3, can1_sel, ARRAY_SIZE(can1_sel));
|
||||
hws[IMX7D_CAN2_ROOT_SRC] = imx_clk_hw_mux2("can2_src", base + 0xad00, 24, 3, can2_sel, ARRAY_SIZE(can2_sel));
|
||||
hws[IMX7D_I2C1_ROOT_SRC] = imx_clk_hw_mux2("i2c1_src", base + 0xad80, 24, 3, i2c1_sel, ARRAY_SIZE(i2c1_sel));
|
||||
hws[IMX7D_I2C2_ROOT_SRC] = imx_clk_hw_mux2("i2c2_src", base + 0xae00, 24, 3, i2c2_sel, ARRAY_SIZE(i2c2_sel));
|
||||
hws[IMX7D_I2C3_ROOT_SRC] = imx_clk_hw_mux2("i2c3_src", base + 0xae80, 24, 3, i2c3_sel, ARRAY_SIZE(i2c3_sel));
|
||||
hws[IMX7D_I2C4_ROOT_SRC] = imx_clk_hw_mux2("i2c4_src", base + 0xaf00, 24, 3, i2c4_sel, ARRAY_SIZE(i2c4_sel));
|
||||
hws[IMX7D_UART1_ROOT_SRC] = imx_clk_hw_mux2("uart1_src", base + 0xaf80, 24, 3, uart1_sel, ARRAY_SIZE(uart1_sel));
|
||||
hws[IMX7D_UART2_ROOT_SRC] = imx_clk_hw_mux2("uart2_src", base + 0xb000, 24, 3, uart2_sel, ARRAY_SIZE(uart2_sel));
|
||||
hws[IMX7D_UART3_ROOT_SRC] = imx_clk_hw_mux2("uart3_src", base + 0xb080, 24, 3, uart3_sel, ARRAY_SIZE(uart3_sel));
|
||||
hws[IMX7D_UART4_ROOT_SRC] = imx_clk_hw_mux2("uart4_src", base + 0xb100, 24, 3, uart4_sel, ARRAY_SIZE(uart4_sel));
|
||||
hws[IMX7D_UART5_ROOT_SRC] = imx_clk_hw_mux2("uart5_src", base + 0xb180, 24, 3, uart5_sel, ARRAY_SIZE(uart5_sel));
|
||||
hws[IMX7D_UART6_ROOT_SRC] = imx_clk_hw_mux2("uart6_src", base + 0xb200, 24, 3, uart6_sel, ARRAY_SIZE(uart6_sel));
|
||||
hws[IMX7D_UART7_ROOT_SRC] = imx_clk_hw_mux2("uart7_src", base + 0xb280, 24, 3, uart7_sel, ARRAY_SIZE(uart7_sel));
|
||||
hws[IMX7D_ECSPI1_ROOT_SRC] = imx_clk_hw_mux2("ecspi1_src", base + 0xb300, 24, 3, ecspi1_sel, ARRAY_SIZE(ecspi1_sel));
|
||||
hws[IMX7D_ECSPI2_ROOT_SRC] = imx_clk_hw_mux2("ecspi2_src", base + 0xb380, 24, 3, ecspi2_sel, ARRAY_SIZE(ecspi2_sel));
|
||||
hws[IMX7D_ECSPI3_ROOT_SRC] = imx_clk_hw_mux2("ecspi3_src", base + 0xb400, 24, 3, ecspi3_sel, ARRAY_SIZE(ecspi3_sel));
|
||||
hws[IMX7D_ECSPI4_ROOT_SRC] = imx_clk_hw_mux2("ecspi4_src", base + 0xb480, 24, 3, ecspi4_sel, ARRAY_SIZE(ecspi4_sel));
|
||||
hws[IMX7D_PWM1_ROOT_SRC] = imx_clk_hw_mux2("pwm1_src", base + 0xb500, 24, 3, pwm1_sel, ARRAY_SIZE(pwm1_sel));
|
||||
hws[IMX7D_PWM2_ROOT_SRC] = imx_clk_hw_mux2("pwm2_src", base + 0xb580, 24, 3, pwm2_sel, ARRAY_SIZE(pwm2_sel));
|
||||
hws[IMX7D_PWM3_ROOT_SRC] = imx_clk_hw_mux2("pwm3_src", base + 0xb600, 24, 3, pwm3_sel, ARRAY_SIZE(pwm3_sel));
|
||||
hws[IMX7D_PWM4_ROOT_SRC] = imx_clk_hw_mux2("pwm4_src", base + 0xb680, 24, 3, pwm4_sel, ARRAY_SIZE(pwm4_sel));
|
||||
hws[IMX7D_FLEXTIMER1_ROOT_SRC] = imx_clk_hw_mux2("flextimer1_src", base + 0xb700, 24, 3, flextimer1_sel, ARRAY_SIZE(flextimer1_sel));
|
||||
hws[IMX7D_FLEXTIMER2_ROOT_SRC] = imx_clk_hw_mux2("flextimer2_src", base + 0xb780, 24, 3, flextimer2_sel, ARRAY_SIZE(flextimer2_sel));
|
||||
hws[IMX7D_SIM1_ROOT_SRC] = imx_clk_hw_mux2("sim1_src", base + 0xb800, 24, 3, sim1_sel, ARRAY_SIZE(sim1_sel));
|
||||
hws[IMX7D_SIM2_ROOT_SRC] = imx_clk_hw_mux2("sim2_src", base + 0xb880, 24, 3, sim2_sel, ARRAY_SIZE(sim2_sel));
|
||||
hws[IMX7D_GPT1_ROOT_SRC] = imx_clk_hw_mux2("gpt1_src", base + 0xb900, 24, 3, gpt1_sel, ARRAY_SIZE(gpt1_sel));
|
||||
hws[IMX7D_GPT2_ROOT_SRC] = imx_clk_hw_mux2("gpt2_src", base + 0xb980, 24, 3, gpt2_sel, ARRAY_SIZE(gpt2_sel));
|
||||
hws[IMX7D_GPT3_ROOT_SRC] = imx_clk_hw_mux2("gpt3_src", base + 0xba00, 24, 3, gpt3_sel, ARRAY_SIZE(gpt3_sel));
|
||||
hws[IMX7D_GPT4_ROOT_SRC] = imx_clk_hw_mux2("gpt4_src", base + 0xba80, 24, 3, gpt4_sel, ARRAY_SIZE(gpt4_sel));
|
||||
hws[IMX7D_TRACE_ROOT_SRC] = imx_clk_hw_mux2("trace_src", base + 0xbb00, 24, 3, trace_sel, ARRAY_SIZE(trace_sel));
|
||||
hws[IMX7D_WDOG_ROOT_SRC] = imx_clk_hw_mux2("wdog_src", base + 0xbb80, 24, 3, wdog_sel, ARRAY_SIZE(wdog_sel));
|
||||
hws[IMX7D_CSI_MCLK_ROOT_SRC] = imx_clk_hw_mux2("csi_mclk_src", base + 0xbc00, 24, 3, csi_mclk_sel, ARRAY_SIZE(csi_mclk_sel));
|
||||
hws[IMX7D_AUDIO_MCLK_ROOT_SRC] = imx_clk_hw_mux2("audio_mclk_src", base + 0xbc80, 24, 3, audio_mclk_sel, ARRAY_SIZE(audio_mclk_sel));
|
||||
hws[IMX7D_WRCLK_ROOT_SRC] = imx_clk_hw_mux2("wrclk_src", base + 0xbd00, 24, 3, wrclk_sel, ARRAY_SIZE(wrclk_sel));
|
||||
hws[IMX7D_CLKO1_ROOT_SRC] = imx_clk_hw_mux2("clko1_src", base + 0xbd80, 24, 3, clko1_sel, ARRAY_SIZE(clko1_sel));
|
||||
hws[IMX7D_CLKO2_ROOT_SRC] = imx_clk_hw_mux2("clko2_src", base + 0xbe00, 24, 3, clko2_sel, ARRAY_SIZE(clko2_sel));
|
||||
|
||||
hws[IMX7D_ENET_AXI_ROOT_SRC] = imx_clk_hw_mux2_flags("enet_axi_src", base + 0x8900, 24, 3, enet_axi_sel, ARRAY_SIZE(enet_axi_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_NAND_USDHC_BUS_ROOT_SRC] = imx_clk_hw_mux2_flags("nand_usdhc_src", base + 0x8980, 24, 3, nand_usdhc_bus_sel, ARRAY_SIZE(nand_usdhc_bus_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_DRAM_PHYM_ROOT_SRC] = imx_clk_hw_mux2_flags("dram_phym_src", base + 0x9800, 24, 1, dram_phym_sel, ARRAY_SIZE(dram_phym_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_DRAM_ROOT_SRC] = imx_clk_hw_mux2_flags("dram_src", base + 0x9880, 24, 1, dram_sel, ARRAY_SIZE(dram_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_DRAM_PHYM_ALT_ROOT_SRC] = imx_clk_hw_mux2_flags("dram_phym_alt_src", base + 0xa000, 24, 3, dram_phym_alt_sel, ARRAY_SIZE(dram_phym_alt_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_DRAM_ALT_ROOT_SRC] = imx_clk_hw_mux2_flags("dram_alt_src", base + 0xa080, 24, 3, dram_alt_sel, ARRAY_SIZE(dram_alt_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_USB_HSIC_ROOT_SRC] = imx_clk_hw_mux2_flags("usb_hsic_src", base + 0xa100, 24, 3, usb_hsic_sel, ARRAY_SIZE(usb_hsic_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_PCIE_CTRL_ROOT_SRC] = imx_clk_hw_mux2_flags("pcie_ctrl_src", base + 0xa180, 24, 3, pcie_ctrl_sel, ARRAY_SIZE(pcie_ctrl_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_PCIE_PHY_ROOT_SRC] = imx_clk_hw_mux2_flags("pcie_phy_src", base + 0xa200, 24, 3, pcie_phy_sel, ARRAY_SIZE(pcie_phy_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_EPDC_PIXEL_ROOT_SRC] = imx_clk_hw_mux2_flags("epdc_pixel_src", base + 0xa280, 24, 3, epdc_pixel_sel, ARRAY_SIZE(epdc_pixel_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_LCDIF_PIXEL_ROOT_SRC] = imx_clk_hw_mux2_flags("lcdif_pixel_src", base + 0xa300, 24, 3, lcdif_pixel_sel, ARRAY_SIZE(lcdif_pixel_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_MIPI_DSI_ROOT_SRC] = imx_clk_hw_mux2_flags("mipi_dsi_src", base + 0xa380, 24, 3, mipi_dsi_sel, ARRAY_SIZE(mipi_dsi_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_MIPI_CSI_ROOT_SRC] = imx_clk_hw_mux2_flags("mipi_csi_src", base + 0xa400, 24, 3, mipi_csi_sel, ARRAY_SIZE(mipi_csi_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_MIPI_DPHY_ROOT_SRC] = imx_clk_hw_mux2_flags("mipi_dphy_src", base + 0xa480, 24, 3, mipi_dphy_sel, ARRAY_SIZE(mipi_dphy_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_SAI1_ROOT_SRC] = imx_clk_hw_mux2_flags("sai1_src", base + 0xa500, 24, 3, sai1_sel, ARRAY_SIZE(sai1_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_SAI2_ROOT_SRC] = imx_clk_hw_mux2_flags("sai2_src", base + 0xa580, 24, 3, sai2_sel, ARRAY_SIZE(sai2_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_SAI3_ROOT_SRC] = imx_clk_hw_mux2_flags("sai3_src", base + 0xa600, 24, 3, sai3_sel, ARRAY_SIZE(sai3_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_SPDIF_ROOT_SRC] = imx_clk_hw_mux2_flags("spdif_src", base + 0xa680, 24, 3, spdif_sel, ARRAY_SIZE(spdif_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_ENET1_REF_ROOT_SRC] = imx_clk_hw_mux2_flags("enet1_ref_src", base + 0xa700, 24, 3, enet1_ref_sel, ARRAY_SIZE(enet1_ref_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_ENET1_TIME_ROOT_SRC] = imx_clk_hw_mux2_flags("enet1_time_src", base + 0xa780, 24, 3, enet1_time_sel, ARRAY_SIZE(enet1_time_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_ENET2_REF_ROOT_SRC] = imx_clk_hw_mux2_flags("enet2_ref_src", base + 0xa800, 24, 3, enet2_ref_sel, ARRAY_SIZE(enet2_ref_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_ENET2_TIME_ROOT_SRC] = imx_clk_hw_mux2_flags("enet2_time_src", base + 0xa880, 24, 3, enet2_time_sel, ARRAY_SIZE(enet2_time_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_ENET_PHY_REF_ROOT_SRC] = imx_clk_hw_mux2_flags("enet_phy_ref_src", base + 0xa900, 24, 3, enet_phy_ref_sel, ARRAY_SIZE(enet_phy_ref_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_EIM_ROOT_SRC] = imx_clk_hw_mux2_flags("eim_src", base + 0xa980, 24, 3, eim_sel, ARRAY_SIZE(eim_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_NAND_ROOT_SRC] = imx_clk_hw_mux2_flags("nand_src", base + 0xaa00, 24, 3, nand_sel, ARRAY_SIZE(nand_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_QSPI_ROOT_SRC] = imx_clk_hw_mux2_flags("qspi_src", base + 0xaa80, 24, 3, qspi_sel, ARRAY_SIZE(qspi_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_USDHC1_ROOT_SRC] = imx_clk_hw_mux2_flags("usdhc1_src", base + 0xab00, 24, 3, usdhc1_sel, ARRAY_SIZE(usdhc1_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_USDHC2_ROOT_SRC] = imx_clk_hw_mux2_flags("usdhc2_src", base + 0xab80, 24, 3, usdhc2_sel, ARRAY_SIZE(usdhc2_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_USDHC3_ROOT_SRC] = imx_clk_hw_mux2_flags("usdhc3_src", base + 0xac00, 24, 3, usdhc3_sel, ARRAY_SIZE(usdhc3_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_CAN1_ROOT_SRC] = imx_clk_hw_mux2_flags("can1_src", base + 0xac80, 24, 3, can1_sel, ARRAY_SIZE(can1_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_CAN2_ROOT_SRC] = imx_clk_hw_mux2_flags("can2_src", base + 0xad00, 24, 3, can2_sel, ARRAY_SIZE(can2_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_I2C1_ROOT_SRC] = imx_clk_hw_mux2_flags("i2c1_src", base + 0xad80, 24, 3, i2c1_sel, ARRAY_SIZE(i2c1_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_I2C2_ROOT_SRC] = imx_clk_hw_mux2_flags("i2c2_src", base + 0xae00, 24, 3, i2c2_sel, ARRAY_SIZE(i2c2_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_I2C3_ROOT_SRC] = imx_clk_hw_mux2_flags("i2c3_src", base + 0xae80, 24, 3, i2c3_sel, ARRAY_SIZE(i2c3_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_I2C4_ROOT_SRC] = imx_clk_hw_mux2_flags("i2c4_src", base + 0xaf00, 24, 3, i2c4_sel, ARRAY_SIZE(i2c4_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_UART1_ROOT_SRC] = imx_clk_hw_mux2_flags("uart1_src", base + 0xaf80, 24, 3, uart1_sel, ARRAY_SIZE(uart1_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_UART2_ROOT_SRC] = imx_clk_hw_mux2_flags("uart2_src", base + 0xb000, 24, 3, uart2_sel, ARRAY_SIZE(uart2_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_UART3_ROOT_SRC] = imx_clk_hw_mux2_flags("uart3_src", base + 0xb080, 24, 3, uart3_sel, ARRAY_SIZE(uart3_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_UART4_ROOT_SRC] = imx_clk_hw_mux2_flags("uart4_src", base + 0xb100, 24, 3, uart4_sel, ARRAY_SIZE(uart4_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_UART5_ROOT_SRC] = imx_clk_hw_mux2_flags("uart5_src", base + 0xb180, 24, 3, uart5_sel, ARRAY_SIZE(uart5_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_UART6_ROOT_SRC] = imx_clk_hw_mux2_flags("uart6_src", base + 0xb200, 24, 3, uart6_sel, ARRAY_SIZE(uart6_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_UART7_ROOT_SRC] = imx_clk_hw_mux2_flags("uart7_src", base + 0xb280, 24, 3, uart7_sel, ARRAY_SIZE(uart7_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_ECSPI1_ROOT_SRC] = imx_clk_hw_mux2_flags("ecspi1_src", base + 0xb300, 24, 3, ecspi1_sel, ARRAY_SIZE(ecspi1_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_ECSPI2_ROOT_SRC] = imx_clk_hw_mux2_flags("ecspi2_src", base + 0xb380, 24, 3, ecspi2_sel, ARRAY_SIZE(ecspi2_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_ECSPI3_ROOT_SRC] = imx_clk_hw_mux2_flags("ecspi3_src", base + 0xb400, 24, 3, ecspi3_sel, ARRAY_SIZE(ecspi3_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_ECSPI4_ROOT_SRC] = imx_clk_hw_mux2_flags("ecspi4_src", base + 0xb480, 24, 3, ecspi4_sel, ARRAY_SIZE(ecspi4_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_PWM1_ROOT_SRC] = imx_clk_hw_mux2_flags("pwm1_src", base + 0xb500, 24, 3, pwm1_sel, ARRAY_SIZE(pwm1_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_PWM2_ROOT_SRC] = imx_clk_hw_mux2_flags("pwm2_src", base + 0xb580, 24, 3, pwm2_sel, ARRAY_SIZE(pwm2_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_PWM3_ROOT_SRC] = imx_clk_hw_mux2_flags("pwm3_src", base + 0xb600, 24, 3, pwm3_sel, ARRAY_SIZE(pwm3_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_PWM4_ROOT_SRC] = imx_clk_hw_mux2_flags("pwm4_src", base + 0xb680, 24, 3, pwm4_sel, ARRAY_SIZE(pwm4_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_FLEXTIMER1_ROOT_SRC] = imx_clk_hw_mux2_flags("flextimer1_src", base + 0xb700, 24, 3, flextimer1_sel, ARRAY_SIZE(flextimer1_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_FLEXTIMER2_ROOT_SRC] = imx_clk_hw_mux2_flags("flextimer2_src", base + 0xb780, 24, 3, flextimer2_sel, ARRAY_SIZE(flextimer2_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_SIM1_ROOT_SRC] = imx_clk_hw_mux2_flags("sim1_src", base + 0xb800, 24, 3, sim1_sel, ARRAY_SIZE(sim1_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_SIM2_ROOT_SRC] = imx_clk_hw_mux2_flags("sim2_src", base + 0xb880, 24, 3, sim2_sel, ARRAY_SIZE(sim2_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_GPT1_ROOT_SRC] = imx_clk_hw_mux2_flags("gpt1_src", base + 0xb900, 24, 3, gpt1_sel, ARRAY_SIZE(gpt1_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_GPT2_ROOT_SRC] = imx_clk_hw_mux2_flags("gpt2_src", base + 0xb980, 24, 3, gpt2_sel, ARRAY_SIZE(gpt2_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_GPT3_ROOT_SRC] = imx_clk_hw_mux2_flags("gpt3_src", base + 0xba00, 24, 3, gpt3_sel, ARRAY_SIZE(gpt3_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_GPT4_ROOT_SRC] = imx_clk_hw_mux2_flags("gpt4_src", base + 0xba80, 24, 3, gpt4_sel, ARRAY_SIZE(gpt4_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_TRACE_ROOT_SRC] = imx_clk_hw_mux2_flags("trace_src", base + 0xbb00, 24, 3, trace_sel, ARRAY_SIZE(trace_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_WDOG_ROOT_SRC] = imx_clk_hw_mux2_flags("wdog_src", base + 0xbb80, 24, 3, wdog_sel, ARRAY_SIZE(wdog_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_CSI_MCLK_ROOT_SRC] = imx_clk_hw_mux2_flags("csi_mclk_src", base + 0xbc00, 24, 3, csi_mclk_sel, ARRAY_SIZE(csi_mclk_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_AUDIO_MCLK_ROOT_SRC] = imx_clk_hw_mux2_flags("audio_mclk_src", base + 0xbc80, 24, 3, audio_mclk_sel, ARRAY_SIZE(audio_mclk_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_WRCLK_ROOT_SRC] = imx_clk_hw_mux2_flags("wrclk_src", base + 0xbd00, 24, 3, wrclk_sel, ARRAY_SIZE(wrclk_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_CLKO1_ROOT_SRC] = imx_clk_hw_mux2_flags("clko1_src", base + 0xbd80, 24, 3, clko1_sel, ARRAY_SIZE(clko1_sel), CLK_SET_PARENT_GATE);
|
||||
hws[IMX7D_CLKO2_ROOT_SRC] = imx_clk_hw_mux2_flags("clko2_src", base + 0xbe00, 24, 3, clko2_sel, ARRAY_SIZE(clko2_sel), CLK_SET_PARENT_GATE);
|
||||
|
||||
hws[IMX7D_ARM_A7_ROOT_CG] = imx_clk_hw_gate3("arm_a7_cg", "arm_a7_src", base + 0x8000, 28);
|
||||
hws[IMX7D_ARM_M4_ROOT_CG] = imx_clk_hw_gate3("arm_m4_cg", "arm_m4_src", base + 0x8080, 28);
|
||||
|
|
|
@ -657,3 +657,7 @@ static struct platform_driver imx8mm_clk_driver = {
|
|||
},
|
||||
};
|
||||
module_platform_driver(imx8mm_clk_driver);
|
||||
|
||||
MODULE_AUTHOR("Bai Ping <ping.bai@nxp.com>");
|
||||
MODULE_DESCRIPTION("NXP i.MX8MM clock driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
|
@ -608,3 +608,7 @@ static struct platform_driver imx8mn_clk_driver = {
|
|||
},
|
||||
};
|
||||
module_platform_driver(imx8mn_clk_driver);
|
||||
|
||||
MODULE_AUTHOR("Anson Huang <Anson.Huang@nxp.com>");
|
||||
MODULE_DESCRIPTION("NXP i.MX8MN clock driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
|
@ -152,10 +152,6 @@ static const char * const imx8mp_can2_sels[] = {"osc_24m", "sys_pll2_200m", "sys
|
|||
"sys_pll1_160m", "sys_pll1_800m", "sys_pll3_out",
|
||||
"sys_pll2_250m", "audio_pll2_out", };
|
||||
|
||||
static const char * const imx8mp_memrepair_sels[] = {"osc_24m", "sys_pll1_160m", "sys_pll2_50m",
|
||||
"sys_pll3_out", "audio_pll1_out", "video_pll1_out",
|
||||
"audio_pll2_out", "sys_pll1_133m", };
|
||||
|
||||
static const char * const imx8mp_pcie_phy_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll2_500m",
|
||||
"clk_ext1", "clk_ext2", "clk_ext3",
|
||||
"clk_ext4", "sys_pll1_400m", };
|
||||
|
@ -375,15 +371,14 @@ static const char * const imx8mp_media_cam2_pix_sels[] = {"osc_24m", "sys_pll1_2
|
|||
"sys_pll3_out", "audio_pll2_out",
|
||||
"video_pll1_out", };
|
||||
|
||||
static const char * const imx8mp_media_mipi_phy2_ref_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m",
|
||||
"sys_pll1_800m", "sys_pll2_1000m",
|
||||
"clk_ext2", "audio_pll2_out",
|
||||
"video_pll1_out", };
|
||||
static const char * const imx8mp_media_ldb_sels[] = {"osc_24m", "sys_pll2_333m", "sys_pll2_100m",
|
||||
"sys_pll1_800m", "sys_pll2_1000m",
|
||||
"clk_ext2", "audio_pll2_out",
|
||||
"video_pll1_out", };
|
||||
|
||||
static const char * const imx8mp_media_mipi_csi2_esc_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m",
|
||||
"sys_pll1_800m", "sys_pll2_1000m",
|
||||
"sys_pll3_out", "clk_ext3",
|
||||
"audio_pll2_out", };
|
||||
static const char * const imx8mp_memrepair_sels[] = {"osc_24m", "sys_pll2_100m", "sys_pll1_80m",
|
||||
"sys_pll1_800m", "sys_pll2_1000m", "sys_pll3_out",
|
||||
"clk_ext3", "audio_pll2_out", };
|
||||
|
||||
static const char * const imx8mp_pcie2_ctrl_sels[] = {"osc_24m", "sys_pll2_250m", "sys_pll2_200m",
|
||||
"sys_pll1_266m", "sys_pll1_800m", "sys_pll2_500m",
|
||||
|
@ -590,7 +585,6 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
|
|||
hws[IMX8MP_CLK_VPU_G2] = imx8m_clk_hw_composite("vpu_g2", imx8mp_vpu_g2_sels, ccm_base + 0xa180);
|
||||
hws[IMX8MP_CLK_CAN1] = imx8m_clk_hw_composite("can1", imx8mp_can1_sels, ccm_base + 0xa200);
|
||||
hws[IMX8MP_CLK_CAN2] = imx8m_clk_hw_composite("can2", imx8mp_can2_sels, ccm_base + 0xa280);
|
||||
hws[IMX8MP_CLK_MEMREPAIR] = imx8m_clk_hw_composite("memrepair", imx8mp_memrepair_sels, ccm_base + 0xa300);
|
||||
hws[IMX8MP_CLK_PCIE_PHY] = imx8m_clk_hw_composite("pcie_phy", imx8mp_pcie_phy_sels, ccm_base + 0xa380);
|
||||
hws[IMX8MP_CLK_PCIE_AUX] = imx8m_clk_hw_composite("pcie_aux", imx8mp_pcie_aux_sels, ccm_base + 0xa400);
|
||||
hws[IMX8MP_CLK_I2C5] = imx8m_clk_hw_composite("i2c5", imx8mp_i2c5_sels, ccm_base + 0xa480);
|
||||
|
@ -647,8 +641,8 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
|
|||
hws[IMX8MP_CLK_MEDIA_MIPI_PHY1_REF] = imx8m_clk_hw_composite("media_mipi_phy1_ref", imx8mp_media_mipi_phy1_ref_sels, ccm_base + 0xbd80);
|
||||
hws[IMX8MP_CLK_MEDIA_DISP1_PIX] = imx8m_clk_hw_composite("media_disp1_pix", imx8mp_media_disp1_pix_sels, ccm_base + 0xbe00);
|
||||
hws[IMX8MP_CLK_MEDIA_CAM2_PIX] = imx8m_clk_hw_composite("media_cam2_pix", imx8mp_media_cam2_pix_sels, ccm_base + 0xbe80);
|
||||
hws[IMX8MP_CLK_MEDIA_MIPI_PHY2_REF] = imx8m_clk_hw_composite("media_mipi_phy2_ref", imx8mp_media_mipi_phy2_ref_sels, ccm_base + 0xbf00);
|
||||
hws[IMX8MP_CLK_MEDIA_MIPI_CSI2_ESC] = imx8m_clk_hw_composite("media_mipi_csi2_esc", imx8mp_media_mipi_csi2_esc_sels, ccm_base + 0xbf80);
|
||||
hws[IMX8MP_CLK_MEDIA_LDB] = imx8m_clk_hw_composite("media_ldb", imx8mp_media_ldb_sels, ccm_base + 0xbf00);
|
||||
hws[IMX8MP_CLK_MEMREPAIR] = imx8m_clk_hw_composite_critical("mem_repair", imx8mp_memrepair_sels, ccm_base + 0xbf80);
|
||||
hws[IMX8MP_CLK_PCIE2_CTRL] = imx8m_clk_hw_composite("pcie2_ctrl", imx8mp_pcie2_ctrl_sels, ccm_base + 0xc000);
|
||||
hws[IMX8MP_CLK_PCIE2_PHY] = imx8m_clk_hw_composite("pcie2_phy", imx8mp_pcie2_phy_sels, ccm_base + 0xc080);
|
||||
hws[IMX8MP_CLK_MEDIA_MIPI_TEST_BYTE] = imx8m_clk_hw_composite("media_mipi_test_byte", imx8mp_media_mipi_test_byte_sels, ccm_base + 0xc100);
|
||||
|
@ -773,3 +767,7 @@ static struct platform_driver imx8mp_clk_driver = {
|
|||
},
|
||||
};
|
||||
module_platform_driver(imx8mp_clk_driver);
|
||||
|
||||
MODULE_AUTHOR("Anson Huang <Anson.Huang@nxp.com>");
|
||||
MODULE_DESCRIPTION("NXP i.MX8MP clock driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
|
@ -157,10 +157,10 @@ static const char * const imx8mq_qspi_sels[] = {"osc_25m", "sys1_pll_400m", "sys
|
|||
"audio_pll2_out", "sys1_pll_266m", "sys3_pll_out", "sys1_pll_100m", };
|
||||
|
||||
static const char * const imx8mq_usdhc1_sels[] = {"osc_25m", "sys1_pll_400m", "sys1_pll_800m", "sys2_pll_500m",
|
||||
"audio_pll2_out", "sys1_pll_266m", "sys3_pll_out", "sys1_pll_100m", };
|
||||
"sys3_pll_out", "sys1_pll_266m", "audio_pll2_out", "sys1_pll_100m", };
|
||||
|
||||
static const char * const imx8mq_usdhc2_sels[] = {"osc_25m", "sys1_pll_400m", "sys1_pll_800m", "sys2_pll_500m",
|
||||
"audio_pll2_out", "sys1_pll_266m", "sys3_pll_out", "sys1_pll_100m", };
|
||||
"sys3_pll_out", "sys1_pll_266m", "audio_pll2_out", "sys1_pll_100m", };
|
||||
|
||||
static const char * const imx8mq_i2c1_sels[] = {"osc_25m", "sys1_pll_160m", "sys2_pll_50m", "sys3_pll_out", "audio_pll1_out",
|
||||
"video_pll1_out", "audio_pll2_out", "sys1_pll_133m", };
|
||||
|
@ -643,3 +643,7 @@ static struct platform_driver imx8mq_clk_driver = {
|
|||
},
|
||||
};
|
||||
module_platform_driver(imx8mq_clk_driver);
|
||||
|
||||
MODULE_AUTHOR("Abel Vesa <abel.vesa@nxp.com>");
|
||||
MODULE_DESCRIPTION("NXP i.MX8MQ clock driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
|
@ -232,3 +232,7 @@ static struct platform_driver imx8qxp_lpcg_clk_driver = {
|
|||
};
|
||||
|
||||
builtin_platform_driver(imx8qxp_lpcg_clk_driver);
|
||||
|
||||
MODULE_AUTHOR("Aisheng Dong <aisheng.dong@nxp.com>");
|
||||
MODULE_DESCRIPTION("NXP i.MX8QXP LPCG clock driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
|
@ -152,3 +152,7 @@ static struct platform_driver imx8qxp_clk_driver = {
|
|||
.probe = imx8qxp_clk_probe,
|
||||
};
|
||||
builtin_platform_driver(imx8qxp_clk_driver);
|
||||
|
||||
MODULE_AUTHOR("Aisheng Dong <aisheng.dong@nxp.com>");
|
||||
MODULE_DESCRIPTION("NXP i.MX8QXP clock driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* Dong Aisheng <aisheng.dong@nxp.com>
|
||||
*/
|
||||
|
||||
#include <linux/bits.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
/**
|
||||
* struct clk_pfd - IMX PFD clock
|
||||
* @clk_hw: clock source
|
||||
* @hw: clock source
|
||||
* @reg: PFD register address
|
||||
* @idx: the index of PFD encoded in the register
|
||||
*
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
/**
|
||||
* struct clk_pfdv2 - IMX PFD clock
|
||||
* @clk_hw: clock source
|
||||
* @hw: clock source
|
||||
* @reg: PFD register address
|
||||
* @gate_bit: Gate bit offset
|
||||
* @vld_bit: Valid bit offset
|
||||
|
|
|
@ -3,9 +3,10 @@
|
|||
* Copyright 2017-2018 NXP.
|
||||
*/
|
||||
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/bits.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/slab.h>
|
||||
|
@ -68,6 +69,7 @@ struct imx_pll14xx_clk imx_1443x_pll = {
|
|||
.rate_table = imx_pll1443x_tbl,
|
||||
.rate_count = ARRAY_SIZE(imx_pll1443x_tbl),
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(imx_1443x_pll);
|
||||
|
||||
struct imx_pll14xx_clk imx_1443x_dram_pll = {
|
||||
.type = PLL_1443X,
|
||||
|
@ -75,12 +77,14 @@ struct imx_pll14xx_clk imx_1443x_dram_pll = {
|
|||
.rate_count = ARRAY_SIZE(imx_pll1443x_tbl),
|
||||
.flags = CLK_GET_RATE_NOCACHE,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(imx_1443x_dram_pll);
|
||||
|
||||
struct imx_pll14xx_clk imx_1416x_pll = {
|
||||
.type = PLL_1416X,
|
||||
.rate_table = imx_pll1416x_tbl,
|
||||
.rate_count = ARRAY_SIZE(imx_pll1416x_tbl),
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(imx_1416x_pll);
|
||||
|
||||
static const struct imx_pll14xx_rate_table *imx_get_pll_settings(
|
||||
struct clk_pll14xx *pll, unsigned long rate)
|
||||
|
@ -436,3 +440,4 @@ struct clk_hw *imx_dev_clk_hw_pll14xx(struct device *dev, const char *name,
|
|||
|
||||
return hw;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(imx_dev_clk_hw_pll14xx);
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/bits.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/slab.h>
|
||||
|
|
|
@ -30,12 +30,15 @@
|
|||
|
||||
/**
|
||||
* struct clk_pllv3 - IMX PLL clock version 3
|
||||
* @clk_hw: clock source
|
||||
* @hw: clock source
|
||||
* @base: base address of PLL registers
|
||||
* @power_bit: pll power bit mask
|
||||
* @powerup_set: set power_bit to power up the PLL
|
||||
* @div_mask: mask of divider bits
|
||||
* @div_shift: shift of divider bits
|
||||
* @ref_clock: reference clock rate
|
||||
* @num_offset: num register offset
|
||||
* @denom_offset: denom register offset
|
||||
*
|
||||
* IMX PLL clock version 3, found on i.MX6 series. Divider for pllv3
|
||||
* is actually a multiplier, and always sits at bit 0.
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
*/
|
||||
|
||||
#include <linux/bits.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/export.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/slab.h>
|
||||
|
@ -537,3 +538,4 @@ struct clk_hw *imx_clk_hw_sscg_pll(const char *name,
|
|||
|
||||
return hw;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(imx_clk_hw_sscg_pll);
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/bits.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/syscore_ops.h>
|
||||
#include <dt-bindings/clock/vf610-clock.h>
|
||||
|
@ -328,6 +329,7 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
|
|||
clk[VF610_CLK_DSPI2] = imx_clk_gate2("dspi2", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(12));
|
||||
clk[VF610_CLK_DSPI3] = imx_clk_gate2("dspi3", "ipg_bus", CCM_CCGR6, CCM_CCGRx_CGn(13));
|
||||
|
||||
clk[VF610_CLK_CRC] = imx_clk_gate2("crc", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(3));
|
||||
clk[VF610_CLK_WDT] = imx_clk_gate2("wdt", "ipg_bus", CCM_CCGR1, CCM_CCGRx_CGn(14));
|
||||
|
||||
clk[VF610_CLK_ESDHC0_SEL] = imx_clk_mux("esdhc0_sel", CCM_CSCMR1, 16, 2, esdhc_sels, 4);
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/bits.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
@ -13,6 +15,7 @@
|
|||
#define CCDR_MMDC_CH1_MASK BIT(16)
|
||||
|
||||
DEFINE_SPINLOCK(imx_ccm_lock);
|
||||
EXPORT_SYMBOL_GPL(imx_ccm_lock);
|
||||
|
||||
void imx_unregister_clocks(struct clk *clks[], unsigned int count)
|
||||
{
|
||||
|
@ -29,8 +32,9 @@ void imx_unregister_hw_clocks(struct clk_hw *hws[], unsigned int count)
|
|||
for (i = 0; i < count; i++)
|
||||
clk_hw_unregister(hws[i]);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(imx_unregister_hw_clocks);
|
||||
|
||||
void __init imx_mmdc_mask_handshake(void __iomem *ccm_base,
|
||||
void imx_mmdc_mask_handshake(void __iomem *ccm_base,
|
||||
unsigned int chn)
|
||||
{
|
||||
unsigned int reg;
|
||||
|
@ -59,8 +63,9 @@ void imx_check_clk_hws(struct clk_hw *clks[], unsigned int count)
|
|||
pr_err("i.MX clk %u: register failed with %ld\n",
|
||||
i, PTR_ERR(clks[i]));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(imx_check_clk_hws);
|
||||
|
||||
static struct clk * __init imx_obtain_fixed_clock_from_dt(const char *name)
|
||||
static struct clk *imx_obtain_fixed_clock_from_dt(const char *name)
|
||||
{
|
||||
struct of_phandle_args phandle;
|
||||
struct clk *clk = ERR_PTR(-ENODEV);
|
||||
|
@ -80,7 +85,7 @@ static struct clk * __init imx_obtain_fixed_clock_from_dt(const char *name)
|
|||
return clk;
|
||||
}
|
||||
|
||||
struct clk * __init imx_obtain_fixed_clock(
|
||||
struct clk *imx_obtain_fixed_clock(
|
||||
const char *name, unsigned long rate)
|
||||
{
|
||||
struct clk *clk;
|
||||
|
@ -91,7 +96,7 @@ struct clk * __init imx_obtain_fixed_clock(
|
|||
return clk;
|
||||
}
|
||||
|
||||
struct clk_hw * __init imx_obtain_fixed_clock_hw(
|
||||
struct clk_hw *imx_obtain_fixed_clock_hw(
|
||||
const char *name, unsigned long rate)
|
||||
{
|
||||
struct clk *clk;
|
||||
|
@ -113,6 +118,7 @@ struct clk_hw * imx_obtain_fixed_clk_hw(struct device_node *np,
|
|||
|
||||
return __clk_get_hw(clk);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(imx_obtain_fixed_clk_hw);
|
||||
|
||||
/*
|
||||
* This fixups the register CCM_CSCMR1 write value.
|
||||
|
@ -140,6 +146,7 @@ void imx_cscmr1_fixup(u32 *val)
|
|||
return;
|
||||
}
|
||||
|
||||
#ifndef MODULE
|
||||
static int imx_keep_uart_clocks;
|
||||
static struct clk ** const *imx_uart_clocks;
|
||||
|
||||
|
@ -177,3 +184,6 @@ static int __init imx_clk_disable_uart(void)
|
|||
return 0;
|
||||
}
|
||||
late_initcall_sync(imx_clk_disable_uart);
|
||||
#endif
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#ifndef __MACH_IMX_CLK_H
|
||||
#define __MACH_IMX_CLK_H
|
||||
|
||||
#include <linux/bits.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/clk-provider.h>
|
||||
|
||||
|
@ -11,7 +12,13 @@ extern spinlock_t imx_ccm_lock;
|
|||
|
||||
void imx_check_clocks(struct clk *clks[], unsigned int count);
|
||||
void imx_check_clk_hws(struct clk_hw *clks[], unsigned int count);
|
||||
#ifndef MODULE
|
||||
void imx_register_uart_clocks(struct clk ** const clks[]);
|
||||
#else
|
||||
static inline void imx_register_uart_clocks(struct clk ** const clks[])
|
||||
{
|
||||
}
|
||||
#endif
|
||||
void imx_mmdc_mask_handshake(void __iomem *ccm_base, unsigned int chn);
|
||||
void imx_unregister_clocks(struct clk *clks[], unsigned int count);
|
||||
void imx_unregister_hw_clocks(struct clk_hw *hws[], unsigned int count);
|
||||
|
|
|
@ -12,15 +12,24 @@
|
|||
#include <linux/clkdev.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/math64.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/time.h>
|
||||
|
||||
#include "cgu.h"
|
||||
|
||||
#define MHZ (1000 * 1000)
|
||||
|
||||
static inline const struct ingenic_cgu_clk_info *
|
||||
to_clk_info(struct ingenic_clk *clk)
|
||||
{
|
||||
return &clk->cgu->clock_info[clk->idx];
|
||||
}
|
||||
|
||||
/**
|
||||
* ingenic_cgu_gate_get() - get the value of clock gate register bit
|
||||
* @cgu: reference to the CGU whose registers should be read
|
||||
|
@ -71,14 +80,13 @@ static unsigned long
|
|||
ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
|
||||
{
|
||||
struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
|
||||
const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
|
||||
struct ingenic_cgu *cgu = ingenic_clk->cgu;
|
||||
const struct ingenic_cgu_clk_info *clk_info;
|
||||
const struct ingenic_cgu_pll_info *pll_info;
|
||||
unsigned m, n, od_enc, od;
|
||||
bool bypass;
|
||||
u32 ctl;
|
||||
|
||||
clk_info = &cgu->clock_info[ingenic_clk->idx];
|
||||
BUG_ON(clk_info->type != CGU_CLK_PLL);
|
||||
pll_info = &clk_info->pll;
|
||||
|
||||
|
@ -144,18 +152,6 @@ ingenic_pll_calc(const struct ingenic_cgu_clk_info *clk_info,
|
|||
n * od);
|
||||
}
|
||||
|
||||
static inline const struct ingenic_cgu_clk_info *to_clk_info(
|
||||
struct ingenic_clk *ingenic_clk)
|
||||
{
|
||||
struct ingenic_cgu *cgu = ingenic_clk->cgu;
|
||||
const struct ingenic_cgu_clk_info *clk_info;
|
||||
|
||||
clk_info = &cgu->clock_info[ingenic_clk->idx];
|
||||
BUG_ON(clk_info->type != CGU_CLK_PLL);
|
||||
|
||||
return clk_info;
|
||||
}
|
||||
|
||||
static long
|
||||
ingenic_pll_round_rate(struct clk_hw *hw, unsigned long req_rate,
|
||||
unsigned long *prate)
|
||||
|
@ -166,6 +162,16 @@ ingenic_pll_round_rate(struct clk_hw *hw, unsigned long req_rate,
|
|||
return ingenic_pll_calc(clk_info, req_rate, *prate, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static inline int ingenic_pll_check_stable(struct ingenic_cgu *cgu,
|
||||
const struct ingenic_cgu_pll_info *pll_info)
|
||||
{
|
||||
u32 ctl;
|
||||
|
||||
return readl_poll_timeout(cgu->base + pll_info->reg, ctl,
|
||||
ctl & BIT(pll_info->stable_bit),
|
||||
0, 100 * USEC_PER_MSEC);
|
||||
}
|
||||
|
||||
static int
|
||||
ingenic_pll_set_rate(struct clk_hw *hw, unsigned long req_rate,
|
||||
unsigned long parent_rate)
|
||||
|
@ -176,6 +182,7 @@ ingenic_pll_set_rate(struct clk_hw *hw, unsigned long req_rate,
|
|||
const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll;
|
||||
unsigned long rate, flags;
|
||||
unsigned int m, n, od;
|
||||
int ret = 0;
|
||||
u32 ctl;
|
||||
|
||||
rate = ingenic_pll_calc(clk_info, req_rate, parent_rate,
|
||||
|
@ -197,9 +204,14 @@ ingenic_pll_set_rate(struct clk_hw *hw, unsigned long req_rate,
|
|||
ctl |= pll_info->od_encoding[od - 1] << pll_info->od_shift;
|
||||
|
||||
writel(ctl, cgu->base + pll_info->reg);
|
||||
|
||||
/* If the PLL is enabled, verify that it's stable */
|
||||
if (ctl & BIT(pll_info->enable_bit))
|
||||
ret = ingenic_pll_check_stable(cgu, pll_info);
|
||||
|
||||
spin_unlock_irqrestore(&cgu->lock, flags);
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ingenic_pll_enable(struct clk_hw *hw)
|
||||
|
@ -208,9 +220,8 @@ static int ingenic_pll_enable(struct clk_hw *hw)
|
|||
struct ingenic_cgu *cgu = ingenic_clk->cgu;
|
||||
const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
|
||||
const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll;
|
||||
const unsigned int timeout = 100;
|
||||
unsigned long flags;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
u32 ctl;
|
||||
|
||||
spin_lock_irqsave(&cgu->lock, flags);
|
||||
|
@ -226,20 +237,10 @@ static int ingenic_pll_enable(struct clk_hw *hw)
|
|||
|
||||
writel(ctl, cgu->base + pll_info->reg);
|
||||
|
||||
/* wait for the PLL to stabilise */
|
||||
for (i = 0; i < timeout; i++) {
|
||||
ctl = readl(cgu->base + pll_info->reg);
|
||||
if (ctl & BIT(pll_info->stable_bit))
|
||||
break;
|
||||
mdelay(1);
|
||||
}
|
||||
|
||||
ret = ingenic_pll_check_stable(cgu, pll_info);
|
||||
spin_unlock_irqrestore(&cgu->lock, flags);
|
||||
|
||||
if (i == timeout)
|
||||
return -EBUSY;
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ingenic_pll_disable(struct clk_hw *hw)
|
||||
|
@ -290,13 +291,11 @@ static const struct clk_ops ingenic_pll_ops = {
|
|||
static u8 ingenic_clk_get_parent(struct clk_hw *hw)
|
||||
{
|
||||
struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
|
||||
const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
|
||||
struct ingenic_cgu *cgu = ingenic_clk->cgu;
|
||||
const struct ingenic_cgu_clk_info *clk_info;
|
||||
u32 reg;
|
||||
u8 i, hw_idx, idx = 0;
|
||||
|
||||
clk_info = &cgu->clock_info[ingenic_clk->idx];
|
||||
|
||||
if (clk_info->type & CGU_CLK_MUX) {
|
||||
reg = readl(cgu->base + clk_info->mux.reg);
|
||||
hw_idx = (reg >> clk_info->mux.shift) &
|
||||
|
@ -318,14 +317,12 @@ static u8 ingenic_clk_get_parent(struct clk_hw *hw)
|
|||
static int ingenic_clk_set_parent(struct clk_hw *hw, u8 idx)
|
||||
{
|
||||
struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
|
||||
const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
|
||||
struct ingenic_cgu *cgu = ingenic_clk->cgu;
|
||||
const struct ingenic_cgu_clk_info *clk_info;
|
||||
unsigned long flags;
|
||||
u8 curr_idx, hw_idx, num_poss;
|
||||
u32 reg, mask;
|
||||
|
||||
clk_info = &cgu->clock_info[ingenic_clk->idx];
|
||||
|
||||
if (clk_info->type & CGU_CLK_MUX) {
|
||||
/*
|
||||
* Convert the parent index to the hardware index by adding
|
||||
|
@ -368,13 +365,11 @@ static unsigned long
|
|||
ingenic_clk_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
|
||||
{
|
||||
struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
|
||||
const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
|
||||
struct ingenic_cgu *cgu = ingenic_clk->cgu;
|
||||
const struct ingenic_cgu_clk_info *clk_info;
|
||||
unsigned long rate = parent_rate;
|
||||
u32 div_reg, div;
|
||||
|
||||
clk_info = &cgu->clock_info[ingenic_clk->idx];
|
||||
|
||||
if (clk_info->type & CGU_CLK_DIV) {
|
||||
div_reg = readl(cgu->base + clk_info->div.reg);
|
||||
div = (div_reg >> clk_info->div.shift) &
|
||||
|
@ -443,35 +438,41 @@ ingenic_clk_round_rate(struct clk_hw *hw, unsigned long req_rate,
|
|||
unsigned long *parent_rate)
|
||||
{
|
||||
struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
|
||||
struct ingenic_cgu *cgu = ingenic_clk->cgu;
|
||||
const struct ingenic_cgu_clk_info *clk_info;
|
||||
const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
|
||||
unsigned int div = 1;
|
||||
|
||||
clk_info = &cgu->clock_info[ingenic_clk->idx];
|
||||
|
||||
if (clk_info->type & CGU_CLK_DIV)
|
||||
div = ingenic_clk_calc_div(clk_info, *parent_rate, req_rate);
|
||||
else if (clk_info->type & CGU_CLK_FIXDIV)
|
||||
div = clk_info->fixdiv.div;
|
||||
else if (clk_hw_can_set_rate_parent(hw))
|
||||
*parent_rate = req_rate;
|
||||
|
||||
return DIV_ROUND_UP(*parent_rate, div);
|
||||
}
|
||||
|
||||
static inline int ingenic_clk_check_stable(struct ingenic_cgu *cgu,
|
||||
const struct ingenic_cgu_clk_info *clk_info)
|
||||
{
|
||||
u32 reg;
|
||||
|
||||
return readl_poll_timeout(cgu->base + clk_info->div.reg, reg,
|
||||
!(reg & BIT(clk_info->div.busy_bit)),
|
||||
0, 100 * USEC_PER_MSEC);
|
||||
}
|
||||
|
||||
static int
|
||||
ingenic_clk_set_rate(struct clk_hw *hw, unsigned long req_rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
|
||||
const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
|
||||
struct ingenic_cgu *cgu = ingenic_clk->cgu;
|
||||
const struct ingenic_cgu_clk_info *clk_info;
|
||||
const unsigned timeout = 100;
|
||||
unsigned long rate, flags;
|
||||
unsigned int hw_div, div, i;
|
||||
unsigned int hw_div, div;
|
||||
u32 reg, mask;
|
||||
int ret = 0;
|
||||
|
||||
clk_info = &cgu->clock_info[ingenic_clk->idx];
|
||||
|
||||
if (clk_info->type & CGU_CLK_DIV) {
|
||||
div = ingenic_clk_calc_div(clk_info, parent_rate, req_rate);
|
||||
rate = DIV_ROUND_UP(parent_rate, div);
|
||||
|
@ -504,16 +505,8 @@ ingenic_clk_set_rate(struct clk_hw *hw, unsigned long req_rate,
|
|||
writel(reg, cgu->base + clk_info->div.reg);
|
||||
|
||||
/* wait for the change to take effect */
|
||||
if (clk_info->div.busy_bit != -1) {
|
||||
for (i = 0; i < timeout; i++) {
|
||||
reg = readl(cgu->base + clk_info->div.reg);
|
||||
if (!(reg & BIT(clk_info->div.busy_bit)))
|
||||
break;
|
||||
mdelay(1);
|
||||
}
|
||||
if (i == timeout)
|
||||
ret = -EBUSY;
|
||||
}
|
||||
if (clk_info->div.busy_bit != -1)
|
||||
ret = ingenic_clk_check_stable(cgu, clk_info);
|
||||
|
||||
spin_unlock_irqrestore(&cgu->lock, flags);
|
||||
return ret;
|
||||
|
@ -525,12 +518,10 @@ ingenic_clk_set_rate(struct clk_hw *hw, unsigned long req_rate,
|
|||
static int ingenic_clk_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
|
||||
const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
|
||||
struct ingenic_cgu *cgu = ingenic_clk->cgu;
|
||||
const struct ingenic_cgu_clk_info *clk_info;
|
||||
unsigned long flags;
|
||||
|
||||
clk_info = &cgu->clock_info[ingenic_clk->idx];
|
||||
|
||||
if (clk_info->type & CGU_CLK_GATE) {
|
||||
/* ungate the clock */
|
||||
spin_lock_irqsave(&cgu->lock, flags);
|
||||
|
@ -547,12 +538,10 @@ static int ingenic_clk_enable(struct clk_hw *hw)
|
|||
static void ingenic_clk_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
|
||||
const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
|
||||
struct ingenic_cgu *cgu = ingenic_clk->cgu;
|
||||
const struct ingenic_cgu_clk_info *clk_info;
|
||||
unsigned long flags;
|
||||
|
||||
clk_info = &cgu->clock_info[ingenic_clk->idx];
|
||||
|
||||
if (clk_info->type & CGU_CLK_GATE) {
|
||||
/* gate the clock */
|
||||
spin_lock_irqsave(&cgu->lock, flags);
|
||||
|
@ -564,12 +553,10 @@ static void ingenic_clk_disable(struct clk_hw *hw)
|
|||
static int ingenic_clk_is_enabled(struct clk_hw *hw)
|
||||
{
|
||||
struct ingenic_clk *ingenic_clk = to_ingenic_clk(hw);
|
||||
const struct ingenic_cgu_clk_info *clk_info = to_clk_info(ingenic_clk);
|
||||
struct ingenic_cgu *cgu = ingenic_clk->cgu;
|
||||
const struct ingenic_cgu_clk_info *clk_info;
|
||||
int enabled = 1;
|
||||
|
||||
clk_info = &cgu->clock_info[ingenic_clk->idx];
|
||||
|
||||
if (clk_info->type & CGU_CLK_GATE)
|
||||
enabled = !ingenic_cgu_gate_get(cgu, &clk_info->gate);
|
||||
|
||||
|
@ -644,6 +631,13 @@ static int ingenic_register_clock(struct ingenic_cgu *cgu, unsigned idx)
|
|||
|
||||
caps = clk_info->type;
|
||||
|
||||
if (caps & CGU_CLK_DIV) {
|
||||
caps &= ~CGU_CLK_DIV;
|
||||
} else if (!(caps & CGU_CLK_CUSTOM)) {
|
||||
/* pass rate changes to the parent clock */
|
||||
clk_init.flags |= CLK_SET_RATE_PARENT;
|
||||
}
|
||||
|
||||
if (caps & (CGU_CLK_MUX | CGU_CLK_CUSTOM)) {
|
||||
clk_init.num_parents = 0;
|
||||
|
||||
|
@ -683,7 +677,6 @@ static int ingenic_register_clock(struct ingenic_cgu *cgu, unsigned idx)
|
|||
}
|
||||
} else if (caps & CGU_CLK_PLL) {
|
||||
clk_init.ops = &ingenic_pll_ops;
|
||||
clk_init.flags |= CLK_SET_RATE_GATE;
|
||||
|
||||
caps &= ~CGU_CLK_PLL;
|
||||
|
||||
|
@ -706,13 +699,6 @@ static int ingenic_register_clock(struct ingenic_cgu *cgu, unsigned idx)
|
|||
caps &= ~(CGU_CLK_MUX | CGU_CLK_MUX_GLITCHFREE);
|
||||
}
|
||||
|
||||
if (caps & CGU_CLK_DIV) {
|
||||
caps &= ~CGU_CLK_DIV;
|
||||
} else {
|
||||
/* pass rate changes to the parent clock */
|
||||
clk_init.flags |= CLK_SET_RATE_PARENT;
|
||||
}
|
||||
|
||||
if (caps) {
|
||||
pr_err("%s: unknown clock type 0x%x\n", __func__, caps);
|
||||
goto out;
|
||||
|
|
|
@ -54,6 +54,8 @@ struct sci_clk_provider {
|
|||
* @provider: Master clock provider
|
||||
* @flags: Flags for the clock
|
||||
* @node: Link for handling clocks probed via DT
|
||||
* @cached_req: Cached requested freq for determine rate calls
|
||||
* @cached_res: Cached result freq for determine rate calls
|
||||
*/
|
||||
struct sci_clk {
|
||||
struct clk_hw hw;
|
||||
|
@ -63,6 +65,8 @@ struct sci_clk {
|
|||
struct sci_clk_provider *provider;
|
||||
u8 flags;
|
||||
struct list_head node;
|
||||
unsigned long cached_req;
|
||||
unsigned long cached_res;
|
||||
};
|
||||
|
||||
#define to_sci_clk(_hw) container_of(_hw, struct sci_clk, hw)
|
||||
|
@ -175,6 +179,11 @@ static int sci_clk_determine_rate(struct clk_hw *hw,
|
|||
int ret;
|
||||
u64 new_rate;
|
||||
|
||||
if (clk->cached_req && clk->cached_req == req->rate) {
|
||||
req->rate = clk->cached_res;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ret = clk->provider->ops->get_best_match_freq(clk->provider->sci,
|
||||
clk->dev_id,
|
||||
clk->clk_id,
|
||||
|
@ -189,6 +198,9 @@ static int sci_clk_determine_rate(struct clk_hw *hw,
|
|||
return ret;
|
||||
}
|
||||
|
||||
clk->cached_req = req->rate;
|
||||
clk->cached_res = new_rate;
|
||||
|
||||
req->rate = new_rate;
|
||||
|
||||
return 0;
|
||||
|
@ -209,7 +221,8 @@ static int sci_clk_set_rate(struct clk_hw *hw, unsigned long rate,
|
|||
struct sci_clk *clk = to_sci_clk(hw);
|
||||
|
||||
return clk->provider->ops->set_freq(clk->provider->sci, clk->dev_id,
|
||||
clk->clk_id, rate, rate, rate);
|
||||
clk->clk_id, rate / 10 * 9, rate,
|
||||
rate / 10 * 11);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -249,6 +262,8 @@ static int sci_clk_set_parent(struct clk_hw *hw, u8 index)
|
|||
{
|
||||
struct sci_clk *clk = to_sci_clk(hw);
|
||||
|
||||
clk->cached_req = 0;
|
||||
|
||||
return clk->provider->ops->set_parent(clk->provider->sci, clk->dev_id,
|
||||
clk->clk_id,
|
||||
index + 1 + clk->clk_id);
|
||||
|
@ -522,7 +537,7 @@ static int ti_sci_scan_clocks_from_dt(struct sci_clk_provider *provider)
|
|||
np = of_find_node_with_property(np, *clk_name);
|
||||
if (!np) {
|
||||
clk_name++;
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!of_device_is_available(np))
|
||||
|
|
|
@ -352,6 +352,54 @@ config COMMON_CLK_MT8135
|
|||
help
|
||||
This driver supports MediaTek MT8135 clocks.
|
||||
|
||||
config COMMON_CLK_MT8167
|
||||
bool "Clock driver for MediaTek MT8167"
|
||||
depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
|
||||
select COMMON_CLK_MEDIATEK
|
||||
default ARCH_MEDIATEK
|
||||
help
|
||||
This driver supports MediaTek MT8167 basic clocks.
|
||||
|
||||
config COMMON_CLK_MT8167_AUDSYS
|
||||
bool "Clock driver for MediaTek MT8167 audsys"
|
||||
depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
|
||||
select COMMON_CLK_MEDIATEK
|
||||
default ARCH_MEDIATEK
|
||||
help
|
||||
This driver supports MediaTek MT8167 audsys clocks.
|
||||
|
||||
config COMMON_CLK_MT8167_IMGSYS
|
||||
bool "Clock driver for MediaTek MT8167 imgsys"
|
||||
depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
|
||||
select COMMON_CLK_MEDIATEK
|
||||
default ARCH_MEDIATEK
|
||||
help
|
||||
This driver supports MediaTek MT8167 imgsys clocks.
|
||||
|
||||
config COMMON_CLK_MT8167_MFGCFG
|
||||
bool "Clock driver for MediaTek MT8167 mfgcfg"
|
||||
depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
|
||||
select COMMON_CLK_MEDIATEK
|
||||
default ARCH_MEDIATEK
|
||||
help
|
||||
This driver supports MediaTek MT8167 mfgcfg clocks.
|
||||
|
||||
config COMMON_CLK_MT8167_MMSYS
|
||||
bool "Clock driver for MediaTek MT8167 mmsys"
|
||||
depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
|
||||
select COMMON_CLK_MEDIATEK
|
||||
default ARCH_MEDIATEK
|
||||
help
|
||||
This driver supports MediaTek MT8167 mmsys clocks.
|
||||
|
||||
config COMMON_CLK_MT8167_VDECSYS
|
||||
bool "Clock driver for MediaTek MT8167 vdecsys"
|
||||
depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
|
||||
select COMMON_CLK_MEDIATEK
|
||||
default ARCH_MEDIATEK
|
||||
help
|
||||
This driver supports MediaTek MT8167 vdecsys clocks.
|
||||
|
||||
config COMMON_CLK_MT8173
|
||||
bool "Clock driver for MediaTek MT8173"
|
||||
depends on ARCH_MEDIATEK || COMPILE_TEST
|
||||
|
|
|
@ -47,6 +47,12 @@ obj-$(CONFIG_COMMON_CLK_MT7629) += clk-mt7629.o
|
|||
obj-$(CONFIG_COMMON_CLK_MT7629_ETHSYS) += clk-mt7629-eth.o
|
||||
obj-$(CONFIG_COMMON_CLK_MT7629_HIFSYS) += clk-mt7629-hif.o
|
||||
obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135.o
|
||||
obj-$(CONFIG_COMMON_CLK_MT8167) += clk-mt8167.o
|
||||
obj-$(CONFIG_COMMON_CLK_MT8167_AUDSYS) += clk-mt8167-aud.o
|
||||
obj-$(CONFIG_COMMON_CLK_MT8167_IMGSYS) += clk-mt8167-img.o
|
||||
obj-$(CONFIG_COMMON_CLK_MT8167_MFGCFG) += clk-mt8167-mfgcfg.o
|
||||
obj-$(CONFIG_COMMON_CLK_MT8167_MMSYS) += clk-mt8167-mm.o
|
||||
obj-$(CONFIG_COMMON_CLK_MT8167_VDECSYS) += clk-mt8167-vdec.o
|
||||
obj-$(CONFIG_COMMON_CLK_MT8173) += clk-mt8173.o
|
||||
obj-$(CONFIG_COMMON_CLK_MT8173_MMSYS) += clk-mt8173-mm.o
|
||||
obj-$(CONFIG_COMMON_CLK_MT8183) += clk-mt8183.o
|
||||
|
|
|
@ -909,7 +909,6 @@ static struct platform_driver clk_mt6765_drv = {
|
|||
.probe = clk_mt6765_probe,
|
||||
.driver = {
|
||||
.name = "clk-mt6765",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = of_match_clk_mt6765,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -919,6 +919,8 @@ static const struct mtk_gate infra_clks[] = {
|
|||
"pwm_sel", 19),
|
||||
GATE_INFRA0(CLK_INFRA_PWM, "infra_pwm",
|
||||
"pwm_sel", 21),
|
||||
GATE_INFRA0(CLK_INFRA_UART0, "infra_uart0",
|
||||
"uart_sel", 22),
|
||||
GATE_INFRA0(CLK_INFRA_UART1, "infra_uart1",
|
||||
"uart_sel", 23),
|
||||
GATE_INFRA0(CLK_INFRA_UART2, "infra_uart2",
|
||||
|
|
|
@ -582,7 +582,7 @@ CLK_OF_DECLARE_DRIVER(mtk_infra, "mediatek,mt6797-infracfg",
|
|||
|
||||
static int mtk_infrasys_init(struct platform_device *pdev)
|
||||
{
|
||||
int r, i;
|
||||
int i;
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
|
||||
if (!infra_clk_data) {
|
||||
|
@ -599,11 +599,7 @@ static int mtk_infrasys_init(struct platform_device *pdev)
|
|||
mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs),
|
||||
infra_clk_data);
|
||||
|
||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, infra_clk_data);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
return of_clk_add_provider(node, of_clk_src_onecell_get, infra_clk_data);
|
||||
}
|
||||
|
||||
#define MT6797_PLL_FMAX (3000UL * MHZ)
|
||||
|
|
|
@ -601,7 +601,6 @@ static int mtk_infrasys_init(struct platform_device *pdev)
|
|||
{
|
||||
struct device_node *node = pdev->dev.of_node;
|
||||
struct clk_onecell_data *clk_data;
|
||||
int r;
|
||||
|
||||
clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK);
|
||||
|
||||
|
@ -611,12 +610,8 @@ static int mtk_infrasys_init(struct platform_device *pdev)
|
|||
mtk_clk_register_cpumuxes(node, infra_muxes, ARRAY_SIZE(infra_muxes),
|
||||
clk_data);
|
||||
|
||||
r = of_clk_add_provider(node, of_clk_src_onecell_get,
|
||||
clk_data);
|
||||
if (r)
|
||||
return r;
|
||||
|
||||
return 0;
|
||||
return of_clk_add_provider(node, of_clk_src_onecell_get,
|
||||
clk_data);
|
||||
}
|
||||
|
||||
static int mtk_pericfg_init(struct platform_device *pdev)
|
||||
|
|
|
@ -0,0 +1,66 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2020 MediaTek Inc.
|
||||
* Copyright (c) 2020 BayLibre, SAS
|
||||
* Author: James Liao <jamesjj.liao@mediatek.com>
|
||||
* Fabien Parent <fparent@baylibre.com>
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "clk-mtk.h"
|
||||
#include "clk-gate.h"
|
||||
|
||||
#include <dt-bindings/clock/mt8167-clk.h>
|
||||
|
||||
static const struct mtk_gate_regs aud_cg_regs = {
|
||||
.set_ofs = 0x0,
|
||||
.clr_ofs = 0x0,
|
||||
.sta_ofs = 0x0,
|
||||
};
|
||||
|
||||
#define GATE_AUD(_id, _name, _parent, _shift) { \
|
||||
.id = _id, \
|
||||
.name = _name, \
|
||||
.parent_name = _parent, \
|
||||
.regs = &aud_cg_regs, \
|
||||
.shift = _shift, \
|
||||
.ops = &mtk_clk_gate_ops_no_setclr, \
|
||||
}
|
||||
|
||||
static const struct mtk_gate aud_clks[] __initconst = {
|
||||
GATE_AUD(CLK_AUD_AFE, "aud_afe", "clk26m_ck", 2),
|
||||
GATE_AUD(CLK_AUD_I2S, "aud_i2s", "i2s_infra_bck", 6),
|
||||
GATE_AUD(CLK_AUD_22M, "aud_22m", "rg_aud_engen1", 8),
|
||||
GATE_AUD(CLK_AUD_24M, "aud_24m", "rg_aud_engen2", 9),
|
||||
GATE_AUD(CLK_AUD_INTDIR, "aud_intdir", "rg_aud_spdif_in", 15),
|
||||
GATE_AUD(CLK_AUD_APLL2_TUNER, "aud_apll2_tuner", "rg_aud_engen2", 18),
|
||||
GATE_AUD(CLK_AUD_APLL_TUNER, "aud_apll_tuner", "rg_aud_engen1", 19),
|
||||
GATE_AUD(CLK_AUD_HDMI, "aud_hdmi", "apll12_div4", 20),
|
||||
GATE_AUD(CLK_AUD_SPDF, "aud_spdf", "apll12_div6", 21),
|
||||
GATE_AUD(CLK_AUD_ADC, "aud_adc", "aud_afe", 24),
|
||||
GATE_AUD(CLK_AUD_DAC, "aud_dac", "aud_afe", 25),
|
||||
GATE_AUD(CLK_AUD_DAC_PREDIS, "aud_dac_predis", "aud_afe", 26),
|
||||
GATE_AUD(CLK_AUD_TML, "aud_tml", "aud_afe", 27),
|
||||
};
|
||||
|
||||
static void __init mtk_audsys_init(struct device_node *node)
|
||||
{
|
||||
struct clk_onecell_data *clk_data;
|
||||
int r;
|
||||
|
||||
clk_data = mtk_alloc_clk_data(CLK_AUD_NR_CLK);
|
||||
|
||||
mtk_clk_register_gates(node, aud_clks, ARRAY_SIZE(aud_clks), clk_data);
|
||||
|
||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
||||
if (r)
|
||||
pr_err("%s(): could not register clock provider: %d\n",
|
||||
__func__, r);
|
||||
|
||||
}
|
||||
CLK_OF_DECLARE(mtk_audsys, "mediatek,mt8167-audsys", mtk_audsys_init);
|
|
@ -0,0 +1,60 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2020 MediaTek Inc.
|
||||
* Copyright (c) 2020 BayLibre, SAS
|
||||
* Author: James Liao <jamesjj.liao@mediatek.com>
|
||||
* Fabien Parent <fparent@baylibre.com>
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "clk-mtk.h"
|
||||
#include "clk-gate.h"
|
||||
|
||||
#include <dt-bindings/clock/mt8167-clk.h>
|
||||
|
||||
static const struct mtk_gate_regs img_cg_regs = {
|
||||
.set_ofs = 0x4,
|
||||
.clr_ofs = 0x8,
|
||||
.sta_ofs = 0x0,
|
||||
};
|
||||
|
||||
#define GATE_IMG(_id, _name, _parent, _shift) { \
|
||||
.id = _id, \
|
||||
.name = _name, \
|
||||
.parent_name = _parent, \
|
||||
.regs = &img_cg_regs, \
|
||||
.shift = _shift, \
|
||||
.ops = &mtk_clk_gate_ops_setclr, \
|
||||
}
|
||||
|
||||
static const struct mtk_gate img_clks[] __initconst = {
|
||||
GATE_IMG(CLK_IMG_LARB1_SMI, "img_larb1_smi", "smi_mm", 0),
|
||||
GATE_IMG(CLK_IMG_CAM_SMI, "img_cam_smi", "smi_mm", 5),
|
||||
GATE_IMG(CLK_IMG_CAM_CAM, "img_cam_cam", "smi_mm", 6),
|
||||
GATE_IMG(CLK_IMG_SEN_TG, "img_sen_tg", "cam_mm", 7),
|
||||
GATE_IMG(CLK_IMG_SEN_CAM, "img_sen_cam", "smi_mm", 8),
|
||||
GATE_IMG(CLK_IMG_VENC, "img_venc", "smi_mm", 9),
|
||||
};
|
||||
|
||||
static void __init mtk_imgsys_init(struct device_node *node)
|
||||
{
|
||||
struct clk_onecell_data *clk_data;
|
||||
int r;
|
||||
|
||||
clk_data = mtk_alloc_clk_data(CLK_IMG_NR_CLK);
|
||||
|
||||
mtk_clk_register_gates(node, img_clks, ARRAY_SIZE(img_clks), clk_data);
|
||||
|
||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
||||
|
||||
if (r)
|
||||
pr_err("%s(): could not register clock provider: %d\n",
|
||||
__func__, r);
|
||||
|
||||
}
|
||||
CLK_OF_DECLARE(mtk_imgsys, "mediatek,mt8167-imgsys", mtk_imgsys_init);
|
|
@ -0,0 +1,58 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2020 MediaTek Inc.
|
||||
* Copyright (c) 2020 BayLibre, SAS
|
||||
* Author: James Liao <jamesjj.liao@mediatek.com>
|
||||
* Fabien Parent <fparent@baylibre.com>
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "clk-mtk.h"
|
||||
#include "clk-gate.h"
|
||||
|
||||
#include <dt-bindings/clock/mt8167-clk.h>
|
||||
|
||||
static const struct mtk_gate_regs mfg_cg_regs = {
|
||||
.set_ofs = 0x4,
|
||||
.clr_ofs = 0x8,
|
||||
.sta_ofs = 0x0,
|
||||
};
|
||||
|
||||
#define GATE_MFG(_id, _name, _parent, _shift) { \
|
||||
.id = _id, \
|
||||
.name = _name, \
|
||||
.parent_name = _parent, \
|
||||
.regs = &mfg_cg_regs, \
|
||||
.shift = _shift, \
|
||||
.ops = &mtk_clk_gate_ops_setclr, \
|
||||
}
|
||||
|
||||
static const struct mtk_gate mfg_clks[] __initconst = {
|
||||
GATE_MFG(CLK_MFG_BAXI, "mfg_baxi", "ahb_infra_sel", 0),
|
||||
GATE_MFG(CLK_MFG_BMEM, "mfg_bmem", "gfmux_emi1x_sel", 1),
|
||||
GATE_MFG(CLK_MFG_BG3D, "mfg_bg3d", "mfg_mm", 2),
|
||||
GATE_MFG(CLK_MFG_B26M, "mfg_b26m", "clk26m_ck", 3),
|
||||
};
|
||||
|
||||
static void __init mtk_mfgcfg_init(struct device_node *node)
|
||||
{
|
||||
struct clk_onecell_data *clk_data;
|
||||
int r;
|
||||
|
||||
clk_data = mtk_alloc_clk_data(CLK_MFG_NR_CLK);
|
||||
|
||||
mtk_clk_register_gates(node, mfg_clks, ARRAY_SIZE(mfg_clks), clk_data);
|
||||
|
||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
||||
|
||||
if (r)
|
||||
pr_err("%s(): could not register clock provider: %d\n",
|
||||
__func__, r);
|
||||
|
||||
}
|
||||
CLK_OF_DECLARE(mtk_mfgcfg, "mediatek,mt8167-mfgcfg", mtk_mfgcfg_init);
|
|
@ -0,0 +1,132 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2020 MediaTek Inc.
|
||||
* Copyright (c) 2020 BayLibre, SAS
|
||||
* Author: James Liao <jamesjj.liao@mediatek.com>
|
||||
* Fabien Parent <fparent@baylibre.com>
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "clk-mtk.h"
|
||||
#include "clk-gate.h"
|
||||
|
||||
#include <dt-bindings/clock/mt8167-clk.h>
|
||||
|
||||
static const struct mtk_gate_regs mm0_cg_regs = {
|
||||
.set_ofs = 0x104,
|
||||
.clr_ofs = 0x108,
|
||||
.sta_ofs = 0x100,
|
||||
};
|
||||
|
||||
static const struct mtk_gate_regs mm1_cg_regs = {
|
||||
.set_ofs = 0x114,
|
||||
.clr_ofs = 0x118,
|
||||
.sta_ofs = 0x110,
|
||||
};
|
||||
|
||||
#define GATE_MM0(_id, _name, _parent, _shift) { \
|
||||
.id = _id, \
|
||||
.name = _name, \
|
||||
.parent_name = _parent, \
|
||||
.regs = &mm0_cg_regs, \
|
||||
.shift = _shift, \
|
||||
.ops = &mtk_clk_gate_ops_setclr, \
|
||||
}
|
||||
|
||||
#define GATE_MM1(_id, _name, _parent, _shift) { \
|
||||
.id = _id, \
|
||||
.name = _name, \
|
||||
.parent_name = _parent, \
|
||||
.regs = &mm1_cg_regs, \
|
||||
.shift = _shift, \
|
||||
.ops = &mtk_clk_gate_ops_setclr, \
|
||||
}
|
||||
|
||||
static const struct mtk_gate mm_clks[] = {
|
||||
/* MM0 */
|
||||
GATE_MM0(CLK_MM_SMI_COMMON, "mm_smi_common", "smi_mm", 0),
|
||||
GATE_MM0(CLK_MM_SMI_LARB0, "mm_smi_larb0", "smi_mm", 1),
|
||||
GATE_MM0(CLK_MM_CAM_MDP, "mm_cam_mdp", "smi_mm", 2),
|
||||
GATE_MM0(CLK_MM_MDP_RDMA, "mm_mdp_rdma", "smi_mm", 3),
|
||||
GATE_MM0(CLK_MM_MDP_RSZ0, "mm_mdp_rsz0", "smi_mm", 4),
|
||||
GATE_MM0(CLK_MM_MDP_RSZ1, "mm_mdp_rsz1", "smi_mm", 5),
|
||||
GATE_MM0(CLK_MM_MDP_TDSHP, "mm_mdp_tdshp", "smi_mm", 6),
|
||||
GATE_MM0(CLK_MM_MDP_WDMA, "mm_mdp_wdma", "smi_mm", 7),
|
||||
GATE_MM0(CLK_MM_MDP_WROT, "mm_mdp_wrot", "smi_mm", 8),
|
||||
GATE_MM0(CLK_MM_FAKE_ENG, "mm_fake_eng", "smi_mm", 9),
|
||||
GATE_MM0(CLK_MM_DISP_OVL0, "mm_disp_ovl0", "smi_mm", 10),
|
||||
GATE_MM0(CLK_MM_DISP_RDMA0, "mm_disp_rdma0", "smi_mm", 11),
|
||||
GATE_MM0(CLK_MM_DISP_RDMA1, "mm_disp_rdma1", "smi_mm", 12),
|
||||
GATE_MM0(CLK_MM_DISP_WDMA, "mm_disp_wdma", "smi_mm", 13),
|
||||
GATE_MM0(CLK_MM_DISP_COLOR, "mm_disp_color", "smi_mm", 14),
|
||||
GATE_MM0(CLK_MM_DISP_CCORR, "mm_disp_ccorr", "smi_mm", 15),
|
||||
GATE_MM0(CLK_MM_DISP_AAL, "mm_disp_aal", "smi_mm", 16),
|
||||
GATE_MM0(CLK_MM_DISP_GAMMA, "mm_disp_gamma", "smi_mm", 17),
|
||||
GATE_MM0(CLK_MM_DISP_DITHER, "mm_disp_dither", "smi_mm", 18),
|
||||
GATE_MM0(CLK_MM_DISP_UFOE, "mm_disp_ufoe", "smi_mm", 19),
|
||||
/* MM1 */
|
||||
GATE_MM1(CLK_MM_DISP_PWM_MM, "mm_disp_pwm_mm", "smi_mm", 0),
|
||||
GATE_MM1(CLK_MM_DISP_PWM_26M, "mm_disp_pwm_26m", "smi_mm", 1),
|
||||
GATE_MM1(CLK_MM_DSI_ENGINE, "mm_dsi_engine", "smi_mm", 2),
|
||||
GATE_MM1(CLK_MM_DSI_DIGITAL, "mm_dsi_digital", "dsi0_lntc_dsick", 3),
|
||||
GATE_MM1(CLK_MM_DPI0_ENGINE, "mm_dpi0_engine", "smi_mm", 4),
|
||||
GATE_MM1(CLK_MM_DPI0_PXL, "mm_dpi0_pxl", "rg_fdpi0", 5),
|
||||
GATE_MM1(CLK_MM_LVDS_PXL, "mm_lvds_pxl", "vpll_dpix", 14),
|
||||
GATE_MM1(CLK_MM_LVDS_CTS, "mm_lvds_cts", "lvdstx_dig_cts", 15),
|
||||
GATE_MM1(CLK_MM_DPI1_ENGINE, "mm_dpi1_engine", "smi_mm", 16),
|
||||
GATE_MM1(CLK_MM_DPI1_PXL, "mm_dpi1_pxl", "rg_fdpi1", 17),
|
||||
GATE_MM1(CLK_MM_HDMI_PXL, "mm_hdmi_pxl", "rg_fdpi1", 18),
|
||||
GATE_MM1(CLK_MM_HDMI_SPDIF, "mm_hdmi_spdif", "apll12_div6", 19),
|
||||
GATE_MM1(CLK_MM_HDMI_ADSP_BCK, "mm_hdmi_adsp_b", "apll12_div4b", 20),
|
||||
GATE_MM1(CLK_MM_HDMI_PLL, "mm_hdmi_pll", "hdmtx_dig_cts", 21),
|
||||
};
|
||||
|
||||
struct clk_mt8167_mm_driver_data {
|
||||
const struct mtk_gate *gates_clk;
|
||||
int gates_num;
|
||||
};
|
||||
|
||||
static const struct clk_mt8167_mm_driver_data mt8167_mmsys_driver_data = {
|
||||
.gates_clk = mm_clks,
|
||||
.gates_num = ARRAY_SIZE(mm_clks),
|
||||
};
|
||||
|
||||
static int clk_mt8167_mm_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *node = dev->parent->of_node;
|
||||
const struct clk_mt8167_mm_driver_data *data;
|
||||
struct clk_onecell_data *clk_data;
|
||||
int ret;
|
||||
|
||||
clk_data = mtk_alloc_clk_data(CLK_MM_NR_CLK);
|
||||
if (!clk_data)
|
||||
return -ENOMEM;
|
||||
|
||||
data = &mt8167_mmsys_driver_data;
|
||||
|
||||
ret = mtk_clk_register_gates(node, data->gates_clk, data->gates_num,
|
||||
clk_data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver clk_mt8173_mm_drv = {
|
||||
.driver = {
|
||||
.name = "clk-mt8167-mm",
|
||||
},
|
||||
.probe = clk_mt8167_mm_probe,
|
||||
};
|
||||
|
||||
builtin_platform_driver(clk_mt8173_mm_drv);
|
|
@ -0,0 +1,73 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (c) 2020 MediaTek Inc.
|
||||
* Copyright (c) 2020 BayLibre, SAS
|
||||
* Author: James Liao <jamesjj.liao@mediatek.com>
|
||||
* Fabien Parent <fparent@baylibre.com>
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
|
||||
#include "clk-mtk.h"
|
||||
#include "clk-gate.h"
|
||||
|
||||
#include <dt-bindings/clock/mt8167-clk.h>
|
||||
|
||||
static const struct mtk_gate_regs vdec0_cg_regs = {
|
||||
.set_ofs = 0x0,
|
||||
.clr_ofs = 0x4,
|
||||
.sta_ofs = 0x0,
|
||||
};
|
||||
|
||||
static const struct mtk_gate_regs vdec1_cg_regs = {
|
||||
.set_ofs = 0x8,
|
||||
.clr_ofs = 0xc,
|
||||
.sta_ofs = 0x8,
|
||||
};
|
||||
|
||||
#define GATE_VDEC0_I(_id, _name, _parent, _shift) { \
|
||||
.id = _id, \
|
||||
.name = _name, \
|
||||
.parent_name = _parent, \
|
||||
.regs = &vdec0_cg_regs, \
|
||||
.shift = _shift, \
|
||||
.ops = &mtk_clk_gate_ops_setclr_inv, \
|
||||
}
|
||||
|
||||
#define GATE_VDEC1_I(_id, _name, _parent, _shift) { \
|
||||
.id = _id, \
|
||||
.name = _name, \
|
||||
.parent_name = _parent, \
|
||||
.regs = &vdec1_cg_regs, \
|
||||
.shift = _shift, \
|
||||
.ops = &mtk_clk_gate_ops_setclr_inv, \
|
||||
}
|
||||
|
||||
static const struct mtk_gate vdec_clks[] __initconst = {
|
||||
/* VDEC0 */
|
||||
GATE_VDEC0_I(CLK_VDEC_CKEN, "vdec_cken", "rg_vdec", 0),
|
||||
/* VDEC1 */
|
||||
GATE_VDEC1_I(CLK_VDEC_LARB1_CKEN, "vdec_larb1_cken", "smi_mm", 0),
|
||||
};
|
||||
|
||||
static void __init mtk_vdecsys_init(struct device_node *node)
|
||||
{
|
||||
struct clk_onecell_data *clk_data;
|
||||
int r;
|
||||
|
||||
clk_data = mtk_alloc_clk_data(CLK_VDEC_NR_CLK);
|
||||
|
||||
mtk_clk_register_gates(node, vdec_clks, ARRAY_SIZE(vdec_clks), clk_data);
|
||||
|
||||
r = of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
||||
|
||||
if (r)
|
||||
pr_err("%s(): could not register clock provider: %d\n",
|
||||
__func__, r);
|
||||
|
||||
}
|
||||
CLK_OF_DECLARE(mtk_vdecsys, "mediatek,mt8167-vdecsys", mtk_vdecsys_init);
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,7 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
menu "Clock support for Amlogic platforms"
|
||||
depends on ARCH_MESON || COMPILE_TEST
|
||||
|
||||
config COMMON_CLK_MESON_REGMAP
|
||||
tristate
|
||||
select REGMAP
|
||||
|
@ -41,8 +44,9 @@ config COMMON_CLK_MESON_CPU_DYNDIV
|
|||
select COMMON_CLK_MESON_REGMAP
|
||||
|
||||
config COMMON_CLK_MESON8B
|
||||
bool
|
||||
depends on ARCH_MESON
|
||||
bool "Meson8 SoC Clock controller support"
|
||||
depends on ARM
|
||||
default y
|
||||
select COMMON_CLK_MESON_REGMAP
|
||||
select COMMON_CLK_MESON_MPLL
|
||||
select COMMON_CLK_MESON_PLL
|
||||
|
@ -54,8 +58,9 @@ config COMMON_CLK_MESON8B
|
|||
want peripherals and CPU frequency scaling to work.
|
||||
|
||||
config COMMON_CLK_GXBB
|
||||
bool
|
||||
depends on ARCH_MESON
|
||||
bool "GXBB and GXL SoC clock controllers support"
|
||||
depends on ARM64
|
||||
default y
|
||||
select COMMON_CLK_MESON_REGMAP
|
||||
select COMMON_CLK_MESON_DUALDIV
|
||||
select COMMON_CLK_MESON_VID_PLL_DIV
|
||||
|
@ -69,8 +74,9 @@ config COMMON_CLK_GXBB
|
|||
Say Y if you want peripherals and CPU frequency scaling to work.
|
||||
|
||||
config COMMON_CLK_AXG
|
||||
bool
|
||||
depends on ARCH_MESON
|
||||
bool "AXG SoC clock controllers support"
|
||||
depends on ARM64
|
||||
default y
|
||||
select COMMON_CLK_MESON_REGMAP
|
||||
select COMMON_CLK_MESON_DUALDIV
|
||||
select COMMON_CLK_MESON_MPLL
|
||||
|
@ -84,7 +90,7 @@ config COMMON_CLK_AXG
|
|||
|
||||
config COMMON_CLK_AXG_AUDIO
|
||||
tristate "Meson AXG Audio Clock Controller Driver"
|
||||
depends on ARCH_MESON
|
||||
depends on ARM64
|
||||
select COMMON_CLK_MESON_REGMAP
|
||||
select COMMON_CLK_MESON_PHASE
|
||||
select COMMON_CLK_MESON_SCLK_DIV
|
||||
|
@ -94,8 +100,9 @@ config COMMON_CLK_AXG_AUDIO
|
|||
aka axg, Say Y if you want audio subsystem to work.
|
||||
|
||||
config COMMON_CLK_G12A
|
||||
bool
|
||||
depends on ARCH_MESON
|
||||
bool "G12 and SM1 SoC clock controllers support"
|
||||
depends on ARM64
|
||||
default y
|
||||
select COMMON_CLK_MESON_REGMAP
|
||||
select COMMON_CLK_MESON_DUALDIV
|
||||
select COMMON_CLK_MESON_MPLL
|
||||
|
@ -107,3 +114,4 @@ config COMMON_CLK_G12A
|
|||
help
|
||||
Support for the clock controller on Amlogic S905D2, S905X2 and S905Y2
|
||||
devices, aka g12a. Say Y if you want peripherals to work.
|
||||
endmenu
|
||||
|
|
|
@ -147,6 +147,29 @@
|
|||
}, \
|
||||
}
|
||||
|
||||
#define AUD_SCLK_WS(_name, _reg, _width, _shift_ph, _shift_ws, _pname, \
|
||||
_iflags) { \
|
||||
.data = &(struct meson_sclk_ws_inv_data) { \
|
||||
.ph = { \
|
||||
.reg_off = (_reg), \
|
||||
.shift = (_shift_ph), \
|
||||
.width = (_width), \
|
||||
}, \
|
||||
.ws = { \
|
||||
.reg_off = (_reg), \
|
||||
.shift = (_shift_ws), \
|
||||
.width = (_width), \
|
||||
}, \
|
||||
}, \
|
||||
.hw.init = &(struct clk_init_data) { \
|
||||
.name = "aud_"#_name, \
|
||||
.ops = &meson_clk_phase_ops, \
|
||||
.parent_names = (const char *[]){ #_pname }, \
|
||||
.num_parents = 1, \
|
||||
.flags = (_iflags), \
|
||||
}, \
|
||||
}
|
||||
|
||||
/* Audio Master Clocks */
|
||||
static const struct clk_parent_data mst_mux_parent_data[] = {
|
||||
{ .fw_name = "mst_in0", },
|
||||
|
@ -254,6 +277,10 @@ static const struct clk_parent_data tdm_lrclk_parent_data[] = {
|
|||
AUD_PHASE(tdm##_name##_sclk, _reg, 1, 29, \
|
||||
aud_tdm##_name##_sclk_post_en, \
|
||||
CLK_DUTY_CYCLE_PARENT | CLK_SET_RATE_PARENT)
|
||||
#define AUD_TDM_SCLK_WS(_name, _reg) \
|
||||
AUD_SCLK_WS(tdm##_name##_sclk, _reg, 1, 29, 28, \
|
||||
aud_tdm##_name##_sclk_post_en, \
|
||||
CLK_DUTY_CYCLE_PARENT | CLK_SET_RATE_PARENT)
|
||||
|
||||
#define AUD_TDM_LRLCK(_name, _reg) \
|
||||
AUD_MUX(tdm##_name##_lrclk, _reg, 0xf, 20, \
|
||||
|
@ -499,12 +526,6 @@ static struct clk_regmap tdmin_c_sclk =
|
|||
AUD_TDM_SCLK(in_c, AUDIO_CLK_TDMIN_C_CTRL);
|
||||
static struct clk_regmap tdmin_lb_sclk =
|
||||
AUD_TDM_SCLK(in_lb, AUDIO_CLK_TDMIN_LB_CTRL);
|
||||
static struct clk_regmap tdmout_a_sclk =
|
||||
AUD_TDM_SCLK(out_a, AUDIO_CLK_TDMOUT_A_CTRL);
|
||||
static struct clk_regmap tdmout_b_sclk =
|
||||
AUD_TDM_SCLK(out_b, AUDIO_CLK_TDMOUT_B_CTRL);
|
||||
static struct clk_regmap tdmout_c_sclk =
|
||||
AUD_TDM_SCLK(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
|
||||
|
||||
static struct clk_regmap tdmin_a_lrclk =
|
||||
AUD_TDM_LRLCK(in_a, AUDIO_CLK_TDMIN_A_CTRL);
|
||||
|
@ -521,6 +542,14 @@ static struct clk_regmap tdmout_b_lrclk =
|
|||
static struct clk_regmap tdmout_c_lrclk =
|
||||
AUD_TDM_LRLCK(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
|
||||
|
||||
/* AXG Clocks */
|
||||
static struct clk_regmap axg_tdmout_a_sclk =
|
||||
AUD_TDM_SCLK(out_a, AUDIO_CLK_TDMOUT_A_CTRL);
|
||||
static struct clk_regmap axg_tdmout_b_sclk =
|
||||
AUD_TDM_SCLK(out_b, AUDIO_CLK_TDMOUT_B_CTRL);
|
||||
static struct clk_regmap axg_tdmout_c_sclk =
|
||||
AUD_TDM_SCLK(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
|
||||
|
||||
/* AXG/G12A Clocks */
|
||||
static struct clk_hw axg_aud_top = {
|
||||
.init = &(struct clk_init_data) {
|
||||
|
@ -591,7 +620,13 @@ static struct clk_regmap g12a_tdm_sclk_pad_1 = AUD_TDM_PAD_CTRL(
|
|||
static struct clk_regmap g12a_tdm_sclk_pad_2 = AUD_TDM_PAD_CTRL(
|
||||
sclk_pad_2, AUDIO_MST_PAD_CTRL1, 8, sclk_pad_ctrl_parent_data);
|
||||
|
||||
/* G12a/SM1 clocks */
|
||||
static struct clk_regmap g12a_tdmout_a_sclk =
|
||||
AUD_TDM_SCLK_WS(out_a, AUDIO_CLK_TDMOUT_A_CTRL);
|
||||
static struct clk_regmap g12a_tdmout_b_sclk =
|
||||
AUD_TDM_SCLK_WS(out_b, AUDIO_CLK_TDMOUT_B_CTRL);
|
||||
static struct clk_regmap g12a_tdmout_c_sclk =
|
||||
AUD_TDM_SCLK_WS(out_c, AUDIO_CLK_TDMOUT_C_CTRL);
|
||||
|
||||
static struct clk_regmap toram =
|
||||
AUD_PCLK_GATE(toram, AUDIO_CLK_GATE_EN, 20);
|
||||
static struct clk_regmap spdifout_b =
|
||||
|
@ -889,9 +924,9 @@ static struct clk_hw_onecell_data axg_audio_hw_onecell_data = {
|
|||
[AUD_CLKID_TDMIN_B_SCLK] = &tdmin_b_sclk.hw,
|
||||
[AUD_CLKID_TDMIN_C_SCLK] = &tdmin_c_sclk.hw,
|
||||
[AUD_CLKID_TDMIN_LB_SCLK] = &tdmin_lb_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_A_SCLK] = &tdmout_a_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_B_SCLK] = &tdmout_b_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_C_SCLK] = &tdmout_c_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_A_SCLK] = &axg_tdmout_a_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_B_SCLK] = &axg_tdmout_b_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_C_SCLK] = &axg_tdmout_c_sclk.hw,
|
||||
[AUD_CLKID_TDMIN_A_LRCLK] = &tdmin_a_lrclk.hw,
|
||||
[AUD_CLKID_TDMIN_B_LRCLK] = &tdmin_b_lrclk.hw,
|
||||
[AUD_CLKID_TDMIN_C_LRCLK] = &tdmin_c_lrclk.hw,
|
||||
|
@ -1026,9 +1061,9 @@ static struct clk_hw_onecell_data g12a_audio_hw_onecell_data = {
|
|||
[AUD_CLKID_TDMIN_B_SCLK] = &tdmin_b_sclk.hw,
|
||||
[AUD_CLKID_TDMIN_C_SCLK] = &tdmin_c_sclk.hw,
|
||||
[AUD_CLKID_TDMIN_LB_SCLK] = &tdmin_lb_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_A_SCLK] = &tdmout_a_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_B_SCLK] = &tdmout_b_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_C_SCLK] = &tdmout_c_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_A_SCLK] = &g12a_tdmout_a_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_B_SCLK] = &g12a_tdmout_b_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_C_SCLK] = &g12a_tdmout_c_sclk.hw,
|
||||
[AUD_CLKID_TDMIN_A_LRCLK] = &tdmin_a_lrclk.hw,
|
||||
[AUD_CLKID_TDMIN_B_LRCLK] = &tdmin_b_lrclk.hw,
|
||||
[AUD_CLKID_TDMIN_C_LRCLK] = &tdmin_c_lrclk.hw,
|
||||
|
@ -1170,9 +1205,9 @@ static struct clk_hw_onecell_data sm1_audio_hw_onecell_data = {
|
|||
[AUD_CLKID_TDMIN_B_SCLK] = &tdmin_b_sclk.hw,
|
||||
[AUD_CLKID_TDMIN_C_SCLK] = &tdmin_c_sclk.hw,
|
||||
[AUD_CLKID_TDMIN_LB_SCLK] = &tdmin_lb_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_A_SCLK] = &tdmout_a_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_B_SCLK] = &tdmout_b_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_C_SCLK] = &tdmout_c_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_A_SCLK] = &g12a_tdmout_a_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_B_SCLK] = &g12a_tdmout_b_sclk.hw,
|
||||
[AUD_CLKID_TDMOUT_C_SCLK] = &g12a_tdmout_c_sclk.hw,
|
||||
[AUD_CLKID_TDMIN_A_LRCLK] = &tdmin_a_lrclk.hw,
|
||||
[AUD_CLKID_TDMIN_B_LRCLK] = &tdmin_b_lrclk.hw,
|
||||
[AUD_CLKID_TDMIN_C_LRCLK] = &tdmin_c_lrclk.hw,
|
||||
|
@ -1209,13 +1244,132 @@ static struct clk_hw_onecell_data sm1_audio_hw_onecell_data = {
|
|||
};
|
||||
|
||||
|
||||
/* Convenience table to populate regmap in .probe()
|
||||
* Note that this table is shared between both AXG and G12A,
|
||||
* with spdifout_b clocks being exclusive to G12A. Since those
|
||||
* clocks are not declared within the AXG onecell table, we do not
|
||||
* feel the need to have separate AXG/G12A regmap tables.
|
||||
*/
|
||||
/* Convenience table to populate regmap in .probe(). */
|
||||
static struct clk_regmap *const axg_clk_regmaps[] = {
|
||||
&ddr_arb,
|
||||
&pdm,
|
||||
&tdmin_a,
|
||||
&tdmin_b,
|
||||
&tdmin_c,
|
||||
&tdmin_lb,
|
||||
&tdmout_a,
|
||||
&tdmout_b,
|
||||
&tdmout_c,
|
||||
&frddr_a,
|
||||
&frddr_b,
|
||||
&frddr_c,
|
||||
&toddr_a,
|
||||
&toddr_b,
|
||||
&toddr_c,
|
||||
&loopback,
|
||||
&spdifin,
|
||||
&spdifout,
|
||||
&resample,
|
||||
&power_detect,
|
||||
&mst_a_mclk_sel,
|
||||
&mst_b_mclk_sel,
|
||||
&mst_c_mclk_sel,
|
||||
&mst_d_mclk_sel,
|
||||
&mst_e_mclk_sel,
|
||||
&mst_f_mclk_sel,
|
||||
&mst_a_mclk_div,
|
||||
&mst_b_mclk_div,
|
||||
&mst_c_mclk_div,
|
||||
&mst_d_mclk_div,
|
||||
&mst_e_mclk_div,
|
||||
&mst_f_mclk_div,
|
||||
&mst_a_mclk,
|
||||
&mst_b_mclk,
|
||||
&mst_c_mclk,
|
||||
&mst_d_mclk,
|
||||
&mst_e_mclk,
|
||||
&mst_f_mclk,
|
||||
&spdifout_clk_sel,
|
||||
&spdifout_clk_div,
|
||||
&spdifout_clk,
|
||||
&spdifin_clk_sel,
|
||||
&spdifin_clk_div,
|
||||
&spdifin_clk,
|
||||
&pdm_dclk_sel,
|
||||
&pdm_dclk_div,
|
||||
&pdm_dclk,
|
||||
&pdm_sysclk_sel,
|
||||
&pdm_sysclk_div,
|
||||
&pdm_sysclk,
|
||||
&mst_a_sclk_pre_en,
|
||||
&mst_b_sclk_pre_en,
|
||||
&mst_c_sclk_pre_en,
|
||||
&mst_d_sclk_pre_en,
|
||||
&mst_e_sclk_pre_en,
|
||||
&mst_f_sclk_pre_en,
|
||||
&mst_a_sclk_div,
|
||||
&mst_b_sclk_div,
|
||||
&mst_c_sclk_div,
|
||||
&mst_d_sclk_div,
|
||||
&mst_e_sclk_div,
|
||||
&mst_f_sclk_div,
|
||||
&mst_a_sclk_post_en,
|
||||
&mst_b_sclk_post_en,
|
||||
&mst_c_sclk_post_en,
|
||||
&mst_d_sclk_post_en,
|
||||
&mst_e_sclk_post_en,
|
||||
&mst_f_sclk_post_en,
|
||||
&mst_a_sclk,
|
||||
&mst_b_sclk,
|
||||
&mst_c_sclk,
|
||||
&mst_d_sclk,
|
||||
&mst_e_sclk,
|
||||
&mst_f_sclk,
|
||||
&mst_a_lrclk_div,
|
||||
&mst_b_lrclk_div,
|
||||
&mst_c_lrclk_div,
|
||||
&mst_d_lrclk_div,
|
||||
&mst_e_lrclk_div,
|
||||
&mst_f_lrclk_div,
|
||||
&mst_a_lrclk,
|
||||
&mst_b_lrclk,
|
||||
&mst_c_lrclk,
|
||||
&mst_d_lrclk,
|
||||
&mst_e_lrclk,
|
||||
&mst_f_lrclk,
|
||||
&tdmin_a_sclk_sel,
|
||||
&tdmin_b_sclk_sel,
|
||||
&tdmin_c_sclk_sel,
|
||||
&tdmin_lb_sclk_sel,
|
||||
&tdmout_a_sclk_sel,
|
||||
&tdmout_b_sclk_sel,
|
||||
&tdmout_c_sclk_sel,
|
||||
&tdmin_a_sclk_pre_en,
|
||||
&tdmin_b_sclk_pre_en,
|
||||
&tdmin_c_sclk_pre_en,
|
||||
&tdmin_lb_sclk_pre_en,
|
||||
&tdmout_a_sclk_pre_en,
|
||||
&tdmout_b_sclk_pre_en,
|
||||
&tdmout_c_sclk_pre_en,
|
||||
&tdmin_a_sclk_post_en,
|
||||
&tdmin_b_sclk_post_en,
|
||||
&tdmin_c_sclk_post_en,
|
||||
&tdmin_lb_sclk_post_en,
|
||||
&tdmout_a_sclk_post_en,
|
||||
&tdmout_b_sclk_post_en,
|
||||
&tdmout_c_sclk_post_en,
|
||||
&tdmin_a_sclk,
|
||||
&tdmin_b_sclk,
|
||||
&tdmin_c_sclk,
|
||||
&tdmin_lb_sclk,
|
||||
&axg_tdmout_a_sclk,
|
||||
&axg_tdmout_b_sclk,
|
||||
&axg_tdmout_c_sclk,
|
||||
&tdmin_a_lrclk,
|
||||
&tdmin_b_lrclk,
|
||||
&tdmin_c_lrclk,
|
||||
&tdmin_lb_lrclk,
|
||||
&tdmout_a_lrclk,
|
||||
&tdmout_b_lrclk,
|
||||
&tdmout_c_lrclk,
|
||||
};
|
||||
|
||||
static struct clk_regmap *const g12a_clk_regmaps[] = {
|
||||
&ddr_arb,
|
||||
&pdm,
|
||||
&tdmin_a,
|
||||
|
@ -1328,9 +1482,9 @@ static struct clk_regmap *const axg_clk_regmaps[] = {
|
|||
&tdmin_b_sclk,
|
||||
&tdmin_c_sclk,
|
||||
&tdmin_lb_sclk,
|
||||
&tdmout_a_sclk,
|
||||
&tdmout_b_sclk,
|
||||
&tdmout_c_sclk,
|
||||
&g12a_tdmout_a_sclk,
|
||||
&g12a_tdmout_b_sclk,
|
||||
&g12a_tdmout_c_sclk,
|
||||
&tdmin_a_lrclk,
|
||||
&tdmin_b_lrclk,
|
||||
&tdmin_c_lrclk,
|
||||
|
@ -1465,9 +1619,9 @@ static struct clk_regmap *const sm1_clk_regmaps[] = {
|
|||
&tdmin_b_sclk,
|
||||
&tdmin_c_sclk,
|
||||
&tdmin_lb_sclk,
|
||||
&tdmout_a_sclk,
|
||||
&tdmout_b_sclk,
|
||||
&tdmout_c_sclk,
|
||||
&g12a_tdmout_a_sclk,
|
||||
&g12a_tdmout_b_sclk,
|
||||
&g12a_tdmout_c_sclk,
|
||||
&tdmin_a_lrclk,
|
||||
&tdmin_b_lrclk,
|
||||
&tdmin_c_lrclk,
|
||||
|
@ -1713,8 +1867,8 @@ static const struct audioclk_data axg_audioclk_data = {
|
|||
};
|
||||
|
||||
static const struct audioclk_data g12a_audioclk_data = {
|
||||
.regmap_clks = axg_clk_regmaps,
|
||||
.regmap_clk_num = ARRAY_SIZE(axg_clk_regmaps),
|
||||
.regmap_clks = g12a_clk_regmaps,
|
||||
.regmap_clk_num = ARRAY_SIZE(g12a_clk_regmaps),
|
||||
.hw_onecell_data = &g12a_audio_hw_onecell_data,
|
||||
.reset_offset = AUDIO_SW_RESET,
|
||||
.reset_num = 26,
|
||||
|
|
|
@ -125,6 +125,62 @@ const struct clk_ops meson_clk_triphase_ops = {
|
|||
};
|
||||
EXPORT_SYMBOL_GPL(meson_clk_triphase_ops);
|
||||
|
||||
/*
|
||||
* This is a special clock for the audio controller.
|
||||
* This drive a bit clock inverter for which the
|
||||
* opposite value of the inverter bit needs to be manually
|
||||
* set into another bit
|
||||
*/
|
||||
static inline struct meson_sclk_ws_inv_data *
|
||||
meson_sclk_ws_inv_data(struct clk_regmap *clk)
|
||||
{
|
||||
return (struct meson_sclk_ws_inv_data *)clk->data;
|
||||
}
|
||||
|
||||
static int meson_sclk_ws_inv_sync(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_regmap *clk = to_clk_regmap(hw);
|
||||
struct meson_sclk_ws_inv_data *tph = meson_sclk_ws_inv_data(clk);
|
||||
unsigned int val;
|
||||
|
||||
/* Get phase and sync the inverted value to ws */
|
||||
val = meson_parm_read(clk->map, &tph->ph);
|
||||
meson_parm_write(clk->map, &tph->ws, val ? 0 : 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int meson_sclk_ws_inv_get_phase(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_regmap *clk = to_clk_regmap(hw);
|
||||
struct meson_sclk_ws_inv_data *tph = meson_sclk_ws_inv_data(clk);
|
||||
unsigned int val;
|
||||
|
||||
val = meson_parm_read(clk->map, &tph->ph);
|
||||
|
||||
return meson_clk_degrees_from_val(val, tph->ph.width);
|
||||
}
|
||||
|
||||
static int meson_sclk_ws_inv_set_phase(struct clk_hw *hw, int degrees)
|
||||
{
|
||||
struct clk_regmap *clk = to_clk_regmap(hw);
|
||||
struct meson_sclk_ws_inv_data *tph = meson_sclk_ws_inv_data(clk);
|
||||
unsigned int val;
|
||||
|
||||
val = meson_clk_degrees_to_val(degrees, tph->ph.width);
|
||||
meson_parm_write(clk->map, &tph->ph, val);
|
||||
meson_parm_write(clk->map, &tph->ws, val ? 0 : 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct clk_ops meson_sclk_ws_inv_ops = {
|
||||
.init = meson_sclk_ws_inv_sync,
|
||||
.get_phase = meson_sclk_ws_inv_get_phase,
|
||||
.set_phase = meson_sclk_ws_inv_set_phase,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(meson_sclk_ws_inv_ops);
|
||||
|
||||
|
||||
MODULE_DESCRIPTION("Amlogic phase driver");
|
||||
MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
|
@ -20,7 +20,13 @@ struct meson_clk_triphase_data {
|
|||
struct parm ph2;
|
||||
};
|
||||
|
||||
struct meson_sclk_ws_inv_data {
|
||||
struct parm ph;
|
||||
struct parm ws;
|
||||
};
|
||||
|
||||
extern const struct clk_ops meson_clk_phase_ops;
|
||||
extern const struct clk_ops meson_clk_triphase_ops;
|
||||
extern const struct clk_ops meson_sclk_ws_inv_ops;
|
||||
|
||||
#endif /* __MESON_CLK_PHASE_H */
|
||||
|
|
|
@ -298,6 +298,17 @@ static struct clk_regmap g12a_fclk_div2 = {
|
|||
&g12a_fclk_div2_div.hw
|
||||
},
|
||||
.num_parents = 1,
|
||||
/*
|
||||
* Similar to fclk_div3, it seems that this clock is used by
|
||||
* the resident firmware and is required by the platform to
|
||||
* operate correctly.
|
||||
* Until the following condition are met, we need this clock to
|
||||
* be marked as critical:
|
||||
* a) Mark the clock used by a firmware resource, if possible
|
||||
* b) CCF has a clock hand-off mechanism to make the sure the
|
||||
* clock stays on until the proper driver comes along
|
||||
*/
|
||||
.flags = CLK_IS_CRITICAL,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -57,7 +57,7 @@ int meson_aoclkc_probe(struct platform_device *pdev)
|
|||
rstc->data = data;
|
||||
rstc->regmap = regmap;
|
||||
rstc->reset.ops = &meson_aoclk_reset_ops;
|
||||
rstc->reset.nr_resets = data->num_reset,
|
||||
rstc->reset.nr_resets = data->num_reset;
|
||||
rstc->reset.of_node = dev->of_node;
|
||||
ret = devm_reset_controller_register(dev, &rstc->reset);
|
||||
if (ret) {
|
||||
|
|
|
@ -347,9 +347,9 @@ static struct mmp_param_mux_clk mmp3_apmu_mux_clks[] = {
|
|||
};
|
||||
|
||||
static struct mmp_param_div_clk apmu_div_clks[] = {
|
||||
{0, "disp0_div", "disp0_mux", CLK_SET_RATE_PARENT, APMU_DISP0, 8, 4, 0, &disp0_lock},
|
||||
{0, "disp0_div", "disp0_mux", CLK_SET_RATE_PARENT, APMU_DISP0, 8, 4, CLK_DIVIDER_ONE_BASED, &disp0_lock},
|
||||
{0, "disp0_sphy_div", "disp0_mux", CLK_SET_RATE_PARENT, APMU_DISP0, 15, 5, 0, &disp0_lock},
|
||||
{0, "disp1_div", "disp1_mux", CLK_SET_RATE_PARENT, APMU_DISP1, 8, 4, 0, &disp1_lock},
|
||||
{0, "disp1_div", "disp1_mux", CLK_SET_RATE_PARENT, APMU_DISP1, 8, 4, CLK_DIVIDER_ONE_BASED, &disp1_lock},
|
||||
{0, "ccic0_sphy_div", "ccic0_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC0, 10, 5, 0, &ccic0_lock},
|
||||
{0, "ccic1_sphy_div", "ccic1_mix_clk", CLK_SET_RATE_PARENT, APMU_CCIC1, 10, 5, 0, &ccic1_lock},
|
||||
};
|
||||
|
|
|
@ -68,7 +68,6 @@ static struct mmp_clk_factor_tbl uart_factor_tbl[] = {
|
|||
|
||||
static void pxa1928_pll_init(struct pxa1928_clk_unit *pxa_unit)
|
||||
{
|
||||
struct clk *clk;
|
||||
struct mmp_clk_unit *unit = &pxa_unit->unit;
|
||||
|
||||
mmp_register_fixed_rate_clks(unit, fixed_rate_clks,
|
||||
|
@ -77,7 +76,7 @@ static void pxa1928_pll_init(struct pxa1928_clk_unit *pxa_unit)
|
|||
mmp_register_fixed_factor_clks(unit, fixed_factor_clks,
|
||||
ARRAY_SIZE(fixed_factor_clks));
|
||||
|
||||
clk = mmp_clk_register_factor("uart_pll", "pll1_416",
|
||||
mmp_clk_register_factor("uart_pll", "pll1_416",
|
||||
CLK_SET_RATE_PARENT,
|
||||
pxa_unit->mpmu_base + MPMU_UART_PLL,
|
||||
&uart_factor_masks, uart_factor_tbl,
|
||||
|
|
|
@ -197,7 +197,7 @@ static int ap_cpu_clk_set_rate(struct clk_hw *hw, unsigned long rate,
|
|||
|
||||
stable_bit = BIT(clk->pll_regs->ratio_state_offset +
|
||||
clk->cluster *
|
||||
clk->pll_regs->ratio_state_cluster_offset),
|
||||
clk->pll_regs->ratio_state_cluster_offset);
|
||||
ret = regmap_read_poll_timeout(clk->pll_cr_base,
|
||||
clk->pll_regs->ratio_state_reg, reg,
|
||||
reg & stable_bit, STATUS_POLL_PERIOD_US,
|
||||
|
|
|
@ -19,11 +19,11 @@
|
|||
#define MUX_RO_RATE_RO_OPS(name, clk_name) \
|
||||
static struct clk_hw name ## _mux_hw; \
|
||||
static struct clk_hw name ## _rate_hw; \
|
||||
static struct clk_ops name ## _mux_ops = { \
|
||||
static const struct clk_ops name ## _mux_ops = { \
|
||||
.get_parent = name ## _get_parent, \
|
||||
.set_parent = dummy_clk_set_parent, \
|
||||
}; \
|
||||
static struct clk_ops name ## _rate_ops = { \
|
||||
static const struct clk_ops name ## _rate_ops = { \
|
||||
.recalc_rate = name ## _get_rate, \
|
||||
}; \
|
||||
static struct clk * __init clk_register_ ## name(void) \
|
||||
|
@ -38,7 +38,7 @@
|
|||
|
||||
#define RATE_RO_OPS(name, clk_name) \
|
||||
static struct clk_hw name ## _rate_hw; \
|
||||
static const struct clk_ops name ## _rate_ops = { \
|
||||
static const struct clk_ops name ## _rate_ops = { \
|
||||
.recalc_rate = name ## _get_rate, \
|
||||
}; \
|
||||
static struct clk * __init clk_register_ ## name(void) \
|
||||
|
@ -53,7 +53,7 @@
|
|||
|
||||
#define RATE_OPS(name, clk_name) \
|
||||
static struct clk_hw name ## _rate_hw; \
|
||||
static struct clk_ops name ## _rate_ops = { \
|
||||
static const struct clk_ops name ## _rate_ops = { \
|
||||
.recalc_rate = name ## _get_rate, \
|
||||
.set_rate = name ## _set_rate, \
|
||||
.determine_rate = name ## _determine_rate, \
|
||||
|
|
|
@ -413,6 +413,15 @@ config SDM_LPASSCC_845
|
|||
Say Y if you want to use the LPASS branch clocks of the LPASS clock
|
||||
controller to reset the LPASS subsystem.
|
||||
|
||||
config SM_DISPCC_8250
|
||||
tristate "SM8150 and SM8250 Display Clock Controller"
|
||||
depends on SM_GCC_8150 || SM_GCC_8250
|
||||
help
|
||||
Support for the display clock controller on Qualcomm Technologies, Inc
|
||||
SM8150 and SM8250 devices.
|
||||
Say Y if you want to support display devices and functionality such as
|
||||
splash screen.
|
||||
|
||||
config SM_GCC_8150
|
||||
tristate "SM8150 Global Clock Controller"
|
||||
help
|
||||
|
@ -444,6 +453,24 @@ config SM_GPUCC_8250
|
|||
Say Y if you want to support graphics controller devices and
|
||||
functionality such as 3D graphics.
|
||||
|
||||
config SM_VIDEOCC_8150
|
||||
tristate "SM8150 Video Clock Controller"
|
||||
select SDM_GCC_8150
|
||||
select QCOM_GDSC
|
||||
help
|
||||
Support for the video clock controller on SM8150 devices.
|
||||
Say Y if you want to support video devices and functionality such as
|
||||
video encode and decode.
|
||||
|
||||
config SM_VIDEOCC_8250
|
||||
tristate "SM8250 Video Clock Controller"
|
||||
select SDM_GCC_8250
|
||||
select QCOM_GDSC
|
||||
help
|
||||
Support for the video clock controller on SM8250 devices.
|
||||
Say Y if you want to support video devices and functionality such as
|
||||
video encode and decode.
|
||||
|
||||
config SPMI_PMIC_CLKDIV
|
||||
tristate "SPMI PMIC clkdiv Support"
|
||||
depends on SPMI || COMPILE_TEST
|
||||
|
|
|
@ -64,10 +64,13 @@ obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o
|
|||
obj-$(CONFIG_SDM_GPUCC_845) += gpucc-sdm845.o
|
||||
obj-$(CONFIG_SDM_LPASSCC_845) += lpasscc-sdm845.o
|
||||
obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o
|
||||
obj-$(CONFIG_SM_DISPCC_8250) += dispcc-sm8250.o
|
||||
obj-$(CONFIG_SM_GCC_8150) += gcc-sm8150.o
|
||||
obj-$(CONFIG_SM_GCC_8250) += gcc-sm8250.o
|
||||
obj-$(CONFIG_SM_GPUCC_8150) += gpucc-sm8150.o
|
||||
obj-$(CONFIG_SM_GPUCC_8250) += gpucc-sm8250.o
|
||||
obj-$(CONFIG_SM_VIDEOCC_8150) += videocc-sm8150.o
|
||||
obj-$(CONFIG_SM_VIDEOCC_8250) += videocc-sm8250.o
|
||||
obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o
|
||||
obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o
|
||||
obj-$(CONFIG_QCOM_HFPLL) += hfpll.o
|
||||
|
|
|
@ -609,7 +609,7 @@ static unsigned long
|
|||
alpha_huayra_pll_calc_rate(u64 prate, u32 l, u32 a)
|
||||
{
|
||||
/*
|
||||
* a contains 16 bit alpha_val in two’s compliment number in the range
|
||||
* a contains 16 bit alpha_val in two’s complement number in the range
|
||||
* of [-0.5, 0.5).
|
||||
*/
|
||||
if (a >= BIT(PLL_HUAYRA_ALPHA_WIDTH - 1))
|
||||
|
@ -641,7 +641,7 @@ alpha_huayra_pll_round_rate(unsigned long rate, unsigned long prate,
|
|||
quotient++;
|
||||
|
||||
/*
|
||||
* alpha_val should be in two’s compliment number in the range
|
||||
* alpha_val should be in two’s complement number in the range
|
||||
* of [-0.5, 0.5) so if quotient >= 0.5 then increment the l value
|
||||
* since alpha value will be subtracted in this case.
|
||||
*/
|
||||
|
@ -666,7 +666,7 @@ alpha_pll_huayra_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
|
|||
regmap_read(pll->clkr.regmap, PLL_ALPHA_VAL(pll), &alpha);
|
||||
/*
|
||||
* Depending upon alpha_mode, it can be treated as M/N value or
|
||||
* as a two’s compliment number. When alpha_mode=1,
|
||||
* as a two’s complement number. When alpha_mode=1,
|
||||
* pll_alpha_val<15:8>=M and pll_apla_val<7:0>=N
|
||||
*
|
||||
* Fout=FIN*(L+(M/N))
|
||||
|
@ -674,12 +674,12 @@ alpha_pll_huayra_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
|
|||
* M is a signed number (-128 to 127) and N is unsigned
|
||||
* (0 to 255). M/N has to be within +/-0.5.
|
||||
*
|
||||
* When alpha_mode=0, it is a two’s compliment number in the
|
||||
* When alpha_mode=0, it is a two’s complement number in the
|
||||
* range [-0.5, 0.5).
|
||||
*
|
||||
* Fout=FIN*(L+(alpha_val)/2^16)
|
||||
*
|
||||
* where alpha_val is two’s compliment number.
|
||||
* where alpha_val is two’s complement number.
|
||||
*/
|
||||
if (!(ctl & PLL_ALPHA_MODE))
|
||||
return alpha_huayra_pll_calc_rate(rate, l, alpha);
|
||||
|
|
|
@ -1182,14 +1182,21 @@ static int clk_rcg2_dp_set_rate_and_parent(struct clk_hw *hw,
|
|||
static int clk_rcg2_dp_determine_rate(struct clk_hw *hw,
|
||||
struct clk_rate_request *req)
|
||||
{
|
||||
struct clk_rate_request parent_req = *req;
|
||||
int ret;
|
||||
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
|
||||
unsigned long num, den;
|
||||
u64 tmp;
|
||||
|
||||
ret = __clk_determine_rate(clk_hw_get_parent(hw), &parent_req);
|
||||
if (ret)
|
||||
return ret;
|
||||
/* Parent rate is a fixed phy link rate */
|
||||
rational_best_approximation(req->best_parent_rate, req->rate,
|
||||
GENMASK(rcg->mnd_width - 1, 0),
|
||||
GENMASK(rcg->mnd_width - 1, 0), &den, &num);
|
||||
|
||||
req->best_parent_rate = parent_req.rate;
|
||||
if (!num || !den)
|
||||
return -EINVAL;
|
||||
|
||||
tmp = req->best_parent_rate * num;
|
||||
do_div(tmp, den);
|
||||
req->rate = tmp;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -202,7 +202,6 @@ static struct clk_rcg2 disp_cc_mdss_dp_crypto_clk_src = {
|
|||
.name = "disp_cc_mdss_dp_crypto_clk_src",
|
||||
.parent_data = disp_cc_parent_data_1,
|
||||
.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_byte2_ops,
|
||||
},
|
||||
};
|
||||
|
@ -216,7 +215,6 @@ static struct clk_rcg2 disp_cc_mdss_dp_link_clk_src = {
|
|||
.name = "disp_cc_mdss_dp_link_clk_src",
|
||||
.parent_data = disp_cc_parent_data_1,
|
||||
.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_byte2_ops,
|
||||
},
|
||||
};
|
||||
|
@ -230,7 +228,6 @@ static struct clk_rcg2 disp_cc_mdss_dp_pixel_clk_src = {
|
|||
.name = "disp_cc_mdss_dp_pixel_clk_src",
|
||||
.parent_data = disp_cc_parent_data_1,
|
||||
.num_parents = ARRAY_SIZE(disp_cc_parent_data_1),
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_dp_ops,
|
||||
},
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -4322,7 +4322,7 @@ static const struct freq_tbl ftbl_pcie_rchng_clk_src[] = {
|
|||
{ }
|
||||
};
|
||||
|
||||
struct clk_rcg2 pcie0_rchng_clk_src = {
|
||||
static struct clk_rcg2 pcie0_rchng_clk_src = {
|
||||
.cmd_rcgr = 0x75070,
|
||||
.freq_tbl = ftbl_pcie_rchng_clk_src,
|
||||
.hid_width = 5,
|
||||
|
|
|
@ -595,24 +595,12 @@ static const struct clk_parent_data gcc_xo_gpll1_emclk_sleep_parent_data[] = {
|
|||
{ .fw_name = "sleep_clk", .name = "sleep_clk" },
|
||||
};
|
||||
|
||||
static const struct parent_map gcc_xo_gpll6_gpll0_map[] = {
|
||||
{ P_XO, 0 },
|
||||
{ P_GPLL6, 1 },
|
||||
{ P_GPLL0, 2 },
|
||||
};
|
||||
|
||||
static const struct clk_parent_data gcc_xo_gpll6_gpll0_parent_data[] = {
|
||||
{ .fw_name = "xo" },
|
||||
{ .hw = &gpll6_vote.hw },
|
||||
{ .hw = &gpll0_vote.hw },
|
||||
};
|
||||
|
||||
static const struct parent_map gcc_xo_gpll6_gpll0a_map[] = {
|
||||
{ P_XO, 0 },
|
||||
{ P_GPLL6, 1 },
|
||||
{ P_GPLL0_AUX, 2 },
|
||||
};
|
||||
|
||||
static const struct clk_parent_data gcc_xo_gpll6_gpll0a_parent_data[] = {
|
||||
{ .fw_name = "xo" },
|
||||
{ .hw = &gpll6_vote.hw },
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include "clk-rcg.h"
|
||||
#include "clk-branch.h"
|
||||
#include "reset.h"
|
||||
#include "gdsc.h"
|
||||
|
||||
enum {
|
||||
P_XO,
|
||||
|
@ -1772,6 +1773,32 @@ static struct clk_branch gcc_gp3_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_lpass_q6_axi_clk = {
|
||||
.halt_reg = 0x0280,
|
||||
.clkr = {
|
||||
.enable_reg = 0x0280,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data)
|
||||
{
|
||||
.name = "gcc_lpass_q6_axi_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_mss_q6_bimc_axi_clk = {
|
||||
.halt_reg = 0x0284,
|
||||
.clkr = {
|
||||
.enable_reg = 0x0284,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data)
|
||||
{
|
||||
.name = "gcc_mss_q6_bimc_axi_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_pcie_0_aux_clk = {
|
||||
.halt_reg = 0x1ad4,
|
||||
.clkr = {
|
||||
|
@ -1790,6 +1817,32 @@ static struct clk_branch gcc_pcie_0_aux_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_pcie_0_cfg_ahb_clk = {
|
||||
.halt_reg = 0x1ad0,
|
||||
.clkr = {
|
||||
.enable_reg = 0x1ad0,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data)
|
||||
{
|
||||
.name = "gcc_pcie_0_cfg_ahb_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_pcie_0_mstr_axi_clk = {
|
||||
.halt_reg = 0x1acc,
|
||||
.clkr = {
|
||||
.enable_reg = 0x1acc,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data)
|
||||
{
|
||||
.name = "gcc_pcie_0_mstr_axi_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_pcie_0_pipe_clk = {
|
||||
.halt_reg = 0x1ad8,
|
||||
.halt_check = BRANCH_HALT_DELAY,
|
||||
|
@ -1809,6 +1862,20 @@ static struct clk_branch gcc_pcie_0_pipe_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_pcie_0_slv_axi_clk = {
|
||||
.halt_reg = 0x1ac8,
|
||||
.halt_check = BRANCH_HALT_DELAY,
|
||||
.clkr = {
|
||||
.enable_reg = 0x1ac8,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data)
|
||||
{
|
||||
.name = "gcc_pcie_0_slv_axi_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_pcie_1_aux_clk = {
|
||||
.halt_reg = 0x1b54,
|
||||
.clkr = {
|
||||
|
@ -1827,6 +1894,32 @@ static struct clk_branch gcc_pcie_1_aux_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_pcie_1_cfg_ahb_clk = {
|
||||
.halt_reg = 0x1b54,
|
||||
.clkr = {
|
||||
.enable_reg = 0x1b54,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data)
|
||||
{
|
||||
.name = "gcc_pcie_1_cfg_ahb_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_pcie_1_mstr_axi_clk = {
|
||||
.halt_reg = 0x1b50,
|
||||
.clkr = {
|
||||
.enable_reg = 0x1b50,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data)
|
||||
{
|
||||
.name = "gcc_pcie_1_mstr_axi_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_pcie_1_pipe_clk = {
|
||||
.halt_reg = 0x1b58,
|
||||
.halt_check = BRANCH_HALT_DELAY,
|
||||
|
@ -1846,6 +1939,19 @@ static struct clk_branch gcc_pcie_1_pipe_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_pcie_1_slv_axi_clk = {
|
||||
.halt_reg = 0x1b48,
|
||||
.clkr = {
|
||||
.enable_reg = 0x1b48,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data)
|
||||
{
|
||||
.name = "gcc_pcie_1_slv_axi_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_pdm2_clk = {
|
||||
.halt_reg = 0x0ccc,
|
||||
.clkr = {
|
||||
|
@ -1864,6 +1970,19 @@ static struct clk_branch gcc_pdm2_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_pdm_ahb_clk = {
|
||||
.halt_reg = 0x0cc4,
|
||||
.clkr = {
|
||||
.enable_reg = 0x0cc4,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data)
|
||||
{
|
||||
.name = "gcc_pdm_ahb_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_sdcc1_apps_clk = {
|
||||
.halt_reg = 0x04c4,
|
||||
.clkr = {
|
||||
|
@ -1899,6 +2018,23 @@ static struct clk_branch gcc_sdcc1_ahb_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_sdcc2_ahb_clk = {
|
||||
.halt_reg = 0x0508,
|
||||
.clkr = {
|
||||
.enable_reg = 0x0508,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data)
|
||||
{
|
||||
.name = "gcc_sdcc2_ahb_clk",
|
||||
.parent_names = (const char *[]){
|
||||
"periph_noc_clk_src",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_sdcc2_apps_clk = {
|
||||
.halt_reg = 0x0504,
|
||||
.clkr = {
|
||||
|
@ -1917,6 +2053,23 @@ static struct clk_branch gcc_sdcc2_apps_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_sdcc3_ahb_clk = {
|
||||
.halt_reg = 0x0548,
|
||||
.clkr = {
|
||||
.enable_reg = 0x0548,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data)
|
||||
{
|
||||
.name = "gcc_sdcc3_ahb_clk",
|
||||
.parent_names = (const char *[]){
|
||||
"periph_noc_clk_src",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_sdcc3_apps_clk = {
|
||||
.halt_reg = 0x0544,
|
||||
.clkr = {
|
||||
|
@ -1935,6 +2088,23 @@ static struct clk_branch gcc_sdcc3_apps_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_sdcc4_ahb_clk = {
|
||||
.halt_reg = 0x0588,
|
||||
.clkr = {
|
||||
.enable_reg = 0x0588,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data)
|
||||
{
|
||||
.name = "gcc_sdcc4_ahb_clk",
|
||||
.parent_names = (const char *[]){
|
||||
"periph_noc_clk_src",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_sdcc4_apps_clk = {
|
||||
.halt_reg = 0x0584,
|
||||
.clkr = {
|
||||
|
@ -1989,6 +2159,19 @@ static struct clk_branch gcc_sys_noc_usb3_axi_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_tsif_ahb_clk = {
|
||||
.halt_reg = 0x0d84,
|
||||
.clkr = {
|
||||
.enable_reg = 0x0d84,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data)
|
||||
{
|
||||
.name = "gcc_tsif_ahb_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_tsif_ref_clk = {
|
||||
.halt_reg = 0x0d88,
|
||||
.clkr = {
|
||||
|
@ -2007,6 +2190,19 @@ static struct clk_branch gcc_tsif_ref_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_ufs_ahb_clk = {
|
||||
.halt_reg = 0x1d4c,
|
||||
.clkr = {
|
||||
.enable_reg = 0x1d4c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data)
|
||||
{
|
||||
.name = "gcc_ufs_ahb_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_ufs_axi_clk = {
|
||||
.halt_reg = 0x1d48,
|
||||
.clkr = {
|
||||
|
@ -2043,6 +2239,34 @@ static struct clk_branch gcc_ufs_rx_cfg_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_ufs_rx_symbol_0_clk = {
|
||||
.halt_reg = 0x1d60,
|
||||
.halt_check = BRANCH_HALT_DELAY,
|
||||
.clkr = {
|
||||
.enable_reg = 0x1d60,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data)
|
||||
{
|
||||
.name = "gcc_ufs_rx_symbol_0_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_ufs_rx_symbol_1_clk = {
|
||||
.halt_reg = 0x1d64,
|
||||
.halt_check = BRANCH_HALT_DELAY,
|
||||
.clkr = {
|
||||
.enable_reg = 0x1d64,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data)
|
||||
{
|
||||
.name = "gcc_ufs_rx_symbol_1_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_ufs_tx_cfg_clk = {
|
||||
.halt_reg = 0x1d50,
|
||||
.clkr = {
|
||||
|
@ -2061,6 +2285,47 @@ static struct clk_branch gcc_ufs_tx_cfg_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_ufs_tx_symbol_0_clk = {
|
||||
.halt_reg = 0x1d58,
|
||||
.halt_check = BRANCH_HALT_DELAY,
|
||||
.clkr = {
|
||||
.enable_reg = 0x1d58,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data)
|
||||
{
|
||||
.name = "gcc_ufs_tx_symbol_0_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_ufs_tx_symbol_1_clk = {
|
||||
.halt_reg = 0x1d5c,
|
||||
.halt_check = BRANCH_HALT_DELAY,
|
||||
.clkr = {
|
||||
.enable_reg = 0x1d5c,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data)
|
||||
{
|
||||
.name = "gcc_ufs_tx_symbol_1_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_usb2_hs_phy_sleep_clk = {
|
||||
.halt_reg = 0x04ac,
|
||||
.clkr = {
|
||||
.enable_reg = 0x04ac,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data)
|
||||
{
|
||||
.name = "gcc_usb2_hs_phy_sleep_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_usb30_master_clk = {
|
||||
.halt_reg = 0x03c8,
|
||||
.clkr = {
|
||||
|
@ -2097,6 +2362,19 @@ static struct clk_branch gcc_usb30_mock_utmi_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_usb30_sleep_clk = {
|
||||
.halt_reg = 0x03cc,
|
||||
.clkr = {
|
||||
.enable_reg = 0x03cc,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data)
|
||||
{
|
||||
.name = "gcc_usb30_sleep_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_usb3_phy_aux_clk = {
|
||||
.halt_reg = 0x1408,
|
||||
.clkr = {
|
||||
|
@ -2115,6 +2393,19 @@ static struct clk_branch gcc_usb3_phy_aux_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_usb_hs_ahb_clk = {
|
||||
.halt_reg = 0x0488,
|
||||
.clkr = {
|
||||
.enable_reg = 0x0488,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data)
|
||||
{
|
||||
.name = "gcc_usb_hs_ahb_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_usb_hs_system_clk = {
|
||||
.halt_reg = 0x0484,
|
||||
.clkr = {
|
||||
|
@ -2133,6 +2424,59 @@ static struct clk_branch gcc_usb_hs_system_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_branch gcc_usb_phy_cfg_ahb2phy_clk = {
|
||||
.halt_reg = 0x1a84,
|
||||
.clkr = {
|
||||
.enable_reg = 0x1a84,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data)
|
||||
{
|
||||
.name = "gcc_usb_phy_cfg_ahb2phy_clk",
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct gdsc pcie_gdsc = {
|
||||
.gdscr = 0x1e18,
|
||||
.pd = {
|
||||
.name = "pcie",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
static struct gdsc pcie_0_gdsc = {
|
||||
.gdscr = 0x1ac4,
|
||||
.pd = {
|
||||
.name = "pcie_0",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
static struct gdsc pcie_1_gdsc = {
|
||||
.gdscr = 0x1b44,
|
||||
.pd = {
|
||||
.name = "pcie_1",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
static struct gdsc usb30_gdsc = {
|
||||
.gdscr = 0x3c4,
|
||||
.pd = {
|
||||
.name = "usb30",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
static struct gdsc ufs_gdsc = {
|
||||
.gdscr = 0x1d44,
|
||||
.pd = {
|
||||
.name = "ufs",
|
||||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
static struct clk_regmap *gcc_msm8994_clocks[] = {
|
||||
[GPLL0_EARLY] = &gpll0_early.clkr,
|
||||
[GPLL0] = &gpll0.clkr,
|
||||
|
@ -2233,26 +2577,64 @@ static struct clk_regmap *gcc_msm8994_clocks[] = {
|
|||
[GCC_GP1_CLK] = &gcc_gp1_clk.clkr,
|
||||
[GCC_GP2_CLK] = &gcc_gp2_clk.clkr,
|
||||
[GCC_GP3_CLK] = &gcc_gp3_clk.clkr,
|
||||
[GCC_LPASS_Q6_AXI_CLK] = &gcc_lpass_q6_axi_clk.clkr,
|
||||
[GCC_MSS_Q6_BIMC_AXI_CLK] = &gcc_mss_q6_bimc_axi_clk.clkr,
|
||||
[GCC_PCIE_0_AUX_CLK] = &gcc_pcie_0_aux_clk.clkr,
|
||||
[GCC_PCIE_0_CFG_AHB_CLK] = &gcc_pcie_0_cfg_ahb_clk.clkr,
|
||||
[GCC_PCIE_0_MSTR_AXI_CLK] = &gcc_pcie_0_mstr_axi_clk.clkr,
|
||||
[GCC_PCIE_0_PIPE_CLK] = &gcc_pcie_0_pipe_clk.clkr,
|
||||
[GCC_PCIE_0_SLV_AXI_CLK] = &gcc_pcie_0_slv_axi_clk.clkr,
|
||||
[GCC_PCIE_1_AUX_CLK] = &gcc_pcie_1_aux_clk.clkr,
|
||||
[GCC_PCIE_1_CFG_AHB_CLK] = &gcc_pcie_1_cfg_ahb_clk.clkr,
|
||||
[GCC_PCIE_1_MSTR_AXI_CLK] = &gcc_pcie_1_mstr_axi_clk.clkr,
|
||||
[GCC_PCIE_1_PIPE_CLK] = &gcc_pcie_1_pipe_clk.clkr,
|
||||
[GCC_PCIE_1_SLV_AXI_CLK] = &gcc_pcie_1_slv_axi_clk.clkr,
|
||||
[GCC_PDM2_CLK] = &gcc_pdm2_clk.clkr,
|
||||
[GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr,
|
||||
[GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr,
|
||||
[GCC_SDCC3_APPS_CLK] = &gcc_sdcc3_apps_clk.clkr,
|
||||
[GCC_SDCC4_APPS_CLK] = &gcc_sdcc4_apps_clk.clkr,
|
||||
[GCC_PDM_AHB_CLK] = &gcc_pdm_ahb_clk.clkr,
|
||||
[GCC_SDCC1_AHB_CLK] = &gcc_sdcc1_ahb_clk.clkr,
|
||||
[GCC_SDCC1_APPS_CLK] = &gcc_sdcc1_apps_clk.clkr,
|
||||
[GCC_SDCC2_AHB_CLK] = &gcc_sdcc2_ahb_clk.clkr,
|
||||
[GCC_SDCC2_APPS_CLK] = &gcc_sdcc2_apps_clk.clkr,
|
||||
[GCC_SDCC3_AHB_CLK] = &gcc_sdcc3_ahb_clk.clkr,
|
||||
[GCC_SDCC3_APPS_CLK] = &gcc_sdcc3_apps_clk.clkr,
|
||||
[GCC_SDCC4_AHB_CLK] = &gcc_sdcc4_ahb_clk.clkr,
|
||||
[GCC_SDCC4_APPS_CLK] = &gcc_sdcc4_apps_clk.clkr,
|
||||
[GCC_SYS_NOC_UFS_AXI_CLK] = &gcc_sys_noc_ufs_axi_clk.clkr,
|
||||
[GCC_SYS_NOC_USB3_AXI_CLK] = &gcc_sys_noc_usb3_axi_clk.clkr,
|
||||
[GCC_TSIF_AHB_CLK] = &gcc_tsif_ahb_clk.clkr,
|
||||
[GCC_TSIF_REF_CLK] = &gcc_tsif_ref_clk.clkr,
|
||||
[GCC_UFS_AHB_CLK] = &gcc_ufs_ahb_clk.clkr,
|
||||
[GCC_UFS_AXI_CLK] = &gcc_ufs_axi_clk.clkr,
|
||||
[GCC_UFS_RX_CFG_CLK] = &gcc_ufs_rx_cfg_clk.clkr,
|
||||
[GCC_UFS_RX_SYMBOL_0_CLK] = &gcc_ufs_rx_symbol_0_clk.clkr,
|
||||
[GCC_UFS_RX_SYMBOL_1_CLK] = &gcc_ufs_rx_symbol_1_clk.clkr,
|
||||
[GCC_UFS_TX_CFG_CLK] = &gcc_ufs_tx_cfg_clk.clkr,
|
||||
[GCC_UFS_TX_SYMBOL_0_CLK] = &gcc_ufs_tx_symbol_0_clk.clkr,
|
||||
[GCC_UFS_TX_SYMBOL_1_CLK] = &gcc_ufs_tx_symbol_1_clk.clkr,
|
||||
[GCC_USB2_HS_PHY_SLEEP_CLK] = &gcc_usb2_hs_phy_sleep_clk.clkr,
|
||||
[GCC_USB30_MASTER_CLK] = &gcc_usb30_master_clk.clkr,
|
||||
[GCC_USB30_MOCK_UTMI_CLK] = &gcc_usb30_mock_utmi_clk.clkr,
|
||||
[GCC_USB30_SLEEP_CLK] = &gcc_usb30_sleep_clk.clkr,
|
||||
[GCC_USB3_PHY_AUX_CLK] = &gcc_usb3_phy_aux_clk.clkr,
|
||||
[GCC_USB_HS_AHB_CLK] = &gcc_usb_hs_ahb_clk.clkr,
|
||||
[GCC_USB_HS_SYSTEM_CLK] = &gcc_usb_hs_system_clk.clkr,
|
||||
[GCC_USB_PHY_CFG_AHB2PHY_CLK] = &gcc_usb_phy_cfg_ahb2phy_clk.clkr,
|
||||
};
|
||||
|
||||
static struct gdsc *gcc_msm8994_gdscs[] = {
|
||||
[PCIE_GDSC] = &pcie_gdsc,
|
||||
[PCIE_0_GDSC] = &pcie_0_gdsc,
|
||||
[PCIE_1_GDSC] = &pcie_1_gdsc,
|
||||
[USB30_GDSC] = &usb30_gdsc,
|
||||
[UFS_GDSC] = &ufs_gdsc,
|
||||
};
|
||||
|
||||
static const struct qcom_reset_map gcc_msm8994_resets[] = {
|
||||
[USB3_PHY_RESET] = { 0x1400 },
|
||||
[USB3PHY_PHY_RESET] = { 0x1404 },
|
||||
[PCIE_PHY_0_RESET] = { 0x1b18 },
|
||||
[PCIE_PHY_1_RESET] = { 0x1b98 },
|
||||
[QUSB2_PHY_RESET] = { 0x04b8 },
|
||||
};
|
||||
|
||||
static const struct regmap_config gcc_msm8994_regmap_config = {
|
||||
|
@ -2267,6 +2649,10 @@ static const struct qcom_cc_desc gcc_msm8994_desc = {
|
|||
.config = &gcc_msm8994_regmap_config,
|
||||
.clks = gcc_msm8994_clocks,
|
||||
.num_clks = ARRAY_SIZE(gcc_msm8994_clocks),
|
||||
.resets = gcc_msm8994_resets,
|
||||
.num_resets = ARRAY_SIZE(gcc_msm8994_resets),
|
||||
.gdscs = gcc_msm8994_gdscs,
|
||||
.num_gdscs = ARRAY_SIZE(gcc_msm8994_gdscs),
|
||||
};
|
||||
|
||||
static const struct of_device_id gcc_msm8994_match_table[] = {
|
||||
|
|
|
@ -666,7 +666,7 @@ static struct clk_rcg2 hmss_rbcpr_clk_src = {
|
|||
.cmd_rcgr = 0x48044,
|
||||
.mnd_width = 0,
|
||||
.hid_width = 5,
|
||||
.parent_map = gcc_parent_map_xo_gpll0_gpll0_early_div,
|
||||
.parent_map = gcc_parent_map_xo_gpll0,
|
||||
.freq_tbl = ftbl_hmss_rbcpr_clk_src,
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "hmss_rbcpr_clk_src",
|
||||
|
|
|
@ -358,6 +358,14 @@ static int gdsc_init(struct gdsc *sc)
|
|||
if ((sc->flags & VOTABLE) && on)
|
||||
gdsc_enable(&sc->pd);
|
||||
|
||||
/*
|
||||
* Make sure the retain bit is set if the GDSC is already on, otherwise
|
||||
* we end up turning off the GDSC and destroying all the register
|
||||
* contents that we thought we were saving.
|
||||
*/
|
||||
if ((sc->flags & RETAIN_FF_ENABLE) && on)
|
||||
gdsc_retain_ff_on(sc);
|
||||
|
||||
/* If ALWAYS_ON GDSCs are not ON, turn them ON */
|
||||
if (sc->flags & ALWAYS_ON) {
|
||||
if (!on)
|
||||
|
|
|
@ -0,0 +1,276 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include <dt-bindings/clock/qcom,videocc-sm8150.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "clk-alpha-pll.h"
|
||||
#include "clk-branch.h"
|
||||
#include "clk-rcg.h"
|
||||
#include "clk-regmap.h"
|
||||
#include "reset.h"
|
||||
#include "gdsc.h"
|
||||
|
||||
enum {
|
||||
P_BI_TCXO,
|
||||
P_CHIP_SLEEP_CLK,
|
||||
P_CORE_BI_PLL_TEST_SE,
|
||||
P_VIDEO_PLL0_OUT_EVEN,
|
||||
P_VIDEO_PLL0_OUT_MAIN,
|
||||
P_VIDEO_PLL0_OUT_ODD,
|
||||
};
|
||||
|
||||
static struct pll_vco trion_vco[] = {
|
||||
{ 249600000, 2000000000, 0 },
|
||||
};
|
||||
|
||||
static struct alpha_pll_config video_pll0_config = {
|
||||
.l = 0x14,
|
||||
.alpha = 0xD555,
|
||||
.config_ctl_val = 0x20485699,
|
||||
.config_ctl_hi_val = 0x00002267,
|
||||
.config_ctl_hi1_val = 0x00000024,
|
||||
.user_ctl_val = 0x00000000,
|
||||
.user_ctl_hi_val = 0x00000805,
|
||||
.user_ctl_hi1_val = 0x000000D0,
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll video_pll0 = {
|
||||
.offset = 0x42c,
|
||||
.vco_table = trion_vco,
|
||||
.num_vco = ARRAY_SIZE(trion_vco),
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_TRION],
|
||||
.clkr = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "video_pll0",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.fw_name = "bi_tcxo",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_trion_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static const struct parent_map video_cc_parent_map_0[] = {
|
||||
{ P_BI_TCXO, 0 },
|
||||
{ P_VIDEO_PLL0_OUT_MAIN, 1 },
|
||||
};
|
||||
|
||||
static const struct clk_parent_data video_cc_parent_data_0[] = {
|
||||
{ .fw_name = "bi_tcxo" },
|
||||
{ .hw = &video_pll0.clkr.hw },
|
||||
};
|
||||
|
||||
static const struct freq_tbl ftbl_video_cc_iris_clk_src[] = {
|
||||
F(19200000, P_BI_TCXO, 1, 0, 0),
|
||||
F(200000000, P_VIDEO_PLL0_OUT_MAIN, 2, 0, 0),
|
||||
F(240000000, P_VIDEO_PLL0_OUT_MAIN, 2, 0, 0),
|
||||
F(338000000, P_VIDEO_PLL0_OUT_MAIN, 2, 0, 0),
|
||||
F(365000000, P_VIDEO_PLL0_OUT_MAIN, 2, 0, 0),
|
||||
F(444000000, P_VIDEO_PLL0_OUT_MAIN, 2, 0, 0),
|
||||
F(533000000, P_VIDEO_PLL0_OUT_MAIN, 2, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk_rcg2 video_cc_iris_clk_src = {
|
||||
.cmd_rcgr = 0x7f0,
|
||||
.mnd_width = 0,
|
||||
.hid_width = 5,
|
||||
.parent_map = video_cc_parent_map_0,
|
||||
.freq_tbl = ftbl_video_cc_iris_clk_src,
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "video_cc_iris_clk_src",
|
||||
.parent_data = video_cc_parent_data_0,
|
||||
.num_parents = ARRAY_SIZE(video_cc_parent_data_0),
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_rcg2_shared_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch video_cc_iris_ahb_clk = {
|
||||
.halt_reg = 0x8f4,
|
||||
.halt_check = BRANCH_VOTED,
|
||||
.clkr = {
|
||||
.enable_reg = 0x8f4,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "video_cc_iris_ahb_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &video_cc_iris_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch video_cc_mvs0_core_clk = {
|
||||
.halt_reg = 0x890,
|
||||
.halt_check = BRANCH_VOTED,
|
||||
.clkr = {
|
||||
.enable_reg = 0x890,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "video_cc_mvs0_core_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &video_cc_iris_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch video_cc_mvs1_core_clk = {
|
||||
.halt_reg = 0x8d0,
|
||||
.halt_check = BRANCH_VOTED,
|
||||
.clkr = {
|
||||
.enable_reg = 0x8d0,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "video_cc_mvs1_core_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &video_cc_iris_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch video_cc_mvsc_core_clk = {
|
||||
.halt_reg = 0x850,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0x850,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "video_cc_mvsc_core_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &video_cc_iris_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct gdsc venus_gdsc = {
|
||||
.gdscr = 0x814,
|
||||
.pd = {
|
||||
.name = "venus_gdsc",
|
||||
},
|
||||
.flags = 0,
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
static struct gdsc vcodec0_gdsc = {
|
||||
.gdscr = 0x874,
|
||||
.pd = {
|
||||
.name = "vcodec0_gdsc",
|
||||
},
|
||||
.flags = HW_CTRL,
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
static struct gdsc vcodec1_gdsc = {
|
||||
.gdscr = 0x8b4,
|
||||
.pd = {
|
||||
.name = "vcodec1_gdsc",
|
||||
},
|
||||
.flags = HW_CTRL,
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
static struct clk_regmap *video_cc_sm8150_clocks[] = {
|
||||
[VIDEO_CC_IRIS_AHB_CLK] = &video_cc_iris_ahb_clk.clkr,
|
||||
[VIDEO_CC_IRIS_CLK_SRC] = &video_cc_iris_clk_src.clkr,
|
||||
[VIDEO_CC_MVS0_CORE_CLK] = &video_cc_mvs0_core_clk.clkr,
|
||||
[VIDEO_CC_MVS1_CORE_CLK] = &video_cc_mvs1_core_clk.clkr,
|
||||
[VIDEO_CC_MVSC_CORE_CLK] = &video_cc_mvsc_core_clk.clkr,
|
||||
[VIDEO_CC_PLL0] = &video_pll0.clkr,
|
||||
};
|
||||
|
||||
static struct gdsc *video_cc_sm8150_gdscs[] = {
|
||||
[VENUS_GDSC] = &venus_gdsc,
|
||||
[VCODEC0_GDSC] = &vcodec0_gdsc,
|
||||
[VCODEC1_GDSC] = &vcodec1_gdsc,
|
||||
};
|
||||
|
||||
static const struct regmap_config video_cc_sm8150_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0xb94,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static const struct qcom_reset_map video_cc_sm8150_resets[] = {
|
||||
[VIDEO_CC_MVSC_CORE_CLK_BCR] = { 0x850, 2 },
|
||||
};
|
||||
|
||||
static const struct qcom_cc_desc video_cc_sm8150_desc = {
|
||||
.config = &video_cc_sm8150_regmap_config,
|
||||
.clks = video_cc_sm8150_clocks,
|
||||
.num_clks = ARRAY_SIZE(video_cc_sm8150_clocks),
|
||||
.resets = video_cc_sm8150_resets,
|
||||
.num_resets = ARRAY_SIZE(video_cc_sm8150_resets),
|
||||
.gdscs = video_cc_sm8150_gdscs,
|
||||
.num_gdscs = ARRAY_SIZE(video_cc_sm8150_gdscs),
|
||||
};
|
||||
|
||||
static const struct of_device_id video_cc_sm8150_match_table[] = {
|
||||
{ .compatible = "qcom,sm8150-videocc" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, video_cc_sm8150_match_table);
|
||||
|
||||
static int video_cc_sm8150_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct regmap *regmap;
|
||||
|
||||
regmap = qcom_cc_map(pdev, &video_cc_sm8150_desc);
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
|
||||
clk_trion_pll_configure(&video_pll0, regmap, &video_pll0_config);
|
||||
|
||||
/* Keep VIDEO_CC_XO_CLK ALWAYS-ON */
|
||||
regmap_update_bits(regmap, 0x984, 0x1, 0x1);
|
||||
|
||||
return qcom_cc_really_probe(pdev, &video_cc_sm8150_desc, regmap);
|
||||
}
|
||||
|
||||
static struct platform_driver video_cc_sm8150_driver = {
|
||||
.probe = video_cc_sm8150_probe,
|
||||
.driver = {
|
||||
.name = "video_cc-sm8150",
|
||||
.of_match_table = video_cc_sm8150_match_table,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init video_cc_sm8150_init(void)
|
||||
{
|
||||
return platform_driver_register(&video_cc_sm8150_driver);
|
||||
}
|
||||
subsys_initcall(video_cc_sm8150_init);
|
||||
|
||||
static void __exit video_cc_sm8150_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&video_cc_sm8150_driver);
|
||||
}
|
||||
module_exit(video_cc_sm8150_exit);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION("QTI VIDEOCC SM8150 Driver");
|
|
@ -0,0 +1,369 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2018-2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include <dt-bindings/clock/qcom,videocc-sm8250.h>
|
||||
|
||||
#include "clk-alpha-pll.h"
|
||||
#include "clk-branch.h"
|
||||
#include "clk-rcg.h"
|
||||
#include "clk-regmap.h"
|
||||
#include "clk-regmap-divider.h"
|
||||
#include "common.h"
|
||||
#include "reset.h"
|
||||
#include "gdsc.h"
|
||||
|
||||
enum {
|
||||
P_BI_TCXO,
|
||||
P_CHIP_SLEEP_CLK,
|
||||
P_CORE_BI_PLL_TEST_SE,
|
||||
P_VIDEO_PLL0_OUT_MAIN,
|
||||
P_VIDEO_PLL1_OUT_MAIN,
|
||||
};
|
||||
|
||||
static struct pll_vco lucid_vco[] = {
|
||||
{ 249600000, 2000000000, 0 },
|
||||
};
|
||||
|
||||
static const struct alpha_pll_config video_pll0_config = {
|
||||
.l = 0x25,
|
||||
.alpha = 0x8000,
|
||||
.config_ctl_val = 0x20485699,
|
||||
.config_ctl_hi_val = 0x00002261,
|
||||
.config_ctl_hi1_val = 0x329A699C,
|
||||
.user_ctl_val = 0x00000000,
|
||||
.user_ctl_hi_val = 0x00000805,
|
||||
.user_ctl_hi1_val = 0x00000000,
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll video_pll0 = {
|
||||
.offset = 0x42c,
|
||||
.vco_table = lucid_vco,
|
||||
.num_vco = ARRAY_SIZE(lucid_vco),
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],
|
||||
.clkr = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "video_pll0",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.fw_name = "bi_tcxo",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_lucid_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static const struct alpha_pll_config video_pll1_config = {
|
||||
.l = 0x2B,
|
||||
.alpha = 0xC000,
|
||||
.config_ctl_val = 0x20485699,
|
||||
.config_ctl_hi_val = 0x00002261,
|
||||
.config_ctl_hi1_val = 0x329A699C,
|
||||
.user_ctl_val = 0x00000000,
|
||||
.user_ctl_hi_val = 0x00000805,
|
||||
.user_ctl_hi1_val = 0x00000000,
|
||||
};
|
||||
|
||||
static struct clk_alpha_pll video_pll1 = {
|
||||
.offset = 0x7d0,
|
||||
.vco_table = lucid_vco,
|
||||
.num_vco = ARRAY_SIZE(lucid_vco),
|
||||
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_LUCID],
|
||||
.clkr = {
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "video_pll1",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.fw_name = "bi_tcxo",
|
||||
},
|
||||
.num_parents = 1,
|
||||
.ops = &clk_alpha_pll_lucid_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static const struct parent_map video_cc_parent_map_1[] = {
|
||||
{ P_BI_TCXO, 0 },
|
||||
{ P_VIDEO_PLL0_OUT_MAIN, 1 },
|
||||
};
|
||||
|
||||
static const struct clk_parent_data video_cc_parent_data_1[] = {
|
||||
{ .fw_name = "bi_tcxo" },
|
||||
{ .hw = &video_pll0.clkr.hw },
|
||||
};
|
||||
|
||||
static const struct parent_map video_cc_parent_map_2[] = {
|
||||
{ P_BI_TCXO, 0 },
|
||||
{ P_VIDEO_PLL1_OUT_MAIN, 1 },
|
||||
};
|
||||
|
||||
static const struct clk_parent_data video_cc_parent_data_2[] = {
|
||||
{ .fw_name = "bi_tcxo" },
|
||||
{ .hw = &video_pll1.clkr.hw },
|
||||
};
|
||||
|
||||
static const struct freq_tbl ftbl_video_cc_mvs0_clk_src[] = {
|
||||
F(19200000, P_BI_TCXO, 1, 0, 0),
|
||||
F(720000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0),
|
||||
F(1014000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0),
|
||||
F(1098000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0),
|
||||
F(1332000000, P_VIDEO_PLL0_OUT_MAIN, 1, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk_rcg2 video_cc_mvs0_clk_src = {
|
||||
.cmd_rcgr = 0xb94,
|
||||
.mnd_width = 0,
|
||||
.hid_width = 5,
|
||||
.parent_map = video_cc_parent_map_1,
|
||||
.freq_tbl = ftbl_video_cc_mvs0_clk_src,
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "video_cc_mvs0_clk_src",
|
||||
.parent_data = video_cc_parent_data_1,
|
||||
.num_parents = ARRAY_SIZE(video_cc_parent_data_1),
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_rcg2_shared_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static const struct freq_tbl ftbl_video_cc_mvs1_clk_src[] = {
|
||||
F(19200000, P_BI_TCXO, 1, 0, 0),
|
||||
F(840000000, P_VIDEO_PLL1_OUT_MAIN, 1, 0, 0),
|
||||
F(1098000000, P_VIDEO_PLL1_OUT_MAIN, 1, 0, 0),
|
||||
F(1332000000, P_VIDEO_PLL1_OUT_MAIN, 1, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
static struct clk_rcg2 video_cc_mvs1_clk_src = {
|
||||
.cmd_rcgr = 0xbb4,
|
||||
.mnd_width = 0,
|
||||
.hid_width = 5,
|
||||
.parent_map = video_cc_parent_map_2,
|
||||
.freq_tbl = ftbl_video_cc_mvs1_clk_src,
|
||||
.clkr.hw.init = &(struct clk_init_data){
|
||||
.name = "video_cc_mvs1_clk_src",
|
||||
.parent_data = video_cc_parent_data_2,
|
||||
.num_parents = ARRAY_SIZE(video_cc_parent_data_2),
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_rcg2_shared_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap_div video_cc_mvs0c_div2_div_clk_src = {
|
||||
.reg = 0xc54,
|
||||
.shift = 0,
|
||||
.width = 2,
|
||||
.clkr.hw.init = &(struct clk_init_data) {
|
||||
.name = "video_cc_mvs0c_div2_div_clk_src",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &video_cc_mvs0_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_regmap_div_ro_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap_div video_cc_mvs1c_div2_div_clk_src = {
|
||||
.reg = 0xcf4,
|
||||
.shift = 0,
|
||||
.width = 2,
|
||||
.clkr.hw.init = &(struct clk_init_data) {
|
||||
.name = "video_cc_mvs1c_div2_div_clk_src",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &video_cc_mvs1_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_regmap_div_ro_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch video_cc_mvs0c_clk = {
|
||||
.halt_reg = 0xc34,
|
||||
.halt_check = BRANCH_HALT,
|
||||
.clkr = {
|
||||
.enable_reg = 0xc34,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "video_cc_mvs0c_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &video_cc_mvs0c_div2_div_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch video_cc_mvs1_div2_clk = {
|
||||
.halt_reg = 0xdf4,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.clkr = {
|
||||
.enable_reg = 0xdf4,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "video_cc_mvs1_div2_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &video_cc_mvs1c_div2_div_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch video_cc_mvs1c_clk = {
|
||||
.halt_reg = 0xcd4,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.clkr = {
|
||||
.enable_reg = 0xcd4,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "video_cc_mvs1c_clk",
|
||||
.parent_data = &(const struct clk_parent_data){
|
||||
.hw = &video_cc_mvs1c_div2_div_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct gdsc mvs0c_gdsc = {
|
||||
.gdscr = 0xbf8,
|
||||
.pd = {
|
||||
.name = "mvs0c_gdsc",
|
||||
},
|
||||
.flags = 0,
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
static struct gdsc mvs1c_gdsc = {
|
||||
.gdscr = 0xc98,
|
||||
.pd = {
|
||||
.name = "mvs1c_gdsc",
|
||||
},
|
||||
.flags = 0,
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
static struct gdsc mvs0_gdsc = {
|
||||
.gdscr = 0xd18,
|
||||
.pd = {
|
||||
.name = "mvs0_gdsc",
|
||||
},
|
||||
.flags = HW_CTRL,
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
static struct gdsc mvs1_gdsc = {
|
||||
.gdscr = 0xd98,
|
||||
.pd = {
|
||||
.name = "mvs1_gdsc",
|
||||
},
|
||||
.flags = HW_CTRL,
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
};
|
||||
|
||||
static struct clk_regmap *video_cc_sm8250_clocks[] = {
|
||||
[VIDEO_CC_MVS0_CLK_SRC] = &video_cc_mvs0_clk_src.clkr,
|
||||
[VIDEO_CC_MVS0C_CLK] = &video_cc_mvs0c_clk.clkr,
|
||||
[VIDEO_CC_MVS0C_DIV2_DIV_CLK_SRC] = &video_cc_mvs0c_div2_div_clk_src.clkr,
|
||||
[VIDEO_CC_MVS1_CLK_SRC] = &video_cc_mvs1_clk_src.clkr,
|
||||
[VIDEO_CC_MVS1_DIV2_CLK] = &video_cc_mvs1_div2_clk.clkr,
|
||||
[VIDEO_CC_MVS1C_CLK] = &video_cc_mvs1c_clk.clkr,
|
||||
[VIDEO_CC_MVS1C_DIV2_DIV_CLK_SRC] = &video_cc_mvs1c_div2_div_clk_src.clkr,
|
||||
[VIDEO_CC_PLL0] = &video_pll0.clkr,
|
||||
[VIDEO_CC_PLL1] = &video_pll1.clkr,
|
||||
};
|
||||
|
||||
static const struct qcom_reset_map video_cc_sm8250_resets[] = {
|
||||
[VIDEO_CC_CVP_INTERFACE_BCR] = { 0xe54 },
|
||||
[VIDEO_CC_CVP_MVS0_BCR] = { 0xd14 },
|
||||
[VIDEO_CC_MVS0C_CLK_ARES] = { 0xc34, 2 },
|
||||
[VIDEO_CC_CVP_MVS0C_BCR] = { 0xbf4 },
|
||||
[VIDEO_CC_CVP_MVS1_BCR] = { 0xd94 },
|
||||
[VIDEO_CC_MVS1C_CLK_ARES] = { 0xcd4, 2 },
|
||||
[VIDEO_CC_CVP_MVS1C_BCR] = { 0xc94 },
|
||||
};
|
||||
|
||||
static struct gdsc *video_cc_sm8250_gdscs[] = {
|
||||
[MVS0C_GDSC] = &mvs0c_gdsc,
|
||||
[MVS1C_GDSC] = &mvs1c_gdsc,
|
||||
[MVS0_GDSC] = &mvs0_gdsc,
|
||||
[MVS1_GDSC] = &mvs1_gdsc,
|
||||
};
|
||||
|
||||
static const struct regmap_config video_cc_sm8250_regmap_config = {
|
||||
.reg_bits = 32,
|
||||
.reg_stride = 4,
|
||||
.val_bits = 32,
|
||||
.max_register = 0xf4c,
|
||||
.fast_io = true,
|
||||
};
|
||||
|
||||
static const struct qcom_cc_desc video_cc_sm8250_desc = {
|
||||
.config = &video_cc_sm8250_regmap_config,
|
||||
.clks = video_cc_sm8250_clocks,
|
||||
.num_clks = ARRAY_SIZE(video_cc_sm8250_clocks),
|
||||
.resets = video_cc_sm8250_resets,
|
||||
.num_resets = ARRAY_SIZE(video_cc_sm8250_resets),
|
||||
.gdscs = video_cc_sm8250_gdscs,
|
||||
.num_gdscs = ARRAY_SIZE(video_cc_sm8250_gdscs),
|
||||
};
|
||||
|
||||
static const struct of_device_id video_cc_sm8250_match_table[] = {
|
||||
{ .compatible = "qcom,sm8250-videocc" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, video_cc_sm8250_match_table);
|
||||
|
||||
static int video_cc_sm8250_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct regmap *regmap;
|
||||
|
||||
regmap = qcom_cc_map(pdev, &video_cc_sm8250_desc);
|
||||
if (IS_ERR(regmap))
|
||||
return PTR_ERR(regmap);
|
||||
|
||||
clk_lucid_pll_configure(&video_pll0, regmap, &video_pll0_config);
|
||||
clk_lucid_pll_configure(&video_pll1, regmap, &video_pll1_config);
|
||||
|
||||
/* Keep VIDEO_CC_AHB_CLK and VIDEO_CC_XO_CLK ALWAYS-ON */
|
||||
regmap_update_bits(regmap, 0xe58, BIT(0), BIT(0));
|
||||
regmap_update_bits(regmap, 0xeec, BIT(0), BIT(0));
|
||||
|
||||
return qcom_cc_really_probe(pdev, &video_cc_sm8250_desc, regmap);
|
||||
}
|
||||
|
||||
static struct platform_driver video_cc_sm8250_driver = {
|
||||
.probe = video_cc_sm8250_probe,
|
||||
.driver = {
|
||||
.name = "sm8250-videocc",
|
||||
.of_match_table = video_cc_sm8250_match_table,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init video_cc_sm8250_init(void)
|
||||
{
|
||||
return platform_driver_register(&video_cc_sm8250_driver);
|
||||
}
|
||||
subsys_initcall(video_cc_sm8250_init);
|
||||
|
||||
static void __exit video_cc_sm8250_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&video_cc_sm8250_driver);
|
||||
}
|
||||
module_exit(video_cc_sm8250_exit);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION("QTI VIDEOCC SM8250 Driver");
|
|
@ -30,6 +30,7 @@ config CLK_RENESAS
|
|||
select CLK_R8A77980 if ARCH_R8A77980
|
||||
select CLK_R8A77990 if ARCH_R8A77990
|
||||
select CLK_R8A77995 if ARCH_R8A77995
|
||||
select CLK_R8A779A0 if ARCH_R8A779A0
|
||||
select CLK_R9A06G032 if ARCH_R9A06G032
|
||||
select CLK_SH73A0 if ARCH_SH73A0
|
||||
|
||||
|
@ -145,6 +146,10 @@ config CLK_R8A77995
|
|||
bool "R-Car D3 clock support" if COMPILE_TEST
|
||||
select CLK_RCAR_GEN3_CPG
|
||||
|
||||
config CLK_R8A779A0
|
||||
bool "R-Car V3U clock support" if COMPILE_TEST
|
||||
select CLK_RENESAS_CPG_MSSR
|
||||
|
||||
config CLK_R9A06G032
|
||||
bool "Renesas R9A06G032 clock driver"
|
||||
help
|
||||
|
@ -162,7 +167,7 @@ config CLK_RCAR_GEN2_CPG
|
|||
select CLK_RENESAS_CPG_MSSR
|
||||
|
||||
config CLK_RCAR_GEN3_CPG
|
||||
bool "R-Car Gen3 CPG clock support" if COMPILE_TEST
|
||||
bool "R-Car Gen3 and RZ/G2 CPG clock support" if COMPILE_TEST
|
||||
select CLK_RENESAS_CPG_MSSR
|
||||
|
||||
config CLK_RCAR_USB2_CLOCK_SEL
|
||||
|
|
|
@ -27,6 +27,7 @@ obj-$(CONFIG_CLK_R8A77970) += r8a77970-cpg-mssr.o
|
|||
obj-$(CONFIG_CLK_R8A77980) += r8a77980-cpg-mssr.o
|
||||
obj-$(CONFIG_CLK_R8A77990) += r8a77990-cpg-mssr.o
|
||||
obj-$(CONFIG_CLK_R8A77995) += r8a77995-cpg-mssr.o
|
||||
obj-$(CONFIG_CLK_R8A779A0) += r8a779a0-cpg-mssr.o
|
||||
obj-$(CONFIG_CLK_R9A06G032) += r9a06g032-clocks.o
|
||||
obj-$(CONFIG_CLK_SH73A0) += clk-sh73a0.o
|
||||
|
||||
|
|
|
@ -214,7 +214,7 @@ const struct cpg_mssr_info r7s9210_cpg_mssr_info __initconst = {
|
|||
.cpg_clk_register = rza2_cpg_clk_register,
|
||||
|
||||
/* RZ/A2 has Standby Control Registers */
|
||||
.stbyctrl = true,
|
||||
.reg_layout = CLK_REG_LAYOUT_RZ_A,
|
||||
};
|
||||
|
||||
static void __init r7s9210_cpg_mssr_early_init(struct device_node *np)
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue