[ARM] 5477/1: Freescale STMP platform support [6/10]
[linux-2.6] / arch / arm / plat-stmp3xxx / core.c
1 /*
2  * Freescale STMP37XX/STMP378X core routines
3  *
4  * Embedded Alley Solutions, Inc <source@embeddedalley.com>
5  *
6  * Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
7  * Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
8  */
9
10 /*
11  * The code contained herein is licensed under the GNU General Public
12  * License. You may obtain a copy of the GNU General Public License
13  * Version 2 or later at the following locations:
14  *
15  * http://www.opensource.org/licenses/gpl-license.html
16  * http://www.gnu.org/copyleft/gpl.html
17  */
18 #include <linux/kernel.h>
19 #include <linux/init.h>
20 #include <linux/io.h>
21
22 #include <mach/stmp3xxx.h>
23 #include <mach/dma.h>
24 #include <mach/regs-clkctrl.h>
25
26 static int __stmp3xxx_reset_block(void __iomem *hwreg, int just_enable)
27 {
28         u32 c;
29         int timeout;
30
31         /* the process of software reset of IP block is done
32            in several steps:
33
34            - clear SFTRST and wait for block is enabled;
35            - clear clock gating (CLKGATE bit);
36            - set the SFTRST again and wait for block is in reset;
37            - clear SFTRST and wait for reset completion.
38         */
39         c = __raw_readl(hwreg);
40         c &= ~(1<<31);          /* clear SFTRST */
41         __raw_writel(c, hwreg);
42         for (timeout = 1000000; timeout > 0; timeout--)
43                 /* still in SFTRST state ? */
44                 if ((__raw_readl(hwreg) & (1<<31)) == 0)
45                         break;
46         if (timeout <= 0) {
47                 printk(KERN_ERR"%s(%p): timeout when enabling\n",
48                                 __func__, hwreg);
49                 return -ETIME;
50         }
51
52         c = __raw_readl(hwreg);
53         c &= ~(1<<30);          /* clear CLKGATE */
54         __raw_writel(c, hwreg);
55
56         if (!just_enable) {
57                 c = __raw_readl(hwreg);
58                 c |= (1<<31);           /* now again set SFTRST */
59                 __raw_writel(c, hwreg);
60                 for (timeout = 1000000; timeout > 0; timeout--)
61                         /* poll until CLKGATE set */
62                         if (__raw_readl(hwreg) & (1<<30))
63                                 break;
64                 if (timeout <= 0) {
65                         printk(KERN_ERR"%s(%p): timeout when resetting\n",
66                                         __func__, hwreg);
67                         return -ETIME;
68                 }
69
70                 c = __raw_readl(hwreg);
71                 c &= ~(1<<31);          /* clear SFTRST */
72                 __raw_writel(c, hwreg);
73                 for (timeout = 1000000; timeout > 0; timeout--)
74                         /* still in SFTRST state ? */
75                         if ((__raw_readl(hwreg) & (1<<31)) == 0)
76                                 break;
77                 if (timeout <= 0) {
78                         printk(KERN_ERR"%s(%p): timeout when enabling "
79                                         "after reset\n", __func__, hwreg);
80                         return -ETIME;
81                 }
82
83                 c = __raw_readl(hwreg);
84                 c &= ~(1<<30);          /* clear CLKGATE */
85                 __raw_writel(c, hwreg);
86         }
87         for (timeout = 1000000; timeout > 0; timeout--)
88                 /* still in SFTRST state ? */
89                 if ((__raw_readl(hwreg) & (1<<30)) == 0)
90                         break;
91
92         if (timeout <= 0) {
93                 printk(KERN_ERR"%s(%p): timeout when unclockgating\n",
94                                 __func__, hwreg);
95                 return -ETIME;
96         }
97
98         return 0;
99 }
100
101 int stmp3xxx_reset_block(void __iomem *hwreg, int just_enable)
102 {
103         int try = 10;
104         int r;
105
106         while (try--) {
107                 r = __stmp3xxx_reset_block(hwreg, just_enable);
108                 if (!r)
109                         break;
110                 pr_debug("%s: try %d failed\n", __func__, 10 - try);
111         }
112         return r;
113 }
114 EXPORT_SYMBOL(stmp3xxx_reset_block);
115
116 struct platform_device stmp3xxx_dbguart = {
117         .name = "stmp3xxx-dbguart",
118         .id = -1,
119 };
120
121 void __init stmp3xxx_init(void)
122 {
123         /* Turn off auto-slow and other tricks */
124         HW_CLKCTRL_HBUS_CLR(0x07f00000U);
125
126         stmp3xxx_dma_init();
127 }