diff --git a/arch/arm/include/asm/arch-imx8/i2c.h b/arch/arm/include/asm/arch-imx8/i2c.h index 4c88b9f5d7..6506efffda 100644 --- a/arch/arm/include/asm/arch-imx8/i2c.h +++ b/arch/arm/include/asm/arch-imx8/i2c.h @@ -8,29 +8,40 @@ #define __ASM_ARCH_IMX8_I2C_H__ #include +#include struct imx_i2c_map { - int index; + unsigned index; sc_rsrc_t rsrc; + u32 lpcg[4]; }; static struct imx_i2c_map imx_i2c_desc[] = { - {0, SC_R_I2C_0}, - {1, SC_R_I2C_1}, - {2, SC_R_I2C_2}, - {3, SC_R_I2C_3}, - {4, SC_R_I2C_4}, - {5, SC_R_LVDS_0_I2C_0}, /* lvds0 i2c0 */ - {6, SC_R_LVDS_0_I2C_0}, /* lvds0 i2c1 */ - {7, SC_R_LVDS_1_I2C_0}, /* lvds1 i2c0 */ - {8, SC_R_LVDS_1_I2C_0}, /* lvds1 i2c1 */ - {9, SC_R_CSI_0_I2C_0}, - {10, SC_R_CSI_1_I2C_0}, - {11, SC_R_HDMI_I2C_0}, - {12, SC_R_HDMI_RX_I2C_0}, - {13, SC_R_MIPI_0_I2C_0}, - {14, SC_R_MIPI_0_I2C_1}, - {15, SC_R_MIPI_1_I2C_0}, - {16, SC_R_MIPI_1_I2C_1}, + {0, SC_R_I2C_0, {LPI2C_0_LPCG}}, + {1, SC_R_I2C_1, {LPI2C_1_LPCG}}, + {2, SC_R_I2C_2, {LPI2C_2_LPCG}}, + {3, SC_R_I2C_3, {LPI2C_3_LPCG}}, +#ifdef CONFIG_IMX8QM + {4, SC_R_I2C_4, {LPI2C_4_LPCG}}, +#endif + {5, SC_R_LVDS_0_I2C_0, {DI_LVDS_0_LPCG + 0x10}}, /* lvds0 i2c0 */ + {6, SC_R_LVDS_0_I2C_0, {DI_LVDS_0_LPCG + 0x10}}, /* lvds0 i2c1 */ + {7, SC_R_LVDS_1_I2C_0, {DI_LVDS_1_LPCG + 0x10}}, /* lvds1 i2c0 */ + {8, SC_R_LVDS_1_I2C_0, {DI_LVDS_1_LPCG + 0x10}}, /* lvds1 i2c1 */ + {9, SC_R_CSI_0_I2C_0, {MIPI_CSI_0_LPCG + 0x14}}, + {10, SC_R_CSI_1_I2C_0, {MIPI_CSI_1_LPCG + 0x14}}, + {11, SC_R_HDMI_I2C_0, {DI_HDMI_LPCG}}, + {12, SC_R_HDMI_RX_I2C_0, {RX_HDMI_LPCG + 0x10, RX_HDMI_LPCG + 0x14, RX_HDMI_LPCG + 0x18, RX_HDMI_LPCG + 0x1C}}, +#ifdef CONFIG_IMX8QM + {13, SC_R_MIPI_0_I2C_0, {MIPI_DSI_0_LPCG + 0x14, MIPI_DSI_0_LPCG + 0x18, MIPI_DSI_0_LPCG + 0x1c}}, + {14, SC_R_MIPI_0_I2C_1, {MIPI_DSI_0_LPCG + 0x24, MIPI_DSI_0_LPCG + 0x28, MIPI_DSI_0_LPCG + 0x2c}}, + {15, SC_R_MIPI_1_I2C_0, {MIPI_DSI_1_LPCG + 0x14, MIPI_DSI_1_LPCG + 0x18, MIPI_DSI_1_LPCG + 0x1c}}, + {16, SC_R_MIPI_1_I2C_1, {MIPI_DSI_1_LPCG + 0x24, MIPI_DSI_1_LPCG + 0x28, MIPI_DSI_1_LPCG + 0x2c}}, +#else + {13, SC_R_MIPI_0_I2C_0, {DI_MIPI0_LPCG, DI_MIPI0_LPCG + 0x10, DI_MIPI0_LPCG + 0x14}}, + {14, SC_R_MIPI_0_I2C_1, {DI_MIPI0_LPCG, DI_MIPI0_LPCG + 0x10, DI_MIPI0_LPCG + 0x14}}, + {15, SC_R_MIPI_1_I2C_0, {DI_MIPI1_LPCG, DI_MIPI1_LPCG + 0x10, DI_MIPI1_LPCG + 0x14}}, + {16, SC_R_MIPI_1_I2C_1, {DI_MIPI1_LPCG, DI_MIPI1_LPCG + 0x10, DI_MIPI1_LPCG + 0x14}}, +#endif }; #endif /* __ASM_ARCH_IMX8_I2C_H__ */ diff --git a/arch/arm/mach-imx/imx8/Makefile b/arch/arm/mach-imx/imx8/Makefile index e3be955b2d..24cbbebf8e 100644 --- a/arch/arm/mach-imx/imx8/Makefile +++ b/arch/arm/mach-imx/imx8/Makefile @@ -6,6 +6,7 @@ obj-y += lowlevel_init.o obj-y += cpu.o obj-y += clock.o +obj-y += lpcg.o obj-y += fsl_mu_hal.o obj-y += fuse.o obj-y += iomux.o diff --git a/arch/arm/mach-imx/imx8/clock.c b/arch/arm/mach-imx/imx8/clock.c index fb9df7fedc..78b53f2816 100644 --- a/arch/arm/mach-imx/imx8/clock.c +++ b/arch/arm/mach-imx/imx8/clock.c @@ -12,6 +12,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -121,28 +122,47 @@ u32 imx_get_fecclk(void) return mxc_get_clock(MXC_FEC_CLK); } +static struct imx_i2c_map *get_i2c_desc(unsigned i2c_num) +{ + int i; + for (i = 0; i < ARRAY_SIZE(imx_i2c_desc); i++) { + if (imx_i2c_desc[i].index == i2c_num) + return &imx_i2c_desc[i]; + } + return NULL; +} + int enable_i2c_clk(unsigned char enable, unsigned i2c_num) { sc_ipc_t ipc; sc_err_t err; + struct imx_i2c_map *desc; + int i; - if (i2c_num >= ARRAY_SIZE(imx_i2c_desc)) + desc = get_i2c_desc(i2c_num); + if (!desc) return -EINVAL; ipc = gd->arch.ipc_channel_handle; if (enable) err = sc_pm_clock_enable(ipc, - imx_i2c_desc[i2c_num].rsrc, 2, true, false); + desc->rsrc, 2, true, false); else err = sc_pm_clock_enable(ipc, - imx_i2c_desc[i2c_num].rsrc, 2, false, false); + desc->rsrc, 2, false, false); if (err != SC_ERR_NONE) { printf("i2c clock error %d\n", err); return -EPERM; } + for (i = 0; i < 4; i++) { + if (desc->lpcg[i] == 0) + break; + LPCG_AllClockOn(desc->lpcg[i]); + } + return 0; } @@ -151,12 +171,14 @@ u32 imx_get_i2cclk(unsigned i2c_num) sc_err_t err; sc_ipc_t ipc; u32 clock_rate; + struct imx_i2c_map *desc; - if (i2c_num >= ARRAY_SIZE(imx_i2c_desc)) - return 0; + desc = get_i2c_desc(i2c_num); + if (!desc) + return -EINVAL; ipc = gd->arch.ipc_channel_handle; - err = sc_pm_get_clock_rate(ipc, imx_i2c_desc[i2c_num].rsrc, 2, + err = sc_pm_get_clock_rate(ipc, desc->rsrc, 2, &clock_rate); if (err != SC_ERR_NONE) return 0; @@ -185,6 +207,8 @@ void init_clk_fspi(int index) return; } + LPCG_AllClockOn(FSPI_0_LPCG); + return; } @@ -224,11 +248,14 @@ void init_clk_gpmi_nand(void) return; } + LPCG_AllClockOn(NAND_LPCG); + return; } void enable_usboh3_clk(unsigned char enable) { + LPCG_AllClockOn(USB_2_LPCG); return; } @@ -254,6 +281,7 @@ void init_clk_usb3(int index) printf("USB3 set clock failed!, line=%d (error = %d)\n", __LINE__, err); + LPCG_AllClockOn(USB_3_LPCG); return; } @@ -270,6 +298,8 @@ int cdns3_disable_clks(int index) ipc = gd->arch.ipc_channel_handle; + LPCG_AllClockOff(USB_3_LPCG); + err = sc_pm_clock_enable(ipc, SC_R_USB_2, SC_PM_CLK_MISC, false, false); if (err != SC_ERR_NONE) printf("USB3 disable clock failed!, line=%d (error = %d)\n", @@ -345,6 +375,8 @@ void init_clk_usdhc(u32 index) printf("SDHC_%d per clk enable failed!\n", index); return; } + + LPCG_AllClockOn(USDHC_0_LPCG + index * 0x10000); } void init_clk_fec(int index) @@ -389,6 +421,8 @@ void init_clk_fec(int index) printf("\nSC_R_ENET_0 set clock enable failed! (error = %d)\n", err); return; } + + LPCG_AllClockOn(ENET_0_LPCG + index * 0x10000); } /* diff --git a/arch/arm/mach-imx/imx8/cpu.c b/arch/arm/mach-imx/imx8/cpu.c index 55cc320c80..f554ad8d54 100644 --- a/arch/arm/mach-imx/imx8/cpu.c +++ b/arch/arm/mach-imx/imx8/cpu.c @@ -27,6 +27,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -506,6 +507,8 @@ int arch_auxiliary_core_up(u32 core_id, ulong boot_private_data) return -EIO; } + LPCG_AllClockOn(AUD_DSP_LPCG); + if (!power_domain_lookup_name("audio_sai0", &pd)) { if (power_domain_on(&pd)) { printf("Error power on SAI0\n"); @@ -519,6 +522,9 @@ int arch_auxiliary_core_up(u32 core_id, ulong boot_private_data) return -EIO; } } + + LPCG_AllClockOn(AUD_OCRAM_LPCG); + LPCG_AllClockOn(AUD_SAI_0_LPCG); } printf("Copy image from 0x%lx to 0x%lx\n", addr, (ulong)aux_core_ram); diff --git a/arch/arm/mach-imx/imx8/video_common.c b/arch/arm/mach-imx/imx8/video_common.c index efed987878..01ab94a00e 100644 --- a/arch/arm/mach-imx/imx8/video_common.c +++ b/arch/arm/mach-imx/imx8/video_common.c @@ -22,6 +22,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -342,6 +343,7 @@ int display_controller_setup(sc_pm_clock_rate_t pixel_clock) sc_pm_clock_rate_t pll_clk; const char *pll1_pd_name; sc_ipc_t ipcHndl = gd->arch.ipc_channel_handle; + u32 dc_lpcg; int dc_id = gdc; @@ -353,11 +355,13 @@ int display_controller_setup(sc_pm_clock_rate_t pixel_clock) pll0_rsrc = SC_R_DC_0_PLL_0; pll1_rsrc = SC_R_DC_0_PLL_1; pll1_pd_name = "dc0_pll1"; + dc_lpcg = DC_0_LPCG; } else { dc_rsrc = SC_R_DC_1; pll0_rsrc = SC_R_DC_1_PLL_0; pll1_rsrc = SC_R_DC_1_PLL_1; pll1_pd_name = "dc1_pll1"; + dc_lpcg = DC_1_LPCG; } if (!power_domain_lookup_name(pll1_pd_name, &pd)) { @@ -425,6 +429,8 @@ int display_controller_setup(sc_pm_clock_rate_t pixel_clock) return -EIO; } + LPCG_AllClockOn(dc_lpcg); + err = sc_misc_set_control(ipcHndl, dc_rsrc, SC_C_PXL_LINK_MST1_ADDR, 0); if (err != SC_ERR_NONE) { printf("DC Set control fSC_C_PXL_LINK_MST1_ADDR ailed! (error = %d)\n", err); diff --git a/board/freescale/imx8qm_arm2/imx8qm_arm2.c b/board/freescale/imx8qm_arm2/imx8qm_arm2.c index 6827b57a64..911485e5dc 100644 --- a/board/freescale/imx8qm_arm2/imx8qm_arm2.c +++ b/board/freescale/imx8qm_arm2/imx8qm_arm2.c @@ -29,6 +29,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -90,6 +91,8 @@ int board_early_init_f(void) if (sciErr != SC_ERR_NONE) return 0; + LPCG_AllClockOn(LPUART_0_LPCG); + setup_iomux_uart(); return 0; @@ -485,6 +488,19 @@ static void imx8qm_hsio_initialize(void) printf("hsio_gpio Power up failed! (error = %d)\n", ret); } + LPCG_AllClockOn(HSIO_PCIE_X2_LPCG); + LPCG_AllClockOn(HSIO_PCIE_X1_LPCG); + LPCG_AllClockOn(HSIO_SATA_LPCG); + LPCG_AllClockOn(HSIO_PHY_X2_LPCG); + LPCG_AllClockOn(HSIO_PHY_X1_LPCG); + LPCG_AllClockOn(HSIO_PHY_X2_CRR0_LPCG); + LPCG_AllClockOn(HSIO_PHY_X1_CRR1_LPCG); + LPCG_AllClockOn(HSIO_PCIE_X2_CRR2_LPCG); + LPCG_AllClockOn(HSIO_PCIE_X1_CRR3_LPCG); + LPCG_AllClockOn(HSIO_SATA_CRR4_LPCG); + LPCG_AllClockOn(HSIO_MISC_LPCG); + LPCG_AllClockOn(HSIO_GPIO_LPCG); + imx8_iomux_setup_multiple_pads(board_pcie_pins, ARRAY_SIZE(board_pcie_pins)); } diff --git a/board/freescale/imx8qm_mek/imx8qm_mek.c b/board/freescale/imx8qm_mek/imx8qm_mek.c index 943bb2f792..2efec39736 100644 --- a/board/freescale/imx8qm_mek/imx8qm_mek.c +++ b/board/freescale/imx8qm_mek/imx8qm_mek.c @@ -29,6 +29,7 @@ #include #include "../common/tcpc.h" #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -87,6 +88,8 @@ int board_early_init_f(void) if (sciErr != SC_ERR_NONE) return 0; + LPCG_AllClockOn(LPUART_0_LPCG); + setup_iomux_uart(); return 0; @@ -267,6 +270,19 @@ static void imx8qm_hsio_initialize(void) printf("hsio_gpio Power up failed! (error = %d)\n", ret); } + LPCG_AllClockOn(HSIO_PCIE_X2_LPCG); + LPCG_AllClockOn(HSIO_PCIE_X1_LPCG); + LPCG_AllClockOn(HSIO_SATA_LPCG); + LPCG_AllClockOn(HSIO_PHY_X2_LPCG); + LPCG_AllClockOn(HSIO_PHY_X1_LPCG); + LPCG_AllClockOn(HSIO_PHY_X2_CRR0_LPCG); + LPCG_AllClockOn(HSIO_PHY_X1_CRR1_LPCG); + LPCG_AllClockOn(HSIO_PCIE_X2_CRR2_LPCG); + LPCG_AllClockOn(HSIO_PCIE_X1_CRR3_LPCG); + LPCG_AllClockOn(HSIO_SATA_CRR4_LPCG); + LPCG_AllClockOn(HSIO_MISC_LPCG); + LPCG_AllClockOn(HSIO_GPIO_LPCG); + imx8_iomux_setup_multiple_pads(board_pcie_pins, ARRAY_SIZE(board_pcie_pins)); } diff --git a/board/freescale/imx8qxp_arm2/imx8qxp_arm2.c b/board/freescale/imx8qxp_arm2/imx8qxp_arm2.c index 39be56f262..e448001d7c 100644 --- a/board/freescale/imx8qxp_arm2/imx8qxp_arm2.c +++ b/board/freescale/imx8qxp_arm2/imx8qxp_arm2.c @@ -30,6 +30,7 @@ #include #include #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -162,6 +163,8 @@ int board_early_init_f(void) if (sciErr != SC_ERR_NONE) return 0; + LPCG_AllClockOn(LPUART_0_LPCG); + setup_iomux_uart(); #ifdef CONFIG_SPL_BUILD @@ -512,6 +515,13 @@ static void imx8qxp_hsio_initialize(void) printf("hsio_gpio Power up failed! (error = %d)\n", ret); } + LPCG_AllClockOn(HSIO_PCIE_X1_LPCG); + LPCG_AllClockOn(HSIO_PHY_X1_LPCG); + LPCG_AllClockOn(HSIO_PHY_X1_CRR1_LPCG); + LPCG_AllClockOn(HSIO_PCIE_X1_CRR3_LPCG); + LPCG_AllClockOn(HSIO_MISC_LPCG); + LPCG_AllClockOn(HSIO_GPIO_LPCG); + imx8_iomux_setup_multiple_pads(board_pcie_pins, ARRAY_SIZE(board_pcie_pins)); } diff --git a/board/freescale/imx8qxp_mek/imx8qxp_mek.c b/board/freescale/imx8qxp_mek/imx8qxp_mek.c index 6f0a75e774..71e882b899 100644 --- a/board/freescale/imx8qxp_mek/imx8qxp_mek.c +++ b/board/freescale/imx8qxp_mek/imx8qxp_mek.c @@ -30,6 +30,7 @@ #include #include "../common/tcpc.h" #include +#include DECLARE_GLOBAL_DATA_PTR; @@ -91,6 +92,8 @@ int board_early_init_f(void) if (sciErr != SC_ERR_NONE) return 0; + LPCG_AllClockOn(LPUART_0_LPCG); + setup_iomux_uart(); return 0; @@ -398,6 +401,13 @@ static void imx8qxp_hsio_initialize(void) printf("hsio_gpio Power up failed! (error = %d)\n", ret); } + LPCG_AllClockOn(HSIO_PCIE_X1_LPCG); + LPCG_AllClockOn(HSIO_PHY_X1_LPCG); + LPCG_AllClockOn(HSIO_PHY_X1_CRR1_LPCG); + LPCG_AllClockOn(HSIO_PCIE_X1_CRR3_LPCG); + LPCG_AllClockOn(HSIO_MISC_LPCG); + LPCG_AllClockOn(HSIO_GPIO_LPCG); + imx8_iomux_setup_multiple_pads(board_pcie_pins, ARRAY_SIZE(board_pcie_pins)); }