Re: [PATCH v3 1/2] mtd: spi-nor: add support to non-uniform SFDP SPI NOR flash memories
Hi Yogesh, Tudor, Le 17/10/2018 à 04:07, Yogesh Narayan Gaur a écrit : > Hi Tudor, > >> -Original Message----- >> From: Cyrille Pitchen [mailto:cyrille.pitc...@wedev4u.fr] >> Sent: Tuesday, October 16, 2018 10:04 PM >> To: Tudor Ambarus ; Yogesh Narayan Gaur >> ; marek.va...@gmail.com; >> dw...@infradead.org; computersforpe...@gmail.com; >> boris.brezil...@bootlin.com; rich...@nod.at >> Cc: linux-kernel@vger.kernel.org; nicolas.fe...@microchip.com; >> cyrille.pitc...@microchip.com; linux-...@lists.infradead.org; linux-arm- >> ker...@lists.infradead.org; cristian.bir...@microchip.com >> Subject: Re: [PATCH v3 1/2] mtd: spi-nor: add support to non-uniform SFDP SPI >> NOR flash memories >> >> Hi Tudor, >> >> Le 16/10/2018 à 17:14, Tudor Ambarus a écrit : >>> Hi, Yogesh, >>> >>> On 10/16/2018 12:51 PM, Yogesh Narayan Gaur wrote: >>>> Hi Tudor, >>>> >>>> This patch is breaking the 1-4-4 Read protocol for the spansion flash >> "s25fl512s". >>>> >>>> Without this patch read request command for Quad mode, 4-byte enable, is >> coming as 0xEC i.e. SPINOR_OP_READ_1_4_4_4B. >>>> But after applying this patch, read request command for Quad mode is >> coming as 0x6C i.e. SPINOR_OP_READ_1_1_4_4B. >>>> >>>> This flash also supports non-uniform erase. >>>> Can you please check and provide some suggestion? >>> >>> I don't have this memory to test it, but I'll try to help. >>> >>> Does s25fl512s support non-uniform erase? I'm looking in datasheet[1] >>> at JEDEC BFPT table, dwords 8 and 9, page 132/146 and it looks like it >>> supports just 256KB uniform erase. >>> >> > Actually there is no entry of s25fs512s in current spi-nor.c file. > For my connected flash part, jedec ID read points to s25fl512s. I have asked > my board team to confirm the name of exact connected flash part. > When I check the data sheet of s25fs512s, it also points to the same Jedec ID > information. > { "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, } > At least the 6th byte of the JEDEC ID, the Cypress Family ID, is different between S25FL512S (0x80) and S25FS512S (0x81). Hence the INFO6() macro can be used to create separated entries in the spi_nor_ids[] array. Warning: the exact value of the 4th byte of the JEDEC ID for S25FL512S memory parts is not provided by the Cypress datasheet I read. It's only written that "The value is OPN dependent". Maybe you can do the magic by placing a new INFO6() entry for the S25FL512S, just before the legacy INFO() entry for S25FL512S. Indeed entries are tested in the order they appear inside the spi_nor_ids[] array from spi_nor_read_id(), so the INFO6() entry would be tested 1st, trying to match 6 bytes, then the INFO() entry only trying to match 3 bytes. Maybe it won't solve your issue but since this is not the 1st time that someone needs to make the difference between those 2 memory parts... Best regards, Cyrille > But as stated earlier, if I skip reading SFDP or read using 1-1-1 protocol > then read are always correct. > For 1-4-4 protocol read are wrong and on further debugging found that Read > code of 0x6C is being send as opcode instead of 0xEC. > > If I revert this patch, reads are working fine. > > -- > Regards > Yogesh Gaur > >> s25fS512s supports both uniform and non uniform erase options but s25fL512s >> is >> always uniform. L is an old memory part, S is newer. >> >> Also, the 8th and 9th WORDs of the Basic Flash Parameter Table alone can't >> tell >> you whether or not the memory part can be non uniform. >> If the memory can be non uniform then the sector erase map table is >> mandatory, >> hence when the table is missing you know that your memory part is always >> uniform. >> >> Best regards, >> >> Cyrille >> >>> Thanks, >>> ta >>> >>> [1] >>> https://emea01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww. >>> >> cypress.com%2Ffile%2F177971%2Fdownloaddata=02%7C01%7Cyogeshn >> araya >>> >> n.gaur%40nxp.com%7C76e7e1555f4a4cda378008d63385480b%7C686ea1d3bc2 >> b4c6f >>> >> a92cd99c5c301635%7C0%7C0%7C636753044876199155sdata=cioC98EH >> OGlFbg >>> XPhoIIJ72K3JrNUnzA1pYhSB9jDwg%3Dreserved=0 >>> >>>> >>>> -- >>>> Regards >>>> Yogesh Gaur >>>> >>>>> -Original Message- >>>>> From: linux-mtd [mailto:linux-mtd-boun...@lists.infradead.org] On >
Re: [PATCH v3 1/2] mtd: spi-nor: add support to non-uniform SFDP SPI NOR flash memories
Hi Yogesh, Tudor, Le 17/10/2018 à 04:07, Yogesh Narayan Gaur a écrit : > Hi Tudor, > >> -Original Message----- >> From: Cyrille Pitchen [mailto:cyrille.pitc...@wedev4u.fr] >> Sent: Tuesday, October 16, 2018 10:04 PM >> To: Tudor Ambarus ; Yogesh Narayan Gaur >> ; marek.va...@gmail.com; >> dw...@infradead.org; computersforpe...@gmail.com; >> boris.brezil...@bootlin.com; rich...@nod.at >> Cc: linux-kernel@vger.kernel.org; nicolas.fe...@microchip.com; >> cyrille.pitc...@microchip.com; linux-...@lists.infradead.org; linux-arm- >> ker...@lists.infradead.org; cristian.bir...@microchip.com >> Subject: Re: [PATCH v3 1/2] mtd: spi-nor: add support to non-uniform SFDP SPI >> NOR flash memories >> >> Hi Tudor, >> >> Le 16/10/2018 à 17:14, Tudor Ambarus a écrit : >>> Hi, Yogesh, >>> >>> On 10/16/2018 12:51 PM, Yogesh Narayan Gaur wrote: >>>> Hi Tudor, >>>> >>>> This patch is breaking the 1-4-4 Read protocol for the spansion flash >> "s25fl512s". >>>> >>>> Without this patch read request command for Quad mode, 4-byte enable, is >> coming as 0xEC i.e. SPINOR_OP_READ_1_4_4_4B. >>>> But after applying this patch, read request command for Quad mode is >> coming as 0x6C i.e. SPINOR_OP_READ_1_1_4_4B. >>>> >>>> This flash also supports non-uniform erase. >>>> Can you please check and provide some suggestion? >>> >>> I don't have this memory to test it, but I'll try to help. >>> >>> Does s25fl512s support non-uniform erase? I'm looking in datasheet[1] >>> at JEDEC BFPT table, dwords 8 and 9, page 132/146 and it looks like it >>> supports just 256KB uniform erase. >>> >> > Actually there is no entry of s25fs512s in current spi-nor.c file. > For my connected flash part, jedec ID read points to s25fl512s. I have asked > my board team to confirm the name of exact connected flash part. > When I check the data sheet of s25fs512s, it also points to the same Jedec ID > information. > { "s25fl512s", INFO(0x010220, 0x4d00, 256 * 1024, 256, } > At least the 6th byte of the JEDEC ID, the Cypress Family ID, is different between S25FL512S (0x80) and S25FS512S (0x81). Hence the INFO6() macro can be used to create separated entries in the spi_nor_ids[] array. Warning: the exact value of the 4th byte of the JEDEC ID for S25FL512S memory parts is not provided by the Cypress datasheet I read. It's only written that "The value is OPN dependent". Maybe you can do the magic by placing a new INFO6() entry for the S25FL512S, just before the legacy INFO() entry for S25FL512S. Indeed entries are tested in the order they appear inside the spi_nor_ids[] array from spi_nor_read_id(), so the INFO6() entry would be tested 1st, trying to match 6 bytes, then the INFO() entry only trying to match 3 bytes. Maybe it won't solve your issue but since this is not the 1st time that someone needs to make the difference between those 2 memory parts... Best regards, Cyrille > But as stated earlier, if I skip reading SFDP or read using 1-1-1 protocol > then read are always correct. > For 1-4-4 protocol read are wrong and on further debugging found that Read > code of 0x6C is being send as opcode instead of 0xEC. > > If I revert this patch, reads are working fine. > > -- > Regards > Yogesh Gaur > >> s25fS512s supports both uniform and non uniform erase options but s25fL512s >> is >> always uniform. L is an old memory part, S is newer. >> >> Also, the 8th and 9th WORDs of the Basic Flash Parameter Table alone can't >> tell >> you whether or not the memory part can be non uniform. >> If the memory can be non uniform then the sector erase map table is >> mandatory, >> hence when the table is missing you know that your memory part is always >> uniform. >> >> Best regards, >> >> Cyrille >> >>> Thanks, >>> ta >>> >>> [1] >>> https://emea01.safelinks.protection.outlook.com/?url=http%3A%2F%2Fwww. >>> >> cypress.com%2Ffile%2F177971%2Fdownloaddata=02%7C01%7Cyogeshn >> araya >>> >> n.gaur%40nxp.com%7C76e7e1555f4a4cda378008d63385480b%7C686ea1d3bc2 >> b4c6f >>> >> a92cd99c5c301635%7C0%7C0%7C636753044876199155sdata=cioC98EH >> OGlFbg >>> XPhoIIJ72K3JrNUnzA1pYhSB9jDwg%3Dreserved=0 >>> >>>> >>>> -- >>>> Regards >>>> Yogesh Gaur >>>> >>>>> -Original Message- >>>>> From: linux-mtd [mailto:linux-mtd-boun...@lists.infradead.org] On >
Re: [PATCH v3 1/2] mtd: spi-nor: add support to non-uniform SFDP SPI NOR flash memories
Hi Tudor, Le 16/10/2018 à 17:14, Tudor Ambarus a écrit : > Hi, Yogesh, > > On 10/16/2018 12:51 PM, Yogesh Narayan Gaur wrote: >> Hi Tudor, >> >> This patch is breaking the 1-4-4 Read protocol for the spansion flash >> "s25fl512s". >> >> Without this patch read request command for Quad mode, 4-byte enable, is >> coming as 0xEC i.e. SPINOR_OP_READ_1_4_4_4B. >> But after applying this patch, read request command for Quad mode is coming >> as 0x6C i.e. SPINOR_OP_READ_1_1_4_4B. >> >> This flash also supports non-uniform erase. >> Can you please check and provide some suggestion? > > I don't have this memory to test it, but I'll try to help. > > Does s25fl512s support non-uniform erase? I'm looking in datasheet[1] at JEDEC > BFPT table, dwords 8 and 9, page 132/146 and it looks like it supports just > 256KB uniform erase. > s25fS512s supports both uniform and non uniform erase options but s25fL512s is always uniform. L is an old memory part, S is newer. Also, the 8th and 9th WORDs of the Basic Flash Parameter Table alone can't tell you whether or not the memory part can be non uniform. If the memory can be non uniform then the sector erase map table is mandatory, hence when the table is missing you know that your memory part is always uniform. Best regards, Cyrille > Thanks, > ta > > [1] http://www.cypress.com/file/177971/download > >> >> -- >> Regards >> Yogesh Gaur >> >>> -Original Message- >>> From: linux-mtd [mailto:linux-mtd-boun...@lists.infradead.org] On Behalf Of >>> Tudor Ambarus >>> Sent: Tuesday, September 11, 2018 9:10 PM >>> To: marek.va...@gmail.com; dw...@infradead.org; >>> computersforpe...@gmail.com; boris.brezil...@bootlin.com; rich...@nod.at >>> Cc: Tudor Ambarus ; linux- >>> ker...@vger.kernel.org; nicolas.fe...@microchip.com; >>> cyrille.pitc...@microchip.com; linux-...@lists.infradead.org; linux-arm- >>> ker...@lists.infradead.org; cristian.bir...@microchip.com >>> Subject: [PATCH v3 1/2] mtd: spi-nor: add support to non-uniform SFDP SPI >>> NOR >>> flash memories >>> >>> Based on Cyrille Pitchen's patch >>> https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flkml.or >>> g%2Flkml%2F2017%2F3%2F22%2F935data=02%7C01%7Cyogeshnarayan. >>> gaur%40nxp.com%7C3c782e52b7fd4a8b9af008d617fd5154%7C686ea1d3bc2b4 >>> c6fa92cd99c5c301635%7C0%7C0%7C636722774108718782sdata=szyc% >>> 2FTumG6eYAmBd0oW3IL7v1yLh9E1SAZqL%2BCWczOA%3Dreserved=0. >>> >>> This patch is a transitional patch in introducing the support of SFDP SPI >>> memories with non-uniform erase sizes like Spansion s25fs512s. >>> Non-uniform erase maps will be used later when initialized based on the SFDP >>> data. >>> >>> Introduce the memory erase map which splits the memory array into one or >>> many erase regions. Each erase region supports up to 4 erase types, as >>> defined >>> by the JEDEC JESD216B (SFDP) specification. >>> >>> To be backward compatible, the erase map of uniform SPI NOR flash memories >>> is initialized so it contains only one erase region and this erase region >>> supports >>> only one erase command. Hence a single size is used to erase any >>> sector/block >>> of the memory. >>> >>> Besides, since the algorithm used to erase sectors on non-uniform SPI NOR >>> flash >>> memories is quite expensive, when possible, the erase map is tuned to come >>> back to the uniform case. >>> >>> The 'erase with the best command, move forward and repeat' approach was >>> suggested by Cristian Birsan in a brainstorm session, so: >>> >>> Suggested-by: Cristian Birsan >>> Signed-off-by: Tudor Ambarus >>> --- >>> drivers/mtd/spi-nor/spi-nor.c | 594 >>> +++--- >>> include/linux/mtd/spi-nor.h | 107 >>> 2 files changed, 659 insertions(+), 42 deletions(-) >>> >>> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c >>> index >>> dc8757e..4687345 100644 >>> --- a/drivers/mtd/spi-nor/spi-nor.c >>> +++ b/drivers/mtd/spi-nor/spi-nor.c >>> @@ -18,6 +18,7 @@ >>> #include >>> #include >>> #include >>> +#include >>> >>> #include >>> #include >>> @@ -261,6 +262,18 @@ static void spi_nor_set_4byte_opcodes(struct spi_nor >>> *nor, >>> nor->read_opcode = spi_nor_convert_3to4_read(nor->read_opcode); >>> nor->program_opcode = spi_nor_convert_3to4_program(nor- program_opcode); >>> nor->erase_opcode = spi_nor_convert_3to4_erase(nor->erase_opcode); >>> + >>> + if (!spi_nor_has_uniform_erase(nor)) { >>> + struct spi_nor_erase_map *map = >erase_map; >>> + struct spi_nor_erase_type *erase; >>> + int i; >>> + >>> + for (i = 0; i < SNOR_ERASE_TYPE_MAX; i++) { >>> + erase = >erase_type[i]; >>> + erase->opcode = >>> + spi_nor_convert_3to4_erase(erase->opcode); >>> + } >>> + } >>> } >>> >>> /* Enable/disable 4-byte addressing mode. */ @@ -499,6 +512,275 @@ static >>> int spi_nor_erase_sector(struct spi_nor
Re: [PATCH v3 1/2] mtd: spi-nor: add support to non-uniform SFDP SPI NOR flash memories
Hi Tudor, Le 16/10/2018 à 17:14, Tudor Ambarus a écrit : > Hi, Yogesh, > > On 10/16/2018 12:51 PM, Yogesh Narayan Gaur wrote: >> Hi Tudor, >> >> This patch is breaking the 1-4-4 Read protocol for the spansion flash >> "s25fl512s". >> >> Without this patch read request command for Quad mode, 4-byte enable, is >> coming as 0xEC i.e. SPINOR_OP_READ_1_4_4_4B. >> But after applying this patch, read request command for Quad mode is coming >> as 0x6C i.e. SPINOR_OP_READ_1_1_4_4B. >> >> This flash also supports non-uniform erase. >> Can you please check and provide some suggestion? > > I don't have this memory to test it, but I'll try to help. > > Does s25fl512s support non-uniform erase? I'm looking in datasheet[1] at JEDEC > BFPT table, dwords 8 and 9, page 132/146 and it looks like it supports just > 256KB uniform erase. > s25fS512s supports both uniform and non uniform erase options but s25fL512s is always uniform. L is an old memory part, S is newer. Also, the 8th and 9th WORDs of the Basic Flash Parameter Table alone can't tell you whether or not the memory part can be non uniform. If the memory can be non uniform then the sector erase map table is mandatory, hence when the table is missing you know that your memory part is always uniform. Best regards, Cyrille > Thanks, > ta > > [1] http://www.cypress.com/file/177971/download > >> >> -- >> Regards >> Yogesh Gaur >> >>> -Original Message- >>> From: linux-mtd [mailto:linux-mtd-boun...@lists.infradead.org] On Behalf Of >>> Tudor Ambarus >>> Sent: Tuesday, September 11, 2018 9:10 PM >>> To: marek.va...@gmail.com; dw...@infradead.org; >>> computersforpe...@gmail.com; boris.brezil...@bootlin.com; rich...@nod.at >>> Cc: Tudor Ambarus ; linux- >>> ker...@vger.kernel.org; nicolas.fe...@microchip.com; >>> cyrille.pitc...@microchip.com; linux-...@lists.infradead.org; linux-arm- >>> ker...@lists.infradead.org; cristian.bir...@microchip.com >>> Subject: [PATCH v3 1/2] mtd: spi-nor: add support to non-uniform SFDP SPI >>> NOR >>> flash memories >>> >>> Based on Cyrille Pitchen's patch >>> https://emea01.safelinks.protection.outlook.com/?url=https%3A%2F%2Flkml.or >>> g%2Flkml%2F2017%2F3%2F22%2F935data=02%7C01%7Cyogeshnarayan. >>> gaur%40nxp.com%7C3c782e52b7fd4a8b9af008d617fd5154%7C686ea1d3bc2b4 >>> c6fa92cd99c5c301635%7C0%7C0%7C636722774108718782sdata=szyc% >>> 2FTumG6eYAmBd0oW3IL7v1yLh9E1SAZqL%2BCWczOA%3Dreserved=0. >>> >>> This patch is a transitional patch in introducing the support of SFDP SPI >>> memories with non-uniform erase sizes like Spansion s25fs512s. >>> Non-uniform erase maps will be used later when initialized based on the SFDP >>> data. >>> >>> Introduce the memory erase map which splits the memory array into one or >>> many erase regions. Each erase region supports up to 4 erase types, as >>> defined >>> by the JEDEC JESD216B (SFDP) specification. >>> >>> To be backward compatible, the erase map of uniform SPI NOR flash memories >>> is initialized so it contains only one erase region and this erase region >>> supports >>> only one erase command. Hence a single size is used to erase any >>> sector/block >>> of the memory. >>> >>> Besides, since the algorithm used to erase sectors on non-uniform SPI NOR >>> flash >>> memories is quite expensive, when possible, the erase map is tuned to come >>> back to the uniform case. >>> >>> The 'erase with the best command, move forward and repeat' approach was >>> suggested by Cristian Birsan in a brainstorm session, so: >>> >>> Suggested-by: Cristian Birsan >>> Signed-off-by: Tudor Ambarus >>> --- >>> drivers/mtd/spi-nor/spi-nor.c | 594 >>> +++--- >>> include/linux/mtd/spi-nor.h | 107 >>> 2 files changed, 659 insertions(+), 42 deletions(-) >>> >>> diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c >>> index >>> dc8757e..4687345 100644 >>> --- a/drivers/mtd/spi-nor/spi-nor.c >>> +++ b/drivers/mtd/spi-nor/spi-nor.c >>> @@ -18,6 +18,7 @@ >>> #include >>> #include >>> #include >>> +#include >>> >>> #include >>> #include >>> @@ -261,6 +262,18 @@ static void spi_nor_set_4byte_opcodes(struct spi_nor >>> *nor, >>> nor->read_opcode = spi_nor_convert_3to4_read(nor->read_opcode); >>> nor->program_opcode = spi_nor_convert_3to4_program(nor- program_opcode); >>> nor->erase_opcode = spi_nor_convert_3to4_erase(nor->erase_opcode); >>> + >>> + if (!spi_nor_has_uniform_erase(nor)) { >>> + struct spi_nor_erase_map *map = >erase_map; >>> + struct spi_nor_erase_type *erase; >>> + int i; >>> + >>> + for (i = 0; i < SNOR_ERASE_TYPE_MAX; i++) { >>> + erase = >erase_type[i]; >>> + erase->opcode = >>> + spi_nor_convert_3to4_erase(erase->opcode); >>> + } >>> + } >>> } >>> >>> /* Enable/disable 4-byte addressing mode. */ @@ -499,6 +512,275 @@ static >>> int spi_nor_erase_sector(struct spi_nor
Re: [RFC/RFT PATCH v1 9/9] mtd: spi: Skip reading the Serial Flash Discoverable Parameters
Hi Lukasz, Le 27/09/2018 à 00:07, Lukasz Majewski a écrit : > The fsl-quadspi.c driver is not supporting SPINOR_OP_RDSFDP (0x5a) > read opcode - in the legacy driver we do read some garbage > data from AHB mapped area and then return on the first check If your controller reads garbage then spi_nor_parse_sfdp() fails and exists on the very first check: signature of the SFDP header. Hence everything should already go on as if the SPI_NOR_SKIP_SFDP flag is set. So this patch doesn't change anything for your controller but prevents other controller from using QSPI protocols like SPI 1-4-4. This patch introduces a regression for other chips. Best regards, Cyrille > (L2376 @ ./mtd/spi-nor/spi-nor.c) > > Signed-off-by: Lukasz Majewski > --- > drivers/mtd/spi-nor/spi-nor.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c > index 442102be174e..c79b8c33aeeb 100644 > --- a/drivers/mtd/spi-nor/spi-nor.c > +++ b/drivers/mtd/spi-nor/spi-nor.c > @@ -1103,7 +1103,7 @@ static const struct flash_info spi_nor_ids[] = { > { "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128, SECT_4K | > SPI_NOR_QUAD_READ) }, > { "n25q064a",INFO(0x20bb17, 0, 64 * 1024, 128, SECT_4K | > SPI_NOR_QUAD_READ) }, > { "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, SECT_4K | > SPI_NOR_QUAD_READ) }, > - { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, SECT_4K | > SPI_NOR_QUAD_READ | SPI_NOR_DUAL_READ) }, > + { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, SECT_4K | > SPI_NOR_QUAD_READ | SPI_NOR_DUAL_READ | SPI_NOR_SKIP_SFDP) }, > { "n25q256a",INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K | > SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > { "n25q256ax1", INFO(0x20bb19, 0, 64 * 1024, 512, SECT_4K | > SPI_NOR_QUAD_READ) }, > { "n25q512a",INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | > SPI_NOR_QUAD_READ) }, >
Re: [RFC/RFT PATCH v1 9/9] mtd: spi: Skip reading the Serial Flash Discoverable Parameters
Hi Lukasz, Le 27/09/2018 à 00:07, Lukasz Majewski a écrit : > The fsl-quadspi.c driver is not supporting SPINOR_OP_RDSFDP (0x5a) > read opcode - in the legacy driver we do read some garbage > data from AHB mapped area and then return on the first check If your controller reads garbage then spi_nor_parse_sfdp() fails and exists on the very first check: signature of the SFDP header. Hence everything should already go on as if the SPI_NOR_SKIP_SFDP flag is set. So this patch doesn't change anything for your controller but prevents other controller from using QSPI protocols like SPI 1-4-4. This patch introduces a regression for other chips. Best regards, Cyrille > (L2376 @ ./mtd/spi-nor/spi-nor.c) > > Signed-off-by: Lukasz Majewski > --- > drivers/mtd/spi-nor/spi-nor.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c > index 442102be174e..c79b8c33aeeb 100644 > --- a/drivers/mtd/spi-nor/spi-nor.c > +++ b/drivers/mtd/spi-nor/spi-nor.c > @@ -1103,7 +1103,7 @@ static const struct flash_info spi_nor_ids[] = { > { "n25q064", INFO(0x20ba17, 0, 64 * 1024, 128, SECT_4K | > SPI_NOR_QUAD_READ) }, > { "n25q064a",INFO(0x20bb17, 0, 64 * 1024, 128, SECT_4K | > SPI_NOR_QUAD_READ) }, > { "n25q128a11", INFO(0x20bb18, 0, 64 * 1024, 256, SECT_4K | > SPI_NOR_QUAD_READ) }, > - { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, SECT_4K | > SPI_NOR_QUAD_READ | SPI_NOR_DUAL_READ) }, > + { "n25q128a13", INFO(0x20ba18, 0, 64 * 1024, 256, SECT_4K | > SPI_NOR_QUAD_READ | SPI_NOR_DUAL_READ | SPI_NOR_SKIP_SFDP) }, > { "n25q256a",INFO(0x20ba19, 0, 64 * 1024, 512, SECT_4K | > SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) }, > { "n25q256ax1", INFO(0x20bb19, 0, 64 * 1024, 512, SECT_4K | > SPI_NOR_QUAD_READ) }, > { "n25q512a",INFO(0x20bb20, 0, 64 * 1024, 1024, SECT_4K | USE_FSR | > SPI_NOR_QUAD_READ) }, >
Re: [PATCH 1/3] mtd: spi-nor: add Global Block Unlock support
Hi Tudor, Le 17/07/2018 à 18:28, Tudor Ambarus a écrit : > We can't determine this purely by manufacturer type and it's not > autodetectable by anything like SFDP, so make a new flag for it: > UNLOCK_GLOBAL_BLOCK. > > Note that the Global Block Unlock command has different names > depending on the manufacturer, but always the same command value: > 0x98. Macronix's MX25U12835F names it Gang Block Unlock, > Winbound's W25Q128FV names it Global Block Unlock and > Microchip's SST26VF064B names it Global Block Protection Unlock. > > Based on initial work done by Anurag Kumar Vulisha: > https://patchwork.kernel.org/patch/7611271/ > > Signed-off-by: Tudor Ambarus Reviewed-by: Cyrille Pitchen Best regards, Cyrille > --- > drivers/mtd/spi-nor/spi-nor.c | 21 + > include/linux/mtd/spi-nor.h | 1 + > 2 files changed, 22 insertions(+) > > diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c > index d9c368c..6648251 100644 > --- a/drivers/mtd/spi-nor/spi-nor.c > +++ b/drivers/mtd/spi-nor/spi-nor.c > @@ -89,6 +89,7 @@ struct flash_info { > #define NO_CHIP_ERASEBIT(12) /* Chip does not support chip > erase */ > #define SPI_NOR_SKIP_SFDPBIT(13) /* Skip parsing of SFDP tables */ > #define USE_CLSR BIT(14) /* use CLSR command */ > +#define UNLOCK_GLOBAL_BLOCK BIT(15) /* Unlock global block protection */ > > int (*quad_enable)(struct spi_nor *nor); > }; > @@ -2730,6 +2731,17 @@ static int spi_nor_setup(struct spi_nor *nor, const > struct flash_info *info, > return 0; > } > > +static int spi_nor_unlock_global_block_protection(struct spi_nor *nor) > +{ > + int ret; > + > + write_enable(nor); > + ret = nor->write_reg(nor, SPINOR_OP_GBULK, NULL, 0); > + if (ret < 0) > + return ret; > + return spi_nor_wait_till_ready(nor); > +} > + > static int spi_nor_init(struct spi_nor *nor) > { > int err; > @@ -2747,6 +2759,15 @@ static int spi_nor_init(struct spi_nor *nor) > spi_nor_wait_till_ready(nor); > } > > + if (nor->info->flags & UNLOCK_GLOBAL_BLOCK) { > + err = spi_nor_unlock_global_block_protection(nor); > + if (err) { > + dev_err(nor->dev, > + "Cannot unlock the global block protection\n"); > + return err; > + } > + } > + > if (nor->quad_enable) { > err = nor->quad_enable(nor); > if (err) { > diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h > index e60da0d..e8dd11d 100644 > --- a/include/linux/mtd/spi-nor.h > +++ b/include/linux/mtd/spi-nor.h > @@ -64,6 +64,7 @@ > #define SPINOR_OP_CLFSR 0x50/* Clear flag status register */ > #define SPINOR_OP_RDEAR 0xc8/* Read Extended Address > Register */ > #define SPINOR_OP_WREAR 0xc5/* Write Extended Address > Register */ > +#define SPINOR_OP_GBULK 0x98/* Global Block Unlock > Protection */ > > /* 4-byte address opcodes - used on Spansion and some Macronix flashes. */ > #define SPINOR_OP_READ_4B0x13/* Read data bytes (low frequency) */ >
Re: [PATCH 1/3] mtd: spi-nor: add Global Block Unlock support
Hi Tudor, Le 17/07/2018 à 18:28, Tudor Ambarus a écrit : > We can't determine this purely by manufacturer type and it's not > autodetectable by anything like SFDP, so make a new flag for it: > UNLOCK_GLOBAL_BLOCK. > > Note that the Global Block Unlock command has different names > depending on the manufacturer, but always the same command value: > 0x98. Macronix's MX25U12835F names it Gang Block Unlock, > Winbound's W25Q128FV names it Global Block Unlock and > Microchip's SST26VF064B names it Global Block Protection Unlock. > > Based on initial work done by Anurag Kumar Vulisha: > https://patchwork.kernel.org/patch/7611271/ > > Signed-off-by: Tudor Ambarus Reviewed-by: Cyrille Pitchen Best regards, Cyrille > --- > drivers/mtd/spi-nor/spi-nor.c | 21 + > include/linux/mtd/spi-nor.h | 1 + > 2 files changed, 22 insertions(+) > > diff --git a/drivers/mtd/spi-nor/spi-nor.c b/drivers/mtd/spi-nor/spi-nor.c > index d9c368c..6648251 100644 > --- a/drivers/mtd/spi-nor/spi-nor.c > +++ b/drivers/mtd/spi-nor/spi-nor.c > @@ -89,6 +89,7 @@ struct flash_info { > #define NO_CHIP_ERASEBIT(12) /* Chip does not support chip > erase */ > #define SPI_NOR_SKIP_SFDPBIT(13) /* Skip parsing of SFDP tables */ > #define USE_CLSR BIT(14) /* use CLSR command */ > +#define UNLOCK_GLOBAL_BLOCK BIT(15) /* Unlock global block protection */ > > int (*quad_enable)(struct spi_nor *nor); > }; > @@ -2730,6 +2731,17 @@ static int spi_nor_setup(struct spi_nor *nor, const > struct flash_info *info, > return 0; > } > > +static int spi_nor_unlock_global_block_protection(struct spi_nor *nor) > +{ > + int ret; > + > + write_enable(nor); > + ret = nor->write_reg(nor, SPINOR_OP_GBULK, NULL, 0); > + if (ret < 0) > + return ret; > + return spi_nor_wait_till_ready(nor); > +} > + > static int spi_nor_init(struct spi_nor *nor) > { > int err; > @@ -2747,6 +2759,15 @@ static int spi_nor_init(struct spi_nor *nor) > spi_nor_wait_till_ready(nor); > } > > + if (nor->info->flags & UNLOCK_GLOBAL_BLOCK) { > + err = spi_nor_unlock_global_block_protection(nor); > + if (err) { > + dev_err(nor->dev, > + "Cannot unlock the global block protection\n"); > + return err; > + } > + } > + > if (nor->quad_enable) { > err = nor->quad_enable(nor); > if (err) { > diff --git a/include/linux/mtd/spi-nor.h b/include/linux/mtd/spi-nor.h > index e60da0d..e8dd11d 100644 > --- a/include/linux/mtd/spi-nor.h > +++ b/include/linux/mtd/spi-nor.h > @@ -64,6 +64,7 @@ > #define SPINOR_OP_CLFSR 0x50/* Clear flag status register */ > #define SPINOR_OP_RDEAR 0xc8/* Read Extended Address > Register */ > #define SPINOR_OP_WREAR 0xc5/* Write Extended Address > Register */ > +#define SPINOR_OP_GBULK 0x98/* Global Block Unlock > Protection */ > > /* 4-byte address opcodes - used on Spansion and some Macronix flashes. */ > #define SPINOR_OP_READ_4B0x13/* Read data bytes (low frequency) */ >
Re: [PATCH] add support to non-uniform SFDP SPI NOR flash memories
Hi Tudor, Le 08/06/2018 à 15:48, Tudor Ambarus a écrit : > The commit message became wall-of-text, my feeling is that I heavily > reworked the code so I changed the author. If someone thinks differently, > please say and I'll change back to the initial authorship. What I've done: It's obvious that you're the author of the patch so I'm totally fine with this change :) Best regards, Cyrille > > - minimize the amount of erase() calls by using the best sequence of erase > type commands depending on alignment. > > - build the list of best fitted erase commands to be executed once we > validate that the erase can be performed. > > - add improvements on how the erase map is handled. The regions are > consecutive in the address space, walk through the regions incrementally. > > - speed up finding the best erase type command. Order erase types by > size, iterate them from the biggest to the smallest and stop when best > fitted command is found. > > - determine at init if there are erase types that can erase the entire > memory > > - fix the erase size in overlaid regions. S25FS512S states that 'if a sector > erase command is applied to a 256KB range that is overlaid by 4KB secors, > the overlaid 4kB sectors are not affected by the erase' > > Backward compatibility test done on MX25L25673G. > > Changes since RFC PATCH: > - build a list of erase commands to be executed once we validate > that the erase can be performed > - fix walking through the address space in overlaid regions > - drop wall-of-text description commit message, change author > > > Tudor Ambarus (1): > mtd: spi-nor: add support to non-uniform SFDP SPI NOR flash memories > > drivers/mtd/spi-nor/spi-nor.c | 357 > -- > include/linux/mtd/spi-nor.h | 108 + > 2 files changed, 451 insertions(+), 14 deletions(-) >
Re: [PATCH] add support to non-uniform SFDP SPI NOR flash memories
Hi Tudor, Le 08/06/2018 à 15:48, Tudor Ambarus a écrit : > The commit message became wall-of-text, my feeling is that I heavily > reworked the code so I changed the author. If someone thinks differently, > please say and I'll change back to the initial authorship. What I've done: It's obvious that you're the author of the patch so I'm totally fine with this change :) Best regards, Cyrille > > - minimize the amount of erase() calls by using the best sequence of erase > type commands depending on alignment. > > - build the list of best fitted erase commands to be executed once we > validate that the erase can be performed. > > - add improvements on how the erase map is handled. The regions are > consecutive in the address space, walk through the regions incrementally. > > - speed up finding the best erase type command. Order erase types by > size, iterate them from the biggest to the smallest and stop when best > fitted command is found. > > - determine at init if there are erase types that can erase the entire > memory > > - fix the erase size in overlaid regions. S25FS512S states that 'if a sector > erase command is applied to a 256KB range that is overlaid by 4KB secors, > the overlaid 4kB sectors are not affected by the erase' > > Backward compatibility test done on MX25L25673G. > > Changes since RFC PATCH: > - build a list of erase commands to be executed once we validate > that the erase can be performed > - fix walking through the address space in overlaid regions > - drop wall-of-text description commit message, change author > > > Tudor Ambarus (1): > mtd: spi-nor: add support to non-uniform SFDP SPI NOR flash memories > > drivers/mtd/spi-nor/spi-nor.c | 357 > -- > include/linux/mtd/spi-nor.h | 108 + > 2 files changed, 451 insertions(+), 14 deletions(-) >
Re: [PATCH] MAINTAINERS: update maintainers for MTD and SPI NOR subsystems
Hi Marek, Le 18/03/2018 à 00:41, Marek Vasut a écrit : > On 03/15/2018 08:04 PM, Cyrille Pitchen wrote: >> remove myself as MTD and SPI NOR maintainer. >> >> Signed-off-by: Cyrille Pitchen <cyrille.pitc...@wedev4u.fr> > > What happened ? > Nothing to worry. Since I was hired for a new job, I've been facing issues to do spi-nor reviews in a reasonable delay. I have to admit that I took more and more time before replying to people and I suspect it won't go better soon. So I've talked about it with Boris hence he suggested that I remove my name from MAINTAINERS to avoid confusion so people are not surprised or frustrated that I don't review their series on time. I really don't know yet whether I could go back again later to help reviewing mtd/spi-nor patches but for now I just have to admit that about mtd topcis, I'm off-line almost all the time :( Sorry guys and thanks for your concern, Marek! :) Best regards, Cyrille >> --- >> MAINTAINERS | 2 -- >> 1 file changed, 2 deletions(-) >> >> diff --git a/MAINTAINERS b/MAINTAINERS >> index 3bdc260e36b7..7892db9a9494 100644 >> --- a/MAINTAINERS >> +++ b/MAINTAINERS >> @@ -9037,7 +9037,6 @@ M: Brian Norris <computersforpe...@gmail.com> >> M: Boris Brezillon <boris.brezil...@free-electrons.com> >> M: Marek Vasut <marek.va...@gmail.com> >> M: Richard Weinberger <rich...@nod.at> >> -M: Cyrille Pitchen <cyrille.pitc...@wedev4u.fr> >> L: linux-...@lists.infradead.org >> W: http://www.linux-mtd.infradead.org/ >> Q: http://patchwork.ozlabs.org/project/linux-mtd/list/ >> @@ -13006,7 +13005,6 @@ F: arch/arm/boot/dts/spear* >> F: arch/arm/mach-spear/ >> >> SPI NOR SUBSYSTEM >> -M: Cyrille Pitchen <cyrille.pitc...@wedev4u.fr> >> M: Marek Vasut <marek.va...@gmail.com> >> L: linux-...@lists.infradead.org >> W: http://www.linux-mtd.infradead.org/ >> > >
Re: [PATCH] MAINTAINERS: update maintainers for MTD and SPI NOR subsystems
Hi Marek, Le 18/03/2018 à 00:41, Marek Vasut a écrit : > On 03/15/2018 08:04 PM, Cyrille Pitchen wrote: >> remove myself as MTD and SPI NOR maintainer. >> >> Signed-off-by: Cyrille Pitchen > > What happened ? > Nothing to worry. Since I was hired for a new job, I've been facing issues to do spi-nor reviews in a reasonable delay. I have to admit that I took more and more time before replying to people and I suspect it won't go better soon. So I've talked about it with Boris hence he suggested that I remove my name from MAINTAINERS to avoid confusion so people are not surprised or frustrated that I don't review their series on time. I really don't know yet whether I could go back again later to help reviewing mtd/spi-nor patches but for now I just have to admit that about mtd topcis, I'm off-line almost all the time :( Sorry guys and thanks for your concern, Marek! :) Best regards, Cyrille >> --- >> MAINTAINERS | 2 -- >> 1 file changed, 2 deletions(-) >> >> diff --git a/MAINTAINERS b/MAINTAINERS >> index 3bdc260e36b7..7892db9a9494 100644 >> --- a/MAINTAINERS >> +++ b/MAINTAINERS >> @@ -9037,7 +9037,6 @@ M: Brian Norris >> M: Boris Brezillon >> M: Marek Vasut >> M: Richard Weinberger >> -M: Cyrille Pitchen >> L: linux-...@lists.infradead.org >> W: http://www.linux-mtd.infradead.org/ >> Q: http://patchwork.ozlabs.org/project/linux-mtd/list/ >> @@ -13006,7 +13005,6 @@ F: arch/arm/boot/dts/spear* >> F: arch/arm/mach-spear/ >> >> SPI NOR SUBSYSTEM >> -M: Cyrille Pitchen >> M: Marek Vasut >> L: linux-...@lists.infradead.org >> W: http://www.linux-mtd.infradead.org/ >> > >
[PATCH] MAINTAINERS: update maintainers for MTD and SPI NOR subsystems
remove myself as MTD and SPI NOR maintainer. Signed-off-by: Cyrille Pitchen <cyrille.pitc...@wedev4u.fr> --- MAINTAINERS | 2 -- 1 file changed, 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 3bdc260e36b7..7892db9a9494 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9037,7 +9037,6 @@ M:Brian Norris <computersforpe...@gmail.com> M: Boris Brezillon <boris.brezil...@free-electrons.com> M: Marek Vasut <marek.va...@gmail.com> M: Richard Weinberger <rich...@nod.at> -M: Cyrille Pitchen <cyrille.pitc...@wedev4u.fr> L: linux-...@lists.infradead.org W: http://www.linux-mtd.infradead.org/ Q: http://patchwork.ozlabs.org/project/linux-mtd/list/ @@ -13006,7 +13005,6 @@ F: arch/arm/boot/dts/spear* F: arch/arm/mach-spear/ SPI NOR SUBSYSTEM -M: Cyrille Pitchen <cyrille.pitc...@wedev4u.fr> M: Marek Vasut <marek.va...@gmail.com> L: linux-...@lists.infradead.org W: http://www.linux-mtd.infradead.org/ -- 2.14.1
[PATCH] MAINTAINERS: update maintainers for MTD and SPI NOR subsystems
remove myself as MTD and SPI NOR maintainer. Signed-off-by: Cyrille Pitchen --- MAINTAINERS | 2 -- 1 file changed, 2 deletions(-) diff --git a/MAINTAINERS b/MAINTAINERS index 3bdc260e36b7..7892db9a9494 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -9037,7 +9037,6 @@ M:Brian Norris M: Boris Brezillon M: Marek Vasut M: Richard Weinberger -M: Cyrille Pitchen L: linux-...@lists.infradead.org W: http://www.linux-mtd.infradead.org/ Q: http://patchwork.ozlabs.org/project/linux-mtd/list/ @@ -13006,7 +13005,6 @@ F: arch/arm/boot/dts/spear* F: arch/arm/mach-spear/ SPI NOR SUBSYSTEM -M: Cyrille Pitchen M: Marek Vasut L: linux-...@lists.infradead.org W: http://www.linux-mtd.infradead.org/ -- 2.14.1
[PATCH v6 00/11] PCI: Add support to the Cadence PCIe controller
Hi all, this series of patches adds support to the Cadence PCIe controller. It was tested on a ARM64 platform emulated by a Palladium running the pci-next kernel. The host mode was tested with some PCIe devices connected to the Palladium through a speed-bridge. Some of those devices were a USB host controller and a SATA controller. The PCIe host controller was also tested with a second controller configured in endpoint mode and connected back to back to the first controller. The EndPoint Controller (EPC) driver was tested with 2 PCI functions, both handled by the pci-epf-test driver, using the pcitest userspace program. I used the "-D" optional command line parameter to select the proper PCI function. For linux-pci/master, I applied this series on top of Kishon's patch ("PCI: endpoint: Use EPC's device in dma_alloc_coherent/dma_free_coherent") otherwise dma_alloc_coherent() fails when called by pci_epf_alloc_space(). Best regards, Cyrille ChangeLog v5 -> v6: - rebase on linux-pci/master (v4.15-rc4) + Kishon's patch from linux-pci/next: "PCI: endpoint: Use EPC's device in dma_alloc_coherent()/dma_free_coherent()" - all patches unchanged v4 -> v5: - rebase on today's (20180128) linux-pci/next - add again the endpoint driver - Patch 7: move host driver from drivers/pci/cadence into drivers/pci/host and remove all references to the endpoint mode, as requested by Lorenzo. The host driver will be moved back into drivers/pci/cadence by Patch 11 - Patch 8: fix comparison of func_no to BAR5: compare to epc->max_functions - Patch 9: add new patch to fix support of PCI multi-function devices - Patch 10: change the 'cdns,max-outbound-regions' from optional to mandatory as requested by Kishon. - Patch 11: take Kishon's comments into account as much as I could. - Other patches: unchanged v3 -> v4: - split patch 3 from v3 into patches 3 and 4. - remove unused cdns_pcie_reset_outbound_region() from old patch 6 (new patch 7). - other patches are unchanged. v2 -> v3: - rebase on today's linux-pci/next (20180110) patch1: - rework the commit message of patch 1 and add two new comments on why endpoint library users must be linked after the endpoint library itself and why the dwc rule uses obj-y instead of obj-$(CONFIG_PCIE_CONFIG_DW). - update patch 1 to add missing ifdef CONFIG_PCI / endif in drivers/pci/dwc/Makefile around the obj-$(CONFIG_ARM64) += pcie-hisi.o rule, like for the other obj-$(CONFIG_ARM64) rules in drivers/pci/host/Makefile. patch2: unchanged patch3: - update patch 3 so the bridge hooks/members initialization is left to the host bridges probe routines. patch4: unchanged patch5: - collect 'Reviewed-by' tag from Rob Herring for the DT bindings. patch6: - remove explanation in the commit message on why obj-$(CONFIG_PCIE_CANDENCE) is placed after obj-$(CONFIG_PCI_ENDPOINT) in drivers/pci/Makefile since a comment on it has been added into patch1. - remove menuconfig PCI_CADENCE in drivers/pci/cadence/Kconfig to match drivers/pci/dwc/Kconfig. - adapt patch6 to the changes done in patch3 for the pci_host_probe() function. v1 -> v2: - add new properties in the device-tree bindings: 'cdns,max-outbound-regions' and 'cdns,no-bar-match-nbits'. - add a new patch to regroup all makefile rules in drivers/pci/Makefile, hence cleaning drivers/Makefile up. - change the license text to use the recommanded format: // SPDX-License-Identifier: GPL-2.0 - add a new patch updating the API of the EPC library to add support to multi-function devices. - add a 2 new patches to share more common code between host controller drivers - remove some useless tests - add more comments in both drivers. - fix DT bindings examples - remove useless init of the primary, secondary and sub-ordinate bus numbers in the PCI configuration space of the root port. - remove cdns_pcie_ep_stop() function and rework cdns_pcie_ep_start() function Cyrille Pitchen (10): PCI: Regroup all PCI related entries into drivers/pci/Makefile PCI: OF: Add generic function to parse and allocate PCI resources PCI: generic: fix missing call of pci_free_resource_list() PCI: Add generic function to probe PCI host controllers PCI: Add vendor ID for Cadence PCI: cadence: Add host driver for Cadence PCIe controller PCI: endpoint: Add the function number as argument to EPC ops PCI: endpoint: Fix EPF device name to support multi-function devices dt-bindings: PCI: cadence: Add DT bindings for Cadence PCIe endpoint controller PCI: cadence: Add EndPoint Controller driver for Cadence PCIe controller Scott Telford (1): dt-bindings: PCI: cadence: Add DT bindings for Cadence PCIe host controller .../devicetree/bindings/pci/cdns,cdns-pcie-ep.txt | 22 + .../bindings/pci/cdns,cdns-pcie-host.txt | 60 +++ MAINTAINERS| 7 + drivers/Makefile | 5 +- drivers/
[PATCH v6 00/11] PCI: Add support to the Cadence PCIe controller
Hi all, this series of patches adds support to the Cadence PCIe controller. It was tested on a ARM64 platform emulated by a Palladium running the pci-next kernel. The host mode was tested with some PCIe devices connected to the Palladium through a speed-bridge. Some of those devices were a USB host controller and a SATA controller. The PCIe host controller was also tested with a second controller configured in endpoint mode and connected back to back to the first controller. The EndPoint Controller (EPC) driver was tested with 2 PCI functions, both handled by the pci-epf-test driver, using the pcitest userspace program. I used the "-D" optional command line parameter to select the proper PCI function. For linux-pci/master, I applied this series on top of Kishon's patch ("PCI: endpoint: Use EPC's device in dma_alloc_coherent/dma_free_coherent") otherwise dma_alloc_coherent() fails when called by pci_epf_alloc_space(). Best regards, Cyrille ChangeLog v5 -> v6: - rebase on linux-pci/master (v4.15-rc4) + Kishon's patch from linux-pci/next: "PCI: endpoint: Use EPC's device in dma_alloc_coherent()/dma_free_coherent()" - all patches unchanged v4 -> v5: - rebase on today's (20180128) linux-pci/next - add again the endpoint driver - Patch 7: move host driver from drivers/pci/cadence into drivers/pci/host and remove all references to the endpoint mode, as requested by Lorenzo. The host driver will be moved back into drivers/pci/cadence by Patch 11 - Patch 8: fix comparison of func_no to BAR5: compare to epc->max_functions - Patch 9: add new patch to fix support of PCI multi-function devices - Patch 10: change the 'cdns,max-outbound-regions' from optional to mandatory as requested by Kishon. - Patch 11: take Kishon's comments into account as much as I could. - Other patches: unchanged v3 -> v4: - split patch 3 from v3 into patches 3 and 4. - remove unused cdns_pcie_reset_outbound_region() from old patch 6 (new patch 7). - other patches are unchanged. v2 -> v3: - rebase on today's linux-pci/next (20180110) patch1: - rework the commit message of patch 1 and add two new comments on why endpoint library users must be linked after the endpoint library itself and why the dwc rule uses obj-y instead of obj-$(CONFIG_PCIE_CONFIG_DW). - update patch 1 to add missing ifdef CONFIG_PCI / endif in drivers/pci/dwc/Makefile around the obj-$(CONFIG_ARM64) += pcie-hisi.o rule, like for the other obj-$(CONFIG_ARM64) rules in drivers/pci/host/Makefile. patch2: unchanged patch3: - update patch 3 so the bridge hooks/members initialization is left to the host bridges probe routines. patch4: unchanged patch5: - collect 'Reviewed-by' tag from Rob Herring for the DT bindings. patch6: - remove explanation in the commit message on why obj-$(CONFIG_PCIE_CANDENCE) is placed after obj-$(CONFIG_PCI_ENDPOINT) in drivers/pci/Makefile since a comment on it has been added into patch1. - remove menuconfig PCI_CADENCE in drivers/pci/cadence/Kconfig to match drivers/pci/dwc/Kconfig. - adapt patch6 to the changes done in patch3 for the pci_host_probe() function. v1 -> v2: - add new properties in the device-tree bindings: 'cdns,max-outbound-regions' and 'cdns,no-bar-match-nbits'. - add a new patch to regroup all makefile rules in drivers/pci/Makefile, hence cleaning drivers/Makefile up. - change the license text to use the recommanded format: // SPDX-License-Identifier: GPL-2.0 - add a new patch updating the API of the EPC library to add support to multi-function devices. - add a 2 new patches to share more common code between host controller drivers - remove some useless tests - add more comments in both drivers. - fix DT bindings examples - remove useless init of the primary, secondary and sub-ordinate bus numbers in the PCI configuration space of the root port. - remove cdns_pcie_ep_stop() function and rework cdns_pcie_ep_start() function Cyrille Pitchen (10): PCI: Regroup all PCI related entries into drivers/pci/Makefile PCI: OF: Add generic function to parse and allocate PCI resources PCI: generic: fix missing call of pci_free_resource_list() PCI: Add generic function to probe PCI host controllers PCI: Add vendor ID for Cadence PCI: cadence: Add host driver for Cadence PCIe controller PCI: endpoint: Add the function number as argument to EPC ops PCI: endpoint: Fix EPF device name to support multi-function devices dt-bindings: PCI: cadence: Add DT bindings for Cadence PCIe endpoint controller PCI: cadence: Add EndPoint Controller driver for Cadence PCIe controller Scott Telford (1): dt-bindings: PCI: cadence: Add DT bindings for Cadence PCIe host controller .../devicetree/bindings/pci/cdns,cdns-pcie-ep.txt | 22 + .../bindings/pci/cdns,cdns-pcie-host.txt | 60 +++ MAINTAINERS| 7 + drivers/Makefile | 5 +- drivers/
[PATCH v6 08/11] PCI: endpoint: Add the function number as argument to EPC ops
This patch updates the prototype of most handlers from 'struct pci_epc_ops' so the EPC library can now support multi-function devices. Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> --- drivers/pci/dwc/pcie-designware-ep.c | 20 + drivers/pci/endpoint/functions/pci-epf-test.c | 41 ++ drivers/pci/endpoint/pci-epc-core.c | 62 --- include/linux/pci-epc.h | 43 +++ 4 files changed, 96 insertions(+), 70 deletions(-) diff --git a/drivers/pci/dwc/pcie-designware-ep.c b/drivers/pci/dwc/pcie-designware-ep.c index d53d5f168363..7a573d8bb62d 100644 --- a/drivers/pci/dwc/pcie-designware-ep.c +++ b/drivers/pci/dwc/pcie-designware-ep.c @@ -39,7 +39,7 @@ static void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar) dw_pcie_writel_dbi(pci, reg, 0x0); } -static int dw_pcie_ep_write_header(struct pci_epc *epc, +static int dw_pcie_ep_write_header(struct pci_epc *epc, u8 func_no, struct pci_epf_header *hdr) { struct dw_pcie_ep *ep = epc_get_drvdata(epc); @@ -112,7 +112,8 @@ static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, phys_addr_t phys_addr, return 0; } -static void dw_pcie_ep_clear_bar(struct pci_epc *epc, enum pci_barno bar) +static void dw_pcie_ep_clear_bar(struct pci_epc *epc, u8 func_no, +enum pci_barno bar) { struct dw_pcie_ep *ep = epc_get_drvdata(epc); struct dw_pcie *pci = to_dw_pcie_from_ep(ep); @@ -124,7 +125,8 @@ static void dw_pcie_ep_clear_bar(struct pci_epc *epc, enum pci_barno bar) clear_bit(atu_index, >ib_window_map); } -static int dw_pcie_ep_set_bar(struct pci_epc *epc, enum pci_barno bar, +static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no, + enum pci_barno bar, dma_addr_t bar_phys, size_t size, int flags) { int ret; @@ -163,7 +165,8 @@ static int dw_pcie_find_index(struct dw_pcie_ep *ep, phys_addr_t addr, return -EINVAL; } -static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, phys_addr_t addr) +static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, u8 func_no, + phys_addr_t addr) { int ret; u32 atu_index; @@ -178,7 +181,8 @@ static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, phys_addr_t addr) clear_bit(atu_index, >ob_window_map); } -static int dw_pcie_ep_map_addr(struct pci_epc *epc, phys_addr_t addr, +static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 func_no, + phys_addr_t addr, u64 pci_addr, size_t size) { int ret; @@ -194,7 +198,7 @@ static int dw_pcie_ep_map_addr(struct pci_epc *epc, phys_addr_t addr, return 0; } -static int dw_pcie_ep_get_msi(struct pci_epc *epc) +static int dw_pcie_ep_get_msi(struct pci_epc *epc, u8 func_no) { int val; u32 lower_addr; @@ -214,7 +218,7 @@ static int dw_pcie_ep_get_msi(struct pci_epc *epc) return val; } -static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 encode_int) +static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 encode_int) { int val; struct dw_pcie_ep *ep = epc_get_drvdata(epc); @@ -226,7 +230,7 @@ static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 encode_int) return 0; } -static int dw_pcie_ep_raise_irq(struct pci_epc *epc, +static int dw_pcie_ep_raise_irq(struct pci_epc *epc, u8 func_no, enum pci_epc_irq_type type, u8 interrupt_num) { struct dw_pcie_ep *ep = epc_get_drvdata(epc); diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c index f9308c2f22e6..7bacca8daec6 100644 --- a/drivers/pci/endpoint/functions/pci-epf-test.c +++ b/drivers/pci/endpoint/functions/pci-epf-test.c @@ -104,7 +104,8 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test) goto err; } - ret = pci_epc_map_addr(epc, src_phys_addr, reg->src_addr, reg->size); + ret = pci_epc_map_addr(epc, epf->func_no, src_phys_addr, reg->src_addr, + reg->size); if (ret) { dev_err(dev, "failed to map source address\n"); reg->status = STATUS_SRC_ADDR_INVALID; @@ -119,7 +120,8 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test) goto err_src_map_addr; } - ret = pci_epc_map_addr(epc, dst_phys_addr, reg->dst_addr, reg->size); + ret = pci_epc_map_addr(epc, epf->func_no, dst_phys_addr, reg->dst_addr, + reg->size); if (ret) { dev_err(dev, "failed to map destination address\n"); reg->status = STATUS_DST_ADDR_INVALID; @@ -128,13 +1
[PATCH v6 08/11] PCI: endpoint: Add the function number as argument to EPC ops
This patch updates the prototype of most handlers from 'struct pci_epc_ops' so the EPC library can now support multi-function devices. Signed-off-by: Cyrille Pitchen --- drivers/pci/dwc/pcie-designware-ep.c | 20 + drivers/pci/endpoint/functions/pci-epf-test.c | 41 ++ drivers/pci/endpoint/pci-epc-core.c | 62 --- include/linux/pci-epc.h | 43 +++ 4 files changed, 96 insertions(+), 70 deletions(-) diff --git a/drivers/pci/dwc/pcie-designware-ep.c b/drivers/pci/dwc/pcie-designware-ep.c index d53d5f168363..7a573d8bb62d 100644 --- a/drivers/pci/dwc/pcie-designware-ep.c +++ b/drivers/pci/dwc/pcie-designware-ep.c @@ -39,7 +39,7 @@ static void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar) dw_pcie_writel_dbi(pci, reg, 0x0); } -static int dw_pcie_ep_write_header(struct pci_epc *epc, +static int dw_pcie_ep_write_header(struct pci_epc *epc, u8 func_no, struct pci_epf_header *hdr) { struct dw_pcie_ep *ep = epc_get_drvdata(epc); @@ -112,7 +112,8 @@ static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, phys_addr_t phys_addr, return 0; } -static void dw_pcie_ep_clear_bar(struct pci_epc *epc, enum pci_barno bar) +static void dw_pcie_ep_clear_bar(struct pci_epc *epc, u8 func_no, +enum pci_barno bar) { struct dw_pcie_ep *ep = epc_get_drvdata(epc); struct dw_pcie *pci = to_dw_pcie_from_ep(ep); @@ -124,7 +125,8 @@ static void dw_pcie_ep_clear_bar(struct pci_epc *epc, enum pci_barno bar) clear_bit(atu_index, >ib_window_map); } -static int dw_pcie_ep_set_bar(struct pci_epc *epc, enum pci_barno bar, +static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no, + enum pci_barno bar, dma_addr_t bar_phys, size_t size, int flags) { int ret; @@ -163,7 +165,8 @@ static int dw_pcie_find_index(struct dw_pcie_ep *ep, phys_addr_t addr, return -EINVAL; } -static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, phys_addr_t addr) +static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, u8 func_no, + phys_addr_t addr) { int ret; u32 atu_index; @@ -178,7 +181,8 @@ static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, phys_addr_t addr) clear_bit(atu_index, >ob_window_map); } -static int dw_pcie_ep_map_addr(struct pci_epc *epc, phys_addr_t addr, +static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 func_no, + phys_addr_t addr, u64 pci_addr, size_t size) { int ret; @@ -194,7 +198,7 @@ static int dw_pcie_ep_map_addr(struct pci_epc *epc, phys_addr_t addr, return 0; } -static int dw_pcie_ep_get_msi(struct pci_epc *epc) +static int dw_pcie_ep_get_msi(struct pci_epc *epc, u8 func_no) { int val; u32 lower_addr; @@ -214,7 +218,7 @@ static int dw_pcie_ep_get_msi(struct pci_epc *epc) return val; } -static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 encode_int) +static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 encode_int) { int val; struct dw_pcie_ep *ep = epc_get_drvdata(epc); @@ -226,7 +230,7 @@ static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 encode_int) return 0; } -static int dw_pcie_ep_raise_irq(struct pci_epc *epc, +static int dw_pcie_ep_raise_irq(struct pci_epc *epc, u8 func_no, enum pci_epc_irq_type type, u8 interrupt_num) { struct dw_pcie_ep *ep = epc_get_drvdata(epc); diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c index f9308c2f22e6..7bacca8daec6 100644 --- a/drivers/pci/endpoint/functions/pci-epf-test.c +++ b/drivers/pci/endpoint/functions/pci-epf-test.c @@ -104,7 +104,8 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test) goto err; } - ret = pci_epc_map_addr(epc, src_phys_addr, reg->src_addr, reg->size); + ret = pci_epc_map_addr(epc, epf->func_no, src_phys_addr, reg->src_addr, + reg->size); if (ret) { dev_err(dev, "failed to map source address\n"); reg->status = STATUS_SRC_ADDR_INVALID; @@ -119,7 +120,8 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test) goto err_src_map_addr; } - ret = pci_epc_map_addr(epc, dst_phys_addr, reg->dst_addr, reg->size); + ret = pci_epc_map_addr(epc, epf->func_no, dst_phys_addr, reg->dst_addr, + reg->size); if (ret) { dev_err(dev, "failed to map destination address\n"); reg->status = STATUS_DST_ADDR_INVALID; @@ -128,13 +130,13 @@ static int pci_epf_test_copy(struc
Re: [PATCH v5 00/11] PCI: Add support to the Cadence PCIe controller
Hi Lorenzo, Bjorn, Le 30/01/2018 à 12:41, Lorenzo Pieralisi a écrit : > On Sun, Jan 28, 2018 at 03:47:41PM -0600, Bjorn Helgaas wrote: >> On Sun, Jan 28, 2018 at 09:40:14PM +0100, Cyrille Pitchen wrote: >>> Hi all, >>> >>> this series of patches adds support to the Cadence PCIe controller. >>> It was tested on a ARM64 platform emulated by a Palladium running the >>> pci-next kernel. >>> >>> The host mode was tested with some PCIe devices connected to the Palladium >>> through a speed-bridge. Some of those devices were a USB host controller >>> and a SATA controller. The PCIe host controller was also tested with a >>> second controller configured in endpoint mode and connected back to back >>> to the first controller. >>> >>> The EndPoint Controller (EPC) driver was tested with 2 PCI functions, both >>> handled by the pci-epf-test driver, using the pcitest userspace program. >>> I used the "-D" optional command line parameter to select the proper PCI >>> function. >>> >>> Best regards, >>> >>> Cyrille >>> >>> ChangeLog >>> >>> v4 -> v5: >>> - rebase on today's (20180128) linux-pci/next >> >> Don't bother rebasing onto linux-pci/next. >> >> If your patches actually *depend* on something that has already been >> merged onto a PCI topic branch, you should mention that and say which >> branch. > > Yes - Cyrille please advise which branch(es) this series depends on, > it does not apply cleanly to -rc4. > > Merge window is open and I do not know what we can do with this series > for v4.16 but please let me know. > I've just sent v6. No change from v5 except that the series has been rebased onto linux-pci/master (v4.15-rc4) and tested on the Palladium. I've cherry-picked one Kishon's patch from linux-pci/next to test the endpoint mode. Best regards, Cyrille > Thanks, > Lorenzo > -- Cyrille Pitchen, Free Electrons Embedded Linux and Kernel engineering http://free-electrons.com
Re: [PATCH v5 00/11] PCI: Add support to the Cadence PCIe controller
Hi Lorenzo, Bjorn, Le 30/01/2018 à 12:41, Lorenzo Pieralisi a écrit : > On Sun, Jan 28, 2018 at 03:47:41PM -0600, Bjorn Helgaas wrote: >> On Sun, Jan 28, 2018 at 09:40:14PM +0100, Cyrille Pitchen wrote: >>> Hi all, >>> >>> this series of patches adds support to the Cadence PCIe controller. >>> It was tested on a ARM64 platform emulated by a Palladium running the >>> pci-next kernel. >>> >>> The host mode was tested with some PCIe devices connected to the Palladium >>> through a speed-bridge. Some of those devices were a USB host controller >>> and a SATA controller. The PCIe host controller was also tested with a >>> second controller configured in endpoint mode and connected back to back >>> to the first controller. >>> >>> The EndPoint Controller (EPC) driver was tested with 2 PCI functions, both >>> handled by the pci-epf-test driver, using the pcitest userspace program. >>> I used the "-D" optional command line parameter to select the proper PCI >>> function. >>> >>> Best regards, >>> >>> Cyrille >>> >>> ChangeLog >>> >>> v4 -> v5: >>> - rebase on today's (20180128) linux-pci/next >> >> Don't bother rebasing onto linux-pci/next. >> >> If your patches actually *depend* on something that has already been >> merged onto a PCI topic branch, you should mention that and say which >> branch. > > Yes - Cyrille please advise which branch(es) this series depends on, > it does not apply cleanly to -rc4. > > Merge window is open and I do not know what we can do with this series > for v4.16 but please let me know. > I've just sent v6. No change from v5 except that the series has been rebased onto linux-pci/master (v4.15-rc4) and tested on the Palladium. I've cherry-picked one Kishon's patch from linux-pci/next to test the endpoint mode. Best regards, Cyrille > Thanks, > Lorenzo > -- Cyrille Pitchen, Free Electrons Embedded Linux and Kernel engineering http://free-electrons.com
[PATCH v6 11/11] PCI: cadence: Add EndPoint Controller driver for Cadence PCIe controller
This patch adds support to the Cadence PCIe controller in endpoint mode. Since pieces of source code are shared with the host driver (Root Complex mode), we create a new directory under drivers/pci dedicated to the Cadence PCIe controller. The common code is placed into drivers/pci/cadence/pcie-cadence.c and used by both the host and endpoint controller drivers. Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> --- MAINTAINERS | 2 +- drivers/pci/Kconfig | 1 + drivers/pci/Makefile | 1 + drivers/pci/cadence/Kconfig | 27 ++ drivers/pci/cadence/Makefile | 4 + drivers/pci/cadence/pcie-cadence-ep.c | 542 ++ drivers/pci/{host => cadence}/pcie-cadence-host.c | 65 +-- drivers/pci/cadence/pcie-cadence.c| 126 + drivers/pci/{host => cadence}/pcie-cadence.h | 122 + drivers/pci/host/Kconfig | 10 - drivers/pci/host/Makefile | 1 - 11 files changed, 826 insertions(+), 75 deletions(-) create mode 100644 drivers/pci/cadence/Kconfig create mode 100644 drivers/pci/cadence/Makefile create mode 100644 drivers/pci/cadence/pcie-cadence-ep.c rename drivers/pci/{host => cadence}/pcie-cadence-host.c (80%) create mode 100644 drivers/pci/cadence/pcie-cadence.c rename drivers/pci/{host => cadence}/pcie-cadence.h (63%) diff --git a/MAINTAINERS b/MAINTAINERS index 460d5580f87e..ce08e9bd0273 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10407,7 +10407,7 @@ M: Alan Douglas <adoug...@cadence.com> L: linux-...@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/pci/cdns,*.txt -F: drivers/pci/host/pcie-cadence* +F: drivers/pci/cadence/pcie-cadence* PCI DRIVER FOR FREESCALE LAYERSCAPE M: Minghuan Lian <minghuan.l...@freescale.com> diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 7eeb969ab86a..dee90cc1dcaf 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -136,6 +136,7 @@ config PCI_HYPERV PCI devices from a PCI backend to support PCI driver domains. source "drivers/pci/hotplug/Kconfig" +source "drivers/pci/cadence/Kconfig" source "drivers/pci/dwc/Kconfig" source "drivers/pci/host/Kconfig" source "drivers/pci/endpoint/Kconfig" diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index ddb5aa6640d7..941970936840 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -56,5 +56,6 @@ obj-y += switch/ obj-$(CONFIG_PCI_ENDPOINT) += endpoint/ # Endpoint library must be initialized before its users +obj-$(CONFIG_PCIE_CADENCE) += cadence/ # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW obj-y += dwc/ diff --git a/drivers/pci/cadence/Kconfig b/drivers/pci/cadence/Kconfig new file mode 100644 index ..e6824cb56c16 --- /dev/null +++ b/drivers/pci/cadence/Kconfig @@ -0,0 +1,27 @@ +menu "Cadence PCIe controllers support" + +config PCIE_CADENCE + bool + +config PCIE_CADENCE_HOST + bool "Cadence PCIe host controller" + depends on OF + depends on PCI + select IRQ_DOMAIN + select PCIE_CADENCE + help + Say Y here if you want to support the Cadence PCIe controller in host + mode. This PCIe controller may be embedded into many different vendors + SoCs. + +config PCIE_CADENCE_EP + bool "Cadence PCIe endpoint controller" + depends on OF + depends on PCI_ENDPOINT + select PCIE_CADENCE + help + Say Y here if you want to support the Cadence PCIe controller in + endpoint mode. This PCIe controller may be embedded into many + different vendors SoCs. + +endmenu diff --git a/drivers/pci/cadence/Makefile b/drivers/pci/cadence/Makefile new file mode 100644 index ..719392b97998 --- /dev/null +++ b/drivers/pci/cadence/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_PCIE_CADENCE) += pcie-cadence.o +obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host.o +obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep.o diff --git a/drivers/pci/cadence/pcie-cadence-ep.c b/drivers/pci/cadence/pcie-cadence-ep.c new file mode 100644 index ..3c3a97743453 --- /dev/null +++ b/drivers/pci/cadence/pcie-cadence-ep.c @@ -0,0 +1,542 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2017 Cadence +// Cadence PCIe endpoint controller driver. +// Author: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> + +#include +#include +#include +#include +#include +#include +#include + +#include "pcie-cadence.h" + +#define CDNS_PCIE_EP_MIN_APERTURE 128 /* 128 bytes */ +#define CDNS_PCIE_EP_IRQ_PCI_ADDR_NONE 0x1 +#define CDN
[PATCH v6 11/11] PCI: cadence: Add EndPoint Controller driver for Cadence PCIe controller
This patch adds support to the Cadence PCIe controller in endpoint mode. Since pieces of source code are shared with the host driver (Root Complex mode), we create a new directory under drivers/pci dedicated to the Cadence PCIe controller. The common code is placed into drivers/pci/cadence/pcie-cadence.c and used by both the host and endpoint controller drivers. Signed-off-by: Cyrille Pitchen --- MAINTAINERS | 2 +- drivers/pci/Kconfig | 1 + drivers/pci/Makefile | 1 + drivers/pci/cadence/Kconfig | 27 ++ drivers/pci/cadence/Makefile | 4 + drivers/pci/cadence/pcie-cadence-ep.c | 542 ++ drivers/pci/{host => cadence}/pcie-cadence-host.c | 65 +-- drivers/pci/cadence/pcie-cadence.c| 126 + drivers/pci/{host => cadence}/pcie-cadence.h | 122 + drivers/pci/host/Kconfig | 10 - drivers/pci/host/Makefile | 1 - 11 files changed, 826 insertions(+), 75 deletions(-) create mode 100644 drivers/pci/cadence/Kconfig create mode 100644 drivers/pci/cadence/Makefile create mode 100644 drivers/pci/cadence/pcie-cadence-ep.c rename drivers/pci/{host => cadence}/pcie-cadence-host.c (80%) create mode 100644 drivers/pci/cadence/pcie-cadence.c rename drivers/pci/{host => cadence}/pcie-cadence.h (63%) diff --git a/MAINTAINERS b/MAINTAINERS index 460d5580f87e..ce08e9bd0273 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10407,7 +10407,7 @@ M: Alan Douglas L: linux-...@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/pci/cdns,*.txt -F: drivers/pci/host/pcie-cadence* +F: drivers/pci/cadence/pcie-cadence* PCI DRIVER FOR FREESCALE LAYERSCAPE M: Minghuan Lian diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 7eeb969ab86a..dee90cc1dcaf 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -136,6 +136,7 @@ config PCI_HYPERV PCI devices from a PCI backend to support PCI driver domains. source "drivers/pci/hotplug/Kconfig" +source "drivers/pci/cadence/Kconfig" source "drivers/pci/dwc/Kconfig" source "drivers/pci/host/Kconfig" source "drivers/pci/endpoint/Kconfig" diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index ddb5aa6640d7..941970936840 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -56,5 +56,6 @@ obj-y += switch/ obj-$(CONFIG_PCI_ENDPOINT) += endpoint/ # Endpoint library must be initialized before its users +obj-$(CONFIG_PCIE_CADENCE) += cadence/ # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW obj-y += dwc/ diff --git a/drivers/pci/cadence/Kconfig b/drivers/pci/cadence/Kconfig new file mode 100644 index ..e6824cb56c16 --- /dev/null +++ b/drivers/pci/cadence/Kconfig @@ -0,0 +1,27 @@ +menu "Cadence PCIe controllers support" + +config PCIE_CADENCE + bool + +config PCIE_CADENCE_HOST + bool "Cadence PCIe host controller" + depends on OF + depends on PCI + select IRQ_DOMAIN + select PCIE_CADENCE + help + Say Y here if you want to support the Cadence PCIe controller in host + mode. This PCIe controller may be embedded into many different vendors + SoCs. + +config PCIE_CADENCE_EP + bool "Cadence PCIe endpoint controller" + depends on OF + depends on PCI_ENDPOINT + select PCIE_CADENCE + help + Say Y here if you want to support the Cadence PCIe controller in + endpoint mode. This PCIe controller may be embedded into many + different vendors SoCs. + +endmenu diff --git a/drivers/pci/cadence/Makefile b/drivers/pci/cadence/Makefile new file mode 100644 index ..719392b97998 --- /dev/null +++ b/drivers/pci/cadence/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_PCIE_CADENCE) += pcie-cadence.o +obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host.o +obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep.o diff --git a/drivers/pci/cadence/pcie-cadence-ep.c b/drivers/pci/cadence/pcie-cadence-ep.c new file mode 100644 index ..3c3a97743453 --- /dev/null +++ b/drivers/pci/cadence/pcie-cadence-ep.c @@ -0,0 +1,542 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2017 Cadence +// Cadence PCIe endpoint controller driver. +// Author: Cyrille Pitchen + +#include +#include +#include +#include +#include +#include +#include + +#include "pcie-cadence.h" + +#define CDNS_PCIE_EP_MIN_APERTURE 128 /* 128 bytes */ +#define CDNS_PCIE_EP_IRQ_PCI_ADDR_NONE 0x1 +#define CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY 0x3 + +/** + * struct cdns_pcie_ep - private data for this PCIe endpoint controller driver + * @pcie: Cadenc
[PATCH v6 02/11] PCI: OF: Add generic function to parse and allocate PCI resources
The patch moves the gen_pci_parse_request_of_pci_ranges() function from drivers/pci/host/pci-host-common.c into drivers/pci/of.c to easily share common source code between PCI host drivers. Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> --- drivers/pci/host/pci-host-common.c | 49 ++-- drivers/pci/of.c | 51 ++ include/linux/pci.h| 9 +++ 3 files changed, 62 insertions(+), 47 deletions(-) diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c index 44a47d4f0b8f..efd904d93562 100644 --- a/drivers/pci/host/pci-host-common.c +++ b/drivers/pci/host/pci-host-common.c @@ -24,50 +24,6 @@ #include #include -static int gen_pci_parse_request_of_pci_ranges(struct device *dev, - struct list_head *resources, struct resource **bus_range) -{ - int err, res_valid = 0; - struct device_node *np = dev->of_node; - resource_size_t iobase; - struct resource_entry *win, *tmp; - - err = of_pci_get_host_bridge_resources(np, 0, 0xff, resources, ); - if (err) - return err; - - err = devm_request_pci_bus_resources(dev, resources); - if (err) - return err; - - resource_list_for_each_entry_safe(win, tmp, resources) { - struct resource *res = win->res; - - switch (resource_type(res)) { - case IORESOURCE_IO: - err = pci_remap_iospace(res, iobase); - if (err) { - dev_warn(dev, "error %d: failed to map resource %pR\n", -err, res); - resource_list_destroy_entry(win); - } - break; - case IORESOURCE_MEM: - res_valid |= !(res->flags & IORESOURCE_PREFETCH); - break; - case IORESOURCE_BUS: - *bus_range = res; - break; - } - } - - if (res_valid) - return 0; - - dev_err(dev, "non-prefetchable memory resource required\n"); - return -EINVAL; -} - static void gen_pci_unmap_cfg(void *ptr) { pci_ecam_free((struct pci_config_window *)ptr); @@ -82,9 +38,9 @@ static struct pci_config_window *gen_pci_init(struct device *dev, struct pci_config_window *cfg; /* Parse our PCI ranges and request their resources */ - err = gen_pci_parse_request_of_pci_ranges(dev, resources, _range); + err = pci_parse_request_of_pci_ranges(dev, resources, _range); if (err) - goto err_out; + return ERR_PTR(err); err = of_address_to_resource(dev->of_node, 0, ); if (err) { @@ -135,7 +91,6 @@ int pci_host_common_probe(struct platform_device *pdev, of_pci_check_probe_only(); /* Parse and map our Configuration Space windows */ - INIT_LIST_HEAD(); cfg = gen_pci_init(dev, , ops); if (IS_ERR(cfg)) return PTR_ERR(cfg); diff --git a/drivers/pci/of.c b/drivers/pci/of.c index e112da11630e..54e210501b73 100644 --- a/drivers/pci/of.c +++ b/drivers/pci/of.c @@ -88,3 +88,54 @@ struct irq_domain *pci_host_bridge_of_msi_domain(struct pci_bus *bus) return NULL; #endif } + +int pci_parse_request_of_pci_ranges(struct device *dev, + struct list_head *resources, + struct resource **bus_range) +{ + int err, res_valid = 0; + struct device_node *np = dev->of_node; + resource_size_t iobase; + struct resource_entry *win, *tmp; + + INIT_LIST_HEAD(resources); + err = of_pci_get_host_bridge_resources(np, 0, 0xff, resources, ); + if (err) + return err; + + err = devm_request_pci_bus_resources(dev, resources); + if (err) + goto out_release_res; + + resource_list_for_each_entry_safe(win, tmp, resources) { + struct resource *res = win->res; + + switch (resource_type(res)) { + case IORESOURCE_IO: + err = pci_remap_iospace(res, iobase); + if (err) { + dev_warn(dev, "error %d: failed to map resource %pR\n", +err, res); + resource_list_destroy_entry(win); + } + break; + case IORESOURCE_MEM: + res_valid |= !(res->flags & IORESOURCE_PREFETCH); + break; + case IORESOURCE_BUS: + if (bus_range) + *bus_range = res; +
[PATCH v6 02/11] PCI: OF: Add generic function to parse and allocate PCI resources
The patch moves the gen_pci_parse_request_of_pci_ranges() function from drivers/pci/host/pci-host-common.c into drivers/pci/of.c to easily share common source code between PCI host drivers. Signed-off-by: Cyrille Pitchen --- drivers/pci/host/pci-host-common.c | 49 ++-- drivers/pci/of.c | 51 ++ include/linux/pci.h| 9 +++ 3 files changed, 62 insertions(+), 47 deletions(-) diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c index 44a47d4f0b8f..efd904d93562 100644 --- a/drivers/pci/host/pci-host-common.c +++ b/drivers/pci/host/pci-host-common.c @@ -24,50 +24,6 @@ #include #include -static int gen_pci_parse_request_of_pci_ranges(struct device *dev, - struct list_head *resources, struct resource **bus_range) -{ - int err, res_valid = 0; - struct device_node *np = dev->of_node; - resource_size_t iobase; - struct resource_entry *win, *tmp; - - err = of_pci_get_host_bridge_resources(np, 0, 0xff, resources, ); - if (err) - return err; - - err = devm_request_pci_bus_resources(dev, resources); - if (err) - return err; - - resource_list_for_each_entry_safe(win, tmp, resources) { - struct resource *res = win->res; - - switch (resource_type(res)) { - case IORESOURCE_IO: - err = pci_remap_iospace(res, iobase); - if (err) { - dev_warn(dev, "error %d: failed to map resource %pR\n", -err, res); - resource_list_destroy_entry(win); - } - break; - case IORESOURCE_MEM: - res_valid |= !(res->flags & IORESOURCE_PREFETCH); - break; - case IORESOURCE_BUS: - *bus_range = res; - break; - } - } - - if (res_valid) - return 0; - - dev_err(dev, "non-prefetchable memory resource required\n"); - return -EINVAL; -} - static void gen_pci_unmap_cfg(void *ptr) { pci_ecam_free((struct pci_config_window *)ptr); @@ -82,9 +38,9 @@ static struct pci_config_window *gen_pci_init(struct device *dev, struct pci_config_window *cfg; /* Parse our PCI ranges and request their resources */ - err = gen_pci_parse_request_of_pci_ranges(dev, resources, _range); + err = pci_parse_request_of_pci_ranges(dev, resources, _range); if (err) - goto err_out; + return ERR_PTR(err); err = of_address_to_resource(dev->of_node, 0, ); if (err) { @@ -135,7 +91,6 @@ int pci_host_common_probe(struct platform_device *pdev, of_pci_check_probe_only(); /* Parse and map our Configuration Space windows */ - INIT_LIST_HEAD(); cfg = gen_pci_init(dev, , ops); if (IS_ERR(cfg)) return PTR_ERR(cfg); diff --git a/drivers/pci/of.c b/drivers/pci/of.c index e112da11630e..54e210501b73 100644 --- a/drivers/pci/of.c +++ b/drivers/pci/of.c @@ -88,3 +88,54 @@ struct irq_domain *pci_host_bridge_of_msi_domain(struct pci_bus *bus) return NULL; #endif } + +int pci_parse_request_of_pci_ranges(struct device *dev, + struct list_head *resources, + struct resource **bus_range) +{ + int err, res_valid = 0; + struct device_node *np = dev->of_node; + resource_size_t iobase; + struct resource_entry *win, *tmp; + + INIT_LIST_HEAD(resources); + err = of_pci_get_host_bridge_resources(np, 0, 0xff, resources, ); + if (err) + return err; + + err = devm_request_pci_bus_resources(dev, resources); + if (err) + goto out_release_res; + + resource_list_for_each_entry_safe(win, tmp, resources) { + struct resource *res = win->res; + + switch (resource_type(res)) { + case IORESOURCE_IO: + err = pci_remap_iospace(res, iobase); + if (err) { + dev_warn(dev, "error %d: failed to map resource %pR\n", +err, res); + resource_list_destroy_entry(win); + } + break; + case IORESOURCE_MEM: + res_valid |= !(res->flags & IORESOURCE_PREFETCH); + break; + case IORESOURCE_BUS: + if (bus_range) + *bus_range = res; + break; + } + } + +
[PATCH v6 01/11] PCI: Regroup all PCI related entries into drivers/pci/Makefile
Clean up drivers/Makefile by moving the pci/endpoint and pci/dwc entries from drivers/Makefile into drivers/pci/Makefile. Since we don't want to introduce any dependency between CONFIG_PCI and CONFIG_PCI_ENDPOINT, we now always execute drivers/pci/Makefile. Hence all Makefiles in drivers/pci/ were updated accordingly so no file is compiled when CONFIG_PCI is not defined. Also, we add a comment to reinforce that EPC and EPF libraries must be initialized before their users. Hence built-in EPC drivers, such as those of Designware, are linked after the endpoint core libraries. Finally, we add another comment to explain why obj-y has been chosen instead of obj-$(CONFIG_PCIE_DW) to parse the dwc/ sub-folder. Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> --- drivers/Makefile | 5 + drivers/pci/Kconfig | 1 + drivers/pci/Makefile | 13 ++--- drivers/pci/dwc/Makefile | 2 ++ drivers/pci/host/Makefile | 2 ++ 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/Makefile b/drivers/Makefile index e06f7f633f73..8189b1edec00 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -16,10 +16,7 @@ obj-$(CONFIG_PINCTRL)+= pinctrl/ obj-$(CONFIG_GPIOLIB) += gpio/ obj-y += pwm/ -obj-$(CONFIG_PCI) += pci/ -obj-$(CONFIG_PCI_ENDPOINT) += pci/endpoint/ -# PCI dwc controller drivers -obj-y += pci/dwc/ +obj-y += pci/ obj-$(CONFIG_PARISC) += parisc/ obj-$(CONFIG_RAPIDIO) += rapidio/ diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index bda151788f3f..7eeb969ab86a 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -125,6 +125,7 @@ config PCI_PASID config PCI_LABEL def_bool y if (DMI || ACPI) + depends on PCI select NLS config PCI_HYPERV diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index c7819b973df7..ddb5aa6640d7 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -3,12 +3,15 @@ # Makefile for the PCI bus specific drivers. # -obj-y += access.o bus.o probe.o host-bridge.o remove.o pci.o \ +obj-$(CONFIG_PCI) += access.o bus.o probe.o host-bridge.o remove.o pci.o \ pci-driver.o search.o pci-sysfs.o rom.o setup-res.o \ irq.o vpd.o setup-bus.o vc.o mmap.o setup-irq.o +ifdef CONFIG_PCI obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_SYSFS) += slot.o +obj-$(CONFIG_OF) += of.o +endif obj-$(CONFIG_PCI_QUIRKS) += quirks.o @@ -44,10 +47,14 @@ obj-$(CONFIG_PCI_ECAM) += ecam.o obj-$(CONFIG_XEN_PCIDEV_FRONTEND) += xen-pcifront.o -obj-$(CONFIG_OF) += of.o - ccflags-$(CONFIG_PCI_DEBUG) := -DDEBUG # PCI host controller drivers obj-y += host/ obj-y += switch/ + +obj-$(CONFIG_PCI_ENDPOINT) += endpoint/ + +# Endpoint library must be initialized before its users +# pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW +obj-y += dwc/ diff --git a/drivers/pci/dwc/Makefile b/drivers/pci/dwc/Makefile index 41ba499c96ee..cb35e45cd186 100644 --- a/drivers/pci/dwc/Makefile +++ b/drivers/pci/dwc/Makefile @@ -27,4 +27,6 @@ obj-$(CONFIG_PCIE_HISI_STB) += pcie-histb.o # ARM64 and use internal ifdefs to only build the pieces we need # depending on whether ACPI, the DT driver, or both are enabled. +ifdef CONFIG_PCI obj-$(CONFIG_ARM64) += pcie-hisi.o +endif diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile index 34ec1d88f961..3b1059190867 100644 --- a/drivers/pci/host/Makefile +++ b/drivers/pci/host/Makefile @@ -34,6 +34,8 @@ obj-$(CONFIG_VMD) += vmd.o # ARM64 and use internal ifdefs to only build the pieces we need # depending on whether ACPI, the DT driver, or both are enabled. +ifdef CONFIG_PCI obj-$(CONFIG_ARM64) += pci-thunder-ecam.o obj-$(CONFIG_ARM64) += pci-thunder-pem.o obj-$(CONFIG_ARM64) += pci-xgene.o +endif -- 2.11.0
[PATCH v6 01/11] PCI: Regroup all PCI related entries into drivers/pci/Makefile
Clean up drivers/Makefile by moving the pci/endpoint and pci/dwc entries from drivers/Makefile into drivers/pci/Makefile. Since we don't want to introduce any dependency between CONFIG_PCI and CONFIG_PCI_ENDPOINT, we now always execute drivers/pci/Makefile. Hence all Makefiles in drivers/pci/ were updated accordingly so no file is compiled when CONFIG_PCI is not defined. Also, we add a comment to reinforce that EPC and EPF libraries must be initialized before their users. Hence built-in EPC drivers, such as those of Designware, are linked after the endpoint core libraries. Finally, we add another comment to explain why obj-y has been chosen instead of obj-$(CONFIG_PCIE_DW) to parse the dwc/ sub-folder. Signed-off-by: Cyrille Pitchen --- drivers/Makefile | 5 + drivers/pci/Kconfig | 1 + drivers/pci/Makefile | 13 ++--- drivers/pci/dwc/Makefile | 2 ++ drivers/pci/host/Makefile | 2 ++ 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/Makefile b/drivers/Makefile index e06f7f633f73..8189b1edec00 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -16,10 +16,7 @@ obj-$(CONFIG_PINCTRL)+= pinctrl/ obj-$(CONFIG_GPIOLIB) += gpio/ obj-y += pwm/ -obj-$(CONFIG_PCI) += pci/ -obj-$(CONFIG_PCI_ENDPOINT) += pci/endpoint/ -# PCI dwc controller drivers -obj-y += pci/dwc/ +obj-y += pci/ obj-$(CONFIG_PARISC) += parisc/ obj-$(CONFIG_RAPIDIO) += rapidio/ diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index bda151788f3f..7eeb969ab86a 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -125,6 +125,7 @@ config PCI_PASID config PCI_LABEL def_bool y if (DMI || ACPI) + depends on PCI select NLS config PCI_HYPERV diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index c7819b973df7..ddb5aa6640d7 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -3,12 +3,15 @@ # Makefile for the PCI bus specific drivers. # -obj-y += access.o bus.o probe.o host-bridge.o remove.o pci.o \ +obj-$(CONFIG_PCI) += access.o bus.o probe.o host-bridge.o remove.o pci.o \ pci-driver.o search.o pci-sysfs.o rom.o setup-res.o \ irq.o vpd.o setup-bus.o vc.o mmap.o setup-irq.o +ifdef CONFIG_PCI obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_SYSFS) += slot.o +obj-$(CONFIG_OF) += of.o +endif obj-$(CONFIG_PCI_QUIRKS) += quirks.o @@ -44,10 +47,14 @@ obj-$(CONFIG_PCI_ECAM) += ecam.o obj-$(CONFIG_XEN_PCIDEV_FRONTEND) += xen-pcifront.o -obj-$(CONFIG_OF) += of.o - ccflags-$(CONFIG_PCI_DEBUG) := -DDEBUG # PCI host controller drivers obj-y += host/ obj-y += switch/ + +obj-$(CONFIG_PCI_ENDPOINT) += endpoint/ + +# Endpoint library must be initialized before its users +# pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW +obj-y += dwc/ diff --git a/drivers/pci/dwc/Makefile b/drivers/pci/dwc/Makefile index 41ba499c96ee..cb35e45cd186 100644 --- a/drivers/pci/dwc/Makefile +++ b/drivers/pci/dwc/Makefile @@ -27,4 +27,6 @@ obj-$(CONFIG_PCIE_HISI_STB) += pcie-histb.o # ARM64 and use internal ifdefs to only build the pieces we need # depending on whether ACPI, the DT driver, or both are enabled. +ifdef CONFIG_PCI obj-$(CONFIG_ARM64) += pcie-hisi.o +endif diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile index 34ec1d88f961..3b1059190867 100644 --- a/drivers/pci/host/Makefile +++ b/drivers/pci/host/Makefile @@ -34,6 +34,8 @@ obj-$(CONFIG_VMD) += vmd.o # ARM64 and use internal ifdefs to only build the pieces we need # depending on whether ACPI, the DT driver, or both are enabled. +ifdef CONFIG_PCI obj-$(CONFIG_ARM64) += pci-thunder-ecam.o obj-$(CONFIG_ARM64) += pci-thunder-pem.o obj-$(CONFIG_ARM64) += pci-xgene.o +endif -- 2.11.0
[PATCH v6 03/11] PCI: generic: fix missing call of pci_free_resource_list()
Call pci_free_resource_list() from pci_host_common_probe() when probing fails, as done inside gen_pci_init() when this later function fails. Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> --- drivers/pci/host/pci-host-common.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c index efd904d93562..10e3f5b39499 100644 --- a/drivers/pci/host/pci-host-common.c +++ b/drivers/pci/host/pci-host-common.c @@ -110,6 +110,7 @@ int pci_host_common_probe(struct platform_device *pdev, ret = pci_scan_root_bus_bridge(bridge); if (ret < 0) { dev_err(dev, "Scanning root bridge failed"); + pci_free_resource_list(); return ret; } -- 2.11.0
[PATCH v6 03/11] PCI: generic: fix missing call of pci_free_resource_list()
Call pci_free_resource_list() from pci_host_common_probe() when probing fails, as done inside gen_pci_init() when this later function fails. Signed-off-by: Cyrille Pitchen --- drivers/pci/host/pci-host-common.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c index efd904d93562..10e3f5b39499 100644 --- a/drivers/pci/host/pci-host-common.c +++ b/drivers/pci/host/pci-host-common.c @@ -110,6 +110,7 @@ int pci_host_common_probe(struct platform_device *pdev, ret = pci_scan_root_bus_bridge(bridge); if (ret < 0) { dev_err(dev, "Scanning root bridge failed"); + pci_free_resource_list(); return ret; } -- 2.11.0
[PATCH v6 04/11] PCI: Add generic function to probe PCI host controllers
This patchs moves generic source code from drivers/pci/host/pci-host-common.c into drivers/pci/probe.c. Indeed the extracted lines of code were duplicated by many host controller drivers. Regrouping them into a generic function gives a change to properly share this code without introducing a useless dependency to PCI_HOST_COMMON, which selects PCI_ECAM when not needed by most host controller drivers. Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> --- drivers/pci/host/pci-host-common.c | 22 +- drivers/pci/probe.c| 33 + include/linux/pci.h| 1 + 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c index 10e3f5b39499..160b3c1cb5a0 100644 --- a/drivers/pci/host/pci-host-common.c +++ b/drivers/pci/host/pci-host-common.c @@ -72,7 +72,6 @@ int pci_host_common_probe(struct platform_device *pdev, const char *type; struct device *dev = >dev; struct device_node *np = dev->of_node; - struct pci_bus *bus, *child; struct pci_host_bridge *bridge; struct pci_config_window *cfg; struct list_head resources; @@ -107,30 +106,11 @@ int pci_host_common_probe(struct platform_device *pdev, bridge->map_irq = of_irq_parse_and_map_pci; bridge->swizzle_irq = pci_common_swizzle; - ret = pci_scan_root_bus_bridge(bridge); + ret = pci_host_probe(bridge); if (ret < 0) { - dev_err(dev, "Scanning root bridge failed"); pci_free_resource_list(); return ret; } - bus = bridge->bus; - - /* -* We insert PCI resources into the iomem_resource and -* ioport_resource trees in either pci_bus_claim_resources() -* or pci_bus_assign_resources(). -*/ - if (pci_has_flag(PCI_PROBE_ONLY)) { - pci_bus_claim_resources(bus); - } else { - pci_bus_size_bridges(bus); - pci_bus_assign_resources(bus); - - list_for_each_entry(child, >children, node) - pcie_bus_configure_settings(child); - } - - pci_bus_add_devices(bus); return 0; } diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 14e0ea1ff38b..a42bbfc5f2ec 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -2620,6 +2620,39 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, } EXPORT_SYMBOL_GPL(pci_create_root_bus); +int pci_host_probe(struct pci_host_bridge *bridge) +{ + struct pci_bus *bus, *child; + int ret; + + ret = pci_scan_root_bus_bridge(bridge); + if (ret < 0) { + dev_err(bridge->dev.parent, "Scanning root bridge failed"); + return ret; + } + + bus = bridge->bus; + + /* +* We insert PCI resources into the iomem_resource and +* ioport_resource trees in either pci_bus_claim_resources() +* or pci_bus_assign_resources(). +*/ + if (pci_has_flag(PCI_PROBE_ONLY)) { + pci_bus_claim_resources(bus); + } else { + pci_bus_size_bridges(bus); + pci_bus_assign_resources(bus); + + list_for_each_entry(child, >children, node) + pcie_bus_configure_settings(child); + } + + pci_bus_add_devices(bus); + return 0; +} +EXPORT_SYMBOL_GPL(pci_host_probe); + int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int bus_max) { struct resource *res = >busn_res; diff --git a/include/linux/pci.h b/include/linux/pci.h index c7a701abbf17..db6700137bd2 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -887,6 +887,7 @@ struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata); struct pci_bus *pci_create_root_bus(struct device *parent, int bus, struct pci_ops *ops, void *sysdata, struct list_head *resources); +int pci_host_probe(struct pci_host_bridge *bridge); int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int busmax); int pci_bus_update_busn_res_end(struct pci_bus *b, int busmax); void pci_bus_release_busn_res(struct pci_bus *b); -- 2.11.0
[PATCH v6 04/11] PCI: Add generic function to probe PCI host controllers
This patchs moves generic source code from drivers/pci/host/pci-host-common.c into drivers/pci/probe.c. Indeed the extracted lines of code were duplicated by many host controller drivers. Regrouping them into a generic function gives a change to properly share this code without introducing a useless dependency to PCI_HOST_COMMON, which selects PCI_ECAM when not needed by most host controller drivers. Signed-off-by: Cyrille Pitchen --- drivers/pci/host/pci-host-common.c | 22 +- drivers/pci/probe.c| 33 + include/linux/pci.h| 1 + 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c index 10e3f5b39499..160b3c1cb5a0 100644 --- a/drivers/pci/host/pci-host-common.c +++ b/drivers/pci/host/pci-host-common.c @@ -72,7 +72,6 @@ int pci_host_common_probe(struct platform_device *pdev, const char *type; struct device *dev = >dev; struct device_node *np = dev->of_node; - struct pci_bus *bus, *child; struct pci_host_bridge *bridge; struct pci_config_window *cfg; struct list_head resources; @@ -107,30 +106,11 @@ int pci_host_common_probe(struct platform_device *pdev, bridge->map_irq = of_irq_parse_and_map_pci; bridge->swizzle_irq = pci_common_swizzle; - ret = pci_scan_root_bus_bridge(bridge); + ret = pci_host_probe(bridge); if (ret < 0) { - dev_err(dev, "Scanning root bridge failed"); pci_free_resource_list(); return ret; } - bus = bridge->bus; - - /* -* We insert PCI resources into the iomem_resource and -* ioport_resource trees in either pci_bus_claim_resources() -* or pci_bus_assign_resources(). -*/ - if (pci_has_flag(PCI_PROBE_ONLY)) { - pci_bus_claim_resources(bus); - } else { - pci_bus_size_bridges(bus); - pci_bus_assign_resources(bus); - - list_for_each_entry(child, >children, node) - pcie_bus_configure_settings(child); - } - - pci_bus_add_devices(bus); return 0; } diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 14e0ea1ff38b..a42bbfc5f2ec 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -2620,6 +2620,39 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, } EXPORT_SYMBOL_GPL(pci_create_root_bus); +int pci_host_probe(struct pci_host_bridge *bridge) +{ + struct pci_bus *bus, *child; + int ret; + + ret = pci_scan_root_bus_bridge(bridge); + if (ret < 0) { + dev_err(bridge->dev.parent, "Scanning root bridge failed"); + return ret; + } + + bus = bridge->bus; + + /* +* We insert PCI resources into the iomem_resource and +* ioport_resource trees in either pci_bus_claim_resources() +* or pci_bus_assign_resources(). +*/ + if (pci_has_flag(PCI_PROBE_ONLY)) { + pci_bus_claim_resources(bus); + } else { + pci_bus_size_bridges(bus); + pci_bus_assign_resources(bus); + + list_for_each_entry(child, >children, node) + pcie_bus_configure_settings(child); + } + + pci_bus_add_devices(bus); + return 0; +} +EXPORT_SYMBOL_GPL(pci_host_probe); + int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int bus_max) { struct resource *res = >busn_res; diff --git a/include/linux/pci.h b/include/linux/pci.h index c7a701abbf17..db6700137bd2 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -887,6 +887,7 @@ struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata); struct pci_bus *pci_create_root_bus(struct device *parent, int bus, struct pci_ops *ops, void *sysdata, struct list_head *resources); +int pci_host_probe(struct pci_host_bridge *bridge); int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int busmax); int pci_bus_update_busn_res_end(struct pci_bus *b, int busmax); void pci_bus_release_busn_res(struct pci_bus *b); -- 2.11.0
[PATCH v6 10/11] dt-bindings: PCI: cadence: Add DT bindings for Cadence PCIe endpoint controller
This patch documents the DT bindings for the Cadence PCIe controller when configured in endpoint mode. Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> Reviewed-by: Rob Herring <r...@kernel.org> --- .../devicetree/bindings/pci/cdns,cdns-pcie-ep.txt | 22 ++ 1 file changed, 22 insertions(+) create mode 100644 Documentation/devicetree/bindings/pci/cdns,cdns-pcie-ep.txt diff --git a/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-ep.txt b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-ep.txt new file mode 100644 index ..9a305237fa6e --- /dev/null +++ b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-ep.txt @@ -0,0 +1,22 @@ +* Cadence PCIe endpoint controller + +Required properties: +- compatible: Should contain "cdns,cdns-pcie-ep" to identify the IP used. +- reg: Should contain the controller register base address and AXI interface + region base address respectively. +- reg-names: Must be "reg" and "mem" respectively. +- cdns,max-outbound-regions: Set to maximum number of outbound regions + +Optional properties: +- max-functions: Maximum number of functions that can be configured (default 1). + +Example: + +pcie@fc00 { + compatible = "cdns,cdns-pcie-ep"; + reg = <0x0 0xfc00 0x0 0x0100>, + <0x0 0x8000 0x0 0x4000>; + reg-names = "reg", "mem"; + cdns,max-outbound-regions = <16>; + max-functions = /bits/ 8 <8>; +}; -- 2.11.0
[PATCH v6 10/11] dt-bindings: PCI: cadence: Add DT bindings for Cadence PCIe endpoint controller
This patch documents the DT bindings for the Cadence PCIe controller when configured in endpoint mode. Signed-off-by: Cyrille Pitchen Reviewed-by: Rob Herring --- .../devicetree/bindings/pci/cdns,cdns-pcie-ep.txt | 22 ++ 1 file changed, 22 insertions(+) create mode 100644 Documentation/devicetree/bindings/pci/cdns,cdns-pcie-ep.txt diff --git a/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-ep.txt b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-ep.txt new file mode 100644 index ..9a305237fa6e --- /dev/null +++ b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-ep.txt @@ -0,0 +1,22 @@ +* Cadence PCIe endpoint controller + +Required properties: +- compatible: Should contain "cdns,cdns-pcie-ep" to identify the IP used. +- reg: Should contain the controller register base address and AXI interface + region base address respectively. +- reg-names: Must be "reg" and "mem" respectively. +- cdns,max-outbound-regions: Set to maximum number of outbound regions + +Optional properties: +- max-functions: Maximum number of functions that can be configured (default 1). + +Example: + +pcie@fc00 { + compatible = "cdns,cdns-pcie-ep"; + reg = <0x0 0xfc00 0x0 0x0100>, + <0x0 0x8000 0x0 0x4000>; + reg-names = "reg", "mem"; + cdns,max-outbound-regions = <16>; + max-functions = /bits/ 8 <8>; +}; -- 2.11.0
[PATCH v6 09/11] PCI: endpoint: Fix EPF device name to support multi-function devices
Fix the pci_epf_make() function so it can now bind many EPF devices to the same EPF driver. Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> --- drivers/pci/endpoint/pci-ep-cfs.c | 46 +-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/drivers/pci/endpoint/pci-ep-cfs.c b/drivers/pci/endpoint/pci-ep-cfs.c index 4f74386c1ced..48a89dff0e7f 100644 --- a/drivers/pci/endpoint/pci-ep-cfs.c +++ b/drivers/pci/endpoint/pci-ep-cfs.c @@ -18,18 +18,22 @@ */ #include +#include #include #include #include #include +static DEFINE_IDR(functions_idr); +static DEFINE_MUTEX(functions_mutex); static struct config_group *functions_group; static struct config_group *controllers_group; struct pci_epf_group { struct config_group group; struct pci_epf *epf; + int index; }; struct pci_epc_group { @@ -353,6 +357,9 @@ static void pci_epf_release(struct config_item *item) { struct pci_epf_group *epf_group = to_pci_epf_group(item); + mutex_lock(_mutex); + idr_remove(_idr, epf_group->index); + mutex_unlock(_mutex); pci_epf_destroy(epf_group->epf); kfree(epf_group); } @@ -372,22 +379,57 @@ static struct config_group *pci_epf_make(struct config_group *group, { struct pci_epf_group *epf_group; struct pci_epf *epf; + char *epf_name; + int index, err; epf_group = kzalloc(sizeof(*epf_group), GFP_KERNEL); if (!epf_group) return ERR_PTR(-ENOMEM); + mutex_lock(_mutex); + index = idr_alloc(_idr, epf_group, 0, 0, GFP_KERNEL); + mutex_unlock(_mutex); + if (index < 0) { + err = index; + goto free_group; + } + + epf_group->index = index; + config_group_init_type_name(_group->group, name, _epf_type); - epf = pci_epf_create(group->cg_item.ci_name); + epf_name = kasprintf(GFP_KERNEL, "%s.%d", +group->cg_item.ci_name, epf_group->index); + if (!epf_name) { + err = -ENOMEM; + goto remove_idr; + } + + epf = pci_epf_create(epf_name); if (IS_ERR(epf)) { pr_err("failed to create endpoint function device\n"); - return ERR_PTR(-EINVAL); + err = -EINVAL; + goto free_name; } epf_group->epf = epf; + kfree(epf_name); + return _group->group; + +free_name: + kfree(epf_name); + +remove_idr: + mutex_lock(_mutex); + idr_remove(_idr, epf_group->index); + mutex_unlock(_mutex); + +free_group: + kfree(epf_group); + + return ERR_PTR(err); } static void pci_epf_drop(struct config_group *group, struct config_item *item) -- 2.11.0
[PATCH v6 09/11] PCI: endpoint: Fix EPF device name to support multi-function devices
Fix the pci_epf_make() function so it can now bind many EPF devices to the same EPF driver. Signed-off-by: Cyrille Pitchen --- drivers/pci/endpoint/pci-ep-cfs.c | 46 +-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/drivers/pci/endpoint/pci-ep-cfs.c b/drivers/pci/endpoint/pci-ep-cfs.c index 4f74386c1ced..48a89dff0e7f 100644 --- a/drivers/pci/endpoint/pci-ep-cfs.c +++ b/drivers/pci/endpoint/pci-ep-cfs.c @@ -18,18 +18,22 @@ */ #include +#include #include #include #include #include +static DEFINE_IDR(functions_idr); +static DEFINE_MUTEX(functions_mutex); static struct config_group *functions_group; static struct config_group *controllers_group; struct pci_epf_group { struct config_group group; struct pci_epf *epf; + int index; }; struct pci_epc_group { @@ -353,6 +357,9 @@ static void pci_epf_release(struct config_item *item) { struct pci_epf_group *epf_group = to_pci_epf_group(item); + mutex_lock(_mutex); + idr_remove(_idr, epf_group->index); + mutex_unlock(_mutex); pci_epf_destroy(epf_group->epf); kfree(epf_group); } @@ -372,22 +379,57 @@ static struct config_group *pci_epf_make(struct config_group *group, { struct pci_epf_group *epf_group; struct pci_epf *epf; + char *epf_name; + int index, err; epf_group = kzalloc(sizeof(*epf_group), GFP_KERNEL); if (!epf_group) return ERR_PTR(-ENOMEM); + mutex_lock(_mutex); + index = idr_alloc(_idr, epf_group, 0, 0, GFP_KERNEL); + mutex_unlock(_mutex); + if (index < 0) { + err = index; + goto free_group; + } + + epf_group->index = index; + config_group_init_type_name(_group->group, name, _epf_type); - epf = pci_epf_create(group->cg_item.ci_name); + epf_name = kasprintf(GFP_KERNEL, "%s.%d", +group->cg_item.ci_name, epf_group->index); + if (!epf_name) { + err = -ENOMEM; + goto remove_idr; + } + + epf = pci_epf_create(epf_name); if (IS_ERR(epf)) { pr_err("failed to create endpoint function device\n"); - return ERR_PTR(-EINVAL); + err = -EINVAL; + goto free_name; } epf_group->epf = epf; + kfree(epf_name); + return _group->group; + +free_name: + kfree(epf_name); + +remove_idr: + mutex_lock(_mutex); + idr_remove(_idr, epf_group->index); + mutex_unlock(_mutex); + +free_group: + kfree(epf_group); + + return ERR_PTR(err); } static void pci_epf_drop(struct config_group *group, struct config_item *item) -- 2.11.0
[PATCH v6 07/11] PCI: cadence: Add host driver for Cadence PCIe controller
This patch adds support to the Cadence PCIe controller in host mode. Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> --- MAINTAINERS | 7 + drivers/pci/host/Kconfig | 10 + drivers/pci/host/Makefile| 1 + drivers/pci/host/pcie-cadence-host.c | 397 +++ drivers/pci/host/pcie-cadence.h | 189 + 5 files changed, 604 insertions(+) create mode 100644 drivers/pci/host/pcie-cadence-host.c create mode 100644 drivers/pci/host/pcie-cadence.h diff --git a/MAINTAINERS b/MAINTAINERS index a6e86e20761e..460d5580f87e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10402,6 +10402,13 @@ S: Maintained F: Documentation/devicetree/bindings/pci/pci-armada8k.txt F: drivers/pci/dwc/pcie-armada8k.c +PCI DRIVER FOR CADENCE PCIE IP +M: Alan Douglas <adoug...@cadence.com> +L: linux-...@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/pci/cdns,*.txt +F: drivers/pci/host/pcie-cadence* + PCI DRIVER FOR FREESCALE LAYERSCAPE M: Minghuan Lian <minghuan.l...@freescale.com> M: Mingkai Hu <mingkai...@freescale.com> diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig index 38d12980db0f..d6866733d69d 100644 --- a/drivers/pci/host/Kconfig +++ b/drivers/pci/host/Kconfig @@ -210,6 +210,16 @@ config PCIE_TANGO_SMP8759 This can lead to data corruption if drivers perform concurrent config and MMIO accesses. +config PCIE_CADENCE_HOST + bool "Cadence PCIe host controller" + depends on OF + depends on PCI + select IRQ_DOMAIN + help + Say Y here if you want to support the Cadence PCIe controller in host + mode. This PCIe controller may be embedded into many different vendors + SoCs. + config VMD depends on PCI_MSI && X86_64 && SRCU tristate "Intel Volume Management Device Driver" diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile index 3b1059190867..2460f0785120 100644 --- a/drivers/pci/host/Makefile +++ b/drivers/pci/host/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o obj-$(CONFIG_PCIE_ROCKCHIP) += pcie-rockchip.o obj-$(CONFIG_PCIE_MEDIATEK) += pcie-mediatek.o obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-tango.o +obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host.o obj-$(CONFIG_VMD) += vmd.o # The following drivers are for devices that use the generic ACPI diff --git a/drivers/pci/host/pcie-cadence-host.c b/drivers/pci/host/pcie-cadence-host.c new file mode 100644 index ..9332601845ea --- /dev/null +++ b/drivers/pci/host/pcie-cadence-host.c @@ -0,0 +1,397 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2017 Cadence +// Cadence PCIe host controller driver. +// Author: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> + +#include +#include +#include +#include +#include + +#include "pcie-cadence.h" + +/** + * struct cdns_pcie_rc - private data for this PCIe Root Complex driver + * @pcie: Cadence PCIe controller + * @dev: pointer to PCIe device + * @cfg_res: start/end offsets in the physical system memory to map PCI + * configuration space accesses + * @bus_range: first/last buses behind the PCIe host controller + * @cfg_base: IO mapped window to access the PCI configuration space of a + *single function at a time + * @max_regions: maximum number of regions supported by the hardware + * @no_bar_nbits: Number of bits to keep for inbound (PCIe -> CPU) address + *translation (nbits sets into the "no BAR match" register) + * @vendor_id: PCI vendor ID + * @device_id: PCI device ID + */ +struct cdns_pcie_rc { + struct cdns_pciepcie; + struct device *dev; + struct resource *cfg_res; + struct resource *bus_range; + void __iomem*cfg_base; + u32 max_regions; + u32 no_bar_nbits; + u16 vendor_id; + u16 device_id; +}; + +static void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, + u32 r, bool is_io, + u64 cpu_addr, u64 pci_addr, size_t size) +{ + /* +* roundup_pow_of_two() returns an unsigned long, which is not suited +* for 64bit values. +*/ + u64 sz = 1ULL << fls64(size - 1); + int nbits = ilog2(sz); + u32 addr0, addr1, desc0, desc1; + + if (nbits < 8) + nbits = 8; + + /* Set the PCI address */ + addr0 = CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_NBITS(nbits) | + (lower_32_bits(pci_addr) & GENMASK(31, 8)); + addr1 = upper_32_bits(pci_addr); + + cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR0(r)
[PATCH v6 07/11] PCI: cadence: Add host driver for Cadence PCIe controller
This patch adds support to the Cadence PCIe controller in host mode. Signed-off-by: Cyrille Pitchen --- MAINTAINERS | 7 + drivers/pci/host/Kconfig | 10 + drivers/pci/host/Makefile| 1 + drivers/pci/host/pcie-cadence-host.c | 397 +++ drivers/pci/host/pcie-cadence.h | 189 + 5 files changed, 604 insertions(+) create mode 100644 drivers/pci/host/pcie-cadence-host.c create mode 100644 drivers/pci/host/pcie-cadence.h diff --git a/MAINTAINERS b/MAINTAINERS index a6e86e20761e..460d5580f87e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10402,6 +10402,13 @@ S: Maintained F: Documentation/devicetree/bindings/pci/pci-armada8k.txt F: drivers/pci/dwc/pcie-armada8k.c +PCI DRIVER FOR CADENCE PCIE IP +M: Alan Douglas +L: linux-...@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/pci/cdns,*.txt +F: drivers/pci/host/pcie-cadence* + PCI DRIVER FOR FREESCALE LAYERSCAPE M: Minghuan Lian M: Mingkai Hu diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig index 38d12980db0f..d6866733d69d 100644 --- a/drivers/pci/host/Kconfig +++ b/drivers/pci/host/Kconfig @@ -210,6 +210,16 @@ config PCIE_TANGO_SMP8759 This can lead to data corruption if drivers perform concurrent config and MMIO accesses. +config PCIE_CADENCE_HOST + bool "Cadence PCIe host controller" + depends on OF + depends on PCI + select IRQ_DOMAIN + help + Say Y here if you want to support the Cadence PCIe controller in host + mode. This PCIe controller may be embedded into many different vendors + SoCs. + config VMD depends on PCI_MSI && X86_64 && SRCU tristate "Intel Volume Management Device Driver" diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile index 3b1059190867..2460f0785120 100644 --- a/drivers/pci/host/Makefile +++ b/drivers/pci/host/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o obj-$(CONFIG_PCIE_ROCKCHIP) += pcie-rockchip.o obj-$(CONFIG_PCIE_MEDIATEK) += pcie-mediatek.o obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-tango.o +obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host.o obj-$(CONFIG_VMD) += vmd.o # The following drivers are for devices that use the generic ACPI diff --git a/drivers/pci/host/pcie-cadence-host.c b/drivers/pci/host/pcie-cadence-host.c new file mode 100644 index ..9332601845ea --- /dev/null +++ b/drivers/pci/host/pcie-cadence-host.c @@ -0,0 +1,397 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2017 Cadence +// Cadence PCIe host controller driver. +// Author: Cyrille Pitchen + +#include +#include +#include +#include +#include + +#include "pcie-cadence.h" + +/** + * struct cdns_pcie_rc - private data for this PCIe Root Complex driver + * @pcie: Cadence PCIe controller + * @dev: pointer to PCIe device + * @cfg_res: start/end offsets in the physical system memory to map PCI + * configuration space accesses + * @bus_range: first/last buses behind the PCIe host controller + * @cfg_base: IO mapped window to access the PCI configuration space of a + *single function at a time + * @max_regions: maximum number of regions supported by the hardware + * @no_bar_nbits: Number of bits to keep for inbound (PCIe -> CPU) address + *translation (nbits sets into the "no BAR match" register) + * @vendor_id: PCI vendor ID + * @device_id: PCI device ID + */ +struct cdns_pcie_rc { + struct cdns_pciepcie; + struct device *dev; + struct resource *cfg_res; + struct resource *bus_range; + void __iomem*cfg_base; + u32 max_regions; + u32 no_bar_nbits; + u16 vendor_id; + u16 device_id; +}; + +static void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, + u32 r, bool is_io, + u64 cpu_addr, u64 pci_addr, size_t size) +{ + /* +* roundup_pow_of_two() returns an unsigned long, which is not suited +* for 64bit values. +*/ + u64 sz = 1ULL << fls64(size - 1); + int nbits = ilog2(sz); + u32 addr0, addr1, desc0, desc1; + + if (nbits < 8) + nbits = 8; + + /* Set the PCI address */ + addr0 = CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_NBITS(nbits) | + (lower_32_bits(pci_addr) & GENMASK(31, 8)); + addr1 = upper_32_bits(pci_addr); + + cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR0(r), addr0); + cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR1(r), addr1); + + /* Set the PCIe header descriptor */ + if (is_io) + desc0 =
[PATCH v6 06/11] dt-bindings: PCI: cadence: Add DT bindings for Cadence PCIe host controller
From: Scott Telford <stelf...@cadence.com> This patch adds documentation for the DT bindings of the Cadence PCIe controller when configured in host (Root Complex) mode. Signed-off-by: Scott Telford <stelf...@cadence.com> Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> Reviewed-by: Rob Herring <r...@kernel.org> --- .../bindings/pci/cdns,cdns-pcie-host.txt | 60 ++ 1 file changed, 60 insertions(+) create mode 100644 Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt diff --git a/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt new file mode 100644 index ..20a33f38f69d --- /dev/null +++ b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt @@ -0,0 +1,60 @@ +* Cadence PCIe host controller + +This PCIe controller inherits the base properties defined in +host-generic-pci.txt. + +Required properties: +- compatible: Should contain "cdns,cdns-pcie-host" to identify the IP used. +- reg: Should contain the controller register base address, PCIe configuration + window base address, and AXI interface region base address respectively. +- reg-names: Must be "reg", "cfg" and "mem" respectively. +- #address-cells: Set to <3> +- #size-cells: Set to <2> +- device_type: Set to "pci" +- ranges: Ranges for the PCI memory and I/O regions +- #interrupt-cells: Set to <1> +- interrupt-map-mask and interrupt-map: Standard PCI properties to define the + mapping of the PCIe interface to interrupt numbers. + +Optional properties: +- cdns,max-outbound-regions: Set to maximum number of outbound regions + (default 32) +- cdns,no-bar-match-nbits: Set into the no BAR match register to configure the + number of least significant bits kept during inbound (PCIe -> AXI) address + translations (default 32) +- vendor-id: The PCI vendor ID (16 bits, default is design dependent) +- device-id: The PCI device ID (16 bits, default is design dependent) + +Example: + +pcie@fb00 { + compatible = "cdns,cdns-pcie-host"; + device_type = "pci"; + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0x0 0xff>; + linux,pci-domain = <0>; + cdns,max-outbound-regions = <16>; + cdns,no-bar-match-nbits = <32>; + vendor-id = /bits/ 16 <0x17cd>; + device-id = /bits/ 16 <0x0200>; + + reg = <0x0 0xfb00 0x0 0x0100>, + <0x0 0x4100 0x0 0x1000>, + <0x0 0x4000 0x0 0x0400>; + reg-names = "reg", "cfg", "mem"; + + ranges = <0x0200 0x0 0x4200 0x0 0x4200 0x0 0x100>, +<0x0100 0x0 0x4300 0x0 0x4300 0x0 0x001>; + + #interrupt-cells = <0x1>; + + interrupt-map = <0x0 0x0 0x0 0x10x0 0x0 0x0 14 0x1 +0x0 0x0 0x0 0x20x0 0x0 0x0 15 0x1 +0x0 0x0 0x0 0x30x0 0x0 0x0 16 0x1 +0x0 0x0 0x0 0x40x0 0x0 0x0 17 0x1>; + + interrupt-map-mask = <0x0 0x0 0x0 0x7>; + + msi-parent = <_pci>; +}; -- 2.11.0
[PATCH v6 06/11] dt-bindings: PCI: cadence: Add DT bindings for Cadence PCIe host controller
From: Scott Telford This patch adds documentation for the DT bindings of the Cadence PCIe controller when configured in host (Root Complex) mode. Signed-off-by: Scott Telford Signed-off-by: Cyrille Pitchen Reviewed-by: Rob Herring --- .../bindings/pci/cdns,cdns-pcie-host.txt | 60 ++ 1 file changed, 60 insertions(+) create mode 100644 Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt diff --git a/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt new file mode 100644 index ..20a33f38f69d --- /dev/null +++ b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt @@ -0,0 +1,60 @@ +* Cadence PCIe host controller + +This PCIe controller inherits the base properties defined in +host-generic-pci.txt. + +Required properties: +- compatible: Should contain "cdns,cdns-pcie-host" to identify the IP used. +- reg: Should contain the controller register base address, PCIe configuration + window base address, and AXI interface region base address respectively. +- reg-names: Must be "reg", "cfg" and "mem" respectively. +- #address-cells: Set to <3> +- #size-cells: Set to <2> +- device_type: Set to "pci" +- ranges: Ranges for the PCI memory and I/O regions +- #interrupt-cells: Set to <1> +- interrupt-map-mask and interrupt-map: Standard PCI properties to define the + mapping of the PCIe interface to interrupt numbers. + +Optional properties: +- cdns,max-outbound-regions: Set to maximum number of outbound regions + (default 32) +- cdns,no-bar-match-nbits: Set into the no BAR match register to configure the + number of least significant bits kept during inbound (PCIe -> AXI) address + translations (default 32) +- vendor-id: The PCI vendor ID (16 bits, default is design dependent) +- device-id: The PCI device ID (16 bits, default is design dependent) + +Example: + +pcie@fb00 { + compatible = "cdns,cdns-pcie-host"; + device_type = "pci"; + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0x0 0xff>; + linux,pci-domain = <0>; + cdns,max-outbound-regions = <16>; + cdns,no-bar-match-nbits = <32>; + vendor-id = /bits/ 16 <0x17cd>; + device-id = /bits/ 16 <0x0200>; + + reg = <0x0 0xfb00 0x0 0x0100>, + <0x0 0x4100 0x0 0x1000>, + <0x0 0x4000 0x0 0x0400>; + reg-names = "reg", "cfg", "mem"; + + ranges = <0x0200 0x0 0x4200 0x0 0x4200 0x0 0x100>, +<0x0100 0x0 0x4300 0x0 0x4300 0x0 0x001>; + + #interrupt-cells = <0x1>; + + interrupt-map = <0x0 0x0 0x0 0x10x0 0x0 0x0 14 0x1 +0x0 0x0 0x0 0x20x0 0x0 0x0 15 0x1 +0x0 0x0 0x0 0x30x0 0x0 0x0 16 0x1 +0x0 0x0 0x0 0x40x0 0x0 0x0 17 0x1>; + + interrupt-map-mask = <0x0 0x0 0x0 0x7>; + + msi-parent = <_pci>; +}; -- 2.11.0
[PATCH v6 05/11] PCI: Add vendor ID for Cadence
This patch adds a new PCI vendor ID for Cadence. Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> --- include/linux/pci_ids.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index ab20dc5db423..eb13e84e1fef 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2381,6 +2381,8 @@ #define PCI_VENDOR_ID_LENOVO 0x17aa +#define PCI_VENDOR_ID_CDNS 0x17cd + #define PCI_VENDOR_ID_ARECA0x17d3 #define PCI_DEVICE_ID_ARECA_1110 0x1110 #define PCI_DEVICE_ID_ARECA_1120 0x1120 -- 2.11.0
[PATCH v6 05/11] PCI: Add vendor ID for Cadence
This patch adds a new PCI vendor ID for Cadence. Signed-off-by: Cyrille Pitchen --- include/linux/pci_ids.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index ab20dc5db423..eb13e84e1fef 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2381,6 +2381,8 @@ #define PCI_VENDOR_ID_LENOVO 0x17aa +#define PCI_VENDOR_ID_CDNS 0x17cd + #define PCI_VENDOR_ID_ARECA0x17d3 #define PCI_DEVICE_ID_ARECA_1110 0x1110 #define PCI_DEVICE_ID_ARECA_1120 0x1120 -- 2.11.0
[PATCH v5 05/11] PCI: Add vendor ID for Cadence
This patch adds a new PCI vendor ID for Cadence. Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> --- include/linux/pci_ids.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index ab20dc5db423..eb13e84e1fef 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2381,6 +2381,8 @@ #define PCI_VENDOR_ID_LENOVO 0x17aa +#define PCI_VENDOR_ID_CDNS 0x17cd + #define PCI_VENDOR_ID_ARECA0x17d3 #define PCI_DEVICE_ID_ARECA_1110 0x1110 #define PCI_DEVICE_ID_ARECA_1120 0x1120 -- 2.11.0
[PATCH v5 05/11] PCI: Add vendor ID for Cadence
This patch adds a new PCI vendor ID for Cadence. Signed-off-by: Cyrille Pitchen --- include/linux/pci_ids.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index ab20dc5db423..eb13e84e1fef 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2381,6 +2381,8 @@ #define PCI_VENDOR_ID_LENOVO 0x17aa +#define PCI_VENDOR_ID_CDNS 0x17cd + #define PCI_VENDOR_ID_ARECA0x17d3 #define PCI_DEVICE_ID_ARECA_1110 0x1110 #define PCI_DEVICE_ID_ARECA_1120 0x1120 -- 2.11.0
[PATCH v5 01/11] PCI: Regroup all PCI related entries into drivers/pci/Makefile
Clean up drivers/Makefile by moving the pci/endpoint and pci/dwc entries from drivers/Makefile into drivers/pci/Makefile. Since we don't want to introduce any dependency between CONFIG_PCI and CONFIG_PCI_ENDPOINT, we now always execute drivers/pci/Makefile. Hence all Makefiles in drivers/pci/ were updated accordingly so no file is compiled when CONFIG_PCI is not defined. Also, we add a comment to reinforce that EPC and EPF libraries must be initialized before their users. Hence built-in EPC drivers, such as those of Designware, are linked after the endpoint core libraries. Finally, we add another comment to explain why obj-y has been chosen instead of obj-$(CONFIG_PCIE_DW) to parse the dwc/ sub-folder. Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> --- drivers/Makefile | 5 + drivers/pci/Kconfig | 1 + drivers/pci/Makefile | 13 ++--- drivers/pci/dwc/Makefile | 2 ++ drivers/pci/host/Makefile | 2 ++ 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/Makefile b/drivers/Makefile index e06f7f633f73..8189b1edec00 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -16,10 +16,7 @@ obj-$(CONFIG_PINCTRL)+= pinctrl/ obj-$(CONFIG_GPIOLIB) += gpio/ obj-y += pwm/ -obj-$(CONFIG_PCI) += pci/ -obj-$(CONFIG_PCI_ENDPOINT) += pci/endpoint/ -# PCI dwc controller drivers -obj-y += pci/dwc/ +obj-y += pci/ obj-$(CONFIG_PARISC) += parisc/ obj-$(CONFIG_RAPIDIO) += rapidio/ diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index bda151788f3f..7eeb969ab86a 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -125,6 +125,7 @@ config PCI_PASID config PCI_LABEL def_bool y if (DMI || ACPI) + depends on PCI select NLS config PCI_HYPERV diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index c7819b973df7..ddb5aa6640d7 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -3,12 +3,15 @@ # Makefile for the PCI bus specific drivers. # -obj-y += access.o bus.o probe.o host-bridge.o remove.o pci.o \ +obj-$(CONFIG_PCI) += access.o bus.o probe.o host-bridge.o remove.o pci.o \ pci-driver.o search.o pci-sysfs.o rom.o setup-res.o \ irq.o vpd.o setup-bus.o vc.o mmap.o setup-irq.o +ifdef CONFIG_PCI obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_SYSFS) += slot.o +obj-$(CONFIG_OF) += of.o +endif obj-$(CONFIG_PCI_QUIRKS) += quirks.o @@ -44,10 +47,14 @@ obj-$(CONFIG_PCI_ECAM) += ecam.o obj-$(CONFIG_XEN_PCIDEV_FRONTEND) += xen-pcifront.o -obj-$(CONFIG_OF) += of.o - ccflags-$(CONFIG_PCI_DEBUG) := -DDEBUG # PCI host controller drivers obj-y += host/ obj-y += switch/ + +obj-$(CONFIG_PCI_ENDPOINT) += endpoint/ + +# Endpoint library must be initialized before its users +# pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW +obj-y += dwc/ diff --git a/drivers/pci/dwc/Makefile b/drivers/pci/dwc/Makefile index a9d8a6fb48e3..5d2ce72c7a52 100644 --- a/drivers/pci/dwc/Makefile +++ b/drivers/pci/dwc/Makefile @@ -25,4 +25,6 @@ obj-$(CONFIG_PCIE_HISI_STB) += pcie-histb.o # ARM64 and use internal ifdefs to only build the pieces we need # depending on whether ACPI, the DT driver, or both are enabled. +ifdef CONFIG_PCI obj-$(CONFIG_ARM64) += pcie-hisi.o +endif diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile index 34ec1d88f961..3b1059190867 100644 --- a/drivers/pci/host/Makefile +++ b/drivers/pci/host/Makefile @@ -34,6 +34,8 @@ obj-$(CONFIG_VMD) += vmd.o # ARM64 and use internal ifdefs to only build the pieces we need # depending on whether ACPI, the DT driver, or both are enabled. +ifdef CONFIG_PCI obj-$(CONFIG_ARM64) += pci-thunder-ecam.o obj-$(CONFIG_ARM64) += pci-thunder-pem.o obj-$(CONFIG_ARM64) += pci-xgene.o +endif -- 2.11.0
[PATCH v5 01/11] PCI: Regroup all PCI related entries into drivers/pci/Makefile
Clean up drivers/Makefile by moving the pci/endpoint and pci/dwc entries from drivers/Makefile into drivers/pci/Makefile. Since we don't want to introduce any dependency between CONFIG_PCI and CONFIG_PCI_ENDPOINT, we now always execute drivers/pci/Makefile. Hence all Makefiles in drivers/pci/ were updated accordingly so no file is compiled when CONFIG_PCI is not defined. Also, we add a comment to reinforce that EPC and EPF libraries must be initialized before their users. Hence built-in EPC drivers, such as those of Designware, are linked after the endpoint core libraries. Finally, we add another comment to explain why obj-y has been chosen instead of obj-$(CONFIG_PCIE_DW) to parse the dwc/ sub-folder. Signed-off-by: Cyrille Pitchen --- drivers/Makefile | 5 + drivers/pci/Kconfig | 1 + drivers/pci/Makefile | 13 ++--- drivers/pci/dwc/Makefile | 2 ++ drivers/pci/host/Makefile | 2 ++ 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/Makefile b/drivers/Makefile index e06f7f633f73..8189b1edec00 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -16,10 +16,7 @@ obj-$(CONFIG_PINCTRL)+= pinctrl/ obj-$(CONFIG_GPIOLIB) += gpio/ obj-y += pwm/ -obj-$(CONFIG_PCI) += pci/ -obj-$(CONFIG_PCI_ENDPOINT) += pci/endpoint/ -# PCI dwc controller drivers -obj-y += pci/dwc/ +obj-y += pci/ obj-$(CONFIG_PARISC) += parisc/ obj-$(CONFIG_RAPIDIO) += rapidio/ diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index bda151788f3f..7eeb969ab86a 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -125,6 +125,7 @@ config PCI_PASID config PCI_LABEL def_bool y if (DMI || ACPI) + depends on PCI select NLS config PCI_HYPERV diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index c7819b973df7..ddb5aa6640d7 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -3,12 +3,15 @@ # Makefile for the PCI bus specific drivers. # -obj-y += access.o bus.o probe.o host-bridge.o remove.o pci.o \ +obj-$(CONFIG_PCI) += access.o bus.o probe.o host-bridge.o remove.o pci.o \ pci-driver.o search.o pci-sysfs.o rom.o setup-res.o \ irq.o vpd.o setup-bus.o vc.o mmap.o setup-irq.o +ifdef CONFIG_PCI obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_SYSFS) += slot.o +obj-$(CONFIG_OF) += of.o +endif obj-$(CONFIG_PCI_QUIRKS) += quirks.o @@ -44,10 +47,14 @@ obj-$(CONFIG_PCI_ECAM) += ecam.o obj-$(CONFIG_XEN_PCIDEV_FRONTEND) += xen-pcifront.o -obj-$(CONFIG_OF) += of.o - ccflags-$(CONFIG_PCI_DEBUG) := -DDEBUG # PCI host controller drivers obj-y += host/ obj-y += switch/ + +obj-$(CONFIG_PCI_ENDPOINT) += endpoint/ + +# Endpoint library must be initialized before its users +# pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW +obj-y += dwc/ diff --git a/drivers/pci/dwc/Makefile b/drivers/pci/dwc/Makefile index a9d8a6fb48e3..5d2ce72c7a52 100644 --- a/drivers/pci/dwc/Makefile +++ b/drivers/pci/dwc/Makefile @@ -25,4 +25,6 @@ obj-$(CONFIG_PCIE_HISI_STB) += pcie-histb.o # ARM64 and use internal ifdefs to only build the pieces we need # depending on whether ACPI, the DT driver, or both are enabled. +ifdef CONFIG_PCI obj-$(CONFIG_ARM64) += pcie-hisi.o +endif diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile index 34ec1d88f961..3b1059190867 100644 --- a/drivers/pci/host/Makefile +++ b/drivers/pci/host/Makefile @@ -34,6 +34,8 @@ obj-$(CONFIG_VMD) += vmd.o # ARM64 and use internal ifdefs to only build the pieces we need # depending on whether ACPI, the DT driver, or both are enabled. +ifdef CONFIG_PCI obj-$(CONFIG_ARM64) += pci-thunder-ecam.o obj-$(CONFIG_ARM64) += pci-thunder-pem.o obj-$(CONFIG_ARM64) += pci-xgene.o +endif -- 2.11.0
[PATCH v5 04/11] PCI: Add generic function to probe PCI host controllers
This patchs moves generic source code from drivers/pci/host/pci-host-common.c into drivers/pci/probe.c. Indeed the extracted lines of code were duplicated by many host controller drivers. Regrouping them into a generic function gives a change to properly share this code without introducing a useless dependency to PCI_HOST_COMMON, which selects PCI_ECAM when not needed by most host controller drivers. Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> --- drivers/pci/host/pci-host-common.c | 22 +- drivers/pci/probe.c| 33 + include/linux/pci.h| 1 + 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c index 9f27e90f578c..756702d8dd10 100644 --- a/drivers/pci/host/pci-host-common.c +++ b/drivers/pci/host/pci-host-common.c @@ -72,7 +72,6 @@ int pci_host_common_probe(struct platform_device *pdev, const char *type; struct device *dev = >dev; struct device_node *np = dev->of_node; - struct pci_bus *bus, *child; struct pci_host_bridge *bridge; struct pci_config_window *cfg; struct list_head resources; @@ -107,30 +106,11 @@ int pci_host_common_probe(struct platform_device *pdev, bridge->map_irq = of_irq_parse_and_map_pci; bridge->swizzle_irq = pci_common_swizzle; - ret = pci_scan_root_bus_bridge(bridge); + ret = pci_host_probe(bridge); if (ret < 0) { - dev_err(dev, "Scanning root bridge failed"); pci_free_resource_list(); return ret; } - bus = bridge->bus; - - /* -* We insert PCI resources into the iomem_resource and -* ioport_resource trees in either pci_bus_claim_resources() -* or pci_bus_assign_resources(). -*/ - if (pci_has_flag(PCI_PROBE_ONLY)) { - pci_bus_claim_resources(bus); - } else { - pci_bus_size_bridges(bus); - pci_bus_assign_resources(bus); - - list_for_each_entry(child, >children, node) - pcie_bus_configure_settings(child); - } - - pci_bus_add_devices(bus); return 0; } diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 2c673a65d5b0..708785e5871f 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -2684,6 +2684,39 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, } EXPORT_SYMBOL_GPL(pci_create_root_bus); +int pci_host_probe(struct pci_host_bridge *bridge) +{ + struct pci_bus *bus, *child; + int ret; + + ret = pci_scan_root_bus_bridge(bridge); + if (ret < 0) { + dev_err(bridge->dev.parent, "Scanning root bridge failed"); + return ret; + } + + bus = bridge->bus; + + /* +* We insert PCI resources into the iomem_resource and +* ioport_resource trees in either pci_bus_claim_resources() +* or pci_bus_assign_resources(). +*/ + if (pci_has_flag(PCI_PROBE_ONLY)) { + pci_bus_claim_resources(bus); + } else { + pci_bus_size_bridges(bus); + pci_bus_assign_resources(bus); + + list_for_each_entry(child, >children, node) + pcie_bus_configure_settings(child); + } + + pci_bus_add_devices(bus); + return 0; +} +EXPORT_SYMBOL_GPL(pci_host_probe); + int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int bus_max) { struct resource *res = >busn_res; diff --git a/include/linux/pci.h b/include/linux/pci.h index 3b1cfa5dd512..485c571d7648 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -879,6 +879,7 @@ struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata); struct pci_bus *pci_create_root_bus(struct device *parent, int bus, struct pci_ops *ops, void *sysdata, struct list_head *resources); +int pci_host_probe(struct pci_host_bridge *bridge); int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int busmax); int pci_bus_update_busn_res_end(struct pci_bus *b, int busmax); void pci_bus_release_busn_res(struct pci_bus *b); -- 2.11.0
[PATCH v5 00/11] PCI: Add support to the Cadence PCIe controller
Hi all, this series of patches adds support to the Cadence PCIe controller. It was tested on a ARM64 platform emulated by a Palladium running the pci-next kernel. The host mode was tested with some PCIe devices connected to the Palladium through a speed-bridge. Some of those devices were a USB host controller and a SATA controller. The PCIe host controller was also tested with a second controller configured in endpoint mode and connected back to back to the first controller. The EndPoint Controller (EPC) driver was tested with 2 PCI functions, both handled by the pci-epf-test driver, using the pcitest userspace program. I used the "-D" optional command line parameter to select the proper PCI function. Best regards, Cyrille ChangeLog v4 -> v5: - rebase on today's (20180128) linux-pci/next - add again the endpoint driver - Patch 7: move host driver from drivers/pci/cadence into drivers/pci/host and remove all references to the endpoint mode, as requested by Lorenzo. The host driver will be moved back into drivers/pci/cadence by Patch 11 - Patch 8: fix comparison of func_no to BAR5: compare to epc->max_functions - Patch 9: add new patch to fix support of PCI multi-function devices - Patch 10: change the 'cdns,max-outbound-regions' from optional to mandatory as requested by Kishon. - Patch 11: take Kishon's comments into account as much as I could. - Other patches: unchanged v3 -> v4: - split patch 3 from v3 into patches 3 and 4. - remove unused cdns_pcie_reset_outbound_region() from old patch 6 (new patch 7). - other patches are unchanged. v2 -> v3: - rebase on today's linux-pci/next (20180110) patch1: - rework the commit message of patch 1 and add two new comments on why endpoint library users must be linked after the endpoint library itself and why the dwc rule uses obj-y instead of obj-$(CONFIG_PCIE_CONFIG_DW). - update patch 1 to add missing ifdef CONFIG_PCI / endif in drivers/pci/dwc/Makefile around the obj-$(CONFIG_ARM64) += pcie-hisi.o rule, like for the other obj-$(CONFIG_ARM64) rules in drivers/pci/host/Makefile. patch2: unchanged patch3: - update patch 3 so the bridge hooks/members initialization is left to the host bridges probe routines. patch4: unchanged patch5: - collect 'Reviewed-by' tag from Rob Herring for the DT bindings. patch6: - remove explanation in the commit message on why obj-$(CONFIG_PCIE_CANDENCE) is placed after obj-$(CONFIG_PCI_ENDPOINT) in drivers/pci/Makefile since a comment on it has been added into patch1. - remove menuconfig PCI_CADENCE in drivers/pci/cadence/Kconfig to match drivers/pci/dwc/Kconfig. - adapt patch6 to the changes done in patch3 for the pci_host_probe() function. v1 -> v2: - add new properties in the device-tree bindings: 'cdns,max-outbound-regions' and 'cdns,no-bar-match-nbits'. - add a new patch to regroup all makefile rules in drivers/pci/Makefile, hence cleaning drivers/Makefile up. - change the license text to use the recommanded format: // SPDX-License-Identifier: GPL-2.0 - add a new patch updating the API of the EPC library to add support to multi-function devices. - add a 2 new patches to share more common code between host controller drivers - remove some useless tests - add more comments in both drivers. - fix DT bindings examples - remove useless init of the primary, secondary and sub-ordinate bus numbers in the PCI configuration space of the root port. - remove cdns_pcie_ep_stop() function and rework cdns_pcie_ep_start() function Cyrille Pitchen (10): PCI: Regroup all PCI related entries into drivers/pci/Makefile PCI: OF: Add generic function to parse and allocate PCI resources PCI: generic: fix missing call of pci_free_resource_list() PCI: Add generic function to probe PCI host controllers PCI: Add vendor ID for Cadence PCI: cadence: Add host driver for Cadence PCIe controller PCI: endpoint: Add the function number as argument to EPC ops PCI: endpoint: Fix EPF device name to support multi-function devices dt-bindings: PCI: cadence: Add DT bindings for Cadence PCIe endpoint controller PCI: cadence: Add EndPoint Controller driver for Cadence PCIe controller Scott Telford (1): dt-bindings: PCI: cadence: Add DT bindings for Cadence PCIe host controller .../devicetree/bindings/pci/cdns,cdns-pcie-ep.txt | 22 + .../bindings/pci/cdns,cdns-pcie-host.txt | 60 +++ MAINTAINERS| 7 + drivers/Makefile | 5 +- drivers/pci/Kconfig| 2 + drivers/pci/Makefile | 14 +- drivers/pci/cadence/Kconfig| 27 + drivers/pci/cadence/Makefile | 4 + drivers/pci/cadence/pcie-cadence-ep.c | 542 + drivers/pci/cadence/pcie-cadence-host.c| 336 + drivers/pci/cadence/pcie-cadence.c
[PATCH v5 04/11] PCI: Add generic function to probe PCI host controllers
This patchs moves generic source code from drivers/pci/host/pci-host-common.c into drivers/pci/probe.c. Indeed the extracted lines of code were duplicated by many host controller drivers. Regrouping them into a generic function gives a change to properly share this code without introducing a useless dependency to PCI_HOST_COMMON, which selects PCI_ECAM when not needed by most host controller drivers. Signed-off-by: Cyrille Pitchen --- drivers/pci/host/pci-host-common.c | 22 +- drivers/pci/probe.c| 33 + include/linux/pci.h| 1 + 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c index 9f27e90f578c..756702d8dd10 100644 --- a/drivers/pci/host/pci-host-common.c +++ b/drivers/pci/host/pci-host-common.c @@ -72,7 +72,6 @@ int pci_host_common_probe(struct platform_device *pdev, const char *type; struct device *dev = >dev; struct device_node *np = dev->of_node; - struct pci_bus *bus, *child; struct pci_host_bridge *bridge; struct pci_config_window *cfg; struct list_head resources; @@ -107,30 +106,11 @@ int pci_host_common_probe(struct platform_device *pdev, bridge->map_irq = of_irq_parse_and_map_pci; bridge->swizzle_irq = pci_common_swizzle; - ret = pci_scan_root_bus_bridge(bridge); + ret = pci_host_probe(bridge); if (ret < 0) { - dev_err(dev, "Scanning root bridge failed"); pci_free_resource_list(); return ret; } - bus = bridge->bus; - - /* -* We insert PCI resources into the iomem_resource and -* ioport_resource trees in either pci_bus_claim_resources() -* or pci_bus_assign_resources(). -*/ - if (pci_has_flag(PCI_PROBE_ONLY)) { - pci_bus_claim_resources(bus); - } else { - pci_bus_size_bridges(bus); - pci_bus_assign_resources(bus); - - list_for_each_entry(child, >children, node) - pcie_bus_configure_settings(child); - } - - pci_bus_add_devices(bus); return 0; } diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 2c673a65d5b0..708785e5871f 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -2684,6 +2684,39 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, } EXPORT_SYMBOL_GPL(pci_create_root_bus); +int pci_host_probe(struct pci_host_bridge *bridge) +{ + struct pci_bus *bus, *child; + int ret; + + ret = pci_scan_root_bus_bridge(bridge); + if (ret < 0) { + dev_err(bridge->dev.parent, "Scanning root bridge failed"); + return ret; + } + + bus = bridge->bus; + + /* +* We insert PCI resources into the iomem_resource and +* ioport_resource trees in either pci_bus_claim_resources() +* or pci_bus_assign_resources(). +*/ + if (pci_has_flag(PCI_PROBE_ONLY)) { + pci_bus_claim_resources(bus); + } else { + pci_bus_size_bridges(bus); + pci_bus_assign_resources(bus); + + list_for_each_entry(child, >children, node) + pcie_bus_configure_settings(child); + } + + pci_bus_add_devices(bus); + return 0; +} +EXPORT_SYMBOL_GPL(pci_host_probe); + int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int bus_max) { struct resource *res = >busn_res; diff --git a/include/linux/pci.h b/include/linux/pci.h index 3b1cfa5dd512..485c571d7648 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -879,6 +879,7 @@ struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata); struct pci_bus *pci_create_root_bus(struct device *parent, int bus, struct pci_ops *ops, void *sysdata, struct list_head *resources); +int pci_host_probe(struct pci_host_bridge *bridge); int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int busmax); int pci_bus_update_busn_res_end(struct pci_bus *b, int busmax); void pci_bus_release_busn_res(struct pci_bus *b); -- 2.11.0
[PATCH v5 00/11] PCI: Add support to the Cadence PCIe controller
Hi all, this series of patches adds support to the Cadence PCIe controller. It was tested on a ARM64 platform emulated by a Palladium running the pci-next kernel. The host mode was tested with some PCIe devices connected to the Palladium through a speed-bridge. Some of those devices were a USB host controller and a SATA controller. The PCIe host controller was also tested with a second controller configured in endpoint mode and connected back to back to the first controller. The EndPoint Controller (EPC) driver was tested with 2 PCI functions, both handled by the pci-epf-test driver, using the pcitest userspace program. I used the "-D" optional command line parameter to select the proper PCI function. Best regards, Cyrille ChangeLog v4 -> v5: - rebase on today's (20180128) linux-pci/next - add again the endpoint driver - Patch 7: move host driver from drivers/pci/cadence into drivers/pci/host and remove all references to the endpoint mode, as requested by Lorenzo. The host driver will be moved back into drivers/pci/cadence by Patch 11 - Patch 8: fix comparison of func_no to BAR5: compare to epc->max_functions - Patch 9: add new patch to fix support of PCI multi-function devices - Patch 10: change the 'cdns,max-outbound-regions' from optional to mandatory as requested by Kishon. - Patch 11: take Kishon's comments into account as much as I could. - Other patches: unchanged v3 -> v4: - split patch 3 from v3 into patches 3 and 4. - remove unused cdns_pcie_reset_outbound_region() from old patch 6 (new patch 7). - other patches are unchanged. v2 -> v3: - rebase on today's linux-pci/next (20180110) patch1: - rework the commit message of patch 1 and add two new comments on why endpoint library users must be linked after the endpoint library itself and why the dwc rule uses obj-y instead of obj-$(CONFIG_PCIE_CONFIG_DW). - update patch 1 to add missing ifdef CONFIG_PCI / endif in drivers/pci/dwc/Makefile around the obj-$(CONFIG_ARM64) += pcie-hisi.o rule, like for the other obj-$(CONFIG_ARM64) rules in drivers/pci/host/Makefile. patch2: unchanged patch3: - update patch 3 so the bridge hooks/members initialization is left to the host bridges probe routines. patch4: unchanged patch5: - collect 'Reviewed-by' tag from Rob Herring for the DT bindings. patch6: - remove explanation in the commit message on why obj-$(CONFIG_PCIE_CANDENCE) is placed after obj-$(CONFIG_PCI_ENDPOINT) in drivers/pci/Makefile since a comment on it has been added into patch1. - remove menuconfig PCI_CADENCE in drivers/pci/cadence/Kconfig to match drivers/pci/dwc/Kconfig. - adapt patch6 to the changes done in patch3 for the pci_host_probe() function. v1 -> v2: - add new properties in the device-tree bindings: 'cdns,max-outbound-regions' and 'cdns,no-bar-match-nbits'. - add a new patch to regroup all makefile rules in drivers/pci/Makefile, hence cleaning drivers/Makefile up. - change the license text to use the recommanded format: // SPDX-License-Identifier: GPL-2.0 - add a new patch updating the API of the EPC library to add support to multi-function devices. - add a 2 new patches to share more common code between host controller drivers - remove some useless tests - add more comments in both drivers. - fix DT bindings examples - remove useless init of the primary, secondary and sub-ordinate bus numbers in the PCI configuration space of the root port. - remove cdns_pcie_ep_stop() function and rework cdns_pcie_ep_start() function Cyrille Pitchen (10): PCI: Regroup all PCI related entries into drivers/pci/Makefile PCI: OF: Add generic function to parse and allocate PCI resources PCI: generic: fix missing call of pci_free_resource_list() PCI: Add generic function to probe PCI host controllers PCI: Add vendor ID for Cadence PCI: cadence: Add host driver for Cadence PCIe controller PCI: endpoint: Add the function number as argument to EPC ops PCI: endpoint: Fix EPF device name to support multi-function devices dt-bindings: PCI: cadence: Add DT bindings for Cadence PCIe endpoint controller PCI: cadence: Add EndPoint Controller driver for Cadence PCIe controller Scott Telford (1): dt-bindings: PCI: cadence: Add DT bindings for Cadence PCIe host controller .../devicetree/bindings/pci/cdns,cdns-pcie-ep.txt | 22 + .../bindings/pci/cdns,cdns-pcie-host.txt | 60 +++ MAINTAINERS| 7 + drivers/Makefile | 5 +- drivers/pci/Kconfig| 2 + drivers/pci/Makefile | 14 +- drivers/pci/cadence/Kconfig| 27 + drivers/pci/cadence/Makefile | 4 + drivers/pci/cadence/pcie-cadence-ep.c | 542 + drivers/pci/cadence/pcie-cadence-host.c| 336 + drivers/pci/cadence/pcie-cadence.c
[PATCH v5 03/11] PCI: generic: fix missing call of pci_free_resource_list()
Call pci_free_resource_list() from pci_host_common_probe() when probing fails, as done inside gen_pci_init() when this later function fails. Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> --- drivers/pci/host/pci-host-common.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c index a613ea310e76..9f27e90f578c 100644 --- a/drivers/pci/host/pci-host-common.c +++ b/drivers/pci/host/pci-host-common.c @@ -110,6 +110,7 @@ int pci_host_common_probe(struct platform_device *pdev, ret = pci_scan_root_bus_bridge(bridge); if (ret < 0) { dev_err(dev, "Scanning root bridge failed"); + pci_free_resource_list(); return ret; } -- 2.11.0
[PATCH v5 03/11] PCI: generic: fix missing call of pci_free_resource_list()
Call pci_free_resource_list() from pci_host_common_probe() when probing fails, as done inside gen_pci_init() when this later function fails. Signed-off-by: Cyrille Pitchen --- drivers/pci/host/pci-host-common.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c index a613ea310e76..9f27e90f578c 100644 --- a/drivers/pci/host/pci-host-common.c +++ b/drivers/pci/host/pci-host-common.c @@ -110,6 +110,7 @@ int pci_host_common_probe(struct platform_device *pdev, ret = pci_scan_root_bus_bridge(bridge); if (ret < 0) { dev_err(dev, "Scanning root bridge failed"); + pci_free_resource_list(); return ret; } -- 2.11.0
[PATCH v5 09/11] PCI: endpoint: Fix EPF device name to support multi-function devices
Fix the pci_epf_make() function so it can now bind many EPF devices to the same EPF driver. Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> --- drivers/pci/endpoint/pci-ep-cfs.c | 46 +-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/drivers/pci/endpoint/pci-ep-cfs.c b/drivers/pci/endpoint/pci-ep-cfs.c index c9a2fb9dd49d..9ec28be1e378 100644 --- a/drivers/pci/endpoint/pci-ep-cfs.c +++ b/drivers/pci/endpoint/pci-ep-cfs.c @@ -18,18 +18,22 @@ */ #include +#include #include #include #include #include +static DEFINE_IDR(functions_idr); +static DEFINE_MUTEX(functions_mutex); static struct config_group *functions_group; static struct config_group *controllers_group; struct pci_epf_group { struct config_group group; struct pci_epf *epf; + int index; }; struct pci_epc_group { @@ -354,6 +358,9 @@ static void pci_epf_release(struct config_item *item) { struct pci_epf_group *epf_group = to_pci_epf_group(item); + mutex_lock(_mutex); + idr_remove(_idr, epf_group->index); + mutex_unlock(_mutex); pci_epf_destroy(epf_group->epf); kfree(epf_group); } @@ -373,22 +380,57 @@ static struct config_group *pci_epf_make(struct config_group *group, { struct pci_epf_group *epf_group; struct pci_epf *epf; + char *epf_name; + int index, err; epf_group = kzalloc(sizeof(*epf_group), GFP_KERNEL); if (!epf_group) return ERR_PTR(-ENOMEM); + mutex_lock(_mutex); + index = idr_alloc(_idr, epf_group, 0, 0, GFP_KERNEL); + mutex_unlock(_mutex); + if (index < 0) { + err = index; + goto free_group; + } + + epf_group->index = index; + config_group_init_type_name(_group->group, name, _epf_type); - epf = pci_epf_create(group->cg_item.ci_name); + epf_name = kasprintf(GFP_KERNEL, "%s.%d", +group->cg_item.ci_name, epf_group->index); + if (!epf_name) { + err = -ENOMEM; + goto remove_idr; + } + + epf = pci_epf_create(epf_name); if (IS_ERR(epf)) { pr_err("failed to create endpoint function device\n"); - return ERR_PTR(-EINVAL); + err = -EINVAL; + goto free_name; } epf_group->epf = epf; + kfree(epf_name); + return _group->group; + +free_name: + kfree(epf_name); + +remove_idr: + mutex_lock(_mutex); + idr_remove(_idr, epf_group->index); + mutex_unlock(_mutex); + +free_group: + kfree(epf_group); + + return ERR_PTR(err); } static void pci_epf_drop(struct config_group *group, struct config_item *item) -- 2.11.0
[PATCH v5 11/11] PCI: cadence: Add EndPoint Controller driver for Cadence PCIe controller
This patch adds support to the Cadence PCIe controller in endpoint mode. Since pieces of source code are shared with the host driver (Root Complex mode), we create a new directory under drivers/pci dedicated to the Cadence PCIe controller. The common code is placed into drivers/pci/cadence/pcie-cadence.c and used by both the host and endpoint controller drivers. Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> --- MAINTAINERS | 2 +- drivers/pci/Kconfig | 1 + drivers/pci/Makefile | 1 + drivers/pci/cadence/Kconfig | 27 ++ drivers/pci/cadence/Makefile | 4 + drivers/pci/cadence/pcie-cadence-ep.c | 542 ++ drivers/pci/{host => cadence}/pcie-cadence-host.c | 65 +-- drivers/pci/cadence/pcie-cadence.c| 126 + drivers/pci/{host => cadence}/pcie-cadence.h | 122 + drivers/pci/host/Kconfig | 10 - drivers/pci/host/Makefile | 1 - 11 files changed, 826 insertions(+), 75 deletions(-) create mode 100644 drivers/pci/cadence/Kconfig create mode 100644 drivers/pci/cadence/Makefile create mode 100644 drivers/pci/cadence/pcie-cadence-ep.c rename drivers/pci/{host => cadence}/pcie-cadence-host.c (80%) create mode 100644 drivers/pci/cadence/pcie-cadence.c rename drivers/pci/{host => cadence}/pcie-cadence.h (63%) diff --git a/MAINTAINERS b/MAINTAINERS index 08b2e5390a7e..cc24c74a946e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10407,7 +10407,7 @@ M: Alan Douglas <adoug...@cadence.com> L: linux-...@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/pci/cdns,*.txt -F: drivers/pci/host/pcie-cadence* +F: drivers/pci/cadence/pcie-cadence* PCI DRIVER FOR FREESCALE LAYERSCAPE M: Minghuan Lian <minghuan.l...@freescale.com> diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 7eeb969ab86a..dee90cc1dcaf 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -136,6 +136,7 @@ config PCI_HYPERV PCI devices from a PCI backend to support PCI driver domains. source "drivers/pci/hotplug/Kconfig" +source "drivers/pci/cadence/Kconfig" source "drivers/pci/dwc/Kconfig" source "drivers/pci/host/Kconfig" source "drivers/pci/endpoint/Kconfig" diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index ddb5aa6640d7..941970936840 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -56,5 +56,6 @@ obj-y += switch/ obj-$(CONFIG_PCI_ENDPOINT) += endpoint/ # Endpoint library must be initialized before its users +obj-$(CONFIG_PCIE_CADENCE) += cadence/ # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW obj-y += dwc/ diff --git a/drivers/pci/cadence/Kconfig b/drivers/pci/cadence/Kconfig new file mode 100644 index ..e6824cb56c16 --- /dev/null +++ b/drivers/pci/cadence/Kconfig @@ -0,0 +1,27 @@ +menu "Cadence PCIe controllers support" + +config PCIE_CADENCE + bool + +config PCIE_CADENCE_HOST + bool "Cadence PCIe host controller" + depends on OF + depends on PCI + select IRQ_DOMAIN + select PCIE_CADENCE + help + Say Y here if you want to support the Cadence PCIe controller in host + mode. This PCIe controller may be embedded into many different vendors + SoCs. + +config PCIE_CADENCE_EP + bool "Cadence PCIe endpoint controller" + depends on OF + depends on PCI_ENDPOINT + select PCIE_CADENCE + help + Say Y here if you want to support the Cadence PCIe controller in + endpoint mode. This PCIe controller may be embedded into many + different vendors SoCs. + +endmenu diff --git a/drivers/pci/cadence/Makefile b/drivers/pci/cadence/Makefile new file mode 100644 index ..719392b97998 --- /dev/null +++ b/drivers/pci/cadence/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_PCIE_CADENCE) += pcie-cadence.o +obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host.o +obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep.o diff --git a/drivers/pci/cadence/pcie-cadence-ep.c b/drivers/pci/cadence/pcie-cadence-ep.c new file mode 100644 index ..3c3a97743453 --- /dev/null +++ b/drivers/pci/cadence/pcie-cadence-ep.c @@ -0,0 +1,542 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2017 Cadence +// Cadence PCIe endpoint controller driver. +// Author: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> + +#include +#include +#include +#include +#include +#include +#include + +#include "pcie-cadence.h" + +#define CDNS_PCIE_EP_MIN_APERTURE 128 /* 128 bytes */ +#define CDNS_PCIE_EP_IRQ_PCI_ADDR_NONE 0x1 +#define CDN
[PATCH v5 09/11] PCI: endpoint: Fix EPF device name to support multi-function devices
Fix the pci_epf_make() function so it can now bind many EPF devices to the same EPF driver. Signed-off-by: Cyrille Pitchen --- drivers/pci/endpoint/pci-ep-cfs.c | 46 +-- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/drivers/pci/endpoint/pci-ep-cfs.c b/drivers/pci/endpoint/pci-ep-cfs.c index c9a2fb9dd49d..9ec28be1e378 100644 --- a/drivers/pci/endpoint/pci-ep-cfs.c +++ b/drivers/pci/endpoint/pci-ep-cfs.c @@ -18,18 +18,22 @@ */ #include +#include #include #include #include #include +static DEFINE_IDR(functions_idr); +static DEFINE_MUTEX(functions_mutex); static struct config_group *functions_group; static struct config_group *controllers_group; struct pci_epf_group { struct config_group group; struct pci_epf *epf; + int index; }; struct pci_epc_group { @@ -354,6 +358,9 @@ static void pci_epf_release(struct config_item *item) { struct pci_epf_group *epf_group = to_pci_epf_group(item); + mutex_lock(_mutex); + idr_remove(_idr, epf_group->index); + mutex_unlock(_mutex); pci_epf_destroy(epf_group->epf); kfree(epf_group); } @@ -373,22 +380,57 @@ static struct config_group *pci_epf_make(struct config_group *group, { struct pci_epf_group *epf_group; struct pci_epf *epf; + char *epf_name; + int index, err; epf_group = kzalloc(sizeof(*epf_group), GFP_KERNEL); if (!epf_group) return ERR_PTR(-ENOMEM); + mutex_lock(_mutex); + index = idr_alloc(_idr, epf_group, 0, 0, GFP_KERNEL); + mutex_unlock(_mutex); + if (index < 0) { + err = index; + goto free_group; + } + + epf_group->index = index; + config_group_init_type_name(_group->group, name, _epf_type); - epf = pci_epf_create(group->cg_item.ci_name); + epf_name = kasprintf(GFP_KERNEL, "%s.%d", +group->cg_item.ci_name, epf_group->index); + if (!epf_name) { + err = -ENOMEM; + goto remove_idr; + } + + epf = pci_epf_create(epf_name); if (IS_ERR(epf)) { pr_err("failed to create endpoint function device\n"); - return ERR_PTR(-EINVAL); + err = -EINVAL; + goto free_name; } epf_group->epf = epf; + kfree(epf_name); + return _group->group; + +free_name: + kfree(epf_name); + +remove_idr: + mutex_lock(_mutex); + idr_remove(_idr, epf_group->index); + mutex_unlock(_mutex); + +free_group: + kfree(epf_group); + + return ERR_PTR(err); } static void pci_epf_drop(struct config_group *group, struct config_item *item) -- 2.11.0
[PATCH v5 11/11] PCI: cadence: Add EndPoint Controller driver for Cadence PCIe controller
This patch adds support to the Cadence PCIe controller in endpoint mode. Since pieces of source code are shared with the host driver (Root Complex mode), we create a new directory under drivers/pci dedicated to the Cadence PCIe controller. The common code is placed into drivers/pci/cadence/pcie-cadence.c and used by both the host and endpoint controller drivers. Signed-off-by: Cyrille Pitchen --- MAINTAINERS | 2 +- drivers/pci/Kconfig | 1 + drivers/pci/Makefile | 1 + drivers/pci/cadence/Kconfig | 27 ++ drivers/pci/cadence/Makefile | 4 + drivers/pci/cadence/pcie-cadence-ep.c | 542 ++ drivers/pci/{host => cadence}/pcie-cadence-host.c | 65 +-- drivers/pci/cadence/pcie-cadence.c| 126 + drivers/pci/{host => cadence}/pcie-cadence.h | 122 + drivers/pci/host/Kconfig | 10 - drivers/pci/host/Makefile | 1 - 11 files changed, 826 insertions(+), 75 deletions(-) create mode 100644 drivers/pci/cadence/Kconfig create mode 100644 drivers/pci/cadence/Makefile create mode 100644 drivers/pci/cadence/pcie-cadence-ep.c rename drivers/pci/{host => cadence}/pcie-cadence-host.c (80%) create mode 100644 drivers/pci/cadence/pcie-cadence.c rename drivers/pci/{host => cadence}/pcie-cadence.h (63%) diff --git a/MAINTAINERS b/MAINTAINERS index 08b2e5390a7e..cc24c74a946e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10407,7 +10407,7 @@ M: Alan Douglas L: linux-...@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/pci/cdns,*.txt -F: drivers/pci/host/pcie-cadence* +F: drivers/pci/cadence/pcie-cadence* PCI DRIVER FOR FREESCALE LAYERSCAPE M: Minghuan Lian diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 7eeb969ab86a..dee90cc1dcaf 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -136,6 +136,7 @@ config PCI_HYPERV PCI devices from a PCI backend to support PCI driver domains. source "drivers/pci/hotplug/Kconfig" +source "drivers/pci/cadence/Kconfig" source "drivers/pci/dwc/Kconfig" source "drivers/pci/host/Kconfig" source "drivers/pci/endpoint/Kconfig" diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index ddb5aa6640d7..941970936840 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -56,5 +56,6 @@ obj-y += switch/ obj-$(CONFIG_PCI_ENDPOINT) += endpoint/ # Endpoint library must be initialized before its users +obj-$(CONFIG_PCIE_CADENCE) += cadence/ # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW obj-y += dwc/ diff --git a/drivers/pci/cadence/Kconfig b/drivers/pci/cadence/Kconfig new file mode 100644 index ..e6824cb56c16 --- /dev/null +++ b/drivers/pci/cadence/Kconfig @@ -0,0 +1,27 @@ +menu "Cadence PCIe controllers support" + +config PCIE_CADENCE + bool + +config PCIE_CADENCE_HOST + bool "Cadence PCIe host controller" + depends on OF + depends on PCI + select IRQ_DOMAIN + select PCIE_CADENCE + help + Say Y here if you want to support the Cadence PCIe controller in host + mode. This PCIe controller may be embedded into many different vendors + SoCs. + +config PCIE_CADENCE_EP + bool "Cadence PCIe endpoint controller" + depends on OF + depends on PCI_ENDPOINT + select PCIE_CADENCE + help + Say Y here if you want to support the Cadence PCIe controller in + endpoint mode. This PCIe controller may be embedded into many + different vendors SoCs. + +endmenu diff --git a/drivers/pci/cadence/Makefile b/drivers/pci/cadence/Makefile new file mode 100644 index ..719392b97998 --- /dev/null +++ b/drivers/pci/cadence/Makefile @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_PCIE_CADENCE) += pcie-cadence.o +obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host.o +obj-$(CONFIG_PCIE_CADENCE_EP) += pcie-cadence-ep.o diff --git a/drivers/pci/cadence/pcie-cadence-ep.c b/drivers/pci/cadence/pcie-cadence-ep.c new file mode 100644 index ..3c3a97743453 --- /dev/null +++ b/drivers/pci/cadence/pcie-cadence-ep.c @@ -0,0 +1,542 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2017 Cadence +// Cadence PCIe endpoint controller driver. +// Author: Cyrille Pitchen + +#include +#include +#include +#include +#include +#include +#include + +#include "pcie-cadence.h" + +#define CDNS_PCIE_EP_MIN_APERTURE 128 /* 128 bytes */ +#define CDNS_PCIE_EP_IRQ_PCI_ADDR_NONE 0x1 +#define CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY 0x3 + +/** + * struct cdns_pcie_ep - private data for this PCIe endpoint controller driver + * @pcie: Cadenc
[PATCH v5 06/11] dt-bindings: PCI: cadence: Add DT bindings for Cadence PCIe host controller
From: Scott Telford <stelf...@cadence.com> This patch adds documentation for the DT bindings of the Cadence PCIe controller when configured in host (Root Complex) mode. Signed-off-by: Scott Telford <stelf...@cadence.com> Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> Reviewed-by: Rob Herring <r...@kernel.org> --- .../bindings/pci/cdns,cdns-pcie-host.txt | 60 ++ 1 file changed, 60 insertions(+) create mode 100644 Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt diff --git a/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt new file mode 100644 index ..20a33f38f69d --- /dev/null +++ b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt @@ -0,0 +1,60 @@ +* Cadence PCIe host controller + +This PCIe controller inherits the base properties defined in +host-generic-pci.txt. + +Required properties: +- compatible: Should contain "cdns,cdns-pcie-host" to identify the IP used. +- reg: Should contain the controller register base address, PCIe configuration + window base address, and AXI interface region base address respectively. +- reg-names: Must be "reg", "cfg" and "mem" respectively. +- #address-cells: Set to <3> +- #size-cells: Set to <2> +- device_type: Set to "pci" +- ranges: Ranges for the PCI memory and I/O regions +- #interrupt-cells: Set to <1> +- interrupt-map-mask and interrupt-map: Standard PCI properties to define the + mapping of the PCIe interface to interrupt numbers. + +Optional properties: +- cdns,max-outbound-regions: Set to maximum number of outbound regions + (default 32) +- cdns,no-bar-match-nbits: Set into the no BAR match register to configure the + number of least significant bits kept during inbound (PCIe -> AXI) address + translations (default 32) +- vendor-id: The PCI vendor ID (16 bits, default is design dependent) +- device-id: The PCI device ID (16 bits, default is design dependent) + +Example: + +pcie@fb00 { + compatible = "cdns,cdns-pcie-host"; + device_type = "pci"; + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0x0 0xff>; + linux,pci-domain = <0>; + cdns,max-outbound-regions = <16>; + cdns,no-bar-match-nbits = <32>; + vendor-id = /bits/ 16 <0x17cd>; + device-id = /bits/ 16 <0x0200>; + + reg = <0x0 0xfb00 0x0 0x0100>, + <0x0 0x4100 0x0 0x1000>, + <0x0 0x4000 0x0 0x0400>; + reg-names = "reg", "cfg", "mem"; + + ranges = <0x0200 0x0 0x4200 0x0 0x4200 0x0 0x100>, +<0x0100 0x0 0x4300 0x0 0x4300 0x0 0x001>; + + #interrupt-cells = <0x1>; + + interrupt-map = <0x0 0x0 0x0 0x10x0 0x0 0x0 14 0x1 +0x0 0x0 0x0 0x20x0 0x0 0x0 15 0x1 +0x0 0x0 0x0 0x30x0 0x0 0x0 16 0x1 +0x0 0x0 0x0 0x40x0 0x0 0x0 17 0x1>; + + interrupt-map-mask = <0x0 0x0 0x0 0x7>; + + msi-parent = <_pci>; +}; -- 2.11.0
[PATCH v5 06/11] dt-bindings: PCI: cadence: Add DT bindings for Cadence PCIe host controller
From: Scott Telford This patch adds documentation for the DT bindings of the Cadence PCIe controller when configured in host (Root Complex) mode. Signed-off-by: Scott Telford Signed-off-by: Cyrille Pitchen Reviewed-by: Rob Herring --- .../bindings/pci/cdns,cdns-pcie-host.txt | 60 ++ 1 file changed, 60 insertions(+) create mode 100644 Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt diff --git a/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt new file mode 100644 index ..20a33f38f69d --- /dev/null +++ b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt @@ -0,0 +1,60 @@ +* Cadence PCIe host controller + +This PCIe controller inherits the base properties defined in +host-generic-pci.txt. + +Required properties: +- compatible: Should contain "cdns,cdns-pcie-host" to identify the IP used. +- reg: Should contain the controller register base address, PCIe configuration + window base address, and AXI interface region base address respectively. +- reg-names: Must be "reg", "cfg" and "mem" respectively. +- #address-cells: Set to <3> +- #size-cells: Set to <2> +- device_type: Set to "pci" +- ranges: Ranges for the PCI memory and I/O regions +- #interrupt-cells: Set to <1> +- interrupt-map-mask and interrupt-map: Standard PCI properties to define the + mapping of the PCIe interface to interrupt numbers. + +Optional properties: +- cdns,max-outbound-regions: Set to maximum number of outbound regions + (default 32) +- cdns,no-bar-match-nbits: Set into the no BAR match register to configure the + number of least significant bits kept during inbound (PCIe -> AXI) address + translations (default 32) +- vendor-id: The PCI vendor ID (16 bits, default is design dependent) +- device-id: The PCI device ID (16 bits, default is design dependent) + +Example: + +pcie@fb00 { + compatible = "cdns,cdns-pcie-host"; + device_type = "pci"; + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0x0 0xff>; + linux,pci-domain = <0>; + cdns,max-outbound-regions = <16>; + cdns,no-bar-match-nbits = <32>; + vendor-id = /bits/ 16 <0x17cd>; + device-id = /bits/ 16 <0x0200>; + + reg = <0x0 0xfb00 0x0 0x0100>, + <0x0 0x4100 0x0 0x1000>, + <0x0 0x4000 0x0 0x0400>; + reg-names = "reg", "cfg", "mem"; + + ranges = <0x0200 0x0 0x4200 0x0 0x4200 0x0 0x100>, +<0x0100 0x0 0x4300 0x0 0x4300 0x0 0x001>; + + #interrupt-cells = <0x1>; + + interrupt-map = <0x0 0x0 0x0 0x10x0 0x0 0x0 14 0x1 +0x0 0x0 0x0 0x20x0 0x0 0x0 15 0x1 +0x0 0x0 0x0 0x30x0 0x0 0x0 16 0x1 +0x0 0x0 0x0 0x40x0 0x0 0x0 17 0x1>; + + interrupt-map-mask = <0x0 0x0 0x0 0x7>; + + msi-parent = <_pci>; +}; -- 2.11.0
[PATCH v5 02/11] PCI: OF: Add generic function to parse and allocate PCI resources
The patch moves the gen_pci_parse_request_of_pci_ranges() function from drivers/pci/host/pci-host-common.c into drivers/pci/of.c to easily share common source code between PCI host drivers. Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> --- drivers/pci/host/pci-host-common.c | 49 ++-- drivers/pci/of.c | 51 ++ include/linux/pci.h| 9 +++ 3 files changed, 62 insertions(+), 47 deletions(-) diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c index c4b891c84703..a613ea310e76 100644 --- a/drivers/pci/host/pci-host-common.c +++ b/drivers/pci/host/pci-host-common.c @@ -24,50 +24,6 @@ #include #include -static int gen_pci_parse_request_of_pci_ranges(struct device *dev, - struct list_head *resources, struct resource **bus_range) -{ - int err, res_valid = 0; - struct device_node *np = dev->of_node; - resource_size_t iobase; - struct resource_entry *win, *tmp; - - err = of_pci_get_host_bridge_resources(np, 0, 0xff, resources, ); - if (err) - return err; - - err = devm_request_pci_bus_resources(dev, resources); - if (err) - return err; - - resource_list_for_each_entry_safe(win, tmp, resources) { - struct resource *res = win->res; - - switch (resource_type(res)) { - case IORESOURCE_IO: - err = pci_remap_iospace(res, iobase); - if (err) { - dev_warn(dev, "error %d: failed to map resource %pR\n", -err, res); - resource_list_destroy_entry(win); - } - break; - case IORESOURCE_MEM: - res_valid |= !(res->flags & IORESOURCE_PREFETCH); - break; - case IORESOURCE_BUS: - *bus_range = res; - break; - } - } - - if (res_valid) - return 0; - - dev_err(dev, "non-prefetchable memory resource required\n"); - return -EINVAL; -} - static void gen_pci_unmap_cfg(void *ptr) { pci_ecam_free((struct pci_config_window *)ptr); @@ -82,9 +38,9 @@ static struct pci_config_window *gen_pci_init(struct device *dev, struct pci_config_window *cfg; /* Parse our PCI ranges and request their resources */ - err = gen_pci_parse_request_of_pci_ranges(dev, resources, _range); + err = pci_parse_request_of_pci_ranges(dev, resources, _range); if (err) - goto err_out; + return ERR_PTR(err); err = of_address_to_resource(dev->of_node, 0, ); if (err) { @@ -135,7 +91,6 @@ int pci_host_common_probe(struct platform_device *pdev, of_pci_check_probe_only(); /* Parse and map our Configuration Space windows */ - INIT_LIST_HEAD(); cfg = gen_pci_init(dev, , ops); if (IS_ERR(cfg)) return PTR_ERR(cfg); diff --git a/drivers/pci/of.c b/drivers/pci/of.c index e81835bdf4fa..e1e37d020b4c 100644 --- a/drivers/pci/of.c +++ b/drivers/pci/of.c @@ -598,3 +598,54 @@ int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin) } EXPORT_SYMBOL_GPL(of_irq_parse_and_map_pci); #endif /* CONFIG_OF_IRQ */ + +int pci_parse_request_of_pci_ranges(struct device *dev, + struct list_head *resources, + struct resource **bus_range) +{ + int err, res_valid = 0; + struct device_node *np = dev->of_node; + resource_size_t iobase; + struct resource_entry *win, *tmp; + + INIT_LIST_HEAD(resources); + err = of_pci_get_host_bridge_resources(np, 0, 0xff, resources, ); + if (err) + return err; + + err = devm_request_pci_bus_resources(dev, resources); + if (err) + goto out_release_res; + + resource_list_for_each_entry_safe(win, tmp, resources) { + struct resource *res = win->res; + + switch (resource_type(res)) { + case IORESOURCE_IO: + err = pci_remap_iospace(res, iobase); + if (err) { + dev_warn(dev, "error %d: failed to map resource %pR\n", +err, res); + resource_list_destroy_entry(win); + } + break; + case IORESOURCE_MEM: + res_valid |= !(res->flags & IORESOURCE_PREFETCH); + break; + case IORESOURCE_BUS: + if (bus_range) +
[PATCH v5 08/11] PCI: endpoint: Add the function number as argument to EPC ops
This patch updates the prototype of most handlers from 'struct pci_epc_ops' so the EPC library can now support multi-function devices. Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> --- drivers/pci/dwc/pcie-designware-ep.c | 20 + drivers/pci/endpoint/functions/pci-epf-test.c | 41 ++ drivers/pci/endpoint/pci-epc-core.c | 62 --- include/linux/pci-epc.h | 43 +++ 4 files changed, 96 insertions(+), 70 deletions(-) diff --git a/drivers/pci/dwc/pcie-designware-ep.c b/drivers/pci/dwc/pcie-designware-ep.c index 51344794a0e6..cf5c4b4688ae 100644 --- a/drivers/pci/dwc/pcie-designware-ep.c +++ b/drivers/pci/dwc/pcie-designware-ep.c @@ -41,7 +41,7 @@ void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar) dw_pcie_dbi_ro_wr_dis(pci); } -static int dw_pcie_ep_write_header(struct pci_epc *epc, +static int dw_pcie_ep_write_header(struct pci_epc *epc, u8 func_no, struct pci_epf_header *hdr) { struct dw_pcie_ep *ep = epc_get_drvdata(epc); @@ -114,7 +114,8 @@ static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, phys_addr_t phys_addr, return 0; } -static void dw_pcie_ep_clear_bar(struct pci_epc *epc, enum pci_barno bar) +static void dw_pcie_ep_clear_bar(struct pci_epc *epc, u8 func_no, +enum pci_barno bar) { struct dw_pcie_ep *ep = epc_get_drvdata(epc); struct dw_pcie *pci = to_dw_pcie_from_ep(ep); @@ -126,7 +127,8 @@ static void dw_pcie_ep_clear_bar(struct pci_epc *epc, enum pci_barno bar) clear_bit(atu_index, ep->ib_window_map); } -static int dw_pcie_ep_set_bar(struct pci_epc *epc, enum pci_barno bar, +static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no, + enum pci_barno bar, dma_addr_t bar_phys, size_t size, int flags) { int ret; @@ -167,7 +169,8 @@ static int dw_pcie_find_index(struct dw_pcie_ep *ep, phys_addr_t addr, return -EINVAL; } -static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, phys_addr_t addr) +static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, u8 func_no, + phys_addr_t addr) { int ret; u32 atu_index; @@ -182,7 +185,8 @@ static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, phys_addr_t addr) clear_bit(atu_index, ep->ob_window_map); } -static int dw_pcie_ep_map_addr(struct pci_epc *epc, phys_addr_t addr, +static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 func_no, + phys_addr_t addr, u64 pci_addr, size_t size) { int ret; @@ -198,7 +202,7 @@ static int dw_pcie_ep_map_addr(struct pci_epc *epc, phys_addr_t addr, return 0; } -static int dw_pcie_ep_get_msi(struct pci_epc *epc) +static int dw_pcie_ep_get_msi(struct pci_epc *epc, u8 func_no) { int val; struct dw_pcie_ep *ep = epc_get_drvdata(epc); @@ -212,7 +216,7 @@ static int dw_pcie_ep_get_msi(struct pci_epc *epc) return val; } -static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 encode_int) +static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 encode_int) { int val; struct dw_pcie_ep *ep = epc_get_drvdata(epc); @@ -228,7 +232,7 @@ static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 encode_int) return 0; } -static int dw_pcie_ep_raise_irq(struct pci_epc *epc, +static int dw_pcie_ep_raise_irq(struct pci_epc *epc, u8 func_no, enum pci_epc_irq_type type, u8 interrupt_num) { struct dw_pcie_ep *ep = epc_get_drvdata(epc); diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c index f9308c2f22e6..7bacca8daec6 100644 --- a/drivers/pci/endpoint/functions/pci-epf-test.c +++ b/drivers/pci/endpoint/functions/pci-epf-test.c @@ -104,7 +104,8 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test) goto err; } - ret = pci_epc_map_addr(epc, src_phys_addr, reg->src_addr, reg->size); + ret = pci_epc_map_addr(epc, epf->func_no, src_phys_addr, reg->src_addr, + reg->size); if (ret) { dev_err(dev, "failed to map source address\n"); reg->status = STATUS_SRC_ADDR_INVALID; @@ -119,7 +120,8 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test) goto err_src_map_addr; } - ret = pci_epc_map_addr(epc, dst_phys_addr, reg->dst_addr, reg->size); + ret = pci_epc_map_addr(epc, epf->func_no, dst_phys_addr, reg->dst_addr, + reg->size); if (ret) { dev_err(dev, "failed to map destination address\n"); reg->status = STATUS_DST_ADD
[PATCH v5 02/11] PCI: OF: Add generic function to parse and allocate PCI resources
The patch moves the gen_pci_parse_request_of_pci_ranges() function from drivers/pci/host/pci-host-common.c into drivers/pci/of.c to easily share common source code between PCI host drivers. Signed-off-by: Cyrille Pitchen --- drivers/pci/host/pci-host-common.c | 49 ++-- drivers/pci/of.c | 51 ++ include/linux/pci.h| 9 +++ 3 files changed, 62 insertions(+), 47 deletions(-) diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c index c4b891c84703..a613ea310e76 100644 --- a/drivers/pci/host/pci-host-common.c +++ b/drivers/pci/host/pci-host-common.c @@ -24,50 +24,6 @@ #include #include -static int gen_pci_parse_request_of_pci_ranges(struct device *dev, - struct list_head *resources, struct resource **bus_range) -{ - int err, res_valid = 0; - struct device_node *np = dev->of_node; - resource_size_t iobase; - struct resource_entry *win, *tmp; - - err = of_pci_get_host_bridge_resources(np, 0, 0xff, resources, ); - if (err) - return err; - - err = devm_request_pci_bus_resources(dev, resources); - if (err) - return err; - - resource_list_for_each_entry_safe(win, tmp, resources) { - struct resource *res = win->res; - - switch (resource_type(res)) { - case IORESOURCE_IO: - err = pci_remap_iospace(res, iobase); - if (err) { - dev_warn(dev, "error %d: failed to map resource %pR\n", -err, res); - resource_list_destroy_entry(win); - } - break; - case IORESOURCE_MEM: - res_valid |= !(res->flags & IORESOURCE_PREFETCH); - break; - case IORESOURCE_BUS: - *bus_range = res; - break; - } - } - - if (res_valid) - return 0; - - dev_err(dev, "non-prefetchable memory resource required\n"); - return -EINVAL; -} - static void gen_pci_unmap_cfg(void *ptr) { pci_ecam_free((struct pci_config_window *)ptr); @@ -82,9 +38,9 @@ static struct pci_config_window *gen_pci_init(struct device *dev, struct pci_config_window *cfg; /* Parse our PCI ranges and request their resources */ - err = gen_pci_parse_request_of_pci_ranges(dev, resources, _range); + err = pci_parse_request_of_pci_ranges(dev, resources, _range); if (err) - goto err_out; + return ERR_PTR(err); err = of_address_to_resource(dev->of_node, 0, ); if (err) { @@ -135,7 +91,6 @@ int pci_host_common_probe(struct platform_device *pdev, of_pci_check_probe_only(); /* Parse and map our Configuration Space windows */ - INIT_LIST_HEAD(); cfg = gen_pci_init(dev, , ops); if (IS_ERR(cfg)) return PTR_ERR(cfg); diff --git a/drivers/pci/of.c b/drivers/pci/of.c index e81835bdf4fa..e1e37d020b4c 100644 --- a/drivers/pci/of.c +++ b/drivers/pci/of.c @@ -598,3 +598,54 @@ int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin) } EXPORT_SYMBOL_GPL(of_irq_parse_and_map_pci); #endif /* CONFIG_OF_IRQ */ + +int pci_parse_request_of_pci_ranges(struct device *dev, + struct list_head *resources, + struct resource **bus_range) +{ + int err, res_valid = 0; + struct device_node *np = dev->of_node; + resource_size_t iobase; + struct resource_entry *win, *tmp; + + INIT_LIST_HEAD(resources); + err = of_pci_get_host_bridge_resources(np, 0, 0xff, resources, ); + if (err) + return err; + + err = devm_request_pci_bus_resources(dev, resources); + if (err) + goto out_release_res; + + resource_list_for_each_entry_safe(win, tmp, resources) { + struct resource *res = win->res; + + switch (resource_type(res)) { + case IORESOURCE_IO: + err = pci_remap_iospace(res, iobase); + if (err) { + dev_warn(dev, "error %d: failed to map resource %pR\n", +err, res); + resource_list_destroy_entry(win); + } + break; + case IORESOURCE_MEM: + res_valid |= !(res->flags & IORESOURCE_PREFETCH); + break; + case IORESOURCE_BUS: + if (bus_range) +
[PATCH v5 08/11] PCI: endpoint: Add the function number as argument to EPC ops
This patch updates the prototype of most handlers from 'struct pci_epc_ops' so the EPC library can now support multi-function devices. Signed-off-by: Cyrille Pitchen --- drivers/pci/dwc/pcie-designware-ep.c | 20 + drivers/pci/endpoint/functions/pci-epf-test.c | 41 ++ drivers/pci/endpoint/pci-epc-core.c | 62 --- include/linux/pci-epc.h | 43 +++ 4 files changed, 96 insertions(+), 70 deletions(-) diff --git a/drivers/pci/dwc/pcie-designware-ep.c b/drivers/pci/dwc/pcie-designware-ep.c index 51344794a0e6..cf5c4b4688ae 100644 --- a/drivers/pci/dwc/pcie-designware-ep.c +++ b/drivers/pci/dwc/pcie-designware-ep.c @@ -41,7 +41,7 @@ void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar) dw_pcie_dbi_ro_wr_dis(pci); } -static int dw_pcie_ep_write_header(struct pci_epc *epc, +static int dw_pcie_ep_write_header(struct pci_epc *epc, u8 func_no, struct pci_epf_header *hdr) { struct dw_pcie_ep *ep = epc_get_drvdata(epc); @@ -114,7 +114,8 @@ static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, phys_addr_t phys_addr, return 0; } -static void dw_pcie_ep_clear_bar(struct pci_epc *epc, enum pci_barno bar) +static void dw_pcie_ep_clear_bar(struct pci_epc *epc, u8 func_no, +enum pci_barno bar) { struct dw_pcie_ep *ep = epc_get_drvdata(epc); struct dw_pcie *pci = to_dw_pcie_from_ep(ep); @@ -126,7 +127,8 @@ static void dw_pcie_ep_clear_bar(struct pci_epc *epc, enum pci_barno bar) clear_bit(atu_index, ep->ib_window_map); } -static int dw_pcie_ep_set_bar(struct pci_epc *epc, enum pci_barno bar, +static int dw_pcie_ep_set_bar(struct pci_epc *epc, u8 func_no, + enum pci_barno bar, dma_addr_t bar_phys, size_t size, int flags) { int ret; @@ -167,7 +169,8 @@ static int dw_pcie_find_index(struct dw_pcie_ep *ep, phys_addr_t addr, return -EINVAL; } -static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, phys_addr_t addr) +static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, u8 func_no, + phys_addr_t addr) { int ret; u32 atu_index; @@ -182,7 +185,8 @@ static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, phys_addr_t addr) clear_bit(atu_index, ep->ob_window_map); } -static int dw_pcie_ep_map_addr(struct pci_epc *epc, phys_addr_t addr, +static int dw_pcie_ep_map_addr(struct pci_epc *epc, u8 func_no, + phys_addr_t addr, u64 pci_addr, size_t size) { int ret; @@ -198,7 +202,7 @@ static int dw_pcie_ep_map_addr(struct pci_epc *epc, phys_addr_t addr, return 0; } -static int dw_pcie_ep_get_msi(struct pci_epc *epc) +static int dw_pcie_ep_get_msi(struct pci_epc *epc, u8 func_no) { int val; struct dw_pcie_ep *ep = epc_get_drvdata(epc); @@ -212,7 +216,7 @@ static int dw_pcie_ep_get_msi(struct pci_epc *epc) return val; } -static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 encode_int) +static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 func_no, u8 encode_int) { int val; struct dw_pcie_ep *ep = epc_get_drvdata(epc); @@ -228,7 +232,7 @@ static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 encode_int) return 0; } -static int dw_pcie_ep_raise_irq(struct pci_epc *epc, +static int dw_pcie_ep_raise_irq(struct pci_epc *epc, u8 func_no, enum pci_epc_irq_type type, u8 interrupt_num) { struct dw_pcie_ep *ep = epc_get_drvdata(epc); diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c index f9308c2f22e6..7bacca8daec6 100644 --- a/drivers/pci/endpoint/functions/pci-epf-test.c +++ b/drivers/pci/endpoint/functions/pci-epf-test.c @@ -104,7 +104,8 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test) goto err; } - ret = pci_epc_map_addr(epc, src_phys_addr, reg->src_addr, reg->size); + ret = pci_epc_map_addr(epc, epf->func_no, src_phys_addr, reg->src_addr, + reg->size); if (ret) { dev_err(dev, "failed to map source address\n"); reg->status = STATUS_SRC_ADDR_INVALID; @@ -119,7 +120,8 @@ static int pci_epf_test_copy(struct pci_epf_test *epf_test) goto err_src_map_addr; } - ret = pci_epc_map_addr(epc, dst_phys_addr, reg->dst_addr, reg->size); + ret = pci_epc_map_addr(epc, epf->func_no, dst_phys_addr, reg->dst_addr, + reg->size); if (ret) { dev_err(dev, "failed to map destination address\n"); reg->status = STATUS_DST_ADDR_INVALID; @@ -128,13 +130,13 @@ static int pci_
[PATCH v5 10/11] dt-bindings: PCI: cadence: Add DT bindings for Cadence PCIe endpoint controller
This patch documents the DT bindings for the Cadence PCIe controller when configured in endpoint mode. Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> Reviewed-by: Rob Herring <r...@kernel.org> --- .../devicetree/bindings/pci/cdns,cdns-pcie-ep.txt | 22 ++ 1 file changed, 22 insertions(+) create mode 100644 Documentation/devicetree/bindings/pci/cdns,cdns-pcie-ep.txt diff --git a/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-ep.txt b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-ep.txt new file mode 100644 index ..9a305237fa6e --- /dev/null +++ b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-ep.txt @@ -0,0 +1,22 @@ +* Cadence PCIe endpoint controller + +Required properties: +- compatible: Should contain "cdns,cdns-pcie-ep" to identify the IP used. +- reg: Should contain the controller register base address and AXI interface + region base address respectively. +- reg-names: Must be "reg" and "mem" respectively. +- cdns,max-outbound-regions: Set to maximum number of outbound regions + +Optional properties: +- max-functions: Maximum number of functions that can be configured (default 1). + +Example: + +pcie@fc00 { + compatible = "cdns,cdns-pcie-ep"; + reg = <0x0 0xfc00 0x0 0x0100>, + <0x0 0x8000 0x0 0x4000>; + reg-names = "reg", "mem"; + cdns,max-outbound-regions = <16>; + max-functions = /bits/ 8 <8>; +}; -- 2.11.0
[PATCH v5 10/11] dt-bindings: PCI: cadence: Add DT bindings for Cadence PCIe endpoint controller
This patch documents the DT bindings for the Cadence PCIe controller when configured in endpoint mode. Signed-off-by: Cyrille Pitchen Reviewed-by: Rob Herring --- .../devicetree/bindings/pci/cdns,cdns-pcie-ep.txt | 22 ++ 1 file changed, 22 insertions(+) create mode 100644 Documentation/devicetree/bindings/pci/cdns,cdns-pcie-ep.txt diff --git a/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-ep.txt b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-ep.txt new file mode 100644 index ..9a305237fa6e --- /dev/null +++ b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-ep.txt @@ -0,0 +1,22 @@ +* Cadence PCIe endpoint controller + +Required properties: +- compatible: Should contain "cdns,cdns-pcie-ep" to identify the IP used. +- reg: Should contain the controller register base address and AXI interface + region base address respectively. +- reg-names: Must be "reg" and "mem" respectively. +- cdns,max-outbound-regions: Set to maximum number of outbound regions + +Optional properties: +- max-functions: Maximum number of functions that can be configured (default 1). + +Example: + +pcie@fc00 { + compatible = "cdns,cdns-pcie-ep"; + reg = <0x0 0xfc00 0x0 0x0100>, + <0x0 0x8000 0x0 0x4000>; + reg-names = "reg", "mem"; + cdns,max-outbound-regions = <16>; + max-functions = /bits/ 8 <8>; +}; -- 2.11.0
[PATCH v5 07/11] PCI: cadence: Add host driver for Cadence PCIe controller
This patch adds support to the Cadence PCIe controller in host mode. Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> --- MAINTAINERS | 7 + drivers/pci/host/Kconfig | 10 + drivers/pci/host/Makefile| 1 + drivers/pci/host/pcie-cadence-host.c | 397 +++ drivers/pci/host/pcie-cadence.h | 189 + 5 files changed, 604 insertions(+) create mode 100644 drivers/pci/host/pcie-cadence-host.c create mode 100644 drivers/pci/host/pcie-cadence.h diff --git a/MAINTAINERS b/MAINTAINERS index 13945646b95d..08b2e5390a7e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10402,6 +10402,13 @@ S: Maintained F: Documentation/devicetree/bindings/pci/pci-armada8k.txt F: drivers/pci/dwc/pcie-armada8k.c +PCI DRIVER FOR CADENCE PCIE IP +M: Alan Douglas <adoug...@cadence.com> +L: linux-...@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/pci/cdns,*.txt +F: drivers/pci/host/pcie-cadence* + PCI DRIVER FOR FREESCALE LAYERSCAPE M: Minghuan Lian <minghuan.l...@freescale.com> M: Mingkai Hu <mingkai...@freescale.com> diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig index 38d12980db0f..d6866733d69d 100644 --- a/drivers/pci/host/Kconfig +++ b/drivers/pci/host/Kconfig @@ -210,6 +210,16 @@ config PCIE_TANGO_SMP8759 This can lead to data corruption if drivers perform concurrent config and MMIO accesses. +config PCIE_CADENCE_HOST + bool "Cadence PCIe host controller" + depends on OF + depends on PCI + select IRQ_DOMAIN + help + Say Y here if you want to support the Cadence PCIe controller in host + mode. This PCIe controller may be embedded into many different vendors + SoCs. + config VMD depends on PCI_MSI && X86_64 && SRCU tristate "Intel Volume Management Device Driver" diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile index 3b1059190867..2460f0785120 100644 --- a/drivers/pci/host/Makefile +++ b/drivers/pci/host/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o obj-$(CONFIG_PCIE_ROCKCHIP) += pcie-rockchip.o obj-$(CONFIG_PCIE_MEDIATEK) += pcie-mediatek.o obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-tango.o +obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host.o obj-$(CONFIG_VMD) += vmd.o # The following drivers are for devices that use the generic ACPI diff --git a/drivers/pci/host/pcie-cadence-host.c b/drivers/pci/host/pcie-cadence-host.c new file mode 100644 index ..9332601845ea --- /dev/null +++ b/drivers/pci/host/pcie-cadence-host.c @@ -0,0 +1,397 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2017 Cadence +// Cadence PCIe host controller driver. +// Author: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> + +#include +#include +#include +#include +#include + +#include "pcie-cadence.h" + +/** + * struct cdns_pcie_rc - private data for this PCIe Root Complex driver + * @pcie: Cadence PCIe controller + * @dev: pointer to PCIe device + * @cfg_res: start/end offsets in the physical system memory to map PCI + * configuration space accesses + * @bus_range: first/last buses behind the PCIe host controller + * @cfg_base: IO mapped window to access the PCI configuration space of a + *single function at a time + * @max_regions: maximum number of regions supported by the hardware + * @no_bar_nbits: Number of bits to keep for inbound (PCIe -> CPU) address + *translation (nbits sets into the "no BAR match" register) + * @vendor_id: PCI vendor ID + * @device_id: PCI device ID + */ +struct cdns_pcie_rc { + struct cdns_pciepcie; + struct device *dev; + struct resource *cfg_res; + struct resource *bus_range; + void __iomem*cfg_base; + u32 max_regions; + u32 no_bar_nbits; + u16 vendor_id; + u16 device_id; +}; + +static void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, + u32 r, bool is_io, + u64 cpu_addr, u64 pci_addr, size_t size) +{ + /* +* roundup_pow_of_two() returns an unsigned long, which is not suited +* for 64bit values. +*/ + u64 sz = 1ULL << fls64(size - 1); + int nbits = ilog2(sz); + u32 addr0, addr1, desc0, desc1; + + if (nbits < 8) + nbits = 8; + + /* Set the PCI address */ + addr0 = CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_NBITS(nbits) | + (lower_32_bits(pci_addr) & GENMASK(31, 8)); + addr1 = upper_32_bits(pci_addr); + + cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR0(r)
[PATCH v5 07/11] PCI: cadence: Add host driver for Cadence PCIe controller
This patch adds support to the Cadence PCIe controller in host mode. Signed-off-by: Cyrille Pitchen --- MAINTAINERS | 7 + drivers/pci/host/Kconfig | 10 + drivers/pci/host/Makefile| 1 + drivers/pci/host/pcie-cadence-host.c | 397 +++ drivers/pci/host/pcie-cadence.h | 189 + 5 files changed, 604 insertions(+) create mode 100644 drivers/pci/host/pcie-cadence-host.c create mode 100644 drivers/pci/host/pcie-cadence.h diff --git a/MAINTAINERS b/MAINTAINERS index 13945646b95d..08b2e5390a7e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10402,6 +10402,13 @@ S: Maintained F: Documentation/devicetree/bindings/pci/pci-armada8k.txt F: drivers/pci/dwc/pcie-armada8k.c +PCI DRIVER FOR CADENCE PCIE IP +M: Alan Douglas +L: linux-...@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/pci/cdns,*.txt +F: drivers/pci/host/pcie-cadence* + PCI DRIVER FOR FREESCALE LAYERSCAPE M: Minghuan Lian M: Mingkai Hu diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig index 38d12980db0f..d6866733d69d 100644 --- a/drivers/pci/host/Kconfig +++ b/drivers/pci/host/Kconfig @@ -210,6 +210,16 @@ config PCIE_TANGO_SMP8759 This can lead to data corruption if drivers perform concurrent config and MMIO accesses. +config PCIE_CADENCE_HOST + bool "Cadence PCIe host controller" + depends on OF + depends on PCI + select IRQ_DOMAIN + help + Say Y here if you want to support the Cadence PCIe controller in host + mode. This PCIe controller may be embedded into many different vendors + SoCs. + config VMD depends on PCI_MSI && X86_64 && SRCU tristate "Intel Volume Management Device Driver" diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile index 3b1059190867..2460f0785120 100644 --- a/drivers/pci/host/Makefile +++ b/drivers/pci/host/Makefile @@ -22,6 +22,7 @@ obj-$(CONFIG_PCIE_ALTERA_MSI) += pcie-altera-msi.o obj-$(CONFIG_PCIE_ROCKCHIP) += pcie-rockchip.o obj-$(CONFIG_PCIE_MEDIATEK) += pcie-mediatek.o obj-$(CONFIG_PCIE_TANGO_SMP8759) += pcie-tango.o +obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host.o obj-$(CONFIG_VMD) += vmd.o # The following drivers are for devices that use the generic ACPI diff --git a/drivers/pci/host/pcie-cadence-host.c b/drivers/pci/host/pcie-cadence-host.c new file mode 100644 index ..9332601845ea --- /dev/null +++ b/drivers/pci/host/pcie-cadence-host.c @@ -0,0 +1,397 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2017 Cadence +// Cadence PCIe host controller driver. +// Author: Cyrille Pitchen + +#include +#include +#include +#include +#include + +#include "pcie-cadence.h" + +/** + * struct cdns_pcie_rc - private data for this PCIe Root Complex driver + * @pcie: Cadence PCIe controller + * @dev: pointer to PCIe device + * @cfg_res: start/end offsets in the physical system memory to map PCI + * configuration space accesses + * @bus_range: first/last buses behind the PCIe host controller + * @cfg_base: IO mapped window to access the PCI configuration space of a + *single function at a time + * @max_regions: maximum number of regions supported by the hardware + * @no_bar_nbits: Number of bits to keep for inbound (PCIe -> CPU) address + *translation (nbits sets into the "no BAR match" register) + * @vendor_id: PCI vendor ID + * @device_id: PCI device ID + */ +struct cdns_pcie_rc { + struct cdns_pciepcie; + struct device *dev; + struct resource *cfg_res; + struct resource *bus_range; + void __iomem*cfg_base; + u32 max_regions; + u32 no_bar_nbits; + u16 vendor_id; + u16 device_id; +}; + +static void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, + u32 r, bool is_io, + u64 cpu_addr, u64 pci_addr, size_t size) +{ + /* +* roundup_pow_of_two() returns an unsigned long, which is not suited +* for 64bit values. +*/ + u64 sz = 1ULL << fls64(size - 1); + int nbits = ilog2(sz); + u32 addr0, addr1, desc0, desc1; + + if (nbits < 8) + nbits = 8; + + /* Set the PCI address */ + addr0 = CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_NBITS(nbits) | + (lower_32_bits(pci_addr) & GENMASK(31, 8)); + addr1 = upper_32_bits(pci_addr); + + cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR0(r), addr0); + cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR1(r), addr1); + + /* Set the PCIe header descriptor */ + if (is_io) + desc0 =
Re: [PATCH v4 0/7] PCI: Add support to the Cadence PCIe controller
Le 18/01/2018 à 23:52, Cyrille Pitchen a écrit : > Hi all, > > this series of patches adds support to the Cadence PCIe controller. > It was tested on a ARM64 platform emulated by a Palladium running the > pci-next kernel. > > The host mode was tested with some PCIe devices connected to the Palladium > through a speed-bridge. Some of those devices were a USB host controller > and a SATA controller. The PCIe host controller was also tested with a > second controller configured in endpoint mode and connected back to back > to the first controller. > > The EndPoint Controller (EPC) driver was removed only because I didn't > have time to take all Kishon's comments into account. However, using a > fixed patch based on patch 7 of the v2 series + another patch fixing > the EPF device name chosen by pci_epf_make(), I was abled to probe > both function 0 and function 1 of the of the 2nd Cadence PCIe controller > configured in endpoint mode (new hardware design since v2 so function 1 > is now available). > > Currently I'm facing 2 issues, which I didn't have enough time to > investigate and to fix yet: > > 1 - when the vendor:device IDs are set to 104c:b500 for both functions, > then I remove both devfn (echo 1 > /sys/bus/pci/devices/$BDF/remove) > before scanning the PCI bus again (echo 1 > /sys/bus/pci/rescan), > the PCI enumeration fails reporting that the PCI memory is exhausted. > > 2 - when I set the vendor:device IDs to 104c:0100 for function 0 and > 104c:b500 and remove only function 1 before scanning the PCI bus again, > I now pass the PCI enumeration. I also pass the 'pcitest -b ' test > but I fail on the MSI test ('pcitest -m '). > > I'm still investigating on those issues. > Both issues fixed: 1 - For the 1st issue, I was removing endpoint devfn instead of the host controller itself. Then when I configured and enabled the 2nd endpoint function (endpoint side) before scanning the PCI bus again (host side), the memory window for the PCI bridge was not resized, hence there was no space left for BARs of the 2nd endpoint fonction. Now that I remove the host controller itself (bus 0, dev 0, func 0) instead of the endpoint functions, it works: # BDF=":00:00.0" # echo 1 > /sys/bus/pci/devices/$BDF/remove # echo 1 > /sys/bus/pci/rescan The memory window for the PCI bridge is resized as needed and the 6 BARs of each endpoint function can successfully be allocated during the new PCI enumeration. 2 - For the 2nd issue, I added a new parameter to cdns_pcie_set_outbound_region() to pass the function number and now pcitest -m [1 - 32] [-D ] works for both endpoint functions. Finally, I'm able to use both endpoint functions at the same time with pcitest. I guess I'll send v5 within few days moving the endpoint controller driver back into the series. Best regards, Cyrille > Best regards, > > Cyrille > > ChangeLog > > v3 -> v4: > - split patch 3 from v3 into patches 3 and 4. > - remove unused cdns_pcie_reset_outbound_region() from old patch 6 > (new patch 7). > - other patches are unchanged. > > v2 -> v3: > > - rebase on today's linux-pci/next (20180110) > > patch1: > - rework the commit message of patch 1 and add two new comments on why > endpoint > library users must be linked after the endpoint library itself and why > the dwc rule uses obj-y instead of obj-$(CONFIG_PCIE_CONFIG_DW). > - update patch 1 to add missing ifdef CONFIG_PCI / endif in > drivers/pci/dwc/Makefile around the obj-$(CONFIG_ARM64) += pcie-hisi.o rule, > like for the other obj-$(CONFIG_ARM64) rules in drivers/pci/host/Makefile. > > patch2: unchanged > > patch3: > - update patch 3 so the bridge hooks/members initialization is left to the > host bridges probe routines. > > patch4: unchanged > > patch5: > - collect 'Reviewed-by' tag from Rob Herring for the DT bindings. > > patch6: > - remove explanation in the commit message on why obj-$(CONFIG_PCIE_CANDENCE) > is > placed after obj-$(CONFIG_PCI_ENDPOINT) in drivers/pci/Makefile since a > comment on it has been added into patch1. > - remove menuconfig PCI_CADENCE in drivers/pci/cadence/Kconfig to match > drivers/pci/dwc/Kconfig. > - adapt patch6 to the changes done in patch3 for the pci_host_probe() > function. > > v1 -> v2: > - add new properties in the device-tree bindings: 'cdns,max-outbound-regions' > and 'cdns,no-bar-match-nbits'. > - add a new patch to regroup all makefile rules in drivers/pci/Makefile, hence > cleaning drivers/Makefile up. > - change the license text to use the recommanded format: > // SPDX-License-Identifier: GPL-2.0 > - add a new patch updating the API of the EPC library to add support to > multi-function devices
Re: [PATCH v4 0/7] PCI: Add support to the Cadence PCIe controller
Le 18/01/2018 à 23:52, Cyrille Pitchen a écrit : > Hi all, > > this series of patches adds support to the Cadence PCIe controller. > It was tested on a ARM64 platform emulated by a Palladium running the > pci-next kernel. > > The host mode was tested with some PCIe devices connected to the Palladium > through a speed-bridge. Some of those devices were a USB host controller > and a SATA controller. The PCIe host controller was also tested with a > second controller configured in endpoint mode and connected back to back > to the first controller. > > The EndPoint Controller (EPC) driver was removed only because I didn't > have time to take all Kishon's comments into account. However, using a > fixed patch based on patch 7 of the v2 series + another patch fixing > the EPF device name chosen by pci_epf_make(), I was abled to probe > both function 0 and function 1 of the of the 2nd Cadence PCIe controller > configured in endpoint mode (new hardware design since v2 so function 1 > is now available). > > Currently I'm facing 2 issues, which I didn't have enough time to > investigate and to fix yet: > > 1 - when the vendor:device IDs are set to 104c:b500 for both functions, > then I remove both devfn (echo 1 > /sys/bus/pci/devices/$BDF/remove) > before scanning the PCI bus again (echo 1 > /sys/bus/pci/rescan), > the PCI enumeration fails reporting that the PCI memory is exhausted. > > 2 - when I set the vendor:device IDs to 104c:0100 for function 0 and > 104c:b500 and remove only function 1 before scanning the PCI bus again, > I now pass the PCI enumeration. I also pass the 'pcitest -b ' test > but I fail on the MSI test ('pcitest -m '). > > I'm still investigating on those issues. > Both issues fixed: 1 - For the 1st issue, I was removing endpoint devfn instead of the host controller itself. Then when I configured and enabled the 2nd endpoint function (endpoint side) before scanning the PCI bus again (host side), the memory window for the PCI bridge was not resized, hence there was no space left for BARs of the 2nd endpoint fonction. Now that I remove the host controller itself (bus 0, dev 0, func 0) instead of the endpoint functions, it works: # BDF=":00:00.0" # echo 1 > /sys/bus/pci/devices/$BDF/remove # echo 1 > /sys/bus/pci/rescan The memory window for the PCI bridge is resized as needed and the 6 BARs of each endpoint function can successfully be allocated during the new PCI enumeration. 2 - For the 2nd issue, I added a new parameter to cdns_pcie_set_outbound_region() to pass the function number and now pcitest -m [1 - 32] [-D ] works for both endpoint functions. Finally, I'm able to use both endpoint functions at the same time with pcitest. I guess I'll send v5 within few days moving the endpoint controller driver back into the series. Best regards, Cyrille > Best regards, > > Cyrille > > ChangeLog > > v3 -> v4: > - split patch 3 from v3 into patches 3 and 4. > - remove unused cdns_pcie_reset_outbound_region() from old patch 6 > (new patch 7). > - other patches are unchanged. > > v2 -> v3: > > - rebase on today's linux-pci/next (20180110) > > patch1: > - rework the commit message of patch 1 and add two new comments on why > endpoint > library users must be linked after the endpoint library itself and why > the dwc rule uses obj-y instead of obj-$(CONFIG_PCIE_CONFIG_DW). > - update patch 1 to add missing ifdef CONFIG_PCI / endif in > drivers/pci/dwc/Makefile around the obj-$(CONFIG_ARM64) += pcie-hisi.o rule, > like for the other obj-$(CONFIG_ARM64) rules in drivers/pci/host/Makefile. > > patch2: unchanged > > patch3: > - update patch 3 so the bridge hooks/members initialization is left to the > host bridges probe routines. > > patch4: unchanged > > patch5: > - collect 'Reviewed-by' tag from Rob Herring for the DT bindings. > > patch6: > - remove explanation in the commit message on why obj-$(CONFIG_PCIE_CANDENCE) > is > placed after obj-$(CONFIG_PCI_ENDPOINT) in drivers/pci/Makefile since a > comment on it has been added into patch1. > - remove menuconfig PCI_CADENCE in drivers/pci/cadence/Kconfig to match > drivers/pci/dwc/Kconfig. > - adapt patch6 to the changes done in patch3 for the pci_host_probe() > function. > > v1 -> v2: > - add new properties in the device-tree bindings: 'cdns,max-outbound-regions' > and 'cdns,no-bar-match-nbits'. > - add a new patch to regroup all makefile rules in drivers/pci/Makefile, hence > cleaning drivers/Makefile up. > - change the license text to use the recommanded format: > // SPDX-License-Identifier: GPL-2.0 > - add a new patch updating the API of the EPC library to add support to > multi-function devices
Re: [PATCH v3 6/6] PCI: cadence: Add host driver for Cadence PCIe controller
Hi Lorenzo Le 16/01/2018 à 17:07, Lorenzo Pieralisi a écrit : > On Wed, Jan 10, 2018 at 11:47:35PM +0100, Cyrille Pitchen wrote: >> This patch adds support to the Cadence PCIe controller in host mode. >> >> Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> >> --- >> MAINTAINERS | 7 + >> drivers/pci/Kconfig | 1 + >> drivers/pci/Makefile| 1 + >> drivers/pci/cadence/Kconfig | 16 ++ >> drivers/pci/cadence/Makefile| 3 + >> drivers/pci/cadence/pcie-cadence-host.c | 336 >> >> drivers/pci/cadence/pcie-cadence.c | 68 +++ >> drivers/pci/cadence/pcie-cadence.h | 196 +++ > > [...] > >> +void cdns_pcie_reset_outbound_region(struct cdns_pcie *pcie, u32 r) >> +{ >> +cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR0(r), 0); >> +cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR1(r), 0); >> + >> +cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC0(r), 0); >> +cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC1(r), 0); >> + >> +cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR0(r), 0); >> +cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR1(r), 0); >> +} > > Unused function, please remove it. done in v4. > >> diff --git a/drivers/pci/cadence/pcie-cadence.h >> b/drivers/pci/cadence/pcie-cadence.h >> new file mode 100644 >> index ..3a15b4016352 >> --- /dev/null >> +++ b/drivers/pci/cadence/pcie-cadence.h >> @@ -0,0 +1,196 @@ >> +// SPDX-License-Identifier: GPL-2.0 >> +// Copyright (c) 2017 Cadence >> +// Cadence PCIe controller driver. >> +// Author: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> >> + >> +#ifndef _PCIE_CADENCE_H >> +#define _PCIE_CADENCE_H >> + >> +#include >> +#include >> + >> +/* >> + * Local Management Registers >> + */ >> +#define CDNS_PCIE_LM_BASE 0x0010 >> + >> +/* Vendor ID Register */ >> +#define CDNS_PCIE_LM_ID (CDNS_PCIE_LM_BASE + 0x0044) >> +#define CDNS_PCIE_LM_ID_VENDOR_MASKGENMASK(15, 0) >> +#define CDNS_PCIE_LM_ID_VENDOR_SHIFT 0 >> +#define CDNS_PCIE_LM_ID_VENDOR(vid) \ >> +(((vid) << CDNS_PCIE_LM_ID_VENDOR_SHIFT) & CDNS_PCIE_LM_ID_VENDOR_MASK) >> +#define CDNS_PCIE_LM_ID_SUBSYS_MASKGENMASK(31, 16) >> +#define CDNS_PCIE_LM_ID_SUBSYS_SHIFT 16 >> +#define CDNS_PCIE_LM_ID_SUBSYS(sub) \ >> +(((sub) << CDNS_PCIE_LM_ID_SUBSYS_SHIFT) & CDNS_PCIE_LM_ID_SUBSYS_MASK) >> + >> +/* Root Port Requestor ID Register */ >> +#define CDNS_PCIE_LM_RP_RID (CDNS_PCIE_LM_BASE + 0x0228) >> +#define CDNS_PCIE_LM_RP_RID_MASK GENMASK(15, 0) >> +#define CDNS_PCIE_LM_RP_RID_SHIFT 0 >> +#define CDNS_PCIE_LM_RP_RID_(rid) \ >> +(((rid) << CDNS_PCIE_LM_RP_RID_SHIFT) & CDNS_PCIE_LM_RP_RID_MASK) >> + >> +/* Root Complex BAR Configuration Register */ >> +#define CDNS_PCIE_LM_RC_BAR_CFG (CDNS_PCIE_LM_BASE + 0x0300) >> +#define CDNS_PCIE_LM_RC_BAR_CFG_BAR0_APERTURE_MASK GENMASK(5, 0) >> +#define CDNS_PCIE_LM_RC_BAR_CFG_BAR0_APERTURE(a) \ >> +(((a) << 0) & CDNS_PCIE_LM_RC_BAR_CFG_BAR0_APERTURE_MASK) >> +#define CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL_MASK GENMASK(8, 6) >> +#define CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL(c) \ >> +(((c) << 6) & CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL_MASK) >> +#define CDNS_PCIE_LM_RC_BAR_CFG_BAR1_APERTURE_MASK GENMASK(13, 9) >> +#define CDNS_PCIE_LM_RC_BAR_CFG_BAR1_APERTURE(a) \ >> +(((a) << 9) & CDNS_PCIE_LM_RC_BAR_CFG_BAR1_APERTURE_MASK) >> +#define CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL_MASK GENMASK(16, 14) >> +#define CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL(c) \ >> +(((c) << 14) & CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL_MASK) >> +#define CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_ENABLEBIT(17) >> +#define CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_32BITS0 >> +#define CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_64BITSBIT(18) >> +#define CDNS_PCIE_LM_RC_BAR_CFG_IO_ENABLE BIT(19) >> +#define CDNS_PCIE_LM_RC_BAR_CFG_IO_16BITS 0 >> +#define CDNS_PCIE_LM_RC_BAR_CFG_IO_32BITS BIT(20) >> +#define CDNS_PCIE_LM_RC_BAR_CFG_CHECK_ENABLE BIT(31) >> + >> +/* BAR control values applicable to both Endpoint Function and Root Complex >> */ >> +#define CDNS_PCIE_LM_BAR_CFG_CTRL_DISA
Re: [PATCH v3 6/6] PCI: cadence: Add host driver for Cadence PCIe controller
Hi Lorenzo Le 16/01/2018 à 17:07, Lorenzo Pieralisi a écrit : > On Wed, Jan 10, 2018 at 11:47:35PM +0100, Cyrille Pitchen wrote: >> This patch adds support to the Cadence PCIe controller in host mode. >> >> Signed-off-by: Cyrille Pitchen >> --- >> MAINTAINERS | 7 + >> drivers/pci/Kconfig | 1 + >> drivers/pci/Makefile| 1 + >> drivers/pci/cadence/Kconfig | 16 ++ >> drivers/pci/cadence/Makefile| 3 + >> drivers/pci/cadence/pcie-cadence-host.c | 336 >> >> drivers/pci/cadence/pcie-cadence.c | 68 +++ >> drivers/pci/cadence/pcie-cadence.h | 196 +++ > > [...] > >> +void cdns_pcie_reset_outbound_region(struct cdns_pcie *pcie, u32 r) >> +{ >> +cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR0(r), 0); >> +cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR1(r), 0); >> + >> +cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC0(r), 0); >> +cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC1(r), 0); >> + >> +cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR0(r), 0); >> +cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR1(r), 0); >> +} > > Unused function, please remove it. done in v4. > >> diff --git a/drivers/pci/cadence/pcie-cadence.h >> b/drivers/pci/cadence/pcie-cadence.h >> new file mode 100644 >> index ..3a15b4016352 >> --- /dev/null >> +++ b/drivers/pci/cadence/pcie-cadence.h >> @@ -0,0 +1,196 @@ >> +// SPDX-License-Identifier: GPL-2.0 >> +// Copyright (c) 2017 Cadence >> +// Cadence PCIe controller driver. >> +// Author: Cyrille Pitchen >> + >> +#ifndef _PCIE_CADENCE_H >> +#define _PCIE_CADENCE_H >> + >> +#include >> +#include >> + >> +/* >> + * Local Management Registers >> + */ >> +#define CDNS_PCIE_LM_BASE 0x0010 >> + >> +/* Vendor ID Register */ >> +#define CDNS_PCIE_LM_ID (CDNS_PCIE_LM_BASE + 0x0044) >> +#define CDNS_PCIE_LM_ID_VENDOR_MASKGENMASK(15, 0) >> +#define CDNS_PCIE_LM_ID_VENDOR_SHIFT 0 >> +#define CDNS_PCIE_LM_ID_VENDOR(vid) \ >> +(((vid) << CDNS_PCIE_LM_ID_VENDOR_SHIFT) & CDNS_PCIE_LM_ID_VENDOR_MASK) >> +#define CDNS_PCIE_LM_ID_SUBSYS_MASKGENMASK(31, 16) >> +#define CDNS_PCIE_LM_ID_SUBSYS_SHIFT 16 >> +#define CDNS_PCIE_LM_ID_SUBSYS(sub) \ >> +(((sub) << CDNS_PCIE_LM_ID_SUBSYS_SHIFT) & CDNS_PCIE_LM_ID_SUBSYS_MASK) >> + >> +/* Root Port Requestor ID Register */ >> +#define CDNS_PCIE_LM_RP_RID (CDNS_PCIE_LM_BASE + 0x0228) >> +#define CDNS_PCIE_LM_RP_RID_MASK GENMASK(15, 0) >> +#define CDNS_PCIE_LM_RP_RID_SHIFT 0 >> +#define CDNS_PCIE_LM_RP_RID_(rid) \ >> +(((rid) << CDNS_PCIE_LM_RP_RID_SHIFT) & CDNS_PCIE_LM_RP_RID_MASK) >> + >> +/* Root Complex BAR Configuration Register */ >> +#define CDNS_PCIE_LM_RC_BAR_CFG (CDNS_PCIE_LM_BASE + 0x0300) >> +#define CDNS_PCIE_LM_RC_BAR_CFG_BAR0_APERTURE_MASK GENMASK(5, 0) >> +#define CDNS_PCIE_LM_RC_BAR_CFG_BAR0_APERTURE(a) \ >> +(((a) << 0) & CDNS_PCIE_LM_RC_BAR_CFG_BAR0_APERTURE_MASK) >> +#define CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL_MASK GENMASK(8, 6) >> +#define CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL(c) \ >> +(((c) << 6) & CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL_MASK) >> +#define CDNS_PCIE_LM_RC_BAR_CFG_BAR1_APERTURE_MASK GENMASK(13, 9) >> +#define CDNS_PCIE_LM_RC_BAR_CFG_BAR1_APERTURE(a) \ >> +(((a) << 9) & CDNS_PCIE_LM_RC_BAR_CFG_BAR1_APERTURE_MASK) >> +#define CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL_MASK GENMASK(16, 14) >> +#define CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL(c) \ >> +(((c) << 14) & CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL_MASK) >> +#define CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_ENABLEBIT(17) >> +#define CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_32BITS0 >> +#define CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_64BITSBIT(18) >> +#define CDNS_PCIE_LM_RC_BAR_CFG_IO_ENABLE BIT(19) >> +#define CDNS_PCIE_LM_RC_BAR_CFG_IO_16BITS 0 >> +#define CDNS_PCIE_LM_RC_BAR_CFG_IO_32BITS BIT(20) >> +#define CDNS_PCIE_LM_RC_BAR_CFG_CHECK_ENABLE BIT(31) >> + >> +/* BAR control values applicable to both Endpoint Function and Root Complex >> */ >> +#define CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED 0x0 >> +#define CDNS_PCIE_LM_BAR_CFG_CTRL_IO_3
Re: [PATCH v3 6/6] PCI: cadence: Add host driver for Cadence PCIe controller
Hi Kishon, Le 16/01/2018 à 12:16, Kishon Vijay Abraham I a écrit : > Hi Cyrille, > > On Thursday 11 January 2018 04:17 AM, Cyrille Pitchen wrote: >> This patch adds support to the Cadence PCIe controller in host mode. >> >> Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> >> --- >> MAINTAINERS | 7 + >> drivers/pci/Kconfig | 1 + >> drivers/pci/Makefile| 1 + >> drivers/pci/cadence/Kconfig | 16 ++ >> drivers/pci/cadence/Makefile| 3 + >> drivers/pci/cadence/pcie-cadence-host.c | 336 >> >> drivers/pci/cadence/pcie-cadence.c | 68 +++ >> drivers/pci/cadence/pcie-cadence.h | 196 +++ >> 8 files changed, 628 insertions(+) >> create mode 100644 drivers/pci/cadence/Kconfig >> create mode 100644 drivers/pci/cadence/Makefile >> create mode 100644 drivers/pci/cadence/pcie-cadence-host.c >> create mode 100644 drivers/pci/cadence/pcie-cadence.c >> create mode 100644 drivers/pci/cadence/pcie-cadence.h >> >> diff --git a/MAINTAINERS b/MAINTAINERS >> index 13945646b95d..cc24c74a946e 100644 >> --- a/MAINTAINERS >> +++ b/MAINTAINERS >> @@ -10402,6 +10402,13 @@ S: Maintained >> F: Documentation/devicetree/bindings/pci/pci-armada8k.txt >> F: drivers/pci/dwc/pcie-armada8k.c >> >> +PCI DRIVER FOR CADENCE PCIE IP >> +M: Alan Douglas <adoug...@cadence.com> >> +L: linux-...@vger.kernel.org >> +S: Maintained >> +F: Documentation/devicetree/bindings/pci/cdns,*.txt >> +F: drivers/pci/cadence/pcie-cadence* >> + >> PCI DRIVER FOR FREESCALE LAYERSCAPE >> M: Minghuan Lian <minghuan.l...@freescale.com> >> M: Mingkai Hu <mingkai...@freescale.com> >> diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig >> index 7eeb969ab86a..dee90cc1dcaf 100644 >> --- a/drivers/pci/Kconfig >> +++ b/drivers/pci/Kconfig >> @@ -136,6 +136,7 @@ config PCI_HYPERV >>PCI devices from a PCI backend to support PCI driver domains. >> >> source "drivers/pci/hotplug/Kconfig" >> +source "drivers/pci/cadence/Kconfig" >> source "drivers/pci/dwc/Kconfig" >> source "drivers/pci/host/Kconfig" >> source "drivers/pci/endpoint/Kconfig" >> diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile >> index ddb5aa6640d7..941970936840 100644 >> --- a/drivers/pci/Makefile >> +++ b/drivers/pci/Makefile >> @@ -56,5 +56,6 @@ obj-y += switch/ >> obj-$(CONFIG_PCI_ENDPOINT) += endpoint/ >> >> # Endpoint library must be initialized before its users >> +obj-$(CONFIG_PCIE_CADENCE) += cadence/ >> # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW >> obj-y += dwc/ >> diff --git a/drivers/pci/cadence/Kconfig b/drivers/pci/cadence/Kconfig >> new file mode 100644 >> index ..0123d384a628 >> --- /dev/null >> +++ b/drivers/pci/cadence/Kconfig >> @@ -0,0 +1,16 @@ >> +menu "Cadence PCIe controllers support" >> + >> +config PCIE_CADENCE >> +bool >> + >> +config PCIE_CADENCE_HOST >> +bool "Cadence PCIe host controller" >> +depends on OF >> +select IRQ_DOMAIN >> +select PCIE_CADENCE >> +help >> + Say Y here if you want to support the Cadence PCIe controller in host >> + mode. This PCIe controller may be embedded into many different vendors >> + SoCs. >> + >> +endmenu >> diff --git a/drivers/pci/cadence/Makefile b/drivers/pci/cadence/Makefile >> new file mode 100644 >> index 0000..589601a8ff89 >> --- /dev/null >> +++ b/drivers/pci/cadence/Makefile >> @@ -0,0 +1,3 @@ >> +# SPDX-License-Identifier: GPL-2.0 >> +obj-$(CONFIG_PCIE_CADENCE) += pcie-cadence.o >> +obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host.o >> diff --git a/drivers/pci/cadence/pcie-cadence-host.c >> b/drivers/pci/cadence/pcie-cadence-host.c >> new file mode 100644 >> index ..26caf8963e3c >> --- /dev/null >> +++ b/drivers/pci/cadence/pcie-cadence-host.c >> @@ -0,0 +1,336 @@ >> +// SPDX-License-Identifier: GPL-2.0 >> +// Copyright (c) 2017 Cadence >> +// Cadence PCIe host controller driver. >> +// Author: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +
Re: [PATCH v3 6/6] PCI: cadence: Add host driver for Cadence PCIe controller
Hi Kishon, Le 16/01/2018 à 12:16, Kishon Vijay Abraham I a écrit : > Hi Cyrille, > > On Thursday 11 January 2018 04:17 AM, Cyrille Pitchen wrote: >> This patch adds support to the Cadence PCIe controller in host mode. >> >> Signed-off-by: Cyrille Pitchen >> --- >> MAINTAINERS | 7 + >> drivers/pci/Kconfig | 1 + >> drivers/pci/Makefile| 1 + >> drivers/pci/cadence/Kconfig | 16 ++ >> drivers/pci/cadence/Makefile| 3 + >> drivers/pci/cadence/pcie-cadence-host.c | 336 >> >> drivers/pci/cadence/pcie-cadence.c | 68 +++ >> drivers/pci/cadence/pcie-cadence.h | 196 +++ >> 8 files changed, 628 insertions(+) >> create mode 100644 drivers/pci/cadence/Kconfig >> create mode 100644 drivers/pci/cadence/Makefile >> create mode 100644 drivers/pci/cadence/pcie-cadence-host.c >> create mode 100644 drivers/pci/cadence/pcie-cadence.c >> create mode 100644 drivers/pci/cadence/pcie-cadence.h >> >> diff --git a/MAINTAINERS b/MAINTAINERS >> index 13945646b95d..cc24c74a946e 100644 >> --- a/MAINTAINERS >> +++ b/MAINTAINERS >> @@ -10402,6 +10402,13 @@ S: Maintained >> F: Documentation/devicetree/bindings/pci/pci-armada8k.txt >> F: drivers/pci/dwc/pcie-armada8k.c >> >> +PCI DRIVER FOR CADENCE PCIE IP >> +M: Alan Douglas >> +L: linux-...@vger.kernel.org >> +S: Maintained >> +F: Documentation/devicetree/bindings/pci/cdns,*.txt >> +F: drivers/pci/cadence/pcie-cadence* >> + >> PCI DRIVER FOR FREESCALE LAYERSCAPE >> M: Minghuan Lian >> M: Mingkai Hu >> diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig >> index 7eeb969ab86a..dee90cc1dcaf 100644 >> --- a/drivers/pci/Kconfig >> +++ b/drivers/pci/Kconfig >> @@ -136,6 +136,7 @@ config PCI_HYPERV >>PCI devices from a PCI backend to support PCI driver domains. >> >> source "drivers/pci/hotplug/Kconfig" >> +source "drivers/pci/cadence/Kconfig" >> source "drivers/pci/dwc/Kconfig" >> source "drivers/pci/host/Kconfig" >> source "drivers/pci/endpoint/Kconfig" >> diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile >> index ddb5aa6640d7..941970936840 100644 >> --- a/drivers/pci/Makefile >> +++ b/drivers/pci/Makefile >> @@ -56,5 +56,6 @@ obj-y += switch/ >> obj-$(CONFIG_PCI_ENDPOINT) += endpoint/ >> >> # Endpoint library must be initialized before its users >> +obj-$(CONFIG_PCIE_CADENCE) += cadence/ >> # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW >> obj-y += dwc/ >> diff --git a/drivers/pci/cadence/Kconfig b/drivers/pci/cadence/Kconfig >> new file mode 100644 >> index ..0123d384a628 >> --- /dev/null >> +++ b/drivers/pci/cadence/Kconfig >> @@ -0,0 +1,16 @@ >> +menu "Cadence PCIe controllers support" >> + >> +config PCIE_CADENCE >> +bool >> + >> +config PCIE_CADENCE_HOST >> +bool "Cadence PCIe host controller" >> +depends on OF >> +select IRQ_DOMAIN >> +select PCIE_CADENCE >> +help >> + Say Y here if you want to support the Cadence PCIe controller in host >> + mode. This PCIe controller may be embedded into many different vendors >> + SoCs. >> + >> +endmenu >> diff --git a/drivers/pci/cadence/Makefile b/drivers/pci/cadence/Makefile >> new file mode 100644 >> index ..589601a8ff89 >> --- /dev/null >> +++ b/drivers/pci/cadence/Makefile >> @@ -0,0 +1,3 @@ >> +# SPDX-License-Identifier: GPL-2.0 >> +obj-$(CONFIG_PCIE_CADENCE) += pcie-cadence.o >> +obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host.o >> diff --git a/drivers/pci/cadence/pcie-cadence-host.c >> b/drivers/pci/cadence/pcie-cadence-host.c >> new file mode 100644 >> index ..26caf8963e3c >> --- /dev/null >> +++ b/drivers/pci/cadence/pcie-cadence-host.c >> @@ -0,0 +1,336 @@ >> +// SPDX-License-Identifier: GPL-2.0 >> +// Copyright (c) 2017 Cadence >> +// Cadence PCIe host controller driver. >> +// Author: Cyrille Pitchen >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +#include "pcie-cadence.h" >> + >> +/** >> + * struct cdns_pcie_rc - private data for this PCIe Root Complex driver >> + * @pcie:
[PATCH v4 0/7] PCI: Add support to the Cadence PCIe controller
Hi all, this series of patches adds support to the Cadence PCIe controller. It was tested on a ARM64 platform emulated by a Palladium running the pci-next kernel. The host mode was tested with some PCIe devices connected to the Palladium through a speed-bridge. Some of those devices were a USB host controller and a SATA controller. The PCIe host controller was also tested with a second controller configured in endpoint mode and connected back to back to the first controller. The EndPoint Controller (EPC) driver was removed only because I didn't have time to take all Kishon's comments into account. However, using a fixed patch based on patch 7 of the v2 series + another patch fixing the EPF device name chosen by pci_epf_make(), I was abled to probe both function 0 and function 1 of the of the 2nd Cadence PCIe controller configured in endpoint mode (new hardware design since v2 so function 1 is now available). Currently I'm facing 2 issues, which I didn't have enough time to investigate and to fix yet: 1 - when the vendor:device IDs are set to 104c:b500 for both functions, then I remove both devfn (echo 1 > /sys/bus/pci/devices/$BDF/remove) before scanning the PCI bus again (echo 1 > /sys/bus/pci/rescan), the PCI enumeration fails reporting that the PCI memory is exhausted. 2 - when I set the vendor:device IDs to 104c:0100 for function 0 and 104c:b500 and remove only function 1 before scanning the PCI bus again, I now pass the PCI enumeration. I also pass the 'pcitest -b ' test but I fail on the MSI test ('pcitest -m '). I'm still investigating on those issues. Best regards, Cyrille ChangeLog v3 -> v4: - split patch 3 from v3 into patches 3 and 4. - remove unused cdns_pcie_reset_outbound_region() from old patch 6 (new patch 7). - other patches are unchanged. v2 -> v3: - rebase on today's linux-pci/next (20180110) patch1: - rework the commit message of patch 1 and add two new comments on why endpoint library users must be linked after the endpoint library itself and why the dwc rule uses obj-y instead of obj-$(CONFIG_PCIE_CONFIG_DW). - update patch 1 to add missing ifdef CONFIG_PCI / endif in drivers/pci/dwc/Makefile around the obj-$(CONFIG_ARM64) += pcie-hisi.o rule, like for the other obj-$(CONFIG_ARM64) rules in drivers/pci/host/Makefile. patch2: unchanged patch3: - update patch 3 so the bridge hooks/members initialization is left to the host bridges probe routines. patch4: unchanged patch5: - collect 'Reviewed-by' tag from Rob Herring for the DT bindings. patch6: - remove explanation in the commit message on why obj-$(CONFIG_PCIE_CANDENCE) is placed after obj-$(CONFIG_PCI_ENDPOINT) in drivers/pci/Makefile since a comment on it has been added into patch1. - remove menuconfig PCI_CADENCE in drivers/pci/cadence/Kconfig to match drivers/pci/dwc/Kconfig. - adapt patch6 to the changes done in patch3 for the pci_host_probe() function. v1 -> v2: - add new properties in the device-tree bindings: 'cdns,max-outbound-regions' and 'cdns,no-bar-match-nbits'. - add a new patch to regroup all makefile rules in drivers/pci/Makefile, hence cleaning drivers/Makefile up. - change the license text to use the recommanded format: // SPDX-License-Identifier: GPL-2.0 - add a new patch updating the API of the EPC library to add support to multi-function devices. - add a 2 new patches to share more common code between host controller drivers - remove some useless tests - add more comments in both drivers. - fix DT bindings examples - remove useless init of the primary, secondary and sub-ordinate bus numbers in the PCI configuration space of the root port. - remove cdns_pcie_ep_stop() function and rework cdns_pcie_ep_start() function Cyrille Pitchen (6): PCI: Regroup all PCI related entries into drivers/pci/Makefile PCI: OF: Add generic function to parse and allocate PCI resources PCI: generic: fix missing call of pci_free_resource_list() PCI: Add generic function to probe PCI host controllers PCI: Add vendor ID for Cadence PCI: cadence: Add host driver for Cadence PCIe controller Scott Telford (1): dt-bindings: PCI: cadence: Add DT bindings for Cadence PCIe host controller .../bindings/pci/cdns,cdns-pcie-host.txt | 60 MAINTAINERS| 7 + drivers/Makefile | 5 +- drivers/pci/Kconfig| 2 + drivers/pci/Makefile | 14 +- drivers/pci/cadence/Kconfig| 16 + drivers/pci/cadence/Makefile | 3 + drivers/pci/cadence/pcie-cadence-host.c| 336 + drivers/pci/cadence/pcie-cadence.c | 56 drivers/pci/cadence/pcie-cadence.h | 194 drivers/pci/dwc/Makefile | 2 + drivers/pci/host/Makefile | 2 + drivers/pci/host/pc
[PATCH v4 0/7] PCI: Add support to the Cadence PCIe controller
Hi all, this series of patches adds support to the Cadence PCIe controller. It was tested on a ARM64 platform emulated by a Palladium running the pci-next kernel. The host mode was tested with some PCIe devices connected to the Palladium through a speed-bridge. Some of those devices were a USB host controller and a SATA controller. The PCIe host controller was also tested with a second controller configured in endpoint mode and connected back to back to the first controller. The EndPoint Controller (EPC) driver was removed only because I didn't have time to take all Kishon's comments into account. However, using a fixed patch based on patch 7 of the v2 series + another patch fixing the EPF device name chosen by pci_epf_make(), I was abled to probe both function 0 and function 1 of the of the 2nd Cadence PCIe controller configured in endpoint mode (new hardware design since v2 so function 1 is now available). Currently I'm facing 2 issues, which I didn't have enough time to investigate and to fix yet: 1 - when the vendor:device IDs are set to 104c:b500 for both functions, then I remove both devfn (echo 1 > /sys/bus/pci/devices/$BDF/remove) before scanning the PCI bus again (echo 1 > /sys/bus/pci/rescan), the PCI enumeration fails reporting that the PCI memory is exhausted. 2 - when I set the vendor:device IDs to 104c:0100 for function 0 and 104c:b500 and remove only function 1 before scanning the PCI bus again, I now pass the PCI enumeration. I also pass the 'pcitest -b ' test but I fail on the MSI test ('pcitest -m '). I'm still investigating on those issues. Best regards, Cyrille ChangeLog v3 -> v4: - split patch 3 from v3 into patches 3 and 4. - remove unused cdns_pcie_reset_outbound_region() from old patch 6 (new patch 7). - other patches are unchanged. v2 -> v3: - rebase on today's linux-pci/next (20180110) patch1: - rework the commit message of patch 1 and add two new comments on why endpoint library users must be linked after the endpoint library itself and why the dwc rule uses obj-y instead of obj-$(CONFIG_PCIE_CONFIG_DW). - update patch 1 to add missing ifdef CONFIG_PCI / endif in drivers/pci/dwc/Makefile around the obj-$(CONFIG_ARM64) += pcie-hisi.o rule, like for the other obj-$(CONFIG_ARM64) rules in drivers/pci/host/Makefile. patch2: unchanged patch3: - update patch 3 so the bridge hooks/members initialization is left to the host bridges probe routines. patch4: unchanged patch5: - collect 'Reviewed-by' tag from Rob Herring for the DT bindings. patch6: - remove explanation in the commit message on why obj-$(CONFIG_PCIE_CANDENCE) is placed after obj-$(CONFIG_PCI_ENDPOINT) in drivers/pci/Makefile since a comment on it has been added into patch1. - remove menuconfig PCI_CADENCE in drivers/pci/cadence/Kconfig to match drivers/pci/dwc/Kconfig. - adapt patch6 to the changes done in patch3 for the pci_host_probe() function. v1 -> v2: - add new properties in the device-tree bindings: 'cdns,max-outbound-regions' and 'cdns,no-bar-match-nbits'. - add a new patch to regroup all makefile rules in drivers/pci/Makefile, hence cleaning drivers/Makefile up. - change the license text to use the recommanded format: // SPDX-License-Identifier: GPL-2.0 - add a new patch updating the API of the EPC library to add support to multi-function devices. - add a 2 new patches to share more common code between host controller drivers - remove some useless tests - add more comments in both drivers. - fix DT bindings examples - remove useless init of the primary, secondary and sub-ordinate bus numbers in the PCI configuration space of the root port. - remove cdns_pcie_ep_stop() function and rework cdns_pcie_ep_start() function Cyrille Pitchen (6): PCI: Regroup all PCI related entries into drivers/pci/Makefile PCI: OF: Add generic function to parse and allocate PCI resources PCI: generic: fix missing call of pci_free_resource_list() PCI: Add generic function to probe PCI host controllers PCI: Add vendor ID for Cadence PCI: cadence: Add host driver for Cadence PCIe controller Scott Telford (1): dt-bindings: PCI: cadence: Add DT bindings for Cadence PCIe host controller .../bindings/pci/cdns,cdns-pcie-host.txt | 60 MAINTAINERS| 7 + drivers/Makefile | 5 +- drivers/pci/Kconfig| 2 + drivers/pci/Makefile | 14 +- drivers/pci/cadence/Kconfig| 16 + drivers/pci/cadence/Makefile | 3 + drivers/pci/cadence/pcie-cadence-host.c| 336 + drivers/pci/cadence/pcie-cadence.c | 56 drivers/pci/cadence/pcie-cadence.h | 194 drivers/pci/dwc/Makefile | 2 + drivers/pci/host/Makefile | 2 + drivers/pci/host/pc
[PATCH v4 7/7] PCI: cadence: Add host driver for Cadence PCIe controller
This patch adds support to the Cadence PCIe controller in host mode. Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> --- MAINTAINERS | 7 + drivers/pci/Kconfig | 1 + drivers/pci/Makefile| 1 + drivers/pci/cadence/Kconfig | 16 ++ drivers/pci/cadence/Makefile| 3 + drivers/pci/cadence/pcie-cadence-host.c | 336 drivers/pci/cadence/pcie-cadence.c | 56 ++ drivers/pci/cadence/pcie-cadence.h | 194 ++ 8 files changed, 614 insertions(+) create mode 100644 drivers/pci/cadence/Kconfig create mode 100644 drivers/pci/cadence/Makefile create mode 100644 drivers/pci/cadence/pcie-cadence-host.c create mode 100644 drivers/pci/cadence/pcie-cadence.c create mode 100644 drivers/pci/cadence/pcie-cadence.h diff --git a/MAINTAINERS b/MAINTAINERS index 13945646b95d..cc24c74a946e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10402,6 +10402,13 @@ S: Maintained F: Documentation/devicetree/bindings/pci/pci-armada8k.txt F: drivers/pci/dwc/pcie-armada8k.c +PCI DRIVER FOR CADENCE PCIE IP +M: Alan Douglas <adoug...@cadence.com> +L: linux-...@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/pci/cdns,*.txt +F: drivers/pci/cadence/pcie-cadence* + PCI DRIVER FOR FREESCALE LAYERSCAPE M: Minghuan Lian <minghuan.l...@freescale.com> M: Mingkai Hu <mingkai...@freescale.com> diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 7eeb969ab86a..dee90cc1dcaf 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -136,6 +136,7 @@ config PCI_HYPERV PCI devices from a PCI backend to support PCI driver domains. source "drivers/pci/hotplug/Kconfig" +source "drivers/pci/cadence/Kconfig" source "drivers/pci/dwc/Kconfig" source "drivers/pci/host/Kconfig" source "drivers/pci/endpoint/Kconfig" diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index ddb5aa6640d7..941970936840 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -56,5 +56,6 @@ obj-y += switch/ obj-$(CONFIG_PCI_ENDPOINT) += endpoint/ # Endpoint library must be initialized before its users +obj-$(CONFIG_PCIE_CADENCE) += cadence/ # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW obj-y += dwc/ diff --git a/drivers/pci/cadence/Kconfig b/drivers/pci/cadence/Kconfig new file mode 100644 index ..0123d384a628 --- /dev/null +++ b/drivers/pci/cadence/Kconfig @@ -0,0 +1,16 @@ +menu "Cadence PCIe controllers support" + +config PCIE_CADENCE + bool + +config PCIE_CADENCE_HOST + bool "Cadence PCIe host controller" + depends on OF + select IRQ_DOMAIN + select PCIE_CADENCE + help + Say Y here if you want to support the Cadence PCIe controller in host + mode. This PCIe controller may be embedded into many different vendors + SoCs. + +endmenu diff --git a/drivers/pci/cadence/Makefile b/drivers/pci/cadence/Makefile new file mode 100644 index ..589601a8ff89 --- /dev/null +++ b/drivers/pci/cadence/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_PCIE_CADENCE) += pcie-cadence.o +obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host.o diff --git a/drivers/pci/cadence/pcie-cadence-host.c b/drivers/pci/cadence/pcie-cadence-host.c new file mode 100644 index ..26caf8963e3c --- /dev/null +++ b/drivers/pci/cadence/pcie-cadence-host.c @@ -0,0 +1,336 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2017 Cadence +// Cadence PCIe host controller driver. +// Author: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> + +#include +#include +#include +#include +#include + +#include "pcie-cadence.h" + +/** + * struct cdns_pcie_rc - private data for this PCIe Root Complex driver + * @pcie: Cadence PCIe controller + * @dev: pointer to PCIe device + * @cfg_res: start/end offsets in the physical system memory to map PCI + * configuration space accesses + * @bus_range: first/last buses behind the PCIe host controller + * @cfg_base: IO mapped window to access the PCI configuration space of a + *single function at a time + * @max_regions: maximum number of regions supported by the hardware + * @no_bar_nbits: Number of bits to keep for inbound (PCIe -> CPU) address + *translation (nbits sets into the "no BAR match" register) + * @vendor_id: PCI vendor ID + * @device_id: PCI device ID + */ +struct cdns_pcie_rc { + struct cdns_pciepcie; + struct device *dev; + struct resource *cfg_res; + struct resource *bus_range; + void __iomem*cfg_base; + u32 max_regions; + u32 no_
[PATCH v4 7/7] PCI: cadence: Add host driver for Cadence PCIe controller
This patch adds support to the Cadence PCIe controller in host mode. Signed-off-by: Cyrille Pitchen --- MAINTAINERS | 7 + drivers/pci/Kconfig | 1 + drivers/pci/Makefile| 1 + drivers/pci/cadence/Kconfig | 16 ++ drivers/pci/cadence/Makefile| 3 + drivers/pci/cadence/pcie-cadence-host.c | 336 drivers/pci/cadence/pcie-cadence.c | 56 ++ drivers/pci/cadence/pcie-cadence.h | 194 ++ 8 files changed, 614 insertions(+) create mode 100644 drivers/pci/cadence/Kconfig create mode 100644 drivers/pci/cadence/Makefile create mode 100644 drivers/pci/cadence/pcie-cadence-host.c create mode 100644 drivers/pci/cadence/pcie-cadence.c create mode 100644 drivers/pci/cadence/pcie-cadence.h diff --git a/MAINTAINERS b/MAINTAINERS index 13945646b95d..cc24c74a946e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10402,6 +10402,13 @@ S: Maintained F: Documentation/devicetree/bindings/pci/pci-armada8k.txt F: drivers/pci/dwc/pcie-armada8k.c +PCI DRIVER FOR CADENCE PCIE IP +M: Alan Douglas +L: linux-...@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/pci/cdns,*.txt +F: drivers/pci/cadence/pcie-cadence* + PCI DRIVER FOR FREESCALE LAYERSCAPE M: Minghuan Lian M: Mingkai Hu diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 7eeb969ab86a..dee90cc1dcaf 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -136,6 +136,7 @@ config PCI_HYPERV PCI devices from a PCI backend to support PCI driver domains. source "drivers/pci/hotplug/Kconfig" +source "drivers/pci/cadence/Kconfig" source "drivers/pci/dwc/Kconfig" source "drivers/pci/host/Kconfig" source "drivers/pci/endpoint/Kconfig" diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index ddb5aa6640d7..941970936840 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -56,5 +56,6 @@ obj-y += switch/ obj-$(CONFIG_PCI_ENDPOINT) += endpoint/ # Endpoint library must be initialized before its users +obj-$(CONFIG_PCIE_CADENCE) += cadence/ # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW obj-y += dwc/ diff --git a/drivers/pci/cadence/Kconfig b/drivers/pci/cadence/Kconfig new file mode 100644 index ..0123d384a628 --- /dev/null +++ b/drivers/pci/cadence/Kconfig @@ -0,0 +1,16 @@ +menu "Cadence PCIe controllers support" + +config PCIE_CADENCE + bool + +config PCIE_CADENCE_HOST + bool "Cadence PCIe host controller" + depends on OF + select IRQ_DOMAIN + select PCIE_CADENCE + help + Say Y here if you want to support the Cadence PCIe controller in host + mode. This PCIe controller may be embedded into many different vendors + SoCs. + +endmenu diff --git a/drivers/pci/cadence/Makefile b/drivers/pci/cadence/Makefile new file mode 100644 index ..589601a8ff89 --- /dev/null +++ b/drivers/pci/cadence/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_PCIE_CADENCE) += pcie-cadence.o +obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host.o diff --git a/drivers/pci/cadence/pcie-cadence-host.c b/drivers/pci/cadence/pcie-cadence-host.c new file mode 100644 index ..26caf8963e3c --- /dev/null +++ b/drivers/pci/cadence/pcie-cadence-host.c @@ -0,0 +1,336 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2017 Cadence +// Cadence PCIe host controller driver. +// Author: Cyrille Pitchen + +#include +#include +#include +#include +#include + +#include "pcie-cadence.h" + +/** + * struct cdns_pcie_rc - private data for this PCIe Root Complex driver + * @pcie: Cadence PCIe controller + * @dev: pointer to PCIe device + * @cfg_res: start/end offsets in the physical system memory to map PCI + * configuration space accesses + * @bus_range: first/last buses behind the PCIe host controller + * @cfg_base: IO mapped window to access the PCI configuration space of a + *single function at a time + * @max_regions: maximum number of regions supported by the hardware + * @no_bar_nbits: Number of bits to keep for inbound (PCIe -> CPU) address + *translation (nbits sets into the "no BAR match" register) + * @vendor_id: PCI vendor ID + * @device_id: PCI device ID + */ +struct cdns_pcie_rc { + struct cdns_pciepcie; + struct device *dev; + struct resource *cfg_res; + struct resource *bus_range; + void __iomem*cfg_base; + u32 max_regions; + u32 no_bar_nbits; + u16 vendor_id; + u16 device_id; +}; + +static void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int devf
[PATCH v4 4/7] PCI: Add generic function to probe PCI host controllers
This patchs moves generic source code from drivers/pci/host/pci-host-common.c into drivers/pci/probe.c. Indeed the extracted lines of code were duplicated by many host controller drivers. Regrouping them into a generic function gives a change to properly share this code without introducing a useless dependency to PCI_HOST_COMMON, which selects PCI_ECAM when not needed by most host controller drivers. Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> --- drivers/pci/host/pci-host-common.c | 22 +- drivers/pci/probe.c| 33 + include/linux/pci.h| 1 + 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c index 9f27e90f578c..756702d8dd10 100644 --- a/drivers/pci/host/pci-host-common.c +++ b/drivers/pci/host/pci-host-common.c @@ -72,7 +72,6 @@ int pci_host_common_probe(struct platform_device *pdev, const char *type; struct device *dev = >dev; struct device_node *np = dev->of_node; - struct pci_bus *bus, *child; struct pci_host_bridge *bridge; struct pci_config_window *cfg; struct list_head resources; @@ -107,30 +106,11 @@ int pci_host_common_probe(struct platform_device *pdev, bridge->map_irq = of_irq_parse_and_map_pci; bridge->swizzle_irq = pci_common_swizzle; - ret = pci_scan_root_bus_bridge(bridge); + ret = pci_host_probe(bridge); if (ret < 0) { - dev_err(dev, "Scanning root bridge failed"); pci_free_resource_list(); return ret; } - bus = bridge->bus; - - /* -* We insert PCI resources into the iomem_resource and -* ioport_resource trees in either pci_bus_claim_resources() -* or pci_bus_assign_resources(). -*/ - if (pci_has_flag(PCI_PROBE_ONLY)) { - pci_bus_claim_resources(bus); - } else { - pci_bus_size_bridges(bus); - pci_bus_assign_resources(bus); - - list_for_each_entry(child, >children, node) - pcie_bus_configure_settings(child); - } - - pci_bus_add_devices(bus); return 0; } diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 1360db508035..178328d06a32 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -2685,6 +2685,39 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, } EXPORT_SYMBOL_GPL(pci_create_root_bus); +int pci_host_probe(struct pci_host_bridge *bridge) +{ + struct pci_bus *bus, *child; + int ret; + + ret = pci_scan_root_bus_bridge(bridge); + if (ret < 0) { + dev_err(bridge->dev.parent, "Scanning root bridge failed"); + return ret; + } + + bus = bridge->bus; + + /* +* We insert PCI resources into the iomem_resource and +* ioport_resource trees in either pci_bus_claim_resources() +* or pci_bus_assign_resources(). +*/ + if (pci_has_flag(PCI_PROBE_ONLY)) { + pci_bus_claim_resources(bus); + } else { + pci_bus_size_bridges(bus); + pci_bus_assign_resources(bus); + + list_for_each_entry(child, >children, node) + pcie_bus_configure_settings(child); + } + + pci_bus_add_devices(bus); + return 0; +} +EXPORT_SYMBOL_GPL(pci_host_probe); + int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int bus_max) { struct resource *res = >busn_res; diff --git a/include/linux/pci.h b/include/linux/pci.h index 4a4cbd444e1e..83514b34742a 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -879,6 +879,7 @@ struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata); struct pci_bus *pci_create_root_bus(struct device *parent, int bus, struct pci_ops *ops, void *sysdata, struct list_head *resources); +int pci_host_probe(struct pci_host_bridge *bridge); int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int busmax); int pci_bus_update_busn_res_end(struct pci_bus *b, int busmax); void pci_bus_release_busn_res(struct pci_bus *b); -- 2.11.0
[PATCH v4 4/7] PCI: Add generic function to probe PCI host controllers
This patchs moves generic source code from drivers/pci/host/pci-host-common.c into drivers/pci/probe.c. Indeed the extracted lines of code were duplicated by many host controller drivers. Regrouping them into a generic function gives a change to properly share this code without introducing a useless dependency to PCI_HOST_COMMON, which selects PCI_ECAM when not needed by most host controller drivers. Signed-off-by: Cyrille Pitchen --- drivers/pci/host/pci-host-common.c | 22 +- drivers/pci/probe.c| 33 + include/linux/pci.h| 1 + 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c index 9f27e90f578c..756702d8dd10 100644 --- a/drivers/pci/host/pci-host-common.c +++ b/drivers/pci/host/pci-host-common.c @@ -72,7 +72,6 @@ int pci_host_common_probe(struct platform_device *pdev, const char *type; struct device *dev = >dev; struct device_node *np = dev->of_node; - struct pci_bus *bus, *child; struct pci_host_bridge *bridge; struct pci_config_window *cfg; struct list_head resources; @@ -107,30 +106,11 @@ int pci_host_common_probe(struct platform_device *pdev, bridge->map_irq = of_irq_parse_and_map_pci; bridge->swizzle_irq = pci_common_swizzle; - ret = pci_scan_root_bus_bridge(bridge); + ret = pci_host_probe(bridge); if (ret < 0) { - dev_err(dev, "Scanning root bridge failed"); pci_free_resource_list(); return ret; } - bus = bridge->bus; - - /* -* We insert PCI resources into the iomem_resource and -* ioport_resource trees in either pci_bus_claim_resources() -* or pci_bus_assign_resources(). -*/ - if (pci_has_flag(PCI_PROBE_ONLY)) { - pci_bus_claim_resources(bus); - } else { - pci_bus_size_bridges(bus); - pci_bus_assign_resources(bus); - - list_for_each_entry(child, >children, node) - pcie_bus_configure_settings(child); - } - - pci_bus_add_devices(bus); return 0; } diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 1360db508035..178328d06a32 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -2685,6 +2685,39 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, } EXPORT_SYMBOL_GPL(pci_create_root_bus); +int pci_host_probe(struct pci_host_bridge *bridge) +{ + struct pci_bus *bus, *child; + int ret; + + ret = pci_scan_root_bus_bridge(bridge); + if (ret < 0) { + dev_err(bridge->dev.parent, "Scanning root bridge failed"); + return ret; + } + + bus = bridge->bus; + + /* +* We insert PCI resources into the iomem_resource and +* ioport_resource trees in either pci_bus_claim_resources() +* or pci_bus_assign_resources(). +*/ + if (pci_has_flag(PCI_PROBE_ONLY)) { + pci_bus_claim_resources(bus); + } else { + pci_bus_size_bridges(bus); + pci_bus_assign_resources(bus); + + list_for_each_entry(child, >children, node) + pcie_bus_configure_settings(child); + } + + pci_bus_add_devices(bus); + return 0; +} +EXPORT_SYMBOL_GPL(pci_host_probe); + int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int bus_max) { struct resource *res = >busn_res; diff --git a/include/linux/pci.h b/include/linux/pci.h index 4a4cbd444e1e..83514b34742a 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -879,6 +879,7 @@ struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata); struct pci_bus *pci_create_root_bus(struct device *parent, int bus, struct pci_ops *ops, void *sysdata, struct list_head *resources); +int pci_host_probe(struct pci_host_bridge *bridge); int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int busmax); int pci_bus_update_busn_res_end(struct pci_bus *b, int busmax); void pci_bus_release_busn_res(struct pci_bus *b); -- 2.11.0
[PATCH v4 3/7] PCI: generic: fix missing call of pci_free_resource_list()
Call pci_free_resource_list() from pci_host_common_probe() when probing fails, as done inside gen_pci_init() when this later function fails. Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> --- drivers/pci/host/pci-host-common.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c index a613ea310e76..9f27e90f578c 100644 --- a/drivers/pci/host/pci-host-common.c +++ b/drivers/pci/host/pci-host-common.c @@ -110,6 +110,7 @@ int pci_host_common_probe(struct platform_device *pdev, ret = pci_scan_root_bus_bridge(bridge); if (ret < 0) { dev_err(dev, "Scanning root bridge failed"); + pci_free_resource_list(); return ret; } -- 2.11.0
[PATCH v4 5/7] PCI: Add vendor ID for Cadence
This patch adds a new PCI vendor ID for Cadence. Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> --- include/linux/pci_ids.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index ab20dc5db423..eb13e84e1fef 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2381,6 +2381,8 @@ #define PCI_VENDOR_ID_LENOVO 0x17aa +#define PCI_VENDOR_ID_CDNS 0x17cd + #define PCI_VENDOR_ID_ARECA0x17d3 #define PCI_DEVICE_ID_ARECA_1110 0x1110 #define PCI_DEVICE_ID_ARECA_1120 0x1120 -- 2.11.0
[PATCH v4 3/7] PCI: generic: fix missing call of pci_free_resource_list()
Call pci_free_resource_list() from pci_host_common_probe() when probing fails, as done inside gen_pci_init() when this later function fails. Signed-off-by: Cyrille Pitchen --- drivers/pci/host/pci-host-common.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c index a613ea310e76..9f27e90f578c 100644 --- a/drivers/pci/host/pci-host-common.c +++ b/drivers/pci/host/pci-host-common.c @@ -110,6 +110,7 @@ int pci_host_common_probe(struct platform_device *pdev, ret = pci_scan_root_bus_bridge(bridge); if (ret < 0) { dev_err(dev, "Scanning root bridge failed"); + pci_free_resource_list(); return ret; } -- 2.11.0
[PATCH v4 5/7] PCI: Add vendor ID for Cadence
This patch adds a new PCI vendor ID for Cadence. Signed-off-by: Cyrille Pitchen --- include/linux/pci_ids.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index ab20dc5db423..eb13e84e1fef 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2381,6 +2381,8 @@ #define PCI_VENDOR_ID_LENOVO 0x17aa +#define PCI_VENDOR_ID_CDNS 0x17cd + #define PCI_VENDOR_ID_ARECA0x17d3 #define PCI_DEVICE_ID_ARECA_1110 0x1110 #define PCI_DEVICE_ID_ARECA_1120 0x1120 -- 2.11.0
[PATCH v4 2/7] PCI: OF: Add generic function to parse and allocate PCI resources
The patch moves the gen_pci_parse_request_of_pci_ranges() function from drivers/pci/host/pci-host-common.c into drivers/pci/of.c to easily share common source code between PCI host drivers. Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> --- drivers/pci/host/pci-host-common.c | 49 ++-- drivers/pci/of.c | 51 ++ include/linux/pci.h| 9 +++ 3 files changed, 62 insertions(+), 47 deletions(-) diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c index c4b891c84703..a613ea310e76 100644 --- a/drivers/pci/host/pci-host-common.c +++ b/drivers/pci/host/pci-host-common.c @@ -24,50 +24,6 @@ #include #include -static int gen_pci_parse_request_of_pci_ranges(struct device *dev, - struct list_head *resources, struct resource **bus_range) -{ - int err, res_valid = 0; - struct device_node *np = dev->of_node; - resource_size_t iobase; - struct resource_entry *win, *tmp; - - err = of_pci_get_host_bridge_resources(np, 0, 0xff, resources, ); - if (err) - return err; - - err = devm_request_pci_bus_resources(dev, resources); - if (err) - return err; - - resource_list_for_each_entry_safe(win, tmp, resources) { - struct resource *res = win->res; - - switch (resource_type(res)) { - case IORESOURCE_IO: - err = pci_remap_iospace(res, iobase); - if (err) { - dev_warn(dev, "error %d: failed to map resource %pR\n", -err, res); - resource_list_destroy_entry(win); - } - break; - case IORESOURCE_MEM: - res_valid |= !(res->flags & IORESOURCE_PREFETCH); - break; - case IORESOURCE_BUS: - *bus_range = res; - break; - } - } - - if (res_valid) - return 0; - - dev_err(dev, "non-prefetchable memory resource required\n"); - return -EINVAL; -} - static void gen_pci_unmap_cfg(void *ptr) { pci_ecam_free((struct pci_config_window *)ptr); @@ -82,9 +38,9 @@ static struct pci_config_window *gen_pci_init(struct device *dev, struct pci_config_window *cfg; /* Parse our PCI ranges and request their resources */ - err = gen_pci_parse_request_of_pci_ranges(dev, resources, _range); + err = pci_parse_request_of_pci_ranges(dev, resources, _range); if (err) - goto err_out; + return ERR_PTR(err); err = of_address_to_resource(dev->of_node, 0, ); if (err) { @@ -135,7 +91,6 @@ int pci_host_common_probe(struct platform_device *pdev, of_pci_check_probe_only(); /* Parse and map our Configuration Space windows */ - INIT_LIST_HEAD(); cfg = gen_pci_init(dev, , ops); if (IS_ERR(cfg)) return PTR_ERR(cfg); diff --git a/drivers/pci/of.c b/drivers/pci/of.c index e112da11630e..54e210501b73 100644 --- a/drivers/pci/of.c +++ b/drivers/pci/of.c @@ -88,3 +88,54 @@ struct irq_domain *pci_host_bridge_of_msi_domain(struct pci_bus *bus) return NULL; #endif } + +int pci_parse_request_of_pci_ranges(struct device *dev, + struct list_head *resources, + struct resource **bus_range) +{ + int err, res_valid = 0; + struct device_node *np = dev->of_node; + resource_size_t iobase; + struct resource_entry *win, *tmp; + + INIT_LIST_HEAD(resources); + err = of_pci_get_host_bridge_resources(np, 0, 0xff, resources, ); + if (err) + return err; + + err = devm_request_pci_bus_resources(dev, resources); + if (err) + goto out_release_res; + + resource_list_for_each_entry_safe(win, tmp, resources) { + struct resource *res = win->res; + + switch (resource_type(res)) { + case IORESOURCE_IO: + err = pci_remap_iospace(res, iobase); + if (err) { + dev_warn(dev, "error %d: failed to map resource %pR\n", +err, res); + resource_list_destroy_entry(win); + } + break; + case IORESOURCE_MEM: + res_valid |= !(res->flags & IORESOURCE_PREFETCH); + break; + case IORESOURCE_BUS: + if (bus_range) + *bus_range = res; +
[PATCH v4 2/7] PCI: OF: Add generic function to parse and allocate PCI resources
The patch moves the gen_pci_parse_request_of_pci_ranges() function from drivers/pci/host/pci-host-common.c into drivers/pci/of.c to easily share common source code between PCI host drivers. Signed-off-by: Cyrille Pitchen --- drivers/pci/host/pci-host-common.c | 49 ++-- drivers/pci/of.c | 51 ++ include/linux/pci.h| 9 +++ 3 files changed, 62 insertions(+), 47 deletions(-) diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c index c4b891c84703..a613ea310e76 100644 --- a/drivers/pci/host/pci-host-common.c +++ b/drivers/pci/host/pci-host-common.c @@ -24,50 +24,6 @@ #include #include -static int gen_pci_parse_request_of_pci_ranges(struct device *dev, - struct list_head *resources, struct resource **bus_range) -{ - int err, res_valid = 0; - struct device_node *np = dev->of_node; - resource_size_t iobase; - struct resource_entry *win, *tmp; - - err = of_pci_get_host_bridge_resources(np, 0, 0xff, resources, ); - if (err) - return err; - - err = devm_request_pci_bus_resources(dev, resources); - if (err) - return err; - - resource_list_for_each_entry_safe(win, tmp, resources) { - struct resource *res = win->res; - - switch (resource_type(res)) { - case IORESOURCE_IO: - err = pci_remap_iospace(res, iobase); - if (err) { - dev_warn(dev, "error %d: failed to map resource %pR\n", -err, res); - resource_list_destroy_entry(win); - } - break; - case IORESOURCE_MEM: - res_valid |= !(res->flags & IORESOURCE_PREFETCH); - break; - case IORESOURCE_BUS: - *bus_range = res; - break; - } - } - - if (res_valid) - return 0; - - dev_err(dev, "non-prefetchable memory resource required\n"); - return -EINVAL; -} - static void gen_pci_unmap_cfg(void *ptr) { pci_ecam_free((struct pci_config_window *)ptr); @@ -82,9 +38,9 @@ static struct pci_config_window *gen_pci_init(struct device *dev, struct pci_config_window *cfg; /* Parse our PCI ranges and request their resources */ - err = gen_pci_parse_request_of_pci_ranges(dev, resources, _range); + err = pci_parse_request_of_pci_ranges(dev, resources, _range); if (err) - goto err_out; + return ERR_PTR(err); err = of_address_to_resource(dev->of_node, 0, ); if (err) { @@ -135,7 +91,6 @@ int pci_host_common_probe(struct platform_device *pdev, of_pci_check_probe_only(); /* Parse and map our Configuration Space windows */ - INIT_LIST_HEAD(); cfg = gen_pci_init(dev, , ops); if (IS_ERR(cfg)) return PTR_ERR(cfg); diff --git a/drivers/pci/of.c b/drivers/pci/of.c index e112da11630e..54e210501b73 100644 --- a/drivers/pci/of.c +++ b/drivers/pci/of.c @@ -88,3 +88,54 @@ struct irq_domain *pci_host_bridge_of_msi_domain(struct pci_bus *bus) return NULL; #endif } + +int pci_parse_request_of_pci_ranges(struct device *dev, + struct list_head *resources, + struct resource **bus_range) +{ + int err, res_valid = 0; + struct device_node *np = dev->of_node; + resource_size_t iobase; + struct resource_entry *win, *tmp; + + INIT_LIST_HEAD(resources); + err = of_pci_get_host_bridge_resources(np, 0, 0xff, resources, ); + if (err) + return err; + + err = devm_request_pci_bus_resources(dev, resources); + if (err) + goto out_release_res; + + resource_list_for_each_entry_safe(win, tmp, resources) { + struct resource *res = win->res; + + switch (resource_type(res)) { + case IORESOURCE_IO: + err = pci_remap_iospace(res, iobase); + if (err) { + dev_warn(dev, "error %d: failed to map resource %pR\n", +err, res); + resource_list_destroy_entry(win); + } + break; + case IORESOURCE_MEM: + res_valid |= !(res->flags & IORESOURCE_PREFETCH); + break; + case IORESOURCE_BUS: + if (bus_range) + *bus_range = res; + break; + } + } + +
[PATCH v4 6/7] dt-bindings: PCI: cadence: Add DT bindings for Cadence PCIe host controller
From: Scott Telford <stelf...@cadence.com> This patch adds documentation for the DT bindings of the Cadence PCIe controller when configured in host (Root Complex) mode. Signed-off-by: Scott Telford <stelf...@cadence.com> Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> Reviewed-by: Rob Herring <r...@kernel.org> --- .../bindings/pci/cdns,cdns-pcie-host.txt | 60 ++ 1 file changed, 60 insertions(+) create mode 100644 Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt diff --git a/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt new file mode 100644 index ..20a33f38f69d --- /dev/null +++ b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt @@ -0,0 +1,60 @@ +* Cadence PCIe host controller + +This PCIe controller inherits the base properties defined in +host-generic-pci.txt. + +Required properties: +- compatible: Should contain "cdns,cdns-pcie-host" to identify the IP used. +- reg: Should contain the controller register base address, PCIe configuration + window base address, and AXI interface region base address respectively. +- reg-names: Must be "reg", "cfg" and "mem" respectively. +- #address-cells: Set to <3> +- #size-cells: Set to <2> +- device_type: Set to "pci" +- ranges: Ranges for the PCI memory and I/O regions +- #interrupt-cells: Set to <1> +- interrupt-map-mask and interrupt-map: Standard PCI properties to define the + mapping of the PCIe interface to interrupt numbers. + +Optional properties: +- cdns,max-outbound-regions: Set to maximum number of outbound regions + (default 32) +- cdns,no-bar-match-nbits: Set into the no BAR match register to configure the + number of least significant bits kept during inbound (PCIe -> AXI) address + translations (default 32) +- vendor-id: The PCI vendor ID (16 bits, default is design dependent) +- device-id: The PCI device ID (16 bits, default is design dependent) + +Example: + +pcie@fb00 { + compatible = "cdns,cdns-pcie-host"; + device_type = "pci"; + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0x0 0xff>; + linux,pci-domain = <0>; + cdns,max-outbound-regions = <16>; + cdns,no-bar-match-nbits = <32>; + vendor-id = /bits/ 16 <0x17cd>; + device-id = /bits/ 16 <0x0200>; + + reg = <0x0 0xfb00 0x0 0x0100>, + <0x0 0x4100 0x0 0x1000>, + <0x0 0x4000 0x0 0x0400>; + reg-names = "reg", "cfg", "mem"; + + ranges = <0x0200 0x0 0x4200 0x0 0x4200 0x0 0x100>, +<0x0100 0x0 0x4300 0x0 0x4300 0x0 0x001>; + + #interrupt-cells = <0x1>; + + interrupt-map = <0x0 0x0 0x0 0x10x0 0x0 0x0 14 0x1 +0x0 0x0 0x0 0x20x0 0x0 0x0 15 0x1 +0x0 0x0 0x0 0x30x0 0x0 0x0 16 0x1 +0x0 0x0 0x0 0x40x0 0x0 0x0 17 0x1>; + + interrupt-map-mask = <0x0 0x0 0x0 0x7>; + + msi-parent = <_pci>; +}; -- 2.11.0
[PATCH v4 6/7] dt-bindings: PCI: cadence: Add DT bindings for Cadence PCIe host controller
From: Scott Telford This patch adds documentation for the DT bindings of the Cadence PCIe controller when configured in host (Root Complex) mode. Signed-off-by: Scott Telford Signed-off-by: Cyrille Pitchen Reviewed-by: Rob Herring --- .../bindings/pci/cdns,cdns-pcie-host.txt | 60 ++ 1 file changed, 60 insertions(+) create mode 100644 Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt diff --git a/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt new file mode 100644 index ..20a33f38f69d --- /dev/null +++ b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt @@ -0,0 +1,60 @@ +* Cadence PCIe host controller + +This PCIe controller inherits the base properties defined in +host-generic-pci.txt. + +Required properties: +- compatible: Should contain "cdns,cdns-pcie-host" to identify the IP used. +- reg: Should contain the controller register base address, PCIe configuration + window base address, and AXI interface region base address respectively. +- reg-names: Must be "reg", "cfg" and "mem" respectively. +- #address-cells: Set to <3> +- #size-cells: Set to <2> +- device_type: Set to "pci" +- ranges: Ranges for the PCI memory and I/O regions +- #interrupt-cells: Set to <1> +- interrupt-map-mask and interrupt-map: Standard PCI properties to define the + mapping of the PCIe interface to interrupt numbers. + +Optional properties: +- cdns,max-outbound-regions: Set to maximum number of outbound regions + (default 32) +- cdns,no-bar-match-nbits: Set into the no BAR match register to configure the + number of least significant bits kept during inbound (PCIe -> AXI) address + translations (default 32) +- vendor-id: The PCI vendor ID (16 bits, default is design dependent) +- device-id: The PCI device ID (16 bits, default is design dependent) + +Example: + +pcie@fb00 { + compatible = "cdns,cdns-pcie-host"; + device_type = "pci"; + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0x0 0xff>; + linux,pci-domain = <0>; + cdns,max-outbound-regions = <16>; + cdns,no-bar-match-nbits = <32>; + vendor-id = /bits/ 16 <0x17cd>; + device-id = /bits/ 16 <0x0200>; + + reg = <0x0 0xfb00 0x0 0x0100>, + <0x0 0x4100 0x0 0x1000>, + <0x0 0x4000 0x0 0x0400>; + reg-names = "reg", "cfg", "mem"; + + ranges = <0x0200 0x0 0x4200 0x0 0x4200 0x0 0x100>, +<0x0100 0x0 0x4300 0x0 0x4300 0x0 0x001>; + + #interrupt-cells = <0x1>; + + interrupt-map = <0x0 0x0 0x0 0x10x0 0x0 0x0 14 0x1 +0x0 0x0 0x0 0x20x0 0x0 0x0 15 0x1 +0x0 0x0 0x0 0x30x0 0x0 0x0 16 0x1 +0x0 0x0 0x0 0x40x0 0x0 0x0 17 0x1>; + + interrupt-map-mask = <0x0 0x0 0x0 0x7>; + + msi-parent = <_pci>; +}; -- 2.11.0
[PATCH v4 1/7] PCI: Regroup all PCI related entries into drivers/pci/Makefile
Clean up drivers/Makefile by moving the pci/endpoint and pci/dwc entries from drivers/Makefile into drivers/pci/Makefile. Since we don't want to introduce any dependency between CONFIG_PCI and CONFIG_PCI_ENDPOINT, we now always execute drivers/pci/Makefile. Hence all Makefiles in drivers/pci/ were updated accordingly so no file is compiled when CONFIG_PCI is not defined. Also, we add a comment to reinforce that EPC and EPF libraries must be initialized before their users. Hence built-in EPC drivers, such as those of Designware, are linked after the endpoint core libraries. Finally, we add another comment to explain why obj-y has been chosen instead of obj-$(CONFIG_PCIE_DW) to parse the dwc/ sub-folder. Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> --- drivers/Makefile | 5 + drivers/pci/Kconfig | 1 + drivers/pci/Makefile | 13 ++--- drivers/pci/dwc/Makefile | 2 ++ drivers/pci/host/Makefile | 2 ++ 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/Makefile b/drivers/Makefile index e06f7f633f73..8189b1edec00 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -16,10 +16,7 @@ obj-$(CONFIG_PINCTRL)+= pinctrl/ obj-$(CONFIG_GPIOLIB) += gpio/ obj-y += pwm/ -obj-$(CONFIG_PCI) += pci/ -obj-$(CONFIG_PCI_ENDPOINT) += pci/endpoint/ -# PCI dwc controller drivers -obj-y += pci/dwc/ +obj-y += pci/ obj-$(CONFIG_PARISC) += parisc/ obj-$(CONFIG_RAPIDIO) += rapidio/ diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index bda151788f3f..7eeb969ab86a 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -125,6 +125,7 @@ config PCI_PASID config PCI_LABEL def_bool y if (DMI || ACPI) + depends on PCI select NLS config PCI_HYPERV diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index c7819b973df7..ddb5aa6640d7 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -3,12 +3,15 @@ # Makefile for the PCI bus specific drivers. # -obj-y += access.o bus.o probe.o host-bridge.o remove.o pci.o \ +obj-$(CONFIG_PCI) += access.o bus.o probe.o host-bridge.o remove.o pci.o \ pci-driver.o search.o pci-sysfs.o rom.o setup-res.o \ irq.o vpd.o setup-bus.o vc.o mmap.o setup-irq.o +ifdef CONFIG_PCI obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_SYSFS) += slot.o +obj-$(CONFIG_OF) += of.o +endif obj-$(CONFIG_PCI_QUIRKS) += quirks.o @@ -44,10 +47,14 @@ obj-$(CONFIG_PCI_ECAM) += ecam.o obj-$(CONFIG_XEN_PCIDEV_FRONTEND) += xen-pcifront.o -obj-$(CONFIG_OF) += of.o - ccflags-$(CONFIG_PCI_DEBUG) := -DDEBUG # PCI host controller drivers obj-y += host/ obj-y += switch/ + +obj-$(CONFIG_PCI_ENDPOINT) += endpoint/ + +# Endpoint library must be initialized before its users +# pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW +obj-y += dwc/ diff --git a/drivers/pci/dwc/Makefile b/drivers/pci/dwc/Makefile index a9d8a6fb48e3..5d2ce72c7a52 100644 --- a/drivers/pci/dwc/Makefile +++ b/drivers/pci/dwc/Makefile @@ -25,4 +25,6 @@ obj-$(CONFIG_PCIE_HISI_STB) += pcie-histb.o # ARM64 and use internal ifdefs to only build the pieces we need # depending on whether ACPI, the DT driver, or both are enabled. +ifdef CONFIG_PCI obj-$(CONFIG_ARM64) += pcie-hisi.o +endif diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile index 34ec1d88f961..3b1059190867 100644 --- a/drivers/pci/host/Makefile +++ b/drivers/pci/host/Makefile @@ -34,6 +34,8 @@ obj-$(CONFIG_VMD) += vmd.o # ARM64 and use internal ifdefs to only build the pieces we need # depending on whether ACPI, the DT driver, or both are enabled. +ifdef CONFIG_PCI obj-$(CONFIG_ARM64) += pci-thunder-ecam.o obj-$(CONFIG_ARM64) += pci-thunder-pem.o obj-$(CONFIG_ARM64) += pci-xgene.o +endif -- 2.11.0
[PATCH v4 1/7] PCI: Regroup all PCI related entries into drivers/pci/Makefile
Clean up drivers/Makefile by moving the pci/endpoint and pci/dwc entries from drivers/Makefile into drivers/pci/Makefile. Since we don't want to introduce any dependency between CONFIG_PCI and CONFIG_PCI_ENDPOINT, we now always execute drivers/pci/Makefile. Hence all Makefiles in drivers/pci/ were updated accordingly so no file is compiled when CONFIG_PCI is not defined. Also, we add a comment to reinforce that EPC and EPF libraries must be initialized before their users. Hence built-in EPC drivers, such as those of Designware, are linked after the endpoint core libraries. Finally, we add another comment to explain why obj-y has been chosen instead of obj-$(CONFIG_PCIE_DW) to parse the dwc/ sub-folder. Signed-off-by: Cyrille Pitchen --- drivers/Makefile | 5 + drivers/pci/Kconfig | 1 + drivers/pci/Makefile | 13 ++--- drivers/pci/dwc/Makefile | 2 ++ drivers/pci/host/Makefile | 2 ++ 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/Makefile b/drivers/Makefile index e06f7f633f73..8189b1edec00 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -16,10 +16,7 @@ obj-$(CONFIG_PINCTRL)+= pinctrl/ obj-$(CONFIG_GPIOLIB) += gpio/ obj-y += pwm/ -obj-$(CONFIG_PCI) += pci/ -obj-$(CONFIG_PCI_ENDPOINT) += pci/endpoint/ -# PCI dwc controller drivers -obj-y += pci/dwc/ +obj-y += pci/ obj-$(CONFIG_PARISC) += parisc/ obj-$(CONFIG_RAPIDIO) += rapidio/ diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index bda151788f3f..7eeb969ab86a 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -125,6 +125,7 @@ config PCI_PASID config PCI_LABEL def_bool y if (DMI || ACPI) + depends on PCI select NLS config PCI_HYPERV diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index c7819b973df7..ddb5aa6640d7 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -3,12 +3,15 @@ # Makefile for the PCI bus specific drivers. # -obj-y += access.o bus.o probe.o host-bridge.o remove.o pci.o \ +obj-$(CONFIG_PCI) += access.o bus.o probe.o host-bridge.o remove.o pci.o \ pci-driver.o search.o pci-sysfs.o rom.o setup-res.o \ irq.o vpd.o setup-bus.o vc.o mmap.o setup-irq.o +ifdef CONFIG_PCI obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_SYSFS) += slot.o +obj-$(CONFIG_OF) += of.o +endif obj-$(CONFIG_PCI_QUIRKS) += quirks.o @@ -44,10 +47,14 @@ obj-$(CONFIG_PCI_ECAM) += ecam.o obj-$(CONFIG_XEN_PCIDEV_FRONTEND) += xen-pcifront.o -obj-$(CONFIG_OF) += of.o - ccflags-$(CONFIG_PCI_DEBUG) := -DDEBUG # PCI host controller drivers obj-y += host/ obj-y += switch/ + +obj-$(CONFIG_PCI_ENDPOINT) += endpoint/ + +# Endpoint library must be initialized before its users +# pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW +obj-y += dwc/ diff --git a/drivers/pci/dwc/Makefile b/drivers/pci/dwc/Makefile index a9d8a6fb48e3..5d2ce72c7a52 100644 --- a/drivers/pci/dwc/Makefile +++ b/drivers/pci/dwc/Makefile @@ -25,4 +25,6 @@ obj-$(CONFIG_PCIE_HISI_STB) += pcie-histb.o # ARM64 and use internal ifdefs to only build the pieces we need # depending on whether ACPI, the DT driver, or both are enabled. +ifdef CONFIG_PCI obj-$(CONFIG_ARM64) += pcie-hisi.o +endif diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile index 34ec1d88f961..3b1059190867 100644 --- a/drivers/pci/host/Makefile +++ b/drivers/pci/host/Makefile @@ -34,6 +34,8 @@ obj-$(CONFIG_VMD) += vmd.o # ARM64 and use internal ifdefs to only build the pieces we need # depending on whether ACPI, the DT driver, or both are enabled. +ifdef CONFIG_PCI obj-$(CONFIG_ARM64) += pci-thunder-ecam.o obj-$(CONFIG_ARM64) += pci-thunder-pem.o obj-$(CONFIG_ARM64) += pci-xgene.o +endif -- 2.11.0
Re: [PATCH v3 3/6] PCI: Add generic function to probe PCI host controllers
Hi Lorenzo, Le 16/01/2018 à 16:25, Lorenzo Pieralisi a écrit : > On Wed, Jan 10, 2018 at 11:47:32PM +0100, Cyrille Pitchen wrote: >> This patchs moves generic source code from >> drivers/pci/host/pci-host-common.c into drivers/pci/probe.c. >> >> Indeed the extracted lines of code were duplicated by many host >> controller drivers. Regrouping them into a generic function gives a >> change to properly share this code without introducing a useless >> dependency to PCI_HOST_COMMON, which selects PCI_ECAM when not needed by >> most host controller drivers. >> >> We also add a missing call of pci_free_resource_list() from >> pci_host_common_probe() when probing fails, as done inside gen_pci_init() > I have to ask you to split this change into another patch. > > First add the missing pci_free_resource_list() then add this patch. > > Do you have time to respin quickly ? I would like to merge this > series for v4.16. > Sorry, I've been a little bit busy. I've just done it and submit v4. patch 3 from v3 split into patches 3 and 4 in v4. Best regards, Cyrille > Thanks, > Lorenzo > >> when this later function fails. >> >> Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> >> --- >> drivers/pci/host/pci-host-common.c | 25 +++-- >> drivers/pci/probe.c| 33 + >> include/linux/pci.h| 1 + >> 3 files changed, 37 insertions(+), 22 deletions(-) >> >> diff --git a/drivers/pci/host/pci-host-common.c >> b/drivers/pci/host/pci-host-common.c >> index a613ea310e76..df25b4a4edaf 100644 >> --- a/drivers/pci/host/pci-host-common.c >> +++ b/drivers/pci/host/pci-host-common.c >> @@ -72,7 +72,6 @@ int pci_host_common_probe(struct platform_device *pdev, >> const char *type; >> struct device *dev = >dev; >> struct device_node *np = dev->of_node; >> -struct pci_bus *bus, *child; >> struct pci_host_bridge *bridge; >> struct pci_config_window *cfg; >> struct list_head resources; >> @@ -107,29 +106,11 @@ int pci_host_common_probe(struct platform_device *pdev, >> bridge->map_irq = of_irq_parse_and_map_pci; >> bridge->swizzle_irq = pci_common_swizzle; >> >> -ret = pci_scan_root_bus_bridge(bridge); >> -if (ret < 0) { >> -dev_err(dev, "Scanning root bridge failed"); >> +ret = pci_host_probe(bridge); >> +if (ret) { >> +pci_free_resource_list(); >> return ret; >> } >> >> -bus = bridge->bus; >> - >> -/* >> - * We insert PCI resources into the iomem_resource and >> - * ioport_resource trees in either pci_bus_claim_resources() >> - * or pci_bus_assign_resources(). >> - */ >> -if (pci_has_flag(PCI_PROBE_ONLY)) { >> -pci_bus_claim_resources(bus); >> -} else { >> -pci_bus_size_bridges(bus); >> -pci_bus_assign_resources(bus); >> - >> -list_for_each_entry(child, >children, node) >> -pcie_bus_configure_settings(child); >> -} >> - >> -pci_bus_add_devices(bus); >> return 0; >> } >> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c >> index 1360db508035..178328d06a32 100644 >> --- a/drivers/pci/probe.c >> +++ b/drivers/pci/probe.c >> @@ -2685,6 +2685,39 @@ struct pci_bus *pci_create_root_bus(struct device >> *parent, int bus, >> } >> EXPORT_SYMBOL_GPL(pci_create_root_bus); >> >> +int pci_host_probe(struct pci_host_bridge *bridge) >> +{ >> +struct pci_bus *bus, *child; >> +int ret; >> + >> +ret = pci_scan_root_bus_bridge(bridge); >> +if (ret < 0) { >> +dev_err(bridge->dev.parent, "Scanning root bridge failed"); >> +return ret; >> +} >> + >> +bus = bridge->bus; >> + >> +/* >> + * We insert PCI resources into the iomem_resource and >> + * ioport_resource trees in either pci_bus_claim_resources() >> + * or pci_bus_assign_resources(). >> + */ >> +if (pci_has_flag(PCI_PROBE_ONLY)) { >> +pci_bus_claim_resources(bus); >> +} else { >> +pci_bus_size_bridges(bus); >> +pci_bus_assign_resources(bus); >> + >> +list_for_each_entry(child, >children, node) >> +pcie_bus_configure_settings(child); >>
Re: [PATCH v3 3/6] PCI: Add generic function to probe PCI host controllers
Hi Lorenzo, Le 16/01/2018 à 16:25, Lorenzo Pieralisi a écrit : > On Wed, Jan 10, 2018 at 11:47:32PM +0100, Cyrille Pitchen wrote: >> This patchs moves generic source code from >> drivers/pci/host/pci-host-common.c into drivers/pci/probe.c. >> >> Indeed the extracted lines of code were duplicated by many host >> controller drivers. Regrouping them into a generic function gives a >> change to properly share this code without introducing a useless >> dependency to PCI_HOST_COMMON, which selects PCI_ECAM when not needed by >> most host controller drivers. >> >> We also add a missing call of pci_free_resource_list() from >> pci_host_common_probe() when probing fails, as done inside gen_pci_init() > I have to ask you to split this change into another patch. > > First add the missing pci_free_resource_list() then add this patch. > > Do you have time to respin quickly ? I would like to merge this > series for v4.16. > Sorry, I've been a little bit busy. I've just done it and submit v4. patch 3 from v3 split into patches 3 and 4 in v4. Best regards, Cyrille > Thanks, > Lorenzo > >> when this later function fails. >> >> Signed-off-by: Cyrille Pitchen >> --- >> drivers/pci/host/pci-host-common.c | 25 +++-- >> drivers/pci/probe.c| 33 + >> include/linux/pci.h| 1 + >> 3 files changed, 37 insertions(+), 22 deletions(-) >> >> diff --git a/drivers/pci/host/pci-host-common.c >> b/drivers/pci/host/pci-host-common.c >> index a613ea310e76..df25b4a4edaf 100644 >> --- a/drivers/pci/host/pci-host-common.c >> +++ b/drivers/pci/host/pci-host-common.c >> @@ -72,7 +72,6 @@ int pci_host_common_probe(struct platform_device *pdev, >> const char *type; >> struct device *dev = >dev; >> struct device_node *np = dev->of_node; >> -struct pci_bus *bus, *child; >> struct pci_host_bridge *bridge; >> struct pci_config_window *cfg; >> struct list_head resources; >> @@ -107,29 +106,11 @@ int pci_host_common_probe(struct platform_device *pdev, >> bridge->map_irq = of_irq_parse_and_map_pci; >> bridge->swizzle_irq = pci_common_swizzle; >> >> -ret = pci_scan_root_bus_bridge(bridge); >> -if (ret < 0) { >> -dev_err(dev, "Scanning root bridge failed"); >> +ret = pci_host_probe(bridge); >> +if (ret) { >> +pci_free_resource_list(); >> return ret; >> } >> >> -bus = bridge->bus; >> - >> -/* >> - * We insert PCI resources into the iomem_resource and >> - * ioport_resource trees in either pci_bus_claim_resources() >> - * or pci_bus_assign_resources(). >> - */ >> -if (pci_has_flag(PCI_PROBE_ONLY)) { >> -pci_bus_claim_resources(bus); >> -} else { >> -pci_bus_size_bridges(bus); >> -pci_bus_assign_resources(bus); >> - >> -list_for_each_entry(child, >children, node) >> -pcie_bus_configure_settings(child); >> -} >> - >> -pci_bus_add_devices(bus); >> return 0; >> } >> diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c >> index 1360db508035..178328d06a32 100644 >> --- a/drivers/pci/probe.c >> +++ b/drivers/pci/probe.c >> @@ -2685,6 +2685,39 @@ struct pci_bus *pci_create_root_bus(struct device >> *parent, int bus, >> } >> EXPORT_SYMBOL_GPL(pci_create_root_bus); >> >> +int pci_host_probe(struct pci_host_bridge *bridge) >> +{ >> +struct pci_bus *bus, *child; >> +int ret; >> + >> +ret = pci_scan_root_bus_bridge(bridge); >> +if (ret < 0) { >> +dev_err(bridge->dev.parent, "Scanning root bridge failed"); >> +return ret; >> +} >> + >> +bus = bridge->bus; >> + >> +/* >> + * We insert PCI resources into the iomem_resource and >> + * ioport_resource trees in either pci_bus_claim_resources() >> + * or pci_bus_assign_resources(). >> + */ >> +if (pci_has_flag(PCI_PROBE_ONLY)) { >> +pci_bus_claim_resources(bus); >> +} else { >> +pci_bus_size_bridges(bus); >> +pci_bus_assign_resources(bus); >> + >> +list_for_each_entry(child, >children, node) >> +pcie_bus_configure_settings(child); >> +} >> + >> +pci_b
Re: [PATCH] mtd: mtk-nor: modify functions' name more generally
Le 18/12/2017 à 02:47, Guochun Mao a écrit : > Since more and more Mediatek's SoC can use this driver to > control spi-nor flash, functions' name with "mt8173_" is > no longer properly. Replacing "mt8173_" with "mtk_" will > be more accurate to describe these functions' usable scope. > > Signed-off-by: Guochun MaoApplied to the spi-nor/next branch of linux-mtd Thanks! > --- > drivers/mtd/spi-nor/mtk-quadspi.c | 240 > ++--- > 1 file changed, 120 insertions(+), 120 deletions(-) > > diff --git a/drivers/mtd/spi-nor/mtk-quadspi.c > b/drivers/mtd/spi-nor/mtk-quadspi.c > index abe455c..5442993 100644 > --- a/drivers/mtd/spi-nor/mtk-quadspi.c > +++ b/drivers/mtd/spi-nor/mtk-quadspi.c > @@ -110,7 +110,7 @@ > #define MTK_NOR_PRG_REG(n) (MTK_NOR_PRGDATA0_REG + 4 * (n)) > #define MTK_NOR_SHREG(n) (MTK_NOR_SHREG0_REG + 4 * (n)) > > -struct mt8173_nor { > +struct mtk_nor { > struct spi_nor nor; > struct device *dev; > void __iomem *base; /* nor flash base address */ > @@ -118,48 +118,48 @@ struct mt8173_nor { > struct clk *nor_clk; > }; > > -static void mt8173_nor_set_read_mode(struct mt8173_nor *mt8173_nor) > +static void mtk_nor_set_read_mode(struct mtk_nor *mtk_nor) > { > - struct spi_nor *nor = _nor->nor; > + struct spi_nor *nor = _nor->nor; > > switch (nor->read_proto) { > case SNOR_PROTO_1_1_1: > - writeb(nor->read_opcode, mt8173_nor->base + > + writeb(nor->read_opcode, mtk_nor->base + > MTK_NOR_PRGDATA3_REG); > - writeb(MTK_NOR_FAST_READ, mt8173_nor->base + > + writeb(MTK_NOR_FAST_READ, mtk_nor->base + > MTK_NOR_CFG1_REG); > break; > case SNOR_PROTO_1_1_2: > - writeb(nor->read_opcode, mt8173_nor->base + > + writeb(nor->read_opcode, mtk_nor->base + > MTK_NOR_PRGDATA3_REG); > - writeb(MTK_NOR_DUAL_READ_EN, mt8173_nor->base + > + writeb(MTK_NOR_DUAL_READ_EN, mtk_nor->base + > MTK_NOR_DUAL_REG); > break; > case SNOR_PROTO_1_1_4: > - writeb(nor->read_opcode, mt8173_nor->base + > + writeb(nor->read_opcode, mtk_nor->base + > MTK_NOR_PRGDATA4_REG); > - writeb(MTK_NOR_QUAD_READ_EN, mt8173_nor->base + > + writeb(MTK_NOR_QUAD_READ_EN, mtk_nor->base + > MTK_NOR_DUAL_REG); > break; > default: > - writeb(MTK_NOR_DUAL_DISABLE, mt8173_nor->base + > + writeb(MTK_NOR_DUAL_DISABLE, mtk_nor->base + > MTK_NOR_DUAL_REG); > break; > } > } > > -static int mt8173_nor_execute_cmd(struct mt8173_nor *mt8173_nor, u8 cmdval) > +static int mtk_nor_execute_cmd(struct mtk_nor *mtk_nor, u8 cmdval) > { > int reg; > u8 val = cmdval & 0x1f; > > - writeb(cmdval, mt8173_nor->base + MTK_NOR_CMD_REG); > - return readl_poll_timeout(mt8173_nor->base + MTK_NOR_CMD_REG, reg, > + writeb(cmdval, mtk_nor->base + MTK_NOR_CMD_REG); > + return readl_poll_timeout(mtk_nor->base + MTK_NOR_CMD_REG, reg, > !(reg & val), 100, 1); > } > > -static int mt8173_nor_do_tx_rx(struct mt8173_nor *mt8173_nor, u8 op, > -u8 *tx, int txlen, u8 *rx, int rxlen) > +static int mtk_nor_do_tx_rx(struct mtk_nor *mtk_nor, u8 op, > + u8 *tx, int txlen, u8 *rx, int rxlen) > { > int len = 1 + txlen + rxlen; > int i, ret, idx; > @@ -167,26 +167,26 @@ static int mt8173_nor_do_tx_rx(struct mt8173_nor > *mt8173_nor, u8 op, > if (len > MTK_NOR_MAX_SHIFT) > return -EINVAL; > > - writeb(len * 8, mt8173_nor->base + MTK_NOR_CNT_REG); > + writeb(len * 8, mtk_nor->base + MTK_NOR_CNT_REG); > > /* start at PRGDATA5, go down to PRGDATA0 */ > idx = MTK_NOR_MAX_RX_TX_SHIFT - 1; > > /* opcode */ > - writeb(op, mt8173_nor->base + MTK_NOR_PRG_REG(idx)); > + writeb(op, mtk_nor->base + MTK_NOR_PRG_REG(idx)); > idx--; > > /* program TX data */ > for (i = 0; i < txlen; i++, idx--) > - writeb(tx[i], mt8173_nor->base + MTK_NOR_PRG_REG(idx)); > + writeb(tx[i], mtk_nor->base + MTK_NOR_PRG_REG(idx)); > > /* clear out rest of TX registers */ > while (idx >= 0) { > - writeb(0, mt8173_nor->base + MTK_NOR_PRG_REG(idx)); > + writeb(0, mtk_nor->base + MTK_NOR_PRG_REG(idx)); > idx--; > } > > - ret = mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_PRG_CMD); > + ret = mtk_nor_execute_cmd(mtk_nor, MTK_NOR_PRG_CMD); > if (ret) > return ret; > > @@ -195,20 +195,20 @@ static int mt8173_nor_do_tx_rx(struct mt8173_nor > *mt8173_nor, u8 op, > > /* read out RX data */ >
Re: [PATCH] mtd: mtk-nor: modify functions' name more generally
Le 18/12/2017 à 02:47, Guochun Mao a écrit : > Since more and more Mediatek's SoC can use this driver to > control spi-nor flash, functions' name with "mt8173_" is > no longer properly. Replacing "mt8173_" with "mtk_" will > be more accurate to describe these functions' usable scope. > > Signed-off-by: Guochun Mao Applied to the spi-nor/next branch of linux-mtd Thanks! > --- > drivers/mtd/spi-nor/mtk-quadspi.c | 240 > ++--- > 1 file changed, 120 insertions(+), 120 deletions(-) > > diff --git a/drivers/mtd/spi-nor/mtk-quadspi.c > b/drivers/mtd/spi-nor/mtk-quadspi.c > index abe455c..5442993 100644 > --- a/drivers/mtd/spi-nor/mtk-quadspi.c > +++ b/drivers/mtd/spi-nor/mtk-quadspi.c > @@ -110,7 +110,7 @@ > #define MTK_NOR_PRG_REG(n) (MTK_NOR_PRGDATA0_REG + 4 * (n)) > #define MTK_NOR_SHREG(n) (MTK_NOR_SHREG0_REG + 4 * (n)) > > -struct mt8173_nor { > +struct mtk_nor { > struct spi_nor nor; > struct device *dev; > void __iomem *base; /* nor flash base address */ > @@ -118,48 +118,48 @@ struct mt8173_nor { > struct clk *nor_clk; > }; > > -static void mt8173_nor_set_read_mode(struct mt8173_nor *mt8173_nor) > +static void mtk_nor_set_read_mode(struct mtk_nor *mtk_nor) > { > - struct spi_nor *nor = _nor->nor; > + struct spi_nor *nor = _nor->nor; > > switch (nor->read_proto) { > case SNOR_PROTO_1_1_1: > - writeb(nor->read_opcode, mt8173_nor->base + > + writeb(nor->read_opcode, mtk_nor->base + > MTK_NOR_PRGDATA3_REG); > - writeb(MTK_NOR_FAST_READ, mt8173_nor->base + > + writeb(MTK_NOR_FAST_READ, mtk_nor->base + > MTK_NOR_CFG1_REG); > break; > case SNOR_PROTO_1_1_2: > - writeb(nor->read_opcode, mt8173_nor->base + > + writeb(nor->read_opcode, mtk_nor->base + > MTK_NOR_PRGDATA3_REG); > - writeb(MTK_NOR_DUAL_READ_EN, mt8173_nor->base + > + writeb(MTK_NOR_DUAL_READ_EN, mtk_nor->base + > MTK_NOR_DUAL_REG); > break; > case SNOR_PROTO_1_1_4: > - writeb(nor->read_opcode, mt8173_nor->base + > + writeb(nor->read_opcode, mtk_nor->base + > MTK_NOR_PRGDATA4_REG); > - writeb(MTK_NOR_QUAD_READ_EN, mt8173_nor->base + > + writeb(MTK_NOR_QUAD_READ_EN, mtk_nor->base + > MTK_NOR_DUAL_REG); > break; > default: > - writeb(MTK_NOR_DUAL_DISABLE, mt8173_nor->base + > + writeb(MTK_NOR_DUAL_DISABLE, mtk_nor->base + > MTK_NOR_DUAL_REG); > break; > } > } > > -static int mt8173_nor_execute_cmd(struct mt8173_nor *mt8173_nor, u8 cmdval) > +static int mtk_nor_execute_cmd(struct mtk_nor *mtk_nor, u8 cmdval) > { > int reg; > u8 val = cmdval & 0x1f; > > - writeb(cmdval, mt8173_nor->base + MTK_NOR_CMD_REG); > - return readl_poll_timeout(mt8173_nor->base + MTK_NOR_CMD_REG, reg, > + writeb(cmdval, mtk_nor->base + MTK_NOR_CMD_REG); > + return readl_poll_timeout(mtk_nor->base + MTK_NOR_CMD_REG, reg, > !(reg & val), 100, 1); > } > > -static int mt8173_nor_do_tx_rx(struct mt8173_nor *mt8173_nor, u8 op, > -u8 *tx, int txlen, u8 *rx, int rxlen) > +static int mtk_nor_do_tx_rx(struct mtk_nor *mtk_nor, u8 op, > + u8 *tx, int txlen, u8 *rx, int rxlen) > { > int len = 1 + txlen + rxlen; > int i, ret, idx; > @@ -167,26 +167,26 @@ static int mt8173_nor_do_tx_rx(struct mt8173_nor > *mt8173_nor, u8 op, > if (len > MTK_NOR_MAX_SHIFT) > return -EINVAL; > > - writeb(len * 8, mt8173_nor->base + MTK_NOR_CNT_REG); > + writeb(len * 8, mtk_nor->base + MTK_NOR_CNT_REG); > > /* start at PRGDATA5, go down to PRGDATA0 */ > idx = MTK_NOR_MAX_RX_TX_SHIFT - 1; > > /* opcode */ > - writeb(op, mt8173_nor->base + MTK_NOR_PRG_REG(idx)); > + writeb(op, mtk_nor->base + MTK_NOR_PRG_REG(idx)); > idx--; > > /* program TX data */ > for (i = 0; i < txlen; i++, idx--) > - writeb(tx[i], mt8173_nor->base + MTK_NOR_PRG_REG(idx)); > + writeb(tx[i], mtk_nor->base + MTK_NOR_PRG_REG(idx)); > > /* clear out rest of TX registers */ > while (idx >= 0) { > - writeb(0, mt8173_nor->base + MTK_NOR_PRG_REG(idx)); > + writeb(0, mtk_nor->base + MTK_NOR_PRG_REG(idx)); > idx--; > } > > - ret = mt8173_nor_execute_cmd(mt8173_nor, MTK_NOR_PRG_CMD); > + ret = mtk_nor_execute_cmd(mtk_nor, MTK_NOR_PRG_CMD); > if (ret) > return ret; > > @@ -195,20 +195,20 @@ static int mt8173_nor_do_tx_rx(struct mt8173_nor > *mt8173_nor, u8 op, > > /* read out RX data */ > for (i = 0; i <
[PATCH v3 4/6] PCI: Add vendor ID for Cadence
This patch adds a new PCI vendor ID for Cadence. Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> --- include/linux/pci_ids.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index ab20dc5db423..eb13e84e1fef 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2381,6 +2381,8 @@ #define PCI_VENDOR_ID_LENOVO 0x17aa +#define PCI_VENDOR_ID_CDNS 0x17cd + #define PCI_VENDOR_ID_ARECA0x17d3 #define PCI_DEVICE_ID_ARECA_1110 0x1110 #define PCI_DEVICE_ID_ARECA_1120 0x1120 -- 2.11.0
[PATCH v3 4/6] PCI: Add vendor ID for Cadence
This patch adds a new PCI vendor ID for Cadence. Signed-off-by: Cyrille Pitchen --- include/linux/pci_ids.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index ab20dc5db423..eb13e84e1fef 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h @@ -2381,6 +2381,8 @@ #define PCI_VENDOR_ID_LENOVO 0x17aa +#define PCI_VENDOR_ID_CDNS 0x17cd + #define PCI_VENDOR_ID_ARECA0x17d3 #define PCI_DEVICE_ID_ARECA_1110 0x1110 #define PCI_DEVICE_ID_ARECA_1120 0x1120 -- 2.11.0
[PATCH v3 1/6] PCI: Regroup all PCI related entries into drivers/pci/Makefile
Clean up drivers/Makefile by moving the pci/endpoint and pci/dwc entries from drivers/Makefile into drivers/pci/Makefile. Since we don't want to introduce any dependency between CONFIG_PCI and CONFIG_PCI_ENDPOINT, we now always execute drivers/pci/Makefile. Hence all Makefiles in drivers/pci/ were updated accordingly so no file is compiled when CONFIG_PCI is not defined. Also, we add a comment to reinforce that EPC and EPF libraries must be initialized before their users. Hence built-in EPC drivers, such as those of Designware, are linked after the endpoint core libraries. Finally, we add another comment to explain why obj-y has been chosen instead of obj-$(CONFIG_PCIE_DW) to parse the dwc/ sub-folder. Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> --- drivers/Makefile | 5 + drivers/pci/Kconfig | 1 + drivers/pci/Makefile | 13 ++--- drivers/pci/dwc/Makefile | 2 ++ drivers/pci/host/Makefile | 2 ++ 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/Makefile b/drivers/Makefile index e06f7f633f73..8189b1edec00 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -16,10 +16,7 @@ obj-$(CONFIG_PINCTRL)+= pinctrl/ obj-$(CONFIG_GPIOLIB) += gpio/ obj-y += pwm/ -obj-$(CONFIG_PCI) += pci/ -obj-$(CONFIG_PCI_ENDPOINT) += pci/endpoint/ -# PCI dwc controller drivers -obj-y += pci/dwc/ +obj-y += pci/ obj-$(CONFIG_PARISC) += parisc/ obj-$(CONFIG_RAPIDIO) += rapidio/ diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index bda151788f3f..7eeb969ab86a 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -125,6 +125,7 @@ config PCI_PASID config PCI_LABEL def_bool y if (DMI || ACPI) + depends on PCI select NLS config PCI_HYPERV diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index c7819b973df7..ddb5aa6640d7 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -3,12 +3,15 @@ # Makefile for the PCI bus specific drivers. # -obj-y += access.o bus.o probe.o host-bridge.o remove.o pci.o \ +obj-$(CONFIG_PCI) += access.o bus.o probe.o host-bridge.o remove.o pci.o \ pci-driver.o search.o pci-sysfs.o rom.o setup-res.o \ irq.o vpd.o setup-bus.o vc.o mmap.o setup-irq.o +ifdef CONFIG_PCI obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_SYSFS) += slot.o +obj-$(CONFIG_OF) += of.o +endif obj-$(CONFIG_PCI_QUIRKS) += quirks.o @@ -44,10 +47,14 @@ obj-$(CONFIG_PCI_ECAM) += ecam.o obj-$(CONFIG_XEN_PCIDEV_FRONTEND) += xen-pcifront.o -obj-$(CONFIG_OF) += of.o - ccflags-$(CONFIG_PCI_DEBUG) := -DDEBUG # PCI host controller drivers obj-y += host/ obj-y += switch/ + +obj-$(CONFIG_PCI_ENDPOINT) += endpoint/ + +# Endpoint library must be initialized before its users +# pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW +obj-y += dwc/ diff --git a/drivers/pci/dwc/Makefile b/drivers/pci/dwc/Makefile index a9d8a6fb48e3..5d2ce72c7a52 100644 --- a/drivers/pci/dwc/Makefile +++ b/drivers/pci/dwc/Makefile @@ -25,4 +25,6 @@ obj-$(CONFIG_PCIE_HISI_STB) += pcie-histb.o # ARM64 and use internal ifdefs to only build the pieces we need # depending on whether ACPI, the DT driver, or both are enabled. +ifdef CONFIG_PCI obj-$(CONFIG_ARM64) += pcie-hisi.o +endif diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile index 34ec1d88f961..3b1059190867 100644 --- a/drivers/pci/host/Makefile +++ b/drivers/pci/host/Makefile @@ -34,6 +34,8 @@ obj-$(CONFIG_VMD) += vmd.o # ARM64 and use internal ifdefs to only build the pieces we need # depending on whether ACPI, the DT driver, or both are enabled. +ifdef CONFIG_PCI obj-$(CONFIG_ARM64) += pci-thunder-ecam.o obj-$(CONFIG_ARM64) += pci-thunder-pem.o obj-$(CONFIG_ARM64) += pci-xgene.o +endif -- 2.11.0
[PATCH v3 1/6] PCI: Regroup all PCI related entries into drivers/pci/Makefile
Clean up drivers/Makefile by moving the pci/endpoint and pci/dwc entries from drivers/Makefile into drivers/pci/Makefile. Since we don't want to introduce any dependency between CONFIG_PCI and CONFIG_PCI_ENDPOINT, we now always execute drivers/pci/Makefile. Hence all Makefiles in drivers/pci/ were updated accordingly so no file is compiled when CONFIG_PCI is not defined. Also, we add a comment to reinforce that EPC and EPF libraries must be initialized before their users. Hence built-in EPC drivers, such as those of Designware, are linked after the endpoint core libraries. Finally, we add another comment to explain why obj-y has been chosen instead of obj-$(CONFIG_PCIE_DW) to parse the dwc/ sub-folder. Signed-off-by: Cyrille Pitchen --- drivers/Makefile | 5 + drivers/pci/Kconfig | 1 + drivers/pci/Makefile | 13 ++--- drivers/pci/dwc/Makefile | 2 ++ drivers/pci/host/Makefile | 2 ++ 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/Makefile b/drivers/Makefile index e06f7f633f73..8189b1edec00 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -16,10 +16,7 @@ obj-$(CONFIG_PINCTRL)+= pinctrl/ obj-$(CONFIG_GPIOLIB) += gpio/ obj-y += pwm/ -obj-$(CONFIG_PCI) += pci/ -obj-$(CONFIG_PCI_ENDPOINT) += pci/endpoint/ -# PCI dwc controller drivers -obj-y += pci/dwc/ +obj-y += pci/ obj-$(CONFIG_PARISC) += parisc/ obj-$(CONFIG_RAPIDIO) += rapidio/ diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index bda151788f3f..7eeb969ab86a 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -125,6 +125,7 @@ config PCI_PASID config PCI_LABEL def_bool y if (DMI || ACPI) + depends on PCI select NLS config PCI_HYPERV diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index c7819b973df7..ddb5aa6640d7 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -3,12 +3,15 @@ # Makefile for the PCI bus specific drivers. # -obj-y += access.o bus.o probe.o host-bridge.o remove.o pci.o \ +obj-$(CONFIG_PCI) += access.o bus.o probe.o host-bridge.o remove.o pci.o \ pci-driver.o search.o pci-sysfs.o rom.o setup-res.o \ irq.o vpd.o setup-bus.o vc.o mmap.o setup-irq.o +ifdef CONFIG_PCI obj-$(CONFIG_PROC_FS) += proc.o obj-$(CONFIG_SYSFS) += slot.o +obj-$(CONFIG_OF) += of.o +endif obj-$(CONFIG_PCI_QUIRKS) += quirks.o @@ -44,10 +47,14 @@ obj-$(CONFIG_PCI_ECAM) += ecam.o obj-$(CONFIG_XEN_PCIDEV_FRONTEND) += xen-pcifront.o -obj-$(CONFIG_OF) += of.o - ccflags-$(CONFIG_PCI_DEBUG) := -DDEBUG # PCI host controller drivers obj-y += host/ obj-y += switch/ + +obj-$(CONFIG_PCI_ENDPOINT) += endpoint/ + +# Endpoint library must be initialized before its users +# pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW +obj-y += dwc/ diff --git a/drivers/pci/dwc/Makefile b/drivers/pci/dwc/Makefile index a9d8a6fb48e3..5d2ce72c7a52 100644 --- a/drivers/pci/dwc/Makefile +++ b/drivers/pci/dwc/Makefile @@ -25,4 +25,6 @@ obj-$(CONFIG_PCIE_HISI_STB) += pcie-histb.o # ARM64 and use internal ifdefs to only build the pieces we need # depending on whether ACPI, the DT driver, or both are enabled. +ifdef CONFIG_PCI obj-$(CONFIG_ARM64) += pcie-hisi.o +endif diff --git a/drivers/pci/host/Makefile b/drivers/pci/host/Makefile index 34ec1d88f961..3b1059190867 100644 --- a/drivers/pci/host/Makefile +++ b/drivers/pci/host/Makefile @@ -34,6 +34,8 @@ obj-$(CONFIG_VMD) += vmd.o # ARM64 and use internal ifdefs to only build the pieces we need # depending on whether ACPI, the DT driver, or both are enabled. +ifdef CONFIG_PCI obj-$(CONFIG_ARM64) += pci-thunder-ecam.o obj-$(CONFIG_ARM64) += pci-thunder-pem.o obj-$(CONFIG_ARM64) += pci-xgene.o +endif -- 2.11.0
[PATCH v3 6/6] PCI: cadence: Add host driver for Cadence PCIe controller
This patch adds support to the Cadence PCIe controller in host mode. Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> --- MAINTAINERS | 7 + drivers/pci/Kconfig | 1 + drivers/pci/Makefile| 1 + drivers/pci/cadence/Kconfig | 16 ++ drivers/pci/cadence/Makefile| 3 + drivers/pci/cadence/pcie-cadence-host.c | 336 drivers/pci/cadence/pcie-cadence.c | 68 +++ drivers/pci/cadence/pcie-cadence.h | 196 +++ 8 files changed, 628 insertions(+) create mode 100644 drivers/pci/cadence/Kconfig create mode 100644 drivers/pci/cadence/Makefile create mode 100644 drivers/pci/cadence/pcie-cadence-host.c create mode 100644 drivers/pci/cadence/pcie-cadence.c create mode 100644 drivers/pci/cadence/pcie-cadence.h diff --git a/MAINTAINERS b/MAINTAINERS index 13945646b95d..cc24c74a946e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10402,6 +10402,13 @@ S: Maintained F: Documentation/devicetree/bindings/pci/pci-armada8k.txt F: drivers/pci/dwc/pcie-armada8k.c +PCI DRIVER FOR CADENCE PCIE IP +M: Alan Douglas <adoug...@cadence.com> +L: linux-...@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/pci/cdns,*.txt +F: drivers/pci/cadence/pcie-cadence* + PCI DRIVER FOR FREESCALE LAYERSCAPE M: Minghuan Lian <minghuan.l...@freescale.com> M: Mingkai Hu <mingkai...@freescale.com> diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 7eeb969ab86a..dee90cc1dcaf 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -136,6 +136,7 @@ config PCI_HYPERV PCI devices from a PCI backend to support PCI driver domains. source "drivers/pci/hotplug/Kconfig" +source "drivers/pci/cadence/Kconfig" source "drivers/pci/dwc/Kconfig" source "drivers/pci/host/Kconfig" source "drivers/pci/endpoint/Kconfig" diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index ddb5aa6640d7..941970936840 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -56,5 +56,6 @@ obj-y += switch/ obj-$(CONFIG_PCI_ENDPOINT) += endpoint/ # Endpoint library must be initialized before its users +obj-$(CONFIG_PCIE_CADENCE) += cadence/ # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW obj-y += dwc/ diff --git a/drivers/pci/cadence/Kconfig b/drivers/pci/cadence/Kconfig new file mode 100644 index ..0123d384a628 --- /dev/null +++ b/drivers/pci/cadence/Kconfig @@ -0,0 +1,16 @@ +menu "Cadence PCIe controllers support" + +config PCIE_CADENCE + bool + +config PCIE_CADENCE_HOST + bool "Cadence PCIe host controller" + depends on OF + select IRQ_DOMAIN + select PCIE_CADENCE + help + Say Y here if you want to support the Cadence PCIe controller in host + mode. This PCIe controller may be embedded into many different vendors + SoCs. + +endmenu diff --git a/drivers/pci/cadence/Makefile b/drivers/pci/cadence/Makefile new file mode 100644 index ..589601a8ff89 --- /dev/null +++ b/drivers/pci/cadence/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_PCIE_CADENCE) += pcie-cadence.o +obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host.o diff --git a/drivers/pci/cadence/pcie-cadence-host.c b/drivers/pci/cadence/pcie-cadence-host.c new file mode 100644 index ..26caf8963e3c --- /dev/null +++ b/drivers/pci/cadence/pcie-cadence-host.c @@ -0,0 +1,336 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2017 Cadence +// Cadence PCIe host controller driver. +// Author: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> + +#include +#include +#include +#include +#include + +#include "pcie-cadence.h" + +/** + * struct cdns_pcie_rc - private data for this PCIe Root Complex driver + * @pcie: Cadence PCIe controller + * @dev: pointer to PCIe device + * @cfg_res: start/end offsets in the physical system memory to map PCI + * configuration space accesses + * @bus_range: first/last buses behind the PCIe host controller + * @cfg_base: IO mapped window to access the PCI configuration space of a + *single function at a time + * @max_regions: maximum number of regions supported by the hardware + * @no_bar_nbits: Number of bits to keep for inbound (PCIe -> CPU) address + *translation (nbits sets into the "no BAR match" register) + * @vendor_id: PCI vendor ID + * @device_id: PCI device ID + */ +struct cdns_pcie_rc { + struct cdns_pciepcie; + struct device *dev; + struct resource *cfg_res; + struct resource *bus_range; + void __iomem*cfg_base; + u32 max_regions; + u32
[PATCH v3 3/6] PCI: Add generic function to probe PCI host controllers
This patchs moves generic source code from drivers/pci/host/pci-host-common.c into drivers/pci/probe.c. Indeed the extracted lines of code were duplicated by many host controller drivers. Regrouping them into a generic function gives a change to properly share this code without introducing a useless dependency to PCI_HOST_COMMON, which selects PCI_ECAM when not needed by most host controller drivers. We also add a missing call of pci_free_resource_list() from pci_host_common_probe() when probing fails, as done inside gen_pci_init() when this later function fails. Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> --- drivers/pci/host/pci-host-common.c | 25 +++-- drivers/pci/probe.c| 33 + include/linux/pci.h| 1 + 3 files changed, 37 insertions(+), 22 deletions(-) diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c index a613ea310e76..df25b4a4edaf 100644 --- a/drivers/pci/host/pci-host-common.c +++ b/drivers/pci/host/pci-host-common.c @@ -72,7 +72,6 @@ int pci_host_common_probe(struct platform_device *pdev, const char *type; struct device *dev = >dev; struct device_node *np = dev->of_node; - struct pci_bus *bus, *child; struct pci_host_bridge *bridge; struct pci_config_window *cfg; struct list_head resources; @@ -107,29 +106,11 @@ int pci_host_common_probe(struct platform_device *pdev, bridge->map_irq = of_irq_parse_and_map_pci; bridge->swizzle_irq = pci_common_swizzle; - ret = pci_scan_root_bus_bridge(bridge); - if (ret < 0) { - dev_err(dev, "Scanning root bridge failed"); + ret = pci_host_probe(bridge); + if (ret) { + pci_free_resource_list(); return ret; } - bus = bridge->bus; - - /* -* We insert PCI resources into the iomem_resource and -* ioport_resource trees in either pci_bus_claim_resources() -* or pci_bus_assign_resources(). -*/ - if (pci_has_flag(PCI_PROBE_ONLY)) { - pci_bus_claim_resources(bus); - } else { - pci_bus_size_bridges(bus); - pci_bus_assign_resources(bus); - - list_for_each_entry(child, >children, node) - pcie_bus_configure_settings(child); - } - - pci_bus_add_devices(bus); return 0; } diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 1360db508035..178328d06a32 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -2685,6 +2685,39 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, } EXPORT_SYMBOL_GPL(pci_create_root_bus); +int pci_host_probe(struct pci_host_bridge *bridge) +{ + struct pci_bus *bus, *child; + int ret; + + ret = pci_scan_root_bus_bridge(bridge); + if (ret < 0) { + dev_err(bridge->dev.parent, "Scanning root bridge failed"); + return ret; + } + + bus = bridge->bus; + + /* +* We insert PCI resources into the iomem_resource and +* ioport_resource trees in either pci_bus_claim_resources() +* or pci_bus_assign_resources(). +*/ + if (pci_has_flag(PCI_PROBE_ONLY)) { + pci_bus_claim_resources(bus); + } else { + pci_bus_size_bridges(bus); + pci_bus_assign_resources(bus); + + list_for_each_entry(child, >children, node) + pcie_bus_configure_settings(child); + } + + pci_bus_add_devices(bus); + return 0; +} +EXPORT_SYMBOL_GPL(pci_host_probe); + int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int bus_max) { struct resource *res = >busn_res; diff --git a/include/linux/pci.h b/include/linux/pci.h index a1b0672fd38a..0ca261fda900 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -879,6 +879,7 @@ struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata); struct pci_bus *pci_create_root_bus(struct device *parent, int bus, struct pci_ops *ops, void *sysdata, struct list_head *resources); +int pci_host_probe(struct pci_host_bridge *bridge); int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int busmax); int pci_bus_update_busn_res_end(struct pci_bus *b, int busmax); void pci_bus_release_busn_res(struct pci_bus *b); -- 2.11.0
[PATCH v3 6/6] PCI: cadence: Add host driver for Cadence PCIe controller
This patch adds support to the Cadence PCIe controller in host mode. Signed-off-by: Cyrille Pitchen --- MAINTAINERS | 7 + drivers/pci/Kconfig | 1 + drivers/pci/Makefile| 1 + drivers/pci/cadence/Kconfig | 16 ++ drivers/pci/cadence/Makefile| 3 + drivers/pci/cadence/pcie-cadence-host.c | 336 drivers/pci/cadence/pcie-cadence.c | 68 +++ drivers/pci/cadence/pcie-cadence.h | 196 +++ 8 files changed, 628 insertions(+) create mode 100644 drivers/pci/cadence/Kconfig create mode 100644 drivers/pci/cadence/Makefile create mode 100644 drivers/pci/cadence/pcie-cadence-host.c create mode 100644 drivers/pci/cadence/pcie-cadence.c create mode 100644 drivers/pci/cadence/pcie-cadence.h diff --git a/MAINTAINERS b/MAINTAINERS index 13945646b95d..cc24c74a946e 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -10402,6 +10402,13 @@ S: Maintained F: Documentation/devicetree/bindings/pci/pci-armada8k.txt F: drivers/pci/dwc/pcie-armada8k.c +PCI DRIVER FOR CADENCE PCIE IP +M: Alan Douglas +L: linux-...@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/pci/cdns,*.txt +F: drivers/pci/cadence/pcie-cadence* + PCI DRIVER FOR FREESCALE LAYERSCAPE M: Minghuan Lian M: Mingkai Hu diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig index 7eeb969ab86a..dee90cc1dcaf 100644 --- a/drivers/pci/Kconfig +++ b/drivers/pci/Kconfig @@ -136,6 +136,7 @@ config PCI_HYPERV PCI devices from a PCI backend to support PCI driver domains. source "drivers/pci/hotplug/Kconfig" +source "drivers/pci/cadence/Kconfig" source "drivers/pci/dwc/Kconfig" source "drivers/pci/host/Kconfig" source "drivers/pci/endpoint/Kconfig" diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile index ddb5aa6640d7..941970936840 100644 --- a/drivers/pci/Makefile +++ b/drivers/pci/Makefile @@ -56,5 +56,6 @@ obj-y += switch/ obj-$(CONFIG_PCI_ENDPOINT) += endpoint/ # Endpoint library must be initialized before its users +obj-$(CONFIG_PCIE_CADENCE) += cadence/ # pcie-hisi.o quirks are needed even without CONFIG_PCIE_DW obj-y += dwc/ diff --git a/drivers/pci/cadence/Kconfig b/drivers/pci/cadence/Kconfig new file mode 100644 index ..0123d384a628 --- /dev/null +++ b/drivers/pci/cadence/Kconfig @@ -0,0 +1,16 @@ +menu "Cadence PCIe controllers support" + +config PCIE_CADENCE + bool + +config PCIE_CADENCE_HOST + bool "Cadence PCIe host controller" + depends on OF + select IRQ_DOMAIN + select PCIE_CADENCE + help + Say Y here if you want to support the Cadence PCIe controller in host + mode. This PCIe controller may be embedded into many different vendors + SoCs. + +endmenu diff --git a/drivers/pci/cadence/Makefile b/drivers/pci/cadence/Makefile new file mode 100644 index ..589601a8ff89 --- /dev/null +++ b/drivers/pci/cadence/Makefile @@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_PCIE_CADENCE) += pcie-cadence.o +obj-$(CONFIG_PCIE_CADENCE_HOST) += pcie-cadence-host.o diff --git a/drivers/pci/cadence/pcie-cadence-host.c b/drivers/pci/cadence/pcie-cadence-host.c new file mode 100644 index ..26caf8963e3c --- /dev/null +++ b/drivers/pci/cadence/pcie-cadence-host.c @@ -0,0 +1,336 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (c) 2017 Cadence +// Cadence PCIe host controller driver. +// Author: Cyrille Pitchen + +#include +#include +#include +#include +#include + +#include "pcie-cadence.h" + +/** + * struct cdns_pcie_rc - private data for this PCIe Root Complex driver + * @pcie: Cadence PCIe controller + * @dev: pointer to PCIe device + * @cfg_res: start/end offsets in the physical system memory to map PCI + * configuration space accesses + * @bus_range: first/last buses behind the PCIe host controller + * @cfg_base: IO mapped window to access the PCI configuration space of a + *single function at a time + * @max_regions: maximum number of regions supported by the hardware + * @no_bar_nbits: Number of bits to keep for inbound (PCIe -> CPU) address + *translation (nbits sets into the "no BAR match" register) + * @vendor_id: PCI vendor ID + * @device_id: PCI device ID + */ +struct cdns_pcie_rc { + struct cdns_pciepcie; + struct device *dev; + struct resource *cfg_res; + struct resource *bus_range; + void __iomem*cfg_base; + u32 max_regions; + u32 no_bar_nbits; + u16 vendor_id; + u16 device_id; +}; + +static void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned
[PATCH v3 3/6] PCI: Add generic function to probe PCI host controllers
This patchs moves generic source code from drivers/pci/host/pci-host-common.c into drivers/pci/probe.c. Indeed the extracted lines of code were duplicated by many host controller drivers. Regrouping them into a generic function gives a change to properly share this code without introducing a useless dependency to PCI_HOST_COMMON, which selects PCI_ECAM when not needed by most host controller drivers. We also add a missing call of pci_free_resource_list() from pci_host_common_probe() when probing fails, as done inside gen_pci_init() when this later function fails. Signed-off-by: Cyrille Pitchen --- drivers/pci/host/pci-host-common.c | 25 +++-- drivers/pci/probe.c| 33 + include/linux/pci.h| 1 + 3 files changed, 37 insertions(+), 22 deletions(-) diff --git a/drivers/pci/host/pci-host-common.c b/drivers/pci/host/pci-host-common.c index a613ea310e76..df25b4a4edaf 100644 --- a/drivers/pci/host/pci-host-common.c +++ b/drivers/pci/host/pci-host-common.c @@ -72,7 +72,6 @@ int pci_host_common_probe(struct platform_device *pdev, const char *type; struct device *dev = >dev; struct device_node *np = dev->of_node; - struct pci_bus *bus, *child; struct pci_host_bridge *bridge; struct pci_config_window *cfg; struct list_head resources; @@ -107,29 +106,11 @@ int pci_host_common_probe(struct platform_device *pdev, bridge->map_irq = of_irq_parse_and_map_pci; bridge->swizzle_irq = pci_common_swizzle; - ret = pci_scan_root_bus_bridge(bridge); - if (ret < 0) { - dev_err(dev, "Scanning root bridge failed"); + ret = pci_host_probe(bridge); + if (ret) { + pci_free_resource_list(); return ret; } - bus = bridge->bus; - - /* -* We insert PCI resources into the iomem_resource and -* ioport_resource trees in either pci_bus_claim_resources() -* or pci_bus_assign_resources(). -*/ - if (pci_has_flag(PCI_PROBE_ONLY)) { - pci_bus_claim_resources(bus); - } else { - pci_bus_size_bridges(bus); - pci_bus_assign_resources(bus); - - list_for_each_entry(child, >children, node) - pcie_bus_configure_settings(child); - } - - pci_bus_add_devices(bus); return 0; } diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 1360db508035..178328d06a32 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -2685,6 +2685,39 @@ struct pci_bus *pci_create_root_bus(struct device *parent, int bus, } EXPORT_SYMBOL_GPL(pci_create_root_bus); +int pci_host_probe(struct pci_host_bridge *bridge) +{ + struct pci_bus *bus, *child; + int ret; + + ret = pci_scan_root_bus_bridge(bridge); + if (ret < 0) { + dev_err(bridge->dev.parent, "Scanning root bridge failed"); + return ret; + } + + bus = bridge->bus; + + /* +* We insert PCI resources into the iomem_resource and +* ioport_resource trees in either pci_bus_claim_resources() +* or pci_bus_assign_resources(). +*/ + if (pci_has_flag(PCI_PROBE_ONLY)) { + pci_bus_claim_resources(bus); + } else { + pci_bus_size_bridges(bus); + pci_bus_assign_resources(bus); + + list_for_each_entry(child, >children, node) + pcie_bus_configure_settings(child); + } + + pci_bus_add_devices(bus); + return 0; +} +EXPORT_SYMBOL_GPL(pci_host_probe); + int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int bus_max) { struct resource *res = >busn_res; diff --git a/include/linux/pci.h b/include/linux/pci.h index a1b0672fd38a..0ca261fda900 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -879,6 +879,7 @@ struct pci_bus *pci_scan_bus(int bus, struct pci_ops *ops, void *sysdata); struct pci_bus *pci_create_root_bus(struct device *parent, int bus, struct pci_ops *ops, void *sysdata, struct list_head *resources); +int pci_host_probe(struct pci_host_bridge *bridge); int pci_bus_insert_busn_res(struct pci_bus *b, int bus, int busmax); int pci_bus_update_busn_res_end(struct pci_bus *b, int busmax); void pci_bus_release_busn_res(struct pci_bus *b); -- 2.11.0
[PATCH v3 5/6] dt-bindings: PCI: cadence: Add DT bindings for Cadence PCIe host controller
From: Scott Telford <stelf...@cadence.com> This patch adds documentation for the DT bindings of the Cadence PCIe controller when configured in host (Root Complex) mode. Signed-off-by: Scott Telford <stelf...@cadence.com> Signed-off-by: Cyrille Pitchen <cyrille.pitc...@free-electrons.com> Reviewed-by: Rob Herring <r...@kernel.org> --- .../bindings/pci/cdns,cdns-pcie-host.txt | 60 ++ 1 file changed, 60 insertions(+) create mode 100644 Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt diff --git a/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt new file mode 100644 index ..20a33f38f69d --- /dev/null +++ b/Documentation/devicetree/bindings/pci/cdns,cdns-pcie-host.txt @@ -0,0 +1,60 @@ +* Cadence PCIe host controller + +This PCIe controller inherits the base properties defined in +host-generic-pci.txt. + +Required properties: +- compatible: Should contain "cdns,cdns-pcie-host" to identify the IP used. +- reg: Should contain the controller register base address, PCIe configuration + window base address, and AXI interface region base address respectively. +- reg-names: Must be "reg", "cfg" and "mem" respectively. +- #address-cells: Set to <3> +- #size-cells: Set to <2> +- device_type: Set to "pci" +- ranges: Ranges for the PCI memory and I/O regions +- #interrupt-cells: Set to <1> +- interrupt-map-mask and interrupt-map: Standard PCI properties to define the + mapping of the PCIe interface to interrupt numbers. + +Optional properties: +- cdns,max-outbound-regions: Set to maximum number of outbound regions + (default 32) +- cdns,no-bar-match-nbits: Set into the no BAR match register to configure the + number of least significant bits kept during inbound (PCIe -> AXI) address + translations (default 32) +- vendor-id: The PCI vendor ID (16 bits, default is design dependent) +- device-id: The PCI device ID (16 bits, default is design dependent) + +Example: + +pcie@fb00 { + compatible = "cdns,cdns-pcie-host"; + device_type = "pci"; + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0x0 0xff>; + linux,pci-domain = <0>; + cdns,max-outbound-regions = <16>; + cdns,no-bar-match-nbits = <32>; + vendor-id = /bits/ 16 <0x17cd>; + device-id = /bits/ 16 <0x0200>; + + reg = <0x0 0xfb00 0x0 0x0100>, + <0x0 0x4100 0x0 0x1000>, + <0x0 0x4000 0x0 0x0400>; + reg-names = "reg", "cfg", "mem"; + + ranges = <0x0200 0x0 0x4200 0x0 0x4200 0x0 0x100>, +<0x0100 0x0 0x4300 0x0 0x4300 0x0 0x001>; + + #interrupt-cells = <0x1>; + + interrupt-map = <0x0 0x0 0x0 0x10x0 0x0 0x0 14 0x1 +0x0 0x0 0x0 0x20x0 0x0 0x0 15 0x1 +0x0 0x0 0x0 0x30x0 0x0 0x0 16 0x1 +0x0 0x0 0x0 0x40x0 0x0 0x0 17 0x1>; + + interrupt-map-mask = <0x0 0x0 0x0 0x7>; + + msi-parent = <_pci>; +}; -- 2.11.0
[PATCH v3 0/6] PCI: Add support to the Cadence PCIe controller
Hi all, this series of patches adds support to the Cadence PCIe controller. It was tested on a ARM64 platform emulated by a Palladium running the pci-next kernel. The host mode was tested with some PCIe devices connected to the Palladium through a speed-bridge. Some of those devices were a USB host controller and a SATA controller. The PCIe host controller was also tested with a second controller configured in endpoint mode and connected back to back to the first controller. The EndPoint Controller (EPC) driver was removed only because I didn't have time to take all Kishon's comments into account. However, using a fixed patch based on patch 7 of the v2 series + another patch fixing the EPF device name chosen by pci_epf_make(), I was abled to probe both function 0 and function 1 of the of the 2nd Cadence PCIe controller configured in endpoint mode (new hardware design since v2 so function 1 is now available). Currently I'm facing 2 issues, which I didn't have enough time to investigate and to fix yet: 1 - when the vendor:device IDs are set to 104c:b500 for both functions, then I remove both devfn (echo 1 > /sys/bus/pci/devices/$BDF/remove) before scanning the PCI bus again (echo 1 > /sys/bus/pci/rescan), the PCI enumeration fails reporting that the PCI memory is exhausted. 2 - when I set the vendor:device IDs to 104c:0100 for function 0 and 104c:b500 and remove only function 1 before scanning the PCI bus again, I now pass the PCI enumeration. I also pass the 'pcitest -b ' test but I fail on the MSI test ('pcitest -m '). I'm still investigating on those issues. Best regards, Cyrille ChangeLog v2 -> v3: - rebase on today's linux-pci/next (20180110) patch1: - rework the commit message of patch 1 and add two new comments on why endpoint library users must be linked after the endpoint library itself and why the dwc rule uses obj-y instead of obj-$(CONFIG_PCIE_CONFIG_DW). - update patch 1 to add missing ifdef CONFIG_PCI / endif in drivers/pci/dwc/Makefile around the obj-$(CONFIG_ARM64) += pcie-hisi.o rule, like for the other obj-$(CONFIG_ARM64) rules in drivers/pci/host/Makefile. patch2: unchanged patch3: - update patch 3 so the bridge hooks/members initialization is left to the host bridges probe routines. patch4: unchanged patch5: - collect 'Reviewed-by' tag from Rob Herring for the DT bindings. patch6: - remove explanation in the commit message on why obj-$(CONFIG_PCIE_CANDENCE) is placed after obj-$(CONFIG_PCI_ENDPOINT) in drivers/pci/Makefile since a comment on it has been added into patch1. - remove menuconfig PCI_CADENCE in drivers/pci/cadence/Kconfig to match drivers/pci/dwc/Kconfig. - adapt patch6 to the changes done in patch3 for the pci_host_probe() function. v1 -> v2: - add new properties in the device-tree bindings: 'cdns,max-outbound-regions' and 'cdns,no-bar-match-nbits'. - add a new patch to regroup all makefile rules in drivers/pci/Makefile, hence cleaning drivers/Makefile up. - change the license text to use the recommanded format: // SPDX-License-Identifier: GPL-2.0 - add a new patch updating the API of the EPC library to add support to multi-function devices. - add a 2 new patches to share more common code between host controller drivers - remove some useless tests - add more comments in both drivers. - fix DT bindings examples - remove useless init of the primary, secondary and sub-ordinate bus numbers in the PCI configuration space of the root port. - remove cdns_pcie_ep_stop() function and rework cdns_pcie_ep_start() function Cyrille Pitchen (5): PCI: Regroup all PCI related entries into drivers/pci/Makefile PCI: OF: Add generic function to parse and allocate PCI resources PCI: Add generic function to probe PCI host controllers PCI: Add vendor ID for Cadence PCI: cadence: Add host driver for Cadence PCIe controller Scott Telford (1): dt-bindings: PCI: cadence: Add DT bindings for Cadence PCIe host controller .../bindings/pci/cdns,cdns-pcie-host.txt | 60 MAINTAINERS| 7 + drivers/Makefile | 5 +- drivers/pci/Kconfig| 2 + drivers/pci/Makefile | 14 +- drivers/pci/cadence/Kconfig| 16 + drivers/pci/cadence/Makefile | 3 + drivers/pci/cadence/pcie-cadence-host.c| 336 + drivers/pci/cadence/pcie-cadence.c | 68 + drivers/pci/cadence/pcie-cadence.h | 196 drivers/pci/dwc/Makefile | 2 + drivers/pci/host/Makefile | 2 + drivers/pci/host/pci-host-common.c | 74 + drivers/pci/of.c | 51 drivers/pci/probe.c| 33 ++ include/linux/pci.h| 10 + include/lin