Commit 5da847a4fad5d85aab497c78a6008cd94b750b35
1 parent
b053775c03
Exists in
smarc-imx_v2018.03_4.14.78_1.0.0_ga
MLK-20635 imx8: clock: Fix GPR settings for FEC
FEC has some clock settings inside DSC GPR. Kernel configures them, but u-boot not. So when doing partition reset, the GPR keeps the value from kernel, and cause clock issue to u-boot FEC: kernel enables the divclk in GPR and set the clock slice to 250Mhz, u-boot configures the clock slice to 125Mhz, the divclk causes the RGMII TX CLK to 62.5Mhz. Fix the issue by aligning the GPR and clock slice settings with kernel Signed-off-by: Ye Li <ye.li@nxp.com> Reviewed-by: Fugang Duan <fugang.duan@nxp.com> (cherry picked from commit ab6b18bcf3cade15586839274bfde2030726ad37)
Showing 1 changed file with 12 additions and 2 deletions Inline Diff
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 | #include <asm/arch/lpcg.h> |
16 | 16 | ||
17 | DECLARE_GLOBAL_DATA_PTR; | 17 | DECLARE_GLOBAL_DATA_PTR; |
18 | 18 | ||
19 | u32 get_lpuart_clk(void) | 19 | u32 get_lpuart_clk(void) |
20 | { | 20 | { |
21 | return mxc_get_clock(MXC_UART_CLK); | 21 | return mxc_get_clock(MXC_UART_CLK); |
22 | } | 22 | } |
23 | 23 | ||
24 | static u32 get_arm_main_clk(void) | 24 | static u32 get_arm_main_clk(void) |
25 | { | 25 | { |
26 | sc_err_t err; | 26 | sc_err_t err; |
27 | sc_pm_clock_rate_t clkrate; | 27 | sc_pm_clock_rate_t clkrate; |
28 | 28 | ||
29 | if (is_cortex_a53()) | 29 | if (is_cortex_a53()) |
30 | 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, |
31 | SC_R_A53, SC_PM_CLK_CPU, &clkrate); | 31 | SC_R_A53, SC_PM_CLK_CPU, &clkrate); |
32 | else if (is_cortex_a72()) | 32 | else if (is_cortex_a72()) |
33 | 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, |
34 | SC_R_A72, SC_PM_CLK_CPU, &clkrate); | 34 | SC_R_A72, SC_PM_CLK_CPU, &clkrate); |
35 | else if (is_cortex_a35()) | 35 | else if (is_cortex_a35()) |
36 | 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, |
37 | SC_R_A35, SC_PM_CLK_CPU, &clkrate); | 37 | SC_R_A35, SC_PM_CLK_CPU, &clkrate); |
38 | else | 38 | else |
39 | err = SC_ERR_UNAVAILABLE; | 39 | err = SC_ERR_UNAVAILABLE; |
40 | 40 | ||
41 | if (err != SC_ERR_NONE) { | 41 | if (err != SC_ERR_NONE) { |
42 | printf("sc get ARM clk failed! err=%d\n", err); | 42 | printf("sc get ARM clk failed! err=%d\n", err); |
43 | return 0; | 43 | return 0; |
44 | } | 44 | } |
45 | return clkrate; | 45 | return clkrate; |
46 | } | 46 | } |
47 | 47 | ||
48 | unsigned int mxc_get_clock(enum mxc_clock clk) | 48 | unsigned int mxc_get_clock(enum mxc_clock clk) |
49 | { | 49 | { |
50 | sc_err_t err; | 50 | sc_err_t err; |
51 | sc_pm_clock_rate_t clkrate; | 51 | sc_pm_clock_rate_t clkrate; |
52 | 52 | ||
53 | switch (clk) { | 53 | switch (clk) { |
54 | case MXC_UART_CLK: | 54 | case MXC_UART_CLK: |
55 | 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, |
56 | SC_R_UART_0, 2, &clkrate); | 56 | SC_R_UART_0, 2, &clkrate); |
57 | if (err != SC_ERR_NONE) { | 57 | if (err != SC_ERR_NONE) { |
58 | printf("sc get UART clk failed! err=%d\n", err); | 58 | printf("sc get UART clk failed! err=%d\n", err); |
59 | return 0; | 59 | return 0; |
60 | } | 60 | } |
61 | return clkrate; | 61 | return clkrate; |
62 | case MXC_ESDHC_CLK: | 62 | case MXC_ESDHC_CLK: |
63 | 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, |
64 | SC_R_SDHC_0, 2, &clkrate); | 64 | SC_R_SDHC_0, 2, &clkrate); |
65 | if (err != SC_ERR_NONE) { | 65 | if (err != SC_ERR_NONE) { |
66 | printf("sc get uSDHC1 clk failed! err=%d\n", err); | 66 | printf("sc get uSDHC1 clk failed! err=%d\n", err); |
67 | return 0; | 67 | return 0; |
68 | } | 68 | } |
69 | return clkrate; | 69 | return clkrate; |
70 | case MXC_ESDHC2_CLK: | 70 | case MXC_ESDHC2_CLK: |
71 | 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, |
72 | SC_R_SDHC_1, 2, &clkrate); | 72 | SC_R_SDHC_1, 2, &clkrate); |
73 | if (err != SC_ERR_NONE) { | 73 | if (err != SC_ERR_NONE) { |
74 | printf("sc get uSDHC2 clk failed! err=%d\n", err); | 74 | printf("sc get uSDHC2 clk failed! err=%d\n", err); |
75 | return 0; | 75 | return 0; |
76 | } | 76 | } |
77 | return clkrate; | 77 | return clkrate; |
78 | case MXC_ESDHC3_CLK: | 78 | case MXC_ESDHC3_CLK: |
79 | 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, |
80 | SC_R_SDHC_2, 2, &clkrate); | 80 | SC_R_SDHC_2, 2, &clkrate); |
81 | if (err != SC_ERR_NONE) { | 81 | if (err != SC_ERR_NONE) { |
82 | printf("sc get uSDHC3 clk failed! err=%d\n", err); | 82 | printf("sc get uSDHC3 clk failed! err=%d\n", err); |
83 | return 0; | 83 | return 0; |
84 | } | 84 | } |
85 | return clkrate; | 85 | return clkrate; |
86 | case MXC_FEC_CLK: | 86 | case MXC_FEC_CLK: |
87 | 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, |
88 | SC_R_ENET_0, 2, &clkrate); | 88 | SC_R_ENET_0, 2, &clkrate); |
89 | if (err != SC_ERR_NONE) { | 89 | if (err != SC_ERR_NONE) { |
90 | printf("sc get ENET clk failed! err=%d\n", err); | 90 | printf("sc get ENET clk failed! err=%d\n", err); |
91 | return 0; | 91 | return 0; |
92 | } | 92 | } |
93 | return clkrate; | 93 | return clkrate; |
94 | case MXC_FSPI_CLK: | 94 | case MXC_FSPI_CLK: |
95 | 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, |
96 | SC_R_FSPI_0, 2, &clkrate); | 96 | SC_R_FSPI_0, 2, &clkrate); |
97 | if (err != SC_ERR_NONE) { | 97 | if (err != SC_ERR_NONE) { |
98 | printf("sc get FSPI clk failed! err=%d\n", err); | 98 | printf("sc get FSPI clk failed! err=%d\n", err); |
99 | return 0; | 99 | return 0; |
100 | } | 100 | } |
101 | return clkrate; | 101 | return clkrate; |
102 | case MXC_DDR_CLK: | 102 | case MXC_DDR_CLK: |
103 | 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, |
104 | SC_R_DRC_0, 0, &clkrate); | 104 | SC_R_DRC_0, 0, &clkrate); |
105 | if (err != SC_ERR_NONE) { | 105 | if (err != SC_ERR_NONE) { |
106 | printf("sc get DRC0 clk failed! err=%d\n", err); | 106 | printf("sc get DRC0 clk failed! err=%d\n", err); |
107 | return 0; | 107 | return 0; |
108 | } | 108 | } |
109 | return clkrate; | 109 | return clkrate; |
110 | case MXC_ARM_CLK: | 110 | case MXC_ARM_CLK: |
111 | return get_arm_main_clk(); | 111 | return get_arm_main_clk(); |
112 | default: | 112 | default: |
113 | printf("Unsupported mxc_clock %d\n", clk); | 113 | printf("Unsupported mxc_clock %d\n", clk); |
114 | break; | 114 | break; |
115 | } | 115 | } |
116 | 116 | ||
117 | return 0; | 117 | return 0; |
118 | } | 118 | } |
119 | 119 | ||
120 | u32 imx_get_fecclk(void) | 120 | u32 imx_get_fecclk(void) |
121 | { | 121 | { |
122 | return mxc_get_clock(MXC_FEC_CLK); | 122 | return mxc_get_clock(MXC_FEC_CLK); |
123 | } | 123 | } |
124 | 124 | ||
125 | static struct imx_i2c_map *get_i2c_desc(unsigned i2c_num) | 125 | static struct imx_i2c_map *get_i2c_desc(unsigned i2c_num) |
126 | { | 126 | { |
127 | int i; | 127 | int i; |
128 | for (i = 0; i < ARRAY_SIZE(imx_i2c_desc); i++) { | 128 | for (i = 0; i < ARRAY_SIZE(imx_i2c_desc); i++) { |
129 | if (imx_i2c_desc[i].index == i2c_num) | 129 | if (imx_i2c_desc[i].index == i2c_num) |
130 | return &imx_i2c_desc[i]; | 130 | return &imx_i2c_desc[i]; |
131 | } | 131 | } |
132 | return NULL; | 132 | return NULL; |
133 | } | 133 | } |
134 | 134 | ||
135 | int enable_i2c_clk(unsigned char enable, unsigned i2c_num) | 135 | int enable_i2c_clk(unsigned char enable, unsigned i2c_num) |
136 | { | 136 | { |
137 | sc_ipc_t ipc; | 137 | sc_ipc_t ipc; |
138 | sc_err_t err; | 138 | sc_err_t err; |
139 | struct imx_i2c_map *desc; | 139 | struct imx_i2c_map *desc; |
140 | int i; | 140 | int i; |
141 | 141 | ||
142 | desc = get_i2c_desc(i2c_num); | 142 | desc = get_i2c_desc(i2c_num); |
143 | if (!desc) | 143 | if (!desc) |
144 | return -EINVAL; | 144 | return -EINVAL; |
145 | 145 | ||
146 | ipc = gd->arch.ipc_channel_handle; | 146 | ipc = gd->arch.ipc_channel_handle; |
147 | 147 | ||
148 | if (enable) | 148 | if (enable) |
149 | err = sc_pm_clock_enable(ipc, | 149 | err = sc_pm_clock_enable(ipc, |
150 | desc->rsrc, 2, true, false); | 150 | desc->rsrc, 2, true, false); |
151 | else | 151 | else |
152 | err = sc_pm_clock_enable(ipc, | 152 | err = sc_pm_clock_enable(ipc, |
153 | desc->rsrc, 2, false, false); | 153 | desc->rsrc, 2, false, false); |
154 | 154 | ||
155 | if (err != SC_ERR_NONE) { | 155 | if (err != SC_ERR_NONE) { |
156 | printf("i2c clock error %d\n", err); | 156 | printf("i2c clock error %d\n", err); |
157 | return -EPERM; | 157 | return -EPERM; |
158 | } | 158 | } |
159 | 159 | ||
160 | for (i = 0; i < 4; i++) { | 160 | for (i = 0; i < 4; i++) { |
161 | if (desc->lpcg[i] == 0) | 161 | if (desc->lpcg[i] == 0) |
162 | break; | 162 | break; |
163 | LPCG_AllClockOn(desc->lpcg[i]); | 163 | LPCG_AllClockOn(desc->lpcg[i]); |
164 | } | 164 | } |
165 | 165 | ||
166 | return 0; | 166 | return 0; |
167 | } | 167 | } |
168 | 168 | ||
169 | u32 imx_get_i2cclk(unsigned i2c_num) | 169 | u32 imx_get_i2cclk(unsigned i2c_num) |
170 | { | 170 | { |
171 | sc_err_t err; | 171 | sc_err_t err; |
172 | sc_ipc_t ipc; | 172 | sc_ipc_t ipc; |
173 | u32 clock_rate; | 173 | u32 clock_rate; |
174 | struct imx_i2c_map *desc; | 174 | struct imx_i2c_map *desc; |
175 | 175 | ||
176 | desc = get_i2c_desc(i2c_num); | 176 | desc = get_i2c_desc(i2c_num); |
177 | if (!desc) | 177 | if (!desc) |
178 | return -EINVAL; | 178 | return -EINVAL; |
179 | 179 | ||
180 | ipc = gd->arch.ipc_channel_handle; | 180 | ipc = gd->arch.ipc_channel_handle; |
181 | err = sc_pm_get_clock_rate(ipc, desc->rsrc, 2, | 181 | err = sc_pm_get_clock_rate(ipc, desc->rsrc, 2, |
182 | &clock_rate); | 182 | &clock_rate); |
183 | if (err != SC_ERR_NONE) | 183 | if (err != SC_ERR_NONE) |
184 | return 0; | 184 | return 0; |
185 | 185 | ||
186 | return clock_rate; | 186 | return clock_rate; |
187 | } | 187 | } |
188 | 188 | ||
189 | void init_clk_fspi(int index) | 189 | void init_clk_fspi(int index) |
190 | { | 190 | { |
191 | sc_err_t sciErr = 0; | 191 | sc_err_t sciErr = 0; |
192 | sc_pm_clock_rate_t rate; | 192 | sc_pm_clock_rate_t rate; |
193 | sc_ipc_t ipcHndl = gd->arch.ipc_channel_handle; | 193 | sc_ipc_t ipcHndl = gd->arch.ipc_channel_handle; |
194 | 194 | ||
195 | /* Set FSPI0 clock root to 29 MHz */ | 195 | /* Set FSPI0 clock root to 29 MHz */ |
196 | rate = 29000000; | 196 | rate = 29000000; |
197 | 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); |
198 | if (sciErr != SC_ERR_NONE) { | 198 | if (sciErr != SC_ERR_NONE) { |
199 | puts("FSPI0 setrate failed\n"); | 199 | puts("FSPI0 setrate failed\n"); |
200 | return; | 200 | return; |
201 | } | 201 | } |
202 | 202 | ||
203 | /* Enable FSPI0 clock root */ | 203 | /* Enable FSPI0 clock root */ |
204 | 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); |
205 | if (sciErr != SC_ERR_NONE) { | 205 | if (sciErr != SC_ERR_NONE) { |
206 | puts("FSPI0 enable clock failed\n"); | 206 | puts("FSPI0 enable clock failed\n"); |
207 | return; | 207 | return; |
208 | } | 208 | } |
209 | 209 | ||
210 | LPCG_AllClockOn(FSPI_0_LPCG); | 210 | LPCG_AllClockOn(FSPI_0_LPCG); |
211 | 211 | ||
212 | return; | 212 | return; |
213 | } | 213 | } |
214 | 214 | ||
215 | void init_clk_gpmi_nand(void) | 215 | void init_clk_gpmi_nand(void) |
216 | { | 216 | { |
217 | sc_err_t sciErr = 0; | 217 | sc_err_t sciErr = 0; |
218 | sc_pm_clock_rate_t rate; | 218 | sc_pm_clock_rate_t rate; |
219 | sc_ipc_t ipcHndl = gd->arch.ipc_channel_handle; | 219 | sc_ipc_t ipcHndl = gd->arch.ipc_channel_handle; |
220 | 220 | ||
221 | /* Set NAND BCH clock root to 50 MHz */ | 221 | /* Set NAND BCH clock root to 50 MHz */ |
222 | rate = 50000000; | 222 | rate = 50000000; |
223 | 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); |
224 | if (sciErr != SC_ERR_NONE) { | 224 | if (sciErr != SC_ERR_NONE) { |
225 | puts("NAND BCH set rate failed\n"); | 225 | puts("NAND BCH set rate failed\n"); |
226 | return; | 226 | return; |
227 | } | 227 | } |
228 | 228 | ||
229 | /* Enable NAND BCH clock root */ | 229 | /* Enable NAND BCH clock root */ |
230 | 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); |
231 | if (sciErr != SC_ERR_NONE) { | 231 | if (sciErr != SC_ERR_NONE) { |
232 | puts("NAND BCH enable clock failed\n"); | 232 | puts("NAND BCH enable clock failed\n"); |
233 | return; | 233 | return; |
234 | } | 234 | } |
235 | 235 | ||
236 | /* Set NAND GPMI clock root to 50 MHz */ | 236 | /* Set NAND GPMI clock root to 50 MHz */ |
237 | rate = 50000000; | 237 | rate = 50000000; |
238 | 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); |
239 | if (sciErr != SC_ERR_NONE) { | 239 | if (sciErr != SC_ERR_NONE) { |
240 | puts("NAND GPMI set rate failed\n"); | 240 | puts("NAND GPMI set rate failed\n"); |
241 | return; | 241 | return; |
242 | } | 242 | } |
243 | 243 | ||
244 | /* Enable NAND GPMI clock root */ | 244 | /* Enable NAND GPMI clock root */ |
245 | 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); |
246 | if (sciErr != SC_ERR_NONE) { | 246 | if (sciErr != SC_ERR_NONE) { |
247 | puts("NAND GPMI enable clock failed\n"); | 247 | puts("NAND GPMI enable clock failed\n"); |
248 | return; | 248 | return; |
249 | } | 249 | } |
250 | 250 | ||
251 | LPCG_AllClockOn(NAND_LPCG); | 251 | LPCG_AllClockOn(NAND_LPCG); |
252 | 252 | ||
253 | return; | 253 | return; |
254 | } | 254 | } |
255 | 255 | ||
256 | void enable_usboh3_clk(unsigned char enable) | 256 | void enable_usboh3_clk(unsigned char enable) |
257 | { | 257 | { |
258 | LPCG_AllClockOn(USB_2_LPCG); | 258 | LPCG_AllClockOn(USB_2_LPCG); |
259 | return; | 259 | return; |
260 | } | 260 | } |
261 | 261 | ||
262 | void init_clk_usb3(int index) | 262 | void init_clk_usb3(int index) |
263 | { | 263 | { |
264 | sc_err_t err; | 264 | sc_err_t err; |
265 | sc_ipc_t ipc; | 265 | sc_ipc_t ipc; |
266 | 266 | ||
267 | ipc = gd->arch.ipc_channel_handle; | 267 | ipc = gd->arch.ipc_channel_handle; |
268 | 268 | ||
269 | 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); |
270 | if (err != SC_ERR_NONE) | 270 | if (err != SC_ERR_NONE) |
271 | printf("USB3 set clock failed!, line=%d (error = %d)\n", | 271 | printf("USB3 set clock failed!, line=%d (error = %d)\n", |
272 | __LINE__, err); | 272 | __LINE__, err); |
273 | 273 | ||
274 | 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); |
275 | if (err != SC_ERR_NONE) | 275 | if (err != SC_ERR_NONE) |
276 | printf("USB3 set clock failed!, line=%d (error = %d)\n", | 276 | printf("USB3 set clock failed!, line=%d (error = %d)\n", |
277 | __LINE__, err); | 277 | __LINE__, err); |
278 | 278 | ||
279 | 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); |
280 | if (err != SC_ERR_NONE) | 280 | if (err != SC_ERR_NONE) |
281 | printf("USB3 set clock failed!, line=%d (error = %d)\n", | 281 | printf("USB3 set clock failed!, line=%d (error = %d)\n", |
282 | __LINE__, err); | 282 | __LINE__, err); |
283 | 283 | ||
284 | LPCG_AllClockOn(USB_3_LPCG); | 284 | LPCG_AllClockOn(USB_3_LPCG); |
285 | return; | 285 | return; |
286 | } | 286 | } |
287 | 287 | ||
288 | int cdns3_enable_clks(int index) | 288 | int cdns3_enable_clks(int index) |
289 | { | 289 | { |
290 | init_clk_usb3(index); | 290 | init_clk_usb3(index); |
291 | return 0; | 291 | return 0; |
292 | } | 292 | } |
293 | 293 | ||
294 | int cdns3_disable_clks(int index) | 294 | int cdns3_disable_clks(int index) |
295 | { | 295 | { |
296 | sc_err_t err; | 296 | sc_err_t err; |
297 | sc_ipc_t ipc; | 297 | sc_ipc_t ipc; |
298 | 298 | ||
299 | ipc = gd->arch.ipc_channel_handle; | 299 | ipc = gd->arch.ipc_channel_handle; |
300 | 300 | ||
301 | LPCG_AllClockOff(USB_3_LPCG); | 301 | LPCG_AllClockOff(USB_3_LPCG); |
302 | 302 | ||
303 | 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); |
304 | if (err != SC_ERR_NONE) | 304 | if (err != SC_ERR_NONE) |
305 | printf("USB3 disable clock failed!, line=%d (error = %d)\n", | 305 | printf("USB3 disable clock failed!, line=%d (error = %d)\n", |
306 | __LINE__, err); | 306 | __LINE__, err); |
307 | 307 | ||
308 | 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); |
309 | if (err != SC_ERR_NONE) | 309 | if (err != SC_ERR_NONE) |
310 | printf("USB3 disable clock failed!, line=%d (error = %d)\n", | 310 | printf("USB3 disable clock failed!, line=%d (error = %d)\n", |
311 | __LINE__, err); | 311 | __LINE__, err); |
312 | 312 | ||
313 | 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); |
314 | if (err != SC_ERR_NONE) | 314 | if (err != SC_ERR_NONE) |
315 | printf("USB3 disable clock failed!, line=%d (error = %d)\n", | 315 | printf("USB3 disable clock failed!, line=%d (error = %d)\n", |
316 | __LINE__, err); | 316 | __LINE__, err); |
317 | 317 | ||
318 | return 0; | 318 | return 0; |
319 | } | 319 | } |
320 | 320 | ||
321 | void init_clk_usdhc(u32 index) | 321 | void init_clk_usdhc(u32 index) |
322 | { | 322 | { |
323 | #ifdef CONFIG_IMX8QM | 323 | #ifdef CONFIG_IMX8QM |
324 | 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}; |
325 | u32 instances = 3; | 325 | u32 instances = 3; |
326 | #else | 326 | #else |
327 | 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}; |
328 | u32 instances = 2; | 328 | u32 instances = 2; |
329 | #endif | 329 | #endif |
330 | 330 | ||
331 | sc_err_t err; | 331 | sc_err_t err; |
332 | sc_ipc_t ipc; | 332 | sc_ipc_t ipc; |
333 | sc_pm_clock_rate_t actual = 400000000; | 333 | sc_pm_clock_rate_t actual = 400000000; |
334 | 334 | ||
335 | ipc = gd->arch.ipc_channel_handle; | 335 | ipc = gd->arch.ipc_channel_handle; |
336 | 336 | ||
337 | if (index >= instances) | 337 | if (index >= instances) |
338 | return; | 338 | return; |
339 | 339 | ||
340 | /* Must disable the clock before set clock parent */ | 340 | /* Must disable the clock before set clock parent */ |
341 | 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); |
342 | if (err != SC_ERR_NONE) { | 342 | if (err != SC_ERR_NONE) { |
343 | printf("SDHC_%d per clk enable failed!\n", index); | 343 | printf("SDHC_%d per clk enable failed!\n", index); |
344 | return; | 344 | return; |
345 | } | 345 | } |
346 | 346 | ||
347 | /* | 347 | /* |
348 | * IMX8QXP USDHC_CLK_ROOT default source from DPLL, but this DPLL | 348 | * IMX8QXP USDHC_CLK_ROOT default source from DPLL, but this DPLL |
349 | * 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 |
350 | * 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 |
351 | * 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, |
352 | * 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 |
353 | * SDR104 work at 200MHz. | 353 | * SDR104 work at 200MHz. |
354 | */ | 354 | */ |
355 | if (is_imx8qxp()) { | 355 | if (is_imx8qxp()) { |
356 | 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); |
357 | if (err != SC_ERR_NONE) | 357 | if (err != SC_ERR_NONE) |
358 | 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); |
359 | 359 | ||
360 | if (index == 1) | 360 | if (index == 1) |
361 | actual = 200000000; | 361 | actual = 200000000; |
362 | } | 362 | } |
363 | 363 | ||
364 | err = sc_pm_set_clock_rate(ipc, usdhcs[index], 2, &actual); | 364 | err = sc_pm_set_clock_rate(ipc, usdhcs[index], 2, &actual); |
365 | if (err != SC_ERR_NONE) { | 365 | if (err != SC_ERR_NONE) { |
366 | printf("SDHC_%d set clock failed! (error = %d)\n", index, err); | 366 | printf("SDHC_%d set clock failed! (error = %d)\n", index, err); |
367 | return; | 367 | return; |
368 | } | 368 | } |
369 | 369 | ||
370 | if (actual != 400000000) | 370 | if (actual != 400000000) |
371 | debug("Actual rate for SDHC_%d is %d\n", index, actual); | 371 | debug("Actual rate for SDHC_%d is %d\n", index, actual); |
372 | 372 | ||
373 | 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); |
374 | if (err != SC_ERR_NONE) { | 374 | if (err != SC_ERR_NONE) { |
375 | printf("SDHC_%d per clk enable failed!\n", index); | 375 | printf("SDHC_%d per clk enable failed!\n", index); |
376 | return; | 376 | return; |
377 | } | 377 | } |
378 | 378 | ||
379 | LPCG_AllClockOn(USDHC_0_LPCG + index * 0x10000); | 379 | LPCG_AllClockOn(USDHC_0_LPCG + index * 0x10000); |
380 | } | 380 | } |
381 | 381 | ||
382 | void init_clk_fec(int index) | 382 | void init_clk_fec(int index) |
383 | { | 383 | { |
384 | sc_err_t err; | 384 | sc_err_t err; |
385 | sc_ipc_t ipc; | 385 | sc_ipc_t ipc; |
386 | sc_pm_clock_rate_t rate = 24000000; | 386 | sc_pm_clock_rate_t rate = 24000000; |
387 | 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}; |
388 | 388 | ||
389 | if (index > 1) | 389 | if (index > 1) |
390 | return; | 390 | return; |
391 | 391 | ||
392 | if (index == -1) | 392 | if (index == -1) |
393 | index = 0; | 393 | index = 0; |
394 | 394 | ||
395 | ipc = gd->arch.ipc_channel_handle; | 395 | ipc = gd->arch.ipc_channel_handle; |
396 | 396 | ||
397 | /* Disable SC_R_ENET_0 clock root */ | 397 | /* Disable SC_R_ENET_0 clock root */ |
398 | err = sc_pm_clock_enable(ipc, enet[index], 0, false, false); | 398 | err = sc_pm_clock_enable(ipc, enet[index], 0, false, false); |
399 | err |= sc_pm_clock_enable(ipc, enet[index], 2, false, false); | 399 | err |= sc_pm_clock_enable(ipc, enet[index], 2, false, false); |
400 | err |= sc_pm_clock_enable(ipc, enet[index], 4, false, false); | 400 | err |= sc_pm_clock_enable(ipc, enet[index], 4, false, false); |
401 | if (err != SC_ERR_NONE) { | 401 | if (err != SC_ERR_NONE) { |
402 | 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); |
403 | return; | 403 | return; |
404 | } | 404 | } |
405 | 405 | ||
406 | /* Set SC_R_ENET_0 clock root to 125 MHz */ | 406 | /* Set SC_R_ENET_0 clock root to 250 MHz, the clkdiv is set to div 2 |
407 | rate = 125000000; | 407 | * so finally RGMII TX clk is 125Mhz |
408 | */ | ||
409 | rate = 250000000; | ||
408 | 410 | ||
409 | /* div = 8 clk_source = PLL_1 ss_slice #7 in verfication codes */ | 411 | /* div = 8 clk_source = PLL_1 ss_slice #7 in verfication codes */ |
410 | err = sc_pm_set_clock_rate(ipc, enet[index], 2, &rate); | 412 | err = sc_pm_set_clock_rate(ipc, enet[index], 2, &rate); |
411 | if (err != SC_ERR_NONE) { | 413 | if (err != SC_ERR_NONE) { |
412 | printf("\nSC_R_ENET_0 set clock ref clock 125M failed! (error = %d)\n", err); | 414 | printf("\nSC_R_ENET_0 set clock ref clock 125M failed! (error = %d)\n", err); |
413 | return; | 415 | return; |
414 | } | 416 | } |
415 | 417 | ||
416 | /* Enable SC_R_ENET_0 clock root */ | 418 | /* Enable SC_R_ENET_0 clock root */ |
417 | err = sc_pm_clock_enable(ipc, enet[index], 0, true, true); | 419 | err = sc_pm_clock_enable(ipc, enet[index], 0, true, true); |
418 | err |= sc_pm_clock_enable(ipc, enet[index], 2, true, true); | 420 | err |= sc_pm_clock_enable(ipc, enet[index], 2, true, true); |
419 | err |= sc_pm_clock_enable(ipc, enet[index], 4, true, true); | 421 | err |= sc_pm_clock_enable(ipc, enet[index], 4, true, true); |
420 | if (err != SC_ERR_NONE) { | 422 | if (err != SC_ERR_NONE) { |
421 | printf("\nSC_R_ENET_0 set clock enable failed! (error = %d)\n", err); | 423 | printf("\nSC_R_ENET_0 set clock enable failed! (error = %d)\n", err); |
422 | return; | 424 | return; |
423 | } | 425 | } |
426 | |||
427 | /* Configure GPR regisers */ | ||
428 | sc_misc_set_control(ipc, enet[index], SC_C_TXCLK, 0); | ||
429 | sc_misc_set_control(ipc, enet[index], SC_C_CLKDIV, 1); /* Enable divclk */ | ||
430 | sc_misc_set_control(ipc, enet[index], SC_C_DISABLE_50, 1); | ||
431 | sc_misc_set_control(ipc, enet[index], SC_C_DISABLE_125, 1); | ||
432 | sc_misc_set_control(ipc, enet[index], SC_C_SEL_125, 0); | ||
433 | sc_misc_set_control(ipc, enet[index], SC_C_IPG_STOP, 0); | ||
424 | 434 | ||
425 | LPCG_AllClockOn(ENET_0_LPCG + index * 0x10000); | 435 | LPCG_AllClockOn(ENET_0_LPCG + index * 0x10000); |
426 | } | 436 | } |
427 | 437 | ||
428 | /* | 438 | /* |
429 | * Dump some core clockes. | 439 | * Dump some core clockes. |
430 | */ | 440 | */ |
431 | int do_mx8_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) | 441 | int do_mx8_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) |
432 | { | 442 | { |
433 | printf("ARM %8d kHz\n", mxc_get_clock(MXC_ARM_CLK) / 1000); | 443 | printf("ARM %8d kHz\n", mxc_get_clock(MXC_ARM_CLK) / 1000); |
434 | printf("DRC %8d kHz\n", mxc_get_clock(MXC_DDR_CLK) / 1000); | 444 | printf("DRC %8d kHz\n", mxc_get_clock(MXC_DDR_CLK) / 1000); |
435 | printf("USDHC1 %8d kHz\n", mxc_get_clock(MXC_ESDHC_CLK) / 1000); | 445 | printf("USDHC1 %8d kHz\n", mxc_get_clock(MXC_ESDHC_CLK) / 1000); |
436 | printf("USDHC2 %8d kHz\n", mxc_get_clock(MXC_ESDHC2_CLK) / 1000); | 446 | printf("USDHC2 %8d kHz\n", mxc_get_clock(MXC_ESDHC2_CLK) / 1000); |
437 | printf("USDHC3 %8d kHz\n", mxc_get_clock(MXC_ESDHC3_CLK) / 1000); | 447 | printf("USDHC3 %8d kHz\n", mxc_get_clock(MXC_ESDHC3_CLK) / 1000); |
438 | printf("UART0 %8d kHz\n", mxc_get_clock(MXC_UART_CLK) / 1000); | 448 | printf("UART0 %8d kHz\n", mxc_get_clock(MXC_UART_CLK) / 1000); |
439 | printf("FEC0 %8d kHz\n", mxc_get_clock(MXC_FEC_CLK) / 1000); | 449 | printf("FEC0 %8d kHz\n", mxc_get_clock(MXC_FEC_CLK) / 1000); |
440 | printf("FLEXSPI0 %8d kHz\n", mxc_get_clock(MXC_FSPI_CLK) / 1000); | 450 | printf("FLEXSPI0 %8d kHz\n", mxc_get_clock(MXC_FSPI_CLK) / 1000); |
441 | 451 | ||
442 | return 0; | 452 | return 0; |
443 | } | 453 | } |
444 | 454 | ||
445 | U_BOOT_CMD( | 455 | U_BOOT_CMD( |
446 | clocks, CONFIG_SYS_MAXARGS, 1, do_mx8_showclocks, | 456 | clocks, CONFIG_SYS_MAXARGS, 1, do_mx8_showclocks, |
447 | "display clocks", | 457 | "display clocks", |
448 | "" | 458 | "" |
449 | ); | 459 | ); |
450 | 460 |