Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * OMAP Dual-Mode Timers
0003  *
0004  * Copyright (C) 2010 Texas Instruments Incorporated - https://www.ti.com/
0005  * Tarun Kanti DebBarma <tarun.kanti@ti.com>
0006  * Thara Gopinath <thara@ti.com>
0007  *
0008  * Platform device conversion and hwmod support.
0009  *
0010  * Copyright (C) 2005 Nokia Corporation
0011  * Author: Lauri Leukkunen <lauri.leukkunen@nokia.com>
0012  * PWM and clock framwork support by Timo Teras.
0013  *
0014  * This program is free software; you can redistribute it and/or modify it
0015  * under the terms of the GNU General Public License as published by the
0016  * Free Software Foundation; either version 2 of the License, or (at your
0017  * option) any later version.
0018  *
0019  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
0020  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
0021  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
0022  * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
0023  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
0024  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0025  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
0026  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0027  *
0028  * You should have received a copy of the  GNU General Public License along
0029  * with this program; if not, write  to the Free Software Foundation, Inc.,
0030  * 675 Mass Ave, Cambridge, MA 02139, USA.
0031  */
0032 
0033 #include <linux/delay.h>
0034 #include <linux/io.h>
0035 #include <linux/platform_device.h>
0036 
0037 #ifndef __CLOCKSOURCE_DMTIMER_H
0038 #define __CLOCKSOURCE_DMTIMER_H
0039 
0040 /* clock sources */
0041 #define OMAP_TIMER_SRC_SYS_CLK          0x00
0042 #define OMAP_TIMER_SRC_32_KHZ           0x01
0043 #define OMAP_TIMER_SRC_EXT_CLK          0x02
0044 
0045 /* timer interrupt enable bits */
0046 #define OMAP_TIMER_INT_CAPTURE          (1 << 2)
0047 #define OMAP_TIMER_INT_OVERFLOW         (1 << 1)
0048 #define OMAP_TIMER_INT_MATCH            (1 << 0)
0049 
0050 /* trigger types */
0051 #define OMAP_TIMER_TRIGGER_NONE         0x00
0052 #define OMAP_TIMER_TRIGGER_OVERFLOW     0x01
0053 #define OMAP_TIMER_TRIGGER_OVERFLOW_AND_COMPARE 0x02
0054 
0055 /* posted mode types */
0056 #define OMAP_TIMER_NONPOSTED            0x00
0057 #define OMAP_TIMER_POSTED           0x01
0058 
0059 /* timer capabilities used in hwmod database */
0060 #define OMAP_TIMER_SECURE               0x80000000
0061 #define OMAP_TIMER_ALWON                0x40000000
0062 #define OMAP_TIMER_HAS_PWM              0x20000000
0063 #define OMAP_TIMER_NEEDS_RESET              0x10000000
0064 #define OMAP_TIMER_HAS_DSP_IRQ              0x08000000
0065 
0066 /*
0067  * timer errata flags
0068  *
0069  * Errata i103/i767 impacts all OMAP3/4/5 devices including AM33xx. This
0070  * errata prevents us from using posted mode on these devices, unless the
0071  * timer counter register is never read. For more details please refer to
0072  * the OMAP3/4/5 errata documents.
0073  */
0074 #define OMAP_TIMER_ERRATA_I103_I767         0x80000000
0075 
0076 struct timer_regs {
0077     u32 ocp_cfg;
0078     u32 tidr;
0079     u32 tier;
0080     u32 twer;
0081     u32 tclr;
0082     u32 tcrr;
0083     u32 tldr;
0084     u32 ttrg;
0085     u32 twps;
0086     u32 tmar;
0087     u32 tcar1;
0088     u32 tsicr;
0089     u32 tcar2;
0090     u32 tpir;
0091     u32 tnir;
0092     u32 tcvr;
0093     u32 tocr;
0094     u32 towr;
0095 };
0096 
0097 struct omap_dm_timer {
0098     int id;
0099     int irq;
0100     struct clk *fclk;
0101 
0102     void __iomem    *io_base;
0103     void __iomem    *irq_stat;  /* TISR/IRQSTATUS interrupt status */
0104     void __iomem    *irq_ena;   /* irq enable */
0105     void __iomem    *irq_dis;   /* irq disable, only on v2 ip */
0106     void __iomem    *pend;      /* write pending */
0107     void __iomem    *func_base; /* function register base */
0108 
0109     atomic_t enabled;
0110     unsigned long rate;
0111     unsigned reserved:1;
0112     unsigned posted:1;
0113     struct timer_regs context;
0114     int revision;
0115     u32 capability;
0116     u32 errata;
0117     struct platform_device *pdev;
0118     struct list_head node;
0119     struct notifier_block nb;
0120 };
0121 
0122 int omap_dm_timer_reserve_systimer(int id);
0123 struct omap_dm_timer *omap_dm_timer_request_by_cap(u32 cap);
0124 
0125 int omap_dm_timer_get_irq(struct omap_dm_timer *timer);
0126 
0127 u32 omap_dm_timer_modify_idlect_mask(u32 inputmask);
0128 
0129 int omap_dm_timer_trigger(struct omap_dm_timer *timer);
0130 
0131 int omap_dm_timers_active(void);
0132 
0133 /*
0134  * Do not use the defines below, they are not needed. They should be only
0135  * used by dmtimer.c and sys_timer related code.
0136  */
0137 
0138 /*
0139  * The interrupt registers are different between v1 and v2 ip.
0140  * These registers are offsets from timer->iobase.
0141  */
0142 #define OMAP_TIMER_ID_OFFSET        0x00
0143 #define OMAP_TIMER_OCP_CFG_OFFSET   0x10
0144 
0145 #define OMAP_TIMER_V1_SYS_STAT_OFFSET   0x14
0146 #define OMAP_TIMER_V1_STAT_OFFSET   0x18
0147 #define OMAP_TIMER_V1_INT_EN_OFFSET 0x1c
0148 
0149 #define OMAP_TIMER_V2_IRQSTATUS_RAW 0x24
0150 #define OMAP_TIMER_V2_IRQSTATUS     0x28
0151 #define OMAP_TIMER_V2_IRQENABLE_SET 0x2c
0152 #define OMAP_TIMER_V2_IRQENABLE_CLR 0x30
0153 
0154 /*
0155  * The functional registers have a different base on v1 and v2 ip.
0156  * These registers are offsets from timer->func_base. The func_base
0157  * is samae as io_base for v1 and io_base + 0x14 for v2 ip.
0158  *
0159  */
0160 #define OMAP_TIMER_V2_FUNC_OFFSET       0x14
0161 
0162 #define _OMAP_TIMER_WAKEUP_EN_OFFSET    0x20
0163 #define _OMAP_TIMER_CTRL_OFFSET     0x24
0164 #define     OMAP_TIMER_CTRL_GPOCFG      (1 << 14)
0165 #define     OMAP_TIMER_CTRL_CAPTMODE    (1 << 13)
0166 #define     OMAP_TIMER_CTRL_PT      (1 << 12)
0167 #define     OMAP_TIMER_CTRL_TCM_LOWTOHIGH   (0x1 << 8)
0168 #define     OMAP_TIMER_CTRL_TCM_HIGHTOLOW   (0x2 << 8)
0169 #define     OMAP_TIMER_CTRL_TCM_BOTHEDGES   (0x3 << 8)
0170 #define     OMAP_TIMER_CTRL_SCPWM       (1 << 7)
0171 #define     OMAP_TIMER_CTRL_CE      (1 << 6) /* compare enable */
0172 #define     OMAP_TIMER_CTRL_PRE     (1 << 5) /* prescaler enable */
0173 #define     OMAP_TIMER_CTRL_PTV_SHIFT   2 /* prescaler value shift */
0174 #define     OMAP_TIMER_CTRL_POSTED      (1 << 2)
0175 #define     OMAP_TIMER_CTRL_AR      (1 << 1) /* auto-reload enable */
0176 #define     OMAP_TIMER_CTRL_ST      (1 << 0) /* start timer */
0177 #define _OMAP_TIMER_COUNTER_OFFSET  0x28
0178 #define _OMAP_TIMER_LOAD_OFFSET     0x2c
0179 #define _OMAP_TIMER_TRIGGER_OFFSET  0x30
0180 #define _OMAP_TIMER_WRITE_PEND_OFFSET   0x34
0181 #define     WP_NONE         0   /* no write pending bit */
0182 #define     WP_TCLR         (1 << 0)
0183 #define     WP_TCRR         (1 << 1)
0184 #define     WP_TLDR         (1 << 2)
0185 #define     WP_TTGR         (1 << 3)
0186 #define     WP_TMAR         (1 << 4)
0187 #define     WP_TPIR         (1 << 5)
0188 #define     WP_TNIR         (1 << 6)
0189 #define     WP_TCVR         (1 << 7)
0190 #define     WP_TOCR         (1 << 8)
0191 #define     WP_TOWR         (1 << 9)
0192 #define _OMAP_TIMER_MATCH_OFFSET    0x38
0193 #define _OMAP_TIMER_CAPTURE_OFFSET  0x3c
0194 #define _OMAP_TIMER_IF_CTRL_OFFSET  0x40
0195 #define _OMAP_TIMER_CAPTURE2_OFFSET     0x44    /* TCAR2, 34xx only */
0196 #define _OMAP_TIMER_TICK_POS_OFFSET     0x48    /* TPIR, 34xx only */
0197 #define _OMAP_TIMER_TICK_NEG_OFFSET     0x4c    /* TNIR, 34xx only */
0198 #define _OMAP_TIMER_TICK_COUNT_OFFSET       0x50    /* TCVR, 34xx only */
0199 #define _OMAP_TIMER_TICK_INT_MASK_SET_OFFSET    0x54    /* TOCR, 34xx only */
0200 #define _OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET  0x58    /* TOWR, 34xx only */
0201 
0202 /* register offsets with the write pending bit encoded */
0203 #define WPSHIFT                 16
0204 
0205 #define OMAP_TIMER_WAKEUP_EN_REG        (_OMAP_TIMER_WAKEUP_EN_OFFSET \
0206                             | (WP_NONE << WPSHIFT))
0207 
0208 #define OMAP_TIMER_CTRL_REG         (_OMAP_TIMER_CTRL_OFFSET \
0209                             | (WP_TCLR << WPSHIFT))
0210 
0211 #define OMAP_TIMER_COUNTER_REG          (_OMAP_TIMER_COUNTER_OFFSET \
0212                             | (WP_TCRR << WPSHIFT))
0213 
0214 #define OMAP_TIMER_LOAD_REG         (_OMAP_TIMER_LOAD_OFFSET \
0215                             | (WP_TLDR << WPSHIFT))
0216 
0217 #define OMAP_TIMER_TRIGGER_REG          (_OMAP_TIMER_TRIGGER_OFFSET \
0218                             | (WP_TTGR << WPSHIFT))
0219 
0220 #define OMAP_TIMER_WRITE_PEND_REG       (_OMAP_TIMER_WRITE_PEND_OFFSET \
0221                             | (WP_NONE << WPSHIFT))
0222 
0223 #define OMAP_TIMER_MATCH_REG            (_OMAP_TIMER_MATCH_OFFSET \
0224                             | (WP_TMAR << WPSHIFT))
0225 
0226 #define OMAP_TIMER_CAPTURE_REG          (_OMAP_TIMER_CAPTURE_OFFSET \
0227                             | (WP_NONE << WPSHIFT))
0228 
0229 #define OMAP_TIMER_IF_CTRL_REG          (_OMAP_TIMER_IF_CTRL_OFFSET \
0230                             | (WP_NONE << WPSHIFT))
0231 
0232 #define OMAP_TIMER_CAPTURE2_REG         (_OMAP_TIMER_CAPTURE2_OFFSET \
0233                             | (WP_NONE << WPSHIFT))
0234 
0235 #define OMAP_TIMER_TICK_POS_REG         (_OMAP_TIMER_TICK_POS_OFFSET \
0236                             | (WP_TPIR << WPSHIFT))
0237 
0238 #define OMAP_TIMER_TICK_NEG_REG         (_OMAP_TIMER_TICK_NEG_OFFSET \
0239                             | (WP_TNIR << WPSHIFT))
0240 
0241 #define OMAP_TIMER_TICK_COUNT_REG       (_OMAP_TIMER_TICK_COUNT_OFFSET \
0242                             | (WP_TCVR << WPSHIFT))
0243 
0244 #define OMAP_TIMER_TICK_INT_MASK_SET_REG                \
0245         (_OMAP_TIMER_TICK_INT_MASK_SET_OFFSET | (WP_TOCR << WPSHIFT))
0246 
0247 #define OMAP_TIMER_TICK_INT_MASK_COUNT_REG              \
0248         (_OMAP_TIMER_TICK_INT_MASK_COUNT_OFFSET | (WP_TOWR << WPSHIFT))
0249 
0250 #endif /* __CLOCKSOURCE_DMTIMER_H */