mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-09 14:56:54 -04:00
Merge tag 'sunxi-clk-for-4.15' of https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux into clk-next
Pull Allwinner clock driver updates from Maxime Ripard: - Addition of sigma/delta modulation for the audio PLLs on the newer SoCs - A83t Display clocks supports - minor fixes that didn't have any impact on current features * tag 'sunxi-clk-for-4.15' of https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux: clk: sunxi-ng: sun4i: Export video PLLs clk: sunxi-ng: Add A83T display clocks clk: sunxi-ng: sun8i: a23: Use sigma-delta modulation for audio PLL clk: sunxi-ng: sun6i: Use sigma-delta modulation for audio PLL clk: sunxi-ng: sun5i: Use sigma-delta modulation for audio PLL clk: sunxi-ng: sun4i: Use sigma-delta modulation for audio PLL clk: sunxi-ng: sun8i: h3: Use sigma-delta modulation for audio PLL clk: sunxi-ng: nm: Add support for sigma-delta modulation clk: sunxi-ng: Add sigma-delta modulation support clk: sunxi-ng: nm: Check if requested rate is supported by fractional clock clk: sunxi-ng: sun5i: Fix bit offset of audio PLL post-divider clk: sunxi-ng: a83t: Fix invalid csi-mclk mux offset clk: sunxi-ng: sun6i: Rename HDMI DDC clock to avoid name collision clk: sunxi-ng: sun6i: Export video PLLs clk: sunxi-ng: Implement reset control status readback clk: sunxi-ng: Fix missing CLK_SET_RATE_PARENT in ccu-sun4i-a10.c clk: sunxi-ng: add CLK_SET_RATE_PARENT flag to H3 GPU clock clk: sunxi-ng: add CLK_SET_RATE_UNGATE to all H3 PLLs
This commit is contained in:
@@ -10,6 +10,7 @@ lib-$(CONFIG_SUNXI_CCU) += ccu_gate.o
|
||||
lib-$(CONFIG_SUNXI_CCU) += ccu_mux.o
|
||||
lib-$(CONFIG_SUNXI_CCU) += ccu_mult.o
|
||||
lib-$(CONFIG_SUNXI_CCU) += ccu_phase.o
|
||||
lib-$(CONFIG_SUNXI_CCU) += ccu_sdm.o
|
||||
|
||||
# Multi-factor clocks
|
||||
lib-$(CONFIG_SUNXI_CCU) += ccu_nk.o
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include "ccu_nkmp.h"
|
||||
#include "ccu_nm.h"
|
||||
#include "ccu_phase.h"
|
||||
#include "ccu_sdm.h"
|
||||
|
||||
#include "ccu-sun4i-a10.h"
|
||||
|
||||
@@ -51,16 +52,29 @@ static struct ccu_nkmp pll_core_clk = {
|
||||
* the base (2x, 4x and 8x), and one variable divider (the one true
|
||||
* pll audio).
|
||||
*
|
||||
* We don't have any need for the variable divider for now, so we just
|
||||
* hardcode it to match with the clock names.
|
||||
* With sigma-delta modulation for fractional-N on the audio PLL,
|
||||
* we have to use specific dividers. This means the variable divider
|
||||
* can no longer be used, as the audio codec requests the exact clock
|
||||
* rates we support through this mechanism. So we now hard code the
|
||||
* variable divider to 1. This means the clock rates will no longer
|
||||
* match the clock names.
|
||||
*/
|
||||
#define SUN4I_PLL_AUDIO_REG 0x008
|
||||
|
||||
static struct ccu_sdm_setting pll_audio_sdm_table[] = {
|
||||
{ .rate = 22579200, .pattern = 0xc0010d84, .m = 8, .n = 7 },
|
||||
{ .rate = 24576000, .pattern = 0xc000ac02, .m = 14, .n = 14 },
|
||||
};
|
||||
|
||||
static struct ccu_nm pll_audio_base_clk = {
|
||||
.enable = BIT(31),
|
||||
.n = _SUNXI_CCU_MULT_OFFSET(8, 7, 0),
|
||||
.m = _SUNXI_CCU_DIV_OFFSET(0, 5, 0),
|
||||
.sdm = _SUNXI_CCU_SDM(pll_audio_sdm_table, 0,
|
||||
0x00c, BIT(31)),
|
||||
.common = {
|
||||
.reg = 0x008,
|
||||
.features = CCU_FEATURE_SIGMA_DELTA_MOD,
|
||||
.hw.init = CLK_HW_INIT("pll-audio-base",
|
||||
"hosc",
|
||||
&ccu_nm_ops,
|
||||
@@ -223,7 +237,7 @@ static struct ccu_mux cpu_clk = {
|
||||
.hw.init = CLK_HW_INIT_PARENTS("cpu",
|
||||
cpu_parents,
|
||||
&ccu_mux_ops,
|
||||
CLK_IS_CRITICAL),
|
||||
CLK_SET_RATE_PARENT | CLK_IS_CRITICAL),
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1021,9 +1035,9 @@ static struct ccu_common *sun4i_sun7i_ccu_clks[] = {
|
||||
&out_b_clk.common
|
||||
};
|
||||
|
||||
/* Post-divider for pll-audio is hardcoded to 4 */
|
||||
/* Post-divider for pll-audio is hardcoded to 1 */
|
||||
static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
|
||||
"pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
|
||||
"pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
|
||||
static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
|
||||
"pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
|
||||
static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
|
||||
@@ -1420,10 +1434,10 @@ static void __init sun4i_ccu_init(struct device_node *node,
|
||||
return;
|
||||
}
|
||||
|
||||
/* Force the PLL-Audio-1x divider to 4 */
|
||||
/* Force the PLL-Audio-1x divider to 1 */
|
||||
val = readl(reg + SUN4I_PLL_AUDIO_REG);
|
||||
val &= ~GENMASK(29, 26);
|
||||
writel(val | (4 << 26), reg + SUN4I_PLL_AUDIO_REG);
|
||||
writel(val | (1 << 26), reg + SUN4I_PLL_AUDIO_REG);
|
||||
|
||||
/*
|
||||
* Use the peripheral PLL6 as the AHB parent, instead of CPU /
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
#define CLK_PLL_AUDIO_4X 6
|
||||
#define CLK_PLL_AUDIO_8X 7
|
||||
#define CLK_PLL_VIDEO0 8
|
||||
#define CLK_PLL_VIDEO0_2X 9
|
||||
/* The PLL_VIDEO0_2X clock is exported */
|
||||
#define CLK_PLL_VE 10
|
||||
#define CLK_PLL_DDR_BASE 11
|
||||
#define CLK_PLL_DDR 12
|
||||
@@ -38,7 +38,7 @@
|
||||
#define CLK_PLL_PERIPH 15
|
||||
#define CLK_PLL_PERIPH_SATA 16
|
||||
#define CLK_PLL_VIDEO1 17
|
||||
#define CLK_PLL_VIDEO1_2X 18
|
||||
/* The PLL_VIDEO1_2X clock is exported */
|
||||
#define CLK_PLL_GPU 19
|
||||
|
||||
/* The CPU clock is exported */
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "ccu_nkmp.h"
|
||||
#include "ccu_nm.h"
|
||||
#include "ccu_phase.h"
|
||||
#include "ccu_sdm.h"
|
||||
|
||||
#include "ccu-sun5i.h"
|
||||
|
||||
@@ -49,11 +50,20 @@ static struct ccu_nkmp pll_core_clk = {
|
||||
* the base (2x, 4x and 8x), and one variable divider (the one true
|
||||
* pll audio).
|
||||
*
|
||||
* We don't have any need for the variable divider for now, so we just
|
||||
* hardcode it to match with the clock names
|
||||
* With sigma-delta modulation for fractional-N on the audio PLL,
|
||||
* we have to use specific dividers. This means the variable divider
|
||||
* can no longer be used, as the audio codec requests the exact clock
|
||||
* rates we support through this mechanism. So we now hard code the
|
||||
* variable divider to 1. This means the clock rates will no longer
|
||||
* match the clock names.
|
||||
*/
|
||||
#define SUN5I_PLL_AUDIO_REG 0x008
|
||||
|
||||
static struct ccu_sdm_setting pll_audio_sdm_table[] = {
|
||||
{ .rate = 22579200, .pattern = 0xc0010d84, .m = 8, .n = 7 },
|
||||
{ .rate = 24576000, .pattern = 0xc000ac02, .m = 14, .n = 14 },
|
||||
};
|
||||
|
||||
static struct ccu_nm pll_audio_base_clk = {
|
||||
.enable = BIT(31),
|
||||
.n = _SUNXI_CCU_MULT_OFFSET(8, 7, 0),
|
||||
@@ -63,8 +73,11 @@ static struct ccu_nm pll_audio_base_clk = {
|
||||
* offset
|
||||
*/
|
||||
.m = _SUNXI_CCU_DIV_OFFSET(0, 5, 0),
|
||||
.sdm = _SUNXI_CCU_SDM(pll_audio_sdm_table, 0,
|
||||
0x00c, BIT(31)),
|
||||
.common = {
|
||||
.reg = 0x008,
|
||||
.features = CCU_FEATURE_SIGMA_DELTA_MOD,
|
||||
.hw.init = CLK_HW_INIT("pll-audio-base",
|
||||
"hosc",
|
||||
&ccu_nm_ops,
|
||||
@@ -597,9 +610,9 @@ static struct ccu_common *sun5i_a10s_ccu_clks[] = {
|
||||
&iep_clk.common,
|
||||
};
|
||||
|
||||
/* We hardcode the divider to 4 for now */
|
||||
/* We hardcode the divider to 1 for now */
|
||||
static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
|
||||
"pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
|
||||
"pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
|
||||
static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
|
||||
"pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
|
||||
static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
|
||||
@@ -980,10 +993,10 @@ static void __init sun5i_ccu_init(struct device_node *node,
|
||||
return;
|
||||
}
|
||||
|
||||
/* Force the PLL-Audio-1x divider to 4 */
|
||||
/* Force the PLL-Audio-1x divider to 1 */
|
||||
val = readl(reg + SUN5I_PLL_AUDIO_REG);
|
||||
val &= ~GENMASK(19, 16);
|
||||
writel(val | (3 << 16), reg + SUN5I_PLL_AUDIO_REG);
|
||||
val &= ~GENMASK(29, 26);
|
||||
writel(val | (0 << 26), reg + SUN5I_PLL_AUDIO_REG);
|
||||
|
||||
/*
|
||||
* Use the peripheral PLL as the AHB parent, instead of CPU /
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "ccu_nkmp.h"
|
||||
#include "ccu_nm.h"
|
||||
#include "ccu_phase.h"
|
||||
#include "ccu_sdm.h"
|
||||
|
||||
#include "ccu-sun6i-a31.h"
|
||||
|
||||
@@ -48,18 +49,29 @@ static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_cpu_clk, "pll-cpu",
|
||||
* the base (2x, 4x and 8x), and one variable divider (the one true
|
||||
* pll audio).
|
||||
*
|
||||
* We don't have any need for the variable divider for now, so we just
|
||||
* hardcode it to match with the clock names
|
||||
* With sigma-delta modulation for fractional-N on the audio PLL,
|
||||
* we have to use specific dividers. This means the variable divider
|
||||
* can no longer be used, as the audio codec requests the exact clock
|
||||
* rates we support through this mechanism. So we now hard code the
|
||||
* variable divider to 1. This means the clock rates will no longer
|
||||
* match the clock names.
|
||||
*/
|
||||
#define SUN6I_A31_PLL_AUDIO_REG 0x008
|
||||
|
||||
static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
|
||||
"osc24M", 0x008,
|
||||
8, 7, /* N */
|
||||
0, 5, /* M */
|
||||
BIT(31), /* gate */
|
||||
BIT(28), /* lock */
|
||||
CLK_SET_RATE_UNGATE);
|
||||
static struct ccu_sdm_setting pll_audio_sdm_table[] = {
|
||||
{ .rate = 22579200, .pattern = 0xc0010d84, .m = 8, .n = 7 },
|
||||
{ .rate = 24576000, .pattern = 0xc000ac02, .m = 14, .n = 14 },
|
||||
};
|
||||
|
||||
static SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
|
||||
"osc24M", 0x008,
|
||||
8, 7, /* N */
|
||||
0, 5, /* M */
|
||||
pll_audio_sdm_table, BIT(24),
|
||||
0x284, BIT(31),
|
||||
BIT(31), /* gate */
|
||||
BIT(28), /* lock */
|
||||
CLK_SET_RATE_UNGATE);
|
||||
|
||||
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video0_clk, "pll-video0",
|
||||
"osc24M", 0x010,
|
||||
@@ -608,7 +620,7 @@ static SUNXI_CCU_M_WITH_MUX_GATE(hdmi_clk, "hdmi", lcd_ch1_parents,
|
||||
0x150, 0, 4, 24, 2, BIT(31),
|
||||
CLK_SET_RATE_PARENT);
|
||||
|
||||
static SUNXI_CCU_GATE(hdmi_ddc_clk, "hdmi-ddc", "osc24M", 0x150, BIT(30), 0);
|
||||
static SUNXI_CCU_GATE(hdmi_ddc_clk, "ddc", "osc24M", 0x150, BIT(30), 0);
|
||||
|
||||
static SUNXI_CCU_GATE(ps_clk, "ps", "lcd1-ch1", 0x140, BIT(31), 0);
|
||||
|
||||
@@ -950,9 +962,9 @@ static struct ccu_common *sun6i_a31_ccu_clks[] = {
|
||||
&out_c_clk.common,
|
||||
};
|
||||
|
||||
/* We hardcode the divider to 4 for now */
|
||||
/* We hardcode the divider to 1 for now */
|
||||
static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
|
||||
"pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
|
||||
"pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
|
||||
static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
|
||||
"pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
|
||||
static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
|
||||
@@ -1221,10 +1233,10 @@ static void __init sun6i_a31_ccu_setup(struct device_node *node)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Force the PLL-Audio-1x divider to 4 */
|
||||
/* Force the PLL-Audio-1x divider to 1 */
|
||||
val = readl(reg + SUN6I_A31_PLL_AUDIO_REG);
|
||||
val &= ~GENMASK(19, 16);
|
||||
writel(val | (3 << 16), reg + SUN6I_A31_PLL_AUDIO_REG);
|
||||
writel(val | (0 << 16), reg + SUN6I_A31_PLL_AUDIO_REG);
|
||||
|
||||
/* Force PLL-MIPI to MIPI mode */
|
||||
val = readl(reg + SUN6I_A31_PLL_MIPI_REG);
|
||||
|
||||
@@ -27,7 +27,9 @@
|
||||
#define CLK_PLL_AUDIO_4X 4
|
||||
#define CLK_PLL_AUDIO_8X 5
|
||||
#define CLK_PLL_VIDEO0 6
|
||||
#define CLK_PLL_VIDEO0_2X 7
|
||||
|
||||
/* The PLL_VIDEO0_2X clock is exported */
|
||||
|
||||
#define CLK_PLL_VE 8
|
||||
#define CLK_PLL_DDR 9
|
||||
|
||||
@@ -35,7 +37,9 @@
|
||||
|
||||
#define CLK_PLL_PERIPH_2X 11
|
||||
#define CLK_PLL_VIDEO1 12
|
||||
#define CLK_PLL_VIDEO1_2X 13
|
||||
|
||||
/* The PLL_VIDEO1_2X clock is exported */
|
||||
|
||||
#define CLK_PLL_GPU 14
|
||||
#define CLK_PLL_MIPI 15
|
||||
#define CLK_PLL9 16
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "ccu_nkmp.h"
|
||||
#include "ccu_nm.h"
|
||||
#include "ccu_phase.h"
|
||||
#include "ccu_sdm.h"
|
||||
|
||||
#include "ccu-sun8i-a23-a33.h"
|
||||
|
||||
@@ -52,18 +53,29 @@ static struct ccu_nkmp pll_cpux_clk = {
|
||||
* the base (2x, 4x and 8x), and one variable divider (the one true
|
||||
* pll audio).
|
||||
*
|
||||
* We don't have any need for the variable divider for now, so we just
|
||||
* hardcode it to match with the clock names
|
||||
* With sigma-delta modulation for fractional-N on the audio PLL,
|
||||
* we have to use specific dividers. This means the variable divider
|
||||
* can no longer be used, as the audio codec requests the exact clock
|
||||
* rates we support through this mechanism. So we now hard code the
|
||||
* variable divider to 1. This means the clock rates will no longer
|
||||
* match the clock names.
|
||||
*/
|
||||
#define SUN8I_A23_PLL_AUDIO_REG 0x008
|
||||
|
||||
static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
|
||||
"osc24M", 0x008,
|
||||
8, 7, /* N */
|
||||
0, 5, /* M */
|
||||
BIT(31), /* gate */
|
||||
BIT(28), /* lock */
|
||||
CLK_SET_RATE_UNGATE);
|
||||
static struct ccu_sdm_setting pll_audio_sdm_table[] = {
|
||||
{ .rate = 22579200, .pattern = 0xc0010d84, .m = 8, .n = 7 },
|
||||
{ .rate = 24576000, .pattern = 0xc000ac02, .m = 14, .n = 14 },
|
||||
};
|
||||
|
||||
static SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
|
||||
"osc24M", 0x008,
|
||||
8, 7, /* N */
|
||||
0, 5, /* M */
|
||||
pll_audio_sdm_table, BIT(24),
|
||||
0x284, BIT(31),
|
||||
BIT(31), /* gate */
|
||||
BIT(28), /* lock */
|
||||
CLK_SET_RATE_UNGATE);
|
||||
|
||||
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video_clk, "pll-video",
|
||||
"osc24M", 0x010,
|
||||
@@ -538,9 +550,9 @@ static struct ccu_common *sun8i_a23_ccu_clks[] = {
|
||||
&ats_clk.common,
|
||||
};
|
||||
|
||||
/* We hardcode the divider to 4 for now */
|
||||
/* We hardcode the divider to 1 for now */
|
||||
static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
|
||||
"pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
|
||||
"pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
|
||||
static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
|
||||
"pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
|
||||
static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
|
||||
@@ -720,10 +732,10 @@ static void __init sun8i_a23_ccu_setup(struct device_node *node)
|
||||
return;
|
||||
}
|
||||
|
||||
/* Force the PLL-Audio-1x divider to 4 */
|
||||
/* Force the PLL-Audio-1x divider to 1 */
|
||||
val = readl(reg + SUN8I_A23_PLL_AUDIO_REG);
|
||||
val &= ~GENMASK(19, 16);
|
||||
writel(val | (3 << 16), reg + SUN8I_A23_PLL_AUDIO_REG);
|
||||
writel(val | (0 << 16), reg + SUN8I_A23_PLL_AUDIO_REG);
|
||||
|
||||
/* Force PLL-MIPI to MIPI mode */
|
||||
val = readl(reg + SUN8I_A23_PLL_MIPI_REG);
|
||||
|
||||
@@ -506,7 +506,7 @@ static SUNXI_CCU_M_WITH_MUX_TABLE_GATE(csi_mclk_clk, "csi-mclk",
|
||||
csi_mclk_parents, csi_mclk_table,
|
||||
0x134,
|
||||
0, 5, /* M */
|
||||
10, 3, /* mux */
|
||||
8, 3, /* mux */
|
||||
BIT(15), /* gate */
|
||||
0);
|
||||
|
||||
|
||||
@@ -41,11 +41,16 @@ 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);
|
||||
|
||||
static SUNXI_CCU_M(mixer0_div_a83_clk, "mixer0-div", "pll-de", 0x0c, 0, 4,
|
||||
CLK_SET_RATE_PARENT);
|
||||
static SUNXI_CCU_M(mixer1_div_a83_clk, "mixer1-div", "pll-de", 0x0c, 4, 4,
|
||||
CLK_SET_RATE_PARENT);
|
||||
static SUNXI_CCU_M(wb_div_a83_clk, "wb-div", "pll-de", 0x0c, 8, 4,
|
||||
CLK_SET_RATE_PARENT);
|
||||
|
||||
static struct ccu_common *sun8i_a83t_de2_clks[] = {
|
||||
&mixer0_clk.common,
|
||||
&mixer1_clk.common,
|
||||
@@ -55,9 +60,9 @@ static struct ccu_common *sun8i_a83t_de2_clks[] = {
|
||||
&bus_mixer1_clk.common,
|
||||
&bus_wb_clk.common,
|
||||
|
||||
&mixer0_div_clk.common,
|
||||
&mixer1_div_clk.common,
|
||||
&wb_div_clk.common,
|
||||
&mixer0_div_a83_clk.common,
|
||||
&mixer1_div_a83_clk.common,
|
||||
&wb_div_a83_clk.common,
|
||||
};
|
||||
|
||||
static struct ccu_common *sun8i_v3s_de2_clks[] = {
|
||||
@@ -81,9 +86,9 @@ static struct clk_hw_onecell_data sun8i_a83t_de2_hw_clks = {
|
||||
[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,
|
||||
[CLK_MIXER0_DIV] = &mixer0_div_a83_clk.common.hw,
|
||||
[CLK_MIXER1_DIV] = &mixer1_div_a83_clk.common.hw,
|
||||
[CLK_WB_DIV] = &wb_div_a83_clk.common.hw,
|
||||
},
|
||||
.num = CLK_NUMBER,
|
||||
};
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include "ccu_nkmp.h"
|
||||
#include "ccu_nm.h"
|
||||
#include "ccu_phase.h"
|
||||
#include "ccu_sdm.h"
|
||||
|
||||
#include "ccu-sun8i-h3.h"
|
||||
|
||||
@@ -37,25 +38,36 @@ static SUNXI_CCU_NKMP_WITH_GATE_LOCK(pll_cpux_clk, "pll-cpux",
|
||||
16, 2, /* P */
|
||||
BIT(31), /* gate */
|
||||
BIT(28), /* lock */
|
||||
0);
|
||||
CLK_SET_RATE_UNGATE);
|
||||
|
||||
/*
|
||||
* The Audio PLL is supposed to have 4 outputs: 3 fixed factors from
|
||||
* the base (2x, 4x and 8x), and one variable divider (the one true
|
||||
* pll audio).
|
||||
*
|
||||
* We don't have any need for the variable divider for now, so we just
|
||||
* hardcode it to match with the clock names
|
||||
* With sigma-delta modulation for fractional-N on the audio PLL,
|
||||
* we have to use specific dividers. This means the variable divider
|
||||
* can no longer be used, as the audio codec requests the exact clock
|
||||
* rates we support through this mechanism. So we now hard code the
|
||||
* variable divider to 1. This means the clock rates will no longer
|
||||
* match the clock names.
|
||||
*/
|
||||
#define SUN8I_H3_PLL_AUDIO_REG 0x008
|
||||
|
||||
static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
|
||||
"osc24M", 0x008,
|
||||
8, 7, /* N */
|
||||
0, 5, /* M */
|
||||
BIT(31), /* gate */
|
||||
BIT(28), /* lock */
|
||||
0);
|
||||
static struct ccu_sdm_setting pll_audio_sdm_table[] = {
|
||||
{ .rate = 22579200, .pattern = 0xc0010d84, .m = 8, .n = 7 },
|
||||
{ .rate = 24576000, .pattern = 0xc000ac02, .m = 14, .n = 14 },
|
||||
};
|
||||
|
||||
static SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
|
||||
"osc24M", 0x008,
|
||||
8, 7, /* N */
|
||||
0, 5, /* M */
|
||||
pll_audio_sdm_table, BIT(24),
|
||||
0x284, BIT(31),
|
||||
BIT(31), /* gate */
|
||||
BIT(28), /* lock */
|
||||
CLK_SET_RATE_UNGATE);
|
||||
|
||||
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video_clk, "pll-video",
|
||||
"osc24M", 0x0010,
|
||||
@@ -67,7 +79,7 @@ static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video_clk, "pll-video",
|
||||
297000000, /* frac rate 1 */
|
||||
BIT(31), /* gate */
|
||||
BIT(28), /* lock */
|
||||
0);
|
||||
CLK_SET_RATE_UNGATE);
|
||||
|
||||
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
|
||||
"osc24M", 0x0018,
|
||||
@@ -79,7 +91,7 @@ static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
|
||||
297000000, /* frac rate 1 */
|
||||
BIT(31), /* gate */
|
||||
BIT(28), /* lock */
|
||||
0);
|
||||
CLK_SET_RATE_UNGATE);
|
||||
|
||||
static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_ddr_clk, "pll-ddr",
|
||||
"osc24M", 0x020,
|
||||
@@ -88,7 +100,7 @@ static SUNXI_CCU_NKM_WITH_GATE_LOCK(pll_ddr_clk, "pll-ddr",
|
||||
0, 2, /* M */
|
||||
BIT(31), /* gate */
|
||||
BIT(28), /* lock */
|
||||
0);
|
||||
CLK_SET_RATE_UNGATE);
|
||||
|
||||
static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph0_clk, "pll-periph0",
|
||||
"osc24M", 0x028,
|
||||
@@ -97,7 +109,7 @@ static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph0_clk, "pll-periph0",
|
||||
BIT(31), /* gate */
|
||||
BIT(28), /* lock */
|
||||
2, /* post-div */
|
||||
0);
|
||||
CLK_SET_RATE_UNGATE);
|
||||
|
||||
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu",
|
||||
"osc24M", 0x0038,
|
||||
@@ -109,7 +121,7 @@ static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu",
|
||||
297000000, /* frac rate 1 */
|
||||
BIT(31), /* gate */
|
||||
BIT(28), /* lock */
|
||||
0);
|
||||
CLK_SET_RATE_UNGATE);
|
||||
|
||||
static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph1_clk, "pll-periph1",
|
||||
"osc24M", 0x044,
|
||||
@@ -118,7 +130,7 @@ static SUNXI_CCU_NK_WITH_GATE_LOCK_POSTDIV(pll_periph1_clk, "pll-periph1",
|
||||
BIT(31), /* gate */
|
||||
BIT(28), /* lock */
|
||||
2, /* post-div */
|
||||
0);
|
||||
CLK_SET_RATE_UNGATE);
|
||||
|
||||
static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_de_clk, "pll-de",
|
||||
"osc24M", 0x0048,
|
||||
@@ -130,7 +142,7 @@ static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_de_clk, "pll-de",
|
||||
297000000, /* frac rate 1 */
|
||||
BIT(31), /* gate */
|
||||
BIT(28), /* lock */
|
||||
0);
|
||||
CLK_SET_RATE_UNGATE);
|
||||
|
||||
static const char * const cpux_parents[] = { "osc32k", "osc24M",
|
||||
"pll-cpux" , "pll-cpux" };
|
||||
@@ -484,7 +496,7 @@ static SUNXI_CCU_M_WITH_MUX_GATE(mbus_clk, "mbus", mbus_parents,
|
||||
0x15c, 0, 3, 24, 2, BIT(31), CLK_IS_CRITICAL);
|
||||
|
||||
static SUNXI_CCU_M_WITH_GATE(gpu_clk, "gpu", "pll-gpu",
|
||||
0x1a0, 0, 3, BIT(31), 0);
|
||||
0x1a0, 0, 3, BIT(31), CLK_SET_RATE_PARENT);
|
||||
|
||||
static struct ccu_common *sun8i_h3_ccu_clks[] = {
|
||||
&pll_cpux_clk.common,
|
||||
@@ -707,9 +719,9 @@ static struct ccu_common *sun50i_h5_ccu_clks[] = {
|
||||
&gpu_clk.common,
|
||||
};
|
||||
|
||||
/* We hardcode the divider to 4 for now */
|
||||
/* We hardcode the divider to 1 for now */
|
||||
static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
|
||||
"pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
|
||||
"pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
|
||||
static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
|
||||
"pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
|
||||
static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
|
||||
@@ -1129,10 +1141,10 @@ static void __init sunxi_h3_h5_ccu_init(struct device_node *node,
|
||||
return;
|
||||
}
|
||||
|
||||
/* Force the PLL-Audio-1x divider to 4 */
|
||||
/* Force the PLL-Audio-1x divider to 1 */
|
||||
val = readl(reg + SUN8I_H3_PLL_AUDIO_REG);
|
||||
val &= ~GENMASK(19, 16);
|
||||
writel(val | (3 << 16), reg + SUN8I_H3_PLL_AUDIO_REG);
|
||||
writel(val | (0 << 16), reg + SUN8I_H3_PLL_AUDIO_REG);
|
||||
|
||||
sunxi_ccu_probe(node, reg, desc);
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#define CCU_FEATURE_ALL_PREDIV BIT(4)
|
||||
#define CCU_FEATURE_LOCK_REG BIT(5)
|
||||
#define CCU_FEATURE_MMC_TIMING_SWITCH BIT(6)
|
||||
#define CCU_FEATURE_SIGMA_DELTA_MOD BIT(7)
|
||||
|
||||
/* MMC timing mode switch bit */
|
||||
#define CCU_MMC_NEW_TIMING_MODE BIT(30)
|
||||
|
||||
@@ -90,6 +90,14 @@ 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;
|
||||
}
|
||||
|
||||
return parent_rate * n / m;
|
||||
}
|
||||
|
||||
@@ -99,6 +107,12 @@ 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))
|
||||
return rate;
|
||||
|
||||
if (ccu_sdm_helper_has_rate(&nm->common, &nm->sdm, rate))
|
||||
return rate;
|
||||
|
||||
_nm.min_n = nm->n.min ?: 1;
|
||||
_nm.max_n = nm->n.max ?: 1 << nm->n.width;
|
||||
_nm.min_m = 1;
|
||||
@@ -140,7 +154,16 @@ static int ccu_nm_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
_nm.min_m = 1;
|
||||
_nm.max_m = nm->m.max ?: 1 << nm->m.width;
|
||||
|
||||
ccu_nm_find_best(parent_rate, rate, &_nm);
|
||||
if (ccu_sdm_helper_has_rate(&nm->common, &nm->sdm, rate)) {
|
||||
ccu_sdm_helper_enable(&nm->common, &nm->sdm, rate);
|
||||
|
||||
/* Sigma delta modulation requires specific N and M factors */
|
||||
ccu_sdm_helper_get_factors(&nm->common, &nm->sdm, rate,
|
||||
&_nm.m, &_nm.n);
|
||||
} else {
|
||||
ccu_sdm_helper_disable(&nm->common, &nm->sdm);
|
||||
ccu_nm_find_best(parent_rate, rate, &_nm);
|
||||
}
|
||||
|
||||
spin_lock_irqsave(nm->common.lock, flags);
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "ccu_div.h"
|
||||
#include "ccu_frac.h"
|
||||
#include "ccu_mult.h"
|
||||
#include "ccu_sdm.h"
|
||||
|
||||
/*
|
||||
* struct ccu_nm - Definition of an N-M clock
|
||||
@@ -33,10 +34,34 @@ struct ccu_nm {
|
||||
struct ccu_mult_internal n;
|
||||
struct ccu_div_internal m;
|
||||
struct ccu_frac_internal frac;
|
||||
struct ccu_sdm_internal sdm;
|
||||
|
||||
struct ccu_common common;
|
||||
};
|
||||
|
||||
#define SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(_struct, _name, _parent, _reg, \
|
||||
_nshift, _nwidth, \
|
||||
_mshift, _mwidth, \
|
||||
_sdm_table, _sdm_en, \
|
||||
_sdm_reg, _sdm_reg_en, \
|
||||
_gate, _lock, _flags) \
|
||||
struct ccu_nm _struct = { \
|
||||
.enable = _gate, \
|
||||
.lock = _lock, \
|
||||
.n = _SUNXI_CCU_MULT(_nshift, _nwidth), \
|
||||
.m = _SUNXI_CCU_DIV(_mshift, _mwidth), \
|
||||
.sdm = _SUNXI_CCU_SDM(_sdm_table, _sdm_en, \
|
||||
_sdm_reg, _sdm_reg_en),\
|
||||
.common = { \
|
||||
.reg = _reg, \
|
||||
.features = CCU_FEATURE_SIGMA_DELTA_MOD, \
|
||||
.hw.init = CLK_HW_INIT(_name, \
|
||||
_parent, \
|
||||
&ccu_nm_ops, \
|
||||
_flags), \
|
||||
}, \
|
||||
}
|
||||
|
||||
#define SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(_struct, _name, _parent, _reg, \
|
||||
_nshift, _nwidth, \
|
||||
_mshift, _mwidth, \
|
||||
|
||||
@@ -60,8 +60,22 @@ static int ccu_reset_reset(struct reset_controller_dev *rcdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ccu_reset_status(struct reset_controller_dev *rcdev,
|
||||
unsigned long id)
|
||||
{
|
||||
struct ccu_reset *ccu = rcdev_to_ccu_reset(rcdev);
|
||||
const struct ccu_reset_map *map = &ccu->reset_map[id];
|
||||
|
||||
/*
|
||||
* The reset control API expects 0 if reset is not asserted,
|
||||
* which is the opposite of what our hardware uses.
|
||||
*/
|
||||
return !(map->bit & readl(ccu->base + map->reg));
|
||||
}
|
||||
|
||||
const struct reset_control_ops ccu_reset_ops = {
|
||||
.assert = ccu_reset_assert,
|
||||
.deassert = ccu_reset_deassert,
|
||||
.reset = ccu_reset_reset,
|
||||
.status = ccu_reset_status,
|
||||
};
|
||||
|
||||
158
drivers/clk/sunxi-ng/ccu_sdm.c
Normal file
158
drivers/clk/sunxi-ng/ccu_sdm.c
Normal file
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright (C) 2017 Chen-Yu Tsai <wens@csie.org>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
#include "ccu_sdm.h"
|
||||
|
||||
bool ccu_sdm_helper_is_enabled(struct ccu_common *common,
|
||||
struct ccu_sdm_internal *sdm)
|
||||
{
|
||||
if (!(common->features & CCU_FEATURE_SIGMA_DELTA_MOD))
|
||||
return false;
|
||||
|
||||
if (sdm->enable && !(readl(common->base + common->reg) & sdm->enable))
|
||||
return false;
|
||||
|
||||
return !!(readl(common->base + sdm->tuning_reg) & sdm->tuning_enable);
|
||||
}
|
||||
|
||||
void ccu_sdm_helper_enable(struct ccu_common *common,
|
||||
struct ccu_sdm_internal *sdm,
|
||||
unsigned long rate)
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned int i;
|
||||
u32 reg;
|
||||
|
||||
if (!(common->features & CCU_FEATURE_SIGMA_DELTA_MOD))
|
||||
return;
|
||||
|
||||
/* Set the pattern */
|
||||
for (i = 0; i < sdm->table_size; i++)
|
||||
if (sdm->table[i].rate == rate)
|
||||
writel(sdm->table[i].pattern,
|
||||
common->base + sdm->tuning_reg);
|
||||
|
||||
/* Make sure SDM is enabled */
|
||||
spin_lock_irqsave(common->lock, flags);
|
||||
reg = readl(common->base + sdm->tuning_reg);
|
||||
writel(reg | sdm->tuning_enable, common->base + sdm->tuning_reg);
|
||||
spin_unlock_irqrestore(common->lock, flags);
|
||||
|
||||
spin_lock_irqsave(common->lock, flags);
|
||||
reg = readl(common->base + common->reg);
|
||||
writel(reg | sdm->enable, common->base + common->reg);
|
||||
spin_unlock_irqrestore(common->lock, flags);
|
||||
}
|
||||
|
||||
void ccu_sdm_helper_disable(struct ccu_common *common,
|
||||
struct ccu_sdm_internal *sdm)
|
||||
{
|
||||
unsigned long flags;
|
||||
u32 reg;
|
||||
|
||||
if (!(common->features & CCU_FEATURE_SIGMA_DELTA_MOD))
|
||||
return;
|
||||
|
||||
spin_lock_irqsave(common->lock, flags);
|
||||
reg = readl(common->base + common->reg);
|
||||
writel(reg & ~sdm->enable, common->base + common->reg);
|
||||
spin_unlock_irqrestore(common->lock, flags);
|
||||
|
||||
spin_lock_irqsave(common->lock, flags);
|
||||
reg = readl(common->base + sdm->tuning_reg);
|
||||
writel(reg & ~sdm->tuning_enable, common->base + sdm->tuning_reg);
|
||||
spin_unlock_irqrestore(common->lock, flags);
|
||||
}
|
||||
|
||||
/*
|
||||
* Sigma delta modulation provides a way to do fractional-N frequency
|
||||
* synthesis, in essence allowing the PLL to output any frequency
|
||||
* within its operational range. On earlier SoCs such as the A10/A20,
|
||||
* some PLLs support this. On later SoCs, all PLLs support this.
|
||||
*
|
||||
* The datasheets do not explain what the "wave top" and "wave bottom"
|
||||
* parameters mean or do, nor how to calculate the effective output
|
||||
* frequency. The only examples (and real world usage) are for the audio
|
||||
* PLL to generate 24.576 and 22.5792 MHz clock rates used by the audio
|
||||
* peripherals. The author lacks the underlying domain knowledge to
|
||||
* pursue this.
|
||||
*
|
||||
* The goal and function of the following code is to support the two
|
||||
* clock rates used by the audio subsystem, allowing for proper audio
|
||||
* playback and capture without any pitch or speed changes.
|
||||
*/
|
||||
bool ccu_sdm_helper_has_rate(struct ccu_common *common,
|
||||
struct ccu_sdm_internal *sdm,
|
||||
unsigned long rate)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (!(common->features & CCU_FEATURE_SIGMA_DELTA_MOD))
|
||||
return false;
|
||||
|
||||
for (i = 0; i < sdm->table_size; i++)
|
||||
if (sdm->table[i].rate == rate)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned long ccu_sdm_helper_read_rate(struct ccu_common *common,
|
||||
struct ccu_sdm_internal *sdm,
|
||||
u32 m, u32 n)
|
||||
{
|
||||
unsigned int i;
|
||||
u32 reg;
|
||||
|
||||
pr_debug("%s: Read sigma-delta modulation setting\n",
|
||||
clk_hw_get_name(&common->hw));
|
||||
|
||||
if (!(common->features & CCU_FEATURE_SIGMA_DELTA_MOD))
|
||||
return 0;
|
||||
|
||||
pr_debug("%s: clock is sigma-delta modulated\n",
|
||||
clk_hw_get_name(&common->hw));
|
||||
|
||||
reg = readl(common->base + sdm->tuning_reg);
|
||||
|
||||
pr_debug("%s: pattern reg is 0x%x",
|
||||
clk_hw_get_name(&common->hw), reg);
|
||||
|
||||
for (i = 0; i < sdm->table_size; i++)
|
||||
if (sdm->table[i].pattern == reg &&
|
||||
sdm->table[i].m == m && sdm->table[i].n == n)
|
||||
return sdm->table[i].rate;
|
||||
|
||||
/* We can't calculate the effective clock rate, so just fail. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ccu_sdm_helper_get_factors(struct ccu_common *common,
|
||||
struct ccu_sdm_internal *sdm,
|
||||
unsigned long rate,
|
||||
unsigned long *m, unsigned long *n)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (!(common->features & CCU_FEATURE_SIGMA_DELTA_MOD))
|
||||
return -EINVAL;
|
||||
|
||||
for (i = 0; i < sdm->table_size; i++)
|
||||
if (sdm->table[i].rate == rate) {
|
||||
*m = sdm->table[i].m;
|
||||
*n = sdm->table[i].n;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* nothing found */
|
||||
return -EINVAL;
|
||||
}
|
||||
80
drivers/clk/sunxi-ng/ccu_sdm.h
Normal file
80
drivers/clk/sunxi-ng/ccu_sdm.h
Normal file
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* Copyright (c) 2017 Chen-Yu Tsai. All rights reserved.
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* 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_SDM_H
|
||||
#define _CCU_SDM_H
|
||||
|
||||
#include <linux/clk-provider.h>
|
||||
|
||||
#include "ccu_common.h"
|
||||
|
||||
struct ccu_sdm_setting {
|
||||
unsigned long rate;
|
||||
|
||||
/*
|
||||
* XXX We don't know what the step and bottom register fields
|
||||
* mean. Just copy the whole register value from the vendor
|
||||
* kernel for now.
|
||||
*/
|
||||
u32 pattern;
|
||||
|
||||
/*
|
||||
* M and N factors here should be the values used in
|
||||
* calculation, not the raw values written to registers
|
||||
*/
|
||||
u32 m;
|
||||
u32 n;
|
||||
};
|
||||
|
||||
struct ccu_sdm_internal {
|
||||
struct ccu_sdm_setting *table;
|
||||
u32 table_size;
|
||||
/* early SoCs don't have the SDM enable bit in the PLL register */
|
||||
u32 enable;
|
||||
/* second enable bit in tuning register */
|
||||
u32 tuning_enable;
|
||||
u16 tuning_reg;
|
||||
};
|
||||
|
||||
#define _SUNXI_CCU_SDM(_table, _enable, \
|
||||
_reg, _reg_enable) \
|
||||
{ \
|
||||
.table = _table, \
|
||||
.table_size = ARRAY_SIZE(_table), \
|
||||
.enable = _enable, \
|
||||
.tuning_enable = _reg_enable, \
|
||||
.tuning_reg = _reg, \
|
||||
}
|
||||
|
||||
bool ccu_sdm_helper_is_enabled(struct ccu_common *common,
|
||||
struct ccu_sdm_internal *sdm);
|
||||
void ccu_sdm_helper_enable(struct ccu_common *common,
|
||||
struct ccu_sdm_internal *sdm,
|
||||
unsigned long rate);
|
||||
void ccu_sdm_helper_disable(struct ccu_common *common,
|
||||
struct ccu_sdm_internal *sdm);
|
||||
|
||||
bool ccu_sdm_helper_has_rate(struct ccu_common *common,
|
||||
struct ccu_sdm_internal *sdm,
|
||||
unsigned long rate);
|
||||
|
||||
unsigned long ccu_sdm_helper_read_rate(struct ccu_common *common,
|
||||
struct ccu_sdm_internal *sdm,
|
||||
u32 m, u32 n);
|
||||
|
||||
int ccu_sdm_helper_get_factors(struct ccu_common *common,
|
||||
struct ccu_sdm_internal *sdm,
|
||||
unsigned long rate,
|
||||
unsigned long *m, unsigned long *n);
|
||||
|
||||
#endif
|
||||
@@ -43,6 +43,8 @@
|
||||
#define _DT_BINDINGS_CLK_SUN4I_A10_H_
|
||||
|
||||
#define CLK_HOSC 1
|
||||
#define CLK_PLL_VIDEO0_2X 9
|
||||
#define CLK_PLL_VIDEO1_2X 18
|
||||
#define CLK_CPU 20
|
||||
|
||||
/* AHB Gates */
|
||||
|
||||
@@ -43,8 +43,12 @@
|
||||
#ifndef _DT_BINDINGS_CLK_SUN6I_A31_H_
|
||||
#define _DT_BINDINGS_CLK_SUN6I_A31_H_
|
||||
|
||||
#define CLK_PLL_VIDEO0_2X 7
|
||||
|
||||
#define CLK_PLL_PERIPH 10
|
||||
|
||||
#define CLK_PLL_VIDEO1_2X 13
|
||||
|
||||
#define CLK_CPU 18
|
||||
|
||||
#define CLK_AHB1_MIPIDSI 23
|
||||
|
||||
Reference in New Issue
Block a user