This is the initial commit.
[keystone-rtos/netapi.git] / ti / runtime / netapi / src / tim64.c
1 /*
2  * tim64.c  : enable use of timer64 from user space
3  *  (using 64 bit mode)
4  *   TIMER 6
5  **************************************************************
6  * FILE: tim64.c  
7  * 
8  * DESCRIPTION:  tim64 peripheral driver for user space transport
9  *               library
10  * 
11  * REVISION HISTORY:  rev 0.0.1 
12  *
13  *  Copyright (c) Texas Instruments Incorporated 2010-2011
14  * 
15  *  Redistribution and use in source and binary forms, with or without 
16  *  modification, are permitted provided that the following conditions 
17  *  are met:
18  *
19  *    Redistributions of source code must retain the above copyright 
20  *    notice, this list of conditions and the following disclaimer.
21  *
22  *    Redistributions in binary form must reproduce the above copyright
23  *    notice, this list of conditions and the following disclaimer in the 
24  *    documentation and/or other materials provided with the   
25  *    distribution.
26  *
27  *    Neither the name of Texas Instruments Incorporated nor the names of
28  *    its contributors may be used to endorse or promote products derived
29  *    from this software without specific prior written permission.
30  *
31  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
32  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
33  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
34  *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
35  *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
36  *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
37  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
38  *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
39  *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
40  *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
41  *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
43  */
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <unistd.h>
48 #include <string.h>
49 #include <errno.h>
50 #include <signal.h>
51 #include <fcntl.h>
52 #include <ctype.h>
53 #include <termios.h>
54 #include <sys/types.h>
55 #include <sys/mman.h>
56 #include "netapi_timer.h"
58 /* timing */
59 static inline unsigned long timing_start(void)
60 {
61         volatile int vval;
62         //read clock
63         asm volatile("mrc p15, 0, %0, c9, c13, 0" :  "=r"(vval));
64         return vval;
65 }
66 static inline unsigned long timing_stop(void)
67 {
68         volatile int vval2;
69         //read clock
70         asm volatile("mrc p15, 0, %0, c9, c13, 0" :  "=r"(vval2));
71         return vval2;
72 }
75   
76 #define MAP_SIZE 4096UL
77 #define MAP_MASK (MAP_SIZE - 1)
78 //this is for timer 6
79 #define T64BASE_6  (void *)0x02260000
80 volatile unsigned long * t64_virt_addr;
81 static unsigned long tv_lo;
82 static unsigned long tv_hi;
84 //read
85 static unsigned long long read_t64(void)
86 {
87  volatile unsigned long long t1;
88  volatile unsigned long long t2;
89  unsigned long long val;
90  t1 = t64_virt_addr[0x10/4]; //lo
91  t2 = t64_virt_addr[0x14/4]; //hi
92  
93  val = ((unsigned long long) t2) <<32 | t1;
94  return val;
96 }
98 //claibrate
99 static unsigned int t64_cpu_cycle_per_tick=0;
100 unsigned int cpu_cycles_sec=983040000;
101 unsigned long t64_ticks_sec(void)
103    if (t64_cpu_cycle_per_tick)
104       return ( cpu_cycles_sec/t64_cpu_cycle_per_tick); //ticks per/sec
105    else return 166666666;
108 static int t64_calibrate(int n)
110 volatile unsigned long t1;
111 volatile unsigned long t2;
112 volatile unsigned long long t164;
113 volatile unsigned long long t264;
114 int i;
115 volatile int s;
116 t1=timing_start();
117 t164=read_t64();
119 sleep(1);
120 #if 0
121 for(i=0;i<n;i++)
123  s+=t164*20; s=s*(2+i);
125 #endif
126 t264=read_t64();
127 t2=timing_stop();
128 t64_cpu_cycle_per_tick = (unsigned long) ((t2-t1)/(t264-t164));
129 printf("calib - n=%d t2-t1=%lu t264-t164=%llu ccpt=%ld tps=%ld\n",
130        n, t2-t1, t264-t164, t64_cpu_cycle_per_tick,  t64_ticks_sec());
135 /*********************************
136  * memory map t64 into user space
137  *   input: pass in fd for /dev/mem
138  **********************************/
139 int t64_memmap(int fd)
141      off_t t64_base= (off_t) T64BASE_6;
142      void * map_base;
143      int op;
144      volatile unsigned long t1;
145      volatile unsigned long t2;
146      unsigned long long blah;
149     /* Map one page */
150     map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, t64_base & ~MAP_MASK);
151     if(map_base == (void *) -1) exit(-99);
152     printf("tim64>mapbase=Memory mapped at address %p.\n", map_base);
153     fflush(stdout);
155     t64_virt_addr = (long *) map_base + (t64_base & MAP_MASK);
156     printf("tim64>t64_virt_addr: Memory mapped at address %p.\n", t64_virt_addr);
157     fflush(stdout);
158     return 1;
162  /*********************************
163  *  start the timer64
164  ***********************************/
165 int t64_start(void)
167       t64_virt_addr[0x24/4]= 0x00;
168       t64_virt_addr[0x10/4]= 0x00;
169       t64_virt_addr[0x14/4]= 0x00;
170       t64_virt_addr[0x18/4]= 0xffffffff;
171       t64_virt_addr[0x1c/4]= 0xffffffff;
172       t64_virt_addr[0x20/4]= 0x80;
173       t64_virt_addr[0x24/4]= 0x03; //go
174       t64_calibrate(100000);
175       return 1;
179 #ifdef TEST_DRIVER
180 int main(int argc, char **argv) {
181     int fd;
182      off_t t64_base= (off_t) T64BASE_6; 
183     void * map_base;
184     int op;
185 volatile unsigned long t1;
186 volatile unsigned long t2;
187 unsigned long long blah;
188         
189         if(argc < 2) {
190                 fprintf(stderr, "Usage: tim64 start|stop|read  \n"
191                         );
192                 exit(1);
193         }
194         if (!strcmp(argv[1],"start")) op=0;
195         else if (!strcmp(argv[1],"stop")) op =1;
196         else if (!strcmp(argv[1],"read")) op =2;
197         else {  fprintf(stderr, "Usage: tim64 start|stop|read  \n"
198                         );
199                 exit(1);
200              }
203     if((fd = open("/dev/mem", O_RDWR | O_SYNC)) == -1) exit(-99);
204     printf("/dev/mem opened.\n"); 
205     fflush(stdout);
206     
207     /* Map one page */
208     map_base = mmap(0, MAP_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, t64_base & ~MAP_MASK);
209     if(map_base == (void *) -1) exit(-99);
210     printf("mapbase=Memory mapped at address %p.\n", map_base); 
211     fflush(stdout);
212     
213     t64_virt_addr = (long *) map_base + (t64_base & MAP_MASK);
214     printf("t64_virt_ddr: Memory mapped at address %p.\n", t64_virt_addr); 
215     fflush(stdout);
217     switch(op)
218     {
219     case(0):
220     default:
221       //start
222       t64_virt_addr[0x24/4]= 0x00;
223       t64_virt_addr[0x10/4]= 0x00;
224       t64_virt_addr[0x14/4]= 0x00;
225       t64_virt_addr[0x18/4]= 0xffffffff;
226       t64_virt_addr[0x1c/4]= 0xffffffff;
227       t64_virt_addr[0x20/4]= 0x80;
228       t64_virt_addr[0x24/4]= 0x03; //go
229       t64_calibrate(100000);
230       break;
231     case(1):
232      //stop
233       t64_virt_addr[0x24/4]= 0x00;
234       break;
235     case(2):
236       //read
237       tv_lo= t64_virt_addr[0x10/4];
238       tv_hi= t64_virt_addr[0x14/4];
239 t1=timing_start();
240 blah = read_t64();
241 t2=timing_stop();
243       printf("t64 = %x%x   %llx (read_t64 takes %d ticks)\n",tv_hi,tv_lo,blah, t2-t1);
244       break;
245     } 
246     if(munmap(map_base, MAP_SIZE) == -1) exit(-99);
247     close(fd);
248     return 0;
250 #endif