Message ID | 20231011122633.31559-1-jianjun.wang@mediatek.com |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:612c:2908:b0:403:3b70:6f57 with SMTP id ib8csp501016vqb; Wed, 11 Oct 2023 05:27:47 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHO9YKpPBE8QzdS50/d/HId1g6lV1HWd3CnPMJfW4QkXkh1V7a7+l6HKgl830FtFpzutwAO X-Received: by 2002:a17:902:ea0c:b0:1c2:c60:8388 with SMTP id s12-20020a170902ea0c00b001c20c608388mr22854921plg.6.1697027267065; Wed, 11 Oct 2023 05:27:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1697027267; cv=none; d=google.com; s=arc-20160816; b=1FD3BDCiiQzywdBTJHIrdF3YpkM+yVmcfjkcUm1oNUUeVDZrhrh7rJiumETpcAQ5CG msxhehlv8YT2la424n29Hwp++9w+TeiGDmPNXP8nAJBn7g3bARC4OrUBrQx5/aaD9+FO atQreFCXu7XEvkd5FsbpFGtu6nf/VCCaV8apOAgmZelXFMHBOrgopeZOCAI1dUNcpTmG 0lJoE8LmDNaIDcp+fqkWoFMRlkEbAyOOJk2w4lyFBGkg9ZDy5zbqc1EE2m5jATk62bhi 36OsRlbdw1rVpLhh75+lMbCWIVmerh1GvEVaf+IhgD2Xy9IiETM2kdw1Txfr49FLrXj1 ThDQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from:dkim-signature; bh=tjQ7E6Wp7xtRDuxyM0IzhGgHnDmusITOkaUsg2pucuI=; fh=v6Hmzf0gSEje0BMyqZVEWqjV1mxMSW2g4mahG6+cJ7c=; b=sqiKiftOMFUtaFTA7doKLTEOJyyDy+uxft5TLUZ6ft/MVKqMq7i4s9qJjuBytnyxN5 9Q4KWGwH4ZelM07igXAQwTyY/3/xUATK05Ko35oLTkKBZ+DK5jKRz1mNfuJ6JsMIpgP8 GV4NLCavr+BMIZy9qVaDojrWA3Er0rPZ6cQyHB7MdmaKu5zRi9A47YICn3woYqd/2PQj rOXeXp1GVzSSP1uD2YVHWW5Fh8OjF8AmWK970nNIGcOpzc3oTj2Il6IA25de9BlnrsiX 85KZCBDwAbOEHZQx4ZeAQhJM1SE2JQr63p4k6IIxp1mIdOZOC5h4VJjiZCuLNISkeQfJ I4uQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@mediatek.com header.s=dk header.b=uZZ+X3ca; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.31 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=mediatek.com Received: from morse.vger.email (morse.vger.email. [23.128.96.31]) by mx.google.com with ESMTPS id l13-20020a170903244d00b001c413905d87si15409487pls.49.2023.10.11.05.27.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 11 Oct 2023 05:27:47 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.31 as permitted sender) client-ip=23.128.96.31; Authentication-Results: mx.google.com; dkim=pass header.i=@mediatek.com header.s=dk header.b=uZZ+X3ca; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.31 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=mediatek.com Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by morse.vger.email (Postfix) with ESMTP id 6C686836E25C; Wed, 11 Oct 2023 05:27:44 -0700 (PDT) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.10 at morse.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1346252AbjJKM1d (ORCPT <rfc822;kartikey406@gmail.com> + 18 others); Wed, 11 Oct 2023 08:27:33 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44442 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1346994AbjJKM1T (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Wed, 11 Oct 2023 08:27:19 -0400 Received: from mailgw02.mediatek.com (unknown [210.61.82.184]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B1326129; Wed, 11 Oct 2023 05:27:11 -0700 (PDT) X-UUID: 799385de683111ee8051498923ad61e6-20231011 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Type:Content-Transfer-Encoding:MIME-Version:Message-ID:Date:Subject:CC:To:From; bh=tjQ7E6Wp7xtRDuxyM0IzhGgHnDmusITOkaUsg2pucuI=; b=uZZ+X3ca/d4K8RayxRmlPMJoikpMBRo00UOYiPMT5nSfIT/Ww356mG4Z1MuVG1QDFOpTWrSUn+30Yq0Js9i+HJ4ObzDPjk2ySF2afJl+kYRk199qNl2EtRps5R3NN7fnk8dK7R2aYXWmoQI1G53C4T4e2vHcl57fJrz3YYM7FtQ=; X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.1.32,REQID:ec485785-e832-468d-8208-758c8f7f0029,IP:0,U RL:0,TC:0,Content:-25,EDM:0,RT:0,SF:0,FILE:0,BULK:0,RULE:Release_Ham,ACTIO N:release,TS:-25 X-CID-META: VersionHash:5f78ec9,CLOUDID:fdcdabf0-9a6e-4c39-b73e-f2bc08ca3dc5,B ulkID:nil,BulkQuantity:0,Recheck:0,SF:102,TC:nil,Content:0,EDM:-3,IP:nil,U RL:11|1,File:nil,Bulk:nil,QS:nil,BEC:nil,COL:0,OSI:0,OSA:0,AV:0,LES:1,SPR: NO,DKR:0,DKP:0,BRR:0,BRE:0 X-CID-BVR: 0,NGT X-CID-BAS: 0,NGT,0,_ X-CID-FACTOR: TF_CID_SPAM_SNR,TF_CID_SPAM_ULN X-UUID: 799385de683111ee8051498923ad61e6-20231011 Received: from mtkmbs11n1.mediatek.inc [(172.21.101.185)] by mailgw02.mediatek.com (envelope-from <jianjun.wang@mediatek.com>) (Generic MTA with TLSv1.2 ECDHE-RSA-AES256-GCM-SHA384 256/256) with ESMTP id 1890463482; Wed, 11 Oct 2023 20:26:59 +0800 Received: from mtkmbs13n1.mediatek.inc (172.21.101.193) by mtkmbs11n2.mediatek.inc (172.21.101.187) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1118.26; Wed, 11 Oct 2023 20:26:58 +0800 Received: from mhfsdcap04.gcn.mediatek.inc (10.17.3.154) by mtkmbs13n1.mediatek.inc (172.21.101.73) with Microsoft SMTP Server id 15.2.1118.26 via Frontend Transport; Wed, 11 Oct 2023 20:26:57 +0800 From: Jianjun Wang <jianjun.wang@mediatek.com> To: Lorenzo Pieralisi <lpieralisi@kernel.org>, =?utf-8?q?Krzysztof_Wilczy?= =?utf-8?q?=C5=84ski?= <kw@linux.com>, Rob Herring <robh@kernel.org>, Bjorn Helgaas <bhelgaas@google.com>, Matthias Brugger <matthias.bgg@gmail.com>, AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com> CC: <linux-pci@vger.kernel.org>, <linux-mediatek@lists.infradead.org>, <linux-kernel@vger.kernel.org>, <linux-arm-kernel@lists.infradead.org>, Ryder Lee <ryder.lee@mediatek.com>, Jianjun Wang <jianjun.wang@mediatek.com>, <jieyy.yang@mediatek.com>, <chuanjia.liu@mediatek.com>, <qizhong.cheng@mediatek.com>, <jian.yang@mediatek.com> Subject: [PATCH] PCI: mediatek-gen3: Fix translation window Date: Wed, 11 Oct 2023 20:26:33 +0800 Message-ID: <20231011122633.31559-1-jianjun.wang@mediatek.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain X-MTK: N X-Spam-Status: No, score=2.7 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, RCVD_IN_SBL_CSS,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY autolearn=no autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on morse.vger.email Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (morse.vger.email [0.0.0.0]); Wed, 11 Oct 2023 05:27:44 -0700 (PDT) X-Spam-Level: ** X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1779462063291712735 X-GMAIL-MSGID: 1779462063291712735 |
Series |
PCI: mediatek-gen3: Fix translation window
|
|
Commit Message
Jianjun Wang (王建军)
Oct. 11, 2023, 12:26 p.m. UTC
The size of translation table should be a power of 2, using fls() cannot get the proper value when the size is not a power of 2. For example, fls(0x3e00000) - 1 = 25, hence the PCIe translation window size will be set to 0x2000000 instead of the expected size 0x3e00000. Fix translation window by splitting the MMIO space to multiple tables if its size is not a power of 2. Fixes: d3bf75b579b9 ("PCI: mediatek-gen3: Add MediaTek Gen3 driver for MT8192") Signed-off-by: Jianjun Wang <jianjun.wang@mediatek.com> --- Bootup logs on MT8195 Platform: > Before this patch: mtk-pcie-gen3 112f0000.pcie: Parsing ranges property... mtk-pcie-gen3 112f0000.pcie: IO 0x0020000000..0x00201fffff -> 0x0020000000 mtk-pcie-gen3 112f0000.pcie: MEM 0x0020200000..0x0023ffffff -> 0x0020200000 mtk-pcie-gen3 112f0000.pcie: set IO trans window[0]: cpu_addr = 0x20000000, pci_addr = 0x20000000, size = 0x200000 mtk-pcie-gen3 112f0000.pcie: set MEM trans window[1]: cpu_addr = 0x20200000, pci_addr = 0x20200000, size = 0x3e00000 > We expect the MEM trans window size to be 0x3e00000, but its actual available size is 0x2000000. > After applying this patch: mtk-pcie-gen3 112f0000.pcie: Parsing ranges property... mtk-pcie-gen3 112f0000.pcie: IO 0x0020000000..0x00201fffff -> 0x0020000000 mtk-pcie-gen3 112f0000.pcie: MEM 0x0020200000..0x0023ffffff -> 0x0020200000 mtk-pcie-gen3 112f0000.pcie: set IO trans window[0]: cpu_addr = 0x20000000, pci_addr = 0x20000000, size = 0x200000 mtk-pcie-gen3 112f0000.pcie: set MEM trans window[1]: cpu_addr = 0x20200000, pci_addr = 0x20200000, size = 0x200000 mtk-pcie-gen3 112f0000.pcie: set MEM trans window[2]: cpu_addr = 0x20400000, pci_addr = 0x20400000, size = 0x400000 mtk-pcie-gen3 112f0000.pcie: set MEM trans window[3]: cpu_addr = 0x20800000, pci_addr = 0x20800000, size = 0x800000 mtk-pcie-gen3 112f0000.pcie: set MEM trans window[4]: cpu_addr = 0x21000000, pci_addr = 0x21000000, size = 0x1000000 mtk-pcie-gen3 112f0000.pcie: set MEM trans window[5]: cpu_addr = 0x22000000, pci_addr = 0x22000000, size = 0x2000000 > Total available size for MEM trans window is 0x3e00000. --- --- drivers/pci/controller/pcie-mediatek-gen3.c | 87 ++++++++++++--------- 1 file changed, 52 insertions(+), 35 deletions(-)
Comments
On 11/10/2023 14:26, Jianjun Wang wrote: > The size of translation table should be a power of 2, using fls() cannot > get the proper value when the size is not a power of 2. For example, > fls(0x3e00000) - 1 = 25, hence the PCIe translation window size will be > set to 0x2000000 instead of the expected size 0x3e00000. Fix translation > window by splitting the MMIO space to multiple tables if its size is not > a power of 2. Hi Jianjun, I've no knowledge in PCIE, so maybe what my suggestion is stupid: Is it mandatory to fit the translation table size with 0x3e00000 (in this example) ? I'm asking because you can have an issue by reaching the maximum translation table number. Is it possible to just use only one table with the power of 2 size above 0x3e00000 => 0x4000000 ( fls(0x3e00000) = 26 = 0x4000000). The downside of this method is wasting allocation space. AFAIK I already see this kind of method for memory protection/allocation in embedded systems, so I'm wondering if this method is safer than using multiple table for only one size which isn't a power of 2.
On Wed, 2023-10-11 at 17:38 +0200, Alexandre Mergnat wrote: > > External email : Please do not click links or open attachments until > you have verified the sender or the content. > > > On 11/10/2023 14:26, Jianjun Wang wrote: > > The size of translation table should be a power of 2, using fls() > cannot > > get the proper value when the size is not a power of 2. For > example, > > fls(0x3e00000) - 1 = 25, hence the PCIe translation window size > will be > > set to 0x2000000 instead of the expected size 0x3e00000. Fix > translation > > window by splitting the MMIO space to multiple tables if its size > is not > > a power of 2. > > Hi Jianjun, > > I've no knowledge in PCIE, so maybe what my suggestion is stupid: > > Is it mandatory to fit the translation table size with 0x3e00000 (in > this example) ? > I'm asking because you can have an issue by reaching the maximum > translation table number. > > Is it possible to just use only one table with the power of 2 size > above > 0x3e00000 => 0x4000000 ( fls(0x3e00000) = 26 = 0x4000000). The > downside > of this method is wasting allocation space. AFAIK I already see this > kind of method for memory protection/allocation in embedded systems, > so > I'm wondering if this method is safer than using multiple table for > only > one size which isn't a power of 2. Hi Alexandre, It's not mandatory to fit the translation table size with 0x3e00000, and yes we can use only one table with the power of 2 size to prevent this. For MediaTek's SoCs, the MMIO space range for each PCIe port is fixed, and it will always be a power of 2, most of them will be 64MB. The reason we have the size which isn't a power of 2 is that we reserve an IO space for compatible purpose, some older devices may still use IO space. Take MT8195 as an example, its MMIO size is 64MB, and the declaration in the DT is like: ranges = <0x81000000 0 0x20000000 0x0 0x20000000 0 0x200000>, <0x82000000 0 0x20200000 0x0 0x20200000 0 0x3e00000>; The MMIO space is splited to 2MB IO space and 62MB MEM space, that's cause the current risk of the MEM space range, its actual available MEM space is 32MB. But it still works for now because most of the devices only require a very small amount of MEM space and will not reach ranges higher than 32MB. So for the concern of reaching the maximum translation table number, I think maybe we can just print the warning message instead of return error code, since it still works but have some limitations(MEM space not set as DT expected). Thanks. > > > -- > Regards, > Alexandre
On 12/10/2023 08:17, Jianjun Wang (王建军) wrote: > On Wed, 2023-10-11 at 17:38 +0200, Alexandre Mergnat wrote: >> >> External email : Please do not click links or open attachments until >> you have verified the sender or the content. >> >> >> On 11/10/2023 14:26, Jianjun Wang wrote: >> > The size of translation table should be a power of 2, using fls() >> cannot >> > get the proper value when the size is not a power of 2. For >> example, >> > fls(0x3e00000) - 1 = 25, hence the PCIe translation window size >> will be >> > set to 0x2000000 instead of the expected size 0x3e00000. Fix >> translation >> > window by splitting the MMIO space to multiple tables if its size >> is not >> > a power of 2. >> >> Hi Jianjun, >> >> I've no knowledge in PCIE, so maybe what my suggestion is stupid: >> >> Is it mandatory to fit the translation table size with 0x3e00000 (in >> this example) ? >> I'm asking because you can have an issue by reaching the maximum >> translation table number. >> >> Is it possible to just use only one table with the power of 2 size >> above >> 0x3e00000 => 0x4000000 ( fls(0x3e00000) = 26 = 0x4000000). The >> downside >> of this method is wasting allocation space. AFAIK I already see this >> kind of method for memory protection/allocation in embedded systems, >> so >> I'm wondering if this method is safer than using multiple table for >> only >> one size which isn't a power of 2. > > Hi Alexandre, > > It's not mandatory to fit the translation table size with 0x3e00000, > and yes we can use only one table with the power of 2 size to prevent > this. > > For MediaTek's SoCs, the MMIO space range for each PCIe port is fixed, > and it will always be a power of 2, most of them will be 64MB. The > reason we have the size which isn't a power of 2 is that we reserve an > IO space for compatible purpose, some older devices may still use IO > space. > > Take MT8195 as an example, its MMIO size is 64MB, and the declaration > in the DT is like: > ranges = <0x81000000 0 0x20000000 0x0 0x20000000 0 0x200000>, > <0x82000000 0 0x20200000 0x0 0x20200000 0 0x3e00000>; > > The MMIO space is splited to 2MB IO space and 62MB MEM space, that's > cause the current risk of the MEM space range, its actual available MEM > space is 32MB. But it still works for now because most of the devices > only require a very small amount of MEM space and will not reach ranges > higher than 32MB. > > So for the concern of reaching the maximum translation table number, I > think maybe we can just print the warning message instead of return > error code, since it still works but have some limitations(MEM space > not set as DT expected). > Ok understood, thanks for your explanation. Then, IMHO, you should use only one table with the power of 2 size above to make the code simpler, efficient, robust, more readable and avoid confusion about the warning. This is what is done for pci-mvebu.c AFAII. If you prefer waiting another reviewer with a better PCIE expertise than me, it's ok for me. With the information I have currently, I prefer to not approve the current implementation because, from my PoV, it introduce unnecessary complexity. Thanks
Il 12/10/23 12:27, Alexandre Mergnat ha scritto: > > > On 12/10/2023 08:17, Jianjun Wang (王建军) wrote: >> On Wed, 2023-10-11 at 17:38 +0200, Alexandre Mergnat wrote: >>> External email : Please do not click links or open attachments until >>> you have verified the sender or the content. >>> >>> >>> On 11/10/2023 14:26, Jianjun Wang wrote: >>> > The size of translation table should be a power of 2, using fls() >>> cannot > get the proper value when the size is not a power of 2. For >>> example, > fls(0x3e00000) - 1 = 25, hence the PCIe translation window size >>> will be > set to 0x2000000 instead of the expected size 0x3e00000. Fix >>> translation > window by splitting the MMIO space to multiple tables if its size >>> is not > a power of 2. >>> >>> Hi Jianjun, >>> >>> I've no knowledge in PCIE, so maybe what my suggestion is stupid: >>> >>> Is it mandatory to fit the translation table size with 0x3e00000 (in this >>> example) ? >>> I'm asking because you can have an issue by reaching the maximum translation >>> table number. >>> >>> Is it possible to just use only one table with the power of 2 size >>> above 0x3e00000 => 0x4000000 ( fls(0x3e00000) = 26 = 0x4000000). The >>> downside of this method is wasting allocation space. AFAIK I already see this >>> kind of method for memory protection/allocation in embedded systems, >>> so I'm wondering if this method is safer than using multiple table for >>> only one size which isn't a power of 2. >> >> Hi Alexandre, >> >> It's not mandatory to fit the translation table size with 0x3e00000, >> and yes we can use only one table with the power of 2 size to prevent >> this. >> >> For MediaTek's SoCs, the MMIO space range for each PCIe port is fixed, >> and it will always be a power of 2, most of them will be 64MB. The >> reason we have the size which isn't a power of 2 is that we reserve an >> IO space for compatible purpose, some older devices may still use IO >> space. >> >> Take MT8195 as an example, its MMIO size is 64MB, and the declaration >> in the DT is like: >> ranges = <0x81000000 0 0x20000000 0x0 0x20000000 0 0x200000>, >> <0x82000000 0 0x20200000 0x0 0x20200000 0 0x3e00000>; >> >> The MMIO space is splited to 2MB IO space and 62MB MEM space, that's >> cause the current risk of the MEM space range, its actual available MEM >> space is 32MB. But it still works for now because most of the devices >> only require a very small amount of MEM space and will not reach ranges >> higher than 32MB. >> >> So for the concern of reaching the maximum translation table number, I >> think maybe we can just print the warning message instead of return >> error code, since it still works but have some limitations(MEM space >> not set as DT expected). >> > > Ok understood, thanks for your explanation. > Then, IMHO, you should use only one table with the power of 2 size above to make > the code simpler, efficient, robust, more readable and avoid confusion about the > warning. > > This is what is done for pci-mvebu.c AFAII. > > If you prefer waiting another reviewer with a better PCIE expertise than me, it's > ok for me. With the information I have currently, I prefer to not approve the > current implementation because, from my PoV, it introduce unnecessary complexity. > From what I understand, using only one table with a size that is a power of two won't let us use the entire MMIO space, hence the only solution to allow using the entire range is to split to more than one table. I'm not sure, though, whether PCIe devices would be able to use a MEM space that is not power of two, or if those do even exist. If there are devices that can use 32MB < mem <= 62MB, then I completely agree with Jianjun on this commit.... so please, can any PCI(/e) maintainer comment on this situation? Regards, Angelo
On 12/10/2023 14:52, AngeloGioacchino Del Regno wrote: > Il 12/10/23 12:27, Alexandre Mergnat ha scritto: >> >> >> On 12/10/2023 08:17, Jianjun Wang (王建军) wrote: >>> On Wed, 2023-10-11 at 17:38 +0200, Alexandre Mergnat wrote: >>>> External email : Please do not click links or open attachments until >>>> you have verified the sender or the content. >>>> >>>> >>>> On 11/10/2023 14:26, Jianjun Wang wrote: >>>> > The size of translation table should be a power of 2, using fls() >>>> cannot > get the proper value when the size is not a power of 2. For >>>> example, > fls(0x3e00000) - 1 = 25, hence the PCIe translation >>>> window size >>>> will be > set to 0x2000000 instead of the expected size 0x3e00000. Fix >>>> translation > window by splitting the MMIO space to multiple tables >>>> if its size >>>> is not > a power of 2. >>>> >>>> Hi Jianjun, >>>> >>>> I've no knowledge in PCIE, so maybe what my suggestion is stupid: >>>> >>>> Is it mandatory to fit the translation table size with 0x3e00000 (in >>>> this example) ? >>>> I'm asking because you can have an issue by reaching the maximum >>>> translation table number. >>>> >>>> Is it possible to just use only one table with the power of 2 size >>>> above 0x3e00000 => 0x4000000 ( fls(0x3e00000) = 26 = 0x4000000). The >>>> downside of this method is wasting allocation space. AFAIK I already >>>> see this kind of method for memory protection/allocation in embedded >>>> systems, >>>> so I'm wondering if this method is safer than using multiple table for >>>> only one size which isn't a power of 2. >>> >>> Hi Alexandre, >>> >>> It's not mandatory to fit the translation table size with 0x3e00000, >>> and yes we can use only one table with the power of 2 size to prevent >>> this. >>> >>> For MediaTek's SoCs, the MMIO space range for each PCIe port is fixed, >>> and it will always be a power of 2, most of them will be 64MB. The >>> reason we have the size which isn't a power of 2 is that we reserve an >>> IO space for compatible purpose, some older devices may still use IO >>> space. >>> >>> Take MT8195 as an example, its MMIO size is 64MB, and the declaration >>> in the DT is like: >>> ranges = <0x81000000 0 0x20000000 0x0 0x20000000 0 0x200000>, >>> <0x82000000 0 0x20200000 0x0 0x20200000 0 0x3e00000>; >>> >>> The MMIO space is splited to 2MB IO space and 62MB MEM space, that's >>> cause the current risk of the MEM space range, its actual available MEM >>> space is 32MB. But it still works for now because most of the devices >>> only require a very small amount of MEM space and will not reach ranges >>> higher than 32MB. >>> >>> So for the concern of reaching the maximum translation table number, I >>> think maybe we can just print the warning message instead of return >>> error code, since it still works but have some limitations(MEM space >>> not set as DT expected). >>> >> >> Ok understood, thanks for your explanation. >> Then, IMHO, you should use only one table with the power of 2 size >> above to make the code simpler, efficient, robust, more readable and >> avoid confusion about the warning. >> >> This is what is done for pci-mvebu.c AFAII. >> >> If you prefer waiting another reviewer with a better PCIE expertise >> than me, it's ok for me. With the information I have currently, I >> prefer to not approve the current implementation because, from my PoV, >> it introduce unnecessary complexity. >> > > From what I understand, using only one table with a size that is a > power of two > won't let us use the entire MMIO space, hence the only solution to allow > using > the entire range is to split to more than one table. You can take the power of 2 above, which is directly returned by fls(). That let us use the entire MMIO space. In this example, if your size is 0x3e00000, the you will allow 0x4000000.
On Thu, 2023-10-12 at 15:30 +0200, Alexandre Mergnat wrote: > > External email : Please do not click links or open attachments until > you have verified the sender or the content. > > > On 12/10/2023 14:52, AngeloGioacchino Del Regno wrote: > > Il 12/10/23 12:27, Alexandre Mergnat ha scritto: > >> > >> > >> On 12/10/2023 08:17, Jianjun Wang (王建军) wrote: > >>> On Wed, 2023-10-11 at 17:38 +0200, Alexandre Mergnat wrote: > >>>> External email : Please do not click links or open attachments > until > >>>> you have verified the sender or the content. > >>>> > >>>> > >>>> On 11/10/2023 14:26, Jianjun Wang wrote: > >>>> > The size of translation table should be a power of 2, using > fls() > >>>> cannot > get the proper value when the size is not a power of 2. > For > >>>> example, > fls(0x3e00000) - 1 = 25, hence the PCIe translation > >>>> window size > >>>> will be > set to 0x2000000 instead of the expected size > 0x3e00000. Fix > >>>> translation > window by splitting the MMIO space to multiple > tables > >>>> if its size > >>>> is not > a power of 2. > >>>> > >>>> Hi Jianjun, > >>>> > >>>> I've no knowledge in PCIE, so maybe what my suggestion is > stupid: > >>>> > >>>> Is it mandatory to fit the translation table size with 0x3e00000 > (in > >>>> this example) ? > >>>> I'm asking because you can have an issue by reaching the > maximum > >>>> translation table number. > >>>> > >>>> Is it possible to just use only one table with the power of 2 > size > >>>> above 0x3e00000 => 0x4000000 ( fls(0x3e00000) = 26 = 0x4000000). > The > >>>> downside of this method is wasting allocation space. AFAIK I > already > >>>> see this kind of method for memory protection/allocation in > embedded > >>>> systems, > >>>> so I'm wondering if this method is safer than using multiple > table for > >>>> only one size which isn't a power of 2. > >>> > >>> Hi Alexandre, > >>> > >>> It's not mandatory to fit the translation table size with > 0x3e00000, > >>> and yes we can use only one table with the power of 2 size to > prevent > >>> this. > >>> > >>> For MediaTek's SoCs, the MMIO space range for each PCIe port is > fixed, > >>> and it will always be a power of 2, most of them will be 64MB. > The > >>> reason we have the size which isn't a power of 2 is that we > reserve an > >>> IO space for compatible purpose, some older devices may still use > IO > >>> space. > >>> > >>> Take MT8195 as an example, its MMIO size is 64MB, and the > declaration > >>> in the DT is like: > >>> ranges = <0x81000000 0 0x20000000 0x0 0x20000000 0 0x200000>, > >>> <0x82000000 0 0x20200000 0x0 0x20200000 0 0x3e00000>; > >>> > >>> The MMIO space is splited to 2MB IO space and 62MB MEM space, > that's > >>> cause the current risk of the MEM space range, its actual > available MEM > >>> space is 32MB. But it still works for now because most of the > devices > >>> only require a very small amount of MEM space and will not reach > ranges > >>> higher than 32MB. > >>> > >>> So for the concern of reaching the maximum translation table > number, I > >>> think maybe we can just print the warning message instead of > return > >>> error code, since it still works but have some limitations(MEM > space > >>> not set as DT expected). > >>> > >> > >> Ok understood, thanks for your explanation. > >> Then, IMHO, you should use only one table with the power of 2 > size > >> above to make the code simpler, efficient, robust, more readable > and > >> avoid confusion about the warning. > >> > >> This is what is done for pci-mvebu.c AFAII. > >> > >> If you prefer waiting another reviewer with a better PCIE > expertise > >> than me, it's ok for me. With the information I have currently, I > >> prefer to not approve the current implementation because, from my > PoV, > >> it introduce unnecessary complexity. > >> > > > > From what I understand, using only one table with a size that is > a > > power of two > > won't let us use the entire MMIO space, hence the only solution to > allow > > using > > the entire range is to split to more than one table. > > You can take the power of 2 above, which is directly returned by > fls(). > That let us use the entire MMIO space. > In this example, if your size is 0x3e00000, the you will allow > 0x4000000. Take the power of 2 above size is a solution, but another concern will be the flexibility. With this patch, we can split the MMIO space to multiple ranges like: ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x100000>, <0x81000000 0 0x20100000 0x0 0x20100000 0 0x300000>, <0x82000000 0 0x20300000 0x0 0x20300000 0 0x3c00000>; Not sure if that can really happen, but it will have overlap ranges when take the power of 2 above. Thanks. > > > -- > Regards, > Alexandre
On Wed, 2023-10-11 at 17:38 +0200, Alexandre Mergnat wrote: > > External email : Please do not click links or open attachments until > you have verified the sender or the content. > > > On 11/10/2023 14:26, Jianjun Wang wrote: > > The size of translation table should be a power of 2, using fls() > cannot > > get the proper value when the size is not a power of 2. For > example, > > fls(0x3e00000) - 1 = 25, hence the PCIe translation window size > will be > > set to 0x2000000 instead of the expected size 0x3e00000. Fix > translation > > window by splitting the MMIO space to multiple tables if its size > is not > > a power of 2. > > Hi Jianjun, > > I've no knowledge in PCIE, so maybe what my suggestion is stupid: > > Is it mandatory to fit the translation table size with 0x3e00000 (in > this example) ? > I'm asking because you can have an issue by reaching the maximum > translation table number. > > Is it possible to just use only one table with the power of 2 size > above > 0x3e00000 => 0x4000000 ( fls(0x3e00000) = 26 = 0x4000000). The > downside > of this method is wasting allocation space. AFAIK I already see this > kind of method for memory protection/allocation in embedded systems, > so > I'm wondering if this method is safer than using multiple table for > only > one size which isn't a power of 2. Hi Alexandre, It's not mandatory to fit the translation table size with 0x3e00000, and yes we can use only one table with the power of 2 size to prevent this. For MediaTek's SoCs, the MMIO space range for each PCIe port is fixed, and it will always be a power of 2, most of them will be 64MB. The reason we have the size which isn't a power of 2 is that we reserve an IO space for compatible purposes, some older devices may still use IO space. Take MT8195 as an example, its MMIO size is 64MB, and the declaration in the DT is like: ranges = <0x81000000 0 0x20000000 0x0 0x20000000 0 0x200000>, <0x82000000 0 0x20200000 0x0 0x20200000 0 0x3e00000>; The MMIO space is splited to 2MB IO space and 62MB MEM space, that's cause the current risk of using the MEM space, since its actual available MEM space is 32MB. But it still works for now because most of the devices only require a very small amount of MEM space and will not reach ranges higher than 32MB. So for the concern of reaching the maximum translation number, I think maybe we can just print the warning message instead of return error code, since it still works but have some limitations(MEM space not set as DT expected). Thanks. > > > -- > Regards, > Alexandre
On 13/10/2023 04:52, Jianjun Wang (王建军) wrote: > On Thu, 2023-10-12 at 15:30 +0200, Alexandre Mergnat wrote: >> >> External email : Please do not click links or open attachments until >> you have verified the sender or the content. >> >> >> On 12/10/2023 14:52, AngeloGioacchino Del Regno wrote: >> > Il 12/10/23 12:27, Alexandre Mergnat ha scritto: >> >> >> >> >> >> On 12/10/2023 08:17, Jianjun Wang (王建军) wrote: >> >>> On Wed, 2023-10-11 at 17:38 +0200, Alexandre Mergnat wrote: >> >>>> External email : Please do not click links or open attachments >> until >> >>>> you have verified the sender or the content. >> >>>> >> >>>> >> >>>> On 11/10/2023 14:26, Jianjun Wang wrote: >> >>>> > The size of translation table should be a power of 2, using >> fls() >> >>>> cannot > get the proper value when the size is not a power of 2. >> For >> >>>> example, > fls(0x3e00000) - 1 = 25, hence the PCIe translation >> >>>> window size >> >>>> will be > set to 0x2000000 instead of the expected size >> 0x3e00000. Fix >> >>>> translation > window by splitting the MMIO space to multiple >> tables >> >>>> if its size >> >>>> is not > a power of 2. >> >>>> >> >>>> Hi Jianjun, >> >>>> >> >>>> I've no knowledge in PCIE, so maybe what my suggestion is >> stupid: >> >>>> >> >>>> Is it mandatory to fit the translation table size with 0x3e00000 >> (in >> >>>> this example) ? >> >>>> I'm asking because you can have an issue by reaching the >> maximum >> >>>> translation table number. >> >>>> >> >>>> Is it possible to just use only one table with the power of 2 >> size >> >>>> above 0x3e00000 => 0x4000000 ( fls(0x3e00000) = 26 = 0x4000000). >> The >> >>>> downside of this method is wasting allocation space. AFAIK I >> already >> >>>> see this kind of method for memory protection/allocation in >> embedded >> >>>> systems, >> >>>> so I'm wondering if this method is safer than using multiple >> table for >> >>>> only one size which isn't a power of 2. >> >>> >> >>> Hi Alexandre, >> >>> >> >>> It's not mandatory to fit the translation table size with >> 0x3e00000, >> >>> and yes we can use only one table with the power of 2 size to >> prevent >> >>> this. >> >>> >> >>> For MediaTek's SoCs, the MMIO space range for each PCIe port is >> fixed, >> >>> and it will always be a power of 2, most of them will be 64MB. >> The >> >>> reason we have the size which isn't a power of 2 is that we >> reserve an >> >>> IO space for compatible purpose, some older devices may still use >> IO >> >>> space. >> >>> >> >>> Take MT8195 as an example, its MMIO size is 64MB, and the >> declaration >> >>> in the DT is like: >> >>> ranges = <0x81000000 0 0x20000000 0x0 0x20000000 0 0x200000>, >> >>> <0x82000000 0 0x20200000 0x0 0x20200000 0 0x3e00000>; >> >>> >> >>> The MMIO space is splited to 2MB IO space and 62MB MEM space, >> that's >> >>> cause the current risk of the MEM space range, its actual >> available MEM >> >>> space is 32MB. But it still works for now because most of the >> devices >> >>> only require a very small amount of MEM space and will not reach >> ranges >> >>> higher than 32MB. >> >>> >> >>> So for the concern of reaching the maximum translation table >> number, I >> >>> think maybe we can just print the warning message instead of >> return >> >>> error code, since it still works but have some limitations(MEM >> space >> >>> not set as DT expected). >> >>> >> >> >> >> Ok understood, thanks for your explanation. >> >> Then, IMHO, you should use only one table with the power of 2 >> size >> >> above to make the code simpler, efficient, robust, more readable >> and >> >> avoid confusion about the warning. >> >> >> >> This is what is done for pci-mvebu.c AFAII. >> >> >> >> If you prefer waiting another reviewer with a better PCIE >> expertise >> >> than me, it's ok for me. With the information I have currently, I >> >> prefer to not approve the current implementation because, from my >> PoV, >> >> it introduce unnecessary complexity. >> >> >> > >> > From what I understand, using only one table with a size that is >> a >> > power of two >> > won't let us use the entire MMIO space, hence the only solution to >> allow >> > using >> > the entire range is to split to more than one table. >> >> You can take the power of 2 above, which is directly returned by >> fls(). >> That let us use the entire MMIO space. >> In this example, if your size is 0x3e00000, the you will allow >> 0x4000000. > > Take the power of 2 above size is a solution, but another concern will > be the flexibility. With this patch, we can split the MMIO space to > multiple ranges like: > ranges = <0x82000000 0 0x20000000 0x0 0x20000000 0 0x100000>, > <0x81000000 0 0x20100000 0x0 0x20100000 0 0x300000>, > <0x82000000 0 0x20300000 0x0 0x20300000 0 0x3c00000>; > Not sure if that can really happen, but it will have overlap ranges > when take the power of 2 above. Yes, you can avoid overlap by changing the next start address to fit the previous allocated range. If that isn't possible or introduce too much complexity compared to your solution, then your implementation could be the best from my PoV. :)
diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c index e0e27645fdf4..3f2496b135ae 100644 --- a/drivers/pci/controller/pcie-mediatek-gen3.c +++ b/drivers/pci/controller/pcie-mediatek-gen3.c @@ -245,35 +245,62 @@ static int mtk_pcie_set_trans_table(struct mtk_gen3_pcie *pcie, resource_size_t cpu_addr, resource_size_t pci_addr, resource_size_t size, - unsigned long type, int num) + unsigned long type, int *num) { + resource_size_t remaining = size; + resource_size_t table_size; + resource_size_t addr_align; + const char *range_type; void __iomem *table; u32 val; - if (num >= PCIE_MAX_TRANS_TABLES) { - dev_err(pcie->dev, "not enough translate table for addr: %#llx, limited to [%d]\n", - (unsigned long long)cpu_addr, PCIE_MAX_TRANS_TABLES); - return -ENODEV; - } + while (remaining && (*num < PCIE_MAX_TRANS_TABLES)) { + /* Table size needs to be a power of 2 */ + table_size = BIT(fls(remaining) - 1); - table = pcie->base + PCIE_TRANS_TABLE_BASE_REG + - num * PCIE_ATR_TLB_SET_OFFSET; + if (cpu_addr > 0) { + addr_align = BIT(ffs(cpu_addr) - 1); + table_size = min(table_size, addr_align); + } - writel_relaxed(lower_32_bits(cpu_addr) | PCIE_ATR_SIZE(fls(size) - 1), - table); - writel_relaxed(upper_32_bits(cpu_addr), - table + PCIE_ATR_SRC_ADDR_MSB_OFFSET); - writel_relaxed(lower_32_bits(pci_addr), - table + PCIE_ATR_TRSL_ADDR_LSB_OFFSET); - writel_relaxed(upper_32_bits(pci_addr), - table + PCIE_ATR_TRSL_ADDR_MSB_OFFSET); + /* Minimum size of translate table is 4KiB */ + if (table_size < 0x1000) { + dev_err(pcie->dev, "illegal table size %#llx\n", + (unsigned long long)table_size); + return -EINVAL; + } - if (type == IORESOURCE_IO) - val = PCIE_ATR_TYPE_IO | PCIE_ATR_TLP_TYPE_IO; - else - val = PCIE_ATR_TYPE_MEM | PCIE_ATR_TLP_TYPE_MEM; + table = pcie->base + PCIE_TRANS_TABLE_BASE_REG + *num * PCIE_ATR_TLB_SET_OFFSET; + writel_relaxed(lower_32_bits(cpu_addr) | PCIE_ATR_SIZE(fls(table_size) - 1), table); + writel_relaxed(upper_32_bits(cpu_addr), table + PCIE_ATR_SRC_ADDR_MSB_OFFSET); + writel_relaxed(lower_32_bits(pci_addr), table + PCIE_ATR_TRSL_ADDR_LSB_OFFSET); + writel_relaxed(upper_32_bits(pci_addr), table + PCIE_ATR_TRSL_ADDR_MSB_OFFSET); - writel_relaxed(val, table + PCIE_ATR_TRSL_PARAM_OFFSET); + if (type == IORESOURCE_IO) { + val = PCIE_ATR_TYPE_IO | PCIE_ATR_TLP_TYPE_IO; + range_type = "IO"; + } else { + val = PCIE_ATR_TYPE_MEM | PCIE_ATR_TLP_TYPE_MEM; + range_type = "MEM"; + } + + writel_relaxed(val, table + PCIE_ATR_TRSL_PARAM_OFFSET); + + dev_dbg(pcie->dev, "set %s trans window[%d]: cpu_addr = %#llx, pci_addr = %#llx, size = %#llx\n", + range_type, *num, (unsigned long long)cpu_addr, + (unsigned long long)pci_addr, (unsigned long long)table_size); + + cpu_addr += table_size; + pci_addr += table_size; + remaining -= table_size; + (*num)++; + } + + if (remaining) { + dev_err(pcie->dev, "not enough translate table for addr: %#llx, limited to [%d]\n", + (unsigned long long)cpu_addr, PCIE_MAX_TRANS_TABLES); + return -ENODEV; + } return 0; } @@ -380,30 +407,20 @@ static int mtk_pcie_startup_port(struct mtk_gen3_pcie *pcie) resource_size_t cpu_addr; resource_size_t pci_addr; resource_size_t size; - const char *range_type; - if (type == IORESOURCE_IO) { + if (type == IORESOURCE_IO) cpu_addr = pci_pio_to_address(res->start); - range_type = "IO"; - } else if (type == IORESOURCE_MEM) { + else if (type == IORESOURCE_MEM) cpu_addr = res->start; - range_type = "MEM"; - } else { + else continue; - } pci_addr = res->start - entry->offset; size = resource_size(res); err = mtk_pcie_set_trans_table(pcie, cpu_addr, pci_addr, size, - type, table_index); + type, &table_index); if (err) return err; - - dev_dbg(pcie->dev, "set %s trans window[%d]: cpu_addr = %#llx, pci_addr = %#llx, size = %#llx\n", - range_type, table_index, (unsigned long long)cpu_addr, - (unsigned long long)pci_addr, (unsigned long long)size); - - table_index++; } return 0;