staging/ion: sync ion.h with include/linux/ion.h
[profile/mobile/platform/kernel/linux-3.10-sc7730.git] / drivers / watchdog / sprd_wdt_sys.h
1
2 /*
3  * Copyright (C) 2012 Spreadtrum Communications Inc.
4  *
5  * This software is licensed under the terms of the GNU General Public
6  * License version 2, as published by the Free Software Foundation, and
7  * may be copied, distributed, and modified under those terms.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  */
14
15 #ifndef _SPRD_WDT_SYS_H_
16 #define _SPRD_WDT_SYS_H_
17 #include <linux/spinlock.h>
18 #include <linux/bitops.h>
19 #include <soc/sprd/adi.h>
20 #include <soc/sprd/sci_glb_regs.h>
21 #include <soc/sprd/sci.h>
22 #include <soc/sprd/hardware.h>
23
24 unsigned long ap_wdt_addr;
25 unsigned long a7_wdt_addr;
26
27 #define AP_WDG_LOAD_LOW                 (ap_wdt_addr + 0x00)
28 #define AP_WDG_LOAD_HIGH                (ap_wdt_addr + 0x04)
29 #define AP_WDG_CTRL                             (ap_wdt_addr + 0x08)
30 #define AP_WDG_INT_CLR                  (ap_wdt_addr + 0x0C)
31 #define AP_WDG_INT_RAW                  (ap_wdt_addr + 0x10)
32 #define AP_WDG_INT_MSK                  (ap_wdt_addr + 0x14)
33 #define AP_WDG_CNT_LOW                  (ap_wdt_addr + 0x18)
34 #define AP_WDG_CNT_HIGH                 (ap_wdt_addr + 0x1C)
35 #define AP_WDG_LOCK                             (ap_wdt_addr + 0x20)
36
37 #define CA7_WDG_LOAD_LOW                (a7_wdt_addr + 0x00)
38 #define CA7_WDG_LOAD_HIGH               (a7_wdt_addr + 0x04)
39 #define CA7_WDG_CTRL                    (a7_wdt_addr + 0x08)
40 #define CA7_WDG_INT_CLR                 (a7_wdt_addr + 0x0C)
41 #define CA7_WDG_INT_RAW                 (a7_wdt_addr + 0x10)
42 #define CA7_WDG_INT_MSK                 (a7_wdt_addr + 0x14)
43 #define CA7_WDG_CNT_LOW                 (a7_wdt_addr + 0x18)
44 #define CA7_WDG_CNT_HIGH                (a7_wdt_addr + 0x1C)
45 #define CA7_WDG_LOCK                    (a7_wdt_addr + 0x20)
46 #define CA7_WDG_IRQ_LOAD_LOW    (a7_wdt_addr + 0x2c)
47 #define CA7_WDG_IRQ_LOAD_HIGH   (a7_wdt_addr + 0x30)
48
49 #define AP_WDG_LOAD_TIMER_VALUE(value) \
50         do { \
51                 uint32_t   cnt =  0;\
52                 sci_glb_write( AP_WDG_LOAD_HIGH, (uint16_t)(((value) >> 16 ) & 0xffff), -1UL); \
53                 sci_glb_write( AP_WDG_LOAD_LOW , (uint16_t)((value)  & 0xffff), -1UL ); \
54                 while((sci_glb_read(AP_WDG_INT_RAW, -1UL) & WDG_LD_BUSY_BIT) && ( cnt < ANA_WDG_LOAD_TIMEOUT_NUM )) cnt++; \
55         } while (0)
56
57 #define CA7_WDG_LOAD_TIMER_VALUE(margin, irq) \
58         do { \
59                 uint32_t   cnt          =  0; \
60                 sci_glb_write( CA7_WDG_LOAD_HIGH, (uint16_t)(((margin) >> 16 ) & 0xffff), -1UL); \
61                 sci_glb_write( CA7_WDG_LOAD_LOW , (uint16_t)((margin)  & 0xffff), -1UL ); \
62                 sci_glb_write( CA7_WDG_IRQ_LOAD_HIGH, (uint16_t)(((irq) >> 16 ) & 0xffff), -1UL); \
63                 sci_glb_write( CA7_WDG_IRQ_LOAD_LOW , (uint16_t)((irq)  & 0xffff), -1UL ); \
64                 while((sci_glb_read(CA7_WDG_INT_RAW, -1UL) & WDG_LD_BUSY_BIT) && ( cnt < ANA_WDG_LOAD_TIMEOUT_NUM )) cnt++; \
65         } while (0)
66
67
68 #ifdef CONFIG_SC_INTERNAL_WATCHDOG
69 static inline void FEED_ALL_WDG(int chip_margin, int ap_margin,
70                 int ca7_margin, int ca7_irq_margin)
71 {
72         AP_WDG_LOAD_TIMER_VALUE(ap_margin * WDG_CLK);
73         WDG_LOAD_TIMER_VALUE(chip_margin * WDG_CLK);
74         CA7_WDG_LOAD_TIMER_VALUE(ca7_margin * WDG_CLK, (ca7_margin - ca7_irq_margin) * WDG_CLK);
75 }
76 #else
77 static inline void FEED_ALL_WDG(int chip_margin, int ap_margin,
78                 int ca7_margin, int ca7_irq_margin) { }
79 #endif
80
81 #define ENABLE_ALL_WDG() \
82         do { \
83                 sci_adi_set(WDG_CTRL, WDG_CNT_EN_BIT | WDG_RST_EN_BIT); \
84                 sci_glb_set(AP_WDG_CTRL, WDG_CNT_EN_BIT | WDG_RST_EN_BIT); \
85                 sci_glb_set(CA7_WDG_CTRL, WDG_CNT_EN_BIT | WDG_RST_EN_BIT | WDG_INT_EN_BIT); \
86         } while (0)
87
88 #define DISABLE_ALL_WDG() \
89         do { \
90                 sci_adi_clr(WDG_CTRL, WDG_CNT_EN_BIT | WDG_RST_EN_BIT); \
91                 sci_glb_clr(AP_WDG_CTRL, WDG_CNT_EN_BIT | WDG_RST_EN_BIT); \
92                 sci_glb_clr(CA7_WDG_CTRL, WDG_CNT_EN_BIT | WDG_RST_EN_BIT | WDG_INT_EN_BIT); \
93         } while (0)
94
95 #define WATCHDOG_THREAD_USER_BIT                        0
96 #define WATCHDOG_THREAD_KERNEL_BIT                      1
97
98 #define WATCHDOG_FEED_BY_USER_ST_BIT            (0)
99 #define WATCHDOG_FEED_BY_USER_BIT                       (1)
100 #define WATCHDOG_FEED_BY_KERNEL_BIT                     (2)
101 #define WATCHDOG_FEED_ENABLE_BIT                        (30)
102 #define WATCHDOG_FEED_START_BIT                         (31)
103
104 #define WATCHDOG_FEED_BY_KERNEL_THREAD ( \
105                 (1 << WATCHDOG_FEED_BY_USER_BIT) | \
106                 (1 << WATCHDOG_FEED_BY_KERNEL_BIT) \
107                 )
108
109 #define WATCHDOG_FEED_BY_USER_THREAD ( \
110                 (1 << WATCHDOG_FEED_BY_USER_ST_BIT) \
111                 )
112
113 #define WATCHDOG_FEED_BY_THREAD \
114                 (WATCHDOG_FEED_BY_KERNEL_THREAD | WATCHDOG_FEED_BY_USER_THREAD)
115
116 #ifdef CONFIG_SC_INTERNAL_WATCHDOG
117 static inline void watchdog_start(int chip_margin, int ap_margin,
118                                   int ca7_margin, int ca7_irq_margin)
119 {
120         /* start the chip watchdog */
121         sci_adi_set(ANA_AGEN, AGEN_WDG_EN);
122         sci_adi_set(ANA_RTC_CLK_EN, AGEN_RTC_WDG_EN);
123         sci_adi_raw_write(WDG_LOCK, WDG_UNLOCK_KEY);
124         sci_adi_set(WDG_CTRL, WDG_NEW_VER_EN);
125         WDG_LOAD_TIMER_VALUE(chip_margin * WDG_CLK);
126         sci_adi_set(WDG_CTRL, WDG_CNT_EN_BIT | WDG_RST_EN_BIT);
127
128         /* start ap watchdog */
129         sci_glb_set(REG_AON_APB_APB_EB0, BIT_AP_WDG_EB);
130         sci_glb_set(REG_AON_APB_APB_RTC_EB, BIT_AP_WDG_RTC_EB);
131         sci_glb_write(AP_WDG_LOCK, WDG_UNLOCK_KEY, -1UL);
132         sci_glb_set(AP_WDG_CTRL, WDG_NEW_VER_EN);
133         AP_WDG_LOAD_TIMER_VALUE(ap_margin * WDG_CLK);
134         sci_glb_set(AP_WDG_CTRL, WDG_CNT_EN_BIT | WDG_RST_EN_BIT);
135
136         /* start ca7 watchdog */
137         sci_glb_set(REG_AON_APB_APB_EB1, BIT_CA7_WDG_EB);
138         sci_glb_set(REG_AON_APB_APB_RTC_EB, BIT_CA7_WDG_RTC_EB);
139         sci_glb_write(CA7_WDG_LOCK, WDG_UNLOCK_KEY, -1UL);
140         sci_glb_set(CA7_WDG_CTRL, WDG_NEW_VER_EN);
141         CA7_WDG_LOAD_TIMER_VALUE(ca7_margin * WDG_CLK, (ca7_margin - ca7_irq_margin) * WDG_CLK);
142         sci_glb_set(CA7_WDG_CTRL, WDG_CNT_EN_BIT | WDG_RST_EN_BIT | WDG_INT_EN_BIT);
143 }
144
145 #else
146 static inline void watchdog_start(int chip_margin, int ap_margin,
147                 int ca7_margin, int ca7_irq_margin) { }
148 #endif
149 #endif