1*4ccf4beaSWolfram Sang /* 2*4ccf4beaSWolfram Sang * Copyright (C) 1999 ARM Limited 3*4ccf4beaSWolfram Sang * Copyright (C) 2000 Deep Blue Solutions Ltd 4*4ccf4beaSWolfram Sang * Copyright 2006-2007,2010 Freescale Semiconductor, Inc. All Rights Reserved. 5*4ccf4beaSWolfram Sang * Copyright 2008 Juergen Beisert, kernel@pengutronix.de 6*4ccf4beaSWolfram Sang * Copyright 2009 Ilya Yanok, Emcraft Systems Ltd, yanok@emcraft.com 7*4ccf4beaSWolfram Sang * Copyright (C) 2011 Wolfram Sang, Pengutronix e.K. 8*4ccf4beaSWolfram Sang * 9*4ccf4beaSWolfram Sang * This program is free software; you can redistribute it and/or modify 10*4ccf4beaSWolfram Sang * it under the terms of the GNU General Public License as published by 11*4ccf4beaSWolfram Sang * the Free Software Foundation; either version 2 of the License, or 12*4ccf4beaSWolfram Sang * (at your option) any later version. 13*4ccf4beaSWolfram Sang */ 14*4ccf4beaSWolfram Sang 15*4ccf4beaSWolfram Sang #include <linux/io.h> 16*4ccf4beaSWolfram Sang #include <linux/errno.h> 17*4ccf4beaSWolfram Sang #include <linux/delay.h> 18*4ccf4beaSWolfram Sang #include <linux/module.h> 19*4ccf4beaSWolfram Sang #include <linux/stmp_device.h> 20*4ccf4beaSWolfram Sang 21*4ccf4beaSWolfram Sang #define STMP_MODULE_CLKGATE (1 << 30) 22*4ccf4beaSWolfram Sang #define STMP_MODULE_SFTRST (1 << 31) 23*4ccf4beaSWolfram Sang 24*4ccf4beaSWolfram Sang /* 25*4ccf4beaSWolfram Sang * Clear the bit and poll it cleared. This is usually called with 26*4ccf4beaSWolfram Sang * a reset address and mask being either SFTRST(bit 31) or CLKGATE 27*4ccf4beaSWolfram Sang * (bit 30). 28*4ccf4beaSWolfram Sang */ 29*4ccf4beaSWolfram Sang static int stmp_clear_poll_bit(void __iomem *addr, u32 mask) 30*4ccf4beaSWolfram Sang { 31*4ccf4beaSWolfram Sang int timeout = 0x400; 32*4ccf4beaSWolfram Sang 33*4ccf4beaSWolfram Sang writel(mask, addr + STMP_OFFSET_REG_CLR); 34*4ccf4beaSWolfram Sang udelay(1); 35*4ccf4beaSWolfram Sang while ((readl(addr) & mask) && --timeout) 36*4ccf4beaSWolfram Sang /* nothing */; 37*4ccf4beaSWolfram Sang 38*4ccf4beaSWolfram Sang return !timeout; 39*4ccf4beaSWolfram Sang } 40*4ccf4beaSWolfram Sang 41*4ccf4beaSWolfram Sang int stmp_reset_block(void __iomem *reset_addr) 42*4ccf4beaSWolfram Sang { 43*4ccf4beaSWolfram Sang int ret; 44*4ccf4beaSWolfram Sang int timeout = 0x400; 45*4ccf4beaSWolfram Sang 46*4ccf4beaSWolfram Sang /* clear and poll SFTRST */ 47*4ccf4beaSWolfram Sang ret = stmp_clear_poll_bit(reset_addr, STMP_MODULE_SFTRST); 48*4ccf4beaSWolfram Sang if (unlikely(ret)) 49*4ccf4beaSWolfram Sang goto error; 50*4ccf4beaSWolfram Sang 51*4ccf4beaSWolfram Sang /* clear CLKGATE */ 52*4ccf4beaSWolfram Sang writel(STMP_MODULE_CLKGATE, reset_addr + STMP_OFFSET_REG_CLR); 53*4ccf4beaSWolfram Sang 54*4ccf4beaSWolfram Sang /* set SFTRST to reset the block */ 55*4ccf4beaSWolfram Sang writel(STMP_MODULE_SFTRST, reset_addr + STMP_OFFSET_REG_SET); 56*4ccf4beaSWolfram Sang udelay(1); 57*4ccf4beaSWolfram Sang 58*4ccf4beaSWolfram Sang /* poll CLKGATE becoming set */ 59*4ccf4beaSWolfram Sang while ((!(readl(reset_addr) & STMP_MODULE_CLKGATE)) && --timeout) 60*4ccf4beaSWolfram Sang /* nothing */; 61*4ccf4beaSWolfram Sang if (unlikely(!timeout)) 62*4ccf4beaSWolfram Sang goto error; 63*4ccf4beaSWolfram Sang 64*4ccf4beaSWolfram Sang /* clear and poll SFTRST */ 65*4ccf4beaSWolfram Sang ret = stmp_clear_poll_bit(reset_addr, STMP_MODULE_SFTRST); 66*4ccf4beaSWolfram Sang if (unlikely(ret)) 67*4ccf4beaSWolfram Sang goto error; 68*4ccf4beaSWolfram Sang 69*4ccf4beaSWolfram Sang /* clear and poll CLKGATE */ 70*4ccf4beaSWolfram Sang ret = stmp_clear_poll_bit(reset_addr, STMP_MODULE_CLKGATE); 71*4ccf4beaSWolfram Sang if (unlikely(ret)) 72*4ccf4beaSWolfram Sang goto error; 73*4ccf4beaSWolfram Sang 74*4ccf4beaSWolfram Sang return 0; 75*4ccf4beaSWolfram Sang 76*4ccf4beaSWolfram Sang error: 77*4ccf4beaSWolfram Sang pr_err("%s(%p): module reset timeout\n", __func__, reset_addr); 78*4ccf4beaSWolfram Sang return -ETIMEDOUT; 79*4ccf4beaSWolfram Sang } 80*4ccf4beaSWolfram Sang EXPORT_SYMBOL(stmp_reset_block); 81