From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.0 required=3.0 tests=HEADER_FROM_DIFFERENT_DOMAINS, MAILING_LIST_MULTI,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 194F8C04EBF for ; Tue, 4 Dec 2018 10:40:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id DC18520834 for ; Tue, 4 Dec 2018 10:40:42 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org DC18520834 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=amlogic.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726118AbeLDKkl (ORCPT ); Tue, 4 Dec 2018 05:40:41 -0500 Received: from mail-sh2.amlogic.com ([58.32.228.45]:37149 "EHLO mail-sh2.amlogic.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725769AbeLDKkl (ORCPT ); Tue, 4 Dec 2018 05:40:41 -0500 Received: from [10.18.29.147] (10.18.29.147) by mail-sh2.amlogic.com (10.18.11.6) with Microsoft SMTP Server (TLS) id 15.0.1320.4; Tue, 4 Dec 2018 18:40:55 +0800 Subject: Re: [PATCH v6 2/2] PCI: amlogic: Add the Amlogic Meson PCIe controller driver To: Bjorn Helgaas , Lorenzo Pieralisi CC: Rob Herring , Jianxin Pan , Kevin Hilman , Shawn Lin , Philippe Ombredanne , , , Yue Wang , Qiufang Dai , Jian Hu , Liang Yang , Cyrille Pitchen , Gustavo Pimentel , Carlo Caione , , , Jerome Brunet References: <1542876836-191355-1-git-send-email-hanjie.lin@amlogic.com> <1542876836-191355-3-git-send-email-hanjie.lin@amlogic.com> <20181203164150.GA11855@e107981-ln.cambridge.arm.com> <20181203225731.GE207198@google.com> From: Hanjie Lin Message-ID: <1bc8f5bd-6f69-4867-89ca-e5a611da9136@amlogic.com> Date: Tue, 4 Dec 2018 18:40:55 +0800 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:60.0) Gecko/20100101 Thunderbird/60.3.2 MIME-Version: 1.0 In-Reply-To: <20181203225731.GE207198@google.com> Content-Type: text/plain; charset="windows-1252" Content-Language: en-US Content-Transfer-Encoding: 7bit X-Originating-IP: [10.18.29.147] X-ClientProxiedBy: mail-sh2.amlogic.com (10.18.11.6) To mail-sh2.amlogic.com (10.18.11.6) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 2018/12/4 6:57, Bjorn Helgaas wrote: > On Mon, Dec 03, 2018 at 04:41:50PM +0000, Lorenzo Pieralisi wrote: >> On Thu, Nov 22, 2018 at 04:53:54PM +0800, Hanjie Lin wrote: >> >> [...] >> >>> +static int meson_pcie_rd_own_conf(struct pcie_port *pp, int where, int size, >>> + u32 *val) >>> +{ >>> + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); >>> + >>> + /* >>> + * there is a bug of MESON AXG pcie controller that software can not >>> + * programe PCI_CLASS_DEVICE register, so we must return a fake right >>> + * value to ensure driver could probe successfully. >>> + */ >>> + if (where == PCI_CLASS_REVISION) { >>> + *val = readl(pci->dbi_base + PCI_CLASS_REVISION); >>> + /* keep revision id */ >>> + *val &= PCI_CLASS_REVISION_MASK; >>> + *val |= PCI_CLASS_BRIDGE_PCI << 16; >>> + return PCIBIOS_SUCCESSFUL; >>> + } >> >> As I said before, this looks broken. If this code (or other drivers with >> the same broken assumptions, eg dwc/pcie-qcom.c) carries out a, say, >> byte sized config access of eg PCI_CLASS_DEVICE you will get junk out of >> it according to your comment above. >> >> I would like to pick Bjorn's brain on this to see what we can really do >> to fix this (and other) drivers. > > - Check to see whether you're reading anything in the 32-bit dword at > offset 0x08. > > - Do the 32-bit readl(). > > - Insert the correct Sub-Class and Base Class code (you also throw > away the Programming Interface; not sure why that is) > > - If you're reading something smaller than 32 bits, mask & shift as > needed. pci_bridge_emul_conf_read() does something similar that > you might be able to copy. > > Out of curiosity, what code depends on PCI_CLASS_BRIDGE_PCI? There > are several places in the kernel that currently depend on it, but I > think several of them *should* be checking dev->hdr_type to identify a > type 1 header instead. > > Bjorn > > . > Yes, it would be broken in particular scenes(eg: read 1 or 2 bytes from 0xa/PCI_CLASS_DEVICE) that I didn't considered. As your suggestion, I consider some code below may help this issue: 1, First call dw_pcie_read() help to read 1/2/4 bytes from register, request all other *size* bytes will return error and dw_pcie_read() will also check register alignment. 2, If dw_pcie_read() return success and *where* is 0x8/PCI_CLASS_DEVICE or 0xa/PCI_CLASS_REVISION, we may need to correct class code. As PCI_CLASS_REVISION is two-bytes register, so only when read 4 bytes from 0x8/PCI_CLASS_DEVICE or read 2 bytes from 0xa/PCI_CLASS_REVISION we should correct the class code. ps: read 1 byte from 0xa/PCI_CLASS_REVISION or 0xb will get incorrect value. static int meson_pcie_rd_own_conf(struct pcie_port *pp, int where, int size, u32 *val) { struct dw_pcie *pci = to_dw_pcie_from_pp(pp); int ret; ret = dw_pcie_read(pci->dbi_base + where, size, val); if (ret != PCIBIOS_SUCCESSFUL) return ret; /* * there is a bug of MESON AXG pcie controller that software can not * programe PCI_CLASS_DEVICE register, so we must return a fake right * value to ensure driver could probe successfully. */ if (where == PCI_CLASS_REVISION && size == 4) *val = (PCI_CLASS_BRIDGE_PCI << 16) | (*val & 0xffff); else if (where == PCI_CLASS_DEVICE && size == 2) *val = PCI_CLASS_BRIDGE_PCI; return PCIBIOS_SUCCESSFUL; } 3, We must ensure class is PCI_CLASS_BRIDGE_PCI except right hdr_type, or pci_setup_device() will get failed: ... class = pci_class(dev); dev->revision = class & 0xff; dev->class = class >> 8; /* upper 3 bytes */ .... switch (dev->hdr_type) { /* header type */ ... case PCI_HEADER_TYPE_BRIDGE: /* bridge header */ if (class != PCI_CLASS_BRIDGE_PCI) /* class must be PCI_CLASS_BRIDGE_PCI */ goto bad; thanks. hanjie