Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * OMAP IP block custom reset and preprogramming stubs
0003  *
0004  * Copyright (C) 2012 Texas Instruments, Inc.
0005  * Paul Walmsley
0006  *
0007  * A small number of IP blocks need custom reset and preprogramming
0008  * functions.  The stubs in this file provide a standard way for the
0009  * hwmod code to call these functions, which are to be located under
0010  * drivers/.
0011  *
0012  * This program is free software; you can redistribute it and/or
0013  * modify it under the terms of the GNU General Public License as
0014  * published by the Free Software Foundation version 2.
0015  *
0016  * This program is distributed "as is" WITHOUT ANY WARRANTY of any
0017  * kind, whether express or implied; without even the implied warranty
0018  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0019  * GNU General Public License for more details.
0020  *
0021  * You should have received a copy of the GNU General Public License
0022  * along with this program; if not, write to the Free Software
0023  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
0024  * 02110-1301 USA
0025  */
0026 #include <linux/kernel.h>
0027 #include <linux/errno.h>
0028 
0029 #include "omap_hwmod.h"
0030 #include "common.h"
0031 
0032 #define OMAP_RTC_STATUS_REG 0x44
0033 #define OMAP_RTC_KICK0_REG  0x6c
0034 #define OMAP_RTC_KICK1_REG  0x70
0035 
0036 #define OMAP_RTC_KICK0_VALUE    0x83E70B13
0037 #define OMAP_RTC_KICK1_VALUE    0x95A4F1E0
0038 #define OMAP_RTC_STATUS_BUSY    BIT(0)
0039 #define OMAP_RTC_MAX_READY_TIME 50
0040 
0041 /**
0042  * omap_rtc_wait_not_busy - Wait for the RTC BUSY flag
0043  * @oh: struct omap_hwmod *
0044  *
0045  * For updating certain RTC registers, the MPU must wait
0046  * for the BUSY status in OMAP_RTC_STATUS_REG to become zero.
0047  * Once the BUSY status is zero, there is a 15 microseconds access
0048  * period in which the MPU can program.
0049  */
0050 static void omap_rtc_wait_not_busy(struct omap_hwmod *oh)
0051 {
0052     int i;
0053 
0054     /* BUSY may stay active for 1/32768 second (~30 usec) */
0055     omap_test_timeout(omap_hwmod_read(oh, OMAP_RTC_STATUS_REG)
0056               & OMAP_RTC_STATUS_BUSY, OMAP_RTC_MAX_READY_TIME, i);
0057     /* now we have ~15 microseconds to read/write various registers */
0058 }
0059 
0060 /**
0061  * omap_hwmod_rtc_unlock - Unlock the Kicker mechanism.
0062  * @oh: struct omap_hwmod *
0063  *
0064  * RTC IP have kicker feature. This prevents spurious writes to its registers.
0065  * In order to write into any of the RTC registers, KICK values has te be
0066  * written in respective KICK registers. This is needed for hwmod to write into
0067  * sysconfig register.
0068  */
0069 void omap_hwmod_rtc_unlock(struct omap_hwmod *oh)
0070 {
0071     unsigned long flags;
0072 
0073     local_irq_save(flags);
0074     omap_rtc_wait_not_busy(oh);
0075     omap_hwmod_write(OMAP_RTC_KICK0_VALUE, oh, OMAP_RTC_KICK0_REG);
0076     omap_hwmod_write(OMAP_RTC_KICK1_VALUE, oh, OMAP_RTC_KICK1_REG);
0077     local_irq_restore(flags);
0078 }
0079 
0080 /**
0081  * omap_hwmod_rtc_lock - Lock the Kicker mechanism.
0082  * @oh: struct omap_hwmod *
0083  *
0084  * RTC IP have kicker feature. This prevents spurious writes to its registers.
0085  * Once the RTC registers are written, KICK mechanism needs to be locked,
0086  * in order to prevent any spurious writes. This function locks back the RTC
0087  * registers once hwmod completes its write into sysconfig register.
0088  */
0089 void omap_hwmod_rtc_lock(struct omap_hwmod *oh)
0090 {
0091     unsigned long flags;
0092 
0093     local_irq_save(flags);
0094     omap_rtc_wait_not_busy(oh);
0095     omap_hwmod_write(0x0, oh, OMAP_RTC_KICK0_REG);
0096     omap_hwmod_write(0x0, oh, OMAP_RTC_KICK1_REG);
0097     local_irq_restore(flags);
0098 }