Re: pcie-designware: query on MSI IRQ handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thursday, January 09, 2014 2:20 PM, Mohit KUMAR wrote:
> On Wednesday, January 08, 2014 11:02 PM, Karicheri, Muralidharan wrote:
> > On Wednesday, January 08, 2014 10:52 AM, Karicheri, Muralidharan wrote:
> > >
> > >>> void dw_pcie_msi_init(struct pcie_port *pp) {
> > >>> 	pp->msi_data = __get_free_pages(GFP_KERNEL, 0);
> > >>
> > >>I think we can implement dw_pcie_get_msi_addr() to get the MSI address
> > >>as  below. It checks if any specific ops is implemented then it will
> > >>get the address  from there otherwise default as in present case  will
> > >>be used. You should  implement get_msi_addr() specific to your platform.
> > >>
> > >>void dw_pcie_get_msi_addr(struct pcie port *pp) {
> > >>   	if (pp->ops->get_msi_addr)
> > >>		pp->msi_data = pp->ops->get_msi_addr;
> > >>	else
> > >>		pp->msi_data = __get_free_pages(GFP_KERNEL, 0); }
> > >>
> > >>And then call this from dw_pcie_msi_init() as:
> > >>
> > >>void dw_pcie_msi_init(..)
> > >>{
> > >>	dw_pcie_get_msi_addr(..);
> > >>
> > >>	/* program the msi_data */
> > >> 	dw_pcie_wr_own_conf(pp, PCIE_MSI_ADDR_LO, 4,
> > >>			virt_to_phys((void *)pp->msi_data));
> > >>	dw_pcie_wr_own_conf(pp, PCIE_MSI_ADDR_HI, 4, 0); } }
> >
> > On a second thought,  I think we need some change like this since
> > PCIE_MSI_ADDR_LO/HIGH is not applicable for our IP.
> 
> - To just clarify this dw PCIe driver consists 3 parts:
> 1. Common part: Common PCIe code (host_init() etc..) this should
>  be common to all hosts. As already discussed it should be ideally
>  moved out from this driver. It is in todo list and will move to separate
>  file in due course of time.
> 
> 2.  Viewport handling: ATU translation code
> 
> 3. MSI specific code
> 
> Synopsys controllers version 3.70+have been standardized for viewport
>  handling and msi implementation. Current dw driver covers these standard
>  implementation for viewport and MSI.
> 
> Now I can understand that you are using only common part of dw driver
> And have specific viewport and msi implementation. So its getting a bit
>  messy if you modify the driver for your specific implementation as
>  discussed in this thread.
> 
> So ideally I will suggest that you should move the common code (point 1)
>  to outside this driver, and then use this along with your specific viewport
>  and msi implementation.
> 
> Arnd, Jingoo,
> 
> Do you agree with above comments?

I agree with you opinion.
Then, the following is right?

./drivers/pci/host/pcie-designware.c
: There is no change about MSI and viewpoint code.

./drivers/pci/host/pci-omapxxx.c
: Instead of calling dw_pcie_msi_init(), etc, add the SoC specific
   MSI handling code, and the SoC specific viewpoint code.

Karicheri, Muralidharan,
Please, if possible, don't change 'pcie-designware.c' for your
specific SoC, because more than 4 SoCs such as Samsung, Freescale,
ST, and TI (DRA7) are using this 'pcie-designware.c' as a common layer.

If possible, please add some hardware specific code to your SoC
PCI driver such as 'pci-omapxxx.c'.

> 
> Thanks
> Mohit
> >
> > void dw_pcie_msi_init(..)
> > {
> >         if (pp->ops->get_msi_addr)
> >               pp->msi_data = pp->ops->get_msi_addr();
> >         else {
> >               pp->msi_data = __get_free_pages(GFP_KERNEL, 0);
> >               dw_pcie_wr_own_conf(pp, PCIE_MSI_ADDR_LO, 4,
> >                                      virt_to_phys((void *)pp->msi_data));
> >               dw_pcie_wr_own_conf(pp, PCIE_MSI_ADDR_HI, 4, 0);
> >        }
> > }
> >
> > Also see below.
> >
> > >>>
> > >>> In our designware IP, in the Application space, there is a MSI_IRQ
> > >>> register that the EP needs to write with msi vector value to
> > >>> generate msi irq. So in our case, pp->msi_data should be updated
> > >>> with address RC's MSI_IRQ
> > >>register.
> > >>> So I plan to update the msi_data in port's data structure with
> > >>> MSI_IRQ virtual address and not call dw_msi_setup_irq().
> > >>> I am trying to understand how MSI IRQ works on currently supported
> > >>> designware PCIE hardwares (Samsung, Freescale etc). I am assuming
> > >>> dw_pcie_wr_own_conf () write into RC's config space. But in the
> > >>> above code, I see the code is updating the PCIE_MSI_ADDR_LO/HI of
> > >>> the RC's config with a DDR address and in  write_msi_msg() this
> > >>> address along with vector gets written to EP's MSI config space
> > >>> registers. In this case how is the MSI IRQ gets generated from the EP?
> > >>>
> > >>> EP writes to DDR address with the vector value. Does the PCIE
> > >>> hardware match the address in the MSI irq message from EP with that
> > >>> in PCIE_MSI_ADDR_LO/HI and then raise an IRQ?
> > >>
> > >>Yes.
> > >>
> > >>> Is this part of the Per Vector
> > >>> Masking (PVM) option support as discussed in the PCI spec? Anyone
> > >>> can explain this?
> > >>>
> > >>> Also as part of my development, I plan to enhance this driver to
> > >>> override the dw_msi_irq_chip with our platform specific chip data
> > >>> since MSI interrupt controller is using application specific
> > >>> registers instead of the one at offset 0x828. I will sending an
> > >>> patch for review once my driver is
> > >>tested.
> > >>
> > >>So in you controller you do not have regiter offset 0x820-0x830, right?
> > >>Then probably, its not generic MSI controller as implemented in newer
> > verion of IP.
> > >>
> > >>Hmm....if the same registers are in your application space then maybe
> > >>you can handle Similar to to get_msi_addr() as suggested above.
> > >>
> >
> > I can't just get the register address for this as in the case of msi_data.
> > To support 32 MSI irqs, there are 8 application registers triplet (1 for Enable, 1
> > for disable, and status) each handling 4 IRQs.
> >
> > So I need hook in assign_irq() and clear_irq() to enable/disable the interrupts
> > in application register
> >
> > assign_irq()
> > {
> > 	<--- cut --->
> >                 if (pp->ops->enable_msi_irq)
> >                         pp->ops->enable_msi_irq(pp, pos0 + i);
> >                 else {
> >                         res = ((pos0 + i) / 32) * 12;
> >                         bit = (pos0 + i) % 32;
> >                         dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4,
> > &val);
> >                         val |= 1 << bit;
> >                         dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4,
> > val);
> >                 }
> > }
> >
> > clear_irq()
> > {
> > 	<----cut --->
> >
> >         if (pp->ops->disable_msi_irq)
> >                         pp->ops->disable_msi_irq(pp, pos);
> >         else {
> >                 dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, &val);
> >                 val &= ~(1 << bit);
> >                 dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_ENABLE + res, 4, val);
> >         }
> > }
> >
> > And for handling the interrupt, currently the driver rely on unmask_msi_irq
> > and mask_msi_irq from msi.c to mask/unmask the interrupt at the EP even
> > though PVM (Per Vector Masking) is an optional feature. So this may not
> > work on EP devices without PVM support. might need to use
> > desc->msi_attrib.maskbit to call unmask_msi_irq()/mask_msi_irq() or use
> > use masking at RC level. For our IP we have application register to disable or
> > enable interrupt and could make use of this. For other IPs, I am not sure how
> > this can be handled.
> >
> > So we need to have a way to override the default irq_chip with user driver
> > specific (in platform specific glue driver) irq_chip that can mask the interrupt
> > at RC level using application register.
> >
> > For the designware core driver to support non PVM supported EP device,
> > you might require changes to mask/unmask/enable/disable calls in the IRQ
> > chip. I would like to hear how this is handled in other designware base PCIe
> > drivers. Any thoughts?
> >
> > Murali
> > >That is right. Agree with both of your suggestions. Will send a patch
> > >along with my driver patches.
> > >
> > >>Regards
> > >>Mohit
> > >>>
> > >>> Thanks
> > >>>
> > >>> Murali Karicheri
> > >>> Linux Kernel, Software Development
> > >>>

--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux