clk: imx: Add clock support for imx6qp
Subsystems (7)
PATCH v3 1/5 clk: imx: Add clock support for imx6qp
most of the clock tree structures on i.MX6 Quad Plus are same as on i.MX6Q. there still some differences between these two SOCs. compared to the i.XM6Q, the differents of clocks on i.MX6QP is mainly on:
1. New clock gate added to support the PRE and PRG modules
2. 24MHz OSC clock option added to the UART, IPG, ECSPI, and CAN clock roots.
3. MMDC channel 1 clock gate is now controllable.
4. clock gating added to the LDB_DIx_IPU clocks on i.MX6QP
5. EMI clock root divider fix
6. other updates fo CSCMRx, CSCDRx and CS2CDR registers.
detailed infomation, please refer to the i.MX6QP RM.
---
change for V3:
-- move the 'imx6qdl-clock.h' changes into this patch
drivers/clk/imx/clk-imx6q.c | 132 ++++++++++++++++++++++++------ include/dt-bindings/clock/imx6qdl-clock.h | 16 +++- 2 files changed, 120 insertions(+), 28 deletions(-)
drivers/clk/imx/clk-imx6q.c +105 -27
@@ -34,7 +34,9 @@ static const char *periph2_sels[] = { "periph2_pre", "periph2_clk2", };static const char *axi_sels[] = {"periph" ,"pll2_pfd2_396m" ,"periph" ,"pll3_pfd1_540m" , };static const char *audio_sels[] = {"pll4_audio_div" ,"pll3_pfd2_508m" ,"pll3_pfd3_454m" ,"pll3_usb_otg" , };static const char *gpu_axi_sels[] = {"axi" ,"ahb" , }; +static const char *pre_axi_sels[] = {"axi" ,"ahb" , };static const char *gpu2d_core_sels[] = {"axi" ,"pll3_usb_otg" ,"pll2_pfd0_352m" ,"pll2_pfd2_396m" , }; +static const char *gpu2d_core_sels_2[] = {"mmdc_ch0_axi" ,"pll3_usb_otg" ,"pll2_pfd1_594m" ,"pll3_pfd0_720m" ,};static const char *gpu3d_core_sels[] = {"mmdc_ch0_axi" ,"pll3_usb_otg" ,"pll2_pfd1_594m" ,"pll2_pfd2_396m" , };static const char *gpu3d_shader_sels[] = {"mmdc_ch0_axi" ,"pll3_usb_otg" ,"pll2_pfd1_594m" ,"pll3_pfd0_720m" , };static const char *ipu_sels[] = {"mmdc_ch0_axi" ,"pll2_pfd2_396m" ,"pll3_120m" ,"pll3_pfd1_540m" , };
@@ -44,15 +46,24 @@ static const char *ipu1_di0_sels[] = { "ipu1_di0_pre", "dummy", "dummy", "ldb_distatic const char *ipu1_di1_sels[] = {"ipu1_di1_pre" ,"dummy" ,"dummy" ,"ldb_di0" ,"ldb_di1" , };static const char *ipu2_di0_sels[] = {"ipu2_di0_pre" ,"dummy" ,"dummy" ,"ldb_di0" ,"ldb_di1" , };static const char *ipu2_di1_sels[] = {"ipu2_di1_pre" ,"dummy" ,"dummy" ,"ldb_di0" ,"ldb_di1" , }; +static const char *ipu1_di0_sels_2[] = {"ipu1_di0_pre" ,"dummy" ,"dummy" ,"ldb_di0_podf" ,"ldb_di1_podf" , }; +static const char *ipu1_di1_sels_2[] = {"ipu1_di1_pre" ,"dummy" ,"dummy" ,"ldb_di0_podf" ,"ldb_di1_podf" , }; +static const char *ipu2_di0_sels_2[] = {"ipu2_di0_pre" ,"dummy" ,"dummy" ,"ldb_di0_podf" ,"ldb_di1_podf" , }; +static const char *ipu2_di1_sels_2[] = {"ipu2_di1_pre" ,"dummy" ,"dummy" ,"ldb_di0_podf" ,"ldb_di1_podf" , };static const char *hsi_tx_sels[] = {"pll3_120m" ,"pll2_pfd2_396m" , };static const char *pcie_axi_sels[] = {"axi" ,"ahb" , };static const char *ssi_sels[] = {"pll3_pfd2_508m" ,"pll3_pfd3_454m" ,"pll4_audio_div" , };static const char *usdhc_sels[] = {"pll2_pfd2_396m" ,"pll2_pfd0_352m" , };static const char *enfc_sels[] = {"pll2_pfd0_352m" ,"pll2_bus" ,"pll3_usb_otg" ,"pll2_pfd2_396m" , }; +static const char *enfc_sels_2[] = {"pll2_pfd0_352m" ,"pll2_bus" ,"pll3_usb_otg" ,"pll2_pfd2_396m" ,"pll3_pfd3_454m" ,"dummy" , };static const char *eim_sels[] = {"pll2_pfd2_396m" ,"pll3_usb_otg" ,"axi" ,"pll2_pfd0_352m" , };static const char *eim_slow_sels[] = {"axi" ,"pll3_usb_otg" ,"pll2_pfd2_396m" ,"pll2_pfd0_352m" , };static const char *vdo_axi_sels[] = {"axi" ,"ahb" , };static const char *vpu_axi_sels[] = {"axi" ,"pll2_pfd2_396m" ,"pll2_pfd0_352m" , }; +static const char *uart_sels[] = {"pll3_80m" ,"osc" , }; +static const char *ipg_per_sels[] = {"ipg" ,"osc" , }; +static const char *ecspi_sels[] = {"pll3_60m" ,"osc" , }; +static const char *can_sels[] = {"pll3_60m" ,"osc" ,"pll3_80m" , };static const char *cko1_sels[] = {"pll3_usb_otg" ,"pll2_bus" ,"pll1_sys" ,"pll5_video_div" ,"dummy" ,"axi" ,"enfc" ,"ipu1_di0" ,"ipu1_di1" ,"ipu2_di0" ,"ipu2_di1" ,"ahb" ,"ipg" ,"ipg_per" ,"ckil" ,"pll4_audio_div" , };
@@ -121,12 +132,19 @@ static unsigned int share_count_ssi2;static unsigned int share_count_ssi3;static unsigned int share_count_mipi_core_cfg;static unsigned int share_count_spdif; +static unsigned int share_count_prg0; +static unsigned int share_count_prg1;static inline int clk_on_imx6q (void ) {return of_machine_is_compatible ("fsl,imx6q" ); } +static inline int clk_on_imx6qp (void ) +{ +return of_machine_is_compatible ("fsl,imx6qp" ); +} +static inline int clk_on_imx6dl (void ) {return of_machine_is_compatible ("fsl,imx6dl" );
@@ -265,7 +283,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_TWD ] =imx_clk_fixed_factor ("twd" ,"arm" ,1 ,2 ); clk[IMX6QDL_CLK_GPT_3M ] =imx_clk_fixed_factor ("gpt_3m" ,"osc" ,1 ,8 ); clk[IMX6QDL_CLK_VIDEO_27M ] =imx_clk_fixed_factor ("video_27m" ,"pll3_pfd1_540m" ,1 ,20 ); -if (clk_on_imx6dl ()) { +if (clk_on_imx6dl () ||clk_on_imx6qp ()) { clk[IMX6QDL_CLK_GPU2D_AXI ] =imx_clk_fixed_factor ("gpu2d_axi" ,"mmdc_ch0_axi_podf" ,1 ,1 ); clk[IMX6QDL_CLK_GPU3D_AXI ] =imx_clk_fixed_factor ("gpu3d_axi" ,"mmdc_ch0_axi_podf" ,1 ,1 ); }
@@ -294,7 +312,15 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_GPU2D_AXI ] =imx_clk_mux ("gpu2d_axi" , base +0x18 ,0 ,1 , gpu_axi_sels,ARRAY_SIZE (gpu_axi_sels)); clk[IMX6QDL_CLK_GPU3D_AXI ] =imx_clk_mux ("gpu3d_axi" , base +0x18 ,1 ,1 , gpu_axi_sels,ARRAY_SIZE (gpu_axi_sels)); } - clk[IMX6QDL_CLK_GPU2D_CORE_SEL ] =imx_clk_mux ("gpu2d_core_sel" , base +0x18 ,16 ,2 , gpu2d_core_sels,ARRAY_SIZE (gpu2d_core_sels)); +if (clk_on_imx6qp ()) { + clk[IMX6QDL_CLK_CAN_SEL ] =imx_clk_mux ("can_sel" , base +0x20 ,8 ,2 , can_sels,ARRAY_SIZE (can_sels)); + clk[IMX6QDL_CLK_ECSPI_SEL ] =imx_clk_mux ("ecspi_sel" , base +0x38 ,18 ,1 , ecspi_sels,ARRAY_SIZE (ecspi_sels)); + clk[IMX6QDL_CLK_IPG_PER_SEL ] =imx_clk_mux ("ipg_per_sel" , base +0x1c ,6 ,1 , ipg_per_sels,ARRAY_SIZE (ipg_per_sels)); + clk[IMX6QDL_CLK_UART_SEL ] =imx_clk_mux ("uart_sel" , base +0x24 ,6 ,1 , uart_sels,ARRAY_SIZE (uart_sels)); + clk[IMX6QDL_CLK_GPU2D_CORE_SEL ] =imx_clk_mux ("gpu2d_core_sel" , base +0x18 ,16 ,2 , gpu2d_core_sels_2,ARRAY_SIZE (gpu2d_core_sels_2)); + }else { + clk[IMX6QDL_CLK_GPU2D_CORE_SEL ] =imx_clk_mux ("gpu2d_core_sel" , base +0x18 ,16 ,2 , gpu2d_core_sels,ARRAY_SIZE (gpu2d_core_sels)); + } clk[IMX6QDL_CLK_GPU3D_CORE_SEL ] =imx_clk_mux ("gpu3d_core_sel" , base +0x18 ,4 ,2 , gpu3d_core_sels,ARRAY_SIZE (gpu3d_core_sels)); clk[IMX6QDL_CLK_GPU3D_SHADER_SEL ] =imx_clk_mux ("gpu3d_shader_sel" , base +0x18 ,8 ,2 , gpu3d_shader_sels,ARRAY_SIZE (gpu3d_shader_sels)); clk[IMX6QDL_CLK_IPU1_SEL ] =imx_clk_mux ("ipu1_sel" , base +0x3c ,9 ,2 , ipu_sels,ARRAY_SIZE (ipu_sels));
@@ -305,22 +331,40 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_IPU1_DI1_PRE_SEL ] =imx_clk_mux_flags ("ipu1_di1_pre_sel" , base +0x34 ,15 ,3 , ipu_di_pre_sels,ARRAY_SIZE (ipu_di_pre_sels),CLK_SET_RATE_PARENT ); clk[IMX6QDL_CLK_IPU2_DI0_PRE_SEL ] =imx_clk_mux_flags ("ipu2_di0_pre_sel" , base +0x38 ,6 ,3 , ipu_di_pre_sels,ARRAY_SIZE (ipu_di_pre_sels),CLK_SET_RATE_PARENT ); clk[IMX6QDL_CLK_IPU2_DI1_PRE_SEL ] =imx_clk_mux_flags ("ipu2_di1_pre_sel" , base +0x38 ,15 ,3 , ipu_di_pre_sels,ARRAY_SIZE (ipu_di_pre_sels),CLK_SET_RATE_PARENT ); - clk[IMX6QDL_CLK_IPU1_DI0_SEL ] =imx_clk_mux_flags ("ipu1_di0_sel" , base +0x34 ,0 ,3 , ipu1_di0_sels,ARRAY_SIZE (ipu1_di0_sels),CLK_SET_RATE_PARENT ); - clk[IMX6QDL_CLK_IPU1_DI1_SEL ] =imx_clk_mux_flags ("ipu1_di1_sel" , base +0x34 ,9 ,3 , ipu1_di1_sels,ARRAY_SIZE (ipu1_di1_sels),CLK_SET_RATE_PARENT ); - clk[IMX6QDL_CLK_IPU2_DI0_SEL ] =imx_clk_mux_flags ("ipu2_di0_sel" , base +0x38 ,0 ,3 , ipu2_di0_sels,ARRAY_SIZE (ipu2_di0_sels),CLK_SET_RATE_PARENT ); - clk[IMX6QDL_CLK_IPU2_DI1_SEL ] =imx_clk_mux_flags ("ipu2_di1_sel" , base +0x38 ,9 ,3 , ipu2_di1_sels,ARRAY_SIZE (ipu2_di1_sels),CLK_SET_RATE_PARENT ); clk[IMX6QDL_CLK_HSI_TX_SEL ] =imx_clk_mux ("hsi_tx_sel" , base +0x30 ,28 ,1 , hsi_tx_sels,ARRAY_SIZE (hsi_tx_sels)); clk[IMX6QDL_CLK_PCIE_AXI_SEL ] =imx_clk_mux ("pcie_axi_sel" , base +0x18 ,10 ,1 , pcie_axi_sels,ARRAY_SIZE (pcie_axi_sels)); - clk[IMX6QDL_CLK_SSI1_SEL ] =imx_clk_fixup_mux ("ssi1_sel" , base +0x1c ,10 ,2 , ssi_sels,ARRAY_SIZE (ssi_sels), imx_cscmr1_fixup); - clk[IMX6QDL_CLK_SSI2_SEL ] =imx_clk_fixup_mux ("ssi2_sel" , base +0x1c ,12 ,2 , ssi_sels,ARRAY_SIZE (ssi_sels), imx_cscmr1_fixup); - clk[IMX6QDL_CLK_SSI3_SEL ] =imx_clk_fixup_mux ("ssi3_sel" , base +0x1c ,14 ,2 , ssi_sels,ARRAY_SIZE (ssi_sels), imx_cscmr1_fixup); - clk[IMX6QDL_CLK_USDHC1_SEL ] =imx_clk_fixup_mux ("usdhc1_sel" , base +0x1c ,16 ,1 , usdhc_sels,ARRAY_SIZE (usdhc_sels), imx_cscmr1_fixup); - clk[IMX6QDL_CLK_USDHC2_SEL ] =imx_clk_fixup_mux ("usdhc2_sel" , base +0x1c ,17 ,1 , usdhc_sels,ARRAY_SIZE (usdhc_sels), imx_cscmr1_fixup); - clk[IMX6QDL_CLK_USDHC3_SEL ] =imx_clk_fixup_mux ("usdhc3_sel" , base +0x1c ,18 ,1 , usdhc_sels,ARRAY_SIZE (usdhc_sels), imx_cscmr1_fixup); - clk[IMX6QDL_CLK_USDHC4_SEL ] =imx_clk_fixup_mux ("usdhc4_sel" , base +0x1c ,19 ,1 , usdhc_sels,ARRAY_SIZE (usdhc_sels), imx_cscmr1_fixup); - clk[IMX6QDL_CLK_ENFC_SEL ] =imx_clk_mux ("enfc_sel" , base +0x2c ,16 ,2 , enfc_sels,ARRAY_SIZE (enfc_sels)); - clk[IMX6QDL_CLK_EIM_SEL ] =imx_clk_fixup_mux ("eim_sel" , base +0x1c ,27 ,2 , eim_sels,ARRAY_SIZE (eim_sels), imx_cscmr1_fixup); - clk[IMX6QDL_CLK_EIM_SLOW_SEL ] =imx_clk_fixup_mux ("eim_slow_sel" , base +0x1c ,29 ,2 , eim_slow_sels,ARRAY_SIZE (eim_slow_sels), imx_cscmr1_fixup); +if (clk_on_imx6qp ()) { + clk[IMX6QDL_CLK_IPU1_DI0_SEL ] =imx_clk_mux_flags ("ipu1_di0_sel" , base +0x34 ,0 ,3 , ipu1_di0_sels_2,ARRAY_SIZE (ipu1_di0_sels_2),CLK_SET_RATE_PARENT ); + clk[IMX6QDL_CLK_IPU1_DI1_SEL ] =imx_clk_mux_flags ("ipu1_di1_sel" , base +0x34 ,9 ,3 , ipu1_di1_sels_2,ARRAY_SIZE (ipu1_di1_sels_2),CLK_SET_RATE_PARENT ); + clk[IMX6QDL_CLK_IPU2_DI0_SEL ] =imx_clk_mux_flags ("ipu2_di0_sel" , base +0x38 ,0 ,3 , ipu2_di0_sels_2,ARRAY_SIZE (ipu2_di0_sels_2),CLK_SET_RATE_PARENT ); + clk[IMX6QDL_CLK_IPU2_DI1_SEL ] =imx_clk_mux_flags ("ipu2_di1_sel" , base +0x38 ,9 ,3 , ipu2_di1_sels_2,ARRAY_SIZE (ipu2_di1_sels_2),CLK_SET_RATE_PARENT ); + clk[IMX6QDL_CLK_SSI1_SEL ] =imx_clk_mux ("ssi1_sel" , base +0x1c ,10 ,2 , ssi_sels,ARRAY_SIZE (ssi_sels)); + clk[IMX6QDL_CLK_SSI2_SEL ] =imx_clk_mux ("ssi2_sel" , base +0x1c ,12 ,2 , ssi_sels,ARRAY_SIZE (ssi_sels)); + clk[IMX6QDL_CLK_SSI3_SEL ] =imx_clk_mux ("ssi3_sel" , base +0x1c ,14 ,2 , ssi_sels,ARRAY_SIZE (ssi_sels)); + clk[IMX6QDL_CLK_USDHC1_SEL ] =imx_clk_mux ("usdhc1_sel" , base +0x1c ,16 ,1 , usdhc_sels,ARRAY_SIZE (usdhc_sels)); + clk[IMX6QDL_CLK_USDHC2_SEL ] =imx_clk_mux ("usdhc2_sel" , base +0x1c ,17 ,1 , usdhc_sels,ARRAY_SIZE (usdhc_sels)); + clk[IMX6QDL_CLK_USDHC3_SEL ] =imx_clk_mux ("usdhc3_sel" , base +0x1c ,18 ,1 , usdhc_sels,ARRAY_SIZE (usdhc_sels)); + clk[IMX6QDL_CLK_USDHC4_SEL ] =imx_clk_mux ("usdhc4_sel" , base +0x1c ,19 ,1 , usdhc_sels,ARRAY_SIZE (usdhc_sels)); + clk[IMX6QDL_CLK_ENFC_SEL ] =imx_clk_mux ("enfc_sel" , base +0x2c ,15 ,3 , enfc_sels_2,ARRAY_SIZE (enfc_sels_2)); + clk[IMX6QDL_CLK_EIM_SEL ] =imx_clk_mux ("eim_sel" , base +0x1c ,27 ,2 , eim_sels,ARRAY_SIZE (eim_sels)); + clk[IMX6QDL_CLK_EIM_SLOW_SEL ] =imx_clk_mux ("eim_slow_sel" , base +0x1c ,29 ,2 , eim_slow_sels,ARRAY_SIZE (eim_slow_sels)); + clk[IMX6QDL_CLK_PRE_AXI ] =imx_clk_mux ("pre_axi" , base +0x18 ,1 ,1 , pre_axi_sels,ARRAY_SIZE (pre_axi_sels)); + }else { + clk[IMX6QDL_CLK_IPU1_DI0_SEL ] =imx_clk_mux_flags ("ipu1_di0_sel" , base +0x34 ,0 ,3 , ipu1_di0_sels,ARRAY_SIZE (ipu1_di0_sels),CLK_SET_RATE_PARENT ); + clk[IMX6QDL_CLK_IPU1_DI1_SEL ] =imx_clk_mux_flags ("ipu1_di1_sel" , base +0x34 ,9 ,3 , ipu1_di1_sels,ARRAY_SIZE (ipu1_di1_sels),CLK_SET_RATE_PARENT ); + clk[IMX6QDL_CLK_IPU2_DI0_SEL ] =imx_clk_mux_flags ("ipu2_di0_sel" , base +0x38 ,0 ,3 , ipu2_di0_sels,ARRAY_SIZE (ipu2_di0_sels),CLK_SET_RATE_PARENT ); + clk[IMX6QDL_CLK_IPU2_DI1_SEL ] =imx_clk_mux_flags ("ipu2_di1_sel" , base +0x38 ,9 ,3 , ipu2_di1_sels,ARRAY_SIZE (ipu2_di1_sels),CLK_SET_RATE_PARENT ); + clk[IMX6QDL_CLK_SSI1_SEL ] =imx_clk_fixup_mux ("ssi1_sel" , base +0x1c ,10 ,2 , ssi_sels,ARRAY_SIZE (ssi_sels), imx_cscmr1_fixup); + clk[IMX6QDL_CLK_SSI2_SEL ] =imx_clk_fixup_mux ("ssi2_sel" , base +0x1c ,12 ,2 , ssi_sels,ARRAY_SIZE (ssi_sels), imx_cscmr1_fixup); + clk[IMX6QDL_CLK_SSI3_SEL ] =imx_clk_fixup_mux ("ssi3_sel" , base +0x1c ,14 ,2 , ssi_sels,ARRAY_SIZE (ssi_sels), imx_cscmr1_fixup); + clk[IMX6QDL_CLK_USDHC1_SEL ] =imx_clk_fixup_mux ("usdhc1_sel" , base +0x1c ,16 ,1 , usdhc_sels,ARRAY_SIZE (usdhc_sels), imx_cscmr1_fixup); + clk[IMX6QDL_CLK_USDHC2_SEL ] =imx_clk_fixup_mux ("usdhc2_sel" , base +0x1c ,17 ,1 , usdhc_sels,ARRAY_SIZE (usdhc_sels), imx_cscmr1_fixup); + clk[IMX6QDL_CLK_USDHC3_SEL ] =imx_clk_fixup_mux ("usdhc3_sel" , base +0x1c ,18 ,1 , usdhc_sels,ARRAY_SIZE (usdhc_sels), imx_cscmr1_fixup); + clk[IMX6QDL_CLK_USDHC4_SEL ] =imx_clk_fixup_mux ("usdhc4_sel" , base +0x1c ,19 ,1 , usdhc_sels,ARRAY_SIZE (usdhc_sels), imx_cscmr1_fixup); + clk[IMX6QDL_CLK_ENFC_SEL ] =imx_clk_mux ("enfc_sel" , base +0x2c ,16 ,2 , enfc_sels,ARRAY_SIZE (enfc_sels)); + clk[IMX6QDL_CLK_EIM_SEL ] =imx_clk_fixup_mux ("eim_sel" , base +0x1c ,27 ,2 , eim_sels,ARRAY_SIZE (eim_sels), imx_cscmr1_fixup); + clk[IMX6QDL_CLK_EIM_SLOW_SEL ] =imx_clk_fixup_mux ("eim_slow_sel" , base +0x1c ,29 ,2 , eim_slow_sels,ARRAY_SIZE (eim_slow_sels), imx_cscmr1_fixup); + } clk[IMX6QDL_CLK_VDO_AXI_SEL ] =imx_clk_mux ("vdo_axi_sel" , base +0x18 ,11 ,1 , vdo_axi_sels,ARRAY_SIZE (vdo_axi_sels)); clk[IMX6QDL_CLK_VPU_AXI_SEL ] =imx_clk_mux ("vpu_axi_sel" , base +0x18 ,14 ,2 , vpu_axi_sels,ARRAY_SIZE (vpu_axi_sels)); clk[IMX6QDL_CLK_CKO1_SEL ] =imx_clk_mux ("cko1_sel" , base +0x60 ,0 ,4 , cko1_sels,ARRAY_SIZE (cko1_sels));
@@ -335,23 +379,33 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_PERIPH_CLK2 ] =imx_clk_divider ("periph_clk2" ,"periph_clk2_sel" , base +0x14 ,27 ,3 ); clk[IMX6QDL_CLK_PERIPH2_CLK2 ] =imx_clk_divider ("periph2_clk2" ,"periph2_clk2_sel" , base +0x14 ,0 ,3 ); clk[IMX6QDL_CLK_IPG ] =imx_clk_divider ("ipg" ,"ahb" , base +0x14 ,8 ,2 ); - clk[IMX6QDL_CLK_IPG_PER ] =imx_clk_fixup_divider ("ipg_per" ,"ipg" , base +0x1c ,0 ,6 , imx_cscmr1_fixup); clk[IMX6QDL_CLK_ESAI_PRED ] =imx_clk_divider ("esai_pred" ,"esai_sel" , base +0x28 ,9 ,3 ); clk[IMX6QDL_CLK_ESAI_PODF ] =imx_clk_divider ("esai_podf" ,"esai_pred" , base +0x28 ,25 ,3 ); clk[IMX6QDL_CLK_ASRC_PRED ] =imx_clk_divider ("asrc_pred" ,"asrc_sel" , base +0x30 ,12 ,3 ); clk[IMX6QDL_CLK_ASRC_PODF ] =imx_clk_divider ("asrc_podf" ,"asrc_pred" , base +0x30 ,9 ,3 ); clk[IMX6QDL_CLK_SPDIF_PRED ] =imx_clk_divider ("spdif_pred" ,"spdif_sel" , base +0x30 ,25 ,3 ); clk[IMX6QDL_CLK_SPDIF_PODF ] =imx_clk_divider ("spdif_podf" ,"spdif_pred" , base +0x30 ,22 ,3 ); - clk[IMX6QDL_CLK_CAN_ROOT ] =imx_clk_divider ("can_root" ,"pll3_60m" , base +0x20 ,2 ,6 ); - clk[IMX6QDL_CLK_ECSPI_ROOT ] =imx_clk_divider ("ecspi_root" ,"pll3_60m" , base +0x38 ,19 ,6 ); +if (clk_on_imx6qp ()) { + clk[IMX6QDL_CLK_IPG_PER ] =imx_clk_divider ("ipg_per" ,"ipg_per_sel" , base +0x1c ,0 ,6 ); + clk[IMX6QDL_CLK_ECSPI_ROOT ] =imx_clk_divider ("ecspi_root" ,"ecspi_sel" , base +0x38 ,19 ,6 ); + clk[IMX6QDL_CLK_CAN_ROOT ] =imx_clk_divider ("can_root" ,"can_sel" , base +0x20 ,2 ,6 ); + clk[IMX6QDL_CLK_UART_SERIAL_PODF ] =imx_clk_divider ("uart_serial_podf" ,"uart_sel" , base +0x24 ,0 ,6 ); + clk[IMX6QDL_CLK_LDB_DI0_DIV_3_5 ] =imx_clk_fixed_factor ("ldb_di0_div_3_5" ,"ldb_di0" ,2 ,7 ); + clk[IMX6QDL_CLK_LDB_DI1_DIV_3_5 ] =imx_clk_fixed_factor ("ldb_di1_div_3_5" ,"ldb_di1" ,2 ,7 ); + }else { + clk[IMX6QDL_CLK_ECSPI_ROOT ] =imx_clk_divider ("ecspi_root" ,"pll3_60m" , base +0x38 ,19 ,6 ); + clk[IMX6QDL_CLK_CAN_ROOT ] =imx_clk_divider ("can_root" ,"pll3_60" , base +0x20 ,2 ,6 ); + clk[IMX6QDL_CLK_IPG_PER ] =imx_clk_fixup_divider ("ipg_per" ,"ipg" , base +0x1c ,0 ,6 , imx_cscmr1_fixup); + clk[IMX6QDL_CLK_UART_SERIAL_PODF ] =imx_clk_divider ("uart_serial_podf" ,"pll3_80m" , base +0x24 ,0 ,6 ); + clk[IMX6QDL_CLK_LDB_DI0_DIV_3_5 ] =imx_clk_fixed_factor ("ldb_di0_div_3_5" ,"ldb_di0_sel" ,2 ,7 ); + clk[IMX6QDL_CLK_LDB_DI1_DIV_3_5 ] =imx_clk_fixed_factor ("ldb_di1_div_3_5" ,"ldb_di1_sel" ,2 ,7 ); + } clk[IMX6QDL_CLK_GPU2D_CORE_PODF ] =imx_clk_divider ("gpu2d_core_podf" ,"gpu2d_core_sel" , base +0x18 ,23 ,3 ); clk[IMX6QDL_CLK_GPU3D_CORE_PODF ] =imx_clk_divider ("gpu3d_core_podf" ,"gpu3d_core_sel" , base +0x18 ,26 ,3 ); clk[IMX6QDL_CLK_GPU3D_SHADER ] =imx_clk_divider ("gpu3d_shader" ,"gpu3d_shader_sel" , base +0x18 ,29 ,3 ); clk[IMX6QDL_CLK_IPU1_PODF ] =imx_clk_divider ("ipu1_podf" ,"ipu1_sel" , base +0x3c ,11 ,3 ); clk[IMX6QDL_CLK_IPU2_PODF ] =imx_clk_divider ("ipu2_podf" ,"ipu2_sel" , base +0x3c ,16 ,3 ); - clk[IMX6QDL_CLK_LDB_DI0_DIV_3_5 ] =imx_clk_fixed_factor ("ldb_di0_div_3_5" ,"ldb_di0_sel" ,2 ,7 ); clk[IMX6QDL_CLK_LDB_DI0_PODF ] =imx_clk_divider_flags ("ldb_di0_podf" ,"ldb_di0_div_3_5" , base +0x20 ,10 ,1 ,0 ); - clk[IMX6QDL_CLK_LDB_DI1_DIV_3_5 ] =imx_clk_fixed_factor ("ldb_di1_div_3_5" ,"ldb_di1_sel" ,2 ,7 ); clk[IMX6QDL_CLK_LDB_DI1_PODF ] =imx_clk_divider_flags ("ldb_di1_podf" ,"ldb_di1_div_3_5" , base +0x20 ,11 ,1 ,0 ); clk[IMX6QDL_CLK_IPU1_DI0_PRE ] =imx_clk_divider ("ipu1_di0_pre" ,"ipu1_di0_pre_sel" , base +0x34 ,3 ,3 ); clk[IMX6QDL_CLK_IPU1_DI1_PRE ] =imx_clk_divider ("ipu1_di1_pre" ,"ipu1_di1_pre_sel" , base +0x34 ,12 ,3 );
@@ -364,15 +418,19 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_SSI2_PODF ] =imx_clk_divider ("ssi2_podf" ,"ssi2_pred" , base +0x2c ,0 ,6 ); clk[IMX6QDL_CLK_SSI3_PRED ] =imx_clk_divider ("ssi3_pred" ,"ssi3_sel" , base +0x28 ,22 ,3 ); clk[IMX6QDL_CLK_SSI3_PODF ] =imx_clk_divider ("ssi3_podf" ,"ssi3_pred" , base +0x28 ,16 ,6 ); - clk[IMX6QDL_CLK_UART_SERIAL_PODF ] =imx_clk_divider ("uart_serial_podf" ,"pll3_80m" , base +0x24 ,0 ,6 ); clk[IMX6QDL_CLK_USDHC1_PODF ] =imx_clk_divider ("usdhc1_podf" ,"usdhc1_sel" , base +0x24 ,11 ,3 ); clk[IMX6QDL_CLK_USDHC2_PODF ] =imx_clk_divider ("usdhc2_podf" ,"usdhc2_sel" , base +0x24 ,16 ,3 ); clk[IMX6QDL_CLK_USDHC3_PODF ] =imx_clk_divider ("usdhc3_podf" ,"usdhc3_sel" , base +0x24 ,19 ,3 ); clk[IMX6QDL_CLK_USDHC4_PODF ] =imx_clk_divider ("usdhc4_podf" ,"usdhc4_sel" , base +0x24 ,22 ,3 ); clk[IMX6QDL_CLK_ENFC_PRED ] =imx_clk_divider ("enfc_pred" ,"enfc_sel" , base +0x2c ,18 ,3 ); clk[IMX6QDL_CLK_ENFC_PODF ] =imx_clk_divider ("enfc_podf" ,"enfc_pred" , base +0x2c ,21 ,6 ); - clk[IMX6QDL_CLK_EIM_PODF ] =imx_clk_fixup_divider ("eim_podf" ,"eim_sel" , base +0x1c ,20 ,3 , imx_cscmr1_fixup); - clk[IMX6QDL_CLK_EIM_SLOW_PODF ] =imx_clk_fixup_divider ("eim_slow_podf" ,"eim_slow_sel" , base +0x1c ,23 ,3 , imx_cscmr1_fixup); +if (clk_on_imx6qp ()) { + clk[IMX6QDL_CLK_EIM_PODF ] =imx_clk_divider ("eim_podf" ,"eim_sel" , base +0x1c ,20 ,3 ); + clk[IMX6QDL_CLK_EIM_SLOW_PODF ] =imx_clk_divider ("eim_slow_podf" ,"eim_slow_sel" , base +0x1c ,23 ,3 ); + }else { + clk[IMX6QDL_CLK_EIM_PODF ] =imx_clk_fixup_divider ("eim_podf" ,"eim_sel" , base +0x1c ,20 ,3 , imx_cscmr1_fixup); + clk[IMX6QDL_CLK_EIM_SLOW_PODF ] =imx_clk_fixup_divider ("eim_slow_podf" ,"eim_slow_sel" , base +0x1c ,23 ,3 , imx_cscmr1_fixup); + } clk[IMX6QDL_CLK_VPU_AXI_PODF ] =imx_clk_divider ("vpu_axi_podf" ,"vpu_axi_sel" , base +0x24 ,25 ,3 ); clk[IMX6QDL_CLK_CKO1_PODF ] =imx_clk_divider ("cko1_podf" ,"cko1_sel" , base +0x60 ,4 ,3 ); clk[IMX6QDL_CLK_CKO2_PODF ] =imx_clk_divider ("cko2_podf" ,"cko2_sel" , base +0x60 ,21 ,3 );
@@ -380,7 +438,12 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)/* name parent_name reg shift width busy: reg, shift */ clk[IMX6QDL_CLK_AXI ] =imx_clk_busy_divider ("axi" ,"axi_sel" , base +0x14 ,16 ,3 , base +0x48 ,0 ); clk[IMX6QDL_CLK_MMDC_CH0_AXI_PODF ] =imx_clk_busy_divider ("mmdc_ch0_axi_podf" ,"periph" , base +0x14 ,19 ,3 , base +0x48 ,4 ); - clk[IMX6QDL_CLK_MMDC_CH1_AXI_PODF ] =imx_clk_busy_divider ("mmdc_ch1_axi_podf" ,"periph2" , base +0x14 ,3 ,3 , base +0x48 ,2 ); +if (clk_on_imx6qp ()) { + clk[IMX6QDL_CLK_MMDC_CH1_AXI_CG ] =imx_clk_gate ("mmdc_ch1_axi_cg" ,"periph2" , base +0x4 ,18 ); + clk[IMX6QDL_CLK_MMDC_CH1_AXI_PODF ] =imx_clk_busy_divider ("mmdc_ch1_axi_podf" ,"mmdc_ch1_axi_cg" , base +0x14 ,3 ,3 , base +0x48 ,2 ); + }else { + clk[IMX6QDL_CLK_MMDC_CH1_AXI_PODF ] =imx_clk_busy_divider ("mmdc_ch1_axi_podf" ,"periph2" , base +0x14 ,3 ,3 , base +0x48 ,2 ); + } clk[IMX6QDL_CLK_ARM ] =imx_clk_busy_divider ("arm" ,"pll1_sw" , base +0x10 ,0 ,3 , base +0x48 ,16 ); clk[IMX6QDL_CLK_AHB ] =imx_clk_busy_divider ("ahb" ,"periph" , base +0x14 ,10 ,3 , base +0x48 ,1 );
@@ -432,8 +495,13 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_IPU1_DI1 ] =imx_clk_gate2 ("ipu1_di1" ,"ipu1_di1_sel" , base +0x74 ,4 ); clk[IMX6QDL_CLK_IPU2 ] =imx_clk_gate2 ("ipu2" ,"ipu2_podf" , base +0x74 ,6 ); clk[IMX6QDL_CLK_IPU2_DI0 ] =imx_clk_gate2 ("ipu2_di0" ,"ipu2_di0_sel" , base +0x74 ,8 ); - clk[IMX6QDL_CLK_LDB_DI0 ] =imx_clk_gate2 ("ldb_di0" ,"ldb_di0_podf" , base +0x74 ,12 ); - clk[IMX6QDL_CLK_LDB_DI1 ] =imx_clk_gate2 ("ldb_di1" ,"ldb_di1_podf" , base +0x74 ,14 ); +if (clk_on_imx6qp ()) { + clk[IMX6QDL_CLK_LDB_DI0 ] =imx_clk_gate2 ("ldb_di0" ,"ldb_di0_sel" , base +0x74 ,12 ); + clk[IMX6QDL_CLK_LDB_DI1 ] =imx_clk_gate2 ("ldb_di1" ,"ldb_di1_sel" , base +0x74 ,14 ); + }else { + clk[IMX6QDL_CLK_LDB_DI0 ] =imx_clk_gate2 ("ldb_di0" ,"ldb_di0_podf" , base +0x74 ,12 ); + clk[IMX6QDL_CLK_LDB_DI1 ] =imx_clk_gate2 ("ldb_di1" ,"ldb_di1_podf" , base +0x74 ,14 ); + } clk[IMX6QDL_CLK_IPU2_DI1 ] =imx_clk_gate2 ("ipu2_di1" ,"ipu2_di1_sel" , base +0x74 ,10 ); clk[IMX6QDL_CLK_HSI_TX ] =imx_clk_gate2_shared ("hsi_tx" ,"hsi_tx_podf" , base +0x74 ,16 , &share_count_mipi_core_cfg); clk[IMX6QDL_CLK_MIPI_CORE_CFG ] =imx_clk_gate2_shared ("mipi_core_cfg" ,"video_27m" , base +0x74 ,16 , &share_count_mipi_core_cfg);
@@ -482,6 +550,16 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node) clk[IMX6QDL_CLK_EIM_SLOW ] =imx_clk_gate2 ("eim_slow" ,"eim_slow_podf" , base +0x80 ,10 ); clk[IMX6QDL_CLK_VDO_AXI ] =imx_clk_gate2 ("vdo_axi" ,"vdo_axi_sel" , base +0x80 ,12 ); clk[IMX6QDL_CLK_VPU_AXI ] =imx_clk_gate2 ("vpu_axi" ,"vpu_axi_podf" , base +0x80 ,14 ); +if (clk_on_imx6qp ()) { + clk[IMX6QDL_CLK_PRE0 ] =imx_clk_gate2 ("pre0" ,"pre_axi" , base +0x80 ,16 ); + clk[IMX6QDL_CLK_PRE1 ] =imx_clk_gate2 ("pre1" ,"pre_axi" , base +0x80 ,18 ); + clk[IMX6QDL_CLK_PRE2 ] =imx_clk_gate2 ("pre2" ,"pre_axi" , base +0x80 ,20 ); + clk[IMX6QDL_CLK_PRE3 ] =imx_clk_gate2 ("pre3" ,"pre_axi" , base +0x80 ,22 ); + clk[IMX6QDL_CLK_PRG0_AXI ] =imx_clk_gate2_shared ("prg0_axi" ,"ipu1_podf" , base +0x80 ,24 , &share_count_prg0); + clk[IMX6QDL_CLK_PRG1_AXI ] =imx_clk_gate2_shared ("prg1_axi" ,"ipu2_podf" , base +0x80 ,26 , &share_count_prg1); + clk[IMX6QDL_CLK_PRG0_APB ] =imx_clk_gate2_shared ("prg0_apb" ,"ipg" , base +0x80 ,24 , &share_count_prg0); + clk[IMX6QDL_CLK_PRG1_APB ] =imx_clk_gate2_shared ("prg1_apb" ,"ipg" , base +0x80 ,26 , &share_count_prg1); + } clk[IMX6QDL_CLK_CKO1 ] =imx_clk_gate ("cko1" ,"cko1_podf" , base +0x60 ,7 ); clk[IMX6QDL_CLK_CKO2 ] =imx_clk_gate ("cko2" ,"cko2_podf" , base +0x60 ,24 );
include/dt-bindings/clock/imx6qdl-clock.h +15 -1
@@ -255,6 +255,20 @@#define IMX6QDL_CLK_CAAM_ACLK 242#define IMX6QDL_CLK_CAAM_IPG 243#define IMX6QDL_CLK_SPDIF_GCLK 244 -#define IMX6QDL_CLK_END 245 +#define IMX6QDL_CLK_UART_SEL 245 +#define IMX6QDL_CLK_IPG_PER_SEL 246 +#define IMX6QDL_CLK_ECSPI_SEL 247 +#define IMX6QDL_CLK_CAN_SEL 248 +#define IMX6QDL_CLK_MMDC_CH1_AXI_CG 249 +#define IMX6QDL_CLK_PRE0 250 +#define IMX6QDL_CLK_PRE1 251 +#define IMX6QDL_CLK_PRE2 252 +#define IMX6QDL_CLK_PRE3 253 +#define IMX6QDL_CLK_PRG0_AXI 254 +#define IMX6QDL_CLK_PRG1_AXI 255 +#define IMX6QDL_CLK_PRG0_APB 256 +#define IMX6QDL_CLK_PRG1_APB 257 +#define IMX6QDL_CLK_PRE_AXI 258 +#define IMX6QDL_CLK_END 259#endif /* __DT_BINDINGS_CLOCK_IMX6QDL_H */
Signature · 1 line
1.9.1
PATCH v3 2/5 ARM: dts: imx: Add basic dts support for imx6qp SOC
The i.MX6Quad Plus processor is an high performance SOC of i.MX6 family. It has enhanced graphics performance and increased overall memory bandwidth compared to i.MX6Q. Most of the design are same as i.MX6Quad/Dual, so code for i.MX6Quad can be resued by this chip. The revision number is identied as i.MX6Q Rev2.0, but actually it is a new chip, as we did many change to the overall architecture.
This patch adds basic dtsi file support for the new i.MX6Quad Plus processor.
---
change for V3:
--remove some device node that the driver is not ready or stable in upstream -- update the copyright header
arch/arm/boot/dts/imx6q.dtsi | 2 +- arch/arm/boot/dts/imx6qdl-sabresd.dtsi | 1 + arch/arm/boot/dts/imx6qp.dtsi | 86 ++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 1 deletion(-) create mode 100644 arch/arm/boot/dts/imx6qp.dtsi
arch/arm/boot/dts/imx6q.dtsi +1 -1
@@ -22,7 +22,7 @@ #address-cells = <1>; #size-cells = <0>; - cpu at 0 { + cpu0: cpu at 0 { compatible = "arm,cortex-a9"; device_type = "cpu"; reg = <0>;
arch/arm/boot/dts/imx6qdl-sabresd.dtsi +1 -0
@@ -238,6 +238,7 @@ regulator-max-microvolt = <3300000>; regulator-boot-on; regulator-always-on; + regulator-ramp-delay = <6250>; }; sw3a_reg: sw3a {
arch/arm/boot/dts/imx6qp.dtsi new file +86 -0
86 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v3 3/5 ARM: dts: imx: Add basic dts support for imx6qp-sabreauto
In reply to Bai PingThis patch adds basic dts file for i.MX6QP-Sbreauto board.
---
change for V3:
-- correct the dts list in alphabet order
-- update the copyright header for double license
arch/arm/boot/dts/Makefile | 3 +- arch/arm/boot/dts/imx6qp-sabreauto.dts | 93 ++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 arch/arm/boot/dts/imx6qp-sabreauto.dts
arch/arm/boot/dts/Makefile +2 -1
@@ -352,7 +352,8 @@ dtb-$(CONFIG_SOC_IMX6Q) += \ imx6q-tx6q-1110.dtb \ imx6q-udoo.dtb \ imx6q-wandboard.dtb \ - imx6q-wandboard-revb1.dtb + imx6q-wandboard-revb1.dtb \ + imx6qp-sabreauto.dtb dtb-$(CONFIG_SOC_IMX6SL) += \ imx6sl-evk.dtb \ imx6sl-warp.dtb
arch/arm/boot/dts/imx6qp-sabreauto.dts new file +93 -0
93 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v3 4/5 ARM: dts: imx: Add basic dts support for imx6qp-sabresd
In reply to Bai PingThis patch adds dts file for imx6qp-sabresd board.
---
change for V3:
-- update the copyright header
-- add the dtb in alphabet order
arch/arm/boot/dts/Makefile | 3 +- arch/arm/boot/dts/imx6qp-sabresd.dts | 93 ++++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+), 1 deletion(-) create mode 100644 arch/arm/boot/dts/imx6qp-sabresd.dts
arch/arm/boot/dts/Makefile +2 -1
@@ -353,7 +353,8 @@ dtb-$(CONFIG_SOC_IMX6Q) += \ imx6q-udoo.dtb \ imx6q-wandboard.dtb \ imx6q-wandboard-revb1.dtb \ - imx6qp-sabreauto.dtb + imx6qp-sabreauto.dtb \ + imx6qp-sabresd.dtb dtb-$(CONFIG_SOC_IMX6SL) += \ imx6sl-evk.dtb \ imx6sl-warp.dtb
arch/arm/boot/dts/imx6qp-sabresd.dts new file +93 -0
93 lines not on this page · raw message
Signature · 1 line
1.9.1
PATCH v3 5/5 ARM: imx: Add msl code support for imx6qp
In reply to Bai PingThe i.MX6QP is a different SOC, but internally we treate it as i.MX6Q Rev_2.0 to maximum the code reusability. The chip silicon number we read from the ANADIG_DIGPROG is 0x630100. This patch add code to identify it as i.MX6QP Rev_1.0 when print out the silicon version.
---
change for V3:
-- add comment for the revision trick code
arch/arm/mach-imx/anatop.c | 9 ++++++++- arch/arm/mach-imx/mach-imx6q.c | 8 ++++++-- 2 files changed, 14 insertions(+), 3 deletions(-)
arch/arm/mach-imx/anatop.c +8 -1
@@ -129,7 +129,14 @@ void __init imx_init_revision_from_anatop(void)switch (digprog &0xff ) {case 0 : - revision =IMX_CHIP_REVISION_1_0 ; +/* +* For i.MX6QP, most of the code for i.MX6Q can be resued, +* so internally, we identify it as i.MX6Q Rev 2.0 +*/ +if (digprog >>8 &0x01 ) + revision =IMX_CHIP_REVISION_2_0 ; +else + revision =IMX_CHIP_REVISION_1_0 ;break ;case 1 : revision =IMX_CHIP_REVISION_1_1 ;
arch/arm/mach-imx/mach-imx6q.c +6 -2
@@ -266,8 +266,11 @@ static void __init imx6q_init_machine(void) {struct device *parent; -imx_print_silicon_rev (cpu_is_imx6dl () ?"i.MX6DL" :"i.MX6Q" , -imx_get_soc_revision ()); +if (cpu_is_imx6q () &&imx_get_soc_revision () ==IMX_CHIP_REVISION_2_0 ) +imx_print_silicon_rev ("i.MX6QP" ,IMX_CHIP_REVISION_1_0 ); +else +imx_print_silicon_rev (cpu_is_imx6dl () ?"i.MX6DL" :"i.MX6Q" , +imx_get_soc_revision ()); parent =imx_soc_device_init ();if (parent ==NULL )
@@ -399,6 +402,7 @@ static void __init imx6q_init_irq(void)static const char *const imx6q_dt_compat[]__initconst = {"fsl,imx6dl" ,"fsl,imx6q" , +"fsl,imx6qp" ,NULL , };
Signature · 1 line
1.9.1
Shawn Guo
AppliedPATCH v3 1/5 clk: imx: Add clock support for imx6qp
In reply to Bai PingQuoted 13 lines · Bai Ping
most of the clock tree structures on i.MX6 Quad Plus are same as on i.MX6Q. there still some differences between these two SOCs. compared to the i.XM6Q, the differents of clocks on i.MX6QP is mainly on:
1. New clock gate added to support the PRE and PRG modules
2. 24MHz OSC clock option added to the UART, IPG, ECSPI, and CAN clock roots.
3. MMDC channel 1 clock gate is now controllable.
4. clock gating added to theLDB_DIx_IPUclocks on i.MX6QP
5. EMI clock root divider fix
6. other updates fo CSCMRx, CSCDRx and CS2CDR registers.
Quoted 3 lines
detailed infomation, please refer to the i.MX6QP RM.
Signed-off-by Bai Ping <[email protected]>
Applied all, thanks.