Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/1641672/?format=api
{ "id": 1641672, "url": "http://patchwork.ozlabs.org/api/patches/1641672/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-ide/patch/20220610081801.11854-17-Sergey.Semin@baikalelectronics.ru/", "project": { "id": 13, "url": "http://patchwork.ozlabs.org/api/projects/13/?format=api", "name": "Linux IDE development", "link_name": "linux-ide", "list_id": "linux-ide.vger.kernel.org", "list_email": "linux-ide@vger.kernel.org", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20220610081801.11854-17-Sergey.Semin@baikalelectronics.ru>", "list_archive_url": null, "date": "2022-06-10T08:17:54", "name": "[v4,16/23] ata: ahci: Introduce firmware-specific caps initialization", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "e496ba5c966e95efdc8b75de124cfad278cef457", "submitter": { "id": 78624, "url": "http://patchwork.ozlabs.org/api/people/78624/?format=api", "name": "Serge Semin", "email": "Sergey.Semin@baikalelectronics.ru" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/linux-ide/patch/20220610081801.11854-17-Sergey.Semin@baikalelectronics.ru/mbox/", "series": [ { "id": 304159, "url": "http://patchwork.ozlabs.org/api/series/304159/?format=api", "web_url": "http://patchwork.ozlabs.org/project/linux-ide/list/?series=304159", "date": "2022-06-10T08:17:42", "name": "ata: ahci: Add DWC/Baikal-T1 AHCI SATA support", "version": 4, "mbox": "http://patchwork.ozlabs.org/series/304159/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/1641672/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/1641672/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<linux-ide-owner@vger.kernel.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@bilbo.ozlabs.org", "Authentication-Results": [ "bilbo.ozlabs.org;\n\tdkim=pass (1024-bit key;\n unprotected) header.d=baikalelectronics.ru header.i=@baikalelectronics.ru\n header.a=rsa-sha256 header.s=mail header.b=mKd1F5O6;\n\tdkim-atps=neutral", "ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org\n (client-ip=2620:137:e000::1:20; helo=out1.vger.email;\n envelope-from=linux-ide-owner@vger.kernel.org; receiver=<UNKNOWN>)" ], "Received": [ "from out1.vger.email (out1.vger.email [IPv6:2620:137:e000::1:20])\n\tby bilbo.ozlabs.org (Postfix) with ESMTP id 4LKDPw4qBDz9s09\n\tfor <incoming@patchwork.ozlabs.org>; Fri, 10 Jun 2022 18:19:00 +1000 (AEST)", "(majordomo@vger.kernel.org) by vger.kernel.org via listexpand\n id S1347463AbiFJIS6 (ORCPT <rfc822;incoming@patchwork.ozlabs.org>);\n Fri, 10 Jun 2022 04:18:58 -0400", "from lindbergh.monkeyblade.net ([23.128.96.19]:35930 \"EHLO\n lindbergh.monkeyblade.net\" rhost-flags-OK-OK-OK-OK) by vger.kernel.org\n with ESMTP id S1347290AbiFJISm (ORCPT\n <rfc822;linux-ide@vger.kernel.org>); Fri, 10 Jun 2022 04:18:42 -0400", "from mail.baikalelectronics.com (mail.baikalelectronics.com\n [87.245.175.230])\n by lindbergh.monkeyblade.net (Postfix) with ESMTP id 84A5E24A1E6;\n Fri, 10 Jun 2022 01:18:28 -0700 (PDT)", "from mail (mail.baikal.int [192.168.51.25])\n by mail.baikalelectronics.com (Postfix) with ESMTP id 868D116AE;\n Fri, 10 Jun 2022 11:19:08 +0300 (MSK)", "from localhost (192.168.53.207) by mail (192.168.51.25) with\n Microsoft SMTP Server (TLS) id 15.0.1395.4; Fri, 10 Jun 2022 11:18:16 +0300" ], "DKIM-Filter": "OpenDKIM Filter v2.11.0 mail.baikalelectronics.com 868D116AE", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed;\n d=baikalelectronics.ru; s=mail; t=1654849148;\n bh=aj49nk8GP4RPPoYLfWuuwFNJgofK4dTiflyI5+vDZwY=;\n h=From:To:CC:Subject:Date:In-Reply-To:References:From;\n b=mKd1F5O6UPzImTfQDOGnmSMrgHTo1VCDzZebhSkjYbLmlF0av6A9zvhtcInM3iyyf\n 1emmSObb4LMMVEHz/Rk8gl4dDdQbx6/O6/0LyM2Z0mywB/HiN1P95nR2CWfidFSv/u\n c9sRaXRNOoZjoMiNB6oNmDfgNgNacTRBlxBUdXJU=", "From": "Serge Semin <Sergey.Semin@baikalelectronics.ru>", "To": "Damien Le Moal <damien.lemoal@opensource.wdc.com>,\n Hans de Goede <hdegoede@redhat.com>,\n Jens Axboe <axboe@kernel.dk>, Hannes Reinecke <hare@suse.de>", "CC": "Serge Semin <Sergey.Semin@baikalelectronics.ru>,\n Serge Semin <fancer.lancer@gmail.com>,\n Alexey Malahov <Alexey.Malahov@baikalelectronics.ru>,\n Pavel Parkhomenko <Pavel.Parkhomenko@baikalelectronics.ru>,\n Rob Herring <robh+dt@kernel.org>, <linux-ide@vger.kernel.org>,\n <linux-kernel@vger.kernel.org>, <devicetree@vger.kernel.org>", "Subject": "[PATCH v4 16/23] ata: ahci: Introduce firmware-specific caps\n initialization", "Date": "Fri, 10 Jun 2022 11:17:54 +0300", "Message-ID": "<20220610081801.11854-17-Sergey.Semin@baikalelectronics.ru>", "In-Reply-To": "<20220610081801.11854-1-Sergey.Semin@baikalelectronics.ru>", "References": "<20220610081801.11854-1-Sergey.Semin@baikalelectronics.ru>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "Content-Type": "text/plain", "X-ClientProxiedBy": "MAIL.baikal.int (192.168.51.25) To mail (192.168.51.25)", "X-Spam-Status": "No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED,\n DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_PASS,SPF_PASS,\n T_SCC_BODY_TEXT_LINE,URIBL_BLOCKED autolearn=ham autolearn_force=no\n version=3.4.6", "X-Spam-Checker-Version": "SpamAssassin 3.4.6 (2021-04-09) on\n lindbergh.monkeyblade.net", "Precedence": "bulk", "List-ID": "<linux-ide.vger.kernel.org>", "X-Mailing-List": "linux-ide@vger.kernel.org" }, "content": "There are systems with no BIOS or comprehensive embedded firmware which\ncould be able to properly initialize the SATA AHCI controller\nplatform-specific capabilities. In that case a good alternative to having\na clever bootloader is to create a device tree node with the properties\nwell describing all the AHCI-related platform specifics. All the settings\nwhich are normally detected and marked as available in the HBA and its\nports capabilities fields [1] could be defined in the platform DTB by\nmeans of a set of the dedicated properties. Such approach perfectly fits\nto the DTB-philosophy - to provide hardware/platform description.\n\nSo here we suggest to extend the SATA AHCI device tree bindings with two\nadditional DT-properties:\n1) \"hba-cap\" - HBA platform generic capabilities like:\n - SSS - Staggered Spin-up support.\n - SMPS - Mechanical Presence Switch support.\n2) \"hba-port-cap\" - HBA platform port capabilities like:\n - HPCP - Hot Plug Capable Port.\n - MPSP - Mechanical Presence Switch Attached to Port.\n - CPD - Cold Presence Detection.\n - ESP - External SATA Port.\n - FBSCP - FIS-based Switching Capable Port.\nAll of these capabilities require to have a corresponding hardware\nconfiguration. Thus it's ok to have them defined in DTB.\n\nEven though the driver currently takes into account the state of the ESP\nand FBSCP flags state only, there is nothing wrong with having all of them\nsupported by the generic AHCI library in order to have a complete OF-based\nplatform-capabilities initialization procedure. These properties will be\nparsed in the ahci_platform_get_resources() method and their values will\nbe stored in the saved_* fields of the ahci_host_priv structure, which in\nits turn then will be used to restore the H.CAP, H.PI and P#.CMD\ncapability fields on device init and after HBA reset.\n\nPlease note this modification concerns the HW-init HBA and its ports flags\nonly, which are by specification [1] are supposed to be initialized by the\nBIOS/platform firmware/expansion ROM and which are normally declared in\nthe one-time-writable-after-reset register fields. Even though these flags\naren't supposed to be cleared after HBA reset some AHCI instances may\nviolate that rule so we still need to perform the fields resetting after\neach reset. Luckily the corresponding functionality has already been\npartly implemented in the framework of the ahci_save_initial_config() and\nahci_restore_initial_config() methods.\n\n[1] Serial ATA AHCI 1.3.1 Specification, p. 103\n\nSigned-off-by: Serge Semin <Sergey.Semin@baikalelectronics.ru>\n\n---\n\nChangelog v4:\n- Convert the boolean properties to the bitfield DT-properties. (@Rob)\n---\n drivers/ata/ahci.h | 1 +\n drivers/ata/libahci.c | 51 ++++++++++++++++++++++++++++------\n drivers/ata/libahci_platform.c | 41 +++++++++++++++++++++++++--\n 3 files changed, 82 insertions(+), 11 deletions(-)", "diff": "diff --git a/drivers/ata/ahci.h b/drivers/ata/ahci.h\nindex 8b9826533ae5..0de221055961 100644\n--- a/drivers/ata/ahci.h\n+++ b/drivers/ata/ahci.h\n@@ -337,6 +337,7 @@ struct ahci_host_priv {\n \tu32\t\t\tsaved_cap;\t/* saved initial cap */\n \tu32\t\t\tsaved_cap2;\t/* saved initial cap2 */\n \tu32\t\t\tsaved_port_map;\t/* saved initial port_map */\n+\tu32\t\t\tsaved_port_cap[AHCI_MAX_PORTS]; /* saved port_cap */\n \tu32 \t\t\tem_loc; /* enclosure management location */\n \tu32\t\t\tem_buf_sz;\t/* EM buffer size in byte */\n \tu32\t\t\tem_msg_type;\t/* EM message type */\ndiff --git a/drivers/ata/libahci.c b/drivers/ata/libahci.c\nindex 1ffaa5f5f21a..954386a2b500 100644\n--- a/drivers/ata/libahci.c\n+++ b/drivers/ata/libahci.c\n@@ -16,6 +16,7 @@\n * http://www.intel.com/technology/serialata/pdf/rev1_1.pdf\n */\n \n+#include <linux/bitops.h>\n #include <linux/kernel.h>\n #include <linux/gfp.h>\n #include <linux/module.h>\n@@ -443,16 +444,28 @@ static ssize_t ahci_show_em_supported(struct device *dev,\n void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv)\n {\n \tvoid __iomem *mmio = hpriv->mmio;\n-\tu32 cap, cap2, vers, port_map;\n+\tvoid __iomem *port_mmio;\n+\tunsigned long port_map;\n+\tu32 cap, cap2, vers;\n \tint i;\n \n \t/* make sure AHCI mode is enabled before accessing CAP */\n \tahci_enable_ahci(mmio);\n \n-\t/* Values prefixed with saved_ are written back to host after\n-\t * reset. Values without are used for driver operation.\n+\t/*\n+\t * Values prefixed with saved_ are written back to the HBA and ports\n+\t * registers after reset. Values without are used for driver operation.\n+\t */\n+\n+\t/*\n+\t * Override HW-init HBA capability fields with the platform-specific\n+\t * values. The rest of the HBA capabilities are defined as Read-only\n+\t * and can't be modified in CSR anyway.\n \t */\n-\thpriv->saved_cap = cap = readl(mmio + HOST_CAP);\n+\tcap = readl(mmio + HOST_CAP);\n+\tif (hpriv->saved_cap)\n+\t\tcap = (cap & ~(HOST_CAP_SSS | HOST_CAP_MPS)) | hpriv->saved_cap;\n+\thpriv->saved_cap = cap;\n \n \t/* CAP2 register is only defined for AHCI 1.2 and later */\n \tvers = readl(mmio + HOST_VERSION);\n@@ -519,7 +532,7 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv)\n \t/* Override the HBA ports mapping if the platform needs it */\n \tport_map = readl(mmio + HOST_PORTS_IMPL);\n \tif (hpriv->saved_port_map && port_map != hpriv->saved_port_map) {\n-\t\tdev_info(dev, \"forcing port_map 0x%x -> 0x%x\\n\",\n+\t\tdev_info(dev, \"forcing port_map 0x%lx -> 0x%x\\n\",\n \t\t\t port_map, hpriv->saved_port_map);\n \t\tport_map = hpriv->saved_port_map;\n \t} else {\n@@ -527,7 +540,7 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv)\n \t}\n \n \tif (hpriv->mask_port_map) {\n-\t\tdev_warn(dev, \"masking port_map 0x%x -> 0x%x\\n\",\n+\t\tdev_warn(dev, \"masking port_map 0x%lx -> 0x%lx\\n\",\n \t\t\tport_map,\n \t\t\tport_map & hpriv->mask_port_map);\n \t\tport_map &= hpriv->mask_port_map;\n@@ -546,7 +559,7 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv)\n \t\t */\n \t\tif (map_ports > ahci_nr_ports(cap)) {\n \t\t\tdev_warn(dev,\n-\t\t\t\t \"implemented port map (0x%x) contains more ports than nr_ports (%u), using nr_ports\\n\",\n+\t\t\t\t \"implemented port map (0x%lx) contains more ports than nr_ports (%u), using nr_ports\\n\",\n \t\t\t\t port_map, ahci_nr_ports(cap));\n \t\t\tport_map = 0;\n \t\t}\n@@ -555,12 +568,26 @@ void ahci_save_initial_config(struct device *dev, struct ahci_host_priv *hpriv)\n \t/* fabricate port_map from cap.nr_ports for < AHCI 1.3 */\n \tif (!port_map && vers < 0x10300) {\n \t\tport_map = (1 << ahci_nr_ports(cap)) - 1;\n-\t\tdev_warn(dev, \"forcing PORTS_IMPL to 0x%x\\n\", port_map);\n+\t\tdev_warn(dev, \"forcing PORTS_IMPL to 0x%lx\\n\", port_map);\n \n \t\t/* write the fixed up value to the PI register */\n \t\thpriv->saved_port_map = port_map;\n \t}\n \n+\t/*\n+\t * Preserve the ports capabilities defined by the platform. Note there\n+\t * is no need in storing the rest of the P#.CMD fields since they are\n+\t * volatile.\n+\t */\n+\tfor_each_set_bit(i, &port_map, AHCI_MAX_PORTS) {\n+\t\tif (hpriv->saved_port_cap[i])\n+\t\t\tcontinue;\n+\n+\t\tport_mmio = __ahci_port_base(hpriv, i);\n+\t\thpriv->saved_port_cap[i] =\n+\t\t\treadl(port_mmio + PORT_CMD) & PORT_CMD_CAP;\n+\t}\n+\n \t/* record values to use during operation */\n \thpriv->cap = cap;\n \thpriv->cap2 = cap2;\n@@ -590,13 +617,21 @@ EXPORT_SYMBOL_GPL(ahci_save_initial_config);\n static void ahci_restore_initial_config(struct ata_host *host)\n {\n \tstruct ahci_host_priv *hpriv = host->private_data;\n+\tunsigned long port_map = hpriv->port_map;\n \tvoid __iomem *mmio = hpriv->mmio;\n+\tvoid __iomem *port_mmio;\n+\tint i;\n \n \twritel(hpriv->saved_cap, mmio + HOST_CAP);\n \tif (hpriv->saved_cap2)\n \t\twritel(hpriv->saved_cap2, mmio + HOST_CAP2);\n \twritel(hpriv->saved_port_map, mmio + HOST_PORTS_IMPL);\n \t(void) readl(mmio + HOST_PORTS_IMPL);\t/* flush */\n+\n+\tfor_each_set_bit(i, &port_map, AHCI_MAX_PORTS) {\n+\t\tport_mmio = __ahci_port_base(hpriv, i);\n+\t\twritel(hpriv->saved_port_cap[i], port_mmio + PORT_CMD);\n+\t}\n }\n \n static unsigned ahci_scr_offset(struct ata_port *ap, unsigned int sc_reg)\ndiff --git a/drivers/ata/libahci_platform.c b/drivers/ata/libahci_platform.c\nindex efe640603f3f..8b542a8bc487 100644\n--- a/drivers/ata/libahci_platform.c\n+++ b/drivers/ata/libahci_platform.c\n@@ -23,6 +23,7 @@\n #include <linux/pm_runtime.h>\n #include <linux/of_platform.h>\n #include <linux/reset.h>\n+\n #include \"ahci.h\"\n \n static void ahci_host_stop(struct ata_host *host);\n@@ -383,6 +384,34 @@ static int ahci_platform_get_regulator(struct ahci_host_priv *hpriv, u32 port,\n \treturn rc;\n }\n \n+static int ahci_platform_get_firmware(struct ahci_host_priv *hpriv,\n+\t\t\t\t struct device *dev)\n+{\n+\tstruct device_node *child;\n+\tu32 port;\n+\n+\tif (!of_property_read_u32(dev->of_node, \"hba-cap\", &hpriv->saved_cap))\n+\t\thpriv->saved_cap &= (HOST_CAP_SSS | HOST_CAP_MPS);\n+\n+\tof_property_read_u32(dev->of_node,\n+\t\t\t \"ports-implemented\", &hpriv->saved_port_map);\n+\n+\tfor_each_child_of_node(dev->of_node, child) {\n+\t\tif (!of_device_is_available(child))\n+\t\t\tcontinue;\n+\n+\t\tif (of_property_read_u32(child, \"reg\", &port)) {\n+\t\t\tof_node_put(child);\n+\t\t\treturn -EINVAL;\n+\t\t}\n+\n+\t\tif (!of_property_read_u32(child, \"hba-port-cap\", &hpriv->saved_port_cap[port]))\n+\t\t\thpriv->saved_port_cap[port] &= PORT_CMD_CAP;\n+\t}\n+\n+\treturn 0;\n+}\n+\n /**\n * ahci_platform_get_resources - Get platform resources\n * @pdev: platform device to get resources for\n@@ -523,9 +552,6 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev,\n \t\tgoto err_out;\n \t}\n \n-\tof_property_read_u32(dev->of_node,\n-\t\t\t \"ports-implemented\", &hpriv->saved_port_map);\n-\n \tif (child_nodes) {\n \t\tfor_each_child_of_node(dev->of_node, child) {\n \t\t\tu32 port;\n@@ -590,6 +616,15 @@ struct ahci_host_priv *ahci_platform_get_resources(struct platform_device *pdev,\n \t\tif (rc == -EPROBE_DEFER)\n \t\t\tgoto err_out;\n \t}\n+\n+\t/*\n+\t * Retrieve firmware-specific flags which then will be used to set\n+\t * the HW-init fields of HBA and its ports\n+\t */\n+\trc = ahci_platform_get_firmware(hpriv, dev);\n+\tif (rc)\n+\t\tgoto err_out;\n+\n \tpm_runtime_enable(dev);\n \tpm_runtime_get_sync(dev);\n \thpriv->got_runtime_pm = true;\n", "prefixes": [ "v4", "16/23" ] }