diff options
Diffstat (limited to 'drivers/pci/controller/pcie-iproc.c')
| -rw-r--r-- | drivers/pci/controller/pcie-iproc.c | 106 | 
1 files changed, 43 insertions, 63 deletions
diff --git a/drivers/pci/controller/pcie-iproc.c b/drivers/pci/controller/pcie-iproc.c index 2d457bfdaf66..0a468c73bae3 100644 --- a/drivers/pci/controller/pcie-iproc.c +++ b/drivers/pci/controller/pcie-iproc.c @@ -1122,15 +1122,16 @@ static int iproc_pcie_ib_write(struct iproc_pcie *pcie, int region_idx,  }  static int iproc_pcie_setup_ib(struct iproc_pcie *pcie, -			       struct of_pci_range *range, +			       struct resource_entry *entry,  			       enum iproc_pcie_ib_map_type type)  {  	struct device *dev = pcie->dev;  	struct iproc_pcie_ib *ib = &pcie->ib;  	int ret;  	unsigned int region_idx, size_idx; -	u64 axi_addr = range->cpu_addr, pci_addr = range->pci_addr; -	resource_size_t size = range->size; +	u64 axi_addr = entry->res->start; +	u64 pci_addr = entry->res->start - entry->offset; +	resource_size_t size = resource_size(entry->res);  	/* iterate through all IARR mapping regions */  	for (region_idx = 0; region_idx < ib->nr_regions; region_idx++) { @@ -1182,67 +1183,46 @@ err_ib:  	return ret;  } -static int iproc_pcie_add_dma_range(struct device *dev, -				    struct list_head *resources, -				    struct of_pci_range *range) +static int iproc_pcie_map_dma_ranges(struct iproc_pcie *pcie)  { -	struct resource *res; -	struct resource_entry *entry, *tmp; -	struct list_head *head = resources; - -	res = devm_kzalloc(dev, sizeof(struct resource), GFP_KERNEL); -	if (!res) -		return -ENOMEM; +	struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie); +	struct resource_entry *entry; +	int ret = 0; -	resource_list_for_each_entry(tmp, resources) { -		if (tmp->res->start < range->cpu_addr) -			head = &tmp->node; +	resource_list_for_each_entry(entry, &host->dma_ranges) { +		/* Each range entry corresponds to an inbound mapping region */ +		ret = iproc_pcie_setup_ib(pcie, entry, IPROC_PCIE_IB_MAP_MEM); +		if (ret) +			break;  	} -	res->start = range->cpu_addr; -	res->end = res->start + range->size - 1; - -	entry = resource_list_create_entry(res, 0); -	if (!entry) -		return -ENOMEM; - -	entry->offset = res->start - range->cpu_addr; -	resource_list_add(entry, head); - -	return 0; +	return ret;  } -static int iproc_pcie_map_dma_ranges(struct iproc_pcie *pcie) +static void iproc_pcie_invalidate_mapping(struct iproc_pcie *pcie)  { -	struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie); -	struct of_pci_range range; -	struct of_pci_range_parser parser; -	int ret; -	LIST_HEAD(resources); +	struct iproc_pcie_ib *ib = &pcie->ib; +	struct iproc_pcie_ob *ob = &pcie->ob; +	int idx; -	/* Get the dma-ranges from DT */ -	ret = of_pci_dma_range_parser_init(&parser, pcie->dev->of_node); -	if (ret) -		return ret; +	if (pcie->ep_is_internal) +		return; -	for_each_of_pci_range(&parser, &range) { -		ret = iproc_pcie_add_dma_range(pcie->dev, -					       &resources, -					       &range); -		if (ret) -			goto out; -		/* Each range entry corresponds to an inbound mapping region */ -		ret = iproc_pcie_setup_ib(pcie, &range, IPROC_PCIE_IB_MAP_MEM); -		if (ret) -			goto out; +	if (pcie->need_ob_cfg) { +		/* iterate through all OARR mapping regions */ +		for (idx = ob->nr_windows - 1; idx >= 0; idx--) { +			iproc_pcie_write_reg(pcie, +					     MAP_REG(IPROC_PCIE_OARR0, idx), 0); +		}  	} -	list_splice_init(&resources, &host->dma_ranges); - -	return 0; -out: -	pci_free_resource_list(&resources); -	return ret; +	if (pcie->need_ib_cfg) { +		/* iterate through all IARR mapping regions */ +		for (idx = 0; idx < ib->nr_regions; idx++) { +			iproc_pcie_write_reg(pcie, +					     MAP_REG(IPROC_PCIE_IARR0, idx), 0); +		} +	}  }  static int iproce_pcie_get_msi(struct iproc_pcie *pcie, @@ -1276,13 +1256,16 @@ static int iproce_pcie_get_msi(struct iproc_pcie *pcie,  static int iproc_pcie_paxb_v2_msi_steer(struct iproc_pcie *pcie, u64 msi_addr)  {  	int ret; -	struct of_pci_range range; +	struct resource_entry entry; -	memset(&range, 0, sizeof(range)); -	range.size = SZ_32K; -	range.pci_addr = range.cpu_addr = msi_addr & ~(range.size - 1); +	memset(&entry, 0, sizeof(entry)); +	entry.res = &entry.__res; -	ret = iproc_pcie_setup_ib(pcie, &range, IPROC_PCIE_IB_MAP_IO); +	msi_addr &= ~(SZ_32K - 1); +	entry.res->start = msi_addr; +	entry.res->end = msi_addr + SZ_32K - 1; + +	ret = iproc_pcie_setup_ib(pcie, &entry, IPROC_PCIE_IB_MAP_IO);  	return ret;  } @@ -1498,10 +1481,6 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)  		return ret;  	} -	ret = devm_request_pci_bus_resources(dev, res); -	if (ret) -		return ret; -  	ret = phy_init(pcie->phy);  	if (ret) {  		dev_err(dev, "unable to initialize PCIe PHY\n"); @@ -1517,6 +1496,8 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)  	iproc_pcie_perst_ctrl(pcie, true);  	iproc_pcie_perst_ctrl(pcie, false); +	iproc_pcie_invalidate_mapping(pcie); +  	if (pcie->need_ob_cfg) {  		ret = iproc_pcie_map_ranges(pcie, res);  		if (ret) { @@ -1543,7 +1524,6 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)  		if (iproc_pcie_msi_enable(pcie))  			dev_info(dev, "not using iProc MSI\n"); -	list_splice_init(res, &host->windows);  	host->busnr = 0;  	host->dev.parent = dev;  	host->ops = &iproc_pcie_ops;  |