a674a028e9a74ea66d0fd0ef3d2b18175cde5047
[sitara-epos/sitara-epos-kernel.git] / arch / arm / mach-omap2 / sleep33xx.S
1 /*
2  * Low level suspend code for AM33XX SoCs
3  *
4  * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com/
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License as
8  * published by the Free Software Foundation version 2.
9  *
10  * This program is distributed "as is" WITHOUT ANY WARRANTY of any
11  * kind, whether express or implied; without even the implied warranty
12  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  */
16 #include <linux/linkage.h>
17 #include <linux/init.h>
18 #include <asm/memory.h>
19 #include <asm/assembler.h>
20 #include <mach/io.h>
21 #include <plat/emif.h>
22 #include "cm33xx.h"
24 #include <plat/emif.h>
25 #include <plat/sram.h>
27 #include "cm33xx.h"
28 #include "pm33xx.h"
29 #include "control.h"
31 /* We should probably pass in the virtual address of PRCM, Control and EMIF
32  * along with the physical addresses
33  * load it into the registers and then continue
34  */
35         .align 3
36 ENTRY(am33xx_do_wfi)
37         stmfd   sp!, {r4 - r11, lr}     @ save registers on stack
39         .macro  pll_bypass, name, clk_mode_addr, idlest_addr
40 pll_bypass_\name:
41         ldr     r0, \clk_mode_addr
42         ldr     r1, [r0]
43         bic     r1, r1, #(7 << 0)
44         orr     r1, r1, #0x5
45         str     r1, [r0]
46         ldr     r0, \idlest_addr
47 wait_pll_bypass_\name:
48         ldr     r1, [r0]
49         tst     r1, #0x0
50         bne     wait_pll_bypass_\name
51         .endm
53         .macro  pll_lock, name, clk_mode_addr, idlest_addr
54 pll_lock_\name:
55         ldr     r0, \clk_mode_addr
56         ldr     r1, [r0]
57         bic     r1, r1, #(7 << 0)
58         orr     r1, r1, #0x7
59         str     r1, [r0]
60         ldr     r0, \idlest_addr
61 wait_pll_lock_\name:
62         ldr     r1, [r0]
63         tst     r1, #0x1
64         bne     wait_pll_lock_\name
65         .endm
67         /* Put DDR in Self-Refresh */
68         ldr     r0, emif_addr_func
69         blx     r0
70         add     r1, r0, #EMIF4_0_SDRAM_MGMT_CTRL
71         ldr     r2, [r1]
72         orr     r2, r2, #0xa0           @ a reasonable delay for entering SR
73         str     r2, [r1, #0]
75         ldr     r2, ddr_start           @ do a dummy access to DDR
76         ldr     r3, [r2, #0]
77         ldr     r3, [r1, #0]
78         orr     r3, r3, #0x200
79         str     r3, [r1, #0]
81         mov     r1, #0x1000             @ Give some time for the system to enter SR
82 wait_sr:
83         subs    r1, r1, #1
84         bne     wait_sr
86         /* IO to work in mDDR mode */
87         ldr     r0, virt_ddr_io_ctrl
88         ldr     r1, [r0]
89         mov     r2, #1
90         mov     r3, r2, lsl #28
91         str     r3, [r0]
93         /* Put the PLLs in bypass mode */
94         pll_bypass      core, virt_core_clk_mode, virt_core_idlest
95         pll_bypass      ddr, virt_ddr_clk_mode, virt_ddr_idlest
96         pll_bypass      disp, virt_disp_clk_mode, virt_disp_idlest
97         pll_bypass      per, virt_per_clk_mode, virt_per_idlest
98         pll_bypass      mpu, virt_mpu_clk_mode, virt_mpu_idlest
100         dsb
101         dmb
102         isb
104         wfi
105         nop
106         nop
107         nop
108         nop
109         nop
110         nop
111         nop
112         nop
113         nop
114         nop
115         nop
117         /* We come here in case of an abort */
118         /* Revert the PHY and PLL related changes */
120         /* Relock the PLLs */
121         pll_lock        mpu_abt, virt_mpu_clk_mode, virt_mpu_idlest
122         pll_lock        per_abt, virt_per_clk_mode, virt_per_idlest
123         pll_lock        disp_abt, virt_disp_clk_mode, virt_disp_idlest
124         pll_lock        ddr_abt, virt_ddr_clk_mode, virt_ddr_idlest
125         pll_lock        core_abt, virt_core_clk_mode, virt_core_idlest
127         /* IO to work in mDDR mode */
128         ldr     r0, virt_ddr_io_ctrl
129         ldr     r1, [r0]
130         mov     r3, r2, lsl #28
131         str     r3, [r0]
133         mov     r0, #7
134         ldmfd   sp!, {r4 - r11, pc}     @ restore regs and return
136         nop
137         nop
138         nop
139         nop
140         nop
141         nop
142         nop
143         nop
144         nop
145         nop
146         nop
147         nop
148         nop
150         /* Take the PLLs out of LP_BYPASS */
151         pll_lock        mpu, phys_mpu_clk_mode, phys_mpu_idlest
152         pll_lock        per, phys_per_clk_mode, phys_per_idlest
153         pll_lock        disp, phys_disp_clk_mode, phys_disp_idlest
154         pll_lock        ddr, phys_ddr_clk_mode, phys_ddr_idlest
155         pll_lock        core, phys_core_clk_mode, phys_core_idlest
157         /* Disable EMIF self-refresh */
158         ldr     r0, emif_phys_addr
159         add     r0, r0, #EMIF4_0_SDRAM_MGMT_CTRL
160         ldr     r1, [r0]
161         bic     r1, r1, #(0x7 << 7)
162         str     r1, [r0]
164         /* Take out IO of mDDR mode */
165         ldr     r0, phys_ddr_io_ctrl
166         ldr     r1, [r0]
167         bic     r1, r1, #28
168         str     r1, [r0]
170 /*
171  * Instead of harcoding the EMIF and DDR PHY related settings
172  * in this file, the sane thing to do would have been to backup
173  * the register contents during suspend and restore it back in
174  * the resume path. However, due to the Si errata related to
175  * DDR PHY registers, these registers are read-only. So, we'll
176  * need to hardcode atleast the DDR PHY configuration over here.
177  * We _could_ back up the EMIF registers but in order to be
178  * consistent with the DDR setup procedure we skip this for now.
179  * The person updating the DDR PHY config values is expected
180  * to update the EMIF config values also.
181  */
183 config_vtp:
184         ldr     r0, vtp0_addr
185         ldr     r1, [r0]
186         ldr     r2, vtp_enable
187         orr     r1, r2
188         str     r1, [r0]
190         ldr     r1, [r0]
191         bic     r1, #1
192         str     r1, [r0]
194         ldr     r1, [r0]
195         orr     r1, #1
196         str     r1, [r0]
198 poll_vtp_ready:
199         ldr     r1, [r0]
200         tst     r1, #(1 << 5)
201         beq     poll_vtp_ready
203 cmd_macro_config:
204         ldr     r0, ddr_phy_base
205         ldr     r1, [r0]
206         ldr     r2, ddr2_ratio_val
207         mov     r3, r2
208         @ TODO: Need to use proper variable here
209         mov     r4, #0
210         str     r3, [r0, #28]   @cmd0
211         str     r4, [r0, #32]
212         str     r4, [r0, #36]
213         str     r4, [r0, #40]
214         str     r4, [r0, #44]
215         str     r3, [r0, #80]   @cmd1
216         str     r4, [r0, #84]
217         str     r4, [r0, #88]
218         str     r4, [r0, #92]
219         str     r4, [r0, #96]
220         str     r3, [r0, #132]  @cmd2
221         str     r4, [r0, #136]
222         str     r4, [r0, #140]
223         str     r4, [r0, #144]
224         str     r4, [r0, #148]
226         mov     r3, #0x0
227         bl      data_macro_config
228         mov     r3, #0xa4
229         bl      data_macro_config
230         b       setup_rank_delays
232 data_macro_config:
233         ldr     r0, ddr_phy_base
234         add     r0, r0, r3
235 rd_dqs:
236         ldr     r1, data0_rd_dqs_slave_ratio0_val
237         mov     r2, r1
238         /* shift by 30, 20, 10 and orr */
239         mov     r5, r2, lsl #10
240         mov     r6, r2, lsl #20
241         mov     r7, r2, lsl #30
242         orr     r2, r2, r5
243         orr     r2, r2, r6
244         orr     r2, r2, r7
245         /* Done with crazy bit ops. store it now */
246         str     r2, [r0, #200]
247         ldr     r1, data0_rd_dqs_slave_ratio1_val
248         mov     r2, r1
249         mov     r5, r2, lsr #2
250         mov     r2, r5
251         str     r2, [r0, #204]
252 wr_dqs:
253         ldr     r1, data0_wr_dqs_slave_ratio0_val
254         mov     r2, r1
255         /* shift by 30, 20, 10 and orr */
256         mov     r5, r2, lsl #10
257         mov     r6, r2, lsl #20
258         mov     r7, r2, lsl #30
259         orr     r2, r2, r5
260         orr     r2, r2, r6
261         orr     r2, r2, r7
262         /* Done with crazy bit ops. store it now */
263         str     r2, [r0, #220]
264         ldr     r1, data0_wr_dqs_slave_ratio1_val
265         mov     r2, r1
266         mov     r5, r2, lsr #2
267         mov     r2, r5
268         str     r2, [r0, #224]
269 wr_lvl:
270         ldr     r1, data0_wr_lvl_init_ratio0_val
271         mov     r2, r1
272         /* shift by 30, 20, 10 and orr */
273         mov     r5, r2, lsl #10
274         mov     r6, r2, lsl #20
275         mov     r7, r2, lsl #30
276         orr     r2, r2, r5
277         orr     r2, r2, r6
278         orr     r2, r2, r7
279         /* Done with crazy bit ops. store it now */
280         str     r2, [r0, #240]
281         ldr     r1, data0_wr_lvl_init_ratio1_val
282         mov     r2, r1
283         mov     r5, r2, lsr #2
284         mov     r2, r5
285         str     r2, [r0, #244]
286 gate_lvl:
287         ldr     r1, data0_gate_lvl_init_ratio0_val
288         mov     r2, r1
289         /* shift by 30, 20, 10 and orr */
290         mov     r5, r2, lsl #10
291         mov     r6, r2, lsl #20
292         mov     r7, r2, lsl #30
293         orr     r2, r2, r5
294         orr     r2, r2, r6
295         orr     r2, r2, r7
296         /* Done with crazy bit ops. store it now */
297         str     r2, [r0, #248]
298         ldr     r1, data0_gate_lvl_init_ratio1_val
299         mov     r2, r1
300         mov     r5, r2, lsr #2
301         mov     r2, r5
302         str     r2, [r0, #256]
303 we_slv:
304         ldr     r1, data0_wr_lvl_slave_ratio0_val
305         mov     r2, r1
306         /* shift by 30, 20, 10 and orr */
307         mov     r5, r2, lsl #10
308         mov     r6, r2, lsl #20
309         mov     r7, r2, lsl #30
310         orr     r2, r2, r5
311         orr     r2, r2, r6
312         orr     r2, r2, r7
313         /* Done with crazy bit ops. store it now */
314         str     r2, [r0, #264]
315         ldr     r1, data0_wr_lvl_slave_ratio1_val
316         mov     r2, r1
317         mov     r5, r2, lsr #2
318         mov     r2, r5
319         str     r2, [r0, #268]
320 wr_data:
321         ldr     r1, data0_wr_data_slave_ratio0_val
322         mov     r2, r1
323         /* shift by 30, 20, 10 and orr */
324         mov     r5, r2, lsl #10
325         mov     r6, r2, lsl #20
326         mov     r7, r2, lsl #30
327         orr     r2, r2, r5
328         orr     r2, r2, r6
329         orr     r2, r2, r7
330         /* Done with crazy bit ops. store it now */
331         str     r2, [r0, #288]
332         ldr     r1, data0_wr_data_slave_ratio1_val
333         mov     r2, r1
334         mov     r5, r2, lsr #2
335         mov     r2, r5
336         str     r2, [r0, #292]
337 dll_lock:
338         ldr     r1, data0_dll_lock_diff_val
339         mov     r2, r1
340         str     r2, [r0, #312]
342 setup_rank_delays:
343         ldr     r1, data0_rank0_delay0_val
344         mov     r2, r1
345         str     r2, [r0, #308]
346         ldr     r1, data1_rank0_delay1_val
347         mov     r2, r1
348         str     r2, [r0, #472]
350 setup_io_ctrl:
351         ldr     r0, control_base
352         ldr     r1, ddr_ioctrl_val
353         mov     r2, r1
354         ldr     r4, ddr_cmd_offset
355         mov     r3, r4
356         str     r2, [r0, r3]    @cmd0 0x1404
357         add     r3, r3, #4
358         str     r2, [r0, r3]    @cmd1 0x1408
359         add     r3, r3, #4
360         str     r2, [r0, r3]    @cmd2 0x140c
361         ldr     r4, ddr_data_offset
362         mov     r3, r4
363         str     r2, [r0, r3]    @data0 0x1440
364         add     r3, r3, #4
365         str     r2, [r0, r3]    @data1 0x1444
367 misc_config:
368         ldr     r1, ddr_io_ctrl_addr
369         ldr     r2, [r1]
370         and     r2, #0xefffffff
371         str     r2, [r1]
372         ldr     r1, ddr_cke_addr
373         ldr     r2, [r1]
374         orr     r2, #0x00000001
375         str     r2, [r1]
377 config_emif_timings:
378         mov     r3, #1275068416 @ 0x4c000000
379 disable_sr:
380         mov     r4, #0
381         str     r4, [r3, #56]   @ 0x38
382         ldr     r4, emif_rd_lat_val
383         mov     r2, r4
384 rd_lat:
385         str     r2, [r3, #228]  @ 0xe4
386         str     r2, [r3, #232]  @ 0xe8
387         str     r2, [r3, #236]  @ 0xec
388 timing1:
389         ldr     r4, emif_timing1_val
390         mov     r2, r4
391         str     r2, [r3, #24]
392         str     r2, [r3, #28]
393 timing2:
394         ldr     r4, emif_timing2_val
395         mov     r2, r4
396         str     r2, [r3, #32]
397         str     r2, [r3, #36]   @ 0x24
398 timing3:
399         ldr     r4, emif_timing3_val
400         mov     r2, r4
401         str     r2, [r3, #40]   @ 0x28
402         str     r2, [r3, #44]   @ 0x2c
403 sdcfg1:
404         ldr     r4, emif_sdcfg_val
405         mov     r2, r4
406         str     r2, [r3, #8]
407         str     r2, [r3, #12]
408 ref_ctrl_const:
409         ldr     r4, emif_ref_ctrl_const_val
410         mov     r2, r4
411         str     r2, [r3, #16]
412         str     r2, [r3, #20]
414         /* GEL had a loop with init value of 5000 */
415         mov     r0, #0x1000
416 wait_loop1:
417         subs    r0, r0, #1
418         bne     wait_loop1
420 ref_ctrl_actual:
421         ldr     r4, emif_ref_ctrl_val
422         mov     r2, r4
423         str     r2, [r3, #16]
424         str     r2, [r3, #20]
425 sdcfg2:
426         ldr     r4, emif_sdcfg_val
427         mov     r2, r4
428         str     r2, [r3, #8]
429         str     r2, [r3, #12]
431         /* Back from la-la-land. Kill some time for sanity to settle in */
432         mov     r0, #0x1000
433 wait_loop2:
434         subs    r0, r0, #1
435         bne     wait_loop2
437         /* We are back. Branch to the common CPU resume routine */
438 ENTRY(am33xx_resume_vector)
439         ldr     pc, resume_addr
441 /*
442  * Local variables
443  */
445 resume_addr:
446         .word   cpu_resume - PAGE_OFFSET + 0x80000000
448 emif_addr_func:
449         .word   am33xx_get_ram_base
450 emif_phys_addr:
451         .word   AM33XX_EMIF0_BASE
453 emif_pm_ctrl:
454         .word EMIF4_0_SDRAM_MGMT_CTRL
455 ddr_start:
456         .word PAGE_OFFSET
458 virt_mpu_idlest:
459         .word   AM33XX_CM_IDLEST_DPLL_MPU
460 virt_mpu_clk_mode:
461         .word   AM33XX_CM_CLKMODE_DPLL_MPU
463 phys_pll_mod:
464         .word   AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD
465 phys_mpu_clk_mode:
466         .word   AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + AM33XX_CM_CLKMODE_DPLL_MPU_OFFSET
467 phys_mpu_idlest:
468         .word   AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + AM33XX_CM_IDLEST_DPLL_MPU_OFFSET
470 virt_core_idlest:
471         .word   AM33XX_CM_IDLEST_DPLL_CORE
472 virt_core_clk_mode:
473         .word   AM33XX_CM_CLKMODE_DPLL_CORE
474 phys_core_clk_mode:
475         .word   AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + AM33XX_CM_CLKMODE_DPLL_CORE_OFFSET
476 phys_core_idlest:
477         .word   AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + AM33XX_CM_IDLEST_DPLL_CORE_OFFSET
479 virt_per_idlest:
480         .word   AM33XX_CM_IDLEST_DPLL_PER
481 virt_per_clk_mode:
482         .word   AM33XX_CM_CLKMODE_DPLL_PER
483 phys_per_clk_mode:
484         .word   AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + AM33XX_CM_CLKMODE_DPLL_PER_OFFSET
485 phys_per_idlest:
486         .word   AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + AM33XX_CM_IDLEST_DPLL_PER_OFFSET
488 virt_disp_idlest:
489         .word   AM33XX_CM_IDLEST_DPLL_DISP
490 virt_disp_clk_mode:
491         .word   AM33XX_CM_CLKMODE_DPLL_DISP
492 phys_disp_clk_mode:
493         .word   AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + AM33XX_CM_CLKMODE_DPLL_DISP_OFFSET
494 phys_disp_idlest:
495         .word   AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + AM33XX_CM_IDLEST_DPLL_DISP_OFFSET
497 virt_ddr_idlest:
498         .word   AM33XX_CM_IDLEST_DPLL_DDR
499 virt_ddr_clk_mode:
500         .word   AM33XX_CM_CLKMODE_DPLL_DDR
501 phys_ddr_clk_mode:
502         .word   AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + AM33XX_CM_CLKMODE_DPLL_DDR_OFFSET
503 phys_ddr_idlest:
504         .word   AM33XX_CM_BASE + AM33XX_CM_WKUP_MOD + AM33XX_CM_IDLEST_DPLL_DDR_OFFSET
507 /* DDR related stuff */
508 vtp0_addr:
509         .word   VTP0_CTRL_REG
510 vtp_enable:
511         .word   VTP_CTRL_ENABLE
512 vtp_start_en:
513         .word   VTP_CTRL_START_EN
514 vtp_ready:
515         .word   VTP_CTRL_READY
517 ddr_phy_base:
518         .word   DDR_PHY_BASE_ADDR
519 ddr2_ratio_val:
520         .word   DDR2_RATIO
521 data0_rd_dqs_slave_ratio0_val:
522         .word   DDR2_RD_DQS
523 data0_rd_dqs_slave_ratio1_val:
524         .word   DDR2_RD_DQS
525 data0_wr_dqs_slave_ratio0_val:
526         .word   DDR2_WR_DQS
527 data0_wr_dqs_slave_ratio1_val:
528         .word   DDR2_WR_DQS
529 data0_wr_lvl_init_ratio0_val:
530         .word   DDR2_PHY_WRLVL
531 data0_wr_lvl_init_ratio1_val:
532         .word   DDR2_PHY_WRLVL
533 data0_gate_lvl_init_ratio0_val:
534         .word   DDR2_PHY_GATELVL
535 data0_gate_lvl_init_ratio1_val:
536         .word   DDR2_PHY_GATELVL
537 data0_wr_lvl_slave_ratio0_val:
538         .word   DDR2_PHY_FIFO_WE
539 data0_wr_lvl_slave_ratio1_val:
540         .word   DDR2_PHY_FIFO_WE
541 data0_wr_data_slave_ratio0_val:
542         .word   DDR2_PHY_WR_DATA
543 data0_wr_data_slave_ratio1_val:
544         .word   DDR2_PHY_WR_DATA
545 data0_dll_lock_diff_val:
546         .word   PHY_DLL_LOCK_DIFF
548 data0_rank0_delay0_val:
549         .word   PHY_RANK0_DELAY
550 data1_rank0_delay1_val:
551         .word   PHY_RANK0_DELAY
553 control_base:
554         .word   AM33XX_CTRL_BASE
555 ddr_io_ctrl_addr:
556         .word   DDR_IO_CTRL
557 ddr_ioctrl_val:
558         .word   0x18B
559 ddr_cmd_offset:
560         .word   0x1404
561 ddr_data_offset:
562         .word   0x1440
563 virt_ddr_io_ctrl:
564         .word   AM33XX_CTRL_REGADDR(0x0E04)
565 phys_ddr_io_ctrl:
566         .word   DDR_IO_CTRL
568 ddr_cke_addr:
569         .word   DDR_CKE_CTRL
570 emif_rd_lat_val:
571         .word   EMIF_READ_LATENCY
572 emif_timing1_val:
573         .word   EMIF_TIM1
574 emif_timing2_val:
575         .word   EMIF_TIM2
576 emif_timing3_val:
577         .word   EMIF_TIM3
578 emif_sdcfg_val:
579         .word   EMIF_SDCFG
580 emif_ref_ctrl_const_val:
581         .word   0x4650
582 emif_ref_ctrl_val:
583         .word   EMIF_SDREF
585 ENTRY(am33xx_do_wfi_sz)
586         .word   . - am33xx_do_wfi