Home | History | Annotate | Download | only in arch_msm7k
      1 /*
      2  * Copyright (c) 2008, Google Inc.
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *  * Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  *  * Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in
     12  *    the documentation and/or other materials provided with the
     13  *    distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     18  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     19  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
     22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  */
     28 
     29 #include <boot/boot.h>
     30 #include <msm7k/gpt.h>
     31 
     32 static inline unsigned rd_cycle_count(void)
     33 {
     34     unsigned cc;
     35     asm volatile (
     36         "mrc p15, 0, %0, c15, c12, 1\n" :
     37         "=r" (cc)
     38         );
     39     return cc;
     40 }
     41 
     42 static inline unsigned rd_dtcm(void)
     43 {
     44     unsigned cc;
     45     asm volatile (
     46         "mrc p15, 0, %0, c9, c1, 0\n" :
     47         "=r" (cc)
     48         );
     49     return cc;
     50 }
     51 
     52 static inline unsigned rd_itcm(void)
     53 {
     54     unsigned cc;
     55     asm volatile (
     56         "mrc p15, 0, %0, c9, c1, 1\n" :
     57         "=r" (cc)
     58         );
     59     return cc;
     60 }
     61 
     62 static inline void perf_enable(void)
     63 {
     64     asm volatile (
     65         "mcr p15, 0, %0, c15, c12, 0\n" : : "r" (7)
     66         );
     67 }
     68 
     69 static inline void perf_disable(void)
     70 {
     71     asm volatile (
     72         "mcr p15, 0, %0, c15, c12, 0\n" : : "r" (0)
     73         );
     74 }
     75 
     76 unsigned cycles_per_second(void)
     77 {
     78     unsigned T0, T1;
     79 
     80     perf_enable();
     81 
     82     writel(0, GPT_CLEAR);
     83     writel(0, GPT_ENABLE);
     84     while(readl(GPT_COUNT_VAL) != 0) ;
     85 
     86     writel(GPT_ENABLE_EN, GPT_ENABLE);
     87     T0 = rd_cycle_count();
     88     while(readl(GPT_COUNT_VAL) < 32766) ;
     89     T1 = rd_cycle_count();
     90 
     91     writel(0, GPT_ENABLE);
     92     writel(0, GPT_CLEAR);
     93 
     94     perf_disable();
     95 
     96     return T1-T0;
     97 }
     98 
     99 void mdelay(unsigned msecs)
    100 {
    101     msecs *= 33;
    102 
    103     writel(0, GPT_CLEAR);
    104     writel(0, GPT_ENABLE);
    105     while(readl(GPT_COUNT_VAL) != 0) ;
    106 
    107     writel(GPT_ENABLE_EN, GPT_ENABLE);
    108     while(readl(GPT_COUNT_VAL) < msecs) ;
    109 
    110     writel(0, GPT_ENABLE);
    111     writel(0, GPT_CLEAR);
    112 }
    113 
    114 void udelay(unsigned usecs)
    115 {
    116     usecs = (usecs * 33 + 1000 - 33) / 1000;
    117 
    118     writel(0, GPT_CLEAR);
    119     writel(0, GPT_ENABLE);
    120     while(readl(GPT_COUNT_VAL) != 0) ;
    121 
    122     writel(GPT_ENABLE_EN, GPT_ENABLE);
    123     while(readl(GPT_COUNT_VAL) < usecs) ;
    124 
    125     writel(0, GPT_ENABLE);
    126     writel(0, GPT_CLEAR);
    127 }
    128 
    129 void print_cpu_speed(void)
    130 {
    131     unsigned cps = cycles_per_second();
    132     dprintf("1 second = %d cycles\n%d MHz\n", cps, cps / 1000000);
    133 }
    134 
    135 #define A11S_CLK_CNTL 0xC0100100
    136 #define A11S_CLK_SEL  0xC0100104
    137 
    138 #define C A11S_CLK_CNTL
    139 #define S A11S_CLK_SEL
    140 
    141 #if FROM_APPSBOOT_MBN
    142 static unsigned tbl_old[] = {
    143     C, 0x640000,
    144     S, 2,
    145     C, 0x640010,
    146     C, 0x64001F,
    147     S, 3,
    148     C, 0x64101F,
    149     C, 0x64171F,
    150     S, 2,
    151     C, 0x64171F,
    152     C, 0x641715,
    153     S, 3,
    154     S, 5,
    155     C, 0x641715,
    156     C, 0x641315,
    157     S, 4,
    158     S, 6,
    159     C, 0x641315,
    160     C, 0x641312,
    161     S, 7,
    162     C, 0x641312,
    163     C, 0x641112,
    164     S, 6,
    165     0
    166 };
    167 #endif
    168 
    169 static unsigned tbl[] = {
    170 #if EXPLORE
    171     C, 0x640000, S, 2,
    172     C, 0x640001, S, 3,
    173     C, 0x640201, S, 2,
    174     C, 0x640203, S, 3,
    175     C, 0x640403, S, 2,
    176     C, 0x640405, S, 3,
    177     C, 0x640605, S, 2,
    178     C, 0x640607, S, 3,
    179     C, 0x640807, S, 2,
    180     C, 0x640809, S, 3,
    181     C, 0x640A09, S, 2,
    182     C, 0x640A0B, S, 3,
    183     C, 0x640C0B, S, 2,
    184     C, 0x640C0D, S, 3,
    185     C, 0x640E0D, S, 2,
    186     C, 0x640E0F, S, 3,
    187 #endif
    188     C, 0x640000, S, 2,
    189     C, 0x64001F, S, 3,
    190     C, 0x64171F, S, 2,
    191     C, 0x641715, S, 5,
    192     C, 0x641315, S, 6,
    193     C, 0x641312, S, 7,
    194     C, 0x641112, S, 6,
    195     0
    196 };
    197 #undef C
    198 #undef S
    199 
    200 #if TESTCASE
    201 unsigned cc_div[16] = {
    202 	1, 2, 3, 4,  5, 8, 6, 16,
    203 	1, 1, 1, 1,  1, 1, 1, 32  /* guess */
    204 };
    205 
    206 unsigned cc_base[4] = {
    207 	19200000,
    208     245760000,
    209     800000000,
    210     0
    211 };
    212 
    213 unsigned cs_div[4] = {
    214 	1, 2, 3, 4
    215 };
    216 
    217 void info(unsigned c, unsigned s)
    218 {
    219     unsigned src_sel, src_div;
    220 
    221     if(s & 1) {
    222             /* src1 selected */
    223         src_sel = (c >> 4) & 0x7;
    224         src_div = c & 0xF;
    225     } else {
    226             /* src0 selected */
    227         src_sel = (c >> 12) & 0x7;
    228         src_div = (c >> 8) & 0xF;
    229     }
    230 
    231     unsigned src = s & 1;
    232     unsigned pdiv = cs_div[(s >> 1) & 3];
    233     unsigned div = cc_div[src_div];
    234     unsigned clk = cc_base[src_sel] / div;
    235     unsigned pclk = clk / pdiv;
    236 
    237     unsigned cps = cycles_per_second();
    238 
    239     dprintf("CC=0x%x CS=0x%x SRC=%d PDIV=%d SEL=%d DIV=%d CPS=%d ACLK=%d\n",
    240             c, s, src, pdiv, src_sel, div, cps, clk);
    241 }
    242 
    243 
    244 void arm11_clock_test(void)
    245 {
    246     unsigned c, s;
    247     unsigned *x = tbl;
    248 
    249     while(*x) {
    250         unsigned *ptr = (unsigned*) *x++;
    251         unsigned val = *x++;
    252         *ptr = val;
    253 
    254         if(ptr == ((unsigned*) A11S_CLK_CNTL)) {
    255             c = val;
    256         } else {
    257             s = val;
    258             info(c, s);
    259         }
    260     }
    261 }
    262 #endif
    263 
    264 void arm11_clock_init(void)
    265 {
    266     unsigned *x = tbl;
    267     while(*x) {
    268         unsigned *ptr = (unsigned*) *x++;
    269         unsigned val = *x++;
    270         *ptr = val;
    271     }
    272 }
    273 
    274 
    275