5cccd37e |
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> |
98f420b2 |
23 | #include <mach/platform.h> |
5cccd37e |
24 | #include <mach/dma.h> |
25 | #include <mach/regs-clkctrl.h> |
26 | |
27 | static int __stmp3xxx_reset_block(void __iomem *hwreg, int just_enable) |
28 | { |
29 | u32 c; |
30 | int timeout; |
31 | |
32 | /* the process of software reset of IP block is done |
33 | in several steps: |
34 | |
35 | - clear SFTRST and wait for block is enabled; |
36 | - clear clock gating (CLKGATE bit); |
37 | - set the SFTRST again and wait for block is in reset; |
38 | - clear SFTRST and wait for reset completion. |
39 | */ |
40 | c = __raw_readl(hwreg); |
41 | c &= ~(1<<31); /* clear SFTRST */ |
42 | __raw_writel(c, hwreg); |
43 | for (timeout = 1000000; timeout > 0; timeout--) |
44 | /* still in SFTRST state ? */ |
45 | if ((__raw_readl(hwreg) & (1<<31)) == 0) |
46 | break; |
47 | if (timeout <= 0) { |
48 | printk(KERN_ERR"%s(%p): timeout when enabling\n", |
49 | __func__, hwreg); |
50 | return -ETIME; |
51 | } |
52 | |
53 | c = __raw_readl(hwreg); |
54 | c &= ~(1<<30); /* clear CLKGATE */ |
55 | __raw_writel(c, hwreg); |
56 | |
57 | if (!just_enable) { |
58 | c = __raw_readl(hwreg); |
59 | c |= (1<<31); /* now again set SFTRST */ |
60 | __raw_writel(c, hwreg); |
61 | for (timeout = 1000000; timeout > 0; timeout--) |
62 | /* poll until CLKGATE set */ |
63 | if (__raw_readl(hwreg) & (1<<30)) |
64 | break; |
65 | if (timeout <= 0) { |
66 | printk(KERN_ERR"%s(%p): timeout when resetting\n", |
67 | __func__, hwreg); |
68 | return -ETIME; |
69 | } |
70 | |
71 | c = __raw_readl(hwreg); |
72 | c &= ~(1<<31); /* clear SFTRST */ |
73 | __raw_writel(c, hwreg); |
74 | for (timeout = 1000000; timeout > 0; timeout--) |
75 | /* still in SFTRST state ? */ |
76 | if ((__raw_readl(hwreg) & (1<<31)) == 0) |
77 | break; |
78 | if (timeout <= 0) { |
79 | printk(KERN_ERR"%s(%p): timeout when enabling " |
80 | "after reset\n", __func__, hwreg); |
81 | return -ETIME; |
82 | } |
83 | |
84 | c = __raw_readl(hwreg); |
85 | c &= ~(1<<30); /* clear CLKGATE */ |
86 | __raw_writel(c, hwreg); |
87 | } |
88 | for (timeout = 1000000; timeout > 0; timeout--) |
89 | /* still in SFTRST state ? */ |
90 | if ((__raw_readl(hwreg) & (1<<30)) == 0) |
91 | break; |
92 | |
93 | if (timeout <= 0) { |
94 | printk(KERN_ERR"%s(%p): timeout when unclockgating\n", |
95 | __func__, hwreg); |
96 | return -ETIME; |
97 | } |
98 | |
99 | return 0; |
100 | } |
101 | |
102 | int stmp3xxx_reset_block(void __iomem *hwreg, int just_enable) |
103 | { |
104 | int try = 10; |
105 | int r; |
106 | |
107 | while (try--) { |
108 | r = __stmp3xxx_reset_block(hwreg, just_enable); |
109 | if (!r) |
110 | break; |
111 | pr_debug("%s: try %d failed\n", __func__, 10 - try); |
112 | } |
113 | return r; |
114 | } |
115 | EXPORT_SYMBOL(stmp3xxx_reset_block); |
116 | |
117 | struct platform_device stmp3xxx_dbguart = { |
118 | .name = "stmp3xxx-dbguart", |
119 | .id = -1, |
120 | }; |
121 | |
122 | void __init stmp3xxx_init(void) |
123 | { |
124 | /* Turn off auto-slow and other tricks */ |
98f420b2 |
125 | stmp3xxx_clearl(0x7f00000, REGS_CLKCTRL_BASE + HW_CLKCTRL_HBUS); |
5cccd37e |
126 | |
127 | stmp3xxx_dma_init(); |
128 | } |