diff mbox series

[U-Boot,RESEND,PATCHv4,9/9] dm: pci: add APIs for MPS and MRRS accessors

Message ID 20190325022546.38427-10-Zhiqiang.Hou@nxp.com
State Changes Requested
Delegated to: Prabhakar Kushwaha
Headers show
Series pci: Add PCIe Gen4 controller driver for NXP Layerscape SoCs | expand

Commit Message

Z.Q. Hou March 25, 2019, 2:24 a.m. UTC
From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>

This patch introduce APIs for getting and updating the MPS
and MRRS fields of Device capability Device control register.

Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
---
V4:
 - New patch

 drivers/pci/pci-uclass.c | 92 ++++++++++++++++++++++++++++++++++++++++
 include/pci.h            | 13 ++++++
 2 files changed, 105 insertions(+)

Comments

Bin Meng April 1, 2019, 6 a.m. UTC | #1
On Mon, Mar 25, 2019 at 10:24 AM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
>
> From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
>
> This patch introduce APIs for getting and updating the MPS
> and MRRS fields of Device capability Device control register.
>
> Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> ---
> V4:
>  - New patch
>
>  drivers/pci/pci-uclass.c | 92 ++++++++++++++++++++++++++++++++++++++++
>  include/pci.h            | 13 ++++++
>  2 files changed, 105 insertions(+)
>
> diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
> index 4bb30f5d2b..b2d295435a 100644
> --- a/drivers/pci/pci-uclass.c
> +++ b/drivers/pci/pci-uclass.c
> @@ -7,6 +7,7 @@
>  #include <common.h>
>  #include <dm.h>
>  #include <errno.h>
> +#include <linux/log2.h>
>  #include <pci.h>
>  #include <asm/io.h>
>  #include <dm/device-internal.h>
> @@ -1596,6 +1597,97 @@ int dm_pci_capability_clear_and_set_dword(struct udevice *dev, int cap,
>                                                set, PCI_SIZE_32);
>  }
>
> +/**
> + * dm_pci_get_readrq - get PCI Express read request size
> + * @dev: PCI device to query
> + *
> + * Returns maximum memory read request in bytes
> + *    or appropriate error value.
> + */

Please move the comment block to pci.h

> +int dm_pci_get_readrq(struct udevice *dev)
> +{
> +       u16 ctl;
> +       int ret;
> +
> +       ret = dm_pci_capability_read_word(dev, PCI_CAP_ID_EXP,
> +                                         PCI_EXP_DEVCTL, &ctl);
> +       if (ret)
> +               return ret;
> +
> +       return 128 << ((ctl & PCI_EXP_DEVCTL_READRQ) >> 12);
> +}
> +
> +/**
> + * dm_pci_set_readrq - set PCI Express maximum memory read request
> + * @dev: PCI device to query
> + * @rq: maximum memory read count in bytes
> + *    valid values are 128, 256, 512, 1024, 2048, 4096
> + */
> +int dm_pci_set_readrq(struct udevice *dev, int rq)
> +{
> +       u16 val;
> +
> +       if (rq < 128 || rq > 4096 || !is_power_of_2(rq))
> +               return -EINVAL;
> +
> +       val = (ffs(rq) - 8) << 12;
> +
> +       return dm_pci_capability_clear_and_set_word(dev, PCI_CAP_ID_EXP,
> +                                                   PCI_EXP_DEVCTL,
> +                                                   PCI_EXP_DEVCTL_READRQ,
> +                                                   val);
> +}
> +
> +/**
> + * dm_pci_get_mps - get PCI Express maximum payload size
> + * @dev: PCI device to query
> + *
> + * Returns maximum payload size in bytes
> + */
> +int dm_pci_get_mps(struct udevice *dev)
> +{
> +       u16 ctl;
> +       int ret;
> +
> +       ret = dm_pci_capability_read_word(dev, PCI_CAP_ID_EXP,
> +                                         PCI_EXP_DEVCTL, &ctl);
> +       if (ret)
> +               return ret;
> +
> +       return 128 << ((ctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
> +}
> +
> +/**
> + * dm_pci_set_mps - set PCI Express maximum payload size
> + * @dev: PCI device to query
> + * @mps: maximum payload size in bytes
> + *    valid values are 128, 256, 512, 1024, 2048, 4096
> + */
> +int dm_pci_set_mps(struct udevice *dev, int mps)
> +{
> +       u16 val, cap;
> +       int ret;
> +
> +       if (mps < 128 || mps > 4096 || !is_power_of_2(mps))
> +               return -EINVAL;
> +
> +       ret = dm_pci_capability_read_word(dev, PCI_CAP_ID_EXP,
> +                                         PCI_EXP_DEVCAP, &cap);
> +       if (ret)
> +               return ret;
> +
> +       val = ffs(mps) - 8;
> +       if (val > (cap & PCI_EXP_DEVCAP_PAYLOAD))
> +               return -EINVAL;
> +
> +       val <<= 5;
> +
> +       return dm_pci_capability_clear_and_set_word(dev, PCI_CAP_ID_EXP,
> +                                                   PCI_EXP_DEVCTL,
> +                                                   PCI_EXP_DEVCTL_PAYLOAD,
> +                                                   val);
> +}
> +
>  UCLASS_DRIVER(pci) = {
>         .id             = UCLASS_PCI,
>         .name           = "pci",
> diff --git a/include/pci.h b/include/pci.h
> index d7b6d9f4ff..b48df8a363 100644
> --- a/include/pci.h
> +++ b/include/pci.h
> @@ -414,6 +414,14 @@
>  #define PCI_MAX_PCI_DEVICES    32
>  #define PCI_MAX_PCI_FUNCTIONS  8
>
> +/* PCI Express capability registers */
> +#define PCI_EXP_DEVCAP                 4       /* Device capabilities */
> +#define  PCI_EXP_DEVCAP_PAYLOAD                0x0007  /* Max_Payload_Size */
> +
> +#define PCI_EXP_DEVCTL                 8       /* Device Control */
> +#define  PCI_EXP_DEVCTL_PAYLOAD                0x00e0  /* Max_Payload_Size */
> +#define  PCI_EXP_DEVCTL_READRQ         0x7000  /* Max_Read_Request_Size */
> +
>  #define PCI_FIND_CAP_TTL 0x48
>  #define CAP_START_POS 0x40
>
> @@ -1425,6 +1433,11 @@ int dm_pci_capability_clear_and_set_word(struct udevice *dev, int cap,
>  int dm_pci_capability_clear_and_set_dword(struct udevice *dev, int cap,
>                                           int pos, u32 clear, u32 set);
>
> +int dm_pci_get_readrq(struct udevice *dev);
> +int dm_pci_set_readrq(struct udevice *dev, int rq);
> +int dm_pci_get_mps(struct udevice *dev);
> +int dm_pci_set_mps(struct udevice *dev, int mps);
> +
>  #define dm_pci_virt_to_bus(dev, addr, flags) \
>         dm_pci_phys_to_bus(dev, (virt_to_phys(addr)), (flags))
>  #define dm_pci_bus_to_virt(dev, addr, flags, len, map_flags) \
> --

Please add test cases test/dm/pci.c::dm_test_pci_cap()

Regards,
Bin
Bin Meng April 1, 2019, 7:31 a.m. UTC | #2
On Mon, Apr 1, 2019 at 2:00 PM Bin Meng <bmeng.cn@gmail.com> wrote:
>
> On Mon, Mar 25, 2019 at 10:24 AM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
> >
> > From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> >
> > This patch introduce APIs for getting and updating the MPS
> > and MRRS fields of Device capability Device control register.
> >
> > Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> > ---
> > V4:
> >  - New patch
> >
> >  drivers/pci/pci-uclass.c | 92 ++++++++++++++++++++++++++++++++++++++++
> >  include/pci.h            | 13 ++++++
> >  2 files changed, 105 insertions(+)
> >
> > diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
> > index 4bb30f5d2b..b2d295435a 100644
> > --- a/drivers/pci/pci-uclass.c
> > +++ b/drivers/pci/pci-uclass.c
> > @@ -7,6 +7,7 @@
> >  #include <common.h>
> >  #include <dm.h>
> >  #include <errno.h>
> > +#include <linux/log2.h>
> >  #include <pci.h>
> >  #include <asm/io.h>
> >  #include <dm/device-internal.h>
> > @@ -1596,6 +1597,97 @@ int dm_pci_capability_clear_and_set_dword(struct udevice *dev, int cap,
> >                                                set, PCI_SIZE_32);
> >  }
> >
> > +/**
> > + * dm_pci_get_readrq - get PCI Express read request size
> > + * @dev: PCI device to query
> > + *
> > + * Returns maximum memory read request in bytes
> > + *    or appropriate error value.
> > + */
>
> Please move the comment block to pci.h
>
> > +int dm_pci_get_readrq(struct udevice *dev)
> > +{
> > +       u16 ctl;
> > +       int ret;
> > +
> > +       ret = dm_pci_capability_read_word(dev, PCI_CAP_ID_EXP,
> > +                                         PCI_EXP_DEVCTL, &ctl);
> > +       if (ret)
> > +               return ret;
> > +
> > +       return 128 << ((ctl & PCI_EXP_DEVCTL_READRQ) >> 12);
> > +}
> > +
> > +/**
> > + * dm_pci_set_readrq - set PCI Express maximum memory read request
> > + * @dev: PCI device to query
> > + * @rq: maximum memory read count in bytes
> > + *    valid values are 128, 256, 512, 1024, 2048, 4096
> > + */
> > +int dm_pci_set_readrq(struct udevice *dev, int rq)
> > +{
> > +       u16 val;
> > +
> > +       if (rq < 128 || rq > 4096 || !is_power_of_2(rq))
> > +               return -EINVAL;
> > +
> > +       val = (ffs(rq) - 8) << 12;
> > +
> > +       return dm_pci_capability_clear_and_set_word(dev, PCI_CAP_ID_EXP,
> > +                                                   PCI_EXP_DEVCTL,
> > +                                                   PCI_EXP_DEVCTL_READRQ,
> > +                                                   val);
> > +}
> > +
> > +/**
> > + * dm_pci_get_mps - get PCI Express maximum payload size
> > + * @dev: PCI device to query
> > + *
> > + * Returns maximum payload size in bytes
> > + */
> > +int dm_pci_get_mps(struct udevice *dev)
> > +{
> > +       u16 ctl;
> > +       int ret;
> > +
> > +       ret = dm_pci_capability_read_word(dev, PCI_CAP_ID_EXP,
> > +                                         PCI_EXP_DEVCTL, &ctl);
> > +       if (ret)
> > +               return ret;
> > +
> > +       return 128 << ((ctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
> > +}
> > +
> > +/**
> > + * dm_pci_set_mps - set PCI Express maximum payload size
> > + * @dev: PCI device to query
> > + * @mps: maximum payload size in bytes
> > + *    valid values are 128, 256, 512, 1024, 2048, 4096
> > + */
> > +int dm_pci_set_mps(struct udevice *dev, int mps)
> > +{
> > +       u16 val, cap;
> > +       int ret;
> > +
> > +       if (mps < 128 || mps > 4096 || !is_power_of_2(mps))
> > +               return -EINVAL;
> > +
> > +       ret = dm_pci_capability_read_word(dev, PCI_CAP_ID_EXP,
> > +                                         PCI_EXP_DEVCAP, &cap);
> > +       if (ret)
> > +               return ret;
> > +
> > +       val = ffs(mps) - 8;
> > +       if (val > (cap & PCI_EXP_DEVCAP_PAYLOAD))
> > +               return -EINVAL;
> > +
> > +       val <<= 5;
> > +
> > +       return dm_pci_capability_clear_and_set_word(dev, PCI_CAP_ID_EXP,
> > +                                                   PCI_EXP_DEVCTL,
> > +                                                   PCI_EXP_DEVCTL_PAYLOAD,
> > +                                                   val);
> > +}
> > +
> >  UCLASS_DRIVER(pci) = {
> >         .id             = UCLASS_PCI,
> >         .name           = "pci",
> > diff --git a/include/pci.h b/include/pci.h
> > index d7b6d9f4ff..b48df8a363 100644
> > --- a/include/pci.h
> > +++ b/include/pci.h
> > @@ -414,6 +414,14 @@
> >  #define PCI_MAX_PCI_DEVICES    32
> >  #define PCI_MAX_PCI_FUNCTIONS  8
> >
> > +/* PCI Express capability registers */
> > +#define PCI_EXP_DEVCAP                 4       /* Device capabilities */
> > +#define  PCI_EXP_DEVCAP_PAYLOAD                0x0007  /* Max_Payload_Size */
> > +
> > +#define PCI_EXP_DEVCTL                 8       /* Device Control */
> > +#define  PCI_EXP_DEVCTL_PAYLOAD                0x00e0  /* Max_Payload_Size */
> > +#define  PCI_EXP_DEVCTL_READRQ         0x7000  /* Max_Read_Request_Size */
> > +
> >  #define PCI_FIND_CAP_TTL 0x48
> >  #define CAP_START_POS 0x40
> >
> > @@ -1425,6 +1433,11 @@ int dm_pci_capability_clear_and_set_word(struct udevice *dev, int cap,
> >  int dm_pci_capability_clear_and_set_dword(struct udevice *dev, int cap,
> >                                           int pos, u32 clear, u32 set);
> >
> > +int dm_pci_get_readrq(struct udevice *dev);
> > +int dm_pci_set_readrq(struct udevice *dev, int rq);
> > +int dm_pci_get_mps(struct udevice *dev);
> > +int dm_pci_set_mps(struct udevice *dev, int mps);
> > +
> >  #define dm_pci_virt_to_bus(dev, addr, flags) \
> >         dm_pci_phys_to_bus(dev, (virt_to_phys(addr)), (flags))
> >  #define dm_pci_bus_to_virt(dev, addr, flags, len, map_flags) \
> > --
>
> Please add test cases test/dm/pci.c::dm_test_pci_cap()

Zhiqiang, when you do new version patches, please split patch [8,9] to
a separate series, since it is not tightly coupled with other 7
patches, and can go separately.

Regards,
Bin
Z.Q. Hou April 1, 2019, 9:13 a.m. UTC | #3
Hi Bin,

Thanks a lot for your comments!

> -----Original Message-----
> From: Bin Meng [mailto:bmeng.cn@gmail.com]
> Sent: 2019年4月1日 14:00
> To: Z.q. Hou <zhiqiang.hou@nxp.com>
> Cc: u-boot@lists.denx.de; albert.u.boot@aribaud.net; Priyanka Jain
> <priyanka.jain@nxp.com>; York Sun <york.sun@nxp.com>;
> sriram.dash@nxp.com; yamada.masahiro@socionext.com; Prabhakar
> Kushwaha <prabhakar.kushwaha@nxp.com>; Mingkai Hu
> <mingkai.hu@nxp.com>; M.h. Lian <minghuan.lian@nxp.com>
> Subject: Re: [RESEND PATCHv4 9/9] dm: pci: add APIs for MPS and MRRS
> accessors
> 
> On Mon, Mar 25, 2019 at 10:24 AM Z.q. Hou <zhiqiang.hou@nxp.com> wrote:
> >
> > From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> >
> > This patch introduce APIs for getting and updating the MPS and MRRS
> > fields of Device capability Device control register.
> >
> > Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> > ---
> > V4:
> >  - New patch
> >
> >  drivers/pci/pci-uclass.c | 92
> ++++++++++++++++++++++++++++++++++++++++
> >  include/pci.h            | 13 ++++++
> >  2 files changed, 105 insertions(+)
> >
> > diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c index
> > 4bb30f5d2b..b2d295435a 100644
> > --- a/drivers/pci/pci-uclass.c
> > +++ b/drivers/pci/pci-uclass.c
> > @@ -7,6 +7,7 @@
> >  #include <common.h>
> >  #include <dm.h>
> >  #include <errno.h>
> > +#include <linux/log2.h>
> >  #include <pci.h>
> >  #include <asm/io.h>
> >  #include <dm/device-internal.h>
> > @@ -1596,6 +1597,97 @@ int
> dm_pci_capability_clear_and_set_dword(struct udevice *dev, int cap,
> >                                                set,
> PCI_SIZE_32);  }
> >
> > +/**
> > + * dm_pci_get_readrq - get PCI Express read request size
> > + * @dev: PCI device to query
> > + *
> > + * Returns maximum memory read request in bytes
> > + *    or appropriate error value.
> > + */
> 
> Please move the comment block to pci.h

Yes, will fix in v5.

> 
> > +int dm_pci_get_readrq(struct udevice *dev) {
> > +       u16 ctl;
> > +       int ret;
> > +
> > +       ret = dm_pci_capability_read_word(dev, PCI_CAP_ID_EXP,
> > +                                         PCI_EXP_DEVCTL,
> &ctl);
> > +       if (ret)
> > +               return ret;
> > +
> > +       return 128 << ((ctl & PCI_EXP_DEVCTL_READRQ) >> 12); }
> > +
> > +/**
> > + * dm_pci_set_readrq - set PCI Express maximum memory read request
> > + * @dev: PCI device to query
> > + * @rq: maximum memory read count in bytes
> > + *    valid values are 128, 256, 512, 1024, 2048, 4096
> > + */
> > +int dm_pci_set_readrq(struct udevice *dev, int rq) {
> > +       u16 val;
> > +
> > +       if (rq < 128 || rq > 4096 || !is_power_of_2(rq))
> > +               return -EINVAL;
> > +
> > +       val = (ffs(rq) - 8) << 12;
> > +
> > +       return dm_pci_capability_clear_and_set_word(dev,
> PCI_CAP_ID_EXP,
> > +
> PCI_EXP_DEVCTL,
> > +
> PCI_EXP_DEVCTL_READRQ,
> > +                                                   val); }
> > +
> > +/**
> > + * dm_pci_get_mps - get PCI Express maximum payload size
> > + * @dev: PCI device to query
> > + *
> > + * Returns maximum payload size in bytes  */ int
> > +dm_pci_get_mps(struct udevice *dev) {
> > +       u16 ctl;
> > +       int ret;
> > +
> > +       ret = dm_pci_capability_read_word(dev, PCI_CAP_ID_EXP,
> > +                                         PCI_EXP_DEVCTL,
> &ctl);
> > +       if (ret)
> > +               return ret;
> > +
> > +       return 128 << ((ctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5); }
> > +
> > +/**
> > + * dm_pci_set_mps - set PCI Express maximum payload size
> > + * @dev: PCI device to query
> > + * @mps: maximum payload size in bytes
> > + *    valid values are 128, 256, 512, 1024, 2048, 4096
> > + */
> > +int dm_pci_set_mps(struct udevice *dev, int mps) {
> > +       u16 val, cap;
> > +       int ret;
> > +
> > +       if (mps < 128 || mps > 4096 || !is_power_of_2(mps))
> > +               return -EINVAL;
> > +
> > +       ret = dm_pci_capability_read_word(dev, PCI_CAP_ID_EXP,
> > +                                         PCI_EXP_DEVCAP,
> &cap);
> > +       if (ret)
> > +               return ret;
> > +
> > +       val = ffs(mps) - 8;
> > +       if (val > (cap & PCI_EXP_DEVCAP_PAYLOAD))
> > +               return -EINVAL;
> > +
> > +       val <<= 5;
> > +
> > +       return dm_pci_capability_clear_and_set_word(dev,
> PCI_CAP_ID_EXP,
> > +
> PCI_EXP_DEVCTL,
> > +
> PCI_EXP_DEVCTL_PAYLOAD,
> > +                                                   val); }
> > +
> >  UCLASS_DRIVER(pci) = {
> >         .id             = UCLASS_PCI,
> >         .name           = "pci",
> > diff --git a/include/pci.h b/include/pci.h index
> > d7b6d9f4ff..b48df8a363 100644
> > --- a/include/pci.h
> > +++ b/include/pci.h
> > @@ -414,6 +414,14 @@
> >  #define PCI_MAX_PCI_DEVICES    32
> >  #define PCI_MAX_PCI_FUNCTIONS  8
> >
> > +/* PCI Express capability registers */
> > +#define PCI_EXP_DEVCAP                 4       /* Device
> capabilities */
> > +#define  PCI_EXP_DEVCAP_PAYLOAD                0x0007  /*
> Max_Payload_Size */
> > +
> > +#define PCI_EXP_DEVCTL                 8       /* Device Control
> */
> > +#define  PCI_EXP_DEVCTL_PAYLOAD                0x00e0  /*
> Max_Payload_Size */
> > +#define  PCI_EXP_DEVCTL_READRQ         0x7000  /*
> Max_Read_Request_Size */
> > +
> >  #define PCI_FIND_CAP_TTL 0x48
> >  #define CAP_START_POS 0x40
> >
> > @@ -1425,6 +1433,11 @@ int
> dm_pci_capability_clear_and_set_word(struct
> > udevice *dev, int cap,  int dm_pci_capability_clear_and_set_dword(struct
> udevice *dev, int cap,
> >                                           int pos, u32 clear, u32
> > set);
> >
> > +int dm_pci_get_readrq(struct udevice *dev); int
> > +dm_pci_set_readrq(struct udevice *dev, int rq); int
> > +dm_pci_get_mps(struct udevice *dev); int dm_pci_set_mps(struct
> > +udevice *dev, int mps);
> > +
> >  #define dm_pci_virt_to_bus(dev, addr, flags) \
> >         dm_pci_phys_to_bus(dev, (virt_to_phys(addr)), (flags))
> > #define dm_pci_bus_to_virt(dev, addr, flags, len, map_flags) \
> > --
> 
> Please add test cases test/dm/pci.c::dm_test_pci_cap()

Will add in v5.

> 
> Regards,
> Bin

Thanks,
Zhiqiang
Z.Q. Hou April 1, 2019, 9:14 a.m. UTC | #4
Hi Bin,

Thanks a lot for your comments!

> -----Original Message-----
> From: Bin Meng [mailto:bmeng.cn@gmail.com]
> Sent: 2019年4月1日 15:32
> To: Z.q. Hou <zhiqiang.hou@nxp.com>
> Cc: u-boot@lists.denx.de; albert.u.boot@aribaud.net; Priyanka Jain
> <priyanka.jain@nxp.com>; York Sun <york.sun@nxp.com>;
> sriram.dash@nxp.com; yamada.masahiro@socionext.com; Prabhakar
> Kushwaha <prabhakar.kushwaha@nxp.com>; Mingkai Hu
> <mingkai.hu@nxp.com>; M.h. Lian <minghuan.lian@nxp.com>
> Subject: Re: [RESEND PATCHv4 9/9] dm: pci: add APIs for MPS and MRRS
> accessors
> 
> On Mon, Apr 1, 2019 at 2:00 PM Bin Meng <bmeng.cn@gmail.com> wrote:
> >
> > On Mon, Mar 25, 2019 at 10:24 AM Z.q. Hou <zhiqiang.hou@nxp.com>
> wrote:
> > >
> > > From: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> > >
> > > This patch introduce APIs for getting and updating the MPS and MRRS
> > > fields of Device capability Device control register.
> > >
> > > Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
> > > ---
> > > V4:
> > >  - New patch
> > >
> > >  drivers/pci/pci-uclass.c | 92
> ++++++++++++++++++++++++++++++++++++++++
> > >  include/pci.h            | 13 ++++++
> > >  2 files changed, 105 insertions(+)
> > >
> > > diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
> > > index 4bb30f5d2b..b2d295435a 100644
> > > --- a/drivers/pci/pci-uclass.c
> > > +++ b/drivers/pci/pci-uclass.c
> > > @@ -7,6 +7,7 @@
> > >  #include <common.h>
> > >  #include <dm.h>
> > >  #include <errno.h>
> > > +#include <linux/log2.h>
> > >  #include <pci.h>
> > >  #include <asm/io.h>
> > >  #include <dm/device-internal.h>
> > > @@ -1596,6 +1597,97 @@ int
> dm_pci_capability_clear_and_set_dword(struct udevice *dev, int cap,
> > >                                                set,
> PCI_SIZE_32);  }
> > >
> > > +/**
> > > + * dm_pci_get_readrq - get PCI Express read request size
> > > + * @dev: PCI device to query
> > > + *
> > > + * Returns maximum memory read request in bytes
> > > + *    or appropriate error value.
> > > + */
> >
> > Please move the comment block to pci.h
> >
> > > +int dm_pci_get_readrq(struct udevice *dev) {
> > > +       u16 ctl;
> > > +       int ret;
> > > +
> > > +       ret = dm_pci_capability_read_word(dev, PCI_CAP_ID_EXP,
> > > +                                         PCI_EXP_DEVCTL,
> &ctl);
> > > +       if (ret)
> > > +               return ret;
> > > +
> > > +       return 128 << ((ctl & PCI_EXP_DEVCTL_READRQ) >> 12); }
> > > +
> > > +/**
> > > + * dm_pci_set_readrq - set PCI Express maximum memory read request
> > > + * @dev: PCI device to query
> > > + * @rq: maximum memory read count in bytes
> > > + *    valid values are 128, 256, 512, 1024, 2048, 4096
> > > + */
> > > +int dm_pci_set_readrq(struct udevice *dev, int rq) {
> > > +       u16 val;
> > > +
> > > +       if (rq < 128 || rq > 4096 || !is_power_of_2(rq))
> > > +               return -EINVAL;
> > > +
> > > +       val = (ffs(rq) - 8) << 12;
> > > +
> > > +       return dm_pci_capability_clear_and_set_word(dev,
> PCI_CAP_ID_EXP,
> > > +
> PCI_EXP_DEVCTL,
> > > +
> PCI_EXP_DEVCTL_READRQ,
> > > +                                                   val); }
> > > +
> > > +/**
> > > + * dm_pci_get_mps - get PCI Express maximum payload size
> > > + * @dev: PCI device to query
> > > + *
> > > + * Returns maximum payload size in bytes  */ int
> > > +dm_pci_get_mps(struct udevice *dev) {
> > > +       u16 ctl;
> > > +       int ret;
> > > +
> > > +       ret = dm_pci_capability_read_word(dev, PCI_CAP_ID_EXP,
> > > +                                         PCI_EXP_DEVCTL,
> &ctl);
> > > +       if (ret)
> > > +               return ret;
> > > +
> > > +       return 128 << ((ctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5); }
> > > +
> > > +/**
> > > + * dm_pci_set_mps - set PCI Express maximum payload size
> > > + * @dev: PCI device to query
> > > + * @mps: maximum payload size in bytes
> > > + *    valid values are 128, 256, 512, 1024, 2048, 4096
> > > + */
> > > +int dm_pci_set_mps(struct udevice *dev, int mps) {
> > > +       u16 val, cap;
> > > +       int ret;
> > > +
> > > +       if (mps < 128 || mps > 4096 || !is_power_of_2(mps))
> > > +               return -EINVAL;
> > > +
> > > +       ret = dm_pci_capability_read_word(dev, PCI_CAP_ID_EXP,
> > > +                                         PCI_EXP_DEVCAP,
> &cap);
> > > +       if (ret)
> > > +               return ret;
> > > +
> > > +       val = ffs(mps) - 8;
> > > +       if (val > (cap & PCI_EXP_DEVCAP_PAYLOAD))
> > > +               return -EINVAL;
> > > +
> > > +       val <<= 5;
> > > +
> > > +       return dm_pci_capability_clear_and_set_word(dev,
> PCI_CAP_ID_EXP,
> > > +
> PCI_EXP_DEVCTL,
> > > +
> PCI_EXP_DEVCTL_PAYLOAD,
> > > +                                                   val); }
> > > +
> > >  UCLASS_DRIVER(pci) = {
> > >         .id             = UCLASS_PCI,
> > >         .name           = "pci",
> > > diff --git a/include/pci.h b/include/pci.h index
> > > d7b6d9f4ff..b48df8a363 100644
> > > --- a/include/pci.h
> > > +++ b/include/pci.h
> > > @@ -414,6 +414,14 @@
> > >  #define PCI_MAX_PCI_DEVICES    32
> > >  #define PCI_MAX_PCI_FUNCTIONS  8
> > >
> > > +/* PCI Express capability registers */
> > > +#define PCI_EXP_DEVCAP                 4       /* Device
> capabilities */
> > > +#define  PCI_EXP_DEVCAP_PAYLOAD                0x0007  /*
> Max_Payload_Size */
> > > +
> > > +#define PCI_EXP_DEVCTL                 8       /* Device
> Control */
> > > +#define  PCI_EXP_DEVCTL_PAYLOAD                0x00e0  /*
> Max_Payload_Size */
> > > +#define  PCI_EXP_DEVCTL_READRQ         0x7000  /*
> Max_Read_Request_Size */
> > > +
> > >  #define PCI_FIND_CAP_TTL 0x48
> > >  #define CAP_START_POS 0x40
> > >
> > > @@ -1425,6 +1433,11 @@ int
> > > dm_pci_capability_clear_and_set_word(struct udevice *dev, int cap,  int
> dm_pci_capability_clear_and_set_dword(struct udevice *dev, int cap,
> > >                                           int pos, u32 clear,
> u32
> > > set);
> > >
> > > +int dm_pci_get_readrq(struct udevice *dev); int
> > > +dm_pci_set_readrq(struct udevice *dev, int rq); int
> > > +dm_pci_get_mps(struct udevice *dev); int dm_pci_set_mps(struct
> > > +udevice *dev, int mps);
> > > +
> > >  #define dm_pci_virt_to_bus(dev, addr, flags) \
> > >         dm_pci_phys_to_bus(dev, (virt_to_phys(addr)), (flags))
> > > #define dm_pci_bus_to_virt(dev, addr, flags, len, map_flags) \
> > > --
> >
> > Please add test cases test/dm/pci.c::dm_test_pci_cap()
> 
> Zhiqiang, when you do new version patches, please split patch [8,9] to a
> separate series, since it is not tightly coupled with other 7 patches, and can go
> separately.

Ok, make sense.

> 
> Regards,
> Bin

Thanks,
Zhiqiang
diff mbox series

Patch

diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
index 4bb30f5d2b..b2d295435a 100644
--- a/drivers/pci/pci-uclass.c
+++ b/drivers/pci/pci-uclass.c
@@ -7,6 +7,7 @@ 
 #include <common.h>
 #include <dm.h>
 #include <errno.h>
+#include <linux/log2.h>
 #include <pci.h>
 #include <asm/io.h>
 #include <dm/device-internal.h>
@@ -1596,6 +1597,97 @@  int dm_pci_capability_clear_and_set_dword(struct udevice *dev, int cap,
 					       set, PCI_SIZE_32);
 }
 
+/**
+ * dm_pci_get_readrq - get PCI Express read request size
+ * @dev: PCI device to query
+ *
+ * Returns maximum memory read request in bytes
+ *    or appropriate error value.
+ */
+int dm_pci_get_readrq(struct udevice *dev)
+{
+	u16 ctl;
+	int ret;
+
+	ret = dm_pci_capability_read_word(dev, PCI_CAP_ID_EXP,
+					  PCI_EXP_DEVCTL, &ctl);
+	if (ret)
+		return ret;
+
+	return 128 << ((ctl & PCI_EXP_DEVCTL_READRQ) >> 12);
+}
+
+/**
+ * dm_pci_set_readrq - set PCI Express maximum memory read request
+ * @dev: PCI device to query
+ * @rq: maximum memory read count in bytes
+ *    valid values are 128, 256, 512, 1024, 2048, 4096
+ */
+int dm_pci_set_readrq(struct udevice *dev, int rq)
+{
+	u16 val;
+
+	if (rq < 128 || rq > 4096 || !is_power_of_2(rq))
+		return -EINVAL;
+
+	val = (ffs(rq) - 8) << 12;
+
+	return dm_pci_capability_clear_and_set_word(dev, PCI_CAP_ID_EXP,
+						    PCI_EXP_DEVCTL,
+						    PCI_EXP_DEVCTL_READRQ,
+						    val);
+}
+
+/**
+ * dm_pci_get_mps - get PCI Express maximum payload size
+ * @dev: PCI device to query
+ *
+ * Returns maximum payload size in bytes
+ */
+int dm_pci_get_mps(struct udevice *dev)
+{
+	u16 ctl;
+	int ret;
+
+	ret = dm_pci_capability_read_word(dev, PCI_CAP_ID_EXP,
+					  PCI_EXP_DEVCTL, &ctl);
+	if (ret)
+		return ret;
+
+	return 128 << ((ctl & PCI_EXP_DEVCTL_PAYLOAD) >> 5);
+}
+
+/**
+ * dm_pci_set_mps - set PCI Express maximum payload size
+ * @dev: PCI device to query
+ * @mps: maximum payload size in bytes
+ *    valid values are 128, 256, 512, 1024, 2048, 4096
+ */
+int dm_pci_set_mps(struct udevice *dev, int mps)
+{
+	u16 val, cap;
+	int ret;
+
+	if (mps < 128 || mps > 4096 || !is_power_of_2(mps))
+		return -EINVAL;
+
+	ret = dm_pci_capability_read_word(dev, PCI_CAP_ID_EXP,
+					  PCI_EXP_DEVCAP, &cap);
+	if (ret)
+		return ret;
+
+	val = ffs(mps) - 8;
+	if (val > (cap & PCI_EXP_DEVCAP_PAYLOAD))
+		return -EINVAL;
+
+	val <<= 5;
+
+	return dm_pci_capability_clear_and_set_word(dev, PCI_CAP_ID_EXP,
+						    PCI_EXP_DEVCTL,
+						    PCI_EXP_DEVCTL_PAYLOAD,
+						    val);
+}
+
 UCLASS_DRIVER(pci) = {
 	.id		= UCLASS_PCI,
 	.name		= "pci",
diff --git a/include/pci.h b/include/pci.h
index d7b6d9f4ff..b48df8a363 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -414,6 +414,14 @@ 
 #define PCI_MAX_PCI_DEVICES	32
 #define PCI_MAX_PCI_FUNCTIONS	8
 
+/* PCI Express capability registers */
+#define PCI_EXP_DEVCAP			4	/* Device capabilities */
+#define  PCI_EXP_DEVCAP_PAYLOAD		0x0007	/* Max_Payload_Size */
+
+#define PCI_EXP_DEVCTL			8	/* Device Control */
+#define  PCI_EXP_DEVCTL_PAYLOAD		0x00e0	/* Max_Payload_Size */
+#define  PCI_EXP_DEVCTL_READRQ		0x7000	/* Max_Read_Request_Size */
+
 #define PCI_FIND_CAP_TTL 0x48
 #define CAP_START_POS 0x40
 
@@ -1425,6 +1433,11 @@  int dm_pci_capability_clear_and_set_word(struct udevice *dev, int cap,
 int dm_pci_capability_clear_and_set_dword(struct udevice *dev, int cap,
 					  int pos, u32 clear, u32 set);
 
+int dm_pci_get_readrq(struct udevice *dev);
+int dm_pci_set_readrq(struct udevice *dev, int rq);
+int dm_pci_get_mps(struct udevice *dev);
+int dm_pci_set_mps(struct udevice *dev, int mps);
+
 #define dm_pci_virt_to_bus(dev, addr, flags) \
 	dm_pci_phys_to_bus(dev, (virt_to_phys(addr)), (flags))
 #define dm_pci_bus_to_virt(dev, addr, flags, len, map_flags) \