Commit | Line | Data |
---|---|---|
bd117bd1 BD |
1 | /* linux/arch/arm/plat-s3c64xx/include/plat/pm-core.h |
2 | * | |
3 | * Copyright 2008 Openmoko, Inc. | |
4 | * Copyright 2008 Simtec Electronics | |
5 | * Ben Dooks <ben@simtec.co.uk> | |
6 | * http://armlinux.simtec.co.uk/ | |
7 | * | |
8 | * S3C64XX - PM core support for arch/arm/plat-s3c/pm.c | |
9 | * | |
10 | * This program is free software; you can redistribute it and/or modify | |
11 | * it under the terms of the GNU General Public License version 2 as | |
12 | * published by the Free Software Foundation. | |
13 | */ | |
14 | ||
3501c9ae | 15 | #include <mach/regs-gpio.h> |
bd117bd1 BD |
16 | |
17 | static inline void s3c_pm_debug_init_uart(void) | |
18 | { | |
19 | u32 tmp = __raw_readl(S3C_PCLK_GATE); | |
20 | ||
21 | /* As a note, since the S3C64XX UARTs generally have multiple | |
22 | * clock sources, we simply enable PCLK at the moment and hope | |
23 | * that the resume settings for the UART are suitable for the | |
24 | * use with PCLK. | |
25 | */ | |
26 | ||
27 | tmp |= S3C_CLKCON_PCLK_UART0; | |
28 | tmp |= S3C_CLKCON_PCLK_UART1; | |
29 | tmp |= S3C_CLKCON_PCLK_UART2; | |
30 | tmp |= S3C_CLKCON_PCLK_UART3; | |
31 | ||
32 | __raw_writel(tmp, S3C_PCLK_GATE); | |
33 | udelay(10); | |
34 | } | |
35 | ||
36 | static inline void s3c_pm_arch_prepare_irqs(void) | |
37 | { | |
38 | /* VIC should have already been taken care of */ | |
39 | ||
40 | /* clear any pending EINT0 interrupts */ | |
41 | __raw_writel(__raw_readl(S3C64XX_EINT0PEND), S3C64XX_EINT0PEND); | |
42 | } | |
43 | ||
44 | static inline void s3c_pm_arch_stop_clocks(void) | |
45 | { | |
46 | } | |
47 | ||
48 | static inline void s3c_pm_arch_show_resume_irqs(void) | |
49 | { | |
50 | } | |
51 | ||
52 | /* make these defines, we currently do not have any need to change | |
53 | * the IRQ wake controls depending on the CPU we are running on */ | |
54 | ||
55 | #define s3c_irqwake_eintallow ((1 << 28) - 1) | |
56 | #define s3c_irqwake_intallow (0) | |
57 | ||
58 | static inline void s3c_pm_arch_update_uart(void __iomem *regs, | |
59 | struct pm_uart_save *save) | |
60 | { | |
61 | u32 ucon = __raw_readl(regs + S3C2410_UCON); | |
62 | u32 ucon_clk = ucon & S3C6400_UCON_CLKMASK; | |
63 | u32 save_clk = save->ucon & S3C6400_UCON_CLKMASK; | |
64 | u32 new_ucon; | |
65 | u32 delta; | |
66 | ||
67 | /* S3C64XX UART blocks only support level interrupts, so ensure that | |
68 | * when we restore unused UART blocks we force the level interrupt | |
69 | * settigs. */ | |
70 | save->ucon |= S3C2410_UCON_TXILEVEL | S3C2410_UCON_RXILEVEL; | |
71 | ||
72 | /* We have a constraint on changing the clock type of the UART | |
73 | * between UCLKx and PCLK, so ensure that when we restore UCON | |
74 | * that the CLK field is correctly modified if the bootloader | |
75 | * has changed anything. | |
76 | */ | |
77 | if (ucon_clk != save_clk) { | |
78 | new_ucon = save->ucon; | |
79 | delta = ucon_clk ^ save_clk; | |
80 | ||
81 | /* change from UCLKx => wrong PCLK, | |
82 | * either UCLK can be tested for by a bit-test | |
83 | * with UCLK0 */ | |
84 | if (ucon_clk & S3C6400_UCON_UCLK0 && | |
85 | !(save_clk & S3C6400_UCON_UCLK0) && | |
86 | delta & S3C6400_UCON_PCLK2) { | |
87 | new_ucon &= ~S3C6400_UCON_UCLK0; | |
88 | } else if (delta == S3C6400_UCON_PCLK2) { | |
89 | /* as an precaution, don't change from | |
90 | * PCLK2 => PCLK or vice-versa */ | |
91 | new_ucon ^= S3C6400_UCON_PCLK2; | |
92 | } | |
93 | ||
94 | S3C_PMDBG("ucon change %04x => %04x (save=%04x)\n", | |
95 | ucon, new_ucon, save->ucon); | |
96 | save->ucon = new_ucon; | |
97 | } | |
98 | } |