summaryrefslogtreecommitdiff
path: root/cpu/amd/geode_lx/gplvsa_ii/lxvg/msr.c
diff options
context:
space:
mode:
Diffstat (limited to 'cpu/amd/geode_lx/gplvsa_ii/lxvg/msr.c')
-rwxr-xr-xcpu/amd/geode_lx/gplvsa_ii/lxvg/msr.c305
1 files changed, 305 insertions, 0 deletions
diff --git a/cpu/amd/geode_lx/gplvsa_ii/lxvg/msr.c b/cpu/amd/geode_lx/gplvsa_ii/lxvg/msr.c
new file mode 100755
index 0000000..65c40d9
--- /dev/null
+++ b/cpu/amd/geode_lx/gplvsa_ii/lxvg/msr.c
@@ -0,0 +1,305 @@
+/*
+* Copyright (c) 2007-2008 Advanced Micro Devices,Inc. ("AMD").
+*
+* This library is free software; you can redistribute it and/or modify
+* it under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of the
+* License, or (at your option) any later version.
+*
+* This code is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+
+* You should have received a copy of the GNU Lesser General
+* Public License along with this library; if not, write to the
+* Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+* Boston, MA 02111-1307 USA
+*/
+
+
+
+
+#include "lxvg.h"
+#include "vsa2.h"
+
+#define FOUND 0
+#define UNKNOWN 1
+#define REQ_NOT_FOUND 2
+
+struct tagMSR msrDev[] = {
+ { UNKNOWN, ID_MCP, FAKE_ADDRESS },
+ { UNKNOWN, ID_MC, FAKE_ADDRESS },
+ { UNKNOWN, ID_GP, FAKE_ADDRESS },
+ { UNKNOWN, ID_VG, FAKE_ADDRESS },
+ { UNKNOWN, ID_DF, FAKE_ADDRESS },
+ { UNKNOWN, ID_VIP, FAKE_ADDRESS } };
+// DEBUG
+// { UNKNOWN, ID_MBIU, FAKE_ADDRESS } };
+// DEBUG
+
+#define NUM_DEVS sizeof(msrDev) / sizeof(struct tagMSR)
+
+
+//=================================================================
+// BOOL msrInit(void)
+//
+// Handles the details of finding each possible device on the MBUS.
+// If a given device is not found, its structure is left inited at default.
+// If a given device is found, its structure is updated.
+//
+// This init routine only checks for devices already in the structure.
+//
+// Returns:
+// TRUE - If, for every device, its address was found.
+// FALSE - If, for any device, an error was encountered.
+//
+
+unsigned char msrInit(void)
+{
+ unsigned short issues=0, i;
+
+ //
+ // For each item in the list, try to find its address
+ //
+ for (i=0; i < NUM_DEVS; i++)
+ {
+ msrDev[i].Present = msrFindDevice(&msrDev[i]);
+ if (msrDev[i].Present != FOUND) issues++;
+ }
+
+ if (issues) return(FALSE);
+
+/*
+ //
+ // For each item in the list, get its real device ID
+ //
+ for (i=0; i < NUM_DEVS; i++)
+ msrDev[i].Id = msrIdDevice(msrDev[i].Address);
+*/
+ return(TRUE);
+
+}
+
+
+//=================================================================
+// unsigned short msrFindDevice(struct msr *pDev)
+//
+// Returns:
+// FOUND - if no errors were detected. msrAddress has been updated.
+// REQ_NOT_FOUND - Address for 'devId' is unknown. Caller should
+// call msrInit() first. ptr->Address is not updated.
+//
+// NOTE: The structure default for the 'Present' field is "UNKNOWN".
+// Therefore, if a given id is passed to msrFindDevice, the 'Present'
+// field will be updated with either 'FOUND' or 'REQ_NOT_FOUND'. If
+// a given ID is not passed to msrFindDevice, the 'Present' field will
+// be left as 'UNKNOWN'.
+//
+
+unsigned short msrFindDevice(struct tagMSR *pDev)
+{
+ unsigned long msrAdr;
+ msrAdr = SYS_LOOKUP_DEVICE(pDev->Id,1);
+ if (0 != msrAdr)
+ {
+ pDev->Routing = msrAdr;
+ return(FOUND);
+ }
+
+ // All done...
+ return(REQ_NOT_FOUND);
+}
+
+
+//=================================================================
+// unsigned short msrIdDevice(unsigned long address)
+//
+// Reads the capabilities MSR register (typically 0x2000)
+// and returns the 'id' field (bits 23:8)
+//
+// Returns:
+// Bits 23:8 of MSR low DWORD
+//
+
+unsigned short msrIdDevice(unsigned long address)
+{
+ struct mValue msrValue;
+
+ asmRead(MBD_MSR_CAP, address, &msrValue.high, &msrValue.low);
+
+ return((unsigned short)((msrValue.low & DEVID_MASK) >> 8));
+
+}
+
+
+//=================================================================
+// unsigned short msrRead(unsigned short msrIdx, unsigned short msrReg, struct mValue msrValue)
+//
+// Performs a 64-bit read from 'msrReg' in device 'devID'.
+//
+// Returns:
+// FOUND - if no errors were detected and msrValue has been updated.
+// UNKNOWN - an error was detected. msrValue is not updated.
+// REQ_NOT_FOUND - 'msrAddress' for 'devID' is unknown. Caller
+// should call msrInit() first. msrValue is not updated.
+//
+
+unsigned short msrRead(unsigned short msrIdx, unsigned short msrReg, struct mValue *msrValue)
+{
+
+ if (msrDev[msrIdx].Present == FOUND) {
+ asmRead(msrReg, msrDev[msrIdx].Routing, &msrValue->high, &msrValue->low);
+ }
+
+ return (msrDev[msrIdx].Present);
+
+}
+
+
+//=================================================================
+// unsigned short msrWrite(unsigned short msrIdx, unsigned short msrReg, unsigned long outHi, unsigned long outLo)
+//
+// Performs a 64-bit write to 'msrReg' in device 'devID'.
+//
+// Returns:
+// FOUND - if no errors were detected and msrValue has been updated.
+// UNKNOWN - an error was detected. msrValue is not updated.
+// REQ_NOT_FOUND - 'msrAddress' for 'devID' is unknown. Caller
+// should call msrInit() first. msrValue is not updated.
+//
+
+unsigned short msrWrite(unsigned short msrIdx, unsigned short msrReg, unsigned long outHi, unsigned long outLo)
+{
+ struct mValue mVal;
+
+ if (msrDev[msrIdx].Present == FOUND) {
+ // Incorporate the OR values
+ mVal.high = outHi;
+ mVal.low = outLo;
+
+ asmWrite(msrReg, msrDev[msrIdx].Routing, &mVal.high, &mVal.low);
+ }
+
+ return (msrDev[msrIdx].Present);
+
+}
+
+
+//=================================================================
+// void msrModify(unsigned short msrIdx, unsigned short msrReg, unsigned long maskHi, unsigned long maskLo,
+// unsigned long orHi, unsigned long orLo)
+//
+// Performs a 64-bit read-modify-write of 'msrReg' in device 'msrIdx'.
+// The mask values indicate the bits that are to be changed, so the
+// register values are ANDed with the NOT of the mask values to clear
+// out the affected bits.
+//
+// Returns:
+// NONE
+//
+
+void msrModify(unsigned short msrIdx, unsigned short msrReg, unsigned long maskHi, unsigned long maskLo, unsigned long orHi, unsigned long orLo)
+{
+ struct mValue mVal;
+
+ if (msrDev[msrIdx].Present == FOUND) {
+ asmRead(msrReg, msrDev[msrIdx].Routing, &mVal.high, &mVal.low);
+
+ // Incorporate the AND values
+ mVal.high &= ~maskHi;
+ mVal.low &= ~maskLo;
+
+ // Incorporate the OR values
+ mVal.high |= orHi;
+ mVal.low |= orLo;
+
+ asmWrite(msrReg, msrDev[msrIdx].Routing, &mVal.high, &mVal.low);
+ }
+
+ return;
+
+}
+
+
+//=================================================================
+// void msrSave(unsigned short msrIdx, unsigned short *msrList[], struct mValue *msrValue[])
+//
+// Saves a list of MSRs limited by an index value of 0xFFFF.
+//
+//
+
+void msrSave(unsigned short msrIdx, unsigned short *msrList, struct mValue *msrValue)
+{
+ unsigned char finished = FALSE;
+ unsigned char i = 0;
+
+ if (msrDev[msrIdx].Present == FOUND)
+ {
+ while (FALSE == finished)
+ {
+ if (0xFFFF == msrList[i])
+ finished = TRUE;
+ else
+ {
+ asmRead(msrList[i], msrDev[msrIdx].Routing, &msrValue[i].high, &msrValue[i].low);
+ i++;
+ }
+ }
+ }
+
+ return;
+
+}
+
+
+//=================================================================
+// void msrRestore(unsigned short msrIdx, unsigned short *msrList[], struct mValue *msrValue[])
+//
+// Restores a previously saved list of MSRs limited by an index value of 0xFFFF.
+//
+//
+
+void msrRestore(unsigned short msrIdx, unsigned short *msrList, struct mValue *msrValue)
+{
+ unsigned char finished = FALSE;
+ unsigned char i = 0;
+
+ if (msrDev[msrIdx].Present == FOUND)
+ {
+ while (FALSE == finished)
+ {
+ if (0xFFFF == msrList[i])
+ finished = TRUE;
+ else
+ {
+ asmWrite(msrList[i], msrDev[msrIdx].Routing, &msrValue[i].high, &msrValue[i].low);
+ i++;
+ }
+ }
+ }
+
+ return;
+
+}
+
+
+//=================================================================
+// void msrDump(unsigned short msrIdx, unsigned short msrReg)
+//
+// Performs a 64-bit read of 'msrReg' in device 'msrIdx' for debug.
+//
+// Returns:
+// NONE
+//
+
+void msrDump(unsigned short msrIdx, unsigned short msrReg)
+{
+ struct mValue mVal;
+
+ asmRead(msrReg, msrDev[msrIdx].Routing, &mVal.high, &mVal.low);
+
+ return;
+
+}
+