@@ -216,19 +216,29 @@ static struct ccu_nkmp pll_de_clk = {
216216};
217217
218218/*
219- * TODO: Determine SDM settings for the audio PLL. The manual suggests
220- * PLL_FACTOR_N=16, PLL_POST_DIV_P=2, OUTPUT_DIV=2, pattern=0xe000c49b
221- * for 24.576 MHz, and PLL_FACTOR_N=22, PLL_POST_DIV_P=3, OUTPUT_DIV=2,
222- * pattern=0xe001288c for 22.5792 MHz.
223- * This clashes with our fixed PLL_POST_DIV_P .
219+ * Sigma-delta modulation settings table obtained from the vendor SDK driver.
220+ * There are additional M0 and M1 divider bits not modelled here, so forced to
221+ * fixed values in the probe routine. Sigma-delta modulation allows providing a
222+ * fractional-N divider in the PLL, to help reaching those specific
223+ * frequencies with less error .
224224 */
225+ static struct ccu_sdm_setting pll_audio_sdm_table [] = {
226+ { .rate = 90316800 , .pattern = 0xc001288d , .m = 3 , .n = 22 },
227+ { .rate = 98304000 , .pattern = 0xc001eb85 , .m = 5 , .n = 40 },
228+ };
229+
225230#define SUN50I_H616_PLL_AUDIO_REG 0x078
226231static struct ccu_nm pll_audio_hs_clk = {
227232 .enable = BIT (31 ),
228233 .lock = BIT (28 ),
229234 .n = _SUNXI_CCU_MULT_MIN (8 , 8 , 12 ),
230- .m = _SUNXI_CCU_DIV (1 , 1 ), /* input divider */
235+ .m = _SUNXI_CCU_DIV (16 , 6 ),
236+ .sdm = _SUNXI_CCU_SDM (pll_audio_sdm_table ,
237+ BIT (24 ), 0x178 , BIT (31 )),
238+ .fixed_post_div = 2 ,
231239 .common = {
240+ .features = CCU_FEATURE_FIXED_POSTDIV |
241+ CCU_FEATURE_SIGMA_DELTA_MOD ,
232242 .reg = 0x078 ,
233243 .hw .init = CLK_HW_INIT ("pll-audio-hs" , "osc24M" ,
234244 & ccu_nm_ops ,
@@ -685,18 +695,20 @@ static const struct clk_hw *clk_parent_pll_audio[] = {
685695};
686696
687697/*
688- * The divider of pll-audio is fixed to 24 for now, so 24576000 and 22579200
689- * rates can be set exactly in conjunction with sigma-delta modulation.
698+ * The PLL_AUDIO_4X clock defaults to 24.5714 MHz according to the manual, with
699+ * a final divider of 1. The 2X and 1X clocks use 2 and 4 respectively. The 1x
700+ * clock is set to either 24576000 or 22579200 for 48Khz and 44.1Khz (and
701+ * multiples).
690702 */
691703static CLK_FIXED_FACTOR_HWS (pll_audio_1x_clk , "pll-audio-1x" ,
692704 clk_parent_pll_audio ,
693- 96 , 1 , CLK_SET_RATE_PARENT );
705+ 4 , 1 , CLK_SET_RATE_PARENT );
694706static CLK_FIXED_FACTOR_HWS (pll_audio_2x_clk , "pll-audio-2x" ,
695707 clk_parent_pll_audio ,
696- 48 , 1 , CLK_SET_RATE_PARENT );
708+ 2 , 1 , CLK_SET_RATE_PARENT );
697709static CLK_FIXED_FACTOR_HWS (pll_audio_4x_clk , "pll-audio-4x" ,
698710 clk_parent_pll_audio ,
699- 24 , 1 , CLK_SET_RATE_PARENT );
711+ 1 , 1 , CLK_SET_RATE_PARENT );
700712
701713static const struct clk_hw * pll_periph0_parents [] = {
702714 & pll_periph0_clk .common .hw
@@ -990,7 +1002,7 @@ static struct clk_hw_onecell_data sun50i_h616_hw_clks = {
9901002 .num = CLK_NUMBER ,
9911003};
9921004
993- static struct ccu_reset_map sun50i_h616_ccu_resets [] = {
1005+ static const struct ccu_reset_map sun50i_h616_ccu_resets [] = {
9941006 [RST_MBUS ] = { 0x540 , BIT (30 ) },
9951007
9961008 [RST_BUS_DE ] = { 0x60c , BIT (16 ) },
@@ -1136,12 +1148,14 @@ static int sun50i_h616_ccu_probe(struct platform_device *pdev)
11361148 }
11371149
11381150 /*
1139- * Force the post-divider of pll-audio to 12 and the output divider
1140- * of it to 2, so 24576000 and 22579200 rates can be set exactly.
1151+ * Set the output-divider for the pll-audio clocks (M0) to 2 and the
1152+ * input divider (M1) to 1 as recommended by the manual when using
1153+ * SDM.
11411154 */
11421155 val = readl (reg + SUN50I_H616_PLL_AUDIO_REG );
1143- val &= ~(GENMASK (21 , 16 ) | BIT (0 ));
1144- writel (val | (11 << 16 ) | BIT (0 ), reg + SUN50I_H616_PLL_AUDIO_REG );
1156+ val &= ~BIT (1 );
1157+ val |= BIT (0 );
1158+ writel (val , reg + SUN50I_H616_PLL_AUDIO_REG );
11451159
11461160 /*
11471161 * First clock parent (osc32K) is unusable for CEC. But since there
0 commit comments