lkml.org 
[lkml]   [2020]   [May]   [6]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH v4 03/14] PCI: cadence: Add support to use custom read and write accessors
    Date
    Add support to use custom read and write accessors. Platforms that
    don't support half word or byte access or any other constraint
    while accessing registers can use this feature to populate custom
    read and write accessors. These custom accessors are used for both
    standard register access and configuration space register access of
    the PCIe host bridge.

    Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
    ---
    drivers/pci/controller/cadence/pcie-cadence.h | 107 +++++++++++++++---
    1 file changed, 94 insertions(+), 13 deletions(-)

    diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
    index df14ad002fe9..70b6b25153e8 100644
    --- a/drivers/pci/controller/cadence/pcie-cadence.h
    +++ b/drivers/pci/controller/cadence/pcie-cadence.h
    @@ -223,6 +223,11 @@ enum cdns_pcie_msg_routing {
    MSG_ROUTING_GATHER,
    };

    +struct cdns_pcie_ops {
    + u32 (*read)(void __iomem *addr, int size);
    + void (*write)(void __iomem *addr, int size, u32 value);
    +};
    +
    /**
    * struct cdns_pcie - private data for Cadence PCIe controller drivers
    * @reg_base: IO mapped register base
    @@ -239,7 +244,7 @@ struct cdns_pcie {
    int phy_count;
    struct phy **phy;
    struct device_link **link;
    - const struct cdns_pcie_common_ops *ops;
    + const struct cdns_pcie_ops *ops;
    };

    /**
    @@ -299,69 +304,145 @@ struct cdns_pcie_ep {
    /* Register access */
    static inline void cdns_pcie_writeb(struct cdns_pcie *pcie, u32 reg, u8 value)
    {
    - writeb(value, pcie->reg_base + reg);
    + void __iomem *addr = pcie->reg_base + reg;
    +
    + if (pcie->ops && pcie->ops->write) {
    + pcie->ops->write(addr, 0x1, value);
    + return;
    + }
    +
    + writeb(value, addr);
    }

    static inline void cdns_pcie_writew(struct cdns_pcie *pcie, u32 reg, u16 value)
    {
    - writew(value, pcie->reg_base + reg);
    + void __iomem *addr = pcie->reg_base + reg;
    +
    + if (pcie->ops && pcie->ops->write) {
    + pcie->ops->write(addr, 0x2, value);
    + return;
    + }
    +
    + writew(value, addr);
    }

    static inline void cdns_pcie_writel(struct cdns_pcie *pcie, u32 reg, u32 value)
    {
    - writel(value, pcie->reg_base + reg);
    + void __iomem *addr = pcie->reg_base + reg;
    +
    + if (pcie->ops && pcie->ops->write) {
    + pcie->ops->write(addr, 0x4, value);
    + return;
    + }
    +
    + writel(value, addr);
    }

    static inline u32 cdns_pcie_readl(struct cdns_pcie *pcie, u32 reg)
    {
    - return readl(pcie->reg_base + reg);
    + void __iomem *addr = pcie->reg_base + reg;
    +
    + if (pcie->ops && pcie->ops->read)
    + return pcie->ops->read(addr, 0x4);
    +
    + return readl(addr);
    }

    /* Root Port register access */
    static inline void cdns_pcie_rp_writeb(struct cdns_pcie *pcie,
    u32 reg, u8 value)
    {
    - writeb(value, pcie->reg_base + CDNS_PCIE_RP_BASE + reg);
    + void __iomem *addr = pcie->reg_base + CDNS_PCIE_RP_BASE + reg;
    +
    + if (pcie->ops && pcie->ops->write) {
    + pcie->ops->write(addr, 0x1, value);
    + return;
    + }
    +
    + writeb(value, addr);
    }

    static inline void cdns_pcie_rp_writew(struct cdns_pcie *pcie,
    u32 reg, u16 value)
    {
    - writew(value, pcie->reg_base + CDNS_PCIE_RP_BASE + reg);
    + void __iomem *addr = pcie->reg_base + CDNS_PCIE_RP_BASE + reg;
    +
    + if (pcie->ops && pcie->ops->write) {
    + pcie->ops->write(addr, 0x2, value);
    + return;
    + }
    +
    + writew(value, addr);
    }

    /* Endpoint Function register access */
    static inline void cdns_pcie_ep_fn_writeb(struct cdns_pcie *pcie, u8 fn,
    u32 reg, u8 value)
    {
    - writeb(value, pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
    + void __iomem *addr = pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg;
    +
    + if (pcie->ops && pcie->ops->write) {
    + pcie->ops->write(addr, 0x1, value);
    + return;
    + }
    +
    + writeb(value, addr);
    }

    static inline void cdns_pcie_ep_fn_writew(struct cdns_pcie *pcie, u8 fn,
    u32 reg, u16 value)
    {
    - writew(value, pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
    + void __iomem *addr = pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg;
    +
    + if (pcie->ops && pcie->ops->write) {
    + pcie->ops->write(addr, 0x2, value);
    + return;
    + }
    +
    + writew(value, addr);
    }

    static inline void cdns_pcie_ep_fn_writel(struct cdns_pcie *pcie, u8 fn,
    u32 reg, u32 value)
    {
    - writel(value, pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
    + void __iomem *addr = pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg;
    +
    + if (pcie->ops && pcie->ops->write) {
    + pcie->ops->write(addr, 0x4, value);
    + return;
    + }
    +
    + writel(value, addr);
    }

    static inline u8 cdns_pcie_ep_fn_readb(struct cdns_pcie *pcie, u8 fn, u32 reg)
    {
    - return readb(pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
    + void __iomem *addr = pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg;
    +
    + if (pcie->ops && pcie->ops->read)
    + return pcie->ops->read(addr, 0x1);
    +
    + return readb(addr);
    }

    static inline u16 cdns_pcie_ep_fn_readw(struct cdns_pcie *pcie, u8 fn, u32 reg)
    {
    - return readw(pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
    + void __iomem *addr = pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg;
    +
    + if (pcie->ops && pcie->ops->read)
    + return pcie->ops->read(addr, 0x2);
    +
    + return readw(addr);
    }

    static inline u32 cdns_pcie_ep_fn_readl(struct cdns_pcie *pcie, u8 fn, u32 reg)
    {
    - return readl(pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg);
    + void __iomem *addr = pcie->reg_base + CDNS_PCIE_EP_FUNC_BASE(fn) + reg;
    +
    + if (pcie->ops && pcie->ops->read)
    + return pcie->ops->read(addr, 0x4);
    +
    + return readl(addr);
    }

    #ifdef CONFIG_PCIE_CADENCE_HOST
    --
    2.17.1
    \
     
     \ /
      Last update: 2020-05-06 17:15    [W:2.913 / U:0.096 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site