// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2018 Marvell
*
* Authors:
* Evan Wang <xswang@marvell.com>
* Miquèl Raynal <miquel.raynal@bootlin.com>
* Pali Rohár <pali@kernel.org>
* Marek Behún <kabel@kernel.org>
*
* Structure inspired from phy-mvebu-cp110-comphy.c written by Antoine Tenart.
* Comphy code from ARM Trusted Firmware ported by Pali Rohár <pali@kernel.org>
* and Marek Behún <kabel@kernel.org>.
*/
#include <linux/bitfield.h>
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/phy.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/spinlock.h>
#define PLL_SET_DELAY_US 600
#define COMPHY_PLL_SLEEP 1000
#define COMPHY_PLL_TIMEOUT 150000
/* Comphy lane2 indirect access register offset */
#define COMPHY_LANE2_INDIR_ADDR 0x0
#define COMPHY_LANE2_INDIR_DATA 0x4
/* SATA and USB3 PHY offset compared to SATA PHY */
#define COMPHY_LANE2_REGS_BASE 0x200
/*
* When accessing common PHY lane registers directly, we need to shift by 1,
* since the registers are 16-bit.
*/
#define COMPHY_LANE_REG_DIRECT(reg) (((reg) & 0x7FF) << 1)
/* COMPHY registers */
#define COMPHY_POWER_PLL_CTRL 0x01
#define PU_IVREF_BIT BIT(15)
#define PU_PLL_BIT BIT(14)
#define PU_RX_BIT BIT(13)
#define PU_TX_BIT BIT(12)
#define PU_TX_INTP_BIT BIT(11)
#define PU_DFE_BIT BIT(10)
#define RESET_DTL_RX_BIT BIT(9)
#define PLL_LOCK_BIT BIT(8)
#define REF_FREF_SEL_MASK GENMASK(4, 0)
#define REF_FREF_SEL_SERDES_25MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x1)
#define REF_FREF_SEL_SERDES_40MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x3)
#define REF_FREF_SEL_SERDES_50MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x4)
#define REF_FREF_SEL_PCIE_USB3_25MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x2)
#define REF_FREF_SEL_PCIE_USB3_40MHZ FIELD_PREP(REF_FREF_SEL_MASK, 0x3)
#define COMPHY_MODE_MASK GENMASK(7, 5)
#define COMPHY_MODE_SATA FIELD_PREP(COMPHY_MODE_MASK, 0x0)
#define COMPHY_MODE_PCIE FIELD_PREP(COMPHY_MODE_MASK, 0x3)
#define COMPHY_MODE_SERDES FIELD_PREP(COMPHY_MODE_MASK, 0x4)
#define COMPHY_MODE_USB3 FIELD_PREP(COMPHY_MODE_MASK, 0x5)
#define COMPHY_KVCO_CAL_CTRL 0x02
#define USE_MAX_PLL_RATE_BIT BIT(12)
#define SPEED_PLL_MASK GENMASK(7, 2)
#define SPEED_PLL_VALUE_16 FIELD_PREP(SPEED_PLL_MASK, 0x10)
#define COMPHY_DIG_LOOPBACK_EN 0x23
#define SEL_DATA_WIDTH_MASK GENMASK(11, 10)
#define DATA_WIDTH_10BIT FIELD_PREP(SEL_DATA_WIDTH_MASK, 0x0)
#define DATA_WIDTH_20BIT FIELD_PREP(SEL_DATA_WIDTH_MASK, 0x1)
#define DATA_WIDTH_40BIT FIELD_PREP(SEL_DATA_WIDTH_MASK, 0x2)
#define PLL_READY_TX_BIT BIT(4)
#define COMPHY_SYNC_PATTERN 0x24
#define TXD_INVERT_BIT BIT(10)
#define RXD_INVERT_BIT BIT(11)
#define COMPHY_SYNC_MASK_GEN 0x25
#define PHY_GEN_MAX_MASK GENMASK(11, 10)
#define PHY_GEN_MAX_USB3_5G FIELD_PREP(PHY_GEN_MAX_MASK, 0x1)
#define COMPHY_ISOLATION_CTRL 0x26
#define PHY_ISOLATE_MODE BIT(15)
#define COMPHY_GEN2_SET2 0x3e
#define GS2_TX_SSC_AMP_MASK GENMASK(15, 9)
#define GS2_TX_SSC_AMP_4128 FIELD_PREP(GS2_TX_SSC_AMP_MASK, 0x20)
#define GS2_VREG_RXTX_MAS_ISET_MASK GENMASK(8, 7)
#define GS2_VREG_RXTX_MAS_ISET_60U FIELD_PREP(GS2_VREG_RXTX_MAS_ISET_MASK,\
0x0)
#define GS2_VREG_RXTX_MAS_ISET_80U FIELD_PREP(GS2_VREG_RXTX_MAS_ISET_MASK,\
0x1)
#define GS2_VREG_RXTX_MAS_ISET_100U FIELD_PREP(GS2_VREG_RXTX_MAS_ISET_MASK,\
0x2)
#define GS2_VREG_RXTX_MAS_ISET_120U FIELD_PREP(GS2_VREG_RXTX_MAS_ISET_MASK,\
0x3)
#define GS2_RSVD_6_0_MASK GENMASK(6, 0)
#define COMPHY_GEN3_SET2 0x3f
#define COMPHY_IDLE_SYNC_EN 0x48
#define IDLE_SYNC_EN BIT(12)
#define COMPHY_MISC_CTRL0 0x4F
#define CLK100M_125M_EN BIT(4)
#define TXDCLK_2X_SEL BIT(6)
#define CLK500M_EN BIT(7)
#define PHY_REF_CLK_SEL BIT(10)
#define COMPHY_SFT_RESET 0x52
#define SFT_RST BIT(9)
#define SFT_RST_NO_REG BIT(10)
#define COMPHY_MISC_CTRL1 0x73
#define SEL_BITS_PCIE_FORCE BIT(15)
#define COMPHY_GEN2_SET3 0x112
#define GS3_FFE_CAP_SEL_MASK GENMASK(3, 0)
#define GS3_FFE_CAP_SEL_VALUE FIELD_PREP(GS3_FFE_CAP_SEL_MASK, 0xF)
/* PIPE registers */
#define COMPHY_PIPE_LANE_CFG0 0x180
#define PRD_TXDEEMPH0_MASK BIT(0)
#define PRD_TXMARGIN_MASK GENMASK(3, 1)
#define PRD_TXSWING_MASK BIT(4)
#define CFG_TX_ALIGN_POS_MASK GENMASK(8, 5)
#define COMPHY_PIPE_LANE_CFG1 0x181
#define PRD_TXDEEMPH1_MASK BIT(15)
#define USE_MAX_PLL_RATE_EN BIT(9)
#define TX_DET_RX_MODE BIT(6)
#define GEN2_TX_DATA_DLY_MASK GENMASK(4, 3)
#define GEN2_TX_DATA_DLY_DEFT FIELD_PREP(GEN2_TX_DATA_DLY_MASK, 2)
#define TX_ELEC_IDLE_MODE_EN BIT(0)
#define COMPHY_PIPE_LANE_STAT1 0x183
#define TXDCLK_PCLK_EN BIT(0)
#define COMPHY_PIPE_LANE_CFG4 0x188
#define SPREAD_SPECTRUM_CLK_EN BIT(7)
#define COMPHY_PIPE_RST_CLK_CTRL 0x1C1
#define PIPE_SOFT_RESET BIT(0)
#define PIPE_REG_RESET BIT(1)
#define MODE