summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libcpu/arm/pxa255/pmc/pmc.c
blob: 4fb4d2e593e20867265eb5adda3dcff91e58c941 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
/*
 *  By Yang Xi <hiyangxi@gmail.com>.
 *
 *  The license and distribution terms for this file may be
 *  found in the file LICENSE in this distribution or at
 *  http://www.rtems.com/license/LICENSE.
 */

#include <rtems.h>
#include <bsp.h>
#include <pxa255.h>

unsigned int xscale_read_pmc(int reg)
{
  unsigned int val = 0;
  switch(reg){
  case PMC_PMNC:
    __asm__ volatile("mrc p14,0,%0,c0,c1,0\n":"=r"(val):);
    break;
  case PMC_CCNT:
    __asm__ volatile("mrc p14,0,%0,c1,c1,0\n":"=r"(val):);
    break;
  case PMC_INTEN:
    __asm__ volatile("mrc p14,0,%0,c4,c1,0\n":"=r"(val):);
    break;
  case PMC_FLAG:
    __asm__ volatile("mrc p14,0,%0,c5,c1,0\n":"=r"(val):);
    break;
  case PMC_EVTSEL:
    __asm__ volatile("mrc p14,0,%0,c8,c1,0\n":"=r"(val):);
    break;
  case PMC_PMN0:
    __asm__ volatile("mrc p14,0,%0,c0,c2,0\n":"=r"(val):);
    break;
  case PMC_PMN1:
    __asm__ volatile("mrc p14,0,%0,c1,c2,0\n":"=r"(val):);
    break;
  case PMC_PMN2:
    __asm__ volatile("mrc p14,0,%0,c2,c2,0\n":"=r"(val):);
    break;
  case PMC_PMN3:
    __asm__ volatile("mrc p14,0,%0,c3,c2,0\n":"=r"(val):);
    break;
  default:
    val = 0;
    break;
  }
  return val;
}

void xscale_write_pmc(int reg, unsigned int val)
{
  switch(reg){
  case PMC_PMNC:
    __asm__ volatile("mcr p14,0,%0,c0,c1,0\n"::"r"(val));
    break;
  case PMC_CCNT:
    __asm__ volatile("mcr p14,0,%0,c1,c1,0\n"::"r"(val));
    break;
  case PMC_INTEN:
    __asm__ volatile("mcr p14,0,%0,c4,c1,0\n"::"r"(val));
    break;
  case PMC_FLAG:
    __asm__ volatile("mcr p14,0,%0,c5,c1,0\n"::"r"(val));
    break;
  case PMC_EVTSEL:
    __asm__ volatile("mcr p14,0,%0,c8,c1,0\n"::"r"(val));
    break;
  case PMC_PMN0:
    __asm__ volatile("mcr p14,0,%0,c0,c2,0\n"::"r"(val));
    break;
  case PMC_PMN1:
    __asm__ volatile("mcr p14,0,%0,c1,c2,0\n"::"r"(val));
    break;
  case PMC_PMN2:
    __asm__ volatile("mcr p14,0,%0,c2,c2,0\n"::"r"(val));
    break;
  case PMC_PMN3:
    __asm__ volatile("mcr p14,0,%0,c3,c2,0\n"::"r"(val));
    break;
  default:
    break;
  }
}

void xscale_pmc_enable_pmc(void)
{
  unsigned int val;
  val = xscale_read_pmc(PMC_PMNC);
  val = (val | PMC_PMNC_E)&(~PMC_PMNC_PCD);
  xscale_write_pmc(PMC_PMNC,val);
}
void xscale_pmc_disable_pmc(void)
{
  unsigned int val;
  val = xscale_read_pmc(PMC_PMNC);
  val = val & (~PMC_PMNC_E);
  xscale_write_pmc(PMC_PMNC,val);
}

void xscale_pmc_reset_pmc(void)
{
  unsigned int val;
  val = xscale_read_pmc(PMC_PMNC);
  val = val | PMC_PMNC_PCR;
  xscale_write_pmc(PMC_PMNC,val);
}

void xscale_pmc_reset_ccnt(void)
{
  unsigned int val;
  val = xscale_read_pmc(PMC_PMNC);
  val = val | PMC_PMNC_CCR;
  xscale_write_pmc(PMC_PMNC,val);
}

void xscale_pmc_setevent(int reg, unsigned char evt)
{
  unsigned int val;
  val = xscale_read_pmc(PMC_EVTSEL);
  if((reg >= PMC_PMN0) && (reg <= PMC_PMN3)){
    val &= ~(0xff<<(reg-PMC_PMN0)*8);
    val |= evt << (reg-PMC_PMN0)*8;
    xscale_write_pmc(PMC_EVTSEL,val);
  }
}