Re: [v7,5/7] PCI: mediatek-gen3: Add MSI support
On Wed, 2021-01-27 at 13:05 +, Marc Zyngier wrote: > On 2021-01-27 12:31, Jianjun Wang wrote: > > On Tue, 2021-01-26 at 13:57 +, Marc Zyngier wrote: > >> On 2021-01-13 11:39, Jianjun Wang wrote: > >> > Add MSI support for MediaTek Gen3 PCIe controller. > >> > > >> > This PCIe controller supports up to 256 MSI vectors, the MSI hardware > >> > block diagram is as follows: > >> > > >> > +-+ > >> > | GIC | > >> > +-+ > >> > ^ > >> > | > >> > port->irq > >> > | > >> > +-+-+-+-+-+-+-+-+ > >> > |0|1|2|3|4|5|6|7| (PCIe intc) > >> > +-+-+-+-+-+-+-+-+ > >> > ^ ^ ^ > >> > | |...| > >> > +---+ +--++---+ > >> > ||| > >> > +-+-+---+--+--+ +-+-+---+--+--+ +-+-+---+--+--+ > >> > |0|1|...|30|31| |0|1|...|30|31| |0|1|...|30|31| (MSI sets) > >> > +-+-+---+--+--+ +-+-+---+--+--+ +-+-+---+--+--+ > >> > ^ ^ ^ ^^ ^ ^ ^^ ^ ^ ^ > >> > | | | || | | || | | | (MSI vectors) > >> > | | | || | | || | | | > >> > > >> > (MSI SET0) (MSI SET1) ... (MSI SET7) > >> > > >> > With 256 MSI vectors supported, the MSI vectors are composed of 8 sets, > >> > each set has its own address for MSI message, and supports 32 MSI > >> > vectors > >> > to generate interrupt. > >> > > >> > Signed-off-by: Jianjun Wang > >> > Acked-by: Ryder Lee > >> > --- > >> > drivers/pci/controller/pcie-mediatek-gen3.c | 261 > >> > 1 file changed, 261 insertions(+) > >> > > >> > diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c > >> > b/drivers/pci/controller/pcie-mediatek-gen3.c > >> > index 7979a2856c35..471d97cd1ef9 100644 > >> > --- a/drivers/pci/controller/pcie-mediatek-gen3.c > >> > +++ b/drivers/pci/controller/pcie-mediatek-gen3.c > >> > @@ -14,6 +14,7 @@ > >> > #include > >> > #include > >> > #include > >> > +#include > >> > #include > >> > #include > >> > #include > >> > @@ -52,11 +53,28 @@ > >> > #define PCIE_LINK_STATUS_REG0x154 > >> > #define PCIE_PORT_LINKUPBIT(8) > >> > > >> > +#define PCIE_MSI_SET_NUM8 > >> > +#define PCIE_MSI_IRQS_PER_SET 32 > >> > +#define PCIE_MSI_IRQS_NUM \ > >> > +(PCIE_MSI_IRQS_PER_SET * (PCIE_MSI_SET_NUM)) > >> > >> Spurious inner bracketing. > >> > >> > + > >> > #define PCIE_INT_ENABLE_REG 0x180 > >> > +#define PCIE_MSI_ENABLE GENMASK(PCIE_MSI_SET_NUM + 8 - > >> > 1, 8) > >> > +#define PCIE_MSI_SHIFT 8 > >> > #define PCIE_INTX_SHIFT 24 > >> > #define PCIE_INTX_MASK GENMASK(27, 24) > >> > > >> > #define PCIE_INT_STATUS_REG 0x184 > >> > +#define PCIE_MSI_SET_ENABLE_REG 0x190 > >> > +#define PCIE_MSI_SET_ENABLE GENMASK(PCIE_MSI_SET_NUM - 1, 0) > >> > + > >> > +#define PCIE_MSI_SET_BASE_REG 0xc00 > >> > +#define PCIE_MSI_SET_OFFSET 0x10 > >> > +#define PCIE_MSI_SET_STATUS_OFFSET 0x04 > >> > +#define PCIE_MSI_SET_ENABLE_OFFSET 0x08 > >> > + > >> > +#define PCIE_MSI_SET_ADDR_HI_BASE 0xc80 > >> > +#define PCIE_MSI_SET_ADDR_HI_OFFSET 0x04 > >> > > >> > #define PCIE_TRANS_TABLE_BASE_REG 0x800 > >> > #define PCIE_ATR_SRC_ADDR_MSB_OFFSET0x4 > >> > @@ -76,6 +94,18 @@ > >> > #define PCIE_ATR_TLP_TYPE_MEM PCIE_ATR_TLP_TYPE(0) > >> > #define PCIE_ATR_TLP_TYPE_IOPCIE_ATR_TLP_TYPE(2) > >> > > >> > +/** > >> > + * struct mtk_pcie_msi - MSI information for each set > >> > + * @dev: pointer to PCIe device > >> > + * @base: IO mapped register base > >> > + * @msg_addr: MSI message address > >> > + */ > >> > +struct mtk_msi_set { > >> > +struct device *dev; > >> > +void __iomem *base; > >> > +phys_addr_t msg_addr; > >> > +}; > >> > + > >> > /** > >> > * struct mtk_pcie_port - PCIe port information > >> > * @dev: pointer to PCIe device > >> > @@ -88,6 +118,11 @@ > >> > * @num_clks: PCIe clocks count for this port > >> > * @irq: PCIe controller interrupt number > >> > * @intx_domain: legacy INTx IRQ domain > >> > + * @msi_domain: MSI IRQ domain > >> > + * @msi_bottom_domain: MSI IRQ bottom domain > >> > + * @msi_sets: MSI sets information > >> > + * @lock: lock protecting IRQ bit map > >> > + * @msi_irq_in_use: bit map for assigned MSI IRQ > >> > */ > >> > struct mtk_pcie_port { > >> > struct device *dev; > >> > @@ -101,6 +136,11 @@ struct mtk_pcie_port { > >> > > >> > int irq; > >> > struct irq_domain *intx_domain; > >> > +struct irq_domain *msi_domain; > >> > +struct irq_domain *msi_bottom_domain; > >> > +struct mtk_msi_set msi_sets[PCIE_MSI_SET_NUM]; > >> > +struct mutex
Re: [v7,5/7] PCI: mediatek-gen3: Add MSI support
On 2021-01-27 12:31, Jianjun Wang wrote: On Tue, 2021-01-26 at 13:57 +, Marc Zyngier wrote: On 2021-01-13 11:39, Jianjun Wang wrote: > Add MSI support for MediaTek Gen3 PCIe controller. > > This PCIe controller supports up to 256 MSI vectors, the MSI hardware > block diagram is as follows: > > +-+ > | GIC | > +-+ > ^ > | > port->irq > | > +-+-+-+-+-+-+-+-+ > |0|1|2|3|4|5|6|7| (PCIe intc) > +-+-+-+-+-+-+-+-+ > ^ ^ ^ > | |...| > +---+ +--++---+ > ||| > +-+-+---+--+--+ +-+-+---+--+--+ +-+-+---+--+--+ > |0|1|...|30|31| |0|1|...|30|31| |0|1|...|30|31| (MSI sets) > +-+-+---+--+--+ +-+-+---+--+--+ +-+-+---+--+--+ > ^ ^ ^ ^^ ^ ^ ^^ ^ ^ ^ > | | | || | | || | | | (MSI vectors) > | | | || | | || | | | > > (MSI SET0) (MSI SET1) ... (MSI SET7) > > With 256 MSI vectors supported, the MSI vectors are composed of 8 sets, > each set has its own address for MSI message, and supports 32 MSI > vectors > to generate interrupt. > > Signed-off-by: Jianjun Wang > Acked-by: Ryder Lee > --- > drivers/pci/controller/pcie-mediatek-gen3.c | 261 > 1 file changed, 261 insertions(+) > > diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c > b/drivers/pci/controller/pcie-mediatek-gen3.c > index 7979a2856c35..471d97cd1ef9 100644 > --- a/drivers/pci/controller/pcie-mediatek-gen3.c > +++ b/drivers/pci/controller/pcie-mediatek-gen3.c > @@ -14,6 +14,7 @@ > #include > #include > #include > +#include > #include > #include > #include > @@ -52,11 +53,28 @@ > #define PCIE_LINK_STATUS_REG 0x154 > #define PCIE_PORT_LINKUP BIT(8) > > +#define PCIE_MSI_SET_NUM 8 > +#define PCIE_MSI_IRQS_PER_SET 32 > +#define PCIE_MSI_IRQS_NUM \ > + (PCIE_MSI_IRQS_PER_SET * (PCIE_MSI_SET_NUM)) Spurious inner bracketing. > + > #define PCIE_INT_ENABLE_REG 0x180 > +#define PCIE_MSI_ENABLE GENMASK(PCIE_MSI_SET_NUM + 8 - 1, 8) > +#define PCIE_MSI_SHIFT8 > #define PCIE_INTX_SHIFT 24 > #define PCIE_INTX_MASKGENMASK(27, 24) > > #define PCIE_INT_STATUS_REG 0x184 > +#define PCIE_MSI_SET_ENABLE_REG 0x190 > +#define PCIE_MSI_SET_ENABLE GENMASK(PCIE_MSI_SET_NUM - 1, 0) > + > +#define PCIE_MSI_SET_BASE_REG 0xc00 > +#define PCIE_MSI_SET_OFFSET 0x10 > +#define PCIE_MSI_SET_STATUS_OFFSET0x04 > +#define PCIE_MSI_SET_ENABLE_OFFSET0x08 > + > +#define PCIE_MSI_SET_ADDR_HI_BASE 0xc80 > +#define PCIE_MSI_SET_ADDR_HI_OFFSET 0x04 > > #define PCIE_TRANS_TABLE_BASE_REG 0x800 > #define PCIE_ATR_SRC_ADDR_MSB_OFFSET 0x4 > @@ -76,6 +94,18 @@ > #define PCIE_ATR_TLP_TYPE_MEM PCIE_ATR_TLP_TYPE(0) > #define PCIE_ATR_TLP_TYPE_IO PCIE_ATR_TLP_TYPE(2) > > +/** > + * struct mtk_pcie_msi - MSI information for each set > + * @dev: pointer to PCIe device > + * @base: IO mapped register base > + * @msg_addr: MSI message address > + */ > +struct mtk_msi_set { > + struct device *dev; > + void __iomem *base; > + phys_addr_t msg_addr; > +}; > + > /** > * struct mtk_pcie_port - PCIe port information > * @dev: pointer to PCIe device > @@ -88,6 +118,11 @@ > * @num_clks: PCIe clocks count for this port > * @irq: PCIe controller interrupt number > * @intx_domain: legacy INTx IRQ domain > + * @msi_domain: MSI IRQ domain > + * @msi_bottom_domain: MSI IRQ bottom domain > + * @msi_sets: MSI sets information > + * @lock: lock protecting IRQ bit map > + * @msi_irq_in_use: bit map for assigned MSI IRQ > */ > struct mtk_pcie_port { >struct device *dev; > @@ -101,6 +136,11 @@ struct mtk_pcie_port { > >int irq; >struct irq_domain *intx_domain; > + struct irq_domain *msi_domain; > + struct irq_domain *msi_bottom_domain; > + struct mtk_msi_set msi_sets[PCIE_MSI_SET_NUM]; > + struct mutex lock; > + DECLARE_BITMAP(msi_irq_in_use, PCIE_MSI_IRQS_NUM); > }; > > /** > @@ -243,6 +283,15 @@ static int mtk_pcie_startup_port(struct > mtk_pcie_port *port) >return err; >} > > + /* Enable MSI */ > + val = readl_relaxed(port->base + PCIE_MSI_SET_ENABLE_REG); > + val |= PCIE_MSI_SET_ENABLE; > + writel_relaxed(val, port->base + PCIE_MSI_SET_ENABLE_REG); > + > + val = readl_relaxed(port->base + PCIE_INT_ENABLE_REG); > + val |= PCIE_MSI_ENABLE; > + writel_relaxed(val, port->base + PCIE_INT_ENABLE_REG); > + >/* Set PCIe translation windows */ >resource_list_for_each_entry(entry, &host->windows) { >struct resource *res = entry->res; > @@ -286,6 +335,129 @@ static int mtk_pcie_set_affini
Re: [v7,5/7] PCI: mediatek-gen3: Add MSI support
On Tue, 2021-01-26 at 13:57 +, Marc Zyngier wrote: > On 2021-01-13 11:39, Jianjun Wang wrote: > > Add MSI support for MediaTek Gen3 PCIe controller. > > > > This PCIe controller supports up to 256 MSI vectors, the MSI hardware > > block diagram is as follows: > > > > +-+ > > | GIC | > > +-+ > > ^ > > | > > port->irq > > | > > +-+-+-+-+-+-+-+-+ > > |0|1|2|3|4|5|6|7| (PCIe intc) > > +-+-+-+-+-+-+-+-+ > > ^ ^ ^ > > | |...| > > +---+ +--++---+ > > ||| > > +-+-+---+--+--+ +-+-+---+--+--+ +-+-+---+--+--+ > > |0|1|...|30|31| |0|1|...|30|31| |0|1|...|30|31| (MSI sets) > > +-+-+---+--+--+ +-+-+---+--+--+ +-+-+---+--+--+ > > ^ ^ ^ ^^ ^ ^ ^^ ^ ^ ^ > > | | | || | | || | | | (MSI vectors) > > | | | || | | || | | | > > > > (MSI SET0) (MSI SET1) ... (MSI SET7) > > > > With 256 MSI vectors supported, the MSI vectors are composed of 8 sets, > > each set has its own address for MSI message, and supports 32 MSI > > vectors > > to generate interrupt. > > > > Signed-off-by: Jianjun Wang > > Acked-by: Ryder Lee > > --- > > drivers/pci/controller/pcie-mediatek-gen3.c | 261 > > 1 file changed, 261 insertions(+) > > > > diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c > > b/drivers/pci/controller/pcie-mediatek-gen3.c > > index 7979a2856c35..471d97cd1ef9 100644 > > --- a/drivers/pci/controller/pcie-mediatek-gen3.c > > +++ b/drivers/pci/controller/pcie-mediatek-gen3.c > > @@ -14,6 +14,7 @@ > > #include > > #include > > #include > > +#include > > #include > > #include > > #include > > @@ -52,11 +53,28 @@ > > #define PCIE_LINK_STATUS_REG 0x154 > > #define PCIE_PORT_LINKUP BIT(8) > > > > +#define PCIE_MSI_SET_NUM 8 > > +#define PCIE_MSI_IRQS_PER_SET 32 > > +#define PCIE_MSI_IRQS_NUM \ > > + (PCIE_MSI_IRQS_PER_SET * (PCIE_MSI_SET_NUM)) > > Spurious inner bracketing. > > > + > > #define PCIE_INT_ENABLE_REG0x180 > > +#define PCIE_MSI_ENABLEGENMASK(PCIE_MSI_SET_NUM + 8 - > > 1, 8) > > +#define PCIE_MSI_SHIFT 8 > > #define PCIE_INTX_SHIFT24 > > #define PCIE_INTX_MASK GENMASK(27, 24) > > > > #define PCIE_INT_STATUS_REG0x184 > > +#define PCIE_MSI_SET_ENABLE_REG0x190 > > +#define PCIE_MSI_SET_ENABLEGENMASK(PCIE_MSI_SET_NUM - 1, 0) > > + > > +#define PCIE_MSI_SET_BASE_REG 0xc00 > > +#define PCIE_MSI_SET_OFFSET0x10 > > +#define PCIE_MSI_SET_STATUS_OFFSET 0x04 > > +#define PCIE_MSI_SET_ENABLE_OFFSET 0x08 > > + > > +#define PCIE_MSI_SET_ADDR_HI_BASE 0xc80 > > +#define PCIE_MSI_SET_ADDR_HI_OFFSET0x04 > > > > #define PCIE_TRANS_TABLE_BASE_REG 0x800 > > #define PCIE_ATR_SRC_ADDR_MSB_OFFSET 0x4 > > @@ -76,6 +94,18 @@ > > #define PCIE_ATR_TLP_TYPE_MEM PCIE_ATR_TLP_TYPE(0) > > #define PCIE_ATR_TLP_TYPE_IO PCIE_ATR_TLP_TYPE(2) > > > > +/** > > + * struct mtk_pcie_msi - MSI information for each set > > + * @dev: pointer to PCIe device > > + * @base: IO mapped register base > > + * @msg_addr: MSI message address > > + */ > > +struct mtk_msi_set { > > + struct device *dev; > > + void __iomem *base; > > + phys_addr_t msg_addr; > > +}; > > + > > /** > > * struct mtk_pcie_port - PCIe port information > > * @dev: pointer to PCIe device > > @@ -88,6 +118,11 @@ > > * @num_clks: PCIe clocks count for this port > > * @irq: PCIe controller interrupt number > > * @intx_domain: legacy INTx IRQ domain > > + * @msi_domain: MSI IRQ domain > > + * @msi_bottom_domain: MSI IRQ bottom domain > > + * @msi_sets: MSI sets information > > + * @lock: lock protecting IRQ bit map > > + * @msi_irq_in_use: bit map for assigned MSI IRQ > > */ > > struct mtk_pcie_port { > > struct device *dev; > > @@ -101,6 +136,11 @@ struct mtk_pcie_port { > > > > int irq; > > struct irq_domain *intx_domain; > > + struct irq_domain *msi_domain; > > + struct irq_domain *msi_bottom_domain; > > + struct mtk_msi_set msi_sets[PCIE_MSI_SET_NUM]; > > + struct mutex lock; > > + DECLARE_BITMAP(msi_irq_in_use, PCIE_MSI_IRQS_NUM); > > }; > > > > /** > > @@ -243,6 +283,15 @@ static int mtk_pcie_startup_port(struct > > mtk_pcie_port *port) > > return err; > > } > > > > + /* Enable MSI */ > > + val = readl_relaxed(port->base + PCIE_MSI_SET_ENABLE_REG); > > + val |= PCIE_MSI_SET_ENABLE; > > + writel_relaxed(val, port->base + PCIE_MSI_SET_ENABLE_REG); > > + > > + val = readl_relaxed(port->base + PCIE_INT_ENABLE_REG); > > + val |= PC
Re: [v7,5/7] PCI: mediatek-gen3: Add MSI support
On 2021-01-13 11:39, Jianjun Wang wrote: Add MSI support for MediaTek Gen3 PCIe controller. This PCIe controller supports up to 256 MSI vectors, the MSI hardware block diagram is as follows: +-+ | GIC | +-+ ^ | port->irq | +-+-+-+-+-+-+-+-+ |0|1|2|3|4|5|6|7| (PCIe intc) +-+-+-+-+-+-+-+-+ ^ ^ ^ | |...| +---+ +--++---+ ||| +-+-+---+--+--+ +-+-+---+--+--+ +-+-+---+--+--+ |0|1|...|30|31| |0|1|...|30|31| |0|1|...|30|31| (MSI sets) +-+-+---+--+--+ +-+-+---+--+--+ +-+-+---+--+--+ ^ ^ ^ ^^ ^ ^ ^^ ^ ^ ^ | | | || | | || | | | (MSI vectors) | | | || | | || | | | (MSI SET0) (MSI SET1) ... (MSI SET7) With 256 MSI vectors supported, the MSI vectors are composed of 8 sets, each set has its own address for MSI message, and supports 32 MSI vectors to generate interrupt. Signed-off-by: Jianjun Wang Acked-by: Ryder Lee --- drivers/pci/controller/pcie-mediatek-gen3.c | 261 1 file changed, 261 insertions(+) diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c index 7979a2856c35..471d97cd1ef9 100644 --- a/drivers/pci/controller/pcie-mediatek-gen3.c +++ b/drivers/pci/controller/pcie-mediatek-gen3.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -52,11 +53,28 @@ #define PCIE_LINK_STATUS_REG 0x154 #define PCIE_PORT_LINKUP BIT(8) +#define PCIE_MSI_SET_NUM 8 +#define PCIE_MSI_IRQS_PER_SET 32 +#define PCIE_MSI_IRQS_NUM \ + (PCIE_MSI_IRQS_PER_SET * (PCIE_MSI_SET_NUM)) Spurious inner bracketing. + #define PCIE_INT_ENABLE_REG0x180 +#define PCIE_MSI_ENABLEGENMASK(PCIE_MSI_SET_NUM + 8 - 1, 8) +#define PCIE_MSI_SHIFT 8 #define PCIE_INTX_SHIFT24 #define PCIE_INTX_MASK GENMASK(27, 24) #define PCIE_INT_STATUS_REG0x184 +#define PCIE_MSI_SET_ENABLE_REG0x190 +#define PCIE_MSI_SET_ENABLEGENMASK(PCIE_MSI_SET_NUM - 1, 0) + +#define PCIE_MSI_SET_BASE_REG 0xc00 +#define PCIE_MSI_SET_OFFSET0x10 +#define PCIE_MSI_SET_STATUS_OFFSET 0x04 +#define PCIE_MSI_SET_ENABLE_OFFSET 0x08 + +#define PCIE_MSI_SET_ADDR_HI_BASE 0xc80 +#define PCIE_MSI_SET_ADDR_HI_OFFSET0x04 #define PCIE_TRANS_TABLE_BASE_REG 0x800 #define PCIE_ATR_SRC_ADDR_MSB_OFFSET 0x4 @@ -76,6 +94,18 @@ #define PCIE_ATR_TLP_TYPE_MEM PCIE_ATR_TLP_TYPE(0) #define PCIE_ATR_TLP_TYPE_IO PCIE_ATR_TLP_TYPE(2) +/** + * struct mtk_pcie_msi - MSI information for each set + * @dev: pointer to PCIe device + * @base: IO mapped register base + * @msg_addr: MSI message address + */ +struct mtk_msi_set { + struct device *dev; + void __iomem *base; + phys_addr_t msg_addr; +}; + /** * struct mtk_pcie_port - PCIe port information * @dev: pointer to PCIe device @@ -88,6 +118,11 @@ * @num_clks: PCIe clocks count for this port * @irq: PCIe controller interrupt number * @intx_domain: legacy INTx IRQ domain + * @msi_domain: MSI IRQ domain + * @msi_bottom_domain: MSI IRQ bottom domain + * @msi_sets: MSI sets information + * @lock: lock protecting IRQ bit map + * @msi_irq_in_use: bit map for assigned MSI IRQ */ struct mtk_pcie_port { struct device *dev; @@ -101,6 +136,11 @@ struct mtk_pcie_port { int irq; struct irq_domain *intx_domain; + struct irq_domain *msi_domain; + struct irq_domain *msi_bottom_domain; + struct mtk_msi_set msi_sets[PCIE_MSI_SET_NUM]; + struct mutex lock; + DECLARE_BITMAP(msi_irq_in_use, PCIE_MSI_IRQS_NUM); }; /** @@ -243,6 +283,15 @@ static int mtk_pcie_startup_port(struct mtk_pcie_port *port) return err; } + /* Enable MSI */ + val = readl_relaxed(port->base + PCIE_MSI_SET_ENABLE_REG); + val |= PCIE_MSI_SET_ENABLE; + writel_relaxed(val, port->base + PCIE_MSI_SET_ENABLE_REG); + + val = readl_relaxed(port->base + PCIE_INT_ENABLE_REG); + val |= PCIE_MSI_ENABLE; + writel_relaxed(val, port->base + PCIE_INT_ENABLE_REG); + /* Set PCIe translation windows */ resource_list_for_each_entry(entry, &host->windows) { struct resource *res = entry->res; @@ -286,6 +335,129 @@ static int mtk_pcie_set_affinity(struct irq_data *data, return -EINVAL; } +static struct irq_chip mtk_msi_irq_chip = { + .name = "MSI", + .irq_ack = irq_chip_ack_parent, +}; + +static struct msi_domain_info mtk_msi_domain_info = { + .flags = (MS