diff mbox series

[U-Boot,063/126] x86: pci: Add a function to decode a PCI BDF

Message ID 20190925145750.200592-64-sjg@chromium.org
State Superseded
Delegated to: Bin Meng
Headers show
Series x86: Add initial support for apollolake | expand

Commit Message

Simon Glass Sept. 25, 2019, 2:56 p.m. UTC
Early in boot it is necessary to decode the PCI device/function values for
particular peripherals in the device tree or of-platdata. Add functions to
handle this.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 arch/x86/cpu/pci.c         | 18 ++++++++++++++++++
 arch/x86/include/asm/pci.h | 22 ++++++++++++++++++++++
 2 files changed, 40 insertions(+)

Comments

Bin Meng Oct. 7, 2019, 1:53 p.m. UTC | #1
On Wed, Sep 25, 2019 at 10:58 PM Simon Glass <sjg@chromium.org> wrote:
>
> Early in boot it is necessary to decode the PCI device/function values for
> particular peripherals in the device tree or of-platdata. Add functions to
> handle this.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
>  arch/x86/cpu/pci.c         | 18 ++++++++++++++++++
>  arch/x86/include/asm/pci.h | 22 ++++++++++++++++++++++
>  2 files changed, 40 insertions(+)
>
> diff --git a/arch/x86/cpu/pci.c b/arch/x86/cpu/pci.c
> index e1aae158ce5..f551fef5bbb 100644
> --- a/arch/x86/cpu/pci.c
> +++ b/arch/x86/cpu/pci.c
> @@ -69,6 +69,24 @@ int pci_x86_clrset_config(pci_dev_t bdf, uint offset, ulong clr, ulong set,
>         return pci_x86_write_config(bdf, offset, value, size);
>  }
>
> +#if !CONFIG_IS_ENABLED(OF_PLATDATA)
> +int pci_x86_get_devfn(struct udevice *dev)
> +{
> +       struct fdt_pci_addr addr;
> +       int ret;
> +
> +       /* Extract the devfn from fdt_pci_addr */
> +       ret = ofnode_read_pci_addr(dev_ofnode(dev), FDT_PCI_SPACE_CONFIG,
> +                                  "reg", &addr);
> +       if (ret) {
> +               if (ret != -ENOENT)
> +                       return -EINVAL;
> +       }
> +
> +       return addr.phys_hi & 0xff00;
> +}
> +#endif

This function is a duplicates of pci_get_devfn() in pci-uclass driver.

> +
>  void pci_assign_irqs(int bus, int device, u8 irq[4])
>  {
>         pci_dev_t bdf;
> diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
> index 2a720735728..abb770760f5 100644
> --- a/arch/x86/include/asm/pci.h
> +++ b/arch/x86/include/asm/pci.h
> @@ -60,6 +60,28 @@ int pci_x86_write_config(pci_dev_t bdf, uint offset, ulong value,
>  int pci_x86_clrset_config(pci_dev_t bdf, uint offset, ulong clr, ulong set,
>                           enum pci_size_t size);
>
> +/**
> + * pci_x86_get_devfn() - Extract the devfn from fdt_pci_addr of the device
> + *
> + * Get devfn from fdt_pci_addr of the specified device. This is a copy of
> + * pci_get_devfn() for use in TPL on x86, since PCI may not be available.
> + *
> + * @dev:       PCI device
> + * @return devfn in bits 15...8 if found, -ENODEV if not found
> + */
> +int pci_x86_get_devfn(struct udevice *dev);
> +
> +/**
> + * pci_x86_ofplat_get_devfn() - Get the PCI dev/fn from ofplat reg data
> + *
> + * @reg: reg value from dt-platdata.c array (first member)
> + * @return device/function for that device
> + */
> +static inline pci_dev_t pci_x86_ofplat_get_devfn(u32 reg)

Why returns pci_dev_t instead of int? This is inconsistent with the
pci_x86_get_devfn() above.

> +{
> +       return reg & 0xff00;
> +}
> +
>  /**
>   * Assign IRQ number to a PCI device
>   *
> --

Regards,
Bin
Simon Glass Oct. 13, 2019, 3:03 p.m. UTC | #2
Hi Bin,

On Mon, 7 Oct 2019 at 07:53, Bin Meng <bmeng.cn@gmail.com> wrote:
>
> On Wed, Sep 25, 2019 at 10:58 PM Simon Glass <sjg@chromium.org> wrote:
> >
> > Early in boot it is necessary to decode the PCI device/function values for
> > particular peripherals in the device tree or of-platdata. Add functions to
> > handle this.
> >
> > Signed-off-by: Simon Glass <sjg@chromium.org>
> > ---
> >
> >  arch/x86/cpu/pci.c         | 18 ++++++++++++++++++
> >  arch/x86/include/asm/pci.h | 22 ++++++++++++++++++++++
> >  2 files changed, 40 insertions(+)
> >
> > diff --git a/arch/x86/cpu/pci.c b/arch/x86/cpu/pci.c
> > index e1aae158ce5..f551fef5bbb 100644
> > --- a/arch/x86/cpu/pci.c
> > +++ b/arch/x86/cpu/pci.c
> > @@ -69,6 +69,24 @@ int pci_x86_clrset_config(pci_dev_t bdf, uint offset, ulong clr, ulong set,
> >         return pci_x86_write_config(bdf, offset, value, size);
> >  }
> >
> > +#if !CONFIG_IS_ENABLED(OF_PLATDATA)
> > +int pci_x86_get_devfn(struct udevice *dev)
> > +{
> > +       struct fdt_pci_addr addr;
> > +       int ret;
> > +
> > +       /* Extract the devfn from fdt_pci_addr */
> > +       ret = ofnode_read_pci_addr(dev_ofnode(dev), FDT_PCI_SPACE_CONFIG,
> > +                                  "reg", &addr);
> > +       if (ret) {
> > +               if (ret != -ENOENT)
> > +                       return -EINVAL;
> > +       }
> > +
> > +       return addr.phys_hi & 0xff00;
> > +}
> > +#endif
>
> This function is a duplicates of pci_get_devfn() in pci-uclass driver.

Yes that's right. But with TPL we don't enable UCLASS_PCI to save code
size, so we need it somewhere else.

>
> > +
> >  void pci_assign_irqs(int bus, int device, u8 irq[4])
> >  {
> >         pci_dev_t bdf;
> > diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
> > index 2a720735728..abb770760f5 100644
> > --- a/arch/x86/include/asm/pci.h
> > +++ b/arch/x86/include/asm/pci.h
> > @@ -60,6 +60,28 @@ int pci_x86_write_config(pci_dev_t bdf, uint offset, ulong value,
> >  int pci_x86_clrset_config(pci_dev_t bdf, uint offset, ulong clr, ulong set,
> >                           enum pci_size_t size);
> >
> > +/**
> > + * pci_x86_get_devfn() - Extract the devfn from fdt_pci_addr of the device
> > + *
> > + * Get devfn from fdt_pci_addr of the specified device. This is a copy of
> > + * pci_get_devfn() for use in TPL on x86, since PCI may not be available.
> > + *
> > + * @dev:       PCI device
> > + * @return devfn in bits 15...8 if found, -ENODEV if not found
> > + */
> > +int pci_x86_get_devfn(struct udevice *dev);
> > +
> > +/**
> > + * pci_x86_ofplat_get_devfn() - Get the PCI dev/fn from ofplat reg data
> > + *
> > + * @reg: reg value from dt-platdata.c array (first member)
> > + * @return device/function for that device
> > + */
> > +static inline pci_dev_t pci_x86_ofplat_get_devfn(u32 reg)
>
> Why returns pci_dev_t instead of int? This is inconsistent with the
> pci_x86_get_devfn() above.

Will fix.

Regards,
Simon
Bin Meng Oct. 14, 2019, 1:53 a.m. UTC | #3
Hi Simon,

On Sun, Oct 13, 2019 at 11:03 PM Simon Glass <sjg@chromium.org> wrote:
>
> Hi Bin,
>
> On Mon, 7 Oct 2019 at 07:53, Bin Meng <bmeng.cn@gmail.com> wrote:
> >
> > On Wed, Sep 25, 2019 at 10:58 PM Simon Glass <sjg@chromium.org> wrote:
> > >
> > > Early in boot it is necessary to decode the PCI device/function values for
> > > particular peripherals in the device tree or of-platdata. Add functions to
> > > handle this.
> > >
> > > Signed-off-by: Simon Glass <sjg@chromium.org>
> > > ---
> > >
> > >  arch/x86/cpu/pci.c         | 18 ++++++++++++++++++
> > >  arch/x86/include/asm/pci.h | 22 ++++++++++++++++++++++
> > >  2 files changed, 40 insertions(+)
> > >
> > > diff --git a/arch/x86/cpu/pci.c b/arch/x86/cpu/pci.c
> > > index e1aae158ce5..f551fef5bbb 100644
> > > --- a/arch/x86/cpu/pci.c
> > > +++ b/arch/x86/cpu/pci.c
> > > @@ -69,6 +69,24 @@ int pci_x86_clrset_config(pci_dev_t bdf, uint offset, ulong clr, ulong set,
> > >         return pci_x86_write_config(bdf, offset, value, size);
> > >  }
> > >
> > > +#if !CONFIG_IS_ENABLED(OF_PLATDATA)
> > > +int pci_x86_get_devfn(struct udevice *dev)
> > > +{
> > > +       struct fdt_pci_addr addr;
> > > +       int ret;
> > > +
> > > +       /* Extract the devfn from fdt_pci_addr */
> > > +       ret = ofnode_read_pci_addr(dev_ofnode(dev), FDT_PCI_SPACE_CONFIG,
> > > +                                  "reg", &addr);
> > > +       if (ret) {
> > > +               if (ret != -ENOENT)
> > > +                       return -EINVAL;
> > > +       }
> > > +
> > > +       return addr.phys_hi & 0xff00;
> > > +}
> > > +#endif
> >
> > This function is a duplicates of pci_get_devfn() in pci-uclass driver.
>
> Yes that's right. But with TPL we don't enable UCLASS_PCI to save code
> size, so we need it somewhere else.
>

How about we exact the pci_get_devfn() from pci-uclass driver and put
it somewhere else public for both w/ and w/o UCLASS_PCI case?

> >
> > > +
> > >  void pci_assign_irqs(int bus, int device, u8 irq[4])
> > >  {
> > >         pci_dev_t bdf;
> > > diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
> > > index 2a720735728..abb770760f5 100644
> > > --- a/arch/x86/include/asm/pci.h
> > > +++ b/arch/x86/include/asm/pci.h
> > > @@ -60,6 +60,28 @@ int pci_x86_write_config(pci_dev_t bdf, uint offset, ulong value,
> > >  int pci_x86_clrset_config(pci_dev_t bdf, uint offset, ulong clr, ulong set,
> > >                           enum pci_size_t size);
> > >
> > > +/**
> > > + * pci_x86_get_devfn() - Extract the devfn from fdt_pci_addr of the device
> > > + *
> > > + * Get devfn from fdt_pci_addr of the specified device. This is a copy of
> > > + * pci_get_devfn() for use in TPL on x86, since PCI may not be available.
> > > + *
> > > + * @dev:       PCI device
> > > + * @return devfn in bits 15...8 if found, -ENODEV if not found
> > > + */
> > > +int pci_x86_get_devfn(struct udevice *dev);
> > > +
> > > +/**
> > > + * pci_x86_ofplat_get_devfn() - Get the PCI dev/fn from ofplat reg data
> > > + *
> > > + * @reg: reg value from dt-platdata.c array (first member)
> > > + * @return device/function for that device
> > > + */
> > > +static inline pci_dev_t pci_x86_ofplat_get_devfn(u32 reg)
> >
> > Why returns pci_dev_t instead of int? This is inconsistent with the
> > pci_x86_get_devfn() above.
>
> Will fix.

Regards,
Bin
diff mbox series

Patch

diff --git a/arch/x86/cpu/pci.c b/arch/x86/cpu/pci.c
index e1aae158ce5..f551fef5bbb 100644
--- a/arch/x86/cpu/pci.c
+++ b/arch/x86/cpu/pci.c
@@ -69,6 +69,24 @@  int pci_x86_clrset_config(pci_dev_t bdf, uint offset, ulong clr, ulong set,
 	return pci_x86_write_config(bdf, offset, value, size);
 }
 
+#if !CONFIG_IS_ENABLED(OF_PLATDATA)
+int pci_x86_get_devfn(struct udevice *dev)
+{
+	struct fdt_pci_addr addr;
+	int ret;
+
+	/* Extract the devfn from fdt_pci_addr */
+	ret = ofnode_read_pci_addr(dev_ofnode(dev), FDT_PCI_SPACE_CONFIG,
+				   "reg", &addr);
+	if (ret) {
+		if (ret != -ENOENT)
+			return -EINVAL;
+	}
+
+	return addr.phys_hi & 0xff00;
+}
+#endif
+
 void pci_assign_irqs(int bus, int device, u8 irq[4])
 {
 	pci_dev_t bdf;
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index 2a720735728..abb770760f5 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -60,6 +60,28 @@  int pci_x86_write_config(pci_dev_t bdf, uint offset, ulong value,
 int pci_x86_clrset_config(pci_dev_t bdf, uint offset, ulong clr, ulong set,
 			  enum pci_size_t size);
 
+/**
+ * pci_x86_get_devfn() - Extract the devfn from fdt_pci_addr of the device
+ *
+ * Get devfn from fdt_pci_addr of the specified device. This is a copy of
+ * pci_get_devfn() for use in TPL on x86, since PCI may not be available.
+ *
+ * @dev:	PCI device
+ * @return devfn in bits 15...8 if found, -ENODEV if not found
+ */
+int pci_x86_get_devfn(struct udevice *dev);
+
+/**
+ * pci_x86_ofplat_get_devfn() - Get the PCI dev/fn from ofplat reg data
+ *
+ * @reg: reg value from dt-platdata.c array (first member)
+ * @return device/function for that device
+ */
+static inline pci_dev_t pci_x86_ofplat_get_devfn(u32 reg)
+{
+	return reg & 0xff00;
+}
+
 /**
  * Assign IRQ number to a PCI device
  *