Commit 07dd1b9d695ab21355488185995fb25f1933ed74

Authored by Ye Li
1 parent f1cf36095b

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 <ye.li@nxp.com>
(cherry picked from commit 484104758d3c2f98d3c9ae493f778b1427e2630c)

Showing 9 changed files with 134 additions and 24 deletions Side-by-side Diff

arch/arm/include/asm/arch-imx8/i2c.h
... ... @@ -8,30 +8,41 @@
8 8 #define __ASM_ARCH_IMX8_I2C_H__
9 9  
10 10 #include <asm/mach-imx/sci/sci.h>
  11 +#include <asm/arch/lpcg.h>
11 12  
12 13 struct imx_i2c_map {
13   - int index;
  14 + unsigned index;
14 15 sc_rsrc_t rsrc;
  16 + u32 lpcg[4];
15 17 };
16 18  
17 19 static struct imx_i2c_map imx_i2c_desc[] = {
18   - {0, SC_R_I2C_0},
19   - {1, SC_R_I2C_1},
20   - {2, SC_R_I2C_2},
21   - {3, SC_R_I2C_3},
22   - {4, SC_R_I2C_4},
23   - {5, SC_R_LVDS_0_I2C_0}, /* lvds0 i2c0 */
24   - {6, SC_R_LVDS_0_I2C_0}, /* lvds0 i2c1 */
25   - {7, SC_R_LVDS_1_I2C_0}, /* lvds1 i2c0 */
26   - {8, SC_R_LVDS_1_I2C_0}, /* lvds1 i2c1 */
27   - {9, SC_R_CSI_0_I2C_0},
28   - {10, SC_R_CSI_1_I2C_0},
29   - {11, SC_R_HDMI_I2C_0},
30   - {12, SC_R_HDMI_RX_I2C_0},
31   - {13, SC_R_MIPI_0_I2C_0},
32   - {14, SC_R_MIPI_0_I2C_1},
33   - {15, SC_R_MIPI_1_I2C_0},
34   - {16, SC_R_MIPI_1_I2C_1},
  20 + {0, SC_R_I2C_0, {LPI2C_0_LPCG}},
  21 + {1, SC_R_I2C_1, {LPI2C_1_LPCG}},
  22 + {2, SC_R_I2C_2, {LPI2C_2_LPCG}},
  23 + {3, SC_R_I2C_3, {LPI2C_3_LPCG}},
  24 +#ifdef CONFIG_IMX8QM
  25 + {4, SC_R_I2C_4, {LPI2C_4_LPCG}},
  26 +#endif
  27 + {5, SC_R_LVDS_0_I2C_0, {DI_LVDS_0_LPCG + 0x10}}, /* lvds0 i2c0 */
  28 + {6, SC_R_LVDS_0_I2C_0, {DI_LVDS_0_LPCG + 0x10}}, /* lvds0 i2c1 */
  29 + {7, SC_R_LVDS_1_I2C_0, {DI_LVDS_1_LPCG + 0x10}}, /* lvds1 i2c0 */
  30 + {8, SC_R_LVDS_1_I2C_0, {DI_LVDS_1_LPCG + 0x10}}, /* lvds1 i2c1 */
  31 + {9, SC_R_CSI_0_I2C_0, {MIPI_CSI_0_LPCG + 0x14}},
  32 + {10, SC_R_CSI_1_I2C_0, {MIPI_CSI_1_LPCG + 0x14}},
  33 + {11, SC_R_HDMI_I2C_0, {DI_HDMI_LPCG}},
  34 + {12, SC_R_HDMI_RX_I2C_0, {RX_HDMI_LPCG + 0x10, RX_HDMI_LPCG + 0x14, RX_HDMI_LPCG + 0x18, RX_HDMI_LPCG + 0x1C}},
  35 +#ifdef CONFIG_IMX8QM
  36 + {13, SC_R_MIPI_0_I2C_0, {MIPI_DSI_0_LPCG + 0x14, MIPI_DSI_0_LPCG + 0x18, MIPI_DSI_0_LPCG + 0x1c}},
  37 + {14, SC_R_MIPI_0_I2C_1, {MIPI_DSI_0_LPCG + 0x24, MIPI_DSI_0_LPCG + 0x28, MIPI_DSI_0_LPCG + 0x2c}},
  38 + {15, SC_R_MIPI_1_I2C_0, {MIPI_DSI_1_LPCG + 0x14, MIPI_DSI_1_LPCG + 0x18, MIPI_DSI_1_LPCG + 0x1c}},
  39 + {16, SC_R_MIPI_1_I2C_1, {MIPI_DSI_1_LPCG + 0x24, MIPI_DSI_1_LPCG + 0x28, MIPI_DSI_1_LPCG + 0x2c}},
  40 +#else
  41 + {13, SC_R_MIPI_0_I2C_0, {DI_MIPI0_LPCG, DI_MIPI0_LPCG + 0x10, DI_MIPI0_LPCG + 0x14}},
  42 + {14, SC_R_MIPI_0_I2C_1, {DI_MIPI0_LPCG, DI_MIPI0_LPCG + 0x10, DI_MIPI0_LPCG + 0x14}},
  43 + {15, SC_R_MIPI_1_I2C_0, {DI_MIPI1_LPCG, DI_MIPI1_LPCG + 0x10, DI_MIPI1_LPCG + 0x14}},
  44 + {16, SC_R_MIPI_1_I2C_1, {DI_MIPI1_LPCG, DI_MIPI1_LPCG + 0x10, DI_MIPI1_LPCG + 0x14}},
  45 +#endif
35 46 };
36 47 #endif /* __ASM_ARCH_IMX8_I2C_H__ */
arch/arm/mach-imx/imx8/Makefile
... ... @@ -6,6 +6,7 @@
6 6 obj-y += lowlevel_init.o
7 7 obj-y += cpu.o
8 8 obj-y += clock.o
  9 +obj-y += lpcg.o
9 10 obj-y += fsl_mu_hal.o
10 11 obj-y += fuse.o
11 12 obj-y += iomux.o
arch/arm/mach-imx/imx8/clock.c
... ... @@ -12,6 +12,7 @@
12 12 #include <asm/arch/i2c.h>
13 13 #include <asm/arch/sys_proto.h>
14 14 #include <asm/arch/cpu.h>
  15 +#include <asm/arch/lpcg.h>
15 16  
16 17 DECLARE_GLOBAL_DATA_PTR;
17 18  
18 19  
19 20  
20 21  
21 22  
22 23  
... ... @@ -121,28 +122,47 @@
121 122 return mxc_get_clock(MXC_FEC_CLK);
122 123 }
123 124  
  125 +static struct imx_i2c_map *get_i2c_desc(unsigned i2c_num)
  126 +{
  127 + int i;
  128 + for (i = 0; i < ARRAY_SIZE(imx_i2c_desc); i++) {
  129 + if (imx_i2c_desc[i].index == i2c_num)
  130 + return &imx_i2c_desc[i];
  131 + }
  132 + return NULL;
  133 +}
  134 +
124 135 int enable_i2c_clk(unsigned char enable, unsigned i2c_num)
125 136 {
126 137 sc_ipc_t ipc;
127 138 sc_err_t err;
  139 + struct imx_i2c_map *desc;
  140 + int i;
128 141  
129   - if (i2c_num >= ARRAY_SIZE(imx_i2c_desc))
  142 + desc = get_i2c_desc(i2c_num);
  143 + if (!desc)
130 144 return -EINVAL;
131 145  
132 146 ipc = gd->arch.ipc_channel_handle;
133 147  
134 148 if (enable)
135 149 err = sc_pm_clock_enable(ipc,
136   - imx_i2c_desc[i2c_num].rsrc, 2, true, false);
  150 + desc->rsrc, 2, true, false);
137 151 else
138 152 err = sc_pm_clock_enable(ipc,
139   - imx_i2c_desc[i2c_num].rsrc, 2, false, false);
  153 + desc->rsrc, 2, false, false);
140 154  
141 155 if (err != SC_ERR_NONE) {
142 156 printf("i2c clock error %d\n", err);
143 157 return -EPERM;
144 158 }
145 159  
  160 + for (i = 0; i < 4; i++) {
  161 + if (desc->lpcg[i] == 0)
  162 + break;
  163 + LPCG_AllClockOn(desc->lpcg[i]);
  164 + }
  165 +
146 166 return 0;
147 167 }
148 168  
149 169  
150 170  
... ... @@ -151,12 +171,14 @@
151 171 sc_err_t err;
152 172 sc_ipc_t ipc;
153 173 u32 clock_rate;
  174 + struct imx_i2c_map *desc;
154 175  
155   - if (i2c_num >= ARRAY_SIZE(imx_i2c_desc))
156   - return 0;
  176 + desc = get_i2c_desc(i2c_num);
  177 + if (!desc)
  178 + return -EINVAL;
157 179  
158 180 ipc = gd->arch.ipc_channel_handle;
159   - err = sc_pm_get_clock_rate(ipc, imx_i2c_desc[i2c_num].rsrc, 2,
  181 + err = sc_pm_get_clock_rate(ipc, desc->rsrc, 2,
160 182 &clock_rate);
161 183 if (err != SC_ERR_NONE)
162 184 return 0;
... ... @@ -185,6 +207,8 @@
185 207 return;
186 208 }
187 209  
  210 + LPCG_AllClockOn(FSPI_0_LPCG);
  211 +
188 212 return;
189 213 }
190 214  
191 215  
... ... @@ -224,11 +248,14 @@
224 248 return;
225 249 }
226 250  
  251 + LPCG_AllClockOn(NAND_LPCG);
  252 +
227 253 return;
228 254 }
229 255  
230 256 void enable_usboh3_clk(unsigned char enable)
231 257 {
  258 + LPCG_AllClockOn(USB_2_LPCG);
232 259 return;
233 260 }
234 261  
... ... @@ -254,6 +281,7 @@
254 281 printf("USB3 set clock failed!, line=%d (error = %d)\n",
255 282 __LINE__, err);
256 283  
  284 + LPCG_AllClockOn(USB_3_LPCG);
257 285 return;
258 286 }
259 287  
... ... @@ -270,6 +298,8 @@
270 298  
271 299 ipc = gd->arch.ipc_channel_handle;
272 300  
  301 + LPCG_AllClockOff(USB_3_LPCG);
  302 +
273 303 err = sc_pm_clock_enable(ipc, SC_R_USB_2, SC_PM_CLK_MISC, false, false);
274 304 if (err != SC_ERR_NONE)
275 305 printf("USB3 disable clock failed!, line=%d (error = %d)\n",
... ... @@ -345,6 +375,8 @@
345 375 printf("SDHC_%d per clk enable failed!\n", index);
346 376 return;
347 377 }
  378 +
  379 + LPCG_AllClockOn(USDHC_0_LPCG + index * 0x10000);
348 380 }
349 381  
350 382 void init_clk_fec(int index)
... ... @@ -389,6 +421,8 @@
389 421 printf("\nSC_R_ENET_0 set clock enable failed! (error = %d)\n", err);
390 422 return;
391 423 }
  424 +
  425 + LPCG_AllClockOn(ENET_0_LPCG + index * 0x10000);
392 426 }
393 427  
394 428 /*
arch/arm/mach-imx/imx8/cpu.c
... ... @@ -27,6 +27,7 @@
27 27 #include <asm/arch/cpu.h>
28 28 #include <generated/version_autogenerated.h>
29 29 #include <asm/setup.h>
  30 +#include <asm/arch/lpcg.h>
30 31  
31 32 DECLARE_GLOBAL_DATA_PTR;
32 33  
... ... @@ -506,6 +507,8 @@
506 507 return -EIO;
507 508 }
508 509  
  510 + LPCG_AllClockOn(AUD_DSP_LPCG);
  511 +
509 512 if (!power_domain_lookup_name("audio_sai0", &pd)) {
510 513 if (power_domain_on(&pd)) {
511 514 printf("Error power on SAI0\n");
... ... @@ -519,6 +522,9 @@
519 522 return -EIO;
520 523 }
521 524 }
  525 +
  526 + LPCG_AllClockOn(AUD_OCRAM_LPCG);
  527 + LPCG_AllClockOn(AUD_SAI_0_LPCG);
522 528 }
523 529  
524 530 printf("Copy image from 0x%lx to 0x%lx\n", addr, (ulong)aux_core_ram);
arch/arm/mach-imx/imx8/video_common.c
... ... @@ -22,6 +22,7 @@
22 22 #include <asm/arch/imx8_mipi_dsi.h>
23 23 #include <asm/arch/video_common.h>
24 24 #include <power-domain.h>
  25 +#include <asm/arch/lpcg.h>
25 26  
26 27 DECLARE_GLOBAL_DATA_PTR;
27 28  
... ... @@ -342,6 +343,7 @@
342 343 sc_pm_clock_rate_t pll_clk;
343 344 const char *pll1_pd_name;
344 345 sc_ipc_t ipcHndl = gd->arch.ipc_channel_handle;
  346 + u32 dc_lpcg;
345 347  
346 348 int dc_id = gdc;
347 349  
348 350  
... ... @@ -353,11 +355,13 @@
353 355 pll0_rsrc = SC_R_DC_0_PLL_0;
354 356 pll1_rsrc = SC_R_DC_0_PLL_1;
355 357 pll1_pd_name = "dc0_pll1";
  358 + dc_lpcg = DC_0_LPCG;
356 359 } else {
357 360 dc_rsrc = SC_R_DC_1;
358 361 pll0_rsrc = SC_R_DC_1_PLL_0;
359 362 pll1_rsrc = SC_R_DC_1_PLL_1;
360 363 pll1_pd_name = "dc1_pll1";
  364 + dc_lpcg = DC_1_LPCG;
361 365 }
362 366  
363 367 if (!power_domain_lookup_name(pll1_pd_name, &pd)) {
... ... @@ -424,6 +428,8 @@
424 428 printf("DISP1 clock enable failed! (error = %d)\n", err);
425 429 return -EIO;
426 430 }
  431 +
  432 + LPCG_AllClockOn(dc_lpcg);
427 433  
428 434 err = sc_misc_set_control(ipcHndl, dc_rsrc, SC_C_PXL_LINK_MST1_ADDR, 0);
429 435 if (err != SC_ERR_NONE) {
board/freescale/imx8qm_arm2/imx8qm_arm2.c
... ... @@ -29,6 +29,7 @@
29 29 #include <asm/arch/video_common.h>
30 30 #include <power-domain.h>
31 31 #include <cdns3-uboot.h>
  32 +#include <asm/arch/lpcg.h>
32 33  
33 34 DECLARE_GLOBAL_DATA_PTR;
34 35  
... ... @@ -90,6 +91,8 @@
90 91 if (sciErr != SC_ERR_NONE)
91 92 return 0;
92 93  
  94 + LPCG_AllClockOn(LPUART_0_LPCG);
  95 +
93 96 setup_iomux_uart();
94 97  
95 98 return 0;
... ... @@ -484,6 +487,19 @@
484 487 if (ret)
485 488 printf("hsio_gpio Power up failed! (error = %d)\n", ret);
486 489 }
  490 +
  491 + LPCG_AllClockOn(HSIO_PCIE_X2_LPCG);
  492 + LPCG_AllClockOn(HSIO_PCIE_X1_LPCG);
  493 + LPCG_AllClockOn(HSIO_SATA_LPCG);
  494 + LPCG_AllClockOn(HSIO_PHY_X2_LPCG);
  495 + LPCG_AllClockOn(HSIO_PHY_X1_LPCG);
  496 + LPCG_AllClockOn(HSIO_PHY_X2_CRR0_LPCG);
  497 + LPCG_AllClockOn(HSIO_PHY_X1_CRR1_LPCG);
  498 + LPCG_AllClockOn(HSIO_PCIE_X2_CRR2_LPCG);
  499 + LPCG_AllClockOn(HSIO_PCIE_X1_CRR3_LPCG);
  500 + LPCG_AllClockOn(HSIO_SATA_CRR4_LPCG);
  501 + LPCG_AllClockOn(HSIO_MISC_LPCG);
  502 + LPCG_AllClockOn(HSIO_GPIO_LPCG);
487 503  
488 504 imx8_iomux_setup_multiple_pads(board_pcie_pins, ARRAY_SIZE(board_pcie_pins));
489 505  
board/freescale/imx8qm_mek/imx8qm_mek.c
... ... @@ -29,6 +29,7 @@
29 29 #include <power-domain.h>
30 30 #include "../common/tcpc.h"
31 31 #include <cdns3-uboot.h>
  32 +#include <asm/arch/lpcg.h>
32 33  
33 34 DECLARE_GLOBAL_DATA_PTR;
34 35  
... ... @@ -87,6 +88,8 @@
87 88 if (sciErr != SC_ERR_NONE)
88 89 return 0;
89 90  
  91 + LPCG_AllClockOn(LPUART_0_LPCG);
  92 +
90 93 setup_iomux_uart();
91 94  
92 95 return 0;
... ... @@ -266,6 +269,19 @@
266 269 if (ret)
267 270 printf("hsio_gpio Power up failed! (error = %d)\n", ret);
268 271 }
  272 +
  273 + LPCG_AllClockOn(HSIO_PCIE_X2_LPCG);
  274 + LPCG_AllClockOn(HSIO_PCIE_X1_LPCG);
  275 + LPCG_AllClockOn(HSIO_SATA_LPCG);
  276 + LPCG_AllClockOn(HSIO_PHY_X2_LPCG);
  277 + LPCG_AllClockOn(HSIO_PHY_X1_LPCG);
  278 + LPCG_AllClockOn(HSIO_PHY_X2_CRR0_LPCG);
  279 + LPCG_AllClockOn(HSIO_PHY_X1_CRR1_LPCG);
  280 + LPCG_AllClockOn(HSIO_PCIE_X2_CRR2_LPCG);
  281 + LPCG_AllClockOn(HSIO_PCIE_X1_CRR3_LPCG);
  282 + LPCG_AllClockOn(HSIO_SATA_CRR4_LPCG);
  283 + LPCG_AllClockOn(HSIO_MISC_LPCG);
  284 + LPCG_AllClockOn(HSIO_GPIO_LPCG);
269 285  
270 286 imx8_iomux_setup_multiple_pads(board_pcie_pins, ARRAY_SIZE(board_pcie_pins));
271 287 }
board/freescale/imx8qxp_arm2/imx8qxp_arm2.c
... ... @@ -30,6 +30,7 @@
30 30 #include <asm/arch/video_common.h>
31 31 #include <power-domain.h>
32 32 #include <cdns3-uboot.h>
  33 +#include <asm/arch/lpcg.h>
33 34  
34 35 DECLARE_GLOBAL_DATA_PTR;
35 36  
... ... @@ -162,6 +163,8 @@
162 163 if (sciErr != SC_ERR_NONE)
163 164 return 0;
164 165  
  166 + LPCG_AllClockOn(LPUART_0_LPCG);
  167 +
165 168 setup_iomux_uart();
166 169  
167 170 #ifdef CONFIG_SPL_BUILD
... ... @@ -511,6 +514,13 @@
511 514 if (ret)
512 515 printf("hsio_gpio Power up failed! (error = %d)\n", ret);
513 516 }
  517 +
  518 + LPCG_AllClockOn(HSIO_PCIE_X1_LPCG);
  519 + LPCG_AllClockOn(HSIO_PHY_X1_LPCG);
  520 + LPCG_AllClockOn(HSIO_PHY_X1_CRR1_LPCG);
  521 + LPCG_AllClockOn(HSIO_PCIE_X1_CRR3_LPCG);
  522 + LPCG_AllClockOn(HSIO_MISC_LPCG);
  523 + LPCG_AllClockOn(HSIO_GPIO_LPCG);
514 524  
515 525 imx8_iomux_setup_multiple_pads(board_pcie_pins, ARRAY_SIZE(board_pcie_pins));
516 526 }
board/freescale/imx8qxp_mek/imx8qxp_mek.c
... ... @@ -30,6 +30,7 @@
30 30 #include <power-domain.h>
31 31 #include "../common/tcpc.h"
32 32 #include <cdns3-uboot.h>
  33 +#include <asm/arch/lpcg.h>
33 34  
34 35 DECLARE_GLOBAL_DATA_PTR;
35 36  
... ... @@ -91,6 +92,8 @@
91 92 if (sciErr != SC_ERR_NONE)
92 93 return 0;
93 94  
  95 + LPCG_AllClockOn(LPUART_0_LPCG);
  96 +
94 97 setup_iomux_uart();
95 98  
96 99 return 0;
... ... @@ -397,6 +400,13 @@
397 400 if (ret)
398 401 printf("hsio_gpio Power up failed! (error = %d)\n", ret);
399 402 }
  403 +
  404 + LPCG_AllClockOn(HSIO_PCIE_X1_LPCG);
  405 + LPCG_AllClockOn(HSIO_PHY_X1_LPCG);
  406 + LPCG_AllClockOn(HSIO_PHY_X1_CRR1_LPCG);
  407 + LPCG_AllClockOn(HSIO_PCIE_X1_CRR3_LPCG);
  408 + LPCG_AllClockOn(HSIO_MISC_LPCG);
  409 + LPCG_AllClockOn(HSIO_GPIO_LPCG);
400 410  
401 411 imx8_iomux_setup_multiple_pads(board_pcie_pins, ARRAY_SIZE(board_pcie_pins));
402 412 }