From b50eb55b1eb35e8e568ab777dc794370f20464eb Mon Sep 17 00:00:00 2001 From: Nicolin Chen Date: Tue, 22 Apr 2014 15:10:32 +0800 Subject: ENGR00309977-1 ARM: imx6sx: Separate SPDIF and Audio clocks Shawn's patch -- ARM: imx: shared gate support for i.MX clk_gate2 clocko has fixed the problem of clock conflicts due to sharing a same gate. So from now on, we can no longer need to take care the shared gate clock for each audio clock route. Thus this patch separates them by using the new clock registering helper function. And meanwhile, we set a proper rate for each route so as to support each module. For S/PDIF, we use 98304000Hz so that the current driver would perfectly get 32000Hz and 48000Hz sample rate playback support, even though we can only get 43885Hz for 44100Hz sample rate in this way -- If user want to playback 44100Hz group sample rates, they need to change the parent rate. Acked-by: Wang Shengjiu Signed-off-by: Nicolin Chen --- arch/arm/mach-imx/clk-imx6sx.c | 30 +++++++++++------------------- 1 file changed, 11 insertions(+), 19 deletions(-) diff --git a/arch/arm/mach-imx/clk-imx6sx.c b/arch/arm/mach-imx/clk-imx6sx.c index 6a5a8b543c23..e8b9a973b502 100644 --- a/arch/arm/mach-imx/clk-imx6sx.c +++ b/arch/arm/mach-imx/clk-imx6sx.c @@ -115,6 +115,9 @@ static struct clk_div_table video_div_table[] = { { } }; +static u32 share_count_asrc; +static u32 share_count_audio; + static void __init imx6sx_clocks_init(struct device_node *ccm_node) { struct device_node *np; @@ -319,9 +322,8 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) clks[IMX6SX_CLK_AIPS_TZ1] = imx_clk_gate2("aips_tz1", "ahb", base + 0x68, 0); clks[IMX6SX_CLK_AIPS_TZ2] = imx_clk_gate2("aips_tz2", "ahb", base + 0x68, 2); clks[IMX6SX_CLK_APBH_DMA] = imx_clk_gate2("apbh_dma", "usdhc3", base + 0x68, 4); - clks[IMX6SX_CLK_ASRC_GATE] = imx_clk_gate2("asrc_gate", "ahb", base + 0x68, 6); - clks[IMX6SX_CLK_ASRC_MEM] = imx_clk_fixed_factor("asrc_mem", "asrc_gate", 1, 1); - clks[IMX6SX_CLK_ASRC_IPG] = imx_clk_fixed_factor("asrc_ipg", "asrc_gate", 1, 1); + clks[IMX6SX_CLK_ASRC_MEM] = imx_clk_gate2_shared("asrc_mem", "ahb", base + 0x68, 6, &share_count_asrc); + clks[IMX6SX_CLK_ASRC_IPG] = imx_clk_gate2_shared("asrc_ipg", "ahb", base + 0x68, 6, &share_count_asrc); clks[IMX6SX_CLK_CAAM_MEM] = imx_clk_gate2("caam_mem", "ahb", base + 0x68, 8); clks[IMX6SX_CLK_CAAM_ACLK] = imx_clk_gate2("caam_aclk", "ahb", base + 0x68, 10); clks[IMX6SX_CLK_CAAM_IPG] = imx_clk_gate2("caam_ipg", "ipg", base + 0x68, 12); @@ -394,9 +396,8 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) clks[IMX6SX_CLK_ROM] = imx_clk_gate2("rom", "ahb", base + 0x7c, 0); clks[IMX6SX_CLK_SDMA] = imx_clk_gate2("sdma", "ahb", base + 0x7c, 6); clks[IMX6SX_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12); - clks[IMX6SX_CLK_AUDIO_GATE] = imx_clk_gate2("audio_gate", "audio_podf", base + 0x7c, 14); - clks[IMX6SX_CLK_AUDIO] = imx_clk_fixed_factor("audio", "audio_gate", 1, 1); - clks[IMX6SX_CLK_SPDIF] = imx_clk_fixed_factor("spdif", "audio_gate", 1, 1); + clks[IMX6SX_CLK_AUDIO] = imx_clk_gate2_shared("audio", "audio_podf", base + 0x7c, 14, &share_count_audio); + clks[IMX6SX_CLK_SPDIF] = imx_clk_gate2_shared("spdif", "spdif_podf", base + 0x7c, 14, &share_count_audio); clks[IMX6SX_CLK_SSI1_IPG] = imx_clk_gate2("ssi1_ipg", "ipg", base + 0x7c, 18); clks[IMX6SX_CLK_SSI2_IPG] = imx_clk_gate2("ssi2_ipg", "ipg", base + 0x7c, 20); clks[IMX6SX_CLK_SSI3_IPG] = imx_clk_gate2("ssi3_ipg", "ipg", base + 0x7c, 22); @@ -479,20 +480,11 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node) /* Audio clocks */ clk_set_rate(clks[IMX6SX_CLK_PLL4_AUDIO_DIV], 393216000); - /* - * IMPORTANT: - * SPDIF and AUDIO clocks are sharing the same gate on i.MX6 Solo X - * while their rates and gates are being handled by separate drivers. - * To keep them safe, we here merge them into one clock and use one - * exact rate so there'd not be any conflict during usages of them. - * - * But this results a limitation that if using these two simultaneous, - * make sure to keep them identical as what the code does over here. - */ - clk_set_parent(clks[IMX6SX_CLK_SPDIF_SEL], clks[IMX6SX_CLK_PLL3_USB_OTG]); + clk_set_parent(clks[IMX6SX_CLK_SPDIF_SEL], clks[IMX6SX_CLK_PLL4_AUDIO_DIV]); + clk_set_rate(clks[IMX6SX_CLK_SPDIF_PODF], 98304000); + clk_set_parent(clks[IMX6SX_CLK_AUDIO_SEL], clks[IMX6SX_CLK_PLL3_USB_OTG]); - clk_set_rate(clks[IMX6SX_CLK_SPDIF_PODF], 48000000); - clk_set_rate(clks[IMX6SX_CLK_AUDIO_PODF], 48000000); + clk_set_rate(clks[IMX6SX_CLK_AUDIO_PODF], 24000000); clk_set_parent(clks[IMX6SX_CLK_SSI1_SEL], clks[IMX6SX_CLK_PLL4_AUDIO_DIV]); clk_set_parent(clks[IMX6SX_CLK_SSI2_SEL], clks[IMX6SX_CLK_PLL4_AUDIO_DIV]); -- cgit v1.2.2