[U-Boot] [RFC][PATCH 0/5] SATA support for OMAP5 uevm

Hi,
This series adds SATA support for OMAP5 uevm board.
This is an RFC patchset for review only. Patches are based on v2013.10.
cheers, -roger
--- Roger Quadros (5): ahci: Error out with message on malloc() failure ARM: OMAP5: Add Pipe3 PHY driver ARM: OMAP5: Add PRCM and Control information for SATA ARM: OMAP5: Add SATA platform glue ARM: omap5_uevm: Add SATA support
arch/arm/cpu/armv7/omap-common/Makefile | 7 + arch/arm/cpu/armv7/omap-common/pipe3-phy.c | 233 +++++++++++++++++++++++++++++ arch/arm/cpu/armv7/omap-common/pipe3-phy.h | 36 +++++ arch/arm/cpu/armv7/omap-common/sata.c | 78 ++++++++++ arch/arm/cpu/armv7/omap5/prcm-regs.c | 5 + arch/arm/include/asm/arch-omap5/clock.h | 3 + arch/arm/include/asm/arch-omap5/omap.h | 3 + arch/arm/include/asm/arch-omap5/sata.h | 48 ++++++ arch/arm/include/asm/omap_common.h | 3 + board/ti/omap5_uevm/evm.c | 7 + drivers/block/ahci.c | 16 +- include/configs/omap5_uevm.h | 10 ++ 12 files changed, 447 insertions(+), 2 deletions(-) create mode 100644 arch/arm/cpu/armv7/omap-common/pipe3-phy.c create mode 100644 arch/arm/cpu/armv7/omap-common/pipe3-phy.h create mode 100644 arch/arm/cpu/armv7/omap-common/sata.c create mode 100644 arch/arm/include/asm/arch-omap5/sata.h

If malloc() fails, we don't want to continue in ahci_init() and ahci_init_one(). Also print a more informative error message on malloc() failures.
CC: Rob Herring rob.herring@calxeda.com Signed-off-by: Roger Quadros rogerq@ti.com --- drivers/block/ahci.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/drivers/block/ahci.c b/drivers/block/ahci.c index 0daad36..e24d634 100644 --- a/drivers/block/ahci.c +++ b/drivers/block/ahci.c @@ -379,6 +379,11 @@ static int ahci_init_one(pci_dev_t pdev) int rc;
probe_ent = malloc(sizeof(struct ahci_probe_ent)); + if (!probe_ent) { + printf("%s: No memory for probe_ent\n", __func__); + return -ENOMEM; + } + memset(probe_ent, 0, sizeof(struct ahci_probe_ent)); probe_ent->dev = pdev;
@@ -503,7 +508,7 @@ static int ahci_port_start(u8 port) mem = (u32) malloc(AHCI_PORT_PRIV_DMA_SZ + 2048); if (!mem) { free(pp); - printf("No mem for table!\n"); + printf("%s: No mem for table!\n", __func__); return -ENOMEM; }
@@ -638,8 +643,10 @@ static int ata_scsiop_inquiry(ccb *pccb) /* Read id from sata */ port = pccb->target; tmpid = malloc(ATA_ID_WORDS * 2); - if (!tmpid) + if (!tmpid) { + printf("%s: No memory for tmpid\n", __func__); return -ENOMEM; + }
if (ahci_device_data_io(port, (u8 *) &fis, sizeof(fis), (u8 *)tmpid, ATA_ID_WORDS * 2, 0)) { @@ -889,6 +896,11 @@ int ahci_init(u32 base) u32 linkmap;
probe_ent = malloc(sizeof(struct ahci_probe_ent)); + if (!probe_ent) { + printf("%s: No memory for probe_ent\n", __func__); + return -ENOMEM; + } + memset(probe_ent, 0, sizeof(struct ahci_probe_ent));
probe_ent->host_flags = ATA_FLAG_SATA

Pipe3 PHY is used by SATA, USB3 and PCIe modules. This is a driver for the Pipe3 PHY.
Signed-off-by: Roger Quadros rogerq@ti.com --- arch/arm/cpu/armv7/omap-common/Makefile | 4 + arch/arm/cpu/armv7/omap-common/pipe3-phy.c | 233 +++++++++++++++++++++++++++++ arch/arm/cpu/armv7/omap-common/pipe3-phy.h | 36 +++++ 3 files changed, 273 insertions(+) create mode 100644 arch/arm/cpu/armv7/omap-common/pipe3-phy.c create mode 100644 arch/arm/cpu/armv7/omap-common/pipe3-phy.h
diff --git a/arch/arm/cpu/armv7/omap-common/Makefile b/arch/arm/cpu/armv7/omap-common/Makefile index 75b3753..6e4a0f0 100644 --- a/arch/arm/cpu/armv7/omap-common/Makefile +++ b/arch/arm/cpu/armv7/omap-common/Makefile @@ -21,6 +21,10 @@ COBJS += vc.o COBJS += abb.o endif
+ifneq ($(CONFIG_OMAP54XX),) +COBJS += pipe3-phy.o +endif + ifeq ($(CONFIG_OMAP34XX),) COBJS += boot-common.o SOBJS += lowlevel_init.o diff --git a/arch/arm/cpu/armv7/omap-common/pipe3-phy.c b/arch/arm/cpu/armv7/omap-common/pipe3-phy.c new file mode 100644 index 0000000..2756bed --- /dev/null +++ b/arch/arm/cpu/armv7/omap-common/pipe3-phy.c @@ -0,0 +1,233 @@ +/* + * TI PIPE3 PHY + * + * (C) Copyright 2013 + * Texas Instruments, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <sata.h> +#include <asm/arch/clock.h> +#include <asm/arch/sys_proto.h> +#include <asm/io.h> +#include <asm/errno.h> +#include "pipe3-phy.h" + +/* PLLCTRL Registers */ +#define PLL_STATUS 0x00000004 +#define PLL_GO 0x00000008 +#define PLL_CONFIGURATION1 0x0000000C +#define PLL_CONFIGURATION2 0x00000010 +#define PLL_CONFIGURATION3 0x00000014 +#define PLL_CONFIGURATION4 0x00000020 + +#define PLL_REGM_MASK 0x001FFE00 +#define PLL_REGM_SHIFT 9 +#define PLL_REGM_F_MASK 0x0003FFFF +#define PLL_REGM_F_SHIFT 0 +#define PLL_REGN_MASK 0x000001FE +#define PLL_REGN_SHIFT 1 +#define PLL_SELFREQDCO_MASK 0x0000000E +#define PLL_SELFREQDCO_SHIFT 1 +#define PLL_SD_MASK 0x0003FC00 +#define PLL_SD_SHIFT 10 +#define SET_PLL_GO 0x1 +#define PLL_TICOPWDN BIT(16) +#define PLL_LDOPWDN BIT(15) +#define PLL_LOCK 0x2 +#define PLL_IDLE 0x1 + +/* PHY POWER CONTROL Register */ +#define OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_MASK 0x003FC000 +#define OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_SHIFT 0xE + +#define OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_MASK 0xFFC00000 +#define OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_SHIFT 0x16 + +#define OMAP_CTRL_PIPE3_PHY_TX_RX_POWERON 0x3 +#define OMAP_CTRL_PIPE3_PHY_TX_RX_POWEROFF 0x0 + + +#define PLL_IDLE_TIME 100 /* in milliseconds */ +#define PLL_LOCK_TIME 100 /* in milliseconds */ + +#define perror(fmt, args...) printf("%s: " fmt, __func__ , ##args) + +static inline u32 omap_pipe3_readl(void __iomem *addr, unsigned offset) +{ + return __raw_readl(addr + offset); +} + +static inline void omap_pipe3_writel(void __iomem *addr, unsigned offset, + u32 data) +{ + __raw_writel(data, addr + offset); +} + +static struct pipe3_dpll_params *omap_pipe3_get_dpll_params(struct omap_pipe3 + *pipe3) +{ + u32 rate; + struct pipe3_dpll_map *dpll_map = pipe3->dpll_map; + + rate = get_sys_clk_freq(); + + for (; dpll_map->rate; dpll_map++) { + if (rate == dpll_map->rate) + return &dpll_map->params; + } + + perror("%s: No DPLL configuration for %u Hz SYS CLK\n", + __func__, rate); + return NULL; +} + + +static int omap_pipe3_wait_lock(struct omap_pipe3 *phy) +{ + u32 val; + int timeout = PLL_LOCK_TIME; + + do { + mdelay(1); + val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS); + if (val & PLL_LOCK) + break; + } while (--timeout); + + if (!(val & PLL_LOCK)) { + perror("%s: DPLL failed to lock\n", __func__); + return -EBUSY; + } + + return 0; +} + +static int omap_pipe3_dpll_program(struct omap_pipe3 *phy) +{ + u32 val; + struct pipe3_dpll_params *dpll_params; + + dpll_params = omap_pipe3_get_dpll_params(phy); + if (!dpll_params) { + perror("%s: Invalid DPLL parameters\n", __func__); + return -EINVAL; + } + + val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1); + val &= ~PLL_REGN_MASK; + val |= dpll_params->n << PLL_REGN_SHIFT; + omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val); + + val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); + val &= ~PLL_SELFREQDCO_MASK; + val |= dpll_params->freq << PLL_SELFREQDCO_SHIFT; + omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); + + val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION1); + val &= ~PLL_REGM_MASK; + val |= dpll_params->m << PLL_REGM_SHIFT; + omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION1, val); + + val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION4); + val &= ~PLL_REGM_F_MASK; + val |= dpll_params->mf << PLL_REGM_F_SHIFT; + omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION4, val); + + val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION3); + val &= ~PLL_SD_MASK; + val |= dpll_params->sd << PLL_SD_SHIFT; + omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION3, val); + + omap_pipe3_writel(phy->pll_ctrl_base, PLL_GO, SET_PLL_GO); + + return omap_pipe3_wait_lock(phy); +} + +static void omap_control_phy_power(struct omap_pipe3 *phy, int on) +{ + u32 val, rate; + + val = readl(phy->power_reg); + + rate = get_sys_clk_freq(); + rate = rate/1000000; + + if (on) { + val &= ~(OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_MASK | + OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_MASK); + val |= OMAP_CTRL_PIPE3_PHY_TX_RX_POWERON << + OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_SHIFT; + val |= rate << + OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_SHIFT; + } else { + val &= ~OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_MASK; + val |= OMAP_CTRL_PIPE3_PHY_TX_RX_POWEROFF << + OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_SHIFT; + } + + writel(val, phy->power_reg); +} + +int phy_pipe3_power_on(struct omap_pipe3 *phy) +{ + int ret; + u32 val; + + /* Program the DPLL only if not locked */ + val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS); + if (!(val & PLL_LOCK)) { + ret = omap_pipe3_dpll_program(phy); + if (ret) + return ret; + } else { + /* else just bring it out of IDLE mode */ + val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); + if (val & PLL_IDLE) { + val &= ~PLL_IDLE; + omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, + val); + ret = omap_pipe3_wait_lock(phy); + if (ret) + return ret; + } + } + + /* Power up the PHY */ + omap_control_phy_power(phy, 1); + + return 0; +} + +int phy_pipe3_power_off(struct omap_pipe3 *phy) +{ + u32 val; + int timeout = PLL_IDLE_TIME; + + /* Power down the PHY */ + omap_control_phy_power(phy, 0); + + /* Put DPLL in IDLE mode */ + val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_CONFIGURATION2); + val |= PLL_IDLE; + omap_pipe3_writel(phy->pll_ctrl_base, PLL_CONFIGURATION2, val); + + /* wait for LDO and Oscillator to power down */ + do { + mdelay(1); + val = omap_pipe3_readl(phy->pll_ctrl_base, PLL_STATUS); + if ((val & PLL_TICOPWDN) && (val & PLL_LDOPWDN)) + break; + } while (--timeout); + + if (!(val & PLL_TICOPWDN) || !(val & PLL_LDOPWDN)) { + perror("%s: Failed to power down DPLL: PLL_STATUS 0x%x\n", + __func__, val); + return -EBUSY; + } + + return 0; +} + diff --git a/arch/arm/cpu/armv7/omap-common/pipe3-phy.h b/arch/arm/cpu/armv7/omap-common/pipe3-phy.h new file mode 100644 index 0000000..441f49a --- /dev/null +++ b/arch/arm/cpu/armv7/omap-common/pipe3-phy.h @@ -0,0 +1,36 @@ +/* + * TI PIPE3 PHY + * + * (C) Copyright 2013 + * Texas Instruments, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __OMAP_PIPE3_PHY_H +#define __OMAP_PIPE3_PHY_H + +struct pipe3_dpll_params { + u16 m; + u8 n; + u8 freq:3; + u8 sd; + u32 mf; +}; + +struct pipe3_dpll_map { + unsigned long rate; + struct pipe3_dpll_params params; +}; + +struct omap_pipe3 { + void __iomem *pll_ctrl_base; + void __iomem *power_reg; + struct pipe3_dpll_map *dpll_map; +}; + + +int phy_pipe3_power_on(struct omap_pipe3 *phy); +int phy_pipe3_power_off(struct omap_pipe3 *pipe3); + +#endif /* __OMAP_PIPE3_PHY_H */

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 11/06/2013 09:47 AM, Roger Quadros wrote:
Pipe3 PHY is used by SATA, USB3 and PCIe modules. This is a driver for the Pipe3 PHY.
Signed-off-by: Roger Quadros rogerq@ti.com
[snip]
+#define perror(fmt, args...) printf("%s: " fmt, __func__ , ##args)
Please use the debug macro.
[snip[
- perror("%s: No DPLL configuration for %u Hz SYS CLK\n",
__func__, rate);
Indent is wrong, we do like the kernel (and checkpatch.pl is in tools/ and will catch these). Thanks.
Code itself seems fine tho, thanks.
- -- Tom

On 11/06/2013 11:48 PM, Tom Rini wrote:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 11/06/2013 09:47 AM, Roger Quadros wrote:
Pipe3 PHY is used by SATA, USB3 and PCIe modules. This is a driver for the Pipe3 PHY.
Signed-off-by: Roger Quadros rogerq@ti.com
[snip]
+#define perror(fmt, args...) printf("%s: " fmt, __func__ , ##args)
Please use the debug macro.
But I want the message to be printed and not hidden if DEBUG is not defined.
[snip[
- perror("%s: No DPLL configuration for %u Hz SYS CLK\n",
__func__, rate);
Indent is wrong, we do like the kernel (and checkpatch.pl is in tools/ and will catch these). Thanks.
you mean the function arguments '__func__' and 'rate' should be on the same line where perror is?
cheers, -roger

On Thu, Nov 07, 2013 at 02:23:32PM +0200, Roger Quadros wrote:
On 11/06/2013 11:48 PM, Tom Rini wrote:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 11/06/2013 09:47 AM, Roger Quadros wrote:
Pipe3 PHY is used by SATA, USB3 and PCIe modules. This is a driver for the Pipe3 PHY.
Signed-off-by: Roger Quadros rogerq@ti.com
[snip]
+#define perror(fmt, args...) printf("%s: " fmt, __func__ , ##args)
Please use the debug macro.
But I want the message to be printed and not hidden if DEBUG is not defined.
Then just call printf please. Or is this kernel-adapted code?
[snip[
- perror("%s: No DPLL configuration for %u Hz SYS CLK\n",
__func__, rate);
Indent is wrong, we do like the kernel (and checkpatch.pl is in tools/ and will catch these). Thanks.
you mean the function arguments '__func__' and 'rate' should be on the same line where perror is?
perror("....\n", __func_, ...);

On 11/11/2013 03:52 PM, Tom Rini wrote:
On Thu, Nov 07, 2013 at 02:23:32PM +0200, Roger Quadros wrote:
On 11/06/2013 11:48 PM, Tom Rini wrote:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 11/06/2013 09:47 AM, Roger Quadros wrote:
Pipe3 PHY is used by SATA, USB3 and PCIe modules. This is a driver for the Pipe3 PHY.
Signed-off-by: Roger Quadros rogerq@ti.com
[snip]
+#define perror(fmt, args...) printf("%s: " fmt, __func__ , ##args)
Please use the debug macro.
But I want the message to be printed and not hidden if DEBUG is not defined.
Then just call printf please. Or is this kernel-adapted code?
OK. No this isn't in the kernel.
[snip[
- perror("%s: No DPLL configuration for %u Hz SYS CLK\n",
__func__, rate);
Indent is wrong, we do like the kernel (and checkpatch.pl is in tools/ and will catch these). Thanks.
you mean the function arguments '__func__' and 'rate' should be on the same line where perror is?
perror("....\n", __func_, ...);
OK. I'll wait some more time for comments on v2 before I send out a v3 with these changes.
cheers, -roger

Adds the necessary PRCM and Control register information for SATA on OMAP5.
Signed-off-by: Roger Quadros rogerq@ti.com --- arch/arm/cpu/armv7/omap5/prcm-regs.c | 5 +++++ arch/arm/include/asm/arch-omap5/clock.h | 3 +++ arch/arm/include/asm/arch-omap5/omap.h | 3 +++ arch/arm/include/asm/omap_common.h | 3 +++ 4 files changed, 14 insertions(+)
diff --git a/arch/arm/cpu/armv7/omap5/prcm-regs.c b/arch/arm/cpu/armv7/omap5/prcm-regs.c index 764620d..78fd7ec 100644 --- a/arch/arm/cpu/armv7/omap5/prcm-regs.c +++ b/arch/arm/cpu/armv7/omap5/prcm-regs.c @@ -203,8 +203,10 @@ struct prcm_regs const omap5_es1_prcm = { .cm_l3init_hsusbotg_clkctrl = 0x4a009360, .cm_l3init_hsusbtll_clkctrl = 0x4a009368, .cm_l3init_p1500_clkctrl = 0x4a009378, + .cm_l3init_sata_clkctrl = 0x4a009388, .cm_l3init_fsusb_clkctrl = 0x4a0093d0, .cm_l3init_ocp2scp1_clkctrl = 0x4a0093e0, + .cm_l3init_ocp2scp3_clkctrl = 0x4a0093e8,
/* cm2.l4per */ .cm_l4per_clkstctrl = 0x4a009400, @@ -295,6 +297,7 @@ struct prcm_regs const omap5_es1_prcm = { struct omap_sys_ctrl_regs const omap5_ctrl = { .control_status = 0x4A002134, .control_std_fuse_opp_vdd_mpu_2 = 0x4A0021B4, + .control_phy_power_sata = 0x4A002374, .control_padconf_core_base = 0x4A002800, .control_paconf_global = 0x4A002DA0, .control_paconf_mode = 0x4A002DA4, @@ -696,8 +699,10 @@ struct prcm_regs const omap5_es2_prcm = { .cm_l3init_hsusbotg_clkctrl = 0x4a009660, .cm_l3init_hsusbtll_clkctrl = 0x4a009668, .cm_l3init_p1500_clkctrl = 0x4a009678, + .cm_l3init_sata_clkctrl = 0x4a009688, .cm_l3init_fsusb_clkctrl = 0x4a0096d0, .cm_l3init_ocp2scp1_clkctrl = 0x4a0096e0, + .cm_l3init_ocp2scp3_clkctrl = 0x4a0096e8,
/* prm irqstatus regs */ .prm_irqstatus_mpu_2 = 0x4ae06014, diff --git a/arch/arm/include/asm/arch-omap5/clock.h b/arch/arm/include/asm/arch-omap5/clock.h index 9a2166c..aa934fb 100644 --- a/arch/arm/include/asm/arch-omap5/clock.h +++ b/arch/arm/include/asm/arch-omap5/clock.h @@ -137,6 +137,9 @@ #define HSMMC_CLKCTRL_CLKSEL_MASK (1 << 24) #define HSMMC_CLKCTRL_CLKSEL_DIV_MASK (1 << 25)
+/* CM_L3INIT_SATA_CLKCTRL */ +#define SATA_CLKCTRL_OPTFCLKEN_MASK (1 << 8) + /* CM_WKUP_GPTIMER1_CLKCTRL */ #define GPTIMER1_CLKCTRL_CLKSEL_MASK (1 << 24)
diff --git a/arch/arm/include/asm/arch-omap5/omap.h b/arch/arm/include/asm/arch-omap5/omap.h index 414d37a..150db0f 100644 --- a/arch/arm/include/asm/arch-omap5/omap.h +++ b/arch/arm/include/asm/arch-omap5/omap.h @@ -64,6 +64,9 @@ /* QSPI */ #define QSPI_BASE 0x4B300000
+/* SATA */ +#define DWC_AHSATA_BASE 0x4A140000 + /* * Hardware Register Details */ diff --git a/arch/arm/include/asm/omap_common.h b/arch/arm/include/asm/omap_common.h index 3a998cc..cffcb93 100644 --- a/arch/arm/include/asm/omap_common.h +++ b/arch/arm/include/asm/omap_common.h @@ -224,8 +224,10 @@ struct prcm_regs { u32 cm_l3init_hsusbotg_clkctrl; u32 cm_l3init_hsusbtll_clkctrl; u32 cm_l3init_p1500_clkctrl; + u32 cm_l3init_sata_clkctrl; u32 cm_l3init_fsusb_clkctrl; u32 cm_l3init_ocp2scp1_clkctrl; + u32 cm_l3init_ocp2scp3_clkctrl;
u32 prm_irqstatus_mpu_2;
@@ -361,6 +363,7 @@ struct omap_sys_ctrl_regs { u32 control_ldosram_mpu_voltage_ctrl; u32 control_ldosram_core_voltage_ctrl; u32 control_usbotghs_ctrl; + u32 control_phy_power_sata; u32 control_padconf_core_base; u32 control_paconf_global; u32 control_paconf_mode;

Add platform glue logic for the SATA controller.
Signed-off-by: Roger Quadros rogerq@ti.com --- arch/arm/cpu/armv7/omap-common/Makefile | 3 ++ arch/arm/cpu/armv7/omap-common/sata.c | 78 +++++++++++++++++++++++++++++++++ arch/arm/include/asm/arch-omap5/sata.h | 48 ++++++++++++++++++++ 3 files changed, 129 insertions(+) create mode 100644 arch/arm/cpu/armv7/omap-common/sata.c create mode 100644 arch/arm/include/asm/arch-omap5/sata.h
diff --git a/arch/arm/cpu/armv7/omap-common/Makefile b/arch/arm/cpu/armv7/omap-common/Makefile index 6e4a0f0..0535b62 100644 --- a/arch/arm/cpu/armv7/omap-common/Makefile +++ b/arch/arm/cpu/armv7/omap-common/Makefile @@ -23,6 +23,9 @@ endif
ifneq ($(CONFIG_OMAP54XX),) COBJS += pipe3-phy.o +ifdef CONFIG_SCSI_AHCI_PLAT +COBJS += sata.o +endif endif
ifeq ($(CONFIG_OMAP34XX),) diff --git a/arch/arm/cpu/armv7/omap-common/sata.c b/arch/arm/cpu/armv7/omap-common/sata.c new file mode 100644 index 0000000..eb079c3 --- /dev/null +++ b/arch/arm/cpu/armv7/omap-common/sata.c @@ -0,0 +1,78 @@ +/* + * TI SATA platform driver + * + * (C) Copyright 2013 + * Texas Instruments, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <ahci.h> +#include <scsi.h> +#include <asm/arch/clock.h> +#include <asm/arch/sata.h> +#include <asm/io.h> +#include "pipe3-phy.h" + +#if defined(CONFIG_SCSI_AHCI_PLAT) + +static struct pipe3_dpll_map dpll_map_sata[] = { + {12000000, {1000, 7, 4, 6, 0} }, /* 12 MHz */ + {16800000, {714, 7, 4, 6, 0} }, /* 16.8 MHz */ + {19200000, {625, 7, 4, 6, 0} }, /* 19.2 MHz */ + {20000000, {600, 7, 4, 6, 0} }, /* 20 MHz */ + {26000000, {461, 7, 4, 6, 0} }, /* 26 MHz */ + {38400000, {312, 7, 4, 6, 0} }, /* 38.4 MHz */ + { }, /* Terminator */ +}; + +struct omap_pipe3 sata_phy = { + .pll_ctrl_base = (void __iomem *)TI_SATA_PLLCTRL_BASE, + /* .power_reg is updated at runtime */ + .dpll_map = dpll_map_sata, +}; + +int omap_sata_init(void) +{ + int ret; + u32 val; + + u32 const clk_domains_sata[] = { + 0 + }; + + u32 const clk_modules_hw_auto_sata[] = { + (*prcm)->cm_l3init_ocp2scp3_clkctrl, + 0 + }; + + u32 const clk_modules_explicit_en_sata[] = { + (*prcm)->cm_l3init_sata_clkctrl, + 0 + }; + + do_enable_clocks(clk_domains_sata, + clk_modules_hw_auto_sata, + clk_modules_explicit_en_sata, + 0); + + /* Enable optional functional clock for SATA */ + setbits_le32((*prcm)->cm_l3init_sata_clkctrl, + SATA_CLKCTRL_OPTFCLKEN_MASK); + + sata_phy.power_reg = (void __iomem *)(*ctrl)->control_phy_power_sata; + + /* Power up the PHY */ + phy_pipe3_power_on(&sata_phy); + + /* Enable SATA module, No Idle, No Standby */ + val = TI_SATA_IDLE_NO | TI_SATA_STANDBY_NO; + writel(val, TI_SATA_WRAPPER_BASE + TI_SATA_SYSCONFIG); + + ret = ahci_init(DWC_AHSATA_BASE); + scsi_scan(1); + + return ret; +} +#endif diff --git a/arch/arm/include/asm/arch-omap5/sata.h b/arch/arm/include/asm/arch-omap5/sata.h new file mode 100644 index 0000000..2ca8947 --- /dev/null +++ b/arch/arm/include/asm/arch-omap5/sata.h @@ -0,0 +1,48 @@ +/* + * SATA Wrapper Register map + * + * (C) Copyright 2013 + * Texas Instruments, <www.ti.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _TI_SATA_H +#define _TI_SATA_H + +/* SATA Wrapper module */ +#define TI_SATA_WRAPPER_BASE (OMAP54XX_L4_CORE_BASE + 0x141100) +/* SATA PHY Module */ +#define TI_SATA_PLLCTRL_BASE (OMAP54XX_L4_CORE_BASE + 0x96800) + +/* SATA Wrapper register offsets */ +#define TI_SATA_SYSCONFIG 0x00 +#define TI_SATA_CDRLOCK 0x04 + +/* Register Set */ +#define TI_SATA_SYSCONFIG_OVERRIDE0 (1 << 16) +#define TI_SATA_SYSCONFIG_STANDBY_MASK (0x3 << 4) +#define TI_SATA_SYSCONFIG_IDLE_MASK (0x3 << 2) + +/* Standby modes */ +#define TI_SATA_STANDBY_FORCE 0x0 +#define TI_SATA_STANDBY_NO (0x1 << 4) +#define TI_SATA_STANDBY_SMART_WAKE (0x3 << 4) +#define TI_SATA_STANDBY_SMART (0x2 << 4) + +/* Idle modes */ +#define TI_SATA_IDLE_FORCE 0x0 +#define TI_SATA_IDLE_NO (0x1 << 2) +#define TI_SATA_IDLE_SMART_WAKE (0x3 << 2) +#define TI_SATA_IDLE_SMART (0x2 << 2) + +#ifdef CONFIG_SCSI_AHCI_PLAT +int omap_sata_init(void); +#else +static inline int omap_sata_init(void) +{ + return 0; +} +#endif /* CONFIG_SCSI_AHCI_PLAT */ + +#endif /* _TI_SATA_H */

-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 11/06/2013 09:47 AM, Roger Quadros wrote:
Add platform glue logic for the SATA controller.
Signed-off-by: Roger Quadros rogerq@ti.com
[snip]
diff --git a/arch/arm/cpu/armv7/omap-common/Makefile b/arch/arm/cpu/armv7/omap-common/Makefile index 6e4a0f0..0535b62 100644 --- a/arch/arm/cpu/armv7/omap-common/Makefile +++ b/arch/arm/cpu/armv7/omap-common/Makefile @@ -23,6 +23,9 @@ endif
ifneq ($(CONFIG_OMAP54XX),) COBJS += pipe3-phy.o +ifdef CONFIG_SCSI_AHCI_PLAT +COBJS += sata.o +endif
This should be: COBJS-$(CONFIG_SCSI_AHCI_PLAT) += sata.o, or obj-... with the recent changes.
endif
ifeq ($(CONFIG_OMAP34XX),) diff --git a/arch/arm/cpu/armv7/omap-common/sata.c b/arch/arm/cpu/armv7/omap-common/sata.c new file mode 100644 index 0000000..eb079c3 --- /dev/null +++ b/arch/arm/cpu/armv7/omap-common/sata.c
[snip]
+#if defined(CONFIG_SCSI_AHCI_PLAT)
The file already depends on this symbol to be built at all.
- -- Tom

On 11/07/2013 12:11 AM, Tom Rini wrote:
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
On 11/06/2013 09:47 AM, Roger Quadros wrote:
Add platform glue logic for the SATA controller.
Signed-off-by: Roger Quadros rogerq@ti.com
[snip]
diff --git a/arch/arm/cpu/armv7/omap-common/Makefile b/arch/arm/cpu/armv7/omap-common/Makefile index 6e4a0f0..0535b62 100644 --- a/arch/arm/cpu/armv7/omap-common/Makefile +++ b/arch/arm/cpu/armv7/omap-common/Makefile @@ -23,6 +23,9 @@ endif
ifneq ($(CONFIG_OMAP54XX),) COBJS += pipe3-phy.o +ifdef CONFIG_SCSI_AHCI_PLAT +COBJS += sata.o +endif
This should be: COBJS-$(CONFIG_SCSI_AHCI_PLAT) += sata.o, or obj-... with the recent changes.
OK.
endif
ifeq ($(CONFIG_OMAP34XX),) diff --git a/arch/arm/cpu/armv7/omap-common/sata.c b/arch/arm/cpu/armv7/omap-common/sata.c new file mode 100644 index 0000000..eb079c3 --- /dev/null +++ b/arch/arm/cpu/armv7/omap-common/sata.c
[snip]
+#if defined(CONFIG_SCSI_AHCI_PLAT)
The file already depends on this symbol to be built at all.
Right.
cheers, -roger

The uevm has a SATA port. Inititialize the SATA controller.
Signed-off-by: Roger Quadros rogerq@ti.com --- board/ti/omap5_uevm/evm.c | 7 +++++++ include/configs/omap5_uevm.h | 10 ++++++++++ 2 files changed, 17 insertions(+)
diff --git a/board/ti/omap5_uevm/evm.c b/board/ti/omap5_uevm/evm.c index 4706330..86622c3 100644 --- a/board/ti/omap5_uevm/evm.c +++ b/board/ti/omap5_uevm/evm.c @@ -20,6 +20,7 @@ #include <asm/arch/clock.h> #include <asm/arch/ehci.h> #include <asm/ehci-omap.h> +#include <asm/arch/sata.h>
#define DIE_ID_REG_BASE (OMAP54XX_L4_CORE_BASE + 0x2000) #define DIE_ID_REG_OFFSET 0x200 @@ -67,6 +68,12 @@ int board_init(void) return 0; }
+int board_late_init(void) +{ + omap_sata_init(); + return 0; +} + int board_eth_init(bd_t *bis) { return 0; diff --git a/include/configs/omap5_uevm.h b/include/configs/omap5_uevm.h index 4d3a800..2f128b8 100644 --- a/include/configs/omap5_uevm.h +++ b/include/configs/omap5_uevm.h @@ -69,4 +69,14 @@ /* Max time to hold reset on this board, see doc/README.omap-reset-time */ #define CONFIG_OMAP_PLATFORM_RESET_TIME_MAX_USEC 16296
+#define CONFIG_BOARD_LATE_INIT +#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) + #endif /* __CONFIG_OMAP5_EVM_H */

Hi Roger,
Thanks for the patches!
2013/11/6 Roger Quadros rogerq@ti.com:
Hi,
This series adds SATA support for OMAP5 uevm board.
This is an RFC patchset for review only. Patches are based on v2013.10.
cheers, -roger
Roger Quadros (5): ahci: Error out with message on malloc() failure ARM: OMAP5: Add Pipe3 PHY driver ARM: OMAP5: Add PRCM and Control information for SATA ARM: OMAP5: Add SATA platform glue ARM: omap5_uevm: Add SATA support
arch/arm/cpu/armv7/omap-common/Makefile | 7 + arch/arm/cpu/armv7/omap-common/pipe3-phy.c | 233 +++++++++++++++++++++++++++++ arch/arm/cpu/armv7/omap-common/pipe3-phy.h | 36 +++++ arch/arm/cpu/armv7/omap-common/sata.c | 78 ++++++++++ arch/arm/cpu/armv7/omap5/prcm-regs.c | 5 + arch/arm/include/asm/arch-omap5/clock.h | 3 + arch/arm/include/asm/arch-omap5/omap.h | 3 + arch/arm/include/asm/arch-omap5/sata.h | 48 ++++++ arch/arm/include/asm/omap_common.h | 3 + board/ti/omap5_uevm/evm.c | 7 + drivers/block/ahci.c | 16 +- include/configs/omap5_uevm.h | 10 ++ 12 files changed, 447 insertions(+), 2 deletions(-) create mode 100644 arch/arm/cpu/armv7/omap-common/pipe3-phy.c create mode 100644 arch/arm/cpu/armv7/omap-common/pipe3-phy.h create mode 100644 arch/arm/cpu/armv7/omap-common/sata.c create mode 100644 arch/arm/include/asm/arch-omap5/sata.h
-- 1.8.3.2
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
I applied your patches and worked perfectly, however I've two small issues.
The first issue is that I see the following error:
scanning bus for devices... ERROR: v7_dcache_inval_range - start address is not aligned - 0xfee48618 ERROR: v7_dcache_inval_range - stop address is not aligned - 0xfee48818
The second issue, and I'm not sure if the problem should be solved at u-boot level, is that I'm not able to access to the SATA disk at kernel level. I meant, if I boot to the system with latest stable u-boot the kernel recognizes the SATA disk and I'm able to mount, read and write to the disk. If I boot using u-boot with your patches applied the kernel doesn't recognizes the SATA disk and doesn't work. In that case the kernel reports the following error:
ata1: COMRESET failed (errno=-16)
Note that the kernel version that I'm using is 3.8.13 from git.ti.com.
Cheers, Enric

+Aneesh.
Hi Enric,
On 11/07/2013 10:52 AM, Enric Balletbo Serra wrote:
Hi Roger,
Thanks for the patches!
2013/11/6 Roger Quadros rogerq@ti.com:
Hi,
This series adds SATA support for OMAP5 uevm board.
This is an RFC patchset for review only. Patches are based on v2013.10.
cheers, -roger
Roger Quadros (5): ahci: Error out with message on malloc() failure ARM: OMAP5: Add Pipe3 PHY driver ARM: OMAP5: Add PRCM and Control information for SATA ARM: OMAP5: Add SATA platform glue ARM: omap5_uevm: Add SATA support
arch/arm/cpu/armv7/omap-common/Makefile | 7 + arch/arm/cpu/armv7/omap-common/pipe3-phy.c | 233 +++++++++++++++++++++++++++++ arch/arm/cpu/armv7/omap-common/pipe3-phy.h | 36 +++++ arch/arm/cpu/armv7/omap-common/sata.c | 78 ++++++++++ arch/arm/cpu/armv7/omap5/prcm-regs.c | 5 + arch/arm/include/asm/arch-omap5/clock.h | 3 + arch/arm/include/asm/arch-omap5/omap.h | 3 + arch/arm/include/asm/arch-omap5/sata.h | 48 ++++++ arch/arm/include/asm/omap_common.h | 3 + board/ti/omap5_uevm/evm.c | 7 + drivers/block/ahci.c | 16 +- include/configs/omap5_uevm.h | 10 ++ 12 files changed, 447 insertions(+), 2 deletions(-) create mode 100644 arch/arm/cpu/armv7/omap-common/pipe3-phy.c create mode 100644 arch/arm/cpu/armv7/omap-common/pipe3-phy.h create mode 100644 arch/arm/cpu/armv7/omap-common/sata.c create mode 100644 arch/arm/include/asm/arch-omap5/sata.h
-- 1.8.3.2
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot
I applied your patches and worked perfectly, however I've two small issues.
The first issue is that I see the following error:
scanning bus for devices... ERROR: v7_dcache_inval_range - start address is not aligned - 0xfee48618 ERROR: v7_dcache_inval_range - stop address is not aligned - 0xfee48818
I'm seeing this too. Not sure how to fix it. Aneesh, any pointers?
The second issue, and I'm not sure if the problem should be solved at u-boot level, is that I'm not able to access to the SATA disk at kernel level. I meant, if I boot to the system with latest stable u-boot the kernel recognizes the SATA disk and I'm able to mount, read and write to the disk. If I boot using u-boot with your patches applied the kernel doesn't recognizes the SATA disk and doesn't work. In that case the kernel reports the following error:
ata1: COMRESET failed (errno=-16)
Note that the kernel version that I'm using is 3.8.13 from git.ti.com.
There is a known issue with the SATA DPLL
"1.52 SATA Lockup After SATA DPLL Unlock/Relock - Errata ID: i783"
So, we'll need to do something in the kernel before these patches get into u-boot.
I'll try to come up with a solution soon. Something on the lines of not re-initializing the SATA DPLL if it is already locked.
cheers, -roger
participants (3)
-
Enric Balletbo Serra
-
Roger Quadros
-
Tom Rini