diff mbox series

[U-Boot,5/5] arm: socfpga: implement proper peripheral reset

Message ID 20190125203051.10943-6-simon.k.r.goldschmidt@gmail.com
State Superseded
Delegated to: Marek Vasut
Headers show
Series arm: socfpga: implement proper peripheral reset handling | expand

Commit Message

Simon Goldschmidt Jan. 25, 2019, 8:30 p.m. UTC
This commit removes ad-hoc reset handling for peripheral resets from SPL
for socfpga gen5.

This is done because as U-Boot drivers support reset handling by now.

For kernels that don't support taking peripherals out of reset that are
not enabled by U-Boot, a new Kconfig option "OLD_SOCFPGA_KERNEL_COMPAT"
is added, which keeps the old behaviour of just enabling all peripherals.

This new option is enabled by default for now, as even Linux 4.20 does
not support reset handling on all peripherals.

Signed-off-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
---

 arch/arm/mach-socfpga/Kconfig     | 10 ++++++++++
 arch/arm/mach-socfpga/misc_gen5.c |  2 ++
 arch/arm/mach-socfpga/spl_gen5.c  | 10 ++++++++++
 3 files changed, 22 insertions(+)

Comments

Marek Vasut Jan. 26, 2019, 9 a.m. UTC | #1
On 1/25/19 9:30 PM, Simon Goldschmidt wrote:
> This commit removes ad-hoc reset handling for peripheral resets from SPL
> for socfpga gen5.
> 
> This is done because as U-Boot drivers support reset handling by now.
> 
> For kernels that don't support taking peripherals out of reset that are
> not enabled by U-Boot, a new Kconfig option "OLD_SOCFPGA_KERNEL_COMPAT"
> is added, which keeps the old behaviour of just enabling all peripherals.
> 
> This new option is enabled by default for now, as even Linux 4.20 does
> not support reset handling on all peripherals.
> 
> Signed-off-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>

Well ew, don't we have some pre-linux-boot hook which could just flip
the reset register bits in one place ? And also, I'd prefer this to be
runtime-configurable, not compile-time configurable.

> ---
> 
>  arch/arm/mach-socfpga/Kconfig     | 10 ++++++++++
>  arch/arm/mach-socfpga/misc_gen5.c |  2 ++
>  arch/arm/mach-socfpga/spl_gen5.c  | 10 ++++++++++
>  3 files changed, 22 insertions(+)
> 
> diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig
> index 5e87371f8c..89acced8d8 100644
> --- a/arch/arm/mach-socfpga/Kconfig
> +++ b/arch/arm/mach-socfpga/Kconfig
> @@ -142,4 +142,14 @@ config SYS_CONFIG_NAME
>  	default "socfpga_stratix10_socdk" if TARGET_SOCFPGA_STRATIX10_SOCDK
>  	default "socfpga_vining_fpga" if TARGET_SOCFPGA_SAMTEC_VINING_FPGA
>  
> +config OLD_SOCFPGA_KERNEL_COMPAT
> +	bool "Enable workarounds for booting old kernels"
> +	depends on TARGET_SOCFPGA_GEN5
> +	default y
> +	help
> +	  Set this to enable various workarounds for old kernels (e.g. take all
> +	  peripherals out of reset because old kernels cannot handle reset).
> +	  This results in sub-optimal settings for newer kernels, only enable
> +	  if needed.
> +
>  endif
> diff --git a/arch/arm/mach-socfpga/misc_gen5.c b/arch/arm/mach-socfpga/misc_gen5.c
> index 04f237d100..168669923e 100644
> --- a/arch/arm/mach-socfpga/misc_gen5.c
> +++ b/arch/arm/mach-socfpga/misc_gen5.c
> @@ -243,6 +243,7 @@ int arch_early_init_r(void)
>  	/* Add device descriptor to FPGA device table */
>  	socfpga_fpga_add(&altera_fpga[0]);
>  
> +#ifdef CONFIG_OLD_SOCFPGA_KERNEL_COMPAT
>  #ifdef CONFIG_DESIGNWARE_SPI
>  	/* Get Designware SPI controller out of reset */
>  	socfpga_per_reset(SOCFPGA_RESET(SPIM0), 0);
> @@ -252,6 +253,7 @@ int arch_early_init_r(void)
>  #ifdef CONFIG_NAND_DENALI
>  	socfpga_per_reset(SOCFPGA_RESET(NAND), 0);
>  #endif
> +#endif /* CONFIG_OLD_SOCFPGA_KERNEL_COMPAT */
>  
>  	return 0;
>  }
> diff --git a/arch/arm/mach-socfpga/spl_gen5.c b/arch/arm/mach-socfpga/spl_gen5.c
> index f9bea892b1..19a211256d 100644
> --- a/arch/arm/mach-socfpga/spl_gen5.c
> +++ b/arch/arm/mach-socfpga/spl_gen5.c
> @@ -35,16 +35,22 @@ u32 spl_boot_device(void)
>  		return BOOT_DEVICE_RAM;
>  	case 0x2:	/* NAND Flash (1.8V) */
>  	case 0x3:	/* NAND Flash (3.0V) */
> +#ifdef CONFIG_OLD_SOCFPGA_KERNEL_COMPAT
>  		socfpga_per_reset(SOCFPGA_RESET(NAND), 0);
> +#endif
>  		return BOOT_DEVICE_NAND;
>  	case 0x4:	/* SD/MMC External Transceiver (1.8V) */
>  	case 0x5:	/* SD/MMC Internal Transceiver (3.0V) */
> +#ifdef CONFIG_OLD_SOCFPGA_KERNEL_COMPAT
>  		socfpga_per_reset(SOCFPGA_RESET(SDMMC), 0);
>  		socfpga_per_reset(SOCFPGA_RESET(DMA), 0);
> +#endif
>  		return BOOT_DEVICE_MMC1;
>  	case 0x6:	/* QSPI Flash (1.8V) */
>  	case 0x7:	/* QSPI Flash (3.0V) */
> +#ifdef CONFIG_OLD_SOCFPGA_KERNEL_COMPAT
>  		socfpga_per_reset(SOCFPGA_RESET(QSPI), 0);
> +#endif
>  		return BOOT_DEVICE_SPI;
>  	default:
>  		printf("Invalid boot device (bsel=%08x)!\n", bsel);
> @@ -98,7 +104,9 @@ void board_init_f(ulong dummy)
>  		socfpga_bridges_reset(1);
>  	}
>  
> +#ifdef CONFIG_OLD_SOCFPGA_KERNEL_COMPAT
>  	socfpga_per_reset(SOCFPGA_RESET(UART0), 0);
> +#endif
>  	socfpga_per_reset(SOCFPGA_RESET(OSC1TIMER0), 0);
>  
>  	timer_init();
> @@ -122,9 +130,11 @@ void board_init_f(ulong dummy)
>  	sysmgr_pinmux_init();
>  	sysmgr_config_warmrstcfgio(0);
>  
> +#ifdef CONFIG_OLD_SOCFPGA_KERNEL_COMPAT
>  	/* De-assert reset for peripherals and bridges based on handoff */
>  	reset_deassert_peripherals_handoff();
>  	socfpga_bridges_reset(0);
> +#endif
>  
>  	debug("Unfreezing/Thaw all I/O banks\n");
>  	/* unfreeze / thaw all IO banks */
>
Simon Goldschmidt Jan. 27, 2019, 8:56 a.m. UTC | #2
Am 26.01.2019 um 10:00 schrieb Marek Vasut:
> On 1/25/19 9:30 PM, Simon Goldschmidt wrote:
>> This commit removes ad-hoc reset handling for peripheral resets from SPL
>> for socfpga gen5.
>>
>> This is done because as U-Boot drivers support reset handling by now.
>>
>> For kernels that don't support taking peripherals out of reset that are
>> not enabled by U-Boot, a new Kconfig option "OLD_SOCFPGA_KERNEL_COMPAT"
>> is added, which keeps the old behaviour of just enabling all peripherals.
>>
>> This new option is enabled by default for now, as even Linux 4.20 does
>> not support reset handling on all peripherals.
>>
>> Signed-off-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
> 
> Well ew, don't we have some pre-linux-boot hook which could just flip
> the reset register bits in one place ? And also, I'd prefer this to be
> runtime-configurable, not compile-time configurable.


And this will be the biggest change for v2. It's also why I needed so 
long to send this series. What I sent in this version is how Tom said 
the same thing is being handled for mach-sunxi (Kconfig 
"OLD_SUNXI_KERNEL_COMPAT").

So if I remember your last mails about this topic, you'd prefer an 
environment variable with a callback that leads to enabling all 
peripherals just before jumping to Linux (yes, I'll find a hook for that).

I see two problems here:
- enabling all peripherals will need to be the default for some time, 
until Linux supports reset handling in all drivers. How do you want to 
deal with that?
- is this scheme used somewhere else for compatibility? I think it would 
make sense for multiple architectures to use the same way to handle such 
compatibility issues...

Regards,
Simon

> 
>> ---
>>
>>   arch/arm/mach-socfpga/Kconfig     | 10 ++++++++++
>>   arch/arm/mach-socfpga/misc_gen5.c |  2 ++
>>   arch/arm/mach-socfpga/spl_gen5.c  | 10 ++++++++++
>>   3 files changed, 22 insertions(+)
>>
>> diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig
>> index 5e87371f8c..89acced8d8 100644
>> --- a/arch/arm/mach-socfpga/Kconfig
>> +++ b/arch/arm/mach-socfpga/Kconfig
>> @@ -142,4 +142,14 @@ config SYS_CONFIG_NAME
>>   	default "socfpga_stratix10_socdk" if TARGET_SOCFPGA_STRATIX10_SOCDK
>>   	default "socfpga_vining_fpga" if TARGET_SOCFPGA_SAMTEC_VINING_FPGA
>>   
>> +config OLD_SOCFPGA_KERNEL_COMPAT
>> +	bool "Enable workarounds for booting old kernels"
>> +	depends on TARGET_SOCFPGA_GEN5
>> +	default y
>> +	help
>> +	  Set this to enable various workarounds for old kernels (e.g. take all
>> +	  peripherals out of reset because old kernels cannot handle reset).
>> +	  This results in sub-optimal settings for newer kernels, only enable
>> +	  if needed.
>> +
>>   endif
>> diff --git a/arch/arm/mach-socfpga/misc_gen5.c b/arch/arm/mach-socfpga/misc_gen5.c
>> index 04f237d100..168669923e 100644
>> --- a/arch/arm/mach-socfpga/misc_gen5.c
>> +++ b/arch/arm/mach-socfpga/misc_gen5.c
>> @@ -243,6 +243,7 @@ int arch_early_init_r(void)
>>   	/* Add device descriptor to FPGA device table */
>>   	socfpga_fpga_add(&altera_fpga[0]);
>>   
>> +#ifdef CONFIG_OLD_SOCFPGA_KERNEL_COMPAT
>>   #ifdef CONFIG_DESIGNWARE_SPI
>>   	/* Get Designware SPI controller out of reset */
>>   	socfpga_per_reset(SOCFPGA_RESET(SPIM0), 0);
>> @@ -252,6 +253,7 @@ int arch_early_init_r(void)
>>   #ifdef CONFIG_NAND_DENALI
>>   	socfpga_per_reset(SOCFPGA_RESET(NAND), 0);
>>   #endif
>> +#endif /* CONFIG_OLD_SOCFPGA_KERNEL_COMPAT */
>>   
>>   	return 0;
>>   }
>> diff --git a/arch/arm/mach-socfpga/spl_gen5.c b/arch/arm/mach-socfpga/spl_gen5.c
>> index f9bea892b1..19a211256d 100644
>> --- a/arch/arm/mach-socfpga/spl_gen5.c
>> +++ b/arch/arm/mach-socfpga/spl_gen5.c
>> @@ -35,16 +35,22 @@ u32 spl_boot_device(void)
>>   		return BOOT_DEVICE_RAM;
>>   	case 0x2:	/* NAND Flash (1.8V) */
>>   	case 0x3:	/* NAND Flash (3.0V) */
>> +#ifdef CONFIG_OLD_SOCFPGA_KERNEL_COMPAT
>>   		socfpga_per_reset(SOCFPGA_RESET(NAND), 0);
>> +#endif
>>   		return BOOT_DEVICE_NAND;
>>   	case 0x4:	/* SD/MMC External Transceiver (1.8V) */
>>   	case 0x5:	/* SD/MMC Internal Transceiver (3.0V) */
>> +#ifdef CONFIG_OLD_SOCFPGA_KERNEL_COMPAT
>>   		socfpga_per_reset(SOCFPGA_RESET(SDMMC), 0);
>>   		socfpga_per_reset(SOCFPGA_RESET(DMA), 0);
>> +#endif
>>   		return BOOT_DEVICE_MMC1;
>>   	case 0x6:	/* QSPI Flash (1.8V) */
>>   	case 0x7:	/* QSPI Flash (3.0V) */
>> +#ifdef CONFIG_OLD_SOCFPGA_KERNEL_COMPAT
>>   		socfpga_per_reset(SOCFPGA_RESET(QSPI), 0);
>> +#endif
>>   		return BOOT_DEVICE_SPI;
>>   	default:
>>   		printf("Invalid boot device (bsel=%08x)!\n", bsel);
>> @@ -98,7 +104,9 @@ void board_init_f(ulong dummy)
>>   		socfpga_bridges_reset(1);
>>   	}
>>   
>> +#ifdef CONFIG_OLD_SOCFPGA_KERNEL_COMPAT
>>   	socfpga_per_reset(SOCFPGA_RESET(UART0), 0);
>> +#endif
>>   	socfpga_per_reset(SOCFPGA_RESET(OSC1TIMER0), 0);
>>   
>>   	timer_init();
>> @@ -122,9 +130,11 @@ void board_init_f(ulong dummy)
>>   	sysmgr_pinmux_init();
>>   	sysmgr_config_warmrstcfgio(0);
>>   
>> +#ifdef CONFIG_OLD_SOCFPGA_KERNEL_COMPAT
>>   	/* De-assert reset for peripherals and bridges based on handoff */
>>   	reset_deassert_peripherals_handoff();
>>   	socfpga_bridges_reset(0);
>> +#endif
>>   
>>   	debug("Unfreezing/Thaw all I/O banks\n");
>>   	/* unfreeze / thaw all IO banks */
>>
> 
>
Marek Vasut Jan. 28, 2019, 10:58 a.m. UTC | #3
On 1/27/19 9:56 AM, Simon Goldschmidt wrote:
> Am 26.01.2019 um 10:00 schrieb Marek Vasut:
>> On 1/25/19 9:30 PM, Simon Goldschmidt wrote:
>>> This commit removes ad-hoc reset handling for peripheral resets from SPL
>>> for socfpga gen5.
>>>
>>> This is done because as U-Boot drivers support reset handling by now.
>>>
>>> For kernels that don't support taking peripherals out of reset that are
>>> not enabled by U-Boot, a new Kconfig option "OLD_SOCFPGA_KERNEL_COMPAT"
>>> is added, which keeps the old behaviour of just enabling all
>>> peripherals.
>>>
>>> This new option is enabled by default for now, as even Linux 4.20 does
>>> not support reset handling on all peripherals.
>>>
>>> Signed-off-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
>>
>> Well ew, don't we have some pre-linux-boot hook which could just flip
>> the reset register bits in one place ? And also, I'd prefer this to be
>> runtime-configurable, not compile-time configurable.
> 
> 
> And this will be the biggest change for v2. It's also why I needed so
> long to send this series. What I sent in this version is how Tom said
> the same thing is being handled for mach-sunxi (Kconfig
> "OLD_SUNXI_KERNEL_COMPAT").
> 
> So if I remember your last mails about this topic, you'd prefer an
> environment variable with a callback that leads to enabling all
> peripherals just before jumping to Linux (yes, I'll find a hook for that).

Rather, I'd prefer some .remove() code in the SoCFPGA reset driver which
would check an environment variable to determine whether it should
ungate the resets before booting Linux or not.

> I see two problems here:
> - enabling all peripherals will need to be the default for some time,
> until Linux supports reset handling in all drivers. How do you want to
> deal with that?

Set the env variable to default=1 for all socfpga boards ?

> - is this scheme used somewhere else for compatibility? I think it would
> make sense for multiple architectures to use the same way to handle such
> compatibility issues...

I don't think so, however it's better than compile-time setting.

[...]
Simon Goldschmidt Jan. 28, 2019, 11:50 a.m. UTC | #4
On Mon, Jan 28, 2019 at 12:30 PM Marek Vasut <marex@denx.de> wrote:
>
> On 1/27/19 9:56 AM, Simon Goldschmidt wrote:
> > Am 26.01.2019 um 10:00 schrieb Marek Vasut:
> >> On 1/25/19 9:30 PM, Simon Goldschmidt wrote:
> >>> This commit removes ad-hoc reset handling for peripheral resets from SPL
> >>> for socfpga gen5.
> >>>
> >>> This is done because as U-Boot drivers support reset handling by now.
> >>>
> >>> For kernels that don't support taking peripherals out of reset that are
> >>> not enabled by U-Boot, a new Kconfig option "OLD_SOCFPGA_KERNEL_COMPAT"
> >>> is added, which keeps the old behaviour of just enabling all
> >>> peripherals.
> >>>
> >>> This new option is enabled by default for now, as even Linux 4.20 does
> >>> not support reset handling on all peripherals.
> >>>
> >>> Signed-off-by: Simon Goldschmidt <simon.k.r.goldschmidt@gmail.com>
> >>
> >> Well ew, don't we have some pre-linux-boot hook which could just flip
> >> the reset register bits in one place ? And also, I'd prefer this to be
> >> runtime-configurable, not compile-time configurable.
> >
> >
> > And this will be the biggest change for v2. It's also why I needed so
> > long to send this series. What I sent in this version is how Tom said
> > the same thing is being handled for mach-sunxi (Kconfig
> > "OLD_SUNXI_KERNEL_COMPAT").
> >
> > So if I remember your last mails about this topic, you'd prefer an
> > environment variable with a callback that leads to enabling all
> > peripherals just before jumping to Linux (yes, I'll find a hook for that).
>
> Rather, I'd prefer some .remove() code in the SoCFPGA reset driver which
> would check an environment variable to determine whether it should
> ungate the resets before booting Linux or not.

OK, that should work. I'll work on that for v2.

Regards,
Simon

>
> > I see two problems here:
> > - enabling all peripherals will need to be the default for some time,
> > until Linux supports reset handling in all drivers. How do you want to
> > deal with that?
>
> Set the env variable to default=1 for all socfpga boards ?
>
> > - is this scheme used somewhere else for compatibility? I think it would
> > make sense for multiple architectures to use the same way to handle such
> > compatibility issues...
>
> I don't think so, however it's better than compile-time setting.
>
> [...]
>
> --
> Best regards,
> Marek Vasut
diff mbox series

Patch

diff --git a/arch/arm/mach-socfpga/Kconfig b/arch/arm/mach-socfpga/Kconfig
index 5e87371f8c..89acced8d8 100644
--- a/arch/arm/mach-socfpga/Kconfig
+++ b/arch/arm/mach-socfpga/Kconfig
@@ -142,4 +142,14 @@  config SYS_CONFIG_NAME
 	default "socfpga_stratix10_socdk" if TARGET_SOCFPGA_STRATIX10_SOCDK
 	default "socfpga_vining_fpga" if TARGET_SOCFPGA_SAMTEC_VINING_FPGA
 
+config OLD_SOCFPGA_KERNEL_COMPAT
+	bool "Enable workarounds for booting old kernels"
+	depends on TARGET_SOCFPGA_GEN5
+	default y
+	help
+	  Set this to enable various workarounds for old kernels (e.g. take all
+	  peripherals out of reset because old kernels cannot handle reset).
+	  This results in sub-optimal settings for newer kernels, only enable
+	  if needed.
+
 endif
diff --git a/arch/arm/mach-socfpga/misc_gen5.c b/arch/arm/mach-socfpga/misc_gen5.c
index 04f237d100..168669923e 100644
--- a/arch/arm/mach-socfpga/misc_gen5.c
+++ b/arch/arm/mach-socfpga/misc_gen5.c
@@ -243,6 +243,7 @@  int arch_early_init_r(void)
 	/* Add device descriptor to FPGA device table */
 	socfpga_fpga_add(&altera_fpga[0]);
 
+#ifdef CONFIG_OLD_SOCFPGA_KERNEL_COMPAT
 #ifdef CONFIG_DESIGNWARE_SPI
 	/* Get Designware SPI controller out of reset */
 	socfpga_per_reset(SOCFPGA_RESET(SPIM0), 0);
@@ -252,6 +253,7 @@  int arch_early_init_r(void)
 #ifdef CONFIG_NAND_DENALI
 	socfpga_per_reset(SOCFPGA_RESET(NAND), 0);
 #endif
+#endif /* CONFIG_OLD_SOCFPGA_KERNEL_COMPAT */
 
 	return 0;
 }
diff --git a/arch/arm/mach-socfpga/spl_gen5.c b/arch/arm/mach-socfpga/spl_gen5.c
index f9bea892b1..19a211256d 100644
--- a/arch/arm/mach-socfpga/spl_gen5.c
+++ b/arch/arm/mach-socfpga/spl_gen5.c
@@ -35,16 +35,22 @@  u32 spl_boot_device(void)
 		return BOOT_DEVICE_RAM;
 	case 0x2:	/* NAND Flash (1.8V) */
 	case 0x3:	/* NAND Flash (3.0V) */
+#ifdef CONFIG_OLD_SOCFPGA_KERNEL_COMPAT
 		socfpga_per_reset(SOCFPGA_RESET(NAND), 0);
+#endif
 		return BOOT_DEVICE_NAND;
 	case 0x4:	/* SD/MMC External Transceiver (1.8V) */
 	case 0x5:	/* SD/MMC Internal Transceiver (3.0V) */
+#ifdef CONFIG_OLD_SOCFPGA_KERNEL_COMPAT
 		socfpga_per_reset(SOCFPGA_RESET(SDMMC), 0);
 		socfpga_per_reset(SOCFPGA_RESET(DMA), 0);
+#endif
 		return BOOT_DEVICE_MMC1;
 	case 0x6:	/* QSPI Flash (1.8V) */
 	case 0x7:	/* QSPI Flash (3.0V) */
+#ifdef CONFIG_OLD_SOCFPGA_KERNEL_COMPAT
 		socfpga_per_reset(SOCFPGA_RESET(QSPI), 0);
+#endif
 		return BOOT_DEVICE_SPI;
 	default:
 		printf("Invalid boot device (bsel=%08x)!\n", bsel);
@@ -98,7 +104,9 @@  void board_init_f(ulong dummy)
 		socfpga_bridges_reset(1);
 	}
 
+#ifdef CONFIG_OLD_SOCFPGA_KERNEL_COMPAT
 	socfpga_per_reset(SOCFPGA_RESET(UART0), 0);
+#endif
 	socfpga_per_reset(SOCFPGA_RESET(OSC1TIMER0), 0);
 
 	timer_init();
@@ -122,9 +130,11 @@  void board_init_f(ulong dummy)
 	sysmgr_pinmux_init();
 	sysmgr_config_warmrstcfgio(0);
 
+#ifdef CONFIG_OLD_SOCFPGA_KERNEL_COMPAT
 	/* De-assert reset for peripherals and bridges based on handoff */
 	reset_deassert_peripherals_handoff();
 	socfpga_bridges_reset(0);
+#endif
 
 	debug("Unfreezing/Thaw all I/O banks\n");
 	/* unfreeze / thaw all IO banks */