Commit c43a52cf authored by Stephen Boyd's avatar Stephen Boyd

Merge branches 'clk-aspeed', 'clk-lock-UP', 'clk-mediatek' and 'clk-allwinner' into clk-next

* clk-aspeed:
  clk: aspeed: Handle inverse polarity of USB port 1 clock gate
  clk: aspeed: Fix return value check in aspeed_cc_init()
  clk: aspeed: Add reset controller
  clk: aspeed: Register gated clocks
  clk: aspeed: Add platform driver and register PLLs
  clk: aspeed: Register core clocks
  clk: Add clock driver for ASPEED BMC SoCs
  dt-bindings: clock: Add ASPEED constants

* clk-lock-UP:
  clk: fix reentrancy of clk_enable() on UP systems

* clk-mediatek:
  clk: mediatek: adjust dependency of reset.c to avoid unexpectedly being built
  clk: mediatek: Fix all warnings for missing struct clk_onecell_data
  clk: mediatek: fixup test-building of MediaTek clock drivers
  clk: mediatek: group drivers under indpendent menu

* clk-allwinner:
  clk: sunxi-ng: a83t: Add M divider to TCON1 clock
  clk: sunxi-ng: fix the A64/H5 clock description of DE2 CCU
  clk: sunxi-ng: add support for Allwinner H3 DE2 CCU
  dt-bindings: fix the binding of Allwinner DE2 CCU of A83T and H3
  clk: sunxi-ng: sun8i: a83t: Use sigma-delta modulation for audio PLL
  clk: sunxi-ng: sun8i: a83t: Add /2 fixed post divider to audio PLL
  clk: sunxi-ng: Support fixed post-dividers on NM style clocks
  clk: sunxi-ng: sun50i: a64: Add 2x fixed post-divider to MMC module clocks
  clk: sunxi-ng: Support fixed post-dividers on MP style clocks
  clk: sunxi: Use PTR_ERR_OR_ZERO()
......@@ -4,13 +4,14 @@ Allwinner Display Engine 2.0 Clock Control Binding
Required properties :
- compatible: must contain one of the following compatibles:
- "allwinner,sun8i-a83t-de2-clk"
- "allwinner,sun8i-h3-de2-clk"
- "allwinner,sun8i-v3s-de2-clk"
- "allwinner,sun50i-h5-de2-clk"
- reg: Must contain the registers base address and length
- clocks: phandle to the clocks feeding the display engine subsystem.
Three are needed:
- "mod": the display engine module clock
- "mod": the display engine module clock (on A83T it's the DE PLL)
- "bus": the bus clock for the whole display engine subsystem
- clock-names: Must contain the clock names described just above
- resets: phandle to the reset control for the display engine subsystem.
......@@ -19,7 +20,7 @@ Required properties :
Example:
de2_clocks: clock@1000000 {
compatible = "allwinner,sun8i-a83t-de2-clk";
compatible = "allwinner,sun8i-h3-de2-clk";
reg = <0x01000000 0x100000>;
clocks = <&ccu CLK_BUS_DE>,
<&ccu CLK_DE>;
......
......@@ -142,6 +142,18 @@ config COMMON_CLK_GEMINI
This driver supports the SoC clocks on the Cortina Systems Gemini
platform, also known as SL3516 or CS3516.
config COMMON_CLK_ASPEED
bool "Clock driver for Aspeed BMC SoCs"
depends on ARCH_ASPEED || COMPILE_TEST
default ARCH_ASPEED
select MFD_SYSCON
select RESET_CONTROLLER
---help---
This driver supports the SoC clocks on the Aspeed BMC platforms.
The G4 and G5 series, including the ast2400 and ast2500, are supported
by this driver.
config COMMON_CLK_S2MPS11
tristate "Clock driver for S2MPS1X/S5M8767 MFD"
depends on MFD_SEC_CORE || COMPILE_TEST
......
......@@ -27,6 +27,7 @@ obj-$(CONFIG_ARCH_CLPS711X) += clk-clps711x.o
obj-$(CONFIG_COMMON_CLK_CS2000_CP) += clk-cs2000-cp.o
obj-$(CONFIG_ARCH_EFM32) += clk-efm32gg.o
obj-$(CONFIG_COMMON_CLK_GEMINI) += clk-gemini.o
obj-$(CONFIG_COMMON_CLK_ASPEED) += clk-aspeed.o
obj-$(CONFIG_ARCH_HIGHBANK) += clk-highbank.o
obj-$(CONFIG_CLK_HSDK) += clk-hsdk-pll.o
obj-$(CONFIG_COMMON_CLK_MAX77686) += clk-max77686.o
......@@ -67,7 +68,7 @@ obj-$(CONFIG_ARCH_MXC) += imx/
obj-$(CONFIG_MACH_INGENIC) += ingenic/
obj-$(CONFIG_ARCH_KEYSTONE) += keystone/
obj-$(CONFIG_MACH_LOONGSON32) += loongson1/
obj-$(CONFIG_ARCH_MEDIATEK) += mediatek/
obj-y += mediatek/
obj-$(CONFIG_COMMON_CLK_AMLOGIC) += meson/
obj-$(CONFIG_MACH_PIC32) += microchip/
ifeq ($(CONFIG_COMMON_CLK), y)
......
This diff is collapsed.
......@@ -144,10 +144,18 @@ static unsigned long clk_enable_lock(void)
{
unsigned long flags;
if (!spin_trylock_irqsave(&enable_lock, flags)) {
/*
* On UP systems, spin_trylock_irqsave() always returns true, even if
* we already hold the lock. So, in that case, we rely only on
* reference counting.
*/
if (!IS_ENABLED(CONFIG_SMP) ||
!spin_trylock_irqsave(&enable_lock, flags)) {
if (enable_owner == current) {
enable_refcnt++;
__acquire(enable_lock);
if (!IS_ENABLED(CONFIG_SMP))
local_save_flags(flags);
return flags;
}
spin_lock_irqsave(&enable_lock, flags);
......
#
# MediaTek SoC drivers
# MediaTek Clock Drivers
#
menu "Clock driver for MediaTek SoC"
depends on ARCH_MEDIATEK || COMPILE_TEST
config COMMON_CLK_MEDIATEK
bool
select RESET_CONTROLLER
---help---
Mediatek SoCs' clock support.
MediaTek SoCs' clock support.
config COMMON_CLK_MT2701
bool "Clock driver for Mediatek MT2701"
bool "Clock driver for MediaTek MT2701"
depends on (ARCH_MEDIATEK && ARM) || COMPILE_TEST
select COMMON_CLK_MEDIATEK
default ARCH_MEDIATEK && ARM
---help---
This driver supports Mediatek MT2701 basic clocks.
This driver supports MediaTek MT2701 basic clocks.
config COMMON_CLK_MT2701_MMSYS
bool "Clock driver for Mediatek MT2701 mmsys"
bool "Clock driver for MediaTek MT2701 mmsys"
depends on COMMON_CLK_MT2701
---help---
This driver supports Mediatek MT2701 mmsys clocks.
This driver supports MediaTek MT2701 mmsys clocks.
config COMMON_CLK_MT2701_IMGSYS
bool "Clock driver for Mediatek MT2701 imgsys"
bool "Clock driver for MediaTek MT2701 imgsys"
depends on COMMON_CLK_MT2701
---help---
This driver supports Mediatek MT2701 imgsys clocks.
This driver supports MediaTek MT2701 imgsys clocks.
config COMMON_CLK_MT2701_VDECSYS
bool "Clock driver for Mediatek MT2701 vdecsys"
bool "Clock driver for MediaTek MT2701 vdecsys"
depends on COMMON_CLK_MT2701
---help---
This driver supports Mediatek MT2701 vdecsys clocks.
This driver supports MediaTek MT2701 vdecsys clocks.
config COMMON_CLK_MT2701_HIFSYS
bool "Clock driver for Mediatek MT2701 hifsys"
bool "Clock driver for MediaTek MT2701 hifsys"
depends on COMMON_CLK_MT2701
---help---
This driver supports Mediatek MT2701 hifsys clocks.
This driver supports MediaTek MT2701 hifsys clocks.
config COMMON_CLK_MT2701_ETHSYS
bool "Clock driver for Mediatek MT2701 ethsys"
bool "Clock driver for MediaTek MT2701 ethsys"
depends on COMMON_CLK_MT2701
---help---
This driver supports Mediatek MT2701 ethsys clocks.
This driver supports MediaTek MT2701 ethsys clocks.
config COMMON_CLK_MT2701_BDPSYS
bool "Clock driver for Mediatek MT2701 bdpsys"
bool "Clock driver for MediaTek MT2701 bdpsys"
depends on COMMON_CLK_MT2701
---help---
This driver supports Mediatek MT2701 bdpsys clocks.
This driver supports MediaTek MT2701 bdpsys clocks.
config COMMON_CLK_MT2712
bool "Clock driver for Mediatek MT2712"
bool "Clock driver for MediaTek MT2712"
depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
select COMMON_CLK_MEDIATEK
default ARCH_MEDIATEK && ARM64
---help---
This driver supports Mediatek MT2712 basic clocks.
This driver supports MediaTek MT2712 basic clocks.
config COMMON_CLK_MT2712_BDPSYS
bool "Clock driver for Mediatek MT2712 bdpsys"
bool "Clock driver for MediaTek MT2712 bdpsys"
depends on COMMON_CLK_MT2712
---help---
This driver supports Mediatek MT2712 bdpsys clocks.
This driver supports MediaTek MT2712 bdpsys clocks.
config COMMON_CLK_MT2712_IMGSYS
bool "Clock driver for Mediatek MT2712 imgsys"
bool "Clock driver for MediaTek MT2712 imgsys"
depends on COMMON_CLK_MT2712
---help---
This driver supports Mediatek MT2712 imgsys clocks.
This driver supports MediaTek MT2712 imgsys clocks.
config COMMON_CLK_MT2712_JPGDECSYS
bool "Clock driver for Mediatek MT2712 jpgdecsys"
bool "Clock driver for MediaTek MT2712 jpgdecsys"
depends on COMMON_CLK_MT2712
---help---
This driver supports Mediatek MT2712 jpgdecsys clocks.
This driver supports MediaTek MT2712 jpgdecsys clocks.
config COMMON_CLK_MT2712_MFGCFG
bool "Clock driver for Mediatek MT2712 mfgcfg"
bool "Clock driver for MediaTek MT2712 mfgcfg"
depends on COMMON_CLK_MT2712
---help---
This driver supports Mediatek MT2712 mfgcfg clocks.
This driver supports MediaTek MT2712 mfgcfg clocks.
config COMMON_CLK_MT2712_MMSYS
bool "Clock driver for Mediatek MT2712 mmsys"
bool "Clock driver for MediaTek MT2712 mmsys"
depends on COMMON_CLK_MT2712
---help---
This driver supports Mediatek MT2712 mmsys clocks.
This driver supports MediaTek MT2712 mmsys clocks.
config COMMON_CLK_MT2712_VDECSYS
bool "Clock driver for Mediatek MT2712 vdecsys"
bool "Clock driver for MediaTek MT2712 vdecsys"
depends on COMMON_CLK_MT2712
---help---
This driver supports Mediatek MT2712 vdecsys clocks.
This driver supports MediaTek MT2712 vdecsys clocks.
config COMMON_CLK_MT2712_VENCSYS
bool "Clock driver for Mediatek MT2712 vencsys"
bool "Clock driver for MediaTek MT2712 vencsys"
depends on COMMON_CLK_MT2712
---help---
This driver supports Mediatek MT2712 vencsys clocks.
This driver supports MediaTek MT2712 vencsys clocks.
config COMMON_CLK_MT6797
bool "Clock driver for Mediatek MT6797"
bool "Clock driver for MediaTek MT6797"
depends on (ARCH_MEDIATEK && ARM64) || COMPILE_TEST
select COMMON_CLK_MEDIATEK
default ARCH_MEDIATEK && ARM64
---help---
This driver supports Mediatek MT6797 basic clocks.
This driver supports MediaTek MT6797 basic clocks.
config COMMON_CLK_MT6797_MMSYS
bool "Clock driver for Mediatek MT6797 mmsys"
bool "Clock driver for MediaTek MT6797 mmsys"
depends on COMMON_CLK_MT6797
---help---
This driver supports Mediatek MT6797 mmsys clocks.
This driver supports MediaTek MT6797 mmsys clocks.
config COMMON_CLK_MT6797_IMGSYS
bool "Clock driver for Mediatek MT6797 imgsys"
bool "Clock driver for MediaTek MT6797 imgsys"
depends on COMMON_CLK_MT6797
---help---
This driver supports Mediatek MT6797 imgsys clocks.
This driver supports MediaTek MT6797 imgsys clocks.
config COMMON_CLK_MT6797_VDECSYS
bool "Clock driver for Mediatek MT6797 vdecsys"
bool "Clock driver for MediaTek MT6797 vdecsys"
depends on COMMON_CLK_MT6797
---help---
This driver supports Mediatek MT6797 vdecsys clocks.
This driver supports MediaTek MT6797 vdecsys clocks.
config COMMON_CLK_MT6797_VENCSYS
bool "Clock driver for Mediatek MT6797 vencsys"
bool "Clock driver for MediaTek MT6797 vencsys"
depends on COMMON_CLK_MT6797
---help---
This driver supports Mediatek MT6797 vencsys clocks.
This driver supports MediaTek MT6797 vencsys clocks.
config COMMON_CLK_MT7622
bool "Clock driver for MediaTek MT7622"
......@@ -163,17 +167,18 @@ config COMMON_CLK_MT7622_AUDSYS
to audio consumers such as I2S and TDM.
config COMMON_CLK_MT8135
bool "Clock driver for Mediatek MT8135"
bool "Clock driver for MediaTek MT8135"
depends on (ARCH_MEDIATEK && ARM) || COMPILE_TEST
select COMMON_CLK_MEDIATEK
default ARCH_MEDIATEK && ARM
---help---
This driver supports Mediatek MT8135 clocks.
This driver supports MediaTek MT8135 clocks.
config COMMON_CLK_MT8173
bool "Clock driver for Mediatek MT8173"
bool "Clock driver for MediaTek MT8173"
depends on ARCH_MEDIATEK || COMPILE_TEST
select COMMON_CLK_MEDIATEK
default ARCH_MEDIATEK
---help---
This driver supports Mediatek MT8173 clocks.
This driver supports MediaTek MT8173 clocks.
endmenu
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o clk-cpumux.o
obj-$(CONFIG_RESET_CONTROLLER) += reset.o
obj-$(CONFIG_COMMON_CLK_MEDIATEK) += clk-mtk.o clk-pll.o clk-gate.o clk-apmixed.o clk-cpumux.o reset.o
obj-$(CONFIG_COMMON_CLK_MT6797) += clk-mt6797.o
obj-$(CONFIG_COMMON_CLK_MT6797_IMGSYS) += clk-mt6797-img.o
obj-$(CONFIG_COMMON_CLK_MT6797_MMSYS) += clk-mt6797-mm.o
......
......@@ -20,6 +20,7 @@
#include <linux/clk-provider.h>
struct clk;
struct clk_onecell_data;
#define MAX_MUX_GATE_BIT 31
#define INVALID_MUX_GATE_BIT (MAX_MUX_GATE_BIT + 1)
......@@ -228,14 +229,7 @@ void mtk_clk_register_plls(struct device_node *node,
struct clk *mtk_clk_register_ref2usb_tx(const char *name,
const char *parent_name, void __iomem *reg);
#ifdef CONFIG_RESET_CONTROLLER
void mtk_register_reset_controller(struct device_node *np,
unsigned int num_regs, int regofs);
#else
static inline void mtk_register_reset_controller(struct device_node *np,
unsigned int num_regs, int regofs)
{
}
#endif
#endif /* __DRV_CLK_MTK_H */
......@@ -400,28 +400,45 @@ static SUNXI_CCU_MP_WITH_MUX_GATE(nand_clk, "nand", mod0_default_parents, 0x080,
BIT(31), /* gate */
0);
/*
* MMC clocks are the new timing mode (see A83T & H3) variety, but without
* the mode switch. This means they have a 2x post divider between the clock
* and the MMC module. This is not documented in the manual, but is taken
* into consideration when setting the mmc module clocks in the BSP kernel.
* Without it, MMC performance is degraded.
*
* We model it here to be consistent with other SoCs supporting this mode.
* The alternative would be to add the 2x multiplier when setting the MMC
* module clock in the MMC driver, just for the A64.
*/
static const char * const mmc_default_parents[] = { "osc24M", "pll-periph0-2x",
"pll-periph1-2x" };
static SUNXI_CCU_MP_WITH_MUX_GATE(mmc0_clk, "mmc0", mmc_default_parents, 0x088,
0, 4, /* M */
16, 2, /* P */
24, 2, /* mux */
BIT(31), /* gate */
0);
static SUNXI_CCU_MP_WITH_MUX_GATE(mmc1_clk, "mmc1", mmc_default_parents, 0x08c,
0, 4, /* M */
16, 2, /* P */
24, 2, /* mux */
BIT(31), /* gate */
0);
static SUNXI_CCU_MP_WITH_MUX_GATE(mmc2_clk, "mmc2", mmc_default_parents, 0x090,
0, 4, /* M */
16, 2, /* P */
24, 2, /* mux */
BIT(31), /* gate */
0);
static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc0_clk, "mmc0",
mmc_default_parents, 0x088,
0, 4, /* M */
16, 2, /* P */
24, 2, /* mux */
BIT(31), /* gate */
2, /* post-div */
0);
static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc1_clk, "mmc1",
mmc_default_parents, 0x08c,
0, 4, /* M */
16, 2, /* P */
24, 2, /* mux */
BIT(31), /* gate */
2, /* post-div */
0);
static SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(mmc2_clk, "mmc2",
mmc_default_parents, 0x090,
0, 4, /* M */
16, 2, /* P */
24, 2, /* mux */
BIT(31), /* gate */
2, /* post-div */
0);
static const char * const ts_parents[] = { "osc24M", "pll-periph0", };
static SUNXI_CCU_MP_WITH_MUX_GATE(ts_clk, "ts", ts_parents, 0x098,
......
......@@ -76,15 +76,26 @@ static struct ccu_mult pll_c1cpux_clk = {
*/
#define SUN8I_A83T_PLL_AUDIO_REG 0x008
/* clock rates doubled for post divider */
static struct ccu_sdm_setting pll_audio_sdm_table[] = {
{ .rate = 45158400, .pattern = 0xc00121ff, .m = 29, .n = 54 },
{ .rate = 49152000, .pattern = 0xc000e147, .m = 30, .n = 61 },
};
static struct ccu_nm pll_audio_clk = {
.enable = BIT(31),
.lock = BIT(2),
.n = _SUNXI_CCU_MULT_OFFSET_MIN_MAX(8, 8, 0, 12, 0),
.m = _SUNXI_CCU_DIV(0, 6),
.fixed_post_div = 2,
.sdm = _SUNXI_CCU_SDM(pll_audio_sdm_table, BIT(24),
0x284, BIT(31)),
.common = {
.reg = SUN8I_A83T_PLL_AUDIO_REG,
.lock_reg = CCU_SUN8I_A83T_LOCK_REG,
.features = CCU_FEATURE_LOCK_REG,
.features = CCU_FEATURE_LOCK_REG |
CCU_FEATURE_FIXED_POSTDIV |
CCU_FEATURE_SIGMA_DELTA_MOD,
.hw.init = CLK_HW_INIT("pll-audio", "osc24M",
&ccu_nm_ops, CLK_SET_RATE_UNGATE),
},
......@@ -493,8 +504,8 @@ static SUNXI_CCU_MUX_WITH_GATE(tcon0_clk, "tcon0", tcon0_parents,
0x118, 24, 3, BIT(31), CLK_SET_RATE_PARENT);
static const char * const tcon1_parents[] = { "pll-video1" };
static SUNXI_CCU_MUX_WITH_GATE(tcon1_clk, "tcon1", tcon1_parents,
0x11c, 24, 3, BIT(31), CLK_SET_RATE_PARENT);
static SUNXI_CCU_M_WITH_MUX_GATE(tcon1_clk, "tcon1", tcon1_parents,
0x11c, 0, 4, 24, 2, BIT(31), CLK_SET_RATE_PARENT);
static SUNXI_CCU_GATE(csi_misc_clk, "csi-misc", "osc24M", 0x130, BIT(16), 0);
......@@ -889,9 +900,10 @@ static int sun8i_a83t_ccu_probe(struct platform_device *pdev)
if (IS_ERR(reg))
return PTR_ERR(reg);
/* Enforce d1 = 0, d2 = 0 for Audio PLL */
/* Enforce d1 = 0, d2 = 1 for Audio PLL */
val = readl(reg + SUN8I_A83T_PLL_AUDIO_REG);
val &= ~(BIT(16) | BIT(18));
val &= ~BIT(16);
val |= BIT(18);
writel(val, reg + SUN8I_A83T_PLL_AUDIO_REG);
/* Enforce P = 1 for both CPU cluster PLLs */
......
......@@ -41,6 +41,8 @@ static SUNXI_CCU_GATE(wb_clk, "wb", "wb-div",
static SUNXI_CCU_M(mixer0_div_clk, "mixer0-div", "de", 0x0c, 0, 4,
CLK_SET_RATE_PARENT);
static SUNXI_CCU_M(mixer1_div_clk, "mixer1-div", "de", 0x0c, 4, 4,
CLK_SET_RATE_PARENT);
static SUNXI_CCU_M(wb_div_clk, "wb-div", "de", 0x0c, 8, 4,
CLK_SET_RATE_PARENT);
......@@ -65,6 +67,20 @@ static struct ccu_common *sun8i_a83t_de2_clks[] = {
&wb_div_a83_clk.common,
};
static struct ccu_common *sun8i_h3_de2_clks[] = {
&mixer0_clk.common,
&mixer1_clk.common,
&wb_clk.common,
&bus_mixer0_clk.common,
&bus_mixer1_clk.common,
&bus_wb_clk.common,
&mixer0_div_clk.common,
&mixer1_div_clk.common,
&wb_div_clk.common,
};
static struct ccu_common *sun8i_v3s_de2_clks[] = {
&mixer0_clk.common,
&wb_clk.common,
......@@ -93,6 +109,23 @@ static struct clk_hw_onecell_data sun8i_a83t_de2_hw_clks = {
.num = CLK_NUMBER,
};
static struct clk_hw_onecell_data sun8i_h3_de2_hw_clks = {
.hws = {
[CLK_MIXER0] = &mixer0_clk.common.hw,
[CLK_MIXER1] = &mixer1_clk.common.hw,
[CLK_WB] = &wb_clk.common.hw,
[CLK_BUS_MIXER0] = &bus_mixer0_clk.common.hw,
[CLK_BUS_MIXER1] = &bus_mixer1_clk.common.hw,
[CLK_BUS_WB] = &bus_wb_clk.common.hw,
[CLK_MIXER0_DIV] = &mixer0_div_clk.common.hw,
[CLK_MIXER1_DIV] = &mixer1_div_clk.common.hw,
[CLK_WB_DIV] = &wb_div_clk.common.hw,
},
.num = CLK_NUMBER,
};
static struct clk_hw_onecell_data sun8i_v3s_de2_hw_clks = {
.hws = {
[CLK_MIXER0] = &mixer0_clk.common.hw,
......@@ -133,11 +166,21 @@ static const struct sunxi_ccu_desc sun8i_a83t_de2_clk_desc = {
.num_resets = ARRAY_SIZE(sun8i_a83t_de2_resets),
};
static const struct sunxi_ccu_desc sun8i_h3_de2_clk_desc = {
.ccu_clks = sun8i_h3_de2_clks,
.num_ccu_clks = ARRAY_SIZE(sun8i_h3_de2_clks),
.hw_clks = &sun8i_h3_de2_hw_clks,
.resets = sun8i_a83t_de2_resets,
.num_resets = ARRAY_SIZE(sun8i_a83t_de2_resets),
};
static const struct sunxi_ccu_desc sun50i_a64_de2_clk_desc = {
.ccu_clks = sun8i_a83t_de2_clks,
.num_ccu_clks = ARRAY_SIZE(sun8i_a83t_de2_clks),
.ccu_clks = sun8i_h3_de2_clks,
.num_ccu_clks = ARRAY_SIZE(sun8i_h3_de2_clks),
.hw_clks = &sun8i_a83t_de2_hw_clks,
.hw_clks = &sun8i_h3_de2_hw_clks,
.resets = sun50i_a64_de2_resets,
.num_resets = ARRAY_SIZE(sun50i_a64_de2_resets),
......@@ -237,6 +280,10 @@ static const struct of_device_id sunxi_de2_clk_ids[] = {
.compatible = "allwinner,sun8i-a83t-de2-clk",
.data = &sun8i_a83t_de2_clk_desc,
},
{
.compatible = "allwinner,sun8i-h3-de2-clk",
.data = &sun8i_h3_de2_clk_desc,
},
{
.compatible = "allwinner,sun8i-v3s-de2-clk",
.data = &sun8i_v3s_de2_clk_desc,
......
......@@ -50,12 +50,19 @@ static unsigned long ccu_mp_round_rate(struct ccu_mux_internal *mux,
unsigned int max_m, max_p;
unsigned int m, p;
if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
rate *= cmp->fixed_post_div;
max_m = cmp->m.max ?: 1 << cmp->m.width;
max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1);
ccu_mp_find_best(*parent_rate, rate, max_m, max_p, &m, &p);
rate = *parent_rate / p / m;
if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
rate /= cmp->fixed_post_div;
return *parent_rate / p / m;
return rate;
}
static void ccu_mp_disable(struct clk_hw *hw)
......@@ -83,6 +90,7 @@ static unsigned long ccu_mp_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct ccu_mp *cmp = hw_to_ccu_mp(hw);
unsigned long rate;
unsigned int m, p;
u32 reg;
......@@ -101,7 +109,11 @@ static unsigned long ccu_mp_recalc_rate(struct clk_hw *hw,
p = reg >> cmp->p.shift;
p &= (1 << cmp->p.width) - 1;
return (parent_rate >> p) / m;
rate = (parent_rate >> p) / m;
if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
rate /= cmp->fixed_post_div;
return rate;
}
static int ccu_mp_determine_rate(struct clk_hw *hw,
......@@ -129,6 +141,10 @@ static int ccu_mp_set_rate(struct clk_hw *hw, unsigned long rate,
max_m = cmp->m.max ?: 1 << cmp->m.width;
max_p = cmp->p.max ?: 1 << ((1 << cmp->p.width) - 1);
/* Adjust target rate according to post-dividers */
if (cmp->common.features & CCU_FEATURE_FIXED_POSTDIV)
rate = rate * cmp->fixed_post_div;
ccu_mp_find_best(parent_rate, rate, max_m, max_p, &m, &p);
spin_lock_irqsave(cmp->common.lock, flags);
......
......@@ -33,9 +33,33 @@ struct ccu_mp {
struct ccu_div_internal m;
struct ccu_div_internal p;
struct ccu_mux_internal mux;
unsigned int fixed_post_div;
struct ccu_common common;
};
#define SUNXI_CCU_MP_WITH_MUX_GATE_POSTDIV(_struct, _name, _parents, _reg, \
_mshift, _mwidth, \
_pshift, _pwidth, \
_muxshift, _muxwidth, \
_gate, _postdiv, _flags) \
struct ccu_mp _struct = { \
.enable = _gate, \
.m = _SUNXI_CCU_DIV(_mshift, _mwidth), \
.p = _SUNXI_CCU_DIV(_pshift, _pwidth), \
.mux = _SUNXI_CCU_MUX(_muxshift, _muxwidth), \
.fixed_post_div = _postdiv, \
.common = { \
.reg = _reg, \
.features = CCU_FEATURE_FIXED_POSTDIV, \
.hw.init = CLK_HW_INIT_PARENTS(_name, \
_parents, \
&ccu_mp_ops, \
_flags), \
} \
}
#define SUNXI_CCU_MP_WITH_MUX_GATE(_struct, _name, _parents, _reg, \
_mshift, _mwidth, \
_pshift, _pwidth, \
......
......@@ -70,11 +70,18 @@ static unsigned long ccu_nm_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct ccu_nm *nm = hw_to_ccu_nm(hw);
unsigned long rate;
unsigned long n, m;
u32 reg;
if (ccu_frac_helper_is_enabled(&nm->common, &nm->frac))
return ccu_frac_helper_read_rate(&nm->common, &nm->frac);
if (ccu_frac_helper_is_enabled(&nm->common, &nm->frac)) {
rate = ccu_frac_helper_read_rate(&nm->common, &nm->frac);
if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV)
rate /= nm->fixed_post_div;
return rate;
}
reg = readl(nm->common.base + nm->common.reg);
......@@ -90,15 +97,15 @@ static unsigned long ccu_nm_recalc_rate(struct clk_hw *hw,
if (!m)
m++;
if (ccu_sdm_helper_is_enabled(&nm->common, &nm->sdm)) {
unsigned long rate =
ccu_sdm_helper_read_rate(&nm->common, &nm->sdm,
m, n);
if (rate)
return rate;
}
if (ccu_sdm_helper_is_enabled(&nm->common, &nm->sdm))
rate = ccu_sdm_helper_read_rate(&nm->common, &nm->sdm, m, n);
else
rate = parent_rate * n / m;
if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV)
rate /= nm->fixed_post_div;
return parent_rate * n / m;
return rate;
}
static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate,
......@@ -107,11 +114,20 @@ static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate,
struct ccu_nm *nm = hw_to_ccu_nm(hw);
struct _ccu_nm _nm;
if (ccu_frac_helper_has_rate(&nm->common, &nm->frac, rate))
if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV)
rate *= nm->fixed_post_div;
if (ccu_frac_helper_has_rate(&nm->common, &nm->frac, rate)) {
if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV)
rate /= nm->fixed_post_div;
return rate;
}
if (ccu_sdm_helper_has_rate(&nm->common, &nm->sdm, rate))
if (ccu_sdm_helper_has_rate(&nm->common, &nm->sdm, rate)) {
if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV)
rate /= nm->fixed_post_div;
return rate;
}
_nm.min_n = nm->n.min ?: 1;
_nm.max_n = nm->n.max ?: 1 << nm->n.width;
......@@ -119,8 +135,12 @@ static long ccu_nm_round_rate(struct clk_hw *hw, unsigned long rate,
_nm.max_m = nm->m.max ?: 1 << nm->m.width;
ccu_nm_find_best(*parent_rate, rate, &_nm);
rate = *parent_rate * _nm.n / _nm.m;
if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV)
rate /= nm->fixed_post_div;
return *parent_rate * _nm.n / _nm.m;
return rate;
}
static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate,
......@@ -131,6 +151,10 @@ static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long flags;
u32 reg;
/* Adjust target rate according to post-dividers */
if (nm->common.features & CCU_FEATURE_FIXED_POSTDIV)
rate = rate * nm->fixed_post_div;
if (ccu_frac_helper_has_rate(&nm->common, &nm->frac, rate)) {
spin_lock_irqsave(nm->common.lock, flags);
......
......@@ -36,6 +36,8 @@ struct ccu_nm {
struct ccu_frac_internal frac;
struct ccu_sdm_internal sdm;
unsigned int fixed_post_div;
struct ccu_common common;
};
......
......@@ -98,10 +98,7 @@ static int sun8i_a23_apb0_clk_probe(struct platform_device *pdev)
return PTR_ERR(reg);
clk = sun8i_a23_apb0_register(np, reg);
if (IS_ERR(clk))
return PTR_ERR(clk);
return 0;
return PTR_ERR_OR_ZERO(clk);
}
static const struct of_device_id sun8i_a23_apb0_clk_dt_ids[] = {
......
/* SPDX-License-Identifier: (GPL-2.0+ OR MIT) */
#ifndef DT_BINDINGS_ASPEED_CLOCK_H
#define DT_BINDINGS_ASPEED_CLOCK_H
#define ASPEED_CLK_GATE_ECLK 0
#define ASPEED_CLK_GATE_GCLK 1
#define ASPEED_CLK_GATE_MCLK 2
#define ASPEED_CLK_GATE_VCLK 3
#define ASPEED_CLK_GATE_BCLK 4
#define ASPEED_CLK_GATE_DCLK 5
#define ASPEED_CLK_GATE_REFCLK 6
#define ASPEED_CLK_GATE_USBPORT2CLK 7
#define ASPEED_CLK_GATE_LCLK 8
#define ASPEED_CLK_GATE_USBUHCICLK 9
#define ASPEED_CLK_GATE_D1CLK 10
#define ASPEED_CLK_GATE_YCLK 11
#define ASPEED_CLK_GATE_USBPORT1CLK 12
#define ASPEED_CLK_GATE_UART1CLK 13
#define ASPEED_CLK_GATE_UART2CLK 14
#define ASPEED_CLK_GATE_UART5CLK 15
#define ASPEED_CLK_GATE_ESPICLK 16
#define ASPEED_CLK_GATE_MAC1CLK 17
#define ASPEED_CLK_GATE_MAC2CLK 18
#define ASPEED_CLK_GATE_RSACLK 19
#define ASPEED_CLK_GATE_UART3CLK 20
#define ASPEED_CLK_GATE_UART4CLK 21
#define ASPEED_CLK_GATE_SDCLKCLK 22
#define ASPEED_CLK_GATE_LHCCLK 23
#define ASPEED_CLK_HPLL 24
#define ASPEED_CLK_AHB 25
#define ASPEED_CLK_APB 26
#define ASPEED_CLK_UART 27
#define ASPEED_CLK_SDIO 28
#define ASPEED_CLK_ECLK 29
#define ASPEED_CLK_ECLK_MUX 30
#define ASPEED_CLK_LHCLK 31
#define ASPEED_CLK_MAC 32
#define ASPEED_CLK_BCLK 33
#define ASPEED_CLK_MPLL 34
#define ASPEED_RESET_XDMA 0
#define ASPEED_RESET_MCTP 1
#define ASPEED_RESET_ADC 2
#define ASPEED_RESET_JTAG_MASTER 3
#define ASPEED_RESET_MIC 4
#define ASPEED_RESET_PWM 5
#define ASPEED_RESET_PCIVGA 6
#define ASPEED_RESET_I2C 7
#define ASPEED_RESET_AHB 8
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment