From patchwork Thu Apr 18 01:26:58 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rashmica Gupta X-Patchwork-Id: 1087335 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 44l1gR1HJqz9s9h for ; Thu, 18 Apr 2019 11:27:31 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="EeOngrEt"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 44l1gR05vKzDqPl for ; Thu, 18 Apr 2019 11:27:31 +1000 (AEST) X-Original-To: pdbg@lists.ozlabs.org Delivered-To: pdbg@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::644; helo=mail-pl1-x644.google.com; envelope-from=rashmica.g@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="EeOngrEt"; dkim-atps=neutral Received: from mail-pl1-x644.google.com (mail-pl1-x644.google.com [IPv6:2607:f8b0:4864:20::644]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 44l1gG0mZzzDqPQ for ; Thu, 18 Apr 2019 11:27:21 +1000 (AEST) Received: by mail-pl1-x644.google.com with SMTP id ck15so343468plb.3 for ; Wed, 17 Apr 2019 18:27:21 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=1pEDHnG8a8Fi1Mx+OKNhSnEDqc+DqnZ7ohi0E8yyz+g=; b=EeOngrEt1urIUBFVp9RrtoQVGm6oOpSBC+gwhAbCdwgmuiHk7ShT4GlepKCoFlZVF+ 8whA97f692kuXW6rbdyPtDWcz5BAm3YTSz78cBpBcoKBd2D5lwt/e+e+AveiHYWov70O wsnzJqFgJ4XyD4KFAmYUzhGyuJ6jCb7FFC4EY7oeZ0bfEkmgQKfMKJF1oANYL3m47eD9 JyeweKaTACAxE4O6NxeCtP1EHvYvJD6YhJXNRs1dsgTUNGznM1S+3/wVTX7manYTOFVs fIP2X9GQnXeM3kADCYa7fk2Qw+bHlCsn49DjCUsrnQMP+CmEfNNDeYZdCWmFaxuVLqab Qu8w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=1pEDHnG8a8Fi1Mx+OKNhSnEDqc+DqnZ7ohi0E8yyz+g=; b=mIm3L6BFMDyth5R9GEoJ5/qu+ViUT7PiS2ZSq8aF6DJdw7xNE/aYUkreNI23NGV+Kb CIcyv39NS6QW9hE24oOHad3IpTJvT/oJtelExmk9tnhXufRghoXX136pmZJWMLJc1QIQ BhR1dkh7IkTXmL0fzhklcXaTzqMzJkk9tbfFMaOOqhThxn5OadHAUJenFuRHp3atjcxQ 8MOn3+XMASbCWFQXjDM7U1o1EgIm3Tsq25WHihtr+52vPyp0/R5kBnU8Ra6HU3sSphAq PdbqIgCY5YkY+28kecPp4QFzB4Q/3jOLcbYQJJGbNqX+8hlBN+aso74gXkgkX8FMPYfm zdAQ== X-Gm-Message-State: APjAAAV//R6Da6THJsEKFE9Vf6lMOp326GwfNSNisyW9LgANQMQRu+PI gvrEl9NSo8eb/BunJxuUWNCjGks5 X-Google-Smtp-Source: APXvYqy+zKb7e/FaJ7wOixic2cASeJEQqXHONVlBLJmOsP/MVJ8CUEgJiDRuvqIfGxXbjB43cScw7Q== X-Received: by 2002:a17:902:1101:: with SMTP id d1mr75716404pla.16.1555550839388; Wed, 17 Apr 2019 18:27:19 -0700 (PDT) Received: from rashmica.ozlabs.ibm.com ([122.99.82.10]) by smtp.gmail.com with ESMTPSA id j62sm610585pfg.6.2019.04.17.18.27.17 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 17 Apr 2019 18:27:18 -0700 (PDT) From: Rashmica Gupta To: pdbg@lists.ozlabs.org, alistair@popple.id.au, joel@jms.id.au Date: Thu, 18 Apr 2019 11:26:58 +1000 Message-Id: <20190418012658.23315-5-rashmica.g@gmail.com> X-Mailer: git-send-email 2.17.2 In-Reply-To: <20190418012658.23315-1-rashmica.g@gmail.com> References: <20190418012658.23315-1-rashmica.g@gmail.com> Subject: [Pdbg] [PATCH v2 4/4] libpdbg: Add i2c get and put for i2c masters on the PIB X-BeenThere: pdbg@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "mailing list for https://github.com/open-power/pdbg development" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: pdbg-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Pdbg" This enables the basic i2c functions from the host. Signed-off-by: Rashmica Gupta --- libpdbg/i2cm.c | 187 +++++++++++++++++++++++++++++++++++++++++++++-- libpdbg/target.h | 2 + p9-host.dts.m4 | 46 ++++++++++++ 3 files changed, 229 insertions(+), 6 deletions(-) diff --git a/libpdbg/i2cm.c b/libpdbg/i2cm.c index c260405..833f9d3 100644 --- a/libpdbg/i2cm.c +++ b/libpdbg/i2cm.c @@ -31,7 +31,11 @@ #include #include -/* I2C common registers */ +/* + * I2C common registers + * - use as is on CFAM + * - use with I2C_PIB_OFFSET on PIB + */ #define I2C_FIFO_REG 0x0 #define I2C_CMD_REG 0x1 #define I2C_MODE_REG 0x2 @@ -45,11 +49,13 @@ #define I2C_RESIDUAL_REG 0x9 #define I2C_PORT_BUSY_REG 0xA +/* I2C PIB only */ #define I2C_PIB_OFFSET 0x4 #define I2C_PIB_ENGINE_0 0x0000 #define I2C_PIB_ENGINE_1 0x1000 #define I2C_PIB_ENGINE_2 0x2000 #define I2C_PIB_ENGINE_3 0x3000 +#define I2C_PIB_FIFO4_REG 0x12 /* I2C command register bits */ #define I2C_CMD_WITH_START PPC_BIT32(0) @@ -122,13 +128,24 @@ static int _i2cm_reg_write(struct i2cm *i2cm, uint32_t addr, uint32_t data) { - CHECK_ERR(fsi_write(&i2cm->target, addr, data)); + if (i2cm->host) + /* pib addr space is 64 bits and i2cm only uses top 32 bits */ + CHECK_ERR(pib_write(&i2cm->target, addr + I2C_PIB_OFFSET, (uint64_t)data << 32)); + else + CHECK_ERR(fsi_write(&i2cm->target, addr, data)); return 0; } static int _i2cm_reg_read(struct i2cm *i2cm, uint32_t addr, uint32_t *data) { - CHECK_ERR(fsi_read(&i2cm->target, addr, data)); + uint64_t d = (uint64_t)*data; + + if (i2cm->host) { + CHECK_ERR(pib_read(&i2cm->target, addr + I2C_PIB_OFFSET, &d)); + *data = d >> 32; + } else { + CHECK_ERR(fsi_read(&i2cm->target, addr, data)); + } return 0; } @@ -268,7 +285,11 @@ static int i2c_fifo_write(struct i2cm *i2cm, uint32_t *data, uint16_t size) continue; PR_INFO("\twriting: %x to FIFO\n", data[bytes_written / 4]); - rc = _i2cm_reg_write(i2cm, I2C_FIFO_REG, data[bytes_written / 4]); + if (i2cm->host) + rc = _i2cm_reg_write(i2cm, I2C_PIB_FIFO4_REG - I2C_PIB_OFFSET, + data[bytes_written / 4]); + else + rc = _i2cm_reg_write(i2cm, I2C_FIFO_REG, data[bytes_written / 4]); if (rc) return bytes_written; bytes_written += 4; @@ -299,9 +320,14 @@ static int i2c_fifo_read(struct i2cm *i2cm, uint32_t *data, uint16_t size) if (!bytes_to_read) continue; - rc = _i2cm_reg_read(i2cm, I2C_FIFO_REG, &tmp); + if (i2cm->host) + rc = _i2cm_reg_read(i2cm, I2C_PIB_FIFO4_REG -I2C_PIB_OFFSET, &tmp); + else + rc = _i2cm_reg_read(i2cm, I2C_FIFO_REG, &tmp); + if (rc) return bytes_read; + memcpy(data + (bytes_read / 4), &tmp, 4); PR_INFO(" %x \n", data[bytes_read / 4]); bytes_read += 4; @@ -453,10 +479,159 @@ static struct i2cm i2cm_cfam = { .name = "CFAM I2C Master", .compatible = "ibm,fsi-i2c-master", .class = "i2cm", - } + }, + .host = false }; DECLARE_HW_UNIT(i2cm_cfam); + +///////////////////////////////////////////////////////////////////////////// +#define OCC_BASE 0x00000000006C08A +#define OCC_CLEAR 0x00000000006C08B +#define OCC_SET 0x00000000006C08C + + +#define OCC_LOCKED_ENGINE_1 PPC_BIT(17) +#define OCC_LOCKED_ENGINE_2 PPC_BIT(19) +#define OCC_LOCKED_ENGINE_3 PPC_BIT(21) +#define I2CM_DT_TO_ID(x) ((x>>12) & 0xf) +static int i2cm_locked_by_occ(int id, uint64_t occ_base) +{ + uint64_t mask; + switch (id) + { + case 1: + mask = OCC_LOCKED_ENGINE_1; + break; + case 2: + mask = OCC_LOCKED_ENGINE_2; + break; + case 3: + mask = OCC_LOCKED_ENGINE_3; + break; + default: + mask = 0; + break; + } + return !!(mask & occ_base); +} + +static int pib_i2c_get(struct i2cbus *i2cbus, uint8_t addr, uint16_t size, uint8_t *d) +{ + uint64_t data = 0; + uint64_t bit; + struct pdbg_target *p; + struct i2cm *i2cm = target_to_i2cm(i2cbus->target.parent); + + pdbg_for_each_class_target("pib", p) { + if (pdbg_target_probe(p) == PDBG_TARGET_ENABLED) + break; + } + + if (!p) { + fprintf(stderr, "No PIB found\n"); + return 0; + } + bit = PPC_BIT(16 + (i2cbus->id - 1) * 2); + pib_read(p, OCC_BASE, &data); + + if( !i2cm_locked_by_occ(i2cbus->id, data)) { + /* lock i2cm */ + pib_write(p, OCC_SET, bit); + pib_read(p, OCC_BASE, &data); + + _i2c_get(i2cm, i2cbus->port, addr, size, d); + + /* unlock i2cm */ + pib_read(p, OCC_BASE, &data); + pib_read(p, OCC_CLEAR, &data); + pib_write(p, OCC_CLEAR, bit); + pib_read(p, OCC_BASE, &data); + } else { + PR_INFO("I2C: de%d: occflags = 0x%16" PRIx64 "(locks = %x:%x:%x)\n", + i2cbus->id, (u64) data, (u16) GETFIELD(PPC_BITMASK(16, 17), data), + (u16) GETFIELD(PPC_BITMASK(18, 19), data), + (u16) GETFIELD(PPC_BITMASK(20, 21), data)); + PR_INFO("I2C master %x is locked by OCC :( \n", i2cbus->id); + } + + return 0; +} + +static int pib_i2c_put(struct i2cbus *i2cbus, uint8_t addr, uint16_t size, uint8_t *d) +{ + uint64_t data = 0; + uint64_t bit; + struct i2cm *i2cm = target_to_i2cm(i2cbus->target.parent); + struct pdbg_target *p; + + pdbg_for_each_class_target("pib", p) { + if (pdbg_target_probe(p) == PDBG_TARGET_ENABLED) + break; + } + + if (!p) { + fprintf(stderr, "No PIB found\n"); + return 0; + } + bit = PPC_BIT(16 + (i2cbus->id - 1) * 2); + pib_read(p, OCC_BASE, &data); + + if( !i2cm_locked_by_occ(i2cbus->id, data)) { + /* lock i2cm */ + pib_write(p, OCC_SET, bit); + pib_read(p, OCC_BASE, &data); + + _i2c_put(i2cm, i2cbus->port, addr, size, d); + + /* unlock i2cm */ + pib_read(p, OCC_BASE, &data); + pib_read(p, OCC_CLEAR, &data); + pib_write(p, OCC_CLEAR, bit); + pib_read(p, OCC_BASE, &data); + } else { + PR_INFO("I2C: de%d: occflags = 0x%16" PRIx64 "(locks = %x:%x:%x)\n", + i2cbus->id, (u64) data, (u16) GETFIELD(PPC_BITMASK(16, 17), data), + (u16) GETFIELD(PPC_BITMASK(18, 19), data), + (u16) GETFIELD(PPC_BITMASK(20, 21), data)); + PR_INFO("I2C master %x is locked by OCC :( \n", i2cbus->id); + } + return 0; +} + +int host_i2cm_target_probe(struct pdbg_target *target) +{ + int dt_id = pdbg_target_address(target, NULL); + int id = I2CM_DT_TO_ID(dt_id); + struct i2cbus *i2cbus = target_to_i2cbus(target); + + i2cbus->id = id; + i2cbus->port = target->index; + + return 0; +} + +static struct i2cbus i2c_bus_pib = { + .target = { + .name = "PIB I2C Bus", + .compatible = "ibm,power9-i2c-port", + .class = "i2c_bus", + .probe = i2cm_target_probe, + }, + .read = pib_i2c_get, + .write = pib_i2c_put, +}; +DECLARE_HW_UNIT(i2c_bus_pib); + +static struct i2cm i2c_pib = { + .target = { + .name = "PIB I2C Master", + .compatible = "ibm,power9-i2cm", + .class = "i2cm", + }, + .host = true, +}; +DECLARE_HW_UNIT(i2c_pib); ///////////////////////////////////////////////////////////////////////////// #ifdef ENABLE_I2CLIB diff --git a/libpdbg/target.h b/libpdbg/target.h index ca9f401..b864960 100644 --- a/libpdbg/target.h +++ b/libpdbg/target.h @@ -144,11 +144,13 @@ struct i2cbus { int (*write)(struct i2cbus *, uint8_t, uint16_t, uint8_t*); uint8_t port; int i2c_fd; + int id; }; #define target_to_i2cbus(x) container_of(x, struct i2cbus, target) struct i2cm { struct pdbg_target target; + bool host; }; #define target_to_i2cm(x) container_of(x, struct i2cm, target) diff --git a/p9-host.dts.m4 b/p9-host.dts.m4 index 52973ff..24c784f 100644 --- a/p9-host.dts.m4 +++ b/p9-host.dts.m4 @@ -12,6 +12,28 @@ reg = <0x0>; index = <0x0>; include(p9-pib.dts.m4)dnl + + i2cm@a1000 { + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x0 0xa1000 0x400>; + compatible = "ibm,power9-i2cm"; + include(p9-i2c.dts.m4)dnl + }; + i2cm@a2000 { + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x0 0xa2000 0x400>; + compatible = "ibm,power9-i2cm"; + include(p9-i2c.dts.m4)dnl + }; + i2cm@a3000 { + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x0 0xa3000 0x400>; + compatible = "ibm,power9-i2cm"; + include(p9-i2c.dts.m4)dnl + }; }; pib@8 { @@ -21,5 +43,29 @@ reg = <0x8>; index = <0x8>; include(p9-pib.dts.m4)dnl + + i2cm@a1000 { + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x0 0xa1000 0x400>; + compatible = "ibm,power9-i2cm"; + include(p9-i2c.dts.m4)dnl + }; + i2cm@a2000 { + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x0 0xa2000 0x400>; + compatible = "ibm,power9-i2cm"; + include(p9-i2c.dts.m4)dnl + }; + i2cm@a3000 { + #address-cells = <0x1>; + #size-cells = <0x0>; + reg = <0x0 0xa3000 0x400>; + compatible = "ibm,power9-i2cm"; + include(p9-i2c.dts.m4)dnl + }; + + }; };