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
49RETURN_STATUS
50ArmPlatformSysConfigInitialize (
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
66RETURN_STATUS
67AccessSysCfgRegister (
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
111RETURN_STATUS
112ArmPlatformSysConfigGet (
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
162RETURN_STATUS
163ArmPlatformSysConfigGetValues (
164  IN  SYS_CONFIG_FUNCTION   Function,
165  IN  UINTN                 Size,
166  OUT UINT32*               Values
167  )
168{
169  return RETURN_UNSUPPORTED;
170}
171
172RETURN_STATUS
173ArmPlatformSysConfigSet (
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
223RETURN_STATUS
224ArmPlatformSysConfigSetDevice (
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