This phy is found on omap platforms with sata capabilities.
Except for the part related to the DM and the PHY framework, the code is
basically a copy paste from arch/arm/mach-omap2/pipe3-phy.c
Signed-off-by: Jean-Jacques Hiblot
---
drivers/phy/Kconfig| 12 ++
drivers/phy/Makefile | 1 +
drivers/phy/ti-pipe3-phy.c | 368 +
3 files changed, 381 insertions(+)
create mode 100644 drivers/phy/ti-pipe3-phy.c
diff --git a/drivers/phy/Kconfig b/drivers/phy/Kconfig
index b6fed9e..6a48343 100644
--- a/drivers/phy/Kconfig
+++ b/drivers/phy/Kconfig
@@ -19,4 +19,16 @@ config SPL_GENERIC_PHY
This framework is designed to provide a generic interface for PHY
devices.
+config PIPE3_PHY
+ bool "Support omap's PIPE3 PHY"
+ depends on GENERIC_PHY
+ help
+ Support for the omap PIPE3 phy for sata
+
+config SPL_PIPE3_PHY
+ bool "Support omap's PIPE3 PHY in SPL"
+ depends on SPL_GENERIC_PHY
+ help
+ Support for the omap PIPE3 phy for sata in SPL
+
endmenu
diff --git a/drivers/phy/Makefile b/drivers/phy/Makefile
index ccd15ed..60c8a56 100644
--- a/drivers/phy/Makefile
+++ b/drivers/phy/Makefile
@@ -1,4 +1,5 @@
obj-$(CONFIG_$(SPL_)GENERIC_PHY) += phy-uclass.o
+obj-$(CONFIG_$(SPL_)PIPE3_PHY) += ti-pipe3-phy.o
ifeq ($(CONFIG_SPL_BUILD)$(CONFIG_TPL_BUILD),)
obj-y += marvell/
diff --git a/drivers/phy/ti-pipe3-phy.c b/drivers/phy/ti-pipe3-phy.c
new file mode 100644
index 000..94942d3
--- /dev/null
+++ b/drivers/phy/ti-pipe3-phy.c
@@ -0,0 +1,368 @@
+/*
+ * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/
+ * Written by Jean-Jacques Hiblot
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+/* PLLCTRL Registers */
+#define PLL_STATUS 0x0004
+#define PLL_GO 0x0008
+#define PLL_CONFIGURATION1 0x000C
+#define PLL_CONFIGURATION2 0x0010
+#define PLL_CONFIGURATION3 0x0014
+#define PLL_CONFIGURATION4 0x0020
+
+#define PLL_REGM_MASK 0x001FFE00
+#define PLL_REGM_SHIFT 9
+#define PLL_REGM_F_MASK 0x0003
+#define PLL_REGM_F_SHIFT0
+#define PLL_REGN_MASK 0x01FE
+#define PLL_REGN_SHIFT 1
+#define PLL_SELFREQDCO_MASK 0x000E
+#define PLL_SELFREQDCO_SHIFT1
+#define PLL_SD_MASK 0x0003FC00
+#define PLL_SD_SHIFT10
+#define SET_PLL_GO 0x1
+#define PLL_TICOPWDNBIT(16)
+#define PLL_LDOPWDN BIT(15)
+#define PLL_LOCK0x2
+#define PLL_IDLE0x1
+
+/* Software rest for the SATA PLL (in CTRL_CORE_SMA_SW_0 register)*/
+#define SATA_PLL_SOFT_RESET (1<<18)
+
+/* PHY POWER CONTROL Register */
+#define OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_MASK 0x003FC000
+#define OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_SHIFT0xE
+
+#define OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_MASK0xFFC0
+#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 */
+
+struct omap_pipe3 {
+ void __iomem*pll_ctrl_base;
+ void __iomem*power_reg;
+ void __iomem*pll_reset_reg;
+ struct pipe3_dpll_map *dpll_map;
+};
+
+
+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;
+};
+
+static inline u32 omap_pipe3_readl(void __iomem *addr, unsigned offset)
+{
+ return readl(addr + offset);
+}
+
+static inline void omap_pipe3_writel(void __iomem *addr, unsigned offset,
+ u32 data)
+{
+ 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 _map->params;
+ }
+
+ printf("%s: No DPLL configuration for %u Hz SYS CLK\n",
+ __func__, rate);
+ return NULL;
+}
+
+static int omap_pipe3_wait_lock(struct omap_pipe3 *pipe3)
+{
+ u32 val;
+ int timeout = PLL_LOCK_TIME;
+
+ do {
+ mdelay(1);
+ val =