[Skiboot] [PATCH V2 3/6] phb3: Set CAPI mode for both CAPP units on Naples

Philippe Bergheaud felix at linux.vnet.ibm.com
Tue Feb 23 00:16:59 AEDT 2016


Naples has two capp units. In phb3_init_capp_regs and phb3_set_capi_mode,
call CAPP_REG_OFFSET(phb_rev, phb_index) to get the xscom register address
offset, and operate on the right capp unit.

Signed-off-by: Philippe Bergheaud <felix at linux.vnet.ibm.com>
---
V2: after Mikey's review
  - Coding style reworked
  - Naples case moved to front in phb3_set_capi_mode

 hw/phb3.c | 84 ++++++++++++++++++++++++++++++++++++++++-----------------------
 1 file changed, 54 insertions(+), 30 deletions(-)

diff --git a/hw/phb3.c b/hw/phb3.c
index 087f3e0..30088c5 100644
--- a/hw/phb3.c
+++ b/hw/phb3.c
@@ -3295,10 +3295,12 @@ static int64_t phb3_get_diag_data(struct phb *phb,
 static void phb3_init_capp_regs(struct phb3 *p)
 {
 	uint64_t reg;
+	uint32_t reg_offset;
 
-	xscom_read(p->chip_id, APC_MASTER_PB_CTRL, &reg);
+	reg_offset = CAPP_REG_OFFSET(p->rev, p->index);
+	xscom_read(p->chip_id, APC_MASTER_PB_CTRL + reg_offset, &reg);
 	reg |= PPC_BIT(3);
-	xscom_write(p->chip_id, APC_MASTER_PB_CTRL, reg);
+	xscom_write(p->chip_id, APC_MASTER_PB_CTRL + reg_offset, reg);
 
 	/* Dynamically workout which PHB to connect to port 0 of the CAPP.
 	 * Here is the table from the CAPP workbook:
@@ -3317,27 +3319,38 @@ static void phb3_init_capp_regs(struct phb3 *p)
 	 *    PHB0 -> APC MASTER(bits 1:3) = 0b100
 	 *    PHB1 -> APC MASTER(bits 1:3) = 0b010
 	 *    PHB2 -> APC MASTER(bits 1:3) = 0b001
+	 *
+	 * Note: Naples has two CAPP units, statically mapped:
+	 *    CAPP0/PHB0 -> APC MASTER(bits 1:3) = 0b100
+	 *    CAPP1/PHB1 -> APC MASTER(bits 1:3) = 0b010
 	 */
 	reg = 0x4000000000000000ULL >> p->index;
 	reg |= 0x0070000000000000;
-	xscom_write(p->chip_id, APC_MASTER_CAPI_CTRL,reg);
+	xscom_write(p->chip_id, APC_MASTER_CAPI_CTRL + reg_offset, reg);
 	PHBINF(p, "CAPP: port attached\n");
 
 	/* tlb and mmio */
-	xscom_write(p->chip_id, TRANSPORT_CONTROL, 	0x4028000104000000);
+	xscom_write(p->chip_id, TRANSPORT_CONTROL + reg_offset,
+		    0x4028000104000000);
 
-	xscom_write(p->chip_id, CANNED_PRESP_MAP0, 	0);
-	xscom_write(p->chip_id, CANNED_PRESP_MAP1, 	0xFFFFFFFF00000000);
-	xscom_write(p->chip_id, CANNED_PRESP_MAP2, 	0);
+	xscom_write(p->chip_id, CANNED_PRESP_MAP0 + reg_offset, 0);
+	xscom_write(p->chip_id, CANNED_PRESP_MAP1 + reg_offset,
+		    0xFFFFFFFF00000000);
+	xscom_write(p->chip_id, CANNED_PRESP_MAP2 + reg_offset, 0);
 
 	/* error recovery */
-	xscom_write(p->chip_id, CAPP_ERR_STATUS_CTRL,  	0);
-
-	xscom_write(p->chip_id, FLUSH_SUE_STATE_MAP,   	0x1DC20B6600000000);
-	xscom_write(p->chip_id, CAPP_EPOCH_TIMER_CTRL, 	0xC0000000FFF0FFE0);
-	xscom_write(p->chip_id, FLUSH_UOP_CONFIG1, 	0xB188280728000000);
-	xscom_write(p->chip_id, FLUSH_UOP_CONFIG2, 	0xB188400F00000000);
-	xscom_write(p->chip_id, SNOOP_CAPI_CONFIG, 	0xA1F0000000000000);
+	xscom_write(p->chip_id, CAPP_ERR_STATUS_CTRL + reg_offset, 0);
+
+	xscom_write(p->chip_id, FLUSH_SUE_STATE_MAP + reg_offset,
+		    0x1DC20B6600000000);
+	xscom_write(p->chip_id, CAPP_EPOCH_TIMER_CTRL + reg_offset,
+		    0xC0000000FFF0FFE0);
+	xscom_write(p->chip_id,  FLUSH_UOP_CONFIG1 + reg_offset,
+		    0xB188280728000000);
+	xscom_write(p->chip_id, FLUSH_UOP_CONFIG2 + reg_offset,
+		    0xB188400F00000000);
+	xscom_write(p->chip_id, SNOOP_CAPI_CONFIG + reg_offset,
+		    0xA1F0000000000000);
 }
 
 /* override some inits with CAPI defaults */
@@ -3355,6 +3368,7 @@ static int64_t phb3_set_capi_mode(struct phb *phb, uint64_t mode,
 	struct phb3 *p = phb_to_phb3(phb);
 	struct proc_chip *chip = get_chip(p->chip_id);
 	uint64_t reg;
+	uint32_t reg_offset;
 	int i;
 	u8 mask;
 
@@ -3363,23 +3377,30 @@ static int64_t phb3_set_capi_mode(struct phb *phb, uint64_t mode,
 		return OPAL_RESOURCE;
 	}
 
-	/*
-	 * Check if CAPP port is being used by any another PHB.
-	 * Check and set chip->capp_phb3_attached_mask atomically incase
-	 * two phb3_set_capi_mode() calls race.
-	 */
 	lock(&capi_lock);
-	mask = ~(1 << p->index);
-	if (chip->capp_phb3_attached_mask & mask) {
-		PHBERR(p, "CAPP: port already in use by another PHB:%x\n",
-			chip->capp_phb3_attached_mask);
-		unlock(&capi_lock);
-		return false;
+	if (p->rev == PHB3_REV_NAPLES_DD10) {
+		/* Naples has two CAPP units, statically mapped. */
+		chip->capp_phb3_attached_mask |= 1 << p->index;
+	} else {
+		/*
+		* Check if CAPP port is being used by any another PHB.
+		* Check and set chip->capp_phb3_attached_mask atomically
+		* incase two phb3_set_capi_mode() calls race.
+		*/
+		mask = ~(1 << p->index);
+		if (chip->capp_phb3_attached_mask & mask) {
+			PHBERR(p,
+			       "CAPP: port already in use by another PHB:%x\n",
+			       chip->capp_phb3_attached_mask);
+			       unlock(&capi_lock);
+			return false;
+		}
+		chip->capp_phb3_attached_mask = 1 << p->index;
 	}
-	chip->capp_phb3_attached_mask = 1 << p->index;
 	unlock(&capi_lock);
 
-	xscom_read(p->chip_id, CAPP_ERR_STATUS_CTRL, &reg);
+	reg_offset = CAPP_REG_OFFSET(p->rev, p->index);
+	xscom_read(p->chip_id, CAPP_ERR_STATUS_CTRL + reg_offset, &reg);
 	if ((reg & PPC_BIT(5))) {
 		PHBERR(p, "CAPP: recovery failed (%016llx)\n", reg);
 		return OPAL_HARDWARE;
@@ -3392,13 +3413,16 @@ static int64_t phb3_set_capi_mode(struct phb *phb, uint64_t mode,
 		return OPAL_UNSUPPORTED;
 
 	if (mode == OPAL_PHB_CAPI_MODE_SNOOP_OFF) {
-		xscom_write(p->chip_id, SNOOP_CAPI_CONFIG, 	0x0000000000000000);
+		xscom_write(p->chip_id, SNOOP_CAPI_CONFIG + reg_offset,
+			    0x0000000000000000);
 		return OPAL_SUCCESS;
 	}
 
 	if (mode == OPAL_PHB_CAPI_MODE_SNOOP_ON) {
-		xscom_write(p->chip_id, CAPP_ERR_STATUS_CTRL,  	0x0000000000000000);
-		xscom_write(p->chip_id, SNOOP_CAPI_CONFIG, 	0xA1F0000000000000);
+		xscom_write(p->chip_id, CAPP_ERR_STATUS_CTRL + reg_offset,
+			    0x0000000000000000);
+		xscom_write(p->chip_id, SNOOP_CAPI_CONFIG + reg_offset,
+			    0xA1F0000000000000);
 		return OPAL_SUCCESS;
 	}
 
-- 
2.1.0



More information about the Skiboot mailing list