aboutsummaryrefslogtreecommitdiff
path: root/hw/chiptod.c
diff options
context:
space:
mode:
authorMahesh Salgaonkar <mahesh@linux.vnet.ibm.com>2015-06-05 23:37:28 +0530
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-07-09 16:12:03 +1000
commit9a5b78c6662ece62950064c216f5b05ec67f50c5 (patch)
treec3efa4d6a078db5f45949eea158055018f6680db /hw/chiptod.c
parentf52fac4ac03f97db5a6202fdb1eff4df505969d2 (diff)
downloadskiboot-9a5b78c6662ece62950064c216f5b05ec67f50c5.zip
skiboot-9a5b78c6662ece62950064c216f5b05ec67f50c5.tar.gz
skiboot-9a5b78c6662ece62950064c216f5b05ec67f50c5.tar.bz2
opal: Query chip TOD status for a given topology.
Query and update chip TOD status for both topologies. This helps to identify which chip TOD is active master and which one is backup master. During TOD error recovery this information will become very useful. Signed-off-by: Mahesh Salgaonkar <mahesh@linux.vnet.ibm.com> Signed-off-by: Stewart Smith <stewart@linux.vnet.ibm.com>
Diffstat (limited to 'hw/chiptod.c')
-rw-r--r--hw/chiptod.c41
1 files changed, 39 insertions, 2 deletions
diff --git a/hw/chiptod.c b/hw/chiptod.c
index 66e9d3b..ff35e6f 100644
--- a/hw/chiptod.c
+++ b/hw/chiptod.c
@@ -36,6 +36,8 @@
/* -- TOD primary/secondary master/slave status register -- */
#define TOD_STATUS 0x00040008
#define TOD_ST_TOPOLOGY_SELECT PPC_BITMASK(0, 2)
+#define TOD_ST_ACTIVE_MASTER PPC_BIT(23)
+#define TOD_ST_BACKUP_MASTER PPC_BIT(24)
/* TOD chip XSCOM addresses */
#define TOD_TTYPE_0 0x00040011
@@ -111,9 +113,15 @@ enum chiptod_chip_role {
chiptod_chip_role_SDST, /* Slave Drawer Slave TOD */
};
+enum chiptod_chip_status {
+ chiptod_active_master = 0, /* Chip TOD is Active master */
+ chiptod_backup_master = 1, /* Chip TOD is backup master */
+};
+
struct chiptod_chip_config_info {
int32_t id; /* chip id */
enum chiptod_chip_role role; /* Chip role */
+ enum chiptod_chip_status status; /* active/backup/disabled */
};
static int32_t chiptod_primary = -1;
@@ -143,10 +151,13 @@ static struct lock chiptod_lock = LOCK_UNLOCKED;
static void print_topo_info(enum chiptod_topology topo)
{
const char *role[] = { "Unknown", "MDMT", "MDST", "SDMT", "SDST" };
+ const char *status[] = { "Unknown",
+ "Active Master", "Backup Master", "Backup Master Disabled" };
- prlog(PR_DEBUG, "CHIPTOD: chip id: %d, Role: %s\n",
+ prlog(PR_DEBUG, "CHIPTOD: chip id: %d, Role: %s, Status: %s\n",
chiptod_topology_info[topo].id,
- role[chiptod_topology_info[topo].role + 1]);
+ role[chiptod_topology_info[topo].role + 1],
+ status[chiptod_topology_info[topo].status + 1]);
}
static void print_topology_info(void)
@@ -232,11 +243,37 @@ chiptod_get_chip_role(enum chiptod_topology topology, int32_t chip_id)
return role;
}
+static enum chiptod_chip_status _chiptod_get_chip_status(int32_t chip_id)
+{
+ uint64_t tod_status;
+ enum chiptod_chip_status status = -1;
+
+ if (xscom_read(chip_id, TOD_STATUS, &tod_status) != 0) {
+ prerror("CHIPTOD: XSCOM error reading TOD_STATUS reg\n");
+ goto out;
+ }
+
+ if (tod_status & TOD_ST_ACTIVE_MASTER)
+ status = chiptod_active_master;
+ else if (tod_status & TOD_ST_BACKUP_MASTER)
+ status = chiptod_backup_master;
+
+out:
+ return status;
+}
+
+static enum chiptod_chip_status
+chiptod_get_chip_status(enum chiptod_topology topology)
+{
+ return _chiptod_get_chip_status(chiptod_topology_info[topology].id);
+}
+
static void chiptod_update_topology(enum chiptod_topology topo)
{
int32_t chip_id = chiptod_topology_info[topo].id;
chiptod_topology_info[topo].role = chiptod_get_chip_role(topo, chip_id);
+ chiptod_topology_info[topo].status = chiptod_get_chip_status(topo);
}
static void chiptod_setup_base_tfmr(void)