linux-pci.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Vidya Sagar <vidyas@nvidia.com>
To: Kishon Vijay Abraham I <kishon@ti.com>
Cc: Stephen Warren <swarren@wwwdotorg.org>,
	Jingoo Han <jingoohan1@gmail.com>,
	Gustavo Pimentel <gustavo.pimentel@synopsys.com>,
	Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>,
	Bjorn Helgaas <bhelgaas@google.com>, <linux-pci@vger.kernel.org>,
	Manikanta Maddireddy <mmaddireddy@nvidia.com>,
	Trent Piepho <tpiepho@impinj.com>,
	Stephen Warren <swarren@nvidia.com>
Subject: Re: [PATCH V2] PCI: dwc ep: cache config until DBI regs available
Date: Fri, 25 Oct 2019 19:20:54 +0530	[thread overview]
Message-ID: <feaa08b7-8e22-995f-d041-93733e3513ac@nvidia.com> (raw)
In-Reply-To: <79710923-1cff-dce8-bd73-326d7921d621@ti.com>

On 1/8/2019 5:35 PM, Kishon Vijay Abraham I wrote:
> Hi Stephen,
> 
> On 04/01/19 1:32 PM, Kishon Vijay Abraham I wrote:
>> Hi Stephen,
>>
>> On 02/01/19 10:04 PM, Stephen Warren wrote:
>>> On 12/19/18 7:37 AM, Kishon Vijay Abraham I wrote:
>>>> Hi,
>>>>
>>>> On 14/12/18 10:31 PM, Stephen Warren wrote:
>>>>> On 12/11/18 10:23 AM, Stephen Warren wrote:
>>>>>> On 12/10/18 9:36 PM, Kishon Vijay Abraham I wrote:
>>>>>>> Hi,
>>>>>>>
>>>>>>> On 27/11/18 4:39 AM, Stephen Warren wrote:
>>>>>>>> From: Stephen Warren <swarren@nvidia.com>
>>>>>>>>
>>>>>>>> Some implementations of the DWC PCIe endpoint controller do not allow
>>>>>>>> access to DBI registers until the attached host has started REFCLK,
>>>>>>>> released PERST, and the endpoint driver has initialized clocking of the
>>>>>>>> DBI registers based on that. One such system is NVIDIA's T194 SoC. The
>>>>>>>> PCIe endpoint subsystem and DWC driver currently don't work on such
>>>>>>>> hardware, since they assume that all endpoint configuration can happen
>>>>>>>> at any arbitrary time.
>>>>>>>>
>>>>>>>> Enhance the DWC endpoint driver to support such systems by caching all
>>>>>>>> endpoint configuration in software, and only writing the configuration
>>>>>>>> to hardware once it's been initialized. This is implemented by splitting
>>>>>>>> all endpoint controller ops into two functions; the first which simply
>>>>>>>> records/caches the desired configuration whenever called by the
>>>>>>>> associated function driver and optionally calls the second, and the
>>>>>>>> second which actually programs the configuration into hardware, which
>>>>>>>> may be called either by the first function, or later when it's known
>>>>>>>> that the DBI registers are available.
>>>>>>
>>>>>>>> diff --git a/drivers/pci/controller/dwc/pcie-designware-ep.c
>>>>>>>> b/drivers/pci/controller/dwc/pcie-designware-ep.c
>>>>>>
>>>>>>>> +void dw_pcie_set_regs_available(struct dw_pcie *pci)
>>>>>>>> +{
>>>>>>>
>>>>>>> When will this function be invoked? Does the wrapper get an interrupt when
>>>>>>> refclk is enabled where this function will be invoked?
>>>>>>
>>>>>> Yes, there's an IRQ from the HW that indicates when PEXRST is released. I
>>>>>> don't recall right now if this IRQ is something that exists for all DWC
>>>>>> instantiations, or is Tegra-specific.
>>>>>>
>>>>>>>> +    struct dw_pcie_ep *ep = &(pci->ep);
>>>>>>>> +    int i;
>>>>>>>> +
>>>>>>>> +    ep->hw_regs_not_available = false;
>>>>>>>
>>>>>>> This can race with epc_ops.
>>>>>>>
>>>>>>>> +
>>>>>>>> +    dw_pcie_ep_write_header_regs(ep);
>>>>>>>> +    for_each_set_bit(i, ep->ib_window_map, ep->num_ib_windows) {
>>>>>>>> +        dw_pcie_prog_inbound_atu(pci, i,
>>>>>>>> +            ep->cached_inbound_atus[i].bar,
>>>>>>>> +            ep->cached_inbound_atus[i].cpu_addr,
>>>>>>>> +            ep->cached_inbound_atus[i].as_type);
>>>>>>>
>>>>>>> Depending on the context in which this function is invoked, programming
>>>>>>> inbound/outbound ATU can also race with EPC ops.
>>>>>>    >
>>>>>>>> +        dw_pcie_ep_set_bar_regs(ep, 0, ep->cached_inbound_atus[i].bar);
>>>>>>>> +    }
>>>>>>>> +    for_each_set_bit(i, ep->ob_window_map, ep->num_ob_windows)
>>>>>>>> +        dw_pcie_prog_outbound_atu(pci, i, PCIE_ATU_TYPE_MEM,
>>>>>>>> +            ep->cached_outbound_atus[i].addr,
>>>>>>>> +            ep->cached_outbound_atus[i].pci_addr,
>>>>>>>> +            ep->cached_outbound_atus[i].size);
>>>>>>>> +    dw_pcie_dbi_ro_wr_en(pci);
>>>>>>>> +    dw_pcie_writew_dbi(pci, PCI_MSI_FLAGS, ep->cached_msi_flags);
>>>>>>>> +    dw_pcie_writew_dbi(pci, PCI_MSIX_FLAGS, ep->cached_msix_flags);
>>>>>>>> +    dw_pcie_dbi_ro_wr_dis(pci);
>>>>>>>
>>>>>>> IMHO we should add a new epc ops ->epc_init() which indicates if the EPC is
>>>>>>> ready to be initialized or not. Only if the epc_init indicates it's ready
>>>>>>> to be
>>>>>>> initialized, the endpoint function driver should go ahead with further
>>>>>>> initialization. Or else it should wait for a notification from EPC to
>>>>>>> indicate
>>>>>>> when it's ready to be initialized.
>>>>>>
>>>>>> (Did you mean epf op or epc op?)
>>>>>>
>>>>>> I'm not sure how exactly how that would work; do you want the DWC core driver
>>>>>> or the endpoint subsystem to poll that epc op to find out when the HW is
>>>>>> ready to be initialized? Or do you envisage the controller driver still
>>>>>> calling dw_pcie_set_regs_available() (possibly renamed), which in turn calls
>>>>>> ->epc_init() calls for some reason?
>>>>>>
>>>>>> If you don't want to cache the endpoint configuration, perhaps you want:
>>>>>>
>>>>>> a) Endpoint function doesn't pro-actively call the endpoint controller
>>>>>> functions to configure the endpoint.
>>>>>>
>>>>>> b) When endpoint HW is ready, the relevant driver calls pci_epc_ready() (or
>>>>>> whatever name), which lets the core know the HW can be configured. Perhaps
>>>>>> this schedules a work queue item to implement locking to avoid the races you
>>>>>> mentioned.
>>>>>>
>>>>>> c) Endpoint core calls pci_epf_init() which calls epf op ->init().
>>>>>>
>>>>>> One gotcha with this approach, which the caching approach helps avoid:
>>>>>>
>>>>>> Once PEXRST is released, the system must respond to PCIe enumeration requests
>>>>>> within 50ms. Thus, SW must very quickly respond to the IRQ indicating PEXRST
>>>>>> release and program the endpoint configuration into HW. By caching the
>>>>>> configuration in the DWC driver and immediately/synchronously applying it in
>>>>>> the PEXRST IRQ handler, we reduce the number of steps and amount of code
>>>>>> taken to program the HW, so it should get done pretty quickly. If instead we
>>>>>> call back into the endpoint function driver's ->init() op, we run the risk of
>>>>>> that op doing other stuff besides just calling the endpoint HW configuration
>>>>>> APIs (e.g. perhaps the function driver defers memory buffer allocation or
>>>>>> IOVA programming to that ->init function) which in turns makes it much less
>>>>>> likely the 50ms requirement will be hit. Perhaps we can solve this by naming
>>>>>> the op well and providing lots of comments, but my guess is that endpoint
>>>>>> function authors won't notice that...
>>>>>
>>>>> Kishon,
>>>>>
>>>>> Do you have any further details exactly how you'd prefer this to work? Does the
>>>>> approach I describe in points a/b/c above sound like what you want? Thanks.
>>>>
>>>> Agree with your PERST comment.
>>>>
>>>> What I have in mind is we add a new epc_init() ops. I feel there are more uses
>>>> for it (For e.g I have an internal patch which uses epc_init to initialize DMA.
>>>> Hopefully I'll post it soon).
>>>> If you look at pci_epf_test, pci_epf_test_bind() is where the function actually
>>>> starts to write to HW (i.e using pci_epc_*).
>>>> So before the endpoint function invokes pci_epc_write_header(), it should
>>>> invoke epc_init(). Only if that succeeds, it should go ahead with other
>>>> initialization.
>>>> If epc_init_* fails, we can have a particular error value to indicate the
>>>> controller is waiting for clock from host (so that we don't return error from
>>>> ->bind()). Once the controller receives the clock, it can send an atomic
>>>> notification to the endpoint function driver to indicate it is ready to be
>>>> initialized. (Atomic notification makes it easy to handle for multi function
>>>> endpoint devices.)
>>>> The endpoint function can then initialize the controller.
>>>> I think except for pci_epf_test_alloc_space() all other functions are
>>>> configuring the HW (in pci_epf_test_bind). pci_epf_test_alloc_space() could be
>>>> moved to pci_epf_test_probe() so there are no expensive operations to be done
>>>> once the controller is ready to be initialized.
>>>> I have epc_init() and the atomic notification part already implemented and I'm
>>>> planning to post it before next week. Once that is merged, we might have to
>>>> reorder function in pci_epf_test driver and you have to return the correct
>>>> error value for epc_init() if the clock is not there.
>>>
>>> Kishon, did you manage to post the patches that implement epc_init()? If so, a
>>> link would be appreciated. Thanks.
>>
>> I haven't posted the patches yet. Sorry for the delay. Give me some more time
>> please (till next week).
> 
> I have posted one set of cleanup for EPC features [1] by introducing
> epc_get_features(). Some of the things I initially thought should be in
> epc_init actually fits in epc_get_features. However I still believe for your
> usecase we should introduce ->epc_init().

Hi Kishon,
Do you have a Work-In-Progress patch set for ->epc_init()?
If not, I would like to start working on that.

Thanks,
Vidya Sagar

> 
> Thanks
> Kishon
> 
> [1] -> https://www.mail-archive.com/linux-kernel@vger.kernel.org/msg1891393.html
>>
>> Thanks
>> Kishon
>>


  reply	other threads:[~2019-10-25 13:51 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-11-26 23:09 [PATCH V2] PCI: dwc ep: cache config until DBI regs available Stephen Warren
2018-12-03 16:31 ` Stephen Warren
2018-12-04 11:02 ` Gustavo Pimentel
2018-12-10 18:04   ` Stephen Warren
2018-12-11  4:36 ` Kishon Vijay Abraham I
2018-12-11 17:23   ` Stephen Warren
2018-12-14 17:01     ` Stephen Warren
2018-12-19 14:37       ` Kishon Vijay Abraham I
2019-01-02 16:34         ` Stephen Warren
2019-01-04  8:02           ` Kishon Vijay Abraham I
2019-01-08 12:05             ` Kishon Vijay Abraham I
2019-10-25 13:50               ` Vidya Sagar [this message]
2019-10-29  5:55                 ` Kishon Vijay Abraham I
2019-10-29  7:57                   ` Vidya Sagar
2019-11-13  9:12                     ` Vidya Sagar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=feaa08b7-8e22-995f-d041-93733e3513ac@nvidia.com \
    --to=vidyas@nvidia.com \
    --cc=bhelgaas@google.com \
    --cc=gustavo.pimentel@synopsys.com \
    --cc=jingoohan1@gmail.com \
    --cc=kishon@ti.com \
    --cc=linux-pci@vger.kernel.org \
    --cc=lorenzo.pieralisi@arm.com \
    --cc=mmaddireddy@nvidia.com \
    --cc=swarren@nvidia.com \
    --cc=swarren@wwwdotorg.org \
    --cc=tpiepho@impinj.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).