183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
2552a848eSStefano Babic /*
3552a848eSStefano Babic * Copyright (C) 2015 Freescale Semiconductor, Inc.
4552a848eSStefano Babic */
5552a848eSStefano Babic
6552a848eSStefano Babic #include <common.h>
7552a848eSStefano Babic #include <asm/io.h>
8552a848eSStefano Babic #include <asm/arch/imx-regs.h>
9552a848eSStefano Babic #include <asm/arch/clock.h>
10552a848eSStefano Babic #include <asm/arch/sys_proto.h>
11552a848eSStefano Babic #include <asm/mach-imx/dma.h>
12552a848eSStefano Babic #include <asm/mach-imx/hab.h>
13552a848eSStefano Babic #include <asm/mach-imx/rdc-sema.h>
14552a848eSStefano Babic #include <asm/arch/imx-rdc.h>
15552a848eSStefano Babic #include <asm/arch/crm_regs.h>
16552a848eSStefano Babic #include <dm.h>
17552a848eSStefano Babic #include <imx_thermal.h>
18d1ceb0c4SBryan O'Donoghue #include <fsl_sec.h>
19ca831822SBryan O'Donoghue #include <asm/setup.h>
20552a848eSStefano Babic
21b0598378SAnson Huang #define IOMUXC_GPR1 0x4
22b0598378SAnson Huang #define BM_IOMUXC_GPR1_IRQ 0x1000
23b0598378SAnson Huang
24b0598378SAnson Huang #define GPC_LPCR_A7_BSC 0x0
25b0598378SAnson Huang #define GPC_LPCR_M4 0x8
26b0598378SAnson Huang #define GPC_SLPCR 0x14
27b0598378SAnson Huang #define GPC_PGC_ACK_SEL_A7 0x24
28b0598378SAnson Huang #define GPC_IMR1_CORE0 0x30
29b0598378SAnson Huang #define GPC_IMR1_CORE1 0x40
30b0598378SAnson Huang #define GPC_IMR1_M4 0x50
31b0598378SAnson Huang #define GPC_PGC_CPU_MAPPING 0xec
32b0598378SAnson Huang #define GPC_PGC_C0_PUPSCR 0x804
33b0598378SAnson Huang #define GPC_PGC_SCU_TIMING 0x890
34b0598378SAnson Huang #define GPC_PGC_C1_PUPSCR 0x844
35b0598378SAnson Huang
36b0598378SAnson Huang #define BM_LPCR_A7_BSC_IRQ_SRC_A7_WAKEUP 0x70000000
37b0598378SAnson Huang #define BM_LPCR_A7_BSC_CPU_CLK_ON_LPM 0x4000
38b0598378SAnson Huang #define BM_LPCR_M4_MASK_DSM_TRIGGER 0x80000000
39b0598378SAnson Huang #define BM_SLPCR_EN_DSM 0x80000000
40b0598378SAnson Huang #define BM_SLPCR_RBC_EN 0x40000000
41b0598378SAnson Huang #define BM_SLPCR_REG_BYPASS_COUNT 0x3f000000
42b0598378SAnson Huang #define BM_SLPCR_VSTBY 0x4
43b0598378SAnson Huang #define BM_SLPCR_SBYOS 0x2
44b0598378SAnson Huang #define BM_SLPCR_BYPASS_PMIC_READY 0x1
45b0598378SAnson Huang #define BM_SLPCR_EN_A7_FASTWUP_WAIT_MODE 0x10000
46b0598378SAnson Huang
47b0598378SAnson Huang #define BM_GPC_PGC_ACK_SEL_A7_DUMMY_PUP_ACK 0x80000000
48b0598378SAnson Huang #define BM_GPC_PGC_ACK_SEL_A7_DUMMY_PDN_ACK 0x8000
49b0598378SAnson Huang
50b0598378SAnson Huang #define BM_GPC_PGC_CORE_PUPSCR 0x7fff80
51b0598378SAnson Huang
52552a848eSStefano Babic #if defined(CONFIG_IMX_THERMAL)
53552a848eSStefano Babic static const struct imx_thermal_plat imx7_thermal_plat = {
54552a848eSStefano Babic .regs = (void *)ANATOP_BASE_ADDR,
55552a848eSStefano Babic .fuse_bank = 3,
56552a848eSStefano Babic .fuse_word = 3,
57552a848eSStefano Babic };
58552a848eSStefano Babic
59552a848eSStefano Babic U_BOOT_DEVICE(imx7_thermal) = {
60552a848eSStefano Babic .name = "imx_thermal",
61552a848eSStefano Babic .platdata = &imx7_thermal_plat,
62552a848eSStefano Babic };
63552a848eSStefano Babic #endif
64552a848eSStefano Babic
65e872f27aSPeng Fan #if CONFIG_IS_ENABLED(IMX_RDC)
66552a848eSStefano Babic /*
67552a848eSStefano Babic * In current design, if any peripheral was assigned to both A7 and M4,
68552a848eSStefano Babic * it will receive ipg_stop or ipg_wait when any of the 2 platforms enter
69552a848eSStefano Babic * low power mode. So M4 sleep will cause some peripherals fail to work
70552a848eSStefano Babic * at A7 core side. At default, all resources are in domain 0 - 3.
71552a848eSStefano Babic *
72552a848eSStefano Babic * There are 26 peripherals impacted by this IC issue:
73552a848eSStefano Babic * SIM2(sim2/emvsim2)
74552a848eSStefano Babic * SIM1(sim1/emvsim1)
75552a848eSStefano Babic * UART1/UART2/UART3/UART4/UART5/UART6/UART7
76552a848eSStefano Babic * SAI1/SAI2/SAI3
77552a848eSStefano Babic * WDOG1/WDOG2/WDOG3/WDOG4
78552a848eSStefano Babic * GPT1/GPT2/GPT3/GPT4
79552a848eSStefano Babic * PWM1/PWM2/PWM3/PWM4
80552a848eSStefano Babic * ENET1/ENET2
81552a848eSStefano Babic * Software Workaround:
82552a848eSStefano Babic * Here we setup some resources to domain 0 where M4 codes will move
83552a848eSStefano Babic * the M4 out of this domain. Then M4 is not able to access them any longer.
84552a848eSStefano Babic * This is a workaround for ic issue. So the peripherals are not shared
85552a848eSStefano Babic * by them. This way requires the uboot implemented the RDC driver and
86552a848eSStefano Babic * set the 26 IPs above to domain 0 only. M4 code will assign resource
87552a848eSStefano Babic * to its own domain, if it want to use the resource.
88552a848eSStefano Babic */
89552a848eSStefano Babic static rdc_peri_cfg_t const resources[] = {
90552a848eSStefano Babic (RDC_PER_SIM1 | RDC_DOMAIN(0)),
91552a848eSStefano Babic (RDC_PER_SIM2 | RDC_DOMAIN(0)),
92552a848eSStefano Babic (RDC_PER_UART1 | RDC_DOMAIN(0)),
93552a848eSStefano Babic (RDC_PER_UART2 | RDC_DOMAIN(0)),
94552a848eSStefano Babic (RDC_PER_UART3 | RDC_DOMAIN(0)),
95552a848eSStefano Babic (RDC_PER_UART4 | RDC_DOMAIN(0)),
96552a848eSStefano Babic (RDC_PER_UART5 | RDC_DOMAIN(0)),
97552a848eSStefano Babic (RDC_PER_UART6 | RDC_DOMAIN(0)),
98552a848eSStefano Babic (RDC_PER_UART7 | RDC_DOMAIN(0)),
99552a848eSStefano Babic (RDC_PER_SAI1 | RDC_DOMAIN(0)),
100552a848eSStefano Babic (RDC_PER_SAI2 | RDC_DOMAIN(0)),
101552a848eSStefano Babic (RDC_PER_SAI3 | RDC_DOMAIN(0)),
102552a848eSStefano Babic (RDC_PER_WDOG1 | RDC_DOMAIN(0)),
103552a848eSStefano Babic (RDC_PER_WDOG2 | RDC_DOMAIN(0)),
104552a848eSStefano Babic (RDC_PER_WDOG3 | RDC_DOMAIN(0)),
105552a848eSStefano Babic (RDC_PER_WDOG4 | RDC_DOMAIN(0)),
106552a848eSStefano Babic (RDC_PER_GPT1 | RDC_DOMAIN(0)),
107552a848eSStefano Babic (RDC_PER_GPT2 | RDC_DOMAIN(0)),
108552a848eSStefano Babic (RDC_PER_GPT3 | RDC_DOMAIN(0)),
109552a848eSStefano Babic (RDC_PER_GPT4 | RDC_DOMAIN(0)),
110552a848eSStefano Babic (RDC_PER_PWM1 | RDC_DOMAIN(0)),
111552a848eSStefano Babic (RDC_PER_PWM2 | RDC_DOMAIN(0)),
112552a848eSStefano Babic (RDC_PER_PWM3 | RDC_DOMAIN(0)),
113552a848eSStefano Babic (RDC_PER_PWM4 | RDC_DOMAIN(0)),
114552a848eSStefano Babic (RDC_PER_ENET1 | RDC_DOMAIN(0)),
115552a848eSStefano Babic (RDC_PER_ENET2 | RDC_DOMAIN(0)),
116552a848eSStefano Babic };
117552a848eSStefano Babic
isolate_resource(void)118552a848eSStefano Babic static void isolate_resource(void)
119552a848eSStefano Babic {
120552a848eSStefano Babic imx_rdc_setup_peripherals(resources, ARRAY_SIZE(resources));
121552a848eSStefano Babic }
122552a848eSStefano Babic #endif
123552a848eSStefano Babic
124552a848eSStefano Babic #if defined(CONFIG_SECURE_BOOT)
125552a848eSStefano Babic struct imx_sec_config_fuse_t const imx_sec_config_fuse = {
126552a848eSStefano Babic .bank = 1,
127552a848eSStefano Babic .word = 3,
128552a848eSStefano Babic };
129552a848eSStefano Babic #endif
130552a848eSStefano Babic
is_mx7d(void)131552a848eSStefano Babic static bool is_mx7d(void)
132552a848eSStefano Babic {
133552a848eSStefano Babic struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
134552a848eSStefano Babic struct fuse_bank *bank = &ocotp->bank[1];
135552a848eSStefano Babic struct fuse_bank1_regs *fuse =
136552a848eSStefano Babic (struct fuse_bank1_regs *)bank->fuse_regs;
137552a848eSStefano Babic int val;
138552a848eSStefano Babic
139552a848eSStefano Babic val = readl(&fuse->tester4);
140552a848eSStefano Babic if (val & 1)
141552a848eSStefano Babic return false;
142552a848eSStefano Babic else
143552a848eSStefano Babic return true;
144552a848eSStefano Babic }
145552a848eSStefano Babic
get_cpu_rev(void)146552a848eSStefano Babic u32 get_cpu_rev(void)
147552a848eSStefano Babic {
148552a848eSStefano Babic struct mxc_ccm_anatop_reg *ccm_anatop = (struct mxc_ccm_anatop_reg *)
149552a848eSStefano Babic ANATOP_BASE_ADDR;
150552a848eSStefano Babic u32 reg = readl(&ccm_anatop->digprog);
151552a848eSStefano Babic u32 type = (reg >> 16) & 0xff;
152552a848eSStefano Babic
153552a848eSStefano Babic if (!is_mx7d())
154552a848eSStefano Babic type = MXC_CPU_MX7S;
155552a848eSStefano Babic
156552a848eSStefano Babic reg &= 0xff;
157552a848eSStefano Babic return (type << 12) | reg;
158552a848eSStefano Babic }
159552a848eSStefano Babic
160552a848eSStefano Babic #ifdef CONFIG_REVISION_TAG
get_board_rev(void)161552a848eSStefano Babic u32 __weak get_board_rev(void)
162552a848eSStefano Babic {
163552a848eSStefano Babic return get_cpu_rev();
164552a848eSStefano Babic }
165552a848eSStefano Babic #endif
166552a848eSStefano Babic
167be277c3aSRui Miguel Silva #ifndef CONFIG_SKIP_LOWLEVEL_INIT
168552a848eSStefano Babic /* enable all periherial can be accessed in nosec mode */
init_csu(void)169552a848eSStefano Babic static void init_csu(void)
170552a848eSStefano Babic {
171552a848eSStefano Babic int i = 0;
172552a848eSStefano Babic for (i = 0; i < CSU_NUM_REGS; i++)
173552a848eSStefano Babic writel(CSU_INIT_SEC_LEVEL0, CSU_IPS_BASE_ADDR + i * 4);
174552a848eSStefano Babic }
175552a848eSStefano Babic
imx_enet_mdio_fixup(void)176552a848eSStefano Babic static void imx_enet_mdio_fixup(void)
177552a848eSStefano Babic {
178552a848eSStefano Babic struct iomuxc_gpr_base_regs *gpr_regs =
179552a848eSStefano Babic (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR;
180552a848eSStefano Babic
181552a848eSStefano Babic /*
182552a848eSStefano Babic * The management data input/output (MDIO) requires open-drain,
183552a848eSStefano Babic * i.MX7D TO1.0 ENET MDIO pin has no open drain, but TO1.1 supports
184552a848eSStefano Babic * this feature. So to TO1.1, need to enable open drain by setting
185552a848eSStefano Babic * bits GPR0[8:7].
186552a848eSStefano Babic */
187552a848eSStefano Babic
188552a848eSStefano Babic if (soc_rev() >= CHIP_REV_1_1) {
189552a848eSStefano Babic setbits_le32(&gpr_regs->gpr[0],
190552a848eSStefano Babic IOMUXC_GPR_GPR0_ENET_MDIO_OPEN_DRAIN_MASK);
191552a848eSStefano Babic }
192552a848eSStefano Babic }
193552a848eSStefano Babic
imx_gpcv2_init(void)194b0598378SAnson Huang static void imx_gpcv2_init(void)
195b0598378SAnson Huang {
196b0598378SAnson Huang u32 val, i;
197b0598378SAnson Huang
198b0598378SAnson Huang /*
199b0598378SAnson Huang * Force IOMUXC irq pending, so that the interrupt to GPC can be
200b0598378SAnson Huang * used to deassert dsm_request signal when the signal gets
201b0598378SAnson Huang * asserted unexpectedly.
202b0598378SAnson Huang */
203b0598378SAnson Huang val = readl(IOMUXC_GPR_BASE_ADDR + IOMUXC_GPR1);
204b0598378SAnson Huang val |= BM_IOMUXC_GPR1_IRQ;
205b0598378SAnson Huang writel(val, IOMUXC_GPR_BASE_ADDR + IOMUXC_GPR1);
206b0598378SAnson Huang
207b0598378SAnson Huang /* Initially mask all interrupts */
208b0598378SAnson Huang for (i = 0; i < 4; i++) {
209b0598378SAnson Huang writel(~0, GPC_IPS_BASE_ADDR + GPC_IMR1_CORE0 + i * 4);
210b0598378SAnson Huang writel(~0, GPC_IPS_BASE_ADDR + GPC_IMR1_CORE1 + i * 4);
211b0598378SAnson Huang writel(~0, GPC_IPS_BASE_ADDR + GPC_IMR1_M4 + i * 4);
212b0598378SAnson Huang }
213b0598378SAnson Huang
214b0598378SAnson Huang /* set SCU timing */
215b0598378SAnson Huang writel((0x59 << 10) | 0x5B | (0x2 << 20),
216b0598378SAnson Huang GPC_IPS_BASE_ADDR + GPC_PGC_SCU_TIMING);
217b0598378SAnson Huang
218b0598378SAnson Huang /* only external IRQs to wake up LPM and core 0/1 */
219b0598378SAnson Huang val = readl(GPC_IPS_BASE_ADDR + GPC_LPCR_A7_BSC);
220b0598378SAnson Huang val |= BM_LPCR_A7_BSC_IRQ_SRC_A7_WAKEUP;
221b0598378SAnson Huang writel(val, GPC_IPS_BASE_ADDR + GPC_LPCR_A7_BSC);
222b0598378SAnson Huang
223b0598378SAnson Huang /* set C0 power up timming per design requirement */
224b0598378SAnson Huang val = readl(GPC_IPS_BASE_ADDR + GPC_PGC_C0_PUPSCR);
225b0598378SAnson Huang val &= ~BM_GPC_PGC_CORE_PUPSCR;
226b0598378SAnson Huang val |= (0x1A << 7);
227b0598378SAnson Huang writel(val, GPC_IPS_BASE_ADDR + GPC_PGC_C0_PUPSCR);
228b0598378SAnson Huang
229b0598378SAnson Huang /* set C1 power up timming per design requirement */
230b0598378SAnson Huang val = readl(GPC_IPS_BASE_ADDR + GPC_PGC_C1_PUPSCR);
231b0598378SAnson Huang val &= ~BM_GPC_PGC_CORE_PUPSCR;
232b0598378SAnson Huang val |= (0x1A << 7);
233b0598378SAnson Huang writel(val, GPC_IPS_BASE_ADDR + GPC_PGC_C1_PUPSCR);
234b0598378SAnson Huang
235b0598378SAnson Huang /* dummy ack for time slot by default */
236b0598378SAnson Huang writel(BM_GPC_PGC_ACK_SEL_A7_DUMMY_PUP_ACK |
237b0598378SAnson Huang BM_GPC_PGC_ACK_SEL_A7_DUMMY_PDN_ACK,
238b0598378SAnson Huang GPC_IPS_BASE_ADDR + GPC_PGC_ACK_SEL_A7);
239b0598378SAnson Huang
240b0598378SAnson Huang /* mask M4 DSM trigger */
241b0598378SAnson Huang writel(readl(GPC_IPS_BASE_ADDR + GPC_LPCR_M4) |
242b0598378SAnson Huang BM_LPCR_M4_MASK_DSM_TRIGGER,
243b0598378SAnson Huang GPC_IPS_BASE_ADDR + GPC_LPCR_M4);
244b0598378SAnson Huang
245b0598378SAnson Huang /* set mega/fast mix in A7 domain */
246b0598378SAnson Huang writel(0x1, GPC_IPS_BASE_ADDR + GPC_PGC_CPU_MAPPING);
247b0598378SAnson Huang
248b0598378SAnson Huang /* DSM related settings */
249b0598378SAnson Huang val = readl(GPC_IPS_BASE_ADDR + GPC_SLPCR);
250b0598378SAnson Huang val &= ~(BM_SLPCR_EN_DSM | BM_SLPCR_VSTBY | BM_SLPCR_RBC_EN |
251b0598378SAnson Huang BM_SLPCR_SBYOS | BM_SLPCR_BYPASS_PMIC_READY |
252b0598378SAnson Huang BM_SLPCR_REG_BYPASS_COUNT);
253b0598378SAnson Huang val |= BM_SLPCR_EN_A7_FASTWUP_WAIT_MODE;
254b0598378SAnson Huang writel(val, GPC_IPS_BASE_ADDR + GPC_SLPCR);
255b0598378SAnson Huang
256b0598378SAnson Huang /*
257b0598378SAnson Huang * disabling RBC need to delay at least 2 cycles of CKIL(32K)
258b0598378SAnson Huang * due to hardware design requirement, which is
259b0598378SAnson Huang * ~61us, here we use 65us for safe
260b0598378SAnson Huang */
261b0598378SAnson Huang udelay(65);
262b0598378SAnson Huang }
263b0598378SAnson Huang
arch_cpu_init(void)264552a848eSStefano Babic int arch_cpu_init(void)
265552a848eSStefano Babic {
266552a848eSStefano Babic init_aips();
267552a848eSStefano Babic
268552a848eSStefano Babic init_csu();
269552a848eSStefano Babic /* Disable PDE bit of WMCR register */
270e2162d70SFabio Estevam imx_wdog_disable_powerdown();
271552a848eSStefano Babic
272552a848eSStefano Babic imx_enet_mdio_fixup();
273552a848eSStefano Babic
274552a848eSStefano Babic #ifdef CONFIG_APBH_DMA
275552a848eSStefano Babic /* Start APBH DMA */
276552a848eSStefano Babic mxs_dma_init();
277552a848eSStefano Babic #endif
278552a848eSStefano Babic
279e872f27aSPeng Fan #if CONFIG_IS_ENABLED(IMX_RDC)
280552a848eSStefano Babic isolate_resource();
281e872f27aSPeng Fan #endif
282552a848eSStefano Babic
283723f8359SBryan O'Donoghue init_snvs();
284723f8359SBryan O'Donoghue
285b0598378SAnson Huang imx_gpcv2_init();
286b0598378SAnson Huang
287552a848eSStefano Babic return 0;
288552a848eSStefano Babic }
289be277c3aSRui Miguel Silva #endif
290552a848eSStefano Babic
291552a848eSStefano Babic #ifdef CONFIG_ARCH_MISC_INIT
arch_misc_init(void)292552a848eSStefano Babic int arch_misc_init(void)
293552a848eSStefano Babic {
294552a848eSStefano Babic #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
295552a848eSStefano Babic if (is_mx7d())
296382bee57SSimon Glass env_set("soc", "imx7d");
297552a848eSStefano Babic else
298382bee57SSimon Glass env_set("soc", "imx7s");
299552a848eSStefano Babic #endif
300552a848eSStefano Babic
301d1ceb0c4SBryan O'Donoghue #ifdef CONFIG_FSL_CAAM
302d1ceb0c4SBryan O'Donoghue sec_init();
303d1ceb0c4SBryan O'Donoghue #endif
304d1ceb0c4SBryan O'Donoghue
305552a848eSStefano Babic return 0;
306552a848eSStefano Babic }
307552a848eSStefano Babic #endif
308552a848eSStefano Babic
309552a848eSStefano Babic #ifdef CONFIG_SERIAL_TAG
3101ab1ffdeSBryan O'Donoghue /*
3111ab1ffdeSBryan O'Donoghue * OCOTP_TESTER
3121ab1ffdeSBryan O'Donoghue * i.MX 7Solo Applications Processor Reference Manual, Rev. 0.1, 08/2016
3131ab1ffdeSBryan O'Donoghue * OCOTP_TESTER describes a unique ID based on silicon wafer
3141ab1ffdeSBryan O'Donoghue * and die X/Y position
3151ab1ffdeSBryan O'Donoghue *
3161ab1ffdeSBryan O'Donoghue * OCOTOP_TESTER offset 0x410
3171ab1ffdeSBryan O'Donoghue * 31:0 fuse 0
3181ab1ffdeSBryan O'Donoghue * FSL-wide unique, encoded LOT ID STD II/SJC CHALLENGE/ Unique ID
3191ab1ffdeSBryan O'Donoghue *
3201ab1ffdeSBryan O'Donoghue * OCOTP_TESTER1 offset 0x420
3211ab1ffdeSBryan O'Donoghue * 31:24 fuse 1
3221ab1ffdeSBryan O'Donoghue * The X-coordinate of the die location on the wafer/SJC CHALLENGE/ Unique ID
3231ab1ffdeSBryan O'Donoghue * 23:16 fuse 1
3241ab1ffdeSBryan O'Donoghue * The Y-coordinate of the die location on the wafer/SJC CHALLENGE/ Unique ID
3251ab1ffdeSBryan O'Donoghue * 15:11 fuse 1
3261ab1ffdeSBryan O'Donoghue * The wafer number of the wafer on which the device was fabricated/SJC
3271ab1ffdeSBryan O'Donoghue * CHALLENGE/ Unique ID
3281ab1ffdeSBryan O'Donoghue * 10:0 fuse 1
3291ab1ffdeSBryan O'Donoghue * FSL-wide unique, encoded LOT ID STD II/SJC CHALLENGE/ Unique ID
3301ab1ffdeSBryan O'Donoghue */
get_board_serial(struct tag_serialnr * serialnr)331552a848eSStefano Babic void get_board_serial(struct tag_serialnr *serialnr)
332552a848eSStefano Babic {
333552a848eSStefano Babic struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
334552a848eSStefano Babic struct fuse_bank *bank = &ocotp->bank[0];
335552a848eSStefano Babic struct fuse_bank0_regs *fuse =
336552a848eSStefano Babic (struct fuse_bank0_regs *)bank->fuse_regs;
337552a848eSStefano Babic
338552a848eSStefano Babic serialnr->low = fuse->tester0;
339552a848eSStefano Babic serialnr->high = fuse->tester1;
340552a848eSStefano Babic }
341552a848eSStefano Babic #endif
342552a848eSStefano Babic
set_wdog_reset(struct wdog_regs * wdog)343552a848eSStefano Babic void set_wdog_reset(struct wdog_regs *wdog)
344552a848eSStefano Babic {
345552a848eSStefano Babic u32 reg = readw(&wdog->wcr);
346552a848eSStefano Babic /*
347552a848eSStefano Babic * Output WDOG_B signal to reset external pmic or POR_B decided by
348552a848eSStefano Babic * the board desgin. Without external reset, the peripherals/DDR/
349552a848eSStefano Babic * PMIC are not reset, that may cause system working abnormal.
350552a848eSStefano Babic */
351552a848eSStefano Babic reg = readw(&wdog->wcr);
352552a848eSStefano Babic reg |= 1 << 3;
353552a848eSStefano Babic /*
354552a848eSStefano Babic * WDZST bit is write-once only bit. Align this bit in kernel,
355552a848eSStefano Babic * otherwise kernel code will have no chance to set this bit.
356552a848eSStefano Babic */
357552a848eSStefano Babic reg |= 1 << 0;
358552a848eSStefano Babic writew(reg, &wdog->wcr);
359552a848eSStefano Babic }
360552a848eSStefano Babic
s_init(void)361552a848eSStefano Babic void s_init(void)
362552a848eSStefano Babic {
363552a848eSStefano Babic /* clock configuration. */
364552a848eSStefano Babic clock_init();
365552a848eSStefano Babic
366552a848eSStefano Babic return;
367552a848eSStefano Babic }
368552a848eSStefano Babic
reset_misc(void)369552a848eSStefano Babic void reset_misc(void)
370552a848eSStefano Babic {
371*bab289cbSFabio Estevam #ifndef CONFIG_SPL_BUILD
372552a848eSStefano Babic #ifdef CONFIG_VIDEO_MXS
373552a848eSStefano Babic lcdif_power_down();
374552a848eSStefano Babic #endif
375*bab289cbSFabio Estevam #endif
376552a848eSStefano Babic }
377552a848eSStefano Babic
378