diff mbox series

[v5,3/7] PCI: imx6: Toggle the cold reset for i.MX95 PCIe

Message ID 20250408025930.1863551-4-hongxing.zhu@nxp.com (mailing list archive)
State New
Delegated to: Krzysztof Wilczyński
Headers show
Series Add some enhancements for i.MX95 PCIe | expand

Commit Message

Hongxing Zhu April 8, 2025, 2:59 a.m. UTC
Add the cold reset toggle for i.MX95 PCIe to align PHY's power up sequency.

Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
---
 drivers/pci/controller/dwc/pci-imx6.c | 42 +++++++++++++++++++++++++++
 1 file changed, 42 insertions(+)

Comments

Alexander Stein April 9, 2025, 9:51 a.m. UTC | #1
Hi,

Am Dienstag, 8. April 2025, 04:59:26 CEST schrieb Richard Zhu:
> Add the cold reset toggle for i.MX95 PCIe to align PHY's power up sequency.
> 
> Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
> Reviewed-by: Frank Li <Frank.Li@nxp.com>
> ---
>  drivers/pci/controller/dwc/pci-imx6.c | 42 +++++++++++++++++++++++++++
>  1 file changed, 42 insertions(+)
> 
> diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> index c5871c3d4194..7c60b712480a 100644
> --- a/drivers/pci/controller/dwc/pci-imx6.c
> +++ b/drivers/pci/controller/dwc/pci-imx6.c
> @@ -71,6 +71,9 @@
>  #define IMX95_SID_MASK				GENMASK(5, 0)
>  #define IMX95_MAX_LUT				32
>  
> +#define IMX95_PCIE_RST_CTRL			0x3010
> +#define IMX95_PCIE_COLD_RST			BIT(0)
> +
>  #define to_imx_pcie(x)	dev_get_drvdata((x)->dev)
>  
>  enum imx_pcie_variants {
> @@ -773,6 +776,43 @@ static int imx7d_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert)
>  	return 0;
>  }
>  
> +static int imx95_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert)
> +{
> +	u32 val;
> +
> +	if (assert) {
> +		/*
> +		 * From i.MX95 PCIe PHY perspective, the COLD reset toggle
> +		 * should be complete after power-up by the following sequence.
> +		 *                 > 10us(at power-up)
> +		 *                 > 10ns(warm reset)
> +		 *               |<------------>|
> +		 *                ______________
> +		 * phy_reset ____/              \________________
> +		 *                                   ____________
> +		 * ref_clk_en_______________________/
> +		 * Toggle COLD reset aligned with this sequence for i.MX95 PCIe.
> +		 */
> +		regmap_set_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_RST_CTRL,
> +				IMX95_PCIE_COLD_RST);
> +		/*
> +		 * Make sure the write to IMX95_PCIE_RST_CTRL is flushed to the
> +		 * hardware by doing a read. Otherwise, there is no guarantee
> +		 * that the write has reached the hardware before udelay().
> +		 */
> +		regmap_read_bypassed(imx_pcie->iomuxc_gpr, IMX95_PCIE_RST_CTRL,
> +				     &val);
> +		udelay(15);
> +		regmap_clear_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_RST_CTRL,
> +				  IMX95_PCIE_COLD_RST);
> +		regmap_read_bypassed(imx_pcie->iomuxc_gpr, IMX95_PCIE_RST_CTRL,
> +				     &val);
> +		udelay(10);
> +	}
> +
> +	return 0;
> +}
> +
>  static void imx_pcie_assert_core_reset(struct imx_pcie *imx_pcie)
>  {
>  	reset_control_assert(imx_pcie->pciephy_reset);
> @@ -1739,6 +1779,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
>  		.ltssm_mask = IMX95_PCIE_LTSSM_EN,
>  		.mode_off[0]  = IMX95_PE0_GEN_CTRL_1,
>  		.mode_mask[0] = IMX95_PCIE_DEVICE_TYPE,
> +		.core_reset = imx95_pcie_core_reset,
>  		.init_phy = imx95_pcie_init_phy,
>  	},
>  	[IMX8MQ_EP] = {
> @@ -1792,6 +1833,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
>  		.mode_off[0]  = IMX95_PE0_GEN_CTRL_1,
>  		.mode_mask[0] = IMX95_PCIE_DEVICE_TYPE,
>  		.init_phy = imx95_pcie_init_phy,
> +		.core_reset = imx95_pcie_core_reset,
>  		.epc_features = &imx95_pcie_epc_features,
>  		.mode = DW_PCIE_EP_TYPE,
>  	},
> 

This change introduces an invalid memory access on my platform. There is not
even a PCIe device attached to it.

> imx6q-pcie 4c380000.pcie: host bridge /soc/pcie@4c380000 ranges:
> imx6q-pcie 4c300000.pcie: host bridge /soc/pcie@4c300000 ranges:
> imx6q-pcie 4c380000.pcie:       IO 0x088ff00000..0x088fffffff -> 0x0000000000
> imx6q-pcie 4c300000.pcie:       IO 0x006ff00000..0x006fffffff -> 0x0000000000
> imx6q-pcie 4c380000.pcie:      MEM 0x0a10000000..0x0a1fffffff -> 0x0010000000
> imx6q-pcie 4c300000.pcie:      MEM 0x0910000000..0x091fffffff -> 0x0010000000
> imx6q-pcie 4c380000.pcie: config reg[1] 0x880100000 == cpu 0x880100000
> ; no fixup was ever needed for this devicetree
> imx6q-pcie 4c300000.pcie: config reg[1] 0x60100000 == cpu 0x60100000
> ; no fixup was ever needed for this devicetree
> Unable to handle kernel paging request at virtual address ffff800081dc5010
> Unable to handle kernel paging request at virtual address ffff8000821bd010
> Mem abort info:
> 
> Mem abort info:
>   ESR = 0x0000000096000007
>   ESR = 0x0000000096000007
>   EC = 0x25: DABT (current EL), IL = 32 bits
>   EC = 0x25: DABT (current EL), IL = 32 bits
> 
> fsl_enetc_mdio 0003:01:00.0: enabling device (0000 -> 0002)
> 
>   SET = 0, FnV = 0
>   SET = 0, FnV = 0
>   EA = 0, S1PTW = 0
>   EA = 0, S1PTW = 0
>   FSC = 0x07: level 3 translation fault
>   FSC = 0x07: level 3 translation fault
> 
> Data abort info:
> 
> Data abort info:
>   ISV = 0, ISS = 0x00000007, ISS2 = 0x00000000
>   ISV = 0, ISS = 0x00000007, ISS2 = 0x00000000
>   CM = 0, WnR = 0, TnD = 0, TagAccess = 0
>   CM = 0, WnR = 0, TnD = 0, TagAccess = 0
>   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
>   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
> 
> swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000000091a47000
> swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000000091a47000
> [ffff800081dc5010] pgd=1000000092002003
> [ffff8000821bd010] pgd=1000000092002003
> , p4d=1000000092002003
> , p4d=1000000092002003
> , pud=1000000092003003
> , pud=1000000092003003
> , pmd=1000000092008003
> , pmd=100000009299f403
> , pte=0000000000000000
> , pte=0000000000000000
> 
> 
> Internal error: Oops: 0000000096000007 [#1]  SMP
> Modules linked in:
> CPU: 0 UID: 0 PID: 63 Comm: kworker/u24:4 Tainted: G                T  
> 6.15.0-rc1-next-20250409+ #3009 PREEMPT 
> f6bd3cc6346487744ae55f6115e728ff2bc7088b Tainted: [T]=RANDSTRUCT
> Hardware name: TQ-Systems i.MX95 TQMa95xxSA on MB-SMARC-2 (DT)
> Workqueue: async async_run_entry_fn
> pstate: 204000c9 (nzCv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> pc : regmap_mmio_read32le+0x1c/0x3c
> lr : regmap_mmio_read+0x40/0x68
> sp : ffff80008223b860
> x29: ffff80008223b860 x28: ffff00001000c800 x27: ffff8000818679c0
> x26: ffff000013340410 x25: 0000000000000001 x24: 0000000000000000
> x23: ffff000012f5e400 x22: ffff80008223b934 x21: ffff80008223b934
> x20: ffff000012fc4900 x19: 0000000000003010 x18: 00000000a7aa953f
> x17: 3e2d206666666666 x16: 666631393078302e x15: 2e30303030303030
> x14: 3139307830204d45 x13: 3030303030303031 x12: 30307830203e2d20
> x11: 6666666666666631 x10: 393078302e2e3030 x9 : 4d2020202020203a
> x8 : 656963702e303030 x7 : 205d313236353838 x6 : ffff0000134e0000
> x5 : 0000000000000000 x4 : 0000000000000000 x3 : ffff8000809bf028
> x2 : ffff8000809bfb0c x1 : 0000000000003010 x0 : ffff800081dc5010
> 
> Call trace:
>  regmap_mmio_read32le+0x1c/0x3c (P)
>  regmap_mmio_read+0x40/0x68
>  _regmap_bus_reg_read+0x58/0x9c
>  _regmap_read+0x70/0x1c4
>  _regmap_update_bits+0xe4/0x174
>  regmap_update_bits_base+0x60/0x90
>  imx95_pcie_core_reset+0x78/0xd0
>  imx_pcie_assert_core_reset+0x38/0x50
>  imx_pcie_host_init+0x68/0x4a0
>  dw_pcie_host_init+0x16c/0x500
>  imx_pcie_probe+0x2f4/0x71c
>  platform_probe+0x64/0x100
>  really_probe+0xc8/0x3bc
>  __driver_probe_device+0x84/0x16c
>  driver_probe_device+0x40/0x160
>  __device_attach_driver+0xcc/0x1a0
>  bus_for_each_drv+0x88/0xe4
>  __device_attach_async_helper+0xac/0x108
>  async_run_entry_fn+0x30/0x144
>  process_one_work+0x14c/0x3e0
>  worker_thread+0x2f0/0x3fc
>  kthread+0x128/0x1ec
>  ret_from_fork+0x10/0x20
> 
> Code: aa0003f4 2a0103f3 f9400280 8b334000 (b9400000)
> ---[ end trace 0000000000000000 ]---
> note: kworker/u24:4[63] exited with irqs disabled
> Internal error: Oops: 0000000096000007 [#2]  SMP
> Modules linked in:
> note: kworker/u24:4[63] exited with preempt_count 1
> 
> CPU: 4 UID: 0 PID: 52 Comm: kworker/u24:1 Tainted: G      D         T  
> 6.15.0-rc1-next-20250409+ #3009 PREEMPT 
> f6bd3cc6346487744ae55f6115e728ff2bc7088b Tainted: [D]=DIE, [T]=RANDSTRUCT
> Hardware name: TQ-Systems i.MX95 TQMa95xxSA on MB-SMARC-2 (DT)
> Workqueue: async async_run_entry_fn
> pstate: 204000c9 (nzCv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> pc : regmap_mmio_read32le+0x1c/0x3c
> lr : regmap_mmio_read+0x40/0x68
> mmc0: new HS400 Enhanced strobe MMC card at address 0001
> sp : ffff8000821e3860
> mmcblk0: mmc0:0001 DG4016 14.7 GiB
> x29: ffff8000821e3860 x28: ffff00001000c800 x27: ffff8000818679c0
> mmcblk0boot0: mmc0:0001 DG4016 4.00 MiB
> x26: ffff00001333fc10 x25: 0000000000000001 x24: 0000000000000000
> x23: ffff000013895400 x22: ffff8000821e3934 x21: ffff8000821e3934
> x20: ffff0000134672c0
> mmcblk0boot1: mmc0:0001 DG4016 4.00 MiB
> 
>  x19: 0000000000003010 x18: 0000000038868210
> 
> x17: 3038387830207570 x16: 63203d3d20303030 x15: 3030313038387830
> x14: 205d315b67657220
> mmcblk0rpmb: mmc0:0001 DG4016 4.00 MiB, chardev (237:0)
> 
>  x13: 6565727465636976 x12: 6564207369687420
> 
> x11: 726f662064656465 x10: 656e207265766520 x9 : 7420726f66206465
> x8 : 6465656e20726576 x7 : 205d303033353938 x6 : ffff000013371280
> x5 : 0000000000000000 x4 : 0000000000000000 x3 : ffff8000809bf028
> x2 : ffff8000809bfb0c x1 : 0000000000003010 x0 : ffff8000821bd010
> 
> Call trace:
>  regmap_mmio_read32le+0x1c/0x3c (P)
>  regmap_mmio_read+0x40/0x68
>  _regmap_bus_reg_read+0x58/0x9c
>  _regmap_read+0x70/0x1c4
>  _regmap_update_bits+0xe4/0x174
>  regmap_update_bits_base+0x60/0x90
>  imx95_pcie_core_reset+0x78/0xd0
>  imx_pcie_assert_core_reset+0x38/0x50
>  imx_pcie_host_init+0x68/0x4a0
>  dw_pcie_host_init+0x16c/0x500
>  imx_pcie_probe+0x2f4/0x71c
>  platform_probe+0x64/0x100
>  really_probe+0xc8/0x3bc
>  __driver_probe_device+0x84/0x16c
>  driver_probe_device+0x40/0x160
>  __device_attach_driver+0xcc/0x1a0
>  bus_for_each_drv+0x88/0xe4
>  __device_attach_async_helper+0xac/0x108
>  async_run_entry_fn+0x30/0x144
>  process_one_work+0x14c/0x3e0
>  worker_thread+0x2f0/0x3fc
>  kthread+0x128/0x1ec
>  ret_from_fork+0x10/0x20
> 
> Code: aa0003f4 2a0103f3 f9400280 8b334000 (b9400000)
> ---[ end trace 0000000000000000 ]---

Is this series dependent on any other series/patches?

Best regards,
Alexander
Frank Li April 9, 2025, 3:02 p.m. UTC | #2
On Wed, Apr 09, 2025 at 11:51:53AM +0200, Alexander Stein wrote:
> Hi,
>
> Am Dienstag, 8. April 2025, 04:59:26 CEST schrieb Richard Zhu:
> > Add the cold reset toggle for i.MX95 PCIe to align PHY's power up sequency.
> >
> > Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
> > Reviewed-by: Frank Li <Frank.Li@nxp.com>
> > ---
> >  drivers/pci/controller/dwc/pci-imx6.c | 42 +++++++++++++++++++++++++++
> >  1 file changed, 42 insertions(+)
> >
> > diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> > index c5871c3d4194..7c60b712480a 100644
> > --- a/drivers/pci/controller/dwc/pci-imx6.c
> > +++ b/drivers/pci/controller/dwc/pci-imx6.c
> > @@ -71,6 +71,9 @@
> >  #define IMX95_SID_MASK				GENMASK(5, 0)
> >  #define IMX95_MAX_LUT				32
> >
> > +#define IMX95_PCIE_RST_CTRL			0x3010
> > +#define IMX95_PCIE_COLD_RST			BIT(0)
> > +
> >  #define to_imx_pcie(x)	dev_get_drvdata((x)->dev)
> >
> >  enum imx_pcie_variants {
> > @@ -773,6 +776,43 @@ static int imx7d_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert)
> >  	return 0;
> >  }
> >
> > +static int imx95_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert)
> > +{
> > +	u32 val;
> > +
> > +	if (assert) {
> > +		/*
> > +		 * From i.MX95 PCIe PHY perspective, the COLD reset toggle
> > +		 * should be complete after power-up by the following sequence.
> > +		 *                 > 10us(at power-up)
> > +		 *                 > 10ns(warm reset)
> > +		 *               |<------------>|
> > +		 *                ______________
> > +		 * phy_reset ____/              \________________
> > +		 *                                   ____________
> > +		 * ref_clk_en_______________________/
> > +		 * Toggle COLD reset aligned with this sequence for i.MX95 PCIe.
> > +		 */
> > +		regmap_set_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_RST_CTRL,
> > +				IMX95_PCIE_COLD_RST);
> > +		/*
> > +		 * Make sure the write to IMX95_PCIE_RST_CTRL is flushed to the
> > +		 * hardware by doing a read. Otherwise, there is no guarantee
> > +		 * that the write has reached the hardware before udelay().
> > +		 */
> > +		regmap_read_bypassed(imx_pcie->iomuxc_gpr, IMX95_PCIE_RST_CTRL,
> > +				     &val);
> > +		udelay(15);
> > +		regmap_clear_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_RST_CTRL,
> > +				  IMX95_PCIE_COLD_RST);
> > +		regmap_read_bypassed(imx_pcie->iomuxc_gpr, IMX95_PCIE_RST_CTRL,
> > +				     &val);
> > +		udelay(10);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> >  static void imx_pcie_assert_core_reset(struct imx_pcie *imx_pcie)
> >  {
> >  	reset_control_assert(imx_pcie->pciephy_reset);
> > @@ -1739,6 +1779,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
> >  		.ltssm_mask = IMX95_PCIE_LTSSM_EN,
> >  		.mode_off[0]  = IMX95_PE0_GEN_CTRL_1,
> >  		.mode_mask[0] = IMX95_PCIE_DEVICE_TYPE,
> > +		.core_reset = imx95_pcie_core_reset,
> >  		.init_phy = imx95_pcie_init_phy,
> >  	},
> >  	[IMX8MQ_EP] = {
> > @@ -1792,6 +1833,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
> >  		.mode_off[0]  = IMX95_PE0_GEN_CTRL_1,
> >  		.mode_mask[0] = IMX95_PCIE_DEVICE_TYPE,
> >  		.init_phy = imx95_pcie_init_phy,
> > +		.core_reset = imx95_pcie_core_reset,
> >  		.epc_features = &imx95_pcie_epc_features,
> >  		.mode = DW_PCIE_EP_TYPE,
> >  	},
> >
>
> This change introduces an invalid memory access on my platform. There is not
> even a PCIe device attached to it.
>
> > imx6q-pcie 4c380000.pcie: host bridge /soc/pcie@4c380000 ranges:
> > imx6q-pcie 4c300000.pcie: host bridge /soc/pcie@4c300000 ranges:
> > imx6q-pcie 4c380000.pcie:       IO 0x088ff00000..0x088fffffff -> 0x0000000000
> > imx6q-pcie 4c300000.pcie:       IO 0x006ff00000..0x006fffffff -> 0x0000000000
> > imx6q-pcie 4c380000.pcie:      MEM 0x0a10000000..0x0a1fffffff -> 0x0010000000
> > imx6q-pcie 4c300000.pcie:      MEM 0x0910000000..0x091fffffff -> 0x0010000000
> > imx6q-pcie 4c380000.pcie: config reg[1] 0x880100000 == cpu 0x880100000
> > ; no fixup was ever needed for this devicetree
> > imx6q-pcie 4c300000.pcie: config reg[1] 0x60100000 == cpu 0x60100000
> > ; no fixup was ever needed for this devicetree
> > Unable to handle kernel paging request at virtual address ffff800081dc5010
> > Unable to handle kernel paging request at virtual address ffff8000821bd010
> > Mem abort info:
> >
> > Mem abort info:
> >   ESR = 0x0000000096000007
> >   ESR = 0x0000000096000007
> >   EC = 0x25: DABT (current EL), IL = 32 bits
> >   EC = 0x25: DABT (current EL), IL = 32 bits
> >
> > fsl_enetc_mdio 0003:01:00.0: enabling device (0000 -> 0002)
> >
> >   SET = 0, FnV = 0
> >   SET = 0, FnV = 0
> >   EA = 0, S1PTW = 0
> >   EA = 0, S1PTW = 0
> >   FSC = 0x07: level 3 translation fault
> >   FSC = 0x07: level 3 translation fault
> >
> > Data abort info:
> >
> > Data abort info:
> >   ISV = 0, ISS = 0x00000007, ISS2 = 0x00000000
> >   ISV = 0, ISS = 0x00000007, ISS2 = 0x00000000
> >   CM = 0, WnR = 0, TnD = 0, TagAccess = 0
> >   CM = 0, WnR = 0, TnD = 0, TagAccess = 0
> >   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
> >   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
> >
> > swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000000091a47000
> > swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000000091a47000
> > [ffff800081dc5010] pgd=1000000092002003
> > [ffff8000821bd010] pgd=1000000092002003
> > , p4d=1000000092002003
> > , p4d=1000000092002003
> > , pud=1000000092003003
> > , pud=1000000092003003
> > , pmd=1000000092008003
> > , pmd=100000009299f403
> > , pte=0000000000000000
> > , pte=0000000000000000
> >
> >
> > Internal error: Oops: 0000000096000007 [#1]  SMP
> > Modules linked in:
> > CPU: 0 UID: 0 PID: 63 Comm: kworker/u24:4 Tainted: G                T
> > 6.15.0-rc1-next-20250409+ #3009 PREEMPT
> > f6bd3cc6346487744ae55f6115e728ff2bc7088b Tainted: [T]=RANDSTRUCT
> > Hardware name: TQ-Systems i.MX95 TQMa95xxSA on MB-SMARC-2 (DT)
> > Workqueue: async async_run_entry_fn
> > pstate: 204000c9 (nzCv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> > pc : regmap_mmio_read32le+0x1c/0x3c
> > lr : regmap_mmio_read+0x40/0x68
> > sp : ffff80008223b860
> > x29: ffff80008223b860 x28: ffff00001000c800 x27: ffff8000818679c0
> > x26: ffff000013340410 x25: 0000000000000001 x24: 0000000000000000
> > x23: ffff000012f5e400 x22: ffff80008223b934 x21: ffff80008223b934
> > x20: ffff000012fc4900 x19: 0000000000003010 x18: 00000000a7aa953f
> > x17: 3e2d206666666666 x16: 666631393078302e x15: 2e30303030303030
> > x14: 3139307830204d45 x13: 3030303030303031 x12: 30307830203e2d20
> > x11: 6666666666666631 x10: 393078302e2e3030 x9 : 4d2020202020203a
> > x8 : 656963702e303030 x7 : 205d313236353838 x6 : ffff0000134e0000
> > x5 : 0000000000000000 x4 : 0000000000000000 x3 : ffff8000809bf028
> > x2 : ffff8000809bfb0c x1 : 0000000000003010 x0 : ffff800081dc5010
> >
> > Call trace:
> >  regmap_mmio_read32le+0x1c/0x3c (P)
> >  regmap_mmio_read+0x40/0x68
> >  _regmap_bus_reg_read+0x58/0x9c
> >  _regmap_read+0x70/0x1c4
> >  _regmap_update_bits+0xe4/0x174
> >  regmap_update_bits_base+0x60/0x90
> >  imx95_pcie_core_reset+0x78/0xd0
> >  imx_pcie_assert_core_reset+0x38/0x50
> >  imx_pcie_host_init+0x68/0x4a0
> >  dw_pcie_host_init+0x16c/0x500
> >  imx_pcie_probe+0x2f4/0x71c
> >  platform_probe+0x64/0x100
> >  really_probe+0xc8/0x3bc
> >  __driver_probe_device+0x84/0x16c
> >  driver_probe_device+0x40/0x160
> >  __device_attach_driver+0xcc/0x1a0
> >  bus_for_each_drv+0x88/0xe4
> >  __device_attach_async_helper+0xac/0x108
> >  async_run_entry_fn+0x30/0x144
> >  process_one_work+0x14c/0x3e0
> >  worker_thread+0x2f0/0x3fc
> >  kthread+0x128/0x1ec
> >  ret_from_fork+0x10/0x20
> >
> > Code: aa0003f4 2a0103f3 f9400280 8b334000 (b9400000)
> > ---[ end trace 0000000000000000 ]---
> > note: kworker/u24:4[63] exited with irqs disabled
> > Internal error: Oops: 0000000096000007 [#2]  SMP
> > Modules linked in:
> > note: kworker/u24:4[63] exited with preempt_count 1
> >
> > CPU: 4 UID: 0 PID: 52 Comm: kworker/u24:1 Tainted: G      D         T
> > 6.15.0-rc1-next-20250409+ #3009 PREEMPT
> > f6bd3cc6346487744ae55f6115e728ff2bc7088b Tainted: [D]=DIE, [T]=RANDSTRUCT
> > Hardware name: TQ-Systems i.MX95 TQMa95xxSA on MB-SMARC-2 (DT)
> > Workqueue: async async_run_entry_fn
> > pstate: 204000c9 (nzCv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> > pc : regmap_mmio_read32le+0x1c/0x3c
> > lr : regmap_mmio_read+0x40/0x68
> > mmc0: new HS400 Enhanced strobe MMC card at address 0001
> > sp : ffff8000821e3860
> > mmcblk0: mmc0:0001 DG4016 14.7 GiB
> > x29: ffff8000821e3860 x28: ffff00001000c800 x27: ffff8000818679c0
> > mmcblk0boot0: mmc0:0001 DG4016 4.00 MiB
> > x26: ffff00001333fc10 x25: 0000000000000001 x24: 0000000000000000
> > x23: ffff000013895400 x22: ffff8000821e3934 x21: ffff8000821e3934
> > x20: ffff0000134672c0
> > mmcblk0boot1: mmc0:0001 DG4016 4.00 MiB
> >
> >  x19: 0000000000003010 x18: 0000000038868210
> >
> > x17: 3038387830207570 x16: 63203d3d20303030 x15: 3030313038387830
> > x14: 205d315b67657220
> > mmcblk0rpmb: mmc0:0001 DG4016 4.00 MiB, chardev (237:0)
> >
> >  x13: 6565727465636976 x12: 6564207369687420
> >
> > x11: 726f662064656465 x10: 656e207265766520 x9 : 7420726f66206465
> > x8 : 6465656e20726576 x7 : 205d303033353938 x6 : ffff000013371280
> > x5 : 0000000000000000 x4 : 0000000000000000 x3 : ffff8000809bf028
> > x2 : ffff8000809bfb0c x1 : 0000000000003010 x0 : ffff8000821bd010
> >
> > Call trace:
> >  regmap_mmio_read32le+0x1c/0x3c (P)
> >  regmap_mmio_read+0x40/0x68
> >  _regmap_bus_reg_read+0x58/0x9c
> >  _regmap_read+0x70/0x1c4
> >  _regmap_update_bits+0xe4/0x174
> >  regmap_update_bits_base+0x60/0x90
> >  imx95_pcie_core_reset+0x78/0xd0
> >  imx_pcie_assert_core_reset+0x38/0x50
> >  imx_pcie_host_init+0x68/0x4a0
> >  dw_pcie_host_init+0x16c/0x500
> >  imx_pcie_probe+0x2f4/0x71c
> >  platform_probe+0x64/0x100
> >  really_probe+0xc8/0x3bc
> >  __driver_probe_device+0x84/0x16c
> >  driver_probe_device+0x40/0x160
> >  __device_attach_driver+0xcc/0x1a0
> >  bus_for_each_drv+0x88/0xe4
> >  __device_attach_async_helper+0xac/0x108
> >  async_run_entry_fn+0x30/0x144
> >  process_one_work+0x14c/0x3e0
> >  worker_thread+0x2f0/0x3fc
> >  kthread+0x128/0x1ec
> >  ret_from_fork+0x10/0x20
> >
> > Code: aa0003f4 2a0103f3 f9400280 8b334000 (b9400000)
> > ---[ end trace 0000000000000000 ]---
>
> Is this series dependent on any other series/patches?

Please update dts

https://lore.kernel.org/imx/20250314060104.390065-1-hongxing.zhu@nxp.com/
arm64: dts: imx95: Correct the range of PCIe app-reg region

Frank
>
> Best regards,
> Alexander
> --
> TQ-Systems GmbH | Mühlstraße 2, Gut Delling | 82229 Seefeld, Germany
> Amtsgericht München, HRB 105018
> Geschäftsführer: Detlef Schneider, Rüdiger Stahl, Stefan Schneider
> http://www.tq-group.com/
>
>
Alexander Stein April 10, 2025, 1:08 p.m. UTC | #3
Am Mittwoch, 9. April 2025, 17:02:43 CEST schrieb Frank Li:
> ********************
> Achtung externe E-Mail: Öffnen Sie Anhänge und Links nur, wenn Sie wissen, dass diese aus einer sicheren Quelle stammen und sicher sind. Leiten Sie die E-Mail im Zweifelsfall zur Prüfung an den IT-Helpdesk weiter.
> Attention external email: Open attachments and links only if you know that they are from a secure source and are safe. In doubt forward the email to the IT-Helpdesk to check it.
> ********************
> 
> On Wed, Apr 09, 2025 at 11:51:53AM +0200, Alexander Stein wrote:
> > Hi,
> >
> > Am Dienstag, 8. April 2025, 04:59:26 CEST schrieb Richard Zhu:
> > > Add the cold reset toggle for i.MX95 PCIe to align PHY's power up sequency.
> > >
> > > Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
> > > Reviewed-by: Frank Li <Frank.Li@nxp.com>
> > > ---
> > >  drivers/pci/controller/dwc/pci-imx6.c | 42 +++++++++++++++++++++++++++
> > >  1 file changed, 42 insertions(+)
> > >
> > > diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> > > index c5871c3d4194..7c60b712480a 100644
> > > --- a/drivers/pci/controller/dwc/pci-imx6.c
> > > +++ b/drivers/pci/controller/dwc/pci-imx6.c
> > > @@ -71,6 +71,9 @@
> > >  #define IMX95_SID_MASK				GENMASK(5, 0)
> > >  #define IMX95_MAX_LUT				32
> > >
> > > +#define IMX95_PCIE_RST_CTRL			0x3010
> > > +#define IMX95_PCIE_COLD_RST			BIT(0)
> > > +
> > >  #define to_imx_pcie(x)	dev_get_drvdata((x)->dev)
> > >
> > >  enum imx_pcie_variants {
> > > @@ -773,6 +776,43 @@ static int imx7d_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert)
> > >  	return 0;
> > >  }
> > >
> > > +static int imx95_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert)
> > > +{
> > > +	u32 val;
> > > +
> > > +	if (assert) {
> > > +		/*
> > > +		 * From i.MX95 PCIe PHY perspective, the COLD reset toggle
> > > +		 * should be complete after power-up by the following sequence.
> > > +		 *                 > 10us(at power-up)
> > > +		 *                 > 10ns(warm reset)
> > > +		 *               |<------------>|
> > > +		 *                ______________
> > > +		 * phy_reset ____/              \________________
> > > +		 *                                   ____________
> > > +		 * ref_clk_en_______________________/
> > > +		 * Toggle COLD reset aligned with this sequence for i.MX95 PCIe.
> > > +		 */
> > > +		regmap_set_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_RST_CTRL,
> > > +				IMX95_PCIE_COLD_RST);
> > > +		/*
> > > +		 * Make sure the write to IMX95_PCIE_RST_CTRL is flushed to the
> > > +		 * hardware by doing a read. Otherwise, there is no guarantee
> > > +		 * that the write has reached the hardware before udelay().
> > > +		 */
> > > +		regmap_read_bypassed(imx_pcie->iomuxc_gpr, IMX95_PCIE_RST_CTRL,
> > > +				     &val);
> > > +		udelay(15);
> > > +		regmap_clear_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_RST_CTRL,
> > > +				  IMX95_PCIE_COLD_RST);
> > > +		regmap_read_bypassed(imx_pcie->iomuxc_gpr, IMX95_PCIE_RST_CTRL,
> > > +				     &val);
> > > +		udelay(10);
> > > +	}
> > > +
> > > +	return 0;
> > > +}
> > > +
> > >  static void imx_pcie_assert_core_reset(struct imx_pcie *imx_pcie)
> > >  {
> > >  	reset_control_assert(imx_pcie->pciephy_reset);
> > > @@ -1739,6 +1779,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
> > >  		.ltssm_mask = IMX95_PCIE_LTSSM_EN,
> > >  		.mode_off[0]  = IMX95_PE0_GEN_CTRL_1,
> > >  		.mode_mask[0] = IMX95_PCIE_DEVICE_TYPE,
> > > +		.core_reset = imx95_pcie_core_reset,
> > >  		.init_phy = imx95_pcie_init_phy,
> > >  	},
> > >  	[IMX8MQ_EP] = {
> > > @@ -1792,6 +1833,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
> > >  		.mode_off[0]  = IMX95_PE0_GEN_CTRL_1,
> > >  		.mode_mask[0] = IMX95_PCIE_DEVICE_TYPE,
> > >  		.init_phy = imx95_pcie_init_phy,
> > > +		.core_reset = imx95_pcie_core_reset,
> > >  		.epc_features = &imx95_pcie_epc_features,
> > >  		.mode = DW_PCIE_EP_TYPE,
> > >  	},
> > >
> >
> > This change introduces an invalid memory access on my platform. There is not
> > even a PCIe device attached to it.
> >
> > > imx6q-pcie 4c380000.pcie: host bridge /soc/pcie@4c380000 ranges:
> > > imx6q-pcie 4c300000.pcie: host bridge /soc/pcie@4c300000 ranges:
> > > imx6q-pcie 4c380000.pcie:       IO 0x088ff00000..0x088fffffff -> 0x0000000000
> > > imx6q-pcie 4c300000.pcie:       IO 0x006ff00000..0x006fffffff -> 0x0000000000
> > > imx6q-pcie 4c380000.pcie:      MEM 0x0a10000000..0x0a1fffffff -> 0x0010000000
> > > imx6q-pcie 4c300000.pcie:      MEM 0x0910000000..0x091fffffff -> 0x0010000000
> > > imx6q-pcie 4c380000.pcie: config reg[1] 0x880100000 == cpu 0x880100000
> > > ; no fixup was ever needed for this devicetree
> > > imx6q-pcie 4c300000.pcie: config reg[1] 0x60100000 == cpu 0x60100000
> > > ; no fixup was ever needed for this devicetree
> > > Unable to handle kernel paging request at virtual address ffff800081dc5010
> > > Unable to handle kernel paging request at virtual address ffff8000821bd010
> > > Mem abort info:
> > >
> > > Mem abort info:
> > >   ESR = 0x0000000096000007
> > >   ESR = 0x0000000096000007
> > >   EC = 0x25: DABT (current EL), IL = 32 bits
> > >   EC = 0x25: DABT (current EL), IL = 32 bits
> > >
> > > fsl_enetc_mdio 0003:01:00.0: enabling device (0000 -> 0002)
> > >
> > >   SET = 0, FnV = 0
> > >   SET = 0, FnV = 0
> > >   EA = 0, S1PTW = 0
> > >   EA = 0, S1PTW = 0
> > >   FSC = 0x07: level 3 translation fault
> > >   FSC = 0x07: level 3 translation fault
> > >
> > > Data abort info:
> > >
> > > Data abort info:
> > >   ISV = 0, ISS = 0x00000007, ISS2 = 0x00000000
> > >   ISV = 0, ISS = 0x00000007, ISS2 = 0x00000000
> > >   CM = 0, WnR = 0, TnD = 0, TagAccess = 0
> > >   CM = 0, WnR = 0, TnD = 0, TagAccess = 0
> > >   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
> > >   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0
> > >
> > > swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000000091a47000
> > > swapper pgtable: 4k pages, 48-bit VAs, pgdp=0000000091a47000
> > > [ffff800081dc5010] pgd=1000000092002003
> > > [ffff8000821bd010] pgd=1000000092002003
> > > , p4d=1000000092002003
> > > , p4d=1000000092002003
> > > , pud=1000000092003003
> > > , pud=1000000092003003
> > > , pmd=1000000092008003
> > > , pmd=100000009299f403
> > > , pte=0000000000000000
> > > , pte=0000000000000000
> > >
> > >
> > > Internal error: Oops: 0000000096000007 [#1]  SMP
> > > Modules linked in:
> > > CPU: 0 UID: 0 PID: 63 Comm: kworker/u24:4 Tainted: G                T
> > > 6.15.0-rc1-next-20250409+ #3009 PREEMPT
> > > f6bd3cc6346487744ae55f6115e728ff2bc7088b Tainted: [T]=RANDSTRUCT
> > > Hardware name: TQ-Systems i.MX95 TQMa95xxSA on MB-SMARC-2 (DT)
> > > Workqueue: async async_run_entry_fn
> > > pstate: 204000c9 (nzCv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> > > pc : regmap_mmio_read32le+0x1c/0x3c
> > > lr : regmap_mmio_read+0x40/0x68
> > > sp : ffff80008223b860
> > > x29: ffff80008223b860 x28: ffff00001000c800 x27: ffff8000818679c0
> > > x26: ffff000013340410 x25: 0000000000000001 x24: 0000000000000000
> > > x23: ffff000012f5e400 x22: ffff80008223b934 x21: ffff80008223b934
> > > x20: ffff000012fc4900 x19: 0000000000003010 x18: 00000000a7aa953f
> > > x17: 3e2d206666666666 x16: 666631393078302e x15: 2e30303030303030
> > > x14: 3139307830204d45 x13: 3030303030303031 x12: 30307830203e2d20
> > > x11: 6666666666666631 x10: 393078302e2e3030 x9 : 4d2020202020203a
> > > x8 : 656963702e303030 x7 : 205d313236353838 x6 : ffff0000134e0000
> > > x5 : 0000000000000000 x4 : 0000000000000000 x3 : ffff8000809bf028
> > > x2 : ffff8000809bfb0c x1 : 0000000000003010 x0 : ffff800081dc5010
> > >
> > > Call trace:
> > >  regmap_mmio_read32le+0x1c/0x3c (P)
> > >  regmap_mmio_read+0x40/0x68
> > >  _regmap_bus_reg_read+0x58/0x9c
> > >  _regmap_read+0x70/0x1c4
> > >  _regmap_update_bits+0xe4/0x174
> > >  regmap_update_bits_base+0x60/0x90
> > >  imx95_pcie_core_reset+0x78/0xd0
> > >  imx_pcie_assert_core_reset+0x38/0x50
> > >  imx_pcie_host_init+0x68/0x4a0
> > >  dw_pcie_host_init+0x16c/0x500
> > >  imx_pcie_probe+0x2f4/0x71c
> > >  platform_probe+0x64/0x100
> > >  really_probe+0xc8/0x3bc
> > >  __driver_probe_device+0x84/0x16c
> > >  driver_probe_device+0x40/0x160
> > >  __device_attach_driver+0xcc/0x1a0
> > >  bus_for_each_drv+0x88/0xe4
> > >  __device_attach_async_helper+0xac/0x108
> > >  async_run_entry_fn+0x30/0x144
> > >  process_one_work+0x14c/0x3e0
> > >  worker_thread+0x2f0/0x3fc
> > >  kthread+0x128/0x1ec
> > >  ret_from_fork+0x10/0x20
> > >
> > > Code: aa0003f4 2a0103f3 f9400280 8b334000 (b9400000)
> > > ---[ end trace 0000000000000000 ]---
> > > note: kworker/u24:4[63] exited with irqs disabled
> > > Internal error: Oops: 0000000096000007 [#2]  SMP
> > > Modules linked in:
> > > note: kworker/u24:4[63] exited with preempt_count 1
> > >
> > > CPU: 4 UID: 0 PID: 52 Comm: kworker/u24:1 Tainted: G      D         T
> > > 6.15.0-rc1-next-20250409+ #3009 PREEMPT
> > > f6bd3cc6346487744ae55f6115e728ff2bc7088b Tainted: [D]=DIE, [T]=RANDSTRUCT
> > > Hardware name: TQ-Systems i.MX95 TQMa95xxSA on MB-SMARC-2 (DT)
> > > Workqueue: async async_run_entry_fn
> > > pstate: 204000c9 (nzCv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
> > > pc : regmap_mmio_read32le+0x1c/0x3c
> > > lr : regmap_mmio_read+0x40/0x68
> > > mmc0: new HS400 Enhanced strobe MMC card at address 0001
> > > sp : ffff8000821e3860
> > > mmcblk0: mmc0:0001 DG4016 14.7 GiB
> > > x29: ffff8000821e3860 x28: ffff00001000c800 x27: ffff8000818679c0
> > > mmcblk0boot0: mmc0:0001 DG4016 4.00 MiB
> > > x26: ffff00001333fc10 x25: 0000000000000001 x24: 0000000000000000
> > > x23: ffff000013895400 x22: ffff8000821e3934 x21: ffff8000821e3934
> > > x20: ffff0000134672c0
> > > mmcblk0boot1: mmc0:0001 DG4016 4.00 MiB
> > >
> > >  x19: 0000000000003010 x18: 0000000038868210
> > >
> > > x17: 3038387830207570 x16: 63203d3d20303030 x15: 3030313038387830
> > > x14: 205d315b67657220
> > > mmcblk0rpmb: mmc0:0001 DG4016 4.00 MiB, chardev (237:0)
> > >
> > >  x13: 6565727465636976 x12: 6564207369687420
> > >
> > > x11: 726f662064656465 x10: 656e207265766520 x9 : 7420726f66206465
> > > x8 : 6465656e20726576 x7 : 205d303033353938 x6 : ffff000013371280
> > > x5 : 0000000000000000 x4 : 0000000000000000 x3 : ffff8000809bf028
> > > x2 : ffff8000809bfb0c x1 : 0000000000003010 x0 : ffff8000821bd010
> > >
> > > Call trace:
> > >  regmap_mmio_read32le+0x1c/0x3c (P)
> > >  regmap_mmio_read+0x40/0x68
> > >  _regmap_bus_reg_read+0x58/0x9c
> > >  _regmap_read+0x70/0x1c4
> > >  _regmap_update_bits+0xe4/0x174
> > >  regmap_update_bits_base+0x60/0x90
> > >  imx95_pcie_core_reset+0x78/0xd0
> > >  imx_pcie_assert_core_reset+0x38/0x50
> > >  imx_pcie_host_init+0x68/0x4a0
> > >  dw_pcie_host_init+0x16c/0x500
> > >  imx_pcie_probe+0x2f4/0x71c
> > >  platform_probe+0x64/0x100
> > >  really_probe+0xc8/0x3bc
> > >  __driver_probe_device+0x84/0x16c
> > >  driver_probe_device+0x40/0x160
> > >  __device_attach_driver+0xcc/0x1a0
> > >  bus_for_each_drv+0x88/0xe4
> > >  __device_attach_async_helper+0xac/0x108
> > >  async_run_entry_fn+0x30/0x144
> > >  process_one_work+0x14c/0x3e0
> > >  worker_thread+0x2f0/0x3fc
> > >  kthread+0x128/0x1ec
> > >  ret_from_fork+0x10/0x20
> > >
> > > Code: aa0003f4 2a0103f3 f9400280 8b334000 (b9400000)
> > > ---[ end trace 0000000000000000 ]---
> >
> > Is this series dependent on any other series/patches?
> 
> Please update dts
> 
> https://lore.kernel.org/imx/20250314060104.390065-1-hongxing.zhu@nxp.com/
> arm64: dts: imx95: Correct the range of PCIe app-reg region

This should have been mentioned in the cover letter that there are some
dependencies.
Anyway, the series looks okay. Even though I have no documentation
regarding the erratas.

Best regards,
Alexander
Manivannan Sadhasivam April 13, 2025, 3:18 p.m. UTC | #4
On Tue, Apr 08, 2025 at 10:59:26AM +0800, Richard Zhu wrote:
> Add the cold reset toggle for i.MX95 PCIe to align PHY's power up sequency.

Please avoid spelling mistakes in the commit messages.

> 
> Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>

- Mani

> Reviewed-by: Frank Li <Frank.Li@nxp.com>
> ---
>  drivers/pci/controller/dwc/pci-imx6.c | 42 +++++++++++++++++++++++++++
>  1 file changed, 42 insertions(+)
> 
> diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
> index c5871c3d4194..7c60b712480a 100644
> --- a/drivers/pci/controller/dwc/pci-imx6.c
> +++ b/drivers/pci/controller/dwc/pci-imx6.c
> @@ -71,6 +71,9 @@
>  #define IMX95_SID_MASK				GENMASK(5, 0)
>  #define IMX95_MAX_LUT				32
>  
> +#define IMX95_PCIE_RST_CTRL			0x3010
> +#define IMX95_PCIE_COLD_RST			BIT(0)
> +
>  #define to_imx_pcie(x)	dev_get_drvdata((x)->dev)
>  
>  enum imx_pcie_variants {
> @@ -773,6 +776,43 @@ static int imx7d_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert)
>  	return 0;
>  }
>  
> +static int imx95_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert)
> +{
> +	u32 val;
> +
> +	if (assert) {
> +		/*
> +		 * From i.MX95 PCIe PHY perspective, the COLD reset toggle
> +		 * should be complete after power-up by the following sequence.
> +		 *                 > 10us(at power-up)
> +		 *                 > 10ns(warm reset)
> +		 *               |<------------>|
> +		 *                ______________
> +		 * phy_reset ____/              \________________
> +		 *                                   ____________
> +		 * ref_clk_en_______________________/
> +		 * Toggle COLD reset aligned with this sequence for i.MX95 PCIe.
> +		 */
> +		regmap_set_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_RST_CTRL,
> +				IMX95_PCIE_COLD_RST);
> +		/*
> +		 * Make sure the write to IMX95_PCIE_RST_CTRL is flushed to the
> +		 * hardware by doing a read. Otherwise, there is no guarantee
> +		 * that the write has reached the hardware before udelay().
> +		 */
> +		regmap_read_bypassed(imx_pcie->iomuxc_gpr, IMX95_PCIE_RST_CTRL,
> +				     &val);
> +		udelay(15);
> +		regmap_clear_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_RST_CTRL,
> +				  IMX95_PCIE_COLD_RST);
> +		regmap_read_bypassed(imx_pcie->iomuxc_gpr, IMX95_PCIE_RST_CTRL,
> +				     &val);
> +		udelay(10);
> +	}
> +
> +	return 0;
> +}
> +
>  static void imx_pcie_assert_core_reset(struct imx_pcie *imx_pcie)
>  {
>  	reset_control_assert(imx_pcie->pciephy_reset);
> @@ -1739,6 +1779,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
>  		.ltssm_mask = IMX95_PCIE_LTSSM_EN,
>  		.mode_off[0]  = IMX95_PE0_GEN_CTRL_1,
>  		.mode_mask[0] = IMX95_PCIE_DEVICE_TYPE,
> +		.core_reset = imx95_pcie_core_reset,
>  		.init_phy = imx95_pcie_init_phy,
>  	},
>  	[IMX8MQ_EP] = {
> @@ -1792,6 +1833,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
>  		.mode_off[0]  = IMX95_PE0_GEN_CTRL_1,
>  		.mode_mask[0] = IMX95_PCIE_DEVICE_TYPE,
>  		.init_phy = imx95_pcie_init_phy,
> +		.core_reset = imx95_pcie_core_reset,
>  		.epc_features = &imx95_pcie_epc_features,
>  		.mode = DW_PCIE_EP_TYPE,
>  	},
> -- 
> 2.37.1
>
Hongxing Zhu April 14, 2025, 3:18 a.m. UTC | #5
> -----Original Message-----
> From: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
> Sent: 2025年4月13日 23:18
> To: Hongxing Zhu <hongxing.zhu@nxp.com>
> Cc: Frank Li <frank.li@nxp.com>; l.stach@pengutronix.de;
> lpieralisi@kernel.org; kw@linux.com; robh@kernel.org;
> bhelgaas@google.com; shawnguo@kernel.org; s.hauer@pengutronix.de;
> kernel@pengutronix.de; festevam@gmail.com; linux-pci@vger.kernel.org;
> linux-arm-kernel@lists.infradead.org; imx@lists.linux.dev;
> linux-kernel@vger.kernel.org
> Subject: Re: [PATCH v5 3/7] PCI: imx6: Toggle the cold reset for i.MX95 PCIe
> 
> On Tue, Apr 08, 2025 at 10:59:26AM +0800, Richard Zhu wrote:
> > Add the cold reset toggle for i.MX95 PCIe to align PHY's power up sequency.
> 
> Please avoid spelling mistakes in the commit messages.
> 
Okay, would be replaced by the following one.
Add a cold reset toggle for the i.MX95 PCIe to align the PHY's power-up
 sequence.

> >
> > Signed-off-by: Richard Zhu <hongxing.zhu@nxp.com>
> 
> Reviewed-by: Manivannan Sadhasivam
> <manivannan.sadhasivam@linaro.org>
> 
Thanks.
Best Regards
Richard

> - Mani
> 
> > Reviewed-by: Frank Li <Frank.Li@nxp.com>
> > ---
> >  drivers/pci/controller/dwc/pci-imx6.c | 42
> > +++++++++++++++++++++++++++
> >  1 file changed, 42 insertions(+)
> >
> > diff --git a/drivers/pci/controller/dwc/pci-imx6.c
> > b/drivers/pci/controller/dwc/pci-imx6.c
> > index c5871c3d4194..7c60b712480a 100644
> > --- a/drivers/pci/controller/dwc/pci-imx6.c
> > +++ b/drivers/pci/controller/dwc/pci-imx6.c
> > @@ -71,6 +71,9 @@
> >  #define IMX95_SID_MASK				GENMASK(5, 0)
> >  #define IMX95_MAX_LUT				32
> >
> > +#define IMX95_PCIE_RST_CTRL			0x3010
> > +#define IMX95_PCIE_COLD_RST			BIT(0)
> > +
> >  #define to_imx_pcie(x)	dev_get_drvdata((x)->dev)
> >
> >  enum imx_pcie_variants {
> > @@ -773,6 +776,43 @@ static int imx7d_pcie_core_reset(struct imx_pcie
> *imx_pcie, bool assert)
> >  	return 0;
> >  }
> >
> > +static int imx95_pcie_core_reset(struct imx_pcie *imx_pcie, bool
> > +assert) {
> > +	u32 val;
> > +
> > +	if (assert) {
> > +		/*
> > +		 * From i.MX95 PCIe PHY perspective, the COLD reset toggle
> > +		 * should be complete after power-up by the following sequence.
> > +		 *                 > 10us(at power-up)
> > +		 *                 > 10ns(warm reset)
> > +		 *               |<------------>|
> > +		 *                ______________
> > +		 * phy_reset ____/              \________________
> > +		 *                                   ____________
> > +		 * ref_clk_en_______________________/
> > +		 * Toggle COLD reset aligned with this sequence for i.MX95 PCIe.
> > +		 */
> > +		regmap_set_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_RST_CTRL,
> > +				IMX95_PCIE_COLD_RST);
> > +		/*
> > +		 * Make sure the write to IMX95_PCIE_RST_CTRL is flushed to the
> > +		 * hardware by doing a read. Otherwise, there is no guarantee
> > +		 * that the write has reached the hardware before udelay().
> > +		 */
> > +		regmap_read_bypassed(imx_pcie->iomuxc_gpr,
> IMX95_PCIE_RST_CTRL,
> > +				     &val);
> > +		udelay(15);
> > +		regmap_clear_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_RST_CTRL,
> > +				  IMX95_PCIE_COLD_RST);
> > +		regmap_read_bypassed(imx_pcie->iomuxc_gpr,
> IMX95_PCIE_RST_CTRL,
> > +				     &val);
> > +		udelay(10);
> > +	}
> > +
> > +	return 0;
> > +}
> > +
> >  static void imx_pcie_assert_core_reset(struct imx_pcie *imx_pcie)  {
> >  	reset_control_assert(imx_pcie->pciephy_reset);
> > @@ -1739,6 +1779,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
> >  		.ltssm_mask = IMX95_PCIE_LTSSM_EN,
> >  		.mode_off[0]  = IMX95_PE0_GEN_CTRL_1,
> >  		.mode_mask[0] = IMX95_PCIE_DEVICE_TYPE,
> > +		.core_reset = imx95_pcie_core_reset,
> >  		.init_phy = imx95_pcie_init_phy,
> >  	},
> >  	[IMX8MQ_EP] = {
> > @@ -1792,6 +1833,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
> >  		.mode_off[0]  = IMX95_PE0_GEN_CTRL_1,
> >  		.mode_mask[0] = IMX95_PCIE_DEVICE_TYPE,
> >  		.init_phy = imx95_pcie_init_phy,
> > +		.core_reset = imx95_pcie_core_reset,
> >  		.epc_features = &imx95_pcie_epc_features,
> >  		.mode = DW_PCIE_EP_TYPE,
> >  	},
> > --
> > 2.37.1
> >
> 
> --
> மணிவண்ணன் சதாசிவம்
diff mbox series

Patch

diff --git a/drivers/pci/controller/dwc/pci-imx6.c b/drivers/pci/controller/dwc/pci-imx6.c
index c5871c3d4194..7c60b712480a 100644
--- a/drivers/pci/controller/dwc/pci-imx6.c
+++ b/drivers/pci/controller/dwc/pci-imx6.c
@@ -71,6 +71,9 @@ 
 #define IMX95_SID_MASK				GENMASK(5, 0)
 #define IMX95_MAX_LUT				32
 
+#define IMX95_PCIE_RST_CTRL			0x3010
+#define IMX95_PCIE_COLD_RST			BIT(0)
+
 #define to_imx_pcie(x)	dev_get_drvdata((x)->dev)
 
 enum imx_pcie_variants {
@@ -773,6 +776,43 @@  static int imx7d_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert)
 	return 0;
 }
 
+static int imx95_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert)
+{
+	u32 val;
+
+	if (assert) {
+		/*
+		 * From i.MX95 PCIe PHY perspective, the COLD reset toggle
+		 * should be complete after power-up by the following sequence.
+		 *                 > 10us(at power-up)
+		 *                 > 10ns(warm reset)
+		 *               |<------------>|
+		 *                ______________
+		 * phy_reset ____/              \________________
+		 *                                   ____________
+		 * ref_clk_en_______________________/
+		 * Toggle COLD reset aligned with this sequence for i.MX95 PCIe.
+		 */
+		regmap_set_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_RST_CTRL,
+				IMX95_PCIE_COLD_RST);
+		/*
+		 * Make sure the write to IMX95_PCIE_RST_CTRL is flushed to the
+		 * hardware by doing a read. Otherwise, there is no guarantee
+		 * that the write has reached the hardware before udelay().
+		 */
+		regmap_read_bypassed(imx_pcie->iomuxc_gpr, IMX95_PCIE_RST_CTRL,
+				     &val);
+		udelay(15);
+		regmap_clear_bits(imx_pcie->iomuxc_gpr, IMX95_PCIE_RST_CTRL,
+				  IMX95_PCIE_COLD_RST);
+		regmap_read_bypassed(imx_pcie->iomuxc_gpr, IMX95_PCIE_RST_CTRL,
+				     &val);
+		udelay(10);
+	}
+
+	return 0;
+}
+
 static void imx_pcie_assert_core_reset(struct imx_pcie *imx_pcie)
 {
 	reset_control_assert(imx_pcie->pciephy_reset);
@@ -1739,6 +1779,7 @@  static const struct imx_pcie_drvdata drvdata[] = {
 		.ltssm_mask = IMX95_PCIE_LTSSM_EN,
 		.mode_off[0]  = IMX95_PE0_GEN_CTRL_1,
 		.mode_mask[0] = IMX95_PCIE_DEVICE_TYPE,
+		.core_reset = imx95_pcie_core_reset,
 		.init_phy = imx95_pcie_init_phy,
 	},
 	[IMX8MQ_EP] = {
@@ -1792,6 +1833,7 @@  static const struct imx_pcie_drvdata drvdata[] = {
 		.mode_off[0]  = IMX95_PE0_GEN_CTRL_1,
 		.mode_mask[0] = IMX95_PCIE_DEVICE_TYPE,
 		.init_phy = imx95_pcie_init_phy,
+		.core_reset = imx95_pcie_core_reset,
 		.epc_features = &imx95_pcie_epc_features,
 		.mode = DW_PCIE_EP_TYPE,
 	},