From 07dd1b9d695ab21355488185995fb25f1933ed74 Mon Sep 17 00:00:00 2001 From: Ye Li Date: Wed, 5 Dec 2018 20:00:25 -0800 Subject: [PATCH] MLK-20528-2 imx8: Enable clocks LPCG To support partition reboot, the u-boot has to enable clocks by LPCG. The LPCG will reset to default value only when the subsystem is totally power off and reset. However, the resources in one subsystem may belong to different partitions, so the partition reboot may not reboot the entire subsystem. Powers, clocks/lpcg, GPR, IP may not reset depends on various cases and HW design. Thus, AP software has to ensure everything is reset by SW itself to support such above cases. Signed-off-by: Ye Li (cherry picked from commit 484104758d3c2f98d3c9ae493f778b1427e2630c) --- arch/arm/include/asm/arch-imx8/i2c.h | 47 ++++++++++++++++++----------- arch/arm/mach-imx/imx8/Makefile | 1 + arch/arm/mach-imx/imx8/clock.c | 46 ++++++++++++++++++++++++---- arch/arm/mach-imx/imx8/cpu.c | 6 ++++ arch/arm/mach-imx/imx8/video_common.c | 6 ++++ board/freescale/imx8qm_arm2/imx8qm_arm2.c | 16 ++++++++++ board/freescale/imx8qm_mek/imx8qm_mek.c | 16 ++++++++++ board/freescale/imx8qxp_arm2/imx8qxp_arm2.c | 10 ++++++ board/freescale/imx8qxp_mek/imx8qxp_mek.c | 10 ++++++ 9 files changed, 134 insertions(+), 24 deletions(-) diff --git a/arch/arm/include/asm/arch-imx8/i2c.h b/arch/arm/include/asm/arch-imx8/i2c.h index 4c88b9f..6506eff 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 e3be955..24cbbeb 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 fb9df7f..78b53f2 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 55cc320..f554ad8 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 efed987..01ab94a 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 6827b57..911485e 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 943bb2f..2efec39 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 39be56f..e448001 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 6f0a75e..71e882b 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)); } -- 1.9.1