Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.1/patches/2224924/?format=api
{ "id": 2224924, "url": "http://patchwork.ozlabs.org/api/1.1/patches/2224924/?format=api", "web_url": "http://patchwork.ozlabs.org/project/opensbi/patch/20260419150857.2705843-2-aurelien@aurel32.net/", "project": { "id": 67, "url": "http://patchwork.ozlabs.org/api/1.1/projects/67/?format=api", "name": "OpenSBI development", "link_name": "opensbi", "list_id": "opensbi.lists.infradead.org", "list_email": "opensbi@lists.infradead.org", "web_url": "https://github.com/riscv/opensbi", "scm_url": "", "webscm_url": "" }, "msgid": "<20260419150857.2705843-2-aurelien@aurel32.net>", "date": "2026-04-19T14:49:19", "name": "[1/2] lib: utils/i2c: add minimal SpacemiT I2C driver", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "930c4e349abaef88456bcb2a1f1df93cadbf291c", "submitter": { "id": 2775, "url": "http://patchwork.ozlabs.org/api/1.1/people/2775/?format=api", "name": "Aurelien Jarno", "email": "aurelien@aurel32.net" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/opensbi/patch/20260419150857.2705843-2-aurelien@aurel32.net/mbox/", "series": [ { "id": 500513, "url": "http://patchwork.ozlabs.org/api/1.1/series/500513/?format=api", "web_url": "http://patchwork.ozlabs.org/project/opensbi/list/?series=500513", "date": "2026-04-19T14:49:20", "name": "Add reboot support for SpacemiT K1 platforms", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/500513/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2224924/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2224924/checks/", "tags": {}, "headers": { "Return-Path": "\n <opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n secure) header.d=lists.infradead.org header.i=@lists.infradead.org\n header.a=rsa-sha256 header.s=bombadil.20210309 header.b=wqXwlaYe;\n\tdkim=fail reason=\"signature verification failed\" (2048-bit key;\n secure) header.d=aurel32.net header.i=@aurel32.net header.a=rsa-sha256\n header.s=202004.hall header.b=wqj82zpb;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=none (no SPF record) smtp.mailfrom=lists.infradead.org\n (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org;\n envelope-from=opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org;\n receiver=patchwork.ozlabs.org)" ], "Received": [ "from bombadil.infradead.org (bombadil.infradead.org\n [IPv6:2607:7c80:54:3::133])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519 server-signature ECDSA (secp384r1) server-digest SHA384)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4fzBqL4p8jz1yHk\n\tfor <incoming@patchwork.ozlabs.org>; Mon, 20 Apr 2026 01:09:29 +1000 (AEST)", "from localhost ([::1] helo=bombadil.infradead.org)\n\tby bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux))\n\tid 1wETlu-00000005sFB-1Hzl;\n\tSun, 19 Apr 2026 15:09:18 +0000", "from hall.aurel32.net ([2001:bc8:30d7:100::1])\n\tby bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux))\n\tid 1wETlq-00000005sDi-3L4p\n\tfor opensbi@lists.infradead.org;\n\tSun, 19 Apr 2026 15:09:17 +0000", "from authenticated user\n\tby hall.aurel32.net with esmtpsa (TLS1.3) tls\n TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384\n\t(Exim 4.98.2)\n\t(envelope-from <aurelien@aurel32.net>)\n\tid 1wETlh-0000000CKQr-434Z;\n\tSun, 19 Apr 2026 17:09:05 +0200" ], "DKIM-Signature": [ "v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed;\n\td=lists.infradead.org; s=bombadil.20210309; h=Sender:\n\tContent-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post:\n\tList-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:\n\tMessage-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description:\n\tResent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:\n\tList-Owner; bh=NY8qntMEu5W9WlpBwCExF17LlUPhDeJHrzIF931nQiU=; b=wqXwlaYeJvl/Yj\n\tOzYGhor+6p/3/e/8mNl22+8VA3nOvDWKr5NYDIMzQUZ0KsU42hcos611paf47qSTRHMXqXibueOWC\n\tcAIC03zV2QQgFNXWc3aiKWwkK/44nDlMQVMhMLNgBGCjWu3QtbfvYJzvQXaF3EZXRwwn1RRCUcoTI\n\tJo7nk6E7DvnJEy8wxmgCkdc/z2PceAKA/nKDZ8r2tvsJwIr0yog7yrFE5rniqB+f44H3bafLDbY8e\n\tteh5ZNjBaCo7fUVZ7ZQrMNyVZulfMx4pAaQFEfCNLsqIB49nko6y3L/LLX6DwOsaDSp+0WmbujCh/\n\tqS6KiXXq0rr6sqRkyuiA==;", "v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=aurel32.net\n\t; s=202004.hall; h=Content-Transfer-Encoding:MIME-Version:References:\n\tIn-Reply-To:Message-ID:Date:Subject:Cc:To:From:Content-Type:From:Reply-To:\n\tSubject:Content-ID:Content-Description:X-Debbugs-Cc;\n\tbh=iri5KGkp/slv6HhjVn/aZZjwIDTF7TECFoCLFHO7Cno=; b=wqj82zpbBcfK4V50oknagg41EE\n\tM/f7v61JuyMPt5JKN6P1cVtlXwvr5CmoXvzdrJxdIdkLgqqD6/Ttz1IUrwg4Z27xO6ulySivQZlHs\n\tCCgjUcCdQ3JraPlZPM6r2ZUpL0fWkzhgfiNgPjJAMT0CQX9bXMnu8Ycds7OMeRBJr6txkxDltEDba\n\tbAw0CwjYXtfC2ikH91GQZhEQ/hxvt2BaXOzU86vt5ETiHaBVESs4JWY9dhD/tAXAQYJ0k4v3SNRkd\n\td+90lpMFhc0Xy78CWl9gfRPp/sR3M2TT4TiCyh/8nYYC/jKnceiDKpLlPf9bpWvEy/VSf9ddJdJIA\n\tJmQbtJeg==;" ], "From": "Aurelien Jarno <aurelien@aurel32.net>", "To": "opensbi@lists.infradead.org", "Cc": "Aurelien Jarno <aurelien@aurel32.net>", "Subject": "[PATCH 1/2] lib: utils/i2c: add minimal SpacemiT I2C driver", "Date": "Sun, 19 Apr 2026 16:49:19 +0200", "Message-ID": "<20260419150857.2705843-2-aurelien@aurel32.net>", "X-Mailer": "git-send-email 2.53.0", "In-Reply-To": "<20260419150857.2705843-1-aurelien@aurel32.net>", "References": "<20260419150857.2705843-1-aurelien@aurel32.net>", "MIME-Version": "1.0", "X-CRM114-Version": "20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 ", "X-CRM114-CacheID": "sfid-20260419_080914_969309_67F3313F ", "X-CRM114-Status": "GOOD ( 20.97 )", "X-Spam-Score": "-4.4 (----)", "X-Spam-Report": "Spam detection software,\n running on the system \"bombadil.infradead.org\",\n has NOT identified this incoming email as spam. The original\n message has been attached to this so you can view it or label\n similar future email. If you have any questions, see\n the administrator of that system for details.\n Content preview: Add a simple SpacemiT I2C driver for basic byte transfers\n over the I2C bus,\n prioritizing simplicity over performance. The driver operates\n in PIO mode and does not use interrupts, FIFO, or DMA. The controller is\n reset at the start of each transaction to ensure a known initial state,\n regardless\n of prior configuration by the kernel. This also avoids the need for\n additional\n error recovery code.\n Content analysis details: (-4.4 points, 5.0 required)\n pts rule name description\n ---- ----------------------\n --------------------------------------------------\n -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/,\n medium trust\n [2001:bc8:30d7:100:0:0:0:1 listed in]\n [list.dnswl.org]\n -0.0 SPF_HELO_PASS SPF: HELO matches SPF record\n -0.0 SPF_PASS SPF: sender matches SPF record\n -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from\n author's\n domain\n 0.1 DKIM_SIGNED Message has a DKIM or DK signature,\n not necessarily valid\n -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from\n envelope-from domain\n -0.1 DKIM_VALID Message has at least one valid DKIM or DK\n signature\n -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1%\n [score: 0.0000]\n 0.0 UNPARSEABLE_RELAY Informational: message has unparseable relay\n lines", "X-BeenThere": "opensbi@lists.infradead.org", "X-Mailman-Version": "2.1.34", "Precedence": "list", "List-Id": "<opensbi.lists.infradead.org>", "List-Unsubscribe": "<http://lists.infradead.org/mailman/options/opensbi>,\n <mailto:opensbi-request@lists.infradead.org?subject=unsubscribe>", "List-Archive": "<http://lists.infradead.org/pipermail/opensbi/>", "List-Post": "<mailto:opensbi@lists.infradead.org>", "List-Help": "<mailto:opensbi-request@lists.infradead.org?subject=help>", "List-Subscribe": "<http://lists.infradead.org/mailman/listinfo/opensbi>,\n <mailto:opensbi-request@lists.infradead.org?subject=subscribe>", "Content-Type": "text/plain; charset=\"us-ascii\"", "Content-Transfer-Encoding": "7bit", "Sender": "\"opensbi\" <opensbi-bounces@lists.infradead.org>", "Errors-To": "opensbi-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org" }, "content": "Add a simple SpacemiT I2C driver for basic byte transfers over the I2C\nbus, prioritizing simplicity over performance. The driver operates in\nPIO mode and does not use interrupts, FIFO, or DMA.\n\nThe controller is reset at the start of each transaction to ensure a\nknown initial state, regardless of prior configuration by the kernel.\nThis also avoids the need for additional error recovery code.\n\nThis will be used for communication with onboard PMIC to reset and\npower-off the board.\n\nSigned-off-by: Aurelien Jarno <aurelien@aurel32.net>\n---\n lib/utils/i2c/Kconfig | 4 +\n lib/utils/i2c/fdt_i2c_spacemit.c | 220 +++++++++++++++++++++++++++++\n lib/utils/i2c/objects.mk | 3 +\n platform/generic/configs/defconfig | 1 +\n 4 files changed, 228 insertions(+)\n create mode 100644 lib/utils/i2c/fdt_i2c_spacemit.c", "diff": "diff --git a/lib/utils/i2c/Kconfig b/lib/utils/i2c/Kconfig\nindex 7fa32fcf..bdaaff62 100644\n--- a/lib/utils/i2c/Kconfig\n+++ b/lib/utils/i2c/Kconfig\n@@ -14,6 +14,10 @@ config FDT_I2C_SIFIVE\n \tbool \"SiFive I2C FDT driver\"\n \tdefault n\n \n+config FDT_I2C_SPACEMIT\n+\tbool \"SpacemiT I2C FDT driver\"\n+\tdefault n\n+\n config FDT_I2C_DW\n \tbool \"Synopsys Designware I2C FDT driver\"\n \tselect I2C_DW\ndiff --git a/lib/utils/i2c/fdt_i2c_spacemit.c b/lib/utils/i2c/fdt_i2c_spacemit.c\nnew file mode 100644\nindex 00000000..9009b6b6\n--- /dev/null\n+++ b/lib/utils/i2c/fdt_i2c_spacemit.c\n@@ -0,0 +1,220 @@\n+/*\n+ * SPDX-License-Identifier: BSD-2-Clause\n+ *\n+ * Copyright (c) 2026 Aurelien Jarno\n+ *\n+ * Authors:\n+ * Aurelien Jarno <aurelien@aurel32.net>\n+ */\n+\n+#include <sbi/riscv_io.h>\n+#include <sbi/sbi_error.h>\n+#include <sbi/sbi_heap.h>\n+#include <sbi/sbi_timer.h>\n+#include <sbi_utils/fdt/fdt_helper.h>\n+#include <sbi_utils/i2c/fdt_i2c.h>\n+\n+/* Controller registers */\n+#define ICR_OFFSET\t0x00\t\t/* I2C control register */\n+#define IDBR_OFFSET\t0x0c\t\t/* I2C data buffer register */\n+\n+/* Control register bits */\n+#define ICR_START\tBIT(0)\t\t/* start */\n+#define ICR_STOP\tBIT(1)\t\t/* stop */\n+#define ICR_ACKNAK\tBIT(2)\t\t/* ACK(0) or NAK(1) */\n+#define ICR_TB\t\tBIT(3)\t\t/* transfer byte */\n+#define ICR_UR\t\tBIT(10)\t\t/* unit reset */\n+#define ICR_SCLE\tBIT(13)\t\t/* SCL enable */\n+#define ICR_IUE\t\tBIT(14)\t\t/* unit enable */\n+\n+/* Timing */\n+#define I2C_RESET_US\t10\n+#define I2C_TIMEOUT_US\t1000\n+\n+struct spacemit_i2c_adapter {\n+\tunsigned long base;\n+\tstruct i2c_adapter adapter;\n+};\n+\n+static inline void spacemit_i2c_set_reg(struct spacemit_i2c_adapter *adap,\n+\t\t\t\t\tuint8_t reg, uint32_t val)\n+{\n+\twritel(val, (void *)adap->base + reg);\n+}\n+\n+static inline uint32_t spacemit_i2c_get_reg(struct spacemit_i2c_adapter *adap,\n+\t\t\t\t\t uint32_t reg)\n+{\n+\treturn readl((void *)adap->base + reg);\n+}\n+\n+static void spacemit_i2c_reset(struct spacemit_i2c_adapter *adap)\n+{\n+\t/* disable unit */\n+\tspacemit_i2c_set_reg(adap, ICR_OFFSET, 0);\n+\tsbi_timer_udelay(I2C_RESET_US);\n+\n+\t/* reset unit */\n+\tspacemit_i2c_set_reg(adap, ICR_OFFSET, ICR_UR);\n+\tsbi_timer_udelay(I2C_RESET_US);\n+\n+\t/* clear reset and enable unit and SCL */\n+\tspacemit_i2c_set_reg(adap, ICR_OFFSET, ICR_IUE | ICR_SCLE);\n+}\n+\n+static int spacemit_i2c_wait_xfer_done(struct spacemit_i2c_adapter *adap)\n+{\n+\tfor (int i = 0; i < I2C_TIMEOUT_US; i++) {\n+\t\tuint32_t val = spacemit_i2c_get_reg(adap, ICR_OFFSET);\n+\n+\t\tif (!(val & ICR_TB))\n+\t\t\treturn 0;\n+\n+\t\tsbi_timer_udelay(1);\n+\t};\n+\n+\treturn SBI_ETIMEDOUT;\n+}\n+\n+static void spacemit_i2c_start_xfer(struct spacemit_i2c_adapter *adap,\n+\t\t\t\t uint32_t ctrl)\n+{\n+\tconst uint32_t ctrl_mask = ICR_START | ICR_STOP | ICR_ACKNAK;\n+\tuint32_t val;\n+\n+\tval = spacemit_i2c_get_reg(adap, ICR_OFFSET);\n+\tval &= ~ctrl_mask;\n+\tval |= (ctrl & ctrl_mask);\n+\tval |= ICR_TB;\n+\n+\tspacemit_i2c_set_reg(adap, ICR_OFFSET, val);\n+}\n+\n+static int spacemit_i2c_xfer_write(struct spacemit_i2c_adapter *adap,\n+\t\t\t\t uint8_t byte, uint32_t ctrl)\n+{\n+\tspacemit_i2c_set_reg(adap, IDBR_OFFSET, byte);\n+\tspacemit_i2c_start_xfer(adap, ctrl);\n+\n+\treturn spacemit_i2c_wait_xfer_done(adap);\n+}\n+\n+static int spacemit_i2c_xfer_read(struct spacemit_i2c_adapter *adap,\n+\t\t\t\t uint8_t *byte, uint32_t ctrl)\n+{\n+\tint rc;\n+\n+\tspacemit_i2c_start_xfer(adap, ctrl);\n+\n+\trc = spacemit_i2c_wait_xfer_done(adap);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\t*byte = spacemit_i2c_get_reg(adap, IDBR_OFFSET);\n+\treturn 0;\n+}\n+\n+static int spacemit_i2c_adapter_write(struct i2c_adapter *ia, uint8_t addr,\n+\t\t\t\t uint8_t reg, uint8_t *buffer, int len)\n+{\n+\tstruct spacemit_i2c_adapter *adap =\n+\t\tcontainer_of(ia, struct spacemit_i2c_adapter, adapter);\n+\tint rc;\n+\n+\t/* reset controller to a known state */\n+\tspacemit_i2c_reset(adap);\n+\n+\t/* send device address (in write mode) */\n+\trc = spacemit_i2c_xfer_write(adap, addr << 1, ICR_START);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\t/* send register + data bytes */\n+\tfor (int i = 0; i < len + 1; i++) {\n+\t\tuint32_t ctrl = (i == len) ? ICR_STOP : 0;\n+\t\tuint8_t byte = (i == 0) ? reg : buffer[i - 1];\n+\n+\t\trc = spacemit_i2c_xfer_write(adap, byte, ctrl);\n+\t\tif (rc)\n+\t\t\treturn rc;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int spacemit_i2c_adapter_read(struct i2c_adapter *ia, uint8_t addr,\n+\t\t\t\t uint8_t reg, uint8_t *buffer, int len)\n+{\n+\tstruct spacemit_i2c_adapter *adap =\n+\t\tcontainer_of(ia, struct spacemit_i2c_adapter, adapter);\n+\tint rc;\n+\n+\t/* reset controller to a known state */\n+\tspacemit_i2c_reset(adap);\n+\n+\t/* send device address (in write mode) */\n+\trc = spacemit_i2c_xfer_write(adap, addr << 1, ICR_START);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\t/* send register */\n+\trc = spacemit_i2c_xfer_write(adap, reg, 0);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\t/* repeated start and send device address (in read mode) */\n+\trc = spacemit_i2c_xfer_write(adap, (addr << 1) | 1, ICR_START);\n+\tif (rc)\n+\t\treturn rc;\n+\n+\t/* read data bytes */\n+\tfor (int i = 0; i < len; i++) {\n+\t\tuint32_t ctrl = (i == len - 1) ? (ICR_ACKNAK | ICR_STOP) : 0;\n+\n+\t\trc = spacemit_i2c_xfer_read(adap, &buffer[i], ctrl);\n+\t\tif (rc)\n+\t\t\treturn rc;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static int spacemit_i2c_init(const void *fdt, int nodeoff,\n+\t\t\t const struct fdt_match *match)\n+{\n+\tstruct spacemit_i2c_adapter *adapter;\n+\tuint64_t base;\n+\tint rc;\n+\n+\tadapter = sbi_zalloc(sizeof(*adapter));\n+\tif (!adapter)\n+\t\treturn SBI_ENOMEM;\n+\n+\trc = fdt_get_node_addr_size(fdt, nodeoff, 0, &base, NULL);\n+\tif (rc) {\n+\t\tsbi_free(adapter);\n+\t\treturn rc;\n+\t}\n+\n+\tadapter->base = base;\n+\tadapter->adapter.id = nodeoff;\n+\tadapter->adapter.write = spacemit_i2c_adapter_write;\n+\tadapter->adapter.read = spacemit_i2c_adapter_read;\n+\trc = i2c_adapter_add(&adapter->adapter);\n+\tif (rc) {\n+\t\tsbi_free(adapter);\n+\t\treturn rc;\n+\t}\n+\n+\treturn 0;\n+}\n+\n+static const struct fdt_match spacemit_i2c_match[] = {\n+\t{ .compatible = \"spacemit,k1-i2c\" },\n+\t{ },\n+};\n+\n+const struct fdt_driver fdt_i2c_adapter_spacemit = {\n+\t.match_table = spacemit_i2c_match,\n+\t.init = spacemit_i2c_init,\n+};\ndiff --git a/lib/utils/i2c/objects.mk b/lib/utils/i2c/objects.mk\nindex d34d6648..91ac17ec 100644\n--- a/lib/utils/i2c/objects.mk\n+++ b/lib/utils/i2c/objects.mk\n@@ -15,6 +15,9 @@ libsbiutils-objs-$(CONFIG_FDT_I2C) += i2c/fdt_i2c_adapter_drivers.carray.o\n carray-fdt_i2c_adapter_drivers-$(CONFIG_FDT_I2C_SIFIVE) += fdt_i2c_adapter_sifive\n libsbiutils-objs-$(CONFIG_FDT_I2C_SIFIVE) += i2c/fdt_i2c_sifive.o\n \n+carray-fdt_i2c_adapter_drivers-$(CONFIG_FDT_I2C_SPACEMIT) += fdt_i2c_adapter_spacemit\n+libsbiutils-objs-$(CONFIG_FDT_I2C_SPACEMIT) += i2c/fdt_i2c_spacemit.o\n+\n carray-fdt_i2c_adapter_drivers-$(CONFIG_FDT_I2C_DW) += fdt_i2c_adapter_dw\n libsbiutils-objs-$(CONFIG_FDT_I2C_DW) += i2c/fdt_i2c_dw.o\n \ndiff --git a/platform/generic/configs/defconfig b/platform/generic/configs/defconfig\nindex 1d3431e7..a9cb0f06 100644\n--- a/platform/generic/configs/defconfig\n+++ b/platform/generic/configs/defconfig\n@@ -31,6 +31,7 @@ CONFIG_FDT_HSM_RPMI=y\n CONFIG_FDT_HSM_SIFIVE_TMC0=y\n CONFIG_FDT_I2C=y\n CONFIG_FDT_I2C_SIFIVE=y\n+CONFIG_FDT_I2C_SPACEMIT=y\n CONFIG_FDT_I2C_DW=y\n CONFIG_FDT_IPI=y\n CONFIG_FDT_IPI_MSWI=y\n", "prefixes": [ "1/2" ] }