This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TDA4VH-Q1:TDA4VH:RC1&amp PCIe 问题;RT Linux 补丁

Guru**** 667810 points
Other Parts Discussed in Thread: TDA4VM
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1228253/tda4vh-q1-tda4vh-pcie-problems-with-rc1-rt-linux-patch

器件型号:TDA4VH-Q1
主题中讨论的其他器件:TDA4VMTDA4VH

您好、TI PCIe 专家、

我的行业客户正在使用 TDA4VH SDK8.6、并且需要 SDK 中的 RT 补丁用于行业实时应用。 客户正在 RC 模式下使用我们的处理器 TDA4VM/VH PCIe、并 在 EP 模式下连接到第三方 PCIe NIC (Realtek_RTL8111H)。 有2个与 PCIe 相关的问题阻止了他们的进度。 经过一些测试和搜索、也有一些其他的客户在 TDA4VH 中遇到了同样的问题。   

https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1207224/tda4vh-q1-questions-about-j784s4-pcie?tisearch=e2e-sitesearch&keymatch=pcie%25252525252525252520FAILED%25252525252525252520TO%25252525252525252520INIT%25252525252525252520PHY#

对于问题1 (没有 RT 补丁)、PCIE0的根复合体可以运行、但 PCIE1 (RC1)将具有 phy init 错误、并且无法以相同的设置建立链路。 TDA4VM 中不存在此问题。

对于问题2 (使用 RT 补丁)、在相同的软件和硬件环境下、仅添加 RT 补丁、 在 TDA4VM 和 TDA4VH 中、PCIE0和 PCIE1都将出现内核崩溃问题。

感谢您对上述2个问题的帮助!

以下是问题2的错误日志。

[   1.026490] j721e-PCIe 2900000.PCIe:主机桥/bus@100000/PCIe@2900000范围:

[   1.026511] j721e-PCIe 2900000。PCIe:      IO 0x0010001000……0x0010010fff -> 0x001000

[   1.026522] j721e-PCIe 2900000.PCIe:     MEM 0x0010011000..0x0017ffff -> 0x0010011000

[   1.026532] j721e-PCIe 2900000.PCIe:  IB MEM 0x0000000000..0xFFffffff -> 0x0000000000

[   1.137304] j721e-pcie 29000.pcie:链路接通

[   1.137309] j721e-pcie 29000.pcie:链路接通

[1.137375]   j721e-pcie 2900000.pcie:PCI 主机桥接至总线0000:00

[   1.137379] PCI_BUS 0000:00:根总线资源[总线00-ff]

[   1.137384] PCI_BUS 0000:根总线资源[IO 0x0000-0FFF](总线地址[0x10001000-0x10010fff])

[   1.137388] PCI_BUS 0000:00:根总线资源[mem 0x10011000-0x17ffff]

[   1.137418] PCI 0000:00:00.0:[104C:b00d]类型01类0x060400

[   1.137423] PCI_BUS 0000:00:2字节 CONFIG 写入0000:00:00.0偏移量0x4可能会损坏相邻的 RW1C 位

[   1.137509] PCI 0000:00:00.0:支持 D1

[1.137512]   PCI 0000:00:00.0:D0 D1 D3hot 支持 PME#

[   1.137530] PCI 0000:00:00.0:寄存器0x224:[MEM 0x00000000-0x003fff 64位]

[   1.137534] PCI 0000:00:00.0:VF (n) BAR0空间:[MEM 0x00000000-0x00ffff 64位](包含4个 VF 的 BAR0)

[   1.139524] PCI 0000:00:00.0:桥配置无效([bus 00-00]),重新配置

[   1.161305] CPU1上的 SError 中断、代码0xbf000000 -- SError

[1.161311]   CPU:1 PID:66 Comm:kworker/1:2 not dament 5.10.162-rt79-g02a1d48fd7 #3

[   1.161314]硬件名称:德州仪器(TI) K3 J721E SoC (DT)

[   1.161320 ] j721e-pcie 29000.pcie:link down!

[1.161321]   workqueue:事件 defended_probe_work_func

[1.161334]   pstate:20000085 (nzCv daIf -pan -uao -TCO BTYPE=-)

[1.161338]   PC : PCI_GENERAL_CONFIG_READ+0x3c/0xe0

[1.161346]   lr : PCI_GENERAL_CONFIG_READ+0x24/0xe0

[1.161349]   sp : ff800011883720

[1.161350]   x29:ff800011883720 x28:ff000801be6800

[   1.161354] x27:000000000000 x26:0000000000000001

[1.161357]   x25:ff800011256bf8 x24:000000000000

[   1.161360] x23:ff800011883864 x22:0000000000000087

[1.161363]   x21:ff000801be7000 x20:000000000004

[1.161366]   x19:ff8000118837a4 x18:000000000000

[   1.161368] x17:00000000f6ae94a3 x16:00000000e360973d

[1.161372]   x15:ff000800d9b260 x14:ffffffffffffffffffffffffffffffffffffffff

[1.161374]   x13:ff000801ab9a1c x12:ff000801ab929a

[1.161377]   x11:01010101010101 x10:7f7f7f7f7f7f7f7f7f7f7f7f7f

[1.16 1380]   x9:00000000b00d104c x8:0000000080b5111d

[1.161383]   x7 : 000000000000ea60 x6 : ff800011883864

[   1.161386] x5:ff000801be6800 x4:00000000000b

[   1.161388] x3 : 0000000000000001 x2 : ff800013c00008

[   1.161391] x1 : 0000000000000000 x0 : ff8000116b5000

[   1.161394]内核紧急-未同步:

[1.161395]   异步错误中断

[1.161397]   CPU: 1 PID: 66 Comm: kwork/1:2 not dament 5.10.162-rt79-g02a1d48fd7 #3

[   1.161400]硬件名称:德州仪器(TI) K3 J721E SoC (DT)

[   1.161406] workqueue:事件 defended_probe_work_func

[1.161410]   呼叫跟踪:

[   1.161411] dump_backtrace+0x0/0x1a0

[   1.161420] show_stack+0x18/0x68

[   1.161424] dump_stack+0xd0/0x12c

[1.161430]    恐慌+0xcc/0x360

[   1.161434] NMI_PANE+0x94/0x98

[   1.161439] arm64_serror_pania+0x78/0x84

[   1.161442] do_serror+0x38/0x98

[   1.161447] el1_error+0x90/0x110

[   1.16 1449] pci_generic_config_read+0x3c/0xe0

[   1.161453] cdns_ti_pci_config_read+0x18/0x38

[   1.161459] PCI_BUS_READ_CONFIG_DWORD+0x80/0xd8

[   1.161462] PCI_BUS_GENERAL_READ_DEV_VENTER_id+0x34/0x1b0

[   1.161465] PCI_BUS_READ_DEV_VENTOR_id+0x4c/0x70

[   1.161468] PCI_SCAN_SINGLE_DEVICE+0x7c/0xf8

[   1.161470] PCI_SCAN_SLOT+0x40/0x120

[   1.161472] PCI_SCAN_CHILD_BUS_EXTEND+0x54/0x298

[   1.161475] PCI_SCAN_BRIDGE_EXTEND+0x29c/0x580

[   1.161477] PCI_SCAN_CHILD_BUS_EXTEND+0x1e4/0x298

[   1.161480] PCI_SCAN_ROOT_BUS_BRIDGE+0x64/0xd8

[   1.161482] PCI_HOST_PROBE+0x18/0xc8

[   1.161485] cdns_pci_host_setup+0x51c/0x8f8

[   1.161489] j721e_pci_prob+0x494/0x820

[   1.161492] platform_drv_probed+0x54/0xa8

[   1.161498] reallet_prob+0xec/0x3e0

[   1.16 1501] driver_probe_device+0x58/0xb8

[   1.161504] _device_attach_driver+0xb8/0xe0

[   1.16 1507] bus_for_each_drv+0x78/0xc8

[   1.161510] __DEVICE_ATIAT+0xf8/0x188

[   1.161513] DEVICE_INITIAL_PROBE+0x14/0x20

[   1.161516] BUS_PROBE_DEVICE+0x9C/0xa8

[   1.161519] Defered_probe_work_func+0x88/0xc0

[   1.161522] proce_one_work+0x1a0/0x328

[1.161527]    worker_thread+0x1f8/0x420

[1.161531]    kthread+0x174/0x198

[   1.161534] ret_from_fork+0x10/0x34

此致、

凯文

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Kevin 老师好!

    请应用随附的补丁并检查它是否修复了发现的问题:
    e2e.ti.com/.../6644.PCI_2D00_cadence_2D00_Fix_2D00_Gen2_2D00_Link_2D00_Retraining_2D00_process.patch

    此致、
    Siddharth。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Siddharth:

    该补丁不能解决观察到的问题、PCIE1仍然存在 phy init 错误。 此外、调试信息"xqqqq"添加到如下所示的 cdns_pci_host_training_complete 函数中、但在日志中找不到它。 这个新函数似乎没有执行。 经过一些调试后、默认的 J7S84 Linux SDK (无 RT 补丁)不满足  cdns_pci_host_training_complete 的"if"条件。

    此致、

    凯文

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    Kevin 老师好!

    对于 J784S4、因为  Quirk_retraine_flag 如果设置为 true,则应调用 cdns_pci_retrain()函数。
     调用 cdns_pci_host_training_complete()函数。
    如果  cdns_pci_host_training_complete()的返回值为-ETIMEDOUT,则表示
    培训未完成。 电流超时设置为1Hz、您能否
    5 Hz、并检查培训是否完成? 发生崩溃是因为函数:
    PCI_通用_配置_读取
    尝试在未完成培训的情况下执行寄存器访问。

    此致、
    Siddharth。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Siddharth

       感谢您的支持!

       您提到的解决方案可解决 PCIe 崩溃问题。

       但 PCIE1 Phy init 初始化失败问题仍然存在。  

    diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c
    index 0a79e553e..584022b3f 100644
    --- a/drivers/pci/controller/cadence/pcie-cadence-host.c
    +++ b/drivers/pci/controller/cadence/pcie-cadence-host.c
    @@ -13,6 +13,8 @@
     
     #include "pcie-cadence.h"
     
    +#define LINK_RETRAIN_TIMEOUT (5 * HZ)
    +
     static u64 bar_max_size[] = {
     	[RP_BAR0] = _ULL(128 * SZ_2G),
     	[RP_BAR1] = SZ_2G,
    @@ -79,6 +81,27 @@ static struct pci_ops cdns_pcie_host_ops = {
     	.write		= pci_generic_config_write,
     };
     
    +static int cdns_pcie_host_training_complete(struct cdns_pcie *pcie)
    +{
    +	u32 pcie_cap_off = CDNS_PCIE_RP_CAP_OFFSET;
    +	unsigned long end_jiffies;
    +	u16 lnk_stat;
    +
    +	/* Wait for link training to complete. Exit after timeout. */
    +	end_jiffies = jiffies + LINK_RETRAIN_TIMEOUT;
    +	do {
    +		lnk_stat = cdns_pcie_rp_readw(pcie, pcie_cap_off + PCI_EXP_LNKSTA);
    +		if (!(lnk_stat & PCI_EXP_LNKSTA_LT))
    +			break;
    +		usleep_range(0, 1000);
    +	} while (time_before(jiffies, end_jiffies));
    +
    +	if (!(lnk_stat & PCI_EXP_LNKSTA_LT))
    +		return 0;
    +
    +	return -ETIMEDOUT;
    +}
    +
     static int cdns_pcie_host_wait_for_link(struct cdns_pcie *pcie)
     {
     	struct device *dev = pcie->dev;
    @@ -120,6 +143,9 @@ static int cdns_pcie_retrain(struct cdns_pcie *pcie)
     		cdns_pcie_rp_writew(pcie, pcie_cap_off + PCI_EXP_LNKCTL,
     				    lnk_ctl);
     
    +		ret = cdns_pcie_host_training_complete(pcie);
    +		if (ret)
    +			return ret;
     		ret = cdns_pcie_host_wait_for_link(pcie);
     	}
     	return ret;
    diff --git a/drivers/pci/controller/cadence/pcie-cadence.h b/drivers/pci/controller/cadence/pcie-cadence.h
    index 56fe4f843..f7a740124 100644
    --- a/drivers/pci/controller/cadence/pcie-cadence.h
    +++ b/drivers/pci/controller/cadence/pcie-cadence.h
    @@ -11,7 +11,7 @@
     #include <linux/phy/phy.h>
     
     /* Parameters for the waiting for link up routine */
    -#define LINK_WAIT_MAX_RETRIES	10
    +#define LINK_WAIT_MAX_RETRIES	30
     #define LINK_WAIT_USLEEP_MIN	90000
     #define LINK_WAIT_USLEEP_MAX	100000
     
    diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c
    index 875d50c16..4d07bc830 100644
    --- a/drivers/pci/setup-res.c
    +++ b/drivers/pci/setup-res.c
    @@ -20,6 +20,7 @@
     #include <linux/ioport.h>
     #include <linux/cache.h>
     #include <linux/slab.h>
    +#include <linux/delay.h>
     #include "pci.h"
     
     static void pci_std_update_resource(struct pci_dev *dev, int resno)
    @@ -96,6 +97,8 @@ static void pci_std_update_resource(struct pci_dev *dev, int resno)
     				      cmd & ~PCI_COMMAND_MEMORY);
     	}
     
    +	usleep_range(90000, 120000);
    +
     	pci_write_config_dword(dev, reg, new);
     	pci_read_config_dword(dev, reg, &check);
     
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好!

    "FAILED TO INIT PHY"错误中的"PHY"对应于串行器/解串器。
    串行器/解串器支持两种类型的配置:
    1.单链路(串行器/解串器配置为单个协议)(例如、仅限 PCIe)
    2.多链路(串行器/解串器配置用于两种不同的协议)(例如 PCIe +USB)

    PCIe0实例使用串行器/解串器的 Serdes1实例、该实例配置为单个协议(仅限 PCIe)。
    PCIe1实例使用 Serdes 的 Serdes0实例、该实例针对两个协议(PCIe + USB)进行配置。
    这是实例 PCIe0和 PCIe1之间的主要区别。

    接下来、根据是否必须对串行器/解串器进行配置、执行方式有所不同
    单个协议或两个协议。 在单链路配置中、Serdes 驱动程序不会将
    串行器/解串器。 相反、将使用串行器/解串器的外设应请求串行器/解串器
    可以通过 PHY API (phy_init ()和 phy_power_on ())进行配置。 另一方面、对于多链路配置、
    串行器/解串器驱动程序本身使用串行器/解串器配置串行器/解串器和外设、不必尝试
    配置串行器/解串器。

    对于 PCIe0、由于它是 Serdes1的唯一用户、所以它请求将串行器/解串器配置为仅 PCIe 配置
    通过调用其他 PHY API 的 cdns_pci_init_phy ()函数实现的。 这不会导致任何误差、因为
    SerDes 驱动程序无法配置它。

    对于 PCIe1、由于它与 USB 共享 Serdes0、因此 Serdes 驱动程序将自动在 PCIe + USB
    基于 serdes0内的器件树节点。 因此、我们看到在写入 PHY 时出现错误("FAILED TO INIT PHY")
    PCIe 驱动程序为 PCIe1实例调用 cdns_pci_init_phy ()。 这实际上并不是一个错误、因为串行器/解串器
    串行器/解串器驱动程序本身正确配置的通道。 在已配置串行器/解串器时尝试对其进行配置的
    尝试配置它失败的原因。 不过、这不会影响功能。

    其他驱动程序使用 devm_of_phy_optional_get ()函数,而不是 PCIe 使用的 devm_phy_get ()函数
    驱动程序。 这两者的区别在于、 前一个函数指示 PHY 是否已被另一个驱动程序使用
    (串行器/解串器驱动器配置中的串行器/解串器)、而后者的功能由于无法获取
    另一个驱动器正在使用的 PHY、这会导致"FAILED TO INIT PHY"错误。

    或者、请应用以下差异、以便禁用 USB 并将整个 Serdes0实例分配给 PCIe1:

    diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
    index 49297514473f..f5c74e9cd4a4 100644
    --- a/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
    +++ b/arch/arm64/boot/dts/ti/k3-j784s4-evm.dts
    @@ -500,11 +500,11 @@ J784S4_IOPAD(0x010, PIN_INPUT_PULLUP, 8) /* (AH33) MCAN13_RX.I2C4_SDA */
     		>;
     	};
     
    -	main_usbss0_pins_default: main-usbss0-pins-default {
    -		pinctrl-single,pins = <
    -			J784S4_IOPAD(0x0ec, PIN_OUTPUT, 6) /* (AN37) TIMER_IO1.USB0_DRVVBUS */
    -		>;
    -	};
    +//	main_usbss0_pins_default: main-usbss0-pins-default {
    +//		pinctrl-single,pins = <
    +//			J784S4_IOPAD(0x0ec, PIN_OUTPUT, 6) /* (AN37) TIMER_IO1.USB0_DRVVBUS */
    +//		>;
    +//	};
     
     	main_mcan16_pins_default: main-mcan16-pins-default {
     		pinctrl-single,pins = <
    @@ -706,19 +706,20 @@ &serdes0 {
     	status = "okay";
     	serdes0_pcie_link: phy@0 {
     		reg = <0>;
    -		cdns,num-lanes = <2>;
    +		cdns,num-lanes = <4>;
     		#phy-cells = <0>;
     		cdns,phy-type = <PHY_TYPE_PCIE>;
    -		resets = <&serdes_wiz0 1>, <&serdes_wiz0 2>;
    +		resets = <&serdes_wiz0 1>, <&serdes_wiz0 2>,
    +			 <&serdes_wiz0 3>, <&serdes_wiz0 4>;
     	};
     
    -	serdes0_usb_link: phy@3 {
    -		reg = <3>;
    -		cdns,num-lanes = <1>;
    -		#phy-cells = <0>;
    -		cdns,phy-type = <PHY_TYPE_USB3>;
    -		resets = <&serdes_wiz0 4>;
    -	};
    +//	serdes0_usb_link: phy@3 {
    +//		reg = <3>;
    +//		cdns,num-lanes = <1>;
    +//		#phy-cells = <0>;
    +//		cdns,phy-type = <PHY_TYPE_USB3>;
    +//		resets = <&serdes_wiz0 4>;
    +//	};
     };
     
     &serdes_wiz0 {
    @@ -780,7 +781,7 @@ &main_navss_intr {
     
     &serdes_ln_ctrl {
     	idle-states = <J784S4_SERDES0_LANE0_PCIE1_LANE0>, <J784S4_SERDES0_LANE1_PCIE1_LANE1>,
    -		      <J784S4_SERDES0_LANE2_IP3_UNUSED>, <J784S4_SERDES0_LANE3_USB>,
    +		      <J784S4_SERDES0_LANE2_PCIE1_LANE2>, <J784S4_SERDES0_LANE3_PCIE1_LANE3>,
     		      <J784S4_SERDES1_LANE0_PCIE0_LANE0>, <J784S4_SERDES1_LANE1_PCIE0_LANE1>,
     		      <J784S4_SERDES1_LANE2_PCIE0_LANE2>, <J784S4_SERDES1_LANE3_PCIE0_LANE3>,
     		      <J784S4_SERDES2_LANE2_QSGMII_LANE1>, <J784S4_SERDES2_LANE3_QSGMII_LANE2>;
    @@ -1229,29 +1230,29 @@ &main_mcan16 {
     	phys = <&transceiver3>;
     };
     
    -&serdes_wiz0 {
    -	typec-dir-gpios = <&wkup_gpio0 28 GPIO_ACTIVE_HIGH>;
    -	typec-dir-debounce-ms = <700>;	/* TUSB321, tCCB_DEFAULT 133 ms */
    -};
    -
    -&usb_serdes_mux {
    -	idle-states = <0>; /* USB0 to SERDES lane 3 */
    -};
    -
    -&usbss0 {
    -	status = "okay";
    -	pinctrl-0 = <&main_usbss0_pins_default>;
    -	pinctrl-names = "default";
    -	ti,vbus-divider;
    -};
    -
    -&usb0 {
    -	status = "okay";
    -	dr_mode = "otg";
    -	maximum-speed = "super-speed";
    -	phys = <&serdes0_usb_link>;
    -	phy-names = "cdns3,usb3-phy";
    -};
    +//&serdes_wiz0 {
    +//	typec-dir-gpios = <&wkup_gpio0 28 GPIO_ACTIVE_HIGH>;
    +//	typec-dir-debounce-ms = <700>;	/* TUSB321, tCCB_DEFAULT 133 ms */
    +//};
    +//
    +//&usb_serdes_mux {
    +//	idle-states = <0>; /* USB0 to SERDES lane 3 */
    +//};
    +
    +//&usbss0 {
    +//	status = "okay";
    +//	pinctrl-0 = <&main_usbss0_pins_default>;
    +//	pinctrl-names = "default";
    +//	ti,vbus-divider;
    +//};
    +//
    +//&usb0 {
    +//	status = "okay";
    +//	dr_mode = "otg";
    +//	maximum-speed = "super-speed";
    +//	phys = <&serdes0_usb_link>;
    +//	phy-names = "cdns3,usb3-phy";
    +//};
     
     &tscadc0 {
     	status = "okay";

    应用上述差分后、由于 Serdes0现在也将配置为单链路配置、
    将不再显示错误"Failed to init phy"。

    此致、
    Siddharth。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好,Siddharth

        感谢您的全面解释!

        我应用了 dts diff。 "FAILED TO INIT PHY"日志确实消失。

        但没有针对 PCIE1的"链路建立"。 PCIE1仍无法工作。   

        PCIE0正常。  

    此致!

    Johnson.Xu

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    尊敬的 Johnson:

    J7S84 EVM 电路板中的默认硬件设置是 PCIE0处于 RC 模式、PCIE1处于 EP 模式、这可在原理图中找到。

    PCIe 1情形:

     

     

    PCIe 0情况:

     

    若要使 PCIE1在 RC 模式下工作、建议参考 PCIE0的硬件连接。

    删除:R3、R4、C1、C2、R905、 R906

    连接:R1、R2、R5、R6、R899、 R900

    您可以测试上述硬件更改是否适用于 PCIE1 RC 模式吗?

    此致、

    凯文

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    大家好、Kevin

       这种返修方法可以使 PCIE1 RC 模式正常工作!

       感谢您的支持!

    此致!

    徐强生