aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/clk/sunxi-ng/Makefile1
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun4i-a10.c28
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun4i-a10.h4
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun5i.c27
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun6i-a31.c40
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun6i-a31.h8
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun8i-a23.c38
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun8i-a83t.c2
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun8i-de2.c21
-rw-r--r--drivers/clk/sunxi-ng/ccu-sun8i-h3.c56
-rw-r--r--drivers/clk/sunxi-ng/ccu_common.h1
-rw-r--r--drivers/clk/sunxi-ng/ccu_nm.c25
-rw-r--r--drivers/clk/sunxi-ng/ccu_nm.h25
-rw-r--r--drivers/clk/sunxi-ng/ccu_reset.c14
-rw-r--r--drivers/clk/sunxi-ng/ccu_sdm.c158
-rw-r--r--drivers/clk/sunxi-ng/ccu_sdm.h80
-rw-r--r--include/dt-bindings/clock/sun4i-a10-ccu.h2
-rw-r--r--include/dt-bindings/clock/sun6i-a31-ccu.h4
18 files changed, 457 insertions, 77 deletions
diff --git a/drivers/clk/sunxi-ng/Makefile b/drivers/clk/sunxi-ng/Makefile
index 85a0633c1eac..8504d9c6f03a 100644
--- a/drivers/clk/sunxi-ng/Makefile
+++ b/drivers/clk/sunxi-ng/Makefile
@@ -10,6 +10,7 @@ lib-$(CONFIG_SUNXI_CCU) += ccu_gate.o
10lib-$(CONFIG_SUNXI_CCU) += ccu_mux.o 10lib-$(CONFIG_SUNXI_CCU) += ccu_mux.o
11lib-$(CONFIG_SUNXI_CCU) += ccu_mult.o 11lib-$(CONFIG_SUNXI_CCU) += ccu_mult.o
12lib-$(CONFIG_SUNXI_CCU) += ccu_phase.o 12lib-$(CONFIG_SUNXI_CCU) += ccu_phase.o
13lib-$(CONFIG_SUNXI_CCU) += ccu_sdm.o
13 14
14# Multi-factor clocks 15# Multi-factor clocks
15lib-$(CONFIG_SUNXI_CCU) += ccu_nk.o 16lib-$(CONFIG_SUNXI_CCU) += ccu_nk.o
diff --git a/drivers/clk/sunxi-ng/ccu-sun4i-a10.c b/drivers/clk/sunxi-ng/ccu-sun4i-a10.c
index 286b0049b7b6..ffa5dac221e4 100644
--- a/drivers/clk/sunxi-ng/ccu-sun4i-a10.c
+++ b/drivers/clk/sunxi-ng/ccu-sun4i-a10.c
@@ -28,6 +28,7 @@
28#include "ccu_nkmp.h" 28#include "ccu_nkmp.h"
29#include "ccu_nm.h" 29#include "ccu_nm.h"
30#include "ccu_phase.h" 30#include "ccu_phase.h"
31#include "ccu_sdm.h"
31 32
32#include "ccu-sun4i-a10.h" 33#include "ccu-sun4i-a10.h"
33 34
@@ -51,16 +52,29 @@ static struct ccu_nkmp pll_core_clk = {
51 * the base (2x, 4x and 8x), and one variable divider (the one true 52 * the base (2x, 4x and 8x), and one variable divider (the one true
52 * pll audio). 53 * pll audio).
53 * 54 *
54 * We don't have any need for the variable divider for now, so we just 55 * With sigma-delta modulation for fractional-N on the audio PLL,
55 * hardcode it to match with the clock names. 56 * we have to use specific dividers. This means the variable divider
57 * can no longer be used, as the audio codec requests the exact clock
58 * rates we support through this mechanism. So we now hard code the
59 * variable divider to 1. This means the clock rates will no longer
60 * match the clock names.
56 */ 61 */
57#define SUN4I_PLL_AUDIO_REG 0x008 62#define SUN4I_PLL_AUDIO_REG 0x008
63
64static struct ccu_sdm_setting pll_audio_sdm_table[] = {
65 { .rate = 22579200, .pattern = 0xc0010d84, .m = 8, .n = 7 },
66 { .rate = 24576000, .pattern = 0xc000ac02, .m = 14, .n = 14 },
67};
68
58static struct ccu_nm pll_audio_base_clk = { 69static struct ccu_nm pll_audio_base_clk = {
59 .enable = BIT(31), 70 .enable = BIT(31),
60 .n = _SUNXI_CCU_MULT_OFFSET(8, 7, 0), 71 .n = _SUNXI_CCU_MULT_OFFSET(8, 7, 0),
61 .m = _SUNXI_CCU_DIV_OFFSET(0, 5, 0), 72 .m = _SUNXI_CCU_DIV_OFFSET(0, 5, 0),
73 .sdm = _SUNXI_CCU_SDM(pll_audio_sdm_table, 0,
74 0x00c, BIT(31)),
62 .common = { 75 .common = {
63 .reg = 0x008, 76 .reg = 0x008,
77 .features = CCU_FEATURE_SIGMA_DELTA_MOD,
64 .hw.init = CLK_HW_INIT("pll-audio-base", 78 .hw.init = CLK_HW_INIT("pll-audio-base",
65 "hosc", 79 "hosc",
66 &ccu_nm_ops, 80 &ccu_nm_ops,
@@ -223,7 +237,7 @@ static struct ccu_mux cpu_clk = {
223 .hw.init = CLK_HW_INIT_PARENTS("cpu", 237 .hw.init = CLK_HW_INIT_PARENTS("cpu",
224 cpu_parents, 238 cpu_parents,
225 &ccu_mux_ops, 239 &ccu_mux_ops,
226 CLK_IS_CRITICAL), 240 CLK_SET_RATE_PARENT | CLK_IS_CRITICAL),
227 } 241 }
228}; 242};
229 243
@@ -1021,9 +1035,9 @@ static struct ccu_common *sun4i_sun7i_ccu_clks[] = {
1021 &out_b_clk.common 1035 &out_b_clk.common
1022}; 1036};
1023 1037
1024/* Post-divider for pll-audio is hardcoded to 4 */ 1038/* Post-divider for pll-audio is hardcoded to 1 */
1025static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", 1039static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
1026 "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT); 1040 "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
1027static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", 1041static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
1028 "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT); 1042 "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
1029static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", 1043static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
@@ -1420,10 +1434,10 @@ static void __init sun4i_ccu_init(struct device_node *node,
1420 return; 1434 return;
1421 } 1435 }
1422 1436
1423 /* Force the PLL-Audio-1x divider to 4 */ 1437 /* Force the PLL-Audio-1x divider to 1 */
1424 val = readl(reg + SUN4I_PLL_AUDIO_REG); 1438 val = readl(reg + SUN4I_PLL_AUDIO_REG);
1425 val &= ~GENMASK(29, 26); 1439 val &= ~GENMASK(29, 26);
1426 writel(val | (4 << 26), reg + SUN4I_PLL_AUDIO_REG); 1440 writel(val | (1 << 26), reg + SUN4I_PLL_AUDIO_REG);
1427 1441
1428 /* 1442 /*
1429 * Use the peripheral PLL6 as the AHB parent, instead of CPU / 1443 * Use the peripheral PLL6 as the AHB parent, instead of CPU /
diff --git a/drivers/clk/sunxi-ng/ccu-sun4i-a10.h b/drivers/clk/sunxi-ng/ccu-sun4i-a10.h
index c5947c7c050e..23c908ad509f 100644
--- a/drivers/clk/sunxi-ng/ccu-sun4i-a10.h
+++ b/drivers/clk/sunxi-ng/ccu-sun4i-a10.h
@@ -29,7 +29,7 @@
29#define CLK_PLL_AUDIO_4X 6 29#define CLK_PLL_AUDIO_4X 6
30#define CLK_PLL_AUDIO_8X 7 30#define CLK_PLL_AUDIO_8X 7
31#define CLK_PLL_VIDEO0 8 31#define CLK_PLL_VIDEO0 8
32#define CLK_PLL_VIDEO0_2X 9 32/* The PLL_VIDEO0_2X clock is exported */
33#define CLK_PLL_VE 10 33#define CLK_PLL_VE 10
34#define CLK_PLL_DDR_BASE 11 34#define CLK_PLL_DDR_BASE 11
35#define CLK_PLL_DDR 12 35#define CLK_PLL_DDR 12
@@ -38,7 +38,7 @@
38#define CLK_PLL_PERIPH 15 38#define CLK_PLL_PERIPH 15
39#define CLK_PLL_PERIPH_SATA 16 39#define CLK_PLL_PERIPH_SATA 16
40#define CLK_PLL_VIDEO1 17 40#define CLK_PLL_VIDEO1 17
41#define CLK_PLL_VIDEO1_2X 18 41/* The PLL_VIDEO1_2X clock is exported */
42#define CLK_PLL_GPU 19 42#define CLK_PLL_GPU 19
43 43
44/* The CPU clock is exported */ 44/* The CPU clock is exported */
diff --git a/drivers/clk/sunxi-ng/ccu-sun5i.c b/drivers/clk/sunxi-ng/ccu-sun5i.c
index ab9e850b3707..fa2c2dd77102 100644
--- a/drivers/clk/sunxi-ng/ccu-sun5i.c
+++ b/drivers/clk/sunxi-ng/ccu-sun5i.c
@@ -26,6 +26,7 @@
26#include "ccu_nkmp.h" 26#include "ccu_nkmp.h"
27#include "ccu_nm.h" 27#include "ccu_nm.h"
28#include "ccu_phase.h" 28#include "ccu_phase.h"
29#include "ccu_sdm.h"
29 30
30#include "ccu-sun5i.h" 31#include "ccu-sun5i.h"
31 32
@@ -49,11 +50,20 @@ static struct ccu_nkmp pll_core_clk = {
49 * the base (2x, 4x and 8x), and one variable divider (the one true 50 * the base (2x, 4x and 8x), and one variable divider (the one true
50 * pll audio). 51 * pll audio).
51 * 52 *
52 * We don't have any need for the variable divider for now, so we just 53 * With sigma-delta modulation for fractional-N on the audio PLL,
53 * hardcode it to match with the clock names 54 * we have to use specific dividers. This means the variable divider
55 * can no longer be used, as the audio codec requests the exact clock
56 * rates we support through this mechanism. So we now hard code the
57 * variable divider to 1. This means the clock rates will no longer
58 * match the clock names.
54 */ 59 */
55#define SUN5I_PLL_AUDIO_REG 0x008 60#define SUN5I_PLL_AUDIO_REG 0x008
56 61
62static struct ccu_sdm_setting pll_audio_sdm_table[] = {
63 { .rate = 22579200, .pattern = 0xc0010d84, .m = 8, .n = 7 },
64 { .rate = 24576000, .pattern = 0xc000ac02, .m = 14, .n = 14 },
65};
66
57static struct ccu_nm pll_audio_base_clk = { 67static struct ccu_nm pll_audio_base_clk = {
58 .enable = BIT(31), 68 .enable = BIT(31),
59 .n = _SUNXI_CCU_MULT_OFFSET(8, 7, 0), 69 .n = _SUNXI_CCU_MULT_OFFSET(8, 7, 0),
@@ -63,8 +73,11 @@ static struct ccu_nm pll_audio_base_clk = {
63 * offset 73 * offset
64 */ 74 */
65 .m = _SUNXI_CCU_DIV_OFFSET(0, 5, 0), 75 .m = _SUNXI_CCU_DIV_OFFSET(0, 5, 0),
76 .sdm = _SUNXI_CCU_SDM(pll_audio_sdm_table, 0,
77 0x00c, BIT(31)),