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

Philippe Bergheaud felix at linux.vnet.ibm.com
Fri Feb 12 00:22:13 AEDT 2016


Michael Neuling wrote:
> On Mon, 2016-02-08 at 16:30 +0100, Philippe Bergheaud wrote:
> 
> 
>>In phb3_init_capp_regs and phb3_set_capi_mode, check for phb3
>>revision,
>>and write to the scoms registers of the targeted capp.
>>
>>Signed-off-by: Philippe Bergheaud <felix at linux.vnet.ibm.com>
>>---
>> hw/phb3.c | 94 +++++++++++++++++++++++++++++++++++++++++------------
>>----------
>> 1 file changed, 61 insertions(+), 33 deletions(-)
>>
>>diff --git a/hw/phb3.c b/hw/phb3.c
>>index e4f131d..3ec14f3 100644
>>--- a/hw/phb3.c
>>+++ b/hw/phb3.c
>>@@ -3290,11 +3290,14 @@ static int64_t phb3_get_diag_data(struct phb
>>*phb,
>> 
>> static void phb3_init_capp_regs(struct phb3 *p)
>> {
>>-	uint64_t reg;
>>+	uint64_t addr, reg;
>>+	uint32_t reg_offset;
>> 
>>-	xscom_read(p->chip_id, APC_MASTER_PB_CTRL, &reg);
>>+	reg_offset = CAPP_REG_OFFSET(p->rev, p->index);
>>+	addr = APC_MASTER_PB_CTRL + reg_offset;
>>+	xscom_read(p->chip_id, addr, &reg);
>> 	reg |= PPC_BIT(3);
>>-	xscom_write(p->chip_id, APC_MASTER_PB_CTRL, reg);
>>+	xscom_write(p->chip_id, addr, reg);
>> 
>> 	/* Dynamically workout which PHB to connect to port 0 of the
>>CAPP.
>> 	 * Here is the table from the CAPP workbook:
>>@@ -3313,27 +3316,40 @@ 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);
>>+	addr = APC_MASTER_CAPI_CTRL + reg_offset;
>>+	xscom_write(p->chip_id, addr, reg);
> 
> 
> Again, I'd prefer just
> 
> 	xscom_write(p->chip_id, APC_MASTER_CAPI_CTRL + off, reg);
>  
Agreed.
> 
>> 	PHBINF(p, "CAPP: port attached\n");
>> 
>> 	/* tlb and mmio */
>>-	xscom_write(p->chip_id, TRANSPORT_CONTROL, 	0x4028000
>>104000000);
>>-
>>-	xscom_write(p->chip_id, CANNED_PRESP_MAP0, 	0);
>>-	xscom_write(p->chip_id, CANNED_PRESP_MAP1, 	0xFFFFFFF
>>F00000000);
>>-	xscom_write(p->chip_id, CANNED_PRESP_MAP2, 	0);
>>+	addr = TRANSPORT_CONTROL + reg_offset;
>>+	xscom_write(p->chip_id, addr, 0x4028000104000000);
>>+	addr = CANNED_PRESP_MAP0 + reg_offset;
>>+	xscom_write(p->chip_id, addr, 0);
>>+	addr = CANNED_PRESP_MAP1 + reg_offset;
>>+	xscom_write(p->chip_id, addr, 0xFFFFFFFF00000000);
>>+	addr = CANNED_PRESP_MAP2 + reg_offset;
>>+	xscom_write(p->chip_id, addr, 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);
>>+	addr = CAPP_ERR_STATUS_CTRL + reg_offset;
>>+	xscom_write(p->chip_id, addr, 0);
>>+	addr = FLUSH_SUE_STATE_MAP + reg_offset;
>>+	xscom_write(p->chip_id, addr, 0x1DC20B6600000000);
>>+	addr = CAPP_EPOCH_TIMER_CTRL + reg_offset;
>>+	xscom_write(p->chip_id, addr, 0xC0000000FFF0FFE0);
>>+	addr = FLUSH_UOP_CONFIG1 + reg_offset;
>>+	xscom_write(p->chip_id, addr, 0xB188280728000000);
>>+	addr = FLUSH_UOP_CONFIG2 + reg_offset;
>>+	xscom_write(p->chip_id, addr, 0xB188400F00000000);
>>+	addr = SNOOP_CAPI_CONFIG + reg_offset;
>>+	xscom_write(p->chip_id, addr, 0xA1F0000000000000);
>> }
>> 
>> /* override some inits with CAPI defaults */
>>@@ -3350,7 +3366,8 @@ 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;
>>+	uint64_t addr, reg;
>>+	uint32_t reg_offset;
>> 	int i;
>> 	u8 mask;
>> 
>>@@ -3359,23 +3376,31 @@ 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) {
> 
> 
> Make this (p->rev == PHB3_REV_NAPLES_DD10) and do the naples one first.
> 
Yes.
> 
>>+		/*
>>+		* 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;
>>+	} else {
>>+		/* Naples has two CAPP units, statically mapped. */
>>+		chip->capp_phb3_attached_mask |= 1 << p->index;
> 
> 
> 
> Naples has 4 phbs (2 for nvdia), so do you need to check for p->index
> < 2 here as well and return false if so?
> 
I think that we do not need to check p->index here. If the phb were for nvidia,
then phb3_set_capi_mode would return immediately after the first test:

	if (!CAPP_UCODE_LOADED(chip, p)) {
		PHBERR(p, "CAPP: ucode not loaded\n");
		return OPAL_RESOURCE;
	}

Philippe
> 
>> 	}
>>-	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);
>>+	addr = CAPP_ERR_STATUS_CTRL + reg_offset;
>>+	xscom_read(p->chip_id, addr, &reg);
>> 	if ((reg & PPC_BIT(5))) {
>> 		PHBERR(p, "CAPP: recovery failed (%016llx)\n", reg);
>> 		return OPAL_HARDWARE;
>>@@ -3388,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, 	0
>>x0000000000000000);
>>+		addr = SNOOP_CAPI_CONFIG + reg_offset;
>>+		xscom_write(p->chip_id, addr, 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, 	0
>>xA1F0000000000000);
>>+		addr = CAPP_ERR_STATUS_CTRL + reg_offset;
>>+		xscom_write(p->chip_id, addr, 0x0000000000000000);
>>+		addr = SNOOP_CAPI_CONFIG + reg_offset;
>>+		xscom_write(p->chip_id, addr, 0xA1F0000000000000);
>> 		return OPAL_SUCCESS;
>> 	}
>> 
> 
> 



More information about the Skiboot mailing list