Allwinner clock changes for 4.14, round 2
Usual improvements: - Added support for fixed post-divider on divider and NKM-style clocks - Added driver for R40 CCU Non critical fixes (from round 1): - Fix sunxi-ng/ccu-sunxi-r.h header file guard macro typo - Make fractional clock modes really used and correctly configured - Make H3 cpu clock rate change correctly to be used with cpufreq -----BEGIN PGP SIGNATURE----- iQJCBAABCgAsFiEE2nN1m/hhnkhOWjtHOJpUIZwPJDAFAlmaR6AOHHdlbnNAY3Np ZS5vcmcACgkQOJpUIZwPJDC8YA//aLULoosISnyHs+wKowVHuDb7/mQ82O1gOAxC oE/vscd/WCRm7A5tfy+xHfajX/YRf32Qc09wB7fxUF4R0lgkO9QjUO0yX74a6bPh HCh/+bcmeNl9TZAYpTs72Q4nfc1x63OZwxMqTRnBmh3cevyIBJiFvqPjoMeD+Ari n32QEBgGE+A8bWshVFpNFyId6iyfMfozSYninIkVkwMGr7QgBgJRK1/5sftyZMR+ NQ2IGkaUfICnXofF//pNKsH7TN770gyDtFVWjrKZMrEKoP+gp3mawzMpfePKH/O6 4ihcm5LOo1Kdg5UzRTpQ2B/9fNUn2EvFYT6RuIBfddQcaflT1AzWtNK52j2L/crD tFyamcCSsNY5LzeySbVW+pQMRfrq6UCYtssiL7HYEcwMzvv61PfyDtKq5dxtJd0Q W8S6wPE/foj0i0JQWs0K70AacGU6XdEanUAtc5r3AsniCwwOtlwnaQqOlE5CiwAo HOSItOxX4Y/9QglnntsDyhNUaKpaSiG21XdE3ho3xq1/CS9ED3p5Ljbshem5fnPi mPisF6Ca6NVvCZ+sjH2RVvmGyh3d+BPfQLWC/sTamC4rnpDalrMq6IsCOivzbxqQ ltkYwUO1nmz5NMloeWYCUWWmLUOECCQu7Mppf2UQxpidrEEY0mbBYFdOlehrlHZT bWt2NdQ= =DKSp -----END PGP SIGNATURE----- Merge tag 'sunxi-clk-for-4.14-2' of https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux into clk-next Pull Allwinner clock changes from Chen-Yu Tsai: * Added support for fixed post-divider on divider and NKM-style clocks * Added driver for R40 CCU * Fix sunxi-ng/ccu-sunxi-r.h header file guard macro typo * Make fractional clock modes really used and correctly configured * Make H3 cpu clock rate change correctly to be used with cpufreq * tag 'sunxi-clk-for-4.14-2' of https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux: clk: sunxi-ng: support R40 SoC dt-bindings: add compatible string for Allwinner R40 CCU clk: sunxi-ng: nkm: add support for fixed post-divider clk: sunxi-ng: div: Add support for fixed post-divider dt-bindings: clock: sunxi-ccu: Add compatibles for sun5i CCU driver clk: sunxi-ng: allow set parent clock (PLL_CPUX) for CPUX clock on H3 clk: sunxi-ng: h3: gate then ungate PLL CPU clk after rate change clk: sunxi-ng: Wait for lock when using fractional mode clk: sunxi-ng: Make fractional helper less chatty clk: sunxi-ng: multiplier: Fix fractional mode clk: sunxi-ng: Fix fractional mode for N-M clocks clk: sunxi-ng: Fix header guard of ccu-sun8i-r.h
This commit is contained in:
commit
1fea70bc18
|
@ -3,6 +3,8 @@ Allwinner Clock Control Unit Binding
|
||||||
|
|
||||||
Required properties :
|
Required properties :
|
||||||
- compatible: must contain one of the following compatibles:
|
- compatible: must contain one of the following compatibles:
|
||||||
|
- "allwinner,sun5i-a10s-ccu"
|
||||||
|
- "allwinner,sun5i-a13-ccu"
|
||||||
- "allwinner,sun6i-a31-ccu"
|
- "allwinner,sun6i-a31-ccu"
|
||||||
- "allwinner,sun8i-a23-ccu"
|
- "allwinner,sun8i-a23-ccu"
|
||||||
- "allwinner,sun8i-a33-ccu"
|
- "allwinner,sun8i-a33-ccu"
|
||||||
|
@ -10,11 +12,13 @@ Required properties :
|
||||||
- "allwinner,sun8i-a83t-r-ccu"
|
- "allwinner,sun8i-a83t-r-ccu"
|
||||||
- "allwinner,sun8i-h3-ccu"
|
- "allwinner,sun8i-h3-ccu"
|
||||||
- "allwinner,sun8i-h3-r-ccu"
|
- "allwinner,sun8i-h3-r-ccu"
|
||||||
|
+ - "allwinner,sun8i-r40-ccu"
|
||||||
- "allwinner,sun8i-v3s-ccu"
|
- "allwinner,sun8i-v3s-ccu"
|
||||||
- "allwinner,sun9i-a80-ccu"
|
- "allwinner,sun9i-a80-ccu"
|
||||||
- "allwinner,sun50i-a64-ccu"
|
- "allwinner,sun50i-a64-ccu"
|
||||||
- "allwinner,sun50i-a64-r-ccu"
|
- "allwinner,sun50i-a64-r-ccu"
|
||||||
- "allwinner,sun50i-h5-ccu"
|
- "allwinner,sun50i-h5-ccu"
|
||||||
|
- "nextthing,gr8-ccu"
|
||||||
|
|
||||||
- reg: Must contain the registers base address and length
|
- reg: Must contain the registers base address and length
|
||||||
- clocks: phandle to the oscillators feeding the CCU. Two are needed:
|
- clocks: phandle to the oscillators feeding the CCU. Two are needed:
|
||||||
|
|
|
@ -48,6 +48,11 @@ config SUN8I_V3S_CCU
|
||||||
config SUN8I_DE2_CCU
|
config SUN8I_DE2_CCU
|
||||||
bool "Support for the Allwinner SoCs DE2 CCU"
|
bool "Support for the Allwinner SoCs DE2 CCU"
|
||||||
|
|
||||||
|
config SUN8I_R40_CCU
|
||||||
|
bool "Support for the Allwinner R40 CCU"
|
||||||
|
default MACH_SUN8I
|
||||||
|
depends on MACH_SUN8I || COMPILE_TEST
|
||||||
|
|
||||||
config SUN9I_A80_CCU
|
config SUN9I_A80_CCU
|
||||||
bool "Support for the Allwinner A80 CCU"
|
bool "Support for the Allwinner A80 CCU"
|
||||||
default MACH_SUN9I
|
default MACH_SUN9I
|
||||||
|
|
|
@ -28,6 +28,7 @@ obj-$(CONFIG_SUN8I_H3_CCU) += ccu-sun8i-h3.o
|
||||||
obj-$(CONFIG_SUN8I_V3S_CCU) += ccu-sun8i-v3s.o
|
obj-$(CONFIG_SUN8I_V3S_CCU) += ccu-sun8i-v3s.o
|
||||||
obj-$(CONFIG_SUN8I_DE2_CCU) += ccu-sun8i-de2.o
|
obj-$(CONFIG_SUN8I_DE2_CCU) += ccu-sun8i-de2.o
|
||||||
obj-$(CONFIG_SUN8I_R_CCU) += ccu-sun8i-r.o
|
obj-$(CONFIG_SUN8I_R_CCU) += ccu-sun8i-r.o
|
||||||
|
obj-$(CONFIG_SUN8I_R40_CCU) += ccu-sun8i-r40.o
|
||||||
obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80.o
|
obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80.o
|
||||||
obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-de.o
|
obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-de.o
|
||||||
obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-usb.o
|
obj-$(CONFIG_SUN9I_A80_CCU) += ccu-sun9i-a80-usb.o
|
||||||
|
|
|
@ -135,7 +135,7 @@ static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_de_clk, "pll-de",
|
||||||
static const char * const cpux_parents[] = { "osc32k", "osc24M",
|
static const char * const cpux_parents[] = { "osc32k", "osc24M",
|
||||||
"pll-cpux" , "pll-cpux" };
|
"pll-cpux" , "pll-cpux" };
|
||||||
static SUNXI_CCU_MUX(cpux_clk, "cpux", cpux_parents,
|
static SUNXI_CCU_MUX(cpux_clk, "cpux", cpux_parents,
|
||||||
0x050, 16, 2, CLK_IS_CRITICAL);
|
0x050, 16, 2, CLK_IS_CRITICAL | CLK_SET_RATE_PARENT);
|
||||||
|
|
||||||
static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x050, 0, 2, 0);
|
static SUNXI_CCU_M(axi_clk, "axi", "cpux", 0x050, 0, 2, 0);
|
||||||
|
|
||||||
|
@ -1103,6 +1103,13 @@ static const struct sunxi_ccu_desc sun50i_h5_ccu_desc = {
|
||||||
.num_resets = ARRAY_SIZE(sun50i_h5_ccu_resets),
|
.num_resets = ARRAY_SIZE(sun50i_h5_ccu_resets),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct ccu_pll_nb sun8i_h3_pll_cpu_nb = {
|
||||||
|
.common = &pll_cpux_clk.common,
|
||||||
|
/* copy from pll_cpux_clk */
|
||||||
|
.enable = BIT(31),
|
||||||
|
.lock = BIT(28),
|
||||||
|
};
|
||||||
|
|
||||||
static struct ccu_mux_nb sun8i_h3_cpu_nb = {
|
static struct ccu_mux_nb sun8i_h3_cpu_nb = {
|
||||||
.common = &cpux_clk.common,
|
.common = &cpux_clk.common,
|
||||||
.cm = &cpux_clk.mux,
|
.cm = &cpux_clk.mux,
|
||||||
|
@ -1129,6 +1136,10 @@ static void __init sunxi_h3_h5_ccu_init(struct device_node *node,
|
||||||
|
|
||||||
sunxi_ccu_probe(node, reg, desc);
|
sunxi_ccu_probe(node, reg, desc);
|
||||||
|
|
||||||
|
/* Gate then ungate PLL CPU after any rate changes */
|
||||||
|
ccu_pll_notifier_register(&sun8i_h3_pll_cpu_nb);
|
||||||
|
|
||||||
|
/* Reparent CPU during PLL CPU rate changes */
|
||||||
ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
|
ccu_mux_notifier_register(pll_cpux_clk.common.hw.clk,
|
||||||
&sun8i_h3_cpu_nb);
|
&sun8i_h3_cpu_nb);
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _CCU_SUN8I_R_H
|
#ifndef _CCU_SUN8I_R_H
|
||||||
#define _CCU_SUN8I_R_H_
|
#define _CCU_SUN8I_R_H
|
||||||
|
|
||||||
#include <dt-bindings/clock/sun8i-r-ccu.h>
|
#include <dt-bindings/clock/sun8i-r-ccu.h>
|
||||||
#include <dt-bindings/reset/sun8i-r-ccu.h>
|
#include <dt-bindings/reset/sun8i-r-ccu.h>
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,69 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2017 Icenowy Zheng <icenowy@aosc.io>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _CCU_SUN8I_R40_H_
|
||||||
|
#define _CCU_SUN8I_R40_H_
|
||||||
|
|
||||||
|
#include <dt-bindings/clock/sun8i-r40-ccu.h>
|
||||||
|
#include <dt-bindings/reset/sun8i-r40-ccu.h>
|
||||||
|
|
||||||
|
#define CLK_OSC_12M 0
|
||||||
|
#define CLK_PLL_CPU 1
|
||||||
|
#define CLK_PLL_AUDIO_BASE 2
|
||||||
|
#define CLK_PLL_AUDIO 3
|
||||||
|
#define CLK_PLL_AUDIO_2X 4
|
||||||
|
#define CLK_PLL_AUDIO_4X 5
|
||||||
|
#define CLK_PLL_AUDIO_8X 6
|
||||||
|
#define CLK_PLL_VIDEO0 7
|
||||||
|
#define CLK_PLL_VIDEO0_2X 8
|
||||||
|
#define CLK_PLL_VE 9
|
||||||
|
#define CLK_PLL_DDR0 10
|
||||||
|
#define CLK_PLL_PERIPH0 11
|
||||||
|
#define CLK_PLL_PERIPH0_SATA 12
|
||||||
|
#define CLK_PLL_PERIPH0_2X 13
|
||||||
|
#define CLK_PLL_PERIPH1 14
|
||||||
|
#define CLK_PLL_PERIPH1_2X 15
|
||||||
|
#define CLK_PLL_VIDEO1 16
|
||||||
|
#define CLK_PLL_VIDEO1_2X 17
|
||||||
|
#define CLK_PLL_SATA 18
|
||||||
|
#define CLK_PLL_SATA_OUT 19
|
||||||
|
#define CLK_PLL_GPU 20
|
||||||
|
#define CLK_PLL_MIPI 21
|
||||||
|
#define CLK_PLL_DE 22
|
||||||
|
#define CLK_PLL_DDR1 23
|
||||||
|
|
||||||
|
/* The CPU clock is exported */
|
||||||
|
|
||||||
|
#define CLK_AXI 25
|
||||||
|
#define CLK_AHB1 26
|
||||||
|
#define CLK_APB1 27
|
||||||
|
#define CLK_APB2 28
|
||||||
|
|
||||||
|
/* All the bus gates are exported */
|
||||||
|
|
||||||
|
/* The first bunch of module clocks are exported */
|
||||||
|
|
||||||
|
#define CLK_DRAM 132
|
||||||
|
|
||||||
|
/* All the DRAM gates are exported */
|
||||||
|
|
||||||
|
/* Some more module clocks are exported */
|
||||||
|
|
||||||
|
#define CLK_MBUS 155
|
||||||
|
|
||||||
|
/* Another bunch of module clocks are exported */
|
||||||
|
|
||||||
|
#define CLK_NUMBER (CLK_OUTB + 1)
|
||||||
|
|
||||||
|
#endif /* _CCU_SUN8I_R40_H_ */
|
|
@ -21,10 +21,18 @@ static unsigned long ccu_div_round_rate(struct ccu_mux_internal *mux,
|
||||||
{
|
{
|
||||||
struct ccu_div *cd = data;
|
struct ccu_div *cd = data;
|
||||||
|
|
||||||
return divider_round_rate_parent(&cd->common.hw, parent,
|
if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV)
|
||||||
|
rate *= cd->fixed_post_div;
|
||||||
|
|
||||||
|
rate = divider_round_rate_parent(&cd->common.hw, parent,
|
||||||
rate, parent_rate,
|
rate, parent_rate,
|
||||||
cd->div.table, cd->div.width,
|
cd->div.table, cd->div.width,
|
||||||
cd->div.flags);
|
cd->div.flags);
|
||||||
|
|
||||||
|
if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV)
|
||||||
|
rate /= cd->fixed_post_div;
|
||||||
|
|
||||||
|
return rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ccu_div_disable(struct clk_hw *hw)
|
static void ccu_div_disable(struct clk_hw *hw)
|
||||||
|
@ -62,8 +70,13 @@ static unsigned long ccu_div_recalc_rate(struct clk_hw *hw,
|
||||||
parent_rate = ccu_mux_helper_apply_prediv(&cd->common, &cd->mux, -1,
|
parent_rate = ccu_mux_helper_apply_prediv(&cd->common, &cd->mux, -1,
|
||||||
parent_rate);
|
parent_rate);
|
||||||
|
|
||||||
return divider_recalc_rate(hw, parent_rate, val, cd->div.table,
|
val = divider_recalc_rate(hw, parent_rate, val, cd->div.table,
|
||||||
cd->div.flags);
|
cd->div.flags);
|
||||||
|
|
||||||
|
if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV)
|
||||||
|
val /= cd->fixed_post_div;
|
||||||
|
|
||||||
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ccu_div_determine_rate(struct clk_hw *hw,
|
static int ccu_div_determine_rate(struct clk_hw *hw,
|
||||||
|
@ -86,6 +99,9 @@ static int ccu_div_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||||
parent_rate = ccu_mux_helper_apply_prediv(&cd->common, &cd->mux, -1,
|
parent_rate = ccu_mux_helper_apply_prediv(&cd->common, &cd->mux, -1,
|
||||||
parent_rate);
|
parent_rate);
|
||||||
|
|
||||||
|
if (cd->common.features & CCU_FEATURE_FIXED_POSTDIV)
|
||||||
|
rate *= cd->fixed_post_div;
|
||||||
|
|
||||||
val = divider_get_val(rate, parent_rate, cd->div.table, cd->div.width,
|
val = divider_get_val(rate, parent_rate, cd->div.table, cd->div.width,
|
||||||
cd->div.flags);
|
cd->div.flags);
|
||||||
|
|
||||||
|
|
|
@ -89,6 +89,7 @@ struct ccu_div {
|
||||||
struct ccu_div_internal div;
|
struct ccu_div_internal div;
|
||||||
struct ccu_mux_internal mux;
|
struct ccu_mux_internal mux;
|
||||||
struct ccu_common common;
|
struct ccu_common common;
|
||||||
|
unsigned int fixed_post_div;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SUNXI_CCU_DIV_TABLE_WITH_GATE(_struct, _name, _parent, _reg, \
|
#define SUNXI_CCU_DIV_TABLE_WITH_GATE(_struct, _name, _parent, _reg, \
|
||||||
|
|
|
@ -67,17 +67,17 @@ unsigned long ccu_frac_helper_read_rate(struct ccu_common *common,
|
||||||
{
|
{
|
||||||
u32 reg;
|
u32 reg;
|
||||||
|
|
||||||
printk("%s: Read fractional\n", clk_hw_get_name(&common->hw));
|
pr_debug("%s: Read fractional\n", clk_hw_get_name(&common->hw));
|
||||||
|
|
||||||
if (!(common->features & CCU_FEATURE_FRACTIONAL))
|
if (!(common->features & CCU_FEATURE_FRACTIONAL))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
printk("%s: clock is fractional (rates %lu and %lu)\n",
|
pr_debug("%s: clock is fractional (rates %lu and %lu)\n",
|
||||||
clk_hw_get_name(&common->hw), cf->rates[0], cf->rates[1]);
|
clk_hw_get_name(&common->hw), cf->rates[0], cf->rates[1]);
|
||||||
|
|
||||||
reg = readl(common->base + common->reg);
|
reg = readl(common->base + common->reg);
|
||||||
|
|
||||||
printk("%s: clock reg is 0x%x (select is 0x%x)\n",
|
pr_debug("%s: clock reg is 0x%x (select is 0x%x)\n",
|
||||||
clk_hw_get_name(&common->hw), reg, cf->select);
|
clk_hw_get_name(&common->hw), reg, cf->select);
|
||||||
|
|
||||||
return (reg & cf->select) ? cf->rates[1] : cf->rates[0];
|
return (reg & cf->select) ? cf->rates[1] : cf->rates[0];
|
||||||
|
@ -85,7 +85,7 @@ unsigned long ccu_frac_helper_read_rate(struct ccu_common *common,
|
||||||
|
|
||||||
int ccu_frac_helper_set_rate(struct ccu_common *common,
|
int ccu_frac_helper_set_rate(struct ccu_common *common,
|
||||||
struct ccu_frac_internal *cf,
|
struct ccu_frac_internal *cf,
|
||||||
unsigned long rate)
|
unsigned long rate, u32 lock)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u32 reg, sel;
|
u32 reg, sel;
|
||||||
|
@ -106,5 +106,7 @@ int ccu_frac_helper_set_rate(struct ccu_common *common,
|
||||||
writel(reg | sel, common->base + common->reg);
|
writel(reg | sel, common->base + common->reg);
|
||||||
spin_unlock_irqrestore(common->lock, flags);
|
spin_unlock_irqrestore(common->lock, flags);
|
||||||
|
|
||||||
|
ccu_helper_wait_for_lock(common, lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,6 +48,6 @@ unsigned long ccu_frac_helper_read_rate(struct ccu_common *common,
|
||||||
|
|
||||||
int ccu_frac_helper_set_rate(struct ccu_common *common,
|
int ccu_frac_helper_set_rate(struct ccu_common *common,
|
||||||
struct ccu_frac_internal *cf,
|
struct ccu_frac_internal *cf,
|
||||||
unsigned long rate);
|
unsigned long rate, u32 lock);
|
||||||
|
|
||||||
#endif /* _CCU_FRAC_H_ */
|
#endif /* _CCU_FRAC_H_ */
|
||||||
|
|
|
@ -111,10 +111,14 @@ static int ccu_mult_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u32 reg;
|
u32 reg;
|
||||||
|
|
||||||
if (ccu_frac_helper_has_rate(&cm->common, &cm->frac, rate))
|
if (ccu_frac_helper_has_rate(&cm->common, &cm->frac, rate)) {
|
||||||
return ccu_frac_helper_set_rate(&cm->common, &cm->frac, rate);
|
ccu_frac_helper_enable(&cm->common, &cm->frac);
|
||||||
else
|
|
||||||
|
return ccu_frac_helper_set_rate(&cm->common, &cm->frac,
|
||||||
|
rate, cm->lock);
|
||||||
|
} else {
|
||||||
ccu_frac_helper_disable(&cm->common, &cm->frac);
|
ccu_frac_helper_disable(&cm->common, &cm->frac);
|
||||||
|
}
|
||||||
|
|
||||||
parent_rate = ccu_mux_helper_apply_prediv(&cm->common, &cm->mux, -1,
|
parent_rate = ccu_mux_helper_apply_prediv(&cm->common, &cm->mux, -1,
|
||||||
parent_rate);
|
parent_rate);
|
||||||
|
|
|
@ -75,7 +75,7 @@ static unsigned long ccu_nkm_recalc_rate(struct clk_hw *hw,
|
||||||
unsigned long parent_rate)
|
unsigned long parent_rate)
|
||||||
{
|
{
|
||||||
struct ccu_nkm *nkm = hw_to_ccu_nkm(hw);
|
struct ccu_nkm *nkm = hw_to_ccu_nkm(hw);
|
||||||
unsigned long n, m, k;
|
unsigned long n, m, k, rate;
|
||||||
u32 reg;
|
u32 reg;
|
||||||
|
|
||||||
reg = readl(nkm->common.base + nkm->common.reg);
|
reg = readl(nkm->common.base + nkm->common.reg);
|
||||||
|
@ -98,7 +98,12 @@ static unsigned long ccu_nkm_recalc_rate(struct clk_hw *hw,
|
||||||
if (!m)
|
if (!m)
|
||||||
m++;
|
m++;
|
||||||
|
|
||||||
return parent_rate * n * k / m;
|
rate = parent_rate * n * k / m;
|
||||||
|
|
||||||
|
if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
|
||||||
|
rate /= nkm->fixed_post_div;
|
||||||
|
|
||||||
|
return rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
|
static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
|
||||||
|
@ -117,9 +122,17 @@ static unsigned long ccu_nkm_round_rate(struct ccu_mux_internal *mux,
|
||||||
_nkm.min_m = 1;
|
_nkm.min_m = 1;
|
||||||
_nkm.max_m = nkm->m.max ?: 1 << nkm->m.width;
|
_nkm.max_m = nkm->m.max ?: 1 << nkm->m.width;
|
||||||
|
|
||||||
|
if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
|
||||||
|
rate *= nkm->fixed_post_div;
|
||||||
|
|
||||||
ccu_nkm_find_best(*parent_rate, rate, &_nkm);
|
ccu_nkm_find_best(*parent_rate, rate, &_nkm);
|
||||||
|
|
||||||
return *parent_rate * _nkm.n * _nkm.k / _nkm.m;
|
rate = *parent_rate * _nkm.n * _nkm.k / _nkm.m;
|
||||||
|
|
||||||
|
if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
|
||||||
|
rate /= nkm->fixed_post_div;
|
||||||
|
|
||||||
|
return rate;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ccu_nkm_determine_rate(struct clk_hw *hw,
|
static int ccu_nkm_determine_rate(struct clk_hw *hw,
|
||||||
|
@ -139,6 +152,9 @@ static int ccu_nkm_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u32 reg;
|
u32 reg;
|
||||||
|
|
||||||
|
if (nkm->common.features & CCU_FEATURE_FIXED_POSTDIV)
|
||||||
|
rate *= nkm->fixed_post_div;
|
||||||
|
|
||||||
_nkm.min_n = nkm->n.min ?: 1;
|
_nkm.min_n = nkm->n.min ?: 1;
|
||||||
_nkm.max_n = nkm->n.max ?: 1 << nkm->n.width;
|
_nkm.max_n = nkm->n.max ?: 1 << nkm->n.width;
|
||||||
_nkm.min_k = nkm->k.min ?: 1;
|
_nkm.min_k = nkm->k.min ?: 1;
|
||||||
|
|
|
@ -34,6 +34,8 @@ struct ccu_nkm {
|
||||||
struct ccu_div_internal m;
|
struct ccu_div_internal m;
|
||||||
struct ccu_mux_internal mux;
|
struct ccu_mux_internal mux;
|
||||||
|
|
||||||
|
unsigned int fixed_post_div;
|
||||||
|
|
||||||
struct ccu_common common;
|
struct ccu_common common;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -117,10 +117,23 @@ static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u32 reg;
|
u32 reg;
|
||||||
|
|
||||||
if (ccu_frac_helper_has_rate(&nm->common, &nm->frac, rate))
|
if (ccu_frac_helper_has_rate(&nm->common, &nm->frac, rate)) {
|
||||||
return ccu_frac_helper_set_rate(&nm->common, &nm->frac, rate);
|
spin_lock_irqsave(nm->common.lock, flags);
|
||||||
else
|
|
||||||
|
/* most SoCs require M to be 0 if fractional mode is used */
|
||||||
|
reg = readl(nm->common.base + nm->common.reg);
|
||||||
|
reg &= ~GENMASK(nm->m.width + nm->m.shift - 1, nm->m.shift);
|
||||||
|
writel(reg, nm->common.base + nm->common.reg);
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(nm->common.lock, flags);
|
||||||
|
|
||||||
|
ccu_frac_helper_enable(&nm->common, &nm->frac);
|
||||||
|
|
||||||
|
return ccu_frac_helper_set_rate(&nm->common, &nm->frac,
|
||||||
|
rate, nm->lock);
|
||||||
|
} else {
|
||||||
ccu_frac_helper_disable(&nm->common, &nm->frac);
|
ccu_frac_helper_disable(&nm->common, &nm->frac);
|
||||||
|
}
|
||||||
|
|
||||||
_nm.min_n = nm->n.min ?: 1;
|
_nm.min_n = nm->n.min ?: 1;
|
||||||
_nm.max_n = nm->n.max ?: 1 << nm->n.width;
|
_nm.max_n = nm->n.max ?: 1 << nm->n.width;
|
||||||
|
|
|
@ -0,0 +1,187 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.io>
|
||||||
|
*
|
||||||
|
* This file is dual-licensed: you can use it either under the terms
|
||||||
|
* of the GPL or the X11 license, at your option. Note that this dual
|
||||||
|
* licensing only applies to this file, and not this project as a
|
||||||
|
* whole.
|
||||||
|
*
|
||||||
|
* a) This file is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This file is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* Or, alternatively,
|
||||||
|
*
|
||||||
|
* b) Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
* sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following
|
||||||
|
* conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _DT_BINDINGS_CLK_SUN8I_R40_H_
|
||||||
|
#define _DT_BINDINGS_CLK_SUN8I_R40_H_
|
||||||
|
|
||||||
|
#define CLK_CPU 24
|
||||||
|
|
||||||
|
#define CLK_BUS_MIPI_DSI 29
|
||||||
|
#define CLK_BUS_CE 30
|
||||||
|
#define CLK_BUS_DMA 31
|
||||||
|
#define CLK_BUS_MMC0 32
|
||||||
|
#define CLK_BUS_MMC1 33
|
||||||
|
#define CLK_BUS_MMC2 34
|
||||||
|
#define CLK_BUS_MMC3 35
|
||||||
|
#define CLK_BUS_NAND 36
|
||||||
|
#define CLK_BUS_DRAM 37
|
||||||
|
#define CLK_BUS_EMAC 38
|
||||||
|
#define CLK_BUS_TS 39
|
||||||
|
#define CLK_BUS_HSTIMER 40
|
||||||
|
#define CLK_BUS_SPI0 41
|
||||||
|
#define CLK_BUS_SPI1 42
|
||||||
|
#define CLK_BUS_SPI2 43
|
||||||
|
#define CLK_BUS_SPI3 44
|
||||||
|
#define CLK_BUS_SATA 45
|
||||||
|
#define CLK_BUS_OTG 46
|
||||||
|
#define CLK_BUS_EHCI0 47
|
||||||
|
#define CLK_BUS_EHCI1 48
|
||||||
|
#define CLK_BUS_EHCI2 49
|
||||||
|
#define CLK_BUS_OHCI0 50
|
||||||
|
#define CLK_BUS_OHCI1 51
|
||||||
|
#define CLK_BUS_OHCI2 52
|
||||||
|
#define CLK_BUS_VE 53
|
||||||
|
#define CLK_BUS_MP 54
|
||||||
|
#define CLK_BUS_DEINTERLACE 55
|
||||||
|
#define CLK_BUS_CSI0 56
|
||||||
|
#define CLK_BUS_CSI1 57
|
||||||
|
#define CLK_BUS_HDMI1 58
|
||||||
|
#define CLK_BUS_HDMI0 59
|
||||||
|
#define CLK_BUS_DE 60
|
||||||
|
#define CLK_BUS_TVE0 61
|
||||||
|
#define CLK_BUS_TVE1 62
|
||||||
|
#define CLK_BUS_TVE_TOP 63
|
||||||
|
#define CLK_BUS_GMAC 64
|
||||||
|
#define CLK_BUS_GPU 65
|
||||||
|
#define CLK_BUS_TVD0 66
|
||||||
|
#define CLK_BUS_TVD1 67
|
||||||
|
#define CLK_BUS_TVD2 68
|
||||||
|
#define CLK_BUS_TVD3 69
|
||||||
|
#define CLK_BUS_TVD_TOP 70
|
||||||
|
#define CLK_BUS_TCON_LCD0 71
|
||||||
|
#define CLK_BUS_TCON_LCD1 72
|
||||||
|
#define CLK_BUS_TCON_TV0 73
|
||||||
|
#define CLK_BUS_TCON_TV1 74
|
||||||
|
#define CLK_BUS_TCON_TOP 75
|
||||||
|
#define CLK_BUS_CODEC 76
|
||||||
|
#define CLK_BUS_SPDIF 77
|
||||||
|
#define CLK_BUS_AC97 78
|
||||||
|
#define CLK_BUS_PIO 79
|
||||||
|
#define CLK_BUS_IR0 80
|
||||||
|
#define CLK_BUS_IR1 81
|
||||||
|
#define CLK_BUS_THS 82
|
||||||
|
#define CLK_BUS_KEYPAD 83
|
||||||
|
#define CLK_BUS_I2S0 84
|
||||||
|
#define CLK_BUS_I2S1 85
|
||||||
|
#define CLK_BUS_I2S2 86
|
||||||
|
#define CLK_BUS_I2C0 87
|
||||||
|
#define CLK_BUS_I2C1 88
|
||||||
|
#define CLK_BUS_I2C2 89
|
||||||
|
#define CLK_BUS_I2C3 90
|
||||||
|
#define CLK_BUS_CAN 91
|
||||||
|
#define CLK_BUS_SCR 92
|
||||||
|
#define CLK_BUS_PS20 93
|
||||||
|
#define CLK_BUS_PS21 94
|
||||||
|
#define CLK_BUS_I2C4 95
|
||||||
|
#define CLK_BUS_UART0 96
|
||||||
|
#define CLK_BUS_UART1 97
|
||||||
|
#define CLK_BUS_UART2 98
|
||||||
|
#define CLK_BUS_UART3 99
|
||||||
|
#define CLK_BUS_UART4 100
|
||||||
|
#define CLK_BUS_UART5 101
|
||||||
|
#define CLK_BUS_UART6 102
|
||||||
|
#define CLK_BUS_UART7 103
|
||||||
|
#define CLK_BUS_DBG 104
|
||||||
|
|
||||||
|
#define CLK_THS 105
|
||||||
|
#define CLK_NAND 106
|
||||||
|
#define CLK_MMC0 107
|
||||||
|
#define CLK_MMC1 108
|
||||||
|
#define CLK_MMC2 109
|
||||||
|
#define CLK_MMC3 110
|
||||||
|
#define CLK_TS 111
|
||||||
|
#define CLK_CE 112
|
||||||
|
#define CLK_SPI0 113
|
||||||
|
#define CLK_SPI1 114
|
||||||
|
#define CLK_SPI2 115
|
||||||
|
#define CLK_SPI3 116
|
||||||
|
#define CLK_I2S0 117
|
||||||
|
#define CLK_I2S1 118
|
||||||
|
#define CLK_I2S2 119
|
||||||
|
#define CLK_AC97 120
|
||||||
|
#define CLK_SPDIF 121
|
||||||
|
#define CLK_KEYPAD 122
|
||||||
|
#define CLK_SATA 123
|
||||||
|
#define CLK_USB_PHY0 124
|
||||||
|
#define CLK_USB_PHY1 125
|
||||||
|
#define CLK_USB_PHY2 126
|
||||||
|
#define CLK_USB_OHCI0 127
|
||||||
|
#define CLK_USB_OHCI1 128
|
||||||
|
#define CLK_USB_OHCI2 129
|
||||||
|
#define CLK_IR0 130
|
||||||
|
#define CLK_IR1 131
|
||||||
|
|
||||||
|
#define CLK_DRAM_VE 133
|
||||||
|
#define CLK_DRAM_CSI0 134
|
||||||
|
#define CLK_DRAM_CSI1 135
|
||||||
|
#define CLK_DRAM_TS 136
|
||||||
|
#define CLK_DRAM_TVD 137
|
||||||
|
#define CLK_DRAM_MP 138
|
||||||
|
#define CLK_DRAM_DEINTERLACE 139
|
||||||
|
#define CLK_DE 140
|
||||||
|
#define CLK_MP 141
|
||||||
|
#define CLK_TCON_LCD0 142
|
||||||
|
#define CLK_TCON_LCD1 143
|
||||||
|
#define CLK_TCON_TV0 144
|
||||||
|
#define CLK_TCON_TV1 145
|
||||||
|
#define CLK_DEINTERLACE 146
|
||||||
|
#define CLK_CSI1_MCLK 147
|
||||||
|
#define CLK_CSI_SCLK 148
|
||||||
|
#define CLK_CSI0_MCLK 149
|
||||||
|
#define CLK_VE 150
|
||||||
|
#define CLK_CODEC 151
|
||||||
|
#define CLK_AVS 152
|
||||||
|
#define CLK_HDMI 153
|
||||||
|
#define CLK_HDMI_SLOW 154
|
||||||
|
|
||||||
|
#define CLK_DSI_DPHY 156
|
||||||
|
#define CLK_TVE0 157
|
||||||
|
#define CLK_TVE1 158
|
||||||
|
#define CLK_TVD0 159
|
||||||
|
#define CLK_TVD1 160
|
||||||
|
#define CLK_TVD2 161
|
||||||
|
#define CLK_TVD3 162
|
||||||
|
#define CLK_GPU 163
|
||||||
|
#define CLK_OUTA 164
|
||||||
|
#define CLK_OUTB 165
|
||||||
|
|
||||||
|
#endif /* _DT_BINDINGS_CLK_SUN8I_R40_H_ */
|
|
@ -0,0 +1,130 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2017 Icenowy Zheng <icenowy@aosc.io>
|
||||||
|
*
|
||||||
|
* This file is dual-licensed: you can use it either under the terms
|
||||||
|
* of the GPL or the X11 license, at your option. Note that this dual
|
||||||
|
* licensing only applies to this file, and not this project as a
|
||||||
|
* whole.
|
||||||
|
*
|
||||||
|
* a) This file is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This file is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* Or, alternatively,
|
||||||
|
*
|
||||||
|
* b) Permission is hereby granted, free of charge, to any person
|
||||||
|
* obtaining a copy of this software and associated documentation
|
||||||
|
* files (the "Software"), to deal in the Software without
|
||||||
|
* restriction, including without limitation the rights to use,
|
||||||
|
* copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
* sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following
|
||||||
|
* conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be
|
||||||
|
* included in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||||
|
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||||
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||||
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||||
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||||
|
* OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _DT_BINDINGS_RST_SUN8I_R40_H_
|
||||||
|
#define _DT_BINDINGS_RST_SUN8I_R40_H_
|
||||||
|
|
||||||
|
#define RST_USB_PHY0 0
|
||||||
|
#define RST_USB_PHY1 1
|
||||||
|
#define RST_USB_PHY2 2
|
||||||
|
|
||||||
|
#define RST_DRAM 3
|
||||||
|
#define RST_MBUS 4
|
||||||
|
|
||||||
|
#define RST_BUS_MIPI_DSI 5
|
||||||
|
#define RST_BUS_CE 6
|
||||||
|
#define RST_BUS_DMA 7
|
||||||
|
#define RST_BUS_MMC0 8
|
||||||
|
#define RST_BUS_MMC1 9
|
||||||
|
#define RST_BUS_MMC2 10
|
||||||
|
#define RST_BUS_MMC3 11
|
||||||
|
#define RST_BUS_NAND 12
|
||||||
|
#define RST_BUS_DRAM 13
|
||||||
|
#define RST_BUS_EMAC 14
|
||||||
|
#define RST_BUS_TS 15
|
||||||
|
#define RST_BUS_HSTIMER 16
|
||||||
|
#define RST_BUS_SPI0 17
|
||||||
|
#define RST_BUS_SPI1 18
|
||||||
|
#define RST_BUS_SPI2 19
|
||||||
|
#define RST_BUS_SPI3 20
|
||||||
|
#define RST_BUS_SATA 21
|
||||||
|
#define RST_BUS_OTG 22
|
||||||
|
#define RST_BUS_EHCI0 23
|
||||||
|
#define RST_BUS_EHCI1 24
|
||||||
|
#define RST_BUS_EHCI2 25
|
||||||
|
#define RST_BUS_OHCI0 26
|
||||||
|
#define RST_BUS_OHCI1 27
|
||||||
|
#define RST_BUS_OHCI2 28
|
||||||
|
#define RST_BUS_VE 29
|
||||||
|
#define RST_BUS_MP 30
|
||||||
|
#define RST_BUS_DEINTERLACE 31
|
||||||
|
#define RST_BUS_CSI0 32
|
||||||
|
#define RST_BUS_CSI1 33
|
||||||
|
#define RST_BUS_HDMI0 34
|
||||||
|
#define RST_BUS_HDMI1 35
|
||||||
|
#define RST_BUS_DE 36
|
||||||
|
#define RST_BUS_TVE0 37
|
||||||
|
#define RST_BUS_TVE1 38
|
||||||
|
#define RST_BUS_TVE_TOP 39
|
||||||
|
#define RST_BUS_GMAC 40
|
||||||
|
#define RST_BUS_GPU 41
|
||||||
|
#define RST_BUS_TVD0 42
|
||||||
|
#define RST_BUS_TVD1 43
|
||||||
|
#define RST_BUS_TVD2 44
|
||||||
|
#define RST_BUS_TVD3 45
|
||||||
|
#define RST_BUS_TVD_TOP 46
|
||||||
|
#define RST_BUS_TCON_LCD0 47
|
||||||
|
#define RST_BUS_TCON_LCD1 48
|
||||||
|
#define RST_BUS_TCON_TV0 49
|
||||||
|
#define RST_BUS_TCON_TV1 50
|
||||||
|
#define RST_BUS_TCON_TOP 51
|
||||||
|
#define RST_BUS_DBG 52
|
||||||
|
#define RST_BUS_LVDS 53
|
||||||
|
#define RST_BUS_CODEC 54
|
||||||
|
#define RST_BUS_SPDIF 55
|
||||||
|
#define RST_BUS_AC97 56
|
||||||
|
#define RST_BUS_IR0 57
|
||||||
|
#define RST_BUS_IR1 58
|
||||||
|
#define RST_BUS_THS 59
|
||||||
|
#define RST_BUS_KEYPAD 60
|
||||||
|
#define RST_BUS_I2S0 61
|
||||||
|
#define RST_BUS_I2S1 62
|
||||||
|
#define RST_BUS_I2S2 63
|
||||||
|
#define RST_BUS_I2C0 64
|
||||||
|
#define RST_BUS_I2C1 65
|
||||||
|
#define RST_BUS_I2C2 66
|
||||||
|
#define RST_BUS_I2C3 67
|
||||||
|
#define RST_BUS_CAN 68
|
||||||
|
#define RST_BUS_SCR 69
|
||||||
|
#define RST_BUS_PS20 70
|
||||||
|
#define RST_BUS_PS21 71
|
||||||
|
#define RST_BUS_I2C4 72
|
||||||
|
#define RST_BUS_UART0 73
|
||||||
|
#define RST_BUS_UART1 74
|
||||||
|
#define RST_BUS_UART2 75
|
||||||
|
#define RST_BUS_UART3 76
|
||||||
|
#define RST_BUS_UART4 77
|
||||||
|
#define RST_BUS_UART5 78
|
||||||
|
#define RST_BUS_UART6 79
|
||||||
|
#define RST_BUS_UART7 80
|
||||||
|
|
||||||
|
#endif /* _DT_BINDINGS_RST_SUN8I_R40_H_ */
|
Loading…
Reference in New Issue