diff mbox

[U-Boot,7/7] pci/layerscape: set LUT and msi-map for discovered PCI devices

Message ID 1456154749-19629-8-git-send-email-stuart.yoder@nxp.com
State Superseded
Delegated to: York Sun
Headers show

Commit Message

Stuart Yoder Feb. 22, 2016, 3:25 p.m. UTC
From: Stuart Yoder <stuart.yoder@nxp.com>

for all PCI devices discovered in a system:
  -allocate a LUT (look-up-table) entry in that PCI controller
  -allocate a stream ID for the device
  -program and enable a LUT entry (maps PCI requester id to stream ID)
  -set the msi-map property on the controller reflecting the
   LUT mapping

basic bus scanning loop/logic was taken from drivers/pci/pci.c
pci_hose_scan_bus().

Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
---
 drivers/pci/pcie_layerscape.c |   68 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 68 insertions(+)

Comments

M.h. Lian Feb. 23, 2016, 9:57 a.m. UTC | #1
Hi Stuart,


> -----Original Message-----
> From: Stuart Yoder [mailto:stuart.yoder@nxp.com]
> Sent: Monday, February 22, 2016 11:26 PM
> To: u-boot@lists.denx.de
> Cc: york sun <york.sun@nxp.com>; Prabhakar Kushwaha
> <prabhakar.kushwaha@nxp.com>; Mingkai Hu <mingkai.hu@nxp.com>;
> Minghuan Lian <minghuan.lian@nxp.com>; Yang-Leo Li <leoyang.li@nxp.com>;
> marc.zyngier@arm.com; Stuart Yoder <stuart.yoder@nxp.com>
> Subject: [PATCH 7/7] pci/layerscape: set LUT and msi-map for discovered PCI
> devices
> 
> From: Stuart Yoder <stuart.yoder@nxp.com>
> 
> for all PCI devices discovered in a system:
>   -allocate a LUT (look-up-table) entry in that PCI controller
>   -allocate a stream ID for the device
>   -program and enable a LUT entry (maps PCI requester id to stream ID)
>   -set the msi-map property on the controller reflecting the
>    LUT mapping
> 
> basic bus scanning loop/logic was taken from drivers/pci/pci.c
> pci_hose_scan_bus().
> 
> Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
> ---
>  drivers/pci/pcie_layerscape.c |   68
> +++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 68 insertions(+)
> 
> diff --git a/drivers/pci/pcie_layerscape.c b/drivers/pci/pcie_layerscape.c index
> dfafaf2..eaac9e1 100644
> --- a/drivers/pci/pcie_layerscape.c
> +++ b/drivers/pci/pcie_layerscape.c
> @@ -569,6 +569,70 @@ static void fdt_pcie_set_msi_map_entry(void *blob,
> struct ls_pcie *pcie,
>  	fdt_appendprop_u32(blob, nodeoffset, "msi-map", 1);  }
> 
> +static void fdt_fixup_pcie(void *blob)
> +{
> +	unsigned int found_multi = 0;
> +	unsigned char header_type;
> +	int index;
> +	u32 streamid;
> +	pci_dev_t dev;
> +	int bus;
> +	unsigned short id;
> +	struct pci_controller *hose;
> +	struct ls_pcie *pcie;
> +	int i;
> +
> +	for (i = 0, hose = pci_get_hose_head(); hose; hose = hose->next, i++) {
> +		pcie = hose->priv_data;
> +		for (bus = hose->first_busno; bus <= hose->last_busno; bus++) {
> +
> +			for (dev =  PCI_BDF(bus, 0, 0);
> +			     dev <  PCI_BDF(bus, PCI_MAX_PCI_DEVICES - 1,
> +					    PCI_MAX_PCI_FUNCTIONS - 1);
> +			     dev += PCI_BDF(0, 0, 1)) {
> +
> +				/* skip the host bridge */
> +				if (dev == PCI_BDF(0, 0, 0))
> +					continue;
[Lian Minghuan-B31939] PCIe controller also needs a stream ID. It may request a MSI for AER PME hotplug service.
> +
> +				if (PCI_FUNC(dev) && !found_multi)
> +					continue;
> +
> +				pci_read_config_word(dev, PCI_VENDOR_ID, &id);
> +
> +				pci_read_config_byte(dev, PCI_HEADER_TYPE,
> +						     &header_type);
> +
> +				if ((id == 0xFFFF) || (id == 0x0000))
> +					continue;
> +
> +				if (!PCI_FUNC(dev))
> +					found_multi = header_type & 0x80;
> +
> +				streamid = ls_pcie_next_streamid();
> +				if (streamid < 0) {
> +					printf("ERROR: no stream ids free\n");
> +					continue;
> +				}
> +
> +				index = ls_pcie_next_lut_index(pcie);
> +				if (index < 0) {
> +					printf("ERROR: no LUT indexes free\n");
> +					continue;
> +				}
> +
> +				/* map PCI b.d.f to streamID in LUT */
> +				ls_pcie_lut_set_mapping(pcie, index, dev >> 8,
> +							streamid);
> +
> +				/* update msi-map in device tree */
> +				fdt_pcie_set_msi_map_entry(blob, pcie, dev >> 8,
> +							   streamid);
> +			}
> +		}
> +	}
> +}
> +
>  int ls_pcie_init_ctrl(int busno, enum srds_prtcl dev, struct ls_pcie_info *info)
> {
>  	struct ls_pcie *pcie;
> @@ -745,6 +809,10 @@ void ft_pci_setup(void *blob, bd_t *bd)
>  	#ifdef CONFIG_PCIE4
>  	ft_pcie_ls_setup(blob, FSL_PCIE_COMPAT, CONFIG_SYS_PCIE4_ADDR,
> PCIE4);
>  	#endif
> +
> +	#if defined(CONFIG_LS2080A) || defined(CONFIG_LS2085A)
> +	fdt_fixup_pcie(blob);
> +	#endif
>  }
> 
>  #else
> --
> 1.7.9.5
Stuart Yoder Feb. 23, 2016, 3:01 p.m. UTC | #2
> -----Original Message-----
> From: Minghuan Lian
> Sent: Tuesday, February 23, 2016 3:57 AM
> To: Stuart Yoder <stuart.yoder@nxp.com>; u-boot@lists.denx.de
> Cc: york sun <york.sun@nxp.com>; Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>;
> Mingkai Hu <mingkai.hu@nxp.com>; Yang-Leo Li <leoyang.li@nxp.com>; marc.zyngier@arm.com;
> Stuart Yoder <stuart.yoder@nxp.com>
> Subject: RE: [PATCH 7/7] pci/layerscape: set LUT and msi-map for discovered PCI devices
> 
> Hi Stuart,
> 
> 
> > -----Original Message-----
> > From: Stuart Yoder [mailto:stuart.yoder@nxp.com]
> > Sent: Monday, February 22, 2016 11:26 PM
> > To: u-boot@lists.denx.de
> > Cc: york sun <york.sun@nxp.com>; Prabhakar Kushwaha
> > <prabhakar.kushwaha@nxp.com>; Mingkai Hu <mingkai.hu@nxp.com>;
> > Minghuan Lian <minghuan.lian@nxp.com>; Yang-Leo Li <leoyang.li@nxp.com>;
> > marc.zyngier@arm.com; Stuart Yoder <stuart.yoder@nxp.com>
> > Subject: [PATCH 7/7] pci/layerscape: set LUT and msi-map for discovered PCI
> > devices
> >
> > From: Stuart Yoder <stuart.yoder@nxp.com>
> >
> > for all PCI devices discovered in a system:
> >   -allocate a LUT (look-up-table) entry in that PCI controller
> >   -allocate a stream ID for the device
> >   -program and enable a LUT entry (maps PCI requester id to stream ID)
> >   -set the msi-map property on the controller reflecting the
> >    LUT mapping
> >
> > basic bus scanning loop/logic was taken from drivers/pci/pci.c
> > pci_hose_scan_bus().
> >
> > Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
> > ---
> >  drivers/pci/pcie_layerscape.c |   68
> > +++++++++++++++++++++++++++++++++++++++++
> >  1 file changed, 68 insertions(+)
> >
> > diff --git a/drivers/pci/pcie_layerscape.c b/drivers/pci/pcie_layerscape.c index
> > dfafaf2..eaac9e1 100644
> > --- a/drivers/pci/pcie_layerscape.c
> > +++ b/drivers/pci/pcie_layerscape.c
> > @@ -569,6 +569,70 @@ static void fdt_pcie_set_msi_map_entry(void *blob,
> > struct ls_pcie *pcie,
> >  	fdt_appendprop_u32(blob, nodeoffset, "msi-map", 1);  }
> >
> > +static void fdt_fixup_pcie(void *blob)
> > +{
> > +	unsigned int found_multi = 0;
> > +	unsigned char header_type;
> > +	int index;
> > +	u32 streamid;
> > +	pci_dev_t dev;
> > +	int bus;
> > +	unsigned short id;
> > +	struct pci_controller *hose;
> > +	struct ls_pcie *pcie;
> > +	int i;
> > +
> > +	for (i = 0, hose = pci_get_hose_head(); hose; hose = hose->next, i++) {
> > +		pcie = hose->priv_data;
> > +		for (bus = hose->first_busno; bus <= hose->last_busno; bus++) {
> > +
> > +			for (dev =  PCI_BDF(bus, 0, 0);
> > +			     dev <  PCI_BDF(bus, PCI_MAX_PCI_DEVICES - 1,
> > +					    PCI_MAX_PCI_FUNCTIONS - 1);
> > +			     dev += PCI_BDF(0, 0, 1)) {
> > +
> > +				/* skip the host bridge */
> > +				if (dev == PCI_BDF(0, 0, 0))
> > +					continue;
> [Lian Minghuan-B31939] PCIe controller also needs a stream ID. It may request a MSI for
> AER PME hotplug service.

Is this a theoretical problem, or does the ls2080a actually support
hotplug and assert an MSI?  Mingkai said that a hotplug interrupt
could be an INTx interrupt.  The fdt_fixup_pcie() in this patch
is specifically for Layerscape SoCs and I think it makes sense
to implement what hardware actually supports.

Stuart
Marc Zyngier Feb. 23, 2016, 3:19 p.m. UTC | #3
On 23/02/16 15:01, Stuart Yoder wrote:
> 
> 
>> -----Original Message-----
>> From: Minghuan Lian
>> Sent: Tuesday, February 23, 2016 3:57 AM
>> To: Stuart Yoder <stuart.yoder@nxp.com>; u-boot@lists.denx.de
>> Cc: york sun <york.sun@nxp.com>; Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>;
>> Mingkai Hu <mingkai.hu@nxp.com>; Yang-Leo Li <leoyang.li@nxp.com>; marc.zyngier@arm.com;
>> Stuart Yoder <stuart.yoder@nxp.com>
>> Subject: RE: [PATCH 7/7] pci/layerscape: set LUT and msi-map for discovered PCI devices
>>
>> Hi Stuart,
>>
>>
>>> -----Original Message-----
>>> From: Stuart Yoder [mailto:stuart.yoder@nxp.com]
>>> Sent: Monday, February 22, 2016 11:26 PM
>>> To: u-boot@lists.denx.de
>>> Cc: york sun <york.sun@nxp.com>; Prabhakar Kushwaha
>>> <prabhakar.kushwaha@nxp.com>; Mingkai Hu <mingkai.hu@nxp.com>;
>>> Minghuan Lian <minghuan.lian@nxp.com>; Yang-Leo Li <leoyang.li@nxp.com>;
>>> marc.zyngier@arm.com; Stuart Yoder <stuart.yoder@nxp.com>
>>> Subject: [PATCH 7/7] pci/layerscape: set LUT and msi-map for discovered PCI
>>> devices
>>>
>>> From: Stuart Yoder <stuart.yoder@nxp.com>
>>>
>>> for all PCI devices discovered in a system:
>>>   -allocate a LUT (look-up-table) entry in that PCI controller
>>>   -allocate a stream ID for the device
>>>   -program and enable a LUT entry (maps PCI requester id to stream ID)
>>>   -set the msi-map property on the controller reflecting the
>>>    LUT mapping
>>>
>>> basic bus scanning loop/logic was taken from drivers/pci/pci.c
>>> pci_hose_scan_bus().
>>>
>>> Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
>>> ---
>>>  drivers/pci/pcie_layerscape.c |   68
>>> +++++++++++++++++++++++++++++++++++++++++
>>>  1 file changed, 68 insertions(+)
>>>
>>> diff --git a/drivers/pci/pcie_layerscape.c b/drivers/pci/pcie_layerscape.c index
>>> dfafaf2..eaac9e1 100644
>>> --- a/drivers/pci/pcie_layerscape.c
>>> +++ b/drivers/pci/pcie_layerscape.c
>>> @@ -569,6 +569,70 @@ static void fdt_pcie_set_msi_map_entry(void *blob,
>>> struct ls_pcie *pcie,
>>>  	fdt_appendprop_u32(blob, nodeoffset, "msi-map", 1);  }
>>>
>>> +static void fdt_fixup_pcie(void *blob)
>>> +{
>>> +	unsigned int found_multi = 0;
>>> +	unsigned char header_type;
>>> +	int index;
>>> +	u32 streamid;
>>> +	pci_dev_t dev;
>>> +	int bus;
>>> +	unsigned short id;
>>> +	struct pci_controller *hose;
>>> +	struct ls_pcie *pcie;
>>> +	int i;
>>> +
>>> +	for (i = 0, hose = pci_get_hose_head(); hose; hose = hose->next, i++) {
>>> +		pcie = hose->priv_data;
>>> +		for (bus = hose->first_busno; bus <= hose->last_busno; bus++) {
>>> +
>>> +			for (dev =  PCI_BDF(bus, 0, 0);
>>> +			     dev <  PCI_BDF(bus, PCI_MAX_PCI_DEVICES - 1,
>>> +					    PCI_MAX_PCI_FUNCTIONS - 1);
>>> +			     dev += PCI_BDF(0, 0, 1)) {
>>> +
>>> +				/* skip the host bridge */
>>> +				if (dev == PCI_BDF(0, 0, 0))
>>> +					continue;
>> [Lian Minghuan-B31939] PCIe controller also needs a stream ID. It may request a MSI for
>> AER PME hotplug service.
> 
> Is this a theoretical problem, or does the ls2080a actually support
> hotplug and assert an MSI?  Mingkai said that a hotplug interrupt
> could be an INTx interrupt.  The fdt_fixup_pcie() in this patch
> is specifically for Layerscape SoCs and I think it makes sense
> to implement what hardware actually supports.

For sure, the ls2085 reports such a capability, and the kernel assigns a
pair of MSIs to it.

 97:          0          0          0          0          0          0
        0          0   ITS-MSI   0 Edge      PCIe PME
 98:          0          0          0          0          0          0
        0          0   ITS-MSI   1 Edge      aerdrv

I haven't tried to exercise it though.

	M.
Stuart Yoder Feb. 23, 2016, 8:31 p.m. UTC | #4
> -----Original Message-----
> From: Marc Zyngier [mailto:marc.zyngier@arm.com]
> Sent: Tuesday, February 23, 2016 9:19 AM
> To: Stuart Yoder <stuart.yoder@nxp.com>; Minghuan Lian <minghuan.lian@nxp.com>; u-
> boot@lists.denx.de
> Cc: york sun <york.sun@nxp.com>; Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>;
> Mingkai Hu <mingkai.hu@nxp.com>; Yang-Leo Li <leoyang.li@nxp.com>
> Subject: Re: [PATCH 7/7] pci/layerscape: set LUT and msi-map for discovered PCI devices
> 
> On 23/02/16 15:01, Stuart Yoder wrote:
> >
> >
> >> -----Original Message-----
> >> From: Minghuan Lian
> >> Sent: Tuesday, February 23, 2016 3:57 AM
> >> To: Stuart Yoder <stuart.yoder@nxp.com>; u-boot@lists.denx.de
> >> Cc: york sun <york.sun@nxp.com>; Prabhakar Kushwaha <prabhakar.kushwaha@nxp.com>;
> >> Mingkai Hu <mingkai.hu@nxp.com>; Yang-Leo Li <leoyang.li@nxp.com>;
> marc.zyngier@arm.com;
> >> Stuart Yoder <stuart.yoder@nxp.com>
> >> Subject: RE: [PATCH 7/7] pci/layerscape: set LUT and msi-map for discovered PCI
> devices
> >>
> >> Hi Stuart,
> >>
> >>
> >>> -----Original Message-----
> >>> From: Stuart Yoder [mailto:stuart.yoder@nxp.com]
> >>> Sent: Monday, February 22, 2016 11:26 PM
> >>> To: u-boot@lists.denx.de
> >>> Cc: york sun <york.sun@nxp.com>; Prabhakar Kushwaha
> >>> <prabhakar.kushwaha@nxp.com>; Mingkai Hu <mingkai.hu@nxp.com>;
> >>> Minghuan Lian <minghuan.lian@nxp.com>; Yang-Leo Li <leoyang.li@nxp.com>;
> >>> marc.zyngier@arm.com; Stuart Yoder <stuart.yoder@nxp.com>
> >>> Subject: [PATCH 7/7] pci/layerscape: set LUT and msi-map for discovered PCI
> >>> devices
> >>>
> >>> From: Stuart Yoder <stuart.yoder@nxp.com>
> >>>
> >>> for all PCI devices discovered in a system:
> >>>   -allocate a LUT (look-up-table) entry in that PCI controller
> >>>   -allocate a stream ID for the device
> >>>   -program and enable a LUT entry (maps PCI requester id to stream ID)
> >>>   -set the msi-map property on the controller reflecting the
> >>>    LUT mapping
> >>>
> >>> basic bus scanning loop/logic was taken from drivers/pci/pci.c
> >>> pci_hose_scan_bus().
> >>>
> >>> Signed-off-by: Stuart Yoder <stuart.yoder@nxp.com>
> >>> ---
> >>>  drivers/pci/pcie_layerscape.c |   68
> >>> +++++++++++++++++++++++++++++++++++++++++
> >>>  1 file changed, 68 insertions(+)
> >>>
> >>> diff --git a/drivers/pci/pcie_layerscape.c b/drivers/pci/pcie_layerscape.c index
> >>> dfafaf2..eaac9e1 100644
> >>> --- a/drivers/pci/pcie_layerscape.c
> >>> +++ b/drivers/pci/pcie_layerscape.c
> >>> @@ -569,6 +569,70 @@ static void fdt_pcie_set_msi_map_entry(void *blob,
> >>> struct ls_pcie *pcie,
> >>>  	fdt_appendprop_u32(blob, nodeoffset, "msi-map", 1);  }
> >>>
> >>> +static void fdt_fixup_pcie(void *blob)
> >>> +{
> >>> +	unsigned int found_multi = 0;
> >>> +	unsigned char header_type;
> >>> +	int index;
> >>> +	u32 streamid;
> >>> +	pci_dev_t dev;
> >>> +	int bus;
> >>> +	unsigned short id;
> >>> +	struct pci_controller *hose;
> >>> +	struct ls_pcie *pcie;
> >>> +	int i;
> >>> +
> >>> +	for (i = 0, hose = pci_get_hose_head(); hose; hose = hose->next, i++) {
> >>> +		pcie = hose->priv_data;
> >>> +		for (bus = hose->first_busno; bus <= hose->last_busno; bus++) {
> >>> +
> >>> +			for (dev =  PCI_BDF(bus, 0, 0);
> >>> +			     dev <  PCI_BDF(bus, PCI_MAX_PCI_DEVICES - 1,
> >>> +					    PCI_MAX_PCI_FUNCTIONS - 1);
> >>> +			     dev += PCI_BDF(0, 0, 1)) {
> >>> +
> >>> +				/* skip the host bridge */
> >>> +				if (dev == PCI_BDF(0, 0, 0))
> >>> +					continue;
> >> [Lian Minghuan-B31939] PCIe controller also needs a stream ID. It may request a MSI
> for
> >> AER PME hotplug service.
> >
> > Is this a theoretical problem, or does the ls2080a actually support
> > hotplug and assert an MSI?  Mingkai said that a hotplug interrupt
> > could be an INTx interrupt.  The fdt_fixup_pcie() in this patch
> > is specifically for Layerscape SoCs and I think it makes sense
> > to implement what hardware actually supports.
> 
> For sure, the ls2085 reports such a capability, and the kernel assigns a
> pair of MSIs to it.
> 
>  97:          0          0          0          0          0          0
>         0          0   ITS-MSI   0 Edge      PCIe PME
>  98:          0          0          0          0          0          0
>         0          0   ITS-MSI   1 Edge      aerdrv
> 
> I haven't tried to exercise it though.

Ok, I will respin and remove the "skip the host bridge"
check, which will allow the host bridge to get a LUT
entry created for it.

Stuart
diff mbox

Patch

diff --git a/drivers/pci/pcie_layerscape.c b/drivers/pci/pcie_layerscape.c
index dfafaf2..eaac9e1 100644
--- a/drivers/pci/pcie_layerscape.c
+++ b/drivers/pci/pcie_layerscape.c
@@ -569,6 +569,70 @@  static void fdt_pcie_set_msi_map_entry(void *blob, struct ls_pcie *pcie,
 	fdt_appendprop_u32(blob, nodeoffset, "msi-map", 1);
 }
 
+static void fdt_fixup_pcie(void *blob)
+{
+	unsigned int found_multi = 0;
+	unsigned char header_type;
+	int index;
+	u32 streamid;
+	pci_dev_t dev;
+	int bus;
+	unsigned short id;
+	struct pci_controller *hose;
+	struct ls_pcie *pcie;
+	int i;
+
+	for (i = 0, hose = pci_get_hose_head(); hose; hose = hose->next, i++) {
+		pcie = hose->priv_data;
+		for (bus = hose->first_busno; bus <= hose->last_busno; bus++) {
+
+			for (dev =  PCI_BDF(bus, 0, 0);
+			     dev <  PCI_BDF(bus, PCI_MAX_PCI_DEVICES - 1,
+					    PCI_MAX_PCI_FUNCTIONS - 1);
+			     dev += PCI_BDF(0, 0, 1)) {
+
+				/* skip the host bridge */
+				if (dev == PCI_BDF(0, 0, 0))
+					continue;
+
+				if (PCI_FUNC(dev) && !found_multi)
+					continue;
+
+				pci_read_config_word(dev, PCI_VENDOR_ID, &id);
+
+				pci_read_config_byte(dev, PCI_HEADER_TYPE,
+						     &header_type);
+
+				if ((id == 0xFFFF) || (id == 0x0000))
+					continue;
+
+				if (!PCI_FUNC(dev))
+					found_multi = header_type & 0x80;
+
+				streamid = ls_pcie_next_streamid();
+				if (streamid < 0) {
+					printf("ERROR: no stream ids free\n");
+					continue;
+				}
+
+				index = ls_pcie_next_lut_index(pcie);
+				if (index < 0) {
+					printf("ERROR: no LUT indexes free\n");
+					continue;
+				}
+
+				/* map PCI b.d.f to streamID in LUT */
+				ls_pcie_lut_set_mapping(pcie, index, dev >> 8,
+							streamid);
+
+				/* update msi-map in device tree */
+				fdt_pcie_set_msi_map_entry(blob, pcie, dev >> 8,
+							   streamid);
+			}
+		}
+	}
+}
+
 int ls_pcie_init_ctrl(int busno, enum srds_prtcl dev, struct ls_pcie_info *info)
 {
 	struct ls_pcie *pcie;
@@ -745,6 +809,10 @@  void ft_pci_setup(void *blob, bd_t *bd)
 	#ifdef CONFIG_PCIE4
 	ft_pcie_ls_setup(blob, FSL_PCIE_COMPAT, CONFIG_SYS_PCIE4_ADDR, PCIE4);
 	#endif
+
+	#if defined(CONFIG_LS2080A) || defined(CONFIG_LS2085A)
+	fdt_fixup_pcie(blob);
+	#endif
 }
 
 #else