[U-Boot] [PATCH 0/5] arm: omap: reset sata on OS boot

This series adds a SATA controller reset mechanism for OMAP platforms.
On OMAP platforms SATA support is provided via SCSI subsystem. Implement missing SCSI reset command.
Use the new functionality to reset SATA on OS boot.
Dmitry Lifshitz (5): ahci: introduce ahci_reset() ahci-plat: provide a weak scsi_bus_reset() hook OMAP5+: sata/scsi: implement scsi_bus_reset() arm: omap: reset sata on boot omap5: cm-t54: add sata support
arch/arm/cpu/armv7/omap-common/boot-common.c | 9 +++++ arch/arm/cpu/armv7/omap-common/sata.c | 6 +++ drivers/block/ahci.c | 50 ++++++++++++++++---------- include/ahci.h | 1 + include/configs/cm_t54.h | 13 +++++++ 5 files changed, 60 insertions(+), 19 deletions(-)

Extract controller reset code from ahci_host_init() into separate ahci_reset().
Signed-off-by: Dmitry Lifshitz lifshitz@compulab.co.il --- drivers/block/ahci.c | 47 ++++++++++++++++++++++++++++++----------------- include/ahci.h | 1 + 2 files changed, 31 insertions(+), 17 deletions(-)
diff --git a/drivers/block/ahci.c b/drivers/block/ahci.c index c9a3beb..12ed5e3 100644 --- a/drivers/block/ahci.c +++ b/drivers/block/ahci.c @@ -137,6 +137,33 @@ static void sunxi_dma_init(volatile u8 *port_mmio) } #endif
+int ahci_reset(u32 base) +{ + int i = 1000; + u32 host_ctl_reg = base + HOST_CTL; + u32 tmp = readl(host_ctl_reg); /* global controller reset */ + + if ((tmp & HOST_RESET) == 0) + writel_with_flush(tmp | HOST_RESET, host_ctl_reg); + + /* + * reset must complete within 1 second, or + * the hardware should be considered fried. + */ + do { + udelay(1000); + tmp = readl(host_ctl_reg); + i--; + } while ((i > 0) && (tmp & HOST_RESET)); + + if (i == 0) { + printf("controller reset failed (0x%x)\n", tmp); + return -1; + } + + return 0; +} + static int ahci_host_init(struct ahci_probe_ent *probe_ent) { #ifndef CONFIG_SCSI_AHCI_PLAT @@ -156,23 +183,9 @@ static int ahci_host_init(struct ahci_probe_ent *probe_ent) cap_save &= ((1 << 28) | (1 << 17)); cap_save |= (1 << 27); /* Staggered Spin-up. Not needed. */
- /* global controller reset */ - tmp = readl(mmio + HOST_CTL); - if ((tmp & HOST_RESET) == 0) - writel_with_flush(tmp | HOST_RESET, mmio + HOST_CTL); - - /* reset must complete within 1 second, or - * the hardware should be considered fried. - */ - i = 1000; - do { - udelay(1000); - tmp = readl(mmio + HOST_CTL); - if (!i--) { - debug("controller reset failed (0x%x)\n", tmp); - return -1; - } - } while (tmp & HOST_RESET); + ret = ahci_reset(probe_ent->mmio_base); + if (ret) + return ret;
writel_with_flush(HOST_AHCI_EN, mmio + HOST_CTL); writel(cap_save, mmio + HOST_CAP); diff --git a/include/ahci.h b/include/ahci.h index 35b8a8c..e8dee53 100644 --- a/include/ahci.h +++ b/include/ahci.h @@ -161,5 +161,6 @@ struct ahci_probe_ent { };
int ahci_init(u32 base); +int ahci_reset(u32 base);
#endif

On Mon, Dec 15, 2014 at 04:02:55PM +0200, Dmitry Lifshitz wrote:
Extract controller reset code from ahci_host_init() into separate ahci_reset().
Signed-off-by: Dmitry Lifshitz lifshitz@compulab.co.il
Reviewed-by: Tom Rini trini@ti.com

On Mon, Dec 15, 2014 at 04:02:55PM +0200, Dmitry Lifshitz wrote:
Extract controller reset code from ahci_host_init() into separate ahci_reset().
Signed-off-by: Dmitry Lifshitz lifshitz@compulab.co.il Reviewed-by: Tom Rini trini@ti.com
Applied to u-boot/master, thanks!

This allow the platform to handle a custom reset sequence.
Signed-off-by: Dmitry Lifshitz lifshitz@compulab.co.il --- drivers/block/ahci.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-)
diff --git a/drivers/block/ahci.c b/drivers/block/ahci.c index 12ed5e3..37d2d2a 100644 --- a/drivers/block/ahci.c +++ b/drivers/block/ahci.c @@ -1010,12 +1010,11 @@ static int ata_io_flush(u8 port) }
-void scsi_bus_reset(void) +__weak void scsi_bus_reset(void) { /*Not implement*/ }
- void scsi_print_error(ccb * pccb) { /*The ahci error info can be read in the ahci driver*/

On Mon, Dec 15, 2014 at 04:02:56PM +0200, Dmitry Lifshitz wrote:
This allow the platform to handle a custom reset sequence.
Signed-off-by: Dmitry Lifshitz lifshitz@compulab.co.il
Reviewed-by: Tom Rini trini@ti.com

On Mon, Dec 15, 2014 at 04:02:56PM +0200, Dmitry Lifshitz wrote:
This allow the platform to handle a custom reset sequence.
Signed-off-by: Dmitry Lifshitz lifshitz@compulab.co.il Reviewed-by: Tom Rini trini@ti.com
Applied to u-boot/master, thanks!

Implement missing scsi_bus_reset() for SCSI subsystem commands on OMAP platforms.
Signed-off-by: Dmitry Lifshitz lifshitz@compulab.co.il --- arch/arm/cpu/armv7/omap-common/sata.c | 6 ++++++ 1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/sata.c b/arch/arm/cpu/armv7/omap-common/sata.c index a24baa1..d18bc50 100644 --- a/arch/arm/cpu/armv7/omap-common/sata.c +++ b/arch/arm/cpu/armv7/omap-common/sata.c @@ -85,3 +85,9 @@ void scsi_init(void) init_sata(0); scsi_scan(1); } + +void scsi_bus_reset(void) +{ + ahci_reset(DWC_AHSATA_BASE); + ahci_init(DWC_AHSATA_BASE); +}

On Mon, Dec 15, 2014 at 04:02:57PM +0200, Dmitry Lifshitz wrote:
Implement missing scsi_bus_reset() for SCSI subsystem commands on OMAP platforms.
Signed-off-by: Dmitry Lifshitz lifshitz@compulab.co.il
Reviewed-by: Tom Rini trini@ti.com

On Mon, Dec 15, 2014 at 04:02:57PM +0200, Dmitry Lifshitz wrote:
Implement missing scsi_bus_reset() for SCSI subsystem commands on OMAP platforms.
Signed-off-by: Dmitry Lifshitz lifshitz@compulab.co.il Reviewed-by: Tom Rini trini@ti.com
Applied to u-boot/master, thanks!

On OMAP platforms (like OMAP5) Linux kernel fails to detect a SATA device if it is used by U-Boot.
It happens because U-Boot does not reset SATA controller before boot.
Reset the controller on OS boot so that Linux will have a clean state to work with.
Signed-off-by: Dmitry Lifshitz lifshitz@compulab.co.il --- arch/arm/cpu/armv7/omap-common/boot-common.c | 9 +++++++++ 1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/arch/arm/cpu/armv7/omap-common/boot-common.c b/arch/arm/cpu/armv7/omap-common/boot-common.c index cb18908..00a1082 100644 --- a/arch/arm/cpu/armv7/omap-common/boot-common.c +++ b/arch/arm/cpu/armv7/omap-common/boot-common.c @@ -9,12 +9,14 @@ */
#include <common.h> +#include <ahci.h> #include <spl.h> #include <asm/omap_common.h> #include <asm/arch/omap.h> #include <asm/arch/mmc_host_def.h> #include <asm/arch/sys_proto.h> #include <watchdog.h> +#include <scsi.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -143,3 +145,10 @@ void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) image_entry((u32 *)&gd->arch.omap_boot_params); } #endif + +#ifdef CONFIG_SCSI_AHCI_PLAT +void arch_preboot_os(void) +{ + ahci_reset(DWC_AHSATA_BASE); +} +#endif

On Mon, Dec 15, 2014 at 04:02:58PM +0200, Dmitry Lifshitz wrote:
On OMAP platforms (like OMAP5) Linux kernel fails to detect a SATA device if it is used by U-Boot.
It happens because U-Boot does not reset SATA controller before boot.
Reset the controller on OS boot so that Linux will have a clean state to work with.
Signed-off-by: Dmitry Lifshitz lifshitz@compulab.co.il
To be clear, since we're using CMD_SCSI and not CMD_SATA is why we need this reset sequence here instead of the sata_stop() that say i.MX uses.
Reviewed-by: Tom Rini trini@ti.com

Hi Tom,
On 12/15/2014 07:00 PM, Tom Rini wrote:
On Mon, Dec 15, 2014 at 04:02:58PM +0200, Dmitry Lifshitz wrote:
On OMAP platforms (like OMAP5) Linux kernel fails to detect a SATA device if it is used by U-Boot.
It happens because U-Boot does not reset SATA controller before boot.
Reset the controller on OS boot so that Linux will have a clean state to work with.
Signed-off-by: Dmitry Lifshitz lifshitz@compulab.co.il
To be clear, since we're using CMD_SCSI and not CMD_SATA is why we need this reset sequence here instead of the sata_stop() that say i.MX uses.
You are right, sata_stop() can be used here.
Unfortunately, OMAP SATA access is implemented via SCSI, so I managed to implement this workaround.
Regards,
Dmitry

On Mon, Dec 15, 2014 at 04:02:58PM +0200, Dmitry Lifshitz wrote:
On OMAP platforms (like OMAP5) Linux kernel fails to detect a SATA device if it is used by U-Boot.
It happens because U-Boot does not reset SATA controller before boot.
Reset the controller on OS boot so that Linux will have a clean state to work with.
Signed-off-by: Dmitry Lifshitz lifshitz@compulab.co.il Reviewed-by: Tom Rini trini@ti.com
Applied to u-boot/master, thanks!

Add configs required for SATA support on CM-T54 board.
Signed-off-by: Dmitry Lifshitz lifshitz@compulab.co.il --- include/configs/cm_t54.h | 13 +++++++++++++ 1 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/include/configs/cm_t54.h b/include/configs/cm_t54.h index 92ce1e1..0cd4aec 100644 --- a/include/configs/cm_t54.h +++ b/include/configs/cm_t54.h @@ -63,6 +63,19 @@ #define CONFIG_HSMMC2_8BIT #define CONFIG_SUPPORT_EMMC_BOOT
+/* SATA Boot related defines */ +#define CONFIG_SPL_SATA_SUPPORT +#define CONFIG_SPL_SATA_BOOT_DEVICE 0 +#define CONFIG_SYS_SATA_FAT_BOOT_PARTITION 1 + +#define CONFIG_CMD_SCSI +#define CONFIG_LIBATA +#define CONFIG_SCSI_AHCI +#define CONFIG_SCSI_AHCI_PLAT +#define CONFIG_SYS_SCSI_MAX_SCSI_ID 1 +#define CONFIG_SYS_SCSI_MAX_LUN 1 +#define CONFIG_SYS_SCSI_MAX_DEVICE (CONFIG_SYS_SCSI_MAX_SCSI_ID * \ + CONFIG_SYS_SCSI_MAX_LUN) /* USB UHH support options */ #define CONFIG_CMD_USB #define CONFIG_USB_HOST

On Mon, Dec 15, 2014 at 04:02:59PM +0200, Dmitry Lifshitz wrote:
Add configs required for SATA support on CM-T54 board.
Signed-off-by: Dmitry Lifshitz lifshitz@compulab.co.il
Reviewed-by: Tom Rini trini@ti.com

On Mon, Dec 15, 2014 at 04:02:59PM +0200, Dmitry Lifshitz wrote:
Add configs required for SATA support on CM-T54 board.
Signed-off-by: Dmitry Lifshitz lifshitz@compulab.co.il Reviewed-by: Tom Rini trini@ti.com
Applied to u-boot/master, thanks!
participants (2)
-
Dmitry Lifshitz
-
Tom Rini