[PATCH 4/8] pci: pcie_dw_rockchip: Hide BARs of the root complex

Jonas Karlman jonas at kwiboo.se
Tue May 9 16:01:54 CEST 2023


Hi Kever,

On 2023-05-09 14:19, Kever Yang wrote:
> Hi Jonas,
> 
> On 2023/4/23 02:19, Jonas Karlman wrote:
>> PCI Autoconfig read the Root Complex BARs and try to claim the entire
>> 1 GiB memory region on RK3568, leaving no space for any attached device.
>>
>> Return an invalid value during config read of Root Complex BARs during
>> autoconfig to work around such issue.
> 
> Could you share the error message without this workaround?
> 
> I think the driver can works without this patch, the 1GiB memory BAR 
> will assigned fail
> 
> and has no affect to BAR allocate for attached device.
> 

Both BAR0 and BAR1 of the Root Complex on RK3568 report that it wants
1 GiB allocations (value=c0000000). On RK3588 the Root Complex BARs was
entirely skipped (value=0).

The 1 GiB memory BAR assignment used to fail when a 0x0-0x3fffffff pci
range was used, because u-boot would skip initial 4 KiB and instead use
0x1000-0x3fffffff as the pci range.

https://source.denx.de/u-boot/u-boot/-/blob/master/drivers/pci/pci_auto_common.c#L28

With the change to use a 0x40000000-0x7fffffff pci range, the first
1 GiB allocation instead succeed and consume the entire usable range,
leaving allocation for BAR1 of the Root Complex and BARs for any
attached devices to fail.

I did not find any hw reg that could be used to control the returned
value for the BAR0/1 or the Root Complex, value c0000000 was always
read back.

With this change to mask BAR0 and BAR1 for Root Complex on RK3568, the
entire pci range is available for BARs of any attached device.

Regards,
Jonas

> 
> Thanks,
> 
> - Kever
> 
>>
>> Signed-off-by: Jonas Karlman <jonas at kwiboo.se>
>> ---
>>   drivers/pci/pcie_dw_rockchip.c | 28 +++++++++++++++++++++++++++-
>>   1 file changed, 27 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/pci/pcie_dw_rockchip.c b/drivers/pci/pcie_dw_rockchip.c
>> index fd3da47272b3..924ecb93e963 100644
>> --- a/drivers/pci/pcie_dw_rockchip.c
>> +++ b/drivers/pci/pcie_dw_rockchip.c
>> @@ -146,6 +146,32 @@ static inline void rk_pcie_writel_apb(struct rk_pcie *rk_pcie, u32 reg,
>>   	__rk_pcie_write_apb(rk_pcie, rk_pcie->apb_base, reg, 0x4, val);
>>   }
>>   
>> +/**
>> + * The BARs of bridge should be hidden during enumeration to avoid
>> + * allocation of the entire memory region by PCIe core on RK3568.
>> + */
>> +static bool rk_pcie_hide_rc_bar(struct pcie_dw *pcie, pci_dev_t bdf,
>> +				uint offset)
>> +{
>> +	int bus = PCI_BUS(bdf) - pcie->first_busno;
>> +
>> +	return bus == 0 && PCI_DEV(bdf) == 0 && PCI_FUNC(bdf) == 0 &&
>> +	       offset >= PCI_BASE_ADDRESS_0 && offset <= PCI_BASE_ADDRESS_1;
>> +}
>> +
>> +static int rk_pcie_read_config(const struct udevice *bus, pci_dev_t bdf,
>> +			       uint offset, ulong *valuep,
>> +			       enum pci_size_t size)
>> +{
>> +	struct pcie_dw *pcie = dev_get_priv(bus);
>> +	int ret = pcie_dw_read_config(bus, bdf, offset, valuep, size);
>> +
>> +	if (!ret && rk_pcie_hide_rc_bar(pcie, bdf, offset))
>> +		*valuep = pci_get_ff(size);
>> +
>> +	return ret;
>> +}
>> +
>>   /**
>>    * rk_pcie_configure() - Configure link capabilities and speed
>>    *
>> @@ -476,7 +502,7 @@ rockchip_pcie_probe_err_init_port:
>>   }
>>   
>>   static const struct dm_pci_ops rockchip_pcie_ops = {
>> -	.read_config	= pcie_dw_read_config,
>> +	.read_config	= rk_pcie_read_config,
>>   	.write_config	= pcie_dw_write_config,
>>   };
>>   



More information about the U-Boot mailing list