pci: layerscape: move kernel DT fixup to a separate file
To make the layerscape pcie driver clear, move the kernel DT fixup code from pcie_layerscape.c to pcie_layerscape_fixup.c. Signed-off-by: Hou Zhiqiang <Zhiqiang.Hou@nxp.com> Reviewed-by: Simon Glass <sjg@chromium.org> Reviewed-by: York Sun <york.sun@nxp.com>
This commit is contained in:
		
							parent
							
								
									33f61e07b3
								
							
						
					
					
						commit
						a7294aba08
					
				|  | @ -32,4 +32,5 @@ obj-$(CONFIG_TSI108_PCI) += tsi108_pci.o | |||
| obj-$(CONFIG_WINBOND_83C553) += w83c553f.o | ||||
| obj-$(CONFIG_PCIE_DW_MVEBU) += pcie_dw_mvebu.o | ||||
| obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape.o | ||||
| obj-$(CONFIG_PCIE_LAYERSCAPE) += pcie_layerscape_fixup.o | ||||
| obj-$(CONFIG_PCI_XILINX) += pcie_xilinx.o | ||||
|  |  | |||
|  | @ -14,129 +14,12 @@ | |||
| #ifndef CONFIG_LS102XA | ||||
| #include <asm/arch/fdt.h> | ||||
| #include <asm/arch/soc.h> | ||||
| #else | ||||
| #include <asm/arch/immap_ls102xa.h> | ||||
| #endif | ||||
| 
 | ||||
| #ifndef CONFIG_SYS_PCI_MEMORY_BUS | ||||
| #define CONFIG_SYS_PCI_MEMORY_BUS CONFIG_SYS_SDRAM_BASE | ||||
| #endif | ||||
| 
 | ||||
| #ifndef CONFIG_SYS_PCI_MEMORY_PHYS | ||||
| #define CONFIG_SYS_PCI_MEMORY_PHYS CONFIG_SYS_SDRAM_BASE | ||||
| #endif | ||||
| 
 | ||||
| #ifndef CONFIG_SYS_PCI_MEMORY_SIZE | ||||
| #define CONFIG_SYS_PCI_MEMORY_SIZE (2 * 1024 * 1024 * 1024UL) /* 2G */ | ||||
| #endif | ||||
| 
 | ||||
| #ifndef CONFIG_SYS_PCI_EP_MEMORY_BASE | ||||
| #define CONFIG_SYS_PCI_EP_MEMORY_BASE CONFIG_SYS_LOAD_ADDR | ||||
| #endif | ||||
| 
 | ||||
| /* iATU registers */ | ||||
| #define PCIE_ATU_VIEWPORT		0x900 | ||||
| #define PCIE_ATU_REGION_INBOUND		(0x1 << 31) | ||||
| #define PCIE_ATU_REGION_OUTBOUND	(0x0 << 31) | ||||
| #define PCIE_ATU_REGION_INDEX0		(0x0 << 0) | ||||
| #define PCIE_ATU_REGION_INDEX1		(0x1 << 0) | ||||
| #define PCIE_ATU_REGION_INDEX2		(0x2 << 0) | ||||
| #define PCIE_ATU_REGION_INDEX3		(0x3 << 0) | ||||
| #define PCIE_ATU_CR1			0x904 | ||||
| #define PCIE_ATU_TYPE_MEM		(0x0 << 0) | ||||
| #define PCIE_ATU_TYPE_IO		(0x2 << 0) | ||||
| #define PCIE_ATU_TYPE_CFG0		(0x4 << 0) | ||||
| #define PCIE_ATU_TYPE_CFG1		(0x5 << 0) | ||||
| #define PCIE_ATU_CR2			0x908 | ||||
| #define PCIE_ATU_ENABLE			(0x1 << 31) | ||||
| #define PCIE_ATU_BAR_MODE_ENABLE	(0x1 << 30) | ||||
| #define PCIE_ATU_BAR_NUM(bar)		((bar) << 8) | ||||
| #define PCIE_ATU_LOWER_BASE		0x90C | ||||
| #define PCIE_ATU_UPPER_BASE		0x910 | ||||
| #define PCIE_ATU_LIMIT			0x914 | ||||
| #define PCIE_ATU_LOWER_TARGET		0x918 | ||||
| #define PCIE_ATU_BUS(x)			(((x) & 0xff) << 24) | ||||
| #define PCIE_ATU_DEV(x)			(((x) & 0x1f) << 19) | ||||
| #define PCIE_ATU_FUNC(x)		(((x) & 0x7) << 16) | ||||
| #define PCIE_ATU_UPPER_TARGET		0x91C | ||||
| 
 | ||||
| #define PCIE_DBI_RO_WR_EN	0x8bc | ||||
| 
 | ||||
| #define PCIE_LINK_CAP		0x7c | ||||
| #define PCIE_LINK_SPEED_MASK	0xf | ||||
| #define PCIE_LINK_STA		0x82 | ||||
| 
 | ||||
| #define LTSSM_STATE_MASK	0x3f | ||||
| #define LTSSM_PCIE_L0		0x11 /* L0 state */ | ||||
| 
 | ||||
| #define PCIE_DBI_SIZE		0x100000 /* 1M */ | ||||
| 
 | ||||
| #define PCIE_LCTRL0_CFG2_ENABLE	(1 << 31) | ||||
| #define PCIE_LCTRL0_VF(vf)	((vf) << 22) | ||||
| #define PCIE_LCTRL0_PF(pf)	((pf) << 16) | ||||
| #define PCIE_LCTRL0_VF_ACTIVE	(1 << 21) | ||||
| #define PCIE_LCTRL0_VAL(pf, vf)	(PCIE_LCTRL0_PF(pf) |			   \ | ||||
| 				 PCIE_LCTRL0_VF(vf) |			   \ | ||||
| 				 ((vf) == 0 ? 0 : PCIE_LCTRL0_VF_ACTIVE) | \ | ||||
| 				 PCIE_LCTRL0_CFG2_ENABLE) | ||||
| 
 | ||||
| #define PCIE_NO_SRIOV_BAR_BASE	0x1000 | ||||
| 
 | ||||
| #define PCIE_PF_NUM		2 | ||||
| #define PCIE_VF_NUM		64 | ||||
| 
 | ||||
| #define PCIE_BAR0_SIZE		(4 * 1024) /* 4K */ | ||||
| #define PCIE_BAR1_SIZE		(8 * 1024) /* 8K for MSIX */ | ||||
| #define PCIE_BAR2_SIZE		(4 * 1024) /* 4K */ | ||||
| #define PCIE_BAR4_SIZE		(1 * 1024 * 1024) /* 1M */ | ||||
| 
 | ||||
| struct ls_pcie { | ||||
| 	int idx; | ||||
| 	void __iomem *dbi; | ||||
| 	void __iomem *va_cfg0; | ||||
| 	void __iomem *va_cfg1; | ||||
| 	int next_lut_index; | ||||
| 	struct pci_controller hose; | ||||
| }; | ||||
| 
 | ||||
| struct ls_pcie_info { | ||||
| 	unsigned long regs; | ||||
| 	int pci_num; | ||||
| 	u64 phys_base; | ||||
| 	u64 cfg0_phys; | ||||
| 	u64 cfg0_size; | ||||
| 	u64 cfg1_phys; | ||||
| 	u64 cfg1_size; | ||||
| 	u64 mem_bus; | ||||
| 	u64 mem_phys; | ||||
| 	u64 mem_size; | ||||
| 	u64 io_bus; | ||||
| 	u64 io_phys; | ||||
| 	u64 io_size; | ||||
| }; | ||||
| 
 | ||||
| #define SET_LS_PCIE_INFO(x, num)			\ | ||||
| {							\ | ||||
| 	x.regs = CONFIG_SYS_PCIE##num##_ADDR;		\ | ||||
| 	x.phys_base = CONFIG_SYS_PCIE##num##_PHYS_ADDR;	\ | ||||
| 	x.cfg0_phys = CONFIG_SYS_PCIE_CFG0_PHYS_OFF +	\ | ||||
| 		      CONFIG_SYS_PCIE##num##_PHYS_ADDR;	\ | ||||
| 	x.cfg0_size = CONFIG_SYS_PCIE_CFG0_SIZE;	\ | ||||
| 	x.cfg1_phys = CONFIG_SYS_PCIE_CFG1_PHYS_OFF +	\ | ||||
| 		      CONFIG_SYS_PCIE##num##_PHYS_ADDR;	\ | ||||
| 	x.cfg1_size = CONFIG_SYS_PCIE_CFG1_SIZE;	\ | ||||
| 	x.mem_bus = CONFIG_SYS_PCIE_MEM_BUS;		\ | ||||
| 	x.mem_phys = CONFIG_SYS_PCIE_MEM_PHYS_OFF +	\ | ||||
| 		     CONFIG_SYS_PCIE##num##_PHYS_ADDR;	\ | ||||
| 	x.mem_size = CONFIG_SYS_PCIE_MEM_SIZE;		\ | ||||
| 	x.io_bus = CONFIG_SYS_PCIE_IO_BUS;		\ | ||||
| 	x.io_phys = CONFIG_SYS_PCIE_IO_PHYS_OFF +	\ | ||||
| 		    CONFIG_SYS_PCIE##num##_PHYS_ADDR;	\ | ||||
| 	x.io_size = CONFIG_SYS_PCIE_IO_SIZE;		\ | ||||
| 	x.pci_num = num;				\ | ||||
| } | ||||
| #include "pcie_layerscape.h" | ||||
| 
 | ||||
| #ifdef CONFIG_LS102XA | ||||
| #include <asm/arch/immap_ls102xa.h> | ||||
| 
 | ||||
| /* PEX1/2 Misc Ports Status Register */ | ||||
| #define LTSSM_STATE_SHIFT	20 | ||||
| 
 | ||||
|  | @ -483,150 +366,6 @@ static void ls_pcie_setup_ep(struct ls_pcie *pcie, struct ls_pcie_info *info) | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| #ifdef CONFIG_FSL_LSCH3 | ||||
| /*
 | ||||
|  * Return next available LUT index. | ||||
|  */ | ||||
| static int ls_pcie_next_lut_index(struct ls_pcie *pcie) | ||||
| { | ||||
| 	if (pcie->next_lut_index < PCIE_LUT_ENTRY_COUNT) | ||||
| 		return pcie->next_lut_index++; | ||||
| 	else | ||||
| 		return -1;  /* LUT is full */ | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Program a single LUT entry | ||||
|  */ | ||||
| static void ls_pcie_lut_set_mapping(struct ls_pcie *pcie, int index, u32 devid, | ||||
| 			     u32 streamid) | ||||
| { | ||||
| 	void __iomem *lut; | ||||
| 
 | ||||
| 	lut = pcie->dbi + PCIE_LUT_BASE; | ||||
| 
 | ||||
| 	/* leave mask as all zeroes, want to match all bits */ | ||||
| 	writel((devid << 16), lut + PCIE_LUT_UDR(index)); | ||||
| 	writel(streamid | PCIE_LUT_ENABLE, lut + PCIE_LUT_LDR(index)); | ||||
| } | ||||
| 
 | ||||
| /* returns the next available streamid */ | ||||
| static u32 ls_pcie_next_streamid(void) | ||||
| { | ||||
| 	static int next_stream_id = FSL_PEX_STREAM_ID_START; | ||||
| 
 | ||||
| 	if (next_stream_id > FSL_PEX_STREAM_ID_END) | ||||
| 		return 0xffffffff; | ||||
| 
 | ||||
| 	return next_stream_id++; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * An msi-map is a property to be added to the pci controller | ||||
|  * node.  It is a table, where each entry consists of 4 fields | ||||
|  * e.g.: | ||||
|  * | ||||
|  *      msi-map = <[devid] [phandle-to-msi-ctrl] [stream-id] [count] | ||||
|  *                 [devid] [phandle-to-msi-ctrl] [stream-id] [count]>; | ||||
|  */ | ||||
| static void fdt_pcie_set_msi_map_entry(void *blob, struct ls_pcie *pcie, | ||||
| 				       u32 devid, u32 streamid) | ||||
| { | ||||
| 	char pcie_path[19]; | ||||
| 	u32 *prop; | ||||
| 	u32 phandle; | ||||
| 	int nodeoffset; | ||||
| 
 | ||||
| 	/* find pci controller node */ | ||||
| 	snprintf(pcie_path, sizeof(pcie_path), "/soc/pcie@%llx", | ||||
| 		 (u64)pcie->dbi); | ||||
| 	nodeoffset = fdt_path_offset(blob, pcie_path); | ||||
| 	if (nodeoffset < 0) { | ||||
| 		printf("\n%s: ERROR: unable to update PCIe node: %s\n", | ||||
| 		       __func__, pcie_path); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	/* get phandle to MSI controller */ | ||||
| 	prop = (u32 *)fdt_getprop(blob, nodeoffset, "msi-parent", 0); | ||||
| 	if (prop == NULL) { | ||||
| 		printf("\n%s: ERROR: missing msi-parent: %s\n", __func__, | ||||
| 		       pcie_path); | ||||
| 		return; | ||||
| 	} | ||||
| 	phandle = be32_to_cpu(*prop); | ||||
| 
 | ||||
| 	/* set one msi-map row */ | ||||
| 	fdt_appendprop_u32(blob, nodeoffset, "msi-map", devid); | ||||
| 	fdt_appendprop_u32(blob, nodeoffset, "msi-map", phandle); | ||||
| 	fdt_appendprop_u32(blob, nodeoffset, "msi-map", streamid); | ||||
| 	fdt_appendprop_u32(blob, nodeoffset, "msi-map", 1); | ||||
| } | ||||
| 
 | ||||
| static void fdt_fixup_pcie(void *blob) | ||||
| { | ||||
| 	unsigned int found_multi = 0; | ||||
| 	unsigned char header_type; | ||||
| 	int index; | ||||
| 	u32 streamid; | ||||
| 	pci_dev_t dev, bdf; | ||||
| 	int bus; | ||||
| 	unsigned short id; | ||||
| 	struct pci_controller *hose; | ||||
| 	struct ls_pcie *pcie; | ||||
| 	int i; | ||||
| 
 | ||||
| 	for (i = 0, hose = pci_get_hose_head(); hose; hose = hose->next, i++) { | ||||
| 		pcie = hose->priv_data; | ||||
| 		for (bus = hose->first_busno; bus <= hose->last_busno; bus++) { | ||||
| 
 | ||||
| 			for (dev =  PCI_BDF(bus, 0, 0); | ||||
| 			     dev <  PCI_BDF(bus, PCI_MAX_PCI_DEVICES - 1, | ||||
| 					    PCI_MAX_PCI_FUNCTIONS - 1); | ||||
| 			     dev += PCI_BDF(0, 0, 1)) { | ||||
| 
 | ||||
| 				if (PCI_FUNC(dev) && !found_multi) | ||||
| 					continue; | ||||
| 
 | ||||
| 				pci_read_config_word(dev, PCI_VENDOR_ID, &id); | ||||
| 
 | ||||
| 				pci_read_config_byte(dev, PCI_HEADER_TYPE, | ||||
| 						     &header_type); | ||||
| 
 | ||||
| 				if ((id == 0xFFFF) || (id == 0x0000)) | ||||
| 					continue; | ||||
| 
 | ||||
| 				if (!PCI_FUNC(dev)) | ||||
| 					found_multi = header_type & 0x80; | ||||
| 
 | ||||
| 				streamid = ls_pcie_next_streamid(); | ||||
| 				if (streamid == 0xffffffff) { | ||||
| 					printf("ERROR: no stream ids free\n"); | ||||
| 					continue; | ||||
| 				} | ||||
| 
 | ||||
| 				index = ls_pcie_next_lut_index(pcie); | ||||
| 				if (index < 0) { | ||||
| 					printf("ERROR: no LUT indexes free\n"); | ||||
| 					continue; | ||||
| 				} | ||||
| 
 | ||||
| 				/* the DT fixup must be relative to the hose first_busno */ | ||||
| 				bdf = dev - PCI_BDF(hose->first_busno, 0, 0); | ||||
| 
 | ||||
| 				/* map PCI b.d.f to streamID in LUT */ | ||||
| 				ls_pcie_lut_set_mapping(pcie, index, bdf >> 8, | ||||
| 							streamid); | ||||
| 
 | ||||
| 				/* update msi-map in device tree */ | ||||
| 				fdt_pcie_set_msi_map_entry(blob, pcie, bdf >> 8, | ||||
| 							   streamid); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| int ls_pcie_init_ctrl(int busno, enum srds_prtcl dev, struct ls_pcie_info *info) | ||||
| { | ||||
| 	struct ls_pcie *pcie; | ||||
|  | @ -767,50 +506,3 @@ void pci_init_board(void) | |||
| { | ||||
| 	ls_pcie_init_board(0); | ||||
| } | ||||
| 
 | ||||
| #ifdef CONFIG_OF_BOARD_SETUP | ||||
| #include <libfdt.h> | ||||
| #include <fdt_support.h> | ||||
| 
 | ||||
| static void ft_pcie_ls_setup(void *blob, const char *pci_compat, | ||||
| 			     unsigned long ctrl_addr, enum srds_prtcl dev) | ||||
| { | ||||
| 	int off; | ||||
| 
 | ||||
| 	off = fdt_node_offset_by_compat_reg(blob, pci_compat, | ||||
| 					    (phys_addr_t)ctrl_addr); | ||||
| 	if (off < 0) | ||||
| 		return; | ||||
| 
 | ||||
| 	if (!is_serdes_configured(dev)) | ||||
| 		fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0); | ||||
| } | ||||
| 
 | ||||
| void ft_pci_setup(void *blob, bd_t *bd) | ||||
| { | ||||
| 	#ifdef CONFIG_PCIE1 | ||||
| 	ft_pcie_ls_setup(blob, FSL_PCIE_COMPAT, CONFIG_SYS_PCIE1_ADDR, PCIE1); | ||||
| 	#endif | ||||
| 
 | ||||
| 	#ifdef CONFIG_PCIE2 | ||||
| 	ft_pcie_ls_setup(blob, FSL_PCIE_COMPAT, CONFIG_SYS_PCIE2_ADDR, PCIE2); | ||||
| 	#endif | ||||
| 
 | ||||
| 	#ifdef CONFIG_PCIE3 | ||||
| 	ft_pcie_ls_setup(blob, FSL_PCIE_COMPAT, CONFIG_SYS_PCIE3_ADDR, PCIE3); | ||||
| 	#endif | ||||
| 
 | ||||
| 	#ifdef CONFIG_PCIE4 | ||||
| 	ft_pcie_ls_setup(blob, FSL_PCIE_COMPAT, CONFIG_SYS_PCIE4_ADDR, PCIE4); | ||||
| 	#endif | ||||
| 
 | ||||
| 	#ifdef CONFIG_FSL_LSCH3 | ||||
| 	fdt_fixup_pcie(blob); | ||||
| 	#endif | ||||
| } | ||||
| 
 | ||||
| #else | ||||
| void ft_pci_setup(void *blob, bd_t *bd) | ||||
| { | ||||
| } | ||||
| #endif | ||||
|  |  | |||
|  | @ -0,0 +1,135 @@ | |||
| /*
 | ||||
|  * Copyright 2014-2015 Freescale Semiconductor, Inc. | ||||
|  * Layerscape PCIe driver | ||||
|  * | ||||
|  * SPDX-License-Identifier:	GPL-2.0+ | ||||
|  */ | ||||
| 
 | ||||
| #ifndef _PCIE_LAYERSCAPE_H_ | ||||
| #define _PCIE_LAYERSCAPE_H_ | ||||
| #include <pci.h> | ||||
| 
 | ||||
| #ifndef CONFIG_SYS_PCI_MEMORY_BUS | ||||
| #define CONFIG_SYS_PCI_MEMORY_BUS CONFIG_SYS_SDRAM_BASE | ||||
| #endif | ||||
| 
 | ||||
| #ifndef CONFIG_SYS_PCI_MEMORY_PHYS | ||||
| #define CONFIG_SYS_PCI_MEMORY_PHYS CONFIG_SYS_SDRAM_BASE | ||||
| #endif | ||||
| 
 | ||||
| #ifndef CONFIG_SYS_PCI_MEMORY_SIZE | ||||
| #define CONFIG_SYS_PCI_MEMORY_SIZE (2 * 1024 * 1024 * 1024UL) /* 2G */ | ||||
| #endif | ||||
| 
 | ||||
| #ifndef CONFIG_SYS_PCI_EP_MEMORY_BASE | ||||
| #define CONFIG_SYS_PCI_EP_MEMORY_BASE CONFIG_SYS_LOAD_ADDR | ||||
| #endif | ||||
| 
 | ||||
| /* iATU registers */ | ||||
| #define PCIE_ATU_VIEWPORT		0x900 | ||||
| #define PCIE_ATU_REGION_INBOUND		(0x1 << 31) | ||||
| #define PCIE_ATU_REGION_OUTBOUND	(0x0 << 31) | ||||
| #define PCIE_ATU_REGION_INDEX0		(0x0 << 0) | ||||
| #define PCIE_ATU_REGION_INDEX1		(0x1 << 0) | ||||
| #define PCIE_ATU_REGION_INDEX2		(0x2 << 0) | ||||
| #define PCIE_ATU_REGION_INDEX3		(0x3 << 0) | ||||
| #define PCIE_ATU_REGION_NUM		6 | ||||
| #define PCIE_ATU_CR1			0x904 | ||||
| #define PCIE_ATU_TYPE_MEM		(0x0 << 0) | ||||
| #define PCIE_ATU_TYPE_IO		(0x2 << 0) | ||||
| #define PCIE_ATU_TYPE_CFG0		(0x4 << 0) | ||||
| #define PCIE_ATU_TYPE_CFG1		(0x5 << 0) | ||||
| #define PCIE_ATU_CR2			0x908 | ||||
| #define PCIE_ATU_ENABLE			(0x1 << 31) | ||||
| #define PCIE_ATU_BAR_MODE_ENABLE	(0x1 << 30) | ||||
| #define PCIE_ATU_BAR_NUM(bar)		((bar) << 8) | ||||
| #define PCIE_ATU_LOWER_BASE		0x90C | ||||
| #define PCIE_ATU_UPPER_BASE		0x910 | ||||
| #define PCIE_ATU_LIMIT			0x914 | ||||
| #define PCIE_ATU_LOWER_TARGET		0x918 | ||||
| #define PCIE_ATU_BUS(x)			(((x) & 0xff) << 24) | ||||
| #define PCIE_ATU_DEV(x)			(((x) & 0x1f) << 19) | ||||
| #define PCIE_ATU_FUNC(x)		(((x) & 0x7) << 16) | ||||
| #define PCIE_ATU_UPPER_TARGET		0x91C | ||||
| 
 | ||||
| /* DBI registers */ | ||||
| #define PCIE_SRIOV		0x178 | ||||
| #define PCIE_STRFMR1		0x71c /* Symbol Timer & Filter Mask Register1 */ | ||||
| #define PCIE_DBI_RO_WR_EN	0x8bc | ||||
| 
 | ||||
| #define PCIE_LINK_CAP		0x7c | ||||
| #define PCIE_LINK_SPEED_MASK	0xf | ||||
| #define PCIE_LINK_WIDTH_MASK	0x3f0 | ||||
| #define PCIE_LINK_STA		0x82 | ||||
| 
 | ||||
| #define LTSSM_STATE_MASK	0x3f | ||||
| #define LTSSM_PCIE_L0		0x11 /* L0 state */ | ||||
| 
 | ||||
| #define PCIE_DBI_SIZE		0x100000 /* 1M */ | ||||
| 
 | ||||
| #define PCIE_LCTRL0_CFG2_ENABLE	(1 << 31) | ||||
| #define PCIE_LCTRL0_VF(vf)	((vf) << 22) | ||||
| #define PCIE_LCTRL0_PF(pf)	((pf) << 16) | ||||
| #define PCIE_LCTRL0_VF_ACTIVE	(1 << 21) | ||||
| #define PCIE_LCTRL0_VAL(pf, vf)	(PCIE_LCTRL0_PF(pf) |			   \ | ||||
| 				 PCIE_LCTRL0_VF(vf) |			   \ | ||||
| 				 ((vf) == 0 ? 0 : PCIE_LCTRL0_VF_ACTIVE) | \ | ||||
| 				 PCIE_LCTRL0_CFG2_ENABLE) | ||||
| 
 | ||||
| #define PCIE_NO_SRIOV_BAR_BASE	0x1000 | ||||
| 
 | ||||
| #define PCIE_PF_NUM		2 | ||||
| #define PCIE_VF_NUM		64 | ||||
| 
 | ||||
| #define PCIE_BAR0_SIZE		(4 * 1024) /* 4K */ | ||||
| #define PCIE_BAR1_SIZE		(8 * 1024) /* 8K for MSIX */ | ||||
| #define PCIE_BAR2_SIZE		(4 * 1024) /* 4K */ | ||||
| #define PCIE_BAR4_SIZE		(1 * 1024 * 1024) /* 1M */ | ||||
| 
 | ||||
| struct ls_pcie { | ||||
| 	int idx; | ||||
| 	void __iomem *dbi; | ||||
| 	void __iomem *va_cfg0; | ||||
| 	void __iomem *va_cfg1; | ||||
| 	int next_lut_index; | ||||
| 	struct pci_controller hose; | ||||
| }; | ||||
| 
 | ||||
| struct ls_pcie_info { | ||||
| 	unsigned long regs; | ||||
| 	int pci_num; | ||||
| 	u64 phys_base; | ||||
| 	u64 cfg0_phys; | ||||
| 	u64 cfg0_size; | ||||
| 	u64 cfg1_phys; | ||||
| 	u64 cfg1_size; | ||||
| 	u64 mem_bus; | ||||
| 	u64 mem_phys; | ||||
| 	u64 mem_size; | ||||
| 	u64 io_bus; | ||||
| 	u64 io_phys; | ||||
| 	u64 io_size; | ||||
| }; | ||||
| 
 | ||||
| #define SET_LS_PCIE_INFO(x, num)			\ | ||||
| {							\ | ||||
| 	x.regs = CONFIG_SYS_PCIE##num##_ADDR;		\ | ||||
| 	x.phys_base = CONFIG_SYS_PCIE##num##_PHYS_ADDR;	\ | ||||
| 	x.cfg0_phys = CONFIG_SYS_PCIE_CFG0_PHYS_OFF +	\ | ||||
| 		      CONFIG_SYS_PCIE##num##_PHYS_ADDR;	\ | ||||
| 	x.cfg0_size = CONFIG_SYS_PCIE_CFG0_SIZE;	\ | ||||
| 	x.cfg1_phys = CONFIG_SYS_PCIE_CFG1_PHYS_OFF +	\ | ||||
| 		      CONFIG_SYS_PCIE##num##_PHYS_ADDR;	\ | ||||
| 	x.cfg1_size = CONFIG_SYS_PCIE_CFG1_SIZE;	\ | ||||
| 	x.mem_bus = CONFIG_SYS_PCIE_MEM_BUS;		\ | ||||
| 	x.mem_phys = CONFIG_SYS_PCIE_MEM_PHYS_OFF +	\ | ||||
| 		     CONFIG_SYS_PCIE##num##_PHYS_ADDR;	\ | ||||
| 	x.mem_size = CONFIG_SYS_PCIE_MEM_SIZE;		\ | ||||
| 	x.io_bus = CONFIG_SYS_PCIE_IO_BUS;		\ | ||||
| 	x.io_phys = CONFIG_SYS_PCIE_IO_PHYS_OFF +	\ | ||||
| 		    CONFIG_SYS_PCIE##num##_PHYS_ADDR;	\ | ||||
| 	x.io_size = CONFIG_SYS_PCIE_IO_SIZE;		\ | ||||
| 	x.pci_num = num;				\ | ||||
| } | ||||
| 
 | ||||
| #endif /* _PCIE_LAYERSCAPE_H_ */ | ||||
|  | @ -0,0 +1,204 @@ | |||
| /*
 | ||||
|  * Copyright 2014-2015 Freescale Semiconductor, Inc. | ||||
|  * Layerscape PCIe driver | ||||
|  * | ||||
|  * SPDX-License-Identifier:	GPL-2.0+ | ||||
|  */ | ||||
| 
 | ||||
| #include <common.h> | ||||
| #include <pci.h> | ||||
| #include <asm/arch/fsl_serdes.h> | ||||
| #include <asm/io.h> | ||||
| #include <errno.h> | ||||
| #ifdef CONFIG_OF_BOARD_SETUP | ||||
| #include <libfdt.h> | ||||
| #include <fdt_support.h> | ||||
| #include "pcie_layerscape.h" | ||||
| 
 | ||||
| #ifdef CONFIG_FSL_LSCH3 | ||||
| /*
 | ||||
|  * Return next available LUT index. | ||||
|  */ | ||||
| static int ls_pcie_next_lut_index(struct ls_pcie *pcie) | ||||
| { | ||||
| 	if (pcie->next_lut_index < PCIE_LUT_ENTRY_COUNT) | ||||
| 		return pcie->next_lut_index++; | ||||
| 	else | ||||
| 		return -ENOSPC;  /* LUT is full */ | ||||
| } | ||||
| 
 | ||||
| /* returns the next available streamid for pcie, -errno if failed */ | ||||
| static int ls_pcie_next_streamid(void) | ||||
| { | ||||
| 	static int next_stream_id = FSL_PEX_STREAM_ID_START; | ||||
| 
 | ||||
| 	if (next_stream_id > FSL_PEX_STREAM_ID_END) | ||||
| 		return -EINVAL; | ||||
| 
 | ||||
| 	return next_stream_id++; | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Program a single LUT entry | ||||
|  */ | ||||
| static void ls_pcie_lut_set_mapping(struct ls_pcie *pcie, int index, u32 devid, | ||||
| 			     u32 streamid) | ||||
| { | ||||
| 	void __iomem *lut; | ||||
| 
 | ||||
| 	lut = pcie->dbi + PCIE_LUT_BASE; | ||||
| 
 | ||||
| 	/* leave mask as all zeroes, want to match all bits */ | ||||
| 	writel((devid << 16), lut + PCIE_LUT_UDR(index)); | ||||
| 	writel(streamid | PCIE_LUT_ENABLE, lut + PCIE_LUT_LDR(index)); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * An msi-map is a property to be added to the pci controller | ||||
|  * node.  It is a table, where each entry consists of 4 fields | ||||
|  * e.g.: | ||||
|  * | ||||
|  *      msi-map = <[devid] [phandle-to-msi-ctrl] [stream-id] [count] | ||||
|  *                 [devid] [phandle-to-msi-ctrl] [stream-id] [count]>; | ||||
|  */ | ||||
| static void fdt_pcie_set_msi_map_entry(void *blob, struct ls_pcie *pcie, | ||||
| 				       u32 devid, u32 streamid) | ||||
| { | ||||
| 	char pcie_path[19]; | ||||
| 	u32 *prop; | ||||
| 	u32 phandle; | ||||
| 	int nodeoffset; | ||||
| 
 | ||||
| 	/* find pci controller node */ | ||||
| 	snprintf(pcie_path, sizeof(pcie_path), "/soc/pcie@%llx", | ||||
| 		 (u64)pcie->dbi); | ||||
| 	nodeoffset = fdt_path_offset(blob, pcie_path); | ||||
| 	if (nodeoffset < 0) { | ||||
| 		printf("\n%s: ERROR: unable to update PCIe node: %s\n", | ||||
| 		       __func__, pcie_path); | ||||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| 	/* get phandle to MSI controller */ | ||||
| 	prop = (u32 *)fdt_getprop(blob, nodeoffset, "msi-parent", 0); | ||||
| 	if (prop == NULL) { | ||||
| 		printf("\n%s: ERROR: missing msi-parent: %s\n", __func__, | ||||
| 		       pcie_path); | ||||
| 		return; | ||||
| 	} | ||||
| 	phandle = fdt32_to_cpu(*prop); | ||||
| 
 | ||||
| 	/* set one msi-map row */ | ||||
| 	fdt_appendprop_u32(blob, nodeoffset, "msi-map", devid); | ||||
| 	fdt_appendprop_u32(blob, nodeoffset, "msi-map", phandle); | ||||
| 	fdt_appendprop_u32(blob, nodeoffset, "msi-map", streamid); | ||||
| 	fdt_appendprop_u32(blob, nodeoffset, "msi-map", 1); | ||||
| } | ||||
| 
 | ||||
| static void fdt_fixup_pcie(void *blob) | ||||
| { | ||||
| 	unsigned int found_multi = 0; | ||||
| 	unsigned char header_type; | ||||
| 	int index; | ||||
| 	u32 streamid; | ||||
| 	pci_dev_t dev, bdf; | ||||
| 	int bus; | ||||
| 	unsigned short id; | ||||
| 	struct pci_controller *hose; | ||||
| 	struct ls_pcie *pcie; | ||||
| 	int i; | ||||
| 
 | ||||
| 	for (i = 0, hose = pci_get_hose_head(); hose; hose = hose->next, i++) { | ||||
| 		pcie = hose->priv_data; | ||||
| 		for (bus = hose->first_busno; bus <= hose->last_busno; bus++) { | ||||
| 
 | ||||
| 			for (dev =  PCI_BDF(bus, 0, 0); | ||||
| 			     dev <  PCI_BDF(bus, PCI_MAX_PCI_DEVICES - 1, | ||||
| 					    PCI_MAX_PCI_FUNCTIONS - 1); | ||||
| 			     dev += PCI_BDF(0, 0, 1)) { | ||||
| 
 | ||||
| 				if (PCI_FUNC(dev) && !found_multi) | ||||
| 					continue; | ||||
| 
 | ||||
| 				pci_read_config_word(dev, PCI_VENDOR_ID, &id); | ||||
| 
 | ||||
| 				pci_read_config_byte(dev, PCI_HEADER_TYPE, | ||||
| 						     &header_type); | ||||
| 
 | ||||
| 				if ((id == 0xFFFF) || (id == 0x0000)) | ||||
| 					continue; | ||||
| 
 | ||||
| 				if (!PCI_FUNC(dev)) | ||||
| 					found_multi = header_type & 0x80; | ||||
| 
 | ||||
| 				streamid = ls_pcie_next_streamid(); | ||||
| 				if (streamid < 0) { | ||||
| 					debug("ERROR: no stream ids free\n"); | ||||
| 					continue; | ||||
| 				} | ||||
| 
 | ||||
| 				index = ls_pcie_next_lut_index(pcie); | ||||
| 				if (index < 0) { | ||||
| 					debug("ERROR: no LUT indexes free\n"); | ||||
| 					continue; | ||||
| 				} | ||||
| 
 | ||||
| 				/* the DT fixup must be relative to the hose first_busno */ | ||||
| 				bdf = dev - PCI_BDF(hose->first_busno, 0, 0); | ||||
| 
 | ||||
| 				/* map PCI b.d.f to streamID in LUT */ | ||||
| 				ls_pcie_lut_set_mapping(pcie, index, bdf >> 8, | ||||
| 							streamid); | ||||
| 
 | ||||
| 				/* update msi-map in device tree */ | ||||
| 				fdt_pcie_set_msi_map_entry(blob, pcie, bdf >> 8, | ||||
| 							   streamid); | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| static void ft_pcie_ls_setup(void *blob, const char *pci_compat, | ||||
| 			     unsigned long ctrl_addr, enum srds_prtcl dev) | ||||
| { | ||||
| 	int off; | ||||
| 
 | ||||
| 	off = fdt_node_offset_by_compat_reg(blob, pci_compat, | ||||
| 					    (phys_addr_t)ctrl_addr); | ||||
| 	if (off < 0) | ||||
| 		return; | ||||
| 
 | ||||
| 	if (!is_serdes_configured(dev)) | ||||
| 		fdt_set_node_status(blob, off, FDT_STATUS_DISABLED, 0); | ||||
| } | ||||
| 
 | ||||
| /* Fixup Kernel DT for PCIe */ | ||||
| void ft_pci_setup(void *blob, bd_t *bd) | ||||
| { | ||||
| #ifdef CONFIG_PCIE1 | ||||
| 	ft_pcie_ls_setup(blob, FSL_PCIE_COMPAT, CONFIG_SYS_PCIE1_ADDR, PCIE1); | ||||
| #endif | ||||
| 
 | ||||
| #ifdef CONFIG_PCIE2 | ||||
| 	ft_pcie_ls_setup(blob, FSL_PCIE_COMPAT, CONFIG_SYS_PCIE2_ADDR, PCIE2); | ||||
| #endif | ||||
| 
 | ||||
| #ifdef CONFIG_PCIE3 | ||||
| 	ft_pcie_ls_setup(blob, FSL_PCIE_COMPAT, CONFIG_SYS_PCIE3_ADDR, PCIE3); | ||||
| #endif | ||||
| 
 | ||||
| #ifdef CONFIG_PCIE4 | ||||
| 	ft_pcie_ls_setup(blob, FSL_PCIE_COMPAT, CONFIG_SYS_PCIE4_ADDR, PCIE4); | ||||
| #endif | ||||
| 
 | ||||
| #ifdef CONFIG_FSL_LSCH3 | ||||
| 	fdt_fixup_pcie(blob); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| #else /* !CONFIG_OF_BOARD_SETUP */ | ||||
| void ft_pci_setup(void *blob, bd_t *bd) | ||||
| { | ||||
| } | ||||
| #endif | ||||
		Loading…
	
		Reference in New Issue