summaryrefslogtreecommitdiffstats
path: root/hw/chiptod.c
diff options
context:
space:
mode:
authorMahesh Salgaonkar <mahesh@linux.vnet.ibm.com>2015-06-05 23:37:38 +0530
committerStewart Smith <stewart@linux.vnet.ibm.com>2015-07-09 16:12:59 +1000
commit23d192639b961fe2d1e6ef190e3d72b939984fd1 (patch)
treeca2a387fda8c4955a6bbf64cddd0953d3bed259b /hw/chiptod.c
parent9a5b78c6662ece62950064c216f5b05ec67f50c5 (diff)
downloadblackbird-skiboot-23d192639b961fe2d1e6ef190e3d72b939984fd1.tar.gz
blackbird-skiboot-23d192639b961fe2d1e6ef190e3d72b939984fd1.zip
opal: Introduce a function to check sync/step network status.
Introduce a function to check sync/step network status for a given topology. During chiptod initialization, check sync/step network status for backup topology to find out whether backup topology is enabled or disabled and update the topology info accordingly. In the subsequent patches this function will also be used for one of the checks to detect whether topology switch is required for TOD failure recovery. 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.c116
1 files changed, 116 insertions, 0 deletions
diff --git a/hw/chiptod.c b/hw/chiptod.c
index ff35e6fc..180e138c 100644
--- a/hw/chiptod.c
+++ b/hw/chiptod.c
@@ -36,6 +36,16 @@
/* -- TOD primary/secondary master/slave status register -- */
#define TOD_STATUS 0x00040008
#define TOD_ST_TOPOLOGY_SELECT PPC_BITMASK(0, 2)
+#define TOD_ST_MPATH0_STEP_VALID PPC_BIT(6) /* MasterPath0 step valid */
+#define TOD_ST_MPATH1_STEP_VALID PPC_BIT(7) /* MasterPath1 step valid */
+#define TOD_ST_SPATH0_STEP_VALID PPC_BIT(8) /* SlavePath0 step valid */
+#define TOD_ST_SPATH1_STEP_VALID PPC_BIT(10) /* SlavePath1 step valid */
+/* Primary master/slave path select (0 = PATH_0, 1 = PATH_1) */
+#define TOD_ST_PRI_MPATH_SELECT PPC_BIT(12) /* Primary MPath Select */
+#define TOD_ST_PRI_SPATH_SELECT PPC_BIT(15) /* Primary SPath Select */
+/* Secondary master/slave path select (0 = PATH_0, 1 = PATH_1) */
+#define TOD_ST_SEC_MPATH_SELECT PPC_BIT(16) /* Secondary MPath Select */
+#define TOD_ST_SEC_SPATH_SELECT PPC_BIT(19) /* Secondary SPath Select */
#define TOD_ST_ACTIVE_MASTER PPC_BIT(23)
#define TOD_ST_BACKUP_MASTER PPC_BIT(24)
@@ -116,6 +126,7 @@ enum chiptod_chip_role {
enum chiptod_chip_status {
chiptod_active_master = 0, /* Chip TOD is Active master */
chiptod_backup_master = 1, /* Chip TOD is backup master */
+ chiptod_backup_disabled, /* Chip TOD is backup but disabled */
};
struct chiptod_chip_config_info {
@@ -243,6 +254,102 @@ chiptod_get_chip_role(enum chiptod_topology topology, int32_t chip_id)
return role;
}
+/*
+ * Check and return the status of sync step network for a given
+ * topology configuration.
+ * Return values:
+ * true: Sync Step network is running
+ * false: Sync Step network is not running
+ */
+static bool chiptod_sync_step_check_running(enum chiptod_topology topology)
+{
+ uint64_t tod_status;
+ enum chiptod_chip_role role;
+ bool running = false;
+ int32_t chip_id = chiptod_topology_info[topology].id;
+
+ /* Sanity check */
+ if (chip_id < 0)
+ return false;
+
+ if (xscom_read(chip_id, TOD_STATUS, &tod_status) != 0) {
+ prerror("CHIPTOD: XSCOM error reading TOD_STATUS reg\n");
+ return false;
+ }
+
+ switch (topology) {
+ case chiptod_topo_primary:
+ /* Primary configuration */
+ role = chiptod_topology_info[topology].role;
+ if (role == chiptod_chip_role_MDMT) {
+ /*
+ * Chip is using Master path.
+ * Check if it is using path_0/path_1 and then
+ * validity of that path.
+ *
+ * TOD_STATUS[12]: 0 = PATH_0, 1 = PATH_1
+ */
+ if (tod_status & TOD_ST_PRI_MPATH_SELECT) {
+ if (tod_status & TOD_ST_MPATH1_STEP_VALID)
+ running = true;
+ } else {
+ if (tod_status & TOD_ST_MPATH0_STEP_VALID)
+ running = true;
+ }
+ } else {
+ /*
+ * Chip is using Slave path.
+ *
+ * TOD_STATUS[15]: 0 = PATH_0, 1 = PATH_1
+ */
+ if (tod_status & TOD_ST_PRI_SPATH_SELECT) {
+ if (tod_status & TOD_ST_SPATH1_STEP_VALID)
+ running = true;
+ } else {
+ if (tod_status & TOD_ST_SPATH0_STEP_VALID)
+ running = true;
+ }
+ }
+ break;
+ case chiptod_topo_secondary:
+ /* Secondary configuration */
+ role = chiptod_topology_info[topology].role;
+ if (role == chiptod_chip_role_MDMT) {
+ /*
+ * Chip is using Master path.
+ * Check if it is using path_0/path_1 and then
+ * validity of that path.
+ *
+ * TOD_STATUS[12]: 0 = PATH_0, 1 = PATH_1
+ */
+ if (tod_status & TOD_ST_SEC_MPATH_SELECT) {
+ if (tod_status & TOD_ST_MPATH1_STEP_VALID)
+ running = true;
+ } else {
+ if (tod_status & TOD_ST_MPATH0_STEP_VALID)
+ running = true;
+ }
+ } else {
+ /*
+ * Chip is using Slave path.
+ *
+ * TOD_STATUS[15]: 0 = PATH_0, 1 = PATH_1
+ */
+ if (tod_status & TOD_ST_SEC_SPATH_SELECT) {
+ if (tod_status & TOD_ST_SPATH1_STEP_VALID)
+ running = true;
+ } else {
+ if (tod_status & TOD_ST_SPATH0_STEP_VALID)
+ running = true;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+ return running;
+}
+
static enum chiptod_chip_status _chiptod_get_chip_status(int32_t chip_id)
{
uint64_t tod_status;
@@ -274,6 +381,15 @@ static void chiptod_update_topology(enum chiptod_topology topo)
chiptod_topology_info[topo].role = chiptod_get_chip_role(topo, chip_id);
chiptod_topology_info[topo].status = chiptod_get_chip_status(topo);
+
+ /*
+ * If chip TOD on this topology is a backup master then check if
+ * sync/step network is running on this topology. If not,
+ * then mark status as backup not valid.
+ */
+ if ((chiptod_topology_info[topo].status == chiptod_backup_master) &&
+ !chiptod_sync_step_check_running(topo))
+ chiptod_topology_info[topo].status = chiptod_backup_disabled;
}
static void chiptod_setup_base_tfmr(void)
OpenPOWER on IntegriCloud