[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_offset = CAPP_REG_OFFSET(p->rev, p->index);
>>+ addr = APC_MASTER_PB_CTRL + reg_offset;
>>+ xscom_read(p->chip_id, addr, ®);
>> 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_offset = CAPP_REG_OFFSET(p->rev, p->index);
>>+ addr = CAPP_ERR_STATUS_CTRL + reg_offset;
>>+ xscom_read(p->chip_id, addr, ®);
>> 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