Commit 07dd1b9d695ab21355488185995fb25f1933ed74
1 parent
f1cf36095b
Exists in
smarc-imx_v2018.03_4.14.78_1.0.0_ga
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 Inline Diff
- arch/arm/include/asm/arch-imx8/i2c.h
- arch/arm/mach-imx/imx8/Makefile
- arch/arm/mach-imx/imx8/clock.c
- arch/arm/mach-imx/imx8/cpu.c
- arch/arm/mach-imx/imx8/video_common.c
- board/freescale/imx8qm_arm2/imx8qm_arm2.c
- board/freescale/imx8qm_mek/imx8qm_mek.c
- board/freescale/imx8qxp_arm2/imx8qxp_arm2.c
- board/freescale/imx8qxp_mek/imx8qxp_mek.c
arch/arm/include/asm/arch-imx8/i2c.h
1 | /* | 1 | /* |
2 | * Copyright 2017 NXP | 2 | * Copyright 2017 NXP |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: GPL-2.0+ | 4 | * SPDX-License-Identifier: GPL-2.0+ |
5 | * | 5 | * |
6 | */ | 6 | */ |
7 | #ifndef __ASM_ARCH_IMX8_I2C_H__ | 7 | #ifndef __ASM_ARCH_IMX8_I2C_H__ |
8 | #define __ASM_ARCH_IMX8_I2C_H__ | 8 | #define __ASM_ARCH_IMX8_I2C_H__ |
9 | 9 | ||
10 | #include <asm/mach-imx/sci/sci.h> | 10 | #include <asm/mach-imx/sci/sci.h> |
11 | #include <asm/arch/lpcg.h> | ||
11 | 12 | ||
12 | struct imx_i2c_map { | 13 | struct imx_i2c_map { |
13 | int index; | 14 | unsigned index; |
14 | sc_rsrc_t rsrc; | 15 | sc_rsrc_t rsrc; |
16 | u32 lpcg[4]; | ||
15 | }; | 17 | }; |
16 | 18 | ||
17 | static struct imx_i2c_map imx_i2c_desc[] = { | 19 | static struct imx_i2c_map imx_i2c_desc[] = { |
18 | {0, SC_R_I2C_0}, | 20 | {0, SC_R_I2C_0, {LPI2C_0_LPCG}}, |
19 | {1, SC_R_I2C_1}, | 21 | {1, SC_R_I2C_1, {LPI2C_1_LPCG}}, |
20 | {2, SC_R_I2C_2}, | 22 | {2, SC_R_I2C_2, {LPI2C_2_LPCG}}, |
21 | {3, SC_R_I2C_3}, | 23 | {3, SC_R_I2C_3, {LPI2C_3_LPCG}}, |
22 | {4, SC_R_I2C_4}, | 24 | #ifdef CONFIG_IMX8QM |
23 | {5, SC_R_LVDS_0_I2C_0}, /* lvds0 i2c0 */ | 25 | {4, SC_R_I2C_4, {LPI2C_4_LPCG}}, |
24 | {6, SC_R_LVDS_0_I2C_0}, /* lvds0 i2c1 */ | 26 | #endif |
25 | {7, SC_R_LVDS_1_I2C_0}, /* lvds1 i2c0 */ | 27 | {5, SC_R_LVDS_0_I2C_0, {DI_LVDS_0_LPCG + 0x10}}, /* lvds0 i2c0 */ |
26 | {8, SC_R_LVDS_1_I2C_0}, /* lvds1 i2c1 */ | 28 | {6, SC_R_LVDS_0_I2C_0, {DI_LVDS_0_LPCG + 0x10}}, /* lvds0 i2c1 */ |
27 | {9, SC_R_CSI_0_I2C_0}, | 29 | {7, SC_R_LVDS_1_I2C_0, {DI_LVDS_1_LPCG + 0x10}}, /* lvds1 i2c0 */ |
28 | {10, SC_R_CSI_1_I2C_0}, | 30 | {8, SC_R_LVDS_1_I2C_0, {DI_LVDS_1_LPCG + 0x10}}, /* lvds1 i2c1 */ |
29 | {11, SC_R_HDMI_I2C_0}, | 31 | {9, SC_R_CSI_0_I2C_0, {MIPI_CSI_0_LPCG + 0x14}}, |
30 | {12, SC_R_HDMI_RX_I2C_0}, | 32 | {10, SC_R_CSI_1_I2C_0, {MIPI_CSI_1_LPCG + 0x14}}, |
31 | {13, SC_R_MIPI_0_I2C_0}, | 33 | {11, SC_R_HDMI_I2C_0, {DI_HDMI_LPCG}}, |
32 | {14, SC_R_MIPI_0_I2C_1}, | 34 | {12, SC_R_HDMI_RX_I2C_0, {RX_HDMI_LPCG + 0x10, RX_HDMI_LPCG + 0x14, RX_HDMI_LPCG + 0x18, RX_HDMI_LPCG + 0x1C}}, |
33 | {15, SC_R_MIPI_1_I2C_0}, | 35 | #ifdef CONFIG_IMX8QM |
34 | {16, SC_R_MIPI_1_I2C_1}, | 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 | #endif /* __ASM_ARCH_IMX8_I2C_H__ */ | 47 | #endif /* __ASM_ARCH_IMX8_I2C_H__ */ |
37 | 48 |
arch/arm/mach-imx/imx8/Makefile
1 | # | 1 | # |
2 | # Copyright 2017 NXP | 2 | # Copyright 2017 NXP |
3 | # | 3 | # |
4 | # SPDX-License-Identifier: GPL-2.0+ | 4 | # SPDX-License-Identifier: GPL-2.0+ |
5 | # | 5 | # |
6 | obj-y += lowlevel_init.o | 6 | obj-y += lowlevel_init.o |
7 | obj-y += cpu.o | 7 | obj-y += cpu.o |
8 | obj-y += clock.o | 8 | obj-y += clock.o |
9 | obj-y += lpcg.o | ||
9 | obj-y += fsl_mu_hal.o | 10 | obj-y += fsl_mu_hal.o |
10 | obj-y += fuse.o | 11 | obj-y += fuse.o |
11 | obj-y += iomux.o | 12 | obj-y += iomux.o |
12 | obj-y += image.o | 13 | obj-y += image.o |
13 | obj-$(CONFIG_SPL_BUILD) += parser.o | 14 | obj-$(CONFIG_SPL_BUILD) += parser.o |
14 | ifneq ($(CONFIG_SPL_BUILD),y) | 15 | ifneq ($(CONFIG_SPL_BUILD),y) |
15 | obj-y += partition.o | 16 | obj-y += partition.o |
16 | endif | 17 | endif |
17 | obj-$(CONFIG_AHAB_BOOT) += ahab.o | 18 | obj-$(CONFIG_AHAB_BOOT) += ahab.o |
18 | obj-$(CONFIG_VIDEO_IMXDPUV1) += video_common.o | 19 | obj-$(CONFIG_VIDEO_IMXDPUV1) += video_common.o |
19 | 20 |
arch/arm/mach-imx/imx8/clock.c
1 | /* | 1 | /* |
2 | * Copyright 2017-2018 NXP | 2 | * Copyright 2017-2018 NXP |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: GPL-2.0+ | 4 | * SPDX-License-Identifier: GPL-2.0+ |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <common.h> | 7 | #include <common.h> |
8 | #include <linux/errno.h> | 8 | #include <linux/errno.h> |
9 | #include <asm/arch/clock.h> | 9 | #include <asm/arch/clock.h> |
10 | #include <asm/mach-imx/sci/sci.h> | 10 | #include <asm/mach-imx/sci/sci.h> |
11 | #include <asm/arch/imx8-pins.h> | 11 | #include <asm/arch/imx8-pins.h> |
12 | #include <asm/arch/i2c.h> | 12 | #include <asm/arch/i2c.h> |
13 | #include <asm/arch/sys_proto.h> | 13 | #include <asm/arch/sys_proto.h> |
14 | #include <asm/arch/cpu.h> | 14 | #include <asm/arch/cpu.h> |
15 | #include <asm/arch/lpcg.h> | ||
15 | 16 | ||
16 | DECLARE_GLOBAL_DATA_PTR; | 17 | DECLARE_GLOBAL_DATA_PTR; |
17 | 18 | ||
18 | u32 get_lpuart_clk(void) | 19 | u32 get_lpuart_clk(void) |
19 | { | 20 | { |
20 | return mxc_get_clock(MXC_UART_CLK); | 21 | return mxc_get_clock(MXC_UART_CLK); |
21 | } | 22 | } |
22 | 23 | ||
23 | static u32 get_arm_main_clk(void) | 24 | static u32 get_arm_main_clk(void) |
24 | { | 25 | { |
25 | sc_err_t err; | 26 | sc_err_t err; |
26 | sc_pm_clock_rate_t clkrate; | 27 | sc_pm_clock_rate_t clkrate; |
27 | 28 | ||
28 | if (is_cortex_a53()) | 29 | if (is_cortex_a53()) |
29 | err = sc_pm_get_clock_rate((sc_ipc_t)gd->arch.ipc_channel_handle, | 30 | err = sc_pm_get_clock_rate((sc_ipc_t)gd->arch.ipc_channel_handle, |
30 | SC_R_A53, SC_PM_CLK_CPU, &clkrate); | 31 | SC_R_A53, SC_PM_CLK_CPU, &clkrate); |
31 | else if (is_cortex_a72()) | 32 | else if (is_cortex_a72()) |
32 | err = sc_pm_get_clock_rate((sc_ipc_t)gd->arch.ipc_channel_handle, | 33 | err = sc_pm_get_clock_rate((sc_ipc_t)gd->arch.ipc_channel_handle, |
33 | SC_R_A72, SC_PM_CLK_CPU, &clkrate); | 34 | SC_R_A72, SC_PM_CLK_CPU, &clkrate); |
34 | else if (is_cortex_a35()) | 35 | else if (is_cortex_a35()) |
35 | err = sc_pm_get_clock_rate((sc_ipc_t)gd->arch.ipc_channel_handle, | 36 | err = sc_pm_get_clock_rate((sc_ipc_t)gd->arch.ipc_channel_handle, |
36 | SC_R_A35, SC_PM_CLK_CPU, &clkrate); | 37 | SC_R_A35, SC_PM_CLK_CPU, &clkrate); |
37 | else | 38 | else |
38 | err = SC_ERR_UNAVAILABLE; | 39 | err = SC_ERR_UNAVAILABLE; |
39 | 40 | ||
40 | if (err != SC_ERR_NONE) { | 41 | if (err != SC_ERR_NONE) { |
41 | printf("sc get ARM clk failed! err=%d\n", err); | 42 | printf("sc get ARM clk failed! err=%d\n", err); |
42 | return 0; | 43 | return 0; |
43 | } | 44 | } |
44 | return clkrate; | 45 | return clkrate; |
45 | } | 46 | } |
46 | 47 | ||
47 | unsigned int mxc_get_clock(enum mxc_clock clk) | 48 | unsigned int mxc_get_clock(enum mxc_clock clk) |
48 | { | 49 | { |
49 | sc_err_t err; | 50 | sc_err_t err; |
50 | sc_pm_clock_rate_t clkrate; | 51 | sc_pm_clock_rate_t clkrate; |
51 | 52 | ||
52 | switch (clk) { | 53 | switch (clk) { |
53 | case MXC_UART_CLK: | 54 | case MXC_UART_CLK: |
54 | err = sc_pm_get_clock_rate((sc_ipc_t)gd->arch.ipc_channel_handle, | 55 | err = sc_pm_get_clock_rate((sc_ipc_t)gd->arch.ipc_channel_handle, |
55 | SC_R_UART_0, 2, &clkrate); | 56 | SC_R_UART_0, 2, &clkrate); |
56 | if (err != SC_ERR_NONE) { | 57 | if (err != SC_ERR_NONE) { |
57 | printf("sc get UART clk failed! err=%d\n", err); | 58 | printf("sc get UART clk failed! err=%d\n", err); |
58 | return 0; | 59 | return 0; |
59 | } | 60 | } |
60 | return clkrate; | 61 | return clkrate; |
61 | case MXC_ESDHC_CLK: | 62 | case MXC_ESDHC_CLK: |
62 | err = sc_pm_get_clock_rate((sc_ipc_t)gd->arch.ipc_channel_handle, | 63 | err = sc_pm_get_clock_rate((sc_ipc_t)gd->arch.ipc_channel_handle, |
63 | SC_R_SDHC_0, 2, &clkrate); | 64 | SC_R_SDHC_0, 2, &clkrate); |
64 | if (err != SC_ERR_NONE) { | 65 | if (err != SC_ERR_NONE) { |
65 | printf("sc get uSDHC1 clk failed! err=%d\n", err); | 66 | printf("sc get uSDHC1 clk failed! err=%d\n", err); |
66 | return 0; | 67 | return 0; |
67 | } | 68 | } |
68 | return clkrate; | 69 | return clkrate; |
69 | case MXC_ESDHC2_CLK: | 70 | case MXC_ESDHC2_CLK: |
70 | err = sc_pm_get_clock_rate((sc_ipc_t)gd->arch.ipc_channel_handle, | 71 | err = sc_pm_get_clock_rate((sc_ipc_t)gd->arch.ipc_channel_handle, |
71 | SC_R_SDHC_1, 2, &clkrate); | 72 | SC_R_SDHC_1, 2, &clkrate); |
72 | if (err != SC_ERR_NONE) { | 73 | if (err != SC_ERR_NONE) { |
73 | printf("sc get uSDHC2 clk failed! err=%d\n", err); | 74 | printf("sc get uSDHC2 clk failed! err=%d\n", err); |
74 | return 0; | 75 | return 0; |
75 | } | 76 | } |
76 | return clkrate; | 77 | return clkrate; |
77 | case MXC_ESDHC3_CLK: | 78 | case MXC_ESDHC3_CLK: |
78 | err = sc_pm_get_clock_rate((sc_ipc_t)gd->arch.ipc_channel_handle, | 79 | err = sc_pm_get_clock_rate((sc_ipc_t)gd->arch.ipc_channel_handle, |
79 | SC_R_SDHC_2, 2, &clkrate); | 80 | SC_R_SDHC_2, 2, &clkrate); |
80 | if (err != SC_ERR_NONE) { | 81 | if (err != SC_ERR_NONE) { |
81 | printf("sc get uSDHC3 clk failed! err=%d\n", err); | 82 | printf("sc get uSDHC3 clk failed! err=%d\n", err); |
82 | return 0; | 83 | return 0; |
83 | } | 84 | } |
84 | return clkrate; | 85 | return clkrate; |
85 | case MXC_FEC_CLK: | 86 | case MXC_FEC_CLK: |
86 | err = sc_pm_get_clock_rate((sc_ipc_t)gd->arch.ipc_channel_handle, | 87 | err = sc_pm_get_clock_rate((sc_ipc_t)gd->arch.ipc_channel_handle, |
87 | SC_R_ENET_0, 2, &clkrate); | 88 | SC_R_ENET_0, 2, &clkrate); |
88 | if (err != SC_ERR_NONE) { | 89 | if (err != SC_ERR_NONE) { |
89 | printf("sc get ENET clk failed! err=%d\n", err); | 90 | printf("sc get ENET clk failed! err=%d\n", err); |
90 | return 0; | 91 | return 0; |
91 | } | 92 | } |
92 | return clkrate; | 93 | return clkrate; |
93 | case MXC_FSPI_CLK: | 94 | case MXC_FSPI_CLK: |
94 | err = sc_pm_get_clock_rate((sc_ipc_t)gd->arch.ipc_channel_handle, | 95 | err = sc_pm_get_clock_rate((sc_ipc_t)gd->arch.ipc_channel_handle, |
95 | SC_R_FSPI_0, 2, &clkrate); | 96 | SC_R_FSPI_0, 2, &clkrate); |
96 | if (err != SC_ERR_NONE) { | 97 | if (err != SC_ERR_NONE) { |
97 | printf("sc get FSPI clk failed! err=%d\n", err); | 98 | printf("sc get FSPI clk failed! err=%d\n", err); |
98 | return 0; | 99 | return 0; |
99 | } | 100 | } |
100 | return clkrate; | 101 | return clkrate; |
101 | case MXC_DDR_CLK: | 102 | case MXC_DDR_CLK: |
102 | err = sc_pm_get_clock_rate((sc_ipc_t)gd->arch.ipc_channel_handle, | 103 | err = sc_pm_get_clock_rate((sc_ipc_t)gd->arch.ipc_channel_handle, |
103 | SC_R_DRC_0, 0, &clkrate); | 104 | SC_R_DRC_0, 0, &clkrate); |
104 | if (err != SC_ERR_NONE) { | 105 | if (err != SC_ERR_NONE) { |
105 | printf("sc get DRC0 clk failed! err=%d\n", err); | 106 | printf("sc get DRC0 clk failed! err=%d\n", err); |
106 | return 0; | 107 | return 0; |
107 | } | 108 | } |
108 | return clkrate; | 109 | return clkrate; |
109 | case MXC_ARM_CLK: | 110 | case MXC_ARM_CLK: |
110 | return get_arm_main_clk(); | 111 | return get_arm_main_clk(); |
111 | default: | 112 | default: |
112 | printf("Unsupported mxc_clock %d\n", clk); | 113 | printf("Unsupported mxc_clock %d\n", clk); |
113 | break; | 114 | break; |
114 | } | 115 | } |
115 | 116 | ||
116 | return 0; | 117 | return 0; |
117 | } | 118 | } |
118 | 119 | ||
119 | u32 imx_get_fecclk(void) | 120 | u32 imx_get_fecclk(void) |
120 | { | 121 | { |
121 | return mxc_get_clock(MXC_FEC_CLK); | 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 | int enable_i2c_clk(unsigned char enable, unsigned i2c_num) | 135 | int enable_i2c_clk(unsigned char enable, unsigned i2c_num) |
125 | { | 136 | { |
126 | sc_ipc_t ipc; | 137 | sc_ipc_t ipc; |
127 | sc_err_t err; | 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 | return -EINVAL; | 144 | return -EINVAL; |
131 | 145 | ||
132 | ipc = gd->arch.ipc_channel_handle; | 146 | ipc = gd->arch.ipc_channel_handle; |
133 | 147 | ||
134 | if (enable) | 148 | if (enable) |
135 | err = sc_pm_clock_enable(ipc, | 149 | err = sc_pm_clock_enable(ipc, |
136 | imx_i2c_desc[i2c_num].rsrc, 2, true, false); | 150 | desc->rsrc, 2, true, false); |
137 | else | 151 | else |
138 | err = sc_pm_clock_enable(ipc, | 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 | if (err != SC_ERR_NONE) { | 155 | if (err != SC_ERR_NONE) { |
142 | printf("i2c clock error %d\n", err); | 156 | printf("i2c clock error %d\n", err); |
143 | return -EPERM; | 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 | return 0; | 166 | return 0; |
147 | } | 167 | } |
148 | 168 | ||
149 | u32 imx_get_i2cclk(unsigned i2c_num) | 169 | u32 imx_get_i2cclk(unsigned i2c_num) |
150 | { | 170 | { |
151 | sc_err_t err; | 171 | sc_err_t err; |
152 | sc_ipc_t ipc; | 172 | sc_ipc_t ipc; |
153 | u32 clock_rate; | 173 | u32 clock_rate; |
174 | struct imx_i2c_map *desc; | ||
154 | 175 | ||
155 | if (i2c_num >= ARRAY_SIZE(imx_i2c_desc)) | 176 | desc = get_i2c_desc(i2c_num); |
156 | return 0; | 177 | if (!desc) |
178 | return -EINVAL; | ||
157 | 179 | ||
158 | ipc = gd->arch.ipc_channel_handle; | 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 | &clock_rate); | 182 | &clock_rate); |
161 | if (err != SC_ERR_NONE) | 183 | if (err != SC_ERR_NONE) |
162 | return 0; | 184 | return 0; |
163 | 185 | ||
164 | return clock_rate; | 186 | return clock_rate; |
165 | } | 187 | } |
166 | 188 | ||
167 | void init_clk_fspi(int index) | 189 | void init_clk_fspi(int index) |
168 | { | 190 | { |
169 | sc_err_t sciErr = 0; | 191 | sc_err_t sciErr = 0; |
170 | sc_pm_clock_rate_t rate; | 192 | sc_pm_clock_rate_t rate; |
171 | sc_ipc_t ipcHndl = gd->arch.ipc_channel_handle; | 193 | sc_ipc_t ipcHndl = gd->arch.ipc_channel_handle; |
172 | 194 | ||
173 | /* Set FSPI0 clock root to 29 MHz */ | 195 | /* Set FSPI0 clock root to 29 MHz */ |
174 | rate = 29000000; | 196 | rate = 29000000; |
175 | sciErr = sc_pm_set_clock_rate(ipcHndl, SC_R_FSPI_0, SC_PM_CLK_PER, &rate); | 197 | sciErr = sc_pm_set_clock_rate(ipcHndl, SC_R_FSPI_0, SC_PM_CLK_PER, &rate); |
176 | if (sciErr != SC_ERR_NONE) { | 198 | if (sciErr != SC_ERR_NONE) { |
177 | puts("FSPI0 setrate failed\n"); | 199 | puts("FSPI0 setrate failed\n"); |
178 | return; | 200 | return; |
179 | } | 201 | } |
180 | 202 | ||
181 | /* Enable FSPI0 clock root */ | 203 | /* Enable FSPI0 clock root */ |
182 | sciErr = sc_pm_clock_enable(ipcHndl, SC_R_FSPI_0, SC_PM_CLK_PER, true, false); | 204 | sciErr = sc_pm_clock_enable(ipcHndl, SC_R_FSPI_0, SC_PM_CLK_PER, true, false); |
183 | if (sciErr != SC_ERR_NONE) { | 205 | if (sciErr != SC_ERR_NONE) { |
184 | puts("FSPI0 enable clock failed\n"); | 206 | puts("FSPI0 enable clock failed\n"); |
185 | return; | 207 | return; |
186 | } | 208 | } |
187 | 209 | ||
210 | LPCG_AllClockOn(FSPI_0_LPCG); | ||
211 | |||
188 | return; | 212 | return; |
189 | } | 213 | } |
190 | 214 | ||
191 | void init_clk_gpmi_nand(void) | 215 | void init_clk_gpmi_nand(void) |
192 | { | 216 | { |
193 | sc_err_t sciErr = 0; | 217 | sc_err_t sciErr = 0; |
194 | sc_pm_clock_rate_t rate; | 218 | sc_pm_clock_rate_t rate; |
195 | sc_ipc_t ipcHndl = gd->arch.ipc_channel_handle; | 219 | sc_ipc_t ipcHndl = gd->arch.ipc_channel_handle; |
196 | 220 | ||
197 | /* Set NAND BCH clock root to 50 MHz */ | 221 | /* Set NAND BCH clock root to 50 MHz */ |
198 | rate = 50000000; | 222 | rate = 50000000; |
199 | sciErr = sc_pm_set_clock_rate(ipcHndl, SC_R_NAND, SC_PM_CLK_PER, &rate); | 223 | sciErr = sc_pm_set_clock_rate(ipcHndl, SC_R_NAND, SC_PM_CLK_PER, &rate); |
200 | if (sciErr != SC_ERR_NONE) { | 224 | if (sciErr != SC_ERR_NONE) { |
201 | puts("NAND BCH set rate failed\n"); | 225 | puts("NAND BCH set rate failed\n"); |
202 | return; | 226 | return; |
203 | } | 227 | } |
204 | 228 | ||
205 | /* Enable NAND BCH clock root */ | 229 | /* Enable NAND BCH clock root */ |
206 | sciErr = sc_pm_clock_enable(ipcHndl, SC_R_NAND, SC_PM_CLK_PER, true, false); | 230 | sciErr = sc_pm_clock_enable(ipcHndl, SC_R_NAND, SC_PM_CLK_PER, true, false); |
207 | if (sciErr != SC_ERR_NONE) { | 231 | if (sciErr != SC_ERR_NONE) { |
208 | puts("NAND BCH enable clock failed\n"); | 232 | puts("NAND BCH enable clock failed\n"); |
209 | return; | 233 | return; |
210 | } | 234 | } |
211 | 235 | ||
212 | /* Set NAND GPMI clock root to 50 MHz */ | 236 | /* Set NAND GPMI clock root to 50 MHz */ |
213 | rate = 50000000; | 237 | rate = 50000000; |
214 | sciErr = sc_pm_set_clock_rate(ipcHndl, SC_R_NAND, SC_PM_CLK_MST_BUS, &rate); | 238 | sciErr = sc_pm_set_clock_rate(ipcHndl, SC_R_NAND, SC_PM_CLK_MST_BUS, &rate); |
215 | if (sciErr != SC_ERR_NONE) { | 239 | if (sciErr != SC_ERR_NONE) { |
216 | puts("NAND GPMI set rate failed\n"); | 240 | puts("NAND GPMI set rate failed\n"); |
217 | return; | 241 | return; |
218 | } | 242 | } |
219 | 243 | ||
220 | /* Enable NAND GPMI clock root */ | 244 | /* Enable NAND GPMI clock root */ |
221 | sciErr = sc_pm_clock_enable(ipcHndl, SC_R_NAND, SC_PM_CLK_MST_BUS, true, false); | 245 | sciErr = sc_pm_clock_enable(ipcHndl, SC_R_NAND, SC_PM_CLK_MST_BUS, true, false); |
222 | if (sciErr != SC_ERR_NONE) { | 246 | if (sciErr != SC_ERR_NONE) { |
223 | puts("NAND GPMI enable clock failed\n"); | 247 | puts("NAND GPMI enable clock failed\n"); |
224 | return; | 248 | return; |
225 | } | 249 | } |
226 | 250 | ||
251 | LPCG_AllClockOn(NAND_LPCG); | ||
252 | |||
227 | return; | 253 | return; |
228 | } | 254 | } |
229 | 255 | ||
230 | void enable_usboh3_clk(unsigned char enable) | 256 | void enable_usboh3_clk(unsigned char enable) |
231 | { | 257 | { |
258 | LPCG_AllClockOn(USB_2_LPCG); | ||
232 | return; | 259 | return; |
233 | } | 260 | } |
234 | 261 | ||
235 | void init_clk_usb3(int index) | 262 | void init_clk_usb3(int index) |
236 | { | 263 | { |
237 | sc_err_t err; | 264 | sc_err_t err; |
238 | sc_ipc_t ipc; | 265 | sc_ipc_t ipc; |
239 | 266 | ||
240 | ipc = gd->arch.ipc_channel_handle; | 267 | ipc = gd->arch.ipc_channel_handle; |
241 | 268 | ||
242 | err = sc_pm_clock_enable(ipc, SC_R_USB_2, SC_PM_CLK_MISC, true, false); | 269 | err = sc_pm_clock_enable(ipc, SC_R_USB_2, SC_PM_CLK_MISC, true, false); |
243 | if (err != SC_ERR_NONE) | 270 | if (err != SC_ERR_NONE) |
244 | printf("USB3 set clock failed!, line=%d (error = %d)\n", | 271 | printf("USB3 set clock failed!, line=%d (error = %d)\n", |
245 | __LINE__, err); | 272 | __LINE__, err); |
246 | 273 | ||
247 | err = sc_pm_clock_enable(ipc, SC_R_USB_2, SC_PM_CLK_MST_BUS, true, false); | 274 | err = sc_pm_clock_enable(ipc, SC_R_USB_2, SC_PM_CLK_MST_BUS, true, false); |
248 | if (err != SC_ERR_NONE) | 275 | if (err != SC_ERR_NONE) |
249 | printf("USB3 set clock failed!, line=%d (error = %d)\n", | 276 | printf("USB3 set clock failed!, line=%d (error = %d)\n", |
250 | __LINE__, err); | 277 | __LINE__, err); |
251 | 278 | ||
252 | err = sc_pm_clock_enable(ipc, SC_R_USB_2, SC_PM_CLK_PER, true, false); | 279 | err = sc_pm_clock_enable(ipc, SC_R_USB_2, SC_PM_CLK_PER, true, false); |
253 | if (err != SC_ERR_NONE) | 280 | if (err != SC_ERR_NONE) |
254 | printf("USB3 set clock failed!, line=%d (error = %d)\n", | 281 | printf("USB3 set clock failed!, line=%d (error = %d)\n", |
255 | __LINE__, err); | 282 | __LINE__, err); |
256 | 283 | ||
284 | LPCG_AllClockOn(USB_3_LPCG); | ||
257 | return; | 285 | return; |
258 | } | 286 | } |
259 | 287 | ||
260 | int cdns3_enable_clks(int index) | 288 | int cdns3_enable_clks(int index) |
261 | { | 289 | { |
262 | init_clk_usb3(index); | 290 | init_clk_usb3(index); |
263 | return 0; | 291 | return 0; |
264 | } | 292 | } |
265 | 293 | ||
266 | int cdns3_disable_clks(int index) | 294 | int cdns3_disable_clks(int index) |
267 | { | 295 | { |
268 | sc_err_t err; | 296 | sc_err_t err; |
269 | sc_ipc_t ipc; | 297 | sc_ipc_t ipc; |
270 | 298 | ||
271 | ipc = gd->arch.ipc_channel_handle; | 299 | ipc = gd->arch.ipc_channel_handle; |
272 | 300 | ||
301 | LPCG_AllClockOff(USB_3_LPCG); | ||
302 | |||
273 | err = sc_pm_clock_enable(ipc, SC_R_USB_2, SC_PM_CLK_MISC, false, false); | 303 | err = sc_pm_clock_enable(ipc, SC_R_USB_2, SC_PM_CLK_MISC, false, false); |
274 | if (err != SC_ERR_NONE) | 304 | if (err != SC_ERR_NONE) |
275 | printf("USB3 disable clock failed!, line=%d (error = %d)\n", | 305 | printf("USB3 disable clock failed!, line=%d (error = %d)\n", |
276 | __LINE__, err); | 306 | __LINE__, err); |
277 | 307 | ||
278 | err = sc_pm_clock_enable(ipc, SC_R_USB_2, SC_PM_CLK_MST_BUS, false, false); | 308 | err = sc_pm_clock_enable(ipc, SC_R_USB_2, SC_PM_CLK_MST_BUS, false, false); |
279 | if (err != SC_ERR_NONE) | 309 | if (err != SC_ERR_NONE) |
280 | printf("USB3 disable clock failed!, line=%d (error = %d)\n", | 310 | printf("USB3 disable clock failed!, line=%d (error = %d)\n", |
281 | __LINE__, err); | 311 | __LINE__, err); |
282 | 312 | ||
283 | err = sc_pm_clock_enable(ipc, SC_R_USB_2, SC_PM_CLK_PER, false, false); | 313 | err = sc_pm_clock_enable(ipc, SC_R_USB_2, SC_PM_CLK_PER, false, false); |
284 | if (err != SC_ERR_NONE) | 314 | if (err != SC_ERR_NONE) |
285 | printf("USB3 disable clock failed!, line=%d (error = %d)\n", | 315 | printf("USB3 disable clock failed!, line=%d (error = %d)\n", |
286 | __LINE__, err); | 316 | __LINE__, err); |
287 | 317 | ||
288 | return 0; | 318 | return 0; |
289 | } | 319 | } |
290 | 320 | ||
291 | void init_clk_usdhc(u32 index) | 321 | void init_clk_usdhc(u32 index) |
292 | { | 322 | { |
293 | #ifdef CONFIG_IMX8QM | 323 | #ifdef CONFIG_IMX8QM |
294 | sc_rsrc_t usdhcs[] = {SC_R_SDHC_0, SC_R_SDHC_1, SC_R_SDHC_2}; | 324 | sc_rsrc_t usdhcs[] = {SC_R_SDHC_0, SC_R_SDHC_1, SC_R_SDHC_2}; |
295 | u32 instances = 3; | 325 | u32 instances = 3; |
296 | #else | 326 | #else |
297 | sc_rsrc_t usdhcs[] = {SC_R_SDHC_0, SC_R_SDHC_1}; | 327 | sc_rsrc_t usdhcs[] = {SC_R_SDHC_0, SC_R_SDHC_1}; |
298 | u32 instances = 2; | 328 | u32 instances = 2; |
299 | #endif | 329 | #endif |
300 | 330 | ||
301 | sc_err_t err; | 331 | sc_err_t err; |
302 | sc_ipc_t ipc; | 332 | sc_ipc_t ipc; |
303 | sc_pm_clock_rate_t actual = 400000000; | 333 | sc_pm_clock_rate_t actual = 400000000; |
304 | 334 | ||
305 | ipc = gd->arch.ipc_channel_handle; | 335 | ipc = gd->arch.ipc_channel_handle; |
306 | 336 | ||
307 | if (index >= instances) | 337 | if (index >= instances) |
308 | return; | 338 | return; |
309 | 339 | ||
310 | /* Must disable the clock before set clock parent */ | 340 | /* Must disable the clock before set clock parent */ |
311 | err = sc_pm_clock_enable(ipc, usdhcs[index], SC_PM_CLK_PER, false, false); | 341 | err = sc_pm_clock_enable(ipc, usdhcs[index], SC_PM_CLK_PER, false, false); |
312 | if (err != SC_ERR_NONE) { | 342 | if (err != SC_ERR_NONE) { |
313 | printf("SDHC_%d per clk enable failed!\n", index); | 343 | printf("SDHC_%d per clk enable failed!\n", index); |
314 | return; | 344 | return; |
315 | } | 345 | } |
316 | 346 | ||
317 | /* | 347 | /* |
318 | * IMX8QXP USDHC_CLK_ROOT default source from DPLL, but this DPLL | 348 | * IMX8QXP USDHC_CLK_ROOT default source from DPLL, but this DPLL |
319 | * do not stable, will cause usdhc data transfer crc error. So here | 349 | * do not stable, will cause usdhc data transfer crc error. So here |
320 | * is a workaround, let USDHC_CLK_ROOT source from AVPLL. Due to | 350 | * is a workaround, let USDHC_CLK_ROOT source from AVPLL. Due to |
321 | * AVPLL is fixed to 1000MHz, so here config USDHC1_CLK_ROOT to 333MHz, | 351 | * AVPLL is fixed to 1000MHz, so here config USDHC1_CLK_ROOT to 333MHz, |
322 | * USDHC2_CLK_ROOT to 200MHz, make eMMC HS400ES work at 166MHz, and SD | 352 | * USDHC2_CLK_ROOT to 200MHz, make eMMC HS400ES work at 166MHz, and SD |
323 | * SDR104 work at 200MHz. | 353 | * SDR104 work at 200MHz. |
324 | */ | 354 | */ |
325 | if (is_imx8qxp()) { | 355 | if (is_imx8qxp()) { |
326 | err = sc_pm_set_clock_parent(ipc, usdhcs[index], 2, SC_PM_PARENT_PLL1); | 356 | err = sc_pm_set_clock_parent(ipc, usdhcs[index], 2, SC_PM_PARENT_PLL1); |
327 | if (err != SC_ERR_NONE) | 357 | if (err != SC_ERR_NONE) |
328 | printf("SDHC_%d set clock parent failed!(error = %d)\n", index, err); | 358 | printf("SDHC_%d set clock parent failed!(error = %d)\n", index, err); |
329 | 359 | ||
330 | if (index == 1) | 360 | if (index == 1) |
331 | actual = 200000000; | 361 | actual = 200000000; |
332 | } | 362 | } |
333 | 363 | ||
334 | err = sc_pm_set_clock_rate(ipc, usdhcs[index], 2, &actual); | 364 | err = sc_pm_set_clock_rate(ipc, usdhcs[index], 2, &actual); |
335 | if (err != SC_ERR_NONE) { | 365 | if (err != SC_ERR_NONE) { |
336 | printf("SDHC_%d set clock failed! (error = %d)\n", index, err); | 366 | printf("SDHC_%d set clock failed! (error = %d)\n", index, err); |
337 | return; | 367 | return; |
338 | } | 368 | } |
339 | 369 | ||
340 | if (actual != 400000000) | 370 | if (actual != 400000000) |
341 | debug("Actual rate for SDHC_%d is %d\n", index, actual); | 371 | debug("Actual rate for SDHC_%d is %d\n", index, actual); |
342 | 372 | ||
343 | err = sc_pm_clock_enable(ipc, usdhcs[index], SC_PM_CLK_PER, true, false); | 373 | err = sc_pm_clock_enable(ipc, usdhcs[index], SC_PM_CLK_PER, true, false); |
344 | if (err != SC_ERR_NONE) { | 374 | if (err != SC_ERR_NONE) { |
345 | printf("SDHC_%d per clk enable failed!\n", index); | 375 | printf("SDHC_%d per clk enable failed!\n", index); |
346 | return; | 376 | return; |
347 | } | 377 | } |
378 | |||
379 | LPCG_AllClockOn(USDHC_0_LPCG + index * 0x10000); | ||
348 | } | 380 | } |
349 | 381 | ||
350 | void init_clk_fec(int index) | 382 | void init_clk_fec(int index) |
351 | { | 383 | { |
352 | sc_err_t err; | 384 | sc_err_t err; |
353 | sc_ipc_t ipc; | 385 | sc_ipc_t ipc; |
354 | sc_pm_clock_rate_t rate = 24000000; | 386 | sc_pm_clock_rate_t rate = 24000000; |
355 | sc_rsrc_t enet[2] = {SC_R_ENET_0, SC_R_ENET_1}; | 387 | sc_rsrc_t enet[2] = {SC_R_ENET_0, SC_R_ENET_1}; |
356 | 388 | ||
357 | if (index > 1) | 389 | if (index > 1) |
358 | return; | 390 | return; |
359 | 391 | ||
360 | if (index == -1) | 392 | if (index == -1) |
361 | index = 0; | 393 | index = 0; |
362 | 394 | ||
363 | ipc = gd->arch.ipc_channel_handle; | 395 | ipc = gd->arch.ipc_channel_handle; |
364 | 396 | ||
365 | /* Disable SC_R_ENET_0 clock root */ | 397 | /* Disable SC_R_ENET_0 clock root */ |
366 | err = sc_pm_clock_enable(ipc, enet[index], 0, false, false); | 398 | err = sc_pm_clock_enable(ipc, enet[index], 0, false, false); |
367 | err |= sc_pm_clock_enable(ipc, enet[index], 2, false, false); | 399 | err |= sc_pm_clock_enable(ipc, enet[index], 2, false, false); |
368 | err |= sc_pm_clock_enable(ipc, enet[index], 4, false, false); | 400 | err |= sc_pm_clock_enable(ipc, enet[index], 4, false, false); |
369 | if (err != SC_ERR_NONE) { | 401 | if (err != SC_ERR_NONE) { |
370 | printf("\nSC_R_ENET_0 set clock disable failed! (error = %d)\n", err); | 402 | printf("\nSC_R_ENET_0 set clock disable failed! (error = %d)\n", err); |
371 | return; | 403 | return; |
372 | } | 404 | } |
373 | 405 | ||
374 | /* Set SC_R_ENET_0 clock root to 125 MHz */ | 406 | /* Set SC_R_ENET_0 clock root to 125 MHz */ |
375 | rate = 125000000; | 407 | rate = 125000000; |
376 | 408 | ||
377 | /* div = 8 clk_source = PLL_1 ss_slice #7 in verfication codes */ | 409 | /* div = 8 clk_source = PLL_1 ss_slice #7 in verfication codes */ |
378 | err = sc_pm_set_clock_rate(ipc, enet[index], 2, &rate); | 410 | err = sc_pm_set_clock_rate(ipc, enet[index], 2, &rate); |
379 | if (err != SC_ERR_NONE) { | 411 | if (err != SC_ERR_NONE) { |
380 | printf("\nSC_R_ENET_0 set clock ref clock 125M failed! (error = %d)\n", err); | 412 | printf("\nSC_R_ENET_0 set clock ref clock 125M failed! (error = %d)\n", err); |
381 | return; | 413 | return; |
382 | } | 414 | } |
383 | 415 | ||
384 | /* Enable SC_R_ENET_0 clock root */ | 416 | /* Enable SC_R_ENET_0 clock root */ |
385 | err = sc_pm_clock_enable(ipc, enet[index], 0, true, true); | 417 | err = sc_pm_clock_enable(ipc, enet[index], 0, true, true); |
386 | err |= sc_pm_clock_enable(ipc, enet[index], 2, true, true); | 418 | err |= sc_pm_clock_enable(ipc, enet[index], 2, true, true); |
387 | err |= sc_pm_clock_enable(ipc, enet[index], 4, true, true); | 419 | err |= sc_pm_clock_enable(ipc, enet[index], 4, true, true); |
388 | if (err != SC_ERR_NONE) { | 420 | if (err != SC_ERR_NONE) { |
389 | printf("\nSC_R_ENET_0 set clock enable failed! (error = %d)\n", err); | 421 | printf("\nSC_R_ENET_0 set clock enable failed! (error = %d)\n", err); |
390 | return; | 422 | return; |
391 | } | 423 | } |
424 | |||
425 | LPCG_AllClockOn(ENET_0_LPCG + index * 0x10000); | ||
392 | } | 426 | } |
393 | 427 | ||
394 | /* | 428 | /* |
395 | * Dump some core clockes. | 429 | * Dump some core clockes. |
396 | */ | 430 | */ |
397 | int do_mx8_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | 431 | int do_mx8_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
398 | { | 432 | { |
399 | printf("ARM %8d kHz\n", mxc_get_clock(MXC_ARM_CLK) / 1000); | 433 | printf("ARM %8d kHz\n", mxc_get_clock(MXC_ARM_CLK) / 1000); |
400 | printf("DRC %8d kHz\n", mxc_get_clock(MXC_DDR_CLK) / 1000); | 434 | printf("DRC %8d kHz\n", mxc_get_clock(MXC_DDR_CLK) / 1000); |
401 | printf("USDHC1 %8d kHz\n", mxc_get_clock(MXC_ESDHC_CLK) / 1000); | 435 | printf("USDHC1 %8d kHz\n", mxc_get_clock(MXC_ESDHC_CLK) / 1000); |
402 | printf("USDHC2 %8d kHz\n", mxc_get_clock(MXC_ESDHC2_CLK) / 1000); | 436 | printf("USDHC2 %8d kHz\n", mxc_get_clock(MXC_ESDHC2_CLK) / 1000); |
403 | printf("USDHC3 %8d kHz\n", mxc_get_clock(MXC_ESDHC3_CLK) / 1000); | 437 | printf("USDHC3 %8d kHz\n", mxc_get_clock(MXC_ESDHC3_CLK) / 1000); |
404 | printf("UART0 %8d kHz\n", mxc_get_clock(MXC_UART_CLK) / 1000); | 438 | printf("UART0 %8d kHz\n", mxc_get_clock(MXC_UART_CLK) / 1000); |
405 | printf("FEC0 %8d kHz\n", mxc_get_clock(MXC_FEC_CLK) / 1000); | 439 | printf("FEC0 %8d kHz\n", mxc_get_clock(MXC_FEC_CLK) / 1000); |
406 | printf("FLEXSPI0 %8d kHz\n", mxc_get_clock(MXC_FSPI_CLK) / 1000); | 440 | printf("FLEXSPI0 %8d kHz\n", mxc_get_clock(MXC_FSPI_CLK) / 1000); |
407 | 441 | ||
408 | return 0; | 442 | return 0; |
409 | } | 443 | } |
410 | 444 | ||
411 | U_BOOT_CMD( | 445 | U_BOOT_CMD( |
412 | clocks, CONFIG_SYS_MAXARGS, 1, do_mx8_showclocks, | 446 | clocks, CONFIG_SYS_MAXARGS, 1, do_mx8_showclocks, |
413 | "display clocks", | 447 | "display clocks", |
414 | "" | 448 | "" |
415 | ); | 449 | ); |
416 | 450 |
arch/arm/mach-imx/imx8/cpu.c
1 | /* | 1 | /* |
2 | * Copyright 2017 NXP | 2 | * Copyright 2017 NXP |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: GPL-2.0+ | 4 | * SPDX-License-Identifier: GPL-2.0+ |
5 | * | 5 | * |
6 | */ | 6 | */ |
7 | 7 | ||
8 | #include <common.h> | 8 | #include <common.h> |
9 | #include <errno.h> | 9 | #include <errno.h> |
10 | #include <asm/io.h> | 10 | #include <asm/io.h> |
11 | #include <power-domain.h> | 11 | #include <power-domain.h> |
12 | #include <dm/device.h> | 12 | #include <dm/device.h> |
13 | #include <dm/uclass-internal.h> | 13 | #include <dm/uclass-internal.h> |
14 | #include <asm/mach-imx/sci/sci.h> | 14 | #include <asm/mach-imx/sci/sci.h> |
15 | #include <asm/mach-imx/boot_mode.h> | 15 | #include <asm/mach-imx/boot_mode.h> |
16 | #include <asm/arch/clock.h> | 16 | #include <asm/arch/clock.h> |
17 | #include <thermal.h> | 17 | #include <thermal.h> |
18 | #include <asm/armv8/mmu.h> | 18 | #include <asm/armv8/mmu.h> |
19 | #include <elf.h> | 19 | #include <elf.h> |
20 | #include <asm/arch/sid.h> | 20 | #include <asm/arch/sid.h> |
21 | #include <asm/arch-imx/cpu.h> | 21 | #include <asm/arch-imx/cpu.h> |
22 | #include <asm/arch/sys_proto.h> | 22 | #include <asm/arch/sys_proto.h> |
23 | #include <asm/arch/video_common.h> | 23 | #include <asm/arch/video_common.h> |
24 | #include <linux/libfdt.h> | 24 | #include <linux/libfdt.h> |
25 | #include <fdt_support.h> | 25 | #include <fdt_support.h> |
26 | #include <fdtdec.h> | 26 | #include <fdtdec.h> |
27 | #include <asm/arch/cpu.h> | 27 | #include <asm/arch/cpu.h> |
28 | #include <generated/version_autogenerated.h> | 28 | #include <generated/version_autogenerated.h> |
29 | #include <asm/setup.h> | 29 | #include <asm/setup.h> |
30 | #include <asm/arch/lpcg.h> | ||
30 | 31 | ||
31 | DECLARE_GLOBAL_DATA_PTR; | 32 | DECLARE_GLOBAL_DATA_PTR; |
32 | 33 | ||
33 | struct edma_ch_map { | 34 | struct edma_ch_map { |
34 | sc_rsrc_t ch_start_rsrc; | 35 | sc_rsrc_t ch_start_rsrc; |
35 | u32 ch_start_regs; | 36 | u32 ch_start_regs; |
36 | u32 ch_num; | 37 | u32 ch_num; |
37 | const char* node_path; | 38 | const char* node_path; |
38 | }; | 39 | }; |
39 | 40 | ||
40 | u32 get_cpu_rev(void) | 41 | u32 get_cpu_rev(void) |
41 | { | 42 | { |
42 | sc_ipc_t ipcHndl; | 43 | sc_ipc_t ipcHndl; |
43 | uint32_t id = 0, rev = 0; | 44 | uint32_t id = 0, rev = 0; |
44 | sc_err_t err; | 45 | sc_err_t err; |
45 | 46 | ||
46 | ipcHndl = gd->arch.ipc_channel_handle; | 47 | ipcHndl = gd->arch.ipc_channel_handle; |
47 | 48 | ||
48 | err = sc_misc_get_control(ipcHndl, SC_R_SYSTEM, SC_C_ID, &id); | 49 | err = sc_misc_get_control(ipcHndl, SC_R_SYSTEM, SC_C_ID, &id); |
49 | if (err != SC_ERR_NONE) | 50 | if (err != SC_ERR_NONE) |
50 | return 0; | 51 | return 0; |
51 | 52 | ||
52 | rev = (id >> 5) & 0xf; | 53 | rev = (id >> 5) & 0xf; |
53 | id = (id & 0x1f) + MXC_SOC_IMX8; /* Dummy ID for chip */ | 54 | id = (id & 0x1f) + MXC_SOC_IMX8; /* Dummy ID for chip */ |
54 | 55 | ||
55 | return (id << 12) | rev; | 56 | return (id << 12) | rev; |
56 | } | 57 | } |
57 | 58 | ||
58 | #ifdef CONFIG_DISPLAY_CPUINFO | 59 | #ifdef CONFIG_DISPLAY_CPUINFO |
59 | const char *get_imx8_type(u32 imxtype) | 60 | const char *get_imx8_type(u32 imxtype) |
60 | { | 61 | { |
61 | switch (imxtype) { | 62 | switch (imxtype) { |
62 | case MXC_CPU_IMX8QM: | 63 | case MXC_CPU_IMX8QM: |
63 | return "8QM"; /* i.MX8 Quad MAX */ | 64 | return "8QM"; /* i.MX8 Quad MAX */ |
64 | case MXC_CPU_IMX8QXP: | 65 | case MXC_CPU_IMX8QXP: |
65 | return "8QXP"; /* i.MX8 Quad XP */ | 66 | return "8QXP"; /* i.MX8 Quad XP */ |
66 | case MXC_CPU_IMX8DX: | 67 | case MXC_CPU_IMX8DX: |
67 | return "8DX"; /* i.MX8 Dual X */ | 68 | return "8DX"; /* i.MX8 Dual X */ |
68 | default: | 69 | default: |
69 | return "??"; | 70 | return "??"; |
70 | } | 71 | } |
71 | } | 72 | } |
72 | 73 | ||
73 | const char *get_imx8_rev(u32 rev) | 74 | const char *get_imx8_rev(u32 rev) |
74 | { | 75 | { |
75 | switch (rev) { | 76 | switch (rev) { |
76 | case CHIP_REV_A: | 77 | case CHIP_REV_A: |
77 | return "A"; | 78 | return "A"; |
78 | case CHIP_REV_B: | 79 | case CHIP_REV_B: |
79 | return "B"; | 80 | return "B"; |
80 | default: | 81 | default: |
81 | return "?"; | 82 | return "?"; |
82 | } | 83 | } |
83 | } | 84 | } |
84 | 85 | ||
85 | const char *get_core_name(void) | 86 | const char *get_core_name(void) |
86 | { | 87 | { |
87 | if (is_cortex_a53()) | 88 | if (is_cortex_a53()) |
88 | return "A53"; | 89 | return "A53"; |
89 | else if (is_cortex_a35()) | 90 | else if (is_cortex_a35()) |
90 | return "A35"; | 91 | return "A35"; |
91 | else if (is_cortex_a72()) | 92 | else if (is_cortex_a72()) |
92 | return "A72"; | 93 | return "A72"; |
93 | else | 94 | else |
94 | return "?"; | 95 | return "?"; |
95 | } | 96 | } |
96 | 97 | ||
97 | 98 | ||
98 | int print_cpuinfo(void) | 99 | int print_cpuinfo(void) |
99 | { | 100 | { |
100 | u32 cpurev; | 101 | u32 cpurev; |
101 | 102 | ||
102 | cpurev = get_cpu_rev(); | 103 | cpurev = get_cpu_rev(); |
103 | 104 | ||
104 | printf("CPU: Freescale i.MX%s rev%s %s at %d MHz", | 105 | printf("CPU: Freescale i.MX%s rev%s %s at %d MHz", |
105 | get_imx8_type((cpurev & 0xFF000) >> 12), | 106 | get_imx8_type((cpurev & 0xFF000) >> 12), |
106 | get_imx8_rev((cpurev & 0xFFF)), | 107 | get_imx8_rev((cpurev & 0xFFF)), |
107 | get_core_name(), | 108 | get_core_name(), |
108 | mxc_get_clock(MXC_ARM_CLK) / 1000000); | 109 | mxc_get_clock(MXC_ARM_CLK) / 1000000); |
109 | 110 | ||
110 | #if defined(CONFIG_IMX_SC_THERMAL) | 111 | #if defined(CONFIG_IMX_SC_THERMAL) |
111 | struct udevice *thermal_dev; | 112 | struct udevice *thermal_dev; |
112 | int cpu_tmp, ret; | 113 | int cpu_tmp, ret; |
113 | 114 | ||
114 | if (is_imx8qm() && is_cortex_a72()) | 115 | if (is_imx8qm() && is_cortex_a72()) |
115 | ret = uclass_get_device_by_name(UCLASS_THERMAL, "cpu-thermal1", &thermal_dev); | 116 | ret = uclass_get_device_by_name(UCLASS_THERMAL, "cpu-thermal1", &thermal_dev); |
116 | else | 117 | else |
117 | ret = uclass_get_device_by_name(UCLASS_THERMAL, "cpu-thermal0", &thermal_dev); | 118 | ret = uclass_get_device_by_name(UCLASS_THERMAL, "cpu-thermal0", &thermal_dev); |
118 | 119 | ||
119 | if (!ret) { | 120 | if (!ret) { |
120 | ret = thermal_get_temp(thermal_dev, &cpu_tmp); | 121 | ret = thermal_get_temp(thermal_dev, &cpu_tmp); |
121 | 122 | ||
122 | if (!ret) | 123 | if (!ret) |
123 | printf(" at %dC", cpu_tmp); | 124 | printf(" at %dC", cpu_tmp); |
124 | else | 125 | else |
125 | debug(" - invalid sensor data"); | 126 | debug(" - invalid sensor data"); |
126 | } else { | 127 | } else { |
127 | debug(" - invalid sensor device"); | 128 | debug(" - invalid sensor device"); |
128 | } | 129 | } |
129 | #endif | 130 | #endif |
130 | 131 | ||
131 | printf("\n"); | 132 | printf("\n"); |
132 | return 0; | 133 | return 0; |
133 | } | 134 | } |
134 | #endif | 135 | #endif |
135 | 136 | ||
136 | #define BT_PASSOVER_TAG (0x504F) | 137 | #define BT_PASSOVER_TAG (0x504F) |
137 | struct pass_over_info_t *get_pass_over_info(void) | 138 | struct pass_over_info_t *get_pass_over_info(void) |
138 | { | 139 | { |
139 | struct pass_over_info_t *p = (struct pass_over_info_t *)PASS_OVER_INFO_ADDR; | 140 | struct pass_over_info_t *p = (struct pass_over_info_t *)PASS_OVER_INFO_ADDR; |
140 | 141 | ||
141 | if (p->barker != BT_PASSOVER_TAG || p->len != sizeof(struct pass_over_info_t)) | 142 | if (p->barker != BT_PASSOVER_TAG || p->len != sizeof(struct pass_over_info_t)) |
142 | return NULL; | 143 | return NULL; |
143 | 144 | ||
144 | return p; | 145 | return p; |
145 | } | 146 | } |
146 | 147 | ||
147 | int arch_cpu_init(void) | 148 | int arch_cpu_init(void) |
148 | { | 149 | { |
149 | sc_ipc_t ipcHndl = 0; | 150 | sc_ipc_t ipcHndl = 0; |
150 | sc_err_t sciErr = 0; | 151 | sc_err_t sciErr = 0; |
151 | struct pass_over_info_t *pass_over; | 152 | struct pass_over_info_t *pass_over; |
152 | 153 | ||
153 | gd->arch.ipc_channel_handle = 0; | 154 | gd->arch.ipc_channel_handle = 0; |
154 | 155 | ||
155 | /* Open IPC channel */ | 156 | /* Open IPC channel */ |
156 | sciErr = sc_ipc_open(&ipcHndl, SC_IPC_CH); | 157 | sciErr = sc_ipc_open(&ipcHndl, SC_IPC_CH); |
157 | if (sciErr != SC_ERR_NONE) | 158 | if (sciErr != SC_ERR_NONE) |
158 | return -EPERM; | 159 | return -EPERM; |
159 | 160 | ||
160 | gd->arch.ipc_channel_handle = ipcHndl; | 161 | gd->arch.ipc_channel_handle = ipcHndl; |
161 | 162 | ||
162 | if (IS_ENABLED(CONFIG_XEN)) | 163 | if (IS_ENABLED(CONFIG_XEN)) |
163 | return 0; | 164 | return 0; |
164 | 165 | ||
165 | pass_over = get_pass_over_info(); | 166 | pass_over = get_pass_over_info(); |
166 | if (pass_over && pass_over->g_ap_mu == 0) { | 167 | if (pass_over && pass_over->g_ap_mu == 0) { |
167 | /* When ap_mu is 0, means the u-boot is boot from first container */ | 168 | /* When ap_mu is 0, means the u-boot is boot from first container */ |
168 | sc_misc_boot_status(ipcHndl, SC_MISC_BOOT_STATUS_SUCCESS); | 169 | sc_misc_boot_status(ipcHndl, SC_MISC_BOOT_STATUS_SUCCESS); |
169 | } | 170 | } |
170 | 171 | ||
171 | #ifdef CONFIG_IMX_SMMU | 172 | #ifdef CONFIG_IMX_SMMU |
172 | sciErr = sc_pm_set_resource_power_mode(ipcHndl, SC_R_SMMU, | 173 | sciErr = sc_pm_set_resource_power_mode(ipcHndl, SC_R_SMMU, |
173 | SC_PM_PW_MODE_ON); | 174 | SC_PM_PW_MODE_ON); |
174 | if (sciErr != SC_ERR_NONE) | 175 | if (sciErr != SC_ERR_NONE) |
175 | return 0; | 176 | return 0; |
176 | #endif | 177 | #endif |
177 | 178 | ||
178 | return 0; | 179 | return 0; |
179 | } | 180 | } |
180 | 181 | ||
181 | u32 cpu_mask(void) | 182 | u32 cpu_mask(void) |
182 | { | 183 | { |
183 | #ifdef CONFIG_IMX8QM | 184 | #ifdef CONFIG_IMX8QM |
184 | return 0x3f; | 185 | return 0x3f; |
185 | #else | 186 | #else |
186 | return 0xf; /*For IMX8QXP*/ | 187 | return 0xf; /*For IMX8QXP*/ |
187 | #endif | 188 | #endif |
188 | } | 189 | } |
189 | 190 | ||
190 | #define CCI400_DVM_MESSAGE_REQ_EN 0x00000002 | 191 | #define CCI400_DVM_MESSAGE_REQ_EN 0x00000002 |
191 | #define CCI400_SNOOP_REQ_EN 0x00000001 | 192 | #define CCI400_SNOOP_REQ_EN 0x00000001 |
192 | #define CHANGE_PENDING_BIT (1 << 0) | 193 | #define CHANGE_PENDING_BIT (1 << 0) |
193 | int imx8qm_wake_seconday_cores(void) | 194 | int imx8qm_wake_seconday_cores(void) |
194 | { | 195 | { |
195 | #ifdef CONFIG_ARMV8_MULTIENTRY | 196 | #ifdef CONFIG_ARMV8_MULTIENTRY |
196 | sc_ipc_t ipcHndl; | 197 | sc_ipc_t ipcHndl; |
197 | u64 *table = get_spin_tbl_addr(); | 198 | u64 *table = get_spin_tbl_addr(); |
198 | 199 | ||
199 | /* Clear spin table so that secondary processors | 200 | /* Clear spin table so that secondary processors |
200 | * observe the correct value after waking up from wfe. | 201 | * observe the correct value after waking up from wfe. |
201 | */ | 202 | */ |
202 | memset(table, 0, CONFIG_MAX_CPUS*SPIN_TABLE_ELEM_SIZE); | 203 | memset(table, 0, CONFIG_MAX_CPUS*SPIN_TABLE_ELEM_SIZE); |
203 | flush_dcache_range((unsigned long)table, | 204 | flush_dcache_range((unsigned long)table, |
204 | (unsigned long)table + | 205 | (unsigned long)table + |
205 | (CONFIG_MAX_CPUS*SPIN_TABLE_ELEM_SIZE)); | 206 | (CONFIG_MAX_CPUS*SPIN_TABLE_ELEM_SIZE)); |
206 | 207 | ||
207 | /* Open IPC channel */ | 208 | /* Open IPC channel */ |
208 | if (sc_ipc_open(&ipcHndl, SC_IPC_CH) != SC_ERR_NONE) | 209 | if (sc_ipc_open(&ipcHndl, SC_IPC_CH) != SC_ERR_NONE) |
209 | return -EIO; | 210 | return -EIO; |
210 | 211 | ||
211 | __raw_writel(0xc, 0x52090000); | 212 | __raw_writel(0xc, 0x52090000); |
212 | __raw_writel(1, 0x52090008); | 213 | __raw_writel(1, 0x52090008); |
213 | 214 | ||
214 | /* IPC to pwr up and boot other cores */ | 215 | /* IPC to pwr up and boot other cores */ |
215 | if (sc_pm_set_resource_power_mode(ipcHndl, SC_R_A53_1, SC_PM_PW_MODE_ON) != SC_ERR_NONE) | 216 | if (sc_pm_set_resource_power_mode(ipcHndl, SC_R_A53_1, SC_PM_PW_MODE_ON) != SC_ERR_NONE) |
216 | return -EIO; | 217 | return -EIO; |
217 | if (sc_pm_cpu_start(ipcHndl, SC_R_A53_1, true, 0x80000000) != SC_ERR_NONE) | 218 | if (sc_pm_cpu_start(ipcHndl, SC_R_A53_1, true, 0x80000000) != SC_ERR_NONE) |
218 | return -EIO; | 219 | return -EIO; |
219 | 220 | ||
220 | if (sc_pm_set_resource_power_mode(ipcHndl, SC_R_A53_2, SC_PM_PW_MODE_ON) != SC_ERR_NONE) | 221 | if (sc_pm_set_resource_power_mode(ipcHndl, SC_R_A53_2, SC_PM_PW_MODE_ON) != SC_ERR_NONE) |
221 | return -EIO; | 222 | return -EIO; |
222 | if (sc_pm_cpu_start(ipcHndl, SC_R_A53_2, true, 0x80000000) != SC_ERR_NONE) | 223 | if (sc_pm_cpu_start(ipcHndl, SC_R_A53_2, true, 0x80000000) != SC_ERR_NONE) |
223 | return -EIO; | 224 | return -EIO; |
224 | 225 | ||
225 | if (sc_pm_set_resource_power_mode(ipcHndl, SC_R_A53_3, SC_PM_PW_MODE_ON) != SC_ERR_NONE) | 226 | if (sc_pm_set_resource_power_mode(ipcHndl, SC_R_A53_3, SC_PM_PW_MODE_ON) != SC_ERR_NONE) |
226 | return -EIO; | 227 | return -EIO; |
227 | if (sc_pm_cpu_start(ipcHndl, SC_R_A53_3, true, 0x80000000) != SC_ERR_NONE) | 228 | if (sc_pm_cpu_start(ipcHndl, SC_R_A53_3, true, 0x80000000) != SC_ERR_NONE) |
228 | return -EIO; | 229 | return -EIO; |
229 | 230 | ||
230 | /* Enable snoop and dvm msg requests for a53 port on CCI slave interface 3 */ | 231 | /* Enable snoop and dvm msg requests for a53 port on CCI slave interface 3 */ |
231 | __raw_writel(CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN, 0x52094000); | 232 | __raw_writel(CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN, 0x52094000); |
232 | 233 | ||
233 | while (__raw_readl(0x5209000c) & CHANGE_PENDING_BIT) | 234 | while (__raw_readl(0x5209000c) & CHANGE_PENDING_BIT) |
234 | ; | 235 | ; |
235 | 236 | ||
236 | /* Pwr up cluster 1 and boot core 0*/ | 237 | /* Pwr up cluster 1 and boot core 0*/ |
237 | if (sc_pm_set_resource_power_mode(ipcHndl, SC_R_A72, SC_PM_PW_MODE_ON) != SC_ERR_NONE) | 238 | if (sc_pm_set_resource_power_mode(ipcHndl, SC_R_A72, SC_PM_PW_MODE_ON) != SC_ERR_NONE) |
238 | return -EIO; | 239 | return -EIO; |
239 | 240 | ||
240 | if (sc_pm_set_resource_power_mode(ipcHndl, SC_R_A72_0, SC_PM_PW_MODE_ON) != SC_ERR_NONE) | 241 | if (sc_pm_set_resource_power_mode(ipcHndl, SC_R_A72_0, SC_PM_PW_MODE_ON) != SC_ERR_NONE) |
241 | return -EIO; | 242 | return -EIO; |
242 | if (sc_pm_cpu_start(ipcHndl, SC_R_A72_0, true, 0x80000000) != SC_ERR_NONE) | 243 | if (sc_pm_cpu_start(ipcHndl, SC_R_A72_0, true, 0x80000000) != SC_ERR_NONE) |
243 | return -EIO; | 244 | return -EIO; |
244 | 245 | ||
245 | /* IPC to pwr up and boot core 1 */ | 246 | /* IPC to pwr up and boot core 1 */ |
246 | if (sc_pm_set_resource_power_mode(ipcHndl, SC_R_A72_1, SC_PM_PW_MODE_ON) != SC_ERR_NONE) | 247 | if (sc_pm_set_resource_power_mode(ipcHndl, SC_R_A72_1, SC_PM_PW_MODE_ON) != SC_ERR_NONE) |
247 | return -EIO; | 248 | return -EIO; |
248 | if (sc_pm_cpu_start(ipcHndl, SC_R_A72_1, true, 0x80000000) != SC_ERR_NONE) | 249 | if (sc_pm_cpu_start(ipcHndl, SC_R_A72_1, true, 0x80000000) != SC_ERR_NONE) |
249 | return -EIO; | 250 | return -EIO; |
250 | 251 | ||
251 | /* Enable snoop and dvm msg requests for a72 port on CCI slave interface 4 */ | 252 | /* Enable snoop and dvm msg requests for a72 port on CCI slave interface 4 */ |
252 | __raw_writel(CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN, 0x52095000); | 253 | __raw_writel(CCI400_DVM_MESSAGE_REQ_EN | CCI400_SNOOP_REQ_EN, 0x52095000); |
253 | 254 | ||
254 | while (__raw_readl(0x5209000c) & CHANGE_PENDING_BIT) | 255 | while (__raw_readl(0x5209000c) & CHANGE_PENDING_BIT) |
255 | ; | 256 | ; |
256 | #endif | 257 | #endif |
257 | return 0; | 258 | return 0; |
258 | } | 259 | } |
259 | 260 | ||
260 | int imx8qxp_wake_secondary_cores(void) | 261 | int imx8qxp_wake_secondary_cores(void) |
261 | { | 262 | { |
262 | #ifdef CONFIG_ARMV8_MULTIENTRY | 263 | #ifdef CONFIG_ARMV8_MULTIENTRY |
263 | sc_ipc_t ipcHndl; | 264 | sc_ipc_t ipcHndl; |
264 | u64 *table = get_spin_tbl_addr(); | 265 | u64 *table = get_spin_tbl_addr(); |
265 | 266 | ||
266 | /* Clear spin table so that secondary processors | 267 | /* Clear spin table so that secondary processors |
267 | * observe the correct value after waking up from wfe. | 268 | * observe the correct value after waking up from wfe. |
268 | */ | 269 | */ |
269 | memset(table, 0, CONFIG_MAX_CPUS*SPIN_TABLE_ELEM_SIZE); | 270 | memset(table, 0, CONFIG_MAX_CPUS*SPIN_TABLE_ELEM_SIZE); |
270 | flush_dcache_range((unsigned long)table, | 271 | flush_dcache_range((unsigned long)table, |
271 | (unsigned long)table + | 272 | (unsigned long)table + |
272 | (CONFIG_MAX_CPUS*SPIN_TABLE_ELEM_SIZE)); | 273 | (CONFIG_MAX_CPUS*SPIN_TABLE_ELEM_SIZE)); |
273 | 274 | ||
274 | /* Open IPC channel */ | 275 | /* Open IPC channel */ |
275 | if (sc_ipc_open(&ipcHndl, SC_IPC_CH) != SC_ERR_NONE) | 276 | if (sc_ipc_open(&ipcHndl, SC_IPC_CH) != SC_ERR_NONE) |
276 | return -EIO; | 277 | return -EIO; |
277 | 278 | ||
278 | /* IPC to pwr up and boot other cores */ | 279 | /* IPC to pwr up and boot other cores */ |
279 | if (sc_pm_set_resource_power_mode(ipcHndl, SC_R_A35_1, SC_PM_PW_MODE_ON) != SC_ERR_NONE) | 280 | if (sc_pm_set_resource_power_mode(ipcHndl, SC_R_A35_1, SC_PM_PW_MODE_ON) != SC_ERR_NONE) |
280 | return -EIO; | 281 | return -EIO; |
281 | if (sc_pm_cpu_start(ipcHndl, SC_R_A35_1, true, 0x80000000) != SC_ERR_NONE) | 282 | if (sc_pm_cpu_start(ipcHndl, SC_R_A35_1, true, 0x80000000) != SC_ERR_NONE) |
282 | return -EIO; | 283 | return -EIO; |
283 | 284 | ||
284 | if (sc_pm_set_resource_power_mode(ipcHndl, SC_R_A35_2, SC_PM_PW_MODE_ON) != SC_ERR_NONE) | 285 | if (sc_pm_set_resource_power_mode(ipcHndl, SC_R_A35_2, SC_PM_PW_MODE_ON) != SC_ERR_NONE) |
285 | return -EIO; | 286 | return -EIO; |
286 | if (sc_pm_cpu_start(ipcHndl, SC_R_A35_2, true, 0x80000000) != SC_ERR_NONE) | 287 | if (sc_pm_cpu_start(ipcHndl, SC_R_A35_2, true, 0x80000000) != SC_ERR_NONE) |
287 | return -EIO; | 288 | return -EIO; |
288 | 289 | ||
289 | if (sc_pm_set_resource_power_mode(ipcHndl, SC_R_A35_3, SC_PM_PW_MODE_ON) != SC_ERR_NONE) | 290 | if (sc_pm_set_resource_power_mode(ipcHndl, SC_R_A35_3, SC_PM_PW_MODE_ON) != SC_ERR_NONE) |
290 | return -EIO; | 291 | return -EIO; |
291 | if (sc_pm_cpu_start(ipcHndl, SC_R_A35_3, true, 0x80000000) != SC_ERR_NONE) | 292 | if (sc_pm_cpu_start(ipcHndl, SC_R_A35_3, true, 0x80000000) != SC_ERR_NONE) |
292 | return -EIO; | 293 | return -EIO; |
293 | 294 | ||
294 | #endif | 295 | #endif |
295 | return 0; | 296 | return 0; |
296 | } | 297 | } |
297 | 298 | ||
298 | #if defined(CONFIG_IMX8QM) | 299 | #if defined(CONFIG_IMX8QM) |
299 | #define FUSE_MAC0_WORD0 452 | 300 | #define FUSE_MAC0_WORD0 452 |
300 | #define FUSE_MAC0_WORD1 453 | 301 | #define FUSE_MAC0_WORD1 453 |
301 | #define FUSE_MAC1_WORD0 454 | 302 | #define FUSE_MAC1_WORD0 454 |
302 | #define FUSE_MAC1_WORD1 455 | 303 | #define FUSE_MAC1_WORD1 455 |
303 | #elif defined(CONFIG_IMX8QXP) | 304 | #elif defined(CONFIG_IMX8QXP) |
304 | #define FUSE_MAC0_WORD0 708 | 305 | #define FUSE_MAC0_WORD0 708 |
305 | #define FUSE_MAC0_WORD1 709 | 306 | #define FUSE_MAC0_WORD1 709 |
306 | #define FUSE_MAC1_WORD0 710 | 307 | #define FUSE_MAC1_WORD0 710 |
307 | #define FUSE_MAC1_WORD1 711 | 308 | #define FUSE_MAC1_WORD1 711 |
308 | #endif | 309 | #endif |
309 | 310 | ||
310 | void imx_get_mac_from_fuse(int dev_id, unsigned char *mac) | 311 | void imx_get_mac_from_fuse(int dev_id, unsigned char *mac) |
311 | { | 312 | { |
312 | sc_err_t err; | 313 | sc_err_t err; |
313 | sc_ipc_t ipc; | 314 | sc_ipc_t ipc; |
314 | uint32_t val1 = 0, val2 = 0; | 315 | uint32_t val1 = 0, val2 = 0; |
315 | uint32_t word1, word2; | 316 | uint32_t word1, word2; |
316 | 317 | ||
317 | ipc = gd->arch.ipc_channel_handle; | 318 | ipc = gd->arch.ipc_channel_handle; |
318 | 319 | ||
319 | if (dev_id == 0) { | 320 | if (dev_id == 0) { |
320 | word1 = FUSE_MAC0_WORD0; | 321 | word1 = FUSE_MAC0_WORD0; |
321 | word2 = FUSE_MAC0_WORD1; | 322 | word2 = FUSE_MAC0_WORD1; |
322 | } else { | 323 | } else { |
323 | word1 = FUSE_MAC1_WORD0; | 324 | word1 = FUSE_MAC1_WORD0; |
324 | word2 = FUSE_MAC1_WORD1; | 325 | word2 = FUSE_MAC1_WORD1; |
325 | } | 326 | } |
326 | 327 | ||
327 | err = sc_misc_otp_fuse_read(ipc, word1, &val1); | 328 | err = sc_misc_otp_fuse_read(ipc, word1, &val1); |
328 | if (err != SC_ERR_NONE) { | 329 | if (err != SC_ERR_NONE) { |
329 | printf("%s fuse %d read error: %d\n", __func__, word1, err); | 330 | printf("%s fuse %d read error: %d\n", __func__, word1, err); |
330 | return; | 331 | return; |
331 | } | 332 | } |
332 | 333 | ||
333 | err = sc_misc_otp_fuse_read(ipc, word2, &val2); | 334 | err = sc_misc_otp_fuse_read(ipc, word2, &val2); |
334 | if (err != SC_ERR_NONE) { | 335 | if (err != SC_ERR_NONE) { |
335 | printf("%s fuse %d read error: %d\n", __func__, word2, err); | 336 | printf("%s fuse %d read error: %d\n", __func__, word2, err); |
336 | return; | 337 | return; |
337 | } | 338 | } |
338 | 339 | ||
339 | mac[0] = val1; | 340 | mac[0] = val1; |
340 | mac[1] = val1 >> 8; | 341 | mac[1] = val1 >> 8; |
341 | mac[2] = val1 >> 16; | 342 | mac[2] = val1 >> 16; |
342 | mac[3] = val1 >> 24; | 343 | mac[3] = val1 >> 24; |
343 | mac[4] = val2; | 344 | mac[4] = val2; |
344 | mac[5] = val2 >> 8; | 345 | mac[5] = val2 >> 8; |
345 | } | 346 | } |
346 | 347 | ||
347 | #ifdef CONFIG_IMX_BOOTAUX | 348 | #ifdef CONFIG_IMX_BOOTAUX |
348 | 349 | ||
349 | #ifdef CONFIG_IMX8QM | 350 | #ifdef CONFIG_IMX8QM |
350 | int arch_auxiliary_core_up(u32 core_id, ulong boot_private_data) | 351 | int arch_auxiliary_core_up(u32 core_id, ulong boot_private_data) |
351 | { | 352 | { |
352 | sc_ipc_t ipcHndl; | 353 | sc_ipc_t ipcHndl; |
353 | sc_rsrc_t core_rsrc, mu_rsrc; | 354 | sc_rsrc_t core_rsrc, mu_rsrc; |
354 | sc_faddr_t tcml_addr; | 355 | sc_faddr_t tcml_addr; |
355 | u32 tcml_size = SZ_128K; | 356 | u32 tcml_size = SZ_128K; |
356 | ulong addr; | 357 | ulong addr; |
357 | 358 | ||
358 | ipcHndl = gd->arch.ipc_channel_handle; | 359 | ipcHndl = gd->arch.ipc_channel_handle; |
359 | 360 | ||
360 | switch (core_id) { | 361 | switch (core_id) { |
361 | case 0: | 362 | case 0: |
362 | core_rsrc = SC_R_M4_0_PID0; | 363 | core_rsrc = SC_R_M4_0_PID0; |
363 | tcml_addr = 0x34FE0000; | 364 | tcml_addr = 0x34FE0000; |
364 | mu_rsrc = SC_R_M4_0_MU_1A; | 365 | mu_rsrc = SC_R_M4_0_MU_1A; |
365 | break; | 366 | break; |
366 | case 1: | 367 | case 1: |
367 | core_rsrc = SC_R_M4_1_PID0; | 368 | core_rsrc = SC_R_M4_1_PID0; |
368 | tcml_addr = 0x38FE0000; | 369 | tcml_addr = 0x38FE0000; |
369 | mu_rsrc = SC_R_M4_1_MU_1A; | 370 | mu_rsrc = SC_R_M4_1_MU_1A; |
370 | break; | 371 | break; |
371 | default: | 372 | default: |
372 | printf("Not support this core boot up, ID:%u\n", core_id); | 373 | printf("Not support this core boot up, ID:%u\n", core_id); |
373 | return -EINVAL; | 374 | return -EINVAL; |
374 | } | 375 | } |
375 | 376 | ||
376 | addr = (sc_faddr_t)boot_private_data; | 377 | addr = (sc_faddr_t)boot_private_data; |
377 | 378 | ||
378 | if (addr >= tcml_addr && addr <= tcml_addr + tcml_size) { | 379 | if (addr >= tcml_addr && addr <= tcml_addr + tcml_size) { |
379 | printf("Wrong image address 0x%lx, should not in TCML\n", | 380 | printf("Wrong image address 0x%lx, should not in TCML\n", |
380 | addr); | 381 | addr); |
381 | return -EINVAL; | 382 | return -EINVAL; |
382 | } | 383 | } |
383 | 384 | ||
384 | printf("Power on M4 and MU\n"); | 385 | printf("Power on M4 and MU\n"); |
385 | 386 | ||
386 | if (sc_pm_set_resource_power_mode(ipcHndl, core_rsrc, SC_PM_PW_MODE_ON) != SC_ERR_NONE) | 387 | if (sc_pm_set_resource_power_mode(ipcHndl, core_rsrc, SC_PM_PW_MODE_ON) != SC_ERR_NONE) |
387 | return -EIO; | 388 | return -EIO; |
388 | 389 | ||
389 | if (sc_pm_set_resource_power_mode(ipcHndl, mu_rsrc, SC_PM_PW_MODE_ON) != SC_ERR_NONE) | 390 | if (sc_pm_set_resource_power_mode(ipcHndl, mu_rsrc, SC_PM_PW_MODE_ON) != SC_ERR_NONE) |
390 | return -EIO; | 391 | return -EIO; |
391 | 392 | ||
392 | printf("Copy M4 image from 0x%lx to TCML 0x%lx\n", addr, (ulong)tcml_addr); | 393 | printf("Copy M4 image from 0x%lx to TCML 0x%lx\n", addr, (ulong)tcml_addr); |
393 | 394 | ||
394 | if (addr != tcml_addr) | 395 | if (addr != tcml_addr) |
395 | memcpy((void *)tcml_addr, (void *)addr, tcml_size); | 396 | memcpy((void *)tcml_addr, (void *)addr, tcml_size); |
396 | 397 | ||
397 | printf("Start M4 %u\n", core_id); | 398 | printf("Start M4 %u\n", core_id); |
398 | if (sc_pm_cpu_start(ipcHndl, core_rsrc, true, tcml_addr) != SC_ERR_NONE) | 399 | if (sc_pm_cpu_start(ipcHndl, core_rsrc, true, tcml_addr) != SC_ERR_NONE) |
399 | return -EIO; | 400 | return -EIO; |
400 | 401 | ||
401 | printf("bootaux complete\n"); | 402 | printf("bootaux complete\n"); |
402 | return 0; | 403 | return 0; |
403 | } | 404 | } |
404 | #endif | 405 | #endif |
405 | 406 | ||
406 | #ifdef CONFIG_IMX8QXP | 407 | #ifdef CONFIG_IMX8QXP |
407 | static unsigned long load_elf_image_shdr(unsigned long addr) | 408 | static unsigned long load_elf_image_shdr(unsigned long addr) |
408 | { | 409 | { |
409 | Elf32_Ehdr *ehdr; /* Elf header structure pointer */ | 410 | Elf32_Ehdr *ehdr; /* Elf header structure pointer */ |
410 | Elf32_Shdr *shdr; /* Section header structure pointer */ | 411 | Elf32_Shdr *shdr; /* Section header structure pointer */ |
411 | unsigned char *strtab = 0; /* String table pointer */ | 412 | unsigned char *strtab = 0; /* String table pointer */ |
412 | unsigned char *image; /* Binary image pointer */ | 413 | unsigned char *image; /* Binary image pointer */ |
413 | int i; /* Loop counter */ | 414 | int i; /* Loop counter */ |
414 | 415 | ||
415 | ehdr = (Elf32_Ehdr *)addr; | 416 | ehdr = (Elf32_Ehdr *)addr; |
416 | 417 | ||
417 | /* Find the section header string table for output info */ | 418 | /* Find the section header string table for output info */ |
418 | shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff + | 419 | shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff + |
419 | (ehdr->e_shstrndx * sizeof(Elf32_Shdr))); | 420 | (ehdr->e_shstrndx * sizeof(Elf32_Shdr))); |
420 | 421 | ||
421 | if (shdr->sh_type == SHT_STRTAB) | 422 | if (shdr->sh_type == SHT_STRTAB) |
422 | strtab = (unsigned char *)(addr + shdr->sh_offset); | 423 | strtab = (unsigned char *)(addr + shdr->sh_offset); |
423 | 424 | ||
424 | /* Load each appropriate section */ | 425 | /* Load each appropriate section */ |
425 | for (i = 0; i < ehdr->e_shnum; ++i) { | 426 | for (i = 0; i < ehdr->e_shnum; ++i) { |
426 | shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff + | 427 | shdr = (Elf32_Shdr *)(addr + ehdr->e_shoff + |
427 | (i * sizeof(Elf32_Shdr))); | 428 | (i * sizeof(Elf32_Shdr))); |
428 | 429 | ||
429 | if (!(shdr->sh_flags & SHF_ALLOC) || | 430 | if (!(shdr->sh_flags & SHF_ALLOC) || |
430 | shdr->sh_addr == 0 || shdr->sh_size == 0) { | 431 | shdr->sh_addr == 0 || shdr->sh_size == 0) { |
431 | continue; | 432 | continue; |
432 | } | 433 | } |
433 | 434 | ||
434 | if (strtab) { | 435 | if (strtab) { |
435 | debug("%sing %s @ 0x%08lx (%ld bytes)\n", | 436 | debug("%sing %s @ 0x%08lx (%ld bytes)\n", |
436 | (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load", | 437 | (shdr->sh_type == SHT_NOBITS) ? "Clear" : "Load", |
437 | &strtab[shdr->sh_name], | 438 | &strtab[shdr->sh_name], |
438 | (unsigned long)shdr->sh_addr, | 439 | (unsigned long)shdr->sh_addr, |
439 | (long)shdr->sh_size); | 440 | (long)shdr->sh_size); |
440 | } | 441 | } |
441 | 442 | ||
442 | if (shdr->sh_type == SHT_NOBITS) { | 443 | if (shdr->sh_type == SHT_NOBITS) { |
443 | memset((void *)(uintptr_t)shdr->sh_addr, 0, | 444 | memset((void *)(uintptr_t)shdr->sh_addr, 0, |
444 | shdr->sh_size); | 445 | shdr->sh_size); |
445 | } else { | 446 | } else { |
446 | image = (unsigned char *)addr + shdr->sh_offset; | 447 | image = (unsigned char *)addr + shdr->sh_offset; |
447 | memcpy((void *)(uintptr_t)shdr->sh_addr, | 448 | memcpy((void *)(uintptr_t)shdr->sh_addr, |
448 | (const void *)image, shdr->sh_size); | 449 | (const void *)image, shdr->sh_size); |
449 | } | 450 | } |
450 | flush_cache(shdr->sh_addr, shdr->sh_size); | 451 | flush_cache(shdr->sh_addr, shdr->sh_size); |
451 | } | 452 | } |
452 | 453 | ||
453 | return ehdr->e_entry; | 454 | return ehdr->e_entry; |
454 | } | 455 | } |
455 | 456 | ||
456 | int arch_auxiliary_core_up(u32 core_id, ulong boot_private_data) | 457 | int arch_auxiliary_core_up(u32 core_id, ulong boot_private_data) |
457 | { | 458 | { |
458 | sc_ipc_t ipcHndl; | 459 | sc_ipc_t ipcHndl; |
459 | sc_rsrc_t core_rsrc, mu_rsrc = -1; | 460 | sc_rsrc_t core_rsrc, mu_rsrc = -1; |
460 | sc_faddr_t aux_core_ram; | 461 | sc_faddr_t aux_core_ram; |
461 | u32 size; | 462 | u32 size; |
462 | ulong addr; | 463 | ulong addr; |
463 | 464 | ||
464 | ipcHndl = gd->arch.ipc_channel_handle; | 465 | ipcHndl = gd->arch.ipc_channel_handle; |
465 | 466 | ||
466 | switch (core_id) { | 467 | switch (core_id) { |
467 | case 0: | 468 | case 0: |
468 | core_rsrc = SC_R_M4_0_PID0; | 469 | core_rsrc = SC_R_M4_0_PID0; |
469 | aux_core_ram = 0x34FE0000; | 470 | aux_core_ram = 0x34FE0000; |
470 | mu_rsrc = SC_R_M4_0_MU_1A; | 471 | mu_rsrc = SC_R_M4_0_MU_1A; |
471 | size = SZ_128K; | 472 | size = SZ_128K; |
472 | break; | 473 | break; |
473 | case 1: | 474 | case 1: |
474 | core_rsrc = SC_R_DSP; | 475 | core_rsrc = SC_R_DSP; |
475 | aux_core_ram = 0x596f8000; | 476 | aux_core_ram = 0x596f8000; |
476 | size = SZ_2K; | 477 | size = SZ_2K; |
477 | break; | 478 | break; |
478 | default: | 479 | default: |
479 | printf("Not support this core boot up, ID:%u\n", core_id); | 480 | printf("Not support this core boot up, ID:%u\n", core_id); |
480 | return -EINVAL; | 481 | return -EINVAL; |
481 | } | 482 | } |
482 | 483 | ||
483 | addr = (sc_faddr_t)boot_private_data; | 484 | addr = (sc_faddr_t)boot_private_data; |
484 | 485 | ||
485 | if (addr >= aux_core_ram && addr <= aux_core_ram + size) { | 486 | if (addr >= aux_core_ram && addr <= aux_core_ram + size) { |
486 | printf("Wrong image address 0x%lx, should not in aux core ram\n", | 487 | printf("Wrong image address 0x%lx, should not in aux core ram\n", |
487 | addr); | 488 | addr); |
488 | return -EINVAL; | 489 | return -EINVAL; |
489 | } | 490 | } |
490 | 491 | ||
491 | printf("Power on aux core %d\n", core_id); | 492 | printf("Power on aux core %d\n", core_id); |
492 | 493 | ||
493 | if (sc_pm_set_resource_power_mode(ipcHndl, core_rsrc, SC_PM_PW_MODE_ON) != SC_ERR_NONE) | 494 | if (sc_pm_set_resource_power_mode(ipcHndl, core_rsrc, SC_PM_PW_MODE_ON) != SC_ERR_NONE) |
494 | return -EIO; | 495 | return -EIO; |
495 | 496 | ||
496 | if (mu_rsrc != -1) { | 497 | if (mu_rsrc != -1) { |
497 | if (sc_pm_set_resource_power_mode(ipcHndl, mu_rsrc, SC_PM_PW_MODE_ON) != SC_ERR_NONE) | 498 | if (sc_pm_set_resource_power_mode(ipcHndl, mu_rsrc, SC_PM_PW_MODE_ON) != SC_ERR_NONE) |
498 | return -EIO; | 499 | return -EIO; |
499 | } | 500 | } |
500 | 501 | ||
501 | if (core_id == 1) { | 502 | if (core_id == 1) { |
502 | struct power_domain pd; | 503 | struct power_domain pd; |
503 | 504 | ||
504 | if (sc_pm_clock_enable(ipcHndl, core_rsrc, SC_PM_CLK_PER, true, false) != SC_ERR_NONE) { | 505 | if (sc_pm_clock_enable(ipcHndl, core_rsrc, SC_PM_CLK_PER, true, false) != SC_ERR_NONE) { |
505 | printf("Error enable clock\n"); | 506 | printf("Error enable clock\n"); |
506 | return -EIO; | 507 | return -EIO; |
507 | } | 508 | } |
508 | 509 | ||
510 | LPCG_AllClockOn(AUD_DSP_LPCG); | ||
511 | |||
509 | if (!power_domain_lookup_name("audio_sai0", &pd)) { | 512 | if (!power_domain_lookup_name("audio_sai0", &pd)) { |
510 | if (power_domain_on(&pd)) { | 513 | if (power_domain_on(&pd)) { |
511 | printf("Error power on SAI0\n"); | 514 | printf("Error power on SAI0\n"); |
512 | return -EIO; | 515 | return -EIO; |
513 | } | 516 | } |
514 | } | 517 | } |
515 | 518 | ||
516 | if (!power_domain_lookup_name("audio_ocram", &pd)) { | 519 | if (!power_domain_lookup_name("audio_ocram", &pd)) { |
517 | if (power_domain_on(&pd)) { | 520 | if (power_domain_on(&pd)) { |
518 | printf("Error power on HIFI RAM\n"); | 521 | printf("Error power on HIFI RAM\n"); |
519 | return -EIO; | 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 | printf("Copy image from 0x%lx to 0x%lx\n", addr, (ulong)aux_core_ram); | 530 | printf("Copy image from 0x%lx to 0x%lx\n", addr, (ulong)aux_core_ram); |
525 | if (core_id == 0) { | 531 | if (core_id == 0) { |
526 | /* M4 use bin file */ | 532 | /* M4 use bin file */ |
527 | memcpy((void *)aux_core_ram, (void *)addr, size); | 533 | memcpy((void *)aux_core_ram, (void *)addr, size); |
528 | } else { | 534 | } else { |
529 | /* HIFI use elf file */ | 535 | /* HIFI use elf file */ |
530 | if (!valid_elf_image(addr)) | 536 | if (!valid_elf_image(addr)) |
531 | return -1; | 537 | return -1; |
532 | addr = load_elf_image_shdr(addr); | 538 | addr = load_elf_image_shdr(addr); |
533 | } | 539 | } |
534 | 540 | ||
535 | printf("Start %s\n", core_id == 0 ? "M4" : "HIFI"); | 541 | printf("Start %s\n", core_id == 0 ? "M4" : "HIFI"); |
536 | 542 | ||
537 | if (sc_pm_cpu_start(ipcHndl, core_rsrc, true, aux_core_ram) != SC_ERR_NONE) | 543 | if (sc_pm_cpu_start(ipcHndl, core_rsrc, true, aux_core_ram) != SC_ERR_NONE) |
538 | return -EIO; | 544 | return -EIO; |
539 | 545 | ||
540 | printf("bootaux complete\n"); | 546 | printf("bootaux complete\n"); |
541 | return 0; | 547 | return 0; |
542 | } | 548 | } |
543 | #endif | 549 | #endif |
544 | 550 | ||
545 | int arch_auxiliary_core_check_up(u32 core_id) | 551 | int arch_auxiliary_core_check_up(u32 core_id) |
546 | { | 552 | { |
547 | sc_rsrc_t core_rsrc; | 553 | sc_rsrc_t core_rsrc; |
548 | sc_pm_power_mode_t power_mode; | 554 | sc_pm_power_mode_t power_mode; |
549 | sc_ipc_t ipcHndl; | 555 | sc_ipc_t ipcHndl; |
550 | 556 | ||
551 | ipcHndl = gd->arch.ipc_channel_handle; | 557 | ipcHndl = gd->arch.ipc_channel_handle; |
552 | 558 | ||
553 | switch (core_id) { | 559 | switch (core_id) { |
554 | case 0: | 560 | case 0: |
555 | core_rsrc = SC_R_M4_0_PID0; | 561 | core_rsrc = SC_R_M4_0_PID0; |
556 | break; | 562 | break; |
557 | #ifdef CONFIG_IMX8QM | 563 | #ifdef CONFIG_IMX8QM |
558 | case 1: | 564 | case 1: |
559 | core_rsrc = SC_R_M4_1_PID0; | 565 | core_rsrc = SC_R_M4_1_PID0; |
560 | break; | 566 | break; |
561 | #endif | 567 | #endif |
562 | default: | 568 | default: |
563 | printf("Not support this core, ID:%u\n", core_id); | 569 | printf("Not support this core, ID:%u\n", core_id); |
564 | return 0; | 570 | return 0; |
565 | } | 571 | } |
566 | 572 | ||
567 | if (sc_pm_get_resource_power_mode(ipcHndl, core_rsrc, &power_mode) != SC_ERR_NONE) | 573 | if (sc_pm_get_resource_power_mode(ipcHndl, core_rsrc, &power_mode) != SC_ERR_NONE) |
568 | return 0; | 574 | return 0; |
569 | 575 | ||
570 | if (power_mode != SC_PM_PW_MODE_OFF) | 576 | if (power_mode != SC_PM_PW_MODE_OFF) |
571 | return 1; | 577 | return 1; |
572 | 578 | ||
573 | return 0; | 579 | return 0; |
574 | } | 580 | } |
575 | #endif | 581 | #endif |
576 | 582 | ||
577 | #ifdef CONFIG_IMX_SMMU | 583 | #ifdef CONFIG_IMX_SMMU |
578 | struct smmu_sid dev_sids[] = { | 584 | struct smmu_sid dev_sids[] = { |
579 | }; | 585 | }; |
580 | 586 | ||
581 | sc_err_t imx8_config_smmu_sid(struct smmu_sid *dev_sids, int size) | 587 | sc_err_t imx8_config_smmu_sid(struct smmu_sid *dev_sids, int size) |
582 | { | 588 | { |
583 | int i; | 589 | int i; |
584 | sc_err_t sciErr = SC_ERR_NONE; | 590 | sc_err_t sciErr = SC_ERR_NONE; |
585 | 591 | ||
586 | if ((dev_sids == NULL) || (size <= 0)) | 592 | if ((dev_sids == NULL) || (size <= 0)) |
587 | return SC_ERR_NONE; | 593 | return SC_ERR_NONE; |
588 | 594 | ||
589 | for (i = 0; i < size; i++) { | 595 | for (i = 0; i < size; i++) { |
590 | sciErr = sc_rm_set_master_sid(gd->arch.ipc_channel_handle, | 596 | sciErr = sc_rm_set_master_sid(gd->arch.ipc_channel_handle, |
591 | dev_sids[i].rsrc, | 597 | dev_sids[i].rsrc, |
592 | dev_sids[i].sid); | 598 | dev_sids[i].sid); |
593 | if (sciErr != SC_ERR_NONE) { | 599 | if (sciErr != SC_ERR_NONE) { |
594 | printf("set master sid error\n"); | 600 | printf("set master sid error\n"); |
595 | return sciErr; | 601 | return sciErr; |
596 | } | 602 | } |
597 | } | 603 | } |
598 | 604 | ||
599 | return SC_ERR_NONE; | 605 | return SC_ERR_NONE; |
600 | } | 606 | } |
601 | #endif | 607 | #endif |
602 | 608 | ||
603 | void arch_preboot_os(void) | 609 | void arch_preboot_os(void) |
604 | { | 610 | { |
605 | #if defined(CONFIG_VIDEO_IMXDPUV1) | 611 | #if defined(CONFIG_VIDEO_IMXDPUV1) |
606 | imxdpuv1_fb_disable(); | 612 | imxdpuv1_fb_disable(); |
607 | #endif | 613 | #endif |
608 | #ifdef CONFIG_IMX_SMMU | 614 | #ifdef CONFIG_IMX_SMMU |
609 | imx8_config_smmu_sid(dev_sids, ARRAY_SIZE(dev_sids)); | 615 | imx8_config_smmu_sid(dev_sids, ARRAY_SIZE(dev_sids)); |
610 | #endif | 616 | #endif |
611 | } | 617 | } |
612 | 618 | ||
613 | enum boot_device get_boot_device(void) | 619 | enum boot_device get_boot_device(void) |
614 | { | 620 | { |
615 | enum boot_device boot_dev = SD1_BOOT; | 621 | enum boot_device boot_dev = SD1_BOOT; |
616 | 622 | ||
617 | sc_ipc_t ipcHndl = 0; | 623 | sc_ipc_t ipcHndl = 0; |
618 | sc_rsrc_t dev_rsrc; | 624 | sc_rsrc_t dev_rsrc; |
619 | 625 | ||
620 | /* Note we only support android in EMMC SDHC0 */ | 626 | /* Note we only support android in EMMC SDHC0 */ |
621 | if (IS_ENABLED(CONFIG_XEN)) | 627 | if (IS_ENABLED(CONFIG_XEN)) |
622 | return MMC1_BOOT; | 628 | return MMC1_BOOT; |
623 | 629 | ||
624 | ipcHndl = gd->arch.ipc_channel_handle; | 630 | ipcHndl = gd->arch.ipc_channel_handle; |
625 | sc_misc_get_boot_dev(ipcHndl, &dev_rsrc); | 631 | sc_misc_get_boot_dev(ipcHndl, &dev_rsrc); |
626 | 632 | ||
627 | switch (dev_rsrc) { | 633 | switch (dev_rsrc) { |
628 | case SC_R_SDHC_0: | 634 | case SC_R_SDHC_0: |
629 | boot_dev = MMC1_BOOT; | 635 | boot_dev = MMC1_BOOT; |
630 | break; | 636 | break; |
631 | case SC_R_SDHC_1: | 637 | case SC_R_SDHC_1: |
632 | boot_dev = SD2_BOOT; | 638 | boot_dev = SD2_BOOT; |
633 | break; | 639 | break; |
634 | case SC_R_SDHC_2: | 640 | case SC_R_SDHC_2: |
635 | boot_dev = SD3_BOOT; | 641 | boot_dev = SD3_BOOT; |
636 | break; | 642 | break; |
637 | case SC_R_NAND: | 643 | case SC_R_NAND: |
638 | boot_dev = NAND_BOOT; | 644 | boot_dev = NAND_BOOT; |
639 | break; | 645 | break; |
640 | case SC_R_FSPI_0: | 646 | case SC_R_FSPI_0: |
641 | boot_dev = FLEXSPI_BOOT; | 647 | boot_dev = FLEXSPI_BOOT; |
642 | break; | 648 | break; |
643 | case SC_R_SATA_0: | 649 | case SC_R_SATA_0: |
644 | boot_dev = SATA_BOOT; | 650 | boot_dev = SATA_BOOT; |
645 | break; | 651 | break; |
646 | case SC_R_USB_0: | 652 | case SC_R_USB_0: |
647 | case SC_R_USB_1: | 653 | case SC_R_USB_1: |
648 | case SC_R_USB_2: | 654 | case SC_R_USB_2: |
649 | boot_dev = USB_BOOT; | 655 | boot_dev = USB_BOOT; |
650 | break; | 656 | break; |
651 | default: | 657 | default: |
652 | break; | 658 | break; |
653 | } | 659 | } |
654 | 660 | ||
655 | return boot_dev; | 661 | return boot_dev; |
656 | } | 662 | } |
657 | 663 | ||
658 | bool is_usb_boot(void) | 664 | bool is_usb_boot(void) |
659 | { | 665 | { |
660 | return get_boot_device() == USB_BOOT; | 666 | return get_boot_device() == USB_BOOT; |
661 | } | 667 | } |
662 | 668 | ||
663 | #if defined(CONFIG_ARCH_MISC_INIT) | 669 | #if defined(CONFIG_ARCH_MISC_INIT) |
664 | #define FSL_SIP_BUILDINFO 0xC2000003 | 670 | #define FSL_SIP_BUILDINFO 0xC2000003 |
665 | #define FSL_SIP_BUILDINFO_GET_COMMITHASH 0x00 | 671 | #define FSL_SIP_BUILDINFO_GET_COMMITHASH 0x00 |
666 | extern uint32_t _end_ofs; | 672 | extern uint32_t _end_ofs; |
667 | 673 | ||
668 | static void set_buildinfo_to_env(uint32_t scfw, uint32_t secofw, char *mkimage, char *atf) | 674 | static void set_buildinfo_to_env(uint32_t scfw, uint32_t secofw, char *mkimage, char *atf) |
669 | { | 675 | { |
670 | if (!mkimage || !atf) | 676 | if (!mkimage || !atf) |
671 | return; | 677 | return; |
672 | 678 | ||
673 | env_set("commit_mkimage", mkimage); | 679 | env_set("commit_mkimage", mkimage); |
674 | env_set("commit_atf", atf); | 680 | env_set("commit_atf", atf); |
675 | env_set_hex("commit_scfw", (ulong)scfw); | 681 | env_set_hex("commit_scfw", (ulong)scfw); |
676 | env_set_hex("commit_secofw", (ulong)secofw); | 682 | env_set_hex("commit_secofw", (ulong)secofw); |
677 | } | 683 | } |
678 | 684 | ||
679 | static void acquire_buildinfo(void) | 685 | static void acquire_buildinfo(void) |
680 | { | 686 | { |
681 | sc_ipc_t ipc; | 687 | sc_ipc_t ipc; |
682 | uint32_t sc_build = 0, sc_commit = 0; | 688 | uint32_t sc_build = 0, sc_commit = 0; |
683 | uint32_t seco_build = 0, seco_commit = 0; | 689 | uint32_t seco_build = 0, seco_commit = 0; |
684 | char *mkimage_commit, *temp; | 690 | char *mkimage_commit, *temp; |
685 | uint64_t atf_commit = 0; | 691 | uint64_t atf_commit = 0; |
686 | 692 | ||
687 | ipc = gd->arch.ipc_channel_handle; | 693 | ipc = gd->arch.ipc_channel_handle; |
688 | 694 | ||
689 | /* Get SCFW build and commit id */ | 695 | /* Get SCFW build and commit id */ |
690 | sc_misc_build_info(ipc, &sc_build, &sc_commit); | 696 | sc_misc_build_info(ipc, &sc_build, &sc_commit); |
691 | if (sc_build == 0) { | 697 | if (sc_build == 0) { |
692 | debug("SCFW does not support build info\n"); | 698 | debug("SCFW does not support build info\n"); |
693 | sc_commit = 0; /* Display 0 when the build info is not supported*/ | 699 | sc_commit = 0; /* Display 0 when the build info is not supported*/ |
694 | } | 700 | } |
695 | 701 | ||
696 | /* Get SECO FW build and commit id */ | 702 | /* Get SECO FW build and commit id */ |
697 | sc_misc_seco_build_info(ipc, &seco_build, &seco_commit); | 703 | sc_misc_seco_build_info(ipc, &seco_build, &seco_commit); |
698 | if (seco_build == 0) { | 704 | if (seco_build == 0) { |
699 | debug("SECO FW does not support build info\n"); | 705 | debug("SECO FW does not support build info\n"); |
700 | seco_commit = 0; /* Display 0 when the build info is not supported*/ | 706 | seco_commit = 0; /* Display 0 when the build info is not supported*/ |
701 | } | 707 | } |
702 | 708 | ||
703 | /* Get imx-mkimage commit id. | 709 | /* Get imx-mkimage commit id. |
704 | * The imx-mkimage puts the commit hash behind the end of u-boot.bin | 710 | * The imx-mkimage puts the commit hash behind the end of u-boot.bin |
705 | */ | 711 | */ |
706 | mkimage_commit = (char *)(ulong)(CONFIG_SYS_TEXT_BASE + _end_ofs + fdt_totalsize(gd->fdt_blob)); | 712 | mkimage_commit = (char *)(ulong)(CONFIG_SYS_TEXT_BASE + _end_ofs + fdt_totalsize(gd->fdt_blob)); |
707 | temp = mkimage_commit + 8; | 713 | temp = mkimage_commit + 8; |
708 | *temp = '\0'; | 714 | *temp = '\0'; |
709 | 715 | ||
710 | if (strlen(mkimage_commit) == 0) { | 716 | if (strlen(mkimage_commit) == 0) { |
711 | debug("IMX-MKIMAGE does not support build info\n"); | 717 | debug("IMX-MKIMAGE does not support build info\n"); |
712 | mkimage_commit = "0"; /* Display 0 */ | 718 | mkimage_commit = "0"; /* Display 0 */ |
713 | } | 719 | } |
714 | 720 | ||
715 | /* Get ARM Trusted Firmware commit id */ | 721 | /* Get ARM Trusted Firmware commit id */ |
716 | atf_commit = call_imx_sip(FSL_SIP_BUILDINFO, FSL_SIP_BUILDINFO_GET_COMMITHASH, 0, 0, 0); | 722 | atf_commit = call_imx_sip(FSL_SIP_BUILDINFO, FSL_SIP_BUILDINFO_GET_COMMITHASH, 0, 0, 0); |
717 | if (atf_commit == 0xffffffff) { | 723 | if (atf_commit == 0xffffffff) { |
718 | debug("ATF does not support build info\n"); | 724 | debug("ATF does not support build info\n"); |
719 | atf_commit = 0x30; /* Display 0, 0 ascii is 0x30 */ | 725 | atf_commit = 0x30; /* Display 0, 0 ascii is 0x30 */ |
720 | } | 726 | } |
721 | 727 | ||
722 | /* Set all to env */ | 728 | /* Set all to env */ |
723 | set_buildinfo_to_env(sc_commit, seco_commit, mkimage_commit, (char *)&atf_commit); | 729 | set_buildinfo_to_env(sc_commit, seco_commit, mkimage_commit, (char *)&atf_commit); |
724 | 730 | ||
725 | printf("\n BuildInfo: \n - SCFW %08x, SECO-FW %08x, IMX-MKIMAGE %s, ATF %s\n - %s \n\n", | 731 | printf("\n BuildInfo: \n - SCFW %08x, SECO-FW %08x, IMX-MKIMAGE %s, ATF %s\n - %s \n\n", |
726 | sc_commit, seco_commit, mkimage_commit, (char *)&atf_commit, U_BOOT_VERSION); | 732 | sc_commit, seco_commit, mkimage_commit, (char *)&atf_commit, U_BOOT_VERSION); |
727 | } | 733 | } |
728 | 734 | ||
729 | int arch_misc_init(void) | 735 | int arch_misc_init(void) |
730 | { | 736 | { |
731 | acquire_buildinfo(); | 737 | acquire_buildinfo(); |
732 | 738 | ||
733 | return 0; | 739 | return 0; |
734 | } | 740 | } |
735 | #endif | 741 | #endif |
736 | 742 | ||
737 | int print_bootinfo(void) | 743 | int print_bootinfo(void) |
738 | { | 744 | { |
739 | enum boot_device bt_dev; | 745 | enum boot_device bt_dev; |
740 | bt_dev = get_boot_device(); | 746 | bt_dev = get_boot_device(); |
741 | 747 | ||
742 | puts("Boot: "); | 748 | puts("Boot: "); |
743 | switch (bt_dev) { | 749 | switch (bt_dev) { |
744 | case SD1_BOOT: | 750 | case SD1_BOOT: |
745 | puts("SD0\n"); | 751 | puts("SD0\n"); |
746 | break; | 752 | break; |
747 | case SD2_BOOT: | 753 | case SD2_BOOT: |
748 | puts("SD1\n"); | 754 | puts("SD1\n"); |
749 | break; | 755 | break; |
750 | case SD3_BOOT: | 756 | case SD3_BOOT: |
751 | puts("SD2\n"); | 757 | puts("SD2\n"); |
752 | break; | 758 | break; |
753 | case MMC1_BOOT: | 759 | case MMC1_BOOT: |
754 | puts("MMC0\n"); | 760 | puts("MMC0\n"); |
755 | break; | 761 | break; |
756 | case MMC2_BOOT: | 762 | case MMC2_BOOT: |
757 | puts("MMC1\n"); | 763 | puts("MMC1\n"); |
758 | break; | 764 | break; |
759 | case MMC3_BOOT: | 765 | case MMC3_BOOT: |
760 | puts("MMC2\n"); | 766 | puts("MMC2\n"); |
761 | break; | 767 | break; |
762 | case FLEXSPI_BOOT: | 768 | case FLEXSPI_BOOT: |
763 | puts("FLEXSPI\n"); | 769 | puts("FLEXSPI\n"); |
764 | break; | 770 | break; |
765 | case SATA_BOOT: | 771 | case SATA_BOOT: |
766 | puts("SATA\n"); | 772 | puts("SATA\n"); |
767 | break; | 773 | break; |
768 | case NAND_BOOT: | 774 | case NAND_BOOT: |
769 | puts("NAND\n"); | 775 | puts("NAND\n"); |
770 | break; | 776 | break; |
771 | case USB_BOOT: | 777 | case USB_BOOT: |
772 | puts("USB\n"); | 778 | puts("USB\n"); |
773 | break; | 779 | break; |
774 | default: | 780 | default: |
775 | printf("Unknown device %u\n", bt_dev); | 781 | printf("Unknown device %u\n", bt_dev); |
776 | break; | 782 | break; |
777 | } | 783 | } |
778 | 784 | ||
779 | return 0; | 785 | return 0; |
780 | } | 786 | } |
781 | 787 | ||
782 | #ifdef CONFIG_SERIAL_TAG | 788 | #ifdef CONFIG_SERIAL_TAG |
783 | #define FUSE_UNIQUE_ID_WORD0 16 | 789 | #define FUSE_UNIQUE_ID_WORD0 16 |
784 | #define FUSE_UNIQUE_ID_WORD1 17 | 790 | #define FUSE_UNIQUE_ID_WORD1 17 |
785 | void get_board_serial(struct tag_serialnr *serialnr) | 791 | void get_board_serial(struct tag_serialnr *serialnr) |
786 | { | 792 | { |
787 | sc_err_t err; | 793 | sc_err_t err; |
788 | sc_ipc_t ipc; | 794 | sc_ipc_t ipc; |
789 | uint32_t val1 = 0, val2 = 0; | 795 | uint32_t val1 = 0, val2 = 0; |
790 | uint32_t word1, word2; | 796 | uint32_t word1, word2; |
791 | 797 | ||
792 | ipc = gd->arch.ipc_channel_handle; | 798 | ipc = gd->arch.ipc_channel_handle; |
793 | 799 | ||
794 | word1 = FUSE_UNIQUE_ID_WORD0; | 800 | word1 = FUSE_UNIQUE_ID_WORD0; |
795 | word2 = FUSE_UNIQUE_ID_WORD1; | 801 | word2 = FUSE_UNIQUE_ID_WORD1; |
796 | 802 | ||
797 | err = sc_misc_otp_fuse_read(ipc, word1, &val1); | 803 | err = sc_misc_otp_fuse_read(ipc, word1, &val1); |
798 | if (err != SC_ERR_NONE) { | 804 | if (err != SC_ERR_NONE) { |
799 | printf("%s fuse %d read error: %d\n", __func__,word1, err); | 805 | printf("%s fuse %d read error: %d\n", __func__,word1, err); |
800 | return; | 806 | return; |
801 | } | 807 | } |
802 | 808 | ||
803 | err = sc_misc_otp_fuse_read(ipc, word2, &val2); | 809 | err = sc_misc_otp_fuse_read(ipc, word2, &val2); |
804 | if (err != SC_ERR_NONE) { | 810 | if (err != SC_ERR_NONE) { |
805 | printf("%s fuse %d read error: %d\n", __func__, word2, err); | 811 | printf("%s fuse %d read error: %d\n", __func__, word2, err); |
806 | return; | 812 | return; |
807 | } | 813 | } |
808 | serialnr->low = val1; | 814 | serialnr->low = val1; |
809 | serialnr->high = val2; | 815 | serialnr->high = val2; |
810 | } | 816 | } |
811 | #endif /*CONFIG_SERIAL_TAG*/ | 817 | #endif /*CONFIG_SERIAL_TAG*/ |
812 | 818 | ||
813 | __weak int board_mmc_get_env_dev(int devno) | 819 | __weak int board_mmc_get_env_dev(int devno) |
814 | { | 820 | { |
815 | return CONFIG_SYS_MMC_ENV_DEV; | 821 | return CONFIG_SYS_MMC_ENV_DEV; |
816 | } | 822 | } |
817 | 823 | ||
818 | int mmc_get_env_dev(void) | 824 | int mmc_get_env_dev(void) |
819 | { | 825 | { |
820 | sc_ipc_t ipcHndl = 0; | 826 | sc_ipc_t ipcHndl = 0; |
821 | sc_rsrc_t dev_rsrc; | 827 | sc_rsrc_t dev_rsrc; |
822 | int devno; | 828 | int devno; |
823 | 829 | ||
824 | ipcHndl = gd->arch.ipc_channel_handle; | 830 | ipcHndl = gd->arch.ipc_channel_handle; |
825 | sc_misc_get_boot_dev(ipcHndl, &dev_rsrc); | 831 | sc_misc_get_boot_dev(ipcHndl, &dev_rsrc); |
826 | 832 | ||
827 | switch(dev_rsrc) { | 833 | switch(dev_rsrc) { |
828 | case SC_R_SDHC_0: | 834 | case SC_R_SDHC_0: |
829 | devno = 0; | 835 | devno = 0; |
830 | break; | 836 | break; |
831 | case SC_R_SDHC_1: | 837 | case SC_R_SDHC_1: |
832 | devno = 1; | 838 | devno = 1; |
833 | break; | 839 | break; |
834 | case SC_R_SDHC_2: | 840 | case SC_R_SDHC_2: |
835 | devno = 2; | 841 | devno = 2; |
836 | break; | 842 | break; |
837 | default: | 843 | default: |
838 | /* If not boot from sd/mmc, use default value */ | 844 | /* If not boot from sd/mmc, use default value */ |
839 | return env_get_ulong("mmcdev", 10, CONFIG_SYS_MMC_ENV_DEV); | 845 | return env_get_ulong("mmcdev", 10, CONFIG_SYS_MMC_ENV_DEV); |
840 | } | 846 | } |
841 | 847 | ||
842 | return board_mmc_get_env_dev(devno); | 848 | return board_mmc_get_env_dev(devno); |
843 | } | 849 | } |
844 | 850 | ||
845 | static bool check_owned_resource(sc_rsrc_t rsrc_id) | 851 | static bool check_owned_resource(sc_rsrc_t rsrc_id) |
846 | { | 852 | { |
847 | sc_ipc_t ipcHndl = 0; | 853 | sc_ipc_t ipcHndl = 0; |
848 | bool owned; | 854 | bool owned; |
849 | 855 | ||
850 | ipcHndl = gd->arch.ipc_channel_handle; | 856 | ipcHndl = gd->arch.ipc_channel_handle; |
851 | 857 | ||
852 | owned = sc_rm_is_resource_owned(ipcHndl, rsrc_id); | 858 | owned = sc_rm_is_resource_owned(ipcHndl, rsrc_id); |
853 | 859 | ||
854 | return owned; | 860 | return owned; |
855 | } | 861 | } |
856 | 862 | ||
857 | static int disable_fdt_node(void *blob, int nodeoffset) | 863 | static int disable_fdt_node(void *blob, int nodeoffset) |
858 | { | 864 | { |
859 | int rc, ret; | 865 | int rc, ret; |
860 | const char *status = "disabled"; | 866 | const char *status = "disabled"; |
861 | 867 | ||
862 | do { | 868 | do { |
863 | rc = fdt_setprop(blob, nodeoffset, "status", status, strlen(status) + 1); | 869 | rc = fdt_setprop(blob, nodeoffset, "status", status, strlen(status) + 1); |
864 | if (rc) { | 870 | if (rc) { |
865 | if (rc == -FDT_ERR_NOSPACE) { | 871 | if (rc == -FDT_ERR_NOSPACE) { |
866 | ret = fdt_increase_size(blob, 512); | 872 | ret = fdt_increase_size(blob, 512); |
867 | if (ret) | 873 | if (ret) |
868 | return ret; | 874 | return ret; |
869 | } | 875 | } |
870 | } | 876 | } |
871 | } while (rc == -FDT_ERR_NOSPACE); | 877 | } while (rc == -FDT_ERR_NOSPACE); |
872 | 878 | ||
873 | return rc; | 879 | return rc; |
874 | } | 880 | } |
875 | 881 | ||
876 | static void fdt_edma_debug_int_array(u32 *array, int count, u32 stride) | 882 | static void fdt_edma_debug_int_array(u32 *array, int count, u32 stride) |
877 | { | 883 | { |
878 | #ifdef DEBUG | 884 | #ifdef DEBUG |
879 | int i; | 885 | int i; |
880 | for (i = 0; i < count; i++) { | 886 | for (i = 0; i < count; i++) { |
881 | printf("0x%x ", array[i]); | 887 | printf("0x%x ", array[i]); |
882 | if (i % stride == stride - 1) | 888 | if (i % stride == stride - 1) |
883 | printf("\n"); | 889 | printf("\n"); |
884 | } | 890 | } |
885 | 891 | ||
886 | printf("\n"); | 892 | printf("\n"); |
887 | #endif | 893 | #endif |
888 | } | 894 | } |
889 | 895 | ||
890 | static void fdt_edma_debug_stringlist(const char *stringlist, int length) | 896 | static void fdt_edma_debug_stringlist(const char *stringlist, int length) |
891 | { | 897 | { |
892 | #ifdef DEBUG | 898 | #ifdef DEBUG |
893 | int i = 0, len; | 899 | int i = 0, len; |
894 | while (i < length) { | 900 | while (i < length) { |
895 | printf("%s\n", stringlist); | 901 | printf("%s\n", stringlist); |
896 | 902 | ||
897 | len = strlen(stringlist) + 1; | 903 | len = strlen(stringlist) + 1; |
898 | i += len; | 904 | i += len; |
899 | stringlist += len; | 905 | stringlist += len; |
900 | } | 906 | } |
901 | 907 | ||
902 | printf("\n"); | 908 | printf("\n"); |
903 | #endif | 909 | #endif |
904 | } | 910 | } |
905 | 911 | ||
906 | static void fdt_edma_swap_int_array(u32 *array, int count) | 912 | static void fdt_edma_swap_int_array(u32 *array, int count) |
907 | { | 913 | { |
908 | int i; | 914 | int i; |
909 | for (i = 0; i < count; i++) { | 915 | for (i = 0; i < count; i++) { |
910 | array[i] = cpu_to_fdt32(array[i]); | 916 | array[i] = cpu_to_fdt32(array[i]); |
911 | } | 917 | } |
912 | } | 918 | } |
913 | 919 | ||
914 | static int fdt_edma_update_int_array(u32 *array, int count, u32 *new_array, u32 stride, int *remove_array, int remove_count) | 920 | static int fdt_edma_update_int_array(u32 *array, int count, u32 *new_array, u32 stride, int *remove_array, int remove_count) |
915 | { | 921 | { |
916 | int i = 0, j, curr = 0, new_cnt = 0; | 922 | int i = 0, j, curr = 0, new_cnt = 0; |
917 | 923 | ||
918 | do { | 924 | do { |
919 | if (remove_count && curr == remove_array[i]) { | 925 | if (remove_count && curr == remove_array[i]) { |
920 | i++; | 926 | i++; |
921 | remove_count--; | 927 | remove_count--; |
922 | array += stride; | 928 | array += stride; |
923 | } else { | 929 | } else { |
924 | for (j = 0; j< stride; j++) { | 930 | for (j = 0; j< stride; j++) { |
925 | *new_array = *array; | 931 | *new_array = *array; |
926 | new_array++; | 932 | new_array++; |
927 | array++; | 933 | array++; |
928 | } | 934 | } |
929 | new_cnt+= j; | 935 | new_cnt+= j; |
930 | } | 936 | } |
931 | curr++; | 937 | curr++; |
932 | } while ((curr * stride) < count); | 938 | } while ((curr * stride) < count); |
933 | 939 | ||
934 | return new_cnt; | 940 | return new_cnt; |
935 | } | 941 | } |
936 | 942 | ||
937 | static int fdt_edma_update_stringlist(const char *stringlist, int stringlist_count, char *newlist, int *remove_array, int remove_count) | 943 | static int fdt_edma_update_stringlist(const char *stringlist, int stringlist_count, char *newlist, int *remove_array, int remove_count) |
938 | { | 944 | { |
939 | int i = 0, curr = 0, new_len = 0; | 945 | int i = 0, curr = 0, new_len = 0; |
940 | int length; | 946 | int length; |
941 | 947 | ||
942 | debug("fdt_edma_update_stringlist, remove_cnt %d\n", remove_count); | 948 | debug("fdt_edma_update_stringlist, remove_cnt %d\n", remove_count); |
943 | 949 | ||
944 | do { | 950 | do { |
945 | if (remove_count && curr == remove_array[i]) { | 951 | if (remove_count && curr == remove_array[i]) { |
946 | debug("remove %s at %d\n", stringlist, remove_array[i]); | 952 | debug("remove %s at %d\n", stringlist, remove_array[i]); |
947 | 953 | ||
948 | length = strlen(stringlist) + 1; | 954 | length = strlen(stringlist) + 1; |
949 | stringlist += length; | 955 | stringlist += length; |
950 | i++; | 956 | i++; |
951 | remove_count--; | 957 | remove_count--; |
952 | } else { | 958 | } else { |
953 | length = strlen(stringlist) + 1; | 959 | length = strlen(stringlist) + 1; |
954 | strcpy(newlist, stringlist); | 960 | strcpy(newlist, stringlist); |
955 | 961 | ||
956 | debug("copy %s, %s, curr %d, len %d\n", newlist, stringlist, curr, length); | 962 | debug("copy %s, %s, curr %d, len %d\n", newlist, stringlist, curr, length); |
957 | 963 | ||
958 | stringlist += length; | 964 | stringlist += length; |
959 | newlist += length; | 965 | newlist += length; |
960 | new_len += length; | 966 | new_len += length; |
961 | } | 967 | } |
962 | curr++; | 968 | curr++; |
963 | } while (curr < stringlist_count); | 969 | } while (curr < stringlist_count); |
964 | 970 | ||
965 | return new_len; | 971 | return new_len; |
966 | } | 972 | } |
967 | 973 | ||
968 | static int fdt_edma_get_channel_id(u32 *regs, int index, struct edma_ch_map *edma) | 974 | static int fdt_edma_get_channel_id(u32 *regs, int index, struct edma_ch_map *edma) |
969 | { | 975 | { |
970 | u32 ch_reg = regs[(index << 2) + 1]; | 976 | u32 ch_reg = regs[(index << 2) + 1]; |
971 | u32 ch_reg_size = regs[(index << 2) + 3]; | 977 | u32 ch_reg_size = regs[(index << 2) + 3]; |
972 | int ch_id = (ch_reg - edma->ch_start_regs) / ch_reg_size; | 978 | int ch_id = (ch_reg - edma->ch_start_regs) / ch_reg_size; |
973 | if (ch_id >= edma->ch_num) | 979 | if (ch_id >= edma->ch_num) |
974 | return -1; | 980 | return -1; |
975 | 981 | ||
976 | return ch_id; | 982 | return ch_id; |
977 | } | 983 | } |
978 | 984 | ||
979 | static void update_fdt_edma_nodes(void *blob) | 985 | static void update_fdt_edma_nodes(void *blob) |
980 | { | 986 | { |
981 | struct edma_ch_map edma_qm[] = { | 987 | struct edma_ch_map edma_qm[] = { |
982 | { SC_R_DMA_0_CH0, 0x5a200000, 32, "/dma-controller@5a1f0000"}, | 988 | { SC_R_DMA_0_CH0, 0x5a200000, 32, "/dma-controller@5a1f0000"}, |
983 | { SC_R_DMA_1_CH0, 0x5aa00000, 32, "/dma-controller@5a9f0000"}, | 989 | { SC_R_DMA_1_CH0, 0x5aa00000, 32, "/dma-controller@5a9f0000"}, |
984 | { SC_R_DMA_2_CH0, 0x59200000, 5, "/dma-controller@591F0000"}, | 990 | { SC_R_DMA_2_CH0, 0x59200000, 5, "/dma-controller@591F0000"}, |
985 | { SC_R_DMA_2_CH5, 0x59250000, 27, "/dma-controller@591F0000"}, | 991 | { SC_R_DMA_2_CH5, 0x59250000, 27, "/dma-controller@591F0000"}, |
986 | { SC_R_DMA_3_CH0, 0x59a00000, 32, "/dma-controller@599F0000"}, | 992 | { SC_R_DMA_3_CH0, 0x59a00000, 32, "/dma-controller@599F0000"}, |
987 | }; | 993 | }; |
988 | 994 | ||
989 | struct edma_ch_map edma_qxp[] = { | 995 | struct edma_ch_map edma_qxp[] = { |
990 | { SC_R_DMA_0_CH0, 0x59200000, 32, "/dma-controller@591F0000"}, | 996 | { SC_R_DMA_0_CH0, 0x59200000, 32, "/dma-controller@591F0000"}, |
991 | { SC_R_DMA_1_CH0, 0x59a00000, 32, "/dma-controller@599F0000"}, | 997 | { SC_R_DMA_1_CH0, 0x59a00000, 32, "/dma-controller@599F0000"}, |
992 | { SC_R_DMA_2_CH0, 0x5a200000, 5, "/dma-controller@5a1f0000"}, | 998 | { SC_R_DMA_2_CH0, 0x5a200000, 5, "/dma-controller@5a1f0000"}, |
993 | { SC_R_DMA_2_CH5, 0x5a250000, 27, "/dma-controller@5a1f0000"}, | 999 | { SC_R_DMA_2_CH5, 0x5a250000, 27, "/dma-controller@5a1f0000"}, |
994 | { SC_R_DMA_3_CH0, 0x5aa00000, 32, "/dma-controller@5a9f0000"}, | 1000 | { SC_R_DMA_3_CH0, 0x5aa00000, 32, "/dma-controller@5a9f0000"}, |
995 | }; | 1001 | }; |
996 | 1002 | ||
997 | u32 i, j, edma_size; | 1003 | u32 i, j, edma_size; |
998 | int nodeoff, ret; | 1004 | int nodeoff, ret; |
999 | struct edma_ch_map *edma_array; | 1005 | struct edma_ch_map *edma_array; |
1000 | 1006 | ||
1001 | if (is_imx8qm()) { | 1007 | if (is_imx8qm()) { |
1002 | edma_array = edma_qm; | 1008 | edma_array = edma_qm; |
1003 | edma_size = ARRAY_SIZE(edma_qm); | 1009 | edma_size = ARRAY_SIZE(edma_qm); |
1004 | } else { | 1010 | } else { |
1005 | edma_array = edma_qxp; | 1011 | edma_array = edma_qxp; |
1006 | edma_size = ARRAY_SIZE(edma_qxp); | 1012 | edma_size = ARRAY_SIZE(edma_qxp); |
1007 | } | 1013 | } |
1008 | 1014 | ||
1009 | for (i = 0; i < edma_size; i++, edma_array++) { | 1015 | for (i = 0; i < edma_size; i++, edma_array++) { |
1010 | u32 regs[128]; | 1016 | u32 regs[128]; |
1011 | u32 interrupts[96]; | 1017 | u32 interrupts[96]; |
1012 | u32 dma_channels; | 1018 | u32 dma_channels; |
1013 | int regs_count, interrupts_count, int_names_count; | 1019 | int regs_count, interrupts_count, int_names_count; |
1014 | 1020 | ||
1015 | const char *list; | 1021 | const char *list; |
1016 | int list_len, newlist_len; | 1022 | int list_len, newlist_len; |
1017 | int remove[32]; | 1023 | int remove[32]; |
1018 | int remove_cnt = 0; | 1024 | int remove_cnt = 0; |
1019 | char * newlist; | 1025 | char * newlist; |
1020 | 1026 | ||
1021 | nodeoff = fdt_path_offset(blob, edma_array->node_path); | 1027 | nodeoff = fdt_path_offset(blob, edma_array->node_path); |
1022 | if (nodeoff < 0) | 1028 | if (nodeoff < 0) |
1023 | continue; /* Not found, skip it */ | 1029 | continue; /* Not found, skip it */ |
1024 | 1030 | ||
1025 | printf("%s, %d\n", edma_array->node_path, nodeoff); | 1031 | printf("%s, %d\n", edma_array->node_path, nodeoff); |
1026 | 1032 | ||
1027 | regs_count = fdtdec_get_int_array_count(blob, nodeoff, "reg", regs, 128); | 1033 | regs_count = fdtdec_get_int_array_count(blob, nodeoff, "reg", regs, 128); |
1028 | debug("regs_count %d\n", regs_count); | 1034 | debug("regs_count %d\n", regs_count); |
1029 | if (regs_count < 0) | 1035 | if (regs_count < 0) |
1030 | continue; | 1036 | continue; |
1031 | 1037 | ||
1032 | interrupts_count = fdtdec_get_int_array_count(blob, nodeoff, "interrupts", interrupts, 96); | 1038 | interrupts_count = fdtdec_get_int_array_count(blob, nodeoff, "interrupts", interrupts, 96); |
1033 | debug("interrupts_count %d\n", interrupts_count); | 1039 | debug("interrupts_count %d\n", interrupts_count); |
1034 | if (interrupts_count < 0) | 1040 | if (interrupts_count < 0) |
1035 | continue; | 1041 | continue; |
1036 | 1042 | ||
1037 | dma_channels = fdtdec_get_uint(blob, nodeoff, "dma-channels", 0); | 1043 | dma_channels = fdtdec_get_uint(blob, nodeoff, "dma-channels", 0); |
1038 | if (dma_channels == 0) | 1044 | if (dma_channels == 0) |
1039 | continue; | 1045 | continue; |
1040 | 1046 | ||
1041 | list = fdt_getprop(blob, nodeoff, "interrupt-names", &list_len); | 1047 | list = fdt_getprop(blob, nodeoff, "interrupt-names", &list_len); |
1042 | if (!list) | 1048 | if (!list) |
1043 | continue; | 1049 | continue; |
1044 | 1050 | ||
1045 | int_names_count = fdt_stringlist_count(blob, nodeoff, "interrupt-names"); | 1051 | int_names_count = fdt_stringlist_count(blob, nodeoff, "interrupt-names"); |
1046 | 1052 | ||
1047 | fdt_edma_debug_int_array(regs, regs_count, 4); | 1053 | fdt_edma_debug_int_array(regs, regs_count, 4); |
1048 | fdt_edma_debug_int_array(interrupts, interrupts_count, 3); | 1054 | fdt_edma_debug_int_array(interrupts, interrupts_count, 3); |
1049 | fdt_edma_debug_stringlist(list, list_len); | 1055 | fdt_edma_debug_stringlist(list, list_len); |
1050 | 1056 | ||
1051 | for (j = 0; j < (regs_count >> 2); j++) { | 1057 | for (j = 0; j < (regs_count >> 2); j++) { |
1052 | int ch_id = fdt_edma_get_channel_id(regs, j, edma_array); | 1058 | int ch_id = fdt_edma_get_channel_id(regs, j, edma_array); |
1053 | if (ch_id < 0) | 1059 | if (ch_id < 0) |
1054 | continue; | 1060 | continue; |
1055 | 1061 | ||
1056 | if (!check_owned_resource(edma_array->ch_start_rsrc + ch_id)) { | 1062 | if (!check_owned_resource(edma_array->ch_start_rsrc + ch_id)) { |
1057 | printf("remove edma items %d\n", j); | 1063 | printf("remove edma items %d\n", j); |
1058 | 1064 | ||
1059 | dma_channels--; | 1065 | dma_channels--; |
1060 | 1066 | ||
1061 | remove[remove_cnt] = j; | 1067 | remove[remove_cnt] = j; |
1062 | remove_cnt++; | 1068 | remove_cnt++; |
1063 | } | 1069 | } |
1064 | } | 1070 | } |
1065 | 1071 | ||
1066 | if (remove_cnt > 0) { | 1072 | if (remove_cnt > 0) { |
1067 | u32 new_regs[128]; | 1073 | u32 new_regs[128]; |
1068 | u32 new_interrupts[96]; | 1074 | u32 new_interrupts[96]; |
1069 | 1075 | ||
1070 | regs_count = fdt_edma_update_int_array(regs, regs_count, new_regs, 4, remove, remove_cnt); | 1076 | regs_count = fdt_edma_update_int_array(regs, regs_count, new_regs, 4, remove, remove_cnt); |
1071 | interrupts_count = fdt_edma_update_int_array(interrupts, interrupts_count, new_interrupts, 3, remove, remove_cnt); | 1077 | interrupts_count = fdt_edma_update_int_array(interrupts, interrupts_count, new_interrupts, 3, remove, remove_cnt); |
1072 | 1078 | ||
1073 | fdt_edma_debug_int_array(new_regs, regs_count, 4); | 1079 | fdt_edma_debug_int_array(new_regs, regs_count, 4); |
1074 | fdt_edma_debug_int_array(new_interrupts, interrupts_count, 3); | 1080 | fdt_edma_debug_int_array(new_interrupts, interrupts_count, 3); |
1075 | 1081 | ||
1076 | fdt_edma_swap_int_array(new_regs, regs_count); | 1082 | fdt_edma_swap_int_array(new_regs, regs_count); |
1077 | fdt_edma_swap_int_array(new_interrupts, interrupts_count); | 1083 | fdt_edma_swap_int_array(new_interrupts, interrupts_count); |
1078 | 1084 | ||
1079 | /* malloc a new string list */ | 1085 | /* malloc a new string list */ |
1080 | newlist = (char *)malloc(list_len); | 1086 | newlist = (char *)malloc(list_len); |
1081 | if (!newlist) { | 1087 | if (!newlist) { |
1082 | printf("malloc new string list failed, len=%d\n", list_len); | 1088 | printf("malloc new string list failed, len=%d\n", list_len); |
1083 | continue; | 1089 | continue; |
1084 | } | 1090 | } |
1085 | 1091 | ||
1086 | newlist_len = fdt_edma_update_stringlist(list, int_names_count, newlist, remove, remove_cnt); | 1092 | newlist_len = fdt_edma_update_stringlist(list, int_names_count, newlist, remove, remove_cnt); |
1087 | fdt_edma_debug_stringlist(newlist, newlist_len); | 1093 | fdt_edma_debug_stringlist(newlist, newlist_len); |
1088 | 1094 | ||
1089 | ret = fdt_setprop(blob, nodeoff, "reg", new_regs, regs_count * sizeof(u32)); | 1095 | ret = fdt_setprop(blob, nodeoff, "reg", new_regs, regs_count * sizeof(u32)); |
1090 | if (ret) | 1096 | if (ret) |
1091 | printf("fdt_setprop regs error %d\n", ret); | 1097 | printf("fdt_setprop regs error %d\n", ret); |
1092 | 1098 | ||
1093 | ret = fdt_setprop(blob, nodeoff, "interrupts", new_interrupts, interrupts_count * sizeof(u32)); | 1099 | ret = fdt_setprop(blob, nodeoff, "interrupts", new_interrupts, interrupts_count * sizeof(u32)); |
1094 | if (ret) | 1100 | if (ret) |
1095 | printf("fdt_setprop interrupts error %d\n", ret); | 1101 | printf("fdt_setprop interrupts error %d\n", ret); |
1096 | 1102 | ||
1097 | ret = fdt_setprop_u32(blob, nodeoff, "dma-channels", dma_channels); | 1103 | ret = fdt_setprop_u32(blob, nodeoff, "dma-channels", dma_channels); |
1098 | if (ret) | 1104 | if (ret) |
1099 | printf("fdt_setprop_u32 dma-channels error %d\n", ret); | 1105 | printf("fdt_setprop_u32 dma-channels error %d\n", ret); |
1100 | 1106 | ||
1101 | ret = fdt_setprop(blob, nodeoff, "interrupt-names", newlist, newlist_len); | 1107 | ret = fdt_setprop(blob, nodeoff, "interrupt-names", newlist, newlist_len); |
1102 | if (ret) | 1108 | if (ret) |
1103 | printf("fdt_setprop interrupt-names error %d\n", ret); | 1109 | printf("fdt_setprop interrupt-names error %d\n", ret); |
1104 | 1110 | ||
1105 | free(newlist); | 1111 | free(newlist); |
1106 | } | 1112 | } |
1107 | } | 1113 | } |
1108 | } | 1114 | } |
1109 | 1115 | ||
1110 | static void update_fdt_with_owned_resources(void *blob) | 1116 | static void update_fdt_with_owned_resources(void *blob) |
1111 | { | 1117 | { |
1112 | /* Traverses the fdt nodes, | 1118 | /* Traverses the fdt nodes, |
1113 | * check its power domain and use the resource id in the power domain | 1119 | * check its power domain and use the resource id in the power domain |
1114 | * for checking whether it is owned by current partition | 1120 | * for checking whether it is owned by current partition |
1115 | */ | 1121 | */ |
1116 | 1122 | ||
1117 | int offset = 0, next_off, addr; | 1123 | int offset = 0, next_off, addr; |
1118 | int depth, next_depth; | 1124 | int depth, next_depth; |
1119 | unsigned int rsrc_id; | 1125 | unsigned int rsrc_id; |
1120 | const fdt32_t *php; | 1126 | const fdt32_t *php; |
1121 | const char *name; | 1127 | const char *name; |
1122 | int rc; | 1128 | int rc; |
1123 | 1129 | ||
1124 | for (offset = fdt_next_node(blob, offset, &depth); offset > 0; | 1130 | for (offset = fdt_next_node(blob, offset, &depth); offset > 0; |
1125 | offset = fdt_next_node(blob, offset, &depth)) { | 1131 | offset = fdt_next_node(blob, offset, &depth)) { |
1126 | 1132 | ||
1127 | debug("Node name: %s, depth %d\n", fdt_get_name(blob, offset, NULL), depth); | 1133 | debug("Node name: %s, depth %d\n", fdt_get_name(blob, offset, NULL), depth); |
1128 | 1134 | ||
1129 | if (!fdtdec_get_is_enabled(blob, offset)) { | 1135 | if (!fdtdec_get_is_enabled(blob, offset)) { |
1130 | debug(" - ignoring disabled device\n"); | 1136 | debug(" - ignoring disabled device\n"); |
1131 | continue; | 1137 | continue; |
1132 | } | 1138 | } |
1133 | 1139 | ||
1134 | if (!fdt_node_check_compatible(blob, offset, "nxp,imx8-pd")) { | 1140 | if (!fdt_node_check_compatible(blob, offset, "nxp,imx8-pd")) { |
1135 | /* Skip to next depth=1 node*/ | 1141 | /* Skip to next depth=1 node*/ |
1136 | next_off = offset; | 1142 | next_off = offset; |
1137 | next_depth = depth; | 1143 | next_depth = depth; |
1138 | do { | 1144 | do { |
1139 | offset = next_off; | 1145 | offset = next_off; |
1140 | depth = next_depth; | 1146 | depth = next_depth; |
1141 | next_off = fdt_next_node(blob, offset, &next_depth); | 1147 | next_off = fdt_next_node(blob, offset, &next_depth); |
1142 | if (next_off < 0 || next_depth < 1) | 1148 | if (next_off < 0 || next_depth < 1) |
1143 | break; | 1149 | break; |
1144 | 1150 | ||
1145 | debug("PD name: %s, offset %d, depth %d\n", | 1151 | debug("PD name: %s, offset %d, depth %d\n", |
1146 | fdt_get_name(blob, next_off, NULL), next_off, next_depth); | 1152 | fdt_get_name(blob, next_off, NULL), next_off, next_depth); |
1147 | } while (next_depth > 1); | 1153 | } while (next_depth > 1); |
1148 | 1154 | ||
1149 | continue; | 1155 | continue; |
1150 | } | 1156 | } |
1151 | 1157 | ||
1152 | php = fdt_getprop(blob, offset, "power-domains", NULL); | 1158 | php = fdt_getprop(blob, offset, "power-domains", NULL); |
1153 | if (!php) { | 1159 | if (!php) { |
1154 | debug(" - ignoring no power-domains\n"); | 1160 | debug(" - ignoring no power-domains\n"); |
1155 | } else { | 1161 | } else { |
1156 | addr = fdt_node_offset_by_phandle(blob, fdt32_to_cpu(*php)); | 1162 | addr = fdt_node_offset_by_phandle(blob, fdt32_to_cpu(*php)); |
1157 | rsrc_id = fdtdec_get_uint(blob, addr, "reg", 0); | 1163 | rsrc_id = fdtdec_get_uint(blob, addr, "reg", 0); |
1158 | 1164 | ||
1159 | if (rsrc_id == SC_R_LAST) { | 1165 | if (rsrc_id == SC_R_LAST) { |
1160 | name = fdt_get_name(blob, offset, NULL); | 1166 | name = fdt_get_name(blob, offset, NULL); |
1161 | printf("%s's power domain use SC_R_LAST\n", name); | 1167 | printf("%s's power domain use SC_R_LAST\n", name); |
1162 | continue; | 1168 | continue; |
1163 | } | 1169 | } |
1164 | 1170 | ||
1165 | debug("power-domains phandle 0x%x, addr 0x%x, resource id %u\n", | 1171 | debug("power-domains phandle 0x%x, addr 0x%x, resource id %u\n", |
1166 | fdt32_to_cpu(*php), addr, rsrc_id); | 1172 | fdt32_to_cpu(*php), addr, rsrc_id); |
1167 | 1173 | ||
1168 | if (!check_owned_resource(rsrc_id)) { | 1174 | if (!check_owned_resource(rsrc_id)) { |
1169 | 1175 | ||
1170 | /* If the resource is not owned, disable it in FDT */ | 1176 | /* If the resource is not owned, disable it in FDT */ |
1171 | rc = disable_fdt_node(blob, offset); | 1177 | rc = disable_fdt_node(blob, offset); |
1172 | if (!rc) | 1178 | if (!rc) |
1173 | printf("Disable %s, resource id %u, pd phandle 0x%x\n", | 1179 | printf("Disable %s, resource id %u, pd phandle 0x%x\n", |
1174 | fdt_get_name(blob, offset, NULL), rsrc_id, fdt32_to_cpu(*php)); | 1180 | fdt_get_name(blob, offset, NULL), rsrc_id, fdt32_to_cpu(*php)); |
1175 | else | 1181 | else |
1176 | printf("Unable to disable %s, err=%s\n", | 1182 | printf("Unable to disable %s, err=%s\n", |
1177 | fdt_get_name(blob, offset, NULL), fdt_strerror(rc)); | 1183 | fdt_get_name(blob, offset, NULL), fdt_strerror(rc)); |
1178 | } | 1184 | } |
1179 | } | 1185 | } |
1180 | } | 1186 | } |
1181 | } | 1187 | } |
1182 | 1188 | ||
1183 | #ifdef CONFIG_IMX_SMMU | 1189 | #ifdef CONFIG_IMX_SMMU |
1184 | static int get_srsc_from_fdt_node_power_domain(void *blob, int device_offset) | 1190 | static int get_srsc_from_fdt_node_power_domain(void *blob, int device_offset) |
1185 | { | 1191 | { |
1186 | const fdt32_t *prop; | 1192 | const fdt32_t *prop; |
1187 | int pdnode_offset; | 1193 | int pdnode_offset; |
1188 | 1194 | ||
1189 | prop = fdt_getprop(blob, device_offset, "power-domains", NULL); | 1195 | prop = fdt_getprop(blob, device_offset, "power-domains", NULL); |
1190 | if (!prop) { | 1196 | if (!prop) { |
1191 | debug("node %s has no power-domains\n", | 1197 | debug("node %s has no power-domains\n", |
1192 | fdt_get_name(blob, device_offset, NULL)); | 1198 | fdt_get_name(blob, device_offset, NULL)); |
1193 | return -ENOENT; | 1199 | return -ENOENT; |
1194 | } | 1200 | } |
1195 | 1201 | ||
1196 | pdnode_offset = fdt_node_offset_by_phandle(blob, fdt32_to_cpu(*prop)); | 1202 | pdnode_offset = fdt_node_offset_by_phandle(blob, fdt32_to_cpu(*prop)); |
1197 | if (pdnode_offset < 0) { | 1203 | if (pdnode_offset < 0) { |
1198 | pr_err("failed to fetch node %s power-domain", | 1204 | pr_err("failed to fetch node %s power-domain", |
1199 | fdt_get_name(blob, device_offset, NULL)); | 1205 | fdt_get_name(blob, device_offset, NULL)); |
1200 | return pdnode_offset; | 1206 | return pdnode_offset; |
1201 | } | 1207 | } |
1202 | 1208 | ||
1203 | return fdtdec_get_uint(blob, pdnode_offset, "reg", -ENOENT); | 1209 | return fdtdec_get_uint(blob, pdnode_offset, "reg", -ENOENT); |
1204 | } | 1210 | } |
1205 | 1211 | ||
1206 | static int config_smmu_resource_sid(int rsrc, int sid) | 1212 | static int config_smmu_resource_sid(int rsrc, int sid) |
1207 | { | 1213 | { |
1208 | sc_err_t err; | 1214 | sc_err_t err; |
1209 | 1215 | ||
1210 | err = sc_rm_set_master_sid(gd->arch.ipc_channel_handle, rsrc, sid); | 1216 | err = sc_rm_set_master_sid(gd->arch.ipc_channel_handle, rsrc, sid); |
1211 | debug("set_master_sid rsrc=%d sid=0x%x err=%d\n", rsrc, sid, err); | 1217 | debug("set_master_sid rsrc=%d sid=0x%x err=%d\n", rsrc, sid, err); |
1212 | if (err != SC_ERR_NONE) { | 1218 | if (err != SC_ERR_NONE) { |
1213 | pr_err("fail set_master_sid rsrc=%d sid=0x%x err=%d", rsrc, sid, err); | 1219 | pr_err("fail set_master_sid rsrc=%d sid=0x%x err=%d", rsrc, sid, err); |
1214 | return -EINVAL; | 1220 | return -EINVAL; |
1215 | } | 1221 | } |
1216 | 1222 | ||
1217 | return 0; | 1223 | return 0; |
1218 | } | 1224 | } |
1219 | 1225 | ||
1220 | static int config_smmu_fdt_device_sid(void *blob, int device_offset, int sid) | 1226 | static int config_smmu_fdt_device_sid(void *blob, int device_offset, int sid) |
1221 | { | 1227 | { |
1222 | int rsrc; | 1228 | int rsrc; |
1223 | int proplen; | 1229 | int proplen; |
1224 | const fdt32_t *prop; | 1230 | const fdt32_t *prop; |
1225 | const char *name = fdt_get_name(blob, device_offset, NULL); | 1231 | const char *name = fdt_get_name(blob, device_offset, NULL); |
1226 | 1232 | ||
1227 | prop = fdt_getprop(blob, device_offset, "fsl,sc_rsrc_id", &proplen); | 1233 | prop = fdt_getprop(blob, device_offset, "fsl,sc_rsrc_id", &proplen); |
1228 | if (prop) { | 1234 | if (prop) { |
1229 | int i; | 1235 | int i; |
1230 | 1236 | ||
1231 | debug("configure node %s sid 0x%x for %d resources\n", | 1237 | debug("configure node %s sid 0x%x for %d resources\n", |
1232 | name, sid, (int)(proplen / sizeof(fdt32_t))); | 1238 | name, sid, (int)(proplen / sizeof(fdt32_t))); |
1233 | for (i = 0; i < proplen / sizeof(fdt32_t); ++i) { | 1239 | for (i = 0; i < proplen / sizeof(fdt32_t); ++i) { |
1234 | config_smmu_resource_sid(fdt32_to_cpu(prop[i]), sid); | 1240 | config_smmu_resource_sid(fdt32_to_cpu(prop[i]), sid); |
1235 | } | 1241 | } |
1236 | 1242 | ||
1237 | return 0; | 1243 | return 0; |
1238 | } | 1244 | } |
1239 | 1245 | ||
1240 | rsrc = get_srsc_from_fdt_node_power_domain(blob, device_offset); | 1246 | rsrc = get_srsc_from_fdt_node_power_domain(blob, device_offset); |
1241 | debug("configure node %s sid 0x%x rsrc=%d\n", name, sid, rsrc); | 1247 | debug("configure node %s sid 0x%x rsrc=%d\n", name, sid, rsrc); |
1242 | if (rsrc < 0) { | 1248 | if (rsrc < 0) { |
1243 | debug("failed to determine SC_R_* for node %s\n", name); | 1249 | debug("failed to determine SC_R_* for node %s\n", name); |
1244 | return rsrc; | 1250 | return rsrc; |
1245 | } | 1251 | } |
1246 | 1252 | ||
1247 | return config_smmu_resource_sid(rsrc, sid); | 1253 | return config_smmu_resource_sid(rsrc, sid); |
1248 | } | 1254 | } |
1249 | 1255 | ||
1250 | /* assign master sid based on iommu properties in fdt */ | 1256 | /* assign master sid based on iommu properties in fdt */ |
1251 | static int config_smmu_fdt(void *blob) | 1257 | static int config_smmu_fdt(void *blob) |
1252 | { | 1258 | { |
1253 | int offset, proplen, i; | 1259 | int offset, proplen, i; |
1254 | const fdt32_t *prop; | 1260 | const fdt32_t *prop; |
1255 | const char *name; | 1261 | const char *name; |
1256 | 1262 | ||
1257 | /* Legacy smmu bindings, still used by xen. */ | 1263 | /* Legacy smmu bindings, still used by xen. */ |
1258 | offset = fdt_node_offset_by_compatible(blob, 0, "arm,mmu-500"); | 1264 | offset = fdt_node_offset_by_compatible(blob, 0, "arm,mmu-500"); |
1259 | if (offset > 0 && (prop = fdt_getprop(blob, offset, "mmu-masters", &proplen))) | 1265 | if (offset > 0 && (prop = fdt_getprop(blob, offset, "mmu-masters", &proplen))) |
1260 | { | 1266 | { |
1261 | debug("found legacy mmu-masters property\n"); | 1267 | debug("found legacy mmu-masters property\n"); |
1262 | 1268 | ||
1263 | for (i = 0; i < proplen / 8; ++i) { | 1269 | for (i = 0; i < proplen / 8; ++i) { |
1264 | uint32_t phandle = fdt32_to_cpu(prop[2 * i]); | 1270 | uint32_t phandle = fdt32_to_cpu(prop[2 * i]); |
1265 | int sid = fdt32_to_cpu(prop[2 * i + 1]); | 1271 | int sid = fdt32_to_cpu(prop[2 * i + 1]); |
1266 | int device_offset; | 1272 | int device_offset; |
1267 | 1273 | ||
1268 | device_offset = fdt_node_offset_by_phandle(blob, phandle); | 1274 | device_offset = fdt_node_offset_by_phandle(blob, phandle); |
1269 | if (device_offset < 0) { | 1275 | if (device_offset < 0) { |
1270 | pr_err("Failed to fetch device reference from mmu_masters: %d", device_offset); | 1276 | pr_err("Failed to fetch device reference from mmu_masters: %d", device_offset); |
1271 | continue; | 1277 | continue; |
1272 | } | 1278 | } |
1273 | config_smmu_fdt_device_sid(blob, device_offset, sid); | 1279 | config_smmu_fdt_device_sid(blob, device_offset, sid); |
1274 | } | 1280 | } |
1275 | 1281 | ||
1276 | /* Ignore new bindings if old bindings found, just like linux. */ | 1282 | /* Ignore new bindings if old bindings found, just like linux. */ |
1277 | return 0; | 1283 | return 0; |
1278 | } | 1284 | } |
1279 | 1285 | ||
1280 | /* Generic smmu bindings */ | 1286 | /* Generic smmu bindings */ |
1281 | offset = 0; | 1287 | offset = 0; |
1282 | while ((offset = fdt_next_node(blob, offset, NULL)) > 0) | 1288 | while ((offset = fdt_next_node(blob, offset, NULL)) > 0) |
1283 | { | 1289 | { |
1284 | name = fdt_get_name(blob, offset, NULL); | 1290 | name = fdt_get_name(blob, offset, NULL); |
1285 | prop = fdt_getprop(blob, offset, "iommus", &proplen); | 1291 | prop = fdt_getprop(blob, offset, "iommus", &proplen); |
1286 | if (!prop) | 1292 | if (!prop) |
1287 | continue; | 1293 | continue; |
1288 | debug("node %s iommus proplen %d\n", name, proplen); | 1294 | debug("node %s iommus proplen %d\n", name, proplen); |
1289 | 1295 | ||
1290 | if (proplen == 12) { | 1296 | if (proplen == 12) { |
1291 | int sid = fdt32_to_cpu(prop[1]); | 1297 | int sid = fdt32_to_cpu(prop[1]); |
1292 | config_smmu_fdt_device_sid(blob, offset, sid); | 1298 | config_smmu_fdt_device_sid(blob, offset, sid); |
1293 | } else if (proplen != 4) { | 1299 | } else if (proplen != 4) { |
1294 | debug("node %s ignore unexpected iommus proplen=%d\n", name, proplen); | 1300 | debug("node %s ignore unexpected iommus proplen=%d\n", name, proplen); |
1295 | } | 1301 | } |
1296 | } | 1302 | } |
1297 | 1303 | ||
1298 | return 0; | 1304 | return 0; |
1299 | } | 1305 | } |
1300 | #endif | 1306 | #endif |
1301 | 1307 | ||
1302 | #ifdef CONFIG_OF_SYSTEM_SETUP | 1308 | #ifdef CONFIG_OF_SYSTEM_SETUP |
1303 | static int ft_add_optee_node(void *fdt, bd_t *bd) | 1309 | static int ft_add_optee_node(void *fdt, bd_t *bd) |
1304 | { | 1310 | { |
1305 | const char *path, *subpath; | 1311 | const char *path, *subpath; |
1306 | int offs; | 1312 | int offs; |
1307 | 1313 | ||
1308 | /* | 1314 | /* |
1309 | * No TEE space allocated indicating no TEE running, so no | 1315 | * No TEE space allocated indicating no TEE running, so no |
1310 | * need to add optee node in dts | 1316 | * need to add optee node in dts |
1311 | */ | 1317 | */ |
1312 | if (!rom_pointer[1]) | 1318 | if (!rom_pointer[1]) |
1313 | return 0; | 1319 | return 0; |
1314 | 1320 | ||
1315 | offs = fdt_increase_size(fdt, 512); | 1321 | offs = fdt_increase_size(fdt, 512); |
1316 | if (offs) { | 1322 | if (offs) { |
1317 | printf("No Space for dtb\n"); | 1323 | printf("No Space for dtb\n"); |
1318 | return 1; | 1324 | return 1; |
1319 | } | 1325 | } |
1320 | 1326 | ||
1321 | path = "/firmware"; | 1327 | path = "/firmware"; |
1322 | offs = fdt_path_offset(fdt, path); | 1328 | offs = fdt_path_offset(fdt, path); |
1323 | if (offs < 0) { | 1329 | if (offs < 0) { |
1324 | path = "/"; | 1330 | path = "/"; |
1325 | offs = fdt_path_offset(fdt, path); | 1331 | offs = fdt_path_offset(fdt, path); |
1326 | 1332 | ||
1327 | if (offs < 0) { | 1333 | if (offs < 0) { |
1328 | printf("Could not find root node.\n"); | 1334 | printf("Could not find root node.\n"); |
1329 | return 1; | 1335 | return 1; |
1330 | } | 1336 | } |
1331 | 1337 | ||
1332 | subpath = "firmware"; | 1338 | subpath = "firmware"; |
1333 | offs = fdt_add_subnode(fdt, offs, subpath); | 1339 | offs = fdt_add_subnode(fdt, offs, subpath); |
1334 | if (offs < 0) { | 1340 | if (offs < 0) { |
1335 | printf("Could not create %s node.\n", subpath); | 1341 | printf("Could not create %s node.\n", subpath); |
1336 | } | 1342 | } |
1337 | } | 1343 | } |
1338 | 1344 | ||
1339 | subpath = "optee"; | 1345 | subpath = "optee"; |
1340 | offs = fdt_add_subnode(fdt, offs, subpath); | 1346 | offs = fdt_add_subnode(fdt, offs, subpath); |
1341 | if (offs < 0) { | 1347 | if (offs < 0) { |
1342 | printf("Could not create %s node.\n", subpath); | 1348 | printf("Could not create %s node.\n", subpath); |
1343 | } | 1349 | } |
1344 | 1350 | ||
1345 | fdt_setprop_string(fdt, offs, "compatible", "linaro,optee-tz"); | 1351 | fdt_setprop_string(fdt, offs, "compatible", "linaro,optee-tz"); |
1346 | fdt_setprop_string(fdt, offs, "method", "smc"); | 1352 | fdt_setprop_string(fdt, offs, "method", "smc"); |
1347 | 1353 | ||
1348 | return 0; | 1354 | return 0; |
1349 | } | 1355 | } |
1350 | 1356 | ||
1351 | int ft_system_setup(void *blob, bd_t *bd) | 1357 | int ft_system_setup(void *blob, bd_t *bd) |
1352 | { | 1358 | { |
1353 | #ifdef BOOTAUX_RESERVED_MEM_BASE | 1359 | #ifdef BOOTAUX_RESERVED_MEM_BASE |
1354 | int off; | 1360 | int off; |
1355 | off = fdt_add_mem_rsv(blob, BOOTAUX_RESERVED_MEM_BASE, | 1361 | off = fdt_add_mem_rsv(blob, BOOTAUX_RESERVED_MEM_BASE, |
1356 | BOOTAUX_RESERVED_MEM_SIZE); | 1362 | BOOTAUX_RESERVED_MEM_SIZE); |
1357 | if (off < 0) | 1363 | if (off < 0) |
1358 | printf("Failed to reserve memory for bootaux: %s\n", | 1364 | printf("Failed to reserve memory for bootaux: %s\n", |
1359 | fdt_strerror(off)); | 1365 | fdt_strerror(off)); |
1360 | #endif | 1366 | #endif |
1361 | 1367 | ||
1362 | #ifndef CONFIG_SKIP_RESOURCE_CHECING | 1368 | #ifndef CONFIG_SKIP_RESOURCE_CHECING |
1363 | update_fdt_with_owned_resources(blob); | 1369 | update_fdt_with_owned_resources(blob); |
1364 | #endif | 1370 | #endif |
1365 | 1371 | ||
1366 | update_fdt_edma_nodes(blob); | 1372 | update_fdt_edma_nodes(blob); |
1367 | #ifdef CONFIG_IMX_SMMU | 1373 | #ifdef CONFIG_IMX_SMMU |
1368 | config_smmu_fdt(blob); | 1374 | config_smmu_fdt(blob); |
1369 | #endif | 1375 | #endif |
1370 | 1376 | ||
1371 | ft_add_optee_node(blob, bd); | 1377 | ft_add_optee_node(blob, bd); |
1372 | return 0; | 1378 | return 0; |
1373 | } | 1379 | } |
1374 | #endif | 1380 | #endif |
1375 | 1381 | ||
1376 | #define MEMSTART_ALIGNMENT SZ_2M /* Align the memory start with 2MB */ | 1382 | #define MEMSTART_ALIGNMENT SZ_2M /* Align the memory start with 2MB */ |
1377 | 1383 | ||
1378 | static int get_owned_memreg(sc_rm_mr_t mr, sc_faddr_t *addr_start, sc_faddr_t *addr_end) | 1384 | static int get_owned_memreg(sc_rm_mr_t mr, sc_faddr_t *addr_start, sc_faddr_t *addr_end) |
1379 | { | 1385 | { |
1380 | sc_ipc_t ipcHndl = 0; | 1386 | sc_ipc_t ipcHndl = 0; |
1381 | sc_err_t sciErr = 0; | 1387 | sc_err_t sciErr = 0; |
1382 | bool owned; | 1388 | bool owned; |
1383 | sc_faddr_t start, end; | 1389 | sc_faddr_t start, end; |
1384 | 1390 | ||
1385 | ipcHndl = gd->arch.ipc_channel_handle; | 1391 | ipcHndl = gd->arch.ipc_channel_handle; |
1386 | 1392 | ||
1387 | if (ipcHndl) { | 1393 | if (ipcHndl) { |
1388 | owned = sc_rm_is_memreg_owned(ipcHndl, mr); | 1394 | owned = sc_rm_is_memreg_owned(ipcHndl, mr); |
1389 | if (owned) { | 1395 | if (owned) { |
1390 | sciErr = sc_rm_get_memreg_info(ipcHndl, mr, &start, &end); | 1396 | sciErr = sc_rm_get_memreg_info(ipcHndl, mr, &start, &end); |
1391 | if (sciErr) { | 1397 | if (sciErr) { |
1392 | printf("Memreg get info failed, %d\n", sciErr); | 1398 | printf("Memreg get info failed, %d\n", sciErr); |
1393 | return -EINVAL; | 1399 | return -EINVAL; |
1394 | } else { | 1400 | } else { |
1395 | debug("0x%llx -- 0x%llx\n", start, end); | 1401 | debug("0x%llx -- 0x%llx\n", start, end); |
1396 | 1402 | ||
1397 | *addr_start = start; | 1403 | *addr_start = start; |
1398 | *addr_end = end; | 1404 | *addr_end = end; |
1399 | 1405 | ||
1400 | return 0; | 1406 | return 0; |
1401 | } | 1407 | } |
1402 | } | 1408 | } |
1403 | } | 1409 | } |
1404 | 1410 | ||
1405 | return -EINVAL; | 1411 | return -EINVAL; |
1406 | } | 1412 | } |
1407 | 1413 | ||
1408 | phys_size_t get_effective_memsize(void) | 1414 | phys_size_t get_effective_memsize(void) |
1409 | { | 1415 | { |
1410 | sc_rm_mr_t mr; | 1416 | sc_rm_mr_t mr; |
1411 | sc_faddr_t start, end, start_aligned; | 1417 | sc_faddr_t start, end, start_aligned; |
1412 | int err; | 1418 | int err; |
1413 | 1419 | ||
1414 | if (IS_ENABLED(CONFIG_XEN)) | 1420 | if (IS_ENABLED(CONFIG_XEN)) |
1415 | return PHYS_SDRAM_1_SIZE; | 1421 | return PHYS_SDRAM_1_SIZE; |
1416 | 1422 | ||
1417 | for (mr = 0; mr < 64; mr++) { | 1423 | for (mr = 0; mr < 64; mr++) { |
1418 | err = get_owned_memreg(mr, &start, &end); | 1424 | err = get_owned_memreg(mr, &start, &end); |
1419 | if (!err) { | 1425 | if (!err) { |
1420 | start_aligned = roundup(start, MEMSTART_ALIGNMENT); | 1426 | start_aligned = roundup(start, MEMSTART_ALIGNMENT); |
1421 | if (start_aligned > end) /* Too small memory region, not use it */ | 1427 | if (start_aligned > end) /* Too small memory region, not use it */ |
1422 | continue; | 1428 | continue; |
1423 | 1429 | ||
1424 | /* Find the memory region runs the u-boot */ | 1430 | /* Find the memory region runs the u-boot */ |
1425 | if (start >= PHYS_SDRAM_1 && start <= ((sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE) | 1431 | if (start >= PHYS_SDRAM_1 && start <= ((sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE) |
1426 | && (start <= CONFIG_SYS_TEXT_BASE && CONFIG_SYS_TEXT_BASE <= end)){ | 1432 | && (start <= CONFIG_SYS_TEXT_BASE && CONFIG_SYS_TEXT_BASE <= end)){ |
1427 | if ((end + 1) <= ((sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE)) | 1433 | if ((end + 1) <= ((sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE)) |
1428 | return (end - PHYS_SDRAM_1 + 1); | 1434 | return (end - PHYS_SDRAM_1 + 1); |
1429 | else | 1435 | else |
1430 | return PHYS_SDRAM_1_SIZE; | 1436 | return PHYS_SDRAM_1_SIZE; |
1431 | } | 1437 | } |
1432 | } | 1438 | } |
1433 | } | 1439 | } |
1434 | 1440 | ||
1435 | return PHYS_SDRAM_1_SIZE; | 1441 | return PHYS_SDRAM_1_SIZE; |
1436 | } | 1442 | } |
1437 | 1443 | ||
1438 | int dram_init(void) | 1444 | int dram_init(void) |
1439 | { | 1445 | { |
1440 | sc_rm_mr_t mr; | 1446 | sc_rm_mr_t mr; |
1441 | sc_faddr_t start, end; | 1447 | sc_faddr_t start, end; |
1442 | int err; | 1448 | int err; |
1443 | 1449 | ||
1444 | if (IS_ENABLED(CONFIG_XEN)) { | 1450 | if (IS_ENABLED(CONFIG_XEN)) { |
1445 | gd->ram_size = PHYS_SDRAM_1_SIZE; | 1451 | gd->ram_size = PHYS_SDRAM_1_SIZE; |
1446 | gd->ram_size += PHYS_SDRAM_2_SIZE; | 1452 | gd->ram_size += PHYS_SDRAM_2_SIZE; |
1447 | 1453 | ||
1448 | return 0; | 1454 | return 0; |
1449 | } | 1455 | } |
1450 | 1456 | ||
1451 | for (mr = 0; mr < 64; mr++) { | 1457 | for (mr = 0; mr < 64; mr++) { |
1452 | err = get_owned_memreg(mr, &start, &end); | 1458 | err = get_owned_memreg(mr, &start, &end); |
1453 | if (!err) { | 1459 | if (!err) { |
1454 | start = roundup(start, MEMSTART_ALIGNMENT); | 1460 | start = roundup(start, MEMSTART_ALIGNMENT); |
1455 | if (start > end) /* Too small memory region, not use it */ | 1461 | if (start > end) /* Too small memory region, not use it */ |
1456 | continue; | 1462 | continue; |
1457 | 1463 | ||
1458 | if (start >= PHYS_SDRAM_1 && start <= ((sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE)) { | 1464 | if (start >= PHYS_SDRAM_1 && start <= ((sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE)) { |
1459 | 1465 | ||
1460 | if ((end + 1) <= ((sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE)) | 1466 | if ((end + 1) <= ((sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE)) |
1461 | gd->ram_size += end - start + 1; | 1467 | gd->ram_size += end - start + 1; |
1462 | else | 1468 | else |
1463 | gd->ram_size += ((sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE) - start; | 1469 | gd->ram_size += ((sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE) - start; |
1464 | 1470 | ||
1465 | } else if (start >= PHYS_SDRAM_2 && start <= ((sc_faddr_t)PHYS_SDRAM_2 + PHYS_SDRAM_2_SIZE)) { | 1471 | } else if (start >= PHYS_SDRAM_2 && start <= ((sc_faddr_t)PHYS_SDRAM_2 + PHYS_SDRAM_2_SIZE)) { |
1466 | 1472 | ||
1467 | if ((end + 1) <= ((sc_faddr_t)PHYS_SDRAM_2 + PHYS_SDRAM_2_SIZE)) | 1473 | if ((end + 1) <= ((sc_faddr_t)PHYS_SDRAM_2 + PHYS_SDRAM_2_SIZE)) |
1468 | gd->ram_size += end - start + 1; | 1474 | gd->ram_size += end - start + 1; |
1469 | else | 1475 | else |
1470 | gd->ram_size += ((sc_faddr_t)PHYS_SDRAM_2 + PHYS_SDRAM_2_SIZE) - start; | 1476 | gd->ram_size += ((sc_faddr_t)PHYS_SDRAM_2 + PHYS_SDRAM_2_SIZE) - start; |
1471 | } | 1477 | } |
1472 | } | 1478 | } |
1473 | } | 1479 | } |
1474 | 1480 | ||
1475 | /* If error, set to the default value */ | 1481 | /* If error, set to the default value */ |
1476 | if (!gd->ram_size) { | 1482 | if (!gd->ram_size) { |
1477 | gd->ram_size = PHYS_SDRAM_1_SIZE; | 1483 | gd->ram_size = PHYS_SDRAM_1_SIZE; |
1478 | gd->ram_size += PHYS_SDRAM_2_SIZE; | 1484 | gd->ram_size += PHYS_SDRAM_2_SIZE; |
1479 | } | 1485 | } |
1480 | return 0; | 1486 | return 0; |
1481 | } | 1487 | } |
1482 | 1488 | ||
1483 | static void dram_bank_sort(int current_bank) | 1489 | static void dram_bank_sort(int current_bank) |
1484 | { | 1490 | { |
1485 | phys_addr_t start; | 1491 | phys_addr_t start; |
1486 | phys_size_t size; | 1492 | phys_size_t size; |
1487 | while (current_bank > 0) { | 1493 | while (current_bank > 0) { |
1488 | if (gd->bd->bi_dram[current_bank - 1].start > gd->bd->bi_dram[current_bank].start) { | 1494 | if (gd->bd->bi_dram[current_bank - 1].start > gd->bd->bi_dram[current_bank].start) { |
1489 | start = gd->bd->bi_dram[current_bank - 1].start; | 1495 | start = gd->bd->bi_dram[current_bank - 1].start; |
1490 | size = gd->bd->bi_dram[current_bank - 1].size; | 1496 | size = gd->bd->bi_dram[current_bank - 1].size; |
1491 | 1497 | ||
1492 | gd->bd->bi_dram[current_bank - 1].start = gd->bd->bi_dram[current_bank].start; | 1498 | gd->bd->bi_dram[current_bank - 1].start = gd->bd->bi_dram[current_bank].start; |
1493 | gd->bd->bi_dram[current_bank - 1].size = gd->bd->bi_dram[current_bank].size; | 1499 | gd->bd->bi_dram[current_bank - 1].size = gd->bd->bi_dram[current_bank].size; |
1494 | 1500 | ||
1495 | gd->bd->bi_dram[current_bank].start = start; | 1501 | gd->bd->bi_dram[current_bank].start = start; |
1496 | gd->bd->bi_dram[current_bank].size = size; | 1502 | gd->bd->bi_dram[current_bank].size = size; |
1497 | } | 1503 | } |
1498 | 1504 | ||
1499 | current_bank--; | 1505 | current_bank--; |
1500 | } | 1506 | } |
1501 | } | 1507 | } |
1502 | 1508 | ||
1503 | int dram_init_banksize(void) | 1509 | int dram_init_banksize(void) |
1504 | { | 1510 | { |
1505 | sc_rm_mr_t mr; | 1511 | sc_rm_mr_t mr; |
1506 | sc_faddr_t start, end; | 1512 | sc_faddr_t start, end; |
1507 | int i = 0; | 1513 | int i = 0; |
1508 | int err; | 1514 | int err; |
1509 | 1515 | ||
1510 | if (IS_ENABLED(CONFIG_XEN)) { | 1516 | if (IS_ENABLED(CONFIG_XEN)) { |
1511 | gd->bd->bi_dram[0].start = PHYS_SDRAM_1; | 1517 | gd->bd->bi_dram[0].start = PHYS_SDRAM_1; |
1512 | gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; | 1518 | gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; |
1513 | gd->bd->bi_dram[1].start = PHYS_SDRAM_2; | 1519 | gd->bd->bi_dram[1].start = PHYS_SDRAM_2; |
1514 | gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE; | 1520 | gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE; |
1515 | 1521 | ||
1516 | return 0; | 1522 | return 0; |
1517 | } | 1523 | } |
1518 | 1524 | ||
1519 | for (mr = 0; mr < 64 && i < CONFIG_NR_DRAM_BANKS; mr++) { | 1525 | for (mr = 0; mr < 64 && i < CONFIG_NR_DRAM_BANKS; mr++) { |
1520 | err = get_owned_memreg(mr, &start, &end); | 1526 | err = get_owned_memreg(mr, &start, &end); |
1521 | if (!err) { | 1527 | if (!err) { |
1522 | start = roundup(start, MEMSTART_ALIGNMENT); | 1528 | start = roundup(start, MEMSTART_ALIGNMENT); |
1523 | if (start > end) /* Too small memory region, not use it */ | 1529 | if (start > end) /* Too small memory region, not use it */ |
1524 | continue; | 1530 | continue; |
1525 | 1531 | ||
1526 | if (start >= PHYS_SDRAM_1 && start <= ((sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE)) { | 1532 | if (start >= PHYS_SDRAM_1 && start <= ((sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE)) { |
1527 | gd->bd->bi_dram[i].start = start; | 1533 | gd->bd->bi_dram[i].start = start; |
1528 | 1534 | ||
1529 | if ((end + 1) <= ((sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE)) | 1535 | if ((end + 1) <= ((sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE)) |
1530 | gd->bd->bi_dram[i].size = end - start + 1; | 1536 | gd->bd->bi_dram[i].size = end - start + 1; |
1531 | else | 1537 | else |
1532 | gd->bd->bi_dram[i].size = ((sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE) - start; | 1538 | gd->bd->bi_dram[i].size = ((sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE) - start; |
1533 | 1539 | ||
1534 | dram_bank_sort(i); | 1540 | dram_bank_sort(i); |
1535 | i++; | 1541 | i++; |
1536 | } else if (start >= PHYS_SDRAM_2 && start <= ((sc_faddr_t)PHYS_SDRAM_2 + PHYS_SDRAM_2_SIZE)) { | 1542 | } else if (start >= PHYS_SDRAM_2 && start <= ((sc_faddr_t)PHYS_SDRAM_2 + PHYS_SDRAM_2_SIZE)) { |
1537 | gd->bd->bi_dram[i].start = start; | 1543 | gd->bd->bi_dram[i].start = start; |
1538 | 1544 | ||
1539 | if ((end + 1) <= ((sc_faddr_t)PHYS_SDRAM_2 + PHYS_SDRAM_2_SIZE)) | 1545 | if ((end + 1) <= ((sc_faddr_t)PHYS_SDRAM_2 + PHYS_SDRAM_2_SIZE)) |
1540 | gd->bd->bi_dram[i].size = end - start + 1; | 1546 | gd->bd->bi_dram[i].size = end - start + 1; |
1541 | else | 1547 | else |
1542 | gd->bd->bi_dram[i].size = ((sc_faddr_t)PHYS_SDRAM_2 + PHYS_SDRAM_2_SIZE) - start; | 1548 | gd->bd->bi_dram[i].size = ((sc_faddr_t)PHYS_SDRAM_2 + PHYS_SDRAM_2_SIZE) - start; |
1543 | 1549 | ||
1544 | dram_bank_sort(i); | 1550 | dram_bank_sort(i); |
1545 | i++; | 1551 | i++; |
1546 | } | 1552 | } |
1547 | 1553 | ||
1548 | } | 1554 | } |
1549 | } | 1555 | } |
1550 | 1556 | ||
1551 | /* If error, set to the default value */ | 1557 | /* If error, set to the default value */ |
1552 | if (!i) { | 1558 | if (!i) { |
1553 | gd->bd->bi_dram[0].start = PHYS_SDRAM_1; | 1559 | gd->bd->bi_dram[0].start = PHYS_SDRAM_1; |
1554 | gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; | 1560 | gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE; |
1555 | gd->bd->bi_dram[1].start = PHYS_SDRAM_2; | 1561 | gd->bd->bi_dram[1].start = PHYS_SDRAM_2; |
1556 | gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE; | 1562 | gd->bd->bi_dram[1].size = PHYS_SDRAM_2_SIZE; |
1557 | } | 1563 | } |
1558 | 1564 | ||
1559 | return 0; | 1565 | return 0; |
1560 | } | 1566 | } |
1561 | 1567 | ||
1562 | static u64 get_block_attrs(sc_faddr_t addr_start) | 1568 | static u64 get_block_attrs(sc_faddr_t addr_start) |
1563 | { | 1569 | { |
1564 | if ((addr_start >= PHYS_SDRAM_1 && addr_start <= ((sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE)) | 1570 | if ((addr_start >= PHYS_SDRAM_1 && addr_start <= ((sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE)) |
1565 | || (addr_start >= PHYS_SDRAM_2 && addr_start <= ((sc_faddr_t)PHYS_SDRAM_2 + PHYS_SDRAM_2_SIZE))) | 1571 | || (addr_start >= PHYS_SDRAM_2 && addr_start <= ((sc_faddr_t)PHYS_SDRAM_2 + PHYS_SDRAM_2_SIZE))) |
1566 | return (PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_OUTER_SHARE); | 1572 | return (PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_OUTER_SHARE); |
1567 | 1573 | ||
1568 | return (PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN); | 1574 | return (PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN); |
1569 | } | 1575 | } |
1570 | 1576 | ||
1571 | static u64 get_block_size(sc_faddr_t addr_start, sc_faddr_t addr_end) | 1577 | static u64 get_block_size(sc_faddr_t addr_start, sc_faddr_t addr_end) |
1572 | { | 1578 | { |
1573 | if (addr_start >= PHYS_SDRAM_1 && addr_start <= ((sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE)) { | 1579 | if (addr_start >= PHYS_SDRAM_1 && addr_start <= ((sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE)) { |
1574 | if ((addr_end + 1) > ((sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE)) | 1580 | if ((addr_end + 1) > ((sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE)) |
1575 | return ((sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE) - addr_start; | 1581 | return ((sc_faddr_t)PHYS_SDRAM_1 + PHYS_SDRAM_1_SIZE) - addr_start; |
1576 | 1582 | ||
1577 | } else if (addr_start >= PHYS_SDRAM_2 && addr_start <= ((sc_faddr_t)PHYS_SDRAM_2 + PHYS_SDRAM_2_SIZE)) { | 1583 | } else if (addr_start >= PHYS_SDRAM_2 && addr_start <= ((sc_faddr_t)PHYS_SDRAM_2 + PHYS_SDRAM_2_SIZE)) { |
1578 | 1584 | ||
1579 | if ((addr_end + 1) > ((sc_faddr_t)PHYS_SDRAM_2 + PHYS_SDRAM_2_SIZE)) | 1585 | if ((addr_end + 1) > ((sc_faddr_t)PHYS_SDRAM_2 + PHYS_SDRAM_2_SIZE)) |
1580 | return ((sc_faddr_t)PHYS_SDRAM_2 + PHYS_SDRAM_2_SIZE) - addr_start; | 1586 | return ((sc_faddr_t)PHYS_SDRAM_2 + PHYS_SDRAM_2_SIZE) - addr_start; |
1581 | } | 1587 | } |
1582 | 1588 | ||
1583 | return (addr_end - addr_start + 1); | 1589 | return (addr_end - addr_start + 1); |
1584 | } | 1590 | } |
1585 | 1591 | ||
1586 | #define MAX_PTE_ENTRIES 512 | 1592 | #define MAX_PTE_ENTRIES 512 |
1587 | #define MAX_MEM_MAP_REGIONS 16 | 1593 | #define MAX_MEM_MAP_REGIONS 16 |
1588 | 1594 | ||
1589 | static struct mm_region imx8_mem_map[MAX_MEM_MAP_REGIONS]; | 1595 | static struct mm_region imx8_mem_map[MAX_MEM_MAP_REGIONS]; |
1590 | struct mm_region *mem_map = imx8_mem_map; | 1596 | struct mm_region *mem_map = imx8_mem_map; |
1591 | 1597 | ||
1592 | void enable_caches(void) | 1598 | void enable_caches(void) |
1593 | { | 1599 | { |
1594 | sc_rm_mr_t mr; | 1600 | sc_rm_mr_t mr; |
1595 | sc_faddr_t start, end; | 1601 | sc_faddr_t start, end; |
1596 | int err, i; | 1602 | int err, i; |
1597 | 1603 | ||
1598 | if (IS_ENABLED(CONFIG_XEN)) { | 1604 | if (IS_ENABLED(CONFIG_XEN)) { |
1599 | imx8_mem_map[0].virt = 0x00000000UL; | 1605 | imx8_mem_map[0].virt = 0x00000000UL; |
1600 | imx8_mem_map[0].phys = 0x00000000UL; | 1606 | imx8_mem_map[0].phys = 0x00000000UL; |
1601 | imx8_mem_map[0].size = 0x39000000UL; | 1607 | imx8_mem_map[0].size = 0x39000000UL; |
1602 | imx8_mem_map[0].attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | | 1608 | imx8_mem_map[0].attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | |
1603 | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN; | 1609 | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN; |
1604 | imx8_mem_map[1].virt = 0x39000000UL; | 1610 | imx8_mem_map[1].virt = 0x39000000UL; |
1605 | imx8_mem_map[1].phys = 0x39000000UL; | 1611 | imx8_mem_map[1].phys = 0x39000000UL; |
1606 | imx8_mem_map[1].size = 0x01000000UL; | 1612 | imx8_mem_map[1].size = 0x01000000UL; |
1607 | imx8_mem_map[1].attrs = (PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE); | 1613 | imx8_mem_map[1].attrs = (PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE); |
1608 | 1614 | ||
1609 | imx8_mem_map[2].virt = 0x40000000UL; | 1615 | imx8_mem_map[2].virt = 0x40000000UL; |
1610 | imx8_mem_map[2].phys = 0x40000000UL; | 1616 | imx8_mem_map[2].phys = 0x40000000UL; |
1611 | imx8_mem_map[2].size = 0x40000000UL; | 1617 | imx8_mem_map[2].size = 0x40000000UL; |
1612 | imx8_mem_map[2].attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | | 1618 | imx8_mem_map[2].attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | |
1613 | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN; | 1619 | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN; |
1614 | 1620 | ||
1615 | imx8_mem_map[3].virt = 0x80000000UL; | 1621 | imx8_mem_map[3].virt = 0x80000000UL; |
1616 | imx8_mem_map[3].phys = 0x80000000UL; | 1622 | imx8_mem_map[3].phys = 0x80000000UL; |
1617 | imx8_mem_map[3].size = 0x80000000UL; | 1623 | imx8_mem_map[3].size = 0x80000000UL; |
1618 | imx8_mem_map[3].attrs = (PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE); | 1624 | imx8_mem_map[3].attrs = (PTE_BLOCK_MEMTYPE(MT_NORMAL) | PTE_BLOCK_INNER_SHARE); |
1619 | 1625 | ||
1620 | imx8_mem_map[4].virt = 0x100000000UL; | 1626 | imx8_mem_map[4].virt = 0x100000000UL; |
1621 | imx8_mem_map[4].phys = 0x100000000UL; | 1627 | imx8_mem_map[4].phys = 0x100000000UL; |
1622 | imx8_mem_map[4].size = 0x100000000UL; | 1628 | imx8_mem_map[4].size = 0x100000000UL; |
1623 | imx8_mem_map[4].attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | | 1629 | imx8_mem_map[4].attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | |
1624 | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN; | 1630 | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN; |
1625 | 1631 | ||
1626 | icache_enable(); | 1632 | icache_enable(); |
1627 | dcache_enable(); | 1633 | dcache_enable(); |
1628 | 1634 | ||
1629 | return; | 1635 | return; |
1630 | } | 1636 | } |
1631 | 1637 | ||
1632 | /* Create map for registers access from 0x1c000000 to 0x80000000*/ | 1638 | /* Create map for registers access from 0x1c000000 to 0x80000000*/ |
1633 | imx8_mem_map[0].virt = 0x1c000000UL; | 1639 | imx8_mem_map[0].virt = 0x1c000000UL; |
1634 | imx8_mem_map[0].phys = 0x1c000000UL; | 1640 | imx8_mem_map[0].phys = 0x1c000000UL; |
1635 | imx8_mem_map[0].size = 0x64000000UL; | 1641 | imx8_mem_map[0].size = 0x64000000UL; |
1636 | imx8_mem_map[0].attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | | 1642 | imx8_mem_map[0].attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | |
1637 | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN; | 1643 | PTE_BLOCK_NON_SHARE | PTE_BLOCK_PXN | PTE_BLOCK_UXN; |
1638 | 1644 | ||
1639 | i = 1; | 1645 | i = 1; |
1640 | for (mr = 0; mr < 64 && i < MAX_MEM_MAP_REGIONS; mr++) { | 1646 | for (mr = 0; mr < 64 && i < MAX_MEM_MAP_REGIONS; mr++) { |
1641 | err = get_owned_memreg(mr, &start, &end); | 1647 | err = get_owned_memreg(mr, &start, &end); |
1642 | if (!err) { | 1648 | if (!err) { |
1643 | imx8_mem_map[i].virt = start; | 1649 | imx8_mem_map[i].virt = start; |
1644 | imx8_mem_map[i].phys = start; | 1650 | imx8_mem_map[i].phys = start; |
1645 | imx8_mem_map[i].size = get_block_size(start, end); | 1651 | imx8_mem_map[i].size = get_block_size(start, end); |
1646 | imx8_mem_map[i].attrs = get_block_attrs(start); | 1652 | imx8_mem_map[i].attrs = get_block_attrs(start); |
1647 | i++; | 1653 | i++; |
1648 | } | 1654 | } |
1649 | } | 1655 | } |
1650 | 1656 | ||
1651 | if (i < MAX_MEM_MAP_REGIONS) { | 1657 | if (i < MAX_MEM_MAP_REGIONS) { |
1652 | imx8_mem_map[i].size = 0; | 1658 | imx8_mem_map[i].size = 0; |
1653 | imx8_mem_map[i].attrs = 0; | 1659 | imx8_mem_map[i].attrs = 0; |
1654 | } else { | 1660 | } else { |
1655 | printf("Error, need more MEM MAP REGIONS reserved\n"); | 1661 | printf("Error, need more MEM MAP REGIONS reserved\n"); |
1656 | icache_enable(); | 1662 | icache_enable(); |
1657 | return; | 1663 | return; |
1658 | } | 1664 | } |
1659 | 1665 | ||
1660 | for (i = 0;i < MAX_MEM_MAP_REGIONS;i++) { | 1666 | for (i = 0;i < MAX_MEM_MAP_REGIONS;i++) { |
1661 | debug("[%d] vir = 0x%llx phys = 0x%llx size = 0x%llx attrs = 0x%llx\n", i, | 1667 | debug("[%d] vir = 0x%llx phys = 0x%llx size = 0x%llx attrs = 0x%llx\n", i, |
1662 | imx8_mem_map[i].virt, imx8_mem_map[i].phys, imx8_mem_map[i].size, imx8_mem_map[i].attrs); | 1668 | imx8_mem_map[i].virt, imx8_mem_map[i].phys, imx8_mem_map[i].size, imx8_mem_map[i].attrs); |
1663 | } | 1669 | } |
1664 | 1670 | ||
1665 | icache_enable(); | 1671 | icache_enable(); |
1666 | dcache_enable(); | 1672 | dcache_enable(); |
1667 | } | 1673 | } |
1668 | 1674 | ||
1669 | #ifndef CONFIG_SYS_DCACHE_OFF | 1675 | #ifndef CONFIG_SYS_DCACHE_OFF |
1670 | u64 get_page_table_size(void) | 1676 | u64 get_page_table_size(void) |
1671 | { | 1677 | { |
1672 | u64 one_pt = MAX_PTE_ENTRIES * sizeof(u64); | 1678 | u64 one_pt = MAX_PTE_ENTRIES * sizeof(u64); |
1673 | u64 size = 0; | 1679 | u64 size = 0; |
1674 | 1680 | ||
1675 | /* For each memory region, the max table size: 2 level 3 tables + 2 level 2 tables + 1 level 1 table*/ | 1681 | /* For each memory region, the max table size: 2 level 3 tables + 2 level 2 tables + 1 level 1 table*/ |
1676 | size = (2 + 2 + 1) * one_pt * MAX_MEM_MAP_REGIONS + one_pt; | 1682 | size = (2 + 2 + 1) * one_pt * MAX_MEM_MAP_REGIONS + one_pt; |
1677 | 1683 | ||
1678 | /* | 1684 | /* |
1679 | * We need to duplicate our page table once to have an emergency pt to | 1685 | * We need to duplicate our page table once to have an emergency pt to |
1680 | * resort to when splitting page tables later on | 1686 | * resort to when splitting page tables later on |
1681 | */ | 1687 | */ |
1682 | size *= 2; | 1688 | size *= 2; |
1683 | 1689 | ||
1684 | /* | 1690 | /* |
1685 | * We may need to split page tables later on if dcache settings change, | 1691 | * We may need to split page tables later on if dcache settings change, |
1686 | * so reserve up to 4 (random pick) page tables for that. | 1692 | * so reserve up to 4 (random pick) page tables for that. |
1687 | */ | 1693 | */ |
1688 | size += one_pt * 4; | 1694 | size += one_pt * 4; |
1689 | 1695 | ||
1690 | return size; | 1696 | return size; |
1691 | } | 1697 | } |
1692 | #endif | 1698 | #endif |
1693 | 1699 | ||
1694 | static bool check_device_power_off(struct udevice *dev, | 1700 | static bool check_device_power_off(struct udevice *dev, |
1695 | const char* permanent_on_devices[], int size) | 1701 | const char* permanent_on_devices[], int size) |
1696 | { | 1702 | { |
1697 | int i; | 1703 | int i; |
1698 | 1704 | ||
1699 | for (i = 0; i < size; i++) { | 1705 | for (i = 0; i < size; i++) { |
1700 | if (!strcmp(dev->name, permanent_on_devices[i])) | 1706 | if (!strcmp(dev->name, permanent_on_devices[i])) |
1701 | return false; | 1707 | return false; |
1702 | } | 1708 | } |
1703 | 1709 | ||
1704 | return true; | 1710 | return true; |
1705 | } | 1711 | } |
1706 | 1712 | ||
1707 | void power_off_pd_devices(const char* permanent_on_devices[], int size) | 1713 | void power_off_pd_devices(const char* permanent_on_devices[], int size) |
1708 | { | 1714 | { |
1709 | struct udevice *dev; | 1715 | struct udevice *dev; |
1710 | struct power_domain pd; | 1716 | struct power_domain pd; |
1711 | 1717 | ||
1712 | for (uclass_find_first_device(UCLASS_POWER_DOMAIN, &dev); dev; | 1718 | for (uclass_find_first_device(UCLASS_POWER_DOMAIN, &dev); dev; |
1713 | uclass_find_next_device(&dev)) { | 1719 | uclass_find_next_device(&dev)) { |
1714 | 1720 | ||
1715 | if (device_active(dev)) { | 1721 | if (device_active(dev)) { |
1716 | /* Power off active pd devices except the permanent power on devices */ | 1722 | /* Power off active pd devices except the permanent power on devices */ |
1717 | if (check_device_power_off(dev, permanent_on_devices, size)) { | 1723 | if (check_device_power_off(dev, permanent_on_devices, size)) { |
1718 | pd.dev = dev; | 1724 | pd.dev = dev; |
1719 | power_domain_off(&pd); | 1725 | power_domain_off(&pd); |
1720 | } | 1726 | } |
1721 | } | 1727 | } |
1722 | } | 1728 | } |
1723 | } | 1729 | } |
1724 | 1730 | ||
1725 | void disconnect_from_pc(void) | 1731 | void disconnect_from_pc(void) |
1726 | { | 1732 | { |
1727 | int ret; | 1733 | int ret; |
1728 | struct power_domain pd; | 1734 | struct power_domain pd; |
1729 | 1735 | ||
1730 | if (!power_domain_lookup_name("conn_usb0", &pd)) { | 1736 | if (!power_domain_lookup_name("conn_usb0", &pd)) { |
1731 | ret = power_domain_on(&pd); | 1737 | ret = power_domain_on(&pd); |
1732 | if (ret) { | 1738 | if (ret) { |
1733 | printf("conn_usb0 Power up failed! (error = %d)\n", ret); | 1739 | printf("conn_usb0 Power up failed! (error = %d)\n", ret); |
1734 | return; | 1740 | return; |
1735 | } | 1741 | } |
1736 | 1742 | ||
1737 | writel(0x0, USB_BASE_ADDR + 0x140); | 1743 | writel(0x0, USB_BASE_ADDR + 0x140); |
1738 | 1744 | ||
1739 | ret = power_domain_off(&pd); | 1745 | ret = power_domain_off(&pd); |
1740 | if (ret) { | 1746 | if (ret) { |
1741 | printf("conn_usb0 Power off failed! (error = %d)\n", ret); | 1747 | printf("conn_usb0 Power off failed! (error = %d)\n", ret); |
1742 | return; | 1748 | return; |
1743 | } | 1749 | } |
1744 | } else { | 1750 | } else { |
1745 | printf("conn_usb0 finding failed!\n"); | 1751 | printf("conn_usb0 finding failed!\n"); |
1746 | return; | 1752 | return; |
1747 | } | 1753 | } |
1748 | } | 1754 | } |
1749 | 1755 |
arch/arm/mach-imx/imx8/video_common.c
1 | /* | 1 | /* |
2 | * Copyright 2017-2018 NXP | 2 | * Copyright 2017-2018 NXP |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: GPL-2.0+ | 4 | * SPDX-License-Identifier: GPL-2.0+ |
5 | */ | 5 | */ |
6 | 6 | ||
7 | #include <common.h> | 7 | #include <common.h> |
8 | #include <dm.h> | 8 | #include <dm.h> |
9 | #include <asm/io.h> | 9 | #include <asm/io.h> |
10 | #include <linux/errno.h> | 10 | #include <linux/errno.h> |
11 | #include <asm/arch/clock.h> | 11 | #include <asm/arch/clock.h> |
12 | #include <asm/arch/imx-regs.h> | 12 | #include <asm/arch/imx-regs.h> |
13 | #include <asm/mach-imx/sci/sci.h> | 13 | #include <asm/mach-imx/sci/sci.h> |
14 | #include <i2c.h> | 14 | #include <i2c.h> |
15 | #include <asm/arch/sys_proto.h> | 15 | #include <asm/arch/sys_proto.h> |
16 | 16 | ||
17 | #include <imxdpuv1.h> | 17 | #include <imxdpuv1.h> |
18 | #include <imxdpuv1_registers.h> | 18 | #include <imxdpuv1_registers.h> |
19 | #include <imxdpuv1_events.h> | 19 | #include <imxdpuv1_events.h> |
20 | #include <asm/arch/imx8_lvds.h> | 20 | #include <asm/arch/imx8_lvds.h> |
21 | #include <video_fb.h> | 21 | #include <video_fb.h> |
22 | #include <asm/arch/imx8_mipi_dsi.h> | 22 | #include <asm/arch/imx8_mipi_dsi.h> |
23 | #include <asm/arch/video_common.h> | 23 | #include <asm/arch/video_common.h> |
24 | #include <power-domain.h> | 24 | #include <power-domain.h> |
25 | #include <asm/arch/lpcg.h> | ||
25 | 26 | ||
26 | DECLARE_GLOBAL_DATA_PTR; | 27 | DECLARE_GLOBAL_DATA_PTR; |
27 | 28 | ||
28 | static struct imxdpuv1_videomode gmode; | 29 | static struct imxdpuv1_videomode gmode; |
29 | static int8_t gdisp, gdc; | 30 | static int8_t gdisp, gdc; |
30 | static uint32_t gpixfmt; | 31 | static uint32_t gpixfmt; |
31 | static GraphicDevice panel; | 32 | static GraphicDevice panel; |
32 | 33 | ||
33 | static int hdmi_i2c_reg_write(struct udevice *dev, uint addr, uint mask, uint data) | 34 | static int hdmi_i2c_reg_write(struct udevice *dev, uint addr, uint mask, uint data) |
34 | { | 35 | { |
35 | uint8_t valb; | 36 | uint8_t valb; |
36 | int err; | 37 | int err; |
37 | 38 | ||
38 | if (mask != 0xff) { | 39 | if (mask != 0xff) { |
39 | err = dm_i2c_read(dev, addr, &valb, 1); | 40 | err = dm_i2c_read(dev, addr, &valb, 1); |
40 | if (err) | 41 | if (err) |
41 | return err; | 42 | return err; |
42 | 43 | ||
43 | valb &= ~mask; | 44 | valb &= ~mask; |
44 | valb |= data; | 45 | valb |= data; |
45 | } else { | 46 | } else { |
46 | valb = data; | 47 | valb = data; |
47 | } | 48 | } |
48 | 49 | ||
49 | err = dm_i2c_write(dev, addr, &valb, 1); | 50 | err = dm_i2c_write(dev, addr, &valb, 1); |
50 | return err; | 51 | return err; |
51 | } | 52 | } |
52 | 53 | ||
53 | static int hdmi_i2c_reg_read(struct udevice *dev, uint8_t addr, uint8_t *data) | 54 | static int hdmi_i2c_reg_read(struct udevice *dev, uint8_t addr, uint8_t *data) |
54 | { | 55 | { |
55 | uint8_t valb; | 56 | uint8_t valb; |
56 | int err; | 57 | int err; |
57 | 58 | ||
58 | err = dm_i2c_read(dev, addr, &valb, 1); | 59 | err = dm_i2c_read(dev, addr, &valb, 1); |
59 | if (err) | 60 | if (err) |
60 | return err; | 61 | return err; |
61 | 62 | ||
62 | *data = (int)valb; | 63 | *data = (int)valb; |
63 | return 0; | 64 | return 0; |
64 | } | 65 | } |
65 | 66 | ||
66 | /* On 8QXP ARM2, the LVDS1 signals are connected to LVDS2HDMI card's LVDS2 channel, | 67 | /* On 8QXP ARM2, the LVDS1 signals are connected to LVDS2HDMI card's LVDS2 channel, |
67 | * LVDS0 signals are connected to LVDS2HDMI card's LVDS4 channel. | 68 | * LVDS0 signals are connected to LVDS2HDMI card's LVDS4 channel. |
68 | * There totally 6 channels on the cards, from 0-5. | 69 | * There totally 6 channels on the cards, from 0-5. |
69 | */ | 70 | */ |
70 | int lvds2hdmi_setup(int i2c_bus) | 71 | int lvds2hdmi_setup(int i2c_bus) |
71 | { | 72 | { |
72 | struct udevice *bus, *dev; | 73 | struct udevice *bus, *dev; |
73 | uint8_t chip = 0x4c; | 74 | uint8_t chip = 0x4c; |
74 | uint8_t data; | 75 | uint8_t data; |
75 | int ret; | 76 | int ret; |
76 | 77 | ||
77 | ret = uclass_get_device_by_seq(UCLASS_I2C, i2c_bus, &bus); | 78 | ret = uclass_get_device_by_seq(UCLASS_I2C, i2c_bus, &bus); |
78 | if (ret) { | 79 | if (ret) { |
79 | printf("%s: No bus %d\n", __func__, i2c_bus); | 80 | printf("%s: No bus %d\n", __func__, i2c_bus); |
80 | return ret; | 81 | return ret; |
81 | } | 82 | } |
82 | 83 | ||
83 | ret = dm_i2c_probe(bus, chip, 0, &dev); | 84 | ret = dm_i2c_probe(bus, chip, 0, &dev); |
84 | if (ret) { | 85 | if (ret) { |
85 | printf("%s: Can't find device id=0x%x, on bus %d\n", | 86 | printf("%s: Can't find device id=0x%x, on bus %d\n", |
86 | __func__, chip, i2c_bus); | 87 | __func__, chip, i2c_bus); |
87 | return ret; | 88 | return ret; |
88 | } | 89 | } |
89 | 90 | ||
90 | /* InitIT626X(): start */ | 91 | /* InitIT626X(): start */ |
91 | hdmi_i2c_reg_write(dev, 0x04, 0xff, 0x3d); | 92 | hdmi_i2c_reg_write(dev, 0x04, 0xff, 0x3d); |
92 | hdmi_i2c_reg_write(dev, 0x0f, 0xff, 0x00); | 93 | hdmi_i2c_reg_write(dev, 0x0f, 0xff, 0x00); |
93 | hdmi_i2c_reg_write(dev, 0x05, 0xff, 0x40); | 94 | hdmi_i2c_reg_write(dev, 0x05, 0xff, 0x40); |
94 | hdmi_i2c_reg_write(dev, 0x04, 0xff, 0x15); | 95 | hdmi_i2c_reg_write(dev, 0x04, 0xff, 0x15); |
95 | hdmi_i2c_reg_write(dev, 0x0f, 0xff, 0x00); | 96 | hdmi_i2c_reg_write(dev, 0x0f, 0xff, 0x00); |
96 | hdmi_i2c_reg_write(dev, 0x1d, 0xff, 0x66); | 97 | hdmi_i2c_reg_write(dev, 0x1d, 0xff, 0x66); |
97 | hdmi_i2c_reg_write(dev, 0x1e, 0xff, 0x01); | 98 | hdmi_i2c_reg_write(dev, 0x1e, 0xff, 0x01); |
98 | 99 | ||
99 | hdmi_i2c_reg_write(dev, 0x61, 0xff, 0x30); | 100 | hdmi_i2c_reg_write(dev, 0x61, 0xff, 0x30); |
100 | hdmi_i2c_reg_read(dev, 0xf3, &data); /* -> 0x00 */ | 101 | hdmi_i2c_reg_read(dev, 0xf3, &data); /* -> 0x00 */ |
101 | hdmi_i2c_reg_write(dev, 0xf3, 0xff, data & ~0x30); | 102 | hdmi_i2c_reg_write(dev, 0xf3, 0xff, data & ~0x30); |
102 | hdmi_i2c_reg_read(dev, 0xf3, &data); /* -> 0x00 */ | 103 | hdmi_i2c_reg_read(dev, 0xf3, &data); /* -> 0x00 */ |
103 | hdmi_i2c_reg_write(dev, 0xf3, 0xff, data | 0x20); | 104 | hdmi_i2c_reg_write(dev, 0xf3, 0xff, data | 0x20); |
104 | 105 | ||
105 | hdmi_i2c_reg_write(dev, 0x09, 0xff, 0x30); | 106 | hdmi_i2c_reg_write(dev, 0x09, 0xff, 0x30); |
106 | hdmi_i2c_reg_write(dev, 0x0a, 0xff, 0xf8); | 107 | hdmi_i2c_reg_write(dev, 0x0a, 0xff, 0xf8); |
107 | hdmi_i2c_reg_write(dev, 0x0b, 0xff, 0x37); | 108 | hdmi_i2c_reg_write(dev, 0x0b, 0xff, 0x37); |
108 | hdmi_i2c_reg_write(dev, 0x0f, 0xff, 0x00); | 109 | hdmi_i2c_reg_write(dev, 0x0f, 0xff, 0x00); |
109 | hdmi_i2c_reg_write(dev, 0xc9, 0xff, 0x00); | 110 | hdmi_i2c_reg_write(dev, 0xc9, 0xff, 0x00); |
110 | hdmi_i2c_reg_write(dev, 0xca, 0xff, 0x00); | 111 | hdmi_i2c_reg_write(dev, 0xca, 0xff, 0x00); |
111 | hdmi_i2c_reg_write(dev, 0xcb, 0xff, 0x00); | 112 | hdmi_i2c_reg_write(dev, 0xcb, 0xff, 0x00); |
112 | hdmi_i2c_reg_write(dev, 0xcc, 0xff, 0x00); | 113 | hdmi_i2c_reg_write(dev, 0xcc, 0xff, 0x00); |
113 | hdmi_i2c_reg_write(dev, 0xcd, 0xff, 0x00); | 114 | hdmi_i2c_reg_write(dev, 0xcd, 0xff, 0x00); |
114 | hdmi_i2c_reg_write(dev, 0xce, 0xff, 0x00); | 115 | hdmi_i2c_reg_write(dev, 0xce, 0xff, 0x00); |
115 | hdmi_i2c_reg_write(dev, 0xcf, 0xff, 0x00); | 116 | hdmi_i2c_reg_write(dev, 0xcf, 0xff, 0x00); |
116 | hdmi_i2c_reg_write(dev, 0xd0, 0xff, 0x00); | 117 | hdmi_i2c_reg_write(dev, 0xd0, 0xff, 0x00); |
117 | hdmi_i2c_reg_write(dev, 0x0f, 0xff, 0x01); | 118 | hdmi_i2c_reg_write(dev, 0x0f, 0xff, 0x01); |
118 | 119 | ||
119 | hdmi_i2c_reg_read(dev, 0x58, &data); /* -> 0x00 */ | 120 | hdmi_i2c_reg_read(dev, 0x58, &data); /* -> 0x00 */ |
120 | hdmi_i2c_reg_write(dev, 0x58, 0xff, data & ~(3 << 5)); | 121 | hdmi_i2c_reg_write(dev, 0x58, 0xff, data & ~(3 << 5)); |
121 | 122 | ||
122 | hdmi_i2c_reg_write(dev, 0x0f, 0xff, 0x00); | 123 | hdmi_i2c_reg_write(dev, 0x0f, 0xff, 0x00); |
123 | hdmi_i2c_reg_write(dev, 0xe1, 0xff, 0x00); | 124 | hdmi_i2c_reg_write(dev, 0xe1, 0xff, 0x00); |
124 | hdmi_i2c_reg_write(dev, 0x0c, 0xff, 0xff); | 125 | hdmi_i2c_reg_write(dev, 0x0c, 0xff, 0xff); |
125 | hdmi_i2c_reg_write(dev, 0x0d, 0xff, 0xff); | 126 | hdmi_i2c_reg_write(dev, 0x0d, 0xff, 0xff); |
126 | hdmi_i2c_reg_read(dev, 0x0e, &data); /* -> 0x00 */ | 127 | hdmi_i2c_reg_read(dev, 0x0e, &data); /* -> 0x00 */ |
127 | hdmi_i2c_reg_write(dev, 0x0e, 0xff, (data | 0x3)); | 128 | hdmi_i2c_reg_write(dev, 0x0e, 0xff, (data | 0x3)); |
128 | hdmi_i2c_reg_write(dev, 0x0e, 0xff, (data & 0xfe)); | 129 | hdmi_i2c_reg_write(dev, 0x0e, 0xff, (data & 0xfe)); |
129 | hdmi_i2c_reg_write(dev, 0x0f, 0xff, 0x01); | 130 | hdmi_i2c_reg_write(dev, 0x0f, 0xff, 0x01); |
130 | hdmi_i2c_reg_write(dev, 0x33, 0xff, 0x00); | 131 | hdmi_i2c_reg_write(dev, 0x33, 0xff, 0x00); |
131 | hdmi_i2c_reg_write(dev, 0x34, 0xff, 0x18); | 132 | hdmi_i2c_reg_write(dev, 0x34, 0xff, 0x18); |
132 | hdmi_i2c_reg_write(dev, 0x35, 0xff, 0x00); | 133 | hdmi_i2c_reg_write(dev, 0x35, 0xff, 0x00); |
133 | hdmi_i2c_reg_write(dev, 0x0f, 0xff, 0x00); | 134 | hdmi_i2c_reg_write(dev, 0x0f, 0xff, 0x00); |
134 | hdmi_i2c_reg_write(dev, 0xc4, 0xff, 0xfe); | 135 | hdmi_i2c_reg_write(dev, 0xc4, 0xff, 0xfe); |
135 | hdmi_i2c_reg_read(dev, 0xc5, &data); /* -> 0x00 */ | 136 | hdmi_i2c_reg_read(dev, 0xc5, &data); /* -> 0x00 */ |
136 | hdmi_i2c_reg_write(dev, 0xc5, 0xff, data | 0x30); | 137 | hdmi_i2c_reg_write(dev, 0xc5, 0xff, data | 0x30); |
137 | /* InitIT626X end */ | 138 | /* InitIT626X end */ |
138 | 139 | ||
139 | hdmi_i2c_reg_write(dev, 0x0f, 0xff, 0x00); | 140 | hdmi_i2c_reg_write(dev, 0x0f, 0xff, 0x00); |
140 | hdmi_i2c_reg_write(dev, 0x04, 0xff, 0x3d); | 141 | hdmi_i2c_reg_write(dev, 0x04, 0xff, 0x3d); |
141 | hdmi_i2c_reg_write(dev, 0x04, 0xff, 0x15); | 142 | hdmi_i2c_reg_write(dev, 0x04, 0xff, 0x15); |
142 | hdmi_i2c_reg_write(dev, 0x0f, 0xff, 0x00); | 143 | hdmi_i2c_reg_write(dev, 0x0f, 0xff, 0x00); |
143 | hdmi_i2c_reg_write(dev, 0x1d, 0xff, 0x66); | 144 | hdmi_i2c_reg_write(dev, 0x1d, 0xff, 0x66); |
144 | hdmi_i2c_reg_write(dev, 0x1e, 0xff, 0x01); | 145 | hdmi_i2c_reg_write(dev, 0x1e, 0xff, 0x01); |
145 | 146 | ||
146 | hdmi_i2c_reg_read(dev, 0xc1, &data); /* -> 0x00 */ | 147 | hdmi_i2c_reg_read(dev, 0xc1, &data); /* -> 0x00 */ |
147 | hdmi_i2c_reg_write(dev, 0x61, 0xff, 0x10); | 148 | hdmi_i2c_reg_write(dev, 0x61, 0xff, 0x10); |
148 | 149 | ||
149 | /* SetupAFE(): */ | 150 | /* SetupAFE(): */ |
150 | hdmi_i2c_reg_write(dev, 0x62, 0xff, 0x88); | 151 | hdmi_i2c_reg_write(dev, 0x62, 0xff, 0x88); |
151 | hdmi_i2c_reg_write(dev, 0x63, 0xff, 0x10); | 152 | hdmi_i2c_reg_write(dev, 0x63, 0xff, 0x10); |
152 | hdmi_i2c_reg_write(dev, 0x64, 0xff, 0x84); | 153 | hdmi_i2c_reg_write(dev, 0x64, 0xff, 0x84); |
153 | /* SetupAFE(): end */ | 154 | /* SetupAFE(): end */ |
154 | 155 | ||
155 | hdmi_i2c_reg_read(dev, 0x04, &data); /* -> 0x00 */ | 156 | hdmi_i2c_reg_read(dev, 0x04, &data); /* -> 0x00 */ |
156 | hdmi_i2c_reg_write(dev, 0x04, 0xff, 0x1d); | 157 | hdmi_i2c_reg_write(dev, 0x04, 0xff, 0x1d); |
157 | 158 | ||
158 | hdmi_i2c_reg_read(dev, 0x04, &data); /* -> 0x00 */ | 159 | hdmi_i2c_reg_read(dev, 0x04, &data); /* -> 0x00 */ |
159 | hdmi_i2c_reg_write(dev, 0x04, 0xff, 0x15); | 160 | hdmi_i2c_reg_write(dev, 0x04, 0xff, 0x15); |
160 | 161 | ||
161 | hdmi_i2c_reg_read(dev, 0x0e, &data); /* -> 0x00 */ | 162 | hdmi_i2c_reg_read(dev, 0x0e, &data); /* -> 0x00 */ |
162 | 163 | ||
163 | /* Wait video stable */ | 164 | /* Wait video stable */ |
164 | hdmi_i2c_reg_read(dev, 0x0e, &data); /* -> 0x00 */ | 165 | hdmi_i2c_reg_read(dev, 0x0e, &data); /* -> 0x00 */ |
165 | 166 | ||
166 | /* Reset Video */ | 167 | /* Reset Video */ |
167 | hdmi_i2c_reg_read(dev, 0x0d, &data); /* -> 0x00 */ | 168 | hdmi_i2c_reg_read(dev, 0x0d, &data); /* -> 0x00 */ |
168 | hdmi_i2c_reg_write(dev, 0x0d, 0xff, 0x40); | 169 | hdmi_i2c_reg_write(dev, 0x0d, 0xff, 0x40); |
169 | hdmi_i2c_reg_read(dev, 0x0e, &data); /* -> 0x00 */ | 170 | hdmi_i2c_reg_read(dev, 0x0e, &data); /* -> 0x00 */ |
170 | hdmi_i2c_reg_write(dev, 0x0e, 0xff, 0x7d); | 171 | hdmi_i2c_reg_write(dev, 0x0e, 0xff, 0x7d); |
171 | hdmi_i2c_reg_write(dev, 0x0e, 0xff, 0x7c); | 172 | hdmi_i2c_reg_write(dev, 0x0e, 0xff, 0x7c); |
172 | hdmi_i2c_reg_write(dev, 0x0f, 0xff, 0x00); | 173 | hdmi_i2c_reg_write(dev, 0x0f, 0xff, 0x00); |
173 | hdmi_i2c_reg_write(dev, 0x61, 0xff, 0x00); | 174 | hdmi_i2c_reg_write(dev, 0x61, 0xff, 0x00); |
174 | hdmi_i2c_reg_read(dev, 0x61, &data); /* -> 0x00 */ | 175 | hdmi_i2c_reg_read(dev, 0x61, &data); /* -> 0x00 */ |
175 | hdmi_i2c_reg_read(dev, 0x62, &data); /* -> 0x00 */ | 176 | hdmi_i2c_reg_read(dev, 0x62, &data); /* -> 0x00 */ |
176 | hdmi_i2c_reg_read(dev, 0x63, &data); /* -> 0x00 */ | 177 | hdmi_i2c_reg_read(dev, 0x63, &data); /* -> 0x00 */ |
177 | hdmi_i2c_reg_read(dev, 0x64, &data); /* -> 0x00 */ | 178 | hdmi_i2c_reg_read(dev, 0x64, &data); /* -> 0x00 */ |
178 | hdmi_i2c_reg_read(dev, 0x65, &data); /* -> 0x00 */ | 179 | hdmi_i2c_reg_read(dev, 0x65, &data); /* -> 0x00 */ |
179 | hdmi_i2c_reg_read(dev, 0x66, &data); /* -> 0x00 */ | 180 | hdmi_i2c_reg_read(dev, 0x66, &data); /* -> 0x00 */ |
180 | hdmi_i2c_reg_read(dev, 0x67, &data); /* -> 0x00 */ | 181 | hdmi_i2c_reg_read(dev, 0x67, &data); /* -> 0x00 */ |
181 | hdmi_i2c_reg_write(dev, 0x0f, 0xff, 0x00); | 182 | hdmi_i2c_reg_write(dev, 0x0f, 0xff, 0x00); |
182 | hdmi_i2c_reg_read(dev, 0xc1, &data); /* -> 0x00 */ | 183 | hdmi_i2c_reg_read(dev, 0xc1, &data); /* -> 0x00 */ |
183 | hdmi_i2c_reg_write(dev, 0xc1, 0xff, 0x00); | 184 | hdmi_i2c_reg_write(dev, 0xc1, 0xff, 0x00); |
184 | hdmi_i2c_reg_write(dev, 0xc6, 0xff, 0x03); | 185 | hdmi_i2c_reg_write(dev, 0xc6, 0xff, 0x03); |
185 | /* Clear AV mute */ | 186 | /* Clear AV mute */ |
186 | 187 | ||
187 | return 0; | 188 | return 0; |
188 | } | 189 | } |
189 | 190 | ||
190 | 191 | ||
191 | int lvds_soc_setup(int lvds_id, sc_pm_clock_rate_t pixel_clock) | 192 | int lvds_soc_setup(int lvds_id, sc_pm_clock_rate_t pixel_clock) |
192 | { | 193 | { |
193 | sc_err_t err; | 194 | sc_err_t err; |
194 | sc_rsrc_t lvds_rsrc, mipi_rsrc; | 195 | sc_rsrc_t lvds_rsrc, mipi_rsrc; |
195 | const char *pd_name; | 196 | const char *pd_name; |
196 | sc_ipc_t ipcHndl = gd->arch.ipc_channel_handle; | 197 | sc_ipc_t ipcHndl = gd->arch.ipc_channel_handle; |
197 | 198 | ||
198 | struct power_domain pd; | 199 | struct power_domain pd; |
199 | int ret; | 200 | int ret; |
200 | 201 | ||
201 | if (lvds_id == 0) { | 202 | if (lvds_id == 0) { |
202 | lvds_rsrc = SC_R_LVDS_0; | 203 | lvds_rsrc = SC_R_LVDS_0; |
203 | mipi_rsrc = SC_R_MIPI_0; | 204 | mipi_rsrc = SC_R_MIPI_0; |
204 | pd_name = "lvds0_power_domain"; | 205 | pd_name = "lvds0_power_domain"; |
205 | } else { | 206 | } else { |
206 | lvds_rsrc = SC_R_LVDS_1; | 207 | lvds_rsrc = SC_R_LVDS_1; |
207 | mipi_rsrc = SC_R_MIPI_1; | 208 | mipi_rsrc = SC_R_MIPI_1; |
208 | pd_name = "lvds1_power_domain"; | 209 | pd_name = "lvds1_power_domain"; |
209 | } | 210 | } |
210 | /* Power up LVDS */ | 211 | /* Power up LVDS */ |
211 | if (!power_domain_lookup_name(pd_name, &pd)) { | 212 | if (!power_domain_lookup_name(pd_name, &pd)) { |
212 | ret = power_domain_on(&pd); | 213 | ret = power_domain_on(&pd); |
213 | if (ret) { | 214 | if (ret) { |
214 | printf("%s Power up failed! (error = %d)\n", pd_name, ret); | 215 | printf("%s Power up failed! (error = %d)\n", pd_name, ret); |
215 | return -EIO; | 216 | return -EIO; |
216 | } | 217 | } |
217 | } else { | 218 | } else { |
218 | printf("%s lookup failed!\n", pd_name); | 219 | printf("%s lookup failed!\n", pd_name); |
219 | return -EIO; | 220 | return -EIO; |
220 | } | 221 | } |
221 | 222 | ||
222 | /* Setup clocks */ | 223 | /* Setup clocks */ |
223 | err = sc_pm_set_clock_rate(ipcHndl, lvds_rsrc, SC_PM_CLK_BYPASS, &pixel_clock); | 224 | err = sc_pm_set_clock_rate(ipcHndl, lvds_rsrc, SC_PM_CLK_BYPASS, &pixel_clock); |
224 | if (err != SC_ERR_NONE) { | 225 | if (err != SC_ERR_NONE) { |
225 | printf("LVDS set rate SC_PM_CLK_BYPASS failed! (error = %d)\n", err); | 226 | printf("LVDS set rate SC_PM_CLK_BYPASS failed! (error = %d)\n", err); |
226 | return -EIO; | 227 | return -EIO; |
227 | } | 228 | } |
228 | 229 | ||
229 | err = sc_pm_set_clock_rate(ipcHndl, lvds_rsrc, SC_PM_CLK_PER, &pixel_clock); | 230 | err = sc_pm_set_clock_rate(ipcHndl, lvds_rsrc, SC_PM_CLK_PER, &pixel_clock); |
230 | if (err != SC_ERR_NONE) { | 231 | if (err != SC_ERR_NONE) { |
231 | printf("LVDS set rate SC_PM_CLK_BYPASS failed! (error = %d)\n", err); | 232 | printf("LVDS set rate SC_PM_CLK_BYPASS failed! (error = %d)\n", err); |
232 | return -EIO; | 233 | return -EIO; |
233 | } | 234 | } |
234 | 235 | ||
235 | err = sc_pm_set_clock_rate(ipcHndl, lvds_rsrc, SC_PM_CLK_PHY, &pixel_clock); | 236 | err = sc_pm_set_clock_rate(ipcHndl, lvds_rsrc, SC_PM_CLK_PHY, &pixel_clock); |
236 | if (err != SC_ERR_NONE) { | 237 | if (err != SC_ERR_NONE) { |
237 | printf("LVDS set rate SC_PM_CLK_BYPASS failed! (error = %d)\n", err); | 238 | printf("LVDS set rate SC_PM_CLK_BYPASS failed! (error = %d)\n", err); |
238 | return -EIO; | 239 | return -EIO; |
239 | } | 240 | } |
240 | 241 | ||
241 | if (is_imx8qxp()) { | 242 | if (is_imx8qxp()) { |
242 | /* For QXP, there is only one DC, and two pixel links to each LVDS with a mux provided. | 243 | /* For QXP, there is only one DC, and two pixel links to each LVDS with a mux provided. |
243 | * We connect LVDS0 to pixel link 0, lVDS1 to pixel link 1 from DC | 244 | * We connect LVDS0 to pixel link 0, lVDS1 to pixel link 1 from DC |
244 | */ | 245 | */ |
245 | 246 | ||
246 | /* Configure to LVDS mode not MIPI DSI */ | 247 | /* Configure to LVDS mode not MIPI DSI */ |
247 | err = sc_misc_set_control(ipcHndl, mipi_rsrc, SC_C_MODE, 1); | 248 | err = sc_misc_set_control(ipcHndl, mipi_rsrc, SC_C_MODE, 1); |
248 | if (err != SC_ERR_NONE) { | 249 | if (err != SC_ERR_NONE) { |
249 | printf("LVDS sc_misc_set_control SC_C_MODE failed! (error = %d)\n", err); | 250 | printf("LVDS sc_misc_set_control SC_C_MODE failed! (error = %d)\n", err); |
250 | return -EIO; | 251 | return -EIO; |
251 | } | 252 | } |
252 | 253 | ||
253 | /* Configure to LVDS mode with single channel */ | 254 | /* Configure to LVDS mode with single channel */ |
254 | err = sc_misc_set_control(ipcHndl, mipi_rsrc, SC_C_DUAL_MODE, 0); | 255 | err = sc_misc_set_control(ipcHndl, mipi_rsrc, SC_C_DUAL_MODE, 0); |
255 | if (err != SC_ERR_NONE) { | 256 | if (err != SC_ERR_NONE) { |
256 | printf("LVDS sc_misc_set_control SC_C_DUAL_MODE failed! (error = %d)\n", err); | 257 | printf("LVDS sc_misc_set_control SC_C_DUAL_MODE failed! (error = %d)\n", err); |
257 | return -EIO; | 258 | return -EIO; |
258 | } | 259 | } |
259 | 260 | ||
260 | err = sc_misc_set_control(ipcHndl, mipi_rsrc, SC_C_PXL_LINK_SEL, lvds_id); | 261 | err = sc_misc_set_control(ipcHndl, mipi_rsrc, SC_C_PXL_LINK_SEL, lvds_id); |
261 | if (err != SC_ERR_NONE) { | 262 | if (err != SC_ERR_NONE) { |
262 | printf("LVDS sc_misc_set_control SC_C_PXL_LINK_SEL failed! (error = %d)\n", err); | 263 | printf("LVDS sc_misc_set_control SC_C_PXL_LINK_SEL failed! (error = %d)\n", err); |
263 | return -EIO; | 264 | return -EIO; |
264 | } | 265 | } |
265 | } | 266 | } |
266 | 267 | ||
267 | err = sc_pm_clock_enable(ipcHndl, lvds_rsrc, SC_PM_CLK_BYPASS, true, false); | 268 | err = sc_pm_clock_enable(ipcHndl, lvds_rsrc, SC_PM_CLK_BYPASS, true, false); |
268 | if (err != SC_ERR_NONE) { | 269 | if (err != SC_ERR_NONE) { |
269 | printf("LVDS enable clock SC_PM_CLK_BYPASS failed! (error = %d)\n", err); | 270 | printf("LVDS enable clock SC_PM_CLK_BYPASS failed! (error = %d)\n", err); |
270 | return -EIO; | 271 | return -EIO; |
271 | } | 272 | } |
272 | 273 | ||
273 | err = sc_pm_clock_enable(ipcHndl, lvds_rsrc, SC_PM_CLK_PER, true, false); | 274 | err = sc_pm_clock_enable(ipcHndl, lvds_rsrc, SC_PM_CLK_PER, true, false); |
274 | if (err != SC_ERR_NONE) { | 275 | if (err != SC_ERR_NONE) { |
275 | printf("LVDS enable clock SC_PM_CLK_PER failed! (error = %d)\n", err); | 276 | printf("LVDS enable clock SC_PM_CLK_PER failed! (error = %d)\n", err); |
276 | return -EIO; | 277 | return -EIO; |
277 | } | 278 | } |
278 | 279 | ||
279 | err = sc_pm_clock_enable(ipcHndl, lvds_rsrc, SC_PM_CLK_PHY, true, false); | 280 | err = sc_pm_clock_enable(ipcHndl, lvds_rsrc, SC_PM_CLK_PHY, true, false); |
280 | if (err != SC_ERR_NONE) { | 281 | if (err != SC_ERR_NONE) { |
281 | printf("LVDS enable clock SC_PM_CLK_PHY failed! (error = %d)\n", err); | 282 | printf("LVDS enable clock SC_PM_CLK_PHY failed! (error = %d)\n", err); |
282 | return -EIO; | 283 | return -EIO; |
283 | } | 284 | } |
284 | 285 | ||
285 | return 0; | 286 | return 0; |
286 | } | 287 | } |
287 | 288 | ||
288 | void lvds_configure(int lvds_id) | 289 | void lvds_configure(int lvds_id) |
289 | { | 290 | { |
290 | void __iomem *lvds_base; | 291 | void __iomem *lvds_base; |
291 | void __iomem *mipi_base; | 292 | void __iomem *mipi_base; |
292 | uint32_t phy_setting; | 293 | uint32_t phy_setting; |
293 | uint32_t mode; | 294 | uint32_t mode; |
294 | 295 | ||
295 | if (lvds_id == 0) { | 296 | if (lvds_id == 0) { |
296 | lvds_base = (void __iomem *)LVDS0_PHYCTRL_BASE; | 297 | lvds_base = (void __iomem *)LVDS0_PHYCTRL_BASE; |
297 | mipi_base = (void __iomem *)MIPI0_SS_BASE; | 298 | mipi_base = (void __iomem *)MIPI0_SS_BASE; |
298 | } else { | 299 | } else { |
299 | lvds_base = (void __iomem *)LVDS1_PHYCTRL_BASE; | 300 | lvds_base = (void __iomem *)LVDS1_PHYCTRL_BASE; |
300 | mipi_base = (void __iomem *)MIPI1_SS_BASE; | 301 | mipi_base = (void __iomem *)MIPI1_SS_BASE; |
301 | } | 302 | } |
302 | 303 | ||
303 | if (is_imx8qm()) { | 304 | if (is_imx8qm()) { |
304 | mode = | 305 | mode = |
305 | IMX_LVDS_SET_FIELD(LVDS_CTRL_CH0_MODE, LVDS_CTRL_CH0_MODE__DI0) | | 306 | IMX_LVDS_SET_FIELD(LVDS_CTRL_CH0_MODE, LVDS_CTRL_CH0_MODE__DI0) | |
306 | IMX_LVDS_SET_FIELD(LVDS_CTRL_CH0_DATA_WIDTH, LVDS_CTRL_CH0_DATA_WIDTH__24BIT) | | 307 | IMX_LVDS_SET_FIELD(LVDS_CTRL_CH0_DATA_WIDTH, LVDS_CTRL_CH0_DATA_WIDTH__24BIT) | |
307 | IMX_LVDS_SET_FIELD(LVDS_CTRL_CH0_BIT_MAP, LVDS_CTRL_CH0_BIT_MAP__JEIDA) | | 308 | IMX_LVDS_SET_FIELD(LVDS_CTRL_CH0_BIT_MAP, LVDS_CTRL_CH0_BIT_MAP__JEIDA) | |
308 | IMX_LVDS_SET_FIELD(LVDS_CTRL_CH0_10BIT_ENABLE, LVDS_CTRL_CH0_10BIT_ENABLE__10BIT) | | 309 | IMX_LVDS_SET_FIELD(LVDS_CTRL_CH0_10BIT_ENABLE, LVDS_CTRL_CH0_10BIT_ENABLE__10BIT) | |
309 | IMX_LVDS_SET_FIELD(LVDS_CTRL_DI0_DATA_WIDTH, LVDS_CTRL_DI0_DATA_WIDTH__USE_30BIT); | 310 | IMX_LVDS_SET_FIELD(LVDS_CTRL_DI0_DATA_WIDTH, LVDS_CTRL_DI0_DATA_WIDTH__USE_30BIT); |
310 | 311 | ||
311 | writel(mode, lvds_base + LVDS_CTRL); | 312 | writel(mode, lvds_base + LVDS_CTRL); |
312 | 313 | ||
313 | phy_setting = | 314 | phy_setting = |
314 | LVDS_PHY_CTRL_RFB_MASK | | 315 | LVDS_PHY_CTRL_RFB_MASK | |
315 | LVDS_PHY_CTRL_CH0_EN_MASK | | 316 | LVDS_PHY_CTRL_CH0_EN_MASK | |
316 | (0 << LVDS_PHY_CTRL_M_SHIFT) | | 317 | (0 << LVDS_PHY_CTRL_M_SHIFT) | |
317 | (0x04 << LVDS_PHY_CTRL_CCM_SHIFT) | | 318 | (0x04 << LVDS_PHY_CTRL_CCM_SHIFT) | |
318 | (0x04 << LVDS_PHY_CTRL_CA_SHIFT); | 319 | (0x04 << LVDS_PHY_CTRL_CA_SHIFT); |
319 | writel(phy_setting, lvds_base + LVDS_PHY_CTRL); | 320 | writel(phy_setting, lvds_base + LVDS_PHY_CTRL); |
320 | } else if (is_imx8qxp()) { | 321 | } else if (is_imx8qxp()) { |
321 | mode = | 322 | mode = |
322 | IMX_LVDS_SET_FIELD(LVDS_CTRL_CH0_MODE, LVDS_CTRL_CH0_MODE__DI0) | | 323 | IMX_LVDS_SET_FIELD(LVDS_CTRL_CH0_MODE, LVDS_CTRL_CH0_MODE__DI0) | |
323 | IMX_LVDS_SET_FIELD(LVDS_CTRL_CH0_DATA_WIDTH, LVDS_CTRL_CH0_DATA_WIDTH__24BIT) | | 324 | IMX_LVDS_SET_FIELD(LVDS_CTRL_CH0_DATA_WIDTH, LVDS_CTRL_CH0_DATA_WIDTH__24BIT) | |
324 | IMX_LVDS_SET_FIELD(LVDS_CTRL_CH0_BIT_MAP, LVDS_CTRL_CH0_BIT_MAP__JEIDA); | 325 | IMX_LVDS_SET_FIELD(LVDS_CTRL_CH0_BIT_MAP, LVDS_CTRL_CH0_BIT_MAP__JEIDA); |
325 | 326 | ||
326 | phy_setting = 0x4 << 5 | 0x4 << 2 | 1 << 1 | 0x1; | 327 | phy_setting = 0x4 << 5 | 0x4 << 2 | 1 << 1 | 0x1; |
327 | writel(phy_setting, lvds_base + 0 /* PHY_CTRL*/); | 328 | writel(phy_setting, lvds_base + 0 /* PHY_CTRL*/); |
328 | writel(mode, lvds_base + LVDS_CTRL); | 329 | writel(mode, lvds_base + LVDS_CTRL); |
329 | writel(0, lvds_base + MIPIv2_CSR_TX_ULPS); | 330 | writel(0, lvds_base + MIPIv2_CSR_TX_ULPS); |
330 | writel(MIPI_CSR_PXL2DPI_24_BIT, lvds_base + MIPIv2_CSR_PXL2DPI); | 331 | writel(MIPI_CSR_PXL2DPI_24_BIT, lvds_base + MIPIv2_CSR_PXL2DPI); |
331 | 332 | ||
332 | /* Power up PLL in MIPI DSI PHY */ | 333 | /* Power up PLL in MIPI DSI PHY */ |
333 | writel(0, mipi_base + MIPI_DSI_OFFSET + DPHY_PD_PLL); | 334 | writel(0, mipi_base + MIPI_DSI_OFFSET + DPHY_PD_PLL); |
334 | writel(0, mipi_base + MIPI_DSI_OFFSET + DPHY_PD_TX); | 335 | writel(0, mipi_base + MIPI_DSI_OFFSET + DPHY_PD_TX); |
335 | } | 336 | } |
336 | } | 337 | } |
337 | 338 | ||
338 | int display_controller_setup(sc_pm_clock_rate_t pixel_clock) | 339 | int display_controller_setup(sc_pm_clock_rate_t pixel_clock) |
339 | { | 340 | { |
340 | sc_err_t err; | 341 | sc_err_t err; |
341 | sc_rsrc_t dc_rsrc, pll0_rsrc, pll1_rsrc; | 342 | sc_rsrc_t dc_rsrc, pll0_rsrc, pll1_rsrc; |
342 | sc_pm_clock_rate_t pll_clk; | 343 | sc_pm_clock_rate_t pll_clk; |
343 | const char *pll1_pd_name; | 344 | const char *pll1_pd_name; |
344 | sc_ipc_t ipcHndl = gd->arch.ipc_channel_handle; | 345 | sc_ipc_t ipcHndl = gd->arch.ipc_channel_handle; |
346 | u32 dc_lpcg; | ||
345 | 347 | ||
346 | int dc_id = gdc; | 348 | int dc_id = gdc; |
347 | 349 | ||
348 | struct power_domain pd; | 350 | struct power_domain pd; |
349 | int ret; | 351 | int ret; |
350 | 352 | ||
351 | if (dc_id == 0) { | 353 | if (dc_id == 0) { |
352 | dc_rsrc = SC_R_DC_0; | 354 | dc_rsrc = SC_R_DC_0; |
353 | pll0_rsrc = SC_R_DC_0_PLL_0; | 355 | pll0_rsrc = SC_R_DC_0_PLL_0; |
354 | pll1_rsrc = SC_R_DC_0_PLL_1; | 356 | pll1_rsrc = SC_R_DC_0_PLL_1; |
355 | pll1_pd_name = "dc0_pll1"; | 357 | pll1_pd_name = "dc0_pll1"; |
358 | dc_lpcg = DC_0_LPCG; | ||
356 | } else { | 359 | } else { |
357 | dc_rsrc = SC_R_DC_1; | 360 | dc_rsrc = SC_R_DC_1; |
358 | pll0_rsrc = SC_R_DC_1_PLL_0; | 361 | pll0_rsrc = SC_R_DC_1_PLL_0; |
359 | pll1_rsrc = SC_R_DC_1_PLL_1; | 362 | pll1_rsrc = SC_R_DC_1_PLL_1; |
360 | pll1_pd_name = "dc1_pll1"; | 363 | pll1_pd_name = "dc1_pll1"; |
364 | dc_lpcg = DC_1_LPCG; | ||
361 | } | 365 | } |
362 | 366 | ||
363 | if (!power_domain_lookup_name(pll1_pd_name, &pd)) { | 367 | if (!power_domain_lookup_name(pll1_pd_name, &pd)) { |
364 | ret = power_domain_on(&pd); | 368 | ret = power_domain_on(&pd); |
365 | if (ret) { | 369 | if (ret) { |
366 | printf("%s Power up failed! (error = %d)\n", pll1_pd_name, ret); | 370 | printf("%s Power up failed! (error = %d)\n", pll1_pd_name, ret); |
367 | return -EIO; | 371 | return -EIO; |
368 | } | 372 | } |
369 | } else { | 373 | } else { |
370 | printf("%s lookup failed!\n", pll1_pd_name); | 374 | printf("%s lookup failed!\n", pll1_pd_name); |
371 | return -EIO; | 375 | return -EIO; |
372 | } | 376 | } |
373 | 377 | ||
374 | /* Setup the pll1/2 and DISP0/1 clock */ | 378 | /* Setup the pll1/2 and DISP0/1 clock */ |
375 | if (pixel_clock >= 40000000) | 379 | if (pixel_clock >= 40000000) |
376 | pll_clk = 1188000000; | 380 | pll_clk = 1188000000; |
377 | else | 381 | else |
378 | pll_clk = 675000000; | 382 | pll_clk = 675000000; |
379 | 383 | ||
380 | err = sc_pm_set_clock_rate(ipcHndl, pll0_rsrc, SC_PM_CLK_PLL, &pll_clk); | 384 | err = sc_pm_set_clock_rate(ipcHndl, pll0_rsrc, SC_PM_CLK_PLL, &pll_clk); |
381 | if (err != SC_ERR_NONE) { | 385 | if (err != SC_ERR_NONE) { |
382 | printf("PLL0 set clock rate failed! (error = %d)\n", err); | 386 | printf("PLL0 set clock rate failed! (error = %d)\n", err); |
383 | return -EIO; | 387 | return -EIO; |
384 | } | 388 | } |
385 | 389 | ||
386 | err = sc_pm_set_clock_rate(ipcHndl, pll1_rsrc, SC_PM_CLK_PLL, &pll_clk); | 390 | err = sc_pm_set_clock_rate(ipcHndl, pll1_rsrc, SC_PM_CLK_PLL, &pll_clk); |
387 | if (err != SC_ERR_NONE) { | 391 | if (err != SC_ERR_NONE) { |
388 | printf("PLL1 set clock rate failed! (error = %d)\n", err); | 392 | printf("PLL1 set clock rate failed! (error = %d)\n", err); |
389 | return -EIO; | 393 | return -EIO; |
390 | } | 394 | } |
391 | 395 | ||
392 | err = sc_pm_set_clock_rate(ipcHndl, dc_rsrc, SC_PM_CLK_MISC0, &pixel_clock); | 396 | err = sc_pm_set_clock_rate(ipcHndl, dc_rsrc, SC_PM_CLK_MISC0, &pixel_clock); |
393 | if (err != SC_ERR_NONE) { | 397 | if (err != SC_ERR_NONE) { |
394 | printf("DISP0 set clock rate failed! (error = %d)\n", err); | 398 | printf("DISP0 set clock rate failed! (error = %d)\n", err); |
395 | return -EIO; | 399 | return -EIO; |
396 | } | 400 | } |
397 | 401 | ||
398 | err = sc_pm_set_clock_rate(ipcHndl, dc_rsrc, SC_PM_CLK_MISC1, &pixel_clock); | 402 | err = sc_pm_set_clock_rate(ipcHndl, dc_rsrc, SC_PM_CLK_MISC1, &pixel_clock); |
399 | if (err != SC_ERR_NONE) { | 403 | if (err != SC_ERR_NONE) { |
400 | printf("DISP1 set clock rate failed! (error = %d)\n", err); | 404 | printf("DISP1 set clock rate failed! (error = %d)\n", err); |
401 | return -EIO; | 405 | return -EIO; |
402 | } | 406 | } |
403 | 407 | ||
404 | err = sc_pm_clock_enable(ipcHndl, pll0_rsrc, SC_PM_CLK_PLL, true, false); | 408 | err = sc_pm_clock_enable(ipcHndl, pll0_rsrc, SC_PM_CLK_PLL, true, false); |
405 | if (err != SC_ERR_NONE) { | 409 | if (err != SC_ERR_NONE) { |
406 | printf("PLL0 clock enable failed! (error = %d)\n", err); | 410 | printf("PLL0 clock enable failed! (error = %d)\n", err); |
407 | return -EIO; | 411 | return -EIO; |
408 | } | 412 | } |
409 | 413 | ||
410 | err = sc_pm_clock_enable(ipcHndl, pll1_rsrc, SC_PM_CLK_PLL, true, false); | 414 | err = sc_pm_clock_enable(ipcHndl, pll1_rsrc, SC_PM_CLK_PLL, true, false); |
411 | if (err != SC_ERR_NONE) { | 415 | if (err != SC_ERR_NONE) { |
412 | printf("PLL1 clock enable failed! (error = %d)\n", err); | 416 | printf("PLL1 clock enable failed! (error = %d)\n", err); |
413 | return -EIO; | 417 | return -EIO; |
414 | } | 418 | } |
415 | 419 | ||
416 | err = sc_pm_clock_enable(ipcHndl, dc_rsrc, SC_PM_CLK_MISC0, true, false); | 420 | err = sc_pm_clock_enable(ipcHndl, dc_rsrc, SC_PM_CLK_MISC0, true, false); |
417 | if (err != SC_ERR_NONE) { | 421 | if (err != SC_ERR_NONE) { |
418 | printf("DISP0 clock enable failed! (error = %d)\n", err); | 422 | printf("DISP0 clock enable failed! (error = %d)\n", err); |
419 | return -EIO; | 423 | return -EIO; |
420 | } | 424 | } |
421 | 425 | ||
422 | err = sc_pm_clock_enable(ipcHndl, dc_rsrc, SC_PM_CLK_MISC1, true, false); | 426 | err = sc_pm_clock_enable(ipcHndl, dc_rsrc, SC_PM_CLK_MISC1, true, false); |
423 | if (err != SC_ERR_NONE) { | 427 | if (err != SC_ERR_NONE) { |
424 | printf("DISP1 clock enable failed! (error = %d)\n", err); | 428 | printf("DISP1 clock enable failed! (error = %d)\n", err); |
425 | return -EIO; | 429 | return -EIO; |
426 | } | 430 | } |
431 | |||
432 | LPCG_AllClockOn(dc_lpcg); | ||
427 | 433 | ||
428 | err = sc_misc_set_control(ipcHndl, dc_rsrc, SC_C_PXL_LINK_MST1_ADDR, 0); | 434 | err = sc_misc_set_control(ipcHndl, dc_rsrc, SC_C_PXL_LINK_MST1_ADDR, 0); |
429 | if (err != SC_ERR_NONE) { | 435 | if (err != SC_ERR_NONE) { |
430 | printf("DC Set control fSC_C_PXL_LINK_MST1_ADDR ailed! (error = %d)\n", err); | 436 | printf("DC Set control fSC_C_PXL_LINK_MST1_ADDR ailed! (error = %d)\n", err); |
431 | return -EIO; | 437 | return -EIO; |
432 | } | 438 | } |
433 | 439 | ||
434 | err = sc_misc_set_control(ipcHndl, dc_rsrc, SC_C_PXL_LINK_MST1_ENB, 1); | 440 | err = sc_misc_set_control(ipcHndl, dc_rsrc, SC_C_PXL_LINK_MST1_ENB, 1); |
435 | if (err != SC_ERR_NONE) { | 441 | if (err != SC_ERR_NONE) { |
436 | printf("DC Set control SC_C_PXL_LINK_MST1_ENB failed! (error = %d)\n", err); | 442 | printf("DC Set control SC_C_PXL_LINK_MST1_ENB failed! (error = %d)\n", err); |
437 | return -EIO; | 443 | return -EIO; |
438 | } | 444 | } |
439 | 445 | ||
440 | err = sc_misc_set_control(ipcHndl, dc_rsrc, SC_C_PXL_LINK_MST1_VLD, 1); | 446 | err = sc_misc_set_control(ipcHndl, dc_rsrc, SC_C_PXL_LINK_MST1_VLD, 1); |
441 | if (err != SC_ERR_NONE) { | 447 | if (err != SC_ERR_NONE) { |
442 | printf("DC Set control SC_C_PXL_LINK_MST1_VLD failed! (error = %d)\n", err); | 448 | printf("DC Set control SC_C_PXL_LINK_MST1_VLD failed! (error = %d)\n", err); |
443 | return -EIO; | 449 | return -EIO; |
444 | } | 450 | } |
445 | 451 | ||
446 | err = sc_misc_set_control(ipcHndl, dc_rsrc, SC_C_PXL_LINK_MST2_ADDR, 0); | 452 | err = sc_misc_set_control(ipcHndl, dc_rsrc, SC_C_PXL_LINK_MST2_ADDR, 0); |
447 | if (err != SC_ERR_NONE) { | 453 | if (err != SC_ERR_NONE) { |
448 | printf("DC Set control SC_C_PXL_LINK_MST2_ADDR ailed! (error = %d)\n", err); | 454 | printf("DC Set control SC_C_PXL_LINK_MST2_ADDR ailed! (error = %d)\n", err); |
449 | return -EIO; | 455 | return -EIO; |
450 | } | 456 | } |
451 | 457 | ||
452 | err = sc_misc_set_control(ipcHndl, dc_rsrc, SC_C_PXL_LINK_MST2_ENB, 1); | 458 | err = sc_misc_set_control(ipcHndl, dc_rsrc, SC_C_PXL_LINK_MST2_ENB, 1); |
453 | if (err != SC_ERR_NONE) { | 459 | if (err != SC_ERR_NONE) { |
454 | printf("DC Set control SC_C_PXL_LINK_MST2_ENB failed! (error = %d)\n", err); | 460 | printf("DC Set control SC_C_PXL_LINK_MST2_ENB failed! (error = %d)\n", err); |
455 | return -EIO; | 461 | return -EIO; |
456 | } | 462 | } |
457 | 463 | ||
458 | err = sc_misc_set_control(ipcHndl, dc_rsrc, SC_C_PXL_LINK_MST2_VLD, 1); | 464 | err = sc_misc_set_control(ipcHndl, dc_rsrc, SC_C_PXL_LINK_MST2_VLD, 1); |
459 | if (err != SC_ERR_NONE) { | 465 | if (err != SC_ERR_NONE) { |
460 | printf("DC Set control SC_C_PXL_LINK_MST2_VLD failed! (error = %d)\n", err); | 466 | printf("DC Set control SC_C_PXL_LINK_MST2_VLD failed! (error = %d)\n", err); |
461 | return -EIO; | 467 | return -EIO; |
462 | } | 468 | } |
463 | 469 | ||
464 | err = sc_misc_set_control(ipcHndl, dc_rsrc, SC_C_SYNC_CTRL0, 1); | 470 | err = sc_misc_set_control(ipcHndl, dc_rsrc, SC_C_SYNC_CTRL0, 1); |
465 | if (err != SC_ERR_NONE) { | 471 | if (err != SC_ERR_NONE) { |
466 | printf("DC Set control SC_C_SYNC_CTRL0 failed! (error = %d)\n", err); | 472 | printf("DC Set control SC_C_SYNC_CTRL0 failed! (error = %d)\n", err); |
467 | return -EIO; | 473 | return -EIO; |
468 | } | 474 | } |
469 | 475 | ||
470 | err = sc_misc_set_control(ipcHndl, dc_rsrc, SC_C_SYNC_CTRL1, 1); | 476 | err = sc_misc_set_control(ipcHndl, dc_rsrc, SC_C_SYNC_CTRL1, 1); |
471 | if (err != SC_ERR_NONE) { | 477 | if (err != SC_ERR_NONE) { |
472 | printf("DC Set control SC_C_SYNC_CTRL1 failed! (error = %d)\n", err); | 478 | printf("DC Set control SC_C_SYNC_CTRL1 failed! (error = %d)\n", err); |
473 | return -EIO; | 479 | return -EIO; |
474 | } | 480 | } |
475 | 481 | ||
476 | return 0; | 482 | return 0; |
477 | } | 483 | } |
478 | 484 | ||
479 | void *video_hw_init(void) | 485 | void *video_hw_init(void) |
480 | { | 486 | { |
481 | imxdpuv1_channel_params_t channel; | 487 | imxdpuv1_channel_params_t channel; |
482 | imxdpuv1_layer_t layer; | 488 | imxdpuv1_layer_t layer; |
483 | void *fb; | 489 | void *fb; |
484 | 490 | ||
485 | int8_t imxdpuv1_id = gdc; | 491 | int8_t imxdpuv1_id = gdc; |
486 | 492 | ||
487 | if (imxdpuv1_id != 0 || (imxdpuv1_id == 1 && !is_imx8qm())) { | 493 | if (imxdpuv1_id != 0 || (imxdpuv1_id == 1 && !is_imx8qm())) { |
488 | printf("%s(): invalid imxdpuv1_id %d", __func__, imxdpuv1_id); | 494 | printf("%s(): invalid imxdpuv1_id %d", __func__, imxdpuv1_id); |
489 | return NULL; | 495 | return NULL; |
490 | } | 496 | } |
491 | 497 | ||
492 | panel.winSizeX = gmode.hlen; | 498 | panel.winSizeX = gmode.hlen; |
493 | panel.winSizeY = gmode.vlen; | 499 | panel.winSizeY = gmode.vlen; |
494 | panel.plnSizeX = gmode.hlen; | 500 | panel.plnSizeX = gmode.hlen; |
495 | panel.plnSizeY = gmode.vlen; | 501 | panel.plnSizeY = gmode.vlen; |
496 | 502 | ||
497 | panel.gdfBytesPP = 4; | 503 | panel.gdfBytesPP = 4; |
498 | panel.gdfIndex = GDF_32BIT_X888RGB; | 504 | panel.gdfIndex = GDF_32BIT_X888RGB; |
499 | 505 | ||
500 | panel.memSize = gmode.hlen * gmode.vlen * panel.gdfBytesPP; | 506 | panel.memSize = gmode.hlen * gmode.vlen * panel.gdfBytesPP; |
501 | 507 | ||
502 | /* Allocate framebuffer */ | 508 | /* Allocate framebuffer */ |
503 | fb = memalign(0x1000, | 509 | fb = memalign(0x1000, |
504 | roundup(panel.memSize, 0x1000)); | 510 | roundup(panel.memSize, 0x1000)); |
505 | if (!fb) { | 511 | if (!fb) { |
506 | printf("IMXDPUv1: Error allocating framebuffer!\n"); | 512 | printf("IMXDPUv1: Error allocating framebuffer!\n"); |
507 | return NULL; | 513 | return NULL; |
508 | } | 514 | } |
509 | 515 | ||
510 | /* Wipe framebuffer */ | 516 | /* Wipe framebuffer */ |
511 | memset(fb, 0, panel.memSize); | 517 | memset(fb, 0, panel.memSize); |
512 | 518 | ||
513 | panel.frameAdrs = (ulong)fb; | 519 | panel.frameAdrs = (ulong)fb; |
514 | 520 | ||
515 | imxdpuv1_init(imxdpuv1_id); | 521 | imxdpuv1_init(imxdpuv1_id); |
516 | imxdpuv1_disp_enable_frame_gen(imxdpuv1_id, 0, IMXDPUV1_FALSE); | 522 | imxdpuv1_disp_enable_frame_gen(imxdpuv1_id, 0, IMXDPUV1_FALSE); |
517 | imxdpuv1_disp_enable_frame_gen(imxdpuv1_id, 1, IMXDPUV1_FALSE); | 523 | imxdpuv1_disp_enable_frame_gen(imxdpuv1_id, 1, IMXDPUV1_FALSE); |
518 | 524 | ||
519 | imxdpuv1_disp_setup_frame_gen(imxdpuv1_id, gdisp, | 525 | imxdpuv1_disp_setup_frame_gen(imxdpuv1_id, gdisp, |
520 | (const struct imxdpuv1_videomode *)&gmode, | 526 | (const struct imxdpuv1_videomode *)&gmode, |
521 | 0x3ff, 0, 0, 1, IMXDPUV1_DISABLE); | 527 | 0x3ff, 0, 0, 1, IMXDPUV1_DISABLE); |
522 | imxdpuv1_disp_init(imxdpuv1_id, gdisp); | 528 | imxdpuv1_disp_init(imxdpuv1_id, gdisp); |
523 | imxdpuv1_disp_setup_constframe(imxdpuv1_id, | 529 | imxdpuv1_disp_setup_constframe(imxdpuv1_id, |
524 | gdisp, 0, 0, 0xff, 0); /* blue */ | 530 | gdisp, 0, 0, 0xff, 0); /* blue */ |
525 | 531 | ||
526 | if (gdisp == 0) | 532 | if (gdisp == 0) |
527 | channel.common.chan = IMXDPUV1_CHAN_VIDEO_0; | 533 | channel.common.chan = IMXDPUV1_CHAN_VIDEO_0; |
528 | else | 534 | else |
529 | channel.common.chan = IMXDPUV1_CHAN_VIDEO_1; | 535 | channel.common.chan = IMXDPUV1_CHAN_VIDEO_1; |
530 | channel.common.src_pixel_fmt = gpixfmt; | 536 | channel.common.src_pixel_fmt = gpixfmt; |
531 | channel.common.dest_pixel_fmt = gpixfmt; | 537 | channel.common.dest_pixel_fmt = gpixfmt; |
532 | channel.common.src_width = gmode.hlen; | 538 | channel.common.src_width = gmode.hlen; |
533 | channel.common.src_height = gmode.vlen; | 539 | channel.common.src_height = gmode.vlen; |
534 | 540 | ||
535 | channel.common.clip_width = 0; | 541 | channel.common.clip_width = 0; |
536 | channel.common.clip_height = 0; | 542 | channel.common.clip_height = 0; |
537 | channel.common.clip_top = 0; | 543 | channel.common.clip_top = 0; |
538 | channel.common.clip_left = 0; | 544 | channel.common.clip_left = 0; |
539 | 545 | ||
540 | channel.common.dest_width = gmode.hlen; | 546 | channel.common.dest_width = gmode.hlen; |
541 | channel.common.dest_height = gmode.vlen; | 547 | channel.common.dest_height = gmode.vlen; |
542 | channel.common.dest_top = 0; | 548 | channel.common.dest_top = 0; |
543 | channel.common.dest_left = 0; | 549 | channel.common.dest_left = 0; |
544 | channel.common.stride = | 550 | channel.common.stride = |
545 | gmode.hlen * imxdpuv1_bytes_per_pixel(IMXDPUV1_PIX_FMT_BGRA32); | 551 | gmode.hlen * imxdpuv1_bytes_per_pixel(IMXDPUV1_PIX_FMT_BGRA32); |
546 | channel.common.disp_id = gdisp; | 552 | channel.common.disp_id = gdisp; |
547 | channel.common.const_color = 0; | 553 | channel.common.const_color = 0; |
548 | channel.common.use_global_alpha = 0; | 554 | channel.common.use_global_alpha = 0; |
549 | channel.common.use_local_alpha = 0; | 555 | channel.common.use_local_alpha = 0; |
550 | imxdpuv1_init_channel(imxdpuv1_id, &channel); | 556 | imxdpuv1_init_channel(imxdpuv1_id, &channel); |
551 | 557 | ||
552 | imxdpuv1_init_channel_buffer(imxdpuv1_id, | 558 | imxdpuv1_init_channel_buffer(imxdpuv1_id, |
553 | channel.common.chan, | 559 | channel.common.chan, |
554 | gmode.hlen * imxdpuv1_bytes_per_pixel(IMXDPUV1_PIX_FMT_RGB32), | 560 | gmode.hlen * imxdpuv1_bytes_per_pixel(IMXDPUV1_PIX_FMT_RGB32), |
555 | IMXDPUV1_ROTATE_NONE, | 561 | IMXDPUV1_ROTATE_NONE, |
556 | (dma_addr_t)fb, | 562 | (dma_addr_t)fb, |
557 | 0, | 563 | 0, |
558 | 0); | 564 | 0); |
559 | 565 | ||
560 | layer.enable = IMXDPUV1_TRUE; | 566 | layer.enable = IMXDPUV1_TRUE; |
561 | layer.secondary = get_channel_blk(channel.common.chan); | 567 | layer.secondary = get_channel_blk(channel.common.chan); |
562 | 568 | ||
563 | if (gdisp == 0) { | 569 | if (gdisp == 0) { |
564 | layer.stream = IMXDPUV1_DISPLAY_STREAM_0; | 570 | layer.stream = IMXDPUV1_DISPLAY_STREAM_0; |
565 | layer.primary = IMXDPUV1_ID_CONSTFRAME0; | 571 | layer.primary = IMXDPUV1_ID_CONSTFRAME0; |
566 | } else { | 572 | } else { |
567 | layer.stream = IMXDPUV1_DISPLAY_STREAM_1; | 573 | layer.stream = IMXDPUV1_DISPLAY_STREAM_1; |
568 | layer.primary = IMXDPUV1_ID_CONSTFRAME1; | 574 | layer.primary = IMXDPUV1_ID_CONSTFRAME1; |
569 | } | 575 | } |
570 | 576 | ||
571 | imxdpuv1_disp_setup_layer( | 577 | imxdpuv1_disp_setup_layer( |
572 | imxdpuv1_id, &layer, IMXDPUV1_LAYER_0, 1); | 578 | imxdpuv1_id, &layer, IMXDPUV1_LAYER_0, 1); |
573 | imxdpuv1_disp_set_layer_global_alpha( | 579 | imxdpuv1_disp_set_layer_global_alpha( |
574 | imxdpuv1_id, IMXDPUV1_LAYER_0, 0xff); | 580 | imxdpuv1_id, IMXDPUV1_LAYER_0, 0xff); |
575 | 581 | ||
576 | imxdpuv1_disp_set_layer_position( | 582 | imxdpuv1_disp_set_layer_position( |
577 | imxdpuv1_id, IMXDPUV1_LAYER_0, 0, 0); | 583 | imxdpuv1_id, IMXDPUV1_LAYER_0, 0, 0); |
578 | imxdpuv1_disp_set_chan_position( | 584 | imxdpuv1_disp_set_chan_position( |
579 | imxdpuv1_id, channel.common.chan, 0, 0); | 585 | imxdpuv1_id, channel.common.chan, 0, 0); |
580 | 586 | ||
581 | imxdpuv1_disp_enable_frame_gen(imxdpuv1_id, gdisp, IMXDPUV1_ENABLE); | 587 | imxdpuv1_disp_enable_frame_gen(imxdpuv1_id, gdisp, IMXDPUV1_ENABLE); |
582 | 588 | ||
583 | debug("IMXDPU display start ...\n"); | 589 | debug("IMXDPU display start ...\n"); |
584 | 590 | ||
585 | return &panel; | 591 | return &panel; |
586 | } | 592 | } |
587 | 593 | ||
588 | void imxdpuv1_fb_disable(void) | 594 | void imxdpuv1_fb_disable(void) |
589 | { | 595 | { |
590 | /* Disable video only when video init is done */ | 596 | /* Disable video only when video init is done */ |
591 | if (panel.frameAdrs) | 597 | if (panel.frameAdrs) |
592 | imxdpuv1_disp_enable_frame_gen(gdc, gdisp, IMXDPUV1_DISABLE); | 598 | imxdpuv1_disp_enable_frame_gen(gdc, gdisp, IMXDPUV1_DISABLE); |
593 | } | 599 | } |
594 | 600 | ||
595 | int imxdpuv1_fb_init(struct fb_videomode const *mode, | 601 | int imxdpuv1_fb_init(struct fb_videomode const *mode, |
596 | uint8_t disp, uint32_t pixfmt) | 602 | uint8_t disp, uint32_t pixfmt) |
597 | { | 603 | { |
598 | if (disp > 1) { | 604 | if (disp > 1) { |
599 | printf("Invalid disp parameter %d for imxdpuv1_fb_init\n", disp); | 605 | printf("Invalid disp parameter %d for imxdpuv1_fb_init\n", disp); |
600 | return -EINVAL; | 606 | return -EINVAL; |
601 | } | 607 | } |
602 | 608 | ||
603 | memset(&gmode, 0, sizeof(struct imxdpuv1_videomode)); | 609 | memset(&gmode, 0, sizeof(struct imxdpuv1_videomode)); |
604 | gmode.pixelclock = PS2KHZ(mode->pixclock) * 1000; | 610 | gmode.pixelclock = PS2KHZ(mode->pixclock) * 1000; |
605 | gmode.hlen = mode->xres; | 611 | gmode.hlen = mode->xres; |
606 | gmode.hbp = mode->left_margin; | 612 | gmode.hbp = mode->left_margin; |
607 | gmode.hfp = mode->right_margin; | 613 | gmode.hfp = mode->right_margin; |
608 | 614 | ||
609 | gmode.vlen = mode->yres; | 615 | gmode.vlen = mode->yres; |
610 | gmode.vbp = mode->upper_margin; | 616 | gmode.vbp = mode->upper_margin; |
611 | gmode.vfp = mode->lower_margin; | 617 | gmode.vfp = mode->lower_margin; |
612 | 618 | ||
613 | gmode.hsync = mode->hsync_len; | 619 | gmode.hsync = mode->hsync_len; |
614 | gmode.vsync = mode->vsync_len; | 620 | gmode.vsync = mode->vsync_len; |
615 | gmode.flags = IMXDPUV1_MODE_FLAGS_HSYNC_POL | IMXDPUV1_MODE_FLAGS_VSYNC_POL | IMXDPUV1_MODE_FLAGS_DE_POL; | 621 | gmode.flags = IMXDPUV1_MODE_FLAGS_HSYNC_POL | IMXDPUV1_MODE_FLAGS_VSYNC_POL | IMXDPUV1_MODE_FLAGS_DE_POL; |
616 | 622 | ||
617 | if (is_imx8qm()) { /* QM has two DCs each contains one LVDS as secondary display output */ | 623 | if (is_imx8qm()) { /* QM has two DCs each contains one LVDS as secondary display output */ |
618 | gdisp = 1; | 624 | gdisp = 1; |
619 | gdc = disp; | 625 | gdc = disp; |
620 | } else if (is_imx8qxp()) { /* QXP has one DC which contains 2 LVDS/MIPI_DSI combo */ | 626 | } else if (is_imx8qxp()) { /* QXP has one DC which contains 2 LVDS/MIPI_DSI combo */ |
621 | gdisp = disp; | 627 | gdisp = disp; |
622 | gdc = 0; | 628 | gdc = 0; |
623 | } else { | 629 | } else { |
624 | printf("Unsupported SOC for imxdpuv1_fb_init\n"); | 630 | printf("Unsupported SOC for imxdpuv1_fb_init\n"); |
625 | return -EPERM; | 631 | return -EPERM; |
626 | } | 632 | } |
627 | 633 | ||
628 | gpixfmt = pixfmt; | 634 | gpixfmt = pixfmt; |
629 | 635 | ||
630 | debug("imxdpuv1_fb_init, dc=%d, disp=%d\n", gdc, gdisp); | 636 | debug("imxdpuv1_fb_init, dc=%d, disp=%d\n", gdc, gdisp); |
631 | 637 | ||
632 | return 0; | 638 | return 0; |
633 | } | 639 | } |
634 | 640 | ||
635 | 641 |
board/freescale/imx8qm_arm2/imx8qm_arm2.c
1 | /* | 1 | /* |
2 | * Copyright 2017-2018 NXP | 2 | * Copyright 2017-2018 NXP |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: GPL-2.0+ | 4 | * SPDX-License-Identifier: GPL-2.0+ |
5 | */ | 5 | */ |
6 | #include <common.h> | 6 | #include <common.h> |
7 | #include <malloc.h> | 7 | #include <malloc.h> |
8 | #include <errno.h> | 8 | #include <errno.h> |
9 | #include <netdev.h> | 9 | #include <netdev.h> |
10 | #include <fsl_ifc.h> | 10 | #include <fsl_ifc.h> |
11 | #include <fdt_support.h> | 11 | #include <fdt_support.h> |
12 | #include <linux/libfdt.h> | 12 | #include <linux/libfdt.h> |
13 | #include <environment.h> | 13 | #include <environment.h> |
14 | #include <fsl_esdhc.h> | 14 | #include <fsl_esdhc.h> |
15 | #include <i2c.h> | 15 | #include <i2c.h> |
16 | #include "pca953x.h" | 16 | #include "pca953x.h" |
17 | 17 | ||
18 | #include <asm/io.h> | 18 | #include <asm/io.h> |
19 | #include <asm/gpio.h> | 19 | #include <asm/gpio.h> |
20 | #include <asm/arch/clock.h> | 20 | #include <asm/arch/clock.h> |
21 | #include <asm/mach-imx/sci/sci.h> | 21 | #include <asm/mach-imx/sci/sci.h> |
22 | #include <asm/arch/imx8-pins.h> | 22 | #include <asm/arch/imx8-pins.h> |
23 | #include <dm.h> | 23 | #include <dm.h> |
24 | #include <imx8_hsio.h> | 24 | #include <imx8_hsio.h> |
25 | #include <usb.h> | 25 | #include <usb.h> |
26 | #include <asm/arch/iomux.h> | 26 | #include <asm/arch/iomux.h> |
27 | #include <asm/arch/sys_proto.h> | 27 | #include <asm/arch/sys_proto.h> |
28 | #include <asm/mach-imx/video.h> | 28 | #include <asm/mach-imx/video.h> |
29 | #include <asm/arch/video_common.h> | 29 | #include <asm/arch/video_common.h> |
30 | #include <power-domain.h> | 30 | #include <power-domain.h> |
31 | #include <cdns3-uboot.h> | 31 | #include <cdns3-uboot.h> |
32 | #include <asm/arch/lpcg.h> | ||
32 | 33 | ||
33 | DECLARE_GLOBAL_DATA_PTR; | 34 | DECLARE_GLOBAL_DATA_PTR; |
34 | 35 | ||
35 | #define ESDHC_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 36 | #define ESDHC_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
36 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 37 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
37 | 38 | ||
38 | #define ESDHC_CLK_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 39 | #define ESDHC_CLK_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
39 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 40 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
40 | 41 | ||
41 | 42 | ||
42 | #define ENET_INPUT_PAD_CTRL ((SC_PAD_CONFIG_OD_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 43 | #define ENET_INPUT_PAD_CTRL ((SC_PAD_CONFIG_OD_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
43 | | (SC_PAD_28FDSOI_DSE_18V_10MA << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 44 | | (SC_PAD_28FDSOI_DSE_18V_10MA << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
44 | 45 | ||
45 | #define ENET_NORMAL_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 46 | #define ENET_NORMAL_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
46 | | (SC_PAD_28FDSOI_DSE_18V_10MA << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 47 | | (SC_PAD_28FDSOI_DSE_18V_10MA << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
47 | 48 | ||
48 | #define FSPI_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 49 | #define FSPI_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
49 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 50 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
50 | 51 | ||
51 | #define GPIO_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 52 | #define GPIO_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
52 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 53 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
53 | 54 | ||
54 | #define I2C_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 55 | #define I2C_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
55 | | (SC_PAD_28FDSOI_DSE_DV_LOW << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 56 | | (SC_PAD_28FDSOI_DSE_DV_LOW << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
56 | 57 | ||
57 | #define UART_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 58 | #define UART_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
58 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 59 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
59 | 60 | ||
60 | static iomux_cfg_t uart0_pads[] = { | 61 | static iomux_cfg_t uart0_pads[] = { |
61 | SC_P_UART0_RX | MUX_PAD_CTRL(UART_PAD_CTRL), | 62 | SC_P_UART0_RX | MUX_PAD_CTRL(UART_PAD_CTRL), |
62 | SC_P_UART0_TX | MUX_PAD_CTRL(UART_PAD_CTRL), | 63 | SC_P_UART0_TX | MUX_PAD_CTRL(UART_PAD_CTRL), |
63 | }; | 64 | }; |
64 | 65 | ||
65 | static void setup_iomux_uart(void) | 66 | static void setup_iomux_uart(void) |
66 | { | 67 | { |
67 | imx8_iomux_setup_multiple_pads(uart0_pads, ARRAY_SIZE(uart0_pads)); | 68 | imx8_iomux_setup_multiple_pads(uart0_pads, ARRAY_SIZE(uart0_pads)); |
68 | } | 69 | } |
69 | 70 | ||
70 | int board_early_init_f(void) | 71 | int board_early_init_f(void) |
71 | { | 72 | { |
72 | sc_ipc_t ipcHndl = 0; | 73 | sc_ipc_t ipcHndl = 0; |
73 | sc_err_t sciErr = 0; | 74 | sc_err_t sciErr = 0; |
74 | 75 | ||
75 | ipcHndl = gd->arch.ipc_channel_handle; | 76 | ipcHndl = gd->arch.ipc_channel_handle; |
76 | 77 | ||
77 | /* Power up UART0, this is very early while power domain is not working */ | 78 | /* Power up UART0, this is very early while power domain is not working */ |
78 | sciErr = sc_pm_set_resource_power_mode(ipcHndl, SC_R_UART_0, SC_PM_PW_MODE_ON); | 79 | sciErr = sc_pm_set_resource_power_mode(ipcHndl, SC_R_UART_0, SC_PM_PW_MODE_ON); |
79 | if (sciErr != SC_ERR_NONE) | 80 | if (sciErr != SC_ERR_NONE) |
80 | return 0; | 81 | return 0; |
81 | 82 | ||
82 | /* Set UART0 clock root to 80 MHz */ | 83 | /* Set UART0 clock root to 80 MHz */ |
83 | sc_pm_clock_rate_t rate = 80000000; | 84 | sc_pm_clock_rate_t rate = 80000000; |
84 | sciErr = sc_pm_set_clock_rate(ipcHndl, SC_R_UART_0, 2, &rate); | 85 | sciErr = sc_pm_set_clock_rate(ipcHndl, SC_R_UART_0, 2, &rate); |
85 | if (sciErr != SC_ERR_NONE) | 86 | if (sciErr != SC_ERR_NONE) |
86 | return 0; | 87 | return 0; |
87 | 88 | ||
88 | /* Enable UART0 clock root */ | 89 | /* Enable UART0 clock root */ |
89 | sciErr = sc_pm_clock_enable(ipcHndl, SC_R_UART_0, 2, true, false); | 90 | sciErr = sc_pm_clock_enable(ipcHndl, SC_R_UART_0, 2, true, false); |
90 | if (sciErr != SC_ERR_NONE) | 91 | if (sciErr != SC_ERR_NONE) |
91 | return 0; | 92 | return 0; |
92 | 93 | ||
94 | LPCG_AllClockOn(LPUART_0_LPCG); | ||
95 | |||
93 | setup_iomux_uart(); | 96 | setup_iomux_uart(); |
94 | 97 | ||
95 | return 0; | 98 | return 0; |
96 | } | 99 | } |
97 | 100 | ||
98 | #ifdef CONFIG_FSL_ESDHC | 101 | #ifdef CONFIG_FSL_ESDHC |
99 | 102 | ||
100 | #define USDHC1_CD_GPIO IMX_GPIO_NR(5, 22) | 103 | #define USDHC1_CD_GPIO IMX_GPIO_NR(5, 22) |
101 | #define USDHC2_CD_GPIO IMX_GPIO_NR(4, 12) | 104 | #define USDHC2_CD_GPIO IMX_GPIO_NR(4, 12) |
102 | 105 | ||
103 | #ifndef CONFIG_SPL_BUILD | 106 | #ifndef CONFIG_SPL_BUILD |
104 | 107 | ||
105 | static struct fsl_esdhc_cfg usdhc_cfg[CONFIG_SYS_FSL_USDHC_NUM] = { | 108 | static struct fsl_esdhc_cfg usdhc_cfg[CONFIG_SYS_FSL_USDHC_NUM] = { |
106 | #ifdef CONFIG_TARGET_IMX8QM_LPDDR4_ARM2 | 109 | #ifdef CONFIG_TARGET_IMX8QM_LPDDR4_ARM2 |
107 | {USDHC1_BASE_ADDR, 0, 8}, | 110 | {USDHC1_BASE_ADDR, 0, 8}, |
108 | {USDHC2_BASE_ADDR, 0, 4}, | 111 | {USDHC2_BASE_ADDR, 0, 4}, |
109 | #endif | 112 | #endif |
110 | {USDHC3_BASE_ADDR, 0, 4}, | 113 | {USDHC3_BASE_ADDR, 0, 4}, |
111 | }; | 114 | }; |
112 | 115 | ||
113 | #ifdef CONFIG_TARGET_IMX8QM_LPDDR4_ARM2 | 116 | #ifdef CONFIG_TARGET_IMX8QM_LPDDR4_ARM2 |
114 | static iomux_cfg_t emmc0[] = { | 117 | static iomux_cfg_t emmc0[] = { |
115 | SC_P_EMMC0_CLK | MUX_PAD_CTRL(ESDHC_CLK_PAD_CTRL), | 118 | SC_P_EMMC0_CLK | MUX_PAD_CTRL(ESDHC_CLK_PAD_CTRL), |
116 | SC_P_EMMC0_CMD | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 119 | SC_P_EMMC0_CMD | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
117 | SC_P_EMMC0_DATA0 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 120 | SC_P_EMMC0_DATA0 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
118 | SC_P_EMMC0_DATA1 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 121 | SC_P_EMMC0_DATA1 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
119 | SC_P_EMMC0_DATA2 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 122 | SC_P_EMMC0_DATA2 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
120 | SC_P_EMMC0_DATA3 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 123 | SC_P_EMMC0_DATA3 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
121 | SC_P_EMMC0_DATA4 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 124 | SC_P_EMMC0_DATA4 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
122 | SC_P_EMMC0_DATA5 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 125 | SC_P_EMMC0_DATA5 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
123 | SC_P_EMMC0_DATA6 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 126 | SC_P_EMMC0_DATA6 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
124 | SC_P_EMMC0_DATA7 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 127 | SC_P_EMMC0_DATA7 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
125 | SC_P_EMMC0_RESET_B | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 128 | SC_P_EMMC0_RESET_B | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
126 | SC_P_EMMC0_STROBE | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 129 | SC_P_EMMC0_STROBE | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
127 | }; | 130 | }; |
128 | static iomux_cfg_t usdhc1_sd[] = { | 131 | static iomux_cfg_t usdhc1_sd[] = { |
129 | SC_P_USDHC1_CLK | MUX_PAD_CTRL(ESDHC_CLK_PAD_CTRL), | 132 | SC_P_USDHC1_CLK | MUX_PAD_CTRL(ESDHC_CLK_PAD_CTRL), |
130 | SC_P_USDHC1_CMD | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 133 | SC_P_USDHC1_CMD | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
131 | SC_P_USDHC1_DATA0 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 134 | SC_P_USDHC1_DATA0 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
132 | SC_P_USDHC1_DATA1 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 135 | SC_P_USDHC1_DATA1 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
133 | SC_P_USDHC1_DATA2 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 136 | SC_P_USDHC1_DATA2 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
134 | SC_P_USDHC1_DATA3 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 137 | SC_P_USDHC1_DATA3 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
135 | SC_P_USDHC1_DATA6 | MUX_MODE_ALT(2) | MUX_PAD_CTRL(ESDHC_PAD_CTRL), /* Mux for WP */ | 138 | SC_P_USDHC1_DATA6 | MUX_MODE_ALT(2) | MUX_PAD_CTRL(ESDHC_PAD_CTRL), /* Mux for WP */ |
136 | SC_P_USDHC1_DATA7 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ESDHC_PAD_CTRL), /* Mux for CD, GPIO5 IO22 */ | 139 | SC_P_USDHC1_DATA7 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ESDHC_PAD_CTRL), /* Mux for CD, GPIO5 IO22 */ |
137 | SC_P_USDHC1_RESET_B | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 140 | SC_P_USDHC1_RESET_B | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
138 | SC_P_USDHC1_VSELECT | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 141 | SC_P_USDHC1_VSELECT | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
139 | }; | 142 | }; |
140 | #endif | 143 | #endif |
141 | static iomux_cfg_t usdhc2_sd[] = { | 144 | static iomux_cfg_t usdhc2_sd[] = { |
142 | SC_P_USDHC2_CLK | MUX_PAD_CTRL(ESDHC_CLK_PAD_CTRL), | 145 | SC_P_USDHC2_CLK | MUX_PAD_CTRL(ESDHC_CLK_PAD_CTRL), |
143 | SC_P_USDHC2_CMD | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 146 | SC_P_USDHC2_CMD | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
144 | SC_P_USDHC2_DATA0 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 147 | SC_P_USDHC2_DATA0 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
145 | SC_P_USDHC2_DATA1 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 148 | SC_P_USDHC2_DATA1 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
146 | SC_P_USDHC2_DATA2 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 149 | SC_P_USDHC2_DATA2 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
147 | SC_P_USDHC2_DATA3 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 150 | SC_P_USDHC2_DATA3 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
148 | SC_P_USDHC2_RESET_B | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 151 | SC_P_USDHC2_RESET_B | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
149 | SC_P_USDHC2_WP | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 152 | SC_P_USDHC2_WP | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
150 | SC_P_USDHC2_CD_B | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ESDHC_PAD_CTRL), /* Mux to GPIO4 IO12 */ | 153 | SC_P_USDHC2_CD_B | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ESDHC_PAD_CTRL), /* Mux to GPIO4 IO12 */ |
151 | }; | 154 | }; |
152 | 155 | ||
153 | int board_mmc_init(bd_t *bis) | 156 | int board_mmc_init(bd_t *bis) |
154 | { | 157 | { |
155 | int i, ret; | 158 | int i, ret; |
156 | struct power_domain pd; | 159 | struct power_domain pd; |
157 | 160 | ||
158 | /* | 161 | /* |
159 | * According to the board_mmc_init() the following map is done: | 162 | * According to the board_mmc_init() the following map is done: |
160 | * (U-boot device node) (Physical Port) | 163 | * (U-boot device node) (Physical Port) |
161 | * mmc0 USDHC1 | 164 | * mmc0 USDHC1 |
162 | * mmc1 USDHC2 | 165 | * mmc1 USDHC2 |
163 | * mmc2 USDHC3 | 166 | * mmc2 USDHC3 |
164 | */ | 167 | */ |
165 | for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) { | 168 | for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) { |
166 | switch (i) { | 169 | switch (i) { |
167 | #ifdef CONFIG_TARGET_IMX8QM_LPDDR4_ARM2 | 170 | #ifdef CONFIG_TARGET_IMX8QM_LPDDR4_ARM2 |
168 | case 0: | 171 | case 0: |
169 | if (!power_domain_lookup_name("conn_sdhc0", &pd)) | 172 | if (!power_domain_lookup_name("conn_sdhc0", &pd)) |
170 | power_domain_on(&pd); | 173 | power_domain_on(&pd); |
171 | 174 | ||
172 | imx8_iomux_setup_multiple_pads(emmc0, ARRAY_SIZE(emmc0)); | 175 | imx8_iomux_setup_multiple_pads(emmc0, ARRAY_SIZE(emmc0)); |
173 | init_clk_usdhc(0); | 176 | init_clk_usdhc(0); |
174 | usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); | 177 | usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); |
175 | break; | 178 | break; |
176 | case 1: | 179 | case 1: |
177 | if (!power_domain_lookup_name("conn_sdhc1", &pd)) | 180 | if (!power_domain_lookup_name("conn_sdhc1", &pd)) |
178 | power_domain_on(&pd); | 181 | power_domain_on(&pd); |
179 | 182 | ||
180 | imx8_iomux_setup_multiple_pads(usdhc1_sd, ARRAY_SIZE(usdhc1_sd)); | 183 | imx8_iomux_setup_multiple_pads(usdhc1_sd, ARRAY_SIZE(usdhc1_sd)); |
181 | init_clk_usdhc(1); | 184 | init_clk_usdhc(1); |
182 | usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); | 185 | usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); |
183 | gpio_request(USDHC1_CD_GPIO, "sd1_cd"); | 186 | gpio_request(USDHC1_CD_GPIO, "sd1_cd"); |
184 | gpio_direction_input(USDHC1_CD_GPIO); | 187 | gpio_direction_input(USDHC1_CD_GPIO); |
185 | break; | 188 | break; |
186 | case 2: | 189 | case 2: |
187 | #else | 190 | #else |
188 | case 0: | 191 | case 0: |
189 | #endif | 192 | #endif |
190 | 193 | ||
191 | if (!power_domain_lookup_name("conn_sdhc2", &pd)) | 194 | if (!power_domain_lookup_name("conn_sdhc2", &pd)) |
192 | power_domain_on(&pd); | 195 | power_domain_on(&pd); |
193 | 196 | ||
194 | imx8_iomux_setup_multiple_pads(usdhc2_sd, ARRAY_SIZE(usdhc2_sd)); | 197 | imx8_iomux_setup_multiple_pads(usdhc2_sd, ARRAY_SIZE(usdhc2_sd)); |
195 | init_clk_usdhc(2); | 198 | init_clk_usdhc(2); |
196 | usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); | 199 | usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); |
197 | gpio_request(USDHC2_CD_GPIO, "sd2_cd"); | 200 | gpio_request(USDHC2_CD_GPIO, "sd2_cd"); |
198 | gpio_direction_input(USDHC2_CD_GPIO); | 201 | gpio_direction_input(USDHC2_CD_GPIO); |
199 | break; | 202 | break; |
200 | default: | 203 | default: |
201 | printf("Warning: you configured more USDHC controllers" | 204 | printf("Warning: you configured more USDHC controllers" |
202 | "(%d) than supported by the board\n", i + 1); | 205 | "(%d) than supported by the board\n", i + 1); |
203 | return 0; | 206 | return 0; |
204 | } | 207 | } |
205 | ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]); | 208 | ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]); |
206 | if (ret) { | 209 | if (ret) { |
207 | printf("Warning: failed to initialize mmc dev %d\n", i); | 210 | printf("Warning: failed to initialize mmc dev %d\n", i); |
208 | return ret; | 211 | return ret; |
209 | } | 212 | } |
210 | } | 213 | } |
211 | 214 | ||
212 | return 0; | 215 | return 0; |
213 | } | 216 | } |
214 | 217 | ||
215 | int board_mmc_getcd(struct mmc *mmc) | 218 | int board_mmc_getcd(struct mmc *mmc) |
216 | { | 219 | { |
217 | struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; | 220 | struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; |
218 | int ret = 0; | 221 | int ret = 0; |
219 | 222 | ||
220 | switch (cfg->esdhc_base) { | 223 | switch (cfg->esdhc_base) { |
221 | case USDHC1_BASE_ADDR: | 224 | case USDHC1_BASE_ADDR: |
222 | #ifdef CONFIG_TARGET_IMX8QM_LPDDR4_ARM2 | 225 | #ifdef CONFIG_TARGET_IMX8QM_LPDDR4_ARM2 |
223 | ret = 1; /* eMMC */ | 226 | ret = 1; /* eMMC */ |
224 | #else | 227 | #else |
225 | ret = 0; /* eMMC not present on DDR4 board */ | 228 | ret = 0; /* eMMC not present on DDR4 board */ |
226 | #endif | 229 | #endif |
227 | break; | 230 | break; |
228 | case USDHC2_BASE_ADDR: | 231 | case USDHC2_BASE_ADDR: |
229 | ret = !gpio_get_value(USDHC1_CD_GPIO); | 232 | ret = !gpio_get_value(USDHC1_CD_GPIO); |
230 | break; | 233 | break; |
231 | case USDHC3_BASE_ADDR: | 234 | case USDHC3_BASE_ADDR: |
232 | ret = !gpio_get_value(USDHC2_CD_GPIO); | 235 | ret = !gpio_get_value(USDHC2_CD_GPIO); |
233 | break; | 236 | break; |
234 | } | 237 | } |
235 | 238 | ||
236 | return ret; | 239 | return ret; |
237 | } | 240 | } |
238 | #endif /* CONFIG_SPL_BUILD */ | 241 | #endif /* CONFIG_SPL_BUILD */ |
239 | #endif /* CONFIG_FSL_ESDHC */ | 242 | #endif /* CONFIG_FSL_ESDHC */ |
240 | 243 | ||
241 | 244 | ||
242 | #ifdef CONFIG_FEC_MXC | 245 | #ifdef CONFIG_FEC_MXC |
243 | #include <miiphy.h> | 246 | #include <miiphy.h> |
244 | 247 | ||
245 | static iomux_cfg_t pad_enet1[] = { | 248 | static iomux_cfg_t pad_enet1[] = { |
246 | SC_P_ENET1_RGMII_RX_CTL | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 249 | SC_P_ENET1_RGMII_RX_CTL | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
247 | SC_P_ENET1_RGMII_RXD0 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 250 | SC_P_ENET1_RGMII_RXD0 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
248 | SC_P_ENET1_RGMII_RXD1 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 251 | SC_P_ENET1_RGMII_RXD1 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
249 | SC_P_ENET1_RGMII_RXD2 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 252 | SC_P_ENET1_RGMII_RXD2 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
250 | SC_P_ENET1_RGMII_RXD3 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 253 | SC_P_ENET1_RGMII_RXD3 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
251 | SC_P_ENET1_RGMII_RXC | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 254 | SC_P_ENET1_RGMII_RXC | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
252 | SC_P_ENET1_RGMII_TX_CTL | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 255 | SC_P_ENET1_RGMII_TX_CTL | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
253 | SC_P_ENET1_RGMII_TXD0 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 256 | SC_P_ENET1_RGMII_TXD0 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
254 | SC_P_ENET1_RGMII_TXD1 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 257 | SC_P_ENET1_RGMII_TXD1 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
255 | SC_P_ENET1_RGMII_TXD2 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 258 | SC_P_ENET1_RGMII_TXD2 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
256 | SC_P_ENET1_RGMII_TXD3 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 259 | SC_P_ENET1_RGMII_TXD3 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
257 | SC_P_ENET1_RGMII_TXC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 260 | SC_P_ENET1_RGMII_TXC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
258 | 261 | ||
259 | /* Shared MDIO */ | 262 | /* Shared MDIO */ |
260 | SC_P_ENET0_MDC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 263 | SC_P_ENET0_MDC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
261 | SC_P_ENET0_MDIO | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 264 | SC_P_ENET0_MDIO | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
262 | }; | 265 | }; |
263 | 266 | ||
264 | static iomux_cfg_t pad_enet0[] = { | 267 | static iomux_cfg_t pad_enet0[] = { |
265 | SC_P_ENET0_RGMII_RX_CTL | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 268 | SC_P_ENET0_RGMII_RX_CTL | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
266 | SC_P_ENET0_RGMII_RXD0 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 269 | SC_P_ENET0_RGMII_RXD0 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
267 | SC_P_ENET0_RGMII_RXD1 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 270 | SC_P_ENET0_RGMII_RXD1 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
268 | SC_P_ENET0_RGMII_RXD2 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 271 | SC_P_ENET0_RGMII_RXD2 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
269 | SC_P_ENET0_RGMII_RXD3 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 272 | SC_P_ENET0_RGMII_RXD3 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
270 | SC_P_ENET0_RGMII_RXC | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 273 | SC_P_ENET0_RGMII_RXC | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
271 | SC_P_ENET0_RGMII_TX_CTL | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 274 | SC_P_ENET0_RGMII_TX_CTL | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
272 | SC_P_ENET0_RGMII_TXD0 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 275 | SC_P_ENET0_RGMII_TXD0 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
273 | SC_P_ENET0_RGMII_TXD1 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 276 | SC_P_ENET0_RGMII_TXD1 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
274 | SC_P_ENET0_RGMII_TXD2 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 277 | SC_P_ENET0_RGMII_TXD2 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
275 | SC_P_ENET0_RGMII_TXD3 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 278 | SC_P_ENET0_RGMII_TXD3 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
276 | SC_P_ENET0_RGMII_TXC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 279 | SC_P_ENET0_RGMII_TXC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
277 | 280 | ||
278 | /* Shared MDIO */ | 281 | /* Shared MDIO */ |
279 | SC_P_ENET0_MDC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 282 | SC_P_ENET0_MDC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
280 | SC_P_ENET0_MDIO | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 283 | SC_P_ENET0_MDIO | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
281 | }; | 284 | }; |
282 | 285 | ||
283 | static void setup_iomux_fec(void) | 286 | static void setup_iomux_fec(void) |
284 | { | 287 | { |
285 | if (0 == CONFIG_FEC_ENET_DEV) | 288 | if (0 == CONFIG_FEC_ENET_DEV) |
286 | imx8_iomux_setup_multiple_pads(pad_enet0, ARRAY_SIZE(pad_enet0)); | 289 | imx8_iomux_setup_multiple_pads(pad_enet0, ARRAY_SIZE(pad_enet0)); |
287 | else | 290 | else |
288 | imx8_iomux_setup_multiple_pads(pad_enet1, ARRAY_SIZE(pad_enet1)); | 291 | imx8_iomux_setup_multiple_pads(pad_enet1, ARRAY_SIZE(pad_enet1)); |
289 | } | 292 | } |
290 | 293 | ||
291 | static void enet_device_phy_reset(void) | 294 | static void enet_device_phy_reset(void) |
292 | { | 295 | { |
293 | struct gpio_desc desc_enet0; | 296 | struct gpio_desc desc_enet0; |
294 | struct gpio_desc desc_enet1; | 297 | struct gpio_desc desc_enet1; |
295 | int ret; | 298 | int ret; |
296 | 299 | ||
297 | ret = dm_gpio_lookup_name("gpio@18_1", &desc_enet0); | 300 | ret = dm_gpio_lookup_name("gpio@18_1", &desc_enet0); |
298 | if (ret) | 301 | if (ret) |
299 | return; | 302 | return; |
300 | 303 | ||
301 | ret = dm_gpio_request(&desc_enet0, "enet0_reset"); | 304 | ret = dm_gpio_request(&desc_enet0, "enet0_reset"); |
302 | if (ret) | 305 | if (ret) |
303 | return; | 306 | return; |
304 | ret = dm_gpio_lookup_name("gpio@18_4", &desc_enet1); | 307 | ret = dm_gpio_lookup_name("gpio@18_4", &desc_enet1); |
305 | if (ret) | 308 | if (ret) |
306 | return; | 309 | return; |
307 | 310 | ||
308 | ret = dm_gpio_request(&desc_enet1, "enet1_reset"); | 311 | ret = dm_gpio_request(&desc_enet1, "enet1_reset"); |
309 | if (ret) | 312 | if (ret) |
310 | return; | 313 | return; |
311 | 314 | ||
312 | dm_gpio_set_dir_flags(&desc_enet0, GPIOD_IS_OUT); | 315 | dm_gpio_set_dir_flags(&desc_enet0, GPIOD_IS_OUT); |
313 | dm_gpio_set_value(&desc_enet0, 0); | 316 | dm_gpio_set_value(&desc_enet0, 0); |
314 | udelay(50); | 317 | udelay(50); |
315 | dm_gpio_set_value(&desc_enet0, 1); | 318 | dm_gpio_set_value(&desc_enet0, 1); |
316 | 319 | ||
317 | dm_gpio_set_dir_flags(&desc_enet1, GPIOD_IS_OUT); | 320 | dm_gpio_set_dir_flags(&desc_enet1, GPIOD_IS_OUT); |
318 | dm_gpio_set_value(&desc_enet1, 0); | 321 | dm_gpio_set_value(&desc_enet1, 0); |
319 | udelay(50); | 322 | udelay(50); |
320 | dm_gpio_set_value(&desc_enet1, 1); | 323 | dm_gpio_set_value(&desc_enet1, 1); |
321 | 324 | ||
322 | /* The board has a long delay for this reset to become stable */ | 325 | /* The board has a long delay for this reset to become stable */ |
323 | mdelay(200); | 326 | mdelay(200); |
324 | } | 327 | } |
325 | 328 | ||
326 | int board_eth_init(bd_t *bis) | 329 | int board_eth_init(bd_t *bis) |
327 | { | 330 | { |
328 | int ret; | 331 | int ret; |
329 | struct power_domain pd; | 332 | struct power_domain pd; |
330 | 333 | ||
331 | printf("[%s] %d\n", __func__, __LINE__); | 334 | printf("[%s] %d\n", __func__, __LINE__); |
332 | 335 | ||
333 | if (CONFIG_FEC_ENET_DEV) { | 336 | if (CONFIG_FEC_ENET_DEV) { |
334 | if (!power_domain_lookup_name("conn_enet1", &pd)) | 337 | if (!power_domain_lookup_name("conn_enet1", &pd)) |
335 | power_domain_on(&pd); | 338 | power_domain_on(&pd); |
336 | } else { | 339 | } else { |
337 | if (!power_domain_lookup_name("conn_enet0", &pd)) | 340 | if (!power_domain_lookup_name("conn_enet0", &pd)) |
338 | power_domain_on(&pd); | 341 | power_domain_on(&pd); |
339 | } | 342 | } |
340 | 343 | ||
341 | setup_iomux_fec(); | 344 | setup_iomux_fec(); |
342 | 345 | ||
343 | ret = fecmxc_initialize_multi(bis, CONFIG_FEC_ENET_DEV, | 346 | ret = fecmxc_initialize_multi(bis, CONFIG_FEC_ENET_DEV, |
344 | CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE); | 347 | CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE); |
345 | if (ret) | 348 | if (ret) |
346 | printf("FEC1 MXC: %s:failed\n", __func__); | 349 | printf("FEC1 MXC: %s:failed\n", __func__); |
347 | 350 | ||
348 | return ret; | 351 | return ret; |
349 | } | 352 | } |
350 | 353 | ||
351 | int board_phy_config(struct phy_device *phydev) | 354 | int board_phy_config(struct phy_device *phydev) |
352 | { | 355 | { |
353 | #ifdef CONFIG_FEC_ENABLE_MAX7322 | 356 | #ifdef CONFIG_FEC_ENABLE_MAX7322 |
354 | uint8_t value; | 357 | uint8_t value; |
355 | 358 | ||
356 | /* This is needed to drive the pads to 1.8V instead of 1.5V */ | 359 | /* This is needed to drive the pads to 1.8V instead of 1.5V */ |
357 | i2c_set_bus_num(CONFIG_MAX7322_I2C_BUS); | 360 | i2c_set_bus_num(CONFIG_MAX7322_I2C_BUS); |
358 | 361 | ||
359 | if (!i2c_probe(CONFIG_MAX7322_I2C_ADDR)) { | 362 | if (!i2c_probe(CONFIG_MAX7322_I2C_ADDR)) { |
360 | /* Write 0x1 to enable O0 output, this device has no addr */ | 363 | /* Write 0x1 to enable O0 output, this device has no addr */ |
361 | /* hence addr length is 0 */ | 364 | /* hence addr length is 0 */ |
362 | value = 0x1; | 365 | value = 0x1; |
363 | if (i2c_write(CONFIG_MAX7322_I2C_ADDR, 0, 0, &value, 1)) | 366 | if (i2c_write(CONFIG_MAX7322_I2C_ADDR, 0, 0, &value, 1)) |
364 | printf("MAX7322 write failed\n"); | 367 | printf("MAX7322 write failed\n"); |
365 | } else { | 368 | } else { |
366 | printf("MAX7322 Not found\n"); | 369 | printf("MAX7322 Not found\n"); |
367 | } | 370 | } |
368 | mdelay(1); | 371 | mdelay(1); |
369 | #endif | 372 | #endif |
370 | 373 | ||
371 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f); | 374 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f); |
372 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8); | 375 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8); |
373 | 376 | ||
374 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x00); | 377 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x00); |
375 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x82ee); | 378 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x82ee); |
376 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05); | 379 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05); |
377 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100); | 380 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100); |
378 | 381 | ||
379 | if (phydev->drv->config) | 382 | if (phydev->drv->config) |
380 | phydev->drv->config(phydev); | 383 | phydev->drv->config(phydev); |
381 | 384 | ||
382 | return 0; | 385 | return 0; |
383 | } | 386 | } |
384 | 387 | ||
385 | static int setup_fec(int ind) | 388 | static int setup_fec(int ind) |
386 | { | 389 | { |
387 | /* Reset ENET PHY */ | 390 | /* Reset ENET PHY */ |
388 | enet_device_phy_reset(); | 391 | enet_device_phy_reset(); |
389 | 392 | ||
390 | return 0; | 393 | return 0; |
391 | } | 394 | } |
392 | #endif | 395 | #endif |
393 | 396 | ||
394 | #ifdef CONFIG_MXC_GPIO | 397 | #ifdef CONFIG_MXC_GPIO |
395 | 398 | ||
396 | #define LVDS_ENABLE IMX_GPIO_NR(1, 6) | 399 | #define LVDS_ENABLE IMX_GPIO_NR(1, 6) |
397 | #define MIPI_ENABLE IMX_GPIO_NR(1, 7) | 400 | #define MIPI_ENABLE IMX_GPIO_NR(1, 7) |
398 | #define DEBUG_LED IMX_GPIO_NR(2, 15) | 401 | #define DEBUG_LED IMX_GPIO_NR(2, 15) |
399 | #define IOEXP_RESET IMX_GPIO_NR(1, 12) | 402 | #define IOEXP_RESET IMX_GPIO_NR(1, 12) |
400 | 403 | ||
401 | static iomux_cfg_t board_gpios[] = { | 404 | static iomux_cfg_t board_gpios[] = { |
402 | SC_P_LVDS0_I2C0_SCL | MUX_MODE_ALT(3) | MUX_PAD_CTRL(GPIO_PAD_CTRL), | 405 | SC_P_LVDS0_I2C0_SCL | MUX_MODE_ALT(3) | MUX_PAD_CTRL(GPIO_PAD_CTRL), |
403 | SC_P_LVDS0_I2C0_SDA | MUX_MODE_ALT(3) | MUX_PAD_CTRL(GPIO_PAD_CTRL), | 406 | SC_P_LVDS0_I2C0_SDA | MUX_MODE_ALT(3) | MUX_PAD_CTRL(GPIO_PAD_CTRL), |
404 | SC_P_LVDS1_I2C0_SCL | MUX_MODE_ALT(3) | MUX_PAD_CTRL(GPIO_PAD_CTRL), | 407 | SC_P_LVDS1_I2C0_SCL | MUX_MODE_ALT(3) | MUX_PAD_CTRL(GPIO_PAD_CTRL), |
405 | SC_P_SPDIF0_TX | MUX_MODE_ALT(3) | MUX_PAD_CTRL(GPIO_PAD_CTRL), | 408 | SC_P_SPDIF0_TX | MUX_MODE_ALT(3) | MUX_PAD_CTRL(GPIO_PAD_CTRL), |
406 | }; | 409 | }; |
407 | 410 | ||
408 | static void board_gpio_init(void) | 411 | static void board_gpio_init(void) |
409 | { | 412 | { |
410 | imx8_iomux_setup_multiple_pads(board_gpios, ARRAY_SIZE(board_gpios)); | 413 | imx8_iomux_setup_multiple_pads(board_gpios, ARRAY_SIZE(board_gpios)); |
411 | 414 | ||
412 | gpio_request(DEBUG_LED, "debug_led"); | 415 | gpio_request(DEBUG_LED, "debug_led"); |
413 | gpio_direction_output(DEBUG_LED, 1); | 416 | gpio_direction_output(DEBUG_LED, 1); |
414 | 417 | ||
415 | /* enable i2c port expander assert reset line */ | 418 | /* enable i2c port expander assert reset line */ |
416 | gpio_request(IOEXP_RESET, "ioexp_rst"); | 419 | gpio_request(IOEXP_RESET, "ioexp_rst"); |
417 | gpio_direction_output(IOEXP_RESET, 1); | 420 | gpio_direction_output(IOEXP_RESET, 1); |
418 | 421 | ||
419 | /* enable LVDS SAS boards */ | 422 | /* enable LVDS SAS boards */ |
420 | gpio_request(LVDS_ENABLE, "lvds_enable"); | 423 | gpio_request(LVDS_ENABLE, "lvds_enable"); |
421 | gpio_direction_output(LVDS_ENABLE, 1); | 424 | gpio_direction_output(LVDS_ENABLE, 1); |
422 | 425 | ||
423 | /* enable MIPI SAS boards */ | 426 | /* enable MIPI SAS boards */ |
424 | gpio_request(MIPI_ENABLE, "mipi_enable"); | 427 | gpio_request(MIPI_ENABLE, "mipi_enable"); |
425 | gpio_direction_output(MIPI_ENABLE, 1); | 428 | gpio_direction_output(MIPI_ENABLE, 1); |
426 | } | 429 | } |
427 | #endif | 430 | #endif |
428 | 431 | ||
429 | int checkboard(void) | 432 | int checkboard(void) |
430 | { | 433 | { |
431 | #ifdef CONFIG_TARGET_IMX8QM_LPDDR4_ARM2 | 434 | #ifdef CONFIG_TARGET_IMX8QM_LPDDR4_ARM2 |
432 | puts("Board: iMX8QM LPDDR4 ARM2\n"); | 435 | puts("Board: iMX8QM LPDDR4 ARM2\n"); |
433 | #else | 436 | #else |
434 | puts("Board: iMX8QM DDR4 ARM2\n"); | 437 | puts("Board: iMX8QM DDR4 ARM2\n"); |
435 | #endif | 438 | #endif |
436 | 439 | ||
437 | print_bootinfo(); | 440 | print_bootinfo(); |
438 | 441 | ||
439 | /* Note: After reloc, ipcHndl will no longer be valid. If handle | 442 | /* Note: After reloc, ipcHndl will no longer be valid. If handle |
440 | * returned by sc_ipc_open matches SC_IPC_CH, use this | 443 | * returned by sc_ipc_open matches SC_IPC_CH, use this |
441 | * macro (valid after reloc) for subsequent SCI calls. | 444 | * macro (valid after reloc) for subsequent SCI calls. |
442 | */ | 445 | */ |
443 | if (gd->arch.ipc_channel_handle != SC_IPC_CH) { | 446 | if (gd->arch.ipc_channel_handle != SC_IPC_CH) { |
444 | printf("\nSCI error! Invalid handle\n"); | 447 | printf("\nSCI error! Invalid handle\n"); |
445 | } | 448 | } |
446 | 449 | ||
447 | return 0; | 450 | return 0; |
448 | } | 451 | } |
449 | 452 | ||
450 | #ifdef CONFIG_FSL_HSIO | 453 | #ifdef CONFIG_FSL_HSIO |
451 | 454 | ||
452 | #define PCIE_PAD_CTRL ((SC_PAD_CONFIG_OD_IN << PADRING_CONFIG_SHIFT)) | 455 | #define PCIE_PAD_CTRL ((SC_PAD_CONFIG_OD_IN << PADRING_CONFIG_SHIFT)) |
453 | static iomux_cfg_t board_pcie_pins[] = { | 456 | static iomux_cfg_t board_pcie_pins[] = { |
454 | SC_P_PCIE_CTRL0_CLKREQ_B | MUX_MODE_ALT(0) | MUX_PAD_CTRL(PCIE_PAD_CTRL), | 457 | SC_P_PCIE_CTRL0_CLKREQ_B | MUX_MODE_ALT(0) | MUX_PAD_CTRL(PCIE_PAD_CTRL), |
455 | SC_P_PCIE_CTRL0_WAKE_B | MUX_MODE_ALT(0) | MUX_PAD_CTRL(PCIE_PAD_CTRL), | 458 | SC_P_PCIE_CTRL0_WAKE_B | MUX_MODE_ALT(0) | MUX_PAD_CTRL(PCIE_PAD_CTRL), |
456 | SC_P_PCIE_CTRL0_PERST_B | MUX_MODE_ALT(0) | MUX_PAD_CTRL(PCIE_PAD_CTRL), | 459 | SC_P_PCIE_CTRL0_PERST_B | MUX_MODE_ALT(0) | MUX_PAD_CTRL(PCIE_PAD_CTRL), |
457 | }; | 460 | }; |
458 | 461 | ||
459 | static void imx8qm_hsio_initialize(void) | 462 | static void imx8qm_hsio_initialize(void) |
460 | { | 463 | { |
461 | struct power_domain pd; | 464 | struct power_domain pd; |
462 | int ret; | 465 | int ret; |
463 | 466 | ||
464 | if (!power_domain_lookup_name("hsio_sata0", &pd)) { | 467 | if (!power_domain_lookup_name("hsio_sata0", &pd)) { |
465 | ret = power_domain_on(&pd); | 468 | ret = power_domain_on(&pd); |
466 | if (ret) | 469 | if (ret) |
467 | printf("hsio_sata0 Power up failed! (error = %d)\n", ret); | 470 | printf("hsio_sata0 Power up failed! (error = %d)\n", ret); |
468 | } | 471 | } |
469 | 472 | ||
470 | if (!power_domain_lookup_name("hsio_pcie0", &pd)) { | 473 | if (!power_domain_lookup_name("hsio_pcie0", &pd)) { |
471 | ret = power_domain_on(&pd); | 474 | ret = power_domain_on(&pd); |
472 | if (ret) | 475 | if (ret) |
473 | printf("hsio_pcie0 Power up failed! (error = %d)\n", ret); | 476 | printf("hsio_pcie0 Power up failed! (error = %d)\n", ret); |
474 | } | 477 | } |
475 | 478 | ||
476 | if (!power_domain_lookup_name("hsio_pcie1", &pd)) { | 479 | if (!power_domain_lookup_name("hsio_pcie1", &pd)) { |
477 | ret = power_domain_on(&pd); | 480 | ret = power_domain_on(&pd); |
478 | if (ret) | 481 | if (ret) |
479 | printf("hsio_pcie1 Power up failed! (error = %d)\n", ret); | 482 | printf("hsio_pcie1 Power up failed! (error = %d)\n", ret); |
480 | } | 483 | } |
481 | 484 | ||
482 | if (!power_domain_lookup_name("hsio_gpio", &pd)) { | 485 | if (!power_domain_lookup_name("hsio_gpio", &pd)) { |
483 | ret = power_domain_on(&pd); | 486 | ret = power_domain_on(&pd); |
484 | if (ret) | 487 | if (ret) |
485 | printf("hsio_gpio Power up failed! (error = %d)\n", ret); | 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 | imx8_iomux_setup_multiple_pads(board_pcie_pins, ARRAY_SIZE(board_pcie_pins)); | 504 | imx8_iomux_setup_multiple_pads(board_pcie_pins, ARRAY_SIZE(board_pcie_pins)); |
489 | 505 | ||
490 | } | 506 | } |
491 | 507 | ||
492 | void pci_init_board(void) | 508 | void pci_init_board(void) |
493 | { | 509 | { |
494 | /* test the 1 lane mode of the PCIe A controller */ | 510 | /* test the 1 lane mode of the PCIe A controller */ |
495 | mx8qm_pcie_init(); | 511 | mx8qm_pcie_init(); |
496 | } | 512 | } |
497 | #endif | 513 | #endif |
498 | 514 | ||
499 | #ifdef CONFIG_USB_CDNS3_GADGET | 515 | #ifdef CONFIG_USB_CDNS3_GADGET |
500 | 516 | ||
501 | static struct cdns3_device cdns3_device_data = { | 517 | static struct cdns3_device cdns3_device_data = { |
502 | .none_core_base = 0x5B110000, | 518 | .none_core_base = 0x5B110000, |
503 | .xhci_base = 0x5B130000, | 519 | .xhci_base = 0x5B130000, |
504 | .dev_base = 0x5B140000, | 520 | .dev_base = 0x5B140000, |
505 | .phy_base = 0x5B160000, | 521 | .phy_base = 0x5B160000, |
506 | .otg_base = 0x5B120000, | 522 | .otg_base = 0x5B120000, |
507 | .dr_mode = USB_DR_MODE_PERIPHERAL, | 523 | .dr_mode = USB_DR_MODE_PERIPHERAL, |
508 | .index = 1, | 524 | .index = 1, |
509 | }; | 525 | }; |
510 | 526 | ||
511 | int usb_gadget_handle_interrupts(void) | 527 | int usb_gadget_handle_interrupts(void) |
512 | { | 528 | { |
513 | cdns3_uboot_handle_interrupt(1); | 529 | cdns3_uboot_handle_interrupt(1); |
514 | return 0; | 530 | return 0; |
515 | } | 531 | } |
516 | 532 | ||
517 | int board_usb_init(int index, enum usb_init_type init) | 533 | int board_usb_init(int index, enum usb_init_type init) |
518 | { | 534 | { |
519 | int ret = 0; | 535 | int ret = 0; |
520 | 536 | ||
521 | if (index == 1) { | 537 | if (index == 1) { |
522 | if (init == USB_INIT_DEVICE) { | 538 | if (init == USB_INIT_DEVICE) { |
523 | struct power_domain pd; | 539 | struct power_domain pd; |
524 | int ret; | 540 | int ret; |
525 | 541 | ||
526 | /* Power on usb */ | 542 | /* Power on usb */ |
527 | if (!power_domain_lookup_name("conn_usb2", &pd)) { | 543 | if (!power_domain_lookup_name("conn_usb2", &pd)) { |
528 | ret = power_domain_on(&pd); | 544 | ret = power_domain_on(&pd); |
529 | if (ret) | 545 | if (ret) |
530 | printf("conn_usb2 Power up failed! (error = %d)\n", ret); | 546 | printf("conn_usb2 Power up failed! (error = %d)\n", ret); |
531 | } | 547 | } |
532 | 548 | ||
533 | if (!power_domain_lookup_name("conn_usb2_phy", &pd)) { | 549 | if (!power_domain_lookup_name("conn_usb2_phy", &pd)) { |
534 | ret = power_domain_on(&pd); | 550 | ret = power_domain_on(&pd); |
535 | if (ret) | 551 | if (ret) |
536 | printf("conn_usb2_phy Power up failed! (error = %d)\n", ret); | 552 | printf("conn_usb2_phy Power up failed! (error = %d)\n", ret); |
537 | } | 553 | } |
538 | 554 | ||
539 | ret = cdns3_uboot_init(&cdns3_device_data); | 555 | ret = cdns3_uboot_init(&cdns3_device_data); |
540 | printf("%d cdns3_uboot_initmode %d\n", index, ret); | 556 | printf("%d cdns3_uboot_initmode %d\n", index, ret); |
541 | } | 557 | } |
542 | } | 558 | } |
543 | return ret; | 559 | return ret; |
544 | } | 560 | } |
545 | 561 | ||
546 | int board_usb_cleanup(int index, enum usb_init_type init) | 562 | int board_usb_cleanup(int index, enum usb_init_type init) |
547 | { | 563 | { |
548 | int ret = 0; | 564 | int ret = 0; |
549 | 565 | ||
550 | if (index == 1) { | 566 | if (index == 1) { |
551 | if (init == USB_INIT_DEVICE) { | 567 | if (init == USB_INIT_DEVICE) { |
552 | struct power_domain pd; | 568 | struct power_domain pd; |
553 | int ret; | 569 | int ret; |
554 | 570 | ||
555 | cdns3_uboot_exit(1); | 571 | cdns3_uboot_exit(1); |
556 | 572 | ||
557 | /* Power off usb */ | 573 | /* Power off usb */ |
558 | if (!power_domain_lookup_name("conn_usb2", &pd)) { | 574 | if (!power_domain_lookup_name("conn_usb2", &pd)) { |
559 | ret = power_domain_off(&pd); | 575 | ret = power_domain_off(&pd); |
560 | if (ret) | 576 | if (ret) |
561 | printf("conn_usb2 Power up failed! (error = %d)\n", ret); | 577 | printf("conn_usb2 Power up failed! (error = %d)\n", ret); |
562 | } | 578 | } |
563 | 579 | ||
564 | if (!power_domain_lookup_name("conn_usb2_phy", &pd)) { | 580 | if (!power_domain_lookup_name("conn_usb2_phy", &pd)) { |
565 | ret = power_domain_off(&pd); | 581 | ret = power_domain_off(&pd); |
566 | if (ret) | 582 | if (ret) |
567 | printf("conn_usb2_phy Power up failed! (error = %d)\n", ret); | 583 | printf("conn_usb2_phy Power up failed! (error = %d)\n", ret); |
568 | } | 584 | } |
569 | } | 585 | } |
570 | } | 586 | } |
571 | return ret; | 587 | return ret; |
572 | } | 588 | } |
573 | #endif | 589 | #endif |
574 | 590 | ||
575 | int board_init(void) | 591 | int board_init(void) |
576 | { | 592 | { |
577 | #ifdef CONFIG_MXC_GPIO | 593 | #ifdef CONFIG_MXC_GPIO |
578 | board_gpio_init(); | 594 | board_gpio_init(); |
579 | #endif | 595 | #endif |
580 | 596 | ||
581 | #ifdef CONFIG_FEC_MXC | 597 | #ifdef CONFIG_FEC_MXC |
582 | setup_fec(CONFIG_FEC_ENET_DEV); | 598 | setup_fec(CONFIG_FEC_ENET_DEV); |
583 | #endif | 599 | #endif |
584 | 600 | ||
585 | #ifdef CONFIG_FSL_HSIO | 601 | #ifdef CONFIG_FSL_HSIO |
586 | imx8qm_hsio_initialize(); | 602 | imx8qm_hsio_initialize(); |
587 | #ifdef CONFIG_SCSI_AHCI_PLAT | 603 | #ifdef CONFIG_SCSI_AHCI_PLAT |
588 | sata_init(); | 604 | sata_init(); |
589 | #endif | 605 | #endif |
590 | #endif | 606 | #endif |
591 | return 0; | 607 | return 0; |
592 | } | 608 | } |
593 | 609 | ||
594 | void board_quiesce_devices() | 610 | void board_quiesce_devices() |
595 | { | 611 | { |
596 | const char *power_on_devices[] = { | 612 | const char *power_on_devices[] = { |
597 | "dma_lpuart0", | 613 | "dma_lpuart0", |
598 | }; | 614 | }; |
599 | 615 | ||
600 | power_off_pd_devices(power_on_devices, ARRAY_SIZE(power_on_devices)); | 616 | power_off_pd_devices(power_on_devices, ARRAY_SIZE(power_on_devices)); |
601 | } | 617 | } |
602 | 618 | ||
603 | void detail_board_ddr_info(void) | 619 | void detail_board_ddr_info(void) |
604 | { | 620 | { |
605 | puts("\nDDR "); | 621 | puts("\nDDR "); |
606 | } | 622 | } |
607 | 623 | ||
608 | /* | 624 | /* |
609 | * Board specific reset that is system reset. | 625 | * Board specific reset that is system reset. |
610 | */ | 626 | */ |
611 | void reset_cpu(ulong addr) | 627 | void reset_cpu(ulong addr) |
612 | { | 628 | { |
613 | puts("SCI reboot request"); | 629 | puts("SCI reboot request"); |
614 | sc_pm_reboot(SC_IPC_CH, SC_PM_RESET_TYPE_COLD); | 630 | sc_pm_reboot(SC_IPC_CH, SC_PM_RESET_TYPE_COLD); |
615 | while (1) | 631 | while (1) |
616 | putc('.'); | 632 | putc('.'); |
617 | } | 633 | } |
618 | 634 | ||
619 | #ifdef CONFIG_OF_BOARD_SETUP | 635 | #ifdef CONFIG_OF_BOARD_SETUP |
620 | int ft_board_setup(void *blob, bd_t *bd) | 636 | int ft_board_setup(void *blob, bd_t *bd) |
621 | { | 637 | { |
622 | return 0; | 638 | return 0; |
623 | } | 639 | } |
624 | #endif | 640 | #endif |
625 | 641 | ||
626 | int board_mmc_get_env_dev(int devno) | 642 | int board_mmc_get_env_dev(int devno) |
627 | { | 643 | { |
628 | #ifdef CONFIG_TARGET_IMX8QM_LPDDR4_ARM2 | 644 | #ifdef CONFIG_TARGET_IMX8QM_LPDDR4_ARM2 |
629 | return devno; | 645 | return devno; |
630 | #else | 646 | #else |
631 | return devno - 2; | 647 | return devno - 2; |
632 | #endif | 648 | #endif |
633 | } | 649 | } |
634 | 650 | ||
635 | int mmc_map_to_kernel_blk(int dev_no) | 651 | int mmc_map_to_kernel_blk(int dev_no) |
636 | { | 652 | { |
637 | #ifdef CONFIG_TARGET_IMX8QM_LPDDR4_ARM2 | 653 | #ifdef CONFIG_TARGET_IMX8QM_LPDDR4_ARM2 |
638 | return dev_no; | 654 | return dev_no; |
639 | #else | 655 | #else |
640 | return dev_no + 2; | 656 | return dev_no + 2; |
641 | #endif | 657 | #endif |
642 | } | 658 | } |
643 | 659 | ||
644 | int board_late_init(void) | 660 | int board_late_init(void) |
645 | { | 661 | { |
646 | #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG | 662 | #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG |
647 | env_set("board_name", "ARM2"); | 663 | env_set("board_name", "ARM2"); |
648 | env_set("board_rev", "iMX8QM"); | 664 | env_set("board_rev", "iMX8QM"); |
649 | #endif | 665 | #endif |
650 | 666 | ||
651 | env_set("sec_boot", "no"); | 667 | env_set("sec_boot", "no"); |
652 | #ifdef CONFIG_AHAB_BOOT | 668 | #ifdef CONFIG_AHAB_BOOT |
653 | env_set("sec_boot", "yes"); | 669 | env_set("sec_boot", "yes"); |
654 | #endif | 670 | #endif |
655 | 671 | ||
656 | #ifdef CONFIG_ENV_IS_IN_MMC | 672 | #ifdef CONFIG_ENV_IS_IN_MMC |
657 | board_late_mmc_env_init(); | 673 | board_late_mmc_env_init(); |
658 | #endif | 674 | #endif |
659 | 675 | ||
660 | return 0; | 676 | return 0; |
661 | } | 677 | } |
662 | 678 | ||
663 | #ifdef CONFIG_FSL_FASTBOOT | 679 | #ifdef CONFIG_FSL_FASTBOOT |
664 | #ifdef CONFIG_ANDROID_RECOVERY | 680 | #ifdef CONFIG_ANDROID_RECOVERY |
665 | int is_recovery_key_pressing(void) | 681 | int is_recovery_key_pressing(void) |
666 | { | 682 | { |
667 | return 0; /*TODO*/ | 683 | return 0; /*TODO*/ |
668 | } | 684 | } |
669 | #endif /*CONFIG_ANDROID_RECOVERY*/ | 685 | #endif /*CONFIG_ANDROID_RECOVERY*/ |
670 | #endif /*CONFIG_FSL_FASTBOOT*/ | 686 | #endif /*CONFIG_FSL_FASTBOOT*/ |
671 | 687 | ||
672 | #if defined(CONFIG_VIDEO_IMXDPUV1) | 688 | #if defined(CONFIG_VIDEO_IMXDPUV1) |
673 | static void enable_lvds(struct display_info_t const *dev) | 689 | static void enable_lvds(struct display_info_t const *dev) |
674 | { | 690 | { |
675 | display_controller_setup((PS2KHZ(dev->mode.pixclock) * 1000)); | 691 | display_controller_setup((PS2KHZ(dev->mode.pixclock) * 1000)); |
676 | lvds_soc_setup(dev->bus, (PS2KHZ(dev->mode.pixclock) * 1000)); | 692 | lvds_soc_setup(dev->bus, (PS2KHZ(dev->mode.pixclock) * 1000)); |
677 | lvds_configure(dev->bus); | 693 | lvds_configure(dev->bus); |
678 | lvds2hdmi_setup(6); | 694 | lvds2hdmi_setup(6); |
679 | } | 695 | } |
680 | 696 | ||
681 | struct display_info_t const displays[] = {{ | 697 | struct display_info_t const displays[] = {{ |
682 | .bus = 0, /* LVDS0 */ | 698 | .bus = 0, /* LVDS0 */ |
683 | .addr = 0, /* Unused */ | 699 | .addr = 0, /* Unused */ |
684 | .pixfmt = IMXDPUV1_PIX_FMT_BGRA32, | 700 | .pixfmt = IMXDPUV1_PIX_FMT_BGRA32, |
685 | .detect = NULL, | 701 | .detect = NULL, |
686 | .enable = enable_lvds, | 702 | .enable = enable_lvds, |
687 | .mode = { | 703 | .mode = { |
688 | .name = "IT6263", /* 720P60 */ | 704 | .name = "IT6263", /* 720P60 */ |
689 | .refresh = 60, | 705 | .refresh = 60, |
690 | .xres = 1280, | 706 | .xres = 1280, |
691 | .yres = 720, | 707 | .yres = 720, |
692 | .pixclock = 13468, /* 74250000 */ | 708 | .pixclock = 13468, /* 74250000 */ |
693 | .left_margin = 110, | 709 | .left_margin = 110, |
694 | .right_margin = 220, | 710 | .right_margin = 220, |
695 | .upper_margin = 5, | 711 | .upper_margin = 5, |
696 | .lower_margin = 20, | 712 | .lower_margin = 20, |
697 | .hsync_len = 40, | 713 | .hsync_len = 40, |
698 | .vsync_len = 5, | 714 | .vsync_len = 5, |
699 | .sync = FB_SYNC_EXT, | 715 | .sync = FB_SYNC_EXT, |
700 | .vmode = FB_VMODE_NONINTERLACED | 716 | .vmode = FB_VMODE_NONINTERLACED |
701 | } } }; | 717 | } } }; |
702 | size_t display_count = ARRAY_SIZE(displays); | 718 | size_t display_count = ARRAY_SIZE(displays); |
703 | 719 | ||
704 | #endif /* CONFIG_VIDEO_IMXDPUV1 */ | 720 | #endif /* CONFIG_VIDEO_IMXDPUV1 */ |
705 | 721 |
board/freescale/imx8qm_mek/imx8qm_mek.c
1 | /* | 1 | /* |
2 | * Copyright 2017-2018 NXP | 2 | * Copyright 2017-2018 NXP |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: GPL-2.0+ | 4 | * SPDX-License-Identifier: GPL-2.0+ |
5 | */ | 5 | */ |
6 | #include <common.h> | 6 | #include <common.h> |
7 | #include <malloc.h> | 7 | #include <malloc.h> |
8 | #include <errno.h> | 8 | #include <errno.h> |
9 | #include <netdev.h> | 9 | #include <netdev.h> |
10 | #include <fsl_ifc.h> | 10 | #include <fsl_ifc.h> |
11 | #include <fdt_support.h> | 11 | #include <fdt_support.h> |
12 | #include <linux/libfdt.h> | 12 | #include <linux/libfdt.h> |
13 | #include <environment.h> | 13 | #include <environment.h> |
14 | #include <fsl_esdhc.h> | 14 | #include <fsl_esdhc.h> |
15 | #include <i2c.h> | 15 | #include <i2c.h> |
16 | 16 | ||
17 | #include <asm/io.h> | 17 | #include <asm/io.h> |
18 | #include <asm/gpio.h> | 18 | #include <asm/gpio.h> |
19 | #include <asm/arch/clock.h> | 19 | #include <asm/arch/clock.h> |
20 | #include <asm/mach-imx/sci/sci.h> | 20 | #include <asm/mach-imx/sci/sci.h> |
21 | #include <asm/arch/imx8-pins.h> | 21 | #include <asm/arch/imx8-pins.h> |
22 | #include <dm.h> | 22 | #include <dm.h> |
23 | #include <imx8_hsio.h> | 23 | #include <imx8_hsio.h> |
24 | #include <usb.h> | 24 | #include <usb.h> |
25 | #include <asm/arch/iomux.h> | 25 | #include <asm/arch/iomux.h> |
26 | #include <asm/arch/sys_proto.h> | 26 | #include <asm/arch/sys_proto.h> |
27 | #include <asm/mach-imx/video.h> | 27 | #include <asm/mach-imx/video.h> |
28 | #include <asm/arch/video_common.h> | 28 | #include <asm/arch/video_common.h> |
29 | #include <power-domain.h> | 29 | #include <power-domain.h> |
30 | #include "../common/tcpc.h" | 30 | #include "../common/tcpc.h" |
31 | #include <cdns3-uboot.h> | 31 | #include <cdns3-uboot.h> |
32 | #include <asm/arch/lpcg.h> | ||
32 | 33 | ||
33 | DECLARE_GLOBAL_DATA_PTR; | 34 | DECLARE_GLOBAL_DATA_PTR; |
34 | 35 | ||
35 | #define ENET_INPUT_PAD_CTRL ((SC_PAD_CONFIG_OD_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 36 | #define ENET_INPUT_PAD_CTRL ((SC_PAD_CONFIG_OD_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
36 | | (SC_PAD_28FDSOI_DSE_18V_10MA << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 37 | | (SC_PAD_28FDSOI_DSE_18V_10MA << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
37 | 38 | ||
38 | #define ENET_NORMAL_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 39 | #define ENET_NORMAL_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
39 | | (SC_PAD_28FDSOI_DSE_18V_10MA << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 40 | | (SC_PAD_28FDSOI_DSE_18V_10MA << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
40 | 41 | ||
41 | #define FSPI_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 42 | #define FSPI_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
42 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 43 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
43 | 44 | ||
44 | #define GPIO_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 45 | #define GPIO_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
45 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 46 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
46 | 47 | ||
47 | #define I2C_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 48 | #define I2C_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
48 | | (SC_PAD_28FDSOI_DSE_DV_LOW << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 49 | | (SC_PAD_28FDSOI_DSE_DV_LOW << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
49 | 50 | ||
50 | #define UART_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 51 | #define UART_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
51 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 52 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
52 | 53 | ||
53 | static iomux_cfg_t uart0_pads[] = { | 54 | static iomux_cfg_t uart0_pads[] = { |
54 | SC_P_UART0_RX | MUX_PAD_CTRL(UART_PAD_CTRL), | 55 | SC_P_UART0_RX | MUX_PAD_CTRL(UART_PAD_CTRL), |
55 | SC_P_UART0_TX | MUX_PAD_CTRL(UART_PAD_CTRL), | 56 | SC_P_UART0_TX | MUX_PAD_CTRL(UART_PAD_CTRL), |
56 | }; | 57 | }; |
57 | 58 | ||
58 | static void setup_iomux_uart(void) | 59 | static void setup_iomux_uart(void) |
59 | { | 60 | { |
60 | imx8_iomux_setup_multiple_pads(uart0_pads, ARRAY_SIZE(uart0_pads)); | 61 | imx8_iomux_setup_multiple_pads(uart0_pads, ARRAY_SIZE(uart0_pads)); |
61 | } | 62 | } |
62 | 63 | ||
63 | int board_early_init_f(void) | 64 | int board_early_init_f(void) |
64 | { | 65 | { |
65 | sc_ipc_t ipcHndl = 0; | 66 | sc_ipc_t ipcHndl = 0; |
66 | sc_err_t sciErr = 0; | 67 | sc_err_t sciErr = 0; |
67 | 68 | ||
68 | /* When start u-boot in XEN VM, directly return */ | 69 | /* When start u-boot in XEN VM, directly return */ |
69 | if (IS_ENABLED(CONFIG_XEN)) | 70 | if (IS_ENABLED(CONFIG_XEN)) |
70 | return 0; | 71 | return 0; |
71 | 72 | ||
72 | ipcHndl = gd->arch.ipc_channel_handle; | 73 | ipcHndl = gd->arch.ipc_channel_handle; |
73 | 74 | ||
74 | /* Power up UART0, this is very early while power domain is not working */ | 75 | /* Power up UART0, this is very early while power domain is not working */ |
75 | sciErr = sc_pm_set_resource_power_mode(ipcHndl, SC_R_UART_0, SC_PM_PW_MODE_ON); | 76 | sciErr = sc_pm_set_resource_power_mode(ipcHndl, SC_R_UART_0, SC_PM_PW_MODE_ON); |
76 | if (sciErr != SC_ERR_NONE) | 77 | if (sciErr != SC_ERR_NONE) |
77 | return 0; | 78 | return 0; |
78 | 79 | ||
79 | /* Set UART0 clock root to 80 MHz */ | 80 | /* Set UART0 clock root to 80 MHz */ |
80 | sc_pm_clock_rate_t rate = 80000000; | 81 | sc_pm_clock_rate_t rate = 80000000; |
81 | sciErr = sc_pm_set_clock_rate(ipcHndl, SC_R_UART_0, 2, &rate); | 82 | sciErr = sc_pm_set_clock_rate(ipcHndl, SC_R_UART_0, 2, &rate); |
82 | if (sciErr != SC_ERR_NONE) | 83 | if (sciErr != SC_ERR_NONE) |
83 | return 0; | 84 | return 0; |
84 | 85 | ||
85 | /* Enable UART0 clock root */ | 86 | /* Enable UART0 clock root */ |
86 | sciErr = sc_pm_clock_enable(ipcHndl, SC_R_UART_0, 2, true, false); | 87 | sciErr = sc_pm_clock_enable(ipcHndl, SC_R_UART_0, 2, true, false); |
87 | if (sciErr != SC_ERR_NONE) | 88 | if (sciErr != SC_ERR_NONE) |
88 | return 0; | 89 | return 0; |
89 | 90 | ||
91 | LPCG_AllClockOn(LPUART_0_LPCG); | ||
92 | |||
90 | setup_iomux_uart(); | 93 | setup_iomux_uart(); |
91 | 94 | ||
92 | return 0; | 95 | return 0; |
93 | } | 96 | } |
94 | 97 | ||
95 | #ifdef CONFIG_FEC_MXC | 98 | #ifdef CONFIG_FEC_MXC |
96 | #include <miiphy.h> | 99 | #include <miiphy.h> |
97 | 100 | ||
98 | static iomux_cfg_t pad_enet1[] = { | 101 | static iomux_cfg_t pad_enet1[] = { |
99 | SC_P_ENET1_RGMII_RX_CTL | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 102 | SC_P_ENET1_RGMII_RX_CTL | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
100 | SC_P_ENET1_RGMII_RXD0 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 103 | SC_P_ENET1_RGMII_RXD0 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
101 | SC_P_ENET1_RGMII_RXD1 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 104 | SC_P_ENET1_RGMII_RXD1 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
102 | SC_P_ENET1_RGMII_RXD2 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 105 | SC_P_ENET1_RGMII_RXD2 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
103 | SC_P_ENET1_RGMII_RXD3 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 106 | SC_P_ENET1_RGMII_RXD3 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
104 | SC_P_ENET1_RGMII_RXC | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 107 | SC_P_ENET1_RGMII_RXC | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
105 | SC_P_ENET1_RGMII_TX_CTL | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 108 | SC_P_ENET1_RGMII_TX_CTL | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
106 | SC_P_ENET1_RGMII_TXD0 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 109 | SC_P_ENET1_RGMII_TXD0 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
107 | SC_P_ENET1_RGMII_TXD1 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 110 | SC_P_ENET1_RGMII_TXD1 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
108 | SC_P_ENET1_RGMII_TXD2 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 111 | SC_P_ENET1_RGMII_TXD2 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
109 | SC_P_ENET1_RGMII_TXD3 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 112 | SC_P_ENET1_RGMII_TXD3 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
110 | SC_P_ENET1_RGMII_TXC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 113 | SC_P_ENET1_RGMII_TXC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
111 | 114 | ||
112 | /* Shared MDIO */ | 115 | /* Shared MDIO */ |
113 | SC_P_ENET0_MDC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 116 | SC_P_ENET0_MDC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
114 | SC_P_ENET0_MDIO | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 117 | SC_P_ENET0_MDIO | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
115 | }; | 118 | }; |
116 | 119 | ||
117 | static iomux_cfg_t pad_enet0[] = { | 120 | static iomux_cfg_t pad_enet0[] = { |
118 | SC_P_ENET0_RGMII_RX_CTL | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 121 | SC_P_ENET0_RGMII_RX_CTL | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
119 | SC_P_ENET0_RGMII_RXD0 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 122 | SC_P_ENET0_RGMII_RXD0 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
120 | SC_P_ENET0_RGMII_RXD1 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 123 | SC_P_ENET0_RGMII_RXD1 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
121 | SC_P_ENET0_RGMII_RXD2 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 124 | SC_P_ENET0_RGMII_RXD2 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
122 | SC_P_ENET0_RGMII_RXD3 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 125 | SC_P_ENET0_RGMII_RXD3 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
123 | SC_P_ENET0_RGMII_RXC | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 126 | SC_P_ENET0_RGMII_RXC | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
124 | SC_P_ENET0_RGMII_TX_CTL | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 127 | SC_P_ENET0_RGMII_TX_CTL | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
125 | SC_P_ENET0_RGMII_TXD0 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 128 | SC_P_ENET0_RGMII_TXD0 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
126 | SC_P_ENET0_RGMII_TXD1 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 129 | SC_P_ENET0_RGMII_TXD1 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
127 | SC_P_ENET0_RGMII_TXD2 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 130 | SC_P_ENET0_RGMII_TXD2 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
128 | SC_P_ENET0_RGMII_TXD3 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 131 | SC_P_ENET0_RGMII_TXD3 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
129 | SC_P_ENET0_RGMII_TXC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 132 | SC_P_ENET0_RGMII_TXC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
130 | 133 | ||
131 | /* Shared MDIO */ | 134 | /* Shared MDIO */ |
132 | SC_P_ENET0_MDC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 135 | SC_P_ENET0_MDC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
133 | SC_P_ENET0_MDIO | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 136 | SC_P_ENET0_MDIO | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
134 | }; | 137 | }; |
135 | 138 | ||
136 | static void setup_iomux_fec(void) | 139 | static void setup_iomux_fec(void) |
137 | { | 140 | { |
138 | if (0 == CONFIG_FEC_ENET_DEV) | 141 | if (0 == CONFIG_FEC_ENET_DEV) |
139 | imx8_iomux_setup_multiple_pads(pad_enet0, ARRAY_SIZE(pad_enet0)); | 142 | imx8_iomux_setup_multiple_pads(pad_enet0, ARRAY_SIZE(pad_enet0)); |
140 | else | 143 | else |
141 | imx8_iomux_setup_multiple_pads(pad_enet1, ARRAY_SIZE(pad_enet1)); | 144 | imx8_iomux_setup_multiple_pads(pad_enet1, ARRAY_SIZE(pad_enet1)); |
142 | } | 145 | } |
143 | 146 | ||
144 | int board_eth_init(bd_t *bis) | 147 | int board_eth_init(bd_t *bis) |
145 | { | 148 | { |
146 | int ret; | 149 | int ret; |
147 | struct power_domain pd; | 150 | struct power_domain pd; |
148 | 151 | ||
149 | printf("[%s] %d\n", __func__, __LINE__); | 152 | printf("[%s] %d\n", __func__, __LINE__); |
150 | 153 | ||
151 | if (CONFIG_FEC_ENET_DEV) { | 154 | if (CONFIG_FEC_ENET_DEV) { |
152 | if (!power_domain_lookup_name("conn_enet1", &pd)) | 155 | if (!power_domain_lookup_name("conn_enet1", &pd)) |
153 | power_domain_on(&pd); | 156 | power_domain_on(&pd); |
154 | } else { | 157 | } else { |
155 | if (!power_domain_lookup_name("conn_enet0", &pd)) | 158 | if (!power_domain_lookup_name("conn_enet0", &pd)) |
156 | power_domain_on(&pd); | 159 | power_domain_on(&pd); |
157 | } | 160 | } |
158 | 161 | ||
159 | setup_iomux_fec(); | 162 | setup_iomux_fec(); |
160 | 163 | ||
161 | ret = fecmxc_initialize_multi(bis, CONFIG_FEC_ENET_DEV, | 164 | ret = fecmxc_initialize_multi(bis, CONFIG_FEC_ENET_DEV, |
162 | CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE); | 165 | CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE); |
163 | if (ret) | 166 | if (ret) |
164 | printf("FEC1 MXC: %s:failed\n", __func__); | 167 | printf("FEC1 MXC: %s:failed\n", __func__); |
165 | 168 | ||
166 | return ret; | 169 | return ret; |
167 | } | 170 | } |
168 | 171 | ||
169 | int board_phy_config(struct phy_device *phydev) | 172 | int board_phy_config(struct phy_device *phydev) |
170 | { | 173 | { |
171 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f); | 174 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f); |
172 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8); | 175 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8); |
173 | 176 | ||
174 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x00); | 177 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x00); |
175 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x82ee); | 178 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x82ee); |
176 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05); | 179 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05); |
177 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100); | 180 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100); |
178 | 181 | ||
179 | if (phydev->drv->config) | 182 | if (phydev->drv->config) |
180 | phydev->drv->config(phydev); | 183 | phydev->drv->config(phydev); |
181 | 184 | ||
182 | return 0; | 185 | return 0; |
183 | } | 186 | } |
184 | #endif | 187 | #endif |
185 | 188 | ||
186 | #ifdef CONFIG_MXC_GPIO | 189 | #ifdef CONFIG_MXC_GPIO |
187 | 190 | ||
188 | #define LVDS_ENABLE IMX_GPIO_NR(1, 6) | 191 | #define LVDS_ENABLE IMX_GPIO_NR(1, 6) |
189 | #define MIPI_ENABLE IMX_GPIO_NR(1, 7) | 192 | #define MIPI_ENABLE IMX_GPIO_NR(1, 7) |
190 | 193 | ||
191 | #define BB_GPIO_3V3_1 IMX_GPIO_NR(4, 20) | 194 | #define BB_GPIO_3V3_1 IMX_GPIO_NR(4, 20) |
192 | #define BB_GPIO_3V3_2 IMX_GPIO_NR(4, 24) | 195 | #define BB_GPIO_3V3_2 IMX_GPIO_NR(4, 24) |
193 | #define BB_GPIO_3V3_3 IMX_GPIO_NR(4, 23) | 196 | #define BB_GPIO_3V3_3 IMX_GPIO_NR(4, 23) |
194 | 197 | ||
195 | static void board_gpio_init(void) | 198 | static void board_gpio_init(void) |
196 | { | 199 | { |
197 | /* Enable BB 3V3 */ | 200 | /* Enable BB 3V3 */ |
198 | gpio_request(BB_GPIO_3V3_1, "bb_3v3_1"); | 201 | gpio_request(BB_GPIO_3V3_1, "bb_3v3_1"); |
199 | gpio_direction_output(BB_GPIO_3V3_1, 1); | 202 | gpio_direction_output(BB_GPIO_3V3_1, 1); |
200 | gpio_request(BB_GPIO_3V3_2, "bb_3v3_2"); | 203 | gpio_request(BB_GPIO_3V3_2, "bb_3v3_2"); |
201 | gpio_direction_output(BB_GPIO_3V3_2, 1); | 204 | gpio_direction_output(BB_GPIO_3V3_2, 1); |
202 | gpio_request(BB_GPIO_3V3_3, "bb_3v3_3"); | 205 | gpio_request(BB_GPIO_3V3_3, "bb_3v3_3"); |
203 | gpio_direction_output(BB_GPIO_3V3_3, 1); | 206 | gpio_direction_output(BB_GPIO_3V3_3, 1); |
204 | 207 | ||
205 | /* enable LVDS SAS boards */ | 208 | /* enable LVDS SAS boards */ |
206 | gpio_request(LVDS_ENABLE, "lvds_enable"); | 209 | gpio_request(LVDS_ENABLE, "lvds_enable"); |
207 | gpio_direction_output(LVDS_ENABLE, 1); | 210 | gpio_direction_output(LVDS_ENABLE, 1); |
208 | 211 | ||
209 | /* enable MIPI SAS boards */ | 212 | /* enable MIPI SAS boards */ |
210 | gpio_request(MIPI_ENABLE, "mipi_enable"); | 213 | gpio_request(MIPI_ENABLE, "mipi_enable"); |
211 | gpio_direction_output(MIPI_ENABLE, 1); | 214 | gpio_direction_output(MIPI_ENABLE, 1); |
212 | } | 215 | } |
213 | #endif | 216 | #endif |
214 | 217 | ||
215 | int checkboard(void) | 218 | int checkboard(void) |
216 | { | 219 | { |
217 | puts("Board: iMX8QM MEK\n"); | 220 | puts("Board: iMX8QM MEK\n"); |
218 | 221 | ||
219 | print_bootinfo(); | 222 | print_bootinfo(); |
220 | 223 | ||
221 | /* Note: After reloc, ipcHndl will no longer be valid. If handle | 224 | /* Note: After reloc, ipcHndl will no longer be valid. If handle |
222 | * returned by sc_ipc_open matches SC_IPC_CH, use this | 225 | * returned by sc_ipc_open matches SC_IPC_CH, use this |
223 | * macro (valid after reloc) for subsequent SCI calls. | 226 | * macro (valid after reloc) for subsequent SCI calls. |
224 | */ | 227 | */ |
225 | if (gd->arch.ipc_channel_handle != SC_IPC_CH) { | 228 | if (gd->arch.ipc_channel_handle != SC_IPC_CH) { |
226 | printf("\nSCI error! Invalid handle\n"); | 229 | printf("\nSCI error! Invalid handle\n"); |
227 | } | 230 | } |
228 | 231 | ||
229 | return 0; | 232 | return 0; |
230 | } | 233 | } |
231 | 234 | ||
232 | #ifdef CONFIG_FSL_HSIO | 235 | #ifdef CONFIG_FSL_HSIO |
233 | 236 | ||
234 | #define PCIE_PAD_CTRL ((SC_PAD_CONFIG_OD_IN << PADRING_CONFIG_SHIFT)) | 237 | #define PCIE_PAD_CTRL ((SC_PAD_CONFIG_OD_IN << PADRING_CONFIG_SHIFT)) |
235 | static iomux_cfg_t board_pcie_pins[] = { | 238 | static iomux_cfg_t board_pcie_pins[] = { |
236 | SC_P_PCIE_CTRL0_CLKREQ_B | MUX_MODE_ALT(0) | MUX_PAD_CTRL(PCIE_PAD_CTRL), | 239 | SC_P_PCIE_CTRL0_CLKREQ_B | MUX_MODE_ALT(0) | MUX_PAD_CTRL(PCIE_PAD_CTRL), |
237 | SC_P_PCIE_CTRL0_WAKE_B | MUX_MODE_ALT(0) | MUX_PAD_CTRL(PCIE_PAD_CTRL), | 240 | SC_P_PCIE_CTRL0_WAKE_B | MUX_MODE_ALT(0) | MUX_PAD_CTRL(PCIE_PAD_CTRL), |
238 | SC_P_PCIE_CTRL0_PERST_B | MUX_MODE_ALT(0) | MUX_PAD_CTRL(PCIE_PAD_CTRL), | 241 | SC_P_PCIE_CTRL0_PERST_B | MUX_MODE_ALT(0) | MUX_PAD_CTRL(PCIE_PAD_CTRL), |
239 | }; | 242 | }; |
240 | 243 | ||
241 | static void imx8qm_hsio_initialize(void) | 244 | static void imx8qm_hsio_initialize(void) |
242 | { | 245 | { |
243 | struct power_domain pd; | 246 | struct power_domain pd; |
244 | int ret; | 247 | int ret; |
245 | 248 | ||
246 | if (!power_domain_lookup_name("hsio_sata0", &pd)) { | 249 | if (!power_domain_lookup_name("hsio_sata0", &pd)) { |
247 | ret = power_domain_on(&pd); | 250 | ret = power_domain_on(&pd); |
248 | if (ret) | 251 | if (ret) |
249 | printf("hsio_sata0 Power up failed! (error = %d)\n", ret); | 252 | printf("hsio_sata0 Power up failed! (error = %d)\n", ret); |
250 | } | 253 | } |
251 | 254 | ||
252 | if (!power_domain_lookup_name("hsio_pcie0", &pd)) { | 255 | if (!power_domain_lookup_name("hsio_pcie0", &pd)) { |
253 | ret = power_domain_on(&pd); | 256 | ret = power_domain_on(&pd); |
254 | if (ret) | 257 | if (ret) |
255 | printf("hsio_pcie0 Power up failed! (error = %d)\n", ret); | 258 | printf("hsio_pcie0 Power up failed! (error = %d)\n", ret); |
256 | } | 259 | } |
257 | 260 | ||
258 | if (!power_domain_lookup_name("hsio_pcie1", &pd)) { | 261 | if (!power_domain_lookup_name("hsio_pcie1", &pd)) { |
259 | ret = power_domain_on(&pd); | 262 | ret = power_domain_on(&pd); |
260 | if (ret) | 263 | if (ret) |
261 | printf("hsio_pcie1 Power up failed! (error = %d)\n", ret); | 264 | printf("hsio_pcie1 Power up failed! (error = %d)\n", ret); |
262 | } | 265 | } |
263 | 266 | ||
264 | if (!power_domain_lookup_name("hsio_gpio", &pd)) { | 267 | if (!power_domain_lookup_name("hsio_gpio", &pd)) { |
265 | ret = power_domain_on(&pd); | 268 | ret = power_domain_on(&pd); |
266 | if (ret) | 269 | if (ret) |
267 | printf("hsio_gpio Power up failed! (error = %d)\n", ret); | 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 | imx8_iomux_setup_multiple_pads(board_pcie_pins, ARRAY_SIZE(board_pcie_pins)); | 286 | imx8_iomux_setup_multiple_pads(board_pcie_pins, ARRAY_SIZE(board_pcie_pins)); |
271 | } | 287 | } |
272 | 288 | ||
273 | void pci_init_board(void) | 289 | void pci_init_board(void) |
274 | { | 290 | { |
275 | /* test the 1 lane mode of the PCIe A controller */ | 291 | /* test the 1 lane mode of the PCIe A controller */ |
276 | mx8qm_pcie_init(); | 292 | mx8qm_pcie_init(); |
277 | } | 293 | } |
278 | #endif | 294 | #endif |
279 | 295 | ||
280 | #ifdef CONFIG_USB | 296 | #ifdef CONFIG_USB |
281 | 297 | ||
282 | #ifdef CONFIG_USB_TCPC | 298 | #ifdef CONFIG_USB_TCPC |
283 | #define USB_TYPEC_SEL IMX_GPIO_NR(4, 6) | 299 | #define USB_TYPEC_SEL IMX_GPIO_NR(4, 6) |
284 | #define USB_TYPEC_EN IMX_GPIO_NR(4, 19) | 300 | #define USB_TYPEC_EN IMX_GPIO_NR(4, 19) |
285 | 301 | ||
286 | static iomux_cfg_t ss_mux_gpio[] = { | 302 | static iomux_cfg_t ss_mux_gpio[] = { |
287 | SC_P_USB_SS3_TC3 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(GPIO_PAD_CTRL), | 303 | SC_P_USB_SS3_TC3 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(GPIO_PAD_CTRL), |
288 | SC_P_QSPI1A_SS0_B | MUX_MODE_ALT(3) | MUX_PAD_CTRL(GPIO_PAD_CTRL), | 304 | SC_P_QSPI1A_SS0_B | MUX_MODE_ALT(3) | MUX_PAD_CTRL(GPIO_PAD_CTRL), |
289 | }; | 305 | }; |
290 | 306 | ||
291 | struct tcpc_port port; | 307 | struct tcpc_port port; |
292 | struct tcpc_port_config port_config = { | 308 | struct tcpc_port_config port_config = { |
293 | .i2c_bus = 0, | 309 | .i2c_bus = 0, |
294 | .addr = 0x51, | 310 | .addr = 0x51, |
295 | .port_type = TYPEC_PORT_DFP, | 311 | .port_type = TYPEC_PORT_DFP, |
296 | }; | 312 | }; |
297 | 313 | ||
298 | void ss_mux_select(enum typec_cc_polarity pol) | 314 | void ss_mux_select(enum typec_cc_polarity pol) |
299 | { | 315 | { |
300 | if (pol == TYPEC_POLARITY_CC1) | 316 | if (pol == TYPEC_POLARITY_CC1) |
301 | gpio_direction_output(USB_TYPEC_SEL, 0); | 317 | gpio_direction_output(USB_TYPEC_SEL, 0); |
302 | else | 318 | else |
303 | gpio_direction_output(USB_TYPEC_SEL, 1); | 319 | gpio_direction_output(USB_TYPEC_SEL, 1); |
304 | } | 320 | } |
305 | 321 | ||
306 | static void setup_typec(void) | 322 | static void setup_typec(void) |
307 | { | 323 | { |
308 | imx8_iomux_setup_multiple_pads(ss_mux_gpio, ARRAY_SIZE(ss_mux_gpio)); | 324 | imx8_iomux_setup_multiple_pads(ss_mux_gpio, ARRAY_SIZE(ss_mux_gpio)); |
309 | gpio_request(USB_TYPEC_SEL, "typec_sel"); | 325 | gpio_request(USB_TYPEC_SEL, "typec_sel"); |
310 | gpio_request(USB_TYPEC_EN, "typec_en"); | 326 | gpio_request(USB_TYPEC_EN, "typec_en"); |
311 | 327 | ||
312 | gpio_direction_output(USB_TYPEC_EN, 1); | 328 | gpio_direction_output(USB_TYPEC_EN, 1); |
313 | 329 | ||
314 | tcpc_init(&port, port_config, &ss_mux_select); | 330 | tcpc_init(&port, port_config, &ss_mux_select); |
315 | } | 331 | } |
316 | #endif | 332 | #endif |
317 | 333 | ||
318 | #ifdef CONFIG_USB_CDNS3_GADGET | 334 | #ifdef CONFIG_USB_CDNS3_GADGET |
319 | static struct cdns3_device cdns3_device_data = { | 335 | static struct cdns3_device cdns3_device_data = { |
320 | .none_core_base = 0x5B110000, | 336 | .none_core_base = 0x5B110000, |
321 | .xhci_base = 0x5B130000, | 337 | .xhci_base = 0x5B130000, |
322 | .dev_base = 0x5B140000, | 338 | .dev_base = 0x5B140000, |
323 | .phy_base = 0x5B160000, | 339 | .phy_base = 0x5B160000, |
324 | .otg_base = 0x5B120000, | 340 | .otg_base = 0x5B120000, |
325 | .dr_mode = USB_DR_MODE_PERIPHERAL, | 341 | .dr_mode = USB_DR_MODE_PERIPHERAL, |
326 | .index = 1, | 342 | .index = 1, |
327 | }; | 343 | }; |
328 | 344 | ||
329 | int usb_gadget_handle_interrupts(void) | 345 | int usb_gadget_handle_interrupts(void) |
330 | { | 346 | { |
331 | cdns3_uboot_handle_interrupt(1); | 347 | cdns3_uboot_handle_interrupt(1); |
332 | return 0; | 348 | return 0; |
333 | } | 349 | } |
334 | #endif | 350 | #endif |
335 | 351 | ||
336 | int board_usb_init(int index, enum usb_init_type init) | 352 | int board_usb_init(int index, enum usb_init_type init) |
337 | { | 353 | { |
338 | int ret = 0; | 354 | int ret = 0; |
339 | 355 | ||
340 | if (index == 1) { | 356 | if (index == 1) { |
341 | if (init == USB_INIT_HOST) { | 357 | if (init == USB_INIT_HOST) { |
342 | #ifdef CONFIG_USB_TCPC | 358 | #ifdef CONFIG_USB_TCPC |
343 | ret = tcpc_setup_dfp_mode(&port); | 359 | ret = tcpc_setup_dfp_mode(&port); |
344 | #endif | 360 | #endif |
345 | #ifdef CONFIG_USB_CDNS3_GADGET | 361 | #ifdef CONFIG_USB_CDNS3_GADGET |
346 | } else { | 362 | } else { |
347 | struct power_domain pd; | 363 | struct power_domain pd; |
348 | int ret; | 364 | int ret; |
349 | 365 | ||
350 | /* Power on usb */ | 366 | /* Power on usb */ |
351 | if (!power_domain_lookup_name("conn_usb2", &pd)) { | 367 | if (!power_domain_lookup_name("conn_usb2", &pd)) { |
352 | ret = power_domain_on(&pd); | 368 | ret = power_domain_on(&pd); |
353 | if (ret) | 369 | if (ret) |
354 | printf("conn_usb2 Power up failed! (error = %d)\n", ret); | 370 | printf("conn_usb2 Power up failed! (error = %d)\n", ret); |
355 | } | 371 | } |
356 | 372 | ||
357 | if (!power_domain_lookup_name("conn_usb2_phy", &pd)) { | 373 | if (!power_domain_lookup_name("conn_usb2_phy", &pd)) { |
358 | ret = power_domain_on(&pd); | 374 | ret = power_domain_on(&pd); |
359 | if (ret) | 375 | if (ret) |
360 | printf("conn_usb2_phy Power up failed! (error = %d)\n", ret); | 376 | printf("conn_usb2_phy Power up failed! (error = %d)\n", ret); |
361 | } | 377 | } |
362 | 378 | ||
363 | #ifdef CONFIG_USB_TCPC | 379 | #ifdef CONFIG_USB_TCPC |
364 | ret = tcpc_setup_ufp_mode(&port); | 380 | ret = tcpc_setup_ufp_mode(&port); |
365 | printf("%d setufp mode %d\n", index, ret); | 381 | printf("%d setufp mode %d\n", index, ret); |
366 | #endif | 382 | #endif |
367 | 383 | ||
368 | ret = cdns3_uboot_init(&cdns3_device_data); | 384 | ret = cdns3_uboot_init(&cdns3_device_data); |
369 | printf("%d cdns3_uboot_initmode %d\n", index, ret); | 385 | printf("%d cdns3_uboot_initmode %d\n", index, ret); |
370 | #endif | 386 | #endif |
371 | } | 387 | } |
372 | } | 388 | } |
373 | return ret; | 389 | return ret; |
374 | } | 390 | } |
375 | 391 | ||
376 | int board_usb_cleanup(int index, enum usb_init_type init) | 392 | int board_usb_cleanup(int index, enum usb_init_type init) |
377 | { | 393 | { |
378 | int ret = 0; | 394 | int ret = 0; |
379 | 395 | ||
380 | if (index == 1) { | 396 | if (index == 1) { |
381 | if (init == USB_INIT_HOST) { | 397 | if (init == USB_INIT_HOST) { |
382 | #ifdef CONFIG_USB_TCPC | 398 | #ifdef CONFIG_USB_TCPC |
383 | ret = tcpc_disable_src_vbus(&port); | 399 | ret = tcpc_disable_src_vbus(&port); |
384 | #endif | 400 | #endif |
385 | #ifdef CONFIG_USB_CDNS3_GADGET | 401 | #ifdef CONFIG_USB_CDNS3_GADGET |
386 | } else { | 402 | } else { |
387 | struct power_domain pd; | 403 | struct power_domain pd; |
388 | int ret; | 404 | int ret; |
389 | 405 | ||
390 | cdns3_uboot_exit(1); | 406 | cdns3_uboot_exit(1); |
391 | 407 | ||
392 | /* Power off usb */ | 408 | /* Power off usb */ |
393 | if (!power_domain_lookup_name("conn_usb2", &pd)) { | 409 | if (!power_domain_lookup_name("conn_usb2", &pd)) { |
394 | ret = power_domain_off(&pd); | 410 | ret = power_domain_off(&pd); |
395 | if (ret) | 411 | if (ret) |
396 | printf("conn_usb2 Power up failed! (error = %d)\n", ret); | 412 | printf("conn_usb2 Power up failed! (error = %d)\n", ret); |
397 | } | 413 | } |
398 | 414 | ||
399 | if (!power_domain_lookup_name("conn_usb2_phy", &pd)) { | 415 | if (!power_domain_lookup_name("conn_usb2_phy", &pd)) { |
400 | ret = power_domain_off(&pd); | 416 | ret = power_domain_off(&pd); |
401 | if (ret) | 417 | if (ret) |
402 | printf("conn_usb2_phy Power up failed! (error = %d)\n", ret); | 418 | printf("conn_usb2_phy Power up failed! (error = %d)\n", ret); |
403 | } | 419 | } |
404 | #endif | 420 | #endif |
405 | } | 421 | } |
406 | } | 422 | } |
407 | return ret; | 423 | return ret; |
408 | } | 424 | } |
409 | #endif | 425 | #endif |
410 | 426 | ||
411 | int board_init(void) | 427 | int board_init(void) |
412 | { | 428 | { |
413 | if (IS_ENABLED(CONFIG_XEN)) | 429 | if (IS_ENABLED(CONFIG_XEN)) |
414 | return 0; | 430 | return 0; |
415 | 431 | ||
416 | /* Power up base board */ | 432 | /* Power up base board */ |
417 | sc_pm_set_resource_power_mode(gd->arch.ipc_channel_handle, | 433 | sc_pm_set_resource_power_mode(gd->arch.ipc_channel_handle, |
418 | SC_R_BOARD_R1, SC_PM_PW_MODE_ON); | 434 | SC_R_BOARD_R1, SC_PM_PW_MODE_ON); |
419 | 435 | ||
420 | #ifdef CONFIG_MXC_GPIO | 436 | #ifdef CONFIG_MXC_GPIO |
421 | board_gpio_init(); | 437 | board_gpio_init(); |
422 | #endif | 438 | #endif |
423 | 439 | ||
424 | #ifdef CONFIG_FSL_HSIO | 440 | #ifdef CONFIG_FSL_HSIO |
425 | imx8qm_hsio_initialize(); | 441 | imx8qm_hsio_initialize(); |
426 | #ifdef CONFIG_SCSI_AHCI_PLAT | 442 | #ifdef CONFIG_SCSI_AHCI_PLAT |
427 | sata_init(); | 443 | sata_init(); |
428 | #endif | 444 | #endif |
429 | #endif | 445 | #endif |
430 | 446 | ||
431 | #if defined(CONFIG_USB_XHCI_IMX8) && defined(CONFIG_USB_TCPC) | 447 | #if defined(CONFIG_USB_XHCI_IMX8) && defined(CONFIG_USB_TCPC) |
432 | setup_typec(); | 448 | setup_typec(); |
433 | #endif | 449 | #endif |
434 | 450 | ||
435 | return 0; | 451 | return 0; |
436 | } | 452 | } |
437 | 453 | ||
438 | void board_quiesce_devices(void) | 454 | void board_quiesce_devices(void) |
439 | { | 455 | { |
440 | const char *power_on_devices[] = { | 456 | const char *power_on_devices[] = { |
441 | "dma_lpuart0", | 457 | "dma_lpuart0", |
442 | }; | 458 | }; |
443 | 459 | ||
444 | if (IS_ENABLED(CONFIG_XEN)) | 460 | if (IS_ENABLED(CONFIG_XEN)) |
445 | return; | 461 | return; |
446 | 462 | ||
447 | power_off_pd_devices(power_on_devices, ARRAY_SIZE(power_on_devices)); | 463 | power_off_pd_devices(power_on_devices, ARRAY_SIZE(power_on_devices)); |
448 | } | 464 | } |
449 | 465 | ||
450 | void detail_board_ddr_info(void) | 466 | void detail_board_ddr_info(void) |
451 | { | 467 | { |
452 | puts("\nDDR "); | 468 | puts("\nDDR "); |
453 | } | 469 | } |
454 | 470 | ||
455 | /* | 471 | /* |
456 | * Board specific reset that is system reset. | 472 | * Board specific reset that is system reset. |
457 | */ | 473 | */ |
458 | void reset_cpu(ulong addr) | 474 | void reset_cpu(ulong addr) |
459 | { | 475 | { |
460 | puts("SCI reboot request"); | 476 | puts("SCI reboot request"); |
461 | sc_pm_reboot(SC_IPC_CH, SC_PM_RESET_TYPE_COLD); | 477 | sc_pm_reboot(SC_IPC_CH, SC_PM_RESET_TYPE_COLD); |
462 | while (1) | 478 | while (1) |
463 | putc('.'); | 479 | putc('.'); |
464 | } | 480 | } |
465 | 481 | ||
466 | #ifdef CONFIG_OF_BOARD_SETUP | 482 | #ifdef CONFIG_OF_BOARD_SETUP |
467 | int ft_board_setup(void *blob, bd_t *bd) | 483 | int ft_board_setup(void *blob, bd_t *bd) |
468 | { | 484 | { |
469 | return 0; | 485 | return 0; |
470 | } | 486 | } |
471 | #endif | 487 | #endif |
472 | 488 | ||
473 | int board_mmc_get_env_dev(int devno) | 489 | int board_mmc_get_env_dev(int devno) |
474 | { | 490 | { |
475 | /* Use EMMC */ | 491 | /* Use EMMC */ |
476 | if (IS_ENABLED(CONFIG_XEN)) | 492 | if (IS_ENABLED(CONFIG_XEN)) |
477 | return 0; | 493 | return 0; |
478 | 494 | ||
479 | return devno; | 495 | return devno; |
480 | } | 496 | } |
481 | 497 | ||
482 | int mmc_map_to_kernel_blk(int dev_no) | 498 | int mmc_map_to_kernel_blk(int dev_no) |
483 | { | 499 | { |
484 | /* Use EMMC */ | 500 | /* Use EMMC */ |
485 | if (IS_ENABLED(CONFIG_XEN)) | 501 | if (IS_ENABLED(CONFIG_XEN)) |
486 | return 0; | 502 | return 0; |
487 | 503 | ||
488 | return dev_no; | 504 | return dev_no; |
489 | } | 505 | } |
490 | 506 | ||
491 | extern uint32_t _end_ofs; | 507 | extern uint32_t _end_ofs; |
492 | int board_late_init(void) | 508 | int board_late_init(void) |
493 | { | 509 | { |
494 | #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG | 510 | #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG |
495 | env_set("board_name", "MEK"); | 511 | env_set("board_name", "MEK"); |
496 | env_set("board_rev", "iMX8QM"); | 512 | env_set("board_rev", "iMX8QM"); |
497 | #endif | 513 | #endif |
498 | 514 | ||
499 | env_set("sec_boot", "no"); | 515 | env_set("sec_boot", "no"); |
500 | #ifdef CONFIG_AHAB_BOOT | 516 | #ifdef CONFIG_AHAB_BOOT |
501 | env_set("sec_boot", "yes"); | 517 | env_set("sec_boot", "yes"); |
502 | #endif | 518 | #endif |
503 | 519 | ||
504 | #ifdef CONFIG_ENV_IS_IN_MMC | 520 | #ifdef CONFIG_ENV_IS_IN_MMC |
505 | board_late_mmc_env_init(); | 521 | board_late_mmc_env_init(); |
506 | #endif | 522 | #endif |
507 | 523 | ||
508 | #ifdef IMX_LOAD_HDMI_FIMRWARE | 524 | #ifdef IMX_LOAD_HDMI_FIMRWARE |
509 | char *end_of_uboot; | 525 | char *end_of_uboot; |
510 | char command[256]; | 526 | char command[256]; |
511 | end_of_uboot = (char *)(ulong)(CONFIG_SYS_TEXT_BASE + _end_ofs + fdt_totalsize(gd->fdt_blob)); | 527 | end_of_uboot = (char *)(ulong)(CONFIG_SYS_TEXT_BASE + _end_ofs + fdt_totalsize(gd->fdt_blob)); |
512 | end_of_uboot += 9; | 528 | end_of_uboot += 9; |
513 | 529 | ||
514 | /* load hdmitxfw.bin and hdmirxfw.bin*/ | 530 | /* load hdmitxfw.bin and hdmirxfw.bin*/ |
515 | memcpy(IMX_HDMI_FIRMWARE_LOAD_ADDR, end_of_uboot, | 531 | memcpy(IMX_HDMI_FIRMWARE_LOAD_ADDR, end_of_uboot, |
516 | IMX_HDMITX_FIRMWARE_SIZE + IMX_HDMIRX_FIRMWARE_SIZE); | 532 | IMX_HDMITX_FIRMWARE_SIZE + IMX_HDMIRX_FIRMWARE_SIZE); |
517 | 533 | ||
518 | sprintf(command, "hdp load 0x%x", IMX_HDMI_FIRMWARE_LOAD_ADDR); | 534 | sprintf(command, "hdp load 0x%x", IMX_HDMI_FIRMWARE_LOAD_ADDR); |
519 | run_command(command, 0); | 535 | run_command(command, 0); |
520 | 536 | ||
521 | sprintf(command, "hdprx load 0x%x", | 537 | sprintf(command, "hdprx load 0x%x", |
522 | IMX_HDMI_FIRMWARE_LOAD_ADDR + IMX_HDMITX_FIRMWARE_SIZE); | 538 | IMX_HDMI_FIRMWARE_LOAD_ADDR + IMX_HDMITX_FIRMWARE_SIZE); |
523 | run_command(command, 0); | 539 | run_command(command, 0); |
524 | #endif | 540 | #endif |
525 | 541 | ||
526 | return 0; | 542 | return 0; |
527 | } | 543 | } |
528 | 544 | ||
529 | #ifdef CONFIG_FSL_FASTBOOT | 545 | #ifdef CONFIG_FSL_FASTBOOT |
530 | #ifdef CONFIG_ANDROID_RECOVERY | 546 | #ifdef CONFIG_ANDROID_RECOVERY |
531 | int is_recovery_key_pressing(void) | 547 | int is_recovery_key_pressing(void) |
532 | { | 548 | { |
533 | return 0; /*TODO*/ | 549 | return 0; /*TODO*/ |
534 | } | 550 | } |
535 | #endif /*CONFIG_ANDROID_RECOVERY*/ | 551 | #endif /*CONFIG_ANDROID_RECOVERY*/ |
536 | #endif /*CONFIG_FSL_FASTBOOT*/ | 552 | #endif /*CONFIG_FSL_FASTBOOT*/ |
537 | 553 | ||
538 | #if defined(CONFIG_VIDEO_IMXDPUV1) | 554 | #if defined(CONFIG_VIDEO_IMXDPUV1) |
539 | static void enable_lvds(struct display_info_t const *dev) | 555 | static void enable_lvds(struct display_info_t const *dev) |
540 | { | 556 | { |
541 | display_controller_setup((PS2KHZ(dev->mode.pixclock) * 1000)); | 557 | display_controller_setup((PS2KHZ(dev->mode.pixclock) * 1000)); |
542 | lvds_soc_setup(dev->bus, (PS2KHZ(dev->mode.pixclock) * 1000)); | 558 | lvds_soc_setup(dev->bus, (PS2KHZ(dev->mode.pixclock) * 1000)); |
543 | lvds_configure(dev->bus); | 559 | lvds_configure(dev->bus); |
544 | lvds2hdmi_setup(6); | 560 | lvds2hdmi_setup(6); |
545 | } | 561 | } |
546 | 562 | ||
547 | struct display_info_t const displays[] = {{ | 563 | struct display_info_t const displays[] = {{ |
548 | .bus = 0, /* LVDS0 */ | 564 | .bus = 0, /* LVDS0 */ |
549 | .addr = 0, /* Unused */ | 565 | .addr = 0, /* Unused */ |
550 | .pixfmt = IMXDPUV1_PIX_FMT_BGRA32, | 566 | .pixfmt = IMXDPUV1_PIX_FMT_BGRA32, |
551 | .detect = NULL, | 567 | .detect = NULL, |
552 | .enable = enable_lvds, | 568 | .enable = enable_lvds, |
553 | .mode = { | 569 | .mode = { |
554 | .name = "IT6263", /* 720P60 */ | 570 | .name = "IT6263", /* 720P60 */ |
555 | .refresh = 60, | 571 | .refresh = 60, |
556 | .xres = 1280, | 572 | .xres = 1280, |
557 | .yres = 720, | 573 | .yres = 720, |
558 | .pixclock = 13468, /* 74250000 */ | 574 | .pixclock = 13468, /* 74250000 */ |
559 | .left_margin = 110, | 575 | .left_margin = 110, |
560 | .right_margin = 220, | 576 | .right_margin = 220, |
561 | .upper_margin = 5, | 577 | .upper_margin = 5, |
562 | .lower_margin = 20, | 578 | .lower_margin = 20, |
563 | .hsync_len = 40, | 579 | .hsync_len = 40, |
564 | .vsync_len = 5, | 580 | .vsync_len = 5, |
565 | .sync = FB_SYNC_EXT, | 581 | .sync = FB_SYNC_EXT, |
566 | .vmode = FB_VMODE_NONINTERLACED | 582 | .vmode = FB_VMODE_NONINTERLACED |
567 | } } }; | 583 | } } }; |
568 | size_t display_count = ARRAY_SIZE(displays); | 584 | size_t display_count = ARRAY_SIZE(displays); |
569 | 585 | ||
570 | #endif /* CONFIG_VIDEO_IMXDPUV1 */ | 586 | #endif /* CONFIG_VIDEO_IMXDPUV1 */ |
571 | 587 |
board/freescale/imx8qxp_arm2/imx8qxp_arm2.c
1 | /* | 1 | /* |
2 | * Copyright 2017-2018 NXP | 2 | * Copyright 2017-2018 NXP |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: GPL-2.0+ | 4 | * SPDX-License-Identifier: GPL-2.0+ |
5 | */ | 5 | */ |
6 | #include <common.h> | 6 | #include <common.h> |
7 | #include <malloc.h> | 7 | #include <malloc.h> |
8 | #include <errno.h> | 8 | #include <errno.h> |
9 | #include <netdev.h> | 9 | #include <netdev.h> |
10 | #include <fsl_ifc.h> | 10 | #include <fsl_ifc.h> |
11 | #include <fdt_support.h> | 11 | #include <fdt_support.h> |
12 | #include <linux/libfdt.h> | 12 | #include <linux/libfdt.h> |
13 | #include <environment.h> | 13 | #include <environment.h> |
14 | #include <fsl_esdhc.h> | 14 | #include <fsl_esdhc.h> |
15 | #include <i2c.h> | 15 | #include <i2c.h> |
16 | #include "pca953x.h" | 16 | #include "pca953x.h" |
17 | 17 | ||
18 | #include <asm/io.h> | 18 | #include <asm/io.h> |
19 | #include <asm/gpio.h> | 19 | #include <asm/gpio.h> |
20 | #include <asm/arch/clock.h> | 20 | #include <asm/arch/clock.h> |
21 | #include <asm/mach-imx/sci/sci.h> | 21 | #include <asm/mach-imx/sci/sci.h> |
22 | #include <asm/arch/imx8-pins.h> | 22 | #include <asm/arch/imx8-pins.h> |
23 | #include <dm.h> | 23 | #include <dm.h> |
24 | #include <imx8_hsio.h> | 24 | #include <imx8_hsio.h> |
25 | #include <usb.h> | 25 | #include <usb.h> |
26 | #include <asm/arch/iomux.h> | 26 | #include <asm/arch/iomux.h> |
27 | #include <asm/arch/sys_proto.h> | 27 | #include <asm/arch/sys_proto.h> |
28 | #include <asm/mach-imx/video.h> | 28 | #include <asm/mach-imx/video.h> |
29 | #include <asm/mach-imx/dma.h> | 29 | #include <asm/mach-imx/dma.h> |
30 | #include <asm/arch/video_common.h> | 30 | #include <asm/arch/video_common.h> |
31 | #include <power-domain.h> | 31 | #include <power-domain.h> |
32 | #include <cdns3-uboot.h> | 32 | #include <cdns3-uboot.h> |
33 | #include <asm/arch/lpcg.h> | ||
33 | 34 | ||
34 | DECLARE_GLOBAL_DATA_PTR; | 35 | DECLARE_GLOBAL_DATA_PTR; |
35 | 36 | ||
36 | #define ESDHC_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 37 | #define ESDHC_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
37 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 38 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
38 | 39 | ||
39 | #define GPMI_NAND_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) \ | 40 | #define GPMI_NAND_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) \ |
40 | | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 41 | | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
41 | 42 | ||
42 | #define ESDHC_CLK_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 43 | #define ESDHC_CLK_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
43 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 44 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
44 | 45 | ||
45 | 46 | ||
46 | #define ENET_INPUT_PAD_CTRL ((SC_PAD_CONFIG_OD_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 47 | #define ENET_INPUT_PAD_CTRL ((SC_PAD_CONFIG_OD_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
47 | | (SC_PAD_28FDSOI_DSE_18V_10MA << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 48 | | (SC_PAD_28FDSOI_DSE_18V_10MA << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
48 | 49 | ||
49 | #define ENET_NORMAL_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 50 | #define ENET_NORMAL_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
50 | | (SC_PAD_28FDSOI_DSE_18V_10MA << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 51 | | (SC_PAD_28FDSOI_DSE_18V_10MA << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
51 | 52 | ||
52 | #define FSPI_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 53 | #define FSPI_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
53 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 54 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
54 | 55 | ||
55 | #define GPIO_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 56 | #define GPIO_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
56 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 57 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
57 | 58 | ||
58 | #define I2C_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 59 | #define I2C_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
59 | | (SC_PAD_28FDSOI_DSE_DV_LOW << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 60 | | (SC_PAD_28FDSOI_DSE_DV_LOW << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
60 | 61 | ||
61 | #define UART_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 62 | #define UART_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
62 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 63 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
63 | 64 | ||
64 | #ifdef CONFIG_NAND_MXS | 65 | #ifdef CONFIG_NAND_MXS |
65 | static iomux_cfg_t gpmi_nand_pads[] = { | 66 | static iomux_cfg_t gpmi_nand_pads[] = { |
66 | SC_P_EMMC0_CLK | MUX_MODE_ALT(1) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), | 67 | SC_P_EMMC0_CLK | MUX_MODE_ALT(1) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), |
67 | SC_P_EMMC0_DATA0 | MUX_MODE_ALT(1) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), | 68 | SC_P_EMMC0_DATA0 | MUX_MODE_ALT(1) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), |
68 | SC_P_EMMC0_DATA1 | MUX_MODE_ALT(1) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), | 69 | SC_P_EMMC0_DATA1 | MUX_MODE_ALT(1) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), |
69 | SC_P_EMMC0_DATA2 | MUX_MODE_ALT(1) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), | 70 | SC_P_EMMC0_DATA2 | MUX_MODE_ALT(1) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), |
70 | SC_P_EMMC0_DATA3 | MUX_MODE_ALT(1) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), | 71 | SC_P_EMMC0_DATA3 | MUX_MODE_ALT(1) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), |
71 | SC_P_EMMC0_DATA4 | MUX_MODE_ALT(1) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), | 72 | SC_P_EMMC0_DATA4 | MUX_MODE_ALT(1) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), |
72 | SC_P_EMMC0_DATA5 | MUX_MODE_ALT(1) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), | 73 | SC_P_EMMC0_DATA5 | MUX_MODE_ALT(1) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), |
73 | SC_P_EMMC0_DATA6 | MUX_MODE_ALT(1) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), | 74 | SC_P_EMMC0_DATA6 | MUX_MODE_ALT(1) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), |
74 | SC_P_EMMC0_DATA7 | MUX_MODE_ALT(1) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), | 75 | SC_P_EMMC0_DATA7 | MUX_MODE_ALT(1) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), |
75 | SC_P_EMMC0_STROBE | MUX_MODE_ALT(1) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), | 76 | SC_P_EMMC0_STROBE | MUX_MODE_ALT(1) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), |
76 | SC_P_EMMC0_RESET_B | MUX_MODE_ALT(1) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), | 77 | SC_P_EMMC0_RESET_B | MUX_MODE_ALT(1) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), |
77 | SC_P_USDHC1_CMD | MUX_MODE_ALT(1) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), | 78 | SC_P_USDHC1_CMD | MUX_MODE_ALT(1) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), |
78 | SC_P_USDHC1_DATA2 | MUX_MODE_ALT(1) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), | 79 | SC_P_USDHC1_DATA2 | MUX_MODE_ALT(1) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), |
79 | SC_P_USDHC1_DATA3 | MUX_MODE_ALT(1) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), | 80 | SC_P_USDHC1_DATA3 | MUX_MODE_ALT(1) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), |
80 | SC_P_USDHC1_DATA0 | MUX_MODE_ALT(1) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), | 81 | SC_P_USDHC1_DATA0 | MUX_MODE_ALT(1) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), |
81 | 82 | ||
82 | /* i.MX8QXP NAND use nand_re_dqs_pins */ | 83 | /* i.MX8QXP NAND use nand_re_dqs_pins */ |
83 | SC_P_USDHC1_CD_B | MUX_MODE_ALT(3) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), | 84 | SC_P_USDHC1_CD_B | MUX_MODE_ALT(3) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), |
84 | SC_P_USDHC1_VSELECT | MUX_MODE_ALT(3) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), | 85 | SC_P_USDHC1_VSELECT | MUX_MODE_ALT(3) | MUX_PAD_CTRL(GPMI_NAND_PAD_CTRL), |
85 | 86 | ||
86 | }; | 87 | }; |
87 | 88 | ||
88 | static void setup_iomux_gpmi_nand(void) | 89 | static void setup_iomux_gpmi_nand(void) |
89 | { | 90 | { |
90 | imx8_iomux_setup_multiple_pads(gpmi_nand_pads, ARRAY_SIZE(gpmi_nand_pads)); | 91 | imx8_iomux_setup_multiple_pads(gpmi_nand_pads, ARRAY_SIZE(gpmi_nand_pads)); |
91 | } | 92 | } |
92 | 93 | ||
93 | static void imx8qxp_gpmi_nand_initialize(void) | 94 | static void imx8qxp_gpmi_nand_initialize(void) |
94 | { | 95 | { |
95 | int ret; | 96 | int ret; |
96 | #ifdef CONFIG_SPL_BUILD | 97 | #ifdef CONFIG_SPL_BUILD |
97 | sc_ipc_t ipcHndl = 0; | 98 | sc_ipc_t ipcHndl = 0; |
98 | 99 | ||
99 | ipcHndl = gd->arch.ipc_channel_handle; | 100 | ipcHndl = gd->arch.ipc_channel_handle; |
100 | 101 | ||
101 | ret = sc_pm_set_resource_power_mode(ipcHndl, SC_R_DMA_4_CH0, SC_PM_PW_MODE_ON); | 102 | ret = sc_pm_set_resource_power_mode(ipcHndl, SC_R_DMA_4_CH0, SC_PM_PW_MODE_ON); |
102 | if (ret != SC_ERR_NONE) | 103 | if (ret != SC_ERR_NONE) |
103 | return; | 104 | return; |
104 | 105 | ||
105 | 106 | ||
106 | ret = sc_pm_set_resource_power_mode(ipcHndl, SC_R_NAND, SC_PM_PW_MODE_ON); | 107 | ret = sc_pm_set_resource_power_mode(ipcHndl, SC_R_NAND, SC_PM_PW_MODE_ON); |
107 | if (ret != SC_ERR_NONE) | 108 | if (ret != SC_ERR_NONE) |
108 | return; | 109 | return; |
109 | #else | 110 | #else |
110 | struct power_domain pd; | 111 | struct power_domain pd; |
111 | 112 | ||
112 | if (!power_domain_lookup_name("conn_dma4_ch0", &pd)) { | 113 | if (!power_domain_lookup_name("conn_dma4_ch0", &pd)) { |
113 | ret = power_domain_on(&pd); | 114 | ret = power_domain_on(&pd); |
114 | if (ret) | 115 | if (ret) |
115 | printf("conn_dma4_ch0 Power up failed! (error = %d)\n", ret); | 116 | printf("conn_dma4_ch0 Power up failed! (error = %d)\n", ret); |
116 | } | 117 | } |
117 | 118 | ||
118 | if (!power_domain_lookup_name("conn_nand", &pd)) { | 119 | if (!power_domain_lookup_name("conn_nand", &pd)) { |
119 | ret = power_domain_on(&pd); | 120 | ret = power_domain_on(&pd); |
120 | if (ret) | 121 | if (ret) |
121 | printf("conn_nand Power up failed! (error = %d)\n", ret); | 122 | printf("conn_nand Power up failed! (error = %d)\n", ret); |
122 | } | 123 | } |
123 | #endif | 124 | #endif |
124 | 125 | ||
125 | init_clk_gpmi_nand(); | 126 | init_clk_gpmi_nand(); |
126 | setup_iomux_gpmi_nand(); | 127 | setup_iomux_gpmi_nand(); |
127 | mxs_dma_init(); | 128 | mxs_dma_init(); |
128 | 129 | ||
129 | } | 130 | } |
130 | #endif | 131 | #endif |
131 | 132 | ||
132 | static iomux_cfg_t uart0_pads[] = { | 133 | static iomux_cfg_t uart0_pads[] = { |
133 | SC_P_UART0_RX | MUX_PAD_CTRL(UART_PAD_CTRL), | 134 | SC_P_UART0_RX | MUX_PAD_CTRL(UART_PAD_CTRL), |
134 | SC_P_UART0_TX | MUX_PAD_CTRL(UART_PAD_CTRL), | 135 | SC_P_UART0_TX | MUX_PAD_CTRL(UART_PAD_CTRL), |
135 | }; | 136 | }; |
136 | 137 | ||
137 | static void setup_iomux_uart(void) | 138 | static void setup_iomux_uart(void) |
138 | { | 139 | { |
139 | imx8_iomux_setup_multiple_pads(uart0_pads, ARRAY_SIZE(uart0_pads)); | 140 | imx8_iomux_setup_multiple_pads(uart0_pads, ARRAY_SIZE(uart0_pads)); |
140 | } | 141 | } |
141 | 142 | ||
142 | int board_early_init_f(void) | 143 | int board_early_init_f(void) |
143 | { | 144 | { |
144 | sc_ipc_t ipcHndl = 0; | 145 | sc_ipc_t ipcHndl = 0; |
145 | sc_err_t sciErr = 0; | 146 | sc_err_t sciErr = 0; |
146 | 147 | ||
147 | ipcHndl = gd->arch.ipc_channel_handle; | 148 | ipcHndl = gd->arch.ipc_channel_handle; |
148 | 149 | ||
149 | /* Power up UART0 */ | 150 | /* Power up UART0 */ |
150 | sciErr = sc_pm_set_resource_power_mode(ipcHndl, SC_R_UART_0, SC_PM_PW_MODE_ON); | 151 | sciErr = sc_pm_set_resource_power_mode(ipcHndl, SC_R_UART_0, SC_PM_PW_MODE_ON); |
151 | if (sciErr != SC_ERR_NONE) | 152 | if (sciErr != SC_ERR_NONE) |
152 | return 0; | 153 | return 0; |
153 | 154 | ||
154 | /* Set UART0 clock root to 80 MHz */ | 155 | /* Set UART0 clock root to 80 MHz */ |
155 | sc_pm_clock_rate_t rate = 80000000; | 156 | sc_pm_clock_rate_t rate = 80000000; |
156 | sciErr = sc_pm_set_clock_rate(ipcHndl, SC_R_UART_0, 2, &rate); | 157 | sciErr = sc_pm_set_clock_rate(ipcHndl, SC_R_UART_0, 2, &rate); |
157 | if (sciErr != SC_ERR_NONE) | 158 | if (sciErr != SC_ERR_NONE) |
158 | return 0; | 159 | return 0; |
159 | 160 | ||
160 | /* Enable UART0 clock root */ | 161 | /* Enable UART0 clock root */ |
161 | sciErr = sc_pm_clock_enable(ipcHndl, SC_R_UART_0, 2, true, false); | 162 | sciErr = sc_pm_clock_enable(ipcHndl, SC_R_UART_0, 2, true, false); |
162 | if (sciErr != SC_ERR_NONE) | 163 | if (sciErr != SC_ERR_NONE) |
163 | return 0; | 164 | return 0; |
164 | 165 | ||
166 | LPCG_AllClockOn(LPUART_0_LPCG); | ||
167 | |||
165 | setup_iomux_uart(); | 168 | setup_iomux_uart(); |
166 | 169 | ||
167 | #ifdef CONFIG_SPL_BUILD | 170 | #ifdef CONFIG_SPL_BUILD |
168 | #ifdef CONFIG_NAND_MXS | 171 | #ifdef CONFIG_NAND_MXS |
169 | imx8qxp_gpmi_nand_initialize(); | 172 | imx8qxp_gpmi_nand_initialize(); |
170 | #endif | 173 | #endif |
171 | #endif | 174 | #endif |
172 | 175 | ||
173 | return 0; | 176 | return 0; |
174 | } | 177 | } |
175 | 178 | ||
176 | #ifdef CONFIG_FSL_ESDHC | 179 | #ifdef CONFIG_FSL_ESDHC |
177 | 180 | ||
178 | #define USDHC1_CD_GPIO IMX_GPIO_NR(4, 22) | 181 | #define USDHC1_CD_GPIO IMX_GPIO_NR(4, 22) |
179 | 182 | ||
180 | #ifndef CONFIG_SPL_BUILD | 183 | #ifndef CONFIG_SPL_BUILD |
181 | static struct fsl_esdhc_cfg usdhc_cfg[CONFIG_SYS_FSL_USDHC_NUM] = { | 184 | static struct fsl_esdhc_cfg usdhc_cfg[CONFIG_SYS_FSL_USDHC_NUM] = { |
182 | {USDHC1_BASE_ADDR, 0, 8}, | 185 | {USDHC1_BASE_ADDR, 0, 8}, |
183 | #ifndef CONFIG_TARGET_IMX8DX_DDR3_ARM2 | 186 | #ifndef CONFIG_TARGET_IMX8DX_DDR3_ARM2 |
184 | {USDHC2_BASE_ADDR, 0, 4}, | 187 | {USDHC2_BASE_ADDR, 0, 4}, |
185 | #endif | 188 | #endif |
186 | }; | 189 | }; |
187 | 190 | ||
188 | static iomux_cfg_t emmc0[] = { | 191 | static iomux_cfg_t emmc0[] = { |
189 | SC_P_EMMC0_CLK | MUX_PAD_CTRL(ESDHC_CLK_PAD_CTRL), | 192 | SC_P_EMMC0_CLK | MUX_PAD_CTRL(ESDHC_CLK_PAD_CTRL), |
190 | SC_P_EMMC0_CMD | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 193 | SC_P_EMMC0_CMD | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
191 | SC_P_EMMC0_DATA0 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 194 | SC_P_EMMC0_DATA0 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
192 | SC_P_EMMC0_DATA1 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 195 | SC_P_EMMC0_DATA1 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
193 | SC_P_EMMC0_DATA2 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 196 | SC_P_EMMC0_DATA2 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
194 | SC_P_EMMC0_DATA3 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 197 | SC_P_EMMC0_DATA3 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
195 | SC_P_EMMC0_DATA4 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 198 | SC_P_EMMC0_DATA4 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
196 | SC_P_EMMC0_DATA5 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 199 | SC_P_EMMC0_DATA5 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
197 | SC_P_EMMC0_DATA6 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 200 | SC_P_EMMC0_DATA6 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
198 | SC_P_EMMC0_DATA7 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 201 | SC_P_EMMC0_DATA7 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
199 | SC_P_EMMC0_RESET_B | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 202 | SC_P_EMMC0_RESET_B | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
200 | SC_P_EMMC0_STROBE | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 203 | SC_P_EMMC0_STROBE | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
201 | }; | 204 | }; |
202 | 205 | ||
203 | static iomux_cfg_t usdhc1_sd[] = { | 206 | static iomux_cfg_t usdhc1_sd[] = { |
204 | SC_P_USDHC1_CLK | MUX_PAD_CTRL(ESDHC_CLK_PAD_CTRL), | 207 | SC_P_USDHC1_CLK | MUX_PAD_CTRL(ESDHC_CLK_PAD_CTRL), |
205 | SC_P_USDHC1_CMD | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 208 | SC_P_USDHC1_CMD | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
206 | SC_P_USDHC1_DATA0 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 209 | SC_P_USDHC1_DATA0 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
207 | SC_P_USDHC1_DATA1 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 210 | SC_P_USDHC1_DATA1 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
208 | SC_P_USDHC1_DATA2 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 211 | SC_P_USDHC1_DATA2 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
209 | SC_P_USDHC1_DATA3 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 212 | SC_P_USDHC1_DATA3 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
210 | SC_P_USDHC1_WP | MUX_PAD_CTRL(ESDHC_PAD_CTRL), /* Mux for WP */ | 213 | SC_P_USDHC1_WP | MUX_PAD_CTRL(ESDHC_PAD_CTRL), /* Mux for WP */ |
211 | SC_P_USDHC1_CD_B | MUX_MODE_ALT(4) | MUX_PAD_CTRL(ESDHC_PAD_CTRL), /* Mux for CD, GPIO4 IO22 */ | 214 | SC_P_USDHC1_CD_B | MUX_MODE_ALT(4) | MUX_PAD_CTRL(ESDHC_PAD_CTRL), /* Mux for CD, GPIO4 IO22 */ |
212 | SC_P_USDHC1_RESET_B | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 215 | SC_P_USDHC1_RESET_B | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
213 | SC_P_USDHC1_VSELECT | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 216 | SC_P_USDHC1_VSELECT | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
214 | }; | 217 | }; |
215 | 218 | ||
216 | int board_mmc_init(bd_t *bis) | 219 | int board_mmc_init(bd_t *bis) |
217 | { | 220 | { |
218 | int i, ret; | 221 | int i, ret; |
219 | struct power_domain pd; | 222 | struct power_domain pd; |
220 | 223 | ||
221 | #ifdef CONFIG_NAND_MXS | 224 | #ifdef CONFIG_NAND_MXS |
222 | return 0; | 225 | return 0; |
223 | #endif | 226 | #endif |
224 | 227 | ||
225 | /* | 228 | /* |
226 | * According to the board_mmc_init() the following map is done: | 229 | * According to the board_mmc_init() the following map is done: |
227 | * (U-boot device node) (Physical Port) | 230 | * (U-boot device node) (Physical Port) |
228 | * mmc0 USDHC1 | 231 | * mmc0 USDHC1 |
229 | * mmc1 USDHC2 | 232 | * mmc1 USDHC2 |
230 | */ | 233 | */ |
231 | for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) { | 234 | for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) { |
232 | switch (i) { | 235 | switch (i) { |
233 | case 0: | 236 | case 0: |
234 | if (!power_domain_lookup_name("conn_sdhc0", &pd)) | 237 | if (!power_domain_lookup_name("conn_sdhc0", &pd)) |
235 | power_domain_on(&pd); | 238 | power_domain_on(&pd); |
236 | imx8_iomux_setup_multiple_pads(emmc0, ARRAY_SIZE(emmc0)); | 239 | imx8_iomux_setup_multiple_pads(emmc0, ARRAY_SIZE(emmc0)); |
237 | init_clk_usdhc(0); | 240 | init_clk_usdhc(0); |
238 | usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); | 241 | usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); |
239 | break; | 242 | break; |
240 | case 1: | 243 | case 1: |
241 | if (!power_domain_lookup_name("conn_sdhc1", &pd)) | 244 | if (!power_domain_lookup_name("conn_sdhc1", &pd)) |
242 | power_domain_on(&pd); | 245 | power_domain_on(&pd); |
243 | imx8_iomux_setup_multiple_pads(usdhc1_sd, ARRAY_SIZE(usdhc1_sd)); | 246 | imx8_iomux_setup_multiple_pads(usdhc1_sd, ARRAY_SIZE(usdhc1_sd)); |
244 | init_clk_usdhc(1); | 247 | init_clk_usdhc(1); |
245 | usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); | 248 | usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); |
246 | gpio_request(USDHC1_CD_GPIO, "sd1_cd"); | 249 | gpio_request(USDHC1_CD_GPIO, "sd1_cd"); |
247 | gpio_direction_input(USDHC1_CD_GPIO); | 250 | gpio_direction_input(USDHC1_CD_GPIO); |
248 | break; | 251 | break; |
249 | default: | 252 | default: |
250 | printf("Warning: you configured more USDHC controllers" | 253 | printf("Warning: you configured more USDHC controllers" |
251 | "(%d) than supported by the board\n", i + 1); | 254 | "(%d) than supported by the board\n", i + 1); |
252 | return 0; | 255 | return 0; |
253 | } | 256 | } |
254 | ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]); | 257 | ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]); |
255 | if (ret) { | 258 | if (ret) { |
256 | printf("Warning: failed to initialize mmc dev %d\n", i); | 259 | printf("Warning: failed to initialize mmc dev %d\n", i); |
257 | return ret; | 260 | return ret; |
258 | } | 261 | } |
259 | } | 262 | } |
260 | 263 | ||
261 | return 0; | 264 | return 0; |
262 | } | 265 | } |
263 | 266 | ||
264 | int board_mmc_getcd(struct mmc *mmc) | 267 | int board_mmc_getcd(struct mmc *mmc) |
265 | { | 268 | { |
266 | struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; | 269 | struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; |
267 | int ret = 0; | 270 | int ret = 0; |
268 | 271 | ||
269 | switch (cfg->esdhc_base) { | 272 | switch (cfg->esdhc_base) { |
270 | case USDHC1_BASE_ADDR: | 273 | case USDHC1_BASE_ADDR: |
271 | ret = 1; /* eMMC */ | 274 | ret = 1; /* eMMC */ |
272 | break; | 275 | break; |
273 | case USDHC2_BASE_ADDR: | 276 | case USDHC2_BASE_ADDR: |
274 | ret = !gpio_get_value(USDHC1_CD_GPIO); | 277 | ret = !gpio_get_value(USDHC1_CD_GPIO); |
275 | break; | 278 | break; |
276 | } | 279 | } |
277 | 280 | ||
278 | return ret; | 281 | return ret; |
279 | } | 282 | } |
280 | 283 | ||
281 | #endif /* CONFIG_FSL_ESDHC */ | 284 | #endif /* CONFIG_FSL_ESDHC */ |
282 | #endif /* CONFIG_SPL_BUILD */ | 285 | #endif /* CONFIG_SPL_BUILD */ |
283 | 286 | ||
284 | #ifdef CONFIG_FEC_MXC | 287 | #ifdef CONFIG_FEC_MXC |
285 | #include <miiphy.h> | 288 | #include <miiphy.h> |
286 | 289 | ||
287 | static iomux_cfg_t pad_enet1[] = { | 290 | static iomux_cfg_t pad_enet1[] = { |
288 | SC_P_SPDIF0_TX | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 291 | SC_P_SPDIF0_TX | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
289 | SC_P_SPDIF0_RX | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 292 | SC_P_SPDIF0_RX | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
290 | SC_P_ESAI0_TX3_RX2 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 293 | SC_P_ESAI0_TX3_RX2 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
291 | SC_P_ESAI0_TX2_RX3 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 294 | SC_P_ESAI0_TX2_RX3 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
292 | SC_P_ESAI0_TX1 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 295 | SC_P_ESAI0_TX1 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
293 | SC_P_ESAI0_TX0 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 296 | SC_P_ESAI0_TX0 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
294 | SC_P_ESAI0_SCKR | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 297 | SC_P_ESAI0_SCKR | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
295 | SC_P_ESAI0_TX4_RX1 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 298 | SC_P_ESAI0_TX4_RX1 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
296 | SC_P_ESAI0_TX5_RX0 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 299 | SC_P_ESAI0_TX5_RX0 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
297 | SC_P_ESAI0_FST | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 300 | SC_P_ESAI0_FST | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
298 | SC_P_ESAI0_SCKT | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 301 | SC_P_ESAI0_SCKT | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
299 | SC_P_ESAI0_FSR | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 302 | SC_P_ESAI0_FSR | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
300 | 303 | ||
301 | /* Shared MDIO */ | 304 | /* Shared MDIO */ |
302 | SC_P_ENET0_MDC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 305 | SC_P_ENET0_MDC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
303 | SC_P_ENET0_MDIO | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 306 | SC_P_ENET0_MDIO | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
304 | }; | 307 | }; |
305 | 308 | ||
306 | static iomux_cfg_t pad_enet0[] = { | 309 | static iomux_cfg_t pad_enet0[] = { |
307 | SC_P_ENET0_RGMII_RX_CTL | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 310 | SC_P_ENET0_RGMII_RX_CTL | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
308 | SC_P_ENET0_RGMII_RXD0 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 311 | SC_P_ENET0_RGMII_RXD0 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
309 | SC_P_ENET0_RGMII_RXD1 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 312 | SC_P_ENET0_RGMII_RXD1 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
310 | SC_P_ENET0_RGMII_RXD2 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 313 | SC_P_ENET0_RGMII_RXD2 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
311 | SC_P_ENET0_RGMII_RXD3 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 314 | SC_P_ENET0_RGMII_RXD3 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
312 | SC_P_ENET0_RGMII_RXC | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 315 | SC_P_ENET0_RGMII_RXC | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
313 | SC_P_ENET0_RGMII_TX_CTL | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 316 | SC_P_ENET0_RGMII_TX_CTL | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
314 | SC_P_ENET0_RGMII_TXD0 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 317 | SC_P_ENET0_RGMII_TXD0 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
315 | SC_P_ENET0_RGMII_TXD1 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 318 | SC_P_ENET0_RGMII_TXD1 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
316 | SC_P_ENET0_RGMII_TXD2 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 319 | SC_P_ENET0_RGMII_TXD2 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
317 | SC_P_ENET0_RGMII_TXD3 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 320 | SC_P_ENET0_RGMII_TXD3 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
318 | SC_P_ENET0_RGMII_TXC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 321 | SC_P_ENET0_RGMII_TXC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
319 | 322 | ||
320 | /* Shared MDIO */ | 323 | /* Shared MDIO */ |
321 | SC_P_ENET0_MDC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 324 | SC_P_ENET0_MDC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
322 | SC_P_ENET0_MDIO | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 325 | SC_P_ENET0_MDIO | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
323 | }; | 326 | }; |
324 | 327 | ||
325 | static void setup_iomux_fec(void) | 328 | static void setup_iomux_fec(void) |
326 | { | 329 | { |
327 | if (0 == CONFIG_FEC_ENET_DEV) | 330 | if (0 == CONFIG_FEC_ENET_DEV) |
328 | imx8_iomux_setup_multiple_pads(pad_enet0, ARRAY_SIZE(pad_enet0)); | 331 | imx8_iomux_setup_multiple_pads(pad_enet0, ARRAY_SIZE(pad_enet0)); |
329 | else | 332 | else |
330 | imx8_iomux_setup_multiple_pads(pad_enet1, ARRAY_SIZE(pad_enet1)); | 333 | imx8_iomux_setup_multiple_pads(pad_enet1, ARRAY_SIZE(pad_enet1)); |
331 | } | 334 | } |
332 | 335 | ||
333 | static void enet_device_phy_reset(void) | 336 | static void enet_device_phy_reset(void) |
334 | { | 337 | { |
335 | struct gpio_desc desc_enet0; | 338 | struct gpio_desc desc_enet0; |
336 | struct gpio_desc desc_enet1; | 339 | struct gpio_desc desc_enet1; |
337 | int ret; | 340 | int ret; |
338 | 341 | ||
339 | ret = dm_gpio_lookup_name("gpio@18_1", &desc_enet0); | 342 | ret = dm_gpio_lookup_name("gpio@18_1", &desc_enet0); |
340 | if (ret) | 343 | if (ret) |
341 | return; | 344 | return; |
342 | 345 | ||
343 | ret = dm_gpio_request(&desc_enet0, "enet0_reset"); | 346 | ret = dm_gpio_request(&desc_enet0, "enet0_reset"); |
344 | if (ret) | 347 | if (ret) |
345 | return; | 348 | return; |
346 | 349 | ||
347 | ret = dm_gpio_lookup_name("gpio@18_4", &desc_enet1); | 350 | ret = dm_gpio_lookup_name("gpio@18_4", &desc_enet1); |
348 | if (ret) | 351 | if (ret) |
349 | return; | 352 | return; |
350 | 353 | ||
351 | ret = dm_gpio_request(&desc_enet1, "enet1_reset"); | 354 | ret = dm_gpio_request(&desc_enet1, "enet1_reset"); |
352 | if (ret) | 355 | if (ret) |
353 | return; | 356 | return; |
354 | 357 | ||
355 | dm_gpio_set_dir_flags(&desc_enet0, GPIOD_IS_OUT); | 358 | dm_gpio_set_dir_flags(&desc_enet0, GPIOD_IS_OUT); |
356 | dm_gpio_set_value(&desc_enet0, 0); | 359 | dm_gpio_set_value(&desc_enet0, 0); |
357 | udelay(50); | 360 | udelay(50); |
358 | dm_gpio_set_value(&desc_enet0, 1); | 361 | dm_gpio_set_value(&desc_enet0, 1); |
359 | 362 | ||
360 | dm_gpio_set_dir_flags(&desc_enet1, GPIOD_IS_OUT); | 363 | dm_gpio_set_dir_flags(&desc_enet1, GPIOD_IS_OUT); |
361 | dm_gpio_set_value(&desc_enet1, 0); | 364 | dm_gpio_set_value(&desc_enet1, 0); |
362 | udelay(50); | 365 | udelay(50); |
363 | dm_gpio_set_value(&desc_enet1, 1); | 366 | dm_gpio_set_value(&desc_enet1, 1); |
364 | 367 | ||
365 | /* The board has a long delay for this reset to become stable */ | 368 | /* The board has a long delay for this reset to become stable */ |
366 | mdelay(200); | 369 | mdelay(200); |
367 | } | 370 | } |
368 | 371 | ||
369 | int board_eth_init(bd_t *bis) | 372 | int board_eth_init(bd_t *bis) |
370 | { | 373 | { |
371 | int ret; | 374 | int ret; |
372 | struct power_domain pd; | 375 | struct power_domain pd; |
373 | 376 | ||
374 | printf("[%s] %d\n", __func__, __LINE__); | 377 | printf("[%s] %d\n", __func__, __LINE__); |
375 | 378 | ||
376 | if (CONFIG_FEC_ENET_DEV) { | 379 | if (CONFIG_FEC_ENET_DEV) { |
377 | if (!power_domain_lookup_name("conn_enet1", &pd)) | 380 | if (!power_domain_lookup_name("conn_enet1", &pd)) |
378 | power_domain_on(&pd); | 381 | power_domain_on(&pd); |
379 | } else { | 382 | } else { |
380 | if (!power_domain_lookup_name("conn_enet0", &pd)) | 383 | if (!power_domain_lookup_name("conn_enet0", &pd)) |
381 | power_domain_on(&pd); | 384 | power_domain_on(&pd); |
382 | } | 385 | } |
383 | 386 | ||
384 | setup_iomux_fec(); | 387 | setup_iomux_fec(); |
385 | 388 | ||
386 | ret = fecmxc_initialize_multi(bis, CONFIG_FEC_ENET_DEV, | 389 | ret = fecmxc_initialize_multi(bis, CONFIG_FEC_ENET_DEV, |
387 | CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE); | 390 | CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE); |
388 | if (ret) | 391 | if (ret) |
389 | printf("FEC1 MXC: %s:failed\n", __func__); | 392 | printf("FEC1 MXC: %s:failed\n", __func__); |
390 | 393 | ||
391 | return ret; | 394 | return ret; |
392 | } | 395 | } |
393 | 396 | ||
394 | int board_phy_config(struct phy_device *phydev) | 397 | int board_phy_config(struct phy_device *phydev) |
395 | { | 398 | { |
396 | #ifdef CONFIG_FEC_ENABLE_MAX7322 | 399 | #ifdef CONFIG_FEC_ENABLE_MAX7322 |
397 | uint8_t value; | 400 | uint8_t value; |
398 | 401 | ||
399 | /* This is needed to drive the pads to 1.8V instead of 1.5V */ | 402 | /* This is needed to drive the pads to 1.8V instead of 1.5V */ |
400 | i2c_set_bus_num(CONFIG_MAX7322_I2C_BUS); | 403 | i2c_set_bus_num(CONFIG_MAX7322_I2C_BUS); |
401 | 404 | ||
402 | if (!i2c_probe(CONFIG_MAX7322_I2C_ADDR)) { | 405 | if (!i2c_probe(CONFIG_MAX7322_I2C_ADDR)) { |
403 | /* Write 0x1 to enable O0 output, this device has no addr */ | 406 | /* Write 0x1 to enable O0 output, this device has no addr */ |
404 | /* hence addr length is 0 */ | 407 | /* hence addr length is 0 */ |
405 | value = 0x1; | 408 | value = 0x1; |
406 | if (i2c_write(CONFIG_MAX7322_I2C_ADDR, 0, 0, &value, 1)) | 409 | if (i2c_write(CONFIG_MAX7322_I2C_ADDR, 0, 0, &value, 1)) |
407 | printf("MAX7322 write failed\n"); | 410 | printf("MAX7322 write failed\n"); |
408 | } else { | 411 | } else { |
409 | printf("MAX7322 Not found\n"); | 412 | printf("MAX7322 Not found\n"); |
410 | } | 413 | } |
411 | mdelay(1); | 414 | mdelay(1); |
412 | #endif | 415 | #endif |
413 | 416 | ||
414 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f); | 417 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f); |
415 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8); | 418 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8); |
416 | 419 | ||
417 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x00); | 420 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x00); |
418 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x82ee); | 421 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x82ee); |
419 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05); | 422 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05); |
420 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100); | 423 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100); |
421 | 424 | ||
422 | if (phydev->drv->config) | 425 | if (phydev->drv->config) |
423 | phydev->drv->config(phydev); | 426 | phydev->drv->config(phydev); |
424 | 427 | ||
425 | return 0; | 428 | return 0; |
426 | } | 429 | } |
427 | 430 | ||
428 | 431 | ||
429 | 432 | ||
430 | static int setup_fec(int ind) | 433 | static int setup_fec(int ind) |
431 | { | 434 | { |
432 | /* Reset ENET PHY */ | 435 | /* Reset ENET PHY */ |
433 | enet_device_phy_reset(); | 436 | enet_device_phy_reset(); |
434 | 437 | ||
435 | return 0; | 438 | return 0; |
436 | } | 439 | } |
437 | #endif | 440 | #endif |
438 | 441 | ||
439 | #ifdef CONFIG_MXC_GPIO | 442 | #ifdef CONFIG_MXC_GPIO |
440 | 443 | ||
441 | #define DEBUG_LED IMX_GPIO_NR(3, 23) | 444 | #define DEBUG_LED IMX_GPIO_NR(3, 23) |
442 | #define IOEXP_RESET IMX_GPIO_NR(0, 19) | 445 | #define IOEXP_RESET IMX_GPIO_NR(0, 19) |
443 | #define BB_PWR_EN IMX_GPIO_NR(5, 9) | 446 | #define BB_PWR_EN IMX_GPIO_NR(5, 9) |
444 | 447 | ||
445 | static iomux_cfg_t board_gpios[] = { | 448 | static iomux_cfg_t board_gpios[] = { |
446 | SC_P_QSPI0B_SS0_B | MUX_MODE_ALT(4) | MUX_PAD_CTRL(GPIO_PAD_CTRL), | 449 | SC_P_QSPI0B_SS0_B | MUX_MODE_ALT(4) | MUX_PAD_CTRL(GPIO_PAD_CTRL), |
447 | SC_P_MCLK_IN0 | MUX_MODE_ALT(4) | MUX_PAD_CTRL(GPIO_PAD_CTRL), | 450 | SC_P_MCLK_IN0 | MUX_MODE_ALT(4) | MUX_PAD_CTRL(GPIO_PAD_CTRL), |
448 | SC_P_ENET0_REFCLK_125M_25M | MUX_MODE_ALT(4) | MUX_PAD_CTRL(GPIO_PAD_CTRL), | 451 | SC_P_ENET0_REFCLK_125M_25M | MUX_MODE_ALT(4) | MUX_PAD_CTRL(GPIO_PAD_CTRL), |
449 | }; | 452 | }; |
450 | 453 | ||
451 | static void board_gpio_init(void) | 454 | static void board_gpio_init(void) |
452 | { | 455 | { |
453 | imx8_iomux_setup_multiple_pads(board_gpios, ARRAY_SIZE(board_gpios)); | 456 | imx8_iomux_setup_multiple_pads(board_gpios, ARRAY_SIZE(board_gpios)); |
454 | 457 | ||
455 | gpio_request(DEBUG_LED, "debug_led"); | 458 | gpio_request(DEBUG_LED, "debug_led"); |
456 | gpio_direction_output(DEBUG_LED, 1); | 459 | gpio_direction_output(DEBUG_LED, 1); |
457 | 460 | ||
458 | /* enable i2c port expander assert reset line */ | 461 | /* enable i2c port expander assert reset line */ |
459 | gpio_request(IOEXP_RESET, "ioexp_rst"); | 462 | gpio_request(IOEXP_RESET, "ioexp_rst"); |
460 | gpio_direction_output(IOEXP_RESET, 1); | 463 | gpio_direction_output(IOEXP_RESET, 1); |
461 | 464 | ||
462 | /* Enable base board 1.8V power */ | 465 | /* Enable base board 1.8V power */ |
463 | gpio_request(BB_PWR_EN, "bb_pwr_en"); | 466 | gpio_request(BB_PWR_EN, "bb_pwr_en"); |
464 | gpio_direction_output(BB_PWR_EN, 1); | 467 | gpio_direction_output(BB_PWR_EN, 1); |
465 | } | 468 | } |
466 | #endif | 469 | #endif |
467 | 470 | ||
468 | int checkboard(void) | 471 | int checkboard(void) |
469 | { | 472 | { |
470 | #if defined(CONFIG_TARGET_IMX8QXP_DDR3_ARM2) | 473 | #if defined(CONFIG_TARGET_IMX8QXP_DDR3_ARM2) |
471 | puts("Board: iMX8QXP DDR3 ARM2\n"); | 474 | puts("Board: iMX8QXP DDR3 ARM2\n"); |
472 | #elif defined(CONFIG_TARGET_IMX8DX_DDR3_ARM2) | 475 | #elif defined(CONFIG_TARGET_IMX8DX_DDR3_ARM2) |
473 | puts("Board: iMX8DX DDR3 ARM2\n"); | 476 | puts("Board: iMX8DX DDR3 ARM2\n"); |
474 | #else | 477 | #else |
475 | puts("Board: iMX8QXP LPDDR4 ARM2\n"); | 478 | puts("Board: iMX8QXP LPDDR4 ARM2\n"); |
476 | #endif | 479 | #endif |
477 | 480 | ||
478 | print_bootinfo(); | 481 | print_bootinfo(); |
479 | 482 | ||
480 | /* Note: After reloc, ipcHndl will no longer be valid. If handle | 483 | /* Note: After reloc, ipcHndl will no longer be valid. If handle |
481 | * returned by sc_ipc_open matches SC_IPC_CH, use this | 484 | * returned by sc_ipc_open matches SC_IPC_CH, use this |
482 | * macro (valid after reloc) for subsequent SCI calls. | 485 | * macro (valid after reloc) for subsequent SCI calls. |
483 | */ | 486 | */ |
484 | if (gd->arch.ipc_channel_handle != SC_IPC_CH) | 487 | if (gd->arch.ipc_channel_handle != SC_IPC_CH) |
485 | printf("\nSCI error! Invalid handle\n"); | 488 | printf("\nSCI error! Invalid handle\n"); |
486 | 489 | ||
487 | return 0; | 490 | return 0; |
488 | } | 491 | } |
489 | 492 | ||
490 | #ifdef CONFIG_FSL_HSIO | 493 | #ifdef CONFIG_FSL_HSIO |
491 | 494 | ||
492 | #define PCIE_PAD_CTRL ((SC_PAD_CONFIG_OD_IN << PADRING_CONFIG_SHIFT)) | 495 | #define PCIE_PAD_CTRL ((SC_PAD_CONFIG_OD_IN << PADRING_CONFIG_SHIFT)) |
493 | static iomux_cfg_t board_pcie_pins[] = { | 496 | static iomux_cfg_t board_pcie_pins[] = { |
494 | SC_P_PCIE_CTRL0_CLKREQ_B | MUX_MODE_ALT(0) | MUX_PAD_CTRL(PCIE_PAD_CTRL), | 497 | SC_P_PCIE_CTRL0_CLKREQ_B | MUX_MODE_ALT(0) | MUX_PAD_CTRL(PCIE_PAD_CTRL), |
495 | SC_P_PCIE_CTRL0_WAKE_B | MUX_MODE_ALT(0) | MUX_PAD_CTRL(PCIE_PAD_CTRL), | 498 | SC_P_PCIE_CTRL0_WAKE_B | MUX_MODE_ALT(0) | MUX_PAD_CTRL(PCIE_PAD_CTRL), |
496 | SC_P_PCIE_CTRL0_PERST_B | MUX_MODE_ALT(0) | MUX_PAD_CTRL(PCIE_PAD_CTRL), | 499 | SC_P_PCIE_CTRL0_PERST_B | MUX_MODE_ALT(0) | MUX_PAD_CTRL(PCIE_PAD_CTRL), |
497 | }; | 500 | }; |
498 | 501 | ||
499 | static void imx8qxp_hsio_initialize(void) | 502 | static void imx8qxp_hsio_initialize(void) |
500 | { | 503 | { |
501 | struct power_domain pd; | 504 | struct power_domain pd; |
502 | int ret; | 505 | int ret; |
503 | 506 | ||
504 | if (!power_domain_lookup_name("hsio_pcie1", &pd)) { | 507 | if (!power_domain_lookup_name("hsio_pcie1", &pd)) { |
505 | ret = power_domain_on(&pd); | 508 | ret = power_domain_on(&pd); |
506 | if (ret) | 509 | if (ret) |
507 | printf("hsio_pcie1 Power up failed! (error = %d)\n", ret); | 510 | printf("hsio_pcie1 Power up failed! (error = %d)\n", ret); |
508 | } | 511 | } |
509 | if (!power_domain_lookup_name("hsio_gpio", &pd)) { | 512 | if (!power_domain_lookup_name("hsio_gpio", &pd)) { |
510 | ret = power_domain_on(&pd); | 513 | ret = power_domain_on(&pd); |
511 | if (ret) | 514 | if (ret) |
512 | printf("hsio_gpio Power up failed! (error = %d)\n", ret); | 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 | imx8_iomux_setup_multiple_pads(board_pcie_pins, ARRAY_SIZE(board_pcie_pins)); | 525 | imx8_iomux_setup_multiple_pads(board_pcie_pins, ARRAY_SIZE(board_pcie_pins)); |
516 | } | 526 | } |
517 | 527 | ||
518 | void pci_init_board(void) | 528 | void pci_init_board(void) |
519 | { | 529 | { |
520 | imx8qxp_hsio_initialize(); | 530 | imx8qxp_hsio_initialize(); |
521 | 531 | ||
522 | /* test the 1 lane mode of the PCIe A controller */ | 532 | /* test the 1 lane mode of the PCIe A controller */ |
523 | mx8qxp_pcie_init(); | 533 | mx8qxp_pcie_init(); |
524 | } | 534 | } |
525 | 535 | ||
526 | #endif | 536 | #endif |
527 | 537 | ||
528 | #if defined(CONFIG_USB_CDNS3_GADGET) | 538 | #if defined(CONFIG_USB_CDNS3_GADGET) |
529 | 539 | ||
530 | static struct cdns3_device cdns3_device_data = { | 540 | static struct cdns3_device cdns3_device_data = { |
531 | .none_core_base = 0x5B110000, | 541 | .none_core_base = 0x5B110000, |
532 | .xhci_base = 0x5B130000, | 542 | .xhci_base = 0x5B130000, |
533 | .dev_base = 0x5B140000, | 543 | .dev_base = 0x5B140000, |
534 | .phy_base = 0x5B160000, | 544 | .phy_base = 0x5B160000, |
535 | .otg_base = 0x5B120000, | 545 | .otg_base = 0x5B120000, |
536 | .dr_mode = USB_DR_MODE_PERIPHERAL, | 546 | .dr_mode = USB_DR_MODE_PERIPHERAL, |
537 | .index = 1, | 547 | .index = 1, |
538 | }; | 548 | }; |
539 | 549 | ||
540 | int usb_gadget_handle_interrupts(void) | 550 | int usb_gadget_handle_interrupts(void) |
541 | { | 551 | { |
542 | cdns3_uboot_handle_interrupt(1); | 552 | cdns3_uboot_handle_interrupt(1); |
543 | return 0; | 553 | return 0; |
544 | } | 554 | } |
545 | 555 | ||
546 | int board_usb_init(int index, enum usb_init_type init) | 556 | int board_usb_init(int index, enum usb_init_type init) |
547 | { | 557 | { |
548 | int ret = 0; | 558 | int ret = 0; |
549 | 559 | ||
550 | if (index == 1) { | 560 | if (index == 1) { |
551 | if (init == USB_INIT_DEVICE) { | 561 | if (init == USB_INIT_DEVICE) { |
552 | struct power_domain pd; | 562 | struct power_domain pd; |
553 | int ret; | 563 | int ret; |
554 | 564 | ||
555 | /* Power on usb */ | 565 | /* Power on usb */ |
556 | if (!power_domain_lookup_name("conn_usb2", &pd)) { | 566 | if (!power_domain_lookup_name("conn_usb2", &pd)) { |
557 | ret = power_domain_on(&pd); | 567 | ret = power_domain_on(&pd); |
558 | if (ret) | 568 | if (ret) |
559 | printf("conn_usb2 Power up failed! (error = %d)\n", ret); | 569 | printf("conn_usb2 Power up failed! (error = %d)\n", ret); |
560 | } | 570 | } |
561 | 571 | ||
562 | if (!power_domain_lookup_name("conn_usb2_phy", &pd)) { | 572 | if (!power_domain_lookup_name("conn_usb2_phy", &pd)) { |
563 | ret = power_domain_on(&pd); | 573 | ret = power_domain_on(&pd); |
564 | if (ret) | 574 | if (ret) |
565 | printf("conn_usb2_phy Power up failed! (error = %d)\n", ret); | 575 | printf("conn_usb2_phy Power up failed! (error = %d)\n", ret); |
566 | } | 576 | } |
567 | 577 | ||
568 | ret = cdns3_uboot_init(&cdns3_device_data); | 578 | ret = cdns3_uboot_init(&cdns3_device_data); |
569 | printf("%d cdns3_uboot_initmode %d\n", index, ret); | 579 | printf("%d cdns3_uboot_initmode %d\n", index, ret); |
570 | } | 580 | } |
571 | } | 581 | } |
572 | return ret; | 582 | return ret; |
573 | } | 583 | } |
574 | 584 | ||
575 | int board_usb_cleanup(int index, enum usb_init_type init) | 585 | int board_usb_cleanup(int index, enum usb_init_type init) |
576 | { | 586 | { |
577 | int ret = 0; | 587 | int ret = 0; |
578 | 588 | ||
579 | if (index == 1) { | 589 | if (index == 1) { |
580 | if (init == USB_INIT_DEVICE) { | 590 | if (init == USB_INIT_DEVICE) { |
581 | struct power_domain pd; | 591 | struct power_domain pd; |
582 | int ret; | 592 | int ret; |
583 | 593 | ||
584 | cdns3_uboot_exit(1); | 594 | cdns3_uboot_exit(1); |
585 | 595 | ||
586 | /* Power off usb */ | 596 | /* Power off usb */ |
587 | if (!power_domain_lookup_name("conn_usb2", &pd)) { | 597 | if (!power_domain_lookup_name("conn_usb2", &pd)) { |
588 | ret = power_domain_off(&pd); | 598 | ret = power_domain_off(&pd); |
589 | if (ret) | 599 | if (ret) |
590 | printf("conn_usb2 Power up failed! (error = %d)\n", ret); | 600 | printf("conn_usb2 Power up failed! (error = %d)\n", ret); |
591 | } | 601 | } |
592 | 602 | ||
593 | if (!power_domain_lookup_name("conn_usb2_phy", &pd)) { | 603 | if (!power_domain_lookup_name("conn_usb2_phy", &pd)) { |
594 | ret = power_domain_off(&pd); | 604 | ret = power_domain_off(&pd); |
595 | if (ret) | 605 | if (ret) |
596 | printf("conn_usb2_phy Power up failed! (error = %d)\n", ret); | 606 | printf("conn_usb2_phy Power up failed! (error = %d)\n", ret); |
597 | } | 607 | } |
598 | } | 608 | } |
599 | } | 609 | } |
600 | return ret; | 610 | return ret; |
601 | } | 611 | } |
602 | #endif | 612 | #endif |
603 | 613 | ||
604 | int board_init(void) | 614 | int board_init(void) |
605 | { | 615 | { |
606 | #ifdef CONFIG_MXC_GPIO | 616 | #ifdef CONFIG_MXC_GPIO |
607 | board_gpio_init(); | 617 | board_gpio_init(); |
608 | #endif | 618 | #endif |
609 | 619 | ||
610 | #ifdef CONFIG_FEC_MXC | 620 | #ifdef CONFIG_FEC_MXC |
611 | setup_fec(CONFIG_FEC_ENET_DEV); | 621 | setup_fec(CONFIG_FEC_ENET_DEV); |
612 | #endif | 622 | #endif |
613 | 623 | ||
614 | #ifdef CONFIG_NAND_MXS | 624 | #ifdef CONFIG_NAND_MXS |
615 | imx8qxp_gpmi_nand_initialize(); | 625 | imx8qxp_gpmi_nand_initialize(); |
616 | #endif | 626 | #endif |
617 | 627 | ||
618 | return 0; | 628 | return 0; |
619 | } | 629 | } |
620 | 630 | ||
621 | void board_quiesce_devices() | 631 | void board_quiesce_devices() |
622 | { | 632 | { |
623 | const char *power_on_devices[] = { | 633 | const char *power_on_devices[] = { |
624 | "dma_lpuart0", | 634 | "dma_lpuart0", |
625 | 635 | ||
626 | /* HIFI DSP boot */ | 636 | /* HIFI DSP boot */ |
627 | "audio_sai0", | 637 | "audio_sai0", |
628 | "audio_ocram", | 638 | "audio_ocram", |
629 | }; | 639 | }; |
630 | 640 | ||
631 | power_off_pd_devices(power_on_devices, ARRAY_SIZE(power_on_devices)); | 641 | power_off_pd_devices(power_on_devices, ARRAY_SIZE(power_on_devices)); |
632 | } | 642 | } |
633 | 643 | ||
634 | void detail_board_ddr_info(void) | 644 | void detail_board_ddr_info(void) |
635 | { | 645 | { |
636 | puts("\nDDR "); | 646 | puts("\nDDR "); |
637 | } | 647 | } |
638 | 648 | ||
639 | /* | 649 | /* |
640 | * Board specific reset that is system reset. | 650 | * Board specific reset that is system reset. |
641 | */ | 651 | */ |
642 | void reset_cpu(ulong addr) | 652 | void reset_cpu(ulong addr) |
643 | { | 653 | { |
644 | puts("SCI reboot request"); | 654 | puts("SCI reboot request"); |
645 | sc_pm_reboot(SC_IPC_CH, SC_PM_RESET_TYPE_COLD); | 655 | sc_pm_reboot(SC_IPC_CH, SC_PM_RESET_TYPE_COLD); |
646 | while (1) | 656 | while (1) |
647 | putc('.'); | 657 | putc('.'); |
648 | } | 658 | } |
649 | 659 | ||
650 | #ifdef CONFIG_OF_BOARD_SETUP | 660 | #ifdef CONFIG_OF_BOARD_SETUP |
651 | int ft_board_setup(void *blob, bd_t *bd) | 661 | int ft_board_setup(void *blob, bd_t *bd) |
652 | { | 662 | { |
653 | return 0; | 663 | return 0; |
654 | } | 664 | } |
655 | #endif | 665 | #endif |
656 | 666 | ||
657 | int board_mmc_get_env_dev(int devno) | 667 | int board_mmc_get_env_dev(int devno) |
658 | { | 668 | { |
659 | return devno; | 669 | return devno; |
660 | } | 670 | } |
661 | 671 | ||
662 | int board_late_init(void) | 672 | int board_late_init(void) |
663 | { | 673 | { |
664 | #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG | 674 | #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG |
665 | env_set("board_name", "ARM2"); | 675 | env_set("board_name", "ARM2"); |
666 | env_set("board_rev", "iMX8QXP"); | 676 | env_set("board_rev", "iMX8QXP"); |
667 | #endif | 677 | #endif |
668 | 678 | ||
669 | env_set("sec_boot", "no"); | 679 | env_set("sec_boot", "no"); |
670 | #ifdef CONFIG_AHAB_BOOT | 680 | #ifdef CONFIG_AHAB_BOOT |
671 | env_set("sec_boot", "yes"); | 681 | env_set("sec_boot", "yes"); |
672 | #endif | 682 | #endif |
673 | 683 | ||
674 | #ifdef CONFIG_ENV_IS_IN_MMC | 684 | #ifdef CONFIG_ENV_IS_IN_MMC |
675 | board_late_mmc_env_init(); | 685 | board_late_mmc_env_init(); |
676 | #endif | 686 | #endif |
677 | 687 | ||
678 | return 0; | 688 | return 0; |
679 | } | 689 | } |
680 | 690 | ||
681 | #ifdef CONFIG_FSL_FASTBOOT | 691 | #ifdef CONFIG_FSL_FASTBOOT |
682 | #ifdef CONFIG_ANDROID_RECOVERY | 692 | #ifdef CONFIG_ANDROID_RECOVERY |
683 | int is_recovery_key_pressing(void) | 693 | int is_recovery_key_pressing(void) |
684 | { | 694 | { |
685 | return 0; /*TODO*/ | 695 | return 0; /*TODO*/ |
686 | } | 696 | } |
687 | #endif /*CONFIG_ANDROID_RECOVERY*/ | 697 | #endif /*CONFIG_ANDROID_RECOVERY*/ |
688 | #endif /*CONFIG_FSL_FASTBOOT*/ | 698 | #endif /*CONFIG_FSL_FASTBOOT*/ |
689 | 699 | ||
690 | #if defined(CONFIG_VIDEO_IMXDPUV1) | 700 | #if defined(CONFIG_VIDEO_IMXDPUV1) |
691 | static void enable_lvds(struct display_info_t const *dev) | 701 | static void enable_lvds(struct display_info_t const *dev) |
692 | { | 702 | { |
693 | display_controller_setup((PS2KHZ(dev->mode.pixclock) * 1000)); | 703 | display_controller_setup((PS2KHZ(dev->mode.pixclock) * 1000)); |
694 | lvds_soc_setup(dev->bus, (PS2KHZ(dev->mode.pixclock) * 1000)); | 704 | lvds_soc_setup(dev->bus, (PS2KHZ(dev->mode.pixclock) * 1000)); |
695 | lvds_configure(dev->bus); | 705 | lvds_configure(dev->bus); |
696 | lvds2hdmi_setup(13); | 706 | lvds2hdmi_setup(13); |
697 | } | 707 | } |
698 | 708 | ||
699 | struct display_info_t const displays[] = {{ | 709 | struct display_info_t const displays[] = {{ |
700 | .bus = 0, /* LVDS0 */ | 710 | .bus = 0, /* LVDS0 */ |
701 | .addr = 0, /* LVDS0 */ | 711 | .addr = 0, /* LVDS0 */ |
702 | .pixfmt = IMXDPUV1_PIX_FMT_BGRA32, | 712 | .pixfmt = IMXDPUV1_PIX_FMT_BGRA32, |
703 | .detect = NULL, | 713 | .detect = NULL, |
704 | .enable = enable_lvds, | 714 | .enable = enable_lvds, |
705 | .mode = { | 715 | .mode = { |
706 | .name = "IT6263", /* 720P60 */ | 716 | .name = "IT6263", /* 720P60 */ |
707 | .refresh = 60, | 717 | .refresh = 60, |
708 | .xres = 1280, | 718 | .xres = 1280, |
709 | .yres = 720, | 719 | .yres = 720, |
710 | .pixclock = 13468, /* 74250000 */ | 720 | .pixclock = 13468, /* 74250000 */ |
711 | .left_margin = 110, | 721 | .left_margin = 110, |
712 | .right_margin = 220, | 722 | .right_margin = 220, |
713 | .upper_margin = 5, | 723 | .upper_margin = 5, |
714 | .lower_margin = 20, | 724 | .lower_margin = 20, |
715 | .hsync_len = 40, | 725 | .hsync_len = 40, |
716 | .vsync_len = 5, | 726 | .vsync_len = 5, |
717 | .sync = FB_SYNC_EXT, | 727 | .sync = FB_SYNC_EXT, |
718 | .vmode = FB_VMODE_NONINTERLACED | 728 | .vmode = FB_VMODE_NONINTERLACED |
719 | } } }; | 729 | } } }; |
720 | size_t display_count = ARRAY_SIZE(displays); | 730 | size_t display_count = ARRAY_SIZE(displays); |
721 | 731 | ||
722 | #endif /* CONFIG_VIDEO_IMXDPUV1 */ | 732 | #endif /* CONFIG_VIDEO_IMXDPUV1 */ |
723 | 733 |
board/freescale/imx8qxp_mek/imx8qxp_mek.c
1 | /* | 1 | /* |
2 | * Copyright 2017-2018 NXP | 2 | * Copyright 2017-2018 NXP |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: GPL-2.0+ | 4 | * SPDX-License-Identifier: GPL-2.0+ |
5 | */ | 5 | */ |
6 | #include <common.h> | 6 | #include <common.h> |
7 | #include <malloc.h> | 7 | #include <malloc.h> |
8 | #include <errno.h> | 8 | #include <errno.h> |
9 | #include <netdev.h> | 9 | #include <netdev.h> |
10 | #include <fsl_ifc.h> | 10 | #include <fsl_ifc.h> |
11 | #include <fdt_support.h> | 11 | #include <fdt_support.h> |
12 | #include <linux/libfdt.h> | 12 | #include <linux/libfdt.h> |
13 | #include <environment.h> | 13 | #include <environment.h> |
14 | #include <fsl_esdhc.h> | 14 | #include <fsl_esdhc.h> |
15 | #include <i2c.h> | 15 | #include <i2c.h> |
16 | #include "pca953x.h" | 16 | #include "pca953x.h" |
17 | 17 | ||
18 | #include <asm/io.h> | 18 | #include <asm/io.h> |
19 | #include <asm/gpio.h> | 19 | #include <asm/gpio.h> |
20 | #include <asm/arch/clock.h> | 20 | #include <asm/arch/clock.h> |
21 | #include <asm/mach-imx/sci/sci.h> | 21 | #include <asm/mach-imx/sci/sci.h> |
22 | #include <asm/arch/imx8-pins.h> | 22 | #include <asm/arch/imx8-pins.h> |
23 | #include <dm.h> | 23 | #include <dm.h> |
24 | #include <imx8_hsio.h> | 24 | #include <imx8_hsio.h> |
25 | #include <usb.h> | 25 | #include <usb.h> |
26 | #include <asm/arch/iomux.h> | 26 | #include <asm/arch/iomux.h> |
27 | #include <asm/arch/sys_proto.h> | 27 | #include <asm/arch/sys_proto.h> |
28 | #include <asm/mach-imx/video.h> | 28 | #include <asm/mach-imx/video.h> |
29 | #include <asm/arch/video_common.h> | 29 | #include <asm/arch/video_common.h> |
30 | #include <power-domain.h> | 30 | #include <power-domain.h> |
31 | #include "../common/tcpc.h" | 31 | #include "../common/tcpc.h" |
32 | #include <cdns3-uboot.h> | 32 | #include <cdns3-uboot.h> |
33 | #include <asm/arch/lpcg.h> | ||
33 | 34 | ||
34 | DECLARE_GLOBAL_DATA_PTR; | 35 | DECLARE_GLOBAL_DATA_PTR; |
35 | 36 | ||
36 | #define ESDHC_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 37 | #define ESDHC_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
37 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 38 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
38 | 39 | ||
39 | #define ESDHC_CLK_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 40 | #define ESDHC_CLK_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
40 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 41 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
41 | 42 | ||
42 | 43 | ||
43 | #define ENET_INPUT_PAD_CTRL ((SC_PAD_CONFIG_OD_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 44 | #define ENET_INPUT_PAD_CTRL ((SC_PAD_CONFIG_OD_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
44 | | (SC_PAD_28FDSOI_DSE_18V_10MA << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 45 | | (SC_PAD_28FDSOI_DSE_18V_10MA << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
45 | 46 | ||
46 | #define ENET_NORMAL_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 47 | #define ENET_NORMAL_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
47 | | (SC_PAD_28FDSOI_DSE_18V_10MA << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 48 | | (SC_PAD_28FDSOI_DSE_18V_10MA << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
48 | 49 | ||
49 | #define FSPI_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 50 | #define FSPI_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
50 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 51 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
51 | 52 | ||
52 | #define GPIO_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 53 | #define GPIO_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
53 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 54 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
54 | 55 | ||
55 | #define I2C_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 56 | #define I2C_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
56 | | (SC_PAD_28FDSOI_DSE_DV_LOW << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 57 | | (SC_PAD_28FDSOI_DSE_DV_LOW << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
57 | 58 | ||
58 | #define UART_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 59 | #define UART_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
59 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 60 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
60 | 61 | ||
61 | static iomux_cfg_t uart0_pads[] = { | 62 | static iomux_cfg_t uart0_pads[] = { |
62 | SC_P_UART0_RX | MUX_PAD_CTRL(UART_PAD_CTRL), | 63 | SC_P_UART0_RX | MUX_PAD_CTRL(UART_PAD_CTRL), |
63 | SC_P_UART0_TX | MUX_PAD_CTRL(UART_PAD_CTRL), | 64 | SC_P_UART0_TX | MUX_PAD_CTRL(UART_PAD_CTRL), |
64 | }; | 65 | }; |
65 | 66 | ||
66 | static void setup_iomux_uart(void) | 67 | static void setup_iomux_uart(void) |
67 | { | 68 | { |
68 | imx8_iomux_setup_multiple_pads(uart0_pads, ARRAY_SIZE(uart0_pads)); | 69 | imx8_iomux_setup_multiple_pads(uart0_pads, ARRAY_SIZE(uart0_pads)); |
69 | } | 70 | } |
70 | 71 | ||
71 | int board_early_init_f(void) | 72 | int board_early_init_f(void) |
72 | { | 73 | { |
73 | sc_ipc_t ipcHndl = 0; | 74 | sc_ipc_t ipcHndl = 0; |
74 | sc_err_t sciErr = 0; | 75 | sc_err_t sciErr = 0; |
75 | 76 | ||
76 | ipcHndl = gd->arch.ipc_channel_handle; | 77 | ipcHndl = gd->arch.ipc_channel_handle; |
77 | 78 | ||
78 | /* Power up UART0 */ | 79 | /* Power up UART0 */ |
79 | sciErr = sc_pm_set_resource_power_mode(ipcHndl, SC_R_UART_0, SC_PM_PW_MODE_ON); | 80 | sciErr = sc_pm_set_resource_power_mode(ipcHndl, SC_R_UART_0, SC_PM_PW_MODE_ON); |
80 | if (sciErr != SC_ERR_NONE) | 81 | if (sciErr != SC_ERR_NONE) |
81 | return 0; | 82 | return 0; |
82 | 83 | ||
83 | /* Set UART0 clock root to 80 MHz */ | 84 | /* Set UART0 clock root to 80 MHz */ |
84 | sc_pm_clock_rate_t rate = 80000000; | 85 | sc_pm_clock_rate_t rate = 80000000; |
85 | sciErr = sc_pm_set_clock_rate(ipcHndl, SC_R_UART_0, 2, &rate); | 86 | sciErr = sc_pm_set_clock_rate(ipcHndl, SC_R_UART_0, 2, &rate); |
86 | if (sciErr != SC_ERR_NONE) | 87 | if (sciErr != SC_ERR_NONE) |
87 | return 0; | 88 | return 0; |
88 | 89 | ||
89 | /* Enable UART0 clock root */ | 90 | /* Enable UART0 clock root */ |
90 | sciErr = sc_pm_clock_enable(ipcHndl, SC_R_UART_0, 2, true, false); | 91 | sciErr = sc_pm_clock_enable(ipcHndl, SC_R_UART_0, 2, true, false); |
91 | if (sciErr != SC_ERR_NONE) | 92 | if (sciErr != SC_ERR_NONE) |
92 | return 0; | 93 | return 0; |
93 | 94 | ||
95 | LPCG_AllClockOn(LPUART_0_LPCG); | ||
96 | |||
94 | setup_iomux_uart(); | 97 | setup_iomux_uart(); |
95 | 98 | ||
96 | return 0; | 99 | return 0; |
97 | } | 100 | } |
98 | 101 | ||
99 | #ifdef CONFIG_FSL_ESDHC | 102 | #ifdef CONFIG_FSL_ESDHC |
100 | 103 | ||
101 | #define USDHC1_CD_GPIO IMX_GPIO_NR(4, 22) | 104 | #define USDHC1_CD_GPIO IMX_GPIO_NR(4, 22) |
102 | 105 | ||
103 | #ifndef CONFIG_SPL_BUILD | 106 | #ifndef CONFIG_SPL_BUILD |
104 | static struct fsl_esdhc_cfg usdhc_cfg[CONFIG_SYS_FSL_USDHC_NUM] = { | 107 | static struct fsl_esdhc_cfg usdhc_cfg[CONFIG_SYS_FSL_USDHC_NUM] = { |
105 | {USDHC1_BASE_ADDR, 0, 8}, | 108 | {USDHC1_BASE_ADDR, 0, 8}, |
106 | {USDHC2_BASE_ADDR, 0, 4}, | 109 | {USDHC2_BASE_ADDR, 0, 4}, |
107 | }; | 110 | }; |
108 | 111 | ||
109 | static iomux_cfg_t emmc0[] = { | 112 | static iomux_cfg_t emmc0[] = { |
110 | SC_P_EMMC0_CLK | MUX_PAD_CTRL(ESDHC_CLK_PAD_CTRL), | 113 | SC_P_EMMC0_CLK | MUX_PAD_CTRL(ESDHC_CLK_PAD_CTRL), |
111 | SC_P_EMMC0_CMD | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 114 | SC_P_EMMC0_CMD | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
112 | SC_P_EMMC0_DATA0 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 115 | SC_P_EMMC0_DATA0 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
113 | SC_P_EMMC0_DATA1 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 116 | SC_P_EMMC0_DATA1 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
114 | SC_P_EMMC0_DATA2 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 117 | SC_P_EMMC0_DATA2 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
115 | SC_P_EMMC0_DATA3 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 118 | SC_P_EMMC0_DATA3 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
116 | SC_P_EMMC0_DATA4 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 119 | SC_P_EMMC0_DATA4 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
117 | SC_P_EMMC0_DATA5 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 120 | SC_P_EMMC0_DATA5 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
118 | SC_P_EMMC0_DATA6 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 121 | SC_P_EMMC0_DATA6 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
119 | SC_P_EMMC0_DATA7 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 122 | SC_P_EMMC0_DATA7 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
120 | SC_P_EMMC0_STROBE | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 123 | SC_P_EMMC0_STROBE | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
121 | }; | 124 | }; |
122 | 125 | ||
123 | static iomux_cfg_t usdhc1_sd[] = { | 126 | static iomux_cfg_t usdhc1_sd[] = { |
124 | SC_P_USDHC1_CLK | MUX_PAD_CTRL(ESDHC_CLK_PAD_CTRL), | 127 | SC_P_USDHC1_CLK | MUX_PAD_CTRL(ESDHC_CLK_PAD_CTRL), |
125 | SC_P_USDHC1_CMD | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 128 | SC_P_USDHC1_CMD | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
126 | SC_P_USDHC1_DATA0 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 129 | SC_P_USDHC1_DATA0 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
127 | SC_P_USDHC1_DATA1 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 130 | SC_P_USDHC1_DATA1 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
128 | SC_P_USDHC1_DATA2 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 131 | SC_P_USDHC1_DATA2 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
129 | SC_P_USDHC1_DATA3 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 132 | SC_P_USDHC1_DATA3 | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
130 | SC_P_USDHC1_WP | MUX_PAD_CTRL(ESDHC_PAD_CTRL), /* Mux for WP */ | 133 | SC_P_USDHC1_WP | MUX_PAD_CTRL(ESDHC_PAD_CTRL), /* Mux for WP */ |
131 | SC_P_USDHC1_CD_B | MUX_MODE_ALT(4) | MUX_PAD_CTRL(ESDHC_PAD_CTRL), /* Mux for CD, GPIO4 IO22 */ | 134 | SC_P_USDHC1_CD_B | MUX_MODE_ALT(4) | MUX_PAD_CTRL(ESDHC_PAD_CTRL), /* Mux for CD, GPIO4 IO22 */ |
132 | SC_P_USDHC1_RESET_B | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 135 | SC_P_USDHC1_RESET_B | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
133 | SC_P_USDHC1_VSELECT | MUX_PAD_CTRL(ESDHC_PAD_CTRL), | 136 | SC_P_USDHC1_VSELECT | MUX_PAD_CTRL(ESDHC_PAD_CTRL), |
134 | }; | 137 | }; |
135 | 138 | ||
136 | int board_mmc_init(bd_t *bis) | 139 | int board_mmc_init(bd_t *bis) |
137 | { | 140 | { |
138 | int i, ret; | 141 | int i, ret; |
139 | struct power_domain pd; | 142 | struct power_domain pd; |
140 | 143 | ||
141 | /* | 144 | /* |
142 | * According to the board_mmc_init() the following map is done: | 145 | * According to the board_mmc_init() the following map is done: |
143 | * (U-boot device node) (Physical Port) | 146 | * (U-boot device node) (Physical Port) |
144 | * mmc0 USDHC1 | 147 | * mmc0 USDHC1 |
145 | * mmc1 USDHC2 | 148 | * mmc1 USDHC2 |
146 | */ | 149 | */ |
147 | for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) { | 150 | for (i = 0; i < CONFIG_SYS_FSL_USDHC_NUM; i++) { |
148 | switch (i) { | 151 | switch (i) { |
149 | case 0: | 152 | case 0: |
150 | if (!power_domain_lookup_name("conn_sdhc0", &pd)) | 153 | if (!power_domain_lookup_name("conn_sdhc0", &pd)) |
151 | power_domain_on(&pd); | 154 | power_domain_on(&pd); |
152 | imx8_iomux_setup_multiple_pads(emmc0, ARRAY_SIZE(emmc0)); | 155 | imx8_iomux_setup_multiple_pads(emmc0, ARRAY_SIZE(emmc0)); |
153 | init_clk_usdhc(0); | 156 | init_clk_usdhc(0); |
154 | usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); | 157 | usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); |
155 | break; | 158 | break; |
156 | case 1: | 159 | case 1: |
157 | if (!power_domain_lookup_name("conn_sdhc1", &pd)) | 160 | if (!power_domain_lookup_name("conn_sdhc1", &pd)) |
158 | power_domain_on(&pd); | 161 | power_domain_on(&pd); |
159 | imx8_iomux_setup_multiple_pads(usdhc1_sd, ARRAY_SIZE(usdhc1_sd)); | 162 | imx8_iomux_setup_multiple_pads(usdhc1_sd, ARRAY_SIZE(usdhc1_sd)); |
160 | init_clk_usdhc(1); | 163 | init_clk_usdhc(1); |
161 | usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); | 164 | usdhc_cfg[i].sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); |
162 | gpio_request(USDHC1_CD_GPIO, "sd1_cd"); | 165 | gpio_request(USDHC1_CD_GPIO, "sd1_cd"); |
163 | gpio_direction_input(USDHC1_CD_GPIO); | 166 | gpio_direction_input(USDHC1_CD_GPIO); |
164 | break; | 167 | break; |
165 | default: | 168 | default: |
166 | printf("Warning: you configured more USDHC controllers" | 169 | printf("Warning: you configured more USDHC controllers" |
167 | "(%d) than supported by the board\n", i + 1); | 170 | "(%d) than supported by the board\n", i + 1); |
168 | return 0; | 171 | return 0; |
169 | } | 172 | } |
170 | ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]); | 173 | ret = fsl_esdhc_initialize(bis, &usdhc_cfg[i]); |
171 | if (ret) { | 174 | if (ret) { |
172 | printf("Warning: failed to initialize mmc dev %d\n", i); | 175 | printf("Warning: failed to initialize mmc dev %d\n", i); |
173 | return ret; | 176 | return ret; |
174 | } | 177 | } |
175 | } | 178 | } |
176 | 179 | ||
177 | return 0; | 180 | return 0; |
178 | } | 181 | } |
179 | 182 | ||
180 | int board_mmc_getcd(struct mmc *mmc) | 183 | int board_mmc_getcd(struct mmc *mmc) |
181 | { | 184 | { |
182 | struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; | 185 | struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; |
183 | int ret = 0; | 186 | int ret = 0; |
184 | 187 | ||
185 | switch (cfg->esdhc_base) { | 188 | switch (cfg->esdhc_base) { |
186 | case USDHC1_BASE_ADDR: | 189 | case USDHC1_BASE_ADDR: |
187 | ret = 1; /* eMMC */ | 190 | ret = 1; /* eMMC */ |
188 | break; | 191 | break; |
189 | case USDHC2_BASE_ADDR: | 192 | case USDHC2_BASE_ADDR: |
190 | ret = !gpio_get_value(USDHC1_CD_GPIO); | 193 | ret = !gpio_get_value(USDHC1_CD_GPIO); |
191 | break; | 194 | break; |
192 | } | 195 | } |
193 | 196 | ||
194 | return ret; | 197 | return ret; |
195 | } | 198 | } |
196 | 199 | ||
197 | #endif /* CONFIG_SPL_BUILD */ | 200 | #endif /* CONFIG_SPL_BUILD */ |
198 | #endif /* CONFIG_FSL_ESDHC */ | 201 | #endif /* CONFIG_FSL_ESDHC */ |
199 | 202 | ||
200 | 203 | ||
201 | #ifdef CONFIG_FEC_MXC | 204 | #ifdef CONFIG_FEC_MXC |
202 | #include <miiphy.h> | 205 | #include <miiphy.h> |
203 | 206 | ||
204 | static iomux_cfg_t pad_enet1[] = { | 207 | static iomux_cfg_t pad_enet1[] = { |
205 | SC_P_SPDIF0_TX | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 208 | SC_P_SPDIF0_TX | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
206 | SC_P_SPDIF0_RX | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 209 | SC_P_SPDIF0_RX | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
207 | SC_P_ESAI0_TX3_RX2 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 210 | SC_P_ESAI0_TX3_RX2 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
208 | SC_P_ESAI0_TX2_RX3 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 211 | SC_P_ESAI0_TX2_RX3 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
209 | SC_P_ESAI0_TX1 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 212 | SC_P_ESAI0_TX1 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
210 | SC_P_ESAI0_TX0 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 213 | SC_P_ESAI0_TX0 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
211 | SC_P_ESAI0_SCKR | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 214 | SC_P_ESAI0_SCKR | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
212 | SC_P_ESAI0_TX4_RX1 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 215 | SC_P_ESAI0_TX4_RX1 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
213 | SC_P_ESAI0_TX5_RX0 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 216 | SC_P_ESAI0_TX5_RX0 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
214 | SC_P_ESAI0_FST | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 217 | SC_P_ESAI0_FST | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
215 | SC_P_ESAI0_SCKT | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 218 | SC_P_ESAI0_SCKT | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
216 | SC_P_ESAI0_FSR | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 219 | SC_P_ESAI0_FSR | MUX_MODE_ALT(3) | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
217 | 220 | ||
218 | /* Shared MDIO */ | 221 | /* Shared MDIO */ |
219 | SC_P_ENET0_MDC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 222 | SC_P_ENET0_MDC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
220 | SC_P_ENET0_MDIO | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 223 | SC_P_ENET0_MDIO | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
221 | }; | 224 | }; |
222 | 225 | ||
223 | static iomux_cfg_t pad_enet0[] = { | 226 | static iomux_cfg_t pad_enet0[] = { |
224 | SC_P_ENET0_RGMII_RX_CTL | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 227 | SC_P_ENET0_RGMII_RX_CTL | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
225 | SC_P_ENET0_RGMII_RXD0 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 228 | SC_P_ENET0_RGMII_RXD0 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
226 | SC_P_ENET0_RGMII_RXD1 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 229 | SC_P_ENET0_RGMII_RXD1 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
227 | SC_P_ENET0_RGMII_RXD2 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 230 | SC_P_ENET0_RGMII_RXD2 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
228 | SC_P_ENET0_RGMII_RXD3 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 231 | SC_P_ENET0_RGMII_RXD3 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
229 | SC_P_ENET0_RGMII_RXC | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 232 | SC_P_ENET0_RGMII_RXC | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
230 | SC_P_ENET0_RGMII_TX_CTL | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 233 | SC_P_ENET0_RGMII_TX_CTL | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
231 | SC_P_ENET0_RGMII_TXD0 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 234 | SC_P_ENET0_RGMII_TXD0 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
232 | SC_P_ENET0_RGMII_TXD1 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 235 | SC_P_ENET0_RGMII_TXD1 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
233 | SC_P_ENET0_RGMII_TXD2 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 236 | SC_P_ENET0_RGMII_TXD2 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
234 | SC_P_ENET0_RGMII_TXD3 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 237 | SC_P_ENET0_RGMII_TXD3 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
235 | SC_P_ENET0_RGMII_TXC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 238 | SC_P_ENET0_RGMII_TXC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
236 | 239 | ||
237 | /* Shared MDIO */ | 240 | /* Shared MDIO */ |
238 | SC_P_ENET0_MDC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 241 | SC_P_ENET0_MDC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
239 | SC_P_ENET0_MDIO | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 242 | SC_P_ENET0_MDIO | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
240 | }; | 243 | }; |
241 | 244 | ||
242 | static void setup_iomux_fec(void) | 245 | static void setup_iomux_fec(void) |
243 | { | 246 | { |
244 | if (0 == CONFIG_FEC_ENET_DEV) | 247 | if (0 == CONFIG_FEC_ENET_DEV) |
245 | imx8_iomux_setup_multiple_pads(pad_enet0, ARRAY_SIZE(pad_enet0)); | 248 | imx8_iomux_setup_multiple_pads(pad_enet0, ARRAY_SIZE(pad_enet0)); |
246 | else | 249 | else |
247 | imx8_iomux_setup_multiple_pads(pad_enet1, ARRAY_SIZE(pad_enet1)); | 250 | imx8_iomux_setup_multiple_pads(pad_enet1, ARRAY_SIZE(pad_enet1)); |
248 | } | 251 | } |
249 | 252 | ||
250 | static void enet_device_phy_reset(void) | 253 | static void enet_device_phy_reset(void) |
251 | { | 254 | { |
252 | struct gpio_desc desc; | 255 | struct gpio_desc desc; |
253 | int ret; | 256 | int ret; |
254 | 257 | ||
255 | /* The BB_PER_RST_B will reset the ENET1 PHY */ | 258 | /* The BB_PER_RST_B will reset the ENET1 PHY */ |
256 | if (0 == CONFIG_FEC_ENET_DEV) { | 259 | if (0 == CONFIG_FEC_ENET_DEV) { |
257 | ret = dm_gpio_lookup_name("gpio@1a_4", &desc); | 260 | ret = dm_gpio_lookup_name("gpio@1a_4", &desc); |
258 | if (ret) | 261 | if (ret) |
259 | return; | 262 | return; |
260 | 263 | ||
261 | ret = dm_gpio_request(&desc, "enet0_reset"); | 264 | ret = dm_gpio_request(&desc, "enet0_reset"); |
262 | if (ret) | 265 | if (ret) |
263 | return; | 266 | return; |
264 | 267 | ||
265 | dm_gpio_set_dir_flags(&desc, GPIOD_IS_OUT); | 268 | dm_gpio_set_dir_flags(&desc, GPIOD_IS_OUT); |
266 | dm_gpio_set_value(&desc, 0); | 269 | dm_gpio_set_value(&desc, 0); |
267 | udelay(50); | 270 | udelay(50); |
268 | dm_gpio_set_value(&desc, 1); | 271 | dm_gpio_set_value(&desc, 1); |
269 | } | 272 | } |
270 | 273 | ||
271 | /* The board has a long delay for this reset to become stable */ | 274 | /* The board has a long delay for this reset to become stable */ |
272 | mdelay(200); | 275 | mdelay(200); |
273 | } | 276 | } |
274 | 277 | ||
275 | int board_eth_init(bd_t *bis) | 278 | int board_eth_init(bd_t *bis) |
276 | { | 279 | { |
277 | int ret; | 280 | int ret; |
278 | struct power_domain pd; | 281 | struct power_domain pd; |
279 | 282 | ||
280 | printf("[%s] %d\n", __func__, __LINE__); | 283 | printf("[%s] %d\n", __func__, __LINE__); |
281 | 284 | ||
282 | if (CONFIG_FEC_ENET_DEV) { | 285 | if (CONFIG_FEC_ENET_DEV) { |
283 | if (!power_domain_lookup_name("conn_enet1", &pd)) | 286 | if (!power_domain_lookup_name("conn_enet1", &pd)) |
284 | power_domain_on(&pd); | 287 | power_domain_on(&pd); |
285 | } else { | 288 | } else { |
286 | if (!power_domain_lookup_name("conn_enet0", &pd)) | 289 | if (!power_domain_lookup_name("conn_enet0", &pd)) |
287 | power_domain_on(&pd); | 290 | power_domain_on(&pd); |
288 | } | 291 | } |
289 | 292 | ||
290 | setup_iomux_fec(); | 293 | setup_iomux_fec(); |
291 | 294 | ||
292 | ret = fecmxc_initialize_multi(bis, CONFIG_FEC_ENET_DEV, | 295 | ret = fecmxc_initialize_multi(bis, CONFIG_FEC_ENET_DEV, |
293 | CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE); | 296 | CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE); |
294 | if (ret) | 297 | if (ret) |
295 | printf("FEC1 MXC: %s:failed\n", __func__); | 298 | printf("FEC1 MXC: %s:failed\n", __func__); |
296 | 299 | ||
297 | return ret; | 300 | return ret; |
298 | } | 301 | } |
299 | 302 | ||
300 | int board_phy_config(struct phy_device *phydev) | 303 | int board_phy_config(struct phy_device *phydev) |
301 | { | 304 | { |
302 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f); | 305 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f); |
303 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8); | 306 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8); |
304 | 307 | ||
305 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x00); | 308 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x00); |
306 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x82ee); | 309 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x82ee); |
307 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05); | 310 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05); |
308 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100); | 311 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100); |
309 | 312 | ||
310 | if (phydev->drv->config) | 313 | if (phydev->drv->config) |
311 | phydev->drv->config(phydev); | 314 | phydev->drv->config(phydev); |
312 | 315 | ||
313 | return 0; | 316 | return 0; |
314 | } | 317 | } |
315 | 318 | ||
316 | static int setup_fec(int ind) | 319 | static int setup_fec(int ind) |
317 | { | 320 | { |
318 | /* Reset ENET PHY */ | 321 | /* Reset ENET PHY */ |
319 | enet_device_phy_reset(); | 322 | enet_device_phy_reset(); |
320 | 323 | ||
321 | return 0; | 324 | return 0; |
322 | } | 325 | } |
323 | #endif | 326 | #endif |
324 | 327 | ||
325 | #ifdef CONFIG_MXC_GPIO | 328 | #ifdef CONFIG_MXC_GPIO |
326 | #define IOEXP_RESET IMX_GPIO_NR(1, 1) | 329 | #define IOEXP_RESET IMX_GPIO_NR(1, 1) |
327 | 330 | ||
328 | static iomux_cfg_t board_gpios[] = { | 331 | static iomux_cfg_t board_gpios[] = { |
329 | SC_P_SPI2_SDO | MUX_MODE_ALT(4) | MUX_PAD_CTRL(GPIO_PAD_CTRL), | 332 | SC_P_SPI2_SDO | MUX_MODE_ALT(4) | MUX_PAD_CTRL(GPIO_PAD_CTRL), |
330 | SC_P_ENET0_REFCLK_125M_25M | MUX_MODE_ALT(4) | MUX_PAD_CTRL(GPIO_PAD_CTRL), | 333 | SC_P_ENET0_REFCLK_125M_25M | MUX_MODE_ALT(4) | MUX_PAD_CTRL(GPIO_PAD_CTRL), |
331 | }; | 334 | }; |
332 | 335 | ||
333 | static void board_gpio_init(void) | 336 | static void board_gpio_init(void) |
334 | { | 337 | { |
335 | int ret; | 338 | int ret; |
336 | struct gpio_desc desc; | 339 | struct gpio_desc desc; |
337 | 340 | ||
338 | ret = dm_gpio_lookup_name("gpio@1a_3", &desc); | 341 | ret = dm_gpio_lookup_name("gpio@1a_3", &desc); |
339 | if (ret) | 342 | if (ret) |
340 | return; | 343 | return; |
341 | 344 | ||
342 | ret = dm_gpio_request(&desc, "bb_per_rst_b"); | 345 | ret = dm_gpio_request(&desc, "bb_per_rst_b"); |
343 | if (ret) | 346 | if (ret) |
344 | return; | 347 | return; |
345 | 348 | ||
346 | dm_gpio_set_dir_flags(&desc, GPIOD_IS_OUT); | 349 | dm_gpio_set_dir_flags(&desc, GPIOD_IS_OUT); |
347 | dm_gpio_set_value(&desc, 0); | 350 | dm_gpio_set_value(&desc, 0); |
348 | udelay(50); | 351 | udelay(50); |
349 | dm_gpio_set_value(&desc, 1); | 352 | dm_gpio_set_value(&desc, 1); |
350 | 353 | ||
351 | imx8_iomux_setup_multiple_pads(board_gpios, ARRAY_SIZE(board_gpios)); | 354 | imx8_iomux_setup_multiple_pads(board_gpios, ARRAY_SIZE(board_gpios)); |
352 | 355 | ||
353 | /* enable i2c port expander assert reset line */ | 356 | /* enable i2c port expander assert reset line */ |
354 | gpio_request(IOEXP_RESET, "ioexp_rst"); | 357 | gpio_request(IOEXP_RESET, "ioexp_rst"); |
355 | gpio_direction_output(IOEXP_RESET, 1); | 358 | gpio_direction_output(IOEXP_RESET, 1); |
356 | } | 359 | } |
357 | #endif | 360 | #endif |
358 | 361 | ||
359 | int checkboard(void) | 362 | int checkboard(void) |
360 | { | 363 | { |
361 | puts("Board: iMX8QXP MEK\n"); | 364 | puts("Board: iMX8QXP MEK\n"); |
362 | 365 | ||
363 | print_bootinfo(); | 366 | print_bootinfo(); |
364 | 367 | ||
365 | /* Note: After reloc, ipcHndl will no longer be valid. If handle | 368 | /* Note: After reloc, ipcHndl will no longer be valid. If handle |
366 | * returned by sc_ipc_open matches SC_IPC_CH, use this | 369 | * returned by sc_ipc_open matches SC_IPC_CH, use this |
367 | * macro (valid after reloc) for subsequent SCI calls. | 370 | * macro (valid after reloc) for subsequent SCI calls. |
368 | */ | 371 | */ |
369 | if (gd->arch.ipc_channel_handle != SC_IPC_CH) | 372 | if (gd->arch.ipc_channel_handle != SC_IPC_CH) |
370 | printf("\nSCI error! Invalid handle\n"); | 373 | printf("\nSCI error! Invalid handle\n"); |
371 | 374 | ||
372 | return 0; | 375 | return 0; |
373 | } | 376 | } |
374 | 377 | ||
375 | #ifdef CONFIG_FSL_HSIO | 378 | #ifdef CONFIG_FSL_HSIO |
376 | 379 | ||
377 | #define PCIE_PAD_CTRL ((SC_PAD_CONFIG_OD_IN << PADRING_CONFIG_SHIFT)) | 380 | #define PCIE_PAD_CTRL ((SC_PAD_CONFIG_OD_IN << PADRING_CONFIG_SHIFT)) |
378 | static iomux_cfg_t board_pcie_pins[] = { | 381 | static iomux_cfg_t board_pcie_pins[] = { |
379 | SC_P_PCIE_CTRL0_CLKREQ_B | MUX_MODE_ALT(0) | MUX_PAD_CTRL(PCIE_PAD_CTRL), | 382 | SC_P_PCIE_CTRL0_CLKREQ_B | MUX_MODE_ALT(0) | MUX_PAD_CTRL(PCIE_PAD_CTRL), |
380 | SC_P_PCIE_CTRL0_WAKE_B | MUX_MODE_ALT(0) | MUX_PAD_CTRL(PCIE_PAD_CTRL), | 383 | SC_P_PCIE_CTRL0_WAKE_B | MUX_MODE_ALT(0) | MUX_PAD_CTRL(PCIE_PAD_CTRL), |
381 | SC_P_PCIE_CTRL0_PERST_B | MUX_MODE_ALT(0) | MUX_PAD_CTRL(PCIE_PAD_CTRL), | 384 | SC_P_PCIE_CTRL0_PERST_B | MUX_MODE_ALT(0) | MUX_PAD_CTRL(PCIE_PAD_CTRL), |
382 | }; | 385 | }; |
383 | 386 | ||
384 | static void imx8qxp_hsio_initialize(void) | 387 | static void imx8qxp_hsio_initialize(void) |
385 | { | 388 | { |
386 | struct power_domain pd; | 389 | struct power_domain pd; |
387 | int ret; | 390 | int ret; |
388 | 391 | ||
389 | if (!power_domain_lookup_name("hsio_pcie1", &pd)) { | 392 | if (!power_domain_lookup_name("hsio_pcie1", &pd)) { |
390 | ret = power_domain_on(&pd); | 393 | ret = power_domain_on(&pd); |
391 | if (ret) | 394 | if (ret) |
392 | printf("hsio_pcie1 Power up failed! (error = %d)\n", ret); | 395 | printf("hsio_pcie1 Power up failed! (error = %d)\n", ret); |
393 | } | 396 | } |
394 | 397 | ||
395 | if (!power_domain_lookup_name("hsio_gpio", &pd)) { | 398 | if (!power_domain_lookup_name("hsio_gpio", &pd)) { |
396 | ret = power_domain_on(&pd); | 399 | ret = power_domain_on(&pd); |
397 | if (ret) | 400 | if (ret) |
398 | printf("hsio_gpio Power up failed! (error = %d)\n", ret); | 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 | imx8_iomux_setup_multiple_pads(board_pcie_pins, ARRAY_SIZE(board_pcie_pins)); | 411 | imx8_iomux_setup_multiple_pads(board_pcie_pins, ARRAY_SIZE(board_pcie_pins)); |
402 | } | 412 | } |
403 | 413 | ||
404 | void pci_init_board(void) | 414 | void pci_init_board(void) |
405 | { | 415 | { |
406 | imx8qxp_hsio_initialize(); | 416 | imx8qxp_hsio_initialize(); |
407 | 417 | ||
408 | /* test the 1 lane mode of the PCIe A controller */ | 418 | /* test the 1 lane mode of the PCIe A controller */ |
409 | mx8qxp_pcie_init(); | 419 | mx8qxp_pcie_init(); |
410 | } | 420 | } |
411 | 421 | ||
412 | #endif | 422 | #endif |
413 | 423 | ||
414 | #ifdef CONFIG_USB | 424 | #ifdef CONFIG_USB |
415 | 425 | ||
416 | #ifdef CONFIG_USB_TCPC | 426 | #ifdef CONFIG_USB_TCPC |
417 | #define USB_TYPEC_SEL IMX_GPIO_NR(5, 9) | 427 | #define USB_TYPEC_SEL IMX_GPIO_NR(5, 9) |
418 | static iomux_cfg_t ss_mux_gpio[] = { | 428 | static iomux_cfg_t ss_mux_gpio[] = { |
419 | SC_P_ENET0_REFCLK_125M_25M | MUX_MODE_ALT(4) | MUX_PAD_CTRL(GPIO_PAD_CTRL), | 429 | SC_P_ENET0_REFCLK_125M_25M | MUX_MODE_ALT(4) | MUX_PAD_CTRL(GPIO_PAD_CTRL), |
420 | }; | 430 | }; |
421 | 431 | ||
422 | struct tcpc_port port; | 432 | struct tcpc_port port; |
423 | struct tcpc_port_config port_config = { | 433 | struct tcpc_port_config port_config = { |
424 | .i2c_bus = 1, | 434 | .i2c_bus = 1, |
425 | .addr = 0x50, | 435 | .addr = 0x50, |
426 | .port_type = TYPEC_PORT_DFP, | 436 | .port_type = TYPEC_PORT_DFP, |
427 | }; | 437 | }; |
428 | 438 | ||
429 | void ss_mux_select(enum typec_cc_polarity pol) | 439 | void ss_mux_select(enum typec_cc_polarity pol) |
430 | { | 440 | { |
431 | if (pol == TYPEC_POLARITY_CC1) | 441 | if (pol == TYPEC_POLARITY_CC1) |
432 | gpio_direction_output(USB_TYPEC_SEL, 0); | 442 | gpio_direction_output(USB_TYPEC_SEL, 0); |
433 | else | 443 | else |
434 | gpio_direction_output(USB_TYPEC_SEL, 1); | 444 | gpio_direction_output(USB_TYPEC_SEL, 1); |
435 | } | 445 | } |
436 | 446 | ||
437 | static void setup_typec(void) | 447 | static void setup_typec(void) |
438 | { | 448 | { |
439 | int ret; | 449 | int ret; |
440 | struct gpio_desc typec_en_desc; | 450 | struct gpio_desc typec_en_desc; |
441 | 451 | ||
442 | imx8_iomux_setup_multiple_pads(ss_mux_gpio, ARRAY_SIZE(ss_mux_gpio)); | 452 | imx8_iomux_setup_multiple_pads(ss_mux_gpio, ARRAY_SIZE(ss_mux_gpio)); |
443 | gpio_request(USB_TYPEC_SEL, "typec_sel"); | 453 | gpio_request(USB_TYPEC_SEL, "typec_sel"); |
444 | 454 | ||
445 | ret = dm_gpio_lookup_name("gpio@1a_7", &typec_en_desc); | 455 | ret = dm_gpio_lookup_name("gpio@1a_7", &typec_en_desc); |
446 | if (ret) { | 456 | if (ret) { |
447 | printf("%s lookup gpio@1a_7 failed ret = %d\n", __func__, ret); | 457 | printf("%s lookup gpio@1a_7 failed ret = %d\n", __func__, ret); |
448 | return; | 458 | return; |
449 | } | 459 | } |
450 | 460 | ||
451 | ret = dm_gpio_request(&typec_en_desc, "typec_en"); | 461 | ret = dm_gpio_request(&typec_en_desc, "typec_en"); |
452 | if (ret) { | 462 | if (ret) { |
453 | printf("%s request typec_en failed ret = %d\n", __func__, ret); | 463 | printf("%s request typec_en failed ret = %d\n", __func__, ret); |
454 | return; | 464 | return; |
455 | } | 465 | } |
456 | 466 | ||
457 | /* Enable SS MUX */ | 467 | /* Enable SS MUX */ |
458 | dm_gpio_set_dir_flags(&typec_en_desc, GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); | 468 | dm_gpio_set_dir_flags(&typec_en_desc, GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); |
459 | 469 | ||
460 | tcpc_init(&port, port_config, &ss_mux_select); | 470 | tcpc_init(&port, port_config, &ss_mux_select); |
461 | } | 471 | } |
462 | #endif | 472 | #endif |
463 | 473 | ||
464 | #ifdef CONFIG_USB_CDNS3_GADGET | 474 | #ifdef CONFIG_USB_CDNS3_GADGET |
465 | static struct cdns3_device cdns3_device_data = { | 475 | static struct cdns3_device cdns3_device_data = { |
466 | .none_core_base = 0x5B110000, | 476 | .none_core_base = 0x5B110000, |
467 | .xhci_base = 0x5B130000, | 477 | .xhci_base = 0x5B130000, |
468 | .dev_base = 0x5B140000, | 478 | .dev_base = 0x5B140000, |
469 | .phy_base = 0x5B160000, | 479 | .phy_base = 0x5B160000, |
470 | .otg_base = 0x5B120000, | 480 | .otg_base = 0x5B120000, |
471 | .dr_mode = USB_DR_MODE_PERIPHERAL, | 481 | .dr_mode = USB_DR_MODE_PERIPHERAL, |
472 | .index = 1, | 482 | .index = 1, |
473 | }; | 483 | }; |
474 | 484 | ||
475 | int usb_gadget_handle_interrupts(void) | 485 | int usb_gadget_handle_interrupts(void) |
476 | { | 486 | { |
477 | cdns3_uboot_handle_interrupt(1); | 487 | cdns3_uboot_handle_interrupt(1); |
478 | return 0; | 488 | return 0; |
479 | } | 489 | } |
480 | #endif | 490 | #endif |
481 | 491 | ||
482 | int board_usb_init(int index, enum usb_init_type init) | 492 | int board_usb_init(int index, enum usb_init_type init) |
483 | { | 493 | { |
484 | int ret = 0; | 494 | int ret = 0; |
485 | 495 | ||
486 | if (index == 1) { | 496 | if (index == 1) { |
487 | if (init == USB_INIT_HOST) { | 497 | if (init == USB_INIT_HOST) { |
488 | #ifdef CONFIG_USB_TCPC | 498 | #ifdef CONFIG_USB_TCPC |
489 | ret = tcpc_setup_dfp_mode(&port); | 499 | ret = tcpc_setup_dfp_mode(&port); |
490 | #endif | 500 | #endif |
491 | #ifdef CONFIG_USB_CDNS3_GADGET | 501 | #ifdef CONFIG_USB_CDNS3_GADGET |
492 | } else { | 502 | } else { |
493 | struct power_domain pd; | 503 | struct power_domain pd; |
494 | int ret; | 504 | int ret; |
495 | 505 | ||
496 | /* Power on usb */ | 506 | /* Power on usb */ |
497 | if (!power_domain_lookup_name("conn_usb2", &pd)) { | 507 | if (!power_domain_lookup_name("conn_usb2", &pd)) { |
498 | ret = power_domain_on(&pd); | 508 | ret = power_domain_on(&pd); |
499 | if (ret) | 509 | if (ret) |
500 | printf("conn_usb2 Power up failed! (error = %d)\n", ret); | 510 | printf("conn_usb2 Power up failed! (error = %d)\n", ret); |
501 | } | 511 | } |
502 | 512 | ||
503 | if (!power_domain_lookup_name("conn_usb2_phy", &pd)) { | 513 | if (!power_domain_lookup_name("conn_usb2_phy", &pd)) { |
504 | ret = power_domain_on(&pd); | 514 | ret = power_domain_on(&pd); |
505 | if (ret) | 515 | if (ret) |
506 | printf("conn_usb2_phy Power up failed! (error = %d)\n", ret); | 516 | printf("conn_usb2_phy Power up failed! (error = %d)\n", ret); |
507 | } | 517 | } |
508 | #ifdef CONFIG_USB_TCPC | 518 | #ifdef CONFIG_USB_TCPC |
509 | ret = tcpc_setup_ufp_mode(&port); | 519 | ret = tcpc_setup_ufp_mode(&port); |
510 | printf("%d setufp mode %d\n", index, ret); | 520 | printf("%d setufp mode %d\n", index, ret); |
511 | #endif | 521 | #endif |
512 | 522 | ||
513 | ret = cdns3_uboot_init(&cdns3_device_data); | 523 | ret = cdns3_uboot_init(&cdns3_device_data); |
514 | printf("%d cdns3_uboot_initmode %d\n", index, ret); | 524 | printf("%d cdns3_uboot_initmode %d\n", index, ret); |
515 | #endif | 525 | #endif |
516 | } | 526 | } |
517 | } | 527 | } |
518 | 528 | ||
519 | return ret; | 529 | return ret; |
520 | 530 | ||
521 | } | 531 | } |
522 | 532 | ||
523 | int board_usb_cleanup(int index, enum usb_init_type init) | 533 | int board_usb_cleanup(int index, enum usb_init_type init) |
524 | { | 534 | { |
525 | int ret = 0; | 535 | int ret = 0; |
526 | 536 | ||
527 | if (index == 1) { | 537 | if (index == 1) { |
528 | if (init == USB_INIT_HOST) { | 538 | if (init == USB_INIT_HOST) { |
529 | #ifdef CONFIG_USB_TCPC | 539 | #ifdef CONFIG_USB_TCPC |
530 | ret = tcpc_disable_src_vbus(&port); | 540 | ret = tcpc_disable_src_vbus(&port); |
531 | #endif | 541 | #endif |
532 | #ifdef CONFIG_USB_CDNS3_GADGET | 542 | #ifdef CONFIG_USB_CDNS3_GADGET |
533 | } else { | 543 | } else { |
534 | struct power_domain pd; | 544 | struct power_domain pd; |
535 | int ret; | 545 | int ret; |
536 | 546 | ||
537 | cdns3_uboot_exit(1); | 547 | cdns3_uboot_exit(1); |
538 | 548 | ||
539 | /* Power off usb */ | 549 | /* Power off usb */ |
540 | if (!power_domain_lookup_name("conn_usb2", &pd)) { | 550 | if (!power_domain_lookup_name("conn_usb2", &pd)) { |
541 | ret = power_domain_off(&pd); | 551 | ret = power_domain_off(&pd); |
542 | if (ret) | 552 | if (ret) |
543 | printf("conn_usb2 Power up failed! (error = %d)\n", ret); | 553 | printf("conn_usb2 Power up failed! (error = %d)\n", ret); |
544 | } | 554 | } |
545 | 555 | ||
546 | if (!power_domain_lookup_name("conn_usb2_phy", &pd)) { | 556 | if (!power_domain_lookup_name("conn_usb2_phy", &pd)) { |
547 | ret = power_domain_off(&pd); | 557 | ret = power_domain_off(&pd); |
548 | if (ret) | 558 | if (ret) |
549 | printf("conn_usb2_phy Power up failed! (error = %d)\n", ret); | 559 | printf("conn_usb2_phy Power up failed! (error = %d)\n", ret); |
550 | } | 560 | } |
551 | #endif | 561 | #endif |
552 | } | 562 | } |
553 | } | 563 | } |
554 | 564 | ||
555 | return ret; | 565 | return ret; |
556 | } | 566 | } |
557 | #endif | 567 | #endif |
558 | 568 | ||
559 | int board_init(void) | 569 | int board_init(void) |
560 | { | 570 | { |
561 | #ifdef CONFIG_MXC_GPIO | 571 | #ifdef CONFIG_MXC_GPIO |
562 | board_gpio_init(); | 572 | board_gpio_init(); |
563 | #endif | 573 | #endif |
564 | 574 | ||
565 | #ifdef CONFIG_FEC_MXC | 575 | #ifdef CONFIG_FEC_MXC |
566 | setup_fec(CONFIG_FEC_ENET_DEV); | 576 | setup_fec(CONFIG_FEC_ENET_DEV); |
567 | #endif | 577 | #endif |
568 | 578 | ||
569 | #if defined(CONFIG_USB) && defined(CONFIG_USB_TCPC) | 579 | #if defined(CONFIG_USB) && defined(CONFIG_USB_TCPC) |
570 | setup_typec(); | 580 | setup_typec(); |
571 | #endif | 581 | #endif |
572 | 582 | ||
573 | return 0; | 583 | return 0; |
574 | } | 584 | } |
575 | 585 | ||
576 | void board_quiesce_devices() | 586 | void board_quiesce_devices() |
577 | { | 587 | { |
578 | const char *power_on_devices[] = { | 588 | const char *power_on_devices[] = { |
579 | "dma_lpuart0", | 589 | "dma_lpuart0", |
580 | 590 | ||
581 | /* HIFI DSP boot */ | 591 | /* HIFI DSP boot */ |
582 | "audio_sai0", | 592 | "audio_sai0", |
583 | "audio_ocram", | 593 | "audio_ocram", |
584 | }; | 594 | }; |
585 | 595 | ||
586 | power_off_pd_devices(power_on_devices, ARRAY_SIZE(power_on_devices)); | 596 | power_off_pd_devices(power_on_devices, ARRAY_SIZE(power_on_devices)); |
587 | } | 597 | } |
588 | 598 | ||
589 | void detail_board_ddr_info(void) | 599 | void detail_board_ddr_info(void) |
590 | { | 600 | { |
591 | puts("\nDDR "); | 601 | puts("\nDDR "); |
592 | } | 602 | } |
593 | 603 | ||
594 | /* | 604 | /* |
595 | * Board specific reset that is system reset. | 605 | * Board specific reset that is system reset. |
596 | */ | 606 | */ |
597 | void reset_cpu(ulong addr) | 607 | void reset_cpu(ulong addr) |
598 | { | 608 | { |
599 | puts("SCI reboot request"); | 609 | puts("SCI reboot request"); |
600 | sc_pm_reboot(SC_IPC_CH, SC_PM_RESET_TYPE_COLD); | 610 | sc_pm_reboot(SC_IPC_CH, SC_PM_RESET_TYPE_COLD); |
601 | while (1) | 611 | while (1) |
602 | putc('.'); | 612 | putc('.'); |
603 | } | 613 | } |
604 | 614 | ||
605 | #ifdef CONFIG_OF_BOARD_SETUP | 615 | #ifdef CONFIG_OF_BOARD_SETUP |
606 | int ft_board_setup(void *blob, bd_t *bd) | 616 | int ft_board_setup(void *blob, bd_t *bd) |
607 | { | 617 | { |
608 | return 0; | 618 | return 0; |
609 | } | 619 | } |
610 | #endif | 620 | #endif |
611 | 621 | ||
612 | int board_mmc_get_env_dev(int devno) | 622 | int board_mmc_get_env_dev(int devno) |
613 | { | 623 | { |
614 | return devno; | 624 | return devno; |
615 | } | 625 | } |
616 | 626 | ||
617 | int board_late_init(void) | 627 | int board_late_init(void) |
618 | { | 628 | { |
619 | #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG | 629 | #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG |
620 | env_set("board_name", "MEK"); | 630 | env_set("board_name", "MEK"); |
621 | env_set("board_rev", "iMX8QXP"); | 631 | env_set("board_rev", "iMX8QXP"); |
622 | #endif | 632 | #endif |
623 | 633 | ||
624 | env_set("sec_boot", "no"); | 634 | env_set("sec_boot", "no"); |
625 | #ifdef CONFIG_AHAB_BOOT | 635 | #ifdef CONFIG_AHAB_BOOT |
626 | env_set("sec_boot", "yes"); | 636 | env_set("sec_boot", "yes"); |
627 | #endif | 637 | #endif |
628 | 638 | ||
629 | #ifdef CONFIG_ENV_IS_IN_MMC | 639 | #ifdef CONFIG_ENV_IS_IN_MMC |
630 | board_late_mmc_env_init(); | 640 | board_late_mmc_env_init(); |
631 | #endif | 641 | #endif |
632 | 642 | ||
633 | return 0; | 643 | return 0; |
634 | } | 644 | } |
635 | 645 | ||
636 | #ifdef CONFIG_FSL_FASTBOOT | 646 | #ifdef CONFIG_FSL_FASTBOOT |
637 | #ifdef CONFIG_ANDROID_RECOVERY | 647 | #ifdef CONFIG_ANDROID_RECOVERY |
638 | int is_recovery_key_pressing(void) | 648 | int is_recovery_key_pressing(void) |
639 | { | 649 | { |
640 | return 0; /*TODO*/ | 650 | return 0; /*TODO*/ |
641 | } | 651 | } |
642 | #endif /*CONFIG_ANDROID_RECOVERY*/ | 652 | #endif /*CONFIG_ANDROID_RECOVERY*/ |
643 | #endif /*CONFIG_FSL_FASTBOOT*/ | 653 | #endif /*CONFIG_FSL_FASTBOOT*/ |
644 | 654 | ||
645 | #if defined(CONFIG_VIDEO_IMXDPUV1) | 655 | #if defined(CONFIG_VIDEO_IMXDPUV1) |
646 | static void enable_lvds(struct display_info_t const *dev) | 656 | static void enable_lvds(struct display_info_t const *dev) |
647 | { | 657 | { |
648 | struct gpio_desc desc; | 658 | struct gpio_desc desc; |
649 | int ret; | 659 | int ret; |
650 | 660 | ||
651 | /* MIPI_DSI0_EN on IOEXP 0x1a port 6, MIPI_DSI1_EN on IOEXP 0x1d port 7 */ | 661 | /* MIPI_DSI0_EN on IOEXP 0x1a port 6, MIPI_DSI1_EN on IOEXP 0x1d port 7 */ |
652 | ret = dm_gpio_lookup_name("gpio@1a_6", &desc); | 662 | ret = dm_gpio_lookup_name("gpio@1a_6", &desc); |
653 | if (ret) | 663 | if (ret) |
654 | return; | 664 | return; |
655 | 665 | ||
656 | ret = dm_gpio_request(&desc, "lvds0_en"); | 666 | ret = dm_gpio_request(&desc, "lvds0_en"); |
657 | if (ret) | 667 | if (ret) |
658 | return; | 668 | return; |
659 | 669 | ||
660 | dm_gpio_set_dir_flags(&desc, GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); | 670 | dm_gpio_set_dir_flags(&desc, GPIOD_IS_OUT | GPIOD_IS_OUT_ACTIVE); |
661 | 671 | ||
662 | display_controller_setup((PS2KHZ(dev->mode.pixclock) * 1000)); | 672 | display_controller_setup((PS2KHZ(dev->mode.pixclock) * 1000)); |
663 | lvds_soc_setup(dev->bus, (PS2KHZ(dev->mode.pixclock) * 1000)); | 673 | lvds_soc_setup(dev->bus, (PS2KHZ(dev->mode.pixclock) * 1000)); |
664 | lvds_configure(dev->bus); | 674 | lvds_configure(dev->bus); |
665 | lvds2hdmi_setup(13); | 675 | lvds2hdmi_setup(13); |
666 | } | 676 | } |
667 | 677 | ||
668 | struct display_info_t const displays[] = {{ | 678 | struct display_info_t const displays[] = {{ |
669 | .bus = 0, /* LVDS0 */ | 679 | .bus = 0, /* LVDS0 */ |
670 | .addr = 0, /* LVDS0 */ | 680 | .addr = 0, /* LVDS0 */ |
671 | .pixfmt = IMXDPUV1_PIX_FMT_BGRA32, | 681 | .pixfmt = IMXDPUV1_PIX_FMT_BGRA32, |
672 | .detect = NULL, | 682 | .detect = NULL, |
673 | .enable = enable_lvds, | 683 | .enable = enable_lvds, |
674 | .mode = { | 684 | .mode = { |
675 | .name = "IT6263", /* 720P60 */ | 685 | .name = "IT6263", /* 720P60 */ |
676 | .refresh = 60, | 686 | .refresh = 60, |
677 | .xres = 1280, | 687 | .xres = 1280, |
678 | .yres = 720, | 688 | .yres = 720, |
679 | .pixclock = 13468, /* 74250000 */ | 689 | .pixclock = 13468, /* 74250000 */ |
680 | .left_margin = 110, | 690 | .left_margin = 110, |
681 | .right_margin = 220, | 691 | .right_margin = 220, |
682 | .upper_margin = 5, | 692 | .upper_margin = 5, |
683 | .lower_margin = 20, | 693 | .lower_margin = 20, |
684 | .hsync_len = 40, | 694 | .hsync_len = 40, |
685 | .vsync_len = 5, | 695 | .vsync_len = 5, |
686 | .sync = FB_SYNC_EXT, | 696 | .sync = FB_SYNC_EXT, |
687 | .vmode = FB_VMODE_NONINTERLACED | 697 | .vmode = FB_VMODE_NONINTERLACED |
688 | } } }; | 698 | } } }; |
689 | size_t display_count = ARRAY_SIZE(displays); | 699 | size_t display_count = ARRAY_SIZE(displays); |
690 | 700 | ||
691 | #endif /* CONFIG_VIDEO_IMXDPUV1 */ | 701 | #endif /* CONFIG_VIDEO_IMXDPUV1 */ |
692 | 702 |