129 lines
3.1 KiB
C
129 lines
3.1 KiB
C
/*
|
|
* Freescale STMP37XX/STMP378X core routines
|
|
*
|
|
* Embedded Alley Solutions, Inc <source@embeddedalley.com>
|
|
*
|
|
* Copyright 2008 Freescale Semiconductor, Inc. All Rights Reserved.
|
|
* Copyright 2008 Embedded Alley Solutions, Inc All Rights Reserved.
|
|
*/
|
|
|
|
/*
|
|
* The code contained herein is licensed under the GNU General Public
|
|
* License. You may obtain a copy of the GNU General Public License
|
|
* Version 2 or later at the following locations:
|
|
*
|
|
* http://www.opensource.org/licenses/gpl-license.html
|
|
* http://www.gnu.org/copyleft/gpl.html
|
|
*/
|
|
#include <linux/kernel.h>
|
|
#include <linux/init.h>
|
|
#include <linux/io.h>
|
|
|
|
#include <mach/stmp3xxx.h>
|
|
#include <mach/platform.h>
|
|
#include <mach/dma.h>
|
|
#include <mach/regs-clkctrl.h>
|
|
|
|
static int __stmp3xxx_reset_block(void __iomem *hwreg, int just_enable)
|
|
{
|
|
u32 c;
|
|
int timeout;
|
|
|
|
/* the process of software reset of IP block is done
|
|
in several steps:
|
|
|
|
- clear SFTRST and wait for block is enabled;
|
|
- clear clock gating (CLKGATE bit);
|
|
- set the SFTRST again and wait for block is in reset;
|
|
- clear SFTRST and wait for reset completion.
|
|
*/
|
|
c = __raw_readl(hwreg);
|
|
c &= ~(1<<31); /* clear SFTRST */
|
|
__raw_writel(c, hwreg);
|
|
for (timeout = 1000000; timeout > 0; timeout--)
|
|
/* still in SFTRST state ? */
|
|
if ((__raw_readl(hwreg) & (1<<31)) == 0)
|
|
break;
|
|
if (timeout <= 0) {
|
|
printk(KERN_ERR"%s(%p): timeout when enabling\n",
|
|
__func__, hwreg);
|
|
return -ETIME;
|
|
}
|
|
|
|
c = __raw_readl(hwreg);
|
|
c &= ~(1<<30); /* clear CLKGATE */
|
|
__raw_writel(c, hwreg);
|
|
|
|
if (!just_enable) {
|
|
c = __raw_readl(hwreg);
|
|
c |= (1<<31); /* now again set SFTRST */
|
|
__raw_writel(c, hwreg);
|
|
for (timeout = 1000000; timeout > 0; timeout--)
|
|
/* poll until CLKGATE set */
|
|
if (__raw_readl(hwreg) & (1<<30))
|
|
break;
|
|
if (timeout <= 0) {
|
|
printk(KERN_ERR"%s(%p): timeout when resetting\n",
|
|
__func__, hwreg);
|
|
return -ETIME;
|
|
}
|
|
|
|
c = __raw_readl(hwreg);
|
|
c &= ~(1<<31); /* clear SFTRST */
|
|
__raw_writel(c, hwreg);
|
|
for (timeout = 1000000; timeout > 0; timeout--)
|
|
/* still in SFTRST state ? */
|
|
if ((__raw_readl(hwreg) & (1<<31)) == 0)
|
|
break;
|
|
if (timeout <= 0) {
|
|
printk(KERN_ERR"%s(%p): timeout when enabling "
|
|
"after reset\n", __func__, hwreg);
|
|
return -ETIME;
|
|
}
|
|
|
|
c = __raw_readl(hwreg);
|
|
c &= ~(1<<30); /* clear CLKGATE */
|
|
__raw_writel(c, hwreg);
|
|
}
|
|
for (timeout = 1000000; timeout > 0; timeout--)
|
|
/* still in SFTRST state ? */
|
|
if ((__raw_readl(hwreg) & (1<<30)) == 0)
|
|
break;
|
|
|
|
if (timeout <= 0) {
|
|
printk(KERN_ERR"%s(%p): timeout when unclockgating\n",
|
|
__func__, hwreg);
|
|
return -ETIME;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int stmp3xxx_reset_block(void __iomem *hwreg, int just_enable)
|
|
{
|
|
int try = 10;
|
|
int r;
|
|
|
|
while (try--) {
|
|
r = __stmp3xxx_reset_block(hwreg, just_enable);
|
|
if (!r)
|
|
break;
|
|
pr_debug("%s: try %d failed\n", __func__, 10 - try);
|
|
}
|
|
return r;
|
|
}
|
|
EXPORT_SYMBOL(stmp3xxx_reset_block);
|
|
|
|
struct platform_device stmp3xxx_dbguart = {
|
|
.name = "stmp3xxx-dbguart",
|
|
.id = -1,
|
|
};
|
|
|
|
void __init stmp3xxx_init(void)
|
|
{
|
|
/* Turn off auto-slow and other tricks */
|
|
stmp3xxx_clearl(0x7f00000, REGS_CLKCTRL_BASE + HW_CLKCTRL_HBUS);
|
|
|
|
stmp3xxx_dma_init();
|
|
}
|