1982082d9SJean-Jacques Hiblot /* 2982082d9SJean-Jacques Hiblot * Copyright (C) 2017 Texas Instruments Incorporated - http://www.ti.com/ 3982082d9SJean-Jacques Hiblot * Written by Jean-Jacques Hiblot <jjhiblot@ti.com> 4982082d9SJean-Jacques Hiblot * 5982082d9SJean-Jacques Hiblot * SPDX-License-Identifier: GPL-2.0+ 6982082d9SJean-Jacques Hiblot */ 7982082d9SJean-Jacques Hiblot 8982082d9SJean-Jacques Hiblot #include <common.h> 9982082d9SJean-Jacques Hiblot #include <dm.h> 10982082d9SJean-Jacques Hiblot #include <dm/device.h> 11982082d9SJean-Jacques Hiblot #include <generic-phy.h> 12982082d9SJean-Jacques Hiblot #include <asm/io.h> 13982082d9SJean-Jacques Hiblot #include <asm/arch/sys_proto.h> 14982082d9SJean-Jacques Hiblot #include <syscon.h> 15982082d9SJean-Jacques Hiblot #include <regmap.h> 16982082d9SJean-Jacques Hiblot 17982082d9SJean-Jacques Hiblot /* PLLCTRL Registers */ 18982082d9SJean-Jacques Hiblot #define PLL_STATUS 0x00000004 19982082d9SJean-Jacques Hiblot #define PLL_GO 0x00000008 20982082d9SJean-Jacques Hiblot #define PLL_CONFIGURATION1 0x0000000C 21982082d9SJean-Jacques Hiblot #define PLL_CONFIGURATION2 0x00000010 22982082d9SJean-Jacques Hiblot #define PLL_CONFIGURATION3 0x00000014 23982082d9SJean-Jacques Hiblot #define PLL_CONFIGURATION4 0x00000020 24982082d9SJean-Jacques Hiblot 25982082d9SJean-Jacques Hiblot #define PLL_REGM_MASK 0x001FFE00 26982082d9SJean-Jacques Hiblot #define PLL_REGM_SHIFT 9 27982082d9SJean-Jacques Hiblot #define PLL_REGM_F_MASK 0x0003FFFF 28982082d9SJean-Jacques Hiblot #define PLL_REGM_F_SHIFT 0 29982082d9SJean-Jacques Hiblot #define PLL_REGN_MASK 0x000001FE 30982082d9SJean-Jacques Hiblot #define PLL_REGN_SHIFT 1 31982082d9SJean-Jacques Hiblot #define PLL_SELFREQDCO_MASK 0x0000000E 32982082d9SJean-Jacques Hiblot #define PLL_SELFREQDCO_SHIFT 1 33982082d9SJean-Jacques Hiblot #define PLL_SD_MASK 0x0003FC00 34982082d9SJean-Jacques Hiblot #define PLL_SD_SHIFT 10 35982082d9SJean-Jacques Hiblot #define SET_PLL_GO 0x1 36982082d9SJean-Jacques Hiblot #define PLL_TICOPWDN BIT(16) 37982082d9SJean-Jacques Hiblot #define PLL_LDOPWDN BIT(15) 38982082d9SJean-Jacques Hiblot #define PLL_LOCK 0x2 39982082d9SJean-Jacques Hiblot #define PLL_IDLE 0x1 40982082d9SJean-Jacques Hiblot 41982082d9SJean-Jacques Hiblot /* Software rest for the SATA PLL (in CTRL_CORE_SMA_SW_0 register)*/ 42982082d9SJean-Jacques Hiblot #define SATA_PLL_SOFT_RESET (1<<18) 43982082d9SJean-Jacques Hiblot 44982082d9SJean-Jacques Hiblot /* PHY POWER CONTROL Register */ 45982082d9SJean-Jacques Hiblot #define OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_MASK 0x003FC000 46982082d9SJean-Jacques Hiblot #define OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_SHIFT 0xE 47982082d9SJean-Jacques Hiblot 48982082d9SJean-Jacques Hiblot #define OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_MASK 0xFFC00000 49982082d9SJean-Jacques Hiblot #define OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_SHIFT 0x16 50982082d9SJean-Jacques Hiblot 51982082d9SJean-Jacques Hiblot #define OMAP_CTRL_PIPE3_PHY_TX_RX_POWERON 0x3 52982082d9SJean-Jacques Hiblot #define OMAP_CTRL_PIPE3_PHY_TX_RX_POWEROFF 0x0 53982082d9SJean-Jacques Hiblot 54982082d9SJean-Jacques Hiblot 55982082d9SJean-Jacques Hiblot #define PLL_IDLE_TIME 100 /* in milliseconds */ 56982082d9SJean-Jacques Hiblot #define PLL_LOCK_TIME 100 /* in milliseconds */ 57982082d9SJean-Jacques Hiblot 58982082d9SJean-Jacques Hiblot struct omap_pipe3 { 59982082d9SJean-Jacques Hiblot void __iomem *pll_ctrl_base; 60982082d9SJean-Jacques Hiblot void __iomem *power_reg; 61982082d9SJean-Jacques Hiblot void __iomem *pll_reset_reg; 62982082d9SJean-Jacques Hiblot struct pipe3_dpll_map *dpll_map; 63982082d9SJean-Jacques Hiblot }; 64982082d9SJean-Jacques Hiblot 65982082d9SJean-Jacques Hiblot 66982082d9SJean-Jacques Hiblot struct pipe3_dpll_params { 67982082d9SJean-Jacques Hiblot u16 m; 68982082d9SJean-Jacques Hiblot u8 n; 69982082d9SJean-Jacques Hiblot u8 freq:3; 70982082d9SJean-Jacques Hiblot u8 sd; 71982082d9SJean-Jacques Hiblot u32 mf; 72982082d9SJean-Jacques Hiblot }; 73982082d9SJean-Jacques Hiblot 74982082d9SJean-Jacques Hiblot struct pipe3_dpll_map { 75982082d9SJean-Jacques Hiblot unsigned long rate; 76982082d9SJean-Jacques Hiblot struct pipe3_dpll_params params; 77982082d9SJean-Jacques Hiblot }; 78982082d9SJean-Jacques Hiblot 79982082d9SJean-Jacques Hiblot static inline u32 omap_pipe3_readl(void __iomem *addr, unsigned offset) 80982082d9SJean-Jacques Hiblot { 81982082d9SJean-Jacques Hiblot return readl(addr + offset); 82982082d9SJean-Jacques Hiblot } 83982082d9SJean-Jacques Hiblot 84982082d9SJean-Jacques Hiblot static inline void omap_pipe3_writel(void __iomem *addr, unsigned offset, 85982082d9SJean-Jacques Hiblot u32 data) 86982082d9SJean-Jacques Hiblot { 87982082d9SJean-Jacques Hiblot writel(data, addr + offset); 88982082d9SJean-Jacques Hiblot } 89982082d9SJean-Jacques Hiblot 90982082d9SJean-Jacques Hiblot static struct pipe3_dpll_params *omap_pipe3_get_dpll_params(struct omap_pipe3 91982082d9SJean-Jacques Hiblot *pipe3) 92982082d9SJean-Jacques Hiblot { 93982082d9SJean-Jacques Hiblot u32 rate; 94982082d9SJean-Jacques Hiblot struct pipe3_dpll_map *dpll_map = pipe3->dpll_map; 95982082d9SJean-Jacques Hiblot 96982082d9SJean-Jacques Hiblot rate = get_sys_clk_freq(); 97982082d9SJean-Jacques Hiblot 98982082d9SJean-Jacques Hiblot for (; dpll_map->rate; dpll_map++) { 99982082d9SJean-Jacques Hiblot if (rate == dpll_map->rate) 100982082d9SJean-Jacques Hiblot return &dpll_map->params; 101982082d9SJean-Jacques Hiblot } 102982082d9SJean-Jacques Hiblot 103982082d9SJean-Jacques Hiblot printf("%s: No DPLL configuration for %u Hz SYS CLK\n", 104982082d9SJean-Jacques Hiblot __func__, rate); 105982082d9SJean-Jacques Hiblot return NULL; 106982082d9SJean-Jacques Hiblot } 107982082d9SJean-Jacques Hiblot 108982082d9SJean-Jacques Hiblot static int omap_pipe3_wait_lock(struct omap_pipe3 *pipe3) 109982082d9SJean-Jacques Hiblot { 110982082d9SJean-Jacques Hiblot u32 val; 111982082d9SJean-Jacques Hiblot int timeout = PLL_LOCK_TIME; 112982082d9SJean-Jacques Hiblot 113982082d9SJean-Jacques Hiblot do { 114982082d9SJean-Jacques Hiblot mdelay(1); 115982082d9SJean-Jacques Hiblot val = omap_pipe3_readl(pipe3->pll_ctrl_base, PLL_STATUS); 116982082d9SJean-Jacques Hiblot if (val & PLL_LOCK) 117982082d9SJean-Jacques Hiblot break; 118982082d9SJean-Jacques Hiblot } while (--timeout); 119982082d9SJean-Jacques Hiblot 120982082d9SJean-Jacques Hiblot if (!(val & PLL_LOCK)) { 121982082d9SJean-Jacques Hiblot printf("%s: DPLL failed to lock\n", __func__); 122982082d9SJean-Jacques Hiblot return -EBUSY; 123982082d9SJean-Jacques Hiblot } 124982082d9SJean-Jacques Hiblot 125982082d9SJean-Jacques Hiblot return 0; 126982082d9SJean-Jacques Hiblot } 127982082d9SJean-Jacques Hiblot 128982082d9SJean-Jacques Hiblot static int omap_pipe3_dpll_program(struct omap_pipe3 *pipe3) 129982082d9SJean-Jacques Hiblot { 130982082d9SJean-Jacques Hiblot u32 val; 131982082d9SJean-Jacques Hiblot struct pipe3_dpll_params *dpll_params; 132982082d9SJean-Jacques Hiblot 133982082d9SJean-Jacques Hiblot dpll_params = omap_pipe3_get_dpll_params(pipe3); 134982082d9SJean-Jacques Hiblot if (!dpll_params) { 135982082d9SJean-Jacques Hiblot printf("%s: Invalid DPLL parameters\n", __func__); 136982082d9SJean-Jacques Hiblot return -EINVAL; 137982082d9SJean-Jacques Hiblot } 138982082d9SJean-Jacques Hiblot 139982082d9SJean-Jacques Hiblot val = omap_pipe3_readl(pipe3->pll_ctrl_base, PLL_CONFIGURATION1); 140982082d9SJean-Jacques Hiblot val &= ~PLL_REGN_MASK; 141982082d9SJean-Jacques Hiblot val |= dpll_params->n << PLL_REGN_SHIFT; 142982082d9SJean-Jacques Hiblot omap_pipe3_writel(pipe3->pll_ctrl_base, PLL_CONFIGURATION1, val); 143982082d9SJean-Jacques Hiblot 144982082d9SJean-Jacques Hiblot val = omap_pipe3_readl(pipe3->pll_ctrl_base, PLL_CONFIGURATION2); 145982082d9SJean-Jacques Hiblot val &= ~PLL_SELFREQDCO_MASK; 146982082d9SJean-Jacques Hiblot val |= dpll_params->freq << PLL_SELFREQDCO_SHIFT; 147982082d9SJean-Jacques Hiblot omap_pipe3_writel(pipe3->pll_ctrl_base, PLL_CONFIGURATION2, val); 148982082d9SJean-Jacques Hiblot 149982082d9SJean-Jacques Hiblot val = omap_pipe3_readl(pipe3->pll_ctrl_base, PLL_CONFIGURATION1); 150982082d9SJean-Jacques Hiblot val &= ~PLL_REGM_MASK; 151982082d9SJean-Jacques Hiblot val |= dpll_params->m << PLL_REGM_SHIFT; 152982082d9SJean-Jacques Hiblot omap_pipe3_writel(pipe3->pll_ctrl_base, PLL_CONFIGURATION1, val); 153982082d9SJean-Jacques Hiblot 154982082d9SJean-Jacques Hiblot val = omap_pipe3_readl(pipe3->pll_ctrl_base, PLL_CONFIGURATION4); 155982082d9SJean-Jacques Hiblot val &= ~PLL_REGM_F_MASK; 156982082d9SJean-Jacques Hiblot val |= dpll_params->mf << PLL_REGM_F_SHIFT; 157982082d9SJean-Jacques Hiblot omap_pipe3_writel(pipe3->pll_ctrl_base, PLL_CONFIGURATION4, val); 158982082d9SJean-Jacques Hiblot 159982082d9SJean-Jacques Hiblot val = omap_pipe3_readl(pipe3->pll_ctrl_base, PLL_CONFIGURATION3); 160982082d9SJean-Jacques Hiblot val &= ~PLL_SD_MASK; 161982082d9SJean-Jacques Hiblot val |= dpll_params->sd << PLL_SD_SHIFT; 162982082d9SJean-Jacques Hiblot omap_pipe3_writel(pipe3->pll_ctrl_base, PLL_CONFIGURATION3, val); 163982082d9SJean-Jacques Hiblot 164982082d9SJean-Jacques Hiblot omap_pipe3_writel(pipe3->pll_ctrl_base, PLL_GO, SET_PLL_GO); 165982082d9SJean-Jacques Hiblot 166982082d9SJean-Jacques Hiblot return omap_pipe3_wait_lock(pipe3); 167982082d9SJean-Jacques Hiblot } 168982082d9SJean-Jacques Hiblot 169982082d9SJean-Jacques Hiblot static void omap_control_pipe3_power(struct omap_pipe3 *pipe3, int on) 170982082d9SJean-Jacques Hiblot { 171982082d9SJean-Jacques Hiblot u32 val, rate; 172982082d9SJean-Jacques Hiblot 173982082d9SJean-Jacques Hiblot val = readl(pipe3->power_reg); 174982082d9SJean-Jacques Hiblot 175982082d9SJean-Jacques Hiblot rate = get_sys_clk_freq(); 176982082d9SJean-Jacques Hiblot rate = rate/1000000; 177982082d9SJean-Jacques Hiblot 178982082d9SJean-Jacques Hiblot if (on) { 179982082d9SJean-Jacques Hiblot val &= ~(OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_MASK | 180982082d9SJean-Jacques Hiblot OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_MASK); 181982082d9SJean-Jacques Hiblot val |= OMAP_CTRL_PIPE3_PHY_TX_RX_POWERON << 182982082d9SJean-Jacques Hiblot OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_SHIFT; 183982082d9SJean-Jacques Hiblot val |= rate << 184982082d9SJean-Jacques Hiblot OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_FREQ_SHIFT; 185982082d9SJean-Jacques Hiblot } else { 186982082d9SJean-Jacques Hiblot val &= ~OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_MASK; 187982082d9SJean-Jacques Hiblot val |= OMAP_CTRL_PIPE3_PHY_TX_RX_POWEROFF << 188982082d9SJean-Jacques Hiblot OMAP_CTRL_PIPE3_PHY_PWRCTL_CLK_CMD_SHIFT; 189982082d9SJean-Jacques Hiblot } 190982082d9SJean-Jacques Hiblot 191982082d9SJean-Jacques Hiblot writel(val, pipe3->power_reg); 192982082d9SJean-Jacques Hiblot } 193982082d9SJean-Jacques Hiblot 194982082d9SJean-Jacques Hiblot static int pipe3_init(struct phy *phy) 195982082d9SJean-Jacques Hiblot { 196982082d9SJean-Jacques Hiblot int ret; 197982082d9SJean-Jacques Hiblot u32 val; 198982082d9SJean-Jacques Hiblot struct omap_pipe3 *pipe3 = dev_get_priv(phy->dev); 199982082d9SJean-Jacques Hiblot 200982082d9SJean-Jacques Hiblot /* Program the DPLL only if not locked */ 201982082d9SJean-Jacques Hiblot val = omap_pipe3_readl(pipe3->pll_ctrl_base, PLL_STATUS); 202982082d9SJean-Jacques Hiblot if (!(val & PLL_LOCK)) { 203982082d9SJean-Jacques Hiblot ret = omap_pipe3_dpll_program(pipe3); 204982082d9SJean-Jacques Hiblot if (ret) 205982082d9SJean-Jacques Hiblot return ret; 206982082d9SJean-Jacques Hiblot } else { 207982082d9SJean-Jacques Hiblot /* else just bring it out of IDLE mode */ 208982082d9SJean-Jacques Hiblot val = omap_pipe3_readl(pipe3->pll_ctrl_base, 209982082d9SJean-Jacques Hiblot PLL_CONFIGURATION2); 210982082d9SJean-Jacques Hiblot if (val & PLL_IDLE) { 211982082d9SJean-Jacques Hiblot val &= ~PLL_IDLE; 212982082d9SJean-Jacques Hiblot omap_pipe3_writel(pipe3->pll_ctrl_base, 213982082d9SJean-Jacques Hiblot PLL_CONFIGURATION2, val); 214982082d9SJean-Jacques Hiblot ret = omap_pipe3_wait_lock(pipe3); 215982082d9SJean-Jacques Hiblot if (ret) 216982082d9SJean-Jacques Hiblot return ret; 217982082d9SJean-Jacques Hiblot } 218982082d9SJean-Jacques Hiblot } 219982082d9SJean-Jacques Hiblot return 0; 220982082d9SJean-Jacques Hiblot } 221982082d9SJean-Jacques Hiblot 222982082d9SJean-Jacques Hiblot static int pipe3_power_on(struct phy *phy) 223982082d9SJean-Jacques Hiblot { 224982082d9SJean-Jacques Hiblot struct omap_pipe3 *pipe3 = dev_get_priv(phy->dev); 225982082d9SJean-Jacques Hiblot 226982082d9SJean-Jacques Hiblot /* Power up the PHY */ 227982082d9SJean-Jacques Hiblot omap_control_pipe3_power(pipe3, 1); 228982082d9SJean-Jacques Hiblot 229982082d9SJean-Jacques Hiblot return 0; 230982082d9SJean-Jacques Hiblot } 231982082d9SJean-Jacques Hiblot 232982082d9SJean-Jacques Hiblot static int pipe3_power_off(struct phy *phy) 233982082d9SJean-Jacques Hiblot { 234982082d9SJean-Jacques Hiblot struct omap_pipe3 *pipe3 = dev_get_priv(phy->dev); 235982082d9SJean-Jacques Hiblot 236982082d9SJean-Jacques Hiblot /* Power down the PHY */ 237982082d9SJean-Jacques Hiblot omap_control_pipe3_power(pipe3, 0); 238982082d9SJean-Jacques Hiblot 239982082d9SJean-Jacques Hiblot return 0; 240982082d9SJean-Jacques Hiblot } 241982082d9SJean-Jacques Hiblot 242982082d9SJean-Jacques Hiblot static int pipe3_exit(struct phy *phy) 243982082d9SJean-Jacques Hiblot { 244982082d9SJean-Jacques Hiblot u32 val; 245982082d9SJean-Jacques Hiblot int timeout = PLL_IDLE_TIME; 246982082d9SJean-Jacques Hiblot struct omap_pipe3 *pipe3 = dev_get_priv(phy->dev); 247982082d9SJean-Jacques Hiblot 248982082d9SJean-Jacques Hiblot pipe3_power_off(phy); 249982082d9SJean-Jacques Hiblot 250982082d9SJean-Jacques Hiblot /* Put DPLL in IDLE mode */ 251982082d9SJean-Jacques Hiblot val = omap_pipe3_readl(pipe3->pll_ctrl_base, PLL_CONFIGURATION2); 252982082d9SJean-Jacques Hiblot val |= PLL_IDLE; 253982082d9SJean-Jacques Hiblot omap_pipe3_writel(pipe3->pll_ctrl_base, PLL_CONFIGURATION2, val); 254982082d9SJean-Jacques Hiblot 255982082d9SJean-Jacques Hiblot /* wait for LDO and Oscillator to power down */ 256982082d9SJean-Jacques Hiblot do { 257982082d9SJean-Jacques Hiblot mdelay(1); 258982082d9SJean-Jacques Hiblot val = omap_pipe3_readl(pipe3->pll_ctrl_base, PLL_STATUS); 259982082d9SJean-Jacques Hiblot if ((val & PLL_TICOPWDN) && (val & PLL_LDOPWDN)) 260982082d9SJean-Jacques Hiblot break; 261982082d9SJean-Jacques Hiblot } while (--timeout); 262982082d9SJean-Jacques Hiblot 263982082d9SJean-Jacques Hiblot if (!(val & PLL_TICOPWDN) || !(val & PLL_LDOPWDN)) { 264982082d9SJean-Jacques Hiblot error("%s: Failed to power down DPLL: PLL_STATUS 0x%x\n", 265982082d9SJean-Jacques Hiblot __func__, val); 266982082d9SJean-Jacques Hiblot return -EBUSY; 267982082d9SJean-Jacques Hiblot } 268982082d9SJean-Jacques Hiblot 269982082d9SJean-Jacques Hiblot val = readl(pipe3->pll_reset_reg); 270982082d9SJean-Jacques Hiblot writel(val | SATA_PLL_SOFT_RESET, pipe3->pll_reset_reg); 271982082d9SJean-Jacques Hiblot mdelay(1); 272982082d9SJean-Jacques Hiblot writel(val & ~SATA_PLL_SOFT_RESET, pipe3->pll_reset_reg); 273982082d9SJean-Jacques Hiblot return 0; 274982082d9SJean-Jacques Hiblot } 275982082d9SJean-Jacques Hiblot 276982082d9SJean-Jacques Hiblot static void *get_reg(struct udevice *dev, const char *name) 277982082d9SJean-Jacques Hiblot { 278982082d9SJean-Jacques Hiblot struct udevice *syscon; 279982082d9SJean-Jacques Hiblot struct regmap *regmap; 280982082d9SJean-Jacques Hiblot const fdt32_t *cell; 281982082d9SJean-Jacques Hiblot int len, err; 282982082d9SJean-Jacques Hiblot void *base; 283982082d9SJean-Jacques Hiblot 284982082d9SJean-Jacques Hiblot err = uclass_get_device_by_phandle(UCLASS_SYSCON, dev, 285982082d9SJean-Jacques Hiblot name, &syscon); 286982082d9SJean-Jacques Hiblot if (err) { 287982082d9SJean-Jacques Hiblot error("unable to find syscon device for %s (%d)\n", 288982082d9SJean-Jacques Hiblot name, err); 289982082d9SJean-Jacques Hiblot return NULL; 290982082d9SJean-Jacques Hiblot } 291982082d9SJean-Jacques Hiblot 292982082d9SJean-Jacques Hiblot regmap = syscon_get_regmap(syscon); 293982082d9SJean-Jacques Hiblot if (IS_ERR(regmap)) { 294982082d9SJean-Jacques Hiblot error("unable to find regmap for %s (%ld)\n", 295982082d9SJean-Jacques Hiblot name, PTR_ERR(regmap)); 296982082d9SJean-Jacques Hiblot return NULL; 297982082d9SJean-Jacques Hiblot } 298982082d9SJean-Jacques Hiblot 299*da409cccSSimon Glass cell = fdt_getprop(gd->fdt_blob, dev_of_offset(dev), name, 300982082d9SJean-Jacques Hiblot &len); 301982082d9SJean-Jacques Hiblot if (len < 2*sizeof(fdt32_t)) { 302982082d9SJean-Jacques Hiblot error("offset not available for %s\n", name); 303982082d9SJean-Jacques Hiblot return NULL; 304982082d9SJean-Jacques Hiblot } 305982082d9SJean-Jacques Hiblot 306982082d9SJean-Jacques Hiblot base = regmap_get_range(regmap, 0); 307982082d9SJean-Jacques Hiblot if (!base) 308982082d9SJean-Jacques Hiblot return NULL; 309982082d9SJean-Jacques Hiblot 310982082d9SJean-Jacques Hiblot return fdtdec_get_number(cell + 1, 1) + base; 311982082d9SJean-Jacques Hiblot } 312982082d9SJean-Jacques Hiblot 313982082d9SJean-Jacques Hiblot static int pipe3_phy_probe(struct udevice *dev) 314982082d9SJean-Jacques Hiblot { 315982082d9SJean-Jacques Hiblot fdt_addr_t addr; 316982082d9SJean-Jacques Hiblot fdt_size_t sz; 317982082d9SJean-Jacques Hiblot struct omap_pipe3 *pipe3 = dev_get_priv(dev); 318982082d9SJean-Jacques Hiblot 319a821c4afSSimon Glass addr = devfdt_get_addr_size_index(dev, 2, &sz); 320982082d9SJean-Jacques Hiblot if (addr == FDT_ADDR_T_NONE) { 321982082d9SJean-Jacques Hiblot error("missing pll ctrl address\n"); 322982082d9SJean-Jacques Hiblot return -EINVAL; 323982082d9SJean-Jacques Hiblot } 324982082d9SJean-Jacques Hiblot 325982082d9SJean-Jacques Hiblot pipe3->pll_ctrl_base = map_physmem(addr, sz, MAP_NOCACHE); 326982082d9SJean-Jacques Hiblot if (!pipe3->pll_ctrl_base) { 327982082d9SJean-Jacques Hiblot error("unable to remap pll ctrl\n"); 328982082d9SJean-Jacques Hiblot return -EINVAL; 329982082d9SJean-Jacques Hiblot } 330982082d9SJean-Jacques Hiblot 331982082d9SJean-Jacques Hiblot pipe3->power_reg = get_reg(dev, "syscon-phy-power"); 332982082d9SJean-Jacques Hiblot if (!pipe3->power_reg) 333982082d9SJean-Jacques Hiblot return -EINVAL; 334982082d9SJean-Jacques Hiblot 335982082d9SJean-Jacques Hiblot pipe3->pll_reset_reg = get_reg(dev, "syscon-pllreset"); 336982082d9SJean-Jacques Hiblot if (!pipe3->pll_reset_reg) 337982082d9SJean-Jacques Hiblot return -EINVAL; 338982082d9SJean-Jacques Hiblot 339982082d9SJean-Jacques Hiblot pipe3->dpll_map = (struct pipe3_dpll_map *)dev_get_driver_data(dev); 340982082d9SJean-Jacques Hiblot 341982082d9SJean-Jacques Hiblot return 0; 342982082d9SJean-Jacques Hiblot } 343982082d9SJean-Jacques Hiblot 344982082d9SJean-Jacques Hiblot static struct pipe3_dpll_map dpll_map_sata[] = { 345982082d9SJean-Jacques Hiblot {12000000, {1000, 7, 4, 6, 0} }, /* 12 MHz */ 346982082d9SJean-Jacques Hiblot {16800000, {714, 7, 4, 6, 0} }, /* 16.8 MHz */ 347982082d9SJean-Jacques Hiblot {19200000, {625, 7, 4, 6, 0} }, /* 19.2 MHz */ 348982082d9SJean-Jacques Hiblot {20000000, {600, 7, 4, 6, 0} }, /* 20 MHz */ 349982082d9SJean-Jacques Hiblot {26000000, {461, 7, 4, 6, 0} }, /* 26 MHz */ 350982082d9SJean-Jacques Hiblot {38400000, {312, 7, 4, 6, 0} }, /* 38.4 MHz */ 351982082d9SJean-Jacques Hiblot { }, /* Terminator */ 352982082d9SJean-Jacques Hiblot }; 353982082d9SJean-Jacques Hiblot 354982082d9SJean-Jacques Hiblot static const struct udevice_id pipe3_phy_ids[] = { 355982082d9SJean-Jacques Hiblot { .compatible = "ti,phy-pipe3-sata", .data = (ulong)&dpll_map_sata }, 356982082d9SJean-Jacques Hiblot { } 357982082d9SJean-Jacques Hiblot }; 358982082d9SJean-Jacques Hiblot 359982082d9SJean-Jacques Hiblot static struct phy_ops pipe3_phy_ops = { 360982082d9SJean-Jacques Hiblot .init = pipe3_init, 361982082d9SJean-Jacques Hiblot .power_on = pipe3_power_on, 362982082d9SJean-Jacques Hiblot .power_off = pipe3_power_off, 363982082d9SJean-Jacques Hiblot .exit = pipe3_exit, 364982082d9SJean-Jacques Hiblot }; 365982082d9SJean-Jacques Hiblot 366982082d9SJean-Jacques Hiblot U_BOOT_DRIVER(pipe3_phy) = { 367982082d9SJean-Jacques Hiblot .name = "pipe3_phy", 368982082d9SJean-Jacques Hiblot .id = UCLASS_PHY, 369982082d9SJean-Jacques Hiblot .of_match = pipe3_phy_ids, 370982082d9SJean-Jacques Hiblot .ops = &pipe3_phy_ops, 371982082d9SJean-Jacques Hiblot .probe = pipe3_phy_probe, 372982082d9SJean-Jacques Hiblot .priv_auto_alloc_size = sizeof(struct omap_pipe3), 373982082d9SJean-Jacques Hiblot }; 374