[Skiboot] [PATCH V4 4/6] chiptod: Sync timebase in both CAPP units on Naples

Philippe Bergheaud felix at linux.vnet.ibm.com
Fri Apr 1 23:27:59 AEDT 2016


Naples has two capp units. In chiptod_capp_timebase_sync, call
PHB3_CAPP_REG_OFFSET(p) to get the xscom register address offset,
an operate on the right capp unit.

Signed-off-by: Philippe Bergheaud <felix at linux.vnet.ibm.com>
---
V2:
  - Add reg_offset to CAPP_TB in chiptod_capp_timebase_sync
V3:
  - New signature chiptod_capp_timebase_sync(struct phb3 *p)
  - Use new macro PHB3_CAPP_REG_OFFSET(p)
  - s/reg_offset/offset/
V4:
  - No change

 hw/chiptod.c      | 41 +++++++++++++++++++++++------------------
 hw/phb3.c         |  2 +-
 include/chiptod.h |  3 ++-
 3 files changed, 26 insertions(+), 20 deletions(-)

diff --git a/hw/chiptod.c b/hw/chiptod.c
index f7427f1..58302fe 100644
--- a/hw/chiptod.c
+++ b/hw/chiptod.c
@@ -19,10 +19,12 @@
 #define pr_fmt(fmt)	"CHIPTOD: " fmt
 
 #include <skiboot.h>
+#include <xscom.h>
+#include <pci.h>
+#include <phb3.h>
 #include <chiptod.h>
 #include <chip.h>
 #include <capp.h>
-#include <xscom.h>
 #include <io.h>
 #include <cpu.h>
 #include <timebase.h>
@@ -1771,7 +1773,7 @@ void chiptod_init(void)
 
 /* CAPP timebase sync */
 
-static bool chiptod_capp_reset_tb_errors(uint32_t chip_id)
+static bool chiptod_capp_reset_tb_errors(uint32_t chip_id, uint32_t offset)
 {
 	uint64_t tfmr;
 	unsigned long timeout = 0;
@@ -1787,12 +1789,12 @@ static bool chiptod_capp_reset_tb_errors(uint32_t chip_id)
 	tfmr |= SPR_TFMR_TFMR_CORRUPT;
 
 	/* Write CAPP TFMR */
-	xscom_write(chip_id, CAPP_TFMR, tfmr);
+	xscom_write(chip_id, CAPP_TFMR + offset, tfmr);
 
 	/* We have to write "Clear TB Errors" again */
 	tfmr = base_tfmr | SPR_TFMR_CLEAR_TB_ERRORS;
 	/* Write CAPP TFMR */
-	xscom_write(chip_id, CAPP_TFMR, tfmr);
+	xscom_write(chip_id, CAPP_TFMR + offset, tfmr);
 
 	do {
 		if (++timeout >= TIMEOUT_LOOPS) {
@@ -1800,7 +1802,7 @@ static bool chiptod_capp_reset_tb_errors(uint32_t chip_id)
 			return false;
 		}
 		/* Read CAPP TFMR */
-		xscom_read(chip_id, CAPP_TFMR, &tfmr);
+		xscom_read(chip_id, CAPP_TFMR + offset, &tfmr);
 		if (tfmr & SPR_TFMR_TFMR_CORRUPT) {
 			prerror("CAPP: TB error reset: corrupt TFMR!\n");
 			return false;
@@ -1809,20 +1811,20 @@ static bool chiptod_capp_reset_tb_errors(uint32_t chip_id)
 	return true;
 }
 
-static bool chiptod_capp_mod_tb(uint32_t chip_id)
+static bool chiptod_capp_mod_tb(uint32_t chip_id, uint32_t offset)
 {
 	uint64_t timeout = 0;
 	uint64_t tfmr;
 
 	/* Switch CAPP timebase to "Not Set" state */
 	tfmr = base_tfmr | SPR_TFMR_LOAD_TOD_MOD;
-	xscom_write(chip_id, CAPP_TFMR, tfmr);
+	xscom_write(chip_id, CAPP_TFMR + offset, tfmr);
 	do {
 		if (++timeout >= (TIMEOUT_LOOPS*2)) {
 			prerror("CAPP: TB \"Not Set\" timeout\n");
 			return false;
 		}
-		xscom_read(chip_id, CAPP_TFMR, &tfmr);
+		xscom_read(chip_id, CAPP_TFMR + offset, &tfmr);
 		if (tfmr & SPR_TFMR_TFMR_CORRUPT) {
 			prerror("CAPP: TB \"Not Set\" TFMR corrupt\n");
 			return false;
@@ -1857,7 +1859,7 @@ static bool chiptod_wait_for_chip_sync(void)
 	return true;
 }
 
-static bool chiptod_capp_check_tb_running(uint32_t chip_id)
+static bool chiptod_capp_check_tb_running(uint32_t chip_id, uint32_t offset)
 {
 	uint64_t tfmr;
 	uint64_t timeout = 0;
@@ -1868,7 +1870,7 @@ static bool chiptod_capp_check_tb_running(uint32_t chip_id)
 			prerror("CAPP: TB Invalid!\n");
 			return false;
 		}
-		xscom_read(chip_id, CAPP_TFMR, &tfmr);
+		xscom_read(chip_id, CAPP_TFMR + offset, &tfmr);
 		if (tfmr & SPR_TFMR_TFMR_CORRUPT) {
 			prerror("CAPP: TFMR corrupt!\n");
 			return false;
@@ -1877,22 +1879,25 @@ static bool chiptod_capp_check_tb_running(uint32_t chip_id)
 	return true;
 }
 
-bool chiptod_capp_timebase_sync(uint32_t chip_id)
+bool chiptod_capp_timebase_sync(struct phb3 *p)
 {
 	uint64_t tfmr;
 	uint64_t capp_tb;
 	int64_t delta;
+	uint32_t offset;
 	unsigned int retry = 0;
 
+	offset = PHB3_CAPP_REG_OFFSET(p);
+
 	/* Set CAPP TFMR to base tfmr value */
-	xscom_write(chip_id, CAPP_TFMR, base_tfmr);
+	xscom_write(p->chip_id, CAPP_TFMR + offset, base_tfmr);
 
 	/* Reset CAPP TB errors before attempting the sync */
-	if (!chiptod_capp_reset_tb_errors(chip_id))
+	if (!chiptod_capp_reset_tb_errors(p->chip_id, offset))
 		return false;
 
 	/* Switch CAPP TB to "Not Set" state */
-	if (!chiptod_capp_mod_tb(chip_id))
+	if (!chiptod_capp_mod_tb(p->chip_id, offset))
 		return false;
 
 	/* Sync CAPP TB with core TB, retry while difference > 16usecs */
@@ -1904,19 +1909,19 @@ bool chiptod_capp_timebase_sync(uint32_t chip_id)
 
 		/* Make CAPP ready to get the TB, wait for chip sync */
 		tfmr = base_tfmr | SPR_TFMR_MOVE_CHIP_TOD_TO_TB;
-		xscom_write(chip_id, CAPP_TFMR, tfmr);
+		xscom_write(p->chip_id, CAPP_TFMR + offset, tfmr);
 		if (!chiptod_wait_for_chip_sync())
 			return false;
 
 		/* Set CAPP TB from core TB */
-		xscom_write(chip_id, CAPP_TB, mftb());
+		xscom_write(p->chip_id, CAPP_TB + offset, mftb());
 
 		/* Wait for CAPP TFMR tb_valid bit */
-		if (!chiptod_capp_check_tb_running(chip_id))
+		if (!chiptod_capp_check_tb_running(p->chip_id, offset))
 			return false;
 
 		/* Read CAPP TB, read core TB, compare */
-		xscom_read(chip_id, CAPP_TB, &capp_tb);
+		xscom_read(p->chip_id, CAPP_TB + offset, &capp_tb);
 		delta = mftb() - capp_tb;
 		if (delta < 0)
 			delta = -delta;
diff --git a/hw/phb3.c b/hw/phb3.c
index c44b0e4..8374584 100644
--- a/hw/phb3.c
+++ b/hw/phb3.c
@@ -3508,7 +3508,7 @@ static int64_t phb3_set_capi_mode(struct phb *phb, uint64_t mode,
 
 	phb3_init_capp_regs(p);
 
-	if (!chiptod_capp_timebase_sync(p->chip_id)) {
+	if (!chiptod_capp_timebase_sync(p)) {
 		PHBERR(p, "CAPP: Failed to sync timebase\n");
 		return OPAL_HARDWARE;
 	}
diff --git a/include/chiptod.h b/include/chiptod.h
index daf37b1..64df8bc 100644
--- a/include/chiptod.h
+++ b/include/chiptod.h
@@ -32,6 +32,7 @@ extern bool chiptod_wakeup_resync(void);
 extern int chiptod_recover_tb_errors(void);
 extern void chiptod_reset_tb(void);
 extern bool chiptod_adjust_topology(enum chiptod_topology topo, bool enable);
-extern bool chiptod_capp_timebase_sync(uint32_t chip_id);
+struct phb3;
+extern bool chiptod_capp_timebase_sync(struct phb3 *p);
 
 #endif /* __CHIPTOD_H */
-- 
2.1.0



More information about the Skiboot mailing list