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/platform.h>
24 #include <mach/dma.h>
25 #include <mach/regs-clkctrl.h>
26 
__stmp3xxx_reset_block(void __iomem * hwreg,int just_enable)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 
stmp3xxx_reset_block(void __iomem * hwreg,int just_enable)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 
stmp3xxx_init(void)122 void __init stmp3xxx_init(void)
123 {
124 	/* Turn off auto-slow and other tricks */
125 	stmp3xxx_clearl(0x7f00000, REGS_CLKCTRL_BASE + HW_CLKCTRL_HBUS);
126 
127 	stmp3xxx_dma_init();
128 }
129