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

Michael Neuling mikey at neuling.org
Wed Feb 10 11:57:02 AEDT 2016


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);


>  	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.

> +		/*
> +		* 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?

>  	}
> -	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