diff options
| -rw-r--r-- | drivers/clk/sunxi-ng/Makefile | 1 | ||||
| -rw-r--r-- | drivers/clk/sunxi-ng/ccu-sun4i-a10.c | 28 | ||||
| -rw-r--r-- | drivers/clk/sunxi-ng/ccu-sun4i-a10.h | 4 | ||||
| -rw-r--r-- | drivers/clk/sunxi-ng/ccu-sun5i.c | 27 | ||||
| -rw-r--r-- | drivers/clk/sunxi-ng/ccu-sun6i-a31.c | 40 | ||||
| -rw-r--r-- | drivers/clk/sunxi-ng/ccu-sun6i-a31.h | 8 | ||||
| -rw-r--r-- | drivers/clk/sunxi-ng/ccu-sun8i-a23.c | 38 | ||||
| -rw-r--r-- | drivers/clk/sunxi-ng/ccu-sun8i-a83t.c | 2 | ||||
| -rw-r--r-- | drivers/clk/sunxi-ng/ccu-sun8i-de2.c | 21 | ||||
| -rw-r--r-- | drivers/clk/sunxi-ng/ccu-sun8i-h3.c | 56 | ||||
| -rw-r--r-- | drivers/clk/sunxi-ng/ccu_common.h | 1 | ||||
| -rw-r--r-- | drivers/clk/sunxi-ng/ccu_nm.c | 25 | ||||
| -rw-r--r-- | drivers/clk/sunxi-ng/ccu_nm.h | 25 | ||||
| -rw-r--r-- | drivers/clk/sunxi-ng/ccu_reset.c | 14 | ||||
| -rw-r--r-- | drivers/clk/sunxi-ng/ccu_sdm.c | 158 | ||||
| -rw-r--r-- | drivers/clk/sunxi-ng/ccu_sdm.h | 80 | ||||
| -rw-r--r-- | include/dt-bindings/clock/sun4i-a10-ccu.h | 2 | ||||
| -rw-r--r-- | include/dt-bindings/clock/sun6i-a31-ccu.h | 4 |
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 | |||
| 10 | lib-$(CONFIG_SUNXI_CCU) += ccu_mux.o | 10 | lib-$(CONFIG_SUNXI_CCU) += ccu_mux.o |
| 11 | lib-$(CONFIG_SUNXI_CCU) += ccu_mult.o | 11 | lib-$(CONFIG_SUNXI_CCU) += ccu_mult.o |
| 12 | lib-$(CONFIG_SUNXI_CCU) += ccu_phase.o | 12 | lib-$(CONFIG_SUNXI_CCU) += ccu_phase.o |
| 13 | lib-$(CONFIG_SUNXI_CCU) += ccu_sdm.o | ||
| 13 | 14 | ||
| 14 | # Multi-factor clocks | 15 | # Multi-factor clocks |
| 15 | lib-$(CONFIG_SUNXI_CCU) += ccu_nk.o | 16 | lib-$(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 | |||
| 64 | static 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 | |||
| 58 | static struct ccu_nm pll_audio_base_clk = { | 69 | static 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 */ |
| 1025 | static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio", | 1039 | static 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); |
| 1027 | static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x", | 1041 | static 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); |
| 1029 | static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x", | 1043 | 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, | |||
| 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 | ||
| 62 | static 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 | |||
| 57 | static struct ccu_nm pll_audio_base_clk = { | 67 | static 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)), | ||
