forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-10 748e4f3d702def1a4bff191e0cf93b6a05340f01
kernel/drivers/clk/sunxi-ng/ccu-sun50i-a64.c
....@@ -1,17 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (c) 2016 Maxime Ripard. All rights reserved.
3
- *
4
- * This software is licensed under the terms of the GNU General Public
5
- * License version 2, as published by the Free Software Foundation, and
6
- * may be copied, distributed, and modified under those terms.
7
- *
8
- * This program is distributed in the hope that it will be useful,
9
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
- * GNU General Public License for more details.
124 */
135
146 #include <linux/clk-provider.h>
7
+#include <linux/io.h>
158 #include <linux/of_address.h>
169 #include <linux/platform_device.h>
1710
....@@ -51,30 +44,43 @@
5144 * the base (2x, 4x and 8x), and one variable divider (the one true
5245 * pll audio).
5346 *
54
- * We don't have any need for the variable divider for now, so we just
55
- * hardcode it to match with the clock names
47
+ * With sigma-delta modulation for fractional-N on the audio PLL,
48
+ * we have to use specific dividers. This means the variable divider
49
+ * can no longer be used, as the audio codec requests the exact clock
50
+ * rates we support through this mechanism. So we now hard code the
51
+ * variable divider to 1. This means the clock rates will no longer
52
+ * match the clock names.
5653 */
5754 #define SUN50I_A64_PLL_AUDIO_REG 0x008
5855
59
-static SUNXI_CCU_NM_WITH_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
60
- "osc24M", 0x008,
61
- 8, 7, /* N */
62
- 0, 5, /* M */
63
- BIT(31), /* gate */
64
- BIT(28), /* lock */
65
- CLK_SET_RATE_UNGATE);
56
+static struct ccu_sdm_setting pll_audio_sdm_table[] = {
57
+ { .rate = 22579200, .pattern = 0xc0010d84, .m = 8, .n = 7 },
58
+ { .rate = 24576000, .pattern = 0xc000ac02, .m = 14, .n = 14 },
59
+};
6660
67
-static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video0_clk, "pll-video0",
68
- "osc24M", 0x010,
69
- 8, 7, /* N */
70
- 0, 4, /* M */
71
- BIT(24), /* frac enable */
72
- BIT(25), /* frac select */
73
- 270000000, /* frac rate 0 */
74
- 297000000, /* frac rate 1 */
75
- BIT(31), /* gate */
76
- BIT(28), /* lock */
77
- CLK_SET_RATE_UNGATE);
61
+static SUNXI_CCU_NM_WITH_SDM_GATE_LOCK(pll_audio_base_clk, "pll-audio-base",
62
+ "osc24M", 0x008,
63
+ 8, 7, /* N */
64
+ 0, 5, /* M */
65
+ pll_audio_sdm_table, BIT(24),
66
+ 0x284, BIT(31),
67
+ BIT(31), /* gate */
68
+ BIT(28), /* lock */
69
+ CLK_SET_RATE_UNGATE);
70
+
71
+static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video0_clk, "pll-video0",
72
+ "osc24M", 0x010,
73
+ 192000000, /* Minimum rate */
74
+ 1008000000, /* Maximum rate */
75
+ 8, 7, /* N */
76
+ 0, 4, /* M */
77
+ BIT(24), /* frac enable */
78
+ BIT(25), /* frac select */
79
+ 270000000, /* frac rate 0 */
80
+ 297000000, /* frac rate 1 */
81
+ BIT(31), /* gate */
82
+ BIT(28), /* lock */
83
+ CLK_SET_RATE_UNGATE);
7884
7985 static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_ve_clk, "pll-ve",
8086 "osc24M", 0x018,
....@@ -125,17 +131,19 @@
125131 },
126132 };
127133
128
-static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_video1_clk, "pll-video1",
129
- "osc24M", 0x030,
130
- 8, 7, /* N */
131
- 0, 4, /* M */
132
- BIT(24), /* frac enable */
133
- BIT(25), /* frac select */
134
- 270000000, /* frac rate 0 */
135
- 297000000, /* frac rate 1 */
136
- BIT(31), /* gate */
137
- BIT(28), /* lock */
138
- CLK_SET_RATE_UNGATE);
134
+static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK_MIN_MAX(pll_video1_clk, "pll-video1",
135
+ "osc24M", 0x030,
136
+ 192000000, /* Minimum rate */
137
+ 1008000000, /* Maximum rate */
138
+ 8, 7, /* N */
139
+ 0, 4, /* M */
140
+ BIT(24), /* frac enable */
141
+ BIT(25), /* frac select */
142
+ 270000000, /* frac rate 0 */
143
+ 297000000, /* frac rate 1 */
144
+ BIT(31), /* gate */
145
+ BIT(28), /* lock */
146
+ CLK_SET_RATE_UNGATE);
139147
140148 static SUNXI_CCU_NM_WITH_FRAC_GATE_LOCK(pll_gpu_clk, "pll-gpu",
141149 "osc24M", 0x038,
....@@ -517,7 +525,8 @@
517525
518526 static const char * const de_parents[] = { "pll-periph0-2x", "pll-de" };
519527 static SUNXI_CCU_M_WITH_MUX_GATE(de_clk, "de", de_parents,
520
- 0x104, 0, 4, 24, 3, BIT(31), 0);
528
+ 0x104, 0, 4, 24, 3, BIT(31),
529
+ CLK_SET_RATE_PARENT);
521530
522531 static const char * const tcon0_parents[] = { "pll-mipi", "pll-video0-2x" };
523532 static const u8 tcon0_table[] = { 0, 2, };
....@@ -556,7 +565,7 @@
556565 0x134, 0, 5, 8, 3, BIT(15), 0);
557566
558567 static SUNXI_CCU_M_WITH_GATE(ve_clk, "ve", "pll-ve",
559
- 0x13c, 16, 3, BIT(31), 0);
568
+ 0x13c, 16, 3, BIT(31), CLK_SET_RATE_PARENT);
560569
561570 static SUNXI_CCU_GATE(ac_dig_clk, "ac-dig", "pll-audio",
562571 0x140, BIT(31), CLK_SET_RATE_PARENT);
....@@ -589,23 +598,34 @@
589598 0x1a0, 0, 3, BIT(31), CLK_SET_RATE_PARENT);
590599
591600 /* Fixed Factor clocks */
592
-static CLK_FIXED_FACTOR(osc12M_clk, "osc12M", "osc24M", 2, 1, 0);
601
+static CLK_FIXED_FACTOR_FW_NAME(osc12M_clk, "osc12M", "hosc", 2, 1, 0);
593602
594
-/* We hardcode the divider to 4 for now */
595
-static CLK_FIXED_FACTOR(pll_audio_clk, "pll-audio",
596
- "pll-audio-base", 4, 1, CLK_SET_RATE_PARENT);
597
-static CLK_FIXED_FACTOR(pll_audio_2x_clk, "pll-audio-2x",
598
- "pll-audio-base", 2, 1, CLK_SET_RATE_PARENT);
599
-static CLK_FIXED_FACTOR(pll_audio_4x_clk, "pll-audio-4x",
600
- "pll-audio-base", 1, 1, CLK_SET_RATE_PARENT);
601
-static CLK_FIXED_FACTOR(pll_audio_8x_clk, "pll-audio-8x",
602
- "pll-audio-base", 1, 2, CLK_SET_RATE_PARENT);
603
-static CLK_FIXED_FACTOR(pll_periph0_2x_clk, "pll-periph0-2x",
604
- "pll-periph0", 1, 2, 0);
605
-static CLK_FIXED_FACTOR(pll_periph1_2x_clk, "pll-periph1-2x",
606
- "pll-periph1", 1, 2, 0);
607
-static CLK_FIXED_FACTOR(pll_video0_2x_clk, "pll-video0-2x",
608
- "pll-video0", 1, 2, CLK_SET_RATE_PARENT);
603
+static const struct clk_hw *clk_parent_pll_audio[] = {
604
+ &pll_audio_base_clk.common.hw
605
+};
606
+
607
+/* We hardcode the divider to 1 for now */
608
+static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio",
609
+ clk_parent_pll_audio,
610
+ 1, 1, CLK_SET_RATE_PARENT);
611
+static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x",
612
+ clk_parent_pll_audio,
613
+ 2, 1, CLK_SET_RATE_PARENT);
614
+static CLK_FIXED_FACTOR_HWS(pll_audio_4x_clk, "pll-audio-4x",
615
+ clk_parent_pll_audio,
616
+ 1, 1, CLK_SET_RATE_PARENT);
617
+static CLK_FIXED_FACTOR_HWS(pll_audio_8x_clk, "pll-audio-8x",
618
+ clk_parent_pll_audio,
619
+ 1, 2, CLK_SET_RATE_PARENT);
620
+static CLK_FIXED_FACTOR_HW(pll_periph0_2x_clk, "pll-periph0-2x",
621
+ &pll_periph0_clk.common.hw,
622
+ 1, 2, 0);
623
+static CLK_FIXED_FACTOR_HW(pll_periph1_2x_clk, "pll-periph1-2x",
624
+ &pll_periph1_clk.common.hw,
625
+ 1, 2, 0);
626
+static CLK_FIXED_FACTOR_HW(pll_video0_2x_clk, "pll-video0-2x",
627
+ &pll_video0_clk.common.hw,
628
+ 1, 2, CLK_SET_RATE_PARENT);
609629
610630 static struct ccu_common *sun50i_a64_ccu_clks[] = {
611631 &pll_cpux_clk.common,
....@@ -928,10 +948,10 @@
928948 if (IS_ERR(reg))
929949 return PTR_ERR(reg);
930950
931
- /* Force the PLL-Audio-1x divider to 4 */
951
+ /* Force the PLL-Audio-1x divider to 1 */
932952 val = readl(reg + SUN50I_A64_PLL_AUDIO_REG);
933953 val &= ~GENMASK(19, 16);
934
- writel(val | (3 << 16), reg + SUN50I_A64_PLL_AUDIO_REG);
954
+ writel(val | (0 << 16), reg + SUN50I_A64_PLL_AUDIO_REG);
935955
936956 writel(0x515, reg + SUN50I_A64_PLL_MIPI_REG);
937957