/*
 * 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 */

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;
	}

	printf("%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)) {
		printf("%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) {
		printf("%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)) {
		printf("%s: Failed to power down DPLL: PLL_STATUS 0x%x\n",
		       __func__, val);
		return -EBUSY;
	}

	return 0;
}

