blob: d74a6cde9acd35231d96c22bc00cb36b2f97b4b2 [file] [log] [blame]
Tony Xief6118cc2016-01-15 17:17:32 +08001/*
2 * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
9 *
10 * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * Neither the name of ARM nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific
16 * prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include <arch_helpers.h>
32#include <debug.h>
33#include <delay_timer.h>
Derek Basehoreff461d02016-10-20 20:46:43 -070034#include <dfs.h>
35#include <dram.h>
Tony Xief6118cc2016-01-15 17:17:32 +080036#include <mmio.h>
37#include <platform_def.h>
38#include <plat_private.h>
39#include <rk3399_def.h>
Caesar Wangbb228622016-10-12 01:47:51 +080040#include <rk3399m0.h>
Tony Xief6118cc2016-01-15 17:17:32 +080041#include <soc.h>
42
43/* Table of regions to map using the MMU. */
44const mmap_region_t plat_rk_mmap[] = {
Caesar Wangad39cfe2016-07-21 10:36:22 +080045 MAP_REGION_FLAT(RK3399_DEV_RNG0_BASE, RK3399_DEV_RNG0_SIZE,
Tony Xie42e113e2016-07-16 11:16:51 +080046 MT_DEVICE | MT_RW | MT_SECURE),
Caesar Wang5339d182016-10-27 01:13:34 +080047 MAP_REGION_FLAT(PMUSRAM_BASE, PMUSRAM_SIZE,
48 MT_MEMORY | MT_RW | MT_SECURE),
Tony Xie42e113e2016-07-16 11:16:51 +080049
Tony Xief6118cc2016-01-15 17:17:32 +080050 { 0 }
51};
52
53/* The RockChip power domain tree descriptor */
54const unsigned char rockchip_power_domain_tree_desc[] = {
55 /* No of root nodes */
56 PLATFORM_SYSTEM_COUNT,
57 /* No of children for the root node */
58 PLATFORM_CLUSTER_COUNT,
59 /* No of children for the first cluster node */
60 PLATFORM_CLUSTER0_CORE_COUNT,
61 /* No of children for the second cluster node */
62 PLATFORM_CLUSTER1_CORE_COUNT
63};
64
65void secure_timer_init(void)
66{
67 mmio_write_32(STIMER1_CHN_BASE(5) + TIMER_END_COUNT0, 0xffffffff);
68 mmio_write_32(STIMER1_CHN_BASE(5) + TIMER_END_COUNT1, 0xffffffff);
69
70 mmio_write_32(STIMER1_CHN_BASE(5) + TIMER_INIT_COUNT0, 0x0);
71 mmio_write_32(STIMER1_CHN_BASE(5) + TIMER_INIT_COUNT0, 0x0);
72
73 /* auto reload & enable the timer */
74 mmio_write_32(STIMER1_CHN_BASE(5) + TIMER_CONTROL_REG,
75 TIMER_EN | TIMER_FMODE);
76}
77
78void sgrf_init(void)
79{
80 /* security config for master */
81 mmio_write_32(SGRF_BASE + SGRF_SOC_CON3_7(5),
82 SGRF_SOC_CON_WMSK | SGRF_SOC_ALLMST_NS);
83 mmio_write_32(SGRF_BASE + SGRF_SOC_CON3_7(6),
84 SGRF_SOC_CON_WMSK | SGRF_SOC_ALLMST_NS);
85 mmio_write_32(SGRF_BASE + SGRF_SOC_CON3_7(7),
86 SGRF_SOC_CON_WMSK | SGRF_SOC_ALLMST_NS);
87
88 /* security config for slave */
89 mmio_write_32(SGRF_BASE + SGRF_PMU_SLV_CON0_1(0),
90 SGRF_PMU_SLV_S_CFGED |
91 SGRF_PMU_SLV_CRYPTO1_NS);
92 mmio_write_32(SGRF_BASE + SGRF_PMU_SLV_CON0_1(1),
93 SGRF_PMU_SLV_CON1_CFG);
94 mmio_write_32(SGRF_BASE + SGRF_SLV_SECURE_CON0_4(0),
95 SGRF_SLV_S_WMSK | SGRF_SLV_S_ALL_NS);
96 mmio_write_32(SGRF_BASE + SGRF_SLV_SECURE_CON0_4(1),
97 SGRF_SLV_S_WMSK | SGRF_SLV_S_ALL_NS);
98 mmio_write_32(SGRF_BASE + SGRF_SLV_SECURE_CON0_4(2),
99 SGRF_SLV_S_WMSK | SGRF_SLV_S_ALL_NS);
100 mmio_write_32(SGRF_BASE + SGRF_SLV_SECURE_CON0_4(3),
101 SGRF_SLV_S_WMSK | SGRF_SLV_S_ALL_NS);
102 mmio_write_32(SGRF_BASE + SGRF_SLV_SECURE_CON0_4(4),
103 SGRF_SLV_S_WMSK | SGRF_SLV_S_ALL_NS);
104
105 /* security config for ddr memery */
106 mmio_write_32(SGRF_BASE + SGRF_DDRRGN_CON0_16(16),
107 SGRF_DDR_RGN_BYPS);
108}
109
110static void dma_secure_cfg(uint32_t secure)
111{
112 if (secure) {
113 /* rgn0 secure for dmac0 and dmac1 */
114 mmio_write_32(SGRF_BASE + SGRF_DDRRGN_CON20_34(22),
115 SGRF_L_MST_S_DDR_RGN(0) | /* dmac0 */
116 SGRF_H_MST_S_DDR_RGN(0) /* dmac1 */
117 );
118
119 /* set dmac0 boot, under secure state */
120 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(8),
121 SGRF_DMAC_CFG_S);
122 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(9),
123 SGRF_DMAC_CFG_S);
124 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(10),
125 SGRF_DMAC_CFG_S);
126
127 /* dmac0 soft reset */
128 mmio_write_32(CRU_BASE + CRU_SOFTRST_CON(10),
129 CRU_DMAC0_RST);
130 udelay(5);
131 mmio_write_32(CRU_BASE + CRU_SOFTRST_CON(10),
132 CRU_DMAC0_RST_RLS);
133
134 /* set dmac1 boot, under secure state */
135 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(11),
136 SGRF_DMAC_CFG_S);
137 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(12),
138 SGRF_DMAC_CFG_S);
139 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(13),
140 SGRF_DMAC_CFG_S);
141 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(14),
142 SGRF_DMAC_CFG_S);
143 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(15),
144 SGRF_DMAC_CFG_S);
145
146 /* dmac1 soft reset */
147 mmio_write_32(CRU_BASE + CRU_SOFTRST_CON(10),
148 CRU_DMAC1_RST);
149 udelay(5);
150 mmio_write_32(CRU_BASE + CRU_SOFTRST_CON(10),
151 CRU_DMAC1_RST_RLS);
152 } else {
153 /* rgn non-secure for dmac0 and dmac1 */
154 mmio_write_32(SGRF_BASE + SGRF_DDRRGN_CON20_34(22),
155 DMAC1_RGN_NS | DMAC0_RGN_NS);
156
157 /* set dmac0 boot, under non-secure state */
158 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(8),
159 DMAC0_BOOT_CFG_NS);
160 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(9),
161 DMAC0_BOOT_PERIPH_NS);
162 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(10),
163 DMAC0_BOOT_ADDR_NS);
164
165 /* dmac0 soft reset */
166 mmio_write_32(CRU_BASE + CRU_SOFTRST_CON(10),
167 CRU_DMAC0_RST);
168 udelay(5);
169 mmio_write_32(CRU_BASE + CRU_SOFTRST_CON(10),
170 CRU_DMAC0_RST_RLS);
171
172 /* set dmac1 boot, under non-secure state */
173 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(11),
174 DMAC1_BOOT_CFG_NS);
175 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(12),
176 DMAC1_BOOT_PERIPH_L_NS);
177 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(13),
178 DMAC1_BOOT_ADDR_NS);
179 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(14),
180 DMAC1_BOOT_PERIPH_H_NS);
181 mmio_write_32(SGRF_BASE + SGRF_SOC_CON8_15(15),
182 DMAC1_BOOT_IRQ_NS);
183
184 /* dmac1 soft reset */
185 mmio_write_32(CRU_BASE + CRU_SOFTRST_CON(10),
186 CRU_DMAC1_RST);
187 udelay(5);
188 mmio_write_32(CRU_BASE + CRU_SOFTRST_CON(10),
189 CRU_DMAC1_RST_RLS);
190 }
191}
192
193/* pll suspend */
194struct deepsleep_data_s slp_data;
195
Caesar Wang813a89a2016-11-04 21:13:01 +0800196void secure_watchdog_disable(void)
197{
198 slp_data.sgrf_con[3] = mmio_read_32(SGRF_BASE + SGRF_SOC_CON3_7(3));
199
200 /* disable CA53 wdt pclk */
201 mmio_write_32(SGRF_BASE + SGRF_SOC_CON3_7(3),
202 BITS_WITH_WMASK(WDT_CA53_DIS, WDT_CA53_1BIT_MASK,
203 PCLK_WDT_CA53_GATE_SHIFT));
204 /* disable CM0 wdt pclk */
205 mmio_write_32(SGRF_BASE + SGRF_SOC_CON3_7(3),
206 BITS_WITH_WMASK(WDT_CM0_DIS, WDT_CM0_1BIT_MASK,
207 PCLK_WDT_CM0_GATE_SHIFT));
208}
209
210void secure_watchdog_restore(void)
211{
212 mmio_write_32(SGRF_BASE + SGRF_SOC_CON3_7(3),
213 slp_data.sgrf_con[3] |
214 WMSK_BIT(PCLK_WDT_CA53_GATE_SHIFT) |
215 WMSK_BIT(PCLK_WDT_CM0_GATE_SHIFT));
216}
217
Tony Xief6118cc2016-01-15 17:17:32 +0800218static void set_pll_slow_mode(uint32_t pll_id)
219{
220 if (pll_id == PPLL_ID)
221 mmio_write_32(PMUCRU_BASE + PMUCRU_PPLL_CON(3), PLL_SLOW_MODE);
222 else
223 mmio_write_32((CRU_BASE +
224 CRU_PLL_CON(pll_id, 3)), PLL_SLOW_MODE);
225}
226
227static void set_pll_normal_mode(uint32_t pll_id)
228{
229 if (pll_id == PPLL_ID)
230 mmio_write_32(PMUCRU_BASE + PMUCRU_PPLL_CON(3), PLL_NOMAL_MODE);
231 else
232 mmio_write_32(CRU_BASE +
233 CRU_PLL_CON(pll_id, 3), PLL_NOMAL_MODE);
234}
235
236static void set_pll_bypass(uint32_t pll_id)
237{
238 if (pll_id == PPLL_ID)
239 mmio_write_32(PMUCRU_BASE +
240 PMUCRU_PPLL_CON(3), PLL_BYPASS_MODE);
241 else
242 mmio_write_32(CRU_BASE +
243 CRU_PLL_CON(pll_id, 3), PLL_BYPASS_MODE);
244}
245
246static void _pll_suspend(uint32_t pll_id)
247{
248 set_pll_slow_mode(pll_id);
249 set_pll_bypass(pll_id);
250}
251
Caesar Wang5339d182016-10-27 01:13:34 +0800252/**
253 * disable_dvfs_plls - To suspend the specific PLLs
254 *
255 * When we close the center logic, the DPLL will be closed,
256 * so we need to keep the ABPLL and switch to it to supply
257 * clock for DDR during suspend, then we should not close
258 * the ABPLL and exclude ABPLL_ID.
259 */
Caesar Wanged6b9a52016-08-11 02:11:45 +0800260void disable_dvfs_plls(void)
261{
262 _pll_suspend(CPLL_ID);
263 _pll_suspend(NPLL_ID);
264 _pll_suspend(VPLL_ID);
265 _pll_suspend(GPLL_ID);
Caesar Wanged6b9a52016-08-11 02:11:45 +0800266 _pll_suspend(ALPLL_ID);
267}
268
Caesar Wang5339d182016-10-27 01:13:34 +0800269/**
270 * disable_nodvfs_plls - To suspend the PPLL
271 */
Caesar Wanged6b9a52016-08-11 02:11:45 +0800272void disable_nodvfs_plls(void)
273{
274 _pll_suspend(PPLL_ID);
275}
276
Caesar Wang5339d182016-10-27 01:13:34 +0800277/**
278 * restore_pll - Copy PLL settings from memory to a PLL.
279 *
280 * This will copy PLL settings from an array in memory to the memory mapped
281 * registers for a PLL.
282 *
283 * Note that: above the PLL exclude PPLL.
284 *
285 * pll_id: One of the values from enum plls_id
286 * src: Pointer to the array of values to restore from
287 */
288static void restore_pll(int pll_id, uint32_t *src)
289{
290 /* Nice to have PLL off while configuring */
291 mmio_write_32((CRU_BASE + CRU_PLL_CON(pll_id, 3)), PLL_SLOW_MODE);
292
293 mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 0), src[0] | REG_SOC_WMSK);
294 mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 1), src[1] | REG_SOC_WMSK);
295 mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 2), src[2]);
296 mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 4), src[4] | REG_SOC_WMSK);
297 mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 5), src[5] | REG_SOC_WMSK);
298
299 /* Do PLL_CON3 since that will enable things */
300 mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 3), src[3] | REG_SOC_WMSK);
301
302 /* Wait for PLL lock done */
303 while ((mmio_read_32(CRU_BASE + CRU_PLL_CON(pll_id, 2)) &
304 0x80000000) == 0x0)
305 ;
306}
307
308/**
309 * save_pll - Copy PLL settings a PLL to memory
310 *
311 * This will copy PLL settings from the memory mapped registers for a PLL to
312 * an array in memory.
313 *
314 * Note that: above the PLL exclude PPLL.
315 *
316 * pll_id: One of the values from enum plls_id
317 * src: Pointer to the array of values to save to.
318 */
319static void save_pll(uint32_t *dst, int pll_id)
320{
321 int i;
322
323 for (i = 0; i < PLL_CON_COUNT; i++)
324 dst[i] = mmio_read_32(CRU_BASE + CRU_PLL_CON(pll_id, i));
325}
326
327/**
328 * prepare_abpll_for_ddrctrl - Copy DPLL settings to ABPLL
329 *
330 * This will copy DPLL settings from the memory mapped registers for a PLL to
331 * an array in memory.
332 */
333void prepare_abpll_for_ddrctrl(void)
334{
335 save_pll(slp_data.plls_con[ABPLL_ID], ABPLL_ID);
336 save_pll(slp_data.plls_con[DPLL_ID], DPLL_ID);
337
338 restore_pll(ABPLL_ID, slp_data.plls_con[DPLL_ID]);
339}
340
341void restore_abpll(void)
342{
343 restore_pll(ABPLL_ID, slp_data.plls_con[ABPLL_ID]);
344}
345
346void restore_dpll(void)
347{
348 restore_pll(DPLL_ID, slp_data.plls_con[DPLL_ID]);
349}
350
Tony Xie42e113e2016-07-16 11:16:51 +0800351void clk_gate_con_save(void)
352{
353 uint32_t i = 0;
354
355 for (i = 0; i < PMUCRU_GATE_COUNT; i++)
356 slp_data.pmucru_gate_con[i] =
357 mmio_read_32(PMUCRU_BASE + PMUCRU_GATE_CON(i));
358
359 for (i = 0; i < CRU_GATE_COUNT; i++)
360 slp_data.cru_gate_con[i] =
361 mmio_read_32(CRU_BASE + CRU_GATE_CON(i));
362}
363
364void clk_gate_con_disable(void)
365{
366 uint32_t i;
367
368 for (i = 0; i < PMUCRU_GATE_COUNT; i++)
369 mmio_write_32(PMUCRU_BASE + PMUCRU_GATE_CON(i), REG_SOC_WMSK);
370
371 for (i = 0; i < CRU_GATE_COUNT; i++)
372 mmio_write_32(CRU_BASE + CRU_GATE_CON(i), REG_SOC_WMSK);
373}
374
375void clk_gate_con_restore(void)
376{
377 uint32_t i;
378
379 for (i = 0; i < PMUCRU_GATE_COUNT; i++)
380 mmio_write_32(PMUCRU_BASE + PMUCRU_GATE_CON(i),
381 REG_SOC_WMSK | slp_data.pmucru_gate_con[i]);
382
383 for (i = 0; i < CRU_GATE_COUNT; i++)
384 mmio_write_32(CRU_BASE + CRU_GATE_CON(i),
385 REG_SOC_WMSK | slp_data.cru_gate_con[i]);
386}
387
Tony Xief6118cc2016-01-15 17:17:32 +0800388static void set_plls_nobypass(uint32_t pll_id)
389{
390 if (pll_id == PPLL_ID)
391 mmio_write_32(PMUCRU_BASE + PMUCRU_PPLL_CON(3),
392 PLL_NO_BYPASS_MODE);
393 else
394 mmio_write_32(CRU_BASE + CRU_PLL_CON(pll_id, 3),
395 PLL_NO_BYPASS_MODE);
396}
397
Caesar Wanged6b9a52016-08-11 02:11:45 +0800398static void _pll_resume(uint32_t pll_id)
399{
400 set_plls_nobypass(pll_id);
401 set_pll_normal_mode(pll_id);
402}
403
Caesar Wang5339d182016-10-27 01:13:34 +0800404/**
405 * enable_dvfs_plls - To resume the specific PLLs
406 *
407 * Please see the comment at the disable_dvfs_plls()
408 * we don't suspend the ABPLL, so don't need resume
409 * it too.
410 */
Caesar Wanged6b9a52016-08-11 02:11:45 +0800411void enable_dvfs_plls(void)
Tony Xief6118cc2016-01-15 17:17:32 +0800412{
Caesar Wanged6b9a52016-08-11 02:11:45 +0800413 _pll_resume(ALPLL_ID);
Caesar Wanged6b9a52016-08-11 02:11:45 +0800414 _pll_resume(GPLL_ID);
415 _pll_resume(VPLL_ID);
416 _pll_resume(NPLL_ID);
417 _pll_resume(CPLL_ID);
418}
Tony Xief6118cc2016-01-15 17:17:32 +0800419
Caesar Wang5339d182016-10-27 01:13:34 +0800420/**
421 * enable_nodvfs_plls - To resume the PPLL
422 */
Caesar Wanged6b9a52016-08-11 02:11:45 +0800423void enable_nodvfs_plls(void)
424{
425 _pll_resume(PPLL_ID);
Tony Xief6118cc2016-01-15 17:17:32 +0800426}
427
428void soc_global_soft_reset_init(void)
429{
430 mmio_write_32(PMUCRU_BASE + CRU_PMU_RSTHOLD_CON(1),
431 CRU_PMU_SGRF_RST_RLS);
Caesar Wang59e41b52016-04-10 14:11:07 +0800432
433 mmio_clrbits_32(CRU_BASE + CRU_GLB_RST_CON,
434 CRU_PMU_WDTRST_MSK | CRU_PMU_FIRST_SFTRST_MSK);
Tony Xief6118cc2016-01-15 17:17:32 +0800435}
436
437void __dead2 soc_global_soft_reset(void)
438{
Tony Xief6118cc2016-01-15 17:17:32 +0800439 set_pll_slow_mode(VPLL_ID);
440 set_pll_slow_mode(NPLL_ID);
441 set_pll_slow_mode(GPLL_ID);
442 set_pll_slow_mode(CPLL_ID);
443 set_pll_slow_mode(PPLL_ID);
444 set_pll_slow_mode(ABPLL_ID);
445 set_pll_slow_mode(ALPLL_ID);
Caesar Wang59e41b52016-04-10 14:11:07 +0800446
447 dsb();
448
Tony Xief6118cc2016-01-15 17:17:32 +0800449 mmio_write_32(CRU_BASE + CRU_GLB_SRST_FST, GLB_SRST_FST_CFG_VAL);
450
451 /*
452 * Maybe the HW needs some times to reset the system,
453 * so we do not hope the core to excute valid codes.
454 */
455 while (1)
Tony Xie42e113e2016-07-16 11:16:51 +0800456 ;
Tony Xief6118cc2016-01-15 17:17:32 +0800457}
458
Caesar Wangbb228622016-10-12 01:47:51 +0800459static void soc_m0_init(void)
460{
461 /* secure config for pmu M0 */
462 mmio_write_32(SGRF_BASE + SGRF_PMU_CON(0), WMSK_BIT(7));
463
464 /* set the execute address for M0 */
465 mmio_write_32(SGRF_BASE + SGRF_PMU_CON(3),
466 BITS_WITH_WMASK((M0_BINCODE_BASE >> 12) & 0xffff,
467 0xffff, 0));
468 mmio_write_32(SGRF_BASE + SGRF_PMU_CON(7),
469 BITS_WITH_WMASK((M0_BINCODE_BASE >> 28) & 0xf,
470 0xf, 0));
471}
472
Tony Xief6118cc2016-01-15 17:17:32 +0800473void plat_rockchip_soc_init(void)
474{
475 secure_timer_init();
476 dma_secure_cfg(0);
477 sgrf_init();
478 soc_global_soft_reset_init();
Caesar Wang038f6aa2016-05-25 19:21:43 +0800479 plat_rockchip_gpio_init();
Caesar Wangbb228622016-10-12 01:47:51 +0800480 soc_m0_init();
Caesar Wanga8456902016-10-27 01:12:34 +0800481 dram_init();
Derek Basehoreff461d02016-10-20 20:46:43 -0700482 dram_dfs_init();
Tony Xief6118cc2016-01-15 17:17:32 +0800483}