1 /** @file  ArmVExpressSysConfig.c
2 
3   Copyright (c) 2011-2012, ARM Ltd. All rights reserved.<BR>
4 
5   This program and the accompanying materials
6   are licensed and made available under the terms and conditions of the BSD License
7   which accompanies this distribution.  The full text of the license may be found at
8   http://opensource.org/licenses/bsd-license.php
9 
10   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12 
13 **/
14 
15 #include <Base.h>
16 #include <Library/IoLib.h>
17 #include <Library/DebugLib.h>
18 
19 #include <Library/ArmPlatformSysConfigLib.h>
20 #include <ArmPlatform.h>
21 
22 #include <Uefi.h>
23 #include <Library/UefiRuntimeLib.h>
24 
25 //
26 // SYS_CFGCTRL Bits
27 //
28 #define SYS_CFGCTRL_START                 BIT31
29 #define SYS_CFGCTRL_READ                  (0 << 30)
30 #define SYS_CFGCTRL_WRITE                 (1 << 30)
31 #define SYS_CFGCTRL_FUNCTION(fun)         (((fun ) &  0x3F) << 20)
32 #define SYS_CFGCTRL_SITE(site)            (((site) &   0x3) << 16)
33 #define SYS_CFGCTRL_POSITION(pos)         (((pos ) &   0xF) << 12)
34 #define SYS_CFGCTRL_DEVICE(dev)            ((dev ) & 0xFFF)
35 
36 //
37 // SYS_CFGSTAT Bits
38 //
39 #define SYS_CFGSTAT_ERROR                 BIT1
40 #define SYS_CFGSTAT_COMPLETE              BIT0
41 
42 /****************************************************************************
43  *
44  *  This file makes it easier to access the System Configuration Registers
45  *  in the ARM Versatile Express motherboard.
46  *
47  ****************************************************************************/
48 
49 RETURN_STATUS
ArmPlatformSysConfigInitialize(VOID)50 ArmPlatformSysConfigInitialize (
51   VOID
52   )
53 {
54   return RETURN_SUCCESS;
55 }
56 
57 /***************************************
58  * GENERAL FUNCTION: AccessSysCfgRegister
59  * Interacts with
60  *    SYS_CFGSTAT
61  *    SYS_CFGDATA
62  *    SYS_CFGCTRL
63  * for setting and for reading out values
64  ***************************************/
65 
66 RETURN_STATUS
AccessSysCfgRegister(IN UINT32 ReadWrite,IN UINT32 Function,IN UINT32 Site,IN UINT32 Position,IN UINT32 Device,IN OUT UINT32 * Data)67 AccessSysCfgRegister (
68   IN     UINT32   ReadWrite,
69   IN     UINT32   Function,
70   IN     UINT32   Site,
71   IN     UINT32   Position,
72   IN     UINT32   Device,
73   IN OUT UINT32*  Data
74   )
75 {
76   UINT32          SysCfgCtrl;
77 
78   if (EfiAtRuntime ()) {
79     return RETURN_UNSUPPORTED;
80   }
81 
82   // Clear the COMPLETE bit
83   MmioAnd32(ARM_VE_SYS_CFGSTAT_REG, ~SYS_CFGSTAT_COMPLETE);
84 
85   // If writing, then set the data value
86   if(ReadWrite == SYS_CFGCTRL_WRITE) {
87     MmioWrite32(ARM_VE_SYS_CFGDATA_REG, *Data);
88   }
89 
90   // Set the control value
91   SysCfgCtrl = SYS_CFGCTRL_START | ReadWrite | SYS_CFGCTRL_FUNCTION(Function) | SYS_CFGCTRL_SITE(Site) |
92       SYS_CFGCTRL_POSITION(Position) | SYS_CFGCTRL_DEVICE(Device);
93   MmioWrite32(ARM_VE_SYS_CFGCTRL_REG, SysCfgCtrl);
94 
95   // Wait until the COMPLETE bit is set
96   while ((MmioRead32(ARM_VE_SYS_CFGSTAT_REG) & SYS_CFGSTAT_COMPLETE) == 0);
97 
98   // Check for errors
99   if(MmioRead32(ARM_VE_SYS_CFGSTAT_REG) & SYS_CFGSTAT_ERROR) {
100     return RETURN_DEVICE_ERROR;
101   }
102 
103   // If reading then get the data value
104   if(ReadWrite == SYS_CFGCTRL_READ) {
105     *Data = MmioRead32(ARM_VE_SYS_CFGDATA_REG);
106   }
107 
108   return RETURN_SUCCESS;
109 }
110 
111 RETURN_STATUS
ArmPlatformSysConfigGet(IN SYS_CONFIG_FUNCTION Function,OUT UINT32 * Value)112 ArmPlatformSysConfigGet (
113   IN  SYS_CONFIG_FUNCTION   Function,
114   OUT UINT32*               Value
115   )
116 {
117   UINT32          Site;
118   UINT32          Position;
119   UINT32          Device;
120 
121   Position = 0;
122   Device = 0;
123 
124   // Intercept some functions
125   switch(Function) {
126 
127   case SYS_CFG_OSC_SITE1:
128     Function = SYS_CFG_OSC;
129     Site = ARM_VE_DAUGHTERBOARD_1_SITE;
130     break;
131 
132   case SYS_CFG_OSC_SITE2:
133     Function = SYS_CFG_OSC;
134     Site = ARM_VE_DAUGHTERBOARD_2_SITE;
135     break;
136 
137   case SYS_CFG_MUXFPGA:
138     Site = *Value;
139     break;
140 
141   case SYS_CFG_OSC:
142   case SYS_CFG_VOLT:
143   case SYS_CFG_AMP:
144   case SYS_CFG_TEMP:
145   case SYS_CFG_RESET:
146   case SYS_CFG_SCC:
147   case SYS_CFG_DVIMODE:
148   case SYS_CFG_POWER:
149     Site = ARM_VE_MOTHERBOARD_SITE;
150     break;
151 
152   case SYS_CFG_SHUTDOWN:
153   case SYS_CFG_REBOOT:
154   case SYS_CFG_RTC:
155   default:
156     return RETURN_UNSUPPORTED;
157   }
158 
159   return AccessSysCfgRegister (SYS_CFGCTRL_READ, Function, Site, Position, Device, Value);
160 }
161 
162 RETURN_STATUS
ArmPlatformSysConfigGetValues(IN SYS_CONFIG_FUNCTION Function,IN UINTN Size,OUT UINT32 * Values)163 ArmPlatformSysConfigGetValues (
164   IN  SYS_CONFIG_FUNCTION   Function,
165   IN  UINTN                 Size,
166   OUT UINT32*               Values
167   )
168 {
169   return RETURN_UNSUPPORTED;
170 }
171 
172 RETURN_STATUS
ArmPlatformSysConfigSet(IN SYS_CONFIG_FUNCTION Function,IN UINT32 Value)173 ArmPlatformSysConfigSet (
174   IN  SYS_CONFIG_FUNCTION   Function,
175   IN  UINT32                Value
176   )
177 {
178   UINT32          Site;
179   UINT32          Position;
180   UINT32          Device;
181 
182   Position = 0;
183   Device = 0;
184 
185   // Intercept some functions
186   switch(Function) {
187 
188   case SYS_CFG_OSC_SITE1:
189     Function = SYS_CFG_OSC;
190     Site = ARM_VE_DAUGHTERBOARD_1_SITE;
191     break;
192 
193   case SYS_CFG_OSC_SITE2:
194     Function = SYS_CFG_OSC;
195     Site = ARM_VE_DAUGHTERBOARD_2_SITE;
196     break;
197 
198   case SYS_CFG_MUXFPGA:
199     Site = Value;
200     break;
201 
202   case SYS_CFG_RESET:
203   case SYS_CFG_SCC:
204   case SYS_CFG_SHUTDOWN:
205   case SYS_CFG_REBOOT:
206   case SYS_CFG_DVIMODE:
207   case SYS_CFG_POWER:
208     Site = ARM_VE_MOTHERBOARD_SITE;
209     break;
210 
211   case SYS_CFG_OSC:
212   case SYS_CFG_VOLT:
213   case SYS_CFG_AMP:
214   case SYS_CFG_TEMP:
215   case SYS_CFG_RTC:
216   default:
217     return RETURN_UNSUPPORTED;
218   }
219 
220   return AccessSysCfgRegister (SYS_CFGCTRL_WRITE, Function, Site, Position, Device, &Value);
221 }
222 
223 RETURN_STATUS
ArmPlatformSysConfigSetDevice(IN SYS_CONFIG_FUNCTION Function,IN UINT32 Device,IN UINT32 Value)224 ArmPlatformSysConfigSetDevice (
225   IN  SYS_CONFIG_FUNCTION   Function,
226   IN  UINT32                Device,
227   IN  UINT32                Value
228   )
229 {
230   UINT32          Site;
231   UINT32          Position;
232 
233   Position = 0;
234 
235   // Intercept some functions
236   switch(Function) {
237   case SYS_CFG_SCC:
238 #ifdef ARM_VE_SCC_BASE
239     if (EfiAtRuntime ()) {
240       return RETURN_UNSUPPORTED;
241     }
242     MmioWrite32 ((ARM_VE_SCC_BASE + (Device * 4)),Value);
243     return RETURN_SUCCESS;
244 #else
245     // There is no System Configuration Controller on the Model
246     return RETURN_UNSUPPORTED;
247 #endif
248 
249   case SYS_CFG_OSC_SITE1:
250     Function = SYS_CFG_OSC;
251     Site = ARM_VE_DAUGHTERBOARD_1_SITE;
252     break;
253 
254   case SYS_CFG_OSC_SITE2:
255     Function = SYS_CFG_OSC;
256     Site = ARM_VE_DAUGHTERBOARD_2_SITE;
257     break;
258 
259   case SYS_CFG_MUXFPGA:
260     Site = Value;
261     break;
262 
263   case SYS_CFG_RTC:
264     return RETURN_UNSUPPORTED;
265     //break;
266 
267   case SYS_CFG_OSC:
268   case SYS_CFG_VOLT:
269   case SYS_CFG_AMP:
270   case SYS_CFG_TEMP:
271   case SYS_CFG_RESET:
272   case SYS_CFG_SHUTDOWN:
273   case SYS_CFG_REBOOT:
274   case SYS_CFG_DVIMODE:
275   case SYS_CFG_POWER:
276     Site = ARM_VE_MOTHERBOARD_SITE;
277     break;
278   default:
279     return RETURN_UNSUPPORTED;
280   }
281 
282   return AccessSysCfgRegister (SYS_CFGCTRL_WRITE, Function, Site, Position, Device, &Value);
283 }
284