mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	PCI: iproc: Invalidate PAXB address mapping before programming it
Invalidate PAXB inbound/outbound address mapping on probe before programming it. Kernel relies on outbound/inbound windows VALID bit in OARR registers to detect if a window was programmed and if it is set it does not overwrite it. This causes issues on soft reboot (eg kexec) since the host controller does not go through a HW reset on softboot so the kernel detects valid outbound/inbound windows configuration and is not able to reprogramme it as expected. Therefore, in order to make sure outbound/inbound windows are reprogrammed on soft reboot (eg kexec), invalidate memory windows on each probe to fix the issue. Signed-off-by: Abhishek Shah <abhishek.shah@broadcom.com> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Reviewed-by: Ray Jui <ray.jui@broadcom.com> Reviewed-by: Andrew Murray <andrew.murray@arm.com>
This commit is contained in:
		
							parent
							
								
									54ecb8f702
								
							
						
					
					
						commit
						9415743e4c
					
				
					 1 changed files with 28 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -1245,6 +1245,32 @@ static int iproc_pcie_map_dma_ranges(struct iproc_pcie *pcie)
 | 
			
		|||
	return ret;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void iproc_pcie_invalidate_mapping(struct iproc_pcie *pcie)
 | 
			
		||||
{
 | 
			
		||||
	struct iproc_pcie_ib *ib = &pcie->ib;
 | 
			
		||||
	struct iproc_pcie_ob *ob = &pcie->ob;
 | 
			
		||||
	int idx;
 | 
			
		||||
 | 
			
		||||
	if (pcie->ep_is_internal)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	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);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	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,
 | 
			
		||||
			       struct device_node *msi_node,
 | 
			
		||||
			       u64 *msi_addr)
 | 
			
		||||
| 
						 | 
				
			
			@ -1517,6 +1543,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) {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in a new issue